library(CSTools)
library(startR)
library(s2dv)
library(lubridate)
library(multiApply)
library(FNN)
source('/esarchive/scratch/jramon/GitLab_jramon/downscaling/csdownscale/R/Interpolation.R')
source('/esarchive/scratch/jramon/GitLab_jramon/downscaling/csdownscale/R/Intbc.R')
source('/esarchive/scratch/jramon/GitLab_jramon/downscaling/csdownscale/R/Intlr.R')
source('/esarchive/scratch/jramon/GitLab_jramon/downscaling/csdownscale/R/Analogs.R')
source('/esarchive/scratch/jramon/GitLab_jramon/downscaling/csdownscale/R/Utils.R')
source("https://earth.bsc.es/gitlab/external/cstools/-/raw/master/R/CST_BiasCorrection.R")

plotpath <- '/esarchive/scratch/jramon/downscaling/plots/ip'
target_grid <- '/esarchive/recon/ecmwf/era5/monthly_mean/tas_f1h/tas_200002.nc'

lonmin <- -11.5
lonmax <- 5.35
latmin <- 35.1
latmax <- 44.1
extra <- 1

sdates_exp <- format(ymd("20000501") + rep(years(0:4), each=1),"%Y%m%d")
sdates_obs  <- format(ymd("20000501") + rep(years(0:4), each=1),"%Y%m")

obs <- startR::Start(dat = '/esarchive/recon/ecmwf/era5/daily_mean/$var$_f1h/$var$_$sdate$.nc',
                     var = 'tas', time = indices(1:28), 
                     lat = values(list(latmin - extra, latmax + extra)),
                     sdate = sdates_obs, lat_reorder = Sort(decreasing = FALSE),
                     lon = values(list(lonmin - extra, lonmax + extra)),
                     lon_reorder = CircularSort(-180, 180),
                     synonims = list(var = c('var','variable'), lon = c('lon', 'longitude'),
                     lat = c('lat', 'latitude')), return_vars = list(lat = 'dat', lon = 'dat'),
                     num_procs = 1, retrieve = TRUE)


exp <- startR::Start(dat = '/esarchive/exp/ecmwf/system5c3s/daily_mean/$var$_f6h/$var$_$sdate$.nc',
                     var = 'tas', time = indices(1:28), member = indices(1:3), sdate = sdates_exp,
                     lat = values(list(latmin, latmax)), lat_reorder = Sort(decreasing = FALSE),
                     lon = values(list(lonmin, lonmax)), lon_reorder = CircularSort(-180, 180),
                     synonims = list(var = c('var','variable'), lon = c('lon', 'longitude'),
                     lat = c('lat', 'latitude'), member = c('member','ensemble')),
                     return_vars = list(lat = 'dat', lon = 'dat'),
                     num_procs = 1, retrieve = TRUE)

#--------------------------------------
# Interpolation
#--------------------------------------
int_con <- Interpolation(exp = exp, lats = attr(exp, "Variables")$dat1$lat,
                         lons = attr(exp, "Variables")$dat1$lon, target_grid = target_grid, 
                         method_remap = 'con')
int_bil <- Interpolation(exp = exp, lats = attr(exp, "Variables")$dat1$lat,
                         lons = attr(exp, "Variables")$dat1$lon, target_grid = target_grid, 
                         method_remap = 'bil')
int_bic <- Interpolation(exp = exp, lats = attr(exp, "Variables")$dat1$lat,
                         lons = attr(exp, "Variables")$dat1$lon, target_grid = target_grid, 
                         method_remap = 'bic')
int_nn <- Interpolation(exp = exp, lats = attr(exp, "Variables")$dat1$lat,
                        lons = attr(exp, "Variables")$dat1$lon, target_grid = target_grid, 
                        method_remap = 'nn')
int_con2 <- Interpolation(exp = exp, lats = attr(exp, "Variables")$dat1$lat,
                          lons = attr(exp, "Variables")$dat1$lon, target_grid = target_grid, 
                          method_remap = 'con2')

#--------------------------------------
# Interpolation + bias correction
#--------------------------------------
intbc_bic_sbc <- Intbc(exp = exp, obs = obs, exp_lats = attr(exp, "Variables")$dat1$lat,
                   exp_lons = attr(exp, "Variables")$dat1$lon, 
                   obs_lats = attr(obs, "Variables")$dat1$lat,
                   obs_lons = attr(obs, "Variables")$dat1$lon, target_grid = target_grid, 
                   int_method = 'bic', bc_method = 'simple_bias', ncores = 4)

intbc_bic_cal <- Intbc(exp = exp, obs = obs, exp_lats = attr(exp, "Variables")$dat1$lat,
                   exp_lons = attr(exp, "Variables")$dat1$lon, 
                   obs_lats = attr(obs, "Variables")$dat1$lat,
                   obs_lons = attr(obs, "Variables")$dat1$lon, target_grid = target_grid, 
                   int_method = 'bic', bc_method = 'calibration', ncores = 4)

intbc_bic_qm <- Intbc(exp = exp, obs = obs, exp_lats = attr(exp, "Variables")$dat1$lat,
                  exp_lons = attr(exp, "Variables")$dat1$lon, 
                  obs_lats = attr(obs, "Variables")$dat1$lat,
                  obs_lons = attr(obs, "Variables")$dat1$lon, target_grid = target_grid, 
                  int_method = 'bic', bc_method = 'quantile_mapping', ncores = 4)

#--------------------------------------
# Interpolation + linear regression
#--------------------------------------
nao_cpc <- c(1.58, -0.02, -0.22, 0.01, 0.19)
nao <- array(NA, dim = c('sdate' = length(sdates_exp), member = 1, 'vars' = 1))
nao[,1,1] <- nao_cpc

intlr_bil_bas <- Intlr(exp = exp, obs = obs, exp_lats = attr(exp, "Variables")$dat1$lat,
                    exp_lons = attr(exp, "Variables")$dat1$lon, 
                    obs_lats = attr(obs, "Variables")$dat1$lat,
                    obs_lons = attr(obs, "Variables")$dat1$lon, target_grid = target_grid, 
                    lr_method = "basic", int_method = "bilinear", predictors = NULL, 
                    loocv = TRUE, ncores = 4)

intlr_bil_lsc <- Intlr(exp = exp, obs = obs, exp_lats = attr(exp, "Variables")$dat1$lat,
                    exp_lons = attr(exp, "Variables")$dat1$lon, 
                    obs_lats = attr(obs, "Variables")$dat1$lat,
                    obs_lons = attr(obs, "Variables")$dat1$lon, target_grid = target_grid, 
                    lr_method = "large-scale", int_method = "conservative", 
                    predictors = nao, loocv = TRUE, ncores = 4)

intlr_bil_nn <- Intlr(exp = exp, obs = obs, exp_lats = attr(exp, "Variables")$dat1$lat,
                   exp_lons = attr(exp, "Variables")$dat1$lon, 
                   obs_lats = attr(obs, "Variables")$dat1$lat,
                   obs_lons = attr(obs, "Variables")$dat1$lon, target_grid = target_grid, 
                   lr_method = "4nn", int_method = "conservative", loocv = TRUE, ncores = 4)

#--------------------------------------
# Analogs
#--------------------------------------
ana <- Analogs(exp = exp, obs = obs, exp_lats = attr(exp, "Variables")$dat1$lat,
               exp_lons = attr(exp, "Variables")$dat1$lon, 
               obs_lats = attr(obs, "Variables")$dat1$lat,
               obs_lons = attr(obs, "Variables")$dat1$lon, grid_exp = attr(exp, "Files")[1,1,1],
               fun_analog = NULL, loocv_window = TRUE, return_indices = FALSE, ncores = 4)













