
# Creation: 6/2016
# Author: Nicola Cortesi
# Aim: to compute the ACC, RPSS, CRPSS (+ bootstrapping) and the Reliability diagrams for a subseasonal forecast system
# I/O: input monthly hindcasts formatted as in /esnas, output: .png with the desired skill score
# Assumptions: it relies on Load() to import data
# Branch: skill_assessment

#########################################################################################
#                               Sub-seasonal Skill Scores                               #
#########################################################################################
# you can run it from the terminal with the syntax:
#
# Rscript SkillScores_v7.R <chunk to compute>
#
# i.e: to run only the chunk number 3, write:
#
# Rscript SkillScores_v4.R 3
#
# if you don't specify any argument, or you run it from the R interface, it runs all the chunks in a sequential way.
# Use this last approach only if the computational speed is not a problem.

##########################################################################################
#                            Load functions and libraries                                #
##########################################################################################

#load libraries and functions:
library(s2dverification)   # for Load() function
library(SpecsVerification) # for skill scores
library(easyVerification)  # for veriApply() function
library(abind)             # for merging arrays

##########################################################################################
#                                MareNostrum settings                                    #
##########################################################################################

args <- commandArgs(TRUE) # put into variable args the list with all the optional arguments with whom the script was run from the terminal

if(length(args) == 0) print("Running the script in a sequential way")
if(length(args) > 1) stop("Only one argument is required")

mare <- ifelse(length(args) == 1 ,TRUE, FALSE) # set variable 'mare' to TRUE if we are running the script in MareNostrum, FALSE otherwise

if(mare) chunk <- as.integer(args[1])  # number of the chunk to run in this script (if mare == TRUE)

##########################################################################################
#                                     User's settings                                    #
##########################################################################################
#if(!mare) {source('/home/Earth/ncortesi/Downloads/scripts/Rfunctions.R')} else {source('/gpfs/projects/bsc32/bsc32842/scripts/Rfunctions.R')}

# working dir where to put the output maps and files in the /Data and /Maps subdirs:
workdir <- ifelse(!mare, "/scratch/Earth/ncortesi/RESILIENCE", "/gpfs/projects/bsc32/bsc32842/results")

cfs.name <- 'ECMWF'                      # name of the climate forecast system (CFS) used for monthly predictions (to be used in map titles)
var.name <- 'sfcWind'                    # forecast variable. It is the name used inside the netCDF files and as suffix in map filenames, i.e: 'sfcWind' or 'psl'
var.name.map <- '10m Wind Speed'         # forecast variable to verify (name used in the map titles), i.e: '10m Wind Speed' or 'SLP'

forecast.year <- 2014                    # starting year of the weekly sequence of the forecasts
mes <- 1                                 # starting forecast month (1: january, 2: february, etc.)
day <- 2                                 # starting forecast day

# generic path of the forecast system files:
ECMWF_monthly <- list(path = paste0('/esnas/exp/ECMWF/monthly/ensforhc/weekly_mean/$VAR_NAME$_f6h/',forecast.year,'$MONTH$$DAY$00/$VAR_NAME$_$START_DATE$00.nc'))

yr1.hind <- 1994 #1994         # first hindcast year
yr2.hind <- 2013 #2013         # last hindcast year (usually the forecast year -1)

leadtime.week <- c('5-11','12-18','19-25','26-32') # which leadtimes are available in the weekly dataset
n.members <- 4  # number of hindcast members

my.score.name <- c('FairRpss','FairCrpss') #c('EnsCorr','FairRpss','FairCrpss','RelDiagr')  # choose one or more skills scores to compute between EnsCorr, FairRPSS, FairCRPSS and/or RelDiagr
              
veri.month <- 1 #1:12      # select the month(s) you want to compute the chosen skill scores

my.pvalue <- 0.05          # in case of computing the EnsCorr, set the p_value level to show in the ensemble mean correlation maps
my.prob <- c(1/3,2/3)      # quantiles used for FairRPSS and the RelDiagr (usually they are the terciles)
conf.level <- c(0.05, 0.95)# percentiles employed for the calculation of the confidence level for the Rpss and Crpss (can be more than 2 if needed)
int.lat <- NULL #1:160     # latitude position of grid points selected for the Reliability Diagram (if you want to subset a region; if not, put NULL)
int.lon <- NULL #1:320     # longitude position of grid points selected for the Reliability Diagram (if you want to subset a region; if not, put NULL)

boot <- TRUE               # in case of computing the FairRpss and/or the FairCrpss, you can choose to do a bootstrap to evaluate the uncertainty of the skill scores
n.boot <- 20               # number of resamples considered in the bootstrapping

# coordinates of a chosen point in the world to plot the time series over the 52 maps (they must be the same values in objects la y lo)
my.lat <- 55.3197120 
my.lon <- 0.5625

###################################### Derived variables #############################################################################

#source(paste0(workdir,'/ColorBarV.R'))  # Color scale used for maps
n.categ <- 1+length(my.prob)  # number of forecasting categories (usually 3 if terciles are used)

# blue-yellow-red colors:
#col <- ifelse(!mare, as.character(read.csv("/scratch/Earth/ncortesi/RESILIENCE/rgbhex.csv",header=F)[,1]), as.character(read.csv("/gpfs/projects/bsc32//bsc32842/scripts/rgbhex.csv",header=F)[,1]))  
#col<-as.character(read.csv("/home/Earth/vtorralb/rgbhex.csv",header=F)[,1])  # blue-yellow-red colors
col <- c("#0C046E", "#1914BE", "#2341F7", "#2F55FB", "#3E64FF", "#528CFF", "#64AAFF", "#82C8FF", "#A0DCFF", "#B4F0FF", "#FFFBAF", "#FFDD9A", "#FFBF87", "#FFA173", "#FF7055", "#FE6346", "#F7403B", "#E92D36", "#C80F1E", "#A50519")

    
sdates.seq <- weekly.seq(forecast.year,mes,day)  # load the sequence of dates corresponding to all the thursday of the year
n.leadtimes <- length(leadtime.week)
n.yrs.hind <- yr2.hind-yr1.hind+1
my.month.short <- substr(my.month,1,3)

## extract geographic coordinates; do only ONCE for each preducton system and then save the lat/lon in a coordinates.RData and comment these rows to use function load() below: 
#data.hindcast <- Load(var='sfcWind', exp = 'EnsEcmwfWeekHind', 
#	      	 obs = NULL, sdates=paste0(yr1.hind:yr2.hind,substr(sdates.seq[startdate],5,6),substr(sdates.seq[startdate],7,8)),
#		 nleadtime = 1, leadtimemin = 1, leadtimemax = 1, output = 'lonlat', configfile = file_path, method='distance-weighted' )

#lats<-data.hindcast$lat
#lons<-data.hindcast$lon
#save(lats,lons,file=paste0(workdir,'/coordinates.RData'))
#rm(data.hindcast);gc()

# format geographic coordinates to use with PlotEquiMap:
load(paste0(workdir,'/coordinates.RData'))
n.lon <- length(lons)
n.lat <- length(lats)
n.lonr <- n.lon - ceiling(length(lons[lons<180 & lons > 0]))
#la<-rev(lats)
#lo<-c(lons[c((n.lonr+1):n.lon)]-360,lons[1:n.lonr])

if(mare) n.lat == 1

#########################################################################################
#     Calculate and save up to all the chosen Skill Scores for a selected period        #
#########################################################################################
#
# Remember that before computing the skill scores, you have to create and save the anomalies running once the preformatting part at the end of this script.
#
    
for(month in veri.month){
    #month=1 # for the debug
    my.startdates <- which(as.integer(substr(sdates.seq,5,6)) == month) #startdates.monthly[[month]] #c(1:5)    # select the startdates (weeks) you want to compute
    startdate.name <- my.month[month]                       # name given to the period of the selected startdates  # i.e:"January" 
    n.startdates <- length(my.startdates)                    # number of startdates in the selected month
    n.yrs <- length(my.startdates)*n.yrs.hind               # number of total years for the selected month
    
    print(paste0("Computing Skill Scores for ",startdate.name))

    # Merge all selected startdates:
    hind.dim <- c(n.members, n.yrs.hind*n.startdates, n.leadtimes, n.lat, n.lon)  # dimensions of the hindcast array
        
    my.FairRpss <- my.FairCrpss <- my.EnsCorr <- my.PValue <- array(NA,c(n.leadtimes, n.lat,n.lon))
    if(boot) my.FairRpssBoot <- my.FairCrpssBoot <- array(NA, c(n.boot, n.leadtimes, n.lat, n.lon))
    if(boot) my.FairRpssConf <- my.FairCrpssConf <- array(NA, c(length(conf.level), n.leadtimes, n.lat, n.lon))

    cat('Chunk n. ')

    # if we run the script from the terminal with an argument, it only computes the chunk we specify in the second argument and save the results for that chunk.
    # If not, it loops over all chunks in a serial way and save the results at the end.
    if(!mare) {my.chunks <- 1:n.lat} else {my.chunks <- chunk} 
    
    for(c in my.chunks){ # EnsCorr, FairRpss and FairCrpss calculation:
       #s=1 # for the debug
       cat(paste0(c,'/', n.lat,' '))
       anom.hindcast.chunk <- anom.hindcast.chunk.sampled <- array(NA, c(n.members, n.startdates*n.yrs.hind, n.leadtimes, c, n.lon))
       anom.rean.chunk <- anom.hindcast.mean.chunk <- anom.rean.chunk.sampled <- array(NA, c(n.startdates*n.yrs.hind, n.leadtimes, c, n.lon))
       #my.interv<-(1 + sub.size*(s-1)):((sub.size*s) + add.last)          # longitude interval where to load data
        
       # not working on MareNostrum still: 
       # load 1 file ONLY ONCE to retrieve the lat and lon values, then save them in an .RData file to retrieve them when needed:
       coord <- Load(var = 'sfcWind', exp = list(ECMWF_monthly), obs = NULL, sdates=paste0(2013,'0102'), leadtimemin = 1, leadtimemax=1,  output = 'lonlat', nprocs=1)
       # lat <- coord$lat
       # lon <- coord$lon
       # save()
       # load()
       #system.time(a<-Load(var = 'sfcWind', exp = list(ECMWF_monthly), obs = NULL, sdates=paste0(2010:2013,'0102'), leadtimemin = 1, leadtimemax=3,  output = 'lonlat', nprocs=1, latmin = lat[5], latmax = lat[5]))

       for(startdate in my.startdates){
	  pos.startdate<-which(startdate == my.startdates) # count of the number of stardates already loaded+1
          my.time.interv<-(1+(pos.startdate-1)*n.yrs.hind):(pos.startdate*n.yrs.hind)  # time interval where to load data
          
	  # Load reanalysis data:
	  load(paste0(workdir,'/Data_',var.name,'/anom_rean_startdate',startdate,'.RData'))
	  anom.rean <- drop(anom.rean)
	  anom.rean.chunk[my.time.interv,,,] <- anom.rean[,,c,]
          
          # Load hindcast data:
	  if(any(my.score.name=="FairRpss") || any(my.score.name=="FairCrpss" || any(my.score.name=="RelDiagr"))){
	     load(paste0(workdir,'/Data_',var.name,'/anom_hindcast_startdate',startdate,'.RData')) 
	     anom.hindcast <- drop(anom.hindcast)
	     anom.hindcast.chunk[,my.time.interv,,,] <- anom.hindcast[,,,c,]  
	     rm(anom.hindcast, anom.rean)
             gc()
	  }

	  if(any(my.score.name=="EnsCorr")){
	     load(paste0(workdir,'/Data_',var.name,'/anom_hindcast_mean_startdate',startdate,'.RData'))  # load ensemble mean hindcast data
	     anom.hindcast.mean <- drop(anom.hindcast.mean)
	     anom.hindcast.mean.chunk[my.time.interv,,,] <- anom.hindcast.mean[,,c,]
	     rm(anom.hindcast.mean)
             gc()
	  }

       }
        
       if(any(my.score.name=="FairRpss")){
          if(!boot){
            #anom.hindcast.chunk.double <- abind(list(anom.hindcast.chunk,anom.hindcast.chunk),along=4)
            #anom.rean.chunk.double <- abind(list(anom.rean.chunk,anom.rean.chunk),along=3)
            

	    #my.FairRpss.sub <- veriApply("FairRpss", fcst=anom.hindcast.sub, obs=anom.rean.sub, prob=my.prob, tdim=2, ensdim=1, parallel=FALSE, ncpus=n.cpus)
            my.FairRps.chunk <- veriApply("FairRps", fcst=anom.hindcast.chunk, obs=anom.rean.chunk, prob=my.prob, tdim=2, ensdim=1, parallel=FALSE, ncpus=n.cpus)
            #my.FairRps.chunk.double <- veriApply("FairRps", fcst=anom.hindcast.chunk.double, obs=anom.rean.chunk.double, prob=my.prob, tdim=2, ensdim=1, parallel=FALSE, ncpus=n.cpus)
  
            # the prob.for the climatological ensemble can be set without using convert2prob and they are the same for all points and leadtimes (33% for each tercile):
            ens <- array(33,c(n.startdates*n.yrs.hind,3)) 

            # the observed probabilities vary from point to point and for each leadtime:  
            obs <- apply(anom.rean.chunk, c(2,3,4), function(x){convert2prob(x, prob <- my.prob)})

            # reshape obs to be able to apply EnsRps(ens, obs) below:  
            obs2 <- InsertDim(obs,1,3)
            obs2[2,1:(n.startdates*n.yrs.hind),,,] <- obs2[1,(n.startdates*n.yrs.hind + 1:(n.startdates*n.yrs.hind)),,,]
            obs2[3,1:(n.startdates*n.yrs.hind),,,] <- obs2[1,(2*n.startdates*n.yrs.hind + 1:(n.startdates*n.yrs.hind)),,,]
            obs3 <- obs2[,1:(n.startdates*n.yrs.hind),,,,drop=F] # drop=F is used not to loose the dimension(s) with only 1 element
              
            my.Rps.clim.chunk <- apply(obs3,c(3,4,5), function(x){ EnsRps(ens,t(x)) })
        
            my.FairRps.chunk.sum <- apply(my.FairRps.chunk, c(2,3,4), sum)
            my.Rps.clim.chunk.sum <- apply(my.Rps.clim.chunk, c(2,3,4), sum)
          
	    my.FairRpss.chunk <- 1-(my.FairRps.chunk.sum/my.Rps.clim.chunk.sum)
              
            my.FairRpss[,c,] <- my.FairRpss.chunk
              
	    rm(my.FairRpss.chunk, ens, obs, obs2, obs3, my.FairRps.chunk.sum, my.Rps.clim.chunk.sum)
            gc()
              
          } else {    # bootstrapping:                
             
            for(b in 1:n.boot){
                cat(paste0("resampling n. ",b,"/",n.boot))
                yrs.sampled <- sample(1:n.yrs, replace=TRUE)

                for(y in 1:n.yrs) anom.hindcast.chunk.sampled[,y,,,] <- anom.hindcast.chunk[,yrs.sampled[y],,,]
                for(y in 1:n.yrs) anom.rean.chunk.sampled[y,,,] <- anom.rean.chunk[yrs.sampled[y],,,]

                my.FairRps.chunk <- veriApply("FairRps", fcst=anom.hindcast.chunk.sampled, obs=anom.rean.chunk.sampled, prob=my.prob, tdim=2, ensdim=1, parallel=FALSE, ncpus=n.cpus)
                ens <- array(33,c(n.startdates*n.yrs.hind,3)) 
                obs <- apply(anom.rean.chunk.sampled, c(2,3,4), function(x){convert2prob(x, prob <- my.prob)})
                obs2 <- InsertDim(obs,1,3)
                obs2[2,1:(n.startdates*n.yrs.hind),,,] <- obs2[1,(n.startdates*n.yrs.hind + 1:(n.startdates*n.yrs.hind)),,,]
                obs2[3,1:(n.startdates*n.yrs.hind),,,] <- obs2[1,(2*n.startdates*n.yrs.hind + 1:(n.startdates*n.yrs.hind)),,,]
                obs3 <- obs2[,1:(n.startdates*n.yrs.hind),,,,drop=F]
                my.Rps.clim.chunk <- apply(obs3,c(3,4,5), function(x){ EnsRps(ens,t(x)) })
                my.FairRps.chunk.sum <- apply(my.FairRps.chunk,c(2,3,4), sum)
                my.Rps.clim.chunk.sum <- apply(my.Rps.clim.chunk,c(2,3,4), sum)
                my.FairRpss.chunk <- 1-(my.FairRps.chunk.sum/my.Rps.clim.chunk.sum)

                my.FairRpssBoot[b,,,chunk$int[[c]]] <- my.FairRpss.chunk
                rm(my.FairRpss.chunk, ens, obs, obs2, obs3, my.FairRps.chunk.sum, my.Rps.clim.chunk.sum)
                gc()
            }
              
            cat('\n')
              
            # calculate the percentiles of the skill score:
            my.FairRpssConf[,,,chunk$int[[c]]] <- apply(my.FairRpssBoot[,,,chunk$int[[c]]], c(2,3,4), function(x) quantile(x, probs=conf.level, type=8)) 
          }
       }

       if(any(my.score.name=="FairCrpss")){
          if(!boot){ 
	    my.FairCrps.chunk <- veriApply("FairCrps", fcst=anom.hindcast.chunk, obs=anom.rean.chunk, tdim=2, ensdim=1, parallel=FALSE, ncpus=n.cpus)
            anom.all.chunk <- abind(anom.hindcast.chunk,anom.rean.chunk, along=1) # merge exp and obs together to use apply:
            my.Crps.clim.chunk <- apply(anom.all.chunk, c(3,4,5), function(x){ EnsCrps(t(x[1:n.members,]), x[n.members+1,])})
            
            my.FairCrps.chunk.sum <- apply(my.FairCrps.chunk,c(2,3,4), sum)
            my.Crps.clim.chunk.sum <- apply(my.Crps.clim.chunk,c(2,3,4), sum)
            my.FairCrpss.chunk <- 1-(my.FairCrps.chunk.sum/my.Crps.clim.chunk.sum)

	    my.FairCrpss[,,chunk$int[[c]]]<-my.FairCrpss.chunk
	    rm(my.FairCrpss.chunk, my.FairCrps.chunk.sum, my.Crps.clim.chunk.sum)
            gc()
            
          } else { # bootstrapping:
              
            for(b in 1:n.boot){
                print(paste0("resampling n. ",b,"/",n.boot))
                yrs.sampled <- sample(1:n.yrs, replace=TRUE)

                for(y in 1:n.yrs) anom.hindcast.chunk.sampled[,y,,,] <- anom.hindcast.chunk[,yrs.sampled[y],,,]
                for(y in 1:n.yrs) anom.rean.chunk.sampled[y,,,] <- anom.rean.chunk[yrs.sampled[y],,,]

                my.FairCrps.chunk <- veriApply("FairCrps", fcst=anom.hindcast.chunk.sampled, obs=anom.rean.chunk.sampled, tdim=2, ensdim=1, parallel=TRUE, ncpus=n.cpus)
                anom.all.chunk <- abind(anom.hindcast.chunk.sampled, anom.rean.chunk.sampled, along=1) # merge exp and obs together to use apply:
                my.Crps.clim.chunk <- apply(anom.all.chunk, c(3,4,5), function(x){ EnsCrps(t(x[1:n.members,]), x[n.members+1,])})
                my.FairCrps.chunk.sum <- apply(my.FairCrps.chunk,c(2,3,4), sum)
                my.Crps.clim.chunk.sum <- apply(my.Crps.clim.chunk,c(2,3,4), sum)
                my.FairCrpss.chunk <- 1-(my.FairCrps.chunk.sum/my.Crps.clim.chunk.sum)
	         
                my.FairCrpssBoot[b,,,chunk$int[[c]]] <- my.FairCrpss.chunk
                rm(my.FairCrpss.chunk, my.FairCrps.chunk.sum, my.Crps.clim.chunk.sum)
                gc()
          
             }
              
             cat('\n')
              
             # calculate the percentiles of the skill score:
             my.FairCrpssConf[,,,chunk$int[[c]]] <- apply(my.FairCrpssBoot[,,,chunk$int[[c]]], c(2,3,4), function(x) quantile(x, probs=conf.level, type=8)) 
          }
          
        }

       if(any(my.score.name=="EnsCorr")){
	  # ensemble mean correlation for the selected startdates (first dim, 'week') and all leadtimes (second dim):
	  my.EnsCorr.chunk <- my.PValue.chunk <- array(NA, c(n.leadtimes, n.lat, chunk$n.int[[c]]))

	  for(i in 1:n.leadtimes){
	    for(j in 1:n.lat){
	      for(k in 1:chunk$n.int[[c]]){                      
		my.EnsCorr.chunk[i,j,k] <- cor(anom.hindcast.mean.chunk[,i,j,k],anom.rean.chunk[,i,j,k], use="complete.obs")
	        # option 'na.method' is chosen from the following list: c("all.obs", "complete.obs", "pairwise.complete.obs", "everything", "na.or.complete")
               
                my.PValue.chunk[i,j,k] <- cor.test(anom.hindcast.mean.chunk[,i,j,k],anom.rean.chunk[,i,j,k], use="complete.obs")$p.value
                
	      }
	    }
	  }

	  my.EnsCorr[,,chunk$int[[c]]] <- my.EnsCorr.chunk
	  my.PValue[,,chunk$int[[c]]] <- my.PValue.chunk

	  rm(anom.hindcast.chunk,anom.hindcast.mean.chunk,my.EnsCorr.chunk,my.PValue.chunk)
       }

       rm(anom.rean.chunk)
       gc()
       #mem()

       if(mare == TRUE) {
          if(any(my.score.name=="FairRpss")) save(my.FairRpss, file=paste0(workdir,'/Data_',var.name,'/FairRpss_',startdate.name,'_chunk_',c,'.RData'))
          if(any(my.score.name=="FairCrpss")) save(my.FairCrpss, file=paste0(workdir,'/Data_',var.name,'/FairCrpss_',startdate.name,'_chunk_',c'.RData'))
          if(any(my.score.name=="EnsCorr")) save(my.EnsCorr, file=paste0(workdir,'/Data_',var.name,'/EnsCorr_',startdate.name,'_chunk_',c'.RData'))
       }
        
           
    } # next c (chunk) 

    # the Reliability diagram cannot be computed splitting the data in chunk, so it is computed only if the script is run from the R interface or with no arguments:
    if(mare == FALSE) { 
        if(any(my.score.name=="RelDiagr")){ # in this case the computation cannot be split in groups of grid points, but can be split for leadtime instead:   
            my.RelDiagr<-list()
            
            for(lead in 1:n.leadtimes){
                cat(paste0('leadtime n.: ',lead,'/',n.leadtimes))
                anom.rean.chunk <- array(NA,c(n.startdates*n.yrs.hind,n.lat,n.lon))
                anom.hindcast.chunk <- array(NA,c(n.members,n.startdates*n.yrs.hind,n.lat,n.lon))
                cat('  startdate: ')
                i=0 

                for(startdate in my.startdates){
                    i=i+1
                    cat(paste0(i,'/',length(my.startdates),'  '))

                    pos.startdate<-which(startdate==my.startdates) # count of the number of stardates already loaded+1
                    my.time.interv<-(1+(pos.startdate-1)*n.yrs.hind):(pos.startdate*n.yrs.hind)  # time interval where to load data

                    # Load reanalysis data of next startdate:
                    load(paste0(workdir,'/Data_',var.name,'/anom_rean_startdate',startdate,'.RData'))
                    anom.rean <- drop(anom.rean)
                    anom.rean.chunk[my.time.interv,,] <- anom.rean[,lead,,]
                    
                    # Lead hindcast data of next startdate:
                    load(paste0(workdir,'/Data_',var.name,'/anom_hindcast_startdate',startdate,'.RData'))  # load hindcast data
                    anom.hindcast <- drop(anom.hindcast)
                    anom.hindcast.chunk[,my.time.interv,,] <- anom.hindcast[,,lead,,]
                    
                    rm(anom.rean,anom.hindcast)
                }   


                anom.hindcast.chunk.perm<-aperm(anom.hindcast.chunk,c(2,1,3,4))  # swap the first two dimensions to put the years as first dimension (needed for convert2prob)
                gc()

                cat('Computing the Reliability Diagram. Please wait... ')
                ens.chunk<-apply(anom.hindcast.chunk.perm, c(3,4), convert2prob, prob<-my.prob) # its dimens. are: [n.startdates*n.yrs.hind*n.forecast.categories, n.lat, n.lon]
                obs.chunk<-apply(anom.rean.chunk,c(2,3), convert2prob, prob<-my.prob) # the first n.members*n.yrs.hind elements belong to the first tercile, and so on.
                ens.chunk.prob<-apply(ens.chunk, c(2,3), function(x) count2prob(matrix(x, n.startdates*n.yrs.hind, n.categ), type=4)) # type=4 is the only method with sum(prob)=1 !!  
                obs.chunk.prob<-apply(obs.chunk, c(2,3), function(x) count2prob(matrix(x, n.startdates*n.yrs.hind, n.categ), type=4)) #no parallelization here: it only takes 10s

                if(is.null(int.lat)) int.lat <- 1:n.lat  # if there is no region selected, select all the world
                if(is.null(int.lon)) int.lon <- 1:n.lon

                int1 <- 1:(n.startdates*n.yrs.hind)  # time interval of the data of the first tercile
                my.RelDiagr[[lead]]<-ReliabilityDiagram(ens.chunk.prob[int1,int.lat,int.lon], obs.chunk.prob[int1,int.lat,int.lon], nboot=0, plot=FALSE, plot.refin=F) #tercile 1

                int2 <- (1+(n.startdates*n.yrs.hind)):(2*n.startdates*n.yrs.hind)  # time interval of the data of the second tercile
                my.RelDiagr[[n.leadtimes+lead]]<-ReliabilityDiagram(ens.chunk.prob[int2,int.lat,int.lon], obs.chunk.prob[int2,int.lat,int.lon], nboot=0, plot=FALSE, plot.refin=F)

                int3 <- (1+(2*n.startdates*n.yrs.hind)):(3*n.startdates*n.yrs.hind)  # time interval of the data of the third tercile
                my.RelDiagr[[2*n.leadtimes+lead]]<-ReliabilityDiagram(ens.chunk.prob[int3,int.lat,int.lon], obs.chunk.prob[int3,int.lat,int.lon], nboot=0, plot=FALSE, plot.refin=F)

                cat('done\n')
                #print(my.RelDiagr) # for debugging
                
                rm(anom.rean.chunk,anom.hindcast.chunk,ens.chunk,obs.chunk,ens.chunk.prob,obs.chunk.prob)
                gc()

            } # next lead
            
        } # close if on RelDiagr

        # we can save the results for all chunks only if mare == FALSE (if it is TRUE, we have the results for 1 chunk only, that have already been saved
        if(!boot){ 
            if(any(my.score.name=="FairRpss")) save(my.FairRpss, file=paste0(workdir,'/Data_',var.name,'/FairRpss_',startdate.name,'.RData'))
            if(any(my.score.name=="FairCrpss")) save(my.FairCrpss, file=paste0(workdir,'/Data_',var.name,'/FairCrpss_',startdate.name,'.RData'))
            if(any(my.score.name=="EnsCorr")) save(my.EnsCorr, file=paste0(workdir,'/Data_',var.name,'/EnsCorr_',startdate.name,'.RData'))
            if(any(my.score.name=="RelDiagr")) save(my.RelDiagr, my.PValue, file=paste0(workdir,'/Data_',var.name,'/RelDiagr_',startdate.name,'.RData'))
        } else { # bootstrapping output:
            if(any(my.score.name=="FairRpss")) save(my.FairRpssBoot, my.FairRpssConf, file=paste0(workdir,'/Data_',var.name,'/FairRpssBoot_',startdate.name,'.RData'))
            if(any(my.score.name=="FairCrpss")) save(my.FairCrpssBoot, my.FairCrpssConf, file=paste0(workdir,'/Data_',var.name,'/FairCrpssBoot_',startdate.name,'.RData'))
        }

        # If it has finished computing the last chunk, it can load all results in one file, deleting the intermediate output files:
        if(job.chunk == tot.chunks){
            
        }
        
        
    } # close if on mare
        
} # next m (month)

if




# all pre-formatting (conversion to anomalies) and post-formatting (visualization) tasks are done below:
if(mare == FALSE){

###########################################################################################
#                  Visualize and save the score maps for one score and period             #
###########################################################################################

# run it only after computing and saving all the skill score data:

my.months=1 #9:12  # choose the month(s) to plot and save

for(month in my.months){
    #month=2  # for the debug                     
    startdate.name.map<-my.month[month]  # i.e:"January"  

    for(my.score.name.map in my.score.name){
	#my.score.name.map='EnsCorr'  # for the debug

	if(my.score.name.map=="EnsCorr") { load(file=paste0(workdir,'/Data_',var.name,'/EnsCorr_',startdate.name.map,'.RData')); my.score<-my.EnsCorr }
	if(my.score.name.map=='FairRpss') { load(file=paste0(workdir,'/Data_',var.name,'/FairRpss_',startdate.name.map,'.RData')); my.score<-my.FairRpss }
	if(my.score.name.map=='FairCrpss') { load(file=paste0(workdir,'/Data_',var.name,'/FairCrpss_',startdate.name.map,'.RData')); my.score<-my.FairCrpss }
	if(my.score.name.map=="RelDiagr") { load(file=paste0(workdir,'/Data_',var.name,'/RelDiagr_',startdate.name.map,'.RData')); my.score<-my.RelDiagr }

	# old green-red palette:
	# brk.rpss<-c(-1,seq(0,1,by=0.05))
	# col.rpss<-c("darkred",colorRampPalette(c("red","white","darkgreen"))(length(brk.rpss)-2))
	# brk.rps<-c(seq(0,1,by=0.1),10)
	# col.rps<-c(colorRampPalette(c("darkgreen","white","red"))(length(brk.rps)-2),"darkred")
	# if(my.score.name.map==my.Rps | my.score==my.Rps.clim) {my.brk<-brk.rps} else {my.brk<-brk.rpss}
	# if(my.score.name.map==my.Rps | my.score==my.Rps.clim) {my.col<-col.rps} else {my.col<-col.rpss}

	brk.rpss<-c(seq(-1,1,by=0.1))
	col.rpss<-colorRampPalette(col)(length(brk.rpss)-1)

	my.brk<-brk.rpss # at present all breaks and colors are the same, so there is no need to differenciate between indexes
	my.col<-col.rpss

	for(lead in 1:n.leadtimes){

	  #my.title<-paste0(my.score.name.map,' of ',cfs.name,' 
	  #10m Wind Speed for ',startdate.name.map,'. Forecast time ',leadtime.week[lead],'.') 

	  if(my.score.name.map!="RelDiagr"){

	      #postscript(file=paste0(workdir,'/Maps_',var.name,'/',my.score.name.map,'_',startdate.name.map,'_Forecast_time_',leadtime.week[lead],'_',var.name,'.ps'),
	      #           paper="special",width=12,height=7,horizontal=F)

	      jpeg(file=paste0(workdir,'/Maps_',var.name,'/',my.score.name.map,'_',startdate.name.map,'_Forecast_time_',leadtime.week[lead],'_',var.name,'.jpg'),width=1000,height=600)  

	      layout(matrix(c(1,2), 1, 2, byrow = TRUE),widths=c(11,1.2))
	      par(oma=c(1,1,4,1))

	      # lat values must be in decreasing order from +90 to -90 degrees and long from 0 to 360 degrees:         
	      PlotEquiMap(my.score[lead,,][n.lat:1,c((n.lonr+1):n.lon,1:n.lonr)], lons,lats ,sizetit=0.8, brks=my.brk, cols=my.col,axelab=F, filled.continents=FALSE, drawleg=F)
	      my.title<-paste0(my.score.name.map,' of ',cfs.name,'\n ', var.name.map,' for ',startdate.name.map,'. Forecast time ',leadtime.week[lead],'.') 
	      title(my.title,line=0.5,outer=T)

	      ColorBar(my.brk, cols=my.col, vert=T, cex=1.4)

	      if(my.score.name.map=="EnsCorr"){  #add a small grey point if the corr.is significant:

		# arrange lat/ lon in my.PValue (a second variable in the EnsCorr file) to start from +90 degr. (lat) and from 0 degr (lon):
		my.PValue.rev <- my.PValue
		my.PValue.rev[lead,,] <- my.PValue[i,n.lat:1,c((n.lonr+1):n.lon,1:n.lonr)] 
		for (x in 1:n.lon) {
		  for (y in 1:n.lat) {
		      if (my.PValue.rev[lead,y, x] == TRUE) {     
			 text(x = lo[x], y = la[y], ".", cex = .2)
		      }
		  }
		}
	      }
	      dev.off()

	  } # close if on !RelDiagr

	  if(my.score.name.map=="RelDiagr") {

	      jpeg(file=paste0(workdir,'/Maps_',var.name,'/RelDiagr_',startdate.name.map,'_Forecast_time_',leadtime.week[lead],'_',var.name,'.jpg'),width=600,height=600)  

	      my.title<-paste0('Reliability Diagram of ',cfs.name,'\n ',var.name.map,' for ',startdate.name.map,'. Forecast time ',leadtime.week[lead],'.')

	      plot(c(0,1),c(0,1),type="l",xlab="Forecast Frequency",ylab="Observed Frequency", col='gray30', main=my.title)
	      lines(my.score[[lead]]$p.avgs[!is.na(my.score[[lead]]$p.avgs)],my.score[[lead]]$cond.prob[!is.na(my.score[[lead]]$cond.prob)],type="o", pch=16, col="blue")
	      #lines(my.score[[n.leadtimes+lead]]$p.avgs[!is.na(my.score[[n.leadtimes+lead]]$p.avgs)],my.score[[n.leadtimes+lead]]$cond.prob[!is.na(my.score[[n.leadtimes+lead]]$cond.prob)],type="o",pch=16,col="darkgreen")
	      lines(my.score[[2*n.leadtimes+lead]]$p.avgs[!is.na(my.score[[2*n.leadtimes+lead]]$p.avgs)], my.score[[2*n.leadtimes+lead]]$cond.prob[!is.na(my.score[[2*n.leadtimes+lead]]$cond.prob)],type="o", pch=16, col="red")
	      legend("bottomright", legend=c('Lower Tercile','Upper Tercile'), lty=c(1,1), lwd=c(2.5,2.5), col=c('blue','red'))
    
	      dev.off()
	  }

	} # next lead

    } # next score

} # next month


###############################################################################################
#                        Composite map of the four skill scores                               #
###############################################################################################

# run it only when you have all the 4 skill scores for each month:

my.months=9:12  # choose the month(s) to plot and save

for(month in my.months){

    startdate.name.map<-my.month[month]  # i.e:"January"  

    #postscript(file=paste0(workdir,'/Maps_',var.name,'/SkillScores_',startdate.name.map,'_',var.name,'.ps'), paper="special",width=12,height=7,horizontal=F)

    jpeg(file=paste0(workdir,'/Maps_',var.name,'/SkillScores_',startdate.name.map,'_',var.name,'.jpg'), width=4000, height=2400,	quality=100)  

    layout(matrix(1:16, 4, 4, byrow=FALSE), widths=c(1.8,1.8,1.8,1.2), heights=c(1,1,1,1)) 
    #layout.show(16)

    for(score in 1:4){
	for(lead in 1:n.leadtimes){

	img<-readJPEG(paste0(workdir,'/Maps_',var.name,'/',my.score.name[score],'_',startdate.name.map,'_Forecast_time_',leadtime.week[lead],'_',var.name,'.jpg'))
	par(mar = rep(0, 4), xaxs='i', yaxs='i' )
	plot.new()
	rasterImage(img, 0, 0, 1, 1, interpolate=FALSE)

	} # next lead

    } # next score

    dev.off()
    
} # next month



# Dani Map script for the small figure:
#/home/Earth/vtorralb/R/scripts/Veronica_2014/TimeSeries/PlotAno_mod_obs.R

                      
###############################################################################################
#  Preformatting: calculate weekly climatologies and anomalies for each hindcast startdate    #
###############################################################################################

# Run it only once at the beginning:

file_path='/home/Earth/ngonzal2/R/ConfFiles/IC3.conf'              # Load() file path
#file_path <- '/home/Earth/ncortesi/Downloads/RESILIENCE/IC3.conf'
    
my.startdates=1:52  # choose a sequence of startdates to save their anomalies

for(startdate in my.startdates){ # the startdate week to load inside the sdates weekly sequence:
   print(paste0('Computing anomalies for startdate ', which(startdate==my.startdates),'/',length(my.startdates)))

   data.hindcast <- Load(var = var.name, exp = 'EnsEcmwfWeekHind', 
	      	 obs = NULL, sdates = paste0(yr1.hind:yr2.hind, substr(sdates.seq[startdate],5,6), substr(sdates.seq[startdate],7,8)),
		 nleadtime = n.leadtimes, leadtimemin = 1, leadtimemax = n.leadtimes, output = 'lonlat', configfile = file_path, method='bilinear' )

   # dim(data.hindcast$mod) # [1,4,20,4,320,640]

   # Mean of the 4 members of the Hindcasts and of the 20 years (for each point and leadtime);
   clim.hindcast<-apply(data.hindcast$mod,c(1,4,5,6),mean)[1,,,] # average for each leadtime and pixel
   clim.hindcast<-InsertDim(InsertDim(InsertDim(clim.hindcast,1,n.yrs.hind),1,n.members),1,1)  # repeat the same values <n.members> and <n.yrs.hind> times to calc. anomalies

   anom.hindcast <- data.hindcast$mod - clim.hindcast
 
   rm(data.hindcast,clim.hindcast)
   gc()

   # average the anomalies over the 4 hindcast members  [1,20,4,320,640]
   anom.hindcast.mean<-apply(anom.hindcast,c(1,3,4,5,6),mean)

   my.grid<-paste0('r',n.lon,'x',n.lat)
   data.rean <- Load(var = var.name, exp = 'ERAintEnsWeek',
                      obs = NULL, sdates=paste0(yr1.hind:yr2.hind,substr(sdates.seq[startdate],5,6),substr(sdates.seq[startdate],7,8)),
		      nleadtime = n.leadtimes, leadtimemin = 1, leadtimemax = n.leadtimes, output = 'lonlat', configfile = file_path, grid=my.grid, method='bilinear')

   # dim(data.rean$mod) # [1,1,20,4,320,640]

   # Mean of the 20 years (for each point and leadtime)
   clim.rean<-apply(data.rean$mod,c(1,2,4,5,6),mean)[1,1,,,] # average for each leadtime and pixel
   clim.rean<-InsertDim(InsertDim(InsertDim(clim.rean,1,n.yrs.hind),1,1),1,1) # repeat the same values <n.years> times to be able to calculate the anomalies #[1,1,20,4,320,640]

   anom.rean <- data.rean$mod - clim.rean 
  
   anom.rean<-InsertDim(anom.rean[1,1,,,,],1,1) # [1,20,4,320,640]
   
   #save(anom.hindcast.mean,anom.rean,file=paste0(workdir,'/Data/anom_for_ACC_startdate',startdate,'.RData'))

   save(anom.hindcast,file=paste0(workdir,'/Data/anom_hindcast_startdate',startdate,'.RData'))
   save(anom.hindcast.mean,file=paste0(workdir,'/Data/anom_hindcast_mean_startdate',startdate,'.RData'))
   save(anom.rean,file=paste0(workdir,'/Data/anom_rean_startdate',startdate,'.RData'))
   save(clim.rean,file=paste0(workdir,'/Data/clim_rean_startdate',startdate,'.RData'))

   rm(data.rean,anom.hindcast,anom.hindcast.mean,clim.rean,anom.rean)
   gc()

}

###############################################################################################
#  Preformatting: calculate weekly climatologies and anomalies for each forecast startdate    #
###############################################################################################
#
# finish!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#    
# the only difference is that anomalies are computed using climatologies from the hincast data, 
# and not from the forecast data.

# Run it only once at the beginning:

file_path='/home/Earth/ngonzal2/R/ConfFiles/IC3.conf'              # Load() file path
#file_path <- '/home/Earth/ncortesi/Downloads/RESILIENCE/IC3.conf'

my.startdates=1:52  # choose a sequence of forecast startdates to save their anomalies

for(startdate in my.startdates){ # the startdate week to load inside the sdates weekly sequence:
   print(paste0('Computing anomalies for startdate ', which(startdate==my.startdates),'/',length(my.startdates)))

   data.hindcast <- Load(var=var.name, exp = 'EnsEcmwfWeekHind', 
	      	 obs = NULL, sdates=paste0(yr1.hind:yr2.hind,substr(sdates.seq[startdate],5,6),substr(sdates.seq[startdate],7,8)),
		 nleadtime = n.leadtimes, leadtimemin = 1, leadtimemax = n.leadtimes, output = 'lonlat', configfile = file_path, method='distance-weighted' )

   # dim(data.hindcast$mod) # [1,4,20,4,320,640]

   # Mean of the 4 members of the Hindcasts and of the 20 years (for each point and leadtime);
   clim.hindcast<-apply(data.hindcast$mod,c(1,4,5,6),mean)[1,,,] # average for each leadtime and pixel
   clim.hindcast<-InsertDim(InsertDim(InsertDim(clim.hindcast,1,n.yrs.hind),1,n.members),1,1)  # repeat the same values <n.members> and <n.yrs.hind> times to calc. anomalies

   anom.hindcast <- data.hindcast$mod - clim.hindcast
 
   rm(data.hindcast,clim.hindcast)
   gc()

   # average the anomalies over the 4 hindcast members  [1,20,4,320,640]
   anom.hindcast.mean<-apply(anom.hindcast,c(1,3,4,5,6),mean)

   my.grid<-paste0('r',n.lon,'x',n.lat)
   data.rean <- Load(var=var.name, exp = 'ERAintEnsWeek',
                      obs = NULL, sdates=paste0(yr1.hind:yr2.hind,substr(sdates.seq[startdate],5,6),substr(sdates.seq[startdate],7,8)),
		      nleadtime = n.leadtimes, leadtimemin = 1, leadtimemax = n.leadtimes, output = 'lonlat', configfile = file_path, grid=my.grid, method='distance-weighted')
   # dim(data.rean$mod) # [1,1,20,4,320,640]

   # Mean of the 20 years (for each point and leadtime)
   clim.rean<-apply(data.rean$mod,c(1,2,4,5,6),mean)[1,1,,,] # average for each leadtime and pixel
   clim.rean<-InsertDim(InsertDim(InsertDim(clim.rean,1,n.yrs.hind),1,1),1,1) # repeat the same values <n.years> times to be able to calculate the anomalies #[1,1,20,4,320,640]

   anom.rean <- data.rean$mod - clim.rean 
  
   anom.rean<-InsertDim(anom.rean[1,1,,,,],1,1) # [1,20,4,320,640]
   
   #save(anom.hindcast.mean,anom.rean,file=paste0(workdir,'/Data/anom_for_ACC_startdate',startdate,'.RData'))

   save(anom.hindcast,file=paste0(workdir,'/Data/anom_hindcast_startdate',startdate,'.RData'))
   save(anom.hindcast.mean,file=paste0(workdir,'/Data/anom_hindcast_mean_startdate',startdate,'.RData'))
   save(anom.rean,file=paste0(workdir,'/Data/anom_rean_startdate',startdate,'.RData'))
   save(clim.rean,file=paste0(workdir,'/Data/clim_rean_startdate',startdate,'.RData'))

   rm(data.rean,anom.hindcast,anom.hindcast.mean,clim.rean,anom.rean)
   gc()

}






