From 45c4b6d33387f281f2b33acf33f1e61d71372a66 Mon Sep 17 00:00:00 2001
From: jakimowb <benjamin.jakimow@geo.hu-berlin.de>
Date: Thu, 9 Apr 2020 18:00:55 +0200
Subject: [PATCH] refactoring

---
 eotimeseriesviewer/__init__.py             |   2 +-
 eotimeseriesviewer/dateparser.py           |   8 +-
 eotimeseriesviewer/labeling.py             |  60 +++++-----
 eotimeseriesviewer/main.py                 |  38 +++----
 eotimeseriesviewer/mapcanvas.py            |  38 +++----
 eotimeseriesviewer/mapviewscrollarea.py    |   2 +-
 eotimeseriesviewer/mapvisualization.py     | 126 ++++++++++-----------
 eotimeseriesviewer/profilevisualization.py |  14 +--
 eotimeseriesviewer/sensorvisualization.py  |   4 +-
 eotimeseriesviewer/settings.py             |  20 ++--
 eotimeseriesviewer/stackedbandinput.py     |   6 +-
 eotimeseriesviewer/temporalprofiles.py     |  10 +-
 eotimeseriesviewer/tests.py                |   4 +-
 eotimeseriesviewer/timeseries.py           | 122 ++++++++++----------
 14 files changed, 226 insertions(+), 228 deletions(-)

diff --git a/eotimeseriesviewer/__init__.py b/eotimeseriesviewer/__init__.py
index 249ec180..3d24ecc5 100644
--- a/eotimeseriesviewer/__init__.py
+++ b/eotimeseriesviewer/__init__.py
@@ -106,7 +106,7 @@ def initAll():
     initResources()
     initEditorWidgets()
 
-def icon()->QIcon:
+def icon() -> QIcon:
     """
     Returns the EO Time Series Viewer icon
     :return: QIcon
diff --git a/eotimeseriesviewer/dateparser.py b/eotimeseriesviewer/dateparser.py
index fca6c2ae..62a0c869 100644
--- a/eotimeseriesviewer/dateparser.py
+++ b/eotimeseriesviewer/dateparser.py
@@ -31,7 +31,7 @@ def matchOrNone(regex, text):
     else:
         return None
 
-def dateDOY(date:datetime.date)->int:
+def dateDOY(date:datetime.date) -> int:
     """
     Returns the DOY
     :param date:
@@ -43,7 +43,7 @@ def dateDOY(date:datetime.date)->int:
         date = date.astype(datetime.date)
     return date.timetuple().tm_yday
 
-def daysPerYear(year)->int:
+def daysPerYear(year) -> int:
     """Returns the days per year"""
     if isinstance(year, np.datetime64):
         year = year.astype(datetime.date)
@@ -85,7 +85,7 @@ def num2date(n, dt64=True, qDate=False):
         return date
 
 
-def extractDateTimeGroup(text:str)->np.datetime64:
+def extractDateTimeGroup(text:str) -> np.datetime64:
     """
     Extracts a date-time-group from a text string
     :param text: a string
@@ -282,7 +282,7 @@ class ImageDateParserLandsat(ImageDateReader):
 dateParserList = [c for c in ImageDateReader.__subclasses__()]
 dateParserList.insert(0, dateParserList.pop(dateParserList.index(ImageDateReaderDefault))) # set to first position
 
-def parseDateFromDataSet(dataSet:gdal.Dataset)->np.datetime64:
+def parseDateFromDataSet(dataSet:gdal.Dataset) -> np.datetime64:
     assert isinstance(dataSet, gdal.Dataset)
     for parser in dateParserList:
         dtg = parser(dataSet).readDTG()
diff --git a/eotimeseriesviewer/labeling.py b/eotimeseriesviewer/labeling.py
index e748933a..6d0f3442 100644
--- a/eotimeseriesviewer/labeling.py
+++ b/eotimeseriesviewer/labeling.py
@@ -64,7 +64,7 @@ def shortcuts(field:QgsField):
     return result
 
 
-def layerClassSchemes(layer:QgsVectorLayer)->list:
+def layerClassSchemes(layer:QgsVectorLayer) -> list:
     """
     Returns a list of (ClassificationScheme, QgsField) for all QgsFields with QgsEditorWidget being QgsClassificationWidgetWrapper or RasterClassification.
     :param layer: QgsVectorLayer
@@ -117,7 +117,7 @@ def labelShortcutLayerClassificationSchemes(layer:QgsVectorLayer):
 
     return classSchemes
 
-def quickLabelLayers()->typing.List[QgsVectorLayer]:
+def quickLabelLayers() -> typing.List[QgsVectorLayer]:
     """
     Returns a list of known QgsVectorLayers with at least one LabelShortcutEditWidget
     :return: [list-of-QgsVectorLayer]
@@ -259,7 +259,7 @@ class LabelAttributeTableModel(QAbstractTableModel):
 
         self.resetModel()
 
-    def hasVectorLayer(self)->bool:
+    def hasVectorLayer(self) -> bool:
         """
         Returns true if a QgsVectorLayer is specified.
         :return: bool
@@ -279,14 +279,14 @@ class LabelAttributeTableModel(QAbstractTableModel):
 
         self.endResetModel()
 
-    def rowCount(self, parent = QModelIndex())->int:
+    def rowCount(self, parent = QModelIndex()) -> int:
         if isinstance(self.mVectorLayer, QgsVectorLayer):
             return self.mVectorLayer.fields().count()
         else:
             return 0
 
 
-    def fieldName2Index(self, fieldName:str)->str:
+    def fieldName2Index(self, fieldName:str) -> str:
         assert isinstance(fieldName, str)
 
         if isinstance(self.mVectorLayer, QgsVectorLayer):
@@ -298,7 +298,7 @@ class LabelAttributeTableModel(QAbstractTableModel):
             return QModelIndex()
 
 
-    def field2index(self, field:QgsField)->QModelIndex:
+    def field2index(self, field:QgsField) -> QModelIndex:
         assert isinstance(field, QgsField)
         return self.fieldName2Index(field.name())
 
@@ -310,7 +310,7 @@ class LabelAttributeTableModel(QAbstractTableModel):
             return None
 
 
-    def index2field(self, index:QModelIndex)->QgsField:
+    def index2field(self, index:QModelIndex) -> QgsField:
         if index.isValid() and isinstance(self.mVectorLayer, QgsVectorLayer):
             fields = self.mVectorLayer.fields()
             assert isinstance(fields, QgsFields)
@@ -318,7 +318,7 @@ class LabelAttributeTableModel(QAbstractTableModel):
         else:
             return None
 
-    def columnCount(self, parent = QModelIndex())->int:
+    def columnCount(self, parent = QModelIndex()) -> int:
         return len(self.mColumnNames)
 
 
@@ -410,7 +410,7 @@ class LabelAttributeTableModel(QAbstractTableModel):
             self.dataChanged.emit(index, index, [role])
         return changed
 
-    def columnName(self, index: int)->str:
+    def columnName(self, index: int) -> str:
         if isinstance(index, QModelIndex):
             if not index.isValid():
                 return None
@@ -449,7 +449,7 @@ class LabelAttributeTypeWidgetDelegate(QStyledItemDelegate):
         self.mLabelAttributeTableModel = labelAttributeTableModel
         self.setItemDelegates(tableView)
 
-    def model(self)->LabelAttributeTableModel:
+    def model(self) -> LabelAttributeTableModel:
         return self.mTableView.model()
 
     def setItemDelegates(self, tableView):
@@ -459,7 +459,7 @@ class LabelAttributeTypeWidgetDelegate(QStyledItemDelegate):
             i = model.mColumnNames.index(c)
             tableView.setItemDelegateForColumn(i, self)
 
-    def columnName(self, index:QModelIndex)->str:
+    def columnName(self, index:QModelIndex) -> str:
         if not index.isValid():
             return None
         return self.model().mColumnNames[index.column()]
@@ -555,7 +555,7 @@ class LabelingWidget(QMainWindow):
         self.initActions()
         self.onVectorLayerChanged()
 
-    def canvas(self)->QgsMapCanvas:
+    def canvas(self) -> QgsMapCanvas:
         """
         Returns the internal map canvas
         :return: QgsMapCanvas
@@ -597,7 +597,7 @@ class LabelingWidget(QMainWindow):
                     lyr.setEditFormConfig(config.index(), config.editorWidgetSetup())
         self.onVectorLayerChanged()
 
-    def isModified(self)->bool:
+    def isModified(self) -> bool:
         return isinstance(self.currentVectorSource(), QgsVectorLayer) and self.currentVectorSource().isModified()
 
     def onVectorLayerChanged(self):
@@ -685,13 +685,13 @@ class LabelingWidget(QMainWindow):
                 action.setEnabled(False)
 
 
-    def actionAddFeature(self)->QAction:
+    def actionAddFeature(self) -> QAction:
         return self.mActionAddFeature
 
-    def actionSaveEdits(self)->QAction:
+    def actionSaveEdits(self) -> QAction:
         return self.mActionSaveEdits
 
-    def actionToggleEditing(self)->QAction:
+    def actionToggleEditing(self) -> QAction:
         return self.mActionToggleEditing
 
     def onToggleEditing(self, b: bool):
@@ -874,7 +874,7 @@ class LabelingWidget(QMainWindow):
         if layer in cboxLayers:
             self.mVectorLayerComboBox.setCurrentIndex(cboxLayers.index(layer))
 
-    def currentVectorSource(self)->QgsVectorLayer:
+    def currentVectorSource(self) -> QgsVectorLayer:
         """
         Returns the current QgsVectorLayer
         :return: QgsVectorLayer
@@ -913,7 +913,7 @@ class LabelShortcutEditorConfigWidget(QgsEditorConfigWidget):
 
         self.onIndexChanged()
 
-    def config(self, *args, **kwargs)->dict:
+    def config(self, *args, **kwargs) -> dict:
 
         conf = dict()
         conf[CONFKEY_LABELTYPE] = self.mCBShortCutType.currentData()
@@ -954,14 +954,14 @@ class LabelShortcutEditorConfigWidget(QgsEditorConfigWidget):
         #    self.mClassWidget.setVisible(False)
         self.changed.emit()
 
-    #def classificationScheme(self)->ClassificationScheme:
+    #def classificationScheme(self) -> ClassificationScheme:
     #    return self.mClassWidget.classificationScheme()
 
     #def setClassificationScheme(self, classScheme:ClassificationScheme):
     #    assert isinstance(classScheme, ClassificationScheme)
     #    self.mClassWidget.setClassificationScheme(classScheme)
 
-    def shortcutType(self)->LabelShortcutType:
+    def shortcutType(self) -> LabelShortcutType:
         return self.mCBShortCutType.currentData(Qt.UserRole)
 
 
@@ -974,10 +974,10 @@ class LabelShortcutEditorWidgetWrapper(QgsEditorWidgetWrapper):
         self.mEditor = None
         self.mValidator = None
 
-    def configLabelType(self)->LabelShortcutType:
+    def configLabelType(self) -> LabelShortcutType:
         return self.config(CONFKEY_LABELTYPE)
 
-    #def configClassificationScheme(self)->ClassificationScheme:
+    #def configClassificationScheme(self) -> ClassificationScheme:
     #    return self.config(CONFKEY_CLASSIFICATIONSCHEME)
 
     def createWidget(self, parent: QWidget):
@@ -1013,7 +1013,7 @@ class LabelShortcutEditorWidgetWrapper(QgsEditorWidgetWrapper):
         self.valueChanged.emit(self.value())
         s = ""
 
-    def valid(self, *args, **kwargs)->bool:
+    def valid(self, *args, **kwargs) -> bool:
         """
         Returns True if a valid editor widget exists
         :param args:
@@ -1086,10 +1086,10 @@ class LabelShortcutWidgetFactory(QgsEditorWidgetFactory):
         self.mConfigurations = {}
 
 
-    def name(self)->str:
+    def name(self) -> str:
         return EDITOR_WIDGET_REGISTRY_KEY
 
-    def configWidget(self, layer:QgsVectorLayer, fieldIdx:int, parent=QWidget)->LabelShortcutEditorConfigWidget:
+    def configWidget(self, layer:QgsVectorLayer, fieldIdx:int, parent=QWidget) -> LabelShortcutEditorConfigWidget:
         """
         Returns a SpectralProfileEditorConfigWidget
         :param layer: QgsVectorLayer
@@ -1113,7 +1113,7 @@ class LabelShortcutWidgetFactory(QgsEditorWidgetFactory):
         """
         return (layer.id(), fieldIdx)
 
-    def create(self, layer:QgsVectorLayer, fieldIdx:int, editor:QWidget, parent:QWidget)->LabelShortcutEditorWidgetWrapper:
+    def create(self, layer:QgsVectorLayer, fieldIdx:int, editor:QWidget, parent:QWidget) -> LabelShortcutEditorWidgetWrapper:
         """
         Create a ClassificationSchemeEditorWidgetWrapper
         :param layer: QgsVectorLayer
@@ -1144,7 +1144,7 @@ class LabelShortcutWidgetFactory(QgsEditorWidgetFactory):
             conf = {}
         return conf
 
-    def fieldScore(self, vl:QgsVectorLayer, fieldIdx:int)->int:
+    def fieldScore(self, vl:QgsVectorLayer, fieldIdx:int) -> int:
         """
         This method allows disabling this editor widget type for a certain field.
         0: not supported: none String fields
@@ -1165,7 +1165,7 @@ class LabelShortcutWidgetFactory(QgsEditorWidgetFactory):
         else:
             return 0 # no support
 
-    def supportsField(self, vl:QgsVectorLayer, idx:int)->True:
+    def supportsField(self, vl:QgsVectorLayer, idx:int) -> True:
         """
         :param vl: vectorlayers
         :param idx:
@@ -1189,10 +1189,10 @@ class LabelingDock(QgsDockWidget):
         self.setWindowTitle(self.mLabelingWidget.windowTitle())
         self.setWidget(self.mLabelingWidget)
 
-    def labelingWidget(self)->LabelingWidget:
+    def labelingWidget(self) -> LabelingWidget:
         return self.mLabelingWidget
 
-    def canvas(self)->QgsMapCanvas:
+    def canvas(self) -> QgsMapCanvas:
         """
         Returns the QgsMapCanvase
         :return:
diff --git a/eotimeseriesviewer/main.py b/eotimeseriesviewer/main.py
index 188978b5..34bfee0a 100644
--- a/eotimeseriesviewer/main.py
+++ b/eotimeseriesviewer/main.py
@@ -217,7 +217,7 @@ class EOTimeSeriesViewerUI(QMainWindow):
         self.dockTimeSeries.raise_()
 
 
-    def registerMapToolAction(self, a:QAction)->QAction:
+    def registerMapToolAction(self, a:QAction) -> QAction:
         """
         Registers this action as map tools action. If triggered, all other mapt tool actions with be set unchecked
         :param a: QAction
@@ -544,7 +544,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
             w.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
             w.setMinimumSize(0, 0)
 
-    def sensors(self)->typing.List[SensorInstrument]:
+    def sensors(self) -> typing.List[SensorInstrument]:
         """
         Returns the list of Sensors
         :return: [list-of-Sensors]
@@ -566,7 +566,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
         self.ui.actionIdentify.trigger()
         self.ui.optionIdentifySpectralProfile.setChecked(True)
 
-    def _createProgressDialog(self, title='Load Data')->QProgressDialog:
+    def _createProgressDialog(self, title='Load Data') -> QProgressDialog:
         """
         Creates a QProgressDialog to load image data
         :return: QProgressDialog
@@ -649,7 +649,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
         mapView.addLayer(self.spectralTemporalVis.temporalProfileLayer())
         mapView.addLayer(self.spectralLibrary())
 
-    def temporalProfileLayer(self)->TemporalProfileLayer:
+    def temporalProfileLayer(self) -> TemporalProfileLayer:
         """
         Returns the TemporalProfileLayer
         :return:
@@ -658,7 +658,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
         return self.spectralTemporalVis.temporalProfileLayer()
 
 
-    def spectralLibrary(self)->SpectralLibrary:
+    def spectralLibrary(self) -> SpectralLibrary:
         """
         Returns the SpectraLibrary of the SpectralLibrary dock
         :return: SpectraLibrary
@@ -718,14 +718,14 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
             self.ui.mMapWidget.setCurrentDate(tsd)
 
 
-    def mapCanvases(self)->typing.List[MapCanvas]:
+    def mapCanvases(self) -> typing.List[MapCanvas]:
         """
         Returns all MapCanvases of the spatial visualization
         :return: [list-of-MapCanvases]
         """
         return self.ui.mMapWidget.mapCanvases()
 
-    def mapLayerStore(self)->QgsMapLayerStore:
+    def mapLayerStore(self) -> QgsMapLayerStore:
         """
         Returns the QgsMapLayerStore which is used to register QgsMapLayers
         :return: QgsMapLayerStore
@@ -904,14 +904,14 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
         """
         self.mapWidget().setSpatialCenter(spatialPoint)
 
-    def spatialExtent(self)->SpatialExtent:
+    def spatialExtent(self) -> SpatialExtent:
         """
         Returns the map extent
         :return: SpatialExtent
         """
         return self.mapWidget().spatialExtent()
 
-    def spatialCenter(self)->SpatialPoint:
+    def spatialCenter(self) -> SpatialPoint:
         """
         Returns the map center
         :return: SpatialPoint
@@ -1039,7 +1039,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
             s = ""
         pass
 
-    def messageBar(self)->QgsMessageBar:
+    def messageBar(self) -> QgsMessageBar:
         """
         Returns the QgsMessageBar that is used to show messages in the TimeSeriesViewer UI.
         :return: QgsMessageBar
@@ -1074,14 +1074,14 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
             self.mTimeSeries.loadFromFile(path, n_max=n_max, progressDialog=progressDialog, runAsync=runAsync)
 
 
-    def createMapView(self, name:str=None)->MapView:
+    def createMapView(self, name:str=None) -> MapView:
         """
         Creates a new MapView.
         :return: MapView
         """
         return self.ui.dockMapViews.createMapView(name=name)
 
-    def mapViews(self)->typing.List[MapView]:
+    def mapViews(self) -> typing.List[MapView]:
         """
         Returns all MapViews
         :return: [list-of-MapViews]
@@ -1089,7 +1089,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
         return self.ui.dockMapViews[:]
 
 
-    def icon(self)->QIcon:
+    def icon(self) -> QIcon:
         """
         Returns the EO Time Series Viewer icon
         :return: QIcon
@@ -1097,7 +1097,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
         import eotimeseriesviewer
         return eotimeseriesviewer.icon()
 
-    def temporalProfiles(self)->list:
+    def temporalProfiles(self) -> list:
         """
         Returns collected temporal profiles
         :return: [list-of-TemporalProfiles]
@@ -1156,7 +1156,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
         if len(self.mTimeSeries) == 0:
             self.mSpatialMapExtentInitialized = False
 
-    def mapWidget(self)->MapWidget:
+    def mapWidget(self) -> MapWidget:
         """
         Returns the MapWidget that contains all map canvases.
         :return: MapWidget
@@ -1224,7 +1224,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
                     s = ""
 
 
-    def timeSeries(self)->TimeSeries:
+    def timeSeries(self) -> TimeSeries:
         """
         Returns the TimeSeries instance.
         :return: TimeSeries
@@ -1264,7 +1264,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
                 #    w.widget().deleteLater()
         QApplication.processEvents()
 
-    def addVectorData(self, files=None)->list:
+    def addVectorData(self, files=None) -> list:
         """
         Adds vector data
         :param files: vector layer sources
@@ -1378,14 +1378,14 @@ class SaveAllMapsDialog(QDialog):
         self.fileWidget.setFilePath(path)
 
 
-    def directory(self)->str:
+    def directory(self) -> str:
         """
         Returns the selected directory
         :return: str
         """
         return self.fileWidget.filePath()
 
-    def fileType(self)->str:
+    def fileType(self) -> str:
         """
         Returns the selected file type
         :return:
diff --git a/eotimeseriesviewer/mapcanvas.py b/eotimeseriesviewer/mapcanvas.py
index c8b901a1..8d1debd0 100644
--- a/eotimeseriesviewer/mapcanvas.py
+++ b/eotimeseriesviewer/mapcanvas.py
@@ -118,7 +118,7 @@ class MapCanvasInfoItem(QgsMapCanvasItem):
         self.mTextFormat.setFont(QFont('Helvetica', pointSize=10))
         self.mTextFormat.setColor(QColor('yellow'))
 
-    def setWrapChar(self, c:str)->str:
+    def setWrapChar(self, c:str) -> str:
         """
         Sets a Wrap Character
         :param c:
@@ -127,7 +127,7 @@ class MapCanvasInfoItem(QgsMapCanvasItem):
         self.mWrapChar = c
         return self.wrapChar()
 
-    def wrapChar(self)->str:
+    def wrapChar(self) -> str:
         return self.mWrapChar
 
     def setText(self, text:str, alignment:Qt.Alignment=Qt.AlignTop | Qt.AlignHCenter):
@@ -140,14 +140,14 @@ class MapCanvasInfoItem(QgsMapCanvasItem):
         self.mTextFormat = format
         self.updateCanvas()
 
-    def textFormat(self)->QgsTextFormat:
+    def textFormat(self) -> QgsTextFormat:
         """
         Returns the text format.
         :return: QgsTextFormat
         """
         return self.mTextFormat
 
-    def font(self)->QFont:
+    def font(self) -> QFont:
         """
         Returns the font used to write text on the map canvas.
         :return: QFont
@@ -164,7 +164,7 @@ class MapCanvasInfoItem(QgsMapCanvasItem):
         """
         self.mTextFormat.setColor(color)
 
-    def color(self)->QColor:
+    def color(self) -> QColor:
         """
         Returns the info text color
         :return: QColor
@@ -424,7 +424,7 @@ class MapCanvas(QgsMapCanvas):
 
         self.destinationCrsChanged.connect(lambda : self.sigDestinationCrsChanged.emit(self.crs()))
 
-    def userInputWidget(self)->QgsUserInputWidget:
+    def userInputWidget(self) -> QgsUserInputWidget:
         """
         Returns the mapcanvas QgsUserInputWidget
         :return: QgsUserInputWidget
@@ -432,7 +432,7 @@ class MapCanvas(QgsMapCanvas):
         return self.mUserInputWidget
 
 
-    def infoItem(self)->MapCanvasInfoItem:
+    def infoItem(self) -> MapCanvasInfoItem:
         """
         Returns the MapCanvasInfoItem, e.g. to plot text on top of the map canvas
         :return: MapCanvasInfoItem
@@ -446,7 +446,7 @@ class MapCanvas(QgsMapCanvas):
         """
         return self.mMapView
 
-    def mapTools(self)->MapCanvasMapTools:
+    def mapTools(self) -> MapCanvasMapTools:
         """
         Returns the map tools of this MapCanvas
         :return: MapCanvasMapTools
@@ -467,7 +467,7 @@ class MapCanvas(QgsMapCanvas):
         assert isinstance(store, (QgsMapLayerStore, QgsProject))
         self.mMapLayerStore = store
 
-    def renderingFinished(self)->bool:
+    def renderingFinished(self) -> bool:
         """
         Returns whether the MapCanvas is processing a rendering task
         :return: bool
@@ -563,7 +563,7 @@ class MapCanvas(QgsMapCanvas):
 
 
 
-    def tsd(self)->TimeSeriesDate:
+    def tsd(self) -> TimeSeriesDate:
         """
         Returns the TimeSeriesDate
         :return: TimeSeriesDate
@@ -607,7 +607,7 @@ class MapCanvas(QgsMapCanvas):
         if self.crs() != crs:
             self.setDestinationCrs(crs)
 
-    def crs(self)->QgsCoordinateReferenceSystem:
+    def crs(self) -> QgsCoordinateReferenceSystem:
         """
         Shortcut to return self.mapSettings().destinationCrs()
         :return: QgsCoordinateReferenceSystem
@@ -625,10 +625,10 @@ class MapCanvas(QgsMapCanvas):
         super(MapCanvas, self).setLayers(mapLayers)
 
 
-    def isRefreshing(self)->bool:
+    def isRefreshing(self) -> bool:
         return self.mIsRefreshing
 
-    def isVisibleToViewport(self)->bool:
+    def isVisibleToViewport(self) -> bool:
         """
         Returns whether the MapCanvas is visible to a user and not hidden behind the invisible regions of a scroll area.
         :return: bool
@@ -791,7 +791,7 @@ class MapCanvas(QgsMapCanvas):
         if emitSignal:
             self.sigCrosshairStyleChanged.emit(self.mCrosshairItem.crosshairStyle())
 
-    def crosshairStyle(self)->CrosshairStyle:
+    def crosshairStyle(self) -> CrosshairStyle:
         """
         Returns the style of the Crosshair.
         :return: CrosshairStyle
@@ -811,7 +811,7 @@ class MapCanvas(QgsMapCanvas):
             self.mCrosshairItem.setPosition(point)
             self.sigCrosshairPositionChanged.emit(point)
 
-    def crosshairPosition(self)->SpatialPoint:
+    def crosshairPosition(self) -> SpatialPoint:
         """Returns the last crosshair position"""
         return self.mCrosshairItem.mPosition
 
@@ -843,7 +843,7 @@ class MapCanvas(QgsMapCanvas):
         """
         return self.grab()
 
-    def contextMenu(self, pos:QPoint)->QMenu:
+    def contextMenu(self, pos:QPoint) -> QMenu:
         """
         Creates the MapCanvas context menu with options relevant for pixel position ``pos``.
         :param pos: QPoint
@@ -1327,14 +1327,14 @@ class MapCanvas(QgsMapCanvas):
         if isinstance(center, SpatialPoint):
             self.setCenter(center)
 
-    def spatialExtent(self)->SpatialExtent:
+    def spatialExtent(self) -> SpatialExtent:
         """
         Returns the map extent as SpatialExtent (extent + CRS)
         :return: SpatialExtent
         """
         return SpatialExtent.fromMapCanvas(self)
 
-    def spatialCenter(self)->SpatialPoint:
+    def spatialCenter(self) -> SpatialPoint:
         """
         Returns the map center as SpatialPoint (QgsPointXY + CRS)
         :return: SpatialPoint
@@ -1342,7 +1342,7 @@ class MapCanvas(QgsMapCanvas):
         return SpatialPoint.fromMapCanvasCenter(self)
 
 
-    def spatialExtentHint(self)->SpatialExtent:
+    def spatialExtentHint(self) -> SpatialExtent:
         """
         Returns a hint for a SpatialExtent, derived from the first raster layer
         :return: SpatialExtent
diff --git a/eotimeseriesviewer/mapviewscrollarea.py b/eotimeseriesviewer/mapviewscrollarea.py
index ce96378d..ce155f79 100644
--- a/eotimeseriesviewer/mapviewscrollarea.py
+++ b/eotimeseriesviewer/mapviewscrollarea.py
@@ -36,7 +36,7 @@ class MapViewScrollArea(QScrollArea):
         #super(MapViewScrollArea, self).resizeEvent(event)
         #self.sigResized.emit()
 
-    def distanceToCenter(self, widget:QWidget)->int:
+    def distanceToCenter(self, widget:QWidget) -> int:
         # self.visibleRegion().boundingRect().isValid()
         halfSize = widget.size() * 0.5
         centerInParent = widget.mapToParent(QPoint(halfSize.width(), halfSize.height()))
diff --git a/eotimeseriesviewer/mapvisualization.py b/eotimeseriesviewer/mapvisualization.py
index 64ca6cde..0a2446c3 100644
--- a/eotimeseriesviewer/mapvisualization.py
+++ b/eotimeseriesviewer/mapvisualization.py
@@ -62,7 +62,7 @@ KEY_SENSOR_GROUP = 'eotsv/sensorgroup'
 KEY_SENSOR_LAYER = 'eotsv/sensorlayer'
 
 
-def equalTextFormats(tf1:QgsTextFormat, tf2:QgsTextFormat)->True:
+def equalTextFormats(tf1:QgsTextFormat, tf2:QgsTextFormat) -> True:
     return tf1.toMimeData().text() == tf2.toMimeData().text()
 
 class MapViewLayerTreeViewMenuProvider(QgsLayerTreeViewMenuProvider):
@@ -92,16 +92,16 @@ class MapViewLayerTreeViewMenuProvider(QgsLayerTreeViewMenuProvider):
     def mapView(self):
         return self.mMapView
 
-    def layerTreeView(self)->QgsLayerTreeView:
+    def layerTreeView(self) -> QgsLayerTreeView:
         return self.mLayerTreeView
 
-    def layerTree(self)->QgsLayerTree:
+    def layerTree(self) -> QgsLayerTree:
         return self.layerTreeModel().rootGroup()
 
-    def layerTreeModel(self)->QgsLayerTreeModel:
+    def layerTreeModel(self) -> QgsLayerTreeModel:
         return self.layerTreeView().model()
 
-    def createContextMenu(self)->QMenu:
+    def createContextMenu(self) -> QMenu:
 
         model = self.layerTreeModel()
         ltree = self.layerTree()
@@ -318,27 +318,27 @@ class MapView(QFrame):
     def setName(self, name:str):
         self.setTitle(name)
 
-    def name(self)->str:
+    def name(self) -> str:
         return self.title()
 
-    def setMapTextFormat(self, textformat:QgsTextFormat)->QgsTextFormat:
+    def setMapTextFormat(self, textformat:QgsTextFormat) -> QgsTextFormat:
 
         if not equalTextFormats(self.mapTextFormat(), textformat):
             self.mMapTextFormat = textformat
             self.sigCanvasAppearanceChanged.emit()
         return self.mapTextFormat()
 
-    def mapTextFormat(self)->QgsTextFormat:
+    def mapTextFormat(self) -> QgsTextFormat:
         return self.mMapTextFormat
 
-    def mapBackgroundColor(self)->QColor:
+    def mapBackgroundColor(self) -> QColor:
         """
         Returns the map background color
         :return: QColor
         """
         return self.mMapBackgroundColor
 
-    def setMapBackgroundColor(self, color:QColor)->QColor:
+    def setMapBackgroundColor(self, color:QColor) -> QColor:
         """
         Sets the map background color
         :param color: QColor
@@ -350,7 +350,7 @@ class MapView(QFrame):
         return self.mMapBackgroundColor
 
 
-    def visibleMapCanvases(self)->list:
+    def visibleMapCanvases(self) -> list:
         """
         Returns the currently visible mapcanvases
         :return: [list-of-MapCanvases]
@@ -433,7 +433,7 @@ class MapView(QFrame):
         self.mLayerTreeSensorNode.setCustomProperty(KEY_SENSOR_GROUP, True)
         self.mLayerTree.addChildNode(self.mLayerTreeSensorNode)
 
-    def _containsSensorNode(self, root:QgsLayerTreeGroup)->bool:
+    def _containsSensorNode(self, root:QgsLayerTreeGroup) -> bool:
         assert isinstance(root, QgsLayerTreeGroup)
         if root.customProperty(KEY_SENSOR_GROUP) in [True, 'true']:
             return True
@@ -473,14 +473,14 @@ class MapView(QFrame):
         if changed:
             self.sigCanvasAppearanceChanged.emit()
 
-    def isVisible(self)->bool:
+    def isVisible(self) -> bool:
         """
         Returns the map view visibility
         :return: bool
         """
         return not self.actionToggleMapViewHidden.isChecked()
 
-    def mapCanvases(self)->typing.List[MapCanvas]:
+    def mapCanvases(self) -> typing.List[MapCanvas]:
         """
         Returns the MapCanvases related to this map view. Requires that this mapview was added to a MapWidget
         :return: [list-of-MapCanvases]
@@ -520,7 +520,7 @@ class MapView(QFrame):
         for s in timeSeries.sensors():
             self.addSensor(s)
 
-    def timeSeries(self)->TimeSeries:
+    def timeSeries(self) -> TimeSeries:
         """
         Returns the TimeSeries this mapview is connected with
         :return: TimeSeries
@@ -537,14 +537,14 @@ class MapView(QFrame):
             self.tbName.setText(title)
 
 
-    def layers(self)->list:
+    def layers(self) -> list:
         """
         Returns the visible layers, including proxy layer for time-series data
         :return: [list-of-QgsMapLayers]
         """
         return [l for l in self.mLayerTree.checkedLayers() if isinstance(l, QgsMapLayer)]
 
-    def title(self, maskNewLines=True)->str:
+    def title(self, maskNewLines=True) -> str:
         """
         Returns the MapView title
         :return: str
@@ -554,7 +554,7 @@ class MapView(QFrame):
         else:
             return self.tbName.text().strip()
 
-    def setCrosshairStyle(self, crosshairStyle:CrosshairStyle)->CrosshairStyle:
+    def setCrosshairStyle(self, crosshairStyle:CrosshairStyle) -> CrosshairStyle:
         """
         Seths the CrosshairStyle of this MapView
         :param crosshairStyle: CrosshairStyle
@@ -587,7 +587,7 @@ class MapView(QFrame):
             for mapCanvas in self.mapCanvases():
                 mapCanvas.setStyleSheet(styleOff)
 
-    def crosshairStyle(self)->CrosshairStyle:
+    def crosshairStyle(self) -> CrosshairStyle:
         """
         Returns the CrosshairStyle
         :return: CrosshairStyle
@@ -606,11 +606,11 @@ class MapView(QFrame):
             self.sigCrosshairChanged.emit()
 
 
-    def sensorProxyLayers(self)->typing.List[SensorProxyLayer]:
+    def sensorProxyLayers(self) -> typing.List[SensorProxyLayer]:
         layers = [n.layer() for n in self.mLayerTreeSensorNode.findLayers()]
         return [l for l in layers if isinstance(l, SensorProxyLayer)]
 
-    def sensorProxyLayer(self, sensor:SensorInstrument)->SensorProxyLayer:
+    def sensorProxyLayer(self, sensor:SensorInstrument) -> SensorProxyLayer:
         """
         Returns the proxy layer related to a SensorInstrument
         :param sensor: SensorInstrument
@@ -621,7 +621,7 @@ class MapView(QFrame):
                 return l
         return None
 
-    def sensors(self)->list:
+    def sensors(self) -> list:
         """
         Returns a list of SensorsInstruments
         :return: [list-of-SensorInstruments]
@@ -655,7 +655,7 @@ class MapView(QFrame):
             assert isinstance(c, MapCanvas)
             c.addToRefreshPipeLine(MapCanvas.Command.RefreshRenderer)
 
-    def sensorCanvases(self, sensor:SensorInstrument)->list:
+    def sensorCanvases(self, sensor:SensorInstrument) -> list:
         """
         Returns the MapCanvases that show a layer with data for the given ``sensor``
         :param sensor: SensorInstrument
@@ -697,7 +697,7 @@ class MapView(QFrame):
             self.mSensorLayerList.remove(t)
 
 
-    def hasSensor(self, sensor)->bool:
+    def hasSensor(self, sensor) -> bool:
         """
         :param sensor:
         :return:
@@ -903,7 +903,7 @@ class MapWidget(QFrame):
 
 
 
-    def messageBar(self)->QgsMessageBar:
+    def messageBar(self) -> QgsMessageBar:
         """
         Returns the QgsMessageBar
         :return: QgsMessageBar
@@ -915,7 +915,7 @@ class MapWidget(QFrame):
             assert isinstance(c, MapCanvas)
             c.timedRefresh()
 
-    def setMapTextFormat(self, textFormat:QgsTextFormat)->QgsTextFormat:
+    def setMapTextFormat(self, textFormat:QgsTextFormat) -> QgsTextFormat:
 
         if not equalTextFormats(textFormat, self.mMapTextFormat):
             self.mMapTextFormat = textFormat
@@ -925,7 +925,7 @@ class MapWidget(QFrame):
             self.sigMapTextFormatChanged.emit(self.mapTextFormat())
         return self.mapTextFormat()
 
-    def mapTextFormat(self)->QgsTextFormat:
+    def mapTextFormat(self) -> QgsTextFormat:
         return self.mMapTextFormat
 
 
@@ -940,7 +940,7 @@ class MapWidget(QFrame):
                 mts = c.mapTools()
                 mts.activate(self.mMapToolKey)
 
-    def visibleTSDs(self)->list:
+    def visibleTSDs(self) -> list:
         """
         Returns the list of currently shown TimeSeriesDates.
         :return: [list-of-TimeSeriesDates]
@@ -955,14 +955,14 @@ class MapWidget(QFrame):
             return sorted(tsds)
         return []
 
-    def spatialExtent(self)->SpatialExtent:
+    def spatialExtent(self) -> SpatialExtent:
         """
         Returns the current SpatialExtent
         :return: SpatialExtent
         """
         return self.mSpatialExtent
 
-    def setSpatialExtent(self, extent:SpatialExtent)->SpatialExtent:
+    def setSpatialExtent(self, extent:SpatialExtent) -> SpatialExtent:
         """
         Sets a SpatialExtent to all MapCanvases.
         :param extent: SpatialExtent
@@ -1001,7 +1001,7 @@ class MapWidget(QFrame):
                 self.setSpatialExtent(extent)
 
 
-    def spatialCenter(self)->SpatialPoint:
+    def spatialCenter(self) -> SpatialPoint:
         """
         Return the center of all map canvas
         :return: SpatialPoint
@@ -1009,7 +1009,7 @@ class MapWidget(QFrame):
         return self.spatialExtent().spatialCenter()
 
 
-    def setCrs(self, crs:QgsCoordinateReferenceSystem)->QgsCoordinateReferenceSystem:
+    def setCrs(self, crs:QgsCoordinateReferenceSystem) -> QgsCoordinateReferenceSystem:
         """
         Sets the MapCanvas CRS.
         :param crs: QgsCoordinateReferenceSystem
@@ -1043,10 +1043,10 @@ class MapWidget(QFrame):
         return list(layers)
 
 
-    def crs(self)->QgsCoordinateReferenceSystem:
+    def crs(self) -> QgsCoordinateReferenceSystem:
         return self.mCrs
 
-    def setTimeSeries(self, ts:TimeSeries)->TimeSeries:
+    def setTimeSeries(self, ts:TimeSeries) -> TimeSeries:
         assert ts == None or isinstance(ts, TimeSeries)
         self.mTimeSeries = ts
         if isinstance(self.mTimeSeries, TimeSeries):
@@ -1103,7 +1103,7 @@ class MapWidget(QFrame):
             self.setCurrentDate(tsd)
 
 
-    def timeSeries(self)->TimeSeries:
+    def timeSeries(self) -> TimeSeries:
         return self.mTimeSeries
 
     def setMode(self, mode:ViewMode):
@@ -1113,7 +1113,7 @@ class MapWidget(QFrame):
             self._updateGrid()
             self.sigViewModeChanged.emit(self.mViewMode)
 
-    def setMapsPerMapView(self, n:int)->int:
+    def setMapsPerMapView(self, n:int) -> int:
         """
         Sets the number of maps per map viewe
         :param n: int
@@ -1129,14 +1129,14 @@ class MapWidget(QFrame):
         return self.mapsPerMapView()
 
 
-    def mapsPerMapView(self)->int:
+    def mapsPerMapView(self) -> int:
         """
         Returns the number of maps per map view
         :return: int
         """
         return self.mMpMV
 
-    def setMapSize(self, size:QSize)->QSize:
+    def setMapSize(self, size:QSize) -> QSize:
         """
         Sets the MapCanvas size
         :param size: QSite
@@ -1153,21 +1153,21 @@ class MapWidget(QFrame):
 
         return self.mMapSize
 
-    def mapSize(self)->QSize:
+    def mapSize(self) -> QSize:
         """
         Returns the MapCanvas size
         :return: QSize
         """
         return self.mMapSize
 
-    def mapCanvases(self)->typing.List[MapCanvas]:
+    def mapCanvases(self) -> typing.List[MapCanvas]:
         """
         Returns all MapCanvases
         :return: [list-of-MapCanvases]
         """
         return self.findChildren(MapCanvas)
 
-    def mapViewCanvases(self, mapView:MapView)->typing.List[MapCanvas]:
+    def mapViewCanvases(self, mapView:MapView) -> typing.List[MapCanvas]:
         """
         Returns the MapCanvases related to a MapView
         :param mapView: MapView
@@ -1220,7 +1220,7 @@ class MapWidget(QFrame):
                 return
         s  = ""
 
-    def setCurrentDate(self, tsd:TimeSeriesDate)->TimeSeriesDate:
+    def setCurrentDate(self, tsd:TimeSeriesDate) -> TimeSeriesDate:
         """
         Sets the current TimeSeriesDate, i.e. the "center" date of all dates to be shown
         :param tsd: TimeSeriesDate
@@ -1256,17 +1256,17 @@ class MapWidget(QFrame):
 
         return self.mCurrentDate
 
-    def timeSlider(self)->QSlider:
+    def timeSlider(self) -> QSlider:
         return self.mTimeSlider
 
-    def currentDate(self)->TimeSeriesDate:
+    def currentDate(self) -> TimeSeriesDate:
         """
         Returns the current TimeSeriesDate
         :return: TimeSeriesDate
         """
         return self.mCurrentDate
 
-    def addMapView(self, mapView:MapView)->MapView:
+    def addMapView(self, mapView:MapView) -> MapView:
         """
         Adds a MapView
         :param mapView: MapView
@@ -1290,7 +1290,7 @@ class MapWidget(QFrame):
 
         return mapView
 
-    def removeMapView(self, mapView:MapView)->MapView:
+    def removeMapView(self, mapView:MapView) -> MapView:
         """
         Removes a MapView
         :param mapView: Mapview
@@ -1307,7 +1307,7 @@ class MapWidget(QFrame):
             self.sigMapViewRemoved.emit(mapView)
         return mapView
 
-    def mapViews(self)->list:
+    def mapViews(self) -> list:
         """
         Returns a list of all MapViews
         :return: [list-of-MapViews]
@@ -1377,7 +1377,7 @@ class MapWidget(QFrame):
 
         self.mSyncLock = False
 
-    def _createMapCanvas(self)->MapCanvas:
+    def _createMapCanvas(self) -> MapCanvas:
         mapCanvas = MapCanvas()
         mapCanvas.setMapLayerStore(self.mMapLayerStore)
         mapCanvas.mInfoItem.setTextFormat(self.mapTextFormat())
@@ -1421,7 +1421,7 @@ class MapWidget(QFrame):
         for mapView in self.mapViews():
             mapView.setCurrentLayer(layer)
 
-    def setCrosshairPosition(self, spatialPoint)->SpatialPoint:
+    def setCrosshairPosition(self, spatialPoint) -> SpatialPoint:
         spatialPoint = spatialPoint.toCrs(self.crs())
         if self.mCrosshairPosition != spatialPoint:
             self.mCrosshairPosition = spatialPoint
@@ -1433,7 +1433,7 @@ class MapWidget(QFrame):
             self.sigCrosshairPositionChanged[SpatialPoint].emit(self.mCrosshairPosition)
         return self.crosshairPosition()
 
-    def crosshairPosition(self)->SpatialPoint:
+    def crosshairPosition(self) -> SpatialPoint:
         return self.mCrosshairPosition
 
     def _updateGrid(self):
@@ -1538,7 +1538,7 @@ class MapWidget(QFrame):
             w.layout().update()
             w.update()
 
-    def _updateLayerCache(self)->list:
+    def _updateLayerCache(self) -> list:
         canvases = self.findChildren(MapCanvas)
         for c in canvases:
             assert isinstance(c, MapCanvas)
@@ -1747,7 +1747,7 @@ class MapViewDock(QgsDockWidget):
         self.sigMapSizeChanged.emit(QSize(self.spinBoxMapSizeX.value(), self.spinBoxMapSizeY.value()))
         self.sigMapsPerMapViewChanged.emit(self.mapsPerMapView())
 
-    def setMapWidget(self, mw)->MapWidget:
+    def setMapWidget(self, mw) -> MapWidget:
         """
         Connects this MapViewDock with a MapWidget
         :param mw: MapWidget
@@ -1780,14 +1780,14 @@ class MapViewDock(QgsDockWidget):
 
         return self.mMapWidget
 
-    def mapWidget(self)->MapWidget:
+    def mapWidget(self) -> MapWidget:
         """
         Returns the connected MapWidget
         :return: MapWidget
         """
         return self.mMapWidget
 
-    def mapViews(self)->list:
+    def mapViews(self) -> list:
         """
         Returns the defined MapViews
         :return: [list-of-MapViews]
@@ -1800,7 +1800,7 @@ class MapViewDock(QgsDockWidget):
                 mapViews.append(item)
         return mapViews
 
-    def mapCanvases(self)->list:
+    def mapCanvases(self) -> list:
         """
         Returns all MapCanvases from all MapViews
         :return: [list-of-MapCanvases]
@@ -1819,7 +1819,7 @@ class MapViewDock(QgsDockWidget):
                 self.btnCrs.setCrs(crs)
                 self.btnCrs.setLayerCrs(crs)
 
-    def mapsPerMapView(self)->int:
+    def mapsPerMapView(self) -> int:
         return self.sbMpMV.value()
 
     def setMapsPerMapView(self, n:int):
@@ -1834,7 +1834,7 @@ class MapViewDock(QgsDockWidget):
         if not equalTextFormats(textFormat, self.mapTextFormat()):
             self.btnTextFormat.setTextFormat(textFormat)
 
-    def mapTextFormat(self)->QgsTextFormat:
+    def mapTextFormat(self) -> QgsTextFormat:
         return self.btnTextFormat.textFormat()
 
     def setMapSize(self, size):
@@ -1879,7 +1879,7 @@ class MapViewDock(QgsDockWidget):
             self.btnApplySizeChanges.setEnabled(False)
         self.setMapSize(newSize)
 
-    def mapSize(self)->QSize:
+    def mapSize(self) -> QSize:
         return QSize(self.spinBoxMapSizeX.value(),
                      self.spinBoxMapSizeY.value())
 
@@ -1901,7 +1901,7 @@ class MapViewDock(QgsDockWidget):
         self.actionRemoveMapView.setEnabled(len(self.mMapViews) > 0)
 
 
-    def mapBackgroundColor(self)->QColor:
+    def mapBackgroundColor(self) -> QColor:
         """
         Returns the map canvas background color
         :return: QColor
@@ -1927,7 +1927,7 @@ class MapViewDock(QgsDockWidget):
             self.btnMapTextColor.setColor(color)
         return self.mapTextColor()
 
-    def mapTextColor(self)->QColor:
+    def mapTextColor(self) -> QColor:
         """
         Returns the map text color.
         :return: QColor
@@ -1964,7 +1964,7 @@ class MapViewDock(QgsDockWidget):
         self.actionHighlightMapView.setEnabled(b)
 
 
-    def createMapView(self, name:str=None)->MapView:
+    def createMapView(self, name:str=None) -> MapView:
         """
         Create a new MapView
         :return: MapView
@@ -2045,7 +2045,7 @@ class MapViewDock(QgsDockWidget):
                 self.toolBox.setItemText(i, 'Map View {} "{}"'.format(numMV, mapView.title()))
                 break
 
-    def removeMapView(self, mapView:MapView)->MapView:
+    def removeMapView(self, mapView:MapView) -> MapView:
         """
         Removes a MapView
         :param mapView: MapView
@@ -2065,7 +2065,7 @@ class MapViewDock(QgsDockWidget):
 
 
 
-    def __len__(self)->int:
+    def __len__(self) -> int:
         """
         Returns the number of MapViews
         :return: int
diff --git a/eotimeseriesviewer/profilevisualization.py b/eotimeseriesviewer/profilevisualization.py
index 90aeb949..287b292e 100644
--- a/eotimeseriesviewer/profilevisualization.py
+++ b/eotimeseriesviewer/profilevisualization.py
@@ -522,7 +522,7 @@ class PlotSettingsModel2D(QAbstractTableModel):
 
 
 
-    def requiredBandsIndices(self, sensor)->list:
+    def requiredBandsIndices(self, sensor) -> list:
         """
         Returns the band indices required to calculate the values for
         the different PlotStyle expressions making use of sensor
@@ -837,10 +837,10 @@ class PlotSettingsModel2DWidgetDelegate(QStyledItemDelegate):
         else:
             super(PlotSettingsModel2DWidgetDelegate, self).paint(painter, option, index)
 
-    def sortFilterProxyModel(self)->QSortFilterProxyModel:
+    def sortFilterProxyModel(self) -> QSortFilterProxyModel:
         return self.mTableView.model()
 
-    def plotSettingsModel(self)->PlotSettingsModel2D:
+    def plotSettingsModel(self) -> PlotSettingsModel2D:
         return self.sortFilterProxyModel().sourceModel()
 
     def setItemDelegates(self, tableView):
@@ -946,7 +946,7 @@ class PlotSettingsModel2DWidgetDelegate(QStyledItemDelegate):
 
                 self.commitData.emit(w)
 
-    def style(self, proxyIndex:QModelIndex)->PlotStyle:
+    def style(self, proxyIndex:QModelIndex) -> PlotStyle:
         model = self.plotSettingsModel()
         index = self.sortFilterProxyModel().mapToSource(proxyIndex)
         return model.data(index, role=Qt.UserRole)
@@ -1478,7 +1478,7 @@ class SpectralTemporalVisualization(QObject):
     def plotStyles(self):
         return self.plotSettingsModel2D[:]
 
-    def temporalProfileLayer(self)->TemporalProfileLayer:
+    def temporalProfileLayer(self) -> TemporalProfileLayer:
         """
         Returns a QgsVectorLayer that is used to store profile coordinates.
         :return:
@@ -1707,7 +1707,7 @@ class SpectralTemporalVisualization(QObject):
         self.sigMoveToTSD.emit(self.TS[i])
 
 
-    def onPixelLoaded(self, qgsTask ,dump)->typing.List[TemporalProfile]:
+    def onPixelLoaded(self, qgsTask ,dump) -> typing.List[TemporalProfile]:
         """
         Updates TemporalProfiles
         :param qgsTask:
@@ -1907,7 +1907,7 @@ class SpectralTemporalVisualization(QObject):
             if DEBUG:
                 print('Data for geometries already loaded')
 
-    def loadTemporalProfileTasks(self, tasks:typing.Iterable[TemporalProfileLoaderTask], runAsync=True)->typing.List[TemporalProfile]:
+    def loadTemporalProfileTasks(self, tasks:typing.Iterable[TemporalProfileLoaderTask], runAsync=True) -> typing.List[TemporalProfile]:
         """
         Loads data into TemporalProfiles
         :param tasks:
diff --git a/eotimeseriesviewer/sensorvisualization.py b/eotimeseriesviewer/sensorvisualization.py
index d607552c..d3a6dbe1 100644
--- a/eotimeseriesviewer/sensorvisualization.py
+++ b/eotimeseriesviewer/sensorvisualization.py
@@ -137,10 +137,10 @@ class SensorTableModel(QAbstractTableModel):
             self.mSensors.remove(tsd)
         self.endRemoveRows()
 
-    def getIndexFromSensor(self, sensor)->QModelIndex:
+    def getIndexFromSensor(self, sensor) -> QModelIndex:
         return self.createIndex(self.mSensors.index(sensor), 0)
 
-    def getSensorFromIndex(self, index)->SensorInstrument:
+    def getSensorFromIndex(self, index) -> SensorInstrument:
         if index.isValid():
             return self.mSensors[index.row()]
         return None
diff --git a/eotimeseriesviewer/settings.py b/eotimeseriesviewer/settings.py
index 1468c704..b9057ad8 100644
--- a/eotimeseriesviewer/settings.py
+++ b/eotimeseriesviewer/settings.py
@@ -78,7 +78,7 @@ def defaultValues() -> dict:
     return d
 
 
-def settings()->QSettings:
+def settings() -> QSettings:
     """
     Returns the EOTSV settings.
     :return: QSettings
@@ -169,7 +169,7 @@ def saveSensorName(sensor:SensorInstrument):
 
     setValue(Keys.SensorSpecs, sensorSpecs)
 
-def sensorName(id:typing.Union[str, SensorInstrument])->str:
+def sensorName(id:typing.Union[str, SensorInstrument]) -> str:
     """
     Retuns the sensor name stored for a certain sensor id
     :param id: str
@@ -221,7 +221,7 @@ def setValues(values: dict):
         setValue(key, val)
     settings().sync()
 
-def values()->dict:
+def values() -> dict:
     """
     Returns all settings in a dictionary
     :return: dict
@@ -288,7 +288,7 @@ class SensorSettingsTableModel(QAbstractTableModel):
             self.mSensors.remove(sensor)
             self.endRemoveRows()
 
-    def sensor2idx(self, sensor:SensorInstrument)->QModelIndex:
+    def sensor2idx(self, sensor:SensorInstrument) -> QModelIndex:
 
         if not sensor in self.mSensors:
             return QModelIndex()
@@ -316,7 +316,7 @@ class SensorSettingsTableModel(QAbstractTableModel):
         self.clear()
         self.addSensors(sensors)
 
-    def specs(self)->dict:
+    def specs(self) -> dict:
         """
         Returns the specifications for each stored sensor
         :return:
@@ -329,10 +329,10 @@ class SensorSettingsTableModel(QAbstractTableModel):
             specs[sensor.id()] = s
         return specs
 
-    def rowCount(self, parent: QModelIndex = QModelIndex())->int:
+    def rowCount(self, parent: QModelIndex = QModelIndex()) -> int:
         return len(self.mSensors)
 
-    def columnNames(self)->typing.List[str]:
+    def columnNames(self) -> typing.List[str]:
         return [self.mCNKey, self.mCNName]
 
     def columnCount(self, parent: QModelIndex):
@@ -355,13 +355,13 @@ class SensorSettingsTableModel(QAbstractTableModel):
         else:
             return None
 
-    def sensor(self, index)->SensorInstrument:
+    def sensor(self, index) -> SensorInstrument:
         if isinstance(index, int):
             return self.mSensors[index]
         else:
             return self.mSensors[index.row()]
 
-    def sensorIDDisplayString(self, sensor:SensorInstrument)->str:
+    def sensorIDDisplayString(self, sensor:SensorInstrument) -> str:
         """
         Returns a short representation of the sensor id, e.g. "6bands(Int16)@30m"
         :param sensor:
@@ -521,7 +521,7 @@ class SettingsDialog(QDialog):
 
             pass
 
-    def values(self)->dict:
+    def values(self) -> dict:
         """
         Returns the settings as dictionary
         :return: dict
diff --git a/eotimeseriesviewer/stackedbandinput.py b/eotimeseriesviewer/stackedbandinput.py
index a2e0a63f..74bd4a6c 100644
--- a/eotimeseriesviewer/stackedbandinput.py
+++ b/eotimeseriesviewer/stackedbandinput.py
@@ -26,7 +26,7 @@ from .virtualrasters import *
 from .dateparser import *
 from eotimeseriesviewer import DIR_UI
 
-def datesFromDataset(dataset:gdal.Dataset)->list:
+def datesFromDataset(dataset:gdal.Dataset) -> list:
 
     nb = dataset.RasterCount
 
@@ -163,7 +163,7 @@ class InputStackInfo(object):
     def __len__(self):
         return len(self.mDates)
 
-    def dates(self)->list:
+    def dates(self) -> list:
         """Returns a list of dates"""
         return self.mDates
 
@@ -598,7 +598,7 @@ class OutputImageModel(QAbstractTableModel):
             i = i.column()
         return self.mColumnNames[i]
 
-    def columnIndex(self, columnName:str)-> QModelIndex:
+    def columnIndex(self, columnName:str) ->  QModelIndex:
         c = self.mColumnNames.index(columnName)
         return self.createIndex(0, c)
 
diff --git a/eotimeseriesviewer/temporalprofiles.py b/eotimeseriesviewer/temporalprofiles.py
index bf15dcd7..45fb7732 100644
--- a/eotimeseriesviewer/temporalprofiles.py
+++ b/eotimeseriesviewer/temporalprofiles.py
@@ -100,7 +100,7 @@ def temporalProfileFeatureFields(sensor: SensorInstrument, singleBandOnly=False)
 
     return fields
 
-def sensorExampleQgsFeature(sensor:SensorInstrument, singleBandOnly=False)->QgsFeature:
+def sensorExampleQgsFeature(sensor:SensorInstrument, singleBandOnly=False) -> QgsFeature:
     """
     Returns an exemplary QgsFeature with value for a specific sensor
     :param sensor: SensorInstrument
@@ -548,7 +548,7 @@ class TemporalProfile(QObject):
 
         return other.mID == self.mID and self.mLayer == other.mLayer
 
-    def geometry(self, crs:QgsCoordinateReferenceSystem=None)->QgsGeometry:
+    def geometry(self, crs:QgsCoordinateReferenceSystem=None) -> QgsGeometry:
         """
         Returns the geometry
         :param crs:
@@ -567,7 +567,7 @@ class TemporalProfile(QObject):
         return g
 
 
-    def coordinate(self)->SpatialPoint:
+    def coordinate(self) -> SpatialPoint:
         """
         Returns the profile coordinate
         :return:
@@ -839,7 +839,7 @@ class TemporalProfilePlotStyleBase(PlotStyle):
         if isinstance(temporalProfile, TemporalProfile):
             self.setTemporalProfile(temporalProfile)
 
-    def showLastLocation(self)->bool:
+    def showLastLocation(self) -> bool:
         """
         """
         return self.mShowLastLocation
@@ -1392,7 +1392,7 @@ class TemporalProfileLayer(QgsVectorLayer):
         #styles.setRowStyles([red])
 
 
-    def createTemporalProfiles(self, coordinates, names:list=None)->list:
+    def createTemporalProfiles(self, coordinates, names:list=None) -> list:
         """
         Creates temporal profiles
         :param coordinates:
diff --git a/eotimeseriesviewer/tests.py b/eotimeseriesviewer/tests.py
index ad8052b2..b8d092b9 100644
--- a/eotimeseriesviewer/tests.py
+++ b/eotimeseriesviewer/tests.py
@@ -49,7 +49,7 @@ class EOTSVTestCase(TestCase):
         initQtResources(DIR_REPO)
         super().setUpClass()
 
-def testRasterFiles()->list:
+def testRasterFiles() -> list:
     return list(file_search(os.path.dirname(example.__file__), '*.tif', recursive=True))
 
 
@@ -75,7 +75,7 @@ class TestObjects(eotimeseriesviewer.externals.qps.testing.TestObjects):
         return TS
 
     @staticmethod
-    def createArtificialTimeSeries(n=100)->list:
+    def createArtificialTimeSeries(n=100) -> list:
         vsiDir = '/vsimem/tmp'
         d1 = np.datetime64('2000-01-01')
         print('Create in-memory test timeseries of length {}...'.format(n))
diff --git a/eotimeseriesviewer/timeseries.py b/eotimeseriesviewer/timeseries.py
index e4aa699b..cfce91f4 100644
--- a/eotimeseriesviewer/timeseries.py
+++ b/eotimeseriesviewer/timeseries.py
@@ -115,7 +115,7 @@ def convertMetricUnit(value, u1, u2):
     return value * 10**(e1-e2)
 
 
-def getDS(pathOrDataset)->gdal.Dataset:
+def getDS(pathOrDataset) -> gdal.Dataset:
     """
     Returns a gdal.Dataset
     :param pathOrDataset: str | gdal.Dataset | QgsRasterLayer
@@ -132,7 +132,7 @@ def getDS(pathOrDataset)->gdal.Dataset:
 
 
 
-def sensorID(nb:int, px_size_x:float, px_size_y:float, dt:int, wl:list, wlu:str, name:str)->str:
+def sensorID(nb:int, px_size_x:float, px_size_y:float, dt:int, wl:list, wlu:str, name:str) -> str:
     """
     Creates a sensor ID str
     :param nb: number of bands
@@ -166,7 +166,7 @@ def sensorID(nb:int, px_size_x:float, px_size_y:float, dt:int, wl:list, wlu:str,
                 }
     return json.dumps(jsonDict)
 
-def sensorIDtoProperties(idString:str)->tuple:
+def sensorIDtoProperties(idString:str) -> tuple:
     """
     Reads a sensor id string and returns the sensor properties. See sensorID().
     :param idString: str
@@ -262,7 +262,7 @@ class SensorInstrument(QObject):
 
 
 
-    def bandIndexClosestToWavelength(self, wl, wl_unit='nm')->int:
+    def bandIndexClosestToWavelength(self, wl, wl_unit='nm') -> int:
         """
         Returns the band index closets to a certain wavelength
         :param wl: float | int
@@ -281,7 +281,7 @@ class SensorInstrument(QObject):
             wl = convertMetricUnit(wl, wl_unit, self.wlu)
         return int(np.argmin(np.abs(self.wl - wl)))
 
-    def proxyLayer(self)->QgsRasterLayer:
+    def proxyLayer(self) -> QgsRasterLayer:
         """
         Creates an "empty" layer that can be used as proxy for band names, data types and render styles
         :return: QgsRasterLayer
@@ -292,7 +292,7 @@ class SensorInstrument(QObject):
         self.sigNameChanged.connect(lyr.setName)
         return lyr
 
-    def id(self)->str:
+    def id(self) -> str:
         """
         Returns the Sensor id
         :return: str
@@ -313,7 +313,7 @@ class SensorInstrument(QObject):
             self.mName = name
             self.sigNameChanged.emit(self.name())
 
-    def name(self)->str:
+    def name(self) -> str:
         """
         Returns the sensor name
         :return: str
@@ -331,7 +331,7 @@ class SensorInstrument(QObject):
     def __repr__(self):
         return str(self.__class__) +' ' + self.name()
 
-    def description(self)->str:
+    def description(self) -> str:
         """
         Returns a human-readable description
         :return: str
@@ -357,7 +357,7 @@ class SensorProxyLayer(QgsRasterLayer):
         super(SensorProxyLayer, self).__init__(*args, **kwds)
         self.mSensor = sensor
 
-    def sensor(self)->SensorInstrument:
+    def sensor(self) -> SensorInstrument:
         """
         Returns the SensorInstrument this layer relates to
         :return: SensorInstrument
@@ -535,11 +535,9 @@ class TimeSeriesSource(object):
             sName = sensorName(dataset)
             self.mSidOriginal = self.mSid = sensorID(self.nb, px_x, px_y, self.mDataType, self.mWL, self.mWLU, sName)
 
-
             self.mUL = QgsPointXY(*px2geo(QPoint(0, 0), self.mGeoTransform, pxCenter=False))
             self.mLR = QgsPointXY(*px2geo(QPoint(self.ns + 1, self.nl + 1), self.mGeoTransform, pxCenter=False))
 
-
     def __reduce_ex__(self, protocol):
 
         return self.__class__, (), self.__getstate__()
@@ -592,14 +590,14 @@ class TimeSeriesSource(object):
 
         self.__setstatedictionary(d)
 
-    def json(self)->str:
+    def json(self) -> str:
         """
         Returns a JSON representation
         :return:
         """
         return json.dumps(self.__statedictionary())
 
-    def name(self)->str:
+    def name(self) -> str:
         """
         Returns a name for this data source
         :return:
@@ -608,14 +606,14 @@ class TimeSeriesSource(object):
         return '{} {}'.format(bn, self.date())
 
 
-    def uri(self)->str:
+    def uri(self) -> str:
         """
         URI that can be used with GDAL to open a dataset
         :return: str
         """
         return self.mUri
 
-    def qgsMimeDataUtilsUri(self)->QgsMimeDataUtils.Uri:
+    def qgsMimeDataUtilsUri(self) -> QgsMimeDataUtils.Uri:
         uri = QgsMimeDataUtils.Uri()
         uri.name = self.name()
         uri.providerKey = 'gdal'
@@ -623,10 +621,10 @@ class TimeSeriesSource(object):
         uri.layerType = 'raster'
         return uri
 
-    def asRasterLayer(self)->QgsRasterLayer:
+    def asRasterLayer(self) -> QgsRasterLayer:
         return QgsRasterLayer(self.uri(), self.name(), 'gdal')
 
-    def pixelCoordinate(self, geometry)->QPoint:
+    def pixelCoordinate(self, geometry) -> QPoint:
         """
 
         :param QgsGeometry | QgsPoint | SpatialPoint:
@@ -647,7 +645,7 @@ class TimeSeriesSource(object):
             return None
         return px
 
-    def sid(self)->str:
+    def sid(self) -> str:
         """
         Returns the sensor id
         :return: str
@@ -668,7 +666,7 @@ class TimeSeriesSource(object):
         """
         self.mTimeSeriesDate = tsd
 
-    def date(self)->np.datetime64:
+    def date(self) -> np.datetime64:
         """
         Returns the date-time-group of the source image
         :return:
@@ -676,7 +674,7 @@ class TimeSeriesSource(object):
         """
         return self.mDate
 
-    def crs(self)->QgsCoordinateReferenceSystem:
+    def crs(self) -> QgsCoordinateReferenceSystem:
         """
         Returns the coordinate system as QgsCoordinateReferenceSystem
         :return:
@@ -684,7 +682,7 @@ class TimeSeriesSource(object):
         """
         return self.mCRS
 
-    def spatialExtent(self)->SpatialExtent:
+    def spatialExtent(self) -> SpatialExtent:
         """
         Returns the SpatialExtent
         :return:
@@ -694,7 +692,7 @@ class TimeSeriesSource(object):
             self.mSpatialExtent = SpatialExtent(self.mCRS, self.mUL, self.mLR)
         return self.mSpatialExtent
 
-    def asDataset(self)->gdal.Dataset:
+    def asDataset(self) -> gdal.Dataset:
         """
         Returns the source as gdal.Dataset
         :return:
@@ -702,7 +700,7 @@ class TimeSeriesSource(object):
         """
         return gdal.Open(self.uri())
 
-    def asArray(self)->np.ndarray:
+    def asArray(self) -> np.ndarray:
         """
         Returns the entire image as numpy array
         :return:
@@ -810,14 +808,14 @@ class TimeSeriesDate(QAbstractTableModel):
         """
         return self.mVisibility
 
-    def sensor(self)->SensorInstrument:
+    def sensor(self) -> SensorInstrument:
         """
         Returns the SensorInstrument
         :return: SensorInsturment
         """
         return self.mSensor
 
-    def sources(self)->typing.List[TimeSeriesSource]:
+    def sources(self) -> typing.List[TimeSeriesSource]:
         """
         Returns the source images
         :return: [list-of-TimeSeriesSource]
@@ -825,28 +823,28 @@ class TimeSeriesDate(QAbstractTableModel):
         return self.mSources
 
 
-    def sourceUris(self)->typing.List[str]:
+    def sourceUris(self) -> typing.List[str]:
         """
         Returns all source URIs  as list of strings-
         :return: [list-of-str]
         """
         return [tss.uri() for tss in self.sources()]
 
-    def qgsMimeDataUtilsUris(self)->list:
+    def qgsMimeDataUtilsUris(self) -> list:
         """
         Returns all source URIs as list of QgsMimeDataUtils.Uri
         :return: [list-of-QgsMimedataUtils.Uris]
         """
         return [s.qgsMimeDataUtilsUri() for s in self.sources()]
 
-    def date(self)->np.datetime64:
+    def date(self) -> np.datetime64:
         """
         Returns the observation date
         :return: numpy.datetime64
         """
         return np.datetime64(self.mDate)
 
-    def decimalYear(self)->float:
+    def decimalYear(self) -> float:
         """
         Returns the observation date as decimal year (year + doy / (366+1) )
         :return: float
@@ -854,14 +852,14 @@ class TimeSeriesDate(QAbstractTableModel):
 
         return self.year() + self.doy() / (366+1)
 
-    def year(self)->int:
+    def year(self) -> int:
         """
         Returns the observation year
         :return: int
         """
         return self.mDate.astype(object).year
 
-    def doy(self)->int:
+    def doy(self) -> int:
         """
         Returns the day of Year (DOY)
         :return: int
@@ -893,7 +891,7 @@ class TimeSeriesDate(QAbstractTableModel):
                 ext.combineExtentWith(tss.spatialExtent())
         return ext
 
-    def imageBorders(self)->QgsGeometry:
+    def imageBorders(self) -> QgsGeometry:
         """
         Retunrs the exact border polygon
         :return: QgsGeometry
@@ -901,14 +899,14 @@ class TimeSeriesDate(QAbstractTableModel):
 
         return None
 
-    def __repr__(self)->str:
+    def __repr__(self) -> str:
         """
         String representation
         :return:
         """
         return 'TimeSeriesDate({},{})'.format(str(self.mDate), str(self.mSensor))
 
-    def __eq__(self, other)->bool:
+    def __eq__(self, other) -> bool:
         """
         Tow TimeSeriesDate instances are equal if they have the same date, sensor and sources.
         :param other: TimeSeriesDate
@@ -931,14 +929,14 @@ class TimeSeriesDate(QAbstractTableModel):
         """
         return iter(self.mSources)
 
-    def __len__(self)->int:
+    def __len__(self) -> int:
         """
         Returns the number of source images.
         :return: int
         """
         return len(self.mSources)
 
-    def __lt__(self, other)->bool:
+    def __lt__(self, other) -> bool:
         """
         :param other: TimeSeriesDate
         :return: bool
@@ -996,14 +994,14 @@ class TimeSeriesDate(QAbstractTableModel):
         return None   
             
         
-    def id(self)->tuple:
+    def id(self) -> tuple:
         """
         :return: tuple
         """
         return (self.mDate, self.mSensor.id())
 
 
-    def mimeDataUris(self)->list:
+    def mimeDataUris(self) -> list:
         """
         Returns the sources of this TSD as list of QgsMimeDataUtils.Uris
         :return: [list-of-QgsMimeDataUtils]
@@ -1073,7 +1071,7 @@ class SensorMatching(enum.Flag):
         assert isinstance(flags, SensorMatching)
 
     @staticmethod
-    def tooltip(flags)->str:
+    def tooltip(flags) -> str:
         """
         Returns a multi-line tooltip for the flag set
         :param flags:
@@ -1194,7 +1192,7 @@ class TimeSeries(QAbstractItemModel):
                 self.dataChanged.emit(ul, lr, [Qt.CheckStateRole])
                 self.sigVisibilityChanged.emit()
 
-    def currentSpatialExtent(self)->SpatialExtent:
+    def currentSpatialExtent(self) -> SpatialExtent:
         """
         Returns the current spatial extent
         :return: SpatialExtent
@@ -1216,7 +1214,7 @@ class TimeSeries(QAbstractItemModel):
                 idx2 = self.index(idx.row(), self.columnCount()-1)
                 self.dataChanged.emit(idx, idx2, [Qt.BackgroundColorRole])
 
-    def findMatchingSensor(self, sensorID:str)->SensorInstrument:
+    def findMatchingSensor(self, sensorID:str) -> SensorInstrument:
         if isinstance(sensorID, str):
             nb, px_size_x, px_size_y, dt, wl, wlu, name = sensorIDtoProperties(sensorID)
 
@@ -1246,7 +1244,7 @@ class TimeSeries(QAbstractItemModel):
 
         return None
 
-    def sensor(self, sensorID:str)->SensorInstrument:
+    def sensor(self, sensorID:str) -> SensorInstrument:
         """
         Returns the sensor with sid = sid
         :param sensorID: str, sensor id
@@ -1265,7 +1263,7 @@ class TimeSeries(QAbstractItemModel):
         return None
 
 
-    def sensors(self)->typing.List[SensorInstrument]:
+    def sensors(self) -> typing.List[SensorInstrument]:
         """
         Returns the list of sensors derived from the TimeSeries data sources
         :return: [list-of-SensorInstruments]
@@ -1343,7 +1341,7 @@ class TimeSeries(QAbstractItemModel):
         return r
 
 
-    def maxSpatialExtent(self, crs=None)->SpatialExtent:
+    def maxSpatialExtent(self, crs=None) -> SpatialExtent:
         """
         Returns the maximum SpatialExtent of all images of the TimeSeries
         :param crs: QgsCoordinateSystem to express the SpatialExtent coordinates.
@@ -1376,7 +1374,7 @@ class TimeSeries(QAbstractItemModel):
                     return tsd
         return None
 
-    def tsd(self, date: np.datetime64, sensor)->TimeSeriesDate:
+    def tsd(self, date: np.datetime64, sensor) -> TimeSeriesDate:
         """
         Returns the TimeSeriesDate identified by date and sensorID
         :param date: numpy.datetime64
@@ -1396,7 +1394,7 @@ class TimeSeries(QAbstractItemModel):
                     return tsd
         return None
 
-    def insertTSD(self, tsd: TimeSeriesDate)->TimeSeriesDate:
+    def insertTSD(self, tsd: TimeSeriesDate) -> TimeSeriesDate:
         """
         Inserts a TimeSeriesDate
         :param tsd: TimeSeriesDate
@@ -1481,7 +1479,7 @@ class TimeSeries(QAbstractItemModel):
             self.checkSensorList()
             self.sigTimeSeriesDatesRemoved.emit(removed)
 
-    def tsds(self, date:np.datetime64=None, sensor:SensorInstrument=None)->typing.List[TimeSeriesDate]:
+    def tsds(self, date:np.datetime64=None, sensor:SensorInstrument=None) -> typing.List[TimeSeriesDate]:
 
         """
         Returns a list of  TimeSeriesDate of the TimeSeries. By default all TimeSeriesDate will be returned.
@@ -1527,7 +1525,7 @@ class TimeSeries(QAbstractItemModel):
         for sensor in to_remove:
             self.removeSensor(sensor)
 
-    def removeSensor(self, sensor:SensorInstrument)->SensorInstrument:
+    def removeSensor(self, sensor:SensorInstrument) -> SensorInstrument:
         """
         Removes a sensor and all linked images
         :param sensor: SensorInstrument
@@ -1662,7 +1660,7 @@ class TimeSeries(QAbstractItemModel):
             self.mLoadingProgressDialog = None
 
 
-    def _addSource(self, source:TimeSeriesSource)->TimeSeriesDate:
+    def _addSource(self, source:TimeSeriesSource) -> TimeSeriesDate:
         """
         :param source:
         :return: TimeSeriesDate (if new created)
@@ -1726,7 +1724,7 @@ class TimeSeries(QAbstractItemModel):
         self.mSensorMatchingFlags = flags
 
 
-    def date2date(self, date:np.datetime64)->np.datetime64:
+    def date2date(self, date:np.datetime64) -> np.datetime64:
         """
         Converts a date of arbitrary precision into the date with precision according to the EOTSV settions.
         :param date: numpy.datetime64
@@ -1752,7 +1750,7 @@ class TimeSeries(QAbstractItemModel):
 
 
 
-    def sourceUris(self)->list:
+    def sourceUris(self) -> list:
         """
         Returns the uris of all sources
         :return: [list-of-str]
@@ -1766,7 +1764,7 @@ class TimeSeries(QAbstractItemModel):
     def __len__(self):
         return len(self.mTSDs)
 
-    def __iter__(self)->typing.Iterator[TimeSeriesDate]:
+    def __iter__(self) -> typing.Iterator[TimeSeriesDate]:
         return iter(self.mTSDs)
 
     def __getitem__(self, slice):
@@ -1895,7 +1893,7 @@ class TimeSeries(QAbstractItemModel):
 
         return QModelIndex()
 
-    def tsdToIdx(self, tsd:TimeSeriesDate)->QModelIndex:
+    def tsdToIdx(self, tsd:TimeSeriesDate) -> QModelIndex:
         """
         Returns an QModelIndex pointing on a TimeSeriesDate of interest
         :param tsd: TimeSeriesDate
@@ -2035,7 +2033,7 @@ class TimeSeries(QAbstractItemModel):
                     return tssCandidate
         return None
 
-    def findDate(self, date)->TimeSeriesDate:
+    def findDate(self, date) -> TimeSeriesDate:
         """
         Returns a TimeSeriesDate closest to that in date
         :param date: numpy.datetime64 | str | TimeSeriesDate
@@ -2189,7 +2187,7 @@ class TimeSeriesTreeView(QTreeView):
 
 
 regSensorName = re.compile(r'(SATELLITEID|(sensor|product)[ _]?(type|name))', re.IGNORECASE)
-def sensorName(dataset:gdal.Dataset)->str:
+def sensorName(dataset:gdal.Dataset) -> str:
     """
     Reads the sensor/product name. Returns None if a proper name can not be extracted.
     :param dataset: gdal.Dataset
@@ -2237,7 +2235,7 @@ def getSpatialPropertiesFromDataset(ds):
 
     return nb, nl, ns, crs, px_x, px_y
 
-def extractWavelengthsFromGDALMetaData(ds:gdal.Dataset)->(list, str):
+def extractWavelengthsFromGDALMetaData(ds:gdal.Dataset) -> (list, str):
     """
     Reads the wavelength info from standard metadata strings
     :param ds: gdal.Dataset
@@ -2248,7 +2246,7 @@ def extractWavelengthsFromGDALMetaData(ds:gdal.Dataset)->(list, str):
     regWLUkey = re.compile('^wavelength[_ ]*units?$', re.I)
     regNumeric = re.compile(r"([-+]?\d*\.\d+|[-+]?\d+)", re.I)
 
-    def findKey(d:dict, regex)->str:
+    def findKey(d:dict, regex) -> str:
         for key in d.keys():
             if regex.search(key):
                 return key
@@ -2307,7 +2305,7 @@ def extractWavelengthsFromGDALMetaData(ds:gdal.Dataset)->(list, str):
 
 
 
-def extractWavelengthsFromRapidEyeXML(ds:gdal.Dataset, dom:QDomDocument)->(list, str):
+def extractWavelengthsFromRapidEyeXML(ds:gdal.Dataset, dom:QDomDocument) -> (list, str):
     nodes = dom.elementsByTagName('re:bandSpecificMetadata')
     # see http://schemas.rapideye.de/products/re/4.0/RapidEye_ProductMetadata_GeocorrectedLevel.xsd
     # wavelength and units not given in the XML
@@ -2324,7 +2322,7 @@ def extractWavelengthsFromRapidEyeXML(ds:gdal.Dataset, dom:QDomDocument)->(list,
     return None, None
 
 
-def extractWavelengthsFromDIMAPXML(ds:gdal.Dataset, dom:QDomDocument)->(list, str):
+def extractWavelengthsFromDIMAPXML(ds:gdal.Dataset, dom:QDomDocument) -> (list, str):
     """
     :param dom: QDomDocument | gdal.Dataset
     :return: (list of wavelengths, str wavelength unit)
@@ -2390,7 +2388,7 @@ def extractWavelengths(ds):
 
     elif isinstance(ds, gdal.Dataset):
 
-        def testWavelLengthInfo(wl, wlu)->bool:
+        def testWavelLengthInfo(wl, wlu) -> bool:
             return isinstance(wl, list) and len(wl) == ds.RasterCount and isinstance(wlu, str) and wlu in LUT_WAVELENGTH_UNITS.keys()
 
         # try band-specific metadata
@@ -2497,7 +2495,7 @@ class TimeSeriesDock(QgsDockWidget):
             isinstance(self.mSelectionModel, QItemSelectionModel) and
             len(self.mSelectionModel.selectedRows()) > 0)
 
-    def selectedTimeSeriesDates(self)->list:
+    def selectedTimeSeriesDates(self) -> list:
         """
         Returns the TimeSeriesDate selected by a user.
         :return: [list-of-TimeSeriesDate]
@@ -2512,7 +2510,7 @@ class TimeSeriesDock(QgsDockWidget):
                     results.append(tsd)
         return results
 
-    def timeSeries(self)->TimeSeries:
+    def timeSeries(self) -> TimeSeries:
         """
         Returns the connected TimeSeries
         :return: TimeSeries
-- 
GitLab