  library(s2dverification)
  library(multiApply)
  library(SpecsVerification)

  #Write the code for a use case where you load 'psl' data for 10 start dates, 
  #for 4 forecast times, for the Mediterranean region, for 
  #1) an in-house EC-Earth experiment of your choice, and for
  #2) the ECMWF system5 model, as well as for
  #3) the ERA-5 reconstruction

#------------test for file_per_member data read-in------------
   ecearth <- list(name = 'a1lr',
                   path = file.path('/esarchive/exp/ecearth',
                                    '$EXP_NAME$/$STORE_FREQ$_mean',  #month_mean',
                                    '$VAR_NAME$_f6h/$VAR_NAME$_Amon_EC-EARTH_$EXP_NAME$_S$START_DATE$_r$MEMBER_NUMBER$i1p1_200001-200105.nc'))
   startDates <- '20000101'
   time_length <- 7
   lon <- c(-6, 36)
   lat <- c(30, 46)
 
   data <- Load(var = 'tas',
                exp = list(ecearth),
                sdates = startDates,
                storefreq = "monthly",
                leadtimemax = time_length,
                output = 'lonlat',
                nmember = 30,
                #dimnames = list(lon = 'j', lat = 'i'),
                lonmin = lon[1], lonmax = lon[2],
                latmin = lat[1], latmax = lat[2])
 
   mod <- data$mod
   obs <- data$obs
#--------------------end--------------------

#------------------use configuration file to read---------------------
  lon <- c(-6, 36)
  lat <- c(30, 46)

  data <- Load(var = 'tas', exp = 'ecearth/i00k', sdates = '19991101', 
               lonmin = lon[1], lonmax = lon[2],
               latmin = lat[1], latmax = lat[2],
               output = 'lonlat')
#configuration file path: /shared/earth/software/R/3.2.0-foss-2015a-bare/lib64/R/library/s2dverification/config
#--------------------------end-----------------------------

#--------------------try reading irregular/(i, j) data--------------
  ecearth <- list(name = 'a1pc',
                  path = file.path('/esarchive/exp/ecearth',
                                   '$EXP_NAME$/cmorfiles/CMIP/EC-Earth-Consortium',
                                   'EC-Earth3-LR/historical/r1i1p1f1/Amon',
                                   '$VAR_NAME$/gr/v20190205',
                                   '$VAR_NAME$_Amon_EC-Earth3-LR_historical_r1i1p1f1_gr_$YEAR$$MONTH$-$YEAR$$MONTH$.nc'))

  lon <- c(-6, 36)
  lat <- c(30, 46)

  data <- Load(var = 'psl', exp = list(ecearth), sdates = '19900101',
               lonmin = lon[1], lonmax = lon[2],
               latmin = lat[1], latmax = lat[2],
#               grid = 'r96x72',
               dimnames = list(lon = 'i', lat = 'j'),
               output = 'lonlat')

#------------end-------------not working-----------------------


#---------------------issue #227----------------------
#revised function
Ano <- function(var, clim) {
  #
  #  Duplicate clim dimensions to heve same dimensions as var
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #
  dimvar <- dim(var)
  
  if (length(dim(clim)) <= 2) {
    clim <- InsertDim(clim, 2, dimvar[2])
  }

  if ((length(dimvar) > length(dim(clim))) & (dim(clim)[2] != dimvar[2])) {
    clim <- InsertDim(clim, 2, dimvar[2])
  }
  if ((length(dimvar) > length(dim(clim))) & (dim(clim)[2] == dimvar[2])) {
    if (is.null(names(dim(clim))) | is.null(names(dimvar))) {
      stop('The dimensions have the same length. To clarify if they are the same variable, add dimension names to the arrays.')
    } else {
      if (names(dim(clim)[2]) != names(dimvar[2])) {
        clim <- InsertDim(clim, 2, dimvar[2])
      }
    }
  }

  if ((length(dimvar) > length(dim(clim))) & (dim(clim)[3] != dimvar[3])) {
    clim <- InsertDim(clim, 3, dimvar[3])
  }
  if ((length(dimvar) > length(dim(clim))) & (dim(clim)[3] == dimvar[3])) {
    if (is.null(names(dim(clim))) | is.null(names(dimvar))) {
      stop('The dimensions have the same length. To clarify if they are the same variable, add dimension names to the arrays.')
    } else {
      if (names(dim(clim)[3]) != names(dimvar[3])) {
        clim <- InsertDim(clim, 3, dimvar[3])
      }
    }
  }

  if ((length(dimvar) > length(dim(clim))) & (dim(clim)[4] != dimvar[4])) {
    clim <- InsertDim(clim, 4, dimvar[4])
  }
  if ((length(dimvar) > length(dim(clim))) & (dim(clim)[4] == dimvar[4])) {
    if (is.null(names(dim(clim))) | is.null(names(dimvar))) {
      stop('The dimensions have the same length. To clarify if they are the same variable, add dimension names to the arrays.')
    } else {
      if (names(dim(clim)[4]) != names(dimvar[4])) {
        clim <- InsertDim(clim, 4, dimvar[4])
      }
    }
  }
  
  #
  #  Raw anomalies
  # ~~~~~~~~~~~~~~~
  #
  ano <- var - clim
  
  #
  #  Outputs
  # ~~~~~~~~~
  #
  ano
}


t <- array(rnorm(144), c(1,3,4,3,2,2)) # define array as clim expects: nexp,nmemb,nsdates,nltime,nlon,nlat
names(dim(t)) = c("exp", "memb", "sdate", "ftime", "lat", "lon")

c3 <- Clim(t, t, memb = TRUE)$clim_exp # Clim for each member                                     
dim(c3)
dim(Clim(t, t, memb = FALSE)$clim_exp) # dimensions if memb=FALSE                              
c1 <- InsertDim(c3[,1,,,],1,1) # clim as if memb=FALSE but identical to member 1              
names(dim(c1)) <- c('exp', 'ftime', 'lat', 'lon')
dim(c1)

identical(c1[,,,],c3[,1,,,]) # results in TRUE


a3 <- Ano(t, c3)  # ano for each member individually                                           
a1 <- Ano(t, c1)  # ano for first member                                                       
identical(a1[,1,,,,], a3[,1,,,,])  ## RESULTS IN FALSE

#--
T <- array(rnorm(240),c(1,3,4,5,2,2)) # define array as clim expects: nexp,nmemb,nsdates,nltime,nlon,nlat   
names(dim(T)) = c("exp","memb","sdate","ftime","lat","lon")

C3 <- Clim(T,T,memb=TRUE)$clim_exp # Clim for each member                                     
dim(C3)
dim(Clim(T,T,memb=FALSE)$clim_exp) # dimensions if memb=FALSE                              
C1 <- InsertDim(C3[,1,,,],1,1) # clim as if memb=FALSE but identical to member 1              
#names(dim(C1)) <- c('exp', 'ftime', 'lat', 'lon')
dim(C1)
identical(C1[,,,],C3[,1,,,]) # results in TRUE


A3 <- Ano(T,C3)  # ano for each member individually                                           
A1 <- Ano(T,C1)  # ano for first member                                                       
identical(A1[,1,,,,],A3[,1,,,,]) ## RESULTS IN TRUE




#-----------------------------------------------------


  #Set the data path
  ecearth <- list(name = 'm04o',
                  path = file.path('/esarchive/exp/ecearth',
                                   '/$EXP_NAME$/monthly_mean',
                                   '/$VAR_NAME$_f6h/$VAR_NAME$_$START_DATE$.nc'))
  #/esarchive/exp/ecearth/m04o/monthly_mean/psl_f6h
  #psl_19930501.nc

  ecmwf <- list(name = 'system5c3s',
                path = file.path('/esarchive/exp/ecmwf',
                                 '/$EXP_NAME$/monthly_mean',
                                 '/$VAR_NAME$_f6h/$VAR_NAME$_$START_DATE$.nc'))
  #/esarchive/exp/ecmwf/system5c3s/monthly_mean/psl_f6h
  #psl_20190301.nc

  era5 <- list(name = 'era5',
               path = file.path('/esarchive/recon/ecmwf',
                                '$OBS_NAME$/monthly_mean',
                                '$VAR_NAME$_f1h/$VAR_NAME$_$YEAR$$MONTH$.nc'))
  #/esarchive/recon/ecmwf/era5/monthly_mean/psl_f1h
  #psl_201808.nc

  startDates <- c(paste0(1993:2002,'1101'))
  time_length <- 4
  lon <- c(-6, 36)
  lat <- c(30, 46)

  data <- Load(var = 'psl',
               exp = list(ecearth, ecmwf),
               obs = list(era5),
               sdates = startDates,
               storefreq = "monthly",
               leadtimemax = time_length,
               output = 'lonlat',
#               nmember = c(2,4),
               lonmin = lon[1], lonmax = lon[2],
               latmin = lat[1], latmax = lat[2])
  
  mod <- data$mod
  obs <- data$obs
  dim(mod)  #member follows ecearth = 10
  dim(obs)

  #Correct the bias of the data (using Clim and Ano).
  #Compute the CRPSS for each forecast time, latitude and longitude. 
  #You will need to use ProbBins, multiApply, and think a lot.
  clim <- Clim(mod, obs)
  ano_mod <- Ano(mod, clim$clim_exp)
  ano_obs <- Ano(obs, clim$clim_obs)
#  mod_corr <- mod - (clim$clim_exp - clim$clim_obs)

  mod_corr <- array(0, dim = dim(ano_mod))
  for (i in 1 : 2) {
    for (j in 1 : 10) {
      for (k in 1 : 10) {
        mod_corr[i, j, k, , , ] <- clim$clim_obs[1, 1, , , ] + ano_mod[i, j, k, , , ]
      }
    }
  }

  #mod_corr_reorder <- multiApply:::.aperm2(mod_corr, c(1, 3, 2, 4, 5, 6))
  #mod_corr_reorder <- multiApply:::.aperm2(ano_mod, c(1, 3, 2, 4, 5, 6))
  #obs_sub <- s2dverification::Subset(obs, c('dataset'), 1, drop = TRUE)
  obs_sub <- s2dverification::Subset(obs, c('dataset'), 1, drop = TRUE)

  #CRPS <- multiApply::Apply(data = list(mod_corr_reorder, obs_sub),
  CRPS <- multiApply::Apply(data = list(mod_corr, obs_sub),
                            target_dims = list(c('sdate', 'member'),
                                               c('sdate')),
                            #margins = list(c('dataset', 'ftime', 'lat', 'lon'), 
                            #               c('ftime', 'lat', 'lon')),
                            fun = SpecsVerification::EnsCrps)$output1
  names(dim(CRPS))[1] <- c('sdate')

  #mod_corr_sub <- s2dverification::Subset(mod_corr_reorder, c('member'), c(1:2))
  mod_corr_sub <- s2dverification::Subset(mod_corr, c('member'), c(1:2))
  CRPS_ref <- multiApply::Apply(data = list(mod_corr_sub, obs_sub),
                                target_dims = list(c('sdate', 'member'),
                                                   c('sdate')),
                                #margins = list(c('dataset', 'ftime', 'lat', 'lon'), 
                                #               c('ftime', 'lat', 'lon')),
                                fun = SpecsVerification::EnsCrps)$output1
  names(dim(CRPS_ref))[1] <- c('sdate')

  CRPSS <- multiApply::Apply(data = list(CRPS, CRPS_ref),
                             margins = list(c('dataset', 'ftime', 'lat', 'lon'), 
                                            c('dataset', 'ftime', 'lat', 'lon')),
                             fun = SpecsVerification::SkillScore)$output1



  #Plot the CRPSS map of the first forecast time with PlotEquiMap.   
  #Plot all CRPSS maps (for all forecast times) in a single figure with PlotLayout and PlotEquiMap.
  #You can check the s2dverification paper for help, the s2dverification user manual on gitlab,
  # and ask Suso or Núria.

  brks <- seq(min(CRPSS, na.rm = TRUE),# - 0.0001, 
              max(CRPSS, na.rm = TRUE),# - 0.0001, 
              length.out = 31)

  AnimateMap(CRPSS[1, 1, , , ], data$lon, data$lat)

  PlotEquiMap(CRPSS[1, 1, 1, , ], data$lon, data$lat, 
              toptitle = 'CRPSS of 1st ftime (ecearth)', title_scale = 0.7,
              axes_label_scale = 0.7,
              intylat = 5, intxlon = 5,
              filled.continents = FALSE,
              brks = brks,
#              dots = CRPSS[1, 1, 1, , ] > 0
              coast_color = 'grey'
             )
  PlotEquiMap(CRPSS[1, 2, 1, , ], data$lon, data$lat,
              toptitle = 'CRPSS of 1st ftime (ECMWF)', title_scale = 0.7,
              axes_label_scale = 0.7,
              intylat = 5, intxlon = 5,
              brks = brks,
              filled.continents = FALSE
#              dots = CRPSS[1, 2, 1, , ] > 0
             )

  PlotLayout(PlotEquiMap, c('lat', 'lon'), CRPSS[1, 1, , , ], data$lon, data$lat,
             toptitle = 'CRPSS (ecearth)', title_scale = 0.7,
             titles = paste('ftime', 1:4),
             axes_label_scale = 0.7,
             intylat = 5, intxlon = 5,
             filled.continents = FALSE,
             brks = brks
             )
  PlotLayout(PlotEquiMap, c('lat', 'lon'), CRPSS[1, 2, , , ], data$lon, data$lat,
             toptitle = 'CRPSS (ECMWF)', title_scale = 0.7,
             titles = paste('ftime', 1:4),
             axes_label_scale = 0.7,
             intylat = 5, intxlon = 5,
             filled.continents = FALSE,
             brks = brks
             )
  AnimateMap(CRPSS[1, 2, , , ],
               lon = data$lon, lat = data$lat,
               #brks = 100, 
               #units = attr(data$Variable, 'units'),
               intlat = 5, intlon = 5,
               fill = FALSE,
               fileout = 'ani.gif')


  #Plot a map of the most likely quintiles for each experiment using the function
  #CSTools::PlotMostLikelyQuantileMap.

  sub1 <- s2dverification::Subset(CRPSS, c(1, 2, 3), list(1, 1, 1), drop = TRUE)
  sub2 <- s2dverification::Subset(CRPSS, c(1, 2, 3), list(1, 2, 1), drop = TRUE)

  library(CSTools)
  PlotMostLikelyQuantileMap(list(sub1, sub2), 
                            data$lon, data$lat,
                            toptitle = 'Most Likely Quantile Map (ECEARTH)', title_scale = 0.7,
              axes_label_scale = 0.7,
              intylat = 5, intxlon = 5,
              brks = 10,
              width = 8, height = 8
             )



#ano must be of dimension (nexp/nobs, nmemb, nsdates, nleadtime, nlat, nlon)
  PB <- ProbBins(ano_mod, fcyr = c(10), thr = c(1/3, 2/3), posdates = 3,
                 posdim = 2, compPeriod = "Without fcyr")

  tmp <- Apply(PB, target_dims = list(c('sdate','member')), fun = mean)$output1
  prob <- s2dverification::Subset(tmp, c(2, 3), list(1, 1), drop = TRUE)

  PlotMostLikelyQuantileMap(prob,
                            data$lon, data$lat,
                            toptitle = 'Tercile Forecast Map (ECEARTH, 2002)', title_scale = 0.7,
                            bar_titles = paste('% of belonging to', c('below', 'normal', 'above')),
#                            bar_label_scale = 0.2, bar_tick_scale = 0.7,
              axes_label_scale = 0.7,
              intylat = 5, intxlon = 5,
              brks = 20,
              width = 8, height = 8
             )



