Downscale <- function(exp, obs, sdates_train, sdates_test,
                      lon_indices = NULL, lat_indices = NULL, ...) {
  # Apanyo transitori ja disponible a la instalacio de downscaleR a BSC-ES:
  #
  # El fix a donwscale.train és el seguent:
  #   
  # if (isRegular(obj$y)) {
  #   if (length(dim(obj$y$Data)) > 2) {
  #     mat.y <- array3Dto2Dmat(obj$y$Data)
  #   } else {
  #     mat.y <- obj$y$Data
  #   }
  #   mat.p <- matrix(data = NA, nrow = nrow(mat.y), ncol = ncol(mat.y))
  #   regular <- TRUE
  # }
  # 
  # mentres que originalment el codi era
  # 
  # if (isRegular(obj$y)) {
  #   mat.y <- array3Dto2Dmat(obj$y$Data)
  #   mat.p <- matrix(data = NA, nrow = nrow(mat.y), ncol = ncol(mat.y))
  #   regular <- TRUE
  # }
   
  # Check exp
 
  # Check obs

  # Check sdates_train

  # Check sdates_test
 
  # Check lon_indices
 
  # Check lat_indices
 
  # Transform to downscaleR
  data_exp_dw <- S2dvToDownR(exp)$exp[[1]][[1]]
  if (all(c('mod', 'obs') %in% names(obs))) {
    data_obs_dw_stations <- S2dvToDownR(obs)$obs[[1]]
  } else {
    data_obs_dw_stations <- obs
    if (!all(as.POSIXct(data_exp_dw$Dates$start) %in% data_obs_dw_stations$Dates$start)) {
      stop("Provided experimental dates not found in the observational dates.")
    }
    #date_matches <- which(data_obs_dw_stations$Dates$start %in% as.POSIXct(data_exp_dw$Dates$start))
    date_matches <- sapply(data_exp_dw$Dates$start, 
      function(x) {
        which(data_obs_dw_stations$Dates$start == as.POSIXct(x))[1]
      }
    )
    data_obs_dw_stations$Dates$start <- data_exp_dw$Dates$start
    data_obs_dw_stations$Dates$end <- data_exp_dw$Dates$end
    data_obs_dw_stations$InitializationDates[[1]] <- data_exp_dw$InitializationDates[[1]]
    dimname_bk <- names(dim(data_obs_dw_stations$Data))
    data_obs_dw_stations$Data <- data_obs_dw_stations$Data[date_matches, 1, drop = FALSE]
    names(dim(data_obs_dw_stations$Data)) <- dimname_bk
    attr(data_obs_dw_stations$Data, 'dimensions') <- dimname_bk
  }
  if (!('station' %in% names(dim(obs$Data)))) {
    if (is.null(lon_indices) || is.null(lat_indices)) {
      stop("Provided gridded data in 'obs' but no ",
           "'lon_indices' or 'lat_indices' provided.")
    }
    original_data_dims <- dim(data_obs_dw_stations$Data)
    station_data_dims <- c('time' = original_data_dims[1],
                           'station' = length(lon_indices))
    station_data_array <- array(dim = station_data_dims)
    for (station in 1:length(lon_indices)) {
      lat <- lat_indices[station]
      lon <- lon_indices[station]
      station_data_array[, station] <- data_obs_dw_stations$Data[, lat, lon]
    }
    attr(station_data_array, 'dimensions') <- c('time', 'station')
    data_obs_dw_stations$Data <- station_data_array
    data_obs_dw_stations$xyCoords$x <- data_obs_dw_stations$xyCoords$x[lon_indices, drop = FALSE]
    data_obs_dw_stations$xyCoords$y <- data_obs_dw_stations$xyCoords$y[lat_indices, drop = FALSE]
  }

  nmember <- dim(exp$mod)['member']
  sdates <- format(exp$Datasets[[1]][[1]]$InitializationDates[[1]], 
                   format = "%Y%m%d")
  result <- NULL
  for (member in 1:nmember) {
    message("Downscaling member ", member, "...")
    subset_years <- as.numeric(substr(sdates, 1, 4))
    date_years_numeric <- as.numeric(format(exp$Dates$start, format = '%Y'))
    num_ftimes <- length(date_years_numeric) / length(sdates)
    if (!(num_ftimes %% 1 == 0)) {
      stop("Inconsistent number of sdates and ftimes provided in ",
           "the input data.")
    }
    if (date_years_numeric[1] < date_years_numeric[num_ftimes]) {
      subset_years <- subset_years + 1
    }

    x <- subsetYears(data_obs_dw_stations, subset_years[sdates_train])
    # Apanyo transitori
    x$InitializationDates <- lapply(x$InitializationDates, '[', sdates_train)


    y <- subsetYears(
           subsetMembers(data_exp_dw, member),
           subset_years[sdates_train]
         )

    z <- subsetYears(
           subsetMembers(data_exp_dw, member),
           subset_years[sdates_test]
         )

    # DOWNSCALING
    # La función downscale espera tres objetos (tal y como yo interpreté el)
    #   
    # data.obs <- Dimensión TxN (número de estaciones, N, para un periodo train, T).
    # data. pred <- campo training, de dimensión TxLatxLon
    # data.exp <- campo test, de dimensión SxLatxLon
    # 
    # El tutorial en que me he basado está en esta dirección: 
    # https://github.com/SantanderMetGroup/downscaleR/wiki/perfect-prognosis
    #
    # En otras palabras, un ejemplo de dimensiones esperadas:
    #   x:   
    #        time  station
    #           5        6
    #   y: 
    #      member     time   lat   lon
    #           1        5    16    21
    #   new.data:
    #      member     time   lat   lon
    #           1        2    16    21
    #   output:
    #        time  station
    #           2        5

    ds <- downscale(x, y, z, ...)

    # Apanyo transitori
    ds$Data <- Subset(ds$Data, 3, 1, drop = 'selected')
    # Apanyo transitori
    ds$InitializationDates[[1]] <- z$InitializationDates[[1]]
    member_result <- DownRToS2dv(ds)
    if (member == 1) {
      result <- member_result
    } else {
      result$mod <- abind(member_result$mod, result$mod, along = 2)
      names(dim(result$mod)) <- names(dim(member_result$mod))
      mn <- member_name <- paste0("Member_", member)
      result$InitializationDates[[mn]] <- member_result$InitializationDates[[1]]
      result$Members <- c(result$Members, mn)
    }
  }

  result
}
