# Hands-on 2: Data assesment

**Goal**

Use CSTools to calibrate, compute anomalies and skill of a climate dataset over a period.

**Load packages**
```r
library(CSTools) # CST_Calibration
library(startR) # Start
# TODO: remove startR if new CSTools is installed
library(s2dv) # 
```

## 1. Load the data

In this section we will use the function **Start** to load the data. Then, we will transfrom the output `startR_array` to an `s2dv_cube` object in order that the data is easy to use within CSTools functions.

The `s2dv_cube` object is a structured list that contains the information needed to work with multidimensional arrays of data. Coordinates, dimensions, and metadata are neatly combined to allow for a more intuitive, concise, and less error-prone experience.

**Note:** If you have already loaded the data with Start, go directly to section 1b).

### 1a) Load the data
TODO: If CSTools new version can be installed, use CST_Start

The following section is taken from ( TODO: cite handson1 ). 

```r
#TODO: update the path
# Use this one if on workstation or nord3 (have access to /esarchive)
path_exp <- "/esarchive/exp/meteofrance/system7c3s/monthly_mean/$var$_f6h/$var$_$syear$.nc"

# Use this one if on Marenostrum4 and log in with PATC2021 account
path_exp <- paste0('/gpfs/scratch/nct01/nct01127/d3_R_handson/esarchive/',
                'exp/ecmwf/system5c3s/daily_mean/',
                '$var$_s0-24h/$var$_$sdate$.nc')

var <- 'tas'
sdate_hcst <- paste0(1993:2016, '1101')
sdate_fcst <- '20201101'
lon.min <- -20
lon.max <- 40
lat.min <- 20
lat.max <- 80
```

```r
hcst <- Start(dat = path_exp,
              var = var,
              syear = sdate_hcst,
              ensemble = 'all',
              time = 1:2,
              latitude = values(list(lat.min, lat.max)),
              latitude_reorder = Sort(),
              longitude = values(list(lon.min, lon.max)),
              longitude_reorder = CircularSort(-180, 180),
              synonims = list(syear = c('syear', 'sdate'),
                              latitude = c('lat', 'latitude'),
                              longitude = c('lon', 'longitude')),
              return_vars = list(time = 'syear',
                                  longitude = NULL, latitude = NULL),
              retrieve = TRUE)
```

```r
fcst <- Start(dat = path_exp,
              var = var,
              syear = sdate_fcst,
              ensemble = 'all',
              time = 1:2, 
              latitude = values(list(lat.min, lat.max)),
              latitude_reorder = Sort(),
              longitude = values(list(lon.min, lon.max)),
              longitude_reorder = CircularSort(-180, 180),
              synonims = list(syear = c('syear', 'sdate'),
                              latitude = c('lat', 'latitude'),
                              longitude = c('lon', 'longitude')),
              return_vars = list(time = 'syear',
                                  longitude = NULL, latitude = NULL),
              retrieve = TRUE)
```

```r
# Adjust the day to the correct month
attributes(hcst)$Variables$common$time <- attributes(hcst)$Variables$common$time - lubridate::days(1)

date_string <- format(attributes(hcst)$Variables$common$time, '%Y%m')
sdate_obs <- array(date_string, dim = c(syear = 24, time = 2))
```

```r
path_obs <- '/esarchive/recon/ecmwf/era5/monthly_mean/$var$_f1h-r1440x721cds/$var$_$syear$.nc'

obs <- Start(dat = path_obs,
              var = var,
              syear = sdate_obs,
              split_multiselected_dims = TRUE,
              latitude = values(list(lat.min, lat.max)),
              latitude_reorder = Sort(),
              longitude = values(list(lon.min, lon.max)),
              longitude_reorder = CircularSort(-180, 180),
              transform = CDORemapper,
#TODO: Change to relative path
#               transform_params = list(grid = './griddes_system7c3s.txt',
              transform_params = list(grid = '/esarchive/scratch/aho/git/startR/inst/doc/tutorial/PATC2023/griddes_system7c3s.txt',
                                      method = 'bilinear'),
              transform_vars = c('latitude', 'longitude'),
              synonims = list(syear = c('syear', 'sdate'),
                              latitude = c('lat', 'latitude'),
                              longitude = c('lon', 'longitude')),
              return_vars = list(time = 'syear',
                                longitude = NULL, latitude = NULL),
              retrieve = TRUE)
```

### 1b) Create `s2dv_cube`:

Now we convert the data (`startR_array`) into an 's2dv_cube' object with the function **as.s2dv_cube**:

```r
> str(hcst)
 'startR_array' num [1, 1, 1:24, 1:25, 1:2, 1:60, 1:60] 295 296 297 297 297 ...
 - attr(*, "Variables")=List of 2
  ..$ common:List of 4
  .. ..$ time     : POSIXct[1:48], format: "1993-12-01" "1994-12-01" ...
  .. ..$ longitude: num [1:60(1d)] -19.5 -18.5 -17.5 -16.5 -15.5 -14.5 -13.5 -12.5 -11.5 -10.5 ...
  .. .. ..- attr(*, "variables")=List of 1
  .. .. .. ..$ longitude:List of 7
  .. .. .. .. ..$ ndims        : num 1
  .. .. .. .. ..$ size         : int 360
  .. .. .. .. ..$ units        : chr "degrees_east"
  .. .. .. .. ..$ dim          :List of 1
  .. .. .. .. .. ..$ :List of 10

```
Now, we convert the startR object into 's2dv_cube' object.
```r
hcst <- as.s2dv_cube(hcst)
fcst <- as.s2dv_cube(fcst)
obs <- as.s2dv_cube(obs)
```
**Questions 1:**   

Find `s2dv_cube` information:  

1. Can you tell what type of object is an **s2dv_cube** in R structures?  
2. What are the time dimensions of the object?  
3. In which region we have loaded the data?  
4. How many coordinates have the object hcst?  
5. How many ensemble members have the observation dataset?  
6. What is the full variable name of the loaded data?  
7. What season is the data loaded from?  

**Exercise 1**:   
1. Find the mean, the maximum and the minimum of the fcst, hcst and obs data and compare it.
2. Explore the data (TODO: complete it)


## 2. Calibrate the data

Calibrate the hindcast:
```r
hcst_cal <- CST_Calibration(exp = hcst, obs = obs,
                            cal.method = "evmos",
                            eval.method = "leave-one-out",
                            multi.model = FALSE,
                            na.fill = TRUE,
                            na.rm = TRUE,
                            apply_to = NULL,
                            alpha = NULL,
                            memb_dim = "ensemble",
                            sdate_dim = "syear",
                            ncores = 10)
```

Calibrate the forecast: 
```r
fcst_cal <- CST_Calibration(exp = hcst, obs = obs, exp_cor = fcst,
                            cal.method = "evmos",
                            eval.method = "leave-one-out",
                            multi.model = FALSE,
                            na.fill = TRUE,
                            na.rm = TRUE,
                            apply_to = NULL,
                            alpha = NULL,
                            memb_dim = "ensemble",
                            sdate_dim = "syear",
                            ncores = 10)

```



## 2. Compute Anomalies


```r
hcst_anom <- CST_Anomaly(exp = hcst_cal, obs = obs,
                         cross = TRUE,
                         memb = TRUE,
                         memb_dim = 'ensemble',
                         dim_anom = 'syear',
                         dat_dim = c('dat', 'ensemble'),
                         ftime_dim = 'time',
                         ncores = 10)
```
Compute forecast anomaly field:
```r
clim <- s2dv::Clim(exp = hcst_cal$data, obs = obs$data,
                   time_dim = "syear",
                   dat_dim = c("dat", "ensemble"),
                   memb = FALSE,
                   memb_dim = "ensemble",
                   ftime_dim = "time",
                   ncores = 10)
clim_hcst <- InsertDim(clim$clim_exp, posdim = 1, lendim = 1, name = "syear")
dims <- dim(clim_hcst)
clim_hcst <- rep(clim_hcst, fcst$dim[['ensemble']])
dim(clim_hcst) <- c(dims, ensemble = fcst$dim[['ensemble']])
clim_hcst <- Reorder(clim_hcst, order = names(fcst$dim))
fcst_anom <- fcst_cal$data - clim_hcst
```

## 3. Compute skill: RPSS

Compute Ranked Probability Skill Score for anomalies: 
```r

skill <- RPSS(exp = hcst_anom$exp$data, obs = hcst_anom$obs$data,
              time_dim = 'syear',
              memb_dim = 'ensemble',
              Fair = FALSE,
              cross.val = TRUE,
              ncores = 10)
```
Explore the result:  

```r
> summary(skill$rpss)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
-0.54005 -0.11225 -0.03170 -0.03722  0.04480  0.44376 
> summary(skill$sign)
   Mode   FALSE    TRUE 
logical    6798     402 
```


## References