Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DQM: Specificities in Xclim vs. (Cannon,2016)'s description #1837

Open
1 task done
coxipi opened this issue Jul 11, 2024 · 0 comments
Open
1 task done

DQM: Specificities in Xclim vs. (Cannon,2016)'s description #1837

coxipi opened this issue Jul 11, 2024 · 0 comments

Comments

@coxipi
Copy link
Contributor

coxipi commented Jul 11, 2024

Generic Issue

  • xclim version: 0.51.0
  • Python version:
  • Operating System:

Description

I want to underline differences between our implementation in Xclim and the method by Cannon as described in the 2016 paper. In the end, I don't think that this has important consequences for the results, but I think it's worth explaining what I've done.

Let

  • $X$ be a simulation, $Y$ a reference dataset;
  • $X^h,Y^h$ be the datasets in a historical training period.
  • $\overline{X}^T$ is the trend of a field $X_t$ centered on time $t$ (a rolling mean 15 years before/after $t$). Previous fields should also have a subscript $t$ but I only write here for clarity. The $T$ stands for trend, I really want to underline there is still a time dependance (smoothening over 30 years with a rolling window). If I write simply $\overline{X}$, then it's a mean, all points in the time series are taken, time dependance is lost.

For instance, in the Quantile Mapping method, we use $X^h, Y^h$, find a transfer function that computes adjustment factors $A_{QM(X^h, Y^h)}$ and apply this to $X$

$$X_{QM}^{\prime} = X + A_{QM(X^h, Y^h)}(X)$$

For the scaling transformation, we simply have a constant factor added
$$X_{Scaling}^{\prime} = X + A_{Scaling(X^h, Y^h)}$$

DQM Xclim

$$\begin{aligned} X_{1}&=X+A_{\text{Scaling}(X^{h},Y^{h})} \\\ X_{2}&=X_{1}- \overline{X_1}^T \\\ X_{3}&=X_{2}+A_{\text{QM}(X^{h}-\bar{X^{h}} ,Y^{h}-\bar{Y^{h}})}(X_{2}) \\\ X_{\text{BC}}&=X_{3} + \overline{X_1}^T \end{aligned}$$

DQM Cannon

$$\begin{aligned} X_{1}&=X- \overline{X}^T + \overline{X^{h}} \\\ X_{2}&=X_{1}+A_{\text{QM}(X^{h} ,Y^{h})}(X_{1}) \\\ X_{\text{BC}}&=X_{2} + \overline{X}^T - \overline{X^{h}} \end{aligned}$$

What I Did

I programmed Cannon's method to see the differences. In the training, I simply reused eqm_train, and instead of computing scale, I compute mu_hist = hist.mean(dim=dim). Then in the adjustment, I corrected the detrend sim with mu_hist as I would have done for scale in our DQM implementation:

    ds["sim"] = detrending.detrend(sim) 
    ds["sim"] = u.apply_correction(
        ds.sim,
        u.broadcast(
            mu_hist,
            ds.sim,
            group=group,
            interp=interp if group.prop != "dayofyear" else "nearest",
        ),
        kind,
    )

Here is a test:

ref = open_dataset("sdba/CanESM2_1950-2100.nc").tasmax.isel(location=0)
sim = open_dataset("sdba/ahccd_1950-2013.nc").tasmax.isel(location=0)
ref, hist = [da.sel(time=slice("1981","2010")) for da in [ref,sim]]
group = sdba.Grouper("time.dayofyear", 31)
ref = xclim.core.units.convert_units_to(ref,sim) # I want K
scenC = sdba.DetrendedQuantileMappingC.train(ref=ref,hist=hist, group=group).adjust(sim=sim)
scenX = sdba.DetrendedQuantileMapping.train(ref=ref,hist=hist, group=group).adjust(sim=sim)

The climatological means over each days of year (in the historical period) are very similar
image

Looking a time series, the differences are smaller that scen - sim but still not negligible:
image

Other thoughts

A possible alternative implementation could be to work with detrended fields in the training period:

DQM Xclim - alternate

$$\begin{aligned} X_{1}&=X+A_{\text{Scaling}(X^{h},Y^{h})} \\\ X_{2}&=X_{1}- \overline{X_1}^T \\\ X_{3}&=X_{2}+A_{\text{QM}(X^{h}-\bar{X^{h}}^T ,Y^{h}-\bar{Y^{h}}^T)}(X_{2}) \\\ X_{\text{BC}}&=X_{3} + \overline{X_1}^T \end{aligned}$$

Code of Conduct

  • I agree to follow this project's Code of Conduct
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant