nf <- 8   # Choose a downscaling by factor 8
nens <- 3 # Number of ensemble members

exp <- 1 : (2 * 3 * 4 * 8 * 8)
dim(exp) <- c(dataset = 1, member = 2, sdate = 3, ftime = 4, lat = 8, lon = 8)
lon <- seq(10, 13.5, 0.5)
dim(lon) <- c(lon = length(lon))
lat <- seq(40, 43.5, 0.5)
dim(lat) <- c(lat = length(lat))
datas2d <- list(exp = exp, lon = lon, lat = lat)
str(datas2d)


#' # create a test array with dimension 8x8 and 20 timesteps
#' # or provide your own read from a netcdf file
#'
 pr <- rnorm(8*8*20)
 dim(pr) <- c(8,8,20)
 lon_mat <- seq(10,13.5,0.5) # could also be a 2d matrix
 lat_mat <- seq(40,43.5,0.5)
#'
#' # Create a test array of weights
 ww <- array(1., dim = c(8 * nf, 8 * nf))
#' 
#' # ... or create proper weights using an external fine-scale climatology file
#' #     Specify a weightsfn filename if you wish to save the weights
#' 
 ww <- rfweights("./worldclim.nc", nf, lon=lon_mat, lat=lat_mat, weightsfn="", fsmooth = TRUE)
#' 
#' # downscale using weights (ww=1. means do not use weights)
 r <- rainfarm(pr, lon_mat, lat_mat, nf, fsmooth = TRUE, fglob = FALSE, weights = ww, nens = 2, verbose = TRUE)
 lon_f <- r$lon
 lat_f <- r$lat
 rd1 <- r$data[[1]]
 rd2 <- r$data[[2]]
#' @export

res <- Apply(data = datas2d, target_dims = list(c('lat', 'lon'), 'lon', 'lat'), fun = rainfarm, nf = 8)
str(res)

rainfarm <- function(pr, lon, lat, nf, fglob = FALSE,
                     fsmooth = TRUE, weights = 1.,
                     verbose = FALSE, slope = 0, kmin=1) {
  #  library(JuliaCall)
  julia_setup(useRCall = FALSE)
  julia_library("RainFARM")
  
  r <- julia_call("lon_lat_fine", lon, lat, as.integer(nf),
                  need_return = "R")
  lon_f <- r[[1]]
  lat_f <- r[[2]]
  
  if (slope == 0) {
    r <- julia_call("fft3d", pr, need_return = "R")
    fxp <- r[[1]]
    sx <- julia_call("fitslopex", fxp, kmin = as.integer(kmin),
                     need_return = "R")
  } else {
    sx <- slope
  }
  
  #rd <- list()
 # for (j in 1:nens) {
    rd <- julia_call("rainfarm", pr, sx, as.integer(nf), weights,
                                fglob = fglob, fsmooth = fsmooth,
                                verbose = verbose, need_return = "R")
  #}
  return(list(lon = lon_f, lat = lat_f, data = rd))   
}
