## This function is to apply an orographic temperature correction between the
## exp and obs datasets. This correction is relevant for the mean_bias metric.

source("modules/Loading/R/get_regrid_params.R")
source("modules/Loading/R/check_latlon.R")

orography_correction <- function(recipe, data) {
  
  ref.name <- recipe$Analysis$Datasets$Reference$name
  exp.name <- recipe$Analysis$Datasets$System$name
  lats.min <- recipe$Analysis$Region$latmin
  lats.max <- recipe$Analysis$Region$latmax
  lons.min <- recipe$Analysis$Region$lonmin
  lons.max <- recipe$Analysis$Region$lonmax
  
  archive <- get_archive(recipe)

  # Define regrid parameters:
  regrid_params <- get_regrid_params(recipe, archive)
  
  circularsort <- check_latlon(lats.min, lats.max, lons.min, lons.max)
  
  ## Load exp orography
  orography_exp <- Start(dat = archive$System[[exp.name]]$orography, 
                         var = 'orography',  
                         longitude = values(list(lons.min, lons.max)),
                         longitude_reorder = circularsort,
                         latitude = values(list(lats.min, lats.max)),
                         latitude_reorder = Sort(),
                         transform = regrid_params$fcst.transform,
                         transform_params = list(grid = regrid_params$fcst.gridtype,
                                                 method = regrid_params$fcst.gridmethod),
                         transform_vars = c('latitude', 'longitude'),
                         return_vars = list(latitude = NULL, longitude = NULL), 
                         synonims = list(longitude = c('lon', 'longitude'),
                                         latitude = c('lat', 'latitude')),
                         num_procs = 1, retrieve = TRUE)
  
  ## load obs orography
  orography_obs <- Start(dat = archive$Reference[[ref.name]]$orography, 
                         var = 'orography',  
                         longitude = values(list(lons.min, lons.max)),
                         longitude_reorder = circularsort,
                         latitude = values(list(lats.min, lats.max)),
                         latitude_reorder = Sort(),
                         transform = regrid_params$obs.transform,
                         transform_params = list(grid = regrid_params$obs.gridtype,
                                                 method = regrid_params$obs.gridmethod),
                         transform_vars = c('latitude', 'longitude'),
                         return_vars = list(latitude = NULL, longitude = NULL), 
                         synonims = list(longitude = c('lon', 'longitude'),
                                         latitude = c('lat', 'latitude')),
                         num_procs = 1, retrieve = TRUE)
  
  ## Set negative values to zero
  orography_exp <- pmax(orography_exp, 0)
  orography_obs <- pmax(orography_obs, 0)
  
  ## Calculate difference between orographies
  oro_diff <- orography_exp - orography_obs
  
  ## Apply lapse rate factor to correct temperature = -0.0065 K/m (-6.5 K/km)
  oro_obs_corr <- oro_diff * -0.0065
  oro_obs_corr <- Reorder(data = drop(oro_obs_corr), order = c('latitude', 'longitude'))
  
  ## Apply correction to obs temperature data
  data$obs$data <- Apply(data = list(data$obs$data, oro_obs_corr),
                         target_dims = c("latitude", "longitude"),
                         fun = "+",
                         ncores = recipe$Analysis$ncores)$output1
  data$obs$data <- Reorder(data$obs$data, names(data$obs$dims))
  
  return(data)
}

