'''
/****************************************************************************************
* This is a python script for visualizing netCDF files using PyQt5 and matplotlib
* 
* The script is based on the QGIS plugin template by Gispo
* 
* 
****************************************************************************************/

/****************************************************************************************
* The program is free software; you can redistribute it and/or modify                   
* it under the terms of the GNU General Public License as published by                  
* the Free Software Foundation; either version 2 of the License, or                              
* at your option) any later version.                                                     
* 
* The script is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
* See the GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License along with this program. 
* If not, see http://www.gnu.org/licenses/.
****************************************************************************************/
'''
#we import the impotant libraries and modules
#always import the libraries and modules at the top of the code
from datetime import datetime
from json import load
from msilib.schema import tables
from PyQt5.QtCore import *  
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5 import uic

#we want to work with the os module
import os
#to import general tools from QGIS we need the qgis.core module
from qgis.core import *
from qgis.utils import iface


#for loading the netCDF files we need the netCDF4 module
try:
   from pip import main as pipmain
except ImportError:
   from pip._internal import main as pipmain

try:
   import netCDF4 as nc
except ImportError:
   pipmain(['install', 'netCDF4'])
   import netCDF4 as nc
   from netCDF4 import Dataset
   

#we need the matplotlib module to plot the data
import matplotlib.pyplot as plt
#we need gdal to work with the raster data 
from osgeo import osr, gdal, ogr
#we ned the numpy module to work with the data
import numpy as np


#we create the path to the ui file
#Path to the Ordner where the ui file is
ncvPath = os.path.dirname(__file__) #the comand dirname gives the path to the directory where the file is
#path to the ui file
#dosn't matter where the ui file is located in the directory 
uiPath = os.path.join(ncvPath, 'EBVCubeVisualizer.ui')

#TWO CLASES#    
# WIDEGT is a class for the GUI
# BASE is a PyQt5 class to insatalize the GUI
WIDGET, BASE = uic.loadUiType(uiPath)

class maskAndFuntionality (BASE, WIDGET):
    """Class for the mask and the funtionality of the netCDFVisualizer Plugin"""
    def __init__(self, iface):
        #self is GUI and mask
        QDialog.__init__(self, iface.mainWindow())
        self.setupUi(self)
        #self ist our GUI
        #the GUI is built in the running of QGIS in the current session (using the iface)
        """ Here is the place for the Clicked Signal"""
        self.btn_closePlugin.clicked.connect(self.closePlugin)
        self.btn_inputFile.clicked.connect(self.importData)
        self.btn_remove.clicked.connect(self.removePath)
        self.btn_load.clicked.connect(self.loadNetCDF)
        self.btn_load.clicked.connect(self.setMapData)
        self.btn_remove_sel.clicked.connect(self.removeSelection)
        self.tree_data.itemClicked.connect(self.showInfo)
        self.btn_plot.clicked.connect(self.displayData)
        
        """Here is the place for set stzlesheet"""
        #self.btn_plot.setStyleSheet("backgrou")

    def closePlugin(self):
        """This function closes the plugin"""
        #we close the plugin
        self.close()

    def importData(self):
        """This function imports the netCDF file"""
        #we get the path to the netCDF file
        path = QFileDialog.getOpenFileName(None,"select netCDF file", filter="*.nc")[0]
        #we set the path in the text space
        self.text_set.setText(path)

    def removePath(self):
        """This function removes the path from the text space"""
        self.text_set.clear()
        self.tree_data.clear()
        self.text_info.clear()
        self.cbox_entity.clear()
        self.cbox_time.clear()
        self.cbox_scenarios.clear()
        self.cbox_metric.clear()

    def removeSelection(self):
        """this function remove the selection in the tree widget"""
        #if the top level item is selected we remove the Item and the children as well text_info, cbox_entity and cbox_time
        if self.tree_data.currentItem().parent() == None:
            self.tree_data.takeTopLevelItem(self.tree_data.indexOfTopLevelItem(self.tree_data.currentItem()))
            self.text_info.clear()
            self.cbox_entity.clear()
            self.cbox_time.clear()
            self.cbox_scenarios.clear()
            self.cbox_metric.clear()
        #if the child item is selected we don't remove anything
        elif self.tree_data.currentItem() == None:
            pass

        else:
            pass
            

    def loadNetCDF(self):
        """This function loads the netCDF file and shows the variables, groups and the variables of the gorups in the QTreeWidget"""
        #we get the path from the text space
        if self.text_set.text()=="": #if the text space is empty
            QmessageBox.warning(None, "Warning", "Please select a netCDF file") #we show a warning
       
        else: #if the text space is not empty
            path = self.text_set.text() #we get the path from the text space
            ncFile = nc.Dataset(path, 'r', format='NETCDF4')
            ncFileName = os.path.basename(path)
            ncFileTitle = ncFile.title
            #convert file name and file title into a QTreeWidgetItem
            top_level = QTreeWidgetItem([ncFileName, ncFileTitle])
            #we get the variables of the netCDf file
            ncFileVariablesName = list(ncFile.variables.keys())
            ncFileGroupsName = list(ncFile.groups.keys())
  
            
            #we set the top of the tree that it is the name od the file
            self.tree_data.addTopLevelItem(top_level)
            
        
            #we show the groups of the file in the QTreeWidgetite
            for i in range(len(ncFileGroupsName)):
                longNameGroups = ncFile.groups[ncFileGroupsName[i]].long_name
                child = QTreeWidgetItem([ncFileGroupsName[i], longNameGroups])
                top_level.addChild(child)
                
                #we get the groups of the groups
                ncFileGroupsName2 = list(ncFile.groups[ncFileGroupsName[i]].groups.keys())
               
                #we show the groups of the groups in the QTreeWidgetite
                for j in range(len(ncFileGroupsName2)):
                    longNameGroups2 = ncFile.groups[ncFileGroupsName[i]].groups[ncFileGroupsName2[j]].long_name
                    child2 = QTreeWidgetItem([ncFileGroupsName2[j], longNameGroups2])
                    child.addChild(child2)
                        
                    #we get the variables of the groups of the groups
                    ncFileVariablesName2 = list(ncFile.groups[ncFileGroupsName[i]].groups[ncFileGroupsName2[j]].variables.keys())
                   
                    #we show the variables of the groups of the groups in the QTreeWidgetite an set the lon name of the variables
                    for k in range(len(ncFileVariablesName2)):
                        longNameVariables2 = ncFile.groups[ncFileGroupsName[i]].groups[ncFileGroupsName2[j]].variables[ncFileVariablesName2[k]].long_name
                        child3 = QTreeWidgetItem([ncFileVariablesName2[k], longNameVariables2])
                        child2.addChild(child3)

                #we get the variables of the groups
                ncFileGroupsVariablesName = list(ncFile.groups[ncFileGroupsName[i]].variables.keys())
                
                #we show the variables of the groups in the QTreeWidgetite and set the long name of the variables
                for j in range(len(ncFileGroupsVariablesName)):
                    longNameVariables = ncFile.groups[ncFileGroupsName[i]].variables[ncFileGroupsVariablesName[j]].long_name
                    child4 = QTreeWidgetItem([ncFileGroupsVariablesName[j],longNameVariables])
                    child.addChild(child4)
        
            
            #expand all the data 
            self.tree_data.expandAll()
            ncFile.close() #close the file
            
    def setMapData(self):
        """This function sets the entities, time, scenarios and metrics in the QComboBox"""
        #we clear the QComboBox
        self.cbox_entity.clear()
        self.cbox_time.clear()
        self.cbox_scenarios.clear()
        self.cbox_metric.clear()
        
        #we get the path from the text space
        path = self.text_set.text()
        ncFile = nc.Dataset(path, 'r', format='NETCDF4') 

        groups = list(ncFile.groups.keys()) #we get the metrics (name of the groups)
        groupsOfGroups = list(ncFile.groups[groups[0]].groups.keys()) #we get the scenarios(name of the groups of the groups)


        #set scenario and metric in the QComboBox  
        #if there is just groups we set the groups in the cbox_metric 
        self.cbox_metric.addItems(groups)
        self.cbox_scenarios.addItem("not scenarios")
        self.cbox_scenarios.setEnabled(False)
        
        if len(groupsOfGroups)>0:
            self.cbox_scenarios.setEnabled(True)
            self.cbox_scenarios.clear()
            self.cbox_scenarios.addItems(groups)
            self.cbox_metric.clear()
            self.cbox_metric.addItems(groupsOfGroups)
        else:
            pass

        #here we are gonna get the entities and the time of the netCDF file and set them into a QComboBox if the top level is clicked
        #we get the time of the netCDF file
        time = ncFile.variables['time']
        timeUnits = time.units
        timeCalendar = time.calendar
        time = nc.num2date(time[:], timeUnits, timeCalendar)
        time = [str(i).split(" ")[0] for i in time] #we leave just the date and not the time

        #we set the time into the QComboBox
        self.cbox_time.clear()
        self.cbox_time.addItems(time)
        
     
        #we get the entities
        self.cbox_entity.clear()
        entities = ncFile.variables['entity']
        
        #empty list
        entityDrop = []
        
        for i in range(len(entities)):
            entity = entities[i]
            entity = np.array(entity)
            entity = entity.tostring().decode('UTF-8').strip()
            #print(entity)
            #print(type(entity))
            entityDrop.append(entity)

        #set the entities inyo the cbox_enity
        self.cbox_entity.addItems(entityDrop)
        
        #check the number of entitites
        #entityNumber = len(entityDrop)
        #print(entityNumber)

        #we close the netCDF file
        ncFile.close()
        
    def showInfo(self):
        """show the attributes of the scenarios, metrics and variables"""
        self.text_info.clear()
        path = self.text_set.text() #we get the path from the text space
        ncFile = nc.Dataset(path, 'r', format='NETCDF4') #we open the netCDF file
        ncFileName = os.path.basename(path) 
        ncFileTitle = ncFile.title 
        globalAttributesName = list(ncFile.ncattrs())
        print(self.tree_data.currentItem().text(0))
        
        # here remove the info and add the attributes of the selected variable
        globalAttributesName.remove('title')
        globalAttributesName.remove('history')
        globalAttributesName.remove('Conventions')
        globalAttributesName.remove('date_issued')
        

        #groups could be scenarios or metrics
        scenarioOrMetric = list(ncFile.groups.keys())
        
        #first group is scenarios we get the metrics
        metrics = []
        for i in range(len(scenarioOrMetric)):
            metrics.append(list(ncFile.groups[scenarioOrMetric[i]].groups.keys()))

        #first group is metric we get the variables
        metricsVariables1 = [] 
        for i in range(len(scenarioOrMetric)):
            variables = list(ncFile.groups[scenarioOrMetric[i]].variables.keys())
            metricsVariables1.append(variables)
        
        #first group is scenario and second metric than we get the variables of metric
        metricsVariables2 = []
        for i in range(len(scenarioOrMetric)):
            metricsVariables2.append([])
            for j in range(len(metrics[i])):
                variables = list(ncFile.groups[scenarioOrMetric[i]].groups[metrics[i][j]].variables.keys())
                metricsVariables2[i].append(variables)
        
        #we print everthing
        # print('ScenarioOrMetric')
        # print(scenarioOrMetric)
        # print(metricsVariables1)
        # print('metrics')
        # print(metrics)
        # print(metricsVariables2)
        # print('len')
        # print(len(metricsVariables2))
        # print(len(metricsVariables2[0]))
        # #print('metricsVariables1[0]')
        # #print(metricsVariables1[0][0])
        # print('current item')
        # print(self.tree_data.currentItem().text(0))
        
        
        
        #set global attributes from the netCDF file
        if  self.tree_data.currentItem().text(0) == ncFileName:
            #print('global atts')
            self.text_info.clear()
            self.text_info.append("<b><font size=4>" + "File name: " + ncFileName + "</font></b>")
            self.text_info.append("<b><font size=4>" + "Title: " + ncFileTitle + "</font></b>")
            self.text_info.append("____________________________________________________________________________")
            self.text_info.append(" ")
            self.text_info.append("<b><font size=4>" +"Global attributes: " + "</font></b>")
            self.text_info.append(" ")
            for i in range(len(globalAttributesName)):
                attributes = ncFile.getncattr(globalAttributesName[i])
                #print(attributes)
                self.text_info.append("<b><font size=3>" + "-" + globalAttributesName[i] + ": " + "</font></b>" + str(attributes))
        
        #attributes of the groups. The groups are scenarios or metrics
        elif self.tree_data.currentItem().text(0) in scenarioOrMetric:
            #print('group atts: metric or scenario')
            self.text_info.append("<b><font size=4>" + "File name: " + ncFileName + "</font></b>")
            self.text_info.append("<b><font size=4>" + "Title: " + ncFileTitle + "</font></b>")
            self.text_info.append("________________________________________________________________________________")
            self.text_info.append(" ")

            #Scenario or Metric
            #name and standard name of the groups (scenarios or metrics)
            groupName = self.tree_data.currentItem().text(0)
            #print ('scenarioName' + groupName)
            groupStandardName = ncFile.groups[groupName].getncattr('standard_name')
            #print ('scenarioStandardName: ' + groupStandardName)

            #attributes of the groups (scenarios or metrics)
            self.text_info.append("<b><font size=4>" + "Attributes of the Scenario: " + "</font></b>" + groupStandardName)
            self.text_info.append(" ")

            #name attributes of the groups (scenarios or metrics)
            groupAttributesName = list(ncFile.groups[groupName].ncattrs())
            groupAttributesName.remove('standard_name')
            #print ('groupAttributesName: ' + str(groupAttributesName))

            #value of the attributes of the groups
            for i in range(len(groupAttributesName)):
                groupAttributes = ncFile.groups[groupName].getncattr(groupAttributesName[i])
                #print ('groupAttributes: ' + str(groupAttributes))
                self.text_info.append("<b><font size=3>" + "-" + groupAttributesName[i] + ": " + "</font></b>" + str(groupAttributes))
            
        
        #groups of the scenarios are always metric
        elif self.tree_data.currentItem().text(0) in metrics[0]:
            #print('test metric')
            self.text_info.clear()
            self.text_info.append("<b><font size=4>" + "File name: " + ncFileName + "</font></b>")
            self.text_info.append("<b><font size=4>" + "Title: " + ncFileTitle + "</font></b>")
            self.text_info.append("________________________________________________________________________________")
            self.text_info.append(" ")

            #Scenarios
            #get the standard name of the scenario
            scenarioName = self.tree_data.currentItem().parent().text(0)
            #print ("standard name: " + scenarioName)            
            scenarioStandardName = ncFile.groups[scenarioName].getncattr('standard_name')
            #print ("scenario standard name: " + scenarioStandardName)
            
            #attributes of the scenario
            self.text_info.append("<b><font size=4>" + "Attributes of the Scenario: " + "</font></b>" + scenarioStandardName)
            self.text_info.append(" ")
            
            #name of the attributes of the scenario
            attributesNameScenario = ncFile.groups[scenarioName].ncattrs()
            attributesNameScenario.remove('standard_name')
            #print ("attributes name: " + str(attributesNameScenario))

            #value of the attributes of the scenario
            for i in range(len( attributesNameScenario)):
                attributes = ncFile.groups[scenarioName].getncattr(attributesNameScenario[i])
                self.text_info.append("<b><font size=3>" + "-" + attributesNameScenario[i] + ": " + "</font></b>" + str(attributes))
            self.text_info.append("________________________________________________________________________________")
            self.text_info.append(" ")
            
            #Metrics
            #get name and standard name of the metric
            metricName = self.tree_data.currentItem().text(0)
            print ("metric name: " + metricName)
            metricStandardName = ncFile.groups[scenarioName].groups[metricName].getncattr('standard_name')
            print ("metric standard name: " + metricStandardName)
    
            self.text_info.append("<b><font size=4>" + "Attributes of the Metric: " + "</font></b>" + metricStandardName)
            self.text_info.append(" ")
            
            #get the name of the attributes of the metric
            attributesNameMetric = ncFile.groups[scenarioName].groups[metricName].ncattrs()
            print ("attributes name metric: " + str(attributesNameMetric))
            #attributesNameMetric.remove('standard_name')
            
            for i in range(len(attributesNameMetric)):
                attributes = ncFile.groups[scenarioName].groups[metricName].getncattr(attributesNameMetric[i])
                print ("attributes: " + str(attributes))
                self.text_info.append("<b><font size=3>" + "-" + attributesNameMetric[i] + ": " + "</font></b>" + str(attributes))
            
        
        #varibles of the metric, when there is scenarios
        elif len(metricsVariables2[0])!= 0 :
            if self.tree_data.currentItem().text(0) in metricsVariables2[0][0]:
                #print('test')
                self.text_info.clear()
                self.text_info.append("<b><font size=4>" + "File name: " + ncFileName + "</font></b>")
                self.text_info.append("<b><font size=4>" + "Title: " + ncFileTitle + "</font></b>")
                self.text_info.append("________________________________________________________________________________")
                self.text_info.append(" ")
                
                #Scenario
                #get the name of the scenario and 
                scenarioName = self.tree_data.currentItem().parent().parent().text(0)
                #print('scenario Name: ' + str(scenarioName))
                scenarioStandardName = ncFile.groups[scenarioName].getncattr('standard_name')
                #print('scenario Standard Name: ' + str(scenarioStandardName))
                
                #attributes of the scenario
                self.text_info.append("<b><font size=4>" + "Attributes of the Scenario: " + "</font></b>" + scenarioStandardName)
                self.text_info.append(" ")

                #get the name of the attributes of the scenario
                attributesNameScenario = ncFile.groups[scenarioName].ncattrs()
                attributesNameScenario.remove('standard_name')
                #print(attributesNameScenario)
                
                #get the value of the attributes of the scenario
                for i in range(len(attributesNameScenario)):
                    attributesScenario = ncFile.groups[scenarioName].getncattr(attributesNameScenario[i])
                    #print(attributesScenario)
                    self.text_info.append("<b><font size=3>" + "-" + attributesNameScenario[i] + ": " + "</font></b>" + str(attributesScenario))
                self.text_info.append("________________________________________________________________________________")
                self.text_info.append(" ")
                
                #Metric
                #get the name of the metric
                metricName = self.tree_data.currentItem().parent().text(0)
                #print('metric Name: ', metricName)
                metricStandardName = ncFile.groups[scenarioName].groups[metricName].getncattr('standard_name')
                #print('metric standard name: ', metricStandardName)
                
                #attributes of the metric
                self.text_info.append("<b><font size=4>" + "Attribuites of the Metric: " + "</font></b>" + metricStandardName) 
                self.text_info.append(" ")

                #get the name of the attributes of the metric
                attributesNameMetric = ncFile.groups[scenarioName].groups[metricName].ncattrs()
                attributesNameMetric.remove('standard_name')
                #print('Attributes name metric: ', attributesNameMetric)
      
                #get the value of the attributes of the metric
                for i in range(len(attributesNameMetric)):
                    attributesMetric = ncFile.groups[scenarioName].groups[metricName].getncattr(attributesNameMetric[i])
                    #print ('Attributes metric: ', attributesMetric)
                    self.text_info.append("<b><font size=3>" + "-" + attributesNameMetric[i] + ": " + "</font></b>" + str(attributesMetric))
                self.text_info.append("___________________________________________________________________________")
                self.text_info.append(" ")
                
                #EBV Cube
                #attributes of the EBV Cube
                self.text_info.append("<b><font size=4>" + "Attributes of the EBV Cube:" + "</font></b>")
                self.text_info.append(" ")
                
                #get the name of the attributes of the EBV Cube
                variableName = self.tree_data.currentItem().text(0)
                #print(variableName)
                attributesNameCube = ncFile.groups[scenarioName].groups[metricName].variables[variableName].ncattrs()
                attributesNameCube.remove('_FillValue')
                attributesNameCube.remove('grid_mapping')
                attributesNameCube.remove('coordinate')
                #print('attributes name EBV Cube: ', attributesNameCube)
                
                #get the value of the attributes of the EBV Cube
                for i in range(len(attributesNameCube)):
                    attributesCube = ncFile.groups[scenarioName].groups[metricName].variables[variableName].getncattr(attributesNameCube[i])
                    #print('attributes cube: ', attributesCube)
                    self.text_info.append("<b><font size=3>" + "-" + attributesNameCube[i] + ": " + "</font></b>" + str(attributesCube))
    
                #we get the _FillValue
                fillValue = ncFile.groups[scenarioName].groups[metricName].variables[variableName].getncattr('_FillValue')
                #print('fill value: ', fillValue)
                self.text_info.append("<b><font size=3>" + "-" + "Nodata_value: " + "</font></b>" + str(fillValue))
                


        #if the groups are just metrics we get the variables of the metrics
        elif self.tree_data.currentItem().text(0) == metricsVariables1[0][0]:
            #print('ebv cube when ther is just metric')
            self.text_info.clear()
            self.text_info.append("<b><font size=4>" + "File name: " + ncFileName + "</font></b>")
            self.text_info.append("<b><font size=4>" + "Title: " + ncFileTitle + "</font></b>")
            self.text_info.append("___________________________________________________________________________")
            self.text_info.append(" ")

            #Metric
            #name of the metrics and the standard name
            metricName = self.tree_data.currentItem().parent().text(0)
            #print('metric name: ' + metricName)
            standardMetricName = ncFile.groups[metricName].getncattr('standard_name')
            #print('standard Metric Name: ' + standardMetricName)
            
            #attributes of the metric
            self.text_info.append("<b><font size=4>" + "Attributes of Metric: " + "</font></b>" + standardMetricName )
            self.text_info.append(" ")

            #name of the attributes of the metric
            attributesNameMetric = ncFile.groups[metricName].ncattrs()
            #print('attributesNameCube: ', attributesNameMetric)
            attributesNameMetric.remove('standard_name')
            
            for i in range(len(attributesNameMetric)):
                attributesMetric = ncFile.groups[metricName].getncattr(attributesNameMetric[i])
                self.text_info.append("<b><font size=3>" + "-" + attributesNameMetric[i] + ": " + "</font></b>" + str(attributesMetric))
            self.text_info.append("___________________________________________________________________________")
            self.text_info.append(" ")

            #EBV Cube
            #Attributes of the EBV Cube
            self.text_info.append("<b><font size=4>" + "Attributes of the EBV Cube: " + "</font></b>")
            self.text_info.append(" ")

            #name of the EBV Cube
            cubeName = self.tree_data.currentItem().text(0)
            #print('variable name: ' + cubeName)
            attributesNameCube = ncFile.groups[metricName].variables[cubeName].ncattrs()
            attributesNameCube.remove('_FillValue')
            attributesNameCube.remove('grid_mapping')
            attributesNameCube.remove('coordinate')
            #print('attributesNameCube: ', attributesNameCube)

            #get the value of the attributes of the EBV Cube
            for i in range(len(attributesNameCube)):
                attributesCube = ncFile.groups[metricName].variables[cubeName].getncattr(attributesNameCube[i])
                #print ('attributesCube: ' + attributesCube)
                self.text_info.append("<b><font size=3>" + "-" + attributesNameCube[i] + ": " + "</font></b>" + str(attributesCube))

            #set NoData_value
            fillValue = ncFile.groups[metricName].variables[cubeName].getncattr('_FillValue')
            #print ('fillValue: ', fillValue)
            self.text_info.append("<b><font size=3>" + "-" + "nodata_value: " + "</font></b>" + str(fillValue))
            #print ('Eres la mera verga!! sigue asi. Todo sladrá bien en el futuro')
        
        # we close the netCDF file
        ncFile.close()



    def displayData(self):
        """this fuction get the data of each ebv_cube and add it to the map"""
        
        #we get the path from the text space
        path = self.text_set.text() 
        ncFile = nc.Dataset(path, 'r', format='NETCDF4') 
        
    
        #time
        #we get the time 
        time = ncFile.variables['time']
        timeUnits = time.units 
        timeCalendar = time.calendar
        time = nc.num2date(time[:], timeUnits, timeCalendar)
        time = [str(i).split(" ")[0] for i in time] #we have to convert the time into a string
        max_time = len(time) #we get the length of the time
      
        #time selected in the QComboBox
        timeSelected = self.cbox_time.currentText()
        timeIndex = time.index(timeSelected) #we get the index of the time selected
        

        #Entity
        #we get the entities
        entities = ncFile.variables['entity']
        entityDrop = []
        for i in range(len(entities)):
            entity = entities[i]
            entity = np.array(entity)
            entity = entity.tostring().decode('UTF-8').strip()
            entityDrop.append(entity)

        #check the number of entitites
        #entityNumber = len(entityDrop)
        #print(entityNumber)
 
        #entity selected in the QComboBox
        entitySelected = self.cbox_entity.currentText()
        entityIndex = entityDrop.index(entitySelected) #we get the index of the entity selected
        
        
        #get the scenarios and the metrics from the interface
        #scenarios
        scenarioSelected = self.cbox_scenarios.currentText()
        scenarioIndex = self.cbox_scenarios.currentIndex()
        scenarioIndex = scenarioIndex + 1
        
        #metrics
        metricSelected = self.cbox_metric.currentText()
        metricIndex = self.cbox_metric.currentIndex()
        
        
        
        #if there just metrics and no scenarios we have to create a uri with the metric selected in the QComboBox
        if self.cbox_scenarios.isEnabled() == True:
            uri = r'NETCDF:'+ path + ':'+ scenarioSelected + '/' + metricSelected + '/ebv_cube'
            uri = str(uri)
            # print(uri)
            # print("entity Index: " + str(entityIndex+1))
            # print("scenarioSelected: " + str(scenarioSelected))
            # print("metricsSelected: " + str(metricSelected))
            
        else:
            uri = r'NETCDF:'+ path + ':' + metricSelected + '/ebv_cube'
            uri = str(uri)
            # print(uri)
            # print("entity Index: " + str(entityIndex+1))
            # print("metricsSelected: " + str(metricSelected))
        
        
        #here we create the name of the layer
        if self.cbox_scenarios.isEnabled() == True:
            standardName = ncFile.groups[scenarioSelected].groups[metricSelected].getncattr('standard_name')
        else:
            standardName = ncFile.groups[metricSelected].getncattr('standard_name')
            
        entitySelected = self.cbox_entity.currentText()
        timeSelected = self.cbox_time.currentText() 
        rasterName = standardName + "_entity: " + entitySelected + "_time: " + timeSelected
        
        #load the raster layer into the QGIS canvas
        rasterLayer = QgsRasterLayer(uri, rasterName)
        

        #calculate the band number
        realEntityIndex = entityIndex + 1
        realTimeIndex = timeIndex + 1
        band = (realEntityIndex-1)*max_time + realTimeIndex
        
        
        #get the min and the max value of the band
        dp = rasterLayer.dataProvider()
        stats = dp.bandStatistics(band)
        min = stats.minimumValue
        max = stats.maximumValue

        #build the color ramp
        colorRamp = QgsColorRampShader(min, max)
        colorRamp.setColorRampType(QgsColorRampShader.Interpolated)
        colorRamp.setColorRampItemList([QgsColorRampShader.ColorRampItem(min, QColor(0, 0, 255)), 
                                        QgsColorRampShader.ColorRampItem(max, QColor(255, 0, 0))])
        #build the shader
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(colorRamp)

        #build the renderer
        renderer = QgsSingleBandPseudoColorRenderer(rasterLayer.dataProvider(), band, shader) #we have to put the band number
        rasterLayer.setRenderer(renderer)   

        #add the raster layer to the map
        QgsProject.instance().addMapLayer(rasterLayer)

        #close the netCDF file
        ncFile.close()