Statistics
==========
The **Statistics** module consists of a set of functions that are commonly 
used in the forecast verification process to modify or describe the modelled 
or observed measurements for a certain physic variable of interest, or 
**field**, and some functions to generate synthetic data that comply with 
certain distribution parameters.

These functions can be classified in 4 groups as a function of their purpose:

  - [**Normalizing and filtering fields**](#normalizing): `Season()`, `Clim()`, 
`Ano()`, `Ano_Crossvalid()`, `Trend()`, `Consist_Trend()`, `Regression()`, 
`Smoothing()`, `Spectrum()` and `Filter()`.
  - [**Describing fields**](#describing): `Alpha()`, `FitAcfCoef()` and 
`FitAutocor()`.
  - [**Generating derived fields**](#generating_der): `ProbBins()` and 
`StatSeasAtlHurr()`.
  - [**Generating new fields**](#generating_new): `GenSeries()`, `Toymodel()`, 
`Eno()` and `EnoNew()`.

It is important, to master these functions, to have in mind the structure of 
the data arrays provided by `Load()` and used throughout in s2dverification:
```r
  c(n. of datasets, n. of members, n. of starting dates, n. of leadtimes, n. of latitudes, n. of longitudes)
```
the last two being present depending on the parameter `output`.

The explanations in the following sections will be based on the same data used 
in the [**Example**](example.md). See [**Data retrieval**](data_retrieval.md) 
for details.
```r
library(s2dverification)
expA <- list(name = 'experimentA',
             path = file.path('/path/to/experiments/$EXP_NAME$/monthly_mean',
                              '$VAR_NAME$/$VAR_NAME$_$START_DATE$.nc'))
expB <- list(name = 'experimentB',
             path = file.path('/path/to/experiments/$EXP_NAME$/monthly_mean',
                              '$VAR_NAME$/$VAR_NAME$_$START_DATE$.nc'))
obsX <- list(name = 'observationX',
             path = file.path('/path/to/observations/$OBS_NAME$/monthly_mean',
                              '$VAR_NAME$/$VAR_NAME$_$YEAR$$MONTH$.nc'))
sdates <- paste0(1991:1993, '1101')
data <- Load('tas', list(expA, expB), list(obsX),
             sdates = sdates,
             leadtimemin = 2, leadtimemax = 7,
             latmin = -10, latmax = 60,
             lonmin = 100, lonmax = 250,
             output = 'areave', grid = 't106grid',
             method = 'distance-weighted')
```

Normalizing and filtering fields<a name="normalizing"></a>
--------------------------------
Depending on the source and nature of the field to verify it is often needed 
to remove, shift or modulate some of its frequency components before computing 
the quality measurements to avoid __overscore__underscore__.

### Bias correction: climatologies and anomalies<a name="clim_ano_bc"></a>
Due to systematic errors in the models, their mean behaviour along the forecast
time can differ or depart from the mean behaviour of the observed data over the
same time period, a phenomenon also known as **drift**.  
It is hence a standard practice in climate forecast verification to compare 
only the deviations of the experimental data and observed data from the mean 
behaviour along the forecast time. For this reason most of the functions in 
s2dverification use series of deviations as inputs and provide series of 
deviations as outputs.  

The mean behaviour along the forecast time of a data set is also known as the 
**climatology** and multiple methods exist to compute it. The deviation from 
the climatology is known as the **anomaly** or, more explicitly, 
drift-corrected anomaly, and it can be calculated by simply subtracting the 
climatology of a data set to its raw data.

A general purpose climatology could be computed as follows:
```r
clim_exp <- apply(data$mod, dim(data$mod)[-3], mean, na.rm = TRUE)
```
or with the function `Mean1Dim()` in s2dverification:
```r
clim_exp <- Mean1Dim(data$mod, 3)
```

s2dverification, however, builds upon the per-pair method to compute 
climatologies. It is implemented in the function `Clim()`.  
Its parameters `kharin` and `NDV` allow to select two other more refined 
methods: the trend method and the initial-conditions method. All of them are 
documented in
```
Fučkar N, Volpi D, Guemas V, Doblas-Reyes F, 2014, A posteriori adjustment of near-term climate predictions: Accounting for the drift dependence on the initial conditions. Geophysical Research Letters, 41 (14), 5200–5207, doi:10.1002/2014GL060815
```
Following the per-pair method, the climatology of an experimental dataset is 
obtained by calculating an average across the starting dates at each forecast 
time, yielding a time series defined along the forecast times of the 
experiment. The climatology of an observational dataset is obtained by 
computing, for each forecast time, the average of the observations that 
date-correspond that leadtime of each starting date.  
To make easy this process, `Load()` arranges both experimental and 
observational data in a forecast-like arrangement.

`Clim()` and the per-pair method only account, at each forecast time, for the 
starting dates for which data is available in all the experimental and 
observational datasets, hence both experimental and observational data must be
provided as inputs:

```r
clim <- Clim(data$mod, data$obs)
```

The raw data and the climatologies can be visualized with `PlotAno()` and 
`PlotClim()`, respectively:
```r
selected_sdates <- gsub('1101', '1201', sdates)
PlotAno(data$mod, data$obs, selected_sdates, 
        toptitle = paste0(c("Experiment A", "Experiment B"), 
                          ": Raw 'tas' over Atlantic region."), 
        ytitle = c("K", "K"), 
        fileout = paste0("stat_raw_exp", c("A", "B"), "_obsX.eps")) 
PlotClim(clim$clim_exp, clim$clim_obs, monini = 12,
         toptitle = "Per-pair 'tas' climatologies over the Atlantic region.", 
         ytitle = "K",
         listexp = c('Experiment A', 'Experiment B'),
         listobs = c('Observation X'),
         fileout = "stat_clim_expA_expB_obsX.eps")
```
<img src="stat_raw_expA_obsX.png" width="600" />
<img src="stat_raw_expB_obsX.png" width="600" /> 
<img src="stat_clim_expA_expB_obsX.png" width="600" /> 

Each plot in the `Clim()` figure corresponds to the climatology of a member of 
the corresponding experiment or observation. Usually if working with 
atmospheric variables, it is not relevant when computing climatologies to make 
a distinction among members because they are considered to be equivalent. It 
is possible, after seeing they are indeed equivalent, to compute the ensemble
mean climatology with
```r
exp_ens_clim <- Mean1Dim(clim$clim_exp, 2)
obs_ens_clim <- Mean1Dim(clim$clim_obs, 2)
```
or, if sure of their equivalence, by setting the parameter `memb = FALSE` in
`Clim()`: 
```r
clim <- Clim(data$mod, data$obs, memb = FALSE)
```

If working with oceanic variables this may not necessarly apply. See
```
Du, H., F.J. Doblas-Reyes, J. García-Serrano, V. Guemas, Y. Soufflet and B. Wouters (2012). Sensitivity of decadal predictions to the initial atmospheric and oceanic perturbations. Climate Dynamics, 39, 2013-2023, doi:10.1007/s00382-011-1285-9. http://link.springer.com/article/10.1007%2Fs00382-011-1285-9 Fig 2d is a very good example. If only one climatology is used for this variable, the skill is substantially lower.
```

Once the climatologies are computed, the anomalies can be obtained with 
`Ano()`, that subtracts the climatologies to each member, starting date,
latitude and longitude of their corresponding dataset:
```r  
ano_exp <- Ano(data$mod, clim$clim_exp)
ano_obs <- Ano(data$obs, clim$clim_obs)
PlotAno(ano_exp, ano_obs, selected_sdates,
        toptitle = paste0(c("Experiment A", "Experiment B"),
                          ": drift-corrected 'tas' anomalies over Atlantic region."),
        ytitle = c("K", "K"), linezero = TRUE,
        fileout = paste0("stat_ano_exp", c("A", "B"), "_obsX.eps")) 
```
<img src="stat_ano_expA_obsX.png" width="600" />
<img src="stat_ano_expB_obsX.png" width="600" /> 

All the starting dates of an experiment contribute to the per-pair climatology 
and, when the anomaly of that starting date, its contribution to the 
climatology is subtracted, which can imply a loss of information [citation]. 
To avoid this, the function `Ano_CrossValid()` automatically computes a 
climatology for each starting date without taking that starting date and 
subtracts it to the original data:
```r
ano <- Ano_Crossvalid(data$mod, data$obs, memb = FALSE)
```

To fulfill the bias correction of the forecasts, i.e. transforming the forecast
data from the biased model mean state to the real observed mean state, the 
climatology of the observation has to be added to the anomalies of the 
forecasts. Since the score functions take anomalies as working units this step 
won't be needed for verification.

### Detrending data
Trend, Consist_Trend, Regression

### Frequency filtering
Smoothing, Spectrum, Filter

Describing signals<a name="describing"></a>
------------------

### Linear trend


### Frequency spectrum


### Autocorrelation
Knowing whether a field is time-correlated with itself is a crucial step to 
determine whether the size of the sample is large enough to yield a robust 
validation. It is also useful to build synthetic models with the same time 
correlation behaviour as another.  
The function `Alpha()` serves to compute the best estimate of the 
autocorrelation of a signal at 1 time-step lag. Knowing the best estimate 
is needed to __________.  

`Alpha()` has two parameters to enable linear detrending and/or filtering of 
frequency peaks, convenient if ___________.

Assuming we have followed the same data retrieval process as in the 
[**Example**](example.md), we can calculate the best estimate of 
autocorrelation at lag 1 of the bias-corrected, detrended, observed anomalies 
as follows:
```r
clim <- Clim(data$mod, data$exp)
ano <- Ano(clim$clim_exp, clim$clim_obs)
autocorr <- Alpha(ano$obs[1, 1, , 1], detrend = TRUE)
```
Internally, `Alpha()` calls `FitAcfCoef()`. `FitAcfCoef()` computes the 
autocorrelation from the first estimates of the autocorrelation at lags 1 and 
2, that can be obtained providing the original time series to the R built-in 
function `acf()`:
```r
estacf <- acf(ano$obs[1, 1, , 1], plot = FALSE)$acf
autocorr <- FitAcfCoef(max(estacf[2], 0), max(estacf[3], 0))
```  
`FitAutocor()` estimates the autocorrelation from the first autocorrelation 
estimate and a window where to seek in with a dichotomial method.
```r
estacf <- acf(ano$obs[1, 1, , 1], plot = FALSE)$acf
autocorr <-  FitAutocor(estacf, c(-1, 1), 0.01)
```

Generating derived fields<a name="generating_der"></a>
-------------------------

Seasonal means
Season
Should this go to data retrieval?

Cathegorizing data
ProbBins

Statistical downscaling
StatSeasAtlHurr

Generating new fields<a name="generating_new"></a>
---------------------

Empirical models
GenSeries, Toymodel, Eno, EnoNew

