Load <- function(var, exp = NULL, obs = NULL, sdates, lonmin = 0, lonmax = 360, 
                 latmin = -90, latmax = 90, nleadtime = NULL, nmember = NULL, 
                 leadtimemin = 1, leadtimemax = NULL, storefreq = 'monthly', 
                 sampleperiod = 1, output = 'areave', method = 'conservative', 
                 grid = NULL, maskmod = list(NULL, NULL, NULL, NULL, NULL, 
                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), 
                 maskobs = list(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                 NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
  # This function loads experimental data together with the observational 
  # data at the corresponding dates from the specified experimental and 
  # observational datasets. It organizes those data into two matrices with 
  # dimensions:
  #  c(nexp/nmod, nmembers, nsdates, nleadtimes) for the experiments
  #  c(nobs/nreanalyses, nmembers, nsdates, nleadtimes) for the observations
  # up to
  #  c(nexp/nmod, nmembers, nsdates, nleadtimes, ndepth, nlat, nlon) 
  #  c(nobs/nreanalyses, nmembers, nsdates, nleadtimes, ndepth, nlat, nlon )
  # Only a specified variable and set of starting dates is loaded.
  # Once the two matrices are filled by calling this function, other functions
  # of the 2dverification package that requires this data structure can be 
  # executed (e.g: \code{Clim()} to compute climatologies,  \code{Ano()} to 
  # compute anomalies, ...).
  #
  # Load() is currently repository-specific, that meaning you should overwrite
  # it so as to make it work properly with the directory tree and naming
  # conventions in your data repository.
  #
  # The function Load() must return 4 a list which contains four components: 
  # $mod, $obs, $lat and $lon.
  # $mod is the matrix containing the experimental data.
  # $obs is the matrix containing the observational data.
  # $lat and $lon are the latitudes and longitudes of the model grid (0 if the
  # loaded variable is a global mean).
  #
  # The experimental data matrix will contain the values of a given variable for 
  # all the experiments the user wish to compare for a set of starting dates, 
  # lead-times, longitudes and latitudes interpolated to the common grid and
  # with the masks applied.
  # The observational data matrix will contain the observed values of the same
  # variable gathered from the specified observational datasets scanning the 
  # data repository. The observational data is chosen so as to date-correspond
  # the experimental data.
  #
  # The data matrices must be built with the dimensions in the following order 
  # and with the following lengths:
  # 1- The number of experimental datasets determined by the user (we need to 
  # store data of all the experiments in the same array) for the experimental 
  # matrix or the number of observational datasets available for validation in 
  # the observational matrix.
  # 2- The greatest number of members across all experiments.
  # 3- The number of starting dates determined by the user (we need to store 
  # data of each prediction of the model in each starting date).
  # 4- The greatest number of lead-times.
  # 5- The number of latitudes of the zone we want to consider.
  # 6- The number of longitudes of the zone we want to consider.
  #
  # Dimensions 5 and 6 are optional and their presence will depend on whether 
  # the variable loaded is 2-dimensional or an area average. 
  # In the case of an area average the dimensions of the matrix will be only the 
  # first 4.
  #
  # For example, at IC3, we have implemented Load() to select the experimental 
  # and observational datasets from which to load data, the variable to load, 
  # the range of starting dates, the range of lead-times, the frequency and step 
  # in which the data is loaded from the datasets, a common grid, a method of 
  # interpolation, a mask to disable certain experimental values, a mask to 
  # disable certain observational values and an output format:
  #   1) Time series of area-averaged variables over the specified domain. 
  #   2) Time series of meridional averages as a function of longitudes. 
  #   3) Time series of zonal averages as a function of latitudes.
  #   4) Time series of 2d fields.
  #
  # Furthermore, if the user loads a 2-dimensional variable, he/she can ask 
  # Load() to load it as area averages, as longitudinal averages in function of 
  # latitudes or as in latitudinal averages in function of longitudes. In these 
  # cases the 5th and/or 6th dimension will also disappear.
  #
  # The observational data matrix is built very similarly to the experimental 
  # matrix. The only differences are that the first dimension turns to be the
  # number of observational datasets and the length of the 2nd dimension turns  
  # to be the number of members of the observational datasets. Later, for each 
  # lead-time we will store observational data into it if possible.
  #
  # Any value that can't be filled (either in the experimental matrix or the 
  # observational matrix) should figure as an NA value.
  # 
  # Args:
  #   var: One of the following: 'tas', 'prlr', 'tos', 'g500', 'g200', 'ta50',
  #        'psl', 'hflsd', 'hfssd', 'rls', 'rss', 'rsds', 'uas', 'vas', 
  #        'tasmax_q90','tasmin_q90','prlr_q90','prlr_q10',
  #        'prlr_nbdaysq90_1979-2012','prlr_nbdaysq10_1979-2012',
  #        'prlr_nbdaysq90_1979-2005','prlr_nbdaysq10_1979-2005',
  #        'prlr_nbdaysq90_1981-2010','prlr_nbdaysq10_1981-2010',
  #        'tasmax_nbdaysq90_1979-2012','tasmin_nbdaysq10_1979-2012',
  #        'tasmax_nbdaysq90_1979-2005','tasmin_nbdaysq10_1979-2005',
  #        'sieN', 'sivN', 'siaS', 'sieS', 'sivS', 'sia_Arctic_Marginal_Seas',
  #        'sie_Arctic_Marginal_Seas', 'siv_Arctic_Marginal_Seas', [ and similarly
  #        'sia_' or 'sie_' or 'siv_' followed by 'Amundsen_Sea' or 
  #        'Antarctic_Atlantic_Sector' or 'Antarctic_Indian_Sector' or 
  #        'Antarctic_Ocean' or 'ArctOcn' or 'Arctic_Ocean' or 
  #        'Arctic_Ocean_North_Atlantic' or 'Atlantic_Ocean' or 'Baffin' or 
  #        'Baffin_Bay' or 'Baltic_Sea' or 'BarKara' or 'Barents_Sea' or
  #        'Beaufort_Chukchi_Sea' or 'Beaufort_Sea' or 'Bellingshausen_Sea' or 
  #        'Bering' or 'Bering_Strait' or 'CanArch' or 'Canadian_Waters' or 
  #        'Caspian_Sea' or 'Central_Arctic' or 'Chukchi_Sea' or 'East_Siberian_Sea'
  #         or 'Eastern_Central_Arctic' or 'Fram_Strait' or 'Global_Ocean' or 
  #        'Greenland_Sea' or 'Grnland' or 'Hudson' or 'Icelandic_Sea' or 
  #        'Indian_Ocean' or 'Indo_Pacific_Ocean' or 'Kara_Gate_Strait' or 
  #        'Kara_Sea' or 'LAT80N' or 'Labrador_Sea' or 
  #        'Laptev_East_Siberian_Chukchi_Seas' or 'Laptev_East_Siberian_Seas' or
  #        'Laptev_Sea' or 'Lincoln_Sea' or 'Mediterranean_Sea' or 'Nares_Strait'
  #        'Nordic_Barents_Seas' or 'Nordic_Seas' or 'NorthWest_Passage' or
  #        'North_Atlantic_Arctic' or 'North_Atlantic_Ocean' or 
  #        'North_Hemisphere_Ocean' or 'Northern_Hemisphere' or 'Norwegian_Sea' or
  #        'Okhotsk' or 'OpenOcean' or 'Pacific_Ocean' or 'Ross_Sea' or 
  #        'Serreze_Arctic' or 'Southern_Hemisphere' or 'StLawr' or 'Subpolar_Gyre'
  #        'TotalArc' or 'Vilkitsky_Strait' or 'Weddell_Sea' or
  #        'Western_Central_Arctic' ], 'moc_40N55N_1-2km',
  #        'moc_30N40N_1-2km', 'max_moc_38N50N_500m-2km', 'max_moc_40N',
  #        'heatc', '0-315_heatc', '373-657_heatc', '800-5350_heatc',
  #        'mxl_heatc', 'NAtl_10N65N_heatc', 'NAtl_10N65N_0-315_heatc',
  #        'NAtl_10N65N_373-657_heatc', 'NAtl_10N65N_800-5350_heatc',
  #        'mxl_NAtl_10N65N_heatc', [ and similarly ('mxl_' followed by 
  #         or '_0-315' or '_373-657' or '_800-5350' preceded by, optional)
  #        'TAtl_30S30N' or 'NPac_10N70N' or 'TPac_30S30N' or 'Arc_65N90N' or 
  #         'Ant_90S60S' or 'TInd_30S30N' followed by 'heatc'.
  #   exp: IMPORTANT: Place first the experiment with the largest number of 
  #        members and, if possible, with the largest number of leadtimes. If
  #        not possible, it is mandatory to specify the argument nleadtime
  #        and/or nmember.
  #        c('EnsEcmwfDec', 'EnsUkmoDec', 'EnsCerfacsDec', 'EnsIfmDec',
  #          'EnsEcmwfSeas', 'EnsCmccSeas', 'EnsIfmSeas', 'EnsMetfrSeas',
  #          'EnsUkmoSeas', 'DePreSysAsimDec', 'DePreSysNoAsimDec',
  #          'DePreSysAsimSeas', 'ECMWF_S3Seas', 'ECMWF_S4_sea',
  #          'ECMWF_S4_ann', 'hadcm3dec', 'miroc4dec', 'miroc5dec',
  #          'mri-cgcm3dec', 'cancm4dec1', 'cancm4dec2', 'cnrm-cm5dec',
  #          'knmidec', 'smhidec', 'mpimdec', 'gfdldec', 'cmcc-cmdec',
  #          'ipsldec', 'bccdec', 'gfdlhis', 'ipslhis', 'cmcc-cmhis', 'bcchis',
  #          'i00k', 'b013', 'b014', ...)
  #   obs: c('ERA40', 'NCEP', 'ERAint', '20thCv2', 'GHCN', 'GHCNERSSTGISS', 'ERSST',
  #          'HadISST', 'GPCP', 'GPCC', 'CRU', 'HadSLP', 'NSIDC', 'PIOMAS',
  #          'UCL', 'DS94', 'OAFlux', 'DFS4.3', 'NCDCglo', 'NCDCland', 
  #          'NCDCoc', 'GISSglo', 'GISSland', 'GISSoc', 'HadCRUT3glo', 
  #          'HadCRUT4', 'HadSST2oc', 'CRUTEM3land')
  #   sdates: c('YYYYMMDD','YYYYMMDD')
  #   lonmin: >= 0, default: 0
  #   lonmax: <= 360, default: 360
  #   latmin: >= -90, default: -90
  #   latmax: <= 90, default: 90
  #   nleadtime: Optional argument needed only if the first experiment in the
  #              parameter exp does not have the largest number of leadtimes.
  #              Default: number of leadtimes of the first experiment.
  #   nmember: Some experiments have more members in starting dates other than
  #            the first. If it is the case in the first experiment specified,
  #            fill nmember with the largest number of members.
  #   leadtimemin: Load into the matrices only the leadtimes from leadtimemin. 
  #                Default: 1.
  #   leadtimemax: Load into the matrices only the leadtimes before leadtimemax.
  #                Default: nleadtime.
  #   storefreq: Frequency at which the data to be loaded are stored in the 
  #              repository. Can take values 'monthly' or 'daily'. 
  #              Default: 'monthly'.
  #   sampleperiod: To load only a subset between leadtimemin and leadtimemax 
  #                 with a specified period of subsampling. 
  #                 Default: 1 (all leadtimes are loaded).
  #   output: 'areave' / 'lon' / 'lat' / 'lonlat'.
  #           1) Time series of area-averaged variables over the specified 
  #              domain.
  #           2) Time series of meridional averages as a function of longitudes.
  #           3) Time series of zonal averages as a function of latitudes.
  #           4) Time series of 2d fields.
  #           Default: 'areave'
  #   method: 'bilinear' / 'bicubic' / 'conservative' / 'distance-weighted'
  #           Method of interpolation for 'lon' / 'lat' / 'lonlat' output 
  #           options.
  #           Default: 'conservative'.
  #   grid: To choose a common output grid.
  #         Possible options: rNXxNY or tTRgrid, ex: r96x72, t106grid.
  #         Default: By default, the data of each experimental dataset will be 
  #         loaded into the matrix using the grid in which the data is stored 
  #         in the repository.
  #         IMPORTANT: If various experiments in different grids are specified, 
  #         a common grid has to be specified using this argument.
  #
  #         How grids work:
  #  
  #         We may load one or more experiments and corresponding data from one 
  #         or more observations.
  #         The most usual is that they are on different grids.
  #
  #         We can set Load() to output the data in 4 different modes:
  #         
  #         If output = 'areave' all the data is area-averaged.
  #         If output = 'lon', the data are averaged along the latitude 
  #         dimension and output as a function of the longitudes.
  #         If output = 'lat', the data are averaged along the longitude 
  #         dimension and output as a function of the latitudes.
  #         If output = 'lonlat', the data are output as a function of the 
  #         longitudes and latitudes.
  #         
  #         We refer to the last 3 modes as maps.
  #
  #         If we want to get data output in maps but the experiments and
  #         observations are on different grids, we need to specify a common 
  #         gridding (with the  parameter grid) onto which the loaded data 
  #         will be interpolated.
  #         If we don't do, Load() will crash.
  #         
  #         If we want to get area-averages, the experiments and observations 
  #         can be on different grids and there is no need to specify a common 
  #         grid: Load() will calculate their mean over the original grids 
  #         unless a common grid is specified.
  #
  #         Whenever we specify a common gridding, all data (observational and
  #         experimental) is interpolated onto it.
  #
  #   maskmod: list(mask[lon,lat]) = 1/0: kept/removed grid cell over the 
  #            entire model domains.
  #            Warning: list() compulsory even if 1 model!!!
  #            Default: 1 everywhere.
  #
  #            How masks work:
  #            
  #            When we want to disable certain values we can specify masks. The 
  #            disabled values will be replaced with NA values.
  #
  #            In the case that you wish to load data as area-averages:
  #            You can specify a mask for each experiment and observation.
  #            Each area average will be performed on the original experiment 
  #            or observation grid and after applying the respective mask.
  #
  #            In the case that you wish to load maps:
  #            You will have defined a mandatory common grid which all the data 
  #            will be interpolated onto.
  #            If you want to specify a mask, you will have to provide it 
  #            already interpolated onto the common grid (you may use 'cdo' for 
  #            this purpose).
  #            It is not usual to apply different masks on experimental 
  #            datasets on the same grid. All the experiment masks are expected 
  #            to be the same.
  #
  #            Defining masks for the observational data will be useless: the 
  #            same mask applied to the experimental data will be applied to
  #            the observational data because the observations are interpolated 
  #            on the common grid for which the mask has already been defined 
  #            when loading experimental data.
  #
  #   maskobs: list(mask[lon,lat]) = 1/0: kept/removed grid cell over the 
  #            entire observed domains, only necessary for 'areave' output 
  #            option.
  #            Warning: list() compulsory even if 1 dataset !!!
  #            Default: 1 everywhere.
  # 
  # Returns:
  #   $mod: Model outputs.
  #         If output = 'areave', matrix with dimensions
  #           c(nmod/nexp or nobs, nmemb/nparam, nsdates, nltime)
  #         If output = 'lat', matrix with dimensions
  #           c(nmod/nexp or nobs, nmemb/nparam, nsdates, nltime, nlat)
  #         If output = 'lon', matrix with dimensions
  #           c(nmod/nexp or nobs, nmemb/nparam, nsdates, nltime, nlon)
  #         If output = 'lonlat', matrix with dimensions
  #           c(nmod/nexp or nobs, nmemb/nparam, nsdates, nltime, nlat, nlon)
  #   $obs: Observations. Matrix with same dimensions as '$mod'.
  #   $lat: Latitudes of the model grid.
  #   $lon: Longitudes of the model grid.
  # 
  # Details:
  #
  #   Load() is repository-specific, that meaning you should overwrite it so as 
  #   to make it work properly with the directory tree and naming conventions 
  #   in your data repository.
  #   The current layout and documentation is the one being used at IC3 by way 
  #   of illustration.
  #
  #   The function Load() must return a list which contains four components: 
  #   $mod, $obs, $lat and $lon.
  #   $mod is the matrix containing the experimental data.
  #   $obs is the matrix containing the observational data.
  #   $lat and $lon are the latitudes and longitudes of the model grid (0 if 
  #   the loaded variable is a global mean).
  #
  #   The experimental data matrix will contain the values of a given variable 
  #   for all the experiments the user wish to compare for a set of starting 
  #   dates, lead-times, longitudes and latitudes interpolated to the common 
  #   grid and with the masks applied.
  #   The observational data matrix will contain the observed values of the 
  #   same variable gathered from the specified observational datasets scanning 
  #   the data repository. The observational data is chosen so as to 
  #   date-correspond the experimental data.
  #
  #   The data matrices must be built with the dimensions in the following 
  #   order and with the following lengths:
  #   1- The number of experimental datasets determined by the user (we need to 
  #   store data of all the experiments in the same array) for the experimental 
  #   matrix or the number of observational datasets available for validation 
  #   in the observational matrix.
  #   2- The greatest number of members across all experiments.
  #   3- The number of starting dates determined by the user (we need to store 
  #   data of each prediction of the model in each starting date).
  #   4- The greatest number of lead-times.
  #   5- The number of latitudes of the zone we want to consider.
  #   6- The number of longitudes of the zone we want to consider.
  #
  #   Dimensions 5 and 6 are optional and their presence will depend on 
  #   whether the variable loaded is 2-dimensional or an area average. 
  #   In the case of an area average the dimensions of the matrix will be only 
  #   the first 4.
  #
  #   For example, at IC3, we have implemented Load() to select the 
  #   experimental and observational datasets from which to load data, the 
  #   variable to load, the range of starting dates, the range of lead-times, 
  #   the frequency and step in which the data is loaded from the datasets, a 
  #   common grid, a method of interpolation, a mask to disable certain 
  #   experimental values, a mask to disable certain observational values and 
  #   an output format:
  #     1) Time series of area-averaged variables over the specified domain. 
  #     2) Time series of meridional averages as a function of longitudes. 
  #     3) Time series of zonal averages as a function of latitudes.
  #     4) Time series of 2d fields.
  #
  #   Furthermore, if the user loads a 2-dimensional variable, he/she can ask 
  #   Load() to load it as area averages, as longitudinal averages in function 
  #   of latitudes or as in latitudinal averages in function of longitudes. In 
  #   these cases the 5th and/or 6th dimension will also disappear.
  #
  #   The observational data matrix is built very similarly to the experimental 
  #   matrix. The only differences are that the first dimension turns to be the
  #   number of observational datasets and the length of the 2nd dimension 
  #   turns to be the number of members of the observational datasets. Later, 
  #   for each lead-time we will store observational data into it if possible.
  #
  #   Any value that can't be filled (either in the experimental matrix or the 
  #   observational matrix) should figure as an NA value.
  #
  #   
  #   This process can become time-expensive when many experiments or 
  #   observational datasets are involved.
  #   We suggest to use the package 'parallel' to minimize the time by 
  #   performing this task in multiple threads of execution.
  #
  #   This function will very probably require to use the 'ncdf' package.
  #
  # History:
  #   1.0  #  2011-03  (V. Guemas, virginie.guemas@ic3.cat)     # Original code
  #   1.1  #  2014-03  (N. Manubens, nicolau.manubens@ic3.cat)  # Formatting to CRAN
 
  ## Packages and resources required.
  #library(ncdf)
 
  # 
  #  Get matrices dimensions from the input
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #
  # The two data matrices are similar and have 7 dimensions each with the 
  # following lengths:
  #   1) Number of experimental/observational datasets.
  #   2) Number of members.
  #   3) Number of starting dates.
  #   4) Number of lead-times.
  #   5) Number of latitudes (optional).
  #   6) Number of longitudes (optional).
  # 
  # We can give values to some of these lengths already. 
  # The lengths will vary in function of the datasets we load and will be 
  # re-adjusted along the process.
  #
  ## nmod is the number of experimental datasets in the repository we load data 
  ## from, and will be the length of the first dimension of the experimental 
  ## data matrix.
  nmod <- length(exp)
  ## nmemb is the largest number of members among the experiments. Initially it 
  ## is set to 9 because all DePreSys experiments have 9 members. If it is 
  ## another kind of experiment, the number of members is adjusted later.
  nmemb <- 9
  ## nobs is the number of observational datasets we load data from.
  nobs <- length(obs)
  ## nsdates is the number of starting dates specified by the user. Only data 
  ## of simulations started on these dates is loaded into the experimental data 
  ## matrix. 
  nsdates <- length(sdates)
  
  ## The following variables are state flags. The questions commented above 
  ## each explain their meaning.
  ## Are the dimensions of the output matrices yet defined?
  dims2define <- 'T'
  ## Are the output matrices yet created?
  mat2define <- 'T'
  ## Do we have to keep the loaded data with the default grid of each  
  ## experiment? If not, the data is interpolated onto a common grid defined by the 
  ## user using 'cdo' tools.
  defgrid <- is.null(grid)
  ## Is the mask for each experiment still to be created?
  flag_mask_mod <- array('T', dim = nmod)
  ## Is the mask for each observation still to be created?
  flag_mask_obs <- array('T', dim = nobs)
  ## We choose the kind of interpolation for the 'cdo regrid' tool.
  remap <- switch(method, 'bilinear' = 'remapbil', 'bicubic' = 'remapbic', 
                  'conservative' = 'remapcon', 'distance-weighted' = 'remapdis')
  
  ## For each experiment we will keep a matrix of weights to account for the
  ## representativity of the grid cell surface in the area average step.
  ## Due to NA values in the data the weights will change between experiments, 
  ## thus it is needed to keep a matrix of weights for each experiment.
  weight_area <- list()
  ## bugfix: weight_lon <- list()
  ## For each observational dataset we keep likely a matrix of weights.
  weight_area_obs <- list()
  ## bugfix: weight_lon_obs <- list()
  ## lat_mod and lon_mod will be set later with the latitudes and longitudes of 
  ## the common grid applied to the data of the experiments and will be  
  ## returned as outputs by Load().
  lat_mod <- NULL
  lon_mod <- NULL
  
  ## Make sure that longitude bounds are positive. This changes is essential
  ## since our database contain fieds systematically stored on grids from 
  ## 0º to 360º East
  if  (lonmin < 0) {
    lonmin <- lonmin + 360
  }
  if (lonmax < 0) {
    lonmax <- lonmax + 360
  }
  
  # 
  #  Parameters needed to load data
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # 
  ## The following variables contain the paths to the experimental datasets
  roota <- '/cfunas/exp/ENSEMBLES/decadal/MME/'
  rootb <- '/cfunas/exp/*/'
  rootc <- '/cfunas/exp/ENSEMBLES/'
  rootd <- '/cfunas/exp/CMIP5/decadal/'
  roote <- '/cfunas/exp/CMIP5/historical/'
  rootf <- '/cfunas/exp/ECMWF/seasonal/0001/s004/'
  rootg <- '/cfunas/exp/ECMWF/seasonal/0001/s003/m001/'
  rooth <- '/cfunas/exp/SPECS/decadal/'
  
  ## lstatms is a list of the possible atmospheric variables (2-dimensional).
  lstatms <- c('tas', 'prlr', 'tos', 'g500', 'g200', 'ta50', 'psl', 'hflsd',
               'hfssd', 'rls', 'rss', 'rsds', 'uas', 'vas')
  ## lstatm_stats is a list of the atmospheric statistical variables.               
  lstatm_stats <- c('tas_q90', 'tas_mean', 'tas_ndaysq90', 'prlr_q90', 
                    'prlr_mean', 'prlr_ndaysq90', 'tasmax_q90', 'tasmin_q10', 
                    'prlr_q90', 'prlr_q10','tasmax_nbdaysq90_1979-2005', 
                    'tasmin_nbdaysq10_1979-2005', 'prlr_nbdaysq90_1979-2005', 
                    'prlr_nbdaysq10_1979-2005','tasmax_nbdaysq90_1979-2012', 
                    'tasmin_nbdaysq10_1979-2012', 'prlr_nbdaysq90_1979-2012', 
                    'prlr_nbdaysq10_1979-2012','tasmax_nbdaysq90_1981-2010', 
                    'tasmin_nbdaysq10_1981-2010', 'prlr_nbdaysq90_1981-2010', 
                    'prlr_nbdaysq10_1981-2010')
  ## lstoces is a list of the possible oceanic variables (global means). Please, if
  ## you insert new variables, do not change the current order of the variables.
  lstoces <- c('siaN', 'sieN', 'sivN', 'siaS', 'sieS', 'sivS', 
               'sia_Amundsen_Sea', 'sie_Amundsen_Sea', 'siv_Amundsen_Sea',
               'sia_Antarctic_Atlantic_Sector', 'sie_Antarctic_Atlantic_Sector', 'siv_Antarctic_Atlantic_Sector',
               'sia_Antarctic_Indian_Sector', 'sie_Antarctic_Indian_Sector', 'siv_Antarctic_Indian_Sector',
               'sia_Antarctic_Ocean', 'sie_Antarctic_Ocean', 'siv_Antarctic_Ocean',
               'sia_ArctOcn', 'sie_ArctOcn', 'siv_ArctOcn',
               'sia_Arctic_Marginal_Seas', 'sie_Arctic_Marginal_Seas', 'siv_Arctic_Marginal_Seas',
               'sia_Arctic_Ocean', 'sie_Arctic_Ocean', 'siv_Arctic_Ocean',
               'sia_Arctic_Ocean_North_Atlantic', 'sie_Arctic_Ocean_North_Atlantic', 'siv_Arctic_Ocean_North_Atlantic',
               'sia_Atlantic_Ocean', 'sie_Atlantic_Ocean', 'siv_Atlantic_Ocean',
               'sia_Baffin', 'sie_Baffin', 'siv_Baffin',
               'sia_Baffin_Bay', 'sie_Baffin_Bay', 'siv_Baffin_Bay',
               'sia_Baltic_Sea', 'sie_Baltic_Sea', 'siv_Baltic_Sea',
               'sia_BarKara', 'sie_BarKara', 'siv_BarKara',
               'sia_Barents_Sea', 'sie_Barents_Sea', 'siv_Barents_Sea',
               'sia_Beaufort_Chukchi_Sea', 'sie_Beaufort_Chukchi_Sea', 'siv_Beaufort_Chukchi_Sea',
               'sia_Beaufort_Sea', 'sie_Beaufort_Sea', 'siv_Beaufort_Sea',
               'sia_Bellingshausen_Sea', 'sie_Bellingshausen_Sea', 'siv_Bellingshausen_Sea',
               'sia_Bering', 'sie_Bering', 'siv_Bering',
               'sia_Bering_Strait', 'sie_Bering_Strait', 'siv_Bering_Strait',
               'sia_CanArch', 'sie_CanArch', 'siv_CanArch',
               'sia_Canadian_Waters', 'sie_Canadian_Waters', 'siv_Canadian_Waters',
               'sia_Caspian_Sea', 'sie_Caspian_Sea', 'siv_Caspian_Sea',
               'sia_Central_Arctic', 'sie_Central_Arctic', 'siv_Central_Arctic',
               'sia_Chukchi_Sea', 'sie_Chukchi_Sea', 'siv_Chukchi_Sea',
               'sia_East_Siberian_Sea', 'sie_East_Siberian_Sea', 'siv_East_Siberian_Sea',
               'sia_Eastern_Central_Arctic', 'sie_Arctic_Marginal_Seas', 'siv_Arctic_Marginal_Seas',
               'sia_Fram_Strait', 'sie_Fram_Strait', 'siv_Fram_Strait',
               'sia_Global_Ocean', 'sie_Global_Ocean', 'siv_Global_Ocean',
               'sia_Greenland_Sea', 'sie_Greenland_Sea', 'siv_Greenland_Sea',
               'sia_Grnland', 'sie_Grnland', 'siv_Grnland',
               'sia_Hudson', 'sie_Hudson', 'siv_Hudson',
               'sia_Icelandic_Sea', 'sie_Icelandic_Sea', 'siv_Icelandic_Sea',
               'sia_Indian_Ocean', 'sie_Indian_Ocean', 'siv_Indian_Ocean',
               'sia_Indo_Pacific_Ocean', 'sie_Indo_Pacific_Ocean', 'siv_Indo_Pacific_Ocean',
               'sia_Kara_Gate_Strait', 'sie_Kara_Gate_Strait', 'siv_Kara_Gate_Strait',
               'sia_Kara_Sea', 'sie_Kara_Sea', 'siv_Kara_Sea',
               'sia_LAT80N', 'sie_LAT80N', 'siv_LAT80N',
               'sia_Labrador_Sea', 'sie_Labrador_Sea', 'siv_Labrador_Sea',
               'sia_Laptev_East_Siberian_Chukchi_Seas', 'sie_Laptev_East_Siberian_Chukchi_Seas', 'siv_Laptev_East_Siberian_Chukchi_Seas',
               'sia_Laptev_East_Siberian_Seas', 'sie_Laptev_East_Siberian_Seas', 'siv_Laptev_East_Siberian_Seas',
               'sia_Laptev_Sea', 'sie_Laptev_Sea', 'siv_Laptev_Sea',
               'sia_Lincoln_Sea', 'sie_Lincoln_Sea', 'siv_Lincoln_Sea',
               'sia_Mediterranean_Sea', 'sie_Mediterranean_Sea', 'siv_Mediterranean_Sea',
               'sia_Nares_Strait', 'sie_Nares_Strait', 'siv_Nares_Strait',
               'sia_Nordic_Barents_Seas', 'sie_Nordic_Barents_Seas', 'siv_Nordic_Barents_Seas',
               'sia_Nordic_Seas', 'sie_Nordic_Seas', 'siv_Nordic_Seas',
               'sia_NorthWest_Passage', 'sie_NorthWest_Passage', 'siv_NorthWest_Passage',
               'sia_North_Atlantic_Arctic', 'sie_North_Atlantic_Arctic', 'siv_North_Atlantic_Arctic',
               'sia_North_Atlantic_Ocean', 'sie_North_Atlantic_Ocean', 'siv_North_Atlantic_Ocean',
               'sia_North_Hemisphere_Ocean', 'sie_North_Hemisphere_Ocean', 'siv_North_Hemisphere_Ocean',
               'sia_Northern_Hemisphere', 'sie_Northern_Hemisphere', 'siv_Northern_Hemisphere',
               'sia_Norwegian_Sea', 'sie_Norwegian_Sea', 'siv_Norwegian_Sea',
               'sia_Okhotsk', 'sie_Okhotsk', 'siv_Okhotsk',
               'sia_OpenOcean', 'sie_OpenOcean', 'siv_OpenOcean',
               'sia_Pacific_Ocean', 'sie_Pacific_Ocean', 'siv_Pacific_Ocean',
               'sia_Ross_Sea', 'sie_Ross_Sea', 'siv_Ross_Sea',
               'sia_Serreze_Arctic', 'sie_Serreze_Arctic', 'siv_Serreze_Arctic',
               'sia_Southern_Hemisphere', 'sie_Southern_Hemisphere', 'siv_Southern_Hemisphere',
               'sia_StLawr', 'sie_StLawr', 'siv_StLawr',
               'sia_Subpolar_Gyre', 'sie_Subpolar_Gyre', 'siv_Subpolar_Gyre',
               'sia_TotalArc', 'sie_TotalArc', 'siv_TotalArc',
               'sia_Vilkitsky_Strait', 'sie_Vilkitsky_Strait', 'siv_Vilkitsky_Strait',
               'sia_Weddell_Sea', 'sie_Weddell_Sea', 'siv_Weddell_Sea',
               'sia_Western_Central_Arctic', 'sie_Western_Central_Arctic', 'siv_Western_Central_Arctic',
               'moc_40N55N_1-2km', 'moc_30N40N_1-2km', 
               'max_moc_38N50N_500m-2km', 'max_moc_40N', 
               'NAtl_stc_0N25N_0-200m', 'SAtl_stc_25S0S_0-200m', 
               'SPac_stc_25S0S_0-200m', 'NPac_stc_0N25N_0-200m', 'heatc', 
               '0-315_heatc', '373-657_heatc', '800-5350_heatc','mxl_heatc', 
               'NAtl_10N65N_heatc', 'NAtl_10N65N_0-315_heatc', 
               'NAtl_10N65N_373-657_heatc', 'NAtl_10N65N_800-5350_heatc', 
               'mxl_NAtl_10N65N_heatc', 'TAtl_30S30N_heatc', 
               'TAtl_30S30N_0-315_heatc', 'TAtl_30S30N_373-657_heatc', 
               'TAtl_30S30N_800-5350_heatc', 'mxl_TAtl_30S30N_heatc',
               'NPac_10N70N_heatc', 'NPac_10N70N_0-315_heatc', 
               'NPac_10N70N_373-657_heatc', 'NPac_10N70N_800-5350_heatc', 
               'mxl_NPac_10N70N_heatc', 'TPac_30S30N_heatc', 
               'TPac_30S30N_0-315_heatc', 'TPac_30S30N_373-657_heatc', 
               'TPac_30S30N_800-5350_heatc', 'mxl_TPac_30S30N_heatc', 
               'Arc_65N90N_heatc', 'Arc_65N90N_0-315_heatc', 
               'Arc_65N90N_373-657_heatc', 'Arc_65N90N_800-5350_heatc', 
               'mxl_Arc_65N90N_heatc', 'Ant_90S60S_heatc', 
               'Ant_90S60S_0-315_heatc', 'Ant_90S60S_373-657_heatc', 
               'Ant_90S60S_800-5350_heatc', 'mxl_Ant_90S60S_heatc', 
               'TInd_30S30N_heatc', 'TInd_30S30N_0-315_heatc', 
               'TInd_30S30N_373-657_heatc', 'TInd_30S30N_800-5350_heatc',
               'mxl_TInd_30S30N_heatc')

  ## locat is the position in the oceanic variables list of the variable
  ## that the user chose. If they chose an atmospheric variable, will be NA. 
  locat <- match(var, lstoces)
  
  ## If the chosen variable is atmospheric, we can already work out a part of 
  ## the path of the dataset (freq). Also we know that it is a 2-dimensional 
  ## variable and that the observational datasets for this variable will have 
  ## only one member.
  if (is.na(locat)) {
    freq <- "_[36]hourly/"
    var2d <- TRUE
    nmembobs <- 1
  ## If the variable is oceanic, we always use the default grid. We know that  
  ## it is not a 2-dimensional variable and that the data loaded will be area 
  ## averages mandatory and cannot be converted.
  ## The observational datasets have only one member except ORAS4 ocean 
  ## reanalysis.
  } else {
    freq <- "/"
    defgrid <- TRUE
    var2d <- FALSE
    output <- 'areave'
    if (substr(var, 1, 2) == 'si') {
      nmembobs <- 1
    } else {
      nmembobs <- 5
    }
  }
  
  ## Whether the variable is statistical or not determines another part of the
  ## path to the repository.
  if (is.na(match(var, lstatm_stats)) == FALSE) {
    dirtype <- 'statistics'
  } else { 
    dirtype <- 'mean'
  }

  # Now we are ready to start loading data into the matrices.
  # We will loop on the specified starting dates. 
  #   For each starting date, we will loop on the list of experimental datasets. 
  #     For each experimental dataset, we will load the file that contains the 
  #     data of all of its members in the current starting date and then we 
  #     will loop on the members.
  #       For each member, we will apply the weights, mask and the appropriate 
  #       transformations and finally store it into the experimental data 
  #       matrix.
  #       However, if the experiment is 'DePreSys', the data of each member in 
  #       the repository is stored in a separate file. In that case the file  
  #       for each member is read at the time we loop on the members instead of 
  #       once at the time we loop on the experimental dataset.
  #   After we have the experimental data for the current starting date, we  
  #   load the observational data from the specified repositories that date 
  #   correspond the lead-times of the specified experimental datasets in the 
  #   current starting date.
  var_exp <- NULL
  var_obs <- NULL 
 
  ## indyear determines how many starting dates we have looped on so far.
  indyear <- 1
  for (jyear in sdates) {  # Loop on starting dates
    #
    #  Loading experimental data
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # 
    jmod <- 1
    for (mod in exp) {  # Loop on experimental datasets
      ## If the current experimental dataset is not 'DePreSys' then we load the
      ## data for all of its members in the current starting date from a single 
      ## file.
      if (substr(mod, 1, 8) != 'DePreSys') {
        ## In function of the name of the variable and the dataset, we build  
        ## the path to the file.
        if (is.na(locat)) {
          dirin <- var
          file2load <- paste(var, "_", jyear, ".nc", sep = "")
          namevar <- var
        } else {
          lastsivariable <- match('siv_Western_Central_Arctic', lstoces)
          if (lastsivariable >= locat) { 
            dirin <- 'ice'
            lastsiglobvariable <- match('sivS', lstoces)
            if (locat <= lastsiglobvariable)  {
              file2load <- paste('siasiesiv_', substr(var, 4, 4), '_', mod, 
                               "_", jyear, "*.nc", sep = '')
              namevar <- substr(var, 1, 3)
            }else{
              file2load <- paste(substr(var, 1, 3), '_Arcticreg1', '_', mod,
                               "_", jyear, "*.nc", sep = '')
              namevar <- var
            }
          }
          lastmocvariable <- match('NPac_stc_0N25N_0-200m', lstoces) 
          if (locat > lastsivariable & lastmocvariable >= locat) {
            dirin <- 'moc'
            file2load <- paste(var, "_", mod, '_', jyear, "*.nc", 
                               sep = "")
            namevar <- switch(substr(var, 1, 3), 'max' = 'maxmoc', 
                              switch(substr(var, 2, 4), 'Pac' = 'zomsfpac', 
                                     'zomsfatl'))
          }
          lastheatcvariable <- match('mxl_TInd_30S30N_heatc', lstoces)
          if (locat > lastmocvariable & lastheatcvariable >= locat) {
            dirin <- 'heatc'
            file2load <- paste(var, "_", mod, '_', jyear, "*.nc", 
                               sep = "")
            namevar <- 'thc'
          }
        }
        
        ## We obtain the names of all data files in the directory of the 
        ## repository.
        argfiles <- paste('ls ', 
                    ## First part
                    switch(mod, 
                    'EnsEcmwfDec' = paste(roota, 'ecmwf/2005/s001/m001', 
                                          sep = ""), 
                    'EnsCerfacsDec' = paste(roota, 'cerfacs/2002/s000/m001', 
                                            sep = ""), 
                    'EnsIfmDec' = paste(roota, 'ifm/2002/s001/m010', sep = ""), 
                    'EnsUkmoDec' = paste(roota, 'ukmo/2026/s001/m001', 
                                         sep = ""), 
                    'EnsEcmwfSeas' = paste(rootc, '/seasonal/ecmwf', sep = ""),
                    'EnsCerfacsSeas' = paste(rootc, 'seasonal/cerfacs', 
                                             sep = ""),
                    'EnsIfmSeas' = paste(rootc, 'seasonal/ifm', sep = ""),
                    'EnsUkmoSeas' = paste(rootc, 'seasonal/ukmo', sep = ""),
                    'EnsCmccSeas' = paste(rootc, '/seasonal/cmcc', sep = ""),
                    'EnsMetfrSeas' = paste(rootc, '/seasonal/metfr', sep = ""),
                    'ecmwf' = paste(rootc, 'ecmwf/2005/s001/m001', sep = ""),
                    'cerfacs' = paste(roota, 'cerfacs/2002/s000/m001', 
                                      sep = ""),
                    'ifm' = paste(roota, 'ifm/2002/s001/m010', sep = ""),
                    'ukmo' = paste(roota, 'ukmo/2026/s001/m001', sep = ""),
                    'ECMWF_S3Seas' = rootg,
                    'ECMWF_S4_sea' = paste(rootf, 'm001', sep = ""),
                    'ECMWF_S4_ann' = paste(rootf, 'm003', sep = ""),
                    'bccdec' = paste(rootd, 'bcc/i1p1', sep = ""),
                    'hadcm3dec' = paste(rootd, 'hadcm3/i2p1', sep = ""),
                    'miroc4dec' = paste(rootd, 'miroc4h/i1p1', sep = ""),
                    'miroc5dec' = paste(rootd, 'miroc5/i1p1', sep = ""),
                    'mri-cgcm3dec' = paste(rootd, 'mri-cgcm3/i1p1', sep = ""),
                    'cnrm-cm5dec' = paste(rootd, 'cnrm-cm5/i1p1', sep = ""),
                    'cancm4dec1' = paste(rootd, 'cancm4/i1p1', sep = ""),
                    'cancm4dec2' = paste(rootd, 'cancm4/i2p1', sep = ""),
                    'knmidec' = paste(rootd, 'ecearth/i1p1', sep = ""),
                    'smhidec' = paste(rootd, 'ecearth/i3p1', sep = ""), 
                    'mpimdec' = paste(rootd, 'mpi-esm-lr/i1p1', sep = ""),
                    'mpimdec2' = paste(rooth, 'mpi-esm-lr/i1p1', sep = ""),
                    'gfdldec' = paste(rootd, 'gfdl/i1p1', sep = ""),
                    'cmcc-cmdec' = paste(rootd, 'cmcc-cm/i1p1', sep = ""),
                    'ipsldec' = paste(rootd, 'ipsl/i1p1', sep = ""),
                    'ipsldec2' = paste(rooth, 'ipsl/i1p1', sep = ""),
                    'bcchis' = paste(roote, 'bcc/i0p1', sep = ""),
                    'hadcm3his' = paste(roote, 'hadcm3/i0p1', sep = ""),
                    'miroc4his' = paste(roote, 'miroc4h/i0p1', sep = ""),
                    'miroc5his' = paste(roote, 'miroc5/i0p1', sep = ""),
                    'mri-cgcm3his' = paste(roote, 'mri-cgcm3/i0p1', sep = ""),
                    'cnrm-cm5his' = paste(roote, 'cnrm-cm5/i0p1', sep = ""),
                    'knmihis' = paste(roote, 'ecearth/iXpY', sep = ""),
                    'cancm4his' = paste(roote, 'cancm4/i0p1', sep= ""),
                    'mpimhis' = paste(roote, 'mpi-esm-lr/i0p1', sep = ""),
                    'gfdlhis' = paste(roote, 'gfdl/i0p1', sep = ""),
                    'ipslhis' = paste(roote, 'ipsl/i1p1', sep = ""),
                    'cmcc-cmhis' = paste(roote, 'cmcc-cm/i0p1', sep = ""),
                    paste(rootb, mod, sep = "")), 
                    ## Second part
                    '/', storefreq, '_', dirtype, '/', dirin, 
                    ## Third part
                    switch(mod, 'ecmwf' = '/', 'cerfacs' = '/', 
                    'ifm' = '/', 'ukmo' = '/', 'EnsEcmwfDec' = '/', 
                    'EnsCerfacsDec' = '/', 'EnsUkmoDec' =  '/', 
                    'EnsIfmDec' = '/', 'EnsEcmwfSeas' = '/', 
                    'EnsCerfacsSeas' = '/', 'EnsUkmoSeas' = '/', 
                    'EnsIfmSeas' = '/', 'EnsCmccSeas' = '/', 
                    'EnsMetfrSeas' = '/', 
                    'ECMWF_S3Seas' = switch(var, 'tos' = '_24hourly/',
                                            'tas' = '_6hourly/', '/'),
                    'ECMWF_S4_sea' = switch(var, 'tos' = '_24hourly/', 
                    '_6hourly/'), 
                    'ECMWF_S4_ann' = switch(var, 'prlr' = '/', 
                                            'tos' = '_24hourly/', '_6hourly/'),
                    'bccdec' = '/', 'hadcm3dec' = '/', 'miroc4dec' = '/', 
                    'miroc5dec' = '/', 'mri-cgcm3dec' = '/', 
                    'cnrm-cm5dec' = '/', 'cancm4dec1' = '/', 'cancm4dec2' = '/',
                    'knmidec' = '/', 'smhidec' = '/', 'bcchis' = '/', 
                    'hadcm3his' = '/', 'miroc4his' = '/', 'miroc5his' = '/', 
                    'mri-cgcm3his' = '/', 'cancm4his' = '/', 
                    'cnrm-cm5his' = '/', 'knmihis' = '/', 'mpimdec' = '/',
                    'mpimdec2' = '/', 'ipsldec2' = '/',
                    'gfdldec' = '/', 'mpimhis' = '/', 'gfdlhis' = '/', 
                    'cmcc-cmdec' = '/', 'cmcc-cmhis' = '/', 'ipsldec' = '/',
                    'ipslhis' = '/', freq),
                    ## Last part
                    file2load, sep = "")
        files <- system(argfiles, intern = T, ignore.stderr = T)
        
        ## If we do not find any file there, we print a warning and set as file
        ## name 'nofile.nc'. If we find any, we take the last as file name.
        ## Then we set the grid. If the grid to apply is the default grid of  
        ## the experiment we do not apply changes to the data file, so the file 
        ## name remains the same.
        ## If the grid has to be changed, we use 'cdo' for this purpose and 
        ## then save the changes into a temporary file named 'tmp.nc'.
        if (length(files) > 0) {
          filename <- files[length(files)]
          print(filename)        
          if (defgrid) {
            grid <- switch(mod, 
                           'ecmwf' = 'r144x73', 
                           'cerfacs' = 'r144x73',
                           'ukmo' = 'r144x73',
                           'ifm' = 'r144x73',
                           'EnsEcmwfDec' = 'r144x73',
                           'EnsCerfacsDec' = 'r144x73',
                           'EnsUkmoDec' = 'r144x73',
                           'EnsIfmDec' = 'r144x73',
                           'EnsEcmwfSeas' = 'r144x73',
                           'EnsCerfacsSeas' = 'r144x73',
                           'EnsUkmoSeas' = 'r144x73',
                           'EnsIfmSeas' = 'r144x73',
                           'EnsCmccSeas' = 'r144x73',
                           'EnsMetfrSeas' = 'r144x73',
                           'ECMWF_S4_sea' = 't170grid',
                           'ECMWF_S4_ann' = 't170grid',
                           'bccdec' = 't42grid',
                           'hadcm3dec' = switch(var, 
                                                'tos' = 'r288x144',
                                                'tas' = 'r96x73',
                                                'prlr' = 'r96x73',
                                                'psl' = 'r96x73'),
                           'miroc4dec' = 'r360x180',
                           'miroc5dec' = 't85grid',
                           'mri-cgcm3dec' = switch(var,
                                                   'tos' = 'r240x180',
                                                   'tas' = 't106grid',
                                                   'prlr' = 't106grid',
                                                   'psl' = 't106grid'),
                           'cnrm-cm5dec' = 't85grid',
                           'cancm4dec1' = switch(var,
                                                 'tas' = 't42grid',
                                                 'prlr' = 't42grid',
                                                 'psl' = 't42grid'),
                           'cancm4dec2' = switch(var,
                                                 'tas' = 't42grid',
                                                 'prlr' = 't42grid'),
                           'knmidec' = 'r320x161',
                           'mpimdec' = 't63grid',
                           'mpimdec2' = 't63grid',
                           'gfdldec' = switch(var,
                                              'tas' = 'r144x90',
                                              'prlr' = 'r144x90',
                                              'tos' = 'r144x90'),
                           'cmcc-cmdec' = switch(var,
                                                 'tas' = 't159grid',
                                                 'prlr' = 't159grid'),
                           'ipsldec' = 'r96x96',
                           'ipsldec2' = 'r96x96',
                           'bcchis' = 't42grid',
                           'hadcm3his' = switch(var,
                                                'tos' = 'r288x144',
                                                'tas' = 'r96x73',
                                                'prlr' = 'r96x73',
                                                'psl' = 'r96x73'),
                           'miroc4his' = 'r360x180',
                           'miroc5his' = 't85grid',
                           'mri-cgcm3his' = switch(var,
                                                   'tos' = 'r240x180',
                                                   'tas' = 't106grid',
                                                   'prlr' = 't106grid',
                                                   'psl' = 't106grid'),
                           'cnrm-cm5his' = 't85grid',
                           'cancm4his' = switch(var,
                                                'tas' = 't42grid',
                                                'prlr' = 't42grid',
                                                'psl' = 't42grid'),
                           'mpimhis' = 't63grid',
                           'gfdlhis' = switch(var,
                                              'tas' = 'r144x90',
                                              'prlr' = 'r144x90',
                                              'tos' = 'r144x90'),
                           'ipslhis' = 'r96x96',
                           'cmcc-cmhis' = 't159grid',
                           switch(var,
                                  'ta50' = 't159grid',
                                  't106grid'))
            filein <- filename
          } else {
            system(paste("cdo ", remap, ",", grid, " -selname,", namevar, " ", filename, 
                         " tmp.nc 2>/dev/null", sep = ""))
            system("ncrename -v lat,latitude -d lat,latitude -v lon,longitude -d lon,longitude tmp.nc")
            filein <- "tmp.nc"
          }
          
          ## We open the file whichever is its name and we load into the 
          ## variable tmp the data of the specified variable it contains.
          fnc <- open.ncdf(filein)
          tmp <- get.var.ncdf(fnc, namevar)
          ## Now we have to arrange the data in the matrix tmp with the 
          ## dimensions in a common order:
          ##   1) Longitudes 
          ##   2) Latitudes
          ##   3) Members
          ##   4) Lead-times
          ##
          ## If the variable is 2-dimensional (atmospheric):
          if (var2d == TRUE) {
            ## We disable large values which correspond to NA.
            tmp[which(tmp > 1e11)] <- NA
            tmp[which(tmp < (-1e33))] <- NA
            ## If the matrix loaded has only 3 dimensions, it means it only 
            ## contains data for one member so the dimension of the members has
            ## length 1 and has been automatically squeezed.
            ## It has to be added.
            if (length(dim(tmp)) == 3) {
              tmp <- InsertDim(tmp, 3, 1)
            }
            ## We read the longitudes and latitudes from the file.
            lat <- get.var.ncdf(fnc, "latitude")
            lon <- get.var.ncdf(fnc, "longitude")
            ## We re-order the latitudes if needed.
            if (lat[1] < lat[length(lat)]) {         
              tmp <- tmp[, length(lat):1, , ]
              lat <- lat[length(lat):1]
              if (length(dim(tmp)) == 3) {
                tmp <- InsertDim(tmp, 3, 1)
              }
            }
          ## If the variable is a global mean (oceanic):
          } else {
            ## In this case, the file should contain data in two dimensions: 
            ## members and lead-times.
            ## If any of them does not appear, it is because there was only one 
            ## member or only one lead-time and was automatically squeezed.
            if (is.null(dim(tmp))) {
              tmp <- InsertDim(tmp, 1, 1)
            }
            if (length(dim(tmp)) < 2) {
              tmp <- InsertDim(tmp, 1, 1)
            }
            ## We add two dimensions corresponding to latitudes and longitudes 
            ## to fulfill the common order.
            tmp <- InsertDim(tmp, 1, 1)
            tmp <- InsertDim(tmp, 1, 1)
            ## We set as output longitudes and latitudes one single point 
            ## (0, 0) to avoid a crash.
            lat_mod <- 0
            lon_mod <- 0
          }
          close.ncdf(fnc)
          ## At this point, if we are in the first experiment, we can define 
          ## the definitive lengths of the dimensions of the experimental 
          ## matrix.
          if (dims2define) {
            if (is.null(nleadtime)) {
              nleadtime <- dim(tmp)[4]
            }
            if (is.null(leadtimemax)) {
              leadtimemax <- nleadtime
            }
            if (is.null(nmember)) {
              nmemb <- dim(tmp)[3]
            } else {
              nmemb <- nmember
            } 
            dims2define <- 'F'
          }
          ## If we are not in the first experiment, we check that the length of 
          ## the dimensions of data of the current experiment does not exceed 
          ## the lengths of the experimental matrix to make sure no data is 
          ## lost.
          else {
            if (dim(tmp)[3] > nmemb) {
              stop("PUT FIRST THE EXPERIMENT ID WITH THE LARGEST NUMBER OF MEMBERS.
                    If already done, check the dimensions of your files in the repository.")
            }
            if (dim(tmp)[4] > nleadtime) {
              stop("nleadtime argument is wrong")
            }
          }
        } else {
          print(paste('No file in ', argfiles))
          filename <- 'nofile.nc'
        }
      }

      ## Now, if the experiment was not 'DePreSys', the data for all the 
      ## members in the current starting date is already loaded into the matrix 
      ## tmp.
      # We are ready to loop on the members.
      for (jmemb in 1:nmemb) {
        # If the experiment is 'DePreSys', we have to do the same process to 
        # load each file that contains data for the current member.
        if (substr(mod, 1, 8) == 'DePreSys') {
          ## We build the path to the dataset.
          type <- switch(substr(mod, (nchar(mod) - 3), nchar(mod)), 
                         'Seas' = 'seasonal', 
                         'decadal')
          asim <- switch(substr(mod, 1, 12), 'DePreSysAsim' = '2502',
                         'DePreSysNoAs' = '2501')
          numPP <- seq(10, 18)
          dir <- switch(var, 'uas' = '_rg/', 'vas' = '_rg/', '/')
          filename <- paste(rootc, type, '/DePreSys/', asim, "/s051/m0",
                            as.character(numPP[jmemb]), "/monthly_mean/", var,
                            dir, var, "_", jyear, ".nc", sep = "")
          if (is.null(nleadtime)) {
            nleadtime <- switch(type, 'seasonal' = 7, 'decadal' = 120)
          }
          if (is.null(leadtimemax)) {
            leadtimemax <- nleadtime
          }
          print(filename)
          ## If the file is found, we put the data in the corresponding grid 
          ## and store it into the matrix tmp. We disable large values and 
          ## re-order the latitudes if needed.
          ## The data loaded will correspond to a single starting date of a 
          ## single experiment and to a single member. So it will have 3 
          ## dimensions:
          ##   1) Longitudes
          ##   2) Latitudes
          ##   3) Lead-times
          if (file.exists(filename)) {
            if (defgrid) {
              if (type == 'seasonal') {
                grid <- 'r144x73'
              } else {
                grid <- switch(var, 'hfssd' = 'r144x73', 'hflsd' = 'r144x73',
                               'r96x73')
              }
              filein <- filename
            } else {
              system(paste("cdo ", remap, ",", grid, " -selname,", var, " ", filename, 
                           " tmp.nc 2>/dev/null", sep = ""))
              system("ncrename -v lat,latitude -d lat,latitude -v lon,longitude -d lon,longitude tmp.nc")
              filein <- "tmp.nc"
            } 
            fnc <- open.ncdf(filein)
            tmp <- get.var.ncdf(fnc, var)
            tmp[which(tmp > 1e11)] <- NA
            tmp[which(tmp < (-1e33))] <- NA
            lat <- get.var.ncdf(fnc, "latitude")
            lon <- get.var.ncdf(fnc, "longitude")
            close.ncdf(fnc)
            if (lat[1] < lat[length(lat)]) { 
              tmp <- tmp[, length(lat):1, ]
              lat <- lat[length(lat):1]
            }
          }
        }

        ## At this point, if the experiment is 'DePreSys', we have data of the 
        ## current member in the matrix tmp (with 3 dimensions). 
        ## If the experiment is not 'DePreSys', we have data of all of the 
        ## members (4 dimensions).
        ##
        # If data was found in the repository, we apply the mask and weights to 
        # it and store into the experimental data matrix.
        # If no data was found, the output matrix will contain NA values for 
        # the current member (DePreSys) or starting date (non DePreSys) of the 
        # current experiment.
        ## jens <- (jmod - 1) * nmemb + jmemb
        if (file.exists(filename)) {
          ## If the variable is 2-dimensional:
          if (var2d == TRUE) {
            # We loop on the lead-times. 
            for (jtime in seq(leadtimemin, leadtimemax, sampleperiod)) {
              ## For each lead-time we create a matrix
              ## of size longitudes x latitudes and fill it in with the data in 
              ## the matrix tmp that corresponds to the current lead-time.
              tmp1 <- array(dim = c(length(lon), length(lat)))
              if (substr(mod, 1, 8) == 'DePreSys') {
                if (jtime <= dim(tmp)[3]) {
                  tmp1 <- tmp[, , jtime]
                }
              } else {
                if (jmemb <= dim(tmp)[3] & jtime <= dim(tmp)[4]) {
                  tmp1 <- tmp[, , jmemb, jtime]
                }
              }

              #
              #  Selecting the masked domain
              # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
              #
              indlon <- which((lon >= lonmin & lon <= lonmax) | 
                              (lonmax < lonmin & (lon >= lonmin | lon <= lonmax)
                              ))
              tmp2 <- tmp1[indlon, which(lat >= latmin & lat <= latmax)]
              ## In tmp2, we have the data of the current lead-time placed
              ## inside the specified longitudes and latitudes.
              ## If we have not created the mask of te current model yet:
              if (flag_mask_mod[jmod]) {
                ## If the user did not specify a mask, we create one full of 1s.
                if (is.null(maskmod[[jmod]])) {
                  maskmod[[jmod]] <- array(1, dim = dim(tmp1))
                }
                ## Else, we take the specified mask.
                ## We slice it to fit the limited area.
                maskmod[[jmod]] <- maskmod[[jmod]][indlon, 
                                   which(lat >= latmin & lat <= latmax)]
                ## We define the output longitudes and latitudes
                lat_mod <- lat[which(lat >= latmin & lat <= latmax)]
                lon_mod <- lon[indlon]
                ## Now the mask is marked as created.
                flag_mask_mod[jmod] <- 'F'

                #
                #  Computing weigths for averaging
                # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                #
                ## If the mask was not created yet, the weights were not 
                ## computed either. We compute them.
                weight <- InsertDim(cos(lat_mod * pi / 180), 1, dim(tmp2)[1])
                weight[which(maskmod[[jmod]] < 0.5 | is.na(tmp2))] <- NA
                weight_lon <- weight / InsertDim(Mean1Dim(weight, 2, narm = T),
                                                 2, dim(tmp2)[2])
                ## bugfix: 
                ##weight_lon[[jmod]] <- weight / InsertDim(Mean1Dim(weight, 2, 
                ##                                                  narm = T),
                ##                                         2, dim(tmp2)[2])
                weight_area[[jmod]] <- weight / mean(weight, na.rm = T)
                
                #
                #  Defining output matrix
                # ~~~~~~~~~~~~~~~~~~~~~~~~
                #
                ## Now we will apply the weights and store the result into the
                ## experimental matrix. If it has not been created, we create 
                ## it.
                ## We also create the observational matrix as it is the same 
                ## size.
                ## If the user specified an output type of area average, there
                ## will not be the 5th and 6th dimensions of longitudes and 
                ## latitudes, and so on.
                if (mat2define) {
                  nleadtime2 <- (leadtimemax - leadtimemin) %/% sampleperiod + 1
                  var_exp <- switch(output,
                                    'areave' = array(dim = c(nmod, nmemb, 
                                               nsdates, nleadtime2)),
                                    'lon' = array(dim = c(nmod, nmemb, nsdates,
                                            nleadtime2, dim(tmp2)[1])),
                                    'lat' = array(dim = c(nmod, nmemb, nsdates,
                                            nleadtime2, dim(tmp2)[2])),
                                    'lonlat' = array(dim = c(nmod, nmemb, 
                                               nsdates, nleadtime2, 
                                               dim(tmp2)[2:1])))
                  ## We mark that the matrices are now created.
                  mat2define <- 'F'
                }
              }

              ## We apply the mask to the data.
              tmp2[which(maskmod[[jmod]] < 0.5)] <- NA
              # 
              #  Computing the outputs
              # ~~~~~~~~~~~~~~~~~~~~~~~
              #
              # We apply the weights to the data and store it into the 
              # experimental matrix.
              jtime2 <- (jtime - leadtimemin) %/% sampleperiod + 1
              if (output == 'areave') {
                var_exp[jmod, jmemb, indyear, jtime2] <- mean(
                                                         tmp2 * weight_area[[jmod]], 
                                                         na.rm = T)
              } else if (output == 'lon') {
                var_exp[jmod, jmemb, indyear, jtime2, ] <- Mean1Dim(
                                                           tmp2 * weight_lon,
                                                           2, narm = T)
                ## bugfix:
                ##                                           weight_lon[[jmod]],
              } else if (output == 'lat') {
                var_exp[jmod, jmemb, indyear, jtime2, ] <- Mean1Dim(tmp2, 1,
                                                           narm = T)
              } else if (output == 'lonlat') {
                var_exp[jmod, jmemb, indyear, jtime2, , ] <- t(signif(tmp2, 5))
              } else {
                stop("Wrong output option")
              }
            }
          ## If the variable is a global mean:
          } else {
            ## We do not need to apply masks or weights. Just create the 
            ## matrices if not yet created and store the data into the 
            ## experimental one.
            if (mat2define) {
              nleadtime2 <- (leadtimemax - leadtimemin) %/% sampleperiod + 1
              var_exp <- array(dim = c(nmod, nmemb, nsdates, nleadtime2))
              mat2define <- 'F'
            }
            if (dim(tmp)[3] >= jmemb) {
              var_exp[jmod, jmemb, indyear, 1:min(nleadtime2, 
                (dim(tmp)[4] - leadtimemin) %/% sampleperiod + 1)] <- tmp[1, 1, 
                jmemb, seq(leadtimemin, min(leadtimemax, dim(tmp)[4]), 
                sampleperiod)]
            }
          }
        }
      }
      jmod <- jmod + 1
    }
    
    if ( is.null(obs) == FALSE & jyear == sdates[1] ) { 
      if (is.null(leadtimemax)) {
        diff <- Sys.time() - as.POSIXct(paste(substr(jyear, 1, 4), '-',
                substr(jyear, 5, 6), '-', substr(jyear, 7, 8), sep=''))
        if (storefreq == 'monthly') { 
          leadtimemax <- as.integer(diff/30) 
        } else {
          leadtimemax <- as.integer(diff)
        }
      }
      nleadtime2 <- (leadtimemax - leadtimemin) %/% sampleperiod + 1
    }
    #
    #  Loading observational data
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #
    # Now we have to load the observational data in the current starting date
    # from the specified observational datasets that date corresponds the 
    # experimental data.
    # Each file in the repository contains data of one month.
    
    ## indobs tells which observational dataset we are looping on.
    indobs <- 1
    for (jobs in obs) {  # Loop on observational datasets.
      ## If the variable is atmospheric:
      if (is.na(locat)) {
        ## We build the path to the dataset.
        suffixeraint <- switch(var,
                               'tas' = '_f6h/',
                               'tasmin' = '_f6h/',
                               'tasmax_q90'= '/',
                               'tasmin_q10'= '/',
                               'tasmax_nbdaysq90_1979-2005'= '/',
                               'tasmax_nbdaysq90_1981-2010'= '/',
                               'tasmax_nbdaysq90_1979-2012'= '/',
                               'tasmin_nbdaysq10_1979-2005'= '/',  
                               'tasmin_nbdaysq10_1979-2012'= '/',  
                               'tasmin_nbdaysq10_1981-2010'= '/',  
                               'tasmax' = '_f6h/',
                               'tas_q90' = '_f6h/',
                               'tas_mean' = '_f6h/',
                               'tas_ndaysq90' = '_f6h/',
                               'tos' = '_f6h/',
                               'prlr' = '_s0-12h/',
                               'prlr_mean' = '_s0-12h/',
                               'prlr_q90' = '/',
                               'prlr_q10' = '/',
                               'prlr_nbdaysq90_1979-2005'= '/',
                               'prlr_nbdaysq90_1981-2010'= '/',
                               'prlr_nbdaysq90_1979-2012'= '/',
                               'prlr_nbdaysq10_1979-2005'= '/',  
                               'prlr_nbdaysq10_1979-2012'= '/',  
                               'prlr_nbdaysq10_1981-2010'= '/', 
                               'g200' = '_f6h/',
                               'g500' = '_f6h/',
                               'psl' = '_f6h/',
                               'rls' = '_s0-12h/',
                               'rss' = '_s0-12h/',
                               'rsds' = '_s0-12h/',
                               'hflsd' = '_s0-12h/',
                               'hfssd' = '_s0-12h/',
                               'uas' = '_f6h/',
                               'vas' = '_f6h/',
                               'ta50' = '_f6h/')
        suffixncep <- switch(var,
                             'tas' = '_6hourly/',
                             'psl' = '_6hourly/',
                             'rls' = '_step6h/',
                             'rss' = '_step6h/', 
                             'hflsd' = '_step6h/',
                             'hfssd' = '_step6h/',
                             'rsds' = '_step6h/',
                             'uas' = '_6hourly/',
                             'vas' = '_6hourly/')
        pathobs <- switch(jobs,
                          'ERA40' = paste('/cfu/data/ecmwf/era40/', storefreq,
                                    '_', dirtype, '/', var, '_f6h/', var, '_',
                                    sep = ""),
                          'NCEP' = paste('/cfu/data/ncep/', storefreq, '_',
                                   dirtype, '/', var, suffixncep, var, '_ncep_',
                                   sep = ""),
                          'ERAint' = paste('/cfu/data/ecmwf/eraint/', storefreq,
                                     '_', dirtype, '/', var, suffixeraint, var,
                                     '_', sep = ""),
                          '20thCv2' = paste('/cfu/data/noaa/20thc_reanv2/', 
                                      storefreq, '_', dirtype, '/', var, 
                                      suffixeraint, var, '_', sep = ""),
                          'GHCN' = paste('/cfu/data/noaa/ghcn_v2/', storefreq,
                                   '_', dirtype, '/tas/tas_', sep = ''),
                          'GHCNERSSTGISS' = paste('/cfu/data/noaanasa/ghcnersstgiss/',
                                            storefreq, '_', dirtype, 
                                            '/tas/tas_', sep = ''),
                          'ERSST' = paste('/cfu/data/noaa/ersstv3b/', storefreq,
                                    '_', dirtype, '/tos/tos_', sep = ""),
                          'UKMO' = paste('/cfu/data/ukmo/hadisstv1.1/', 
                                   storefreq, '_', dirtype, '/tos/tos_', 
                                   sep = ''),
                          'HadISST' = paste('/cfu/data/ukmo/hadisstv1.1/',
                                      storefreq, '_', dirtype, '/tos/tos_',
                                      sep = ''),
                          'HadSLP' = paste('/cfu/data/ukmo/hadslp2/', storefreq,
                                     '_', dirtype, '/psl/psl_', sep = ''),
                          'GPCC' = paste('/cfu/data/dwd/gpcc_combined1x1_v4/',
                                   storefreq, '_', dirtype, '/prlr/prlr_',
                                   sep = ''),
                          'CRU' = paste('/cfu/data/cru/', storefreq, '_',
                                  dirtype, '/', var, '/', var, '_cru_', 
                                  sep = ""),
                          'GPCP' = paste('/cfu/data/noaa/gpcp_v2.2/', storefreq,
                                   '_', dirtype, '/prlr/prlr_', sep = ''),
                          'EOBS' = '/cfu/data/eobs/prlr_eobs_0.5x0.5/prlr_eobs_'
                                   ,
                          'DS94' = paste('/cfu/data/iri/DaSilva/', storefreq,
                                   '_', dirtype, '/', var, '/', var, '_', 
                                   sep = ""), 
                          'OAFlux' = paste('/cfu/data/whoi/oaflux/', storefreq,
                                     '_', dirtype, '/', var, '/', var, '_', 
                                     sep = ""),
                          'DFS4.3' = paste('/cfu/data/legi/dfs4.3/', storefreq,
                                     '_', dirtype, '/', var, '/', var, '_',
                                     sep = ""),
                          'GISSglo' = '/cfu/data/nasa/global_mean/tas_GISS_',
                          'GISSland' = '/cfu/data/nasa/land_mean/tas_GISS_',
                          'GISSoc' = '/cfu/data/nasa/ocean_mean/tos_GISS_',
                          'CRUTEM3land' = '/cfu/data/ukmo/land_mean/tas_CRUTEM3_'
                          ,
                          'HadSST2oc' = '/cfu/data/ukmo/ocean_mean/tos_HadSST2_'
                          ,
                          'HadCRUT3glo' = '/cfu/data/ukmo/global_mean/tas_hadCRUT3_'
                          ,
                          'HadCRUT4' = '/cfu/data/ukmo/hadcrut4/monthly_mean/tas_anom/tas_'
                          ,
                          'NCDCoc' = paste('/cfu/data/noaa/merged_ocean_mean/',
                                     storefreq, '_', dirtype, '/tos/tos_', 
                                     sep = ''),
                          'NCDCland' = paste('/cfu/data/noaa/merged_land_mean/',
                                       storefreq, '_', dirtype, '/tas/tas_',
                                       sep = ''),
                          'NCDCglo' = paste('/cfu/data/noaa/merged_global_mean/'
                                      , storefreq, '_', dirtype, '/tas/tas_',
                                      sep = ''))
        ## We obtain the names of the files in the directory.
        filesobs <- system(paste('ls ', pathobs, '*', sep = ''), intern = T,
                           ignore.stderr = T)
        print(paste('Files loaded from ', pathobs, '*', sep = ''))
        ## If any file is found:
        if (length(filesobs) > 0) {
          ## The current starting date is transformed into a number.
          if (storefreq == 'daily') {
            iday <- substr(jyear, 7, 8)
            if (iday == '') {
              iday <- '01'
            } 
            startdate <- as.POSIXct(paste(substr(jyear, 1, 4), '-',
                         substr(jyear, 5, 6), '-', iday, ' 12:00:00', 
                                sep = '')) + (leadtimemin - 1) * 86400
          } else {
            imon <- (as.integer(substr(jyear, 5, 
                     6)) + leadtimemin - 2) %% 12 + 1
            iyear <- as.integer(substr(jyear, 1, 4)) + (as.integer(substr(jyear, 
                      5, 6)) + leadtimemin - 2) %/% 12
          }
          ## jtime is the index of the current lead-time.
          jtime <- 1
          # We loop on the lead-times.
          while (jtime <= nleadtime2) {
            ## The current lead-time is calculated from the current starting 
            ## date as number and from the index of the current lead-time.
            if (storefreq == 'daily') {
              newdate <- startdate + 86400 * (jtime - 1) * sampleperiod
              iyear <- substr(newdate, 1, 4)
              imon <- as.integer(substr(newdate, 6, 7))
              itimind <- as.integer(substr(newdate, 9, 10))
              if (LeapYear(as.integer(iyear))) {
                lenmon <- 29
              } else { 
                lenmon <- 28
              }
              lenmon <- switch(substr(newdate, 6, 7), '01' = 31, '03' = 31, 
                        '04' = 30, '05' = 31, '06' = 30, '07' = 31, '08' = 31,
                        '09' = 30, '10' = 31, '11' = 30, '12' = 31, lenmon)
            } else {
              if (jtime > 1) {
                imon <- imon + sampleperiod
                iyear <- iyear + (imon - 1) %/% 12
                imon <- (imon - 1) %% 12 + 1
              }
              itimind <- 1
              lenmon <- 1
            }
            ## The full path to the file that corresponds to the current 
            ## lead-time is built.
            filename <- paste(pathobs, iyear, sprintf("%2.2i", imon), ".nc", 
                              sep = "")
            # If the file is found, the data is loaded into the observational 
            # matrix after putting in order and applying the mask and weights.
            # If not, the associated part of the matrix is left with NA values.
            if (file.exists(filename)) {
              print(filename)
              var2 <- switch(jobs, 'ERSST' = 'tos', 'UKMO' = 'tos',
                             'HadISST' = 'tos', var)
              if ((output != 'areave' & nmod >= 1) | defgrid == FALSE) {
                system(paste("cdo ", remap, ",", grid, " -selname,", var2, " ", filename, 
                             " tmp.nc 2>/dev/null", sep = ""))
                system("ncrename -v lat,latitude -d lat,latitude -v lon,longitude -d lon,longitude tmp.nc")
                filename <- "tmp.nc"
              }
              fnc <- open.ncdf(filename)
              tmp <- get.var.ncdf(fnc, var2)
              if (var == 'tos' | var =='tas' | var=='prlr') { 
                tmp[which(tmp > 599 | tmp < (-999))] <- NA 
              }
              if (substr(jobs, (nchar(jobs) - 3), 
                  nchar(jobs)) != 'land' & substr(jobs, (nchar(jobs) - 1), 
                  nchar(jobs)) != 'oc' & substr(jobs, (nchar(jobs) - 2), 
                  nchar(jobs)) != 'glo') {
                lat <- get.var.ncdf(fnc, "latitude")
                lon <- get.var.ncdf(fnc, "longitude")
                lon[which(lon < 0)] <- lon[which(lon < 0)] + 360
              }
              close.ncdf(fnc)
              if (length(dim(tmp)) == 2) {
                tmp <- InsertDim(tmp, 3, 1)
              }
              if (( (output != 'areave' & nmod >= 1) | defgrid == F) & lat[1] < 0) { 
                tmp <- tmp[, length(lat):1, ] 
                lat <- lat[length(lat):1]
              }
              if (length(dim(tmp)) == 2 ) {
                tmp <- InsertDim(tmp, 3, 1)
              }
              #
              #  Selecting the masked domain 
              # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              #
              if (storefreq == 'monthly') {
                rangeind <- jtime
              } else {
                rangeind <- jtime:min((lenmon - itimind
                                       ) %/% sampleperiod + jtime, nleadtime2)
              }
              rangeindout <- seq(itimind, min(lenmon, (nleadtime2 - jtime + 1
                                 ) * sampleperiod + itimind - 1), sampleperiod)
              if (substr(jobs, (nchar(jobs) - 3), 
                  nchar(jobs)) != 'land' & substr(jobs, (nchar(jobs) - 1), 
                  nchar(jobs)) != 'oc' & substr(jobs, (nchar(jobs) - 2), 
                  nchar(jobs)) != 'glo') {
                indlon <- which((lon >= lonmin & lon <= lonmax) | (
                                lonmax < lonmin & (lon >= lonmin | lon <= lonmax
                                )))
                tmp1 <- tmp[indlon, which(lat >= latmin & lat <= latmax), ]
                if (length(dim(tmp1)) == 2 ) {
                  tmp1 <- InsertDim(tmp1, 3, 1) 
                }
                lat_obs <- lat[which(lat >= latmin & lat <= latmax)]
                lon_obs <- lon[indlon]
                if (flag_mask_obs[indobs]) {
                  if ( (output != 'areave' | defgrid == F) & nmod >= 1 ) {
                    maskobs[[indobs]] <- maskmod[[nmod]] 
                  } else {
                    if (is.null(maskobs[[indobs]])) {
                      maskobs[[indobs]] <- array(1, dim = dim(tmp)[1:2])
                    } 
                    maskobs[[indobs]] <- maskobs[[indobs]][indlon, 
                                         which(lat >= latmin & lat <= latmax)] 
                  }
                  flag_mask_obs[indobs] <- 'F'
                  #
                  #  Computing weigths for averaging
                  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  #
                  weight <- InsertDim(cos(lat_obs * pi / 180), 1, dim(tmp1)[1])
                  weight[which(maskobs[[indobs]] < 0.5 | is.na(tmp1[, , 
                         1]))] <- NA
                  ## bugfix: weight_lon_obs[[jobs]] <- weight / InsertDim(Mean1Dim(weight, 
                  ##                          2, narm = T), 2, dim(tmp1)[2])
                  weight_area_obs[[jobs]] <- weight / mean(weight, na.rm = T)
                  #
                  #  Defining output matrix
                  # ~~~~~~~~~~~~~~~~~~~~~~~~
                  #
                  if (indobs == 1) {
                    var_obs <- switch(output, 
                                   'areave' = array(dim = c(nobs, nmembobs, 
                                                       nsdates, nleadtime2)),
                                   'lon' = array(dim = c(nobs, 1, nsdates, 
                                                  nleadtime2, dim(tmp1)[1])),
                                   'lat' = array(dim = c(nobs, 1, nsdates, 
                                                  nleadtime2, dim(tmp1)[2])),
                                   'lonlat' = array(dim = c(nobs, 1, nsdates, 
                                                  nleadtime2, dim(tmp1)[2:1])))
                  }
                }
                tmp1[which(InsertDim(maskobs[[indobs]], 3, lenmon) < 0.5)] <- NA
                #
                #  Computing the outputs
                # ~~~~~~~~~~~~~~~~~~~~~~~
                #
                if (output == 'areave') {
                  for (ind in 1:lenmon) { 
                    var_obs[indobs, 1, indyear, rangeind[ind]] <- mean(tmp1[, ,
                    rangeindout[ind]] * weight_area_obs[[jobs]], na.rm = T)
                  }
                } else if (output == 'lon') {
                  var_obs[indobs, 1, indyear, rangeind, ] <- aperm(Mean1Dim(
                    tmp1 * InsertDim(weight_lon, 3, lenmon), 2,
                    narm = T)[, rangeindout], length(dim(tmp1[, , 
                    rangeindout])):1)
                  ## bugfix:
                  ## * InsertDim(weight_lon_obs[[jobs]], 3, lenmon), 2,
                } else if (output == 'lat') {
                  var_obs[indobs, 1, indyear, rangeind, ] <- aperm(Mean1Dim(tmp1
                  , 1, narm = T)[, rangeindout], 
                  length(dim(tmp1[, , rangeindout])):1)
                } else if (output == 'lonlat') {
                  var_obs[indobs, 1, indyear, rangeind, , ] <- aperm(
                  signif(tmp1[, , rangeindout], 5), 
                  length(dim(tmp1[, , rangeindout])):1)
                } else {
                  stop("Wrong output option")
                }
              } else {
                var_obs[indobs, 1, indyear, rangeind] <- tmp[rangeindout]
              }
            }
            jtime <- jtime + (lenmon - itimind) %/% sampleperiod + 1
          }
        } else {
          print(paste('No file in ', pathobs, '*', sep = ''))
        }
      ## If the variable is oceanic, it will be a global mean so the weights 
      ## do not need to be calculated:
      } else {      
        ## We build the path to the dataset.
        lastsiglobvariable <- match('sivS', lstoces)
        if ( var == 'sivN' | var == 'sivS' ) {
          filein <- switch(jobs,
                           'PIOMAS' = paste('/cfu/data/psc/piomas/original_files/'
                                            , var, '_piomas.nc', sep = ''),
                           'UCL' = paste('/cfunas/exp/UCL/monthly_mean/ice/siasiesiv_'
                                         , substr(var, 4, 5), 
                                         '_ucl_fc0-0_19790101_197901_200712.nc',
                                          sep = ''))
          namevar <- switch(jobs,
                            'PIOMAS' = var,
                            'UCL' = substr(var, 1, 3))
        } 
        if ( var == 'sieN' | var == 'siaN' | var == 'siaS' | var == 'sieS' ) {
          filein <- paste('/cfu/diagnostics/postprocessed/ice/',
                          switch(jobs,
                                 'HadISST' = 'ukmo/ice_hadisst',
                                 'NSIDC' = 'nsidc/ice_nsidc'),
                          '_', substr(var, 4, 5), '.nc', sep = '')
          namevar <- substr(var, 1, 3)
        }
        lastsivariable <- match('siv_Western_Central_Arctic', lstoces)
        if (locat > lastsiglobvariable & lastsivariable >= locat) {
          filein <- paste('/cfu/data/',
                          switch(jobs,
                                 'HadISST' = 'ukmo/hadisst/postprocessed/siasie_HadISST.nc', 
                                 'NSIDC' = 'nsidc/postprocessed/siasie_NSIDC.nc'),
                          sep='')
          namevar <- var
        } 
        lastmocvariable <- match('NPac_stc_0N25N_0-200m', lstoces) 
        if (locat > lastsivariable & lastmocvariable >= locat) {
          filein <- paste('/cfunas/exp/ECMWF/NEMOVAR_S4/monthly_mean/moc/', var,
                          '_nemovar_s4_19570901_fc0-4_195709_201212.nc', 
                          sep = "")
          namevar <- switch(substr(var, 1, 3), 
                            'max' = 'maxmoc',
                            switch(substr(var, 2, 4),
                                   'Pac' = 'zomsfpac',
                                   'zomsfatl')) 
        }
        lastheatcvariable <- match('mxl_TInd_30S30N_heatc', lstoces)
        if (locat > lastmocvariable & lastheatcvariable >= locat) {
          filein <- paste('/cfunas/exp/ECMWF/NEMOVAR_S4/monthly_mean/heatc/', 
                          var, '_nemovar_s4_19570901_fc0-4_195709_201212.nc', 
                          sep = "")
          namevar <- 'thc'
        }
        ## Load the values into tmp.
        fnc <- open.ncdf(filein)
        tmp <- get.var.ncdf(fnc, namevar)
        ## Put dimensions in order.
        if (is.na(dim(tmp)[2])) {
          tmp <- InsertDim(tmp, 1, 1)
        }
        close.ncdf(fnc)
        mons <- strsplit(system(paste('cdo showmon ', filein, ' 2>/dev/null'),
                                intern = T), split = ' ')
        years <- strsplit(system(paste('cdo showyear ', filein, ' 2>/dev/null'),
                                 intern = T), split = ' ')
        mons <- as.integer(mons[[1]][which(mons[[1]] != "")])
        years <- as.integer(years[[1]][which(years[[1]] != "")])
        tmp_ts <- ts(t(tmp), start = c(years[1], mons[1]), 
                     end = c(years[length(years)], mons[length(mons)]),
                     frequency = 12)
        tmp2 <- window(tmp_ts, start = c(as.integer(substr(jyear, 1, 4)), 
                       as.integer(substr(jyear, 5, 6))), end = c(3000, 12),
                       frequency = 12, extend = TRUE)
        if (indobs == 1 & jyear== sdates[1]) {
          var_obs <- array(dim = c(nobs, nmembobs, nsdates, nleadtime2))
        }
        ## Store values into observational matrix.
        var_obs[indobs, 1:dim(tmp)[1], indyear, ] <- as.matrix(t(tmp2))[, 
                                                     seq(leadtimemin, 
                                                         leadtimemax,
                                                         sampleperiod)]
        lat_obs <- 0
        lon_obs <- 0
      }
      ## Loop on the next observational dataset.
      indobs <- indobs + 1
    } 
    ## Loop on the next starting date.
    indyear <- indyear + 1
  }
  ## Remove auxiliar files.
  system("rm -f tmp.nc")
  # Case exp == NULL
  if ( is.null(lat_mod) ) { lat_mod <- lat_obs }
  if ( is.null(lon_mod) ) { lon_mod <- lon_obs }
  #
  #  Outputs
  # ~~~~~~~~~
  #
  invisible(list(mod = var_exp, obs = var_obs, lat = lat_mod, lon = lon_mod))
}
