Repository: Ouranosinc/xclim
Pull request #50 (2018-10-02 18:45:19)

Rx1day
Added RX1day index to indices.py added tests to test_indices.py

tlogan2000: @Zeitsperre : Not exactly sure what to do with the first commit (test data stuff) ... left over from left week 
codecov[bot]: # [Codecov](https://codecov.io/gh/Ouranosinc/xclim/pull/50?src=pr&el=h1) Report
> Merging [#50](https://codecov.io/gh/Ouranosinc/xclim/pull/50?src=pr&el=desc) into [master](https://codecov.io/gh/Ouranosinc/xclim/commit/6badf8db415a0509aa0e1ad50a9289841022bb37?src=pr&el=desc) will **increase** coverage by `1.23%`.
> The diff coverage is `89.18%`.

[![Impacted file tree graph](https://codecov.io/gh/Ouranosinc/xclim/pull/50/graphs/tree.svg?width=650&token=1clOxQaUPR&height=150&src=pr)](https://codecov.io/gh/Ouranosinc/xclim/pull/50?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master      #50      +/-   ##
==========================================
+ Coverage   58.64%   59.88%   +1.23%     
==========================================
  Files           6        6              
  Lines         324      334      +10     
==========================================
+ Hits          190      200      +10     
  Misses        134      134
```


| [Impacted Files](https://codecov.io/gh/Ouranosinc/xclim/pull/50?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [xclim/stats.py](https://codecov.io/gh/Ouranosinc/xclim/pull/50/diff?src=pr&el=tree#diff-eGNsaW0vc3RhdHMucHk=) | `0% <ø> (ø)` | :arrow_up: |
| [xclim/indices.py](https://codecov.io/gh/Ouranosinc/xclim/pull/50/diff?src=pr&el=tree#diff-eGNsaW0vaW5kaWNlcy5weQ==) | `60% <70%> (+2.5%)` | :arrow_up: |
| [xclim/utils.py](https://codecov.io/gh/Ouranosinc/xclim/pull/50/diff?src=pr&el=tree#diff-eGNsaW0vdXRpbHMucHk=) | `96.29% <96.29%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Ouranosinc/xclim/pull/50?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Ouranosinc/xclim/pull/50?src=pr&el=footer). Last update [6badf8d...1779151](https://codecov.io/gh/Ouranosinc/xclim/pull/50?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

Zeitsperre: Commit reverted. This shouldn't delete anything that's currently added to master.
coveralls: ## Pull Request Test Coverage Report for [Build 126](https://coveralls.io/builds/19309655)

* **9** of **9**   **(100.0%)**  changed or added relevant lines in **1** file are covered.
* **49** unchanged lines in **1** file lost coverage.
* Overall coverage increased (+**1.2%**) to **59.88%**

---


|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [xclim/indices.py](https://coveralls.io/builds/19309655/source?filename=xclim%2Findices.py#L77) | 49 | 60.0% |
<!-- | **Total:** | **49** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/19309655/badge)](https://coveralls.io/builds/19309655) |
| :-- | --: |
| Change from base [Build 123](https://coveralls.io/builds/19307461): |  1.2% |
| Covered Lines: | 200 |
| Relevant Lines: | 334 |

---
##### 💛  - [Coveralls](https://coveralls.io)

coveralls: ## Pull Request Test Coverage Report for [Build 126](https://coveralls.io/builds/19309655)

* **9** of **9**   **(100.0%)**  changed or added relevant lines in **1** file are covered.
* **49** unchanged lines in **1** file lost coverage.
* Overall coverage increased (+**1.2%**) to **59.88%**

---


|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [xclim/indices.py](https://coveralls.io/builds/19309655/source?filename=xclim%2Findices.py#L77) | 49 | 60.0% |
<!-- | **Total:** | **49** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/19309655/badge)](https://coveralls.io/builds/19309655) |
| :-- | --: |
| Change from base [Build 123](https://coveralls.io/builds/19307461): |  1.2% |
| Covered Lines: | 200 |
| Relevant Lines: | 334 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/xclim/indices.py b/xclim/indices.py
index 393cdbbf..18c3d007 100644
--- a/xclim/indices.py
+++ b/xclim/indices.py
@@ -9,7 +9,11 @@ import xarray as xr
 
 from . import run_length as rl
 from .checks import valid_daily_mean_temperature, valid_daily_max_min_temperature, valid_daily_min_temperature, \
-    valid_daily_max_temperature, valid_daily_mean_discharge  # , assert_daily
+    valid_daily_max_temperature, valid_daily_mean_discharge
+from .utils import daily_downsampler as dds
+
+xr.set_options(enable_cftimeindex=True)  # Set xarray to use cftimeindex
+
 
 # Frequencies : YS: year start, QS-DEC: seasons starting in december, MS: month start
 # See http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
@@ -466,6 +470,55 @@ def tn_min(tasmin, freq='YS'):
     return tasmin.resample(time=freq).min(dim='time')
 
 
+# @check_daily_monotonic # TODO create daily timestep check
+# @convert_precip_units   # TODO create units checker / converter
+def max_1day_precipitation_amount(da, freq='YS'):
+    """Highest 1-day precipitation amount for a period (frequency).
+
+    Resample the original daily total precipitaiton temperature series by taking the max over each period.
+
+    Parameters
+    ----------
+    pr : xarray.DataArray
+      daily precipitation values.
+    freq : str, optional
+      Resampling frequency one of : 'YS' (yearly) ,'M' (monthly), or 'QS-DEC' (seasonal - quarters starting in december)
+
+
+    Returns
+    -------
+    xarray.DataArray
+      The highest 1-day precipitation value at the given time frequency.
+
+
+    Examples
+    --------
+    The following would compute for each grid cell of file `pr.day.nc` the highest 1-day total
+    at an annual frequency.
+
+    >>> pr = xr.open_dataset('pr.day.nc')
+    >>> rx1day = max_1day_precipitation_amount(pr, freq="YS")
+
+    """
+
+    # resample the values
+    # arr = da.resample(time=freq,keep_attrs=True)
+    # Get max value for each period
+    # output1 = arr.max(dim='time')
+
+    # use custom resample function for now
+    grouper = dds(da, freq=freq)
+    output = grouper.max(dim='time', keep_attrs=True)
+
+    # add time coords to output and change dimension tags to time
+    time1 = dds(da.time, freq=freq).first()
+    output.coords['time'] = ('tags', time1.values)
+    output = output.swap_dims({'tags': 'time'})
+    output = output.sortby('time')
+
+    return output
+
+
 # @check_is_dataarray
 def prcp_tot(pr, freq='YS', units='kg m-2 s-1'):
     r"""Accumulated total (liquid + solid) precipitation


Test patch:
diff --git a/tests/test_indices.py b/tests/test_indices.py
index 45310ff3..d4266ea6 100644
--- a/tests/test_indices.py
+++ b/tests/test_indices.py
@@ -28,11 +28,46 @@ import xarray as xr
 
 import xclim.indices as xci
 
+xr.set_options(enable_cftimeindex=True)
+
 TESTS_HOME = os.path.abspath(os.path.dirname(__file__))
 TESTS_DATA = os.path.join(TESTS_HOME, 'testdata')
 K2C = 273.15
 
 
+class Test_max_1day_precipitation_amount():
+
+    def time_series(self, values):
+        coords = pd.date_range('7/1/2000', periods=len(values), freq=pd.DateOffset(days=1))
+        return xr.DataArray(values, coords=[coords, ], dims='time',
+                            attrs={'standard_name': 'precipitation_flux',
+                                   'cell_methods': 'time: sum (interval: 1 day)',
+                                   'units': 'mm'})
+
+    # test max precip
+    def test_single_max(self):
+        a = self.time_series(np.array([3, 4, 20, 0, 0]))
+        rx1day = xci.max_1day_precipitation_amount(a)
+        assert rx1day == 20
+        assert rx1day.time.dt.year == 2000
+
+    # test whether repeated maxes are resolved
+    def test_multi_max(self):
+        a = self.time_series(np.array([20, 4, 20, 20, 0]))
+        rx1day = xci.max_1day_precipitation_amount(a)
+        assert rx1day == 20
+        assert rx1day.time.dt.year == 2000
+        assert len(rx1day) == 1
+
+    # test whether uniform maxes are resolved
+    def test_uniform_max(self):
+        a = self.time_series(np.array([20, 20, 20, 20, 20]))
+        rx1day = xci.max_1day_precipitation_amount(a)
+        assert rx1day == 20
+        assert rx1day.time.dt.year == 2000
+        assert len(rx1day) == 1
+
+
 class Test_consecutive_frost_days():
     def time_series(self, values):
         coords = pd.date_range('7/1/2000', periods=len(values), freq=pd.DateOffset(days=1))