-
Notifications
You must be signed in to change notification settings - Fork 61
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
Correctly interpolate seasons in Grouper #2019
Conversation
I just realised that the factor of 1/6 is assuming that all seasons have the same length which in gregorian calendars is not necessarily true but I am not sure it matters too much at least the function should be smooth. |
Warning This Pull Request is coming from a fork and must be manually tagged |
Weirdly and contrary to what I showed yesterday, today I am still getting clear transitions as if there still wasn't any linear interpolation. |
@saschahofmann We recently changed the layout of xclim to use a |
I reinstalled xclim but I am still getting very similar results to before the "fix". You have any advice on where else I could look? |
Could it be that you have obsolete |
I managed to install the environment, for some reason I only had the branch "main" when I cloned the fork yesterday
import inspect
print(inspect.getsource(sdba.base.Grouper.get_index))
I'll try to have look later. Maybe the |
I am pretty sure that the |
It's simply from xclim import sdba
QM = sdba.EmpiricalQuantileMapping.train(
ref, hist, nquantiles=15, group="time.season", kind="+"
)
scen = QM.adjust(sim, extrapolation="constant", interp="nearest")
scen_interp = QM.adjust(sim, extrapolation="constant", interp="linear")
outd = {
"Reference":ref,
"Model - biased":hist,
"Model - adjusted - no interp":scen,
"Model - adjusted - linear interp":scen_interp,
}
for k,da in outd.items():
da.groupby("time.dayofyear").mean().plot(label=k)
plt.legend() This doesn't reproduce your figure however. It seems your figure above was matching the reference very well, better than what I have even with the linear interpolation. But it does get rid of obvious discontinuities. |
@coxipi I think only mention this in the original issue: my analysis is done with |
Yes, I have seen simlilar things by playing with the choice of how |
@Zeitsperre I added these two lines to allow linear interpolation with It was failing in a test |
I'm going to defer to @coxipi or @aulemahal here. This is a bit out of my depth haha |
I don't think there would be a point in doing linear interpolation for dayofyear. We have adjusting factors for each dayofyear, so we don't have in-between values where we need to interpolate the training data. I would say we probably need to change the failing test, let me see I don't see the failing, can you point to a specific commit? |
Yes. Its this test TestExtremeValues.test_real_data: https://github.com/Ouranosinc/xclim/actions/runs/12985440090/job/36210393696 I fixed it by allowing again linear interp of dayofyear. I think it was allowed previously but I slightly restructured the code so now by default it was disabled. |
I reverted the change that allows linear interp with dayofyear grouping and instead changed the test to use nearest |
@coxipi I think maybe reenabling linear interpolation from dayofyear for now is a better solution. Since otherwise it represents a breaking change, e.g. right now the tutorial does some similar (hence the breaking test in sdba-advanced.ipynb) where we do EQM with dayofyer with linear interp. Instead I could add a deprecation warning for maybe 0.57.0? |
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
for more information, see https://pre-commit.ci
@aulemahal or @coxipi . Would love to get this over the line I think if you agree I add a DeprecationWarning and then ready to merge? |
Hi @saschahofmann sorry for the late response, we were busy with a seminar last week and I missed your message One thing I'm starting to realize is that the linear interpolation can act on two fronts, on the grouping dimension (e.g. season, month) but also on the quantiles, I forgot to take this into account in my last comment. We really want to leave open the possibility of linear interpolation on quantiles I think. If you want to leave things as they were in the most economical way possible (if you need to deactivate a test, go for it), I really think this is beyond the scope of your PR anyways, you fixed many things indepently of this. I can take care of this in another PR. No need for deprecation warning, we will just fix this @aulemahal, I think that in def interp_on_quantiles(
...
if prop in ["group", "dayofyear"]:
if prop =="group":
if "group" in xq.dims:
xq = xq.squeeze("group", drop=True)
if "group" in yq.dims:
yq = yq.squeeze("group", drop=True)
out = xr.apply_ufunc(
_interp_on_quantiles_1D,
... |
I guess we can merge then 😬 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just commenting so I can commit my suggestion
Feel free to merge when it becomes possible again, we're just waiting on tests |
I dont have write access so cant merge |
Ah, right. Thanks again for your nice contribution! |
Hello, group = sdba.Grouper("time.dayofyear", window=31)
|
Hi Sylvain, MBCn with In this case of {ref1w31_q01, ref1w31_q03, ... , ref1w31_q99} Compute adjustment factors from those Then the linear interpolation gives you a continuous function of the adjustment factors: In the particular case of day of year grouping, no more interpolation is needed, we have adjustment factors af1 for sim1, af2 for sim2, af3 for sim3, etc. When working with seasons, we have less adjustments factors, instead of af1,af2, ... af365, we only have afDJF, afMAM, afJJA, afSON. But we would still like to have distinct adjustment factors for each dayofyear, so apply different adjustment to sim1, sim2, ... sim365. To achieve this, we interpolate the results between seasons {afDJF, afMAM, afJJA, afSON}. So in this sense, there is also an interpolation on the grouping dimension, not only on quantiles. My description of what is done is not exact, because the two-fold interpolation on quantiles and season is done in one step, but I think it still schematizes well what is happening. Hope this clears this up! Éric |
Hello Éric, |
Pull Request Checklist:
number
) and pull request (:pull:number
) has been addedWhat kind of change does this PR introduce?
This PR adds a line to correctly interpolate seasonal values. It also changes the test_timeseries function that now accepts a
calendar
argument instead ofcftime
. Not providing it or providingNone
is equivalent tocftime=False
andcalendar='standard
to the previouscftime=True
. This allows for testing different calendar implementations e.g. 360_day calendars