        ##########################################
        ####                                 ##### 
        ####    download_seasonal_data.R     #####
        ####                                 #####
        ##########################################

##### This script can be used as an example to download seasonal 
##### data from the CDS - Climate data store (https://cds.climate.copernicus.eu/#!/home)
##### through R. It is called by the main vignette if the parameter 
##### data_stored is set to FALSE.





# The download should be over an extended region to ensure
# that the regrid conducted to match the grids between
# observations and hindcast is done correctly. We extend by 8 
# degrees each one of the region limits (as the parameter transform_extra_cells 
# used when regriding is set to 8)

lons.min_download <- lons.min - transform_extra_cells
lons.max_download <- lons.max + transform_extra_cells
lats.min_download <- lats.min - transform_extra_cells
lats.max_download <- lats.max + transform_extra_cells



##########################################
####                                 ##### 
####   DEFINITION OF THE FUNCTIONS   #####
####                                 #####
##########################################


#separates the month and the year to make properly the request of the download to the CDS 
get_month_year <-function(date){

        ####Fer un diccionari de variables 
        month<-substr(date,5,6)
        year <-substr(date,1,4)

        return(list(month,year))
}


# Main function that allows downloading the seasonal data from the 
# CDS and storing it in your computer (or in the binder environment),
# having the resulting netcfs the names and format needed to calibrate seasonal data through the vignette.
# It is set to allow donloading both, monthly hindcast and monthly observations.  
download_seasonal_R <-function(month,year,variable,type){

    switch (tolower(variable),
          "t2m"     = {var_name_cds <- '2m_temperature'},
          "tasmax"     = {var_name_cds <- '2m_temperature'},
          "tasmin"     = {var_name_cds <- '2m_temperature'},
          "prlr"     = {var_name_cds <- '2m_temperature'},
          "sfcwind"= {var_name_cds <- '2m_temperature'},
          "solarradiation"= {var_name_cds <- '2m_temperature'})

    # The parameters used when requesting the data are set
    # depending on whether the type is set to obs (observations)
    # or hcst (hindcast) 
    switch (tolower(type),
          "obs"     = {dataset_short_name <- "reanalysis-era5-single-levels-monthly-means"; product_type <- "monthly_averaged_reanalysis";
                       outdir = paste0("./esarchive/recon/ecmwf/era5/monthly_mean/downloaded/",variable,"-r1440x721cds/");
                       outfile =paste0(variable,"_",year,month,".nc")},

          "hcst"     = {dataset_short_name <- "seasonal-monthly-single-levels"; product_type <- "monthly_mean";
                        leadtime_month<-seq(1,length(forecast_time)); system <-"5"; originating_centre <- "ecmwf";
                        outdir = paste0("./esarchive/exp/ecmwf/system5c3s/monthly_mean/downloaded/",variable);
                        outfile =paste0(variable,"_",year,month,"01.nc")}) 

    # create the directory where the data will be stored
    dir.create(
      outdir,
      showWarnings = TRUE,
      recursive = TRUE,
      mode = "0777"
    )

    #The download request is defined 
    if (tolower(type) == "obs")
    {
            request <- list(
            dataset_short_name = dataset_short_name,
            product_type   = product_type,
            format = "netcdf",
            variable = var_name_cds,
            year=year,
            month=month,
            time = c("00:00"),
            # area is specified as N, W, S, E
            area = c(lats.max_download, lons.min_download, lats.min_download, lons.max_download),
            target = outfile)

    } else{
            request <- list(
            dataset_short_name = dataset_short_name,
            system = system,
            originating_centre = originating_centre,
            leadtime_month = c("1","2","3"),
            product_type   = product_type,
            format = "netcdf",
            variable = var_name_cds,
            year=year,
            month=month,
            # area is specified as N, W, S, E
            area = c(lats.max_download, lons.min_download, lats.min_download, lons.max_download),
            target = outfile)
    }
    
    #The download request is sent to the CDS server 
    file <- wf_request(user = user_cds,
                         request = request,
                         transfer = TRUE,
                         path =outdir,
                         verbose = TRUE)



}

# Function that calls the main downloading function download_seasonal_R
.download_seasonal_R <- function(type,dates_to_download)
{

for (fcst_time in (1:length(dates_to_download$month[1,])))
{
        for (year in (1:length(sdate_forecast)))
        {
                download_seasonal_R(month=dates_to_download$month[year,fcst_time],year=dates_to_download$year[year,fcst_time],
                                    variable=var_name,type=type)
        }
}

}


##########################################
####                                 ##### 
####         FUNCTIONS CALL          #####
####                                 #####
##########################################


# First the dates as it will be shown in each netcdf are defined

## Creating empty arrays with the 
## dimensions defined by the 
## initial parameters
netcdf_obs_dates <-array(numeric(),c(sdate=length(sdate_forecast),time=length(forecast_time)))
netcdf_hcst_dates <-array(numeric(),c(sdate=length(sdate_forecast),time=1))
netcdf_hcst_dates[,1]<-sdate_forecast

# Filling the arrays
for(fcst_time in (1:length(forecast_time)))
{
        dates_lt<-as.Date(paste0(sdate_forecast,"01"),format="%Y%m%d") %m+% months(forecast_time[fcst_time]) %m-% months(1)
        dates_lt<-format(dates_lt,"%Y%m%d") 
        dates_lt <-substr(dates_lt,1,6)
        netcdf_obs_dates[,fcst_time]<-dates_lt             

}

# Call of the function "get_month_year"
dates_to_download_obs<-multiApply::Apply(data = list(date=netcdf_obs_dates),target_dims =c("sdate","time"), fun = get_month_year)     
names(dates_to_download_obs)<-c("month","year")
 
dates_to_download_hcst<-multiApply::Apply(data = list(date=netcdf_hcst_dates),target_dims =c("sdate","time"), fun = get_month_year)
names(dates_to_download_hcst)<-c("month","year")


## Calling the downloading fuctions
.download_seasonal_R(type="hcst",dates_to_download=dates_to_download_hcst)
.download_seasonal_R(type="obs",dates_to_download=dates_to_download_obs)


