
# Creation:  6/2016
# Author: Nicola Cortesi
# Aim: To compute the four Euro-Atlantic weather regimes from a reanalysis or from a forecast system
#
# I/O: input must be in a format compatible with Load(); 1 output .RData file is created in the 'workdir' folder.
#      You can also run this script from terminal with: Rscript ~/scripts/weather_regimes_maps.R
#
# Assumption:  its output are needed by the scripts weather_regimes_impact.R and  weather_regimes.R
#
# Branch: weather_regimes

rm(list=ls())
library(s2dverification)  # for the function Load()
library(abind)
library(reshape2) # after each update of s2dverification, it's better to remove and install this package again because sometimes it gets broken! 

SMP <- FALSE   # if TRUE, the script is assumed to run on the SMP Machine
if(SMP){
   source('/gpfs/projects/bsc32/bsc32842/Rfunctions.R')
   workdir <- "/gpfs/projects/bsc32/bsc32842/RESILIENCE"  # working dir where output files will be generated
} else {
   source('/home/Earth/ncortesi/scripts/Rfunctions.R')
   workdir <- "/scratch/Earth/ncortesi/RESILIENCE/Regimes"  # working dir where output files will be generated
}

# module load NCO # : load it from the terminal before running this script interactively in the SMP machine, if you didn't load it in the .bashrc

f6h <- TRUE  # set if suffix "_f6h" is present in the file name or not (set it always to TRUE except if rean = JRA55 and psl = "z500")

# available reanalysis for the geopotential (g500) or the geopotential height (z500 = g500/9.81) and for var data:
ERAint <- '/esnas/recon/ecmwf/erainterim/$STORE_FREQ$_mean/$VAR_NAME$_f6h/$VAR_NAME$_$YEAR$$MONTH$.nc'
#ERAint <- '/esarchive/old-files/recon_ecmwf_erainterim/$STORE_FREQ$_mean/$VAR_NAME$_f6h/$VAR_NAME$_$YEAR$$MONTH$.nc'
ERAint <- '/esnas/recon/ecmwf/erainterim/6hourly/$VAR_NAME$/$VAR_NAME$_$YEAR$$MONTH$.nc'   # subdaily data!!!!!
ERAint.name <- "ERA-Interim"

JRA55 <- '/esnas/recon/jma/jra55/$STORE_FREQ$_mean/$VAR_NAME$_f6h/$VAR_NAME$_$YEAR$$MONTH$.nc'
JRA55.name <- "JRA-55"

NCEP <- '/esnas/recon/noaa/ncep-reanalysis/$STORE_FREQ$_mean/$VAR_NAME$_f6h/$VAR_NAME$_$YEAR$$MONTH$.nc'
NCEP.name <- "NCEP"

rean <- JRA55 #JRA55 #ERAint #NCEP  # choose one of the two above reanalysis from where to load the input psl data

# available forecast systems for the psl and var data:
#ECMWF_S4 <- list(path = paste0('/esnas/exp/ECMWF/seasonal/0001/s004/m001/$STORE_FREQ$_mean/$VAR_NAME$_f6h/$VAR_NAME$_$START_DATE$.nc'))
#ECMWF_S4 <- '/esnas/exp/ECMWF/seasonal/0001/s004/m001/$STORE_FREQ$_mean/psl_f6h/psl_$START_DATE$.nc'
ECMWF_S4 <- '/esnas/exp/ecmwf/system4_m1/$STORE_FREQ$_mean/$VAR_NAME$_f6h/$VAR_NAME$_$START_DATE$.nc'
ECMWF_S4.name <- "ECMWF-S4"
member.name <- "ensemble"   # name of the dimension with the ensemble members inside the netCDF files of S4

ECMWF_monthly <- '/esnas/exp/ECMWF/monthly/ensforhc/6hourly/$VAR_NAME$/2014$MONTH$$DAY$00/$VAR_NAME$_$START_DATE$00.nc'
ECMWF_monthly.name <- "ECMWF-Monthly"

# choose a forecast system:
forecast <- ECMWF_S4  

# put 'rean' to load pressure fields and var from reanalisis, or put 'forecast' to load them from forecast systems:
fields <- rean #forecast  

psl <- "psl" # "psl" #"g500"                           # pressure variable to use from the chosen reanalysis
psl.name <- "SLP" # "Z500"                     # the name to show in the maps

year.start <- 1981 #1979 #1981 #1982 #1981 #1994 #1979 #1981
year.end <- 2017 #2017 #2015

year.end.clim <- year.end - 1 # last year for computation of climatology (unless year.end has data available for all months, it's better to set it to the previous year)

LOESS <- TRUE              # To apply the LOESS filter or not to the climatology
running.cluster <- FALSE   # add to the clustering also the daily SLP data of the two closer months to the month to use (only for monthly analysis)
running.15 <- FALSE        # add to the clustering also the daily SLP data of the 15 days of the two closer months (only for monthly analysis). You cannot set to TRUE both
                                        # this variable and 'running.cluster' above
lat.weighting <- TRUE      # set it to true to weight psl data on latitude before applying the cluster analysis
subdaily <- FALSE           # id TRUE, compute the clustering using 6-hourly data instead of daily data, to be more robust (only for reanalysis with 6-hourly data avail.)

sequences <-FALSE          # set it to TRUE if you want to select only days beloning to sequences of at least 5 consecutive days belonging to the same regime.
PCA <- FALSE                # set it to TRUE if you want to apply the PCA before the k-means cluster analysis, FALSE otherwise
variance.explained <- 0.8  # the user can set here the minimum % of variance explained by the PCs (typically 0.8 which is equal to 80%)

# Coordinates of the box enclosing the study region (the Northern Atlantic in this case):
lat.max <- 81 #81 #80 #70
lat.min <- 27 #30 #20 #30
lon.max <- 45 #36 #30 #40 
lon.min <- 274.5 #274.5 #270 #280 # put a positive number here because the geopotential has only positive vaues of longitud!

# Only for reanalysis:
WR.period <- 2 # 13:16 #1:12 #13:16  # 1-12: Jan-Dec; 13-16: Winter-Spring-Summer-Autumn  [bypassed by the optional argument of the script]

# Only for Seasonal forecasts:
startM <- 1                                      # start month (1=January, 12=December)  [bypassed by the optional arguments of the script]
leadM <- 0                                       # select only the data of one lead month:  [bypassed by the optional arguments of the script]
n.members <- 15                                  # number of members of the forecast system to load
n.leadtimes <- 216                               # number of leadtimes of the forecast system to load
missing.forecasts <- FALSE # set it to TRUE if there can be missing hindcasts files in the forecast psl data, so it will load only the available years and deals with NA
res <- 0.75                # set the resolution you want to interpolate the seasonal psl and var data when loading it (i.e: set to 0.75 to use the same res of ERA-Interim)
                           # interpolation method is BILINEAR.

# Only for Monthly forecasts:
#leadtime <- 1:7 #5:11 #1                        # if fields=forecast, set the forecast time (in days) you want to compute the weather regimes.
#startdate.shift <- 1                            # if leadtime=5:11, it's better to shift all startdates of the season 1 week in the past, to fit the exact season of obs.data
                                                 # if leadtime=12:18, it's better to shift all startdates of the season 2 weeks in the past, and so on.
#forecast.year <- year.end+1                     # if fields=forecast, set the forecast year (it is usually the year after year.end)
#mes=1                                           # if fields=forecast, set the month of the first startdate of the forecast year
#day=2                                           # if fields=forecast, set the day of the first startdate of the forecast year

#############################################################################################################################
rean.name <- unname(ifelse(rean == ERAint, ERAint.name, ifelse(rean == JRA55, JRA55.name, NCEP.name)))
forecast.name <- unname(ifelse(forecast == ECMWF_S4, ECMWF_S4.name, ECMWF_monthly.name))
fields.name <- unname(ifelse(fields == rean, rean.name, forecast.name))
n.years <- year.end - year.start + 1
n.years.clim <- year.end.clim - year.start + 1

if(running.cluster && running.15) stop("both 'running.cluster' and 'running.15' cannot be TRUE simultaneously")

if(!f6h) { pos <- regexpr("_f6h", fields); my.string <- strsplit(fields, "_f6h") ; fields <- paste0(my.string[[1]][1],my.string[[1]][2]) } # remove _f6h from filename

# in case the script is run with one argument, it is assumed a reanalysis is being used and the argument becomes the month we want to perform the clustering;
# in case the script is run with two arguments, it is assumed a forecast is used and the first argument represents the startmonth and the second one the leadmonth.
# in case the script is run with no arguments, the values of the variables inside the script are used:
script.arg <- as.integer(commandArgs(TRUE))

if(length(script.arg) == 0){
   start.month <- startM
   #WR.period <- start.month
   if(fields.name == forecast.name) lead.month <- leadM
}

# in case the script is run with 1 argument, it is assumed you are using a reanalysis:
if(length(script.arg) == 1){
   fields <- rean
   fields.name <- rean.name
   WR.period <-  script.arg[1]      
}

if(length(script.arg) >= 2){
   fields <- forecast
   fields.name <- forecast.name
   start.month <- script.arg[1]                 
   lead.month <- script.arg[2]
   WR.period <- start.month
}

if(length(script.arg) == 3){ # in this case, we are running the script in the SMP machine and we need to override the variables below:
   source('/gpfs/projects/bsc32/bsc32842/Rfunctions.R') # for the calendar function
   workdir <- "/gpfs/projects/bsc32/bsc32842/RESILIENCE"  # working dir
}

if(length(script.arg) >= 2) {lead.comment <- paste0("Lead month: ", lead.month)} else {lead.comment <- ""}
cat(paste0("Field: ", fields.name, " Period: ", WR.period, " ", lead.comment, "\n"))

if(lat.min >= lat.max) stop("lat.min cannot be greater than lat.max")

#days.period <- n.days.period <- period.length <- list()
#for (pp in 1:17){
#    days.period[[pp]] <- NA
#    for(y in year.start:year.end) days.period[[pp]] <- c(days.period[[pp]], n.days.in.a.future.year(year.start, y) + pos.period(y,pp))
#    days.period[[pp]] <- days.period[[pp]][-1] # remove the NA at the begin that was introduced only to be able to execute the above command
#    # number of days belonging to that period from year.start to year.end:
#    n.days.period[[pp]] <- length(days.period[[pp]])
#    # Number of days belonging to that period in a single year: 
#    period.length[[pp]] <- n.days.in.a.period(pp,1999) #+ ifelse(period==13 | period==2, 1, 0)  # using year 1999 introduce a small error in winter season length because of #bisestile years
#}

# Create a regular lat/lon grid to interpolate the data to the chosen res: (Notice that the regular grid is always centered at lat=0 and lon=0!)
n.lon.grid <- 360/res
n.lat.grid <- (180/res)+1
my.grid <- paste0('r',n.lon.grid,'x',n.lat.grid)
#domain<-list()
#domain$lon <- seq(0,359.999999999,res) 
#domain$lat <- c(rev(seq(0,90,res)),seq(res[1],-90,-res))

cat("Loading lat/lon. Please wait...\n")
# load only 1 day of pressure data to detect the minimum and maximum lat and lon values which identify only the North Atlantic area:
if(fields.name == rean.name) domain <- Load(var = psl, exp = NULL, obs = list(list(path=fields)), paste0(year.start,'0101'), storefreq = 'daily', leadtimemax = 1, output = 'lonlat', nprocs=1)

### Real test:
### lat <- 
### domain <- Load(var = "psl", exp = list(list(path="/esnas/exp/ecmwf/system4_m1/$STORE_FREQ$_mean/$VAR_NAME$_f6h/$VAR_NAME$_$START_DATE$.nc")), obs=NULL, sdates=paste0(1982:2011,'0101'), storefreq = 'daily', leadtimemax=n.leadtimes, nmember=n.members, output = 'lonlat', latmin = lat[chunk], latmax = lat[chunk+2], nprocs=1)

### if (fields.name="pippo"){
    
# in the case of S4, we also interpolate it to the same resolution of the reanalysis:
# (notice that if the S4 grid has the same grid of the chosen grid (typically ERA-Interim), Load() leaves the S4 grid unchanged)
if(fields.name == ECMWF_S4.name) domain <- Load(var = psl, exp = list(list(path=fields)), obs=NULL, sdates=paste0(year.start,'0101'), storefreq = 'daily', dimnames=list(member=member.name), leadtimemax=1, nmember=1, output = 'lonlat', grid=my.grid, method='bilinear', nprocs=1)

#domain <- Load(var = "psl", exp = list(list(path="/esnas/exp/ecmwf/system4_m1/$STORE_FREQ$_mean/$VAR_NAME$_f6h/$VAR_NAME$_$START_DATE$.nc")), obs=NULL, sdates='19820101', storefreq = 'daily', leadtimemax=1, nmember=1, output = 'lonlat', grid='r480x241', lonmax=100)

if(fields.name == ECMWF_monthly.name) domain <- Load(var = psl, exp = NULL, obs = list(list(path=fields)), paste0(year.start,'0102'), storefreq = 'daily', leadtimemax = 1, output = 'lonlat')    

n.lon <- length(domain$lon)
n.lat <- length(domain$lat)

pos.lat.max <- which(lat.max - round(domain$lat,4) >= 0)[1]           # select the first latitude of the domain below the maximum latitude
pos.lat.min <- tail(which(round(domain$lat,4) - lat.min >= 0),1)      # select the last latitude of the domain over the minumum latitude
pos.lon.max <- tail(which(lon.max - round(domain$lon,4) >= 0),1)
pos.lon.min <- which(round(domain$lon,4) - lon.min >= 0)[1]

pos.lat <- if(pos.lat.min < pos.lat.max) {pos.lat.min:pos.lat.max} else {pos.lat.max:pos.lat.min}
pos.lon <- c(1:pos.lon.max,pos.lon.min:length(domain$lon)) # beware that it only consider the case where the study area cross the meridian of Greenwhich!
n.pos.lat <- length(pos.lat)
n.pos.lon <- length(pos.lon)

lat <- domain$lat[pos.lat] # lat values of chosen area only (it is smaller than the whole spatial domain loaded by the data)
#if (lat[2] < lat[1]) lat <- rev(lat) # reverse lat values if they are in decreasing order
lon <- domain$lon[pos.lon] # lon values of chosen area only

#lat.min.area <- domain$lat[pos.lat.min] # min and max lat/lon of the chosen area only (same as lat.max, but its values correspond to actual values in the lat vector)
#lat.max.area <- domain$lat[pos.lat.max]
#lon.min.area <- domain$lon[pos.lon.min]
#lon.max.area <- domain$lon[pos.lon.max]

#rm(domain)

#################### Start analysis #######################################################3

# Load psl data (interpolating it to the same reanalysis grid, if necessary):
cat("Loading data. Please wait...\n")

if(fields.name == rean.name && subdaily == FALSE){ # Load daily psl data of all years in the reanalysis case:
    psleuFull <-array(NA,c(1, 1, n.years, 365, n.pos.lat, n.pos.lon))

    psleuFull366 <-  Load(var = psl, exp = NULL, obs = list(list(path=fields)), paste0(year.start:year.end,'0101'), storefreq = 'daily', leadtimemax = 366, output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max, nprocs=8)
    
    # remove bisestile days to have all arrays with the same dimensions:
    cat("Removing bisestile days. Please wait...\n")
    psleuFull[,,,,,] <- psleuFull366$obs[,,,1:365,,]

    for(y in year.start:year.end){
        y2 <- y - year.start + 1
        if(n.days.in.a.year(y) == 366) psleuFull[,,y2,60:365,,] <- psleuFull366$obs[,,y2,61:366,,] # take the march to december period removing the 29th of February
    }

    psleuFull366$obs <- NULL
    gc()

    if((running.cluster || running.15) && fields == rean) {        
        ## the months after the last month of the last year loaded are automatically filled with NA by Load(); the clustering algorithm doesn't want NA, so
        ## we have to replace them with some values (in this case the mean of the previous years not to affect the analysis too much)
        ## if we want to be able to compute the running clustering.
        ## WARNING: in case your last month is December, for the running clustering it will use the january data of the last year loaded, not of the next year:
            #psleuFull[,,n.years,305:334,,] <-  psleuFull[,,n.years-1,305:334,,]
        month.NA <- psleuFull366$not_found_files[1] # filename of the file with the first month with NA (string value with full file path)
        first.month.NA <- as.integer(substr(month.NA,nchar(month.NA)-4,nchar(month.NA)-3)) # first month with NA
        first.day.NA <- pos.period(1,first.month.NA)[1] # first day with NA (counting from the start of the year)

        psleuFullnolast <- psleuFull[,,1:(n.years-1),first.day.NA:365,,]
        psleuFullMean <- apply(psleuFullnolast, c(2,3,4), mean, na.rm=TRUE) # mean of the previous years
        
        psleuFull[,,n.years,first.day.NA:365,,] <-  psleuFullMean
        
        rm(psleuFullnolast, psleuFullMean)

    }
         
    # convert psl in daily anomalies with the LOESS filter:
    cat("Calculating anomalies. Please wait...\n")
    psleuFull_no_last_year <- psleuFull[1,1,1:n.years.clim,,,,drop=FALSE]
    pslPeriodClim <- apply(psleuFull_no_last_year, c(1,2,4,5,6), mean, na.rm=T)
    rm(psleuFull_no_last_year)
    gc()
    
    if(LOESS == TRUE){
        pslPeriodClimLoess <- array(NA, dim(pslPeriodClim))
        
        for(i in 1:n.pos.lat){
            for(j in 1:n.pos.lon){
                my.data <- data.frame(ens.mean=pslPeriodClim[1,1,,i,j], day=1:365)
                my.loess <- loess(ens.mean ~ day, my.data, span=0.35)
                pslPeriodClimLoess[1,1,,i,j] <- predict(my.loess)
            }
        }

        rm(pslPeriodClim)
        gc()

        pslPeriodClim2 <- InsertDim(pslPeriodClimLoess, 3, n.years)
        
    } else { # leave the daily climatology to compute the anomalies:
        pslPeriodClim2  <- InsertDim(pslPeriodClim, 3, n.years)
        
        rm(pslPeriodClim)
        gc()
    }
    
    ## s4.data <- data.frame(s4=pslPeriodClim[1,], day=1:216)
    ## s4.loess <- loess(s4 ~ day, s4.data, span=0.35)
    ## s4.pred <- predict(s4.loess)
        
    psleuFull <- psleuFull - pslPeriodClim2    
    rm(pslPeriodClim2)
    gc()

} # close if on fields.name == rean and subdaily == FALSE){


# Load 6-hourly psl data of all years in the reanalysis case:
if(fields.name == rean.name && subdaily == TRUE){ 
    
    #sdates <- as.vector(sapply(year.start:year.end, function(x) paste0(x, sprintf("%02d", 1:12), '01')))
    #my.exp <- list(path=fields)
    #psleuFull366 <- Load(var = psl, exp = list(my.exp), NULL, sdates, output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$obs
    #dim(data$obs) <- c(dim(data$obs)[1:2], 1, dim(data$obs)[3]*dim(data$obs)[4], dim(data$obs)[5:6])

    my.exp <- list(path=fields)

    # Load January data:
    psleu1 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0101'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod

    # Load february data (it automatically discards the 29th of February):
    psleu2 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0201'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod

    # Load March data:
    psleu3 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0301'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu4 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0401'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu5 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0501'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu6 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0601'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu7 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0701'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu8 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0801'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu9 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'0901'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu10 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'1001'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu11 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'1101'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    psleu12 <-  Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates = paste0(year.start:year.end,'1201'), storefreq = 'daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)$mod
    
    if(running.cluster == TRUE && rean.name == "ERA-interim") {
           # in this case, last month of last year might not have in /esnas the data for the 3rd month of the running cluster. Load() set these values to NA,
           # but the clustering analysis is not able to process NA, so we have to remove the NA for that month and replace with the values of the previous year:
           psleu11[,,n.years,,,] <- psleu11[,,n.years-1,,,]
           psleu12[,,n.years,,,] <- psleu12[,,n.years-1,,,]
        
    }
    
    psleuFull <- abind(psleu1, psleu2, psleu3, psleu4, psleu5, psleu6, psleu7, psleu8, psleu9, psleu10, psleu11, psleu12, along=4)
    rm(psleu1, psleu2, psleu3, psleu4, psleu5, psleu6, psleu7, psleu8, psleu9, psleu10, psleu11, psleu12)
    gc()

    # convert psl in daily anomalies with the LOESS filter:
    cat("Calculating anomalies. Please wait...\n")
    pslPeriodClim <- apply(psleuFull, c(1,2,4,5,6), mean, na.rm=T)

    if(LOESS == TRUE){
        # separate psl data in the four hours of the day ( 0.00, 6.00, 12.00, 18.00)
        pslPeriodClim1 <- pslPeriodClim[1,1,seq(1,1460,4),,]
        pslPeriodClim2 <- pslPeriodClim[1,1,seq(2,1460,4),,]
        pslPeriodClim3 <- pslPeriodClim[1,1,seq(3,1460,4),,]
        pslPeriodClim4 <- pslPeriodClim[1,1,seq(4,1460,4),,]

        rm(pslPeriodClim)
        gc()

        pslPeriodClimLoess1 <- array(NA, dim(pslPeriodClim1))
        pslPeriodClimLoess2 <- array(NA, dim(pslPeriodClim2))
        pslPeriodClimLoess3 <- array(NA, dim(pslPeriodClim3))
        pslPeriodClimLoess4 <- array(NA, dim(pslPeriodClim4))

        for(i in 1:n.pos.lat){
            for(j in 1:n.pos.lon){
                my.data1 <- data.frame(ens.mean=pslPeriodClim1[,i,j], hourly=1:(1460/4))
                my.loess1 <- loess(ens.mean ~ hourly, my.data1, span=0.35)
                pslPeriodClimLoess1[,i,j] <- predict(my.loess1)

                my.data2 <- data.frame(ens.mean=pslPeriodClim2[,i,j], hourly=1:(1460/4))
                my.loess2 <- loess(ens.mean ~ hourly, my.data2, span=0.35)
                pslPeriodClimLoess2[,i,j] <- predict(my.loess2)

                my.data3 <- data.frame(ens.mean=pslPeriodClim3[,i,j], hourly=1:(1460/4))
                my.loess3 <- loess(ens.mean ~ hourly, my.data3, span=0.35)
                pslPeriodClimLoess3[,i,j] <- predict(my.loess3)

                my.data4 <- data.frame(ens.mean=pslPeriodClim4[,i,j], hourly=1:(1460/4))
                my.loess4 <- loess(ens.mean ~ hourly, my.data4, span=0.35)
                pslPeriodClimLoess4[,i,j] <- predict(my.loess4)
                
            }
        }

        rm(my.data1, my.data2, my.data3, my.data4, my.loess1, my.loess2, my.loess3, my.loess4)
        rm(pslPeriodClim1, pslPeriodClim2, pslPeriodClim3, pslPeriodClim4)
        gc()

        s1 <- seq(1,1460,4)
        s2 <- seq(2,1460,4)
        s3 <- seq(3,1460,4)
        s4 <- seq(4,1460,4)

        pslPeriodClimLoess <- array(NA,c(365*4,dim(pslPeriodClimLoess1)[2:3]))
            
        for(day in 1:365){
           pslPeriodClimLoess[s1[day],,] <- pslPeriodClimLoess1[day,,]
           pslPeriodClimLoess[s2[day],,] <- pslPeriodClimLoess2[day,,]
           pslPeriodClimLoess[s3[day],,] <- pslPeriodClimLoess3[day,,]
           pslPeriodClimLoess[s4[day],,] <- pslPeriodClimLoess4[day,,]
        }
        
        pslPeriodClim2 <- InsertDim(pslPeriodClimLoess, 1, n.years)
        
    } else { # leave the daily climatology to compute the anomalies:
        pslPeriodClim2  <- InsertDim(pslPeriodClim, 3, n.years)
        
        rm(pslPeriodClim)
        gc()
    }
    
    ## s4.data <- data.frame(s4=pslPeriodClim[1,], day=1:216)
    ## s4.loess <- loess(s4 ~ day, s4.data, span=0.35)
    ## s4.pred <- predict(s4.loess)
        
    psleuFull <- psleuFull[1,1,,,,] - pslPeriodClim2
    
    rm(pslPeriodClim2)
    gc()

} # close if on fields.name == rean & subdaily == TRUE


if(fields.name == ECMWF_S4.name){ # in the forecast case, we load only the data for 1 start month at time and all the lead times (since each month needs ~3 GB of memory)    
    if(start.month <= 9) {start.month.char <- paste0("0",as.character(start.month))} else {start.month.char <- start.month}

    fields2 <- gsub("\\$STORE_FREQ\\$","daily",fields)
    fields3 <- gsub("\\$VAR_NAME\\$",psl,fields2)

    if(missing.forecasts == TRUE){
        years <- c()
        for(y in year.start:year.end){
            fields4 <- gsub("\\$START_DATE\\$",paste0(y, start.month.char,'01'),fields3)

            char.lead <- nchar(system(paste0("ncks -m ",fields4,"| grep -E -i 'psl size' | cut -d '*' -f1"), intern=T))
            # beware, in this way it can only take into account leadtimes from 100 to 999, but it is the only way in the SMP machine:
            #num.lead <- as.integer(substr(system(paste0("ncks -m ",fields4,"| grep -E -i 'psl size' | cut -d '*' -f1"), intern=T),char.lead-3,char.lead)) 
            num.lead <- as.integer(system(paste0("ncks -m ",fields4,"| grep -E -i 'psl size' | cut -d '=' -f2 | cut -d '*' -f1"), intern=T)) # don't work well on the SMP
            num.memb <- as.integer(system(paste0("ncks -m ",fields4,"| grep -E -i 'psl size' | cut -d '=' -f2 | cut -d '*' -f2"), intern=T))
            num.lat  <- as.integer(system(paste0("ncks -m ",fields4,"| grep -E -i 'psl size' | cut -d '=' -f2 | cut -d '*' -f3"), intern=T))
            num.lon  <- as.integer(system(paste0("ncks -m ",fields4,"| grep -E -i 'psl size' | cut -d '=' -f2 | cut -d '*' -f4"), intern=T))

            #if(num.lead == n.leadtimes && num.memb >= n.members && num.lat == 181 && num.lon == 360) years <- c(years,y)
            if(num.lead == n.leadtimes && num.memb >= n.members) years <- c(years,y)      
        }

    } else {
        years <- year.start:year.end
    }

    n.years.full <- length(years)

    if(running.cluster == TRUE) {

        start.month1 <- ifelse(start.month == 1, 12, start.month-1)
        if(start.month1 <= 9) {start.month1.char <- paste0("0",as.character(start.month1))} else {start.month1.char <- start.month1}
        
        start.month2.char <- start.month.char
        
        start.month3 <- ifelse(start.month == 12, 1, start.month+1)
        if(start.month3 <= 9) {start.month3.char <- paste0("0",as.character(start.month3))} else {start.month3.char <- start.month3}

        # load three months of data, inserting all them in the third dimension of the array, one month at time:
        psleuFull1 <- Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates=paste0(years, start.month1.char,'01'), dimnames=list(member=member.name), nmember=n.members, leadtimemax=n.leadtimes, storefreq='daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max, grid=my.grid, method='bilinear')$mod
        gc()

        psleuFull2 <- Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates=paste0(years, start.month2.char,'01'), dimnames=list(member=member.name), nmember=n.members, leadtimemax=n.leadtimes, storefreq='daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max, grid=my.grid, method='bilinear')$mod
        gc()

        psleuFull3 <- Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates=paste0(years, start.month3.char,'01'), dimnames=list(member=member.name), nmember=n.members, leadtimemax=n.leadtimes, storefreq='daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max, grid=my.grid, method='bilinear')$mod
        gc()
        
    } else {
        
        psleuFull <- Load(var = psl, exp = list(list(path=fields)), obs = NULL, sdates=paste0(years, start.month.char,'01'), dimnames=list(member=member.name), nmember=n.members, leadtimemax=n.leadtimes, storefreq='daily', output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max, grid=my.grid, method='bilinear', nprocs=1)$mod
    
    }

     if(LOESS == TRUE){
         # convert psl in daily anomalies with the LOESS filter:
         cat("Calculating anomalies. Please wait...\n")
         
         if(running.cluster == TRUE) {     
            pslPeriodClim1 <- apply(psleuFull1, c(1,4,5,6), mean, na.rm=T)
            pslPeriodClim2 <- apply(psleuFull2, c(1,4,5,6), mean, na.rm=T)
            pslPeriodClim3 <- apply(psleuFull3, c(1,4,5,6), mean, na.rm=T)
    
            pslPeriodClimLoess1 <- pslPeriodClim1
            pslPeriodClimLoess2 <- pslPeriodClim2
            pslPeriodClimLoess3 <- pslPeriodClim3

            for(i in 1:n.pos.lat){
                for(j in 1:n.pos.lon){
                    my.data1 <- data.frame(ens.mean=pslPeriodClim1[1,,i,j], day=1:n.leadtimes)
                    my.loess1 <- loess(ens.mean ~ day, my.data1, span=0.35)
                    pslPeriodClimLoess1[1,,i,j] <- predict(my.loess1)
                    rm(my.data1, my.loess1)
                    gc()

                    my.data2 <- data.frame(ens.mean=pslPeriodClim2[1,,i,j], day=1:n.leadtimes)
                    my.loess2 <- loess(ens.mean ~ day, my.data2, span=0.35)
                    pslPeriodClimLoess2[1,,i,j] <- predict(my.loess2)
                    rm(my.data2, my.loess2)
                    gc()

                    my.data3 <- data.frame(ens.mean=pslPeriodClim3[1,,i,j], day=1:n.leadtimes)
                    my.loess3 <- loess(ens.mean ~ day, my.data3, span=0.35)
                    pslPeriodClimLoess3[1,,i,j] <- predict(my.loess3)
                    rm(my.data3, my.loess3)
                    gc()
                }
            }

            rm(pslPeriodClim1, pslPeriodClim2, pslPeriodClim3)
            gc()

            pslPeriodClimDos1 <- InsertDim(InsertDim(pslPeriodClimLoess1, 2, n.years.full), 2, n.members)
            pslPeriodClimDos2 <- InsertDim(InsertDim(pslPeriodClimLoess2, 2, n.years.full), 2, n.members)
            pslPeriodClimDos3 <- InsertDim(InsertDim(pslPeriodClimLoess3, 2, n.years.full), 2, n.members)

            pslPeriodClimDos <- unname(abind(pslPeriodClimDos1, pslPeriodClimDos2, pslPeriodClimDos3, along=3))
            rm(pslPeriodClimDos1, pslPeriodClimDos2, pslPeriodClimDos3)
            gc()
            
            psleuFull <- unname(abind(psleuFull1, psleuFull2, psleuFull3, along=3))
            rm(psleuFull1, psleuFull2, psleuFull3)
            gc()
                
         } else { # in case of no running cluster:
    
            pslPeriodClim <- apply(psleuFull, c(1,4,5,6), mean, na.rm=T)

            pslPeriodClimLoess <- pslPeriodClim
            for(i in n.pos.lat){
                for(j in n.pos.lon){
                    my.data <- data.frame(ens.mean=pslPeriodClim[1,,i,j], day=1:n.leadtimes)
                    my.loess <- loess(ens.mean ~ day, my.data, span=0.35)
                    pslPeriodClimLoess[1,,i,j] <- predict(my.loess)
                }
            }

            rm(pslPeriodClim)
            gc()

            pslPeriodClimDos <- InsertDim(InsertDim(pslPeriodClimLoess, 2, n.years.full), 2, n.members)
             
         } # close if on running cluster
         
     } else { #in case of no LOESS:
         
       if(running.cluster == TRUE) {
          # in this case, the climatology is measured FOR EACH MONTH INDIPENDENTLY, instead of using a seasonal value: 
          pslPeriodClim1 <- apply(psleuFull1, c(1,4,5,6), mean, na.rm=T)
          pslPeriodClim2 <- apply(psleuFull2, c(1,4,5,6), mean, na.rm=T)
          pslPeriodClim3 <- apply(psleuFull3, c(1,4,5,6), mean, na.rm=T)

          pslPeriodClim <- unname(abind(pslPeriodClim1, pslPeriodClim2, pslPeriodClim3))
           
          pslPeriodClimDos <- InsertDim(InsertDim(pslPeriodClim, 2, n.years.full), 2, n.members)
          rm(pslPeriodClim)
          gc()

          psleuFull <- unname(abind(psleuFull1, psleuFull2, psleuFull3, along=3))
          rm(psleuFull1, psleuFull2, psleuFull3)
          gc()
           
       } else {# in case of no running cluster:
           
          pslPeriodClimDos <- InsertDim(InsertDim(pslPeriodClim, 2, n.years.full), 2, n.members)
          rm(pslPeriodClim)
          gc()
       }
     }
    
     ## s4.data <- data.frame(s4=pslPeriodClim[1,], day=1:216)
     ## s4.loess <- loess(s4 ~ day, s4.data, span=0.35)
     ## s4.pred <- predict(s4.loess)
        
     psleuFull <- psleuFull - pslPeriodClimDos    
     rm(pslPeriodClimDos)
     gc()
    
} # close if on fields.name=forecasts.name

if(fields.name == ECMWF_monthly.name){
    # Load 6-hourly psl data in the forecast case:    
    psleuFull <-array(NA, c(n.sdates*n.years, n.leadtimes, n.pos.lat, n.pos.lon))  # daily order: 19940102 19950102 ... 20130102 19940109 19950109 ... 20130109 ...
    n.leadtimes <- length(leadtime)
    sdates <- weekly.seq(forecast.year,mes,day)
    n.sdates <- length(sdates)
    
    for (startdate in 1:n.sdates){
       for(lday in leadtime){
          var <- Load(var = psl, exp = NULL, obs = list(list(path=fields)), paste0(year.start:year.end, substr(sdates[startdate],5,6), substr(sdates[startdate],7,8) ), storefreq = 'daily', leadtimemin = lday*4-3, leadtimemax = lday*4, output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max)
          
          mean.lday <- apply(var$obs, c(3,5,6), mean, na.rm=T)
          rm(var)
          gc()
                           
          psleuFull[(1+(startdate-1)*n.years):(startdate*n.years), lday-leadtime[1]+1,,] <- mean.lday
          rm(mean.lday)
          gc()
       }
    }
}    

if(psl=="g500") psleuFull <- psleuFull/9.81   # convert geopotential to geopotential height (in m)
if(psl=="psl") psleuFull <- psleuFull/100   # convert MSLP in Pascal to MSLP in hPa
gc()

#save.image(file=paste0(workdir,"/weather_regimes_",fields.name,"_",year.start,"-",year.end,".RData"))
#load(file=paste0(workdir,"/weather_regimes_",fields.name,"_",year.start,"-",year.end,".RData"))

#save.image("/scratch/Earth/ncortesi/RESILIENCE/Regimes/test.R")

# compute the cluster analysis:
my.PCA <- list()
my.cluster <- list()
my.cluster.array <- list()
tot.variance <- list()
n.pcs <- my.cluster <- c()
    
#WR.period=1 # for the debug   
for(p in WR.period){
    # Select only the data of the month/season we want:
    if(fields.name == rean.name){

        #pslPeriod <- psleuFull[days.period[[p]],,] # select only days in the chosen period (i.e: winter)
        if(running.cluster) {
            if(subdaily){
                my.hours <- sort(c(pos.month.extended(1,p)*4-3,  pos.month.extended(1,p)*4-2,  pos.month.extended(1,p)*4-1,  pos.month.extended(1,p)*4))
                if(p == 1) my.hours <- c(1337:1460,1:236)
                if(p == 12) my.hours <- c(1217:1460,1:124)
                           
                pslPeriod <- psleuFull[,my.hours,,] # select all days in the period of 3 months centered on the target month p
                
            } else {
                pslPeriod <- psleuFull[1,1,,pos.month.extended(1,p),,] # select all days in the period of 3 months centered on the target month p
            }
            
        }

       if(running.15) pslPeriod <- psleuFull[1,1,,pos.month.extended15(1,p),,]
       
        ## if there isn't any kind of running clustering:
       if(!running.cluster && !running.15) {
            
            if(subdaily){
                 my.hours <- sort(c(pos.month(1,p)*4-3, pos.month(1,p)*4-2, pos.month(1,p)*4-1, pos.month(1,p)*4))
                 pslPeriod <- psleuFull[,my.hours,,]
            } else {             
                 pslPeriod <- psleuFull[1,1,,pos.period(1,p),,] # select only days in the chosen period (i.e: winter)
            }
        }
        
        # weight the pressure fields based on latitude (apply it to anomalies, not to absolute values!):
        if(lat.weighting){
            lat.weighted <- cos(lat*pi/180)^0.5
            if(!running.cluster && !running.15) lat.weighted.array <- InsertDim(InsertDim(InsertDim(lat.weighted,2,n.pos.lon), 1, length(pos.period(2001,p))), 1, n.years)
            if(running.cluster)  lat.weighted.array <- InsertDim(InsertDim(InsertDim(lat.weighted,2,n.pos.lon), 1, length(pos.month.extended(2001,p))), 1, n.years)
            if(running.15)  lat.weighted.array <- InsertDim(InsertDim(InsertDim(lat.weighted,2,n.pos.lon), 1, length(pos.month.extended15(2001,p))), 1, n.years)

            pslPeriod <- pslPeriod * lat.weighted.array
            
            rm(lat.weighted.array)
            gc()
        }

        gc()
        cat("Preformatting data for clustering. Please wait...\n")
        psl.melted <- melt(pslPeriod[,,,, drop=FALSE], varnames=c("Year","Day","Lat","Lon"))
        gc()
        
        cat("Preformatting data for clustering. Please wait......\n")
        # this function eats much memory!!!
        psl.kmeans <- unname(acast(psl.melted, Year + Day ~ Lat + Lon))
        #gc()

        
        # select period data from psleuFull to use it as input of the cluster analysis:    
        #psl.kmeans <- pslPeriod
        #dim(psl.kmeans) <- c(n.days.period[[p]], n.pos.lat*n.pos.lon) # convert array in a matrix!
        #rm(pslPeriod, pslPeriod.weighted)
    }

    # in case of S4 we don't need to select anything because we already loaded only 1 month of data!
    if(fields.name == ECMWF_S4.name){
        if(running.cluster == TRUE && p < 13) {
            # if you want to fully implement the running cluster of the monthly S4 data, you have to finish selecting automatically the 3-months running period
            # generalizing the command below (which at present only work for the month of January an lead time 0):

            # Select DJF (lead time 0) for our case study, excluding 29 of february):
            pslPeriod <- psleuFull[,,,1:90,,, drop=FALSE]
                
        } else {
            
        # select data only for the startmonth and leadmonth to study:
        cat("Extracting data. Please wait...\n")
        chosen.month <- start.month + lead.month   # find which month we want to select data
        if(chosen.month > 12) chosen.month <- chosen.month - 12
     
        # remove the 29th of February to have the same n. of elements for all years
        i=0
        for(y in years){
           i=i+1
           leadtime.min <- 1 + n.days.in.a.monthly.period(start.month, chosen.month, y) - n.days.in.a.month(chosen.month, y)
           leadtime.max <- leadtime.min + n.days.in.a.month(chosen.month, y) - 1
           #leadtime.max <- 61 
           
           if (n.days.in.a.month(chosen.month, y) == 29) leadtime.max <- leadtime.max - 1 
           int.leadtimes <- leadtime.min:leadtime.max
           num.leadtimes <- leadtime.max - leadtime.min + 1 # number of days in the chosen month (different from 'n.leadtimes',which is the total number of days in the file!)
           # by construction it is equal to: n.days.in.a.month(chosen.month, y)
           
           if(y == years[1]) {
               pslPeriod <- psleuFull[,,1,int.leadtimes,,,drop=FALSE]
           } else {
               pslPeriod <- unname(abind(pslPeriod, psleuFull[,,i,int.leadtimes,,,drop=FALSE], along=3))
           }
        }

        }
        
        # weight the pressure fields based on latitude (apply it to anomalies, not to absolute values!):
        if(lat.weighting){
            lat.weighted <- cos(lat*pi/180)^0.5
            lat.weighted.array <- InsertDim(InsertDim(InsertDim(lat.weighted,2,n.pos.lon), 1, length(pos.month.extended(2001,p))), 1, n.years)
            pslPeriod <- pslPeriod * lat.weighted.array  ######### adapt!!!!!!!!!!!
            rm(lat.weighted.array)
            gc()
        }

        # note that the data order in psl.kmeans[,X] is: year1day1, year1day2, ... , year1day31, year2day1, year2day2, ... , year2day28
        gc()
        cat("Preformatting data. Please wait...\n")
        psl.melted <- melt(pslPeriod[1,,,,,, drop=FALSE], varnames=c("Exp","Member","StartYear","LeadDay","Lat","Lon"))
        gc()

        #save(psl.melted,file=paste0(workdir,"/psl_melted.RData"))
        
        cat("Preformatting data. Please wait......\n")
        # This function eats much memory!!!
        psl.kmeans <- unname(acast(psl.melted, Member + StartYear + LeadDay ~ Lat + Lon))
        #gc()

        #save(psl.kmeans,file=paste0(workdir,"/psl_kmeans.RData"))
        #my.cluster <- kmeans(psl.kmeans, centers=4, iter.max=100, nstart=30, trace=FALSE)
        #save(my.cluster,file=paste0(workdir,"/my_cluster.RData"))

        
        #psl.kmeans <- array(NA,c(dim(pslPeriod)))
        #n.rows <- nrow(psl.melted)
        #a <- psl.melted$Member
        #b <- psl.melted$StartYear
        #c <- psl.melted$LeadDay
        #d <- psl.melted$Lat
        #e <- psl.melted$Lon
        #f <- psl.melted$value

        # this function to convert a data.frame in an array is much less memory-eater than acast but a bit slower:
        #for(i in 1:n.rows) psl.kmeans[1,a[i],b[i],c[i],d[i],e[i]] <- f[i]
        gc()
        #rm(pslPeriod); gc()
    }

    if(fields.name == ECMWF_monthly.name){
        my.startdates.period <- months.period(forecast.year,mes,day,p) # get which startdates belong to the chosen period (remember that there are no bisestile day left!)

        days.period <- list() # get which days inside psleuFull belong to the chosen period
        for(startdate in my.startdates.period){
           days.period[[p]] <- c(days.period[[p]], (1+(startdate-1)*n.years):(startdate*n.years))
        }
        
        # in winter you must remove the 2nd startdate (20140109) because its data is bad, as you can see with: plot(psl.kmeans[,1:2])
        # if(fields.name == forecast.name && period == 13) psl.kmeans[21:40,] <- NA
    }

        
    # compute the clustering:
    cat("Clustering data. Please wait...\n")
    if(PCA){ 
       my.seq <- seq(1, n.pos.lat*n.pos.lon, 16) # select only 1 point of 9
       pslcut <- psl.kmeans[,my.seq]
  
       my.PCA <- princomp(pslcut,cor=FALSE)
       tot.variance <- head(cumsum(my.PCA$sdev^2/sum(my.PCA$sdev^2)),50)  # check how many PCAs to keep basing on the sum of their expl. variance
       n.pcs <- head(as.numeric(which(tot.variance > variance.explained)),1) # select only the pcs that explains at least 80% of variance
       my.cluster <- kmeans(my.PCA$scores[,1:n.pcs], centers=4, iter.max=100, nstart=30)  # 4 is the number of clusters
       rm(pslcut)
    } else {  # 4 is the number of clusters:

       my.cluster <- kmeans(psl.kmeans, centers=4, iter.max=100, nstart=30, trace=FALSE)
        
       gc()

       #save(my.cluster, file=paste0(workdir,"/",fields.name,"_",my.period[p],"_leadmonth_",lead.month,"_series.RData"))
        
       #if(fields.name == rean.name){
           #my.cluster[[p]] <- kmeans(psl.kmeans[which(!is.na(psl.kmeans[,1])),], centers=4, iter.max=100, nstart=30, trace=FALSE)
           # save the time series output of the cluster analysis:
           #save(my.cluster, my.cluster.array, my.PCA, tot.variance, n.pcs, file=paste0(workdir,"/",fields.name,"_",my.period[p],"_series.RData"))
       #}
        
       if(fields.name == ECMWF_S4.name) {
           my.cluster.array <- array(my.cluster$cluster, c(num.leadtimes, n.years.full, n.members)) # in reverse order compared to the definition of psl.kmeans

           # save the time series output of the cluster analysis:
           #save(my.cluster, my.cluster.array, my.PCA, tot.variance, n.pcs, file=paste0(workdir,"/",fields.name,"_",my.period[p],"_leadmonth_",lead.month,"_series.RData"))
           
           #plot(SMA(my.cluster$centers[1,],201),type="l",col="gold",ylim=c(-20,20));lines(SMA(my.cluster$centers[2,],201),type="l",col="red"); lines(SMA(my.cluster$centers[3,],201),type="l",col="green");lines(SMA(my.cluster$centers[4,],201),type="l",col="blue");lines(SMA(psl.kmeans[29,],201),type="l",col="gray");lines(rep(0,14410),type="l",col="black",lty=2)
       }
    }
    
    rm(psl.kmeans)
    gc()
    
#} # close for on 'p'

#save.image(file=paste0(workdir,"/weather_regimes_",fields.name,"_",year.start,"-",year.end,".RData"))
#load(file=paste0(workdir,"/weather_regimes_",fields.name,"_",year.start,"-",year.end,".RData"))

#my.grid<-paste0('r',n.lon,'x',n.lat)
#coord <- Load(var = 'sfcWind', exp = list(ECMWF_monthly), obs = NULL, sdates=paste0(2013,'0102'), leadtimemin = 1, leadtimemax=1,  output = 'lonlat', nprocs=1, grid=my.grid, method='bilinear')

# measure regime anomalies:
    
#for(p in WR.period){ # 1-12: Jan-Dec; 13-16: Winter-Spring-Summer-Autumn; 17: Year  
    
    if(fields.name == rean.name){

      if(running.cluster && p < 13){
          # select only the days inside the 3-months cluster series that belong only to the target month p:
          n.days.period <- length(pos.month.extended(1,p))  # total number of days in the three months
          
          days.month <- days.month.new <- days.month.full <- c()
          days.month <- which(pos.month.extended(1,p) == pos.month(1,p)[1]) - 1 + 1:length(pos.month(1,p))
          
          for(y in 1:n.years){
              days.month.new <- days.month + n.days.period*(y-1)
              days.month.full <- c(days.month.full, days.month.new)
              #print(days.month.new)
              #print(days.month)
          }

          # in this case, we are not selecting days but 6-hourly intervals:
          if(subdaily) days.month.full <- sort(c(days.month.full*4, days.month.full*4+1, days.month.full*4+2, days.month.full*4+3))

          # select only the days of the cluster series inside the target month p:
          cluster.sequence <- my.cluster$cluster[days.month.full] 

      }

        
      if(running.15 && p < 13){
          # select only the days inside the 3-months cluster series that belong only to the target month p:
          n.days.period <- length(pos.month.extended15(1,p))  # total number of days in the three months
          
          days.month <- days.month.new <- days.month.full <- c()
          days.month <- which(pos.month.extended15(1,p) == pos.month(1,p)[1]) - 1 + 1:length(pos.month(1,p))
          
          for(y in 1:n.years){
              days.month.new <- days.month + n.days.period*(y-1)
              days.month.full <- c(days.month.full, days.month.new)
              #print(days.month.new)
              #print(days.month)
          }

          # select only the days of the cluster series inside the target month p:
          cluster.sequence <- my.cluster$cluster[days.month.full] 

      }

      if(!running.cluster && !running.15) cluster.sequence <- my.cluster$cluster
      
      # convert cluster sequence from 6-hourly to daily:
      if(subdaily){
              type <- c()
              
              for(day in 1:(length(cluster.sequence)/4)){
                  #day <- ceiling(hour/4)
                  hourly <- cluster.sequence[(1+(day-1)*4):(4+(day-1)*4)]
                  
                  t1 <- length(which(hourly == 1))
                  t2 <- length(which(hourly == 2))
                  t3 <- length(which(hourly == 3))
                  t4 <- length(which(hourly == 4))    
                  tt <- c(t1,t2,t3,t4)
                  
                  # if all the 4 time steps belong to the same regime, assign it to this day:
                  if(length(unique(hourly)) == 1) type[day] <- hourly[1] 

                  # if there are two different regimes, check if one has a higher frequency:
                  if(length(unique(hourly)) == 2){
                      if(any(tt == 3)){  # if 3 of the 4 time intervals belong to the same weather regime, assign this day to it
                          type[day] <- which(tt == 3) 
                      } else {  # in this case both regimes occur in 2 of the 4 time steps; arbitrary assign the regime occurring at 12.00 of that day
                          type[day] <- hourly[3]
                      }
                  }

                  # if there are three different regimes, assign it to the only possible regime with 2 time steps in that day:
                  if(length(unique(hourly)) == 3)  type[day] <- which(tt == 2) 

                  # if there are four different regimes (a very rare event!), assign it to the regime occurring at 12.00 of that day:
                  if(length(unique(hourly)) == 3)  type[day] <-  hourly[3]
                  
              } # close for on day

      } # close for on subdaily
       
     
      if(sequences){ # it works only for rean data!!!
          # for each of the 4 clusters, remove the days not belonging to sequences of at least 5 days:
          # warning: first 4 days and last 4 days are not take into account y the algorithm and are treated as not belonging to any sequence (sequ=FALSE)    
          wrdiff <- diff(my.cluster$cluster)

          sequ <- rep(FALSE, n.days.period[[p]])
          for(i in 5:(n.days.period[[p]]-5)){
              sequ[i] <- TRUE
              if(wrdiff[i] != 0 & wrdiff[i+1] != 0) sequ[i] = FALSE
              if(wrdiff[i] != 0 & wrdiff[i+2] != 0) sequ[i] = FALSE
              if(wrdiff[i] != 0 & wrdiff[i+3] != 0) sequ[i] = FALSE
              if(wrdiff[i] != 0 & wrdiff[i+4] != 0) sequ[i] = FALSE
              if(wrdiff[i-1] != 0 & wrdiff[i] != 0) sequ[i] = FALSE
              if(wrdiff[i-1] != 0 & wrdiff[i+1] != 0) sequ[i] = FALSE
              if(wrdiff[i-1] != 0 & wrdiff[i+2] != 0) sequ[i] = FALSE
              if(wrdiff[i-1] != 0 & wrdiff[i+3] != 0) sequ[i] = FALSE
              if(wrdiff[i-2] != 0 & wrdiff[i] != 0) sequ[i] = FALSE
              if(wrdiff[i-2] != 0 & wrdiff[i+1] != 0) sequ[i] = FALSE
              if(wrdiff[i-2] != 0 & wrdiff[i+2] != 0) sequ[i] = FALSE
              if(wrdiff[i-3] != 0 & wrdiff[i] != 0) sequ[i] = FALSE
              if(wrdiff[i-3] != 0 & wrdiff[i+1] != 0) sequ[i] = FALSE
              if(wrdiff[i-4] != 0 & wrdiff[i] != 0) sequ[i] = FALSE
          } # close for loop on i
          
          # sequence of daily cluster numbers without the days that doesn't belong to sequences of 5 or more days:
          cluster.sequence <- my.cluster$cluster * sequ
          rm(wrdiff, sequ)
      }


      # Replace the days belonging to a regime with the days belonging to a sequence of at least 5 days of that regime:
      wr1 <- which(cluster.sequence == 1)
      wr2 <- which(cluster.sequence == 2)
      wr3 <- which(cluster.sequence == 3)
      wr4 <- which(cluster.sequence == 4)
      
      # yearly frequency of each regime:    
      wr1y <- wr2y <- wr3y <-wr4y <- c()

      mod.subdaily <- ifelse(subdaily,4,1)
      np <- n.days.in.a.period(p,1)*mod.subdaily

      for(y in year.start:year.end){
        # for both reanalysis and S4, the time order is always: year1day1, year1day2, ..., year1day31, year2day1, year2day2, ..., year2day28, etc,
        wr1y[y-year.start+1] <- length(which(cluster.sequence[(y-year.start)*np + (1:np)] == 1))
        wr2y[y-year.start+1] <- length(which(cluster.sequence[(y-year.start)*np + (1:np)] == 2))
        wr3y[y-year.start+1] <- length(which(cluster.sequence[(y-year.start)*np + (1:np)] == 3))
        wr4y[y-year.start+1] <- length(which(cluster.sequence[(y-year.start)*np + (1:np)] == 4))
      }

      # convert to frequencies in %:
      wr1y <- wr1y/np
      wr2y <- wr2y/np
      wr3y <- wr3y/np
      wr4y <- wr4y/np

      gc()


      # measure regime anomalies:        
      pslmat <- unname(acast(psl.melted, Year + Day ~ Lat ~ Lon))

      if(running.cluster || running.15){
         pslmat.new <- pslmat
         pslmat <- pslmat.new[days.month.full,,]
         rm(pslmat.new)
         gc()
      }

     
      pslwr1 <- pslmat[wr1,,, drop=F]
      pslwr2 <- pslmat[wr2,,, drop=F]
      pslwr3 <- pslmat[wr3,,, drop=F]
      pslwr4 <- pslmat[wr4,,, drop=F]

      # regime structure:
      pslwr1mean <- apply(pslwr1, c(2,3), mean, na.rm=T)
      pslwr2mean <- apply(pslwr2, c(2,3), mean, na.rm=T)
      pslwr3mean <- apply(pslwr3, c(2,3), mean, na.rm=T)
      pslwr4mean <- apply(pslwr4, c(2,3), mean, na.rm=T)

      # spatial mean for each day to save for the measure of the FairRPSS:
      pslwr1spmean <- apply(pslwr1, 1, mean, na.rm=T)
      pslwr2spmean <- apply(pslwr2, 1, mean, na.rm=T)
      pslwr3spmean <- apply(pslwr3, 1, mean, na.rm=T)
      pslwr4spmean <- apply(pslwr4, 1, mean, na.rm=T)

    
      # save all the data necessary to redraw the graphs when we know the right regime:
      save(my.cluster, cluster.sequence, lon, lon.max, lon.min, lat, lat.max, lat.min, pos.lat, pos.lon, n.pos.lat, n.pos.lon, psl, psl.name, my.period, p, workdir, rean.name, fields.name, year.start, year.end, n.years, WR.period, pslwr1mean, pslwr2mean, pslwr3mean, pslwr4mean, pslwr1spmean, pslwr2spmean, pslwr3spmean, pslwr4spmean, wr1y,wr2y,wr3y,wr4y,wr1,wr2,wr3,wr4, LOESS, running.cluster, running.15, lat.weighting, file=paste0(workdir,"/",fields.name,"_",my.period[p],"_psl.RData"))

      ## immediatly save the plots of the ERA-Interim monthly regime anomalies with the running cluster instead than loading them in the next script:
        EU <- c(1:which(lon >= lon.max)[1], (which(lon >= 337)[1]:length(lon)))  # restrict area to continental europe only
        
        if(psl == "g500"){
            my.brks <- c(-300,seq(-200,200,10),300) # % Mean anomaly of a WR
            my.brks2 <- c(-300,seq(-200,200,10),300) # % Mean anomaly of a WR for the contour lines
            values.to.plot <- c(-200, -100, 0, 100, 200)  # values we want to show in the labels
        }

        if(psl == "psl"){
            my.brks <- c(seq(-19,-1,2),0,seq(1,19,2)) # % Mean anomaly of a WR
            my.brks2 <- my.brks #c(seq(-20,20,2)) # % Mean anomaly of a WR for the contour lines
            values.to.plot <- my.brks #c(-17,-15,-13,-11,-9,-7,-5,-3,-1,0,1,3,5,7,9,11,13,15,17)
        }
        my.cols <- colorRampPalette(rev(brewer.pal(11,"RdBu")))(length(my.brks)-1)    # blue--white--red colors
        my.cols[floor(length(my.cols)/2)] <- my.cols[floor(length(my.cols)/2)+1] <- "white"

        map1 <- pslwr1mean
        map2 <- pslwr2mean
        map3 <- pslwr3mean
        map4 <- pslwr4mean
        png(filename=paste0(workdir,"/",fields.name,"_",my.period[p],"_cluster1.png"),width=1000,height=1200)
        PlotEquiMap2(rescale(map1,my.brks[1],tail(my.brks,1)), lon, lat, filled.continents=FALSE, brks=my.brks, cols=my.cols, sizetit=1.2, contours=t(map1), brks2=my.brks2, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F")
        dev.off()
        png(filename=paste0(workdir,"/",fields.name,"_",my.period[p],"_cluster2.png"),width=1000,height=1200)
        PlotEquiMap2(rescale(map2,my.brks[1],tail(my.brks,1)), lon, lat, filled.continents=FALSE, brks=my.brks, cols=my.cols, sizetit=1.2, contours=t(map2), brks2=my.brks2, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, contours.lty="F1FF1F")
        dev.off()
        png(filename=paste0(workdir,"/",fields.name,"_",my.period[p],"_cluster3.png"),width=1000,height=1200)
        PlotEquiMap2(rescale(map3,my.brks[1],tail(my.brks,1)), lon, lat, filled.continents=FALSE, brks=my.brks, cols=my.cols, sizetit=1.2, contours=t(map3), brks2=my.brks2, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, contours.lty="F1FF1F")
        dev.off()
        png(filename=paste0(workdir,"/",fields.name,"_",my.period[p],"_cluster4.png"),width=1000,height=1200)
        PlotEquiMap2(rescale(map4,my.brks[1],tail(my.brks,1)), lon, lat, filled.continents=FALSE, brks=my.brks, cols=my.cols, sizetit=1.2, contours=t(map4), brks2=my.brks2, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, contours.lty="F1FF1F")
        dev.off()
        
        rm(pslwr1mean,pslwr2mean,pslwr3mean,pslwr4mean)
        rm(pslwr1,pslwr2,pslwr3,pslwr4)     
        gc()    
        
    }
        
    if(fields.name == ECMWF_S4.name){
      cat("Computing regime anomalies and frequencies. Please wait...\n")

      #load(file=paste0(workdir,"/",fields.name,"_",my.period[p],"_leadmonth_",lead.month,"_ClusterData.RData"))
      
      cluster.sequence <- my.cluster$cluster #as.vector(my.cluster.array) 

      wr1 <- which(cluster.sequence == 1)
      wr2 <- which(cluster.sequence == 2)
      wr3 <- which(cluster.sequence == 3)
      wr4 <- which(cluster.sequence == 4)

      wr1y <- apply(my.cluster.array == 1, 2, sum)
      wr2y <- apply(my.cluster.array == 2, 2, sum)
      wr3y <- apply(my.cluster.array == 3, 2, sum)
      wr4y <- apply(my.cluster.array == 4, 2, sum)

      # convert to frequencies in %:
      wr1y <- wr1y/(num.leadtimes*n.members) # in this case, n.leadtimes is the number of days of one month of the cluser time series
      wr2y <- wr2y/(num.leadtimes*n.members)
      wr3y <- wr3y/(num.leadtimes*n.members)
      wr4y <- wr4y/(num.leadtimes*n.members)

      # same as above, but to measure the maximum frequence between all the members:
      wr1yMax <- apply(apply(my.cluster.array == 1, c(2,3), sum),1,max)
      wr2yMax <- apply(apply(my.cluster.array == 2, c(2,3), sum),1,max)
      wr3yMax <- apply(apply(my.cluster.array == 3, c(2,3), sum),1,max)
      wr4yMax <- apply(apply(my.cluster.array == 4, c(2,3), sum),1,max)

      wr1yMax <- wr1yMax/num.leadtimes
      wr2yMax <- wr2yMax/num.leadtimes
      wr3yMax <- wr3yMax/num.leadtimes
      wr4yMax <- wr4yMax/num.leadtimes

      wr1yMin <- apply(apply(my.cluster.array == 1, c(2,3), sum),1,min)
      wr2yMin <- apply(apply(my.cluster.array == 2, c(2,3), sum),1,min)
      wr3yMin <- apply(apply(my.cluster.array == 3, c(2,3), sum),1,min)
      wr4yMin <- apply(apply(my.cluster.array == 4, c(2,3), sum),1,min)

      wr1yMin <- wr1yMin/num.leadtimes
      wr2yMin <- wr2yMin/num.leadtimes
      wr3yMin <- wr3yMin/num.leadtimes
      wr4yMin <- wr4yMin/num.leadtimes

      cat("Computing regime anomalies and frequencies. Please wait......\n")

      # in this case, must use psl.melted instead of psleuFull. Both are already in anomalies:
      # (psl.melted depends on the startdate and leadtime, psleuFull no)
      gc()
      pslmat <- unname(acast(psl.melted, Member + StartYear + LeadDay ~ Lat ~ Lon))
      #pslmat <- unname(acast(melt(pslPeriod[1,1:2,,,,, drop=FALSE],varnames=c("Exp","Member","StartYear","LeadDay","Lat","Lon")), Member ~ StartYear + LeadDay ~ Lat ~ Lon))
      gc()

      #for(a in 1:2){
      #    for(b in 1:3){
      #        for(c in 1:4){
      #             pslmat[1, a + (b-1)*a + (c-1)*a*b,,] <- pslPeriod[1,a,b,c,,]
      #        }
      #    }
      #}                                 
      
      pslwr1 <- pslmat[wr1,,, drop=F]
      pslwr2 <- pslmat[wr2,,, drop=F]
      pslwr3 <- pslmat[wr3,,, drop=F]
      pslwr4 <- pslmat[wr4,,, drop=F]

      pslwr1mean <- apply(pslwr1, c(2,3), mean, na.rm=T)
      pslwr2mean <- apply(pslwr2, c(2,3), mean, na.rm=T)
      pslwr3mean <- apply(pslwr3, c(2,3), mean, na.rm=T)
      pslwr4mean <- apply(pslwr4, c(2,3), mean, na.rm=T)

      # spatial mean for each day to save for the meaure of the FairRPSS:
      pslwr1spmean <- apply(pslwr1, 1, mean, na.rm=T)
      pslwr2spmean <- apply(pslwr2, 1, mean, na.rm=T)
      pslwr3spmean <- apply(pslwr3, 1, mean, na.rm=T)
      pslwr4spmean <- apply(pslwr4, 1, mean, na.rm=T)
      
      rm(pslmat)
      gc()

      # save all the data necessary to draw the graphs (but not the impact maps)
      save(my.cluster, cluster.sequence, my.cluster.array, lon, lon.max, lat, pos.lat, pos.lon, n.pos.lat, n.pos.lon, psl, psl.name, my.period, p, workdir,rean.name,fields.name, year.start,year.end, years, n.years, n.years.full, WR.period, pslwr1mean, pslwr2mean, pslwr3mean, pslwr4mean, pslwr1spmean, pslwr2spmean, pslwr3spmean, pslwr4spmean, wr1y, wr2y, wr3y, wr4y, wr1yMax, wr2yMax, wr3yMax, wr4yMax, wr1yMin, wr2yMin, wr3yMin, wr4yMin, wr1, wr2, wr3, wr4, n.leadtimes, num.leadtimes, LOESS, running.cluster, running.15, lat.weighting, file=paste0(workdir,"/",fields.name,"_",my.period[p],"_leadmonth_",lead.month,"_psl.RData"))
      
      rm(pslwr1mean,pslwr2mean,pslwr3mean,pslwr4mean)
      rm(pslwr1,pslwr2,pslwr3,pslwr4)
      gc()   
      
    }

    # for the monthly system, the time order is always:  year1day1, year2day1, ... , yearNday1, year1day2, year2day2, ..., yearNday2, etc.:
    if(fields.name == ECMWF_monthly.name) {
       if(fields.name == ECMWF_monthly.name){
       my.startdates.period <- months.period(forecast.year,mes,day,p)

       #if(p == 13) my.startdates.period <- my.startdates.period[-2]  # remove the second startdate because it is broken
       
       days.period <- period.length <- list()
       for(startdate in my.startdates.period){
          days.period[[p]] <- c(days.period[[p]], (1+(startdate-1)*(year.end-year.start+1)):(startdate*(year.end-year.start+1)))
       }
       period.length[[p]] <- length(my.startdates.period) # number of Thusdays in the period
      }

      wr1y <- wr2y <- wr3y <-wr4y <- c()
      wr1y[y-year.start+1] <- length(which(cluster.sequence[seq((y-year.start+1),length(cluster.sequence), n.years)] == 1))
      wr2y[y-year.start+1] <- length(which(cluster.sequence[seq((y-year.start+1),length(cluster.sequence), n.years)] == 2))
      wr3y[y-year.start+1] <- length(which(cluster.sequence[seq((y-year.start+1),length(cluster.sequence), n.years)] == 3))
      wr4y[y-year.start+1] <- length(which(cluster.sequence[seq((y-year.start+1),length(cluster.sequence), n.years)] == 4))
    }

     cat("Finished!\n")
} # close the for loop on 'p' 








teleconextion <- FALSE
if(teleconexion){
    
    ## bypass the years setted in the script header:
    year.start <- 1981
    year.end <- 2015 #2016

    n.years <- year.end - year.start + 1
    
    ## load monthly psl:
    pslFull <-  Load(var = psl, exp = NULL, obs = list(list(path=fields)), paste0(year.start:year.end,'0101'), storefreq = 'monthly', leadtimemax = 12, output = 'lonlat', latmin = lat.min, latmax = lat.max, lonmin = lon.min, lonmax = lon.max, nprocs=1)

    if(psl == "psl") pslFull$obs <- pslFull$obs/100   # convert MSLP in Pascal to MSLP in hPa
    
    pslFullClim <- apply(pslFull$obs, c(1,2,4,5,6), mean, na.rm=T)

    pslFullSd <- apply(pslFull$obs, c(1,2,4,5,6), sd, na.rm=T)

    pslFullClim2 <- InsertDim(pslFullClim,3,n.years)
    pslFullSd2 <- InsertDim(pslFullSd,3,n.years)

    ## monthly standarized anomalies:
    pslAnom <- ( pslFull$obs - pslFullClim2) / pslFullSd2
    pslAnom <- pslAnom[1,1,,,,]
    
    ##pslAnom.melted <- melt(pslAnom[,,,, drop=FALSE], varnames=c("Year","Month","Lat","Lon"))
    ##pslAnom2 <- unname(acast(pslAnom.melted, Year + Month ~ Lat ~ Lon)) # order: year1 month1, year1 month2, etc
    gc()
                       
    ## load monthly time series of teleconnection indices:
    NAO <- read.table(file="/esarchive/scratch/ncortesi/BSC/RESILIENCE/Regimes/series_teleconnexion_CPC/NAO.txt", header=FALSE)
    EA <- read.table(file="/esarchive/scratch/ncortesi/BSC/RESILIENCE/Regimes/series_teleconnexion_CPC/EA.txt", header=FALSE)
    EAWR <- read.table(file="/esarchive/scratch/ncortesi/BSC/RESILIENCE/Regimes/series_teleconnexion_CPC/EAWR.txt", header=FALSE)
    SCAND <- read.table(file="/esarchive/scratch/ncortesi/BSC/RESILIENCE/Regimes/series_teleconnexion_CPC/SCAND.txt", header=FALSE)

    names(NAO) <- names(EA) <- names(EAWR) <-  names(SCAND) <- c("year","month","index")

    # select only teleconnection in the chosen years:
    row.start1 <- which(NAO[,1] == year.start)[1]
    row.end1 <- which(EA[,1] == year.end)[l(which(EA[,1] == year.end))]
    row.start2 <- which(EA[,1] == year.start)[1]
    row.end2 <- which(EA[,1] == year.end)[l(which(EA[,1] == year.end))]
    row.start3 <- which(EAWR[,1] == year.start)[1]
    row.end3 <- which(EAWR[,1] == year.end)[l(which(EAWR[,1] == year.end))]
    row.start4 <- which(SCAND[,1] == year.start)[1]
    row.end4 <- which(SCAND[,1] == year.end)[l(which(SCAND[,1] == year.end))]
    
    NAOy <- NAO[row.start1:row.end1,]
    EAy <- EA[row.start2:row.end2,]
    EAWRy <- EAWR[row.start3:row.end3,]
    SCANDy <- SCAND[row.start4:row.end4,]

    ## month <- 1:12
    ## for(m in month){
    ##     # select only teleconnection data in month m:
    ##     rows <- which(NAOy[,2] == m)
        
    ##     NAOm <- NAOy[rows,]
    ##     EAm <- EAy[rows,]
    ##     EAWRm <- EAWRy[rows,]
    ##     SCANDm <- SCANDy[rows,]
    ## }

    NAO.map <- EA.map <- EAWR.map <- SCAND.map <- NAO.map.corr <- EA.map.corr <- EAWR.map.corr <- SCAND.map.corr <- array(NA, c(12,dim(pslAnom)[3:4]))
    
    ## create teleconnection maps:

    month <- 1:12
    for(m in month){
        #NAO.map[m,,] <- apply(pslAnom[,m,,], c(2,3), function(x) mean(x * NAOy[which(NAOy[,2] == m),3]))
        #EA.map[m,,] <- apply(pslAnom[,m,,], c(2,3), function(x) mean(x * EAy[which(NAOy[,2] == m),3]))
        #EAWR.map[m,,] <- apply(pslAnom[,m,,], c(2,3), function(x) mean(x * EAWRy[which(EAWRy[,2] == m),3]))
        #SCAND.map[m,,] <- apply(pslAnom[,m,,], c(2,3), function(x) mean(x * SCANDy[which(SCANDy[,2] == m),3]))

        NAO.map.corr[m,,] <- apply(pslAnom[,m,,], c(2,3), function(x) cor(x, NAOy[which(NAOy[,2] == m),3], use = "na.or.complete"))
        EA.map.corr[m,,] <- apply(pslAnom[,m,,], c(2,3), function(x) cor(x, EAy[which(NAOy[,2] == m),3], use = "na.or.complete"))
        EAWR.map.corr[m,,] <- apply(pslAnom[,m,,], c(2,3), function(x) cor(x, EAWRy[which(EAWRy[,2] == m),3], use = "na.or.complete"))
        SCAND.map.corr[m,,] <- apply(pslAnom[,m,,], c(2,3), function(x) cor(x, SCANDy[which(SCANDy[,2] == m),3], use = "na.or.complete"))
    }

    ## NAO.map <- apply(pslAnom2, c(2,3), function(x) mean(x*NAOy[,3]))
    ## NAO.map.corr <- apply(pslAnom2, c(2,3), function(x) cor(x,NAOy[,3]))
    
    #my.brks <- c(-100,seq(-1,1,0.1),100)
    #my.cols <- colorRampPalette(rev(brewer.pal(11,"RdBu")))(length(my.brks)-1)    # blue--red colors
    #my.cols[floor(length(my.cols)/2)] <- my.cols[floor(length(my.cols)/2)+1] <- "white" ## add white in the middle

    my.brks.corr <- c(-1, -0.6, -0.45, -0.3, -0.15, 0,  0.15, 0.30, 0.45, 0.60, 1) #seq(-1,1,0.1)
    my.cols.corr <- colorRampPalette(rev(brewer.pal(11,"RdBu")))(length(my.brks.corr)-1)    # blue--red colors
    my.cols.corr[floor(length(my.cols.corr)/2)] <- my.cols.corr[floor(length(my.cols.corr)/2)+1] <- "white" ## add white in the middle

    fileoutput <- paste0(workdir,"/",fields.name,"_teleconexions.png")

    png(filename=fileoutput,width=15000,height=3700)

    plot.new()

    n.map <- 0
    month <- c(9:12, 1:8)
    for(m in month){
        n.map <- n.map+1
        y1 <- 0.10
        y3 <- 0.315
        y5 <- 0.53
        y7 <- 0.745
        y.width <- 0.18
        
        y2 <- y1 + y.width; y4 <- y3 + y.width; y6 <- y5 + y.width; y8 <- y7 + y.width
        yt1 <- y2+0.003; yt3 <- y4+0.003; yt5 <- y6+0.003; yt7 <- y8+0.003
        yt2 <- yt1 + 0.004; yt4 <- yt3 + 0.005; yt6 <- yt5 + 0.005; yt8 <- yt7 + 0.005
        
        ## ## Teleconnection maps:
        ## map.xpos <- 0.00
        ## map.width <- 0.46
        ## par(fig=c(map.xpos + 0.003, map.xpos + map.width - 0.003, y7, y8), new=TRUE)
        ## PlotEquiMap2(NAO.map[m,,], lon, lat, filled.continents=FALSE, brks=my.brks, cols=my.cols, sizetit=1.2, contours=t(NAO.map[m,,]), brks2=my.brks, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F", continents.col="black")
        ## par(fig=c(map.xpos, map.xpos + map.width, y5, y6), new=TRUE)
        ## PlotEquiMap2(EA.map[m,,], lon, lat, filled.continents=FALSE, brks=my.brks, cols=my.cols, sizetit=1.2, contours=t(EA.map[m,,]), brks2=my.brks, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F", continents.col="black")
        ## par(fig=c(map.xpos, map.xpos + map.width, y3, y4), new=TRUE)
        ## PlotEquiMap2(EAWR.map[m,,], lon, lat, filled.continents=FALSE, brks=my.brks, cols=my.cols, sizetit=1.2, contours=t(EAWR.map[m,,]), brks2=my.brks, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F", continents.col="black")
        ## par(fig=c(map.xpos, map.xpos + map.width, y1, y2), new=TRUE)
        ## PlotEquiMap2(SCAND.map[m,,], lon, lat, filled.continents=FALSE, brks=my.brks, cols=my.cols, sizetit=1.2, contours=t(SCAND.map[m,,]), brks2=my.brks, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F", continents.col="black")        

        ## Correlation maps:

        map.width <- 0.08
        map.xpos <- 0.03 + map.width * (n.map-1)
        par(fig=c(map.xpos + 0.003, map.xpos + map.width - 0.003, y7, y8), new=TRUE)
        PlotEquiMap2(NAO.map.corr[m,,], lon, lat, filled.continents=FALSE, brks=my.brks.corr, cols=my.cols.corr, sizetit=1.2, contours=t(NAO.map.corr[m,,]), brks2=my.brks.corr, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F", continents.col="black")
        par(fig=c(map.xpos, map.xpos + map.width, y5, y6), new=TRUE)
        PlotEquiMap2(EA.map.corr[m,,], lon, lat, filled.continents=FALSE, brks=my.brks.corr, cols=my.cols.corr, sizetit=1.2, contours=t(EA.map.corr[m,,]), brks2=my.brks.corr, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F", continents.col="black")
        par(fig=c(map.xpos, map.xpos + map.width, y3, y4), new=TRUE)
        PlotEquiMap2(EAWR.map.corr[m,,], lon, lat, filled.continents=FALSE, brks=my.brks.corr, cols=my.cols.corr, sizetit=1.2, contours=t(EAWR.map.corr[m,,]), brks2=my.brks.corr, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F", continents.col="black")
        par(fig=c(map.xpos, map.xpos + map.width, y1, y2), new=TRUE)
        PlotEquiMap2(SCAND.map.corr[m,,], lon, lat, filled.continents=FALSE, brks=my.brks.corr, cols=my.cols.corr, sizetit=1.2, contours=t(SCAND.map.corr[m,,]), brks2=my.brks.corr, intxlon=10, intylat=10, drawleg=F, cex.lab=1.5, xlabel.dist=1.5, contours.lty="F1FF1F", continents.col="black")

        ## Title Centroid Maps:
        title1.width <- 0.08
        title1.xpos <- 0.03 + (n.map-1) *  title1.width

        par(fig=c(title1.xpos, title1.xpos + title1.width, 0.9, 0.95), new=TRUE)
        mtext(my.period[m], font=2, cex=8)


    } ## close for on month m

    ## Legend:
    legend.xpos <- 0.3
    legend.width <- 0.4
    legend.cex <- 6
    
    par(fig=c(legend.xpos, legend.xpos + legend.width, 0.035, 0.095), new=TRUE)
    ColorBar(brks=round(my.brks.corr,2), cols=my.cols.corr, vert=FALSE, label_scale=6, subsample=1, triangle_ends=c(FALSE,FALSE))
    ##mtext(side=4,paste0(" ",var.unit[var.num]), cex=legend2.cex, las=1)  
    ##mtext(side=4,"cor", cex=legend2.cex, las=1)  

    yt1 <- yt1 - 0.1
    yt3 <- yt3 - 0.1
    yt5 <- yt5 - 0.13
    yt7 <- yt7 - 0.14
    par(fig=c(0, 0.03, yt7+0.0025, yt7+0.0055), new=TRUE)
    mtext("NAO", font=2, cex=10)
    par(fig=c(0, 0.03, yt5+0.0025, yt5+0.0055), new=TRUE)
    mtext("EA", font=2, cex=10)
    par(fig=c(0, 0.03, yt3+0.0025, yt3+0.0055), new=TRUE)
    mtext("EAWR", font=2, cex=10)
    par(fig=c(0, 0.03, yt1+0.0025, yt1+0.0055), new=TRUE)
    mtext("SCAND", font=2, cex=10)

    dev.off()
    
} # close if on teleconexion



















