Repository: ESA-PhiLab/PyRawS (language: python)

Issue:
Cleaning and fixing typos in setup.py
* Removing unused packages in environment and setup.py
* Changed wrong references to the repo in setup.py
* Made some cleaning in the notebook.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/autoblack.yml b/.github/workflows/autoblack.yml
new file mode 100644
index 0000000..6551a67
--- /dev/null
+++ b/.github/workflows/autoblack.yml
@@ -0,0 +1,15 @@
+name: autoblack
+on: [pull_request]
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v1
+      - name: Set up Python 3.9
+        uses: actions/setup-python@v1
+        with:
+          python-version: 3.9
+      - name: Install Black
+        run: pip install black
+      - name: Run black --check .
+        run: black --check .
\ No newline at end of file
diff --git a/environment.yml b/environment.yml
index cf7efde..92651c6 100644
--- a/environment.yml
+++ b/environment.yml
@@ -5,13 +5,8 @@ channels:
 dependencies:
   - python=3.9
   - geopy
-  - earthengine-api
-  - geopandas
-  - ipywidgets
-  - jupyter
   - numpy
   - geopandas
-  - folium
   - geopy
   - scipy
   - matplotlib
diff --git a/pyraws/__init__.py b/pyraws/__init__.py
index a866c8a..79875ad 100644
--- a/pyraws/__init__.py
+++ b/pyraws/__init__.py
@@ -63,7 +63,9 @@ def set_log_level(level=logging.WARN):
     """Allows setting global log level for the application.
 
     Args:
-        level (logging.level, optional): Level to set, available are (logging.DEBUG,logging.INFO,logging.WARN,logging.ERROR). Defaults to logging.WARN.
+        level (logging.level, optional): Level to set, available are
+                                        (logging.DEBUG,logging.INFO,logging.WARN,logging.ERROR).
+                                        Defaults to logging.WARN.
     """
     logger.setLevel(level)
     if level == 10:
diff --git a/pyraws/l1/l1_event.py b/pyraws/l1/l1_event.py
index 063697a..bc673ce 100644
--- a/pyraws/l1/l1_event.py
+++ b/pyraws/l1/l1_event.py
@@ -1,8 +1,12 @@
-
 from .l1_tile import L1C_tile
 from ..utils.date_utils import get_timestamp
 from ..utils.constants import BAND_SPATIAL_RESOLUTION_DICT
-from ..utils.l1_utils import get_l1C_image_default_path, read_L1C_event_from_database, read_L1C_event_from_path, reproject_raster
+from ..utils.l1_utils import (
+    get_l1C_image_default_path,
+    read_L1C_event_from_database,
+    read_L1C_event_from_path,
+    reproject_raster,
+)
 import matplotlib.pyplot as plt
 import numpy as np
 import os
@@ -15,16 +19,22 @@
 from tqdm import tqdm
 
 
+class L1C_event:
+    __device = None
+    __bands_names = []
+    __tiles_collection = []
+    __event_name = []
 
-
-class L1C_event():
-    __device=None
-    __bands_names=[]
-    __tiles_collection=[]
-    __event_name=[]
-
-    def __init__(self, tiles_collection=None, bands_names=None, event_class=None, event_name=None, device=torch.device("cpu")):
-        """Creates an L1C image from a tiles collection and band_names. It is possible to associate an image class to the image.
+    def __init__(
+        self,
+        tiles_collection=None,
+        bands_names=None,
+        event_class=None,
+        event_name=None,
+        device=torch.device("cpu"),
+    ):
+        """Creates an L1C image from a tiles collection and band_names.
+        It is possible to associate an image class to the image.
 
         Args:
             tiles_collection (list, optional): list of L1C_tile. Defaults to None.
@@ -34,23 +44,25 @@ def __init__(self, tiles_collection=None, bands_names=None, event_class=None, ev
             device (torch.device, optional): device for each L0 tile in the image. Defaults to torch.device("cpu").
         """
         if bands_names is None:
-            self.__bands_names=[]
+            self.__bands_names = []
         else:
-            self.__bands_names=bands_names
+            self.__bands_names = bands_names
 
-        self.__event_class=event_class
+        self.__event_class = event_class
         if tiles_collection is None:
-            self.__tiles_collection=[]
-            self.n_tiles=0
+            self.__tiles_collection = []
+            self.n_tiles = 0
         else:
             for n in range(len(tiles_collection)):
-                self.__tiles_collection.append(torch.device(tiles_collection[n], device=device))
-            self.n_tiles=len(self.__tiles_collection)
+                self.__tiles_collection.append(
+                    torch.device(tiles_collection[n], device=device)
+                )
+            self.n_tiles = len(self.__tiles_collection)
+
+        self.n_tiles = 0
 
-        self.n_tiles=0
+        self.__event_name = event_name
 
-        self.__event_name=event_name
-    
     def get_bands_list(self):
         """Returns the list of bands of every L1C_tile object in the collection.
 
@@ -66,7 +78,7 @@ def get_event_class(self):
             dict: Returns {useful granules : bounding box dictionary}
         """
         return self.__event_class
-    
+
     def from_path(self, l1c_dir_path, bands_list, reproject_bounds=True, verbose=True):
         """Read specific bands of the Sentinel-2 L0 event located at ""l0_dir_path"".
 
@@ -77,68 +89,125 @@ def from_path(self, l1c_dir_path, bands_list, reproject_bounds=True, verbose=Tru
             verbose (bool, optional): if True, if True, verbose mode is used. Defaults to True.
         """
         if reproject_bounds:
-            crs="EPSG:4326:"
+            crs = "EPSG:4326:"
         else:
-            crs="EPSG:32633:"
+            crs = "EPSG:32633:"
 
         if bands_list is None:
-            bands_list=list(BAND_SPATIAL_RESOLUTION_DICT.keys())
+            bands_list = list(BAND_SPATIAL_RESOLUTION_DICT.keys())
         else:
-            bands_list=bands_list
-        
-        try:
-            tiles_collection_dict, tiles_coordinates_dict, footprint_coordinates_dict,bands_file_name_dict_dict=read_L1C_event_from_path(l1c_dir_path, bands_list, reproject_bounds, verbose, device=self.__device)
-        except:
-            raise ValueError("Impossible to open the L1C file at: "+colored(l1c_dir_path, "red")+".")
+            bands_list = bands_list
 
-        self.__event_name=l1c_dir_path.split(os.sep)[-1]
-        tiles_names=list(tiles_collection_dict.keys())
-        self.__bands_names=bands_list
-        self.__event_class=None
+        try:
+            (
+                tiles_collection_dict,
+                tiles_coordinates_dict,
+                footprint_coordinates_dict,
+                bands_file_name_dict_dict,
+            ) = read_L1C_event_from_path(
+                l1c_dir_path,
+                bands_list,
+                reproject_bounds,
+                verbose,
+                device=self.__device,
+            )
+        except:  # noqa: E722
+            raise ValueError(
+                "Impossible to open the L1C file at: "
+                + colored(l1c_dir_path, "red")
+                + "."
+            )
+
+        self.__event_name = l1c_dir_path.split(os.sep)[-1]
+        tiles_names = list(tiles_collection_dict.keys())
+        self.__bands_names = bands_list
+        self.__event_class = None
 
         for tile_name in tiles_names:
-            tile=tiles_collection_dict[tile_name]
-            new_tile=L1C_tile(device=self.__device)
-            new_tile.create_tile(bands_list, tile, tile_name, tiles_coordinates_dict[tile_name], footprint_coordinates_dict[tile_name], bands_file_name_dict_dict[tile_name], crs)
+            tile = tiles_collection_dict[tile_name]
+            new_tile = L1C_tile(device=self.__device)
+            new_tile.create_tile(
+                bands_list,
+                tile,
+                tile_name,
+                tiles_coordinates_dict[tile_name],
+                footprint_coordinates_dict[tile_name],
+                bands_file_name_dict_dict[tile_name],
+                crs,
+            )
             self.__tiles_collection.append(new_tile)
-            
-        self.n_tiles=len(self.__tiles_collection)
-            
-    def from_database(self, id_event, bands_list=None, cfg_file_dict=None, id_l0_l1_dict=None, reproject_bounds=True, verbose=True, database="THRAWS"):
+
+        self.n_tiles = len(self.__tiles_collection)
+
+    def from_database(
+        self,
+        id_event,
+        bands_list=None,
+        cfg_file_dict=None,
+        id_l0_l1_dict=None,
+        reproject_bounds=True,
+        verbose=True,
+        database="THRAWS",
+    ):
         """Read specific bands of the L1 Sentine2 image ""id_event"", specified in "bands_list", from database.
 
         Args:
             id_event (str): event ID.
-            bands_list (list, optional): bands list. If None, all bands are used and sorted according to the datasheet order. Defaults to None.
-            cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories. If None, internal CSV database will be parsed. 
+            bands_list (list, optional): bands list. If None, all bands are used and sorted according to the datasheet order.
+                                         Defaults to None.
+            cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories.
+                                            If None, internal CSV database will be parsed.
             id_l0_l1_dict (dict, optional): id-l0-l1 dictionary. If None, internal CSV database will be parsed.
             reproject_bounds (bool, optional): if True, bounds are reprojected to EPGS:4326.
             verbose (bool, optional): if True, if True, verbose mode is used. Defaults to True.
             database (string, optional): database name. Defaults to "THRAWS".
-            """
+        """
 
-        self.__event_name=id_event
+        self.__event_name = id_event
 
         if reproject_bounds:
-            crs="EPSG:4326:"
+            crs = "EPSG:4326:"
         else:
-            crs="EPSG:32633:"
-        
+            crs = "EPSG:32633:"
+
         if bands_list is None:
-            bands_list=list(BAND_SPATIAL_RESOLUTION_DICT.keys())
-            
-        tiles_collection_dict, tiles_coordinates_dict, footprint_coordinates_dict,bands_file_name_dict_dict,event_class=read_L1C_event_from_database(id_event, bands_list, cfg_file_dict, id_l0_l1_dict, database, reproject_bounds, verbose, device=self.__device)
-        tiles_names=list(tiles_collection_dict.keys())
-        self.__bands_names=bands_list
-        self.__event_class=event_class
+            bands_list = list(BAND_SPATIAL_RESOLUTION_DICT.keys())
+
+        (
+            tiles_collection_dict,
+            tiles_coordinates_dict,
+            footprint_coordinates_dict,
+            bands_file_name_dict_dict,
+            event_class,
+        ) = read_L1C_event_from_database(
+            id_event,
+            bands_list,
+            cfg_file_dict,
+            id_l0_l1_dict,
+            database,
+            reproject_bounds,
+            verbose,
+            device=self.__device,
+        )
+        tiles_names = list(tiles_collection_dict.keys())
+        self.__bands_names = bands_list
+        self.__event_class = event_class
 
         for tile_name in tiles_names:
-            tile=tiles_collection_dict[tile_name]
-            new_tile=L1C_tile(device=self.__device)
-            new_tile.create_tile(bands_list, tile, tile_name, tiles_coordinates_dict[tile_name], footprint_coordinates_dict[tile_name], bands_file_name_dict_dict[tile_name], crs)
+            tile = tiles_collection_dict[tile_name]
+            new_tile = L1C_tile(device=self.__device)
+            new_tile.create_tile(
+                bands_list,
+                tile,
+                tile_name,
+                tiles_coordinates_dict[tile_name],
+                footprint_coordinates_dict[tile_name],
+                bands_file_name_dict_dict[tile_name],
+                crs,
+            )
             self.__tiles_collection.append(new_tile)
-            
-        self.n_tiles=len(self.__tiles_collection)
+
+        self.n_tiles = len(self.__tiles_collection)
 
     def get_tile(self, tile_idx):
         """It returns the tile addressed by tile_idx.
@@ -147,34 +216,50 @@ def get_tile(self, tile_idx):
             tile_idx (int): tile index.
         """
         return self.__tiles_collection[tile_idx]
-                
+
     def show_tiles_info(self):
-        """Print tiles info.
-        """
-        tiles_info=self.get_tiles_info()
-        tiles_names=list(tiles_info.keys())
+        """Print tiles info."""
+        tiles_info = self.get_tiles_info()
+        tiles_names = list(tiles_info.keys())
 
         for n in range(len(tiles_names)):
-            print(colored("------------------Tile "+str(n)+" ----------------------------", "blue"))
+            print(
+                colored(
+                    "------------------Tile "
+                    + str(n)
+                    + " ----------------------------",
+                    "blue",
+                )
+            )
             print("Name: ", colored(tiles_info[tiles_names[n]][0], "red"))
             print("Sensing time: ", colored(tiles_info[tiles_names[n]][1], "red"))
-            print("Creation time: ", colored(tiles_info[tiles_names[n]][2], "red"))  
-            coordinates=tiles_info[tiles_names[n]][3]
-            footprint_coordinates=tiles_info[tiles_names[n]][4]
+            print("Creation time: ", colored(tiles_info[tiles_names[n]][2], "red"))
+            coordinates = tiles_info[tiles_names[n]][3]
+            footprint_coordinates = tiles_info[tiles_names[n]][4]
             print("Corners coordinates: \n")
             for n in range(len(coordinates)):
-                print(colored("\tP_"+str(n), "blue") + " : " + colored(str(coordinates[n])+"\n", "red"))
+                print(
+                    colored("\tP_" + str(n), "blue")
+                    + " : "
+                    + colored(str(coordinates[n]) + "\n", "red")
+                )
             print("\n")
             print("Footprint's coordinates: \n")
             for n in range(len(footprint_coordinates)):
-                print(colored("\tP_"+str(n), "blue") + " : " + colored(str(footprint_coordinates[n])+"\n", "red"))
+                print(
+                    colored("\tP_" + str(n), "blue")
+                    + " : "
+                    + colored(str(footprint_coordinates[n]) + "\n", "red")
+                )
             print("\n")
 
     def get_tiles_names(self, tiles_idx=None):
         """Return names of the tiles requested through tiles_idx from tiles names.
 
         Args:
-            tiles_idx (list, optional): list of tiles for which getting the names. If None, all the names of the tiles in the collection are returned. Defaults to None.
+            tiles_idx (list, optional): list of tiles for which getting the names.
+                                      If None, all the names of the tiles in the collection are returned.
+                                      Defaults to None.
 
         Raises:
             ValueError: Empty tiles lists
@@ -182,12 +267,12 @@ def get_tiles_names(self, tiles_idx=None):
         Returns:
             list: tiles' names.
         """
-        tiles_names=[]
+        tiles_names = []
         if len(self.__tiles_collection) == 0:
             raise ValueError("Empty tiles lists.")
 
         if tiles_idx is None:
-            tiles_idx=range(len(self.__tiles_collection))
+            tiles_idx = range(len(self.__tiles_collection))
 
         for tile_idx in tiles_idx:
             tiles_names.append(self.get_tile(tile_idx).tile_name)
@@ -198,7 +283,8 @@ def get_tiles_info(self, tiles_idx=None):
         """Return info of the tiles requested through tiles_idx from tiles names.
 
         Args:
-            tiles_idx (list, optional): list of tiles for which getting the names. If None, all the names of the tiles in the collection are returned. Defaults to None.
+            tiles_idx (list, optional): list of tiles for which getting the names.
+            If None, all the names of the tiles in the collection are returned. Defaults to None.
 
         Raises:
             ValueError: Empty tiles lists
@@ -206,27 +292,25 @@ def get_tiles_info(self, tiles_idx=None):
         Returns:
             dictionary: tiles name : tiles info
         """
-        tiles_names=[]
-        tiles_info=[]
+        tiles_names = []
+        tiles_info = []
         if len(self.__tiles_collection) == 0:
             raise ValueError("Empty tiles lists.")
 
         if tiles_idx is None:
-            tiles_idx=range(len(self.__tiles_collection))
-        
+            tiles_idx = range(len(self.__tiles_collection))
 
         for tile_idx in tiles_idx:
-            tile=self.get_tile(tile_idx)
-            tile_info=tile.get_tile_info()
+            tile = self.get_tile(tile_idx)
+            tile_info = tile.get_tile_info()
             tiles_info.append(tile_info)
             tiles_names.append(tile_info[0])
 
         return dict(zip(tiles_names, tiles_info))
 
     def set_useful_tiles(self, useful_tiles_list):
-        """useful_tiles_list (list): Set useful tiles from list. """
-        self.__l0_useful_tiles_idx=useful_tiles_list
-
+        """useful_tiles_list (list): Set useful tiles from list."""
+        self.__l0_useful_tiles_idx = useful_tiles_list
 
     def is_void(self):
         """Returns true if the image is void.
@@ -234,56 +318,48 @@ def is_void(self):
         Returns:
             bool: True if the image is void.
         """
-        
+
         if len(self.__tiles_collection) or (self.__tiles_collection is None):
             return False
         else:
             return True
 
-
     def show_tiles(self):
-        """Show tiles.
-        """
-        tiles_collections=self.__tiles_collection
+        """Show tiles."""
+        tiles_collections = self.__tiles_collection
 
-        n_tiles=len(tiles_collections)
-        n_rows=int(np.ceil(n_tiles/3))
+        n_tiles = len(tiles_collections)
+        n_rows = int(np.ceil(n_tiles / 3))
 
-        
         if n_rows > 1:
-            fig, ax = plt.subplots(n_rows, 3, figsize=(40,40))
+            fig, ax = plt.subplots(n_rows, 3, figsize=(40, 40))
             plt.tight_layout()
         else:
             fig, ax = plt.subplots(n_rows, 3)
 
-        
-    
         for n in range(n_rows * 3):
-            
             if n_rows > 1:
-                row=int(np.floor(n/3))
-                column=int(n-3*row)
-                ax_plot=ax[row, column]
+                row = int(np.floor(n / 3))
+                column = int(n - 3 * row)
+                ax_plot = ax[row, column]
             else:
-                ax_plot=ax[n]
-            
-            
+                ax_plot = ax[n]
+
             if n < n_tiles:
-                tile_n=self.get_tile(n)
-                tile_n_tensor=tile_n.as_tensor(downsampling=True)
+                tile_n = self.get_tile(n)
+                tile_n_tensor = tile_n.as_tensor(downsampling=True)
 
                 if self.__device == torch.device("cuda"):
                     ax_plot.imshow(tile_n_tensor.detach().cpu().numpy())
                 else:
                     ax_plot.imshow(tile_n_tensor)
-                
+
                 ax_plot.grid(False)
-                ax_plot.axis('off')
-                ax_plot.set_title ("Tile "+str(n), fontsize=30)
+                ax_plot.axis("off")
+                ax_plot.set_title("Tile " + str(n), fontsize=30)
             else:
                 ax_plot.set_axis_off()
 
-
     def merge_tiles_band(self, band_name, merge_path):
         """Merge tiles by performing a mosaic. The merged file is saved at path ""merge_path""
 
@@ -291,20 +367,31 @@ def merge_tiles_band(self, band_name, merge_path):
             band_name (src): band name
             merge_path (src): output path to save the merged file.
         """
-        src_files_to_mosaic=[]
-        N_granules=len(self.__tiles_collection)
-        raster_dataset=[]
+        src_files_to_mosaic = []
+        N_granules = len(self.__tiles_collection)
+        raster_dataset = []
         for n in range(N_granules):
-            tile_n=self.get_tile(n)
-            timestamp=get_timestamp()
-            tmp_tif_filename=tile_n.get_tile_info()[0]+"_"+band_name+"_"+timestamp+"_tmp.tif"
+            tile_n = self.get_tile(n)
+            timestamp = get_timestamp()
+            tmp_tif_filename = (
+                tile_n.get_tile_info()[0]
+                + "_"
+                + band_name
+                + "_"
+                + timestamp
+                + "_tmp.tif"
+            )
             src_files_to_mosaic.append(tmp_tif_filename)
-            band_n_raster=rasterio.open(tile_n.get_bands_file_name_dict()[band_name], "r")
-            band_n_reprojected=reproject_raster(band_n_raster, tmp_tif_filename)
+            band_n_raster = rasterio.open(
+                tile_n.get_bands_file_name_dict()[band_name], "r"
+            )
+            band_n_reprojected = reproject_raster(band_n_raster, tmp_tif_filename)
             band_n_raster.close()
             raster_dataset.append(band_n_reprojected)
 
-        def custom_merge_works(old_data, new_data, old_nodata, new_nodata, index=None, roff=None, coff=None):
+        def custom_merge_works(
+            old_data, new_data, old_nodata, new_nodata, index=None, roff=None, coff=None
+        ):
             old_data[:] = np.maximum(old_data, new_data)
 
         if len(raster_dataset) > 1:
@@ -312,9 +399,16 @@ def custom_merge_works(old_data, new_data, old_nodata, new_nodata, index=None, r
         else:
             mosaic, out_trans = merge(raster_dataset)
 
-        out_meta=raster_dataset[0].meta.copy()
-        out_meta.update({"driver": "GTiff", "height": mosaic.shape[1], "width": mosaic.shape[2], 
-                     "transform": out_trans, "crs": raster_dataset[0].crs})
+        out_meta = raster_dataset[0].meta.copy()
+        out_meta.update(
+            {
+                "driver": "GTiff",
+                "height": mosaic.shape[1],
+                "width": mosaic.shape[2],
+                "transform": out_trans,
+                "crs": raster_dataset[0].crs,
+            }
+        )
 
         with rasterio.open(merge_path, "w", **out_meta) as dest:
             dest.write(mosaic)
@@ -322,102 +416,133 @@ def custom_merge_works(old_data, new_data, old_nodata, new_nodata, index=None, r
         for n in range(N_granules):
             raster_dataset[n].close()
             os.remove(src_files_to_mosaic[n])
-            os.remove(src_files_to_mosaic[n]+".aux.xml")
-
-
-    def crop_tile(self, l0_granule_coordinates, out_dir_path=None, out_name_ending=None, lat_lon_format=True, verbose=True, cfg_file_dict=None, id_l0_l1_dict=None, database="THRAWS", overwrite=False):
-        """Create a mosaic of l1 tiles and crop the mosaic by using the l0_granule_coordinates. Tge output file is saved as TIF file into the directory specified through ""out_dir_path"".
+            os.remove(src_files_to_mosaic[n] + ".aux.xml")
+
+    def crop_tile(
+        self,
+        l0_granule_coordinates,
+        out_dir_path=None,
+        out_name_ending=None,
+        lat_lon_format=True,
+        verbose=True,
+        cfg_file_dict=None,
+        id_l0_l1_dict=None,
+        database="THRAWS",
+        overwrite=False,
+    ):
+        """Create a mosaic of l1 tiles and crop the mosaic by using the l0_granule_coordinates.
+        The output file is saved as TIF file into the directory specified through ""out_dir_path"".
 
         Args:
             l0_granule_coordinates (list): list of coordinates of a referene l0_granule.
-            out_dir_path (src, optional): path to the output directory containing the cropped TIF file. If None, default path is used.  Defaults to None. 
-            out_name_ending (src, optional): optional ending for the output name. Defaults to None. 
+            out_dir_path (src, optional): path to the output directory containing the cropped TIF file.
+                                          If None, default path is used.  Defaults to None.
+            out_name_ending (src, optional): optional ending for the output name. Defaults to None.
             lat_lon_format (bool, optional): if True, coordinates points are in (LAT, LON) format. Defaults to True.
             verbose (bool, optional): if True, verbose mode is used. Defaults to True.
-            cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories. If None, internal CSV database will be parsed. 
+            cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories.
+                                            If None, internal CSV database will be parsed.
             id_l0_l1_dict (dict, optional): id-l0-l1 dictionary. If None, internal CSV database will be parsed.
             database (string, optional): database name. Defaults to "THRAWS".
-            overwrite (bool, optional): if True, the file is overwritten if exists, otherwise tile generation is skipped. Defaults to False.
+            overwrite (bool, optional): if True, the file is overwritten if exists, otherwise tile generation is skipped.
+                                        Defaults to False.
 
         Returns:
             src: output file name
         """
 
         if out_dir_path is None:
-            out_dir_path = get_l1C_image_default_path(self.__event_name, cfg_file_dict, id_l0_l1_dict, database)
+            out_dir_path = get_l1C_image_default_path(
+                self.__event_name, cfg_file_dict, id_l0_l1_dict, database
+            )
         else:
-            out_dir_path=os.path.join(out_dir_path,self.__event_name)
+            out_dir_path = os.path.join(out_dir_path, self.__event_name)
 
-        #Create output dir if not existing
+        # Create output dir if not existing
         os.makedirs(out_dir_path, exist_ok=True)
 
         if out_name_ending is not None:
-            out_name=os.path.join(out_dir_path+"_"+out_name_ending+".tif")
+            out_name = os.path.join(out_dir_path + "_" + out_name_ending + ".tif")
         else:
-            out_name=os.path.join(out_dir_path+".tif")
-
-        if not(overwrite) and os.path.exists(out_name):
-            print(colored("Warning:", "red"),"the file "+colored(out_name, "blue")+" is already existing. The L1-C crop generation is skipped.")
+            out_name = os.path.join(out_dir_path + ".tif")
+
+        if not (overwrite) and os.path.exists(out_name):
+            print(
+                colored("Warning:", "red"),
+                "the file "
+                + colored(out_name, "blue")
+                + " is already existing. The L1-C crop generation is skipped.",
+            )
             return out_name
 
         if lat_lon_format:
-            l0_granule_coordinates=[(y,x) for (x,y) in l0_granule_coordinates]
-        l0_granule_polygon=Polygon(l0_granule_coordinates) 
-        
-        
-        timestamp=get_timestamp()
-        merged_tile_path=self.__event_name+"_merged_tile_"+timestamp
-        
-        bands_to_merge=self.get_tile(0).get_bands_names()
-        band_cropped_list=[]
-        band_meta_list=[]
+            l0_granule_coordinates = [(y, x) for (x, y) in l0_granule_coordinates]
+        l0_granule_polygon = Polygon(l0_granule_coordinates)
+
+        timestamp = get_timestamp()
+        merged_tile_path = self.__event_name + "_merged_tile_" + timestamp
+
+        bands_to_merge = self.get_tile(0).get_bands_names()
+        band_cropped_list = []
+        band_meta_list = []
 
         if verbose:
-            band_range=tqdm(bands_to_merge, "Processing bands...")
+            band_range = tqdm(bands_to_merge, "Processing bands...")
         else:
-            band_range=bands_to_merge
+            band_range = bands_to_merge
         for band_name in band_range:
             if verbose:
-                print("Creating a mosaic of different tiles for band: "+colored(band_name, "red"))
-            merged_tile_path_band=merged_tile_path+"_"+ band_name+".tif"
-            
+                print(
+                    "Creating a mosaic of different tiles for band: "
+                    + colored(band_name, "red")
+                )
+            merged_tile_path_band = merged_tile_path + "_" + band_name + ".tif"
+
             self.merge_tiles_band(band_name, merged_tile_path_band)
             if verbose:
-                print("Cropping mosaic file for band:"+colored(band_name,"red"))
+                print("Cropping mosaic file for band:" + colored(band_name, "red"))
 
             with rasterio.open(merged_tile_path_band) as src:
                 out_image, out_transform = mask(src, [l0_granule_polygon], crop=True)
                 out_meta = src.meta
-            #Removing temporary mosaic crop
+            # Removing temporary mosaic crop
             os.remove(merged_tile_path_band)
-            out_meta.update({"driver": "GTiff",
-                                "height": out_image.shape[1],
-                                "width": out_image.shape[2],
-                                "transform": out_transform})
+            out_meta.update(
+                {
+                    "driver": "GTiff",
+                    "height": out_image.shape[1],
+                    "width": out_image.shape[2],
+                    "transform": out_transform,
+                }
+            )
             band_cropped_list.append(out_image)
             band_meta_list.append(out_meta)
 
-        
         # BANDS DOWNSAMPLING TO THE ONE WITH LOWEST RESOLUTION
-        bands_resolution_list=[BAND_SPATIAL_RESOLUTION_DICT[b] for b in bands_to_merge]
-        lowest_resolution=max(bands_resolution_list)
-        band_cropped_list_resampled=[]
-        band_resolution_index=0
+        bands_resolution_list = [
+            BAND_SPATIAL_RESOLUTION_DICT[b] for b in bands_to_merge
+        ]
+        lowest_resolution = max(bands_resolution_list)
+        band_cropped_list_resampled = []
+        band_resolution_index = 0
         for band_name, n in zip(bands_to_merge, range(len(bands_to_merge))):
-            band=band_cropped_list[n]
-            band_resolution=BAND_SPATIAL_RESOLUTION_DICT[band_name]
+            band = band_cropped_list[n]
+            band_resolution = BAND_SPATIAL_RESOLUTION_DICT[band_name]
             if band_resolution != lowest_resolution:
-                usf_v=int(lowest_resolution/band_resolution)
-                usf_h=int(lowest_resolution/band_resolution)
-                band=band[::usf_v, ::usf_h]
+                usf_v = int(lowest_resolution / band_resolution)
+                usf_h = int(lowest_resolution / band_resolution)
+                band = band[::usf_v, ::usf_h]
             else:
-                band_resolution_index=n
-                
-                
-            band_cropped_list_resampled.append(band)
-        band_meta_list[band_resolution_index].update({"count" : len(band_cropped_list)})
-        with rasterio.open(out_name, "w", **band_meta_list[band_resolution_index]) as dest:
-            for band,n in zip(band_cropped_list_resampled, range(len(band_cropped_list_resampled))):
-                dest.write(band[0,:,:], n+1)
+                band_resolution_index = n
 
-        return out_name
\ No newline at end of file
+            band_cropped_list_resampled.append(band)
+        band_meta_list[band_resolution_index].update({"count": len(band_cropped_list)})
+        with rasterio.open(
+            out_name, "w", **band_meta_list[band_resolution_index]
+        ) as dest:
+            for band, n in zip(
+                band_cropped_list_resampled, range(len(band_cropped_list_resampled))
+            ):
+                dest.write(band[0, :, :], n + 1)
+
+        return out_name
diff --git a/pyraws/l1/l1_tile.py b/pyraws/l1/l1_tile.py
index 359bf90..235339e 100644
--- a/pyraws/l1/l1_tile.py
+++ b/pyraws/l1/l1_tile.py
@@ -2,76 +2,88 @@
 import torch
 import matplotlib.pyplot as plt
 import os
-from ..utils.constants import BAND_SPATIAL_RESOLUTION_DICT, S2_DEFAULT_QUANTIFICATION_VALUE
+from ..utils.constants import (
+    BAND_SPATIAL_RESOLUTION_DICT,
+    S2_DEFAULT_QUANTIFICATION_VALUE,
+)
 from ..utils.band_shape_utils import image_band_upsample
 from ..utils.date_utils import parse_string_date
 from ..utils.l1_utils import export_band_to_tif, swap_latlon
 
 
-class L1C_tile():
+class L1C_tile:
+    # ------------ PRIVATE VARIABLES ------------
 
-    #### PRIVATE VARIABLES ######
-    
-    __bands_dict=None # Bands dictionary
+    __bands_dict = None  # Bands dictionary
 
-    __device=None # Device
-    
-    __bands_names=None # Bands's names
-    
-    __tile_name=None # tile's name
+    __device = None  # Device
 
-    __crs=None #CRS 
+    __bands_names = None  # Bands's names
 
-    __tile_coordinates=None # tile's corners coordinates.
+    __tile_name = None  # tile's name
 
-    __tile_footprint_coordinates=None # tile's footprints.
+    __crs = None  # CRS
 
-    __bands_file_name_dict=None #bands filename dictionary
+    __tile_coordinates = None  # tile's corners coordinates.
 
-    def __init__(self, tile_bands=None, bands_names=None, tile_name=None, tile_coordinates=None, tile_footprint_coordinates=None, bands_file_name_dict=None, crs=None, device=torch.device("cpu")):
+    __tile_footprint_coordinates = None  # tile's footprints.
+
+    __bands_file_name_dict = None  # bands filename dictionary
+
+    def __init__(
+        self,
+        tile_bands=None,
+        bands_names=None,
+        tile_name=None,
+        tile_coordinates=None,
+        tile_footprint_coordinates=None,
+        bands_file_name_dict=None,
+        crs=None,
+        device=torch.device("cpu"),
+    ):
         """Initialize an L0 tile.
 
         Args:
-            tile_bands (list, optional): list of torch tensors representing the different bands in the format [H,W]. Defaults to None.
+            tile_bands (list, optional): list of torch tensors representing each band in the format [H,W].
+                                         Defaults to None.
             bands_names (list, optional): list of band names. Defaults to None.
             tile_name (string, optionl): tile name. Defaults to None.
-            tile_coordinates (list, optional): list containing [lan, lon] for every corner point. Defaults to None.
-            tile_footprint_coordinates (list, optional): list containing [lan, lon] for every point of the tile. Defaults to None.
-            bands_file_name_dict (dict, optional): dictionary associating the orginal jp2 file to each band. Defaults to None.
+            tile_coordinates (list, optional): list containing [lan, lon] for every corner point.
+                                               Defaults to None.
+            tile_footprint_coordinates (list, optional): list containing [lan, lon] for every point of the tile.
+                                                         Defaults to None.
+            bands_file_name_dict (dict, optional): dictionary associating the orginal jp2 file to each band.
+                                                   Defaults to None.
             csr (string, optional): crs. Defaults to None.
-            device (torch.device, optional): torch.device. Defaults to torch.device("cpu"). 
+            device (torch.device, optional): torch.device. Defaults to torch.device("cpu").
         """
 
         if (tile_bands is not None) and (bands_names is not None):
-            self.__bands_dict=dict(zip(bands_names, tile_bands))
+            self.__bands_dict = dict(zip(bands_names, tile_bands))
         else:
-            self.__bands_dict=None
+            self.__bands_dict = None
+
+        self.__device = device
 
-        self.__device=device
-        
-        self.__bands_names=bands_names
-        
-        self.tile_name=tile_name
+        self.__bands_names = bands_names
+
+        self.tile_name = tile_name
 
         if tile_coordinates is None:
-            self.__tile_coordinates=[]
+            self.__tile_coordinates = []
         else:
-            self.__tile_coordinates=tile_coordinates
+            self.__tile_coordinates = tile_coordinates
 
         if tile_footprint_coordinates is None:
-            self.__tile_footprint_coordinates=[]
+            self.__tile_footprint_coordinates = []
         else:
-            self.__tile_footprint_coordinates=tile_footprint_coordinates
-
-        self.__bands_file_name_dict=bands_file_name_dict
-
-        self.__crs=crs
+            self.__tile_footprint_coordinates = tile_footprint_coordinates
 
-    ###########################PRIVATE METHODS ########################################################
+        self.__bands_file_name_dict = bands_file_name_dict
 
+        self.__crs = crs
 
-    ###########################PUBLIC METHODS ########################################################
-    
+    # ------------PUBLIC METHODS ------------
 
     def get_tile_coordinates(self, latlon_format=True):
         """Returns the tile's coordinates.
@@ -79,12 +91,12 @@ def get_tile_coordinates(self, latlon_format=True):
             latlon_format (bool, optional): if True, LAT, LON format is used. Defaults to True.
 
         Returns:
-            list: polygon coordinates. 
+            list: polygon coordinates.
         """
         if latlon_format:
-            return self.__tile_coordinates 
+            return self.__tile_coordinates
         else:
-            return swap_latlon(self.__tile_coordinates )
+            return swap_latlon(self.__tile_coordinates)
 
     def get_bands_names(self):
         """Returns band names
@@ -98,18 +110,17 @@ def get_bands_file_name_dict(self):
         """Returns the tile's band_name jp2 dictionary.
 
         Returns:
-            dict: tiles bands_file_name_dict. 
+            dict: tiles bands_file_name_dict.
         """
-        return self.__bands_file_name_dict 
+        return self.__bands_file_name_dict
 
     def get_tile_footprint_coordinates(self):
         """Returns the tile's footprint coordinates.
 
         Returns:
-            list: polygon coordinates. 
+            list: polygon coordinates.
         """
-        return self.__tile_footprint_coordinates   
-
+        return self.__tile_footprint_coordinates
 
     def get_band(self, band_name):
         """Returns a specific band as a tensor.
@@ -129,13 +140,24 @@ def export_to_tif(self, save_path):
             save_path (str): save path.
             downsampling (bool, optional): If True, bands are downsampled. Defaults to True.
         """
-        coords=self.get_tile_coordinates(latlon_format=False)
-        
-        for band_name in list(self.__bands_dict.keys()):
-            band=self.__bands_dict[band_name] * S2_DEFAULT_QUANTIFICATION_VALUE
-            export_band_to_tif(band,  self.__crs, coords, os.path.join(save_path, band_name+".tif"))
+        coords = self.get_tile_coordinates(latlon_format=False)
 
-    def create_tile(self, bands_list, tile_bands, tile_name, tile_coordinates, footprint_coordinates, bands_file_name_dict, crs):
+        for band_name in list(self.__bands_dict.keys()):
+            band = self.__bands_dict[band_name] * S2_DEFAULT_QUANTIFICATION_VALUE
+            export_band_to_tif(
+                band, self.__crs, coords, os.path.join(save_path, band_name + ".tif")
+            )
+
+    def create_tile(
+        self,
+        bands_list,
+        tile_bands,
+        tile_name,
+        tile_coordinates,
+        footprint_coordinates,
+        bands_file_name_dict,
+        crs,
+    ):
         """Creates a tile from the list of bands and from a torch tensor.
 
         Args:
@@ -147,18 +169,18 @@ def create_tile(self, bands_list, tile_bands, tile_name, tile_coordinates, footp
             bands_file_name_dict (dict): bands_file_name_dict.
             crs (string): crs
         """
-        self.__bands_dict=dict(zip(bands_list, bands_list))
+        self.__bands_dict = dict(zip(bands_list, bands_list))
 
         for band, n in zip(bands_list, range(len(bands_list))):
-            self.__bands_dict[band]=tile_bands[n].to(self.__device)
-
-        self.__bands_names=bands_list
-        self.tile_name=tile_name
-        self.__tile_coordinates=tile_coordinates
-        self.__tile_footprint_coordinates=footprint_coordinates
-        self.__bands_file_name_dict=bands_file_name_dict
-        self.__crs=crs
-    
+            self.__bands_dict[band] = tile_bands[n].to(self.__device)
+
+        self.__bands_names = bands_list
+        self.tile_name = tile_name
+        self.__tile_coordinates = tile_coordinates
+        self.__tile_footprint_coordinates = footprint_coordinates
+        self.__bands_file_name_dict = bands_file_name_dict
+        self.__crs = crs
+
     def get_tile_info(self):
         """Returns name, sensing time, acquisition time, and coners coordinates.
 
@@ -169,19 +191,26 @@ def get_tile_info(self):
             list: tile's corners' coordinates.
             list: tile's footprint's coordinates.
         """
-        tile_name=self.tile_name
+        tile_name = self.tile_name
 
-        sensing_time=parse_string_date(tile_name[-15:])
-        acquisition_time=parse_string_date(tile_name[11:26])
+        sensing_time = parse_string_date(tile_name[-15:])
+        acquisition_time = parse_string_date(tile_name[11:26])
 
-        return tile_name, sensing_time, acquisition_time, self.get_tile_coordinates(), self.get_tile_footprint_coordinates()
+        return (
+            tile_name,
+            sensing_time,
+            acquisition_time,
+            self.get_tile_coordinates(),
+            self.get_tile_footprint_coordinates(),
+        )
 
     def as_tensor(self, requested_bands=None, downsampling=True):
         """Returns a tensor containing all the bands if all the requested bands have the same resolution.
 
         Args:
             requested_bands (list, optional): list of requested bands. If None, all the bands are used. Defaults to None.
-            downsampling (boolean, optional): if True, bands are downsampled to the lowest resolution. Otherwise, they are upsampled to the highest one. Defaults to True.
+            downsampling (boolean, optional): if True, bands are downsampled to the lowest resolution.
+                                              Otherwise, they are upsampled to the highest one. Defaults to True.
 
         Raises:
             ValueError: The tile is empty
@@ -193,46 +222,62 @@ def as_tensor(self, requested_bands=None, downsampling=True):
             raise ValueError("The tile is empty.")
 
         if requested_bands is None:
-            requested_bands=self.__bands_names
+            requested_bands = self.__bands_names
 
         if downsampling:
-            
-            bands_resolution_list=[BAND_SPATIAL_RESOLUTION_DICT[b] for b in requested_bands]
-            lowest_resolution=max(bands_resolution_list)
+            bands_resolution_list = [
+                BAND_SPATIAL_RESOLUTION_DICT[b] for b in requested_bands
+            ]
+            lowest_resolution = max(bands_resolution_list)
+
+            band_shape = [self.get_band(b) for b in requested_bands][
+                bands_resolution_list.index(lowest_resolution)
+            ].shape
+            bands = torch.zeros(
+                [band_shape[0], band_shape[1], len(requested_bands)],
+                device=self.__device,
+            )
 
-            band_shape=[self.get_band(b) for b in requested_bands][bands_resolution_list.index(lowest_resolution)].shape
-            bands=torch.zeros([band_shape[0], band_shape[1], len(requested_bands)], device=self.__device)
-            
             for band_name, n in zip(requested_bands, range(len(requested_bands))):
-                band=self.__bands_dict[band_name]
-                band_resolution=BAND_SPATIAL_RESOLUTION_DICT[band_name]
+                band = self.__bands_dict[band_name]
+                band_resolution = BAND_SPATIAL_RESOLUTION_DICT[band_name]
                 if band_resolution != lowest_resolution:
-                    usf_v=int(lowest_resolution/band_resolution)
-                    usf_h=int(lowest_resolution/band_resolution)
-                    
-                    band=band[::usf_v, ::usf_h]
-                bands[:,:,n]=band
-                
+                    usf_v = int(lowest_resolution / band_resolution)
+                    usf_h = int(lowest_resolution / band_resolution)
+
+                    band = band[::usf_v, ::usf_h]
+                bands[:, :, n] = band
+
         else:
-            resolution_min=min([BAND_SPATIAL_RESOLUTION_DICT[b] for b in requested_bands])
+            resolution_min = min(
+                [BAND_SPATIAL_RESOLUTION_DICT[b] for b in requested_bands]
+            )
 
-            band_shape=[max(self.get_band(b).shape[0] for b in requested_bands), max(self.get_band(b).shape[1] for b in requested_bands)]
+            band_shape = [
+                max(self.get_band(b).shape[0] for b in requested_bands),
+                max(self.get_band(b).shape[1] for b in requested_bands),
+            ]
 
-            bands=torch.zeros([band_shape[0], band_shape[1], len(requested_bands)], device=self.__device)
+            bands = torch.zeros(
+                [band_shape[0], band_shape[1], len(requested_bands)],
+                device=self.__device,
+            )
 
             for band_name, n in zip(requested_bands, range(len(requested_bands))):
-                band=self.__bands_dict[band_name]
+                band = self.__bands_dict[band_name]
 
                 if resolution_min != BAND_SPATIAL_RESOLUTION_DICT[band_name]:
-                    band_upsampled=image_band_upsample(band, band_name, resolution_min, "bilinear")
+                    band_upsampled = image_band_upsample(
+                        band, band_name, resolution_min, "bilinear"
+                    )
                     if bands.shape[0] > band_upsampled.shape[0]:
-                        bands[:band_upsampled.shape[0],:,n]=band_upsampled
+                        bands[: band_upsampled.shape[0], :, n] = band_upsampled
                     elif bands.shape[0] < band_upsampled.shape[0]:
-                        bands[:,:,n]=band_upsampled[:bands.shape[0],:]
+                        bands[:, :, n] = band_upsampled[: bands.shape[0], :]
                     else:
-                        bands[:,:,n]=band_upsampled
+                        bands[:, :, n] = band_upsampled
                 else:
-                    bands[:,:,n]=band
+                    bands[:, :, n] = band
 
         return bands
 
@@ -246,22 +291,26 @@ def show_bands_superimposition(self, requested_bands=None, downsampling=True):
             ValueError: Impossible to superimpose more than 3 bands
         """
         if requested_bands is None:
-            requested_bands=self.__bands_names
+            requested_bands = self.__bands_names
 
         if len(requested_bands) > 3:
             raise ValueError("Impossible to superimpose more than 3 bands.")
 
-        bands_superimposed=self.as_tensor(requested_bands, downsampling=downsampling)
+        bands_superimposed = self.as_tensor(requested_bands, downsampling=downsampling)
 
         if bands_superimposed.shape[2] == 2:
-            bands_superimposed_zeros=torch.zeros([bands_superimposed.shape[0], bands_superimposed.shape[1],3])
-            bands_superimposed_zeros[:,:,:2]=bands_superimposed
-            bands_superimposed_zeros[:,:,2]=(bands_superimposed[:,:,0] + bands_superimposed[:,:,1])/2
-            bands_superimposed=bands_superimposed_zeros
-
-        bands_superimposed=bands_superimposed/bands_superimposed.max()
-
-        if self.__device==torch.device("cuda"):
+            bands_superimposed_zeros = torch.zeros(
+                [bands_superimposed.shape[0], bands_superimposed.shape[1], 3]
+            )
+            bands_superimposed_zeros[:, :, :2] = bands_superimposed
+            bands_superimposed_zeros[:, :, 2] = (
+                bands_superimposed[:, :, 0] + bands_superimposed[:, :, 1]
+            ) / 2
+            bands_superimposed = bands_superimposed_zeros
+
+        bands_superimposed = bands_superimposed / bands_superimposed.max()
+
+        if self.__device == torch.device("cuda"):
             plt.imshow(bands_superimposed.detach().cpu().numpy())
         else:
             plt.imshow(bands_superimposed)
@@ -270,117 +319,115 @@ def show_bands(self, requested_bands=None, downsampling=False, oversampling=Fals
         """It shows the requested bands.
 
         Args:
-            requested_bands (list, optional): list of requested bands to show. If None, all the bands are shown. Defaults to None.
-            downsampling (bool, optional): if True, bands are downsampled to have the same resolution. Default to False.
-            oversampling (bool, optional): if True, bands are oversampled to have the same resolution. Downsampling has priority over upampling. Default to False.
+            requested_bands (list, optional): list of requested bands to show.
+                                             If None, all the bands are shown. Defaults to None.
+            downsampling (bool, optional): if True, bands are downsampled to have the same resolution.
+                                           Default to False.
+            oversampling (bool, optional): if True, bands are oversampled to have the same resolution.
+                                           Downsampling has priority over upampling. Default to False.
         """
         if requested_bands is None:
-            requested_bands=self.__bands_names
+            requested_bands = self.__bands_names
 
-        n_bands=len(requested_bands)
-        n_rows=int(np.ceil(n_bands/3))
+        n_bands = len(requested_bands)
+        n_rows = int(np.ceil(n_bands / 3))
 
-        
         if n_rows > 1:
-            fig, ax = plt.subplots(n_rows, 3, figsize=(40,40))
+            fig, ax = plt.subplots(n_rows, 3, figsize=(40, 40))
             plt.tight_layout()
         else:
             fig, ax = plt.subplots(n_rows, 3)
 
-        
         if downsampling:
-            n_printed=0
-            tile_tensor=self.as_tensor(downsampling=True)
+            n_printed = 0
+            tile_tensor = self.as_tensor(downsampling=True)
             for n in range(len(self.__bands_names)):
                 if self.__bands_names[n] in requested_bands:
                     if n_rows > 1:
-                        row=int(np.floor(n/3))
-                        column=int(n_printed - 3*row)
-                        ax_plot=ax[row, column]
+                        row = int(np.floor(n / 3))
+                        column = int(n_printed - 3 * row)
+                        ax_plot = ax[row, column]
                     else:
-                        ax_plot=ax[n_printed]
-                        
-                    band_name=self.__bands_names[n]
-                    band=tile_tensor[:,:,n]
+                        ax_plot = ax[n_printed]
+
+                    band_name = self.__bands_names[n]
+                    band = tile_tensor[:, :, n]
 
                     if self.__device == torch.device("cuda"):
                         ax_plot.imshow(band.detach().cpu().numpy())
                     else:
                         ax_plot.imshow(band)
-    
+
                     ax_plot.grid(False)
-                    ax_plot.axis('off')
-                    ax_plot.set_title (band_name, fontsize=30)
-                    n_printed+=1
-            
+                    ax_plot.axis("off")
+                    ax_plot.set_title(band_name, fontsize=30)
+                    n_printed += 1
+
             if n_rows > 1:
                 for n in range(n_printed, 3 * n_rows):
-                    ax_plot=ax[n_rows - 1, n - n_printed + 1]
+                    ax_plot = ax[n_rows - 1, n - n_printed + 1]
                     ax_plot.set_axis_off()
             else:
                 for n in range(n_printed, 3 * n_rows):
-                    ax_plot=ax[n]
+                    ax_plot = ax[n]
                     ax_plot.set_axis_off()
 
-        elif (oversampling) and not(downsampling):
-            n_printed=0
-            tile_tensor=self.as_tensor(downsampling=False)
+        elif (oversampling) and not (downsampling):
+            n_printed = 0
+            tile_tensor = self.as_tensor(downsampling=False)
             for n in range(len(self.__bands_names)):
                 if self.__bands_names[n] in requested_bands:
                     if n_rows > 1:
-                        row=int(np.floor(n/3))
-                        column=int(n_printed - 3*row)
-                        ax_plot=ax[row, column]
+                        row = int(np.floor(n / 3))
+                        column = int(n_printed - 3 * row)
+                        ax_plot = ax[row, column]
                     else:
-                        ax_plot=ax[n_printed]
-                        
-                    band_name=self.__bands_names[n]
+                        ax_plot = ax[n_printed]
 
-                    band=tile_tensor[:,:,n]
+                    band_name = self.__bands_names[n]
+
+                    band = tile_tensor[:, :, n]
 
                     if self.__device == torch.device("cuda"):
                         ax_plot.imshow(band.detach().cpu().numpy())
                     else:
                         ax_plot.imshow(band)
-    
+
                     ax_plot.grid(False)
-                    ax_plot.axis('off')
-                    ax_plot.set_title (band_name, fontsize=30)
-                    n_printed+=1
+                    ax_plot.axis("off")
+                    ax_plot.set_title(band_name, fontsize=30)
+                    n_printed += 1
 
             if n_rows > 1:
                 for n in range(n_printed, 3 * n_rows):
-                    ax_plot=ax[n_rows - 1, n - n_printed + 1]
+                    ax_plot = ax[n_rows - 1, n - n_printed + 1]
                     ax_plot.set_axis_off()
             else:
                 for n in range(n_printed, 3):
-                    ax_plot=ax[n]
+                    ax_plot = ax[n]
                     ax_plot.set_axis_off()
-                    
+
         else:
             for n in range(n_rows * 3):
-                
                 if n_rows > 1:
-                    row=int(np.floor(n/3))
-                    column=int(n-3*row)
-                    ax_plot=ax[row, column]
+                    row = int(np.floor(n / 3))
+                    column = int(n - 3 * row)
+                    ax_plot = ax[row, column]
                 else:
-                    ax_plot=ax[n]
-                
-                
+                    ax_plot = ax[n]
+
                 if n < n_bands:
-                    band_name=requested_bands[n]
-                    band=self.get_band(band_name)
+                    band_name = requested_bands[n]
+                    band = self.get_band(band_name)
 
                     if self.__device == torch.device("cuda"):
                         ax_plot.imshow(band.detach().cpu().numpy())
                     else:
                         ax_plot.imshow(band)
-                    
+
                     ax_plot.grid(False)
-                    ax_plot.axis('off')
+                    ax_plot.axis("off")
                     ax_plot.title.set_text(band_name)
-                    ax_plot.set_title (band_name, fontsize=30)
+                    ax_plot.set_title(band_name, fontsize=30)
                 else:
                     ax_plot.set_axis_off()
-
diff --git a/pyraws/raw/raw_event.py b/pyraws/raw/raw_event.py
index 22fa4fa..d600adb 100644
--- a/pyraws/raw/raw_event.py
+++ b/pyraws/raw/raw_event.py
@@ -31,7 +31,8 @@ def __init__(
         useful_granule_bounding_box_dict=None,
         device=torch.device("cpu"),
     ):
-        """Creates an raw event from a granules collection and band_names. It is possible to associate an image class to the event.
+        """Creates an raw event from a granules collection and band_names.
+        It is possible to associate an image class to the event.
 
         Args:
             granules_collection (list, optional): list of Raw_granule. Defaults to None.
@@ -94,7 +95,7 @@ def from_path(self, raw_dir_path, bands_list, verbose=True):
             ) = read_Raw_event_from_path(
                 raw_dir_path, bands_list, verbose, self.__device
             )
-        except:
+        except:  # noqa: E722
             raise ValueError(
                 "Impossible to open the raw file at: "
                 + colored(raw_dir_path, "red")
@@ -139,8 +140,10 @@ def from_database(
 
         Args:
             id_event (str): event ID.
-            bands_list (list, optional): bands list. If None, all bands are used and sorted according to the datasheet order. Defaults to None.
-            cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories. If None, internal CSV database will be parsed.
+            bands_list (list, optional): bands list. If None, all bands are used and sorted according to the datasheet order.
+                                         Defaults to None.
+            cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories.
+                                          If None, internal CSV database will be parsed.
             id_raw_l1_dict (dict, optional): id-raw-l1 dictionary. If None, internal CSV database will be parsed.
             verbose (bool, optional): if True, if True, verbose mode is used. Defaults to True.
             database (string, optional): database name. Defaults to "THRAWS".
@@ -302,7 +305,10 @@ def show_granules_info(self):
             print("\n")
 
     def stack_granules(self, granules_idx, positions):
-        """Stack different granules recursively specified by granules_idx. Positions will specify the stacking positions. If granules_idx=[0,1,2] and positions=["T", "B"], granule_0 will be stacked at the top of granule_1 and the result will be stacked at the bottom of granule_2.
+        """Stack different granules recursively specified by granules_idx.
+        Positions will specify the stacking positions.
+        If granules_idx=[0,1,2] and positions=["T", "B"], granule_0 will be stacked at the top of granule_1
+        and the result will be stacked at the bottom of granule_2.
 
         Args:
             granules_idx (list): list of granule indices.
@@ -351,7 +357,9 @@ def get_granules_names(self, granules_idx=None):
         """Return names of the granules requested through granules_idx from granules names.
 
         Args:
-            granules_idx (list, optional): list of granules for which getting the names. If None, all the names of the granules in the collection are returned. Defaults to None.
+            granules_idx (list, optional): list of granules for which getting the names.
+                                         If None, all the names of the granules in the collection are returned.
+                                         Defaults to None.
 
         Raises:
             ValueError: Empty granules lists
@@ -375,7 +383,9 @@ def get_granules_info(self, granules_idx=None):
         """Return info of the granules requested through granules_idx from granules names.
 
         Args:
-            granules_idx (list, optional): list of granules for which getting the names. If None, all the names of the granules in the collection are returned. Defaults to None.
+            granules_idx (list, optional): list of granules for which getting the names.
+                                         If None, all the names of the granules in the collection are returned.
+                                         Defaults to None.
 
         Raises:
             ValueError: Empty granules lists
@@ -444,18 +454,28 @@ def coarse_coregistration(
         bands_shifts=None,
         verbose=False,
     ):
-        """It implements the coarse coregistration of the bands by compensating the along-track pixels shift with respect to the first band.
+        """It implements the coarse coregistration of the bands by compensating the along-track pixels shift
+        with respect to the first band.
 
         Args:
-            granules_idx (list, optional): Indices of granules to stack and coregister. If None, internal __raw_useful_granules_idx are used. Defaults to None.
-            use_complementary_granules (boolean, optional): if True, coregistration is performed with filler elements. Defaults to False.
-            crop_empty_pixels (boolean, optional):  if True and use_complementary_granules is False or no filler is available, empty pixels are cropped. Defaults to False.
-            bands_shifts (list, optional): bands shift values compared to the first band. If None, they will be read by the LUT file. Defaults to None.
-            downsampling (boolean, optional): if True, higher resolution bands will be undersampled to match the bands with the lowest resolution. If False, lower resolution bands will be upsampled to match the bands with the highest resolution. Defaults to True.
+            granules_idx (list, optional): Indices of granules to stack and coregister.
+                                           If None, internal __raw_useful_granules_idx are used.
+                                           Defaults to None.
+            use_complementary_granules (boolean, optional): if True, coregistration is performed with filler elements.
+                                                          Defaults to False.
+            crop_empty_pixels (boolean, optional):  if True and use_complementary_granules is False or no filler is available,
+                                                  empty pixels are cropped. Defaults to False.
+            bands_shifts (list, optional): bands shift values compared to the first band.
+                                           If None, they will be read by the LUT file. Defaults to None.
+            downsampling (boolean, optional): if True, higher resolution bands will be undersampled
+                                              to match the bands with the lowest resolution.
+                                              If False, lower resolution bands will be upsampled to match the bands
+                                            with the highest resolution. Defaults to True.
             verbose (boolean, optional): if True, verbose mode is used. Defaults to False.
         Returns:
             Raw_granule: granule with coarse-coregistered bands.
         """
+
         if granules_idx is None:
             print("No granule indexes was specified. Using default.")
             granules_idx = self.__raw_useful_granules_idx
@@ -471,9 +491,7 @@ def coarse_coregistration(
         granule_filler_after = None
 
         if use_complementary_granules:
-
             if len(granules_idx) == 1:
-
                 stackable_couples, positions = self.get_stackable_granules()
                 stackable_couple_sorted = []
 
diff --git a/pyraws/raw/raw_granule.py b/pyraws/raw/raw_granule.py
index 514015b..79b2f96 100644
--- a/pyraws/raw/raw_granule.py
+++ b/pyraws/raw/raw_granule.py
@@ -1,4 +1,3 @@
-from calendar import c
 import torch
 from termcolor import colored
 import matplotlib.pyplot as plt
@@ -28,16 +27,14 @@
 
 
 class Raw_granule:
-
-    #### PRIVATE VARIABLES ######
+    # ---------------- PRIVATE VARIABLES ----------------
     __bands_dict = None  # Bands dictionary
-
     __device = None  # Device
-
     __bands_names = None  # Bands's names
-
-    __original = True  # This parameter is used to keep track of the history of the granule. If it is True, it means the granule was created by reading an image and no operation is applied.
-
+    __original = (
+        True  # This parameter is used to keep track of the history of the granule.
+    )
+    # If it is True, it means the granule was created by reading an image, and no operation is applied.
     __granule_parents = (
         []
     )  # It is used to keep track of the parents granules originating this granule.
@@ -47,9 +44,7 @@ class Raw_granule:
     )  # Coordinates of the polygon interstecting granule area.
 
     __single_granule_along_track_size = None  # Along track size of a single granule.
-
     __cloud_percentage_list = []  # Cloud coverage percentage
-
     __cropped_pixels = [None, None]  # Cropped pixels along-across
 
     def __init__(
@@ -65,11 +60,13 @@ def __init__(
         """Initialize an raw granule.
 
         Args:
-            granule_bands (list, optional): list of torch tensors representing the different bands in the format [H,W]. Defaults to None.
+            granule_bands (list, optional): list of torch tensors representing each band in the format [H,W]. Defaults to None.
             bands_names (list, optional): list of band names. Defaults to None.
             granule_name (string, optionl): granule name. Defaults to None.
             granule_polygon_coordinates (list, optional): list containing [lat, lon] for every polygon point. Defaults to None.
-            single_granule_along_track_size (float, optional): size of a single granule along track. Useful to keep this info when the granule has parents. Defaults to None.
+            single_granule_along_track_size (float, optional): size of a single granule along track.
+                                                                Useful to keep this info when the granule has parents.
+                                                                Defaults to None.
             cloud_percentage (list or float, optional): Cloud coverage percentage metadata. Defaults to None.
             device (torch.device, optional): torch.device. Defaults to torch.device("cpu").
         """
@@ -87,7 +84,10 @@ def __init__(
 
         self.__cropped_pixels = [None, None]
 
-        self.__original = True  # This parameter is used to keep track of the history of the granule. If it is True, it means the granule was created by reading an image and no operation is applied.
+        self.__original = (
+            True  # This parameter is used to keep track of the history of the granule.
+        )
+        # If it is True, it means the granule was created by reading an image and no operation is applied.
 
         self.__granule_parents = (
             []
@@ -109,7 +109,7 @@ def __init__(
         else:
             self.__cloud_percentage_list.append(cloud_percentage)
 
-    ###########################PRIVATE METHODS ########################################################
+    # ----------------------------------PRIVATE METHODS ----------------------------------
 
     def __set_cropped_pixels(self, cropped_pixels):
         """Set the new granule length.
@@ -152,7 +152,7 @@ def __set_cloud_percentage(self, cloud_percentage_list):
         """
         self.__cloud_percentage_list = cloud_percentage_list
 
-    ############################## PUBLIC METHODS ########################################################
+    # ---------------------- PUBLIC METHODS -----------------------
 
     def is_original(self):
         """It shows if the granule is original.
@@ -202,7 +202,7 @@ def show_raw_band(self, band_name):
                     plt.imshow(band.detach().cpu().numpy())
                 else:
                     plt.imshow(band)
-            except:
+            except:  # noqa: E722
                 raise ValueError(
                     "Impossible to show the requested band "
                     + colored(band_name, "red")
@@ -324,8 +324,11 @@ def as_tensor(self, requested_bands=None, downsampling=True):
         """Returns a tensor containing all the bands if all the requested bands have the same resolution.
 
         Args:
-            requested_bands (list, optional): list of requested bands. If None, all the bands are used. Defaults to None.
-            downsampling (boolean, optional): if True, bands are downsampled to the lowest resolution. Otherwise, they are upsampled to the highest one. Defaults to True.
+            requested_bands (list, optional): list of requested bands.
+                                            If None, all the bands are used. Defaults to None.
+            downsampling (boolean, optional): if True, bands are downsampled to the lowest resolution.
+                                            Otherwise, they are upsampled to the highest one.
+                                            Defaults to True.
 
         Raises:
             ValueError: The granule is empty
@@ -340,7 +343,6 @@ def as_tensor(self, requested_bands=None, downsampling=True):
             requested_bands = self.__bands_names
 
         if downsampling:
-
             bands_resolution_list = [
                 BAND_SPATIAL_RESOLUTION_DICT[b] for b in requested_bands
             ]
@@ -407,7 +409,8 @@ def as_tensor(self, requested_bands=None, downsampling=True):
         return bands
 
     def stack_to_granule(self, granule_other, position):
-        """It stacks the granule to another input granule to a specificied position. For instance, if position == ""T"", the granule will be stacked at the top of the ""granule_other"".
+        """It stacks the granule to another input granule to a specificied position.
+        For instance, if position == ""T"", the granule will be stacked at the top of the ""granule_other"".
 
         Args:
             granule_other (Raw_granule): other granule to which the input granule will be stacked to.
@@ -609,15 +612,27 @@ def coarse_coregistration(
         bands_shifts=None,
         verbose=False,
     ):
-        """It implements the coarse coregistration of the bands by compensating the along-track pixels shift with respect to the first band.
+        """It implements the coarse coregistration of the bands by compensating
+        the along-track pixels shift with respect to the first band.
 
         Args:
-            rotate_swir_bands (boolean, optional): if True, SWIR bands are rotated before applying coregistration. Defaults to True.
-            granule_filler_before (Raw_granule, optional): if not None, bands of this tile will be used to fill the missing elements during the coregistration as before granule. Defaults to None.
-            granule_filler_after (Raw_granule, optional): if not None, bands of this tile will be used to fill the missing elements during the coregistration as bottom granule. Defaults to None.
-            crop_empty_pixels (boolean, optional): if True and no fillers are available or granule fillers are None, the image will be crop at the bottom and the top of a number of pixels equal to the maximum zeros pixels stacked from each band.
-            downsampling (boolean, optional): if True, higher resolution bands will be undersampled to match the bands with the lowest resolution. If False, lower resolution bands will be upsampled to match the bands with the highest resolution. Defaults to True.
-            bands_shifts (list, optional): bands shift values compared to the first band. If None, they will be read by the LUT file. Defaults to None.
+            rotate_swir_bands (boolean, optional): if True, SWIR bands are rotated before applying coregistration.
+                                                  Defaults to True.
+            granule_filler_before (Raw_granule, optional): if not None, bands of this tile will be used to fill
+                                                           the missing elements during the coregistration as before granule.
+                                                           Defaults to None.
+            granule_filler_after (Raw_granule, optional): if not None, bands of this tile will be used to fill the missing
+                                                          elements during the coregistration as bottom granule.
+                                                          Defaults to None.
+            crop_empty_pixels (boolean, optional): if True and no fillers are available or granule fillers are None,
+                                                   the image will be crop at the bottom and the top of a number
+                                                   of pixels equal to the maximum zeros pixels stacked from each band.
+            downsampling (boolean, optional): if True, higher resolution bands will be undersampled to match the bands
+                                              with the lowest resolution.
+                                              If False, lower resolution bands will be upsampled to match the bands
+                                              with the highest resolution. Defaults to True.
+            bands_shifts (list, optional): bands shift values compared to the first band.
+                                           If None, they will be read by the LUT file. Defaults to None.
             verbose (boolean, optional): if True, verbose mode is used. Defaults to False.
         Returns:
             Raw_granule: granule with coarse-coregistered bands.
@@ -708,7 +723,8 @@ def maxOffsetUpdate(
                 band (str): curent band name
 
             Returns:
-                The updated maximum offsets in top, bottom, left, right directions, updated max_top, max_bottom, max_right, max_left
+                The updated maximum offsets in top, bottom, left, right directions,
+                updated max_top, max_bottom, max_right, max_left
             """
             top_rescaled, bottom_rescaled = (
                 BAND_SPATIAL_RESOLUTION_DICT[band]
@@ -820,7 +836,7 @@ def maxOffsetUpdate(
                 band_name = self.__bands_names[n]
                 band_shifted = shift_band(band, shifts=[along_track, cross_track])
 
-                ########################## BEFORE CASE:
+                # -------------------------- BEFORE CASE:
                 if granule_filler_before is not None:
                     band_filler_before = granule_filler_before.get_band(band_name)
 
@@ -839,7 +855,7 @@ def maxOffsetUpdate(
                         ]
                         filler_name["top"] = granule_filler_before.get_granule_info()[0]
 
-                ########################## AFTER CASE:
+                # --------------------- AFTER CASE:
                 if granule_filler_after is not None:
                     band_filler_after = granule_filler_after.get_band(band_name)
 
@@ -952,7 +968,9 @@ def maxOffsetUpdate(
 
                 # Adjusting coordinates only in absence of top filling.
                 if filler_name["top"] is None:
-                    # Reprojecting top shift with respect to band 9 (used inside the granule to manage the lenght of the pixel when bands coordinates are used.)
+                    # Reprojecting top shift with respect to band 9
+                    # (used inside the granule to manage the lenght of the
+                    # pixel when bands coordinates are used.)
                     max_top_resized_09 = int(
                         max_top
                         * BAND_SPATIAL_RESOLUTION_DICT[max_top_band]
@@ -968,7 +986,9 @@ def maxOffsetUpdate(
 
                 # Adjusting coordinates only in absence of bottom filling.
                 if filler_name["bottom"] is None:
-                    # Reprojecting bottom shift with respect to band 9 (used inside the granule to manage the lenght of the pixel when bands coordinates are used.)
+                    # Reprojecting bottom shift with respect to band 9
+                    # (used inside the granule to manage the lenght of the pixel
+                    # when bands coordinates are used.)
                     max_bottom_resized_09 = int(
                         max_bottom
                         * BAND_SPATIAL_RESOLUTION_DICT[max_bottom_band]
@@ -1040,7 +1060,9 @@ def maxOffsetUpdate(
                     point_2_shifted,
                     point_3_shifted,
                 ]
-                # Reprojecting right shift with respect to band 9 (used inside the granule to manage the lenght of the pixel across-track when bands coordinates are used.)
+                # Reprojecting right shift with respect to band 9
+                # (used inside the granule to manage the lenght of the pixel
+                # across-track when bands coordinates are used.)
                 max_left_resized_09 = int(
                     max_left
                     * BAND_SPATIAL_RESOLUTION_DICT_ACROSS[max_left_band]
@@ -1069,9 +1091,10 @@ def maxOffsetUpdate(
         # Adjusting granule name.
         granule_name = self.granule_name
 
-        # Adding COMPLEMENTED_WITH_top_granule_number_bottom_granule_number depending on the case
+        # Adding COMPLEMENTED_WITH_top_granule_number_bottom_granule_number
+        # depending on the case
         if filler_name["top"] is not None or filler_name["bottom"] is not None:
-            granule_name = granule_name + f"_COMPLEMENTED_WITH"
+            granule_name = granule_name + "_COMPLEMENTED_WITH"
         if filler_name["top"] is not None:
             granule_name = granule_name + f"_top_{filler_name['top']}"
         if filler_name["bottom"] is not None:
@@ -1112,10 +1135,17 @@ def show_bands_superimposition(
         """It shows the superimposition of bands in requested_bands
 
         Args:
-            requested_bands (list, optional): requested bands list. If None, all the bands are used. Defaults to None.
-            downsampling (boolean, optional): if True, bands are downsampled to have the same resolution. Default to False.
-            equalize (boolean, optional): if True, bands are equalized for a better plotting by saturating the outliers of each band with an upper and lower valuer respectively equal to pixel value mean *- n_std * histogram standard deviation. Default to False.
-            n_std (integer, optional):  number of times the value of the pixel values standard deviation used for histogram cropping. Defaults to 2.
+            requested_bands (list, optional): requested bands list.
+                                              If None, all the bands are used.
+                                              Defaults to None.
+            downsampling (boolean, optional): if True, bands are downsampled to have the same resolution.
+                                              Default to False.
+            equalize (boolean, optional): if True, bands are equalized for a better plotting by saturating
+                                          the outliers of each band with an upper and lower valuer respectively
+                                          equal to pixel value mean *- n_std * histogram standard deviation.
+                                          Default to False.
+            n_std (integer, optional):  number of times the value of the pixel values standard deviation used
+                                        for histogram cropping. Defaults to 2.
         Raises:
             ValueError: Impossible to superimpose more than 3 bands
         """
@@ -1165,9 +1195,12 @@ def show_bands(
         """It shows the requested bands.
 
         Args:
-            requested_bands (list, optional): list of requested bands to show. If None, all the bands are shown. Defaults to None.
-            downsampling (bool, optional): if True, bands are downsampled to have the same resolution. Default to False.
-            oversampling (bool, optional): if True, bands are oversampled to have the same resolution. Downsampling has priority over upampling. Default to False.
+            requested_bands (list, optional): list of requested bands to show.
+                                              If None, all the bands are shown. Defaults to None.
+            downsampling (bool, optional): if True, bands are downsampled to have the same resolution.
+                                           Default to False.
+            oversampling (bool, optional): if True, bands are oversampled to have the same resolution.
+                                           Downsampling has priority over upampling. Default to False.
             rotate_swir_bands (bool, optional): if True, SWIR bands are rotated. Default to False.
 
         """
@@ -1259,7 +1292,6 @@ def show_bands(
 
         else:
             for n in range(n_rows * 3):
-
                 if n_rows > 1:
                     row = int(np.floor(n / 3))
                     column = int(n - 3 * row)
@@ -1286,7 +1318,10 @@ def show_bands(
                     ax_plot.set_axis_off()
 
     def get_granule_info(self):
-        """Returns name, sensing time, acquisition time, detector number information, originality, parents list, polygon coordinates list, cloud percentages. If the granule have parents, sensing time, acquisition time, detector number of parents, and cloud percentages are returned.
+        """Returns name, sensing time, acquisition time, detector number information,
+        originality, parents list, polygon coordinates list, cloud percentages.
+        If the granule have parents, sensing time, acquisition time, detector number of parents,
+        and cloud percentages are returned.
 
         Returns:
             string: name
@@ -1396,8 +1431,10 @@ def get_number_of_granules_along_track_line(self):
     def get_bands_coordinates(self, downsampling=True, latlon_format=True):
         """Returns the coordinates of the bands.
         Args:
-            downsampling (bool, optional): if True, bands are downsampled to have the same resolution. Default to False.
-            latlon_format (bool): format to use to get the granule's coordinates. Default to: Latitude, Longitude. Default to Latitude, Longitude.
+            downsampling (bool, optional): if True, bands are downsampled to have the same resolution.
+                                           Default to False.
+            latlon_format (bool): format to use to get the granule's coordinates.
+                                  Default to: Latitude, Longitude.
         Returns:
             dict: band-names/band coordinates dict.
         """
@@ -1438,7 +1475,6 @@ def get_bands_coordinates(self, downsampling=True, latlon_format=True):
             )
 
             if band_name == "B02":
-
                 point_1_shifted = polygon_coordinates[0] + p0_1_angle
                 point_2_shifted = polygon_coordinates[3] + p3_2_angle
                 shifted_points = [
@@ -1449,7 +1485,6 @@ def get_bands_coordinates(self, downsampling=True, latlon_format=True):
                 ]
 
             elif band_name == "B09":
-
                 point_0_shifted = polygon_coordinates[1] - p0_1_angle
                 point_3_shifted = polygon_coordinates[2] - p3_2_angle
                 shifted_points = [
@@ -1541,7 +1576,7 @@ def export_to_tif(self, save_path):
                 band, coords[band_name], os.path.join(save_path, band_name + ".tif")
             )
 
-    def get_raw_bbox(self, l1c_tif, bbox, mode = "standard"):
+    def get_raw_bbox(self, l1c_tif, bbox, mode="standard"):
         """Changing bbox coordinates from green system (L1C) to raw.
 
         Args:
@@ -1559,7 +1594,6 @@ def get_points_from_bbox(bbox):
             return (p1, topright, p2, bottleft)
 
         def get_srcPoints(l1c_tif):
-
             for k in range(l1c_tif.shape[1]):
                 y = l1c_tif[:, k, 0]
                 dy = torch.where(y != 0)[0]
@@ -1574,8 +1608,8 @@ def get_srcPoints(l1c_tif):
                     dx = dx[0]
                     break
 
-            for l in range(l1c_tif.shape[1] - 1, 0, -1):
-                y_end = l1c_tif[:, l, 0]
+            for k in range(l1c_tif.shape[1] - 1, 0, -1):
+                y_end = l1c_tif[:, k, 0]
                 dy_end = torch.where(y_end != 0)[0]
                 if len(dy_end) != 0:
                     dy_end = dy_end[0]
@@ -1590,7 +1624,7 @@ def get_srcPoints(l1c_tif):
             if mode == "standard":
                 return [np.array([dy, k]), np.array([m, dx]), np.array([q, dx_end])]
             else:
-                return [np.array([m,dx]), np.array([dy_end, l]), np.array([dy, k])]
+                return [np.array([m, dx]), np.array([dy_end, k]), np.array([dy, k])]
 
         def prep_point(point):
             arr = np.array([point[0], point[1], 1])
diff --git a/pyraws/utils/band_shape_utils.py b/pyraws/utils/band_shape_utils.py
index 252760a..0677218 100644
--- a/pyraws/utils/band_shape_utils.py
+++ b/pyraws/utils/band_shape_utils.py
@@ -1,11 +1,11 @@
 import torch
-from termcolor import colored 
+from termcolor import colored
 from torch.nn import Upsample
 from torch.nn.functional import interpolate
 from .constants import BAND_NAMES, BAND_SPATIAL_RESOLUTION_DICT
 
 
-def image_band_upsample(img_band, band_name, target_spatial_resolution, upsample_mode): 
+def image_band_upsample(img_band, band_name, target_spatial_resolution, upsample_mode):
     """Upsample an image band to a target spatial resolution through an upsample mode.
 
     Args:
@@ -22,31 +22,61 @@ def image_band_upsample(img_band, band_name, target_spatial_resolution, upsample
         torch.tensor: upsampled band.
     """
 
-    if not(band_name in BAND_NAMES):
-        raise ValueError("Unsupported band name: "+colored(band_name, "red")+".")
-
-    #print("Upsampling band: "+colored(band_name, "blue")+".")
-    upsample_factor=BAND_SPATIAL_RESOLUTION_DICT[band_name]/target_spatial_resolution
-    if not(upsample_mode in ['nearest', 'bilinear', 'bicubic']):
-        raise ValueError("Upsample mode "+colored(upsample_mode, "blue")+" not supported. Please, choose among: ""nearest"", ""bilinear"", ""bicubic"".")
-        
-    
-    if upsample_factor  <= 1.0:
-        print(colored("Warnings", "red")+". The requested target resolution ("+colored(target_spatial_resolution, "blue") + ") is lower or equal to the orginal band resolution ("+colored(band_name, "red")+","+colored(BAND_SPATIAL_RESOLUTION_DICT[band_name], "green")+").")
+    if not (band_name in BAND_NAMES):
+        raise ValueError("Unsupported band name: " + colored(band_name, "red") + ".")
+
+    # print("Upsampling band: "+colored(band_name, "blue")+".")
+    upsample_factor = (
+        BAND_SPATIAL_RESOLUTION_DICT[band_name] / target_spatial_resolution
+    )
+    if not (upsample_mode in ["nearest", "bilinear", "bicubic"]):
+        raise ValueError(
+            "Upsample mode "
+            + colored(upsample_mode, "blue")
+            + " not supported. Please, choose among: "
+            "nearest"
+            ", "
+            "bilinear"
+            ", "
+            "bicubic"
+            "."
+        )
+
+    if upsample_factor <= 1.0:
+        print(
+            colored("Warnings", "red")
+            + ". The requested target resolution ("
+            + colored(target_spatial_resolution, "blue")
+            + ") is lower or equal to the orginal band resolution ("
+            + colored(band_name, "red")
+            + ","
+            + colored(BAND_SPATIAL_RESOLUTION_DICT[band_name], "green")
+            + ")."
+        )
         return img_band
-    
+
     if upsample_factor != int(upsample_factor):
-        print(colored("Warnings", "red")+". Upsample factor truncanted from "+upsample_factor+" to "+int(upsample_factor)+".")
-    #else:
-        #print("Upsample factor: "+colored(upsample_factor, "blue")+".")
-    upsample_factor=int(upsample_factor)
-    upsample_method=Upsample(scale_factor=upsample_factor, mode=upsample_mode, align_corners=True)
+        print(
+            colored("Warnings", "red")
+            + ". Upsample factor truncanted from "
+            + upsample_factor
+            + " to "
+            + int(upsample_factor)
+            + "."
+        )
+    # else:
+    # print("Upsample factor: "+colored(upsample_factor, "blue")+".")
+    upsample_factor = int(upsample_factor)
+    upsample_method = Upsample(
+        scale_factor=upsample_factor, mode=upsample_mode, align_corners=True
+    )
     with torch.no_grad():
         return upsample_method(img_band.unsqueeze(0).unsqueeze(0)).squeeze(0).squeeze(0)
 
 
-
-def image_band_resize(img_upsample_band, band_name, upsampled_img_spatial_resolution, interpolate_mode): 
+def image_band_resize(
+    img_upsample_band, band_name, upsampled_img_spatial_resolution, interpolate_mode
+):
     """Resize an upsampled image band to a the orginal spatial resolution through an interpolate mode.
 
     Args:
@@ -62,26 +92,65 @@ def image_band_resize(img_upsample_band, band_name, upsampled_img_spatial_resolu
     Returns:
         torch.tensor: resized image.
     """
-    if not(band_name in BAND_NAMES):
-        raise ValueError("Unsupported band name: "+colored(band_name, "red")+".")
-        
-    #print("Downsampling band: "+colored(band_name, "blue")+".")
-    downsample_factor=BAND_SPATIAL_RESOLUTION_DICT[band_name]/upsampled_img_spatial_resolution
-    
-    if not(interpolate_mode in ['nearest', 'bilinear', 'bicubic']):
-        raise ValueError("Interpolate mode "+colored(interpolate_mode, "blue")+" not supported. Please, choose among: ""nearest"", ""bilinear"", ""bicubic"".")
-        
-    
-    if downsample_factor  <= 1.0:
-        print(colored("Warnings", "red")+". The upsampled image resolution ("+colored(upsampled_img_spatial_resolution, "blue") + ") is lower or equal to the orginal band resolution ("+colored(band_name, "red")+","+colored(BAND_SPATIAL_RESOLUTION_DICT[band_name], "green")+").")
+    if not (band_name in BAND_NAMES):
+        raise ValueError("Unsupported band name: " + colored(band_name, "red") + ".")
+
+    # print("Downsampling band: "+colored(band_name, "blue")+".")
+    downsample_factor = (
+        BAND_SPATIAL_RESOLUTION_DICT[band_name] / upsampled_img_spatial_resolution
+    )
+
+    if not (interpolate_mode in ["nearest", "bilinear", "bicubic"]):
+        raise ValueError(
+            "Interpolate mode "
+            + colored(interpolate_mode, "blue")
+            + " not supported. Please, choose among: "
+            "nearest"
+            ", "
+            "bilinear"
+            ", "
+            "bicubic"
+            "."
+        )
+
+    if downsample_factor <= 1.0:
+        print(
+            colored("Warnings", "red")
+            + ". The upsampled image resolution ("
+            + colored(upsampled_img_spatial_resolution, "blue")
+            + ") is lower or equal to the orginal band resolution ("
+            + colored(band_name, "red")
+            + ","
+            + colored(BAND_SPATIAL_RESOLUTION_DICT[band_name], "green")
+            + ")."
+        )
         return img_upsample_band
-    
+
     if downsample_factor != int(downsample_factor):
-        print(colored("Warnings", "red")+". Upsample factor truncanted from "+downsample_factor+" to "+int(downsample_factor)+".")
-    #else:
-        #print("Downsample factor: "+colored(downsample_factor, "blue")+".")
-    downsample_factor=int(downsample_factor)
-    
-    size=(int(img_upsample_band.shape[0]/downsample_factor), int(img_upsample_band.shape[1]/downsample_factor))
+        print(
+            colored("Warnings", "red")
+            + ". Upsample factor truncanted from "
+            + downsample_factor
+            + " to "
+            + int(downsample_factor)
+            + "."
+        )
+    # else:
+    # print("Downsample factor: "+colored(downsample_factor, "blue")+".")
+    downsample_factor = int(downsample_factor)
+
+    size = (
+        int(img_upsample_band.shape[0] / downsample_factor),
+        int(img_upsample_band.shape[1] / downsample_factor),
+    )
     with torch.no_grad():
-        return interpolate(img_upsample_band.unsqueeze(0).unsqueeze(0),size=size, mode=interpolate_mode, align_corners=True).squeeze(0).squeeze(0)
+        return (
+            interpolate(
+                img_upsample_band.unsqueeze(0).unsqueeze(0),
+                size=size,
+                mode=interpolate_mode,
+                align_corners=True,
+            )
+            .squeeze(0)
+            .squeeze(0)
+        )
diff --git a/pyraws/utils/constants.py b/pyraws/utils/constants.py
index cb951bb..15d5df1 100644
--- a/pyraws/utils/constants.py
+++ b/pyraws/utils/constants.py
@@ -1,17 +1,17 @@
 import torch
 
-###################################################################################################################################
+# -------------------------------------------------------------------------------------------------
 # Database constants
-###################################################################################################################################
+# -------------------------------------------------------------------------------------------------
 # Database file names
 DATABASE_FILE_DICTIONARY = {
     "THRAWS": "thraws_db.csv",
     "vessel_detection": "vessel_detection_db.csv",
 }
 
-###################################################################################################################################
+# -------------------------------------------------------------------------------------------------
 # General constants
-###################################################################################################################################
+# -------------------------------------------------------------------------------------------------
 # Band names
 BAND_NAMES = [
     "B01",
@@ -63,9 +63,9 @@
 # SWIR bands
 SWIR_BANDS = ["B10", "B11", "B12"]
 
-###################################################################################################################################
+# -------------------------------------------------------------------------------------------------
 # Raw constants
-###################################################################################################################################
+# -------------------------------------------------------------------------------------------------
 # Bands shape dictionary
 BANDS_RAW_SHAPE_DICT = {
     "B02": torch.Size([2304, 2592]),
@@ -99,9 +99,9 @@
     "B12": 20.0,
 }
 
-###################################################################################################################################
+# -------------------------------------------------------------------------------------------------
 # L1-c constants
-###################################################################################################################################
+# -------------------------------------------------------------------------------------------------
 # Default quantification value
 S2_DEFAULT_QUANTIFICATION_VALUE = (
     10000  # Default value used in case of missing metadata.
diff --git a/pyraws/utils/database_utils.py b/pyraws/utils/database_utils.py
index 3a79b9b..6874ea3 100644
--- a/pyraws/utils/database_utils.py
+++ b/pyraws/utils/database_utils.py
@@ -1,21 +1,19 @@
+try:
+    from pyraws.sys_cfg import PYRAWS_HOME_PATH, DATA_PATH
+except:  # noqa: E722
+    raise ValueError(
+        "sys_cfg.py not found. Please, refer to README.md for instructions on how to generate it."
+    )
 import os
 import pandas as pd
 from termcolor import colored
 import csv
 from .constants import DATABASE_FILE_DICTIONARY, BAND_NAMES_REAL_ORDER
-from pyraws.sys_cfg import DATA_PATH
 from pathlib import Path
 import xml.etree.ElementTree as ET
 from shapely.geometry import Polygon
 from ast import literal_eval
 
-try:
-    from pyraws.sys_cfg import PYRAWS_HOME_PATH, DATA_PATH
-except:
-    raise ValueError(
-        "sys_cfg.py not found. Please, refer to README.md for instructions on how to generate it."
-    )
-
 
 class DatabaseHandler:
     """Creates an Raw-L1C csv database for the APIs."""
@@ -52,7 +50,7 @@ def fetcher(self):
             self.L1 = self.datapath / "l1c"
             self.L1_products = [x for x in self.L1.iterdir() if x.is_dir()]
             print("Found L1c products: ", len(self.L1_products))
-        except:
+        except:  # noqa: E722
             print(
                 "L1 folder not found. If this behaviour is not desidered, please, refer to README.md for instructions."
             )
@@ -207,8 +205,11 @@ def get_raw_shift_lut(
     Args:
         satellite (str, optional): "S2A" or "S2B" respectively for "Sentinel-2A" data and "Sentinel-2B" data.
         detector_number (int): Detectorn number.
-        downsampling (boolean, optional): if True, shift values for downsampled bands of the chosen satellite are used. Otherwise, values for upsampled bands are used. Defaults to True.
-        cfg_file_dict (dict, optional): cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories. If None, internal CSV database will be parsed. Defaults to None.
+        downsampling (boolean, optional): if True, shift values for downsampled bands of the chosen satellite are used.
+                                        Otherwise, values for upsampled bands are used. Defaults to True.
+        cfg_file_dict (dict, optional): cfg_file_dict (dict, optional): dictionary containing paths to
+                                        the different pyraws directories. If None, internal CSV database will be parsed.
+                                        Defaults to None.
     Returns:
         dict: returns the Raw shift LUT.
     """
@@ -269,10 +270,12 @@ def get_raw_shift_lut(
 
 
 def get_id_raw_l1_dict(database="THRAWS", cfg_file_dict=None):
-    """Returns a dictionary containing raw (directory name), l1c (product ID and correspondent granule) and class, raw useful and complementary tiles.
+    """Returns a dictionary containing raw (directory name), l1c (product ID and correspondent granule) and class,
+    raw useful and complementary tiles.
     Args:
         database (string, optional): database name. Defaults to ""THRAWS"".
-        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories. If None, internal CSV database will be parsed.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                       If None, internal CSV database will be parsed.
     Returns:
         dict: label_raw-l1_dict
     """
@@ -319,9 +322,9 @@ def get_id_raw_l1_dict(database="THRAWS", cfg_file_dict=None):
                             for x in polygon[1:]
                         ]
                     )
-                except:
+                except:  # noqa: E722
                     requested_polygon_list.append([[None, None]])
-    except:
+    except:  # noqa: E722
         print(
             colored("ERROR", "red")
             + ". Impossible to parse the file: "
@@ -355,7 +358,8 @@ def get_event_granule_bb_dict(event_id, database="THRAWS", cfg_file_dict=None):
     Args:
         event_id (string): event ID.
         database (string, optional): database name. Defaults to ""THRAWS"".
-        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories. If None, internal CSV database will be parsed.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                    If None, internal CSV database will be parsed.
 
     Returns:
         dict: {useful_granule : bounding_box_list} for the requested event.
@@ -372,7 +376,8 @@ def get_events_list(database="THRAWS", cfg_file_dict=None):
 
     Args:
         database (string, optional): database name. Defaults to ""THRAWS"".
-        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories. If None, internal CSV database will be parsed.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                      If None, internal CSV database will be parsed.
     Returns:
         str: list of events.
     """
@@ -383,11 +388,13 @@ def get_events_list(database="THRAWS", cfg_file_dict=None):
 def get_event_info(
     event_id, cfg_file_dict=None, id_raw_l1_dict=None, database="THRAWS"
 ):
-    """From the event_ID, it returns raw directory path, the path to the l1 image, to the L1C auxiliary file, and the class of the image. If no `id_raw_l1_dict`is provided, it is done by parsing the internal CSV database file.
+    """From the event_ID, it returns raw directory path, the path to the l1 image, to the L1C auxiliary file,
+    and the class of the image. If no `id_raw_l1_dict`is provided, it is done by parsing the internal CSV database file.
 
     Args:
         event_id (string): image name.
-        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories. If None, internal CSV database will be parsed.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                      If None, internal CSV database will be parsed.
         id_raw_l1_dict (dict, optional): id-raw-l1 dictionary. If None, internal CSV database will be parsed.
         database (string, optional): database name. Defaults to "THRAWS".
 
@@ -457,7 +464,7 @@ def parse_string(str, skip_marks=True, return_int=False):
         raw_complementary_granules_str = id_raw_l1_dict[event_id][
             "raw_complementary_granules"
         ]
-    except:
+    except:  # noqa: E722
         raise ValueError(
             colored("ERROR", "red")
             + ". The image: "
@@ -477,7 +484,7 @@ def parse_string(str, skip_marks=True, return_int=False):
             "]" in raw_useful_granules_str
         ):  # Single granules list
             raw_useful_granules = [
-                int(x[0]) if (x[0] != None and x[0] != "None") else [None]
+                int(x[0]) if ((x[0] is not None) and (x[0] != "None")) else [None]
                 for x in [x.split(",") for x in raw_useful_granules_str]
             ]
         else:
diff --git a/pyraws/utils/date_utils.py b/pyraws/utils/date_utils.py
index 44d24a6..537b149 100644
--- a/pyraws/utils/date_utils.py
+++ b/pyraws/utils/date_utils.py
@@ -1,5 +1,6 @@
 from datetime import datetime
 
+
 def get_timestamp():
     """Return current timestamp.
 
@@ -7,8 +8,21 @@ def get_timestamp():
         str: timestamp
     """
     timestamp = datetime.now()
-    return str(timestamp.year)+"_"+str(timestamp.month)+"_"+str(timestamp.day)+"_"+str(timestamp.hour)+"_"+str(timestamp.minute)+"_"+str(timestamp.second)
-  
+    return (
+        str(timestamp.year)
+        + "_"
+        + str(timestamp.month)
+        + "_"
+        + str(timestamp.day)
+        + "_"
+        + str(timestamp.hour)
+        + "_"
+        + str(timestamp.minute)
+        + "_"
+        + str(timestamp.second)
+    )
+
+
 def parse_string_date(date_string):
     """Parse a date in string format and returns a datetime.
 
@@ -18,10 +32,12 @@ def parse_string_date(date_string):
     Returns:
         datetime: correspondent datetime.
     """
-    year=date_string[:4]
-    month=date_string[4:6]
-    day=date_string[6:8]
-    hour=date_string[9: 11]
-    minute=date_string[11: 13]
-    second=date_string[13:]
-    return datetime(int(year), int(month), int(day), int(hour), int(minute), int(second) )
\ No newline at end of file
+    year = date_string[:4]
+    month = date_string[4:6]
+    day = date_string[6:8]
+    hour = date_string[9:11]
+    minute = date_string[11:13]
+    second = date_string[13:]
+    return datetime(
+        int(year), int(month), int(day), int(hour), int(minute), int(second)
+    )
diff --git a/pyraws/utils/l1_utils.py b/pyraws/utils/l1_utils.py
index cc47f67..9b45050 100644
--- a/pyraws/utils/l1_utils.py
+++ b/pyraws/utils/l1_utils.py
@@ -18,7 +18,8 @@
 
 
 def get_event_bounding_box(event_hotmap, coords_dict):
-    """Returns the bounding box and the coordinates of the bounding box top-left, bottom-right corners for each clust of 1 in the event_hotmap.
+    """Returns the bounding box and the coordinates of the bounding box top-left,
+    bottom-right corners for each clust of 1 in the event_hotmap.
 
     Args:
         event_hotmap (torch.tensor): event hotmap. Pixels = 1 indicate event.
@@ -26,7 +27,8 @@ def get_event_bounding_box(event_hotmap, coords_dict):
 
     Returns:
         skimage.bb: bounding box
-        list: list of coordinates [lat, lon] of top-left, bottom-right coordinates for each cluster of events in the hotmap.
+        list: list of coordinates [lat, lon] of top-left,
+             bottom-right coordinates for each cluster of events in the hotmap.
     """
     mask = event_hotmap.numpy()
     lbl = label(mask)
@@ -56,8 +58,10 @@ def get_l1C_image_default_path(
 
     Args:
         id_event (str): event ID.
-        cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories. If None, internal CSV database will be parsed.
-        id_raw_l1_dict (dict, optional): id-raw-l1 dictionary. If None, internal CSV database will be parsed.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                       If None, internal CSV database will be parsed.
+        id_raw_l1_dict (dict, optional): id-raw-l1 dictionary.
+                                       If None, internal CSV database will be parsed.
         database (string, optional): database name. Defaults to "THRAWS".
 
     Returns:
@@ -161,7 +165,9 @@ def read_L1C_tile_from_path(
     verbose=True,
     device=torch.device("cpu"),
 ):
-    """Read specific bands of an L1C Sentine2 tile, specified in "bands_list". The tile, located at "tile_path", is divided by a factor specified in the auxiliary file "auxiliary_file_path" to transform it from DN to TOA reflectance.
+    """Read specific bands of an L1C Sentine2 tile,
+    specified in "bands_list". The tile, located at "tile_path",
+    is divided by a factor specified in the auxiliary file "auxiliary_file_path" to transform it from DN to TOA reflectance.
 
     Args:
         tile_path (str): Sentinel 2 image path.
@@ -203,23 +209,25 @@ def read_L1C_tile_from_path(
         tile_footprint_coordinates = tile_footprint_coordinates[
             :-1
         ]  # Excluding the last couple since it is the repetition of the first one.
-    except:
+    except:  # noqa: E722
         print(
             colored("Warning: ", "red")
-            + "Metadata missing. It is impossible to estimate the footprint coordinates. However, georeferencing of the tile is still possible."
+            + "Metadata missing. "
+            + "It is impossible to estimate the footprint coordinates. "
+            + "However, georeferencing of the tile is still possible."
         )
         tile_footprint_coordinates = [["NA", "NA"] for i in range(4)]
         quantification_value = S2_DEFAULT_QUANTIFICATION_VALUE
 
     try:
-
         granule_name_path = sorted(glob(os.path.join(tile_path, "GRANULE", "*")))[0]
 
         bands_img_paths = sorted(glob(os.path.join(granule_name_path, "IMG_DATA", "*")))
 
         band_name_file_dict = dict(
             zip(bands_list, bands_list)
-        )  # This dictionary is to match the desired band with the file. We initialized with bands_list also as value because they will be fixed in the next for loop.
+        )  # This dictionary is to match the desired band with the file.
+        # We initialized with bands_list also as value because they will be fixed in the next for loop.
         for name in bands_img_paths:
             if name[-3:] == "jp2" and name[-7:-4] in bands_list:
                 band_name_file_dict[name[-7:-4]] = name
@@ -288,7 +296,7 @@ def read_L1C_tile_from_path(
                     band_k_torch.to("cuda")
                 sentinel_img.append(band_k_torch)
                 n += 1
-    except:
+    except:  # noqa: E722
         raise ValueError(
             colored("Error. ", "red")
             + " impossible to open: "
@@ -311,7 +319,8 @@ def read_L1C_event_from_path(
     verbose=True,
     device=torch.device("cpu"),
 ):
-    """Read specific bands of an L1C Sentinel 2 event, specified in "bands_list" from img_name. Every tile of the event is represented as TOA reflectance.
+    """Read specific bands of an L1C Sentinel 2 event, specified in "bands_list" from img_name.
+    Every tile of the event is represented as TOA reflectance.
 
     Args:
         id_event (str): event ID.
@@ -324,10 +333,14 @@ def read_L1C_event_from_path(
         ValueError: impossible to find information on the database.
 
     Returns:
-        dictionary: dictionary containing [tile_name, tile]. Each tile is list of tensors, each of them is made of TOA values of the requested Sentinel 2A image bands.
-        dictionary: dictionary containing [tile_name, coordinates], where coordinates are the corners coordinates of each tile composing the requested image.
-        dictionary: dictionary containing [tile_name, coordinates], where coordinates are the footprint's coordinates of each tile composing the requested image.
-        dictionary: dictionary containing [tile_name, band_filename_dict], where band_filename_dict is the dictionary associating to every band the original jp2 file.
+        dictionary: dictionary containing [tile_name, tile]. Each tile is list of tensors,
+                    each of them is made of TOA values of the requested Sentinel 2A image bands.
+        dictionary: dictionary containing [tile_name, coordinates], where coordinates are the corners
+                    coordinates of each tile composing the requested image.
+        dictionary: dictionary containing [tile_name, coordinates], where coordinates are the footprint's
+                    coordinates of each tile composing the requested image.
+        dictionary: dictionary containing [tile_name, band_filename_dict], where band_filename_dict is the
+                    dictionary associating to every band the original jp2 file.
     """
 
     tiles_paths = sorted(glob(os.path.join(l1c_image_path, "*")))
@@ -395,12 +408,14 @@ def read_L1C_event_from_database(
     verbose=True,
     device=torch.device("cpu"),
 ):
-    """Read specific bands of an L1C Sentinel 2 event, specified in "bands_list" from img_name. Every tile of the event is represented as TOA reflectance.
+    """Read specific bands of an L1C Sentinel 2 event, specified in "bands_list" from img_name.
+    Every tile of the event is represented as TOA reflectance.
 
     Args:
         id_event (str): event ID.
         bands_list (list): bands list.
-        cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories. If None, internal CSV database will be parsed.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                        If None, internal CSV database will be parsed.
         id_raw_l1_dict (dict, optional): id-raw-l1 dictionary. If None, internal CSV database will be parsed.
         database (string, optional): database name. Defaults to "THRAWS".
         reproject_bounds (bool, optional): if True, bounds are reprojected to EPGS:4326.
@@ -411,17 +426,21 @@ def read_L1C_event_from_database(
         ValueError: impossible to find information on the database.
 
     Returns:
-        dictionary: dictionary containing [tile_name, tile]. Each tile is list of tensors, each of them is made of TOA values of the requested Sentinel 2A image bands.
-        dictionary: dictionary containing [tile_name, coordinates], where coordinates are the corners coordinates of each tile composing the requested image.
-        dictionary: dictionary containing [tile_name, coordinates], where coordinates are the footprint's coordinates of each tile composing the requested image.
-        dictionary: dictionary containing [tile_name, band_filename_dict], where band_filename_dict is the dictionary associating to every band the original jp2 file.
+        dictionary: dictionary containing [tile_name, tile].
+                    Each tile is list of tensors, each of them is made of TOA values of the requested Sentinel 2A image bands.
+        dictionary: dictionary containing [tile_name, coordinates], where coordinates are the corners coordinates of each tile
+                    composing the requested image.
+        dictionary: dictionary containing [tile_name, coordinates], where coordinates are the footprint's coordinates
+                    of each tile composing the requested image.
+        dictionary: dictionary containing [tile_name, band_filename_dict], where band_filename_dict is the dictionary
+                    associating to every band the original jp2 file.
         string: expected class name.
     """
     try:
         _, l1c_image_path, _, expected_class, _, _, _, _ = get_event_info(
             id_event, cfg_file_dict, id_raw_l1_dict, database=database
         )
-    except:
+    except:  # noqa: E722
         raise ValueError(
             "Impossible to find information on image: "
             + colored(id_event, "blue")
@@ -453,12 +472,14 @@ def read_L1C_image_from_tif(
     database="THRAWS",
     device=torch.device("cpu"),
 ):
-    """Read an L1C Sentine2 image from a cropped TIF. The image is represented as TOA reflectance. The image is post processed.
+    """Read an L1C Sentine2 image from a cropped TIF. The image is represented as TOA reflectance.
+    The image is post processed.
 
     Args:
         id_event (str): event ID.
         out_name_ending (src, optional): optional ending for the output name. Defaults to None.
-        cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories. If None, internal CSV database will be parsed.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                        If None, internal CSV database will be parsed.
         id_raw_l1_dict (dict, optional): id-raw-l1 dictionary. If None, internal CSV database will be parsed.
         database (string, optional): database name. Defaults to "THRAWS".
         device (torch.device, optional): torch device. Defaults to torch.device("cpu").
@@ -467,7 +488,8 @@ def read_L1C_image_from_tif(
         ValueError: impossible to find information on the database.
 
     Returns:
-        dictionary: dictionary containing every tile composing the requested image. Each tensor is made of TOA values of the requested Sentinel 2A image bands.
+        dictionary: dictionary containing every tile composing the requested image.
+                    Each tensor is made of TOA values of the requested Sentinel 2A image bands.
         dictionary: dictionary containing lat and lon for every point.
         string: expected class name.
     """
@@ -475,7 +497,7 @@ def read_L1C_image_from_tif(
         _, _, l1c_post_processed_path, expected_class, _, _, _, _ = get_event_info(
             id_event, cfg_file_dict, id_raw_l1_dict, database=database
         )
-    except:
+    except:  # noqa: E722
         raise ValueError(
             "Impossible to find information on image: "
             + colored(id_event, "blue")
diff --git a/pyraws/utils/parse_csv_utils.py b/pyraws/utils/parse_csv_utils.py
index 3b1c802..e439a8c 100644
--- a/pyraws/utils/parse_csv_utils.py
+++ b/pyraws/utils/parse_csv_utils.py
@@ -1,5 +1,6 @@
 import csv
 
+
 def parse_csv(csv_name):
     """Parse a CSV file and return a list of rows.
 
@@ -7,13 +8,13 @@ def parse_csv(csv_name):
     :csv_name: CSV name.
     :return: (list of rows. Each row is a dictionary.)
     """
-    row_list=[]
+    row_list = []
     try:
         with open(csv_name) as csv_file:
             csv_reader = csv.DictReader(csv_file)
             for row in csv_reader:
                 row_list.append(row)
-    except:
+    except:  # noqa: E722
         return ValueError("Impossible to parse CSV file: ", csv_name)
 
-    return row_list
\ No newline at end of file
+    return row_list
diff --git a/pyraws/utils/raw_utils.py b/pyraws/utils/raw_utils.py
index 1c9b440..74e9843 100644
--- a/pyraws/utils/raw_utils.py
+++ b/pyraws/utils/raw_utils.py
@@ -17,14 +17,17 @@
 def get_bands_shift(
     bands_list, satellite, detector_number, downsampling=True, cfg_file_dict=None
 ):
-    """It returns the number of backward shift pixels of the various bands with respect to the first band in the list. Negative shift means the bands shall translate forward.
+    """It returns the number of backward shift pixels of the various bands with respect to the first band in the list.
+    Negative shift means the bands shall translate forward.
 
     Args:
         bands_list (list): list of bands
         satellite (str, optional): "S2A" or "S2B" respectively for "Sentinel-2A" data and "Sentinel-2B" data.
         detector_number (int): Detectorn number.
-        downsampling (boolean, optional): if True, shift values for downsampled bands of the chosen satellite are used. Otherwise, values for upsampled bands are used. Defaults to True.
-        cfg_file_dict (dict, optional): cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories. If None, internal CSV database will be parsed. Defaults to None.
+        downsampling (boolean, optional): if True, shift values for downsampled bands of the chosen satellite are used.
+                                          Otherwise, values for upsampled bands are used. Defaults to True.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                        If None, internal CSV database will be parsed. Defaults to None.
 
     Returns:
         list: list of relative pixel shift compared to the first band.
@@ -57,7 +60,6 @@ def get_bands_shift(
             b_s_index = lut_df_keys.index(b_s)
 
         if b_m_index < b_s_index:
-
             s_along_track_ms = np.array(
                 [
                     BAND_SPATIAL_RESOLUTION_DICT[lut_df_keys[k + 1]]
@@ -132,7 +134,8 @@ def get_granule_px_length(
 def read_Raw_granule(
     granule_path, bands_list, verbose=True, device=torch.device("cpu")
 ):
-    """Read specific bands of an Raw Sentine2 granule, specified in "bands_list". The image contains several granules  at "dir_path".
+    """Read specific bands of an Raw Sentine2 granule, specified in "bands_list".
+    The image contains several granules  at "dir_path".
 
     Args:
         granule_path (str): Sentinel 2 Raw granule path.
@@ -154,7 +157,8 @@ def read_Raw_granule(
         bands_img_paths = sorted(glob(os.path.join(granule_path, "*")))
         band_name_file_dict = dict(
             zip(bands_list, bands_list)
-        )  # This dictionary is to match the desired band with the file. We initialized with bands_list also as value because they will be fixed in the next for loop.
+        )  # This dictionary is to match the desired band with the file. We initialized with bands_list also as
+        # value because they will be fixed in the next for loop.
 
         for name in bands_img_paths:
             band_number = name[name.find("_B") + 1 : name.find(".tif")]
@@ -177,7 +181,7 @@ def read_Raw_granule(
                 sentinel_raw_granule.append(
                     torch.from_numpy(band_k.astype(np.float32)).to(device)
                 )
-    except:
+    except:  # noqa: E722
         raise ValueError(
             colored("Error. ", "red")
             + " impossible to open: "
@@ -205,7 +209,7 @@ def read_Raw_granule(
         cloud_percentage = float(
             xml_content.getElementsByTagName("CloudPercentage")[0].firstChild.data
         )
-    except:
+    except:  # noqa: E722
         raise ValueError(
             colored("Error. ", "red")
             + " impossible to read: "
@@ -219,7 +223,8 @@ def read_Raw_granule(
 def read_Raw_event_from_path(
     dir_path, bands_list, verbose=True, device=torch.device("cpu")
 ):
-    """Read specific bands of an Raw Sentine2 event, specified in "bands_list". The image contains several granules  at "dir_path".
+    """Read specific bands of an Raw Sentine2 event, specified in "bands_list".
+    The image contains several granules  at "dir_path".
 
     Args:
         dir_path (str): Sentinel 2 Raw image path.
@@ -264,7 +269,7 @@ def read_Raw_event_from_path(
             cloud_percentages_list,
         )
 
-    except:
+    except:  # noqa: E722
         raise ValueError(
             colored("Error. ", "red")
             + " impossible to open: "
@@ -303,7 +308,8 @@ def read_Raw_event_from_database(
     Args:
         id_event (str): event ID.
         bands_list (list): bands list.
-        cfg_file_dict (dict, optional): dictionary containing paths to the different end2end directories. If None, internal CSV database will be parsed.
+        cfg_file_dict (dict, optional): dictionary containing paths to the different pyraws directories.
+                                        If None, internal CSV database will be parsed.
         id_raw_l1_dict (dict, optional): id-raw-l1 dictionary. If None, internal CSV database will be parsed.
         database (string, optional): database name. Defaults to "THRAWS".
         verbose (bool, optional): if True, if True, verbose mode is used. Defaults to True.
@@ -333,7 +339,7 @@ def read_Raw_event_from_database(
             _,
             _,
         ) = get_event_info(id_event, cfg_file_dict, id_raw_l1_dict, database=database)
-    except:
+    except:  # noqa: E722
         raise ValueError(
             "Impossible to find information on event: "
             + colored(id_event, "blue")
diff --git a/pyraws/utils/shape_utils.py b/pyraws/utils/shape_utils.py
index 56fe8a4..8b67213 100644
--- a/pyraws/utils/shape_utils.py
+++ b/pyraws/utils/shape_utils.py
@@ -1,9 +1,5 @@
-# from end2end.noise_model.noise_model import get_pixel_spsf
-import ee
-import folium
 import geopandas as gpd
 import geopy
-import geopy.distance
 from ..raw.raw_event import Raw_event
 from shapely.geometry import Polygon
 import numpy as np
diff --git a/pyraws/utils/visualization_utils.py b/pyraws/utils/visualization_utils.py
index fa9746d..813788f 100644
--- a/pyraws/utils/visualization_utils.py
+++ b/pyraws/utils/visualization_utils.py
@@ -19,7 +19,8 @@ def image_histogram_equalization(image, number_bins=255):
 
 
 def equalize_tensor(raw_granule_tensor, n_std=2):
-    """Equalizes a tensor for a better visualization by clipping outliers of a histogram higher and lower than than pixels value mean *- n_std times the standarda deviation.
+    """Equalizes a tensor for a better visualization by clipping outliers of a histogram higher and lower than
+    pixels value mean *- n_std times the standarda deviation.
 
     Args:
         raw_granule_tensor (torch.tensor): tensor to equalize.
@@ -60,7 +61,8 @@ def plot_img1_vs_img2_bands(
         img2_band (torch.tensor): second image band.
         img_name_list (list): list of names of different images.
         alert_matrix (torch.tensor, opional): if not None, the hotmap of normal band is shown. Defaults to None.
-        alert_matrix_unregistered (torch.tensor, opional): if not None, the hotmap of unregstered band is shown. Defaults to None.
+        alert_matrix_unregistered (torch.tensor, opional): if not None, the hotmap of unregstered band is shown.
+                                                           Defaults to None.
         save_path (string, optional): if not None, the image is saved at save_path. Defaults to None.
     """
     cmap = "bone"
@@ -102,7 +104,7 @@ def plot_event(img, img_name, bbox_list, alert_matrix=None, save_path=None):
     ax.axis("off")
     ax.title.set_text(img_name)
     for prop in bbox_list:
-        bbox = prop.bbox  #   x,       y,        width, height
+        bbox = prop.bbox  # x, y, width, height
         rect = patches.Rectangle(
             (bbox[1], bbox[0]),
             abs(bbox[1] - bbox[3]),
diff --git a/quickstart/API_demonstration/pyraws_Raw_API_demonstration.ipynb b/quickstart/API_demonstration/pyraws_Raw_API_demonstration.ipynb
index 3473405..a27948d 100644
--- a/quickstart/API_demonstration/pyraws_Raw_API_demonstration.ipynb
+++ b/quickstart/API_demonstration/pyraws_Raw_API_demonstration.ipynb
@@ -19,6 +19,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -26,6 +27,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -47,6 +49,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -68,6 +71,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -84,7 +88,6 @@
    },
    "outputs": [],
    "source": [
-    "import csv\n",
     "import sys\n",
     "sys.path.insert(1, os.path.join(\"..\", \"..\"))\n",
     "sys.path.insert(1, os.path.join(\"..\", \"..\", \"scripts_and_studies\", \"hta_detection_algorithms\"))\n",
@@ -101,10 +104,12 @@
     "from shapely.geometry import Polygon\n",
     "from termcolor import colored\n",
     "import torch\n",
-    "from tqdm import tqdm"
+    "from skimage.measure import label, regionprops\n",
+    "import matplotlib.patches as patches"
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -125,6 +130,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -148,6 +154,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -380,6 +387,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -417,6 +425,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -457,6 +466,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -502,6 +512,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -545,6 +556,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -580,6 +592,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -609,6 +622,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -664,6 +678,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -706,6 +721,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -729,6 +745,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -736,6 +753,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -743,6 +761,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -828,6 +847,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -856,6 +876,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -890,6 +911,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -897,16 +919,7 @@
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from skimage.measure import label, regionprops\n",
-    "import matplotlib.patches as patches"
-   ]
-  },
-  {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -914,6 +927,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -930,6 +944,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -964,6 +979,7 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -989,13 +1005,6 @@
     "     ax.add_patch(rect)\n",
     "plt.show()"
    ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
   }
  ],
  "metadata": {
diff --git a/scripts_and_studies/coregistration_study/coregistration_profiling.py b/scripts_and_studies/coregistration_study/coregistration_profiling.py
index 559eb85..d376039 100644
--- a/scripts_and_studies/coregistration_study/coregistration_profiling.py
+++ b/scripts_and_studies/coregistration_study/coregistration_profiling.py
@@ -181,7 +181,6 @@ def main():
     print(colored("Loading " + str(pargs.n_event) + " granules...", "blue"))
 
     for event in events:
-
         raw_event = Raw_event(device=device)
 
         raw_event.from_database(event, requested_bands, verbose=False)
diff --git a/scripts_and_studies/coregistration_study/coregistration_study.py b/scripts_and_studies/coregistration_study/coregistration_study.py
index ae85572..6efcf5c 100644
--- a/scripts_and_studies/coregistration_study/coregistration_study.py
+++ b/scripts_and_studies/coregistration_study/coregistration_study.py
@@ -112,7 +112,7 @@ def main():
         try:
             raw_event = Raw_event(device=device)
             raw_event.from_database(event, requested_bands, verbose=False)
-        except:
+        except:  # noqa: E722
             print("Skipping event: ", colored(event, "red"))
             continue
 
@@ -220,7 +220,7 @@ def main():
                         coregistration_database,
                     )
                     n_granule_per_image += 1
-                except:
+                except:  # noqa: E722
                     print("Skipping couple: ", colored(stackable_couple, "red"))
                     continue
             else:
diff --git a/scripts_and_studies/coregistration_study/coregistration_study_notebooks_utils.py b/scripts_and_studies/coregistration_study/coregistration_study_notebooks_utils.py
index 0489044..92eb74f 100644
--- a/scripts_and_studies/coregistration_study/coregistration_study_notebooks_utils.py
+++ b/scripts_and_studies/coregistration_study/coregistration_study_notebooks_utils.py
@@ -1,9 +1,11 @@
 import sys
 import os
-sys.path.insert(1, os.path.join("..",".."))
+
+sys.path.insert(1, os.path.join("..", ".."))
 import numpy as np
 import matplotlib.pyplot as plt
 
+
 def extract_test_time(test_name):
     """Extracts test results.
 
@@ -14,32 +16,39 @@ def extract_test_time(test_name):
         dict: results dictionary.
     """
     f = open(test_name, "r")
-    results_txt=f.read()
+    results_txt = f.read()
     f.close()
-    results=results_txt.split("\n")[3].split(" ")
+    results = results_txt.split("\n")[3].split(" ")
 
-    results_clean=[]
+    results_clean = []
     for x in results:
         if x != "":
             results_clean.append(x)
 
-    n_images=int(test_name.split("_n_images_")[1].split("_")[0])
-    coreg_type=test_name.split("_coreg_")[1].split("_")[0]
-    device=test_name.split("_device_")[1].split("_")[0]
-    equalize=test_name.split("_equalize_")[1].split("_")[0]
-    test_iteration=test_name.split("test_iteration_")[1][:-4]
+    n_images = int(test_name.split("_n_images_")[1].split("_")[0])
+    coreg_type = test_name.split("_coreg_")[1].split("_")[0]
+    device = test_name.split("_device_")[1].split("_")[0]
+    equalize = test_name.split("_equalize_")[1].split("_")[0]
+    test_iteration = test_name.split("test_iteration_")[1][:-4]
 
     if results_clean[-3][-2:] == "ms":
-        results=float(results_clean[-3][:-2])/ 1000
+        results = float(results_clean[-3][:-2]) / 1000
     else:
-        results=float(results_clean[-3][:-2])
+        results = float(results_clean[-3][:-2])
 
-    result_dict={"n_images" : n_images, "coreg_type" : coreg_type, "device" : device, "equalize" : equalize, "result [s]" : results}
+    result_dict = {
+        "n_images": n_images,
+        "coreg_type": coreg_type,
+        "device": device,
+        "equalize": equalize,
+        "result [s]": results,
+    }
 
     return test_iteration, result_dict
 
+
 def clean_coregistration_histogram(values):
-    """Clean coregistration histogram by removing values outside -std and std. 
+    """Clean coregistration histogram by removing values outside -std and std.
 
     Args:
         values (numpy array): values to clean.
@@ -47,12 +56,13 @@ def clean_coregistration_histogram(values):
     Returns:
         numpy array: cleaned histogram.
     """
-    values_mean=values.mean()
-    vaues_std=values.std()
-    values = values[values <= values_mean + 0.1*vaues_std]
-    values = values[values >= values_mean - 0.1*vaues_std]
+    values_mean = values.mean()
+    vaues_std = values.std()
+    values = values[values <= values_mean + 0.1 * vaues_std]
+    values = values[values >= values_mean - 0.1 * vaues_std]
     return values
 
+
 def generate_histograms(results_df, satellite, detector, path="histograms", bins=25):
     """Generate histogram for coregistration study results.
 
@@ -64,8 +74,10 @@ def generate_histograms(results_df, satellite, detector, path="histograms", bins
         bins (int, optional): Number of histogram beams. Defaults to 25.
     """
     os.makedirs(path, exist_ok=True)
-    results_df_satellite= results_df[results_df["Sat"]==satellite]
-    results_satellite_detector = results_df_satellite[results_df_satellite['detector_number']== detector]
+    results_df_satellite = results_df[results_df["Sat"] == satellite]
+    results_satellite_detector = results_df_satellite[
+        results_df_satellite["detector_number"] == detector
+    ]
     results_satellite_detector_N_v = np.array(results_satellite_detector.N_v.to_list())
     results_satellite_detector_N_h = np.array(results_satellite_detector.N_h.to_list())
 
@@ -73,12 +85,16 @@ def generate_histograms(results_df, satellite, detector, path="histograms", bins
     plt.hist(results_satellite_detector_N_v, bins=bins)
     plt.xlabel("N_v")
     plt.ylabel("Number of occurrences")
-    plt.title("Hist_"+ str(satellite) + "_" + str(detector) +"_Nv")
-    plt.savefig(os.path.join(path,"hist_" + str(satellite) + "_" + str(detector) +"_Nv.png"))
+    plt.title("Hist_" + str(satellite) + "_" + str(detector) + "_Nv")
+    plt.savefig(
+        os.path.join(path, "hist_" + str(satellite) + "_" + str(detector) + "_Nv.png")
+    )
     plt.figure()
     plt.hist(results_satellite_detector_N_h, bins=bins)
     plt.xlabel("N_h")
     plt.ylabel("Number of occurrences")
-    plt.title("Hist_"+ str(satellite) + "_" + str(detector) +"_Nh")
-    plt.savefig(os.path.join(path,"hist_" + str(satellite) + "_" + str(detector) +"_Nh.png"))
-    return 
\ No newline at end of file
+    plt.title("Hist_" + str(satellite) + "_" + str(detector) + "_Nh")
+    plt.savefig(
+        os.path.join(path, "hist_" + str(satellite) + "_" + str(detector) + "_Nh.png")
+    )
+    return
diff --git a/scripts_and_studies/coregistration_study/coregistration_study_utils.py b/scripts_and_studies/coregistration_study/coregistration_study_utils.py
index 1ccc684..2974bd3 100644
--- a/scripts_and_studies/coregistration_study/coregistration_study_utils.py
+++ b/scripts_and_studies/coregistration_study/coregistration_study_utils.py
@@ -1,9 +1,10 @@
 try:
     from superglue_models.matching import Matching
     from superglue_models.utils import make_matching_plot
-except:
+except:  # noqa: E722
     raise ValueError(
-        "SuperGlue model not found. Please, follow the instructions at: https://gitlab.esa.int/Alix.DeBeusscher/pyraws/#set-up-for-coregistration-study."
+        "SuperGlue model not found. Please, follow the instructions at: "
+        + "https://github.com/ESA-PhiLab/PyRawS#set-up-for-coregistration-study."
     )
 
 import csv
@@ -34,7 +35,8 @@ def get_shift_SuperGlue_profiling(
         sinkhorn_iterations (int, optional): number of sinkorn iterations. Defaults to 30.
         requested_bands (list): list containing two bands for which perform the study.
         equalize (bool, optional): if True, equalization is performed. Defaults to True.
-        n_std (int, optional): Outliers are saturated for equalization at histogram_mean*- n_std * histogram_std. Defaults to 2.
+        n_std (int, optional): Outliers are saturated for equalization at histogram_mean*- n_std * histogram_std.
+                               Defaults to 2.
         device (torch.device, optional): torch.device. Defaults to torch.device("cpu").
 
     Returns:
@@ -80,7 +82,7 @@ def get_shift_SuperGlue_profiling(
     )
     pred = {k: v[0].detach().cpu().numpy() for k, v in pred.items()}
     kpts0, kpts1 = pred["keypoints0"], pred["keypoints1"]
-    matches, conf = pred["matches0"], pred["matching_scores0"]
+    matches, _ = pred["matches0"], pred["matching_scores0"]
     valid = matches > -1
     mkpts0 = kpts0[valid]
     mkpts1 = kpts1[matches[valid]]
@@ -127,7 +129,8 @@ def get_shift_SuperGlue(
         requested_bands (list): list containing two bands for which perform the study.
         save_path (str, optional): path to save quicklooks. No quicklook is generated if None. Defaults to None.
         equalize (bool, optional): if True, equalization is performed. Defaults to True.
-        n_std (int, optional): Outliers are saturated for equalization at histogram_mean*- n_std * histogram_std. Defaults to 2.
+        n_std (int, optional): Outliers are saturated for equalization at histogram_mean*- n_std * histogram_std.
+                               Defaults to 2.
         device (torch.device, optional): torch.device. Defaults to torch.device("cpu").
 
     Returns:
diff --git a/scripts_and_studies/coregistration_study/find_best_coregistration_values_digital_image_correlation.py b/scripts_and_studies/coregistration_study/find_best_coregistration_values_digital_image_correlation.py
index e1f91ec..cab4366 100644
--- a/scripts_and_studies/coregistration_study/find_best_coregistration_values_digital_image_correlation.py
+++ b/scripts_and_studies/coregistration_study/find_best_coregistration_values_digital_image_correlation.py
@@ -15,7 +15,6 @@
 
 
 def update_csv_shift_lut(csv_name, bands_shifts_dict):
-
     band_names = list(bands_shifts_dict.keys())
 
     with open(csv_name, mode="w+") as csv_file:
@@ -208,8 +207,6 @@ def main():
                         bx = rotate(bx.unsqueeze(2), 180).squeeze(2)
 
                     bx_scaled = bx - bx.mean()
-                    by_mean = by.mean()
-                    by_scaled = by - by_mean
 
                     if start_values_lut is not None:
                         start_value = int(start_values_lut[band_name_x][band_name_y])
@@ -290,7 +287,6 @@ def main():
                                 negative_correlation_found = True
                                 break
 
-                            ##print("SHIFT: ", shift, " CORRELATION: ", correlation)
                             if best_correlation < correlation:
                                 print(
                                     "Found new best correlation value: "
@@ -314,7 +310,7 @@ def main():
 
                             if n_without_optimum == n_early:
                                 break
-                        except:
+                        except:  # noqa: E722
                             continue
 
                     if not (negative_correlation_found):
diff --git a/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/create_json_polygons.py b/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/create_json_polygons.py
index b6a1c75..f2945bc 100644
--- a/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/create_json_polygons.py
+++ b/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/create_json_polygons.py
@@ -5,6 +5,7 @@
 import os
 from glob import glob
 
+
 def create_output_dir(out_dir):
     print("Creating the directory: ", out_dir)
     if os.path.isdir(out_dir):
@@ -14,39 +15,58 @@ def create_output_dir(out_dir):
     else:
         os.mkdir(out_dir)
 
+
 def parse_coordinate(coordinate_str):
-    lon=float(coordinate_str[coordinate_str.find('[')+1:coordinate_str.find(',')-1])
-    lat=float(coordinate_str[coordinate_str.find(',')+1:coordinate_str.find(']')-1])
+    lon = float(
+        coordinate_str[coordinate_str.find("[") + 1 : coordinate_str.find(",") - 1]
+    )
+    lat = float(
+        coordinate_str[coordinate_str.find(",") + 1 : coordinate_str.find("]") - 1]
+    )
     return (lon, lat)
 
+
 def get_polygon(eruption):
-    coord_sw=parse_coordinate(eruption["Pol-SW"])
-    coord_nw=parse_coordinate(eruption["Pol-NW"])
-    coord_ne=parse_coordinate(eruption["Pol-NE"])
-    coord_se=parse_coordinate(eruption["Pol-SE"])
+    coord_sw = parse_coordinate(eruption["Pol-SW"])
+    coord_nw = parse_coordinate(eruption["Pol-NW"])
+    coord_ne = parse_coordinate(eruption["Pol-NE"])
+    coord_se = parse_coordinate(eruption["Pol-SE"])
     return Polygon([coord_sw, coord_nw, coord_ne, coord_se])
 
 
 def main():
     parser = argparse.ArgumentParser()
-    parser.add_argument('--eruption_cvs', type=str, help='Eruption list CSV.', default="eruption_selected.csv")
-    parser.add_argument('--json_dir_path', type=str, help='Path to the directory where JSON files are stored.', default="./json")
-    pargs=parser.parse_args()
-    csv_name=pargs.eruption_cvs
-    csv_content=parse_csv(csv_name)
-    json_dir=pargs.json_dir_path
+    parser.add_argument(
+        "--eruption_cvs",
+        type=str,
+        help="Eruption list CSV.",
+        default="eruption_selected.csv",
+    )
+    parser.add_argument(
+        "--json_dir_path",
+        type=str,
+        help="Path to the directory where JSON files are stored.",
+        default="./json",
+    )
+    pargs = parser.parse_args()
+    csv_name = pargs.eruption_cvs
+    csv_content = parse_csv(csv_name)
+    json_dir = pargs.json_dir_path
 
     create_output_dir(json_dir)
 
     for eruption in csv_content:
+        polygon = get_polygon(eruption)
+        json_content = geopandas.GeoSeries([polygon]).to_json()
 
-
-        polygon=get_polygon(eruption)
-        json_content=geopandas.GeoSeries([polygon]).to_json()
-
-        with open(os.path.join(json_dir, eruption["Name"].replace(" ", "_").replace("/", "_")+".json"), 'w') as f:
+        with open(
+            os.path.join(
+                json_dir, eruption["Name"].replace(" ", "_").replace("/", "_") + ".json"
+            ),
+            "w",
+        ) as f:
             f.write(json_content)
 
 
 if __name__ == "__main__":
-    main()
\ No newline at end of file
+    main()
diff --git a/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/create_volcano_csv.py b/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/create_volcano_csv.py
index 27cfae1..d4ecd73 100644
--- a/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/create_volcano_csv.py
+++ b/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/create_volcano_csv.py
@@ -6,155 +6,256 @@
 import argparse
 
 
+sentinel2_starting_date = date(2015, 6, 23)
 
 
-sentinel2_starting_date=date(2015,6,23)
-
 def parse_csv(csv_name):
-    """Parse a CSV file containing volcano eruption list. 
+    """Parse a CSV file containing volcano eruption list.
 
     Returns list of eruptions.
 
     :csv_name: CSV name.
     :return: (list of tests. Each test is a dictionary.)
     """
-    eruptions_list=[]
+    eruptions_list = []
     try:
         with open(csv_name) as csv_file:
             csv_reader = csv.DictReader(csv_file)
             for row in csv_reader:
                 eruptions_list.append(row)
-    except:
+    except:  # noqa: E722
         return ValueError("Impossible to parse CSV file: ", csv_name)
 
     return eruptions_list
 
+
 def get_s2_date(eruption, date_type="Start"):
-    s2_year=eruption[date_type+" Year"]
-    s2_month=eruption[date_type+" Month"]
-    s2_day=eruption[date_type+" Day"]
-    if eruption[date_type+" Year Uncertainty"] == '':
-        s2_year_uncertainty=0
+    s2_year = eruption[date_type + " Year"]
+    s2_month = eruption[date_type + " Month"]
+    s2_day = eruption[date_type + " Day"]
+    if eruption[date_type + " Year Uncertainty"] == "":
+        s2_year_uncertainty = 0
     else:
-        s2_year_uncertainty=int(eruption[date_type+" Year Uncertainty"])
+        s2_year_uncertainty = int(eruption[date_type + " Year Uncertainty"])
 
-    if eruption[date_type+" Day Uncertainty"] == '':
-        s2_day_uncertainty=0
+    if eruption[date_type + " Day Uncertainty"] == "":
+        s2_day_uncertainty = 0
     else:
-        s2_day_uncertainty=int(eruption[date_type+" Day Uncertainty"])
+        s2_day_uncertainty = int(eruption[date_type + " Day Uncertainty"])
+
+    s2_date = date(int(s2_year), int(s2_month), int(s2_day))
+    s2_date -= timedelta(days=s2_year_uncertainty * 365 + s2_day_uncertainty)
 
-    s2_date=date(int(s2_year), int(s2_month), int(s2_day) )
-    s2_date -=timedelta(days=s2_year_uncertainty*365+s2_day_uncertainty)
-    
     return s2_date
 
+
 def parse_eruption(eruption):
-    volcano_name=eruption["Volcano Name"]
-    start_date=get_s2_date(eruption, date_type="Start")
-    end_date=get_s2_date(eruption, date_type="End")
-    discard=False
-    
-    if (sentinel2_starting_date >= start_date) and (sentinel2_starting_date >= end_date): # I check both to be sure there are not errors in the excel.
-        discard=True
-    
-    coordinates={"lat" : float(eruption["Latitude"]), "lon" : float(eruption["Longitude"])}
+    volcano_name = eruption["Volcano Name"]
+    start_date = get_s2_date(eruption, date_type="Start")
+    end_date = get_s2_date(eruption, date_type="End")
+    discard = False
+
+    if (sentinel2_starting_date >= start_date) and (
+        sentinel2_starting_date >= end_date
+    ):  # I check both to be sure there are not errors in the excel.
+        discard = True
+
+    coordinates = {
+        "lat": float(eruption["Latitude"]),
+        "lon": float(eruption["Longitude"]),
+    }
 
     return [volcano_name, start_date, end_date, coordinates, discard]
 
-def create_rectangular_polygon(center_coordinates, center_distance_x, center_distance_y):
 
-    center_distance = np.sqrt(center_distance_x * center_distance_x + center_distance_y * center_distance_y)
+def create_rectangular_polygon(
+    center_coordinates, center_distance_x, center_distance_y
+):
+    center_distance = np.sqrt(
+        center_distance_x * center_distance_x + center_distance_y * center_distance_y
+    )
     bearing_angle_0 = 90 - np.arcsin(center_distance_y / center_distance) * 180 / np.pi
     print(center_distance)
 
-    bearing_angles={"SW" : 180 + bearing_angle_0, "NW" : 360 - bearing_angle_0, "NE" : bearing_angle_0, "SE" : 180 - bearing_angle_0}
+    bearing_angles = {
+        "SW": 180 + bearing_angle_0,
+        "NW": 360 - bearing_angle_0,
+        "NE": bearing_angle_0,
+        "SE": 180 - bearing_angle_0,
+    }
     print(bearing_angles)
-    polygon_dict={"SW" : 0, "NW" : 0, "NE" : 0, "SE" : 0} #South-West, North-West, ...
+    polygon_dict = {"SW": 0, "NW": 0, "NE": 0, "SE": 0}  # South-West, North-West, ...
     for bearing_keys in list(bearing_angles.keys()):
-        polygon_vertex=geopy.distance.distance(meters=center_distance).destination((center_coordinates["lat"], center_coordinates["lon"]), bearing=bearing_angles[bearing_keys])
-        polygon_dict[bearing_keys]=[polygon_vertex[1], polygon_vertex[0]]
+        polygon_vertex = geopy.distance.distance(meters=center_distance).destination(
+            (center_coordinates["lat"], center_coordinates["lon"]),
+            bearing=bearing_angles[bearing_keys],
+        )
+        polygon_dict[bearing_keys] = [polygon_vertex[1], polygon_vertex[0]]
     return polygon_dict
-    
+
 
 def create_polygon(center_coordinates, center_distance):
-    
-    bearing_angles={"SW" : 225.0, "NW" : 135.0, "NE" : 45.0, "SE" : 315.0}
+    bearing_angles = {"SW": 225.0, "NW": 135.0, "NE": 45.0, "SE": 315.0}
 
-    polygon_dict={"SW" : 0, "NW" : 0, "NE" : 0, "SE" : 0} #South-West, North-West, ...
+    polygon_dict = {"SW": 0, "NW": 0, "NE": 0, "SE": 0}  # South-West, North-West, ...
     for bearing_keys in list(bearing_angles.keys()):
-        polygon_vertex=geopy.distance.distance(meters=center_distance).destination((center_coordinates["lat"], center_coordinates["lon"]), bearing=bearing_angles[bearing_keys])
-        polygon_dict[bearing_keys]=[polygon_vertex[1], polygon_vertex[0]]
+        polygon_vertex = geopy.distance.distance(meters=center_distance).destination(
+            (center_coordinates["lat"], center_coordinates["lon"]),
+            bearing=bearing_angles[bearing_keys],
+        )
+        polygon_dict[bearing_keys] = [polygon_vertex[1], polygon_vertex[0]]
     return polygon_dict
-    
-def get_eruptions_info_list(eruption_list_csv_name, n_max_volcano, target_csv_filename="eruption_selected.csv", eruption_day_length=2, polygon_semidiagonal_km=7.0):
-    eruptions_list=parse_csv(eruption_list_csv_name)
 
-    volcanos_count_dict={}
-    eruptions_info_list=[]
-    skipped_eruptions_list=[]
+
+def get_eruptions_info_list(
+    eruption_list_csv_name,
+    n_max_volcano,
+    target_csv_filename="eruption_selected.csv",
+    eruption_day_length=2,
+    polygon_semidiagonal_km=7.0,
+):
+    eruptions_list = parse_csv(eruption_list_csv_name)
+
+    volcanos_count_dict = {}
+    eruptions_info_list = []
+    skipped_eruptions_list = []
     for eruption in eruptions_list:
-        volcano_name=eruption["Volcano Name"]
-        if not(volcano_name in list(volcanos_count_dict.keys())):
-            volcanos_count_dict[volcano_name]=0
+        volcano_name = eruption["Volcano Name"]
+        if not (volcano_name in list(volcanos_count_dict.keys())):
+            volcanos_count_dict[volcano_name] = 0
 
         if volcanos_count_dict[volcano_name] < n_max_volcano:
-            eruption_info=parse_eruption(eruption)
+            eruption_info = parse_eruption(eruption)
             if eruption_info[-1]:
-                print("Skipping volcano eruption: "+colored(volcano_name, "red")+ "for unacceptable dates Start date("+colored(eruption_info[-4], "blue")+"), End date("+colored(eruption_info[-3], "green")+").")
+                print(
+                    "Skipping volcano eruption: "
+                    + colored(volcano_name, "red")
+                    + "for unacceptable dates Start date("
+                    + colored(eruption_info[-4], "blue")
+                    + "), End date("
+                    + colored(eruption_info[-3], "green")
+                    + ")."
+                )
                 skipped_eruptions_list.append(eruption_info[:-1])
             else:
                 eruptions_info_list.append(eruption_info[:-1])
-                volcanos_count_dict[volcano_name]+=1
+                volcanos_count_dict[volcano_name] += 1
         else:
-            eruption_info=parse_eruption(eruption)
+            eruption_info = parse_eruption(eruption)
             skipped_eruptions_list.append(eruption_info[:-1])
-            print("Skipping volcano eruption: "+colored(volcano_name, "red")+ "for passing the number of eruptions for volcano ("+colored(n_max_volcano, "blue")+".")
+            print(
+                "Skipping volcano eruption: "
+                + colored(volcano_name, "red")
+                + "for passing the number of eruptions for volcano ("
+                + colored(n_max_volcano, "blue")
+                + "."
+            )
 
-    fieldnames=["Name", "Starting date", "End date", "Pol-SW", "Pol-NW", "Pol-NE", "Pol-SE"]
+    fieldnames = [
+        "Name",
+        "Starting date",
+        "End date",
+        "Pol-SW",
+        "Pol-NW",
+        "Pol-NE",
+        "Pol-SE",
+    ]
 
-    volcanos_id_cnt=dict(zip(list(volcanos_count_dict.keys()), [0 for n in range(len(list(volcanos_count_dict.keys())))]))
+    volcanos_id_cnt = dict(
+        zip(
+            list(volcanos_count_dict.keys()),
+            [0 for n in range(len(list(volcanos_count_dict.keys())))],
+        )
+    )
 
-    with open(target_csv_filename, mode='w') as csv_file:
+    with open(target_csv_filename, mode="w") as csv_file:
         writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
         writer.writeheader()
         for eruption_info in eruptions_info_list:
-            volcano_name=eruption_info[0]
-            volcano_id=volcano_name+'_'+str(volcanos_id_cnt[volcano_name])
-            volcanos_id_cnt[volcano_name]+=1
-            start_date=eruption_info[1]
-            end_date=eruption_info[2]
-            center_coordinates=eruption_info[3]
+            volcano_name = eruption_info[0]
+            volcano_id = volcano_name + "_" + str(volcanos_id_cnt[volcano_name])
+            volcanos_id_cnt[volcano_name] += 1
+            start_date = eruption_info[1]
+            end_date = eruption_info[2]
+            center_coordinates = eruption_info[3]
 
             if start_date >= sentinel2_starting_date:
-                end_date=start_date+timedelta(days=eruption_day_length)
+                end_date = start_date + timedelta(days=eruption_day_length)
             else:
-                start_date=end_date-timedelta(days=eruption_day_length)
+                start_date = end_date - timedelta(days=eruption_day_length)
 
-            start_date=str(start_date.year)+"-"+str(start_date.month)+"-"+str(start_date.day)+"T00:00:00"
-            end_date=str(end_date.year)+"-"+str(end_date.month)+"-"+str(end_date.day)+"T23:59:59"
-            polygon=create_polygon(center_coordinates, polygon_semidiagonal_km*1000)
-            eruption_record=[volcano_id, start_date, end_date, polygon["SW"], polygon["NW"], polygon["NE"],polygon["SE"]]
-                
-            writer.writerow(dict(zip(fieldnames, eruption_record)))
+            start_date = (
+                str(start_date.year)
+                + "-"
+                + str(start_date.month)
+                + "-"
+                + str(start_date.day)
+                + "T00:00:00"
+            )
+            end_date = (
+                str(end_date.year)
+                + "-"
+                + str(end_date.month)
+                + "-"
+                + str(end_date.day)
+                + "T23:59:59"
+            )
+            polygon = create_polygon(center_coordinates, polygon_semidiagonal_km * 1000)
+            eruption_record = [
+                volcano_id,
+                start_date,
+                end_date,
+                polygon["SW"],
+                polygon["NW"],
+                polygon["NE"],
+                polygon["SE"],
+            ]
 
+            writer.writerow(dict(zip(fieldnames, eruption_record)))
 
-    print("Number of accepted eruptions: "+colored(len(eruptions_info_list), "green"))
-    print("Number of skipped eruptions: "+colored(len(skipped_eruptions_list), "red"))
+    print("Number of accepted eruptions: " + colored(len(eruptions_info_list), "green"))
+    print("Number of skipped eruptions: " + colored(len(skipped_eruptions_list), "red"))
 
 
 def main():
     parser = argparse.ArgumentParser()
-    parser.add_argument('--eruption_cvs', type=str, help='Eruption list CSV.', default="eruption_list.csv")
-    parser.add_argument('--n_max_volcano', type=int, help='Maximum number of eruption per volcano.', default=5)
-    parser.add_argument('--eruption_day_length', type=int, help='Number of days margin per eruption.', default=2)
-    parser.add_argument('--pol_distance_km', type=float, help='Distance of a vertex from the polygon center in km (semidiagonal).', default=7.0)
-    pargs=parser.parse_args()
-    eruption_list_csv_name=pargs.eruption_cvs
-    n_max_volcano=pargs.n_max_volcano
-    eruption_day_length=pargs.eruption_day_length
-    polygon_semidiagonal_km=pargs.pol_distance_km
-    get_eruptions_info_list(eruption_list_csv_name, n_max_volcano, target_csv_filename="eruption_selected.csv", eruption_day_length=eruption_day_length, polygon_semidiagonal_km=polygon_semidiagonal_km)
+    parser.add_argument(
+        "--eruption_cvs",
+        type=str,
+        help="Eruption list CSV.",
+        default="eruption_list.csv",
+    )
+    parser.add_argument(
+        "--n_max_volcano",
+        type=int,
+        help="Maximum number of eruption per volcano.",
+        default=5,
+    )
+    parser.add_argument(
+        "--eruption_day_length",
+        type=int,
+        help="Number of days margin per eruption.",
+        default=2,
+    )
+    parser.add_argument(
+        "--pol_distance_km",
+        type=float,
+        help="Distance of a vertex from the polygon center in km (semidiagonal).",
+        default=7.0,
+    )
+    pargs = parser.parse_args()
+    eruption_list_csv_name = pargs.eruption_cvs
+    n_max_volcano = pargs.n_max_volcano
+    eruption_day_length = pargs.eruption_day_length
+    polygon_semidiagonal_km = pargs.pol_distance_km
+    get_eruptions_info_list(
+        eruption_list_csv_name,
+        n_max_volcano,
+        target_csv_filename="eruption_selected.csv",
+        eruption_day_length=eruption_day_length,
+        polygon_semidiagonal_km=polygon_semidiagonal_km,
+    )
 
 
 if __name__ == "__main__":
-    main()
\ No newline at end of file
+    main()
diff --git a/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/json_polygon_from_point.py b/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/json_polygon_from_point.py
index 592390d..38951ca 100644
--- a/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/json_polygon_from_point.py
+++ b/scripts_and_studies/dataset_preparation/THRAWS/volcano_eruptions/json_polygon_from_point.py
@@ -1,40 +1,62 @@
 import geopandas
 from shapely.geometry import Polygon
 import argparse
-#from l0_dataset_preparation.volcano_eruptions.create_volcano_csv import create_rectangular_polygon, parse_csv
-from .create_volcano_csv import create_rectangular_polygon, parse_csv
 
+# from l0_dataset_preparation.volcano_eruptions.create_volcano_csv import create_rectangular_polygon, parse_csv
+from .create_volcano_csv import create_rectangular_polygon
 
 
-def create_polygon_from_coordinates(lat, lon, center_distance_x, center_distance_y, json_name=None):
-    center_coordinates={'lat' : lat, 'lon' : lon}
-    polygon_dict=create_rectangular_polygon(center_coordinates, center_distance_x, center_distance_y)
-    polygon=Polygon([polygon_dict['SW'], polygon_dict['NW'], polygon_dict['NE'], polygon_dict['SE']])
-    json_content=geopandas.GeoSeries([polygon]).to_json()
+def create_polygon_from_coordinates(
+    lat, lon, center_distance_x, center_distance_y, json_name=None
+):
+    center_coordinates = {"lat": lat, "lon": lon}
+    polygon_dict = create_rectangular_polygon(
+        center_coordinates, center_distance_x, center_distance_y
+    )
+    polygon = Polygon(
+        [polygon_dict["SW"], polygon_dict["NW"], polygon_dict["NE"], polygon_dict["SE"]]
+    )
+    json_content = geopandas.GeoSeries([polygon]).to_json()
 
     if json_name is not None:
-        with open(json_name, 'w') as f:
+        with open(json_name, "w") as f:
             f.write(json_content)
-            f.write('\n\n')
-            f.write(str(polygon_dict['SW']))
-            f.write('\n\n')
-            f.write(str(polygon_dict['NW']))
-            f.write('\n\n')
-            f.write(str(polygon_dict['NE']))
-            f.write('\n\n')
-            f.write(str(polygon_dict['SE']))
+            f.write("\n\n")
+            f.write(str(polygon_dict["SW"]))
+            f.write("\n\n")
+            f.write(str(polygon_dict["NW"]))
+            f.write("\n\n")
+            f.write(str(polygon_dict["NE"]))
+            f.write("\n\n")
+            f.write(str(polygon_dict["SE"]))
 
     return polygon
 
+
 def main():
     parser = argparse.ArgumentParser()
-    parser.add_argument('--lat', type=float, help='Point latitude.')
-    parser.add_argument('--lon', type=float, help='Point latitude.')
-    parser.add_argument('--dx_km', type=float, help='Horizontal distance from the polygon center in km.', default=5.0)
-    parser.add_argument('--dy_km', type=float, help='Vertical distance from the polygon center in km.', default=14.0)
-    parser.add_argument('--json_name', type=str, help='json file name.', default="my_json_polygon.json")
-    pargs=parser.parse_args()
-    create_polygon_from_coordinates(pargs.lat, pargs.lon, pargs.dx_km * 1000, pargs.dy_km * 1000, pargs.json_name)
+    parser.add_argument("--lat", type=float, help="Point latitude.")
+    parser.add_argument("--lon", type=float, help="Point latitude.")
+    parser.add_argument(
+        "--dx_km",
+        type=float,
+        help="Horizontal distance from the polygon center in km.",
+        default=5.0,
+    )
+    parser.add_argument(
+        "--dy_km",
+        type=float,
+        help="Vertical distance from the polygon center in km.",
+        default=14.0,
+    )
+    parser.add_argument(
+        "--json_name", type=str, help="json file name.", default="my_json_polygon.json"
+    )
+    pargs = parser.parse_args()
+    create_polygon_from_coordinates(
+        pargs.lat, pargs.lon, pargs.dx_km * 1000, pargs.dy_km * 1000, pargs.json_name
+    )
+
 
 if __name__ == "__main__":
-    main()
\ No newline at end of file
+    main()
diff --git a/scripts_and_studies/granules_filtering/granules_filtering.py b/scripts_and_studies/granules_filtering/granules_filtering.py
index 67d67da..cbbf35d 100644
--- a/scripts_and_studies/granules_filtering/granules_filtering.py
+++ b/scripts_and_studies/granules_filtering/granules_filtering.py
@@ -6,7 +6,6 @@
 from pyraws.raw.raw_event import Raw_event
 from pyraws.l1.l1_event import L1C_event
 from pyraws.utils.l1_utils import (
-    read_L1C_image_from_tif,
     read_L1C_image_from_tif,
     get_event_bounding_box,
 )
@@ -188,7 +187,7 @@ def main():
 
     for event in tqdm(events_list[start_idx:], desc="Processing events... "):
         print("Processing event: " + colored(event, "blue"))
-        ####Create quicklook###################
+        # ------------------Create quicklook---------------------
         plt.close()
         try:
             raw_event = Raw_event(device=device)
@@ -196,7 +195,7 @@ def main():
             if not (Skip_L1C_generation):
                 l1c_event = L1C_event(device=device)
                 l1c_event.from_database(event, requested_bands, verbose=False)
-        except:
+        except:  # noqa: E722
             print(
                 "Impossible to open either Raw either L1c data. Skipping event: ",
                 colored(event, "red"),
@@ -300,7 +299,7 @@ def main():
                         complementary_granule_names_list.remove(
                             ""
                         )  # Removing empty names
-                    except:
+                    except:  # noqa: E722
                         pass
 
                     # Removing ending character
@@ -428,7 +427,7 @@ def main():
                         event_detected = False
                 else:
                     print(colored("Skipping event: Predicted as NOT EVENT.", "red"))
-            except:
+            except:  # noqa: E722
                 print(
                     "Errors in processing the L1C granule. Skipping event: ",
                     colored(event, "red"),
diff --git a/scripts_and_studies/hta_detection_algorithms/hta_detection.py b/scripts_and_studies/hta_detection_algorithms/hta_detection.py
index 9f68610..09e3697 100644
--- a/scripts_and_studies/hta_detection_algorithms/hta_detection.py
+++ b/scripts_and_studies/hta_detection_algorithms/hta_detection.py
@@ -1,26 +1,29 @@
-# [1] - Liu, Yongxue, et al. "Detecting high-temperature anomalies from Sentinel-2 MSI images." ISPRS Journal of Photogrammetry and Remote Sensing 177 (2021): 174-193.
+# [1] - Liu, Yongxue, et al. "Detecting high-temperature anomalies from Sentinel-2 MSI images."
+# ISPRS Journal of Photogrammetry and Remote Sensing 177 (2021): 174-193.
 # The next functions implement a simplified version of the algorithm described in [1].
 
 import torch
 import torchvision
 
+
 def get_TAI(s2_l1c_img):
     """Returns the th Thermal Anomaly Index (TAI) as defined in [1].
 
-
     Args:
-        s2_l1c_img (torch.tensor): Sentinel2-L1C image. 
+        s2_l1c_img (torch.tensor): Sentinel2-L1C image.
 
     Returns:
         torch.tensor: TAI (with negative values saturated a 0)
     """
 
-    tai=torch.div(s2_l1c_img[:,:,2] - s2_l1c_img[:,:,1],  s2_l1c_img[:,:,0])
+    tai = torch.div(s2_l1c_img[:, :, 2] - s2_l1c_img[:, :, 1], s2_l1c_img[:, :, 0])
 
     return torch.where(tai >= torch.zeros_like(tai), tai, torch.zeros_like(tai))
 
+
 def get_TAI_mean(tai):
-    """It returns the TAI mean as defined in [1]. TAI_mean is calculated by using a 15x15 convolutional filter. The input image is padded with the values at the boundaries to avoid boundaries false positives.
+    """It returns the TAI mean as defined in [1]. TAI_mean is calculated by using a 15x15 convolutional filter.
+    The input image is padded with the values at the boundaries to avoid boundaries false positives.
 
     Args:
         tai (torch.tensor): tai index
@@ -28,16 +31,22 @@ def get_TAI_mean(tai):
     Returns:
         torch.tensor: convoluted alert-map
     """
-    conv=torch.nn.Conv2d(1, 1, 31)
-    weight=torch.nn.Parameter(1/31 * torch.ones([31,31]).unsqueeze(0).unsqueeze(0),requires_grad=False)
-    
-    if tai.device.type=='cuda':
-        conv=conv.cuda()
-    conv.load_state_dict({'weight': weight, 'bias' : torch.zeros([1])}, strict=False)
+    conv = torch.nn.Conv2d(1, 1, 31)
+    weight = torch.nn.Parameter(
+        1 / 31 * torch.ones([31, 31]).unsqueeze(0).unsqueeze(0), requires_grad=False
+    )
+
+    if tai.device.type == "cuda":
+        conv = conv.cuda()
+    conv.load_state_dict({"weight": weight, "bias": torch.zeros([1])}, strict=False)
     with torch.no_grad():
-        padding=torchvision.transforms.Pad((15,15,15,15), padding_mode='edge')
-        img_pad=padding(tai)
-        tai_mean=conv(torch.tensor(img_pad, dtype=torch.float32).unsqueeze(0).unsqueeze(0)).squeeze(0).squeeze(0)
+        padding = torchvision.transforms.Pad((15, 15, 15, 15), padding_mode="edge")
+        img_pad = padding(tai)
+        tai_mean = (
+            conv(torch.tensor(img_pad, dtype=torch.float32).unsqueeze(0).unsqueeze(0))
+            .squeeze(0)
+            .squeeze(0)
+        )
         del weight
         del conv
         del img_pad
@@ -56,20 +65,22 @@ def get_TAI_buffer(tai, tai_mean):
         torch.tensor: TAI buffer.
     """
     with torch.no_grad():
-        s_index=torch.where(tai -tai_mean >= 0.45, 1, 0).nonzero()
-        padding=torchvision.transforms.Pad((15,15,15,15), padding_mode='constant', fill=0)
-        s_pad=padding(tai)
-        b=torch.zeros_like(s_pad)
-        for (r,c) in s_index:
-            b[r-15:r+15,c-15:c+15]=1
+        s_index = torch.where(tai - tai_mean >= 0.45, 1, 0).nonzero()
+        padding = torchvision.transforms.Pad(
+            (15, 15, 15, 15), padding_mode="constant", fill=0
+        )
+        s_pad = padding(tai)
+        b = torch.zeros_like(s_pad)
+        for r, c in s_index:
+            b[r - 15 : r + 15, c - 15 : c + 15] = 1
 
-        b=b[15:-15, 15:-15] #Removing edge pixels having no information.
+        b = b[15:-15, 15:-15]  # Removing edge pixels having no information.
 
         return b
 
 
 def cluster_9px(img):
-    """It performs the convolution to detect clusters of 9 activate pixels (current pixel and 8 surrounding pixels) are at 1. 
+    """It performs the convolution to detect clusters of 9 activate pixels (current pixel and 8 surrounding pixels) are at 1.
 
     Args:
         img (torch.tensor): input alert-matrix
@@ -77,23 +88,33 @@ def cluster_9px(img):
     Returns:
         torch.tensor: convoluted alert-map
     """
-    
-    conv=torch.nn.Conv2d(1, 1, 3)
-    weight=torch.nn.Parameter(torch.tensor([[[[1.0,1.0,1.0], [1.0,1.0,1.0], [1.0,1.0,1.0]]]]),requires_grad=False)
-    img_pad=torch.nn.functional.pad(img, (1,1,1,1), mode='constant', value=1)
-    if img.device.type=='cuda':
-        conv=conv.cuda()
-    conv.load_state_dict({'weight': weight, 'bias' : torch.zeros([1])}, strict=False)
+
+    conv = torch.nn.Conv2d(1, 1, 3)
+    weight = torch.nn.Parameter(
+        torch.tensor([[[[1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]]]),
+        requires_grad=False,
+    )
+    img_pad = torch.nn.functional.pad(img, (1, 1, 1, 1), mode="constant", value=1)
+    if img.device.type == "cuda":
+        conv = conv.cuda()
+    conv.load_state_dict({"weight": weight, "bias": torch.zeros([1])}, strict=False)
     with torch.no_grad():
-        surrounded=conv(torch.tensor(img_pad, dtype=torch.float32).unsqueeze(0).unsqueeze(0)).squeeze(0).squeeze(0)
-        #Adding clipping to the mean
-        surrounded=torch.where(surrounded >= 0.45, 0.45 * torch.ones_like(surrounded), surrounded)
+        surrounded = (
+            conv(torch.tensor(img_pad, dtype=torch.float32).unsqueeze(0).unsqueeze(0))
+            .squeeze(0)
+            .squeeze(0)
+        )
+        # Adding clipping to the mean
+        surrounded = torch.where(
+            surrounded >= 0.45, 0.45 * torch.ones_like(surrounded), surrounded
+        )
         del weight
         del conv
         del img_pad
         torch.cuda.empty_cache()
     return surrounded
 
+
 def manage_saturated_thermal_anomalies(s2_l1c_img):
     """It checks thermal anomalies as described in [1] by returning a mask to control not-8-connected thermal anomalies.
 
@@ -103,9 +124,15 @@ def manage_saturated_thermal_anomalies(s2_l1c_img):
     Returns:
         torch.tensor: saturated thermal anomalies mask
     """
-    saturated_mask=torch.logical_and(torch.where(s2_l1c_img[:,:,2] >= 1, 1, 0), torch.where(s2_l1c_img[:,:,2] >= 1,1,0))
-    saturated_mask_8_connected=cluster_9px(saturated_mask)
-    return torch.logical_or(saturated_mask_8_connected, torch.logical_not(saturated_mask))
+    saturated_mask = torch.logical_and(
+        torch.where(s2_l1c_img[:, :, 2] >= 1, 1, 0),
+        torch.where(s2_l1c_img[:, :, 2] >= 1, 1, 0),
+    )
+    saturated_mask_8_connected = cluster_9px(saturated_mask)
+    return torch.logical_or(
+        saturated_mask_8_connected, torch.logical_not(saturated_mask)
+    )
+
 
 def get_image_lost_source_mask(s2_l1c_img):
     """It removes pixels with lost packages as in [1] by returning a mask.
@@ -116,9 +143,13 @@ def get_image_lost_source_mask(s2_l1c_img):
     Returns:
         torch.tensor: nask to exclude image lost.
     """
-    source_lost_mask_negated=torch.logical_or(torch.where(s2_l1c_img[:,:,0] < 0.01, 1, 0), torch.where(s2_l1c_img[:,:,1] < 0.05,1,0))
+    source_lost_mask_negated = torch.logical_or(
+        torch.where(s2_l1c_img[:, :, 0] < 0.01, 1, 0),
+        torch.where(s2_l1c_img[:, :, 1] < 0.05, 1, 0),
+    )
     return torch.logical_not(source_lost_mask_negated)
 
+
 def remove_false_positives(s2_l1c_img, thermal_anomalies_map):
     """Removing false positives due to saturated surfaces, image packet loss or edge anomalies.
 
@@ -129,13 +160,26 @@ def remove_false_positives(s2_l1c_img, thermal_anomalies_map):
     Returns:
         torch.tensor: clean thermal_anomalies_map
     """
-    thermal_saturated_mask=manage_saturated_thermal_anomalies(s2_l1c_img)
-    thermal_saturated_mask_no_saturation=torch.logical_and(thermal_anomalies_map, thermal_saturated_mask)
-    source_lost_mask=get_image_lost_source_mask(s2_l1c_img)
-    thermal_anomalies_no_lost_no_saturation=torch.logical_and(thermal_saturated_mask_no_saturation, source_lost_mask)
-    #Removing pixel affected by NaN
-    nan_mask=torch.logical_not(torch.logical_or(torch.logical_or(torch.isnan(s2_l1c_img[:,:,0]),torch.isnan(s2_l1c_img[:,:,1])),torch.isnan(s2_l1c_img[:,:,2])))
-    thermal_anomalies_clean_map=torch.logical_and(thermal_anomalies_no_lost_no_saturation, nan_mask)
+    thermal_saturated_mask = manage_saturated_thermal_anomalies(s2_l1c_img)
+    thermal_saturated_mask_no_saturation = torch.logical_and(
+        thermal_anomalies_map, thermal_saturated_mask
+    )
+    source_lost_mask = get_image_lost_source_mask(s2_l1c_img)
+    thermal_anomalies_no_lost_no_saturation = torch.logical_and(
+        thermal_saturated_mask_no_saturation, source_lost_mask
+    )
+    # Removing pixel affected by NaN
+    nan_mask = torch.logical_not(
+        torch.logical_or(
+            torch.logical_or(
+                torch.isnan(s2_l1c_img[:, :, 0]), torch.isnan(s2_l1c_img[:, :, 1])
+            ),
+            torch.isnan(s2_l1c_img[:, :, 2]),
+        )
+    )
+    thermal_anomalies_clean_map = torch.logical_and(
+        thermal_anomalies_no_lost_no_saturation, nan_mask
+    )
     return thermal_anomalies_clean_map
 
 
@@ -148,12 +192,27 @@ def extract_high_tempearature_anomalies(s2_l1c_img):
     Returns:
         torch.tensor: high-temperature anomalis map
     """
-    tai=get_TAI(s2_l1c_img)
-    tai_mean=get_TAI_mean(tai)
-    b=get_TAI_buffer(tai, tai_mean)
-    thr_1=torch.logical_and(torch.where(tai>= 0.45 * torch.ones_like(tai), torch.ones_like(tai), torch.zeros_like(tai)), b) #  Selecting pixels in the buffer meeting TAI >= 0.45
-    thr_2=torch.where(s2_l1c_img[:,:,2] > 2 * s2_l1c_img[:,:,1]  - s2_l1c_img[:,:,0], torch.ones_like(tai) ,torch.zeros_like(tai))  # Condition p_far_SWIR - p_near_SWIR > p_near_SWIR - p_NIR.
-    thr_3=torch.where(s2_l1c_img[:,:,2] > 0.15 * torch.ones_like(tai), torch.ones_like(tai), torch.zeros_like(tai)) #  Removing low reflectivity surfaces in FAR SWIR
-    thermal_anomaly_map=torch.logical_and(torch.logical_and(thr_1, thr_2), thr_3)
-    thermal_anomaly_clean_map=remove_false_positives(s2_l1c_img, thermal_anomaly_map)
-    return thermal_anomaly_clean_map, thermal_anomaly_map
\ No newline at end of file
+    tai = get_TAI(s2_l1c_img)
+    tai_mean = get_TAI_mean(tai)
+    b = get_TAI_buffer(tai, tai_mean)
+    thr_1 = torch.logical_and(
+        torch.where(
+            tai >= 0.45 * torch.ones_like(tai),
+            torch.ones_like(tai),
+            torch.zeros_like(tai),
+        ),
+        b,
+    )  # Selecting pixels in the buffer meeting TAI >= 0.45.
+    thr_2 = torch.where(
+        s2_l1c_img[:, :, 2] > 2 * s2_l1c_img[:, :, 1] - s2_l1c_img[:, :, 0],
+        torch.ones_like(tai),
+        torch.zeros_like(tai),
+    )  # Condition p_far_SWIR - p_near_SWIR > p_near_SWIR - p_NIR.
+    thr_3 = torch.where(
+        s2_l1c_img[:, :, 2] > 0.15 * torch.ones_like(tai),
+        torch.ones_like(tai),
+        torch.zeros_like(tai),
+    )  # Removing low reflectivity surfaces in FAR SWIR.
+    thermal_anomaly_map = torch.logical_and(torch.logical_and(thr_1, thr_2), thr_3)
+    thermal_anomaly_clean_map = remove_false_positives(s2_l1c_img, thermal_anomaly_map)
+    return thermal_anomaly_clean_map, thermal_anomaly_map
diff --git a/scripts_and_studies/hta_detection_algorithms/s2pix_detector.py b/scripts_and_studies/hta_detection_algorithms/s2pix_detector.py
index 4ca9195..fdf07fc 100644
--- a/scripts_and_studies/hta_detection_algorithms/s2pix_detector.py
+++ b/scripts_and_studies/hta_detection_algorithms/s2pix_detector.py
@@ -1,9 +1,17 @@
 import torch
 import numpy as np
 
-"[1] Massimetti, Francesco, et al. ""Volcanic hot-spot detection using SENTINEL-2: a comparison with MODIS–MIROVA thermal data series."" Remote Sensing 12.5 (2020): 820."
+# [1] Massimetti, Francesco, et al. "Volcanic hot-spot detection using SENTINEL-2:
+# a comparison with MODIS–MIROVA thermal data series." Remote Sensing 12.5 (2020): 820."
 
-def get_thresholds(sentinel_img, alpha_thr=[1.4, 1.2, 0.15], beta_thr=[2, 0.5, 0.5], S_thr=[1.2, 1, 1.5, 1], gamma_thr=[1,1,0.5]):
+
+def get_thresholds(
+    sentinel_img,
+    alpha_thr=[1.4, 1.2, 0.15],
+    beta_thr=[2, 0.5, 0.5],
+    S_thr=[1.2, 1, 1.5, 1],
+    gamma_thr=[1, 1, 0.5],
+):
     """It returns the alpha, beta, gamma and S threshold maps for each band as described in [1]
 
     Args:
@@ -19,34 +27,89 @@ def get_thresholds(sentinel_img, alpha_thr=[1.4, 1.2, 0.15], beta_thr=[2, 0.5, 0
         torch.tensor: S threshold map.
         torch.tensor: gamma threshold map.
     """
+
     def check_surrounded(img):
-        conv=torch.nn.Conv2d(1, 1, 3)
-        weight=torch.nn.Parameter(torch.tensor([[[[1.0,1.0,1.0], [1.0,0,1.0], [1.0,1.0,1.0]]]]),requires_grad=False)
-        img_pad=torch.nn.functional.pad(img, (1,1,1,1), mode='constant', value=1)
-        conv.load_state_dict({'weight': weight, 'bias' : torch.zeros([1])}, strict=False)
-        
-        if sentinel_img.device.type == 'cuda':
-            conv=conv.cuda()
+        conv = torch.nn.Conv2d(1, 1, 3)
+        weight = torch.nn.Parameter(
+            torch.tensor([[[[1.0, 1.0, 1.0], [1.0, 0, 1.0], [1.0, 1.0, 1.0]]]]),
+            requires_grad=False,
+        )
+        img_pad = torch.nn.functional.pad(img, (1, 1, 1, 1), mode="constant", value=1)
+        conv.load_state_dict({"weight": weight, "bias": torch.zeros([1])}, strict=False)
+
+        if sentinel_img.device.type == "cuda":
+            conv = conv.cuda()
 
         with torch.no_grad():
-            surrounded=conv(torch.tensor(img_pad, dtype=torch.float32, device=img_pad.device).unsqueeze(0).unsqueeze(0)).squeeze(0).squeeze(0)
-            surrounded[surrounded < 8] =0
-            surrounded[surrounded==8] =1
+            surrounded = (
+                conv(
+                    torch.tensor(img_pad, dtype=torch.float32, device=img_pad.device)
+                    .unsqueeze(0)
+                    .unsqueeze(0)
+                )
+                .squeeze(0)
+                .squeeze(0)
+            )
+            surrounded[surrounded < 8] = 0
+            surrounded[surrounded == 8] = 1
             del weight
-            del conv 
-            del img_pad 
+            del conv
+            del img_pad
             torch.cuda.empty_cache()
             return surrounded
+
     with torch.no_grad():
-        alpha=torch.logical_and(torch.where(sentinel_img[:,:,2] >=alpha_thr[2], 1, 0), torch.logical_and(torch.where(sentinel_img[:,:,2]/sentinel_img[:,:,1] >=alpha_thr[0], 1, 0), torch.where(sentinel_img[:,:,2]/sentinel_img[:,:,0] >=alpha_thr[1], 1, 0) ))
-        beta=torch.logical_and(torch.where(sentinel_img[:,:,1]/sentinel_img[:,:,0] >=beta_thr[0], 1, 0), torch.logical_and(torch.where(sentinel_img[:,:,1] >=beta_thr[1], 1, 0), torch.where(sentinel_img[:,:,2] >=beta_thr[2], 1, 0) ))
-        S=torch.logical_or(torch.logical_and(torch.where(sentinel_img[:,:,2] >=S_thr[0], 1, 0), torch.where(sentinel_img[:,:,0] <=S_thr[1], 1, 0) ),  torch.logical_and(torch.where(sentinel_img[:,:,1] >=S_thr[2], 1, 0), torch.where(sentinel_img[:,:,0] >=S_thr[3], 1, 0) ))
-        alpha_beta_logical_surrounded=check_surrounded(torch.logical_or(alpha, beta))
-        gamma=torch.logical_and(torch.logical_and(torch.logical_and(torch.where(sentinel_img[:,:,2] >=gamma_thr[0], 1, 0), torch.where(sentinel_img[:,:,2] >=gamma_thr[1], 1, 0)), torch.where(sentinel_img[:,:,0] >=gamma_thr[2], 1, 0)), alpha_beta_logical_surrounded)
+        alpha = torch.logical_and(
+            torch.where(sentinel_img[:, :, 2] >= alpha_thr[2], 1, 0),
+            torch.logical_and(
+                torch.where(
+                    sentinel_img[:, :, 2] / sentinel_img[:, :, 1] >= alpha_thr[0], 1, 0
+                ),
+                torch.where(
+                    sentinel_img[:, :, 2] / sentinel_img[:, :, 0] >= alpha_thr[1], 1, 0
+                ),
+            ),
+        )
+        beta = torch.logical_and(
+            torch.where(
+                sentinel_img[:, :, 1] / sentinel_img[:, :, 0] >= beta_thr[0], 1, 0
+            ),
+            torch.logical_and(
+                torch.where(sentinel_img[:, :, 1] >= beta_thr[1], 1, 0),
+                torch.where(sentinel_img[:, :, 2] >= beta_thr[2], 1, 0),
+            ),
+        )
+        S = torch.logical_or(
+            torch.logical_and(
+                torch.where(sentinel_img[:, :, 2] >= S_thr[0], 1, 0),
+                torch.where(sentinel_img[:, :, 0] <= S_thr[1], 1, 0),
+            ),
+            torch.logical_and(
+                torch.where(sentinel_img[:, :, 1] >= S_thr[2], 1, 0),
+                torch.where(sentinel_img[:, :, 0] >= S_thr[3], 1, 0),
+            ),
+        )
+        alpha_beta_logical_surrounded = check_surrounded(torch.logical_or(alpha, beta))
+        gamma = torch.logical_and(
+            torch.logical_and(
+                torch.logical_and(
+                    torch.where(sentinel_img[:, :, 2] >= gamma_thr[0], 1, 0),
+                    torch.where(sentinel_img[:, :, 2] >= gamma_thr[1], 1, 0),
+                ),
+                torch.where(sentinel_img[:, :, 0] >= gamma_thr[2], 1, 0),
+            ),
+            alpha_beta_logical_surrounded,
+        )
     return alpha, beta, S, gamma
 
 
-def get_alert_matrix_and_thresholds(sentinel_img, alpha_thr=[1.4, 1.2, 0.15], beta_thr=[2, 0.5, 0.5], S_thr=[1.2, 1, 1.5, 1], gamma_thr=[1,1,0.5]): 
+def get_alert_matrix_and_thresholds(
+    sentinel_img,
+    alpha_thr=[1.4, 1.2, 0.15],
+    beta_thr=[2, 0.5, 0.5],
+    S_thr=[1.2, 1, 1.5, 1],
+    gamma_thr=[1, 1, 0.5],
+):
     """It calculates the alert-matrix for a certain image.
 
     Args:
@@ -64,12 +127,17 @@ def get_alert_matrix_and_thresholds(sentinel_img, alpha_thr=[1.4, 1.2, 0.15], be
         torch.tensor: gamma threshold map.
     """
     with torch.no_grad():
-        alpha, beta, S, gamma=get_thresholds(sentinel_img, alpha_thr, beta_thr, S_thr, gamma_thr)
-        alert_matrix=torch.logical_or(torch.logical_or(torch.logical_or(alpha, beta), gamma), S)
+        alpha, beta, S, gamma = get_thresholds(
+            sentinel_img, alpha_thr, beta_thr, S_thr, gamma_thr
+        )
+        alert_matrix = torch.logical_or(
+            torch.logical_or(torch.logical_or(alpha, beta), gamma), S
+        )
     return alert_matrix, alpha, beta, S, gamma
 
+
 def cluster_9px(img):
-    """It performs the convolution to detect clusters of 9 activate pixels (current pixel and 8 surrounding pixels) are at 1. 
+    """It performs the convolution to detect clusters of 9 activate pixels (current pixel and 8 surrounding pixels) are at 1.
 
     Args:
         img (torch.tensor): input alert-matrix
@@ -77,15 +145,22 @@ def cluster_9px(img):
     Returns:
         torch.tensor: convoluted alert-map
     """
-    
-    conv=torch.nn.Conv2d(1, 1, 3)
-    weight=torch.nn.Parameter(torch.tensor([[[[1.0,1.0,1.0], [1.0,1.0,1.0], [1.0,1.0,1.0]]]]),requires_grad=False)
-    img_pad=torch.nn.functional.pad(img, (1,1,1,1), mode='constant', value=1)
-    if img.device.type=='cuda':
-        conv=conv.cuda()
-    conv.load_state_dict({'weight': weight, 'bias' : torch.zeros([1])}, strict=False)
+
+    conv = torch.nn.Conv2d(1, 1, 3)
+    weight = torch.nn.Parameter(
+        torch.tensor([[[[1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]]]),
+        requires_grad=False,
+    )
+    img_pad = torch.nn.functional.pad(img, (1, 1, 1, 1), mode="constant", value=1)
+    if img.device.type == "cuda":
+        conv = conv.cuda()
+    conv.load_state_dict({"weight": weight, "bias": torch.zeros([1])}, strict=False)
     with torch.no_grad():
-        surrounded=conv(torch.tensor(img_pad, dtype=torch.float32).unsqueeze(0).unsqueeze(0)).squeeze(0).squeeze(0)
+        surrounded = (
+            conv(torch.tensor(img_pad, dtype=torch.float32).unsqueeze(0).unsqueeze(0))
+            .squeeze(0)
+            .squeeze(0)
+        )
         del weight
         del conv
         del img_pad
@@ -93,7 +168,13 @@ def cluster_9px(img):
     return surrounded
 
 
-def s2pix_detector(sentinel_img, alpha_thr=[1.4, 1.2, 0.15], beta_thr=[2, 0.5, 0.5], S_thr=[1.2, 1, 1.5, 1], gamma_thr=[1,1,0.5]): 
+def s2pix_detector(
+    sentinel_img,
+    alpha_thr=[1.4, 1.2, 0.15],
+    beta_thr=[2, 0.5, 0.5],
+    S_thr=[1.2, 1, 1.5, 1],
+    gamma_thr=[1, 1, 0.5],
+):
     """Implements first step of the one described in [1] by proving a filtered alert-map.
 
     Args:
@@ -109,18 +190,30 @@ def s2pix_detector(sentinel_img, alpha_thr=[1.4, 1.2, 0.15], beta_thr=[2, 0.5, 0
         torch.tensor: alert_matrix threshold map.
     """
     with torch.no_grad():
-        alert_matrix, _, _, _, _=get_alert_matrix_and_thresholds(sentinel_img, alpha_thr, beta_thr, S_thr, gamma_thr)
-        filtered_alert_matrix=cluster_9px(alert_matrix)
-        filtered_alert_matrix[filtered_alert_matrix <9]=0
-        filtered_alert_matrix[filtered_alert_matrix ==9]=1
-        return torch.tensor(float(torch.any(filtered_alert_matrix != 0)), device=filtered_alert_matrix.device), filtered_alert_matrix, alert_matrix
-    
+        alert_matrix, _, _, _, _ = get_alert_matrix_and_thresholds(
+            sentinel_img, alpha_thr, beta_thr, S_thr, gamma_thr
+        )
+        filtered_alert_matrix = cluster_9px(alert_matrix)
+        filtered_alert_matrix[filtered_alert_matrix < 9] = 0
+        filtered_alert_matrix[filtered_alert_matrix == 9] = 1
+        return (
+            torch.tensor(
+                float(torch.any(filtered_alert_matrix != 0)),
+                device=filtered_alert_matrix.device,
+            ),
+            filtered_alert_matrix,
+            alert_matrix,
+        )
+
 
-def filter_bbox_list(alert_matrix, props, event_bbox_coordinates_list=None, num_pixels_threshold=9):
-    """Filters bounding box lists found in an alert matrix by takking only the bounding boxes having at least ""num_pixels_threshold"" active pixels.
+def filter_bbox_list(
+    alert_matrix, props, event_bbox_coordinates_list=None, num_pixels_threshold=9
+):
+    """Filters bounding box lists found in an alert matrix by takking only the bounding boxes having at least
+      ""num_pixels_threshold"" active pixels.
 
     Args:
-        alert_matrix (torc.tensor): alert matrix
+        alert_matrix (torch.tensor): alert matrix
         props (list): bounding box list.
         event_bbox_coordinates_list (list, optional): bounding box coordinates. Defaults to None.
         num_pixels_threshold (int,9): number of active pixels in a bounding box. Defaults to 9.
@@ -129,23 +222,36 @@ def filter_bbox_list(alert_matrix, props, event_bbox_coordinates_list=None, num_
         list: filtered bounding box list.
         list: filtered coordinates list.
     """
-    bbox_filtered_list=[]
-    event_bbox_coordinates_filtered_list=[]
+    bbox_filtered_list = []
+    event_bbox_coordinates_filtered_list = []
     if event_bbox_coordinates_list is not None:
-        for (prop, coords) in zip(props,event_bbox_coordinates_list):
-            bbox=prop.bbox
-            bbox_rounded=[int(np.round(x)) for x in bbox]
-            if torch.sum(alert_matrix[bbox_rounded[0]:bbox_rounded[2]+1, bbox_rounded[1]: bbox_rounded[3]+1]) >= num_pixels_threshold:
-                
+        for prop, coords in zip(props, event_bbox_coordinates_list):
+            bbox = prop.bbox
+            bbox_rounded = [int(np.round(x)) for x in bbox]
+            if (
+                torch.sum(
+                    alert_matrix[
+                        bbox_rounded[0] : bbox_rounded[2] + 1,
+                        bbox_rounded[1] : bbox_rounded[3] + 1,
+                    ]
+                )
+                >= num_pixels_threshold
+            ):
                 bbox_filtered_list.append(prop)
                 event_bbox_coordinates_filtered_list.append(coords)
     else:
-
         for prop in props:
-            bbox=prop.bbox
-            bbox_rounded=[int(np.round(x)) for x in bbox]
-            if torch.sum(alert_matrix[bbox_rounded[0]:bbox_rounded[2]+1, bbox_rounded[1]: bbox_rounded[3]+1]) >= num_pixels_threshold:
+            bbox = prop.bbox
+            bbox_rounded = [int(np.round(x)) for x in bbox]
+            if (
+                torch.sum(
+                    alert_matrix[
+                        bbox_rounded[0] : bbox_rounded[2] + 1,
+                        bbox_rounded[1] : bbox_rounded[3] + 1,
+                    ]
+                )
+                >= num_pixels_threshold
+            ):
                 bbox_filtered_list.append(prop)
-        
-           
-    return bbox_filtered_list, event_bbox_coordinates_filtered_list
\ No newline at end of file
+
+    return bbox_filtered_list, event_bbox_coordinates_filtered_list
diff --git a/scripts_and_studies/l1c_reconstruction/l1c_reconstruction.ipynb b/scripts_and_studies/l1c_reconstruction/l1c_reconstruction.ipynb
index c1ef681..1e8e7a6 100644
--- a/scripts_and_studies/l1c_reconstruction/l1c_reconstruction.ipynb
+++ b/scripts_and_studies/l1c_reconstruction/l1c_reconstruction.ipynb
@@ -8,11 +8,17 @@
    "source": [
     "import sys\n",
     "import os\n",
-    "sys.path.insert(1, os.path.join(\"..\",\"..\"))\n",
+    "\n",
+    "sys.path.insert(1, os.path.join(\"..\", \"..\"))\n",
     "from pyraws.l0.l0_event import L0_event\n",
-    "from pyraws.utils.l1_utils import read_L1C_image_from_tif, get_event_bounding_box, get_l1C_image_default_path\n",
+    "from pyraws.utils.l1_utils import (\n",
+    "    read_L1C_image_from_tif,\n",
+    "    get_event_bounding_box,\n",
+    "    get_l1C_image_default_path,\n",
+    ")\n",
     "import matplotlib.pyplot as plt\n",
     "from l1c_reconstruction_utils import rotate_l1c_tif\n",
+    "\n",
     "%load_ext autoreload\n",
     "%autoreload 2"
    ]
@@ -23,11 +29,13 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "downsampling=True\n",
-    "l1c_tif, coords_dict, expected_class=read_L1C_image_from_tif(\"Etna_00\", \"2\")\n",
-    "l0_event=L0_event()\n",
-    "l0_event.from_database(\"Etna_00\", [\"B8A\",\"B11\",\"B12\"],verbose=False)\n",
-    "l0_granule=l0_event.coarse_coregistration([2], crop_empty_pixels=True, use_complementary_granules=True )"
+    "downsampling = True\n",
+    "l1c_tif, coords_dict, expected_class = read_L1C_image_from_tif(\"Etna_00\", \"2\")\n",
+    "l0_event = L0_event()\n",
+    "l0_event.from_database(\"Etna_00\", [\"B8A\", \"B11\", \"B12\"], verbose=False)\n",
+    "l0_granule = l0_event.coarse_coregistration(\n",
+    "    [2], crop_empty_pixels=True, use_complementary_granules=True\n",
+    ")"
    ]
   },
   {
@@ -36,12 +44,12 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "fig,ax=plt.subplots(1,3,figsize=(10,10))\n",
+    "fig, ax = plt.subplots(1, 3, figsize=(10, 10))\n",
     "\n",
     "ax[0].imshow(l1c_tif)\n",
     "l0_granule.show_bands_superimposition(ax=ax[1])\n",
-    "l1c_rotated=rotate_l1c_tif(l1c_tif)\n",
-    "ax[2].imshow(l1c_rotated)\n"
+    "l1c_rotated = rotate_l1c_tif(l1c_tif)\n",
+    "ax[2].imshow(l1c_rotated)"
    ]
   },
   {
diff --git a/scripts_and_studies/l1c_reconstruction/l1c_reconstruction_utils.py b/scripts_and_studies/l1c_reconstruction/l1c_reconstruction_utils.py
index 2650ebc..86b9bd0 100644
--- a/scripts_and_studies/l1c_reconstruction/l1c_reconstruction_utils.py
+++ b/scripts_and_studies/l1c_reconstruction/l1c_reconstruction_utils.py
@@ -4,6 +4,7 @@
 from glob import glob
 import os
 
+
 def get_intersection_points(l1c_tif):
     """Gets interesection of l1c tif image with image border.
 
@@ -14,38 +15,42 @@ def get_intersection_points(l1c_tif):
         list: list of interesection points
     """
 
-    for k in  range(l1c_tif.shape[1]):
-        y=l1c_tif[:,k,0]
-        dy=torch.where(y != 0)[0]
+    for k in range(l1c_tif.shape[1]):
+        y = l1c_tif[:, k, 0]
+        dy = torch.where(y != 0)[0]
         if len(dy) != 0:
-            dy=dy[0]
+            dy = dy[0]
             break
 
     for m in range(l1c_tif.shape[0]):
-        x=l1c_tif[m,:,0]
-        dx=torch.where(x != 0)[0]
+        x = l1c_tif[m, :, 0]
+        dx = torch.where(x != 0)[0]
         if len(dx) != 0:
-            dx=dx[0]
+            dx = dx[0]
             break
 
-    for l in  range(l1c_tif.shape[1] -1,0,-1):
-    
-        y_end=l1c_tif[:,l,0]
-        dy_end=torch.where(y_end != 0)[-1]
-        
+    for s in range(l1c_tif.shape[1] - 1, 0, -1):
+        y_end = l1c_tif[:, s, 0]
+        dy_end = torch.where(y_end != 0)[-1]
+
         if len(dy_end) != 0:
-            dy_end=dy_end[-1]
+            dy_end = dy_end[-1]
             break
 
-
-    for q in  range(l1c_tif.shape[0] -1,0,-1):
-        x_end=l1c_tif[q,:,0]
-        dx_end=torch.where(x_end != 0)[0]
+    for q in range(l1c_tif.shape[0] - 1, 0, -1):
+        x_end = l1c_tif[q, :, 0]
+        dx_end = torch.where(x_end != 0)[0]
         if len(dx_end) != 0:
-            dx_end=dx_end[0]
+            dx_end = dx_end[0]
             break
 
-    return [torch.tensor([dy, k], device=l1c_tif.device), torch.tensor([m,dx], device=l1c_tif.device), torch.tensor([dy_end, l], device=l1c_tif.device),torch.tensor([q, dx_end], device=l1c_tif.device)]
+    return [
+        torch.tensor([dy, k], device=l1c_tif.device),
+        torch.tensor([m, dx], device=l1c_tif.device),
+        torch.tensor([dy_end, s], device=l1c_tif.device),
+        torch.tensor([q, dx_end], device=l1c_tif.device),
+    ]
+
 
 def rotate_l1c_tif(l1c_tif):
     """Rotate l1c_tif
@@ -57,19 +62,25 @@ def rotate_l1c_tif(l1c_tif):
         torch.tensor: rotated matrix
     """
 
-    l1c_numpy=l1c_tif.detach().numpy()
-    l1c_numpy=np.round(l1c_numpy/l1c_numpy.max() * 255).astype(np.uint8)
-    a,b,_,d=get_intersection_points(l1c_tif)
-    angle_1 = float(torch.atan2(d[0]-a[0], d[1]-a[1])*180/np.pi )
+    l1c_numpy = l1c_tif.detach().numpy()
+    l1c_numpy = np.round(l1c_numpy / l1c_numpy.max() * 255).astype(np.uint8)
+    a, b, _, d = get_intersection_points(l1c_tif)
+    angle_1 = float(torch.atan2(d[0] - a[0], d[1] - a[1]) * 180 / np.pi)
 
     M = cv2.getRotationMatrix2D((int(d[1]), int(d[0])), angle_1, 1.0)
-    rotated = cv2.warpAffine(l1c_tif.detach().numpy(), M, (int(d[1]), int(d[0])),
-        flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
-    
-    rotated_torch=torch.from_numpy(rotated).to(l1c_tif.device)
-    non_zero_last=rotated_torch[:,-1,0].nonzero()[0]
+    rotated = cv2.warpAffine(
+        l1c_tif.detach().numpy(),
+        M,
+        (int(d[1]), int(d[0])),
+        flags=cv2.INTER_CUBIC,
+        borderMode=cv2.BORDER_REPLICATE,
+    )
+
+    rotated_torch = torch.from_numpy(rotated).to(l1c_tif.device)
+    non_zero_last = rotated_torch[:, -1, 0].nonzero()[0]
+
+    return rotated_torch[non_zero_last:, :, :]
 
-    return rotated_torch[non_zero_last:,:,:]
 
 def get_l1c_file_names(path):
     """Get l1c tif file list in path.
@@ -80,13 +91,14 @@ def get_l1c_file_names(path):
     Returns:
         list: list of l1c files.
     """
-    l1c_tif_files=glob(os.path.join(path,"*"))
-    l1c_tif_files_clean=[]
+    l1c_tif_files = glob(os.path.join(path, "*"))
+    l1c_tif_files_clean = []
     for x in l1c_tif_files:
         if ".tif" in x:
             l1c_tif_files_clean.append(x)
     return l1c_tif_files_clean
 
+
 def get_event_granules_dict(l1c_tif_files):
     """Get events tif list in path.
 
@@ -96,19 +108,21 @@ def get_event_granules_dict(l1c_tif_files):
     Returns:
         dict: event : granules dictionary..
     """
-    events_granule_list=[x.split(os.path.sep)[-1].split(".tif")[0] for x in l1c_tif_files]
+    events_granule_list = [
+        x.split(os.path.sep)[-1].split(".tif")[0] for x in l1c_tif_files
+    ]
 
-    events_list=[]
-    granule_per_event_list=[]
+    events_list = []
+    granule_per_event_list = []
     for elem in events_granule_list:
-        event_elems=elem.split("_")
-        event=event_elems[0]+"_"+event_elems[1]
-        granule=event_elems[2]
+        event_elems = elem.split("_")
+        event = event_elems[0] + "_" + event_elems[1]
+        granule = event_elems[2]
         if event in events_list:
-            granule_per_event_list[events_list.index(event)]+=[granule]
+            granule_per_event_list[events_list.index(event)] += [granule]
         else:
             events_list.append(event)
             granule_per_event_list.append([granule])
 
-    event_granules_dict=dict(zip(events_list,granule_per_event_list ))
-    return event_granules_dict
\ No newline at end of file
+    event_granules_dict = dict(zip(events_list, granule_per_event_list))
+    return event_granules_dict
diff --git a/scripts_and_studies/patch_study/patchify.py b/scripts_and_studies/patch_study/patchify.py
index 57e87f6..e4b53fd 100644
--- a/scripts_and_studies/patch_study/patchify.py
+++ b/scripts_and_studies/patch_study/patchify.py
@@ -1,4 +1,3 @@
-import csv
 import sys
 import os
 
@@ -7,36 +6,9 @@
     1, os.path.join("..", "..", "scripts_and_studies", "hta_detection_algorithms")
 )
 from pyraws.raw.raw_event import Raw_event
-from pyraws.l1.l1_event import L1C_event
-from pyraws.l1.l1_tile import L1C_tile
-from pyraws.utils.raw_utils import get_bands_shift
-from pyraws.utils.l1_utils import read_L1C_image_from_tif
-from pyraws.utils.database_utils import get_cfg_file_dict
-from pyraws.utils.parse_csv_utils import parse_csv
-from pyraws.utils.visualization_utils import plot_img1_vs_img2_bands
-from s2pix_detector import s2pix_detector
-from functools import partial
-from geopy.distance import geodesic as GD
-from geopy.geocoders import Nominatim
-from geopy.point import Point
-import geopandas
-from geopandas import GeoSeries
-import matplotlib.pyplot as plt
-from matplotlib import patches
-import numpy as np
 from shapely.geometry import Polygon
-from termcolor import colored
 import torch
-from tqdm import tqdm
 import matplotlib.pyplot as plt
-from pathlib import Path
-from tqdm import tqdm
-import numpy as np
-from copy import deepcopy
-import pandas as pd
-from ast import literal_eval
-from IPython.display import clear_output
-import time
 
 # CONFIG_
 os.environ["KMP_DUPLICATE_LIB_OK"] = "True"
@@ -49,7 +21,6 @@
 
 
 def mulitBox(bbox_list):
-
     if any(isinstance(i, list) for i in bbox_list):
         return True
 
@@ -65,7 +36,8 @@ def sliding_window(image, window_size, overlap):
          - overlap (float): The degree of overlap between two consecutive window movements.
 
     Returns:
-         - sub_images (dict): A dictionary with the top-left and bottom-right corner positions (x1, y1, x2, y2) as keys and the sub-images as values.
+         - sub_images (dict): A dictionary with the top-left and bottom-right corner positions (x1, y1, x2, y2)
+                              as keys and the sub-images as values.
     """
     # Get the dimensions of the input image
     h, w = image.shape[:2]
diff --git a/scripts_and_studies/runscripts/create_quicklook.py b/scripts_and_studies/runscripts/create_quicklook.py
index bc48c8e..f0d60fb 100644
--- a/scripts_and_studies/runscripts/create_quicklook.py
+++ b/scripts_and_studies/runscripts/create_quicklook.py
@@ -6,7 +6,6 @@
 from pyraws.raw.raw_event import Raw_event
 from pyraws.l1.l1_event import L1C_event
 from pyraws.utils.l1_utils import (
-    read_L1C_image_from_tif,
     read_L1C_image_from_tif,
     get_event_bounding_box,
     get_l1C_image_default_path,
@@ -79,9 +78,9 @@ def main():
             print("Parsing L0 event: " + colored(event, "green"))
             raw_event = Raw_event(device=device)
             raw_event.from_database(event, bands_list, verbose=False, database=database)
-        except:
+        except:  # noqa: E722
             raise ValueError(
-                "Impossible to open L0 data for: "
+                "Impossible to open Raw data for: "
                 + colored(event, "red")
                 + ". Check it is included in the database: "
                 + colored(event, "red")
@@ -89,11 +88,11 @@ def main():
             )
 
         if raw_event.is_void():
-            raise ValueError("L0 data for " + colored(event, "red") + " is void.")
+            raise ValueError("Raw data for " + colored(event, "red") + " is void.")
 
         try:
             raw_granule = raw_event.get_granule(granule)
-        except:
+        except:  # noqa: E722
             raise ValueError(
                 "Impossible to get the granule:"
                 + colored(str(granule), "red")
@@ -108,21 +107,6 @@ def main():
         band_shifted_dict = raw_granule.get_bands_coordinates()
         raw_granule_coordinates = band_shifted_dict[bands_list[0]]
 
-    if event + "_" + ending + ".tif" in glob(os.path.join(".", "*")):
-        print(
-            "Skipping creation of L1C crop for the granule: "
-            + colored(granule, "green")
-        )
-    else:
-        print("Creating L1C crop for the granule: " + colored(granule, "cyan"))
-        _ = l1c_event.crop_tile(
-            raw_granule_coordinates,
-            None,
-            verbose=False,
-            out_name_ending=ending,
-            lat_lon_format=True,
-        )
-
         registered_granule_name = raw_granule_registered.get_granule_info()[0]
         if "_COMPLEMENTED_WITH" in registered_granule_name:
             granules_names = registered_granule_name.split("_COMPLEMENTED_WITH")
@@ -143,7 +127,7 @@ def main():
 
             try:
                 complementary_granule_names_list.remove("")  # Removing empty names
-            except:
+            except:  # noqa: E722
                 pass
 
             # Removing ending character
@@ -183,7 +167,7 @@ def main():
                 l1c_event.from_database(
                     event, bands_list, verbose=False, database=database
                 )
-            except:
+            except:  # noqa: E722
                 raise ValueError(
                     "Impossible to open L1 data for: "
                     + colored(event, "red")
@@ -261,7 +245,7 @@ def main():
 
             else:
                 print(colored("Warning:", "red") + " no bounding box found.")
-        except:
+        except:  # noqa: E722
             print(
                 "Errors in processing the L1C granule. Skipping event: ",
                 colored(event, "red"),
@@ -273,5 +257,4 @@ def main():
 
 
 if __name__ == "__main__":
-    # python .\create_quicklook.py --events_list "[Etna_00,Piton_de_la_Fournaise_31, Australia_1]" --bands "[B8A,B11,B12]" --granules_number_list "[2,0,1]"
     main()
diff --git a/scripts_and_studies/runscripts/create_tif.py b/scripts_and_studies/runscripts/create_tif.py
index 57cb15b..42a9c78 100644
--- a/scripts_and_studies/runscripts/create_tif.py
+++ b/scripts_and_studies/runscripts/create_tif.py
@@ -2,7 +2,6 @@
 from pyraws.l0.l0_event import L0_event
 from pyraws.utils.database_utils import get_events_list
 
-from glob import glob
 import argparse
 import torch
 from termcolor import colored
@@ -46,7 +45,7 @@ def main():
         try:
             l0_event = L0_event(device=device)
             l0_event.from_database(event, bands, verbose=False)
-        except:
+        except:  # noqa: E722
             print("Skipping event: ", colored(event, "red") + ".")
 
         if l0_event.is_void():
diff --git a/scripts_and_studies/runscripts/crop_L1_tiles.py b/scripts_and_studies/runscripts/crop_L1_tiles.py
index 4b13d2e..b6451f8 100644
--- a/scripts_and_studies/runscripts/crop_L1_tiles.py
+++ b/scripts_and_studies/runscripts/crop_L1_tiles.py
@@ -52,7 +52,7 @@ def main():
         events_list[1:], desc="Processing events... "
     ):  # Skipping first event, being ":"
         print("Processing event: " + colored(event, "blue"))
-        ####Create quicklook###################
+        # -------------Create quicklook-------------
         plt.close()
         try:
             raw_event = Raw_event(device=device)
@@ -61,7 +61,7 @@ def main():
             )
             l1c_event = L1C_event(device=device)
             l1c_event.from_database(event, requested_bands, database=pargs.database)
-        except:
+        except:  # noqa: E722
             print("Skipping event: ", colored(event, "red"))
             continue
 
@@ -97,7 +97,7 @@ def main():
             )
             band_shifted_dict = raw_granule.get_bands_coordinates()
             raw_granule_coordinates = band_shifted_dict[requested_bands[0]]
-            output_cropped_tile_path = l1c_event.crop_tile(
+            _ = l1c_event.crop_tile(
                 raw_granule_coordinates,
                 output_tif_dir,
                 out_name_ending=str(useful_granule[0]) + "_" + str(useful_granule[1]),
diff --git a/setup.py b/setup.py
index 9688224..6227c85 100644
--- a/setup.py
+++ b/setup.py
@@ -5,25 +5,23 @@
 """
 
 # Always prefer setuptools over distutils
-from setuptools import setup, find_packages
+from setuptools import setup
 
 setup(
     name="pyraws",
     version="1.0.0",
-    description="Python for RAW Sentinel2 data (PyRawS) is a powerful open-source Python package that provides a comprehensive set of tools for working with Sentinel-2 Raw data. It provides utilities for coarse spatial bands coregistration, geo-referencing, data visualization, and image processing.",
+    description="Python for RAW Sentinel2 data (PyRawS) is a powerful open-source Python package"
+    + " that provides a comprehensive set of tools for working with Sentinel-2 Raw data. It provides utilities for"
+    + " coarse spatial bands coregistration, geo-referencing, data visualization, and image processing.",
     long_description=open("README.md", encoding="cp437").read(),
     long_description_content_type="text/markdown",
-    url="https://gitlab.esa.int/Alix.DeBeusscher/pyraws",
+    url="https://github.com/ESA-PhiLab/PyRawS",
     author="ESA Philab",
     author_email="gabriele.meoni@esa.int",
     install_requires=[
-        "earthengine-api",
         "geopy",
-        "folium",
         "geopandas",
         "glymur",
-        "ipywidgets",
-        "jupyter",
         "numpy",
         "opencv-python",
         "pandas",
@@ -37,7 +35,6 @@
         "scikit-learn",
         "rasterio",
         "tifffile",
-        "earthengine-api",
     ],
     classifiers=[
         "Development Status :: 3 - Alpha",
@@ -56,6 +53,6 @@
     ],
     python_requires=">=3.8, <4",
     project_urls={
-        "Source": "https://gitlab.esa.int/Alix.DeBeusscher/pyraws",
+        "Source": "https://github.com/ESA-PhiLab/PyRawS",
     },
 )


Test patch:
diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml
new file mode 100644
index 0000000..9595d37
--- /dev/null
+++ b/.github/workflows/run_tests.yml
@@ -0,0 +1,39 @@
+# This workflow will install Python dependencies, run tests and lint with a single version of Python
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+name: Running tests
+
+on:
+  push:
+    branches:
+      - main
+  pull_request:
+  workflow_dispatch:
+jobs:
+  lint_flake8:
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python 3.9
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.9
+      - name: Lint with flake8
+        run: |
+          pip install flake8
+          flake8 . --count --show-source --statistics --max-line-length=127 --ignore=E402,W503,E203
+
+  build:
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python 3.9
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.9
+      - name: Search for severe code errors with flake8
+        run: |
+          # stop the build if there are Python syntax errors or undefined names
+          pip install flake8
+          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --max-line-length=127