├── .github └── workflows │ └── documentation.yaml ├── .gitignore ├── LICENSE ├── README.md ├── TOSSH_code ├── calculation_functions │ ├── calc_Addor.m │ ├── calc_All.m │ ├── calc_BasicSet.m │ ├── calc_Euser.m │ ├── calc_McMillan_Groundwater.m │ ├── calc_McMillan_OverlandFlow.m │ └── calc_Sawicz.m ├── signature_functions │ ├── sig_Autocorrelation.m │ ├── sig_BFI.m │ ├── sig_BaseflowMagnitude.m │ ├── sig_BaseflowRecessionK.m │ ├── sig_EventGraphThresholds.m │ ├── sig_EventRR.m │ ├── sig_FDC.m │ ├── sig_FDC_slope.m │ ├── sig_FlashinessIndex.m │ ├── sig_HFD_mean.m │ ├── sig_HFI_mean.m │ ├── sig_MRC_SlopeChanges.m │ ├── sig_PQ_Curve.m │ ├── sig_PeakDistribution.m │ ├── sig_QP_elasticity.m │ ├── sig_Q_CoV.m │ ├── sig_Q_mean.m │ ├── sig_Q_mean_monthly.m │ ├── sig_Q_n_day_max.m │ ├── sig_Q_n_day_min.m │ ├── sig_Q_skew.m │ ├── sig_Q_var.m │ ├── sig_RR_Seasonality.m │ ├── sig_RecessionAnalysis.m │ ├── sig_RecessionParts.m │ ├── sig_RecessionUniqueness.m │ ├── sig_ResponseTime.m │ ├── sig_RisingLimbDensity.m │ ├── sig_SeasonalTranslation.m │ ├── sig_SeasonalVarRecessions.m │ ├── sig_SnowDayRatio.m │ ├── sig_SnowStorage.m │ ├── sig_StorageFraction.m │ ├── sig_StorageFromBaseflow.m │ ├── sig_TemplateAdvanced.m │ ├── sig_TemplateBasic.m │ ├── sig_TotalRR.m │ ├── sig_VariabilityIndex.m │ ├── sig_x_Q_duration.m │ ├── sig_x_Q_frequency.m │ └── sig_x_percentile.m └── utility_functions │ ├── nanxcov.m │ ├── util_AggregateTimeSeries.m │ ├── util_AverageYear.m │ ├── util_DataCheck.m │ ├── util_EventSeparation.m │ ├── util_ExtractSubPeriod.m │ ├── util_FitBrokenStick.m │ ├── util_FitExponential.m │ ├── util_FitLinear.m │ ├── util_FitPowerLaw.m │ ├── util_FitSineCurve.m │ ├── util_LyneHollickFilter.m │ ├── util_MasterRecessionCurve.m │ ├── util_RecessionSegments.m │ ├── util_RisingLimbs.m │ ├── util_StorageAndAET.m │ ├── util_Threshold.m │ ├── util_UKIH_Method.m │ ├── util_WaterYear.m │ └── util_dQdt.m ├── docs ├── Makefile ├── _static │ ├── README_example_data.txt │ ├── addor.csv │ ├── basic_set.csv │ ├── custom.css │ ├── euser.csv │ ├── groundwater.csv │ ├── images │ │ ├── FDC_example.png │ │ ├── SDSUprimary3Crgb.png │ │ ├── TOSSH_logo.svg │ │ ├── hydrograph_example.png │ │ ├── logo-full-colour.png │ │ └── toolbox_structure.png │ ├── matlab │ │ ├── TOSSH_code │ │ │ ├── TOSSH │ │ │ │ └── TOSSH_code │ │ │ │ │ ├── calculation_functions │ │ │ │ │ ├── calc_Addor.html │ │ │ │ │ ├── calc_All.html │ │ │ │ │ ├── calc_BasicSet.html │ │ │ │ │ ├── calc_Euser.html │ │ │ │ │ ├── calc_McMillan_Groundwater.html │ │ │ │ │ ├── calc_McMillan_OverlandFlow.html │ │ │ │ │ ├── calc_Sawicz.html │ │ │ │ │ └── index.html │ │ │ │ │ ├── signature_functions │ │ │ │ │ ├── index.html │ │ │ │ │ ├── sig_Autocorrelation.html │ │ │ │ │ ├── sig_BFI.html │ │ │ │ │ ├── sig_BaseflowMagnitude.html │ │ │ │ │ ├── sig_BaseflowRecessionK.html │ │ │ │ │ ├── sig_EventGraphThresholds.html │ │ │ │ │ ├── sig_EventRR.html │ │ │ │ │ ├── sig_FDC.html │ │ │ │ │ ├── sig_FDC_slope.html │ │ │ │ │ ├── sig_FlashinessIndex.html │ │ │ │ │ ├── sig_HFD_mean.html │ │ │ │ │ ├── sig_HFI_mean.html │ │ │ │ │ ├── sig_MRC_SlopeChanges.html │ │ │ │ │ ├── sig_PQ_Curve.html │ │ │ │ │ ├── sig_PeakDistribution.html │ │ │ │ │ ├── sig_QP_elasticity.html │ │ │ │ │ ├── sig_Q_CoV.html │ │ │ │ │ ├── sig_Q_mean.html │ │ │ │ │ ├── sig_Q_mean_monthly.html │ │ │ │ │ ├── sig_Q_n_day_max.html │ │ │ │ │ ├── sig_Q_n_day_min.html │ │ │ │ │ ├── sig_Q_skew.html │ │ │ │ │ ├── sig_Q_var.html │ │ │ │ │ ├── sig_RR_Seasonality.html │ │ │ │ │ ├── sig_RecessionAnalysis.html │ │ │ │ │ ├── sig_RecessionParts.html │ │ │ │ │ ├── sig_RecessionUniqueness.html │ │ │ │ │ ├── sig_ResponseTime.html │ │ │ │ │ ├── sig_RisingLimbDensity.html │ │ │ │ │ ├── sig_SeasonalTranslation.html │ │ │ │ │ ├── sig_SeasonalVarRecessions.html │ │ │ │ │ ├── sig_SnowDayRatio.html │ │ │ │ │ ├── sig_SnowStorage.html │ │ │ │ │ ├── sig_StorageFraction.html │ │ │ │ │ ├── sig_StorageFromBaseflow.html │ │ │ │ │ ├── sig_TemplateAdvanced.html │ │ │ │ │ ├── sig_TemplateBasic.html │ │ │ │ │ ├── sig_TotalRR.html │ │ │ │ │ ├── sig_VariabilityIndex.html │ │ │ │ │ ├── sig_x_Q_duration.html │ │ │ │ │ ├── sig_x_Q_frequency.html │ │ │ │ │ └── sig_x_percentile.html │ │ │ │ │ └── utility_functions │ │ │ │ │ ├── index.html │ │ │ │ │ ├── nanxcov.html │ │ │ │ │ ├── util_AggregateTimeSeries.html │ │ │ │ │ ├── util_AverageYear.html │ │ │ │ │ ├── util_DataCheck.html │ │ │ │ │ ├── util_EventSeparation.html │ │ │ │ │ ├── util_ExtractSubPeriod.html │ │ │ │ │ ├── util_FitBrokenStick.html │ │ │ │ │ ├── util_FitExponential.html │ │ │ │ │ ├── util_FitLinear.html │ │ │ │ │ ├── util_FitPowerLaw.html │ │ │ │ │ ├── util_FitSineCurve.html │ │ │ │ │ ├── util_LyneHollickFilter.html │ │ │ │ │ ├── util_MasterRecessionCurve.html │ │ │ │ │ ├── util_RecessionSegments.html │ │ │ │ │ ├── util_RisingLimbs.html │ │ │ │ │ ├── util_StorageAndAET.html │ │ │ │ │ ├── util_Threshold.html │ │ │ │ │ ├── util_UKIH_Method.html │ │ │ │ │ ├── util_WaterYear.html │ │ │ │ │ └── util_dQdt.html │ │ │ ├── alpha.png │ │ │ ├── c++.png │ │ │ ├── c.png │ │ │ ├── demoicon.gif │ │ │ ├── down.png │ │ │ ├── doxysearch.php │ │ │ ├── fortran.png │ │ │ ├── hp.png │ │ │ ├── index.html │ │ │ ├── left.png │ │ │ ├── linux.png │ │ │ ├── m2html.css │ │ │ ├── matlabicon.gif │ │ │ ├── mex.png │ │ │ ├── pcode.png │ │ │ ├── right.png │ │ │ ├── sgi.png │ │ │ ├── simulinkicon.gif │ │ │ ├── solaris.png │ │ │ ├── up.png │ │ │ └── windows.png │ │ └── example │ │ │ ├── TOSSH │ │ │ └── example │ │ │ │ ├── functions │ │ │ │ ├── data_loading │ │ │ │ │ ├── index.html │ │ │ │ │ ├── loadCAMELSGBstruct.html │ │ │ │ │ ├── loadCAMELSstruct.html │ │ │ │ │ ├── loadCatchmentCAMELS.html │ │ │ │ │ └── loadCatchmentCAMELSGB.html │ │ │ │ └── plotting │ │ │ │ │ ├── index.html │ │ │ │ │ ├── makeScatterPlot.html │ │ │ │ │ ├── myupdatefcn.html │ │ │ │ │ ├── plotMapUK.html │ │ │ │ │ ├── plotMapUS.html │ │ │ │ │ └── saveFig.html │ │ │ │ ├── index.html │ │ │ │ ├── workflow_1_basic.html │ │ │ │ ├── workflow_2_advanced.html │ │ │ │ ├── workflow_3_time_resolution.html │ │ │ │ ├── workflow_4_CAMELS_US.html │ │ │ │ └── workflow_5_CAMELS_GB.html │ │ │ ├── alpha.png │ │ │ ├── c++.png │ │ │ ├── c.png │ │ │ ├── demoicon.gif │ │ │ ├── down.png │ │ │ ├── doxysearch.php │ │ │ ├── fortran.png │ │ │ ├── hp.png │ │ │ ├── index.html │ │ │ ├── left.png │ │ │ ├── linux.png │ │ │ ├── m2html.css │ │ │ ├── matlabicon.gif │ │ │ ├── mex.png │ │ │ ├── pcode.png │ │ │ ├── right.png │ │ │ ├── sgi.png │ │ │ ├── simulinkicon.gif │ │ │ ├── solaris.png │ │ │ ├── up.png │ │ │ └── windows.png │ ├── overland_flow.csv │ ├── overland_flow_Wu.csv │ ├── remaining_signatures.csv │ ├── sawicz.csv │ └── usages │ │ ├── params_overlandflow.csv │ │ ├── params_recession.csv │ │ └── ws_code.csv ├── code │ ├── Code_documentation.m │ └── Matlab_toolboxes.m ├── conf.py ├── index.rst ├── make.bat ├── p1_overview.rst ├── p2_signatures.rst ├── p3_examples.rst ├── p4_usage_notes.rst └── p5_contact.rst └── example ├── example_data ├── 33029_daily.csv ├── 33029_daily.mat ├── 33029_multiple.mat ├── 39020_daily.mat ├── 73014_daily.mat └── README_example_data.txt ├── functions ├── __init__.py ├── data_loading │ ├── loadCAMELSGBstruct.m │ ├── loadCAMELSstruct.m │ ├── loadCatchmentCAMELS.m │ └── loadCatchmentCAMELSGB.m ├── helper_TOSSH_with_python.py └── plotting │ ├── Shapefiles │ ├── great_britain_50m.cpg │ ├── great_britain_50m.dbf │ ├── great_britain_50m.prj │ ├── great_britain_50m.sbn │ ├── great_britain_50m.sbx │ ├── great_britain_50m.shp │ ├── great_britain_50m.shx │ ├── united_kingdom_50m.cpg │ ├── united_kingdom_50m.dbf │ ├── united_kingdom_50m.prj │ ├── united_kingdom_50m.sbn │ ├── united_kingdom_50m.sbx │ ├── united_kingdom_50m.shp │ └── united_kingdom_50m.shx │ ├── makeScatterPlot.m │ ├── myupdatefcn.m │ ├── plotMapUK.m │ ├── plotMapUS.m │ └── saveFig.m ├── results ├── CAMELS_GB_signatures.mat ├── CAMELS_GB_signatures.txt ├── CAMELS_signatures.mat ├── CAMELS_signatures.txt ├── README.md └── images │ ├── TOSSH_scatter_plot_GB.pdf │ ├── TOSSH_scatter_plot_US.pdf │ ├── map_UK_EventRR.png │ ├── map_UK_RecessionK.png │ └── map_UK_Recession_exponent.png ├── workflow_1_basic.m ├── workflow_2_advanced.m ├── workflow_3_time_resolution.m ├── workflow_4_CAMELS_US.m ├── workflow_5_CAMELS_GB.m └── workflow_TOSSH_with_Python.py /.github/workflows/documentation.yaml: -------------------------------------------------------------------------------- 1 | name: docs 2 | on: [push, pull_request] 3 | permissions: 4 | contents: write 5 | jobs: 6 | docs: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: actions/setup-python@v3 11 | - name: Install dependencies 12 | run: | 13 | pip install sphinx sphinx_rtd_theme 14 | - name: Sphinx build 15 | run: | 16 | sphinx-build docs _build 17 | - name: Deploy 18 | uses: peaceiris/actions-gh-pages@v3 19 | if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} 20 | with: 21 | publish_branch: gh-pages 22 | github_token: ${{ secrets.GITHUB_TOKEN }} 23 | publish_dir: _build 24 | force_orphan: true 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | site/ 3 | docs/_site/ 4 | docs/.jekyll-cache/ 5 | docs/Gemfile 6 | docs/Gemfile.lock 7 | *.asv 8 | docs/markdown_misc 9 | signature_test_script_old 10 | # example/results/*.mat 11 | .jekyll-cache/ 12 | example/example_data/CAMELS_v2.0 13 | example/example_data/CAMELS_GB 14 | example/example_data/old 15 | old/ 16 | example/results/CAMELS_GB_TOSSH_signatures.mat 17 | example/results/CAMELS_TOSSH_signatures.mat 18 | _build/ 19 | main_test.m 20 | log.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TOSSH logo 2 | 3 | 4 | [![GitHub license](https://img.shields.io/badge/license-GPLv3-blue.svg)](https://github.com/TOSSHtoolbox/TOSSH/blob/master/LICENSE) 5 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4313275.svg)](https://doi.org/10.5281/zenodo.4313275) 6 | 7 | 8 | This repository contains TOSSH: A Toolbox for Streamflow Signatures in Hydrology (Gnann et al., 2021). 9 | TOSSH is a Matlab toolbox that provides accessible, standardised signature calculations, with clear information on methodological decisions and recommended parameter values. 10 | The online documentation for TOSSH can be found here: . 11 | 12 | 13 | ## Contact 14 | If you have any questions or feedback, or if you spotted an error or bug, please create an issue on Github 15 | (https://github.com/TOSSHtoolbox/TOSSH/issues). 16 | Alternatively, email Hilary McMillan () or Sebastian Gnann (). 17 | 18 | 19 | ## Download 20 | 21 | 22 | 23 | ## Acknowledgements 24 | Thanks to Yves Tramblay for providing helpful feedback. 25 | 26 | Extensive feedback, edits, and usage notes have also been provided by Ryoko Araki. 27 | 28 | 29 | ## Credits 30 | Gnann, S.J., Coxon, G., Woods, R.A., Howden, N.J.K., McMillan H.K., 2021. TOSSH: A Toolbox for Streamflow Signatures in Hydrology. Environmental Modelling & Software. 31 | 32 | 33 | 34 | ## License 35 | This software is distributed under the GNU Public License Version 3. 36 | See https://www.gnu.org/licenses/gpl-3.0.en.html for details. 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /TOSSH_code/calculation_functions/calc_Euser.m: -------------------------------------------------------------------------------- 1 | function [results] = calc_Euser(Q_mat, t_mat) 2 | %calc_Euser calculates signatures from Euser et al. (2013). 3 | % Euser et al. (2013) use 8 signatures that represent different aspects 4 | % of hydrological behaviour. The signatures are used to test the 5 | % consistency of model performance, within the FARM model evaluation 6 | % framework. 7 | % Some of the 8 signatures used in Euser et al. (2013) are the same but 8 | % applied to different parts of the time series, e.g. the low flow 9 | % period. There are two ways of doing this. We can either set all values 10 | % outside the chosen period to NaN, or we can remove them. The latter is 11 | % the default option here. Since this leads to gaps in the time series 12 | % which would raise a warning, we temporarily disable warnings. 13 | % 14 | % INPUT 15 | % Q_mat: streamflow [mm/timestep] matrix (cell array) 16 | % t_mat: time [Matlab datenum] matrix (cell array) 17 | % 18 | % OUTPUT 19 | % results: struc array with all results (each signature for each time 20 | % series and associated error strings) 21 | % 22 | % EXAMPLE 23 | % % load example data 24 | % data = load('example/example_data/33029_daily.mat'); 25 | % % create consistent cell arrays 26 | % Q_mat = {data.Q}; 27 | % t_mat = {data.t}; 28 | % results = calc_Euser(Q_mat,t_mat); 29 | % 30 | % References 31 | % Euser, T., Winsemius, H.C., Hrachowitz, M., Fenicia, F., Uhlenbrook, S. 32 | % and Savenije, H.H.G., 2013. A framework to assess the realism of model 33 | % structures using hydrological signatures. Hydrology and Earth System 34 | % Sciences, 17 (5), 2013. 35 | % 36 | % Copyright (C) 2020 37 | % This software is distributed under the GNU Public License Version 3. 38 | % See for details. 39 | 40 | % check input parameters 41 | if nargin < 2 42 | error('Not enough input arguments.') 43 | end 44 | 45 | ip = inputParser; 46 | ip.CaseSensitive = true; 47 | 48 | % required input arguments 49 | % Please input time series as a cell array of the following format: 50 | % {x_1; x_2; ...; x_n}, where each entry (1, 2, ..., n) corresponds to one 51 | % time series, e.g. from one catchment. For one catchment only, please 52 | % input {x}. Example: {Q_1; Q_2; ...; Q_n} for streamflow. 53 | addRequired(ip, 'Q_mat', @(Q_mat) iscell(Q_mat)) 54 | addRequired(ip, 't_mat', @(t_mat) iscell(t_mat)) 55 | 56 | parse(ip, Q_mat, t_mat) 57 | 58 | % initialise arrays 59 | AC1 = NaN(size(Q_mat,1),1); 60 | AC1_error_str = strings(size(Q_mat,1),1); 61 | AC1_low = NaN(size(Q_mat,1),1); % low flow season 62 | AC1_low_error_str = strings(size(Q_mat,1),1); 63 | RLD = NaN(size(Q_mat,1),1); 64 | RLD_error_str = strings(size(Q_mat,1),1); 65 | PeakDistribution = NaN(size(Q_mat,1),1); 66 | PeakDistribution_error_str = strings(size(Q_mat,1),1); 67 | PeakDistribution_low = NaN(size(Q_mat,1),1); % low flow season 68 | PeakDistribution_low_error_str = strings(size(Q_mat,1),1); 69 | FDC = cell(size(Q_mat,1),1); % they use the total FDC to evaluate models 70 | FDC_error_str = strings(size(Q_mat,1),1); 71 | FDC_low = cell(size(Q_mat,1),1); % low flow season 72 | FDC_low_error_str = strings(size(Q_mat,1),1); 73 | FDC_high = cell(size(Q_mat,1),1); % high flow season 74 | FDC_high_error_str = strings(size(Q_mat,1),1); 75 | 76 | low_flow_season = [5:9]; % May to September 77 | high_flow_season = [11:12, 1:4]; % November to April 78 | 79 | % loop over all catchments 80 | for i = 1:size(Q_mat,1) 81 | 82 | [Q_low, t_low] = ... 83 | util_ExtractSubPeriod(Q_mat{i}, t_mat{i}, low_flow_season); 84 | [Q_high, t_high] = ... 85 | util_ExtractSubPeriod(Q_mat{i}, t_mat{i}, high_flow_season); 86 | 87 | [AC1(i),~,AC1_error_str(i)] = sig_Autocorrelation(Q_mat{i},t_mat{i},'lag',1); 88 | [AC1_low(i),~,AC1_low_error_str(i)] = sig_Autocorrelation(Q_low,t_low,'lag',1); 89 | [RLD(i),~,RLD_error_str(i)] = sig_RisingLimbDensity(Q_mat{i},t_mat{i}); 90 | [PeakDistribution(i),~,PeakDistribution_error_str(i)] = sig_PeakDistribution(Q_mat{i},t_mat{i}); 91 | [PeakDistribution_low(i),~,PeakDistribution_low_error_str(i)] = sig_PeakDistribution(Q_low,t_low); 92 | [FDC{i}(:,1),FDC{i}(:,2),~,FDC_error_str(i)] = sig_FDC(Q_mat{i},t_mat{i}); 93 | [FDC_low{i}(:,1),FDC_low{i}(:,2),~,FDC_low_error_str(i)] = sig_FDC(Q_low,t_low); 94 | [FDC_high{i}(:,1),FDC_high{i}(:,2),~,FDC_high_error_str(i)] = sig_FDC(Q_high,t_high); 95 | 96 | end 97 | 98 | % add results to struct array 99 | results.AC1 = AC1; 100 | results.AC1_error_str = AC1_error_str; 101 | results.AC1_low = AC1_low; 102 | results.AC1_low_error_str = AC1_low_error_str; 103 | results.RLD = RLD; 104 | results.RLD_error_str = RLD_error_str; 105 | results.PeakDistribution = PeakDistribution; 106 | results.PeakDistribution_error_str = PeakDistribution_error_str; 107 | results.PeakDistribution_low = PeakDistribution_low; 108 | results.PeakDistribution_low_error_str = PeakDistribution_low_error_str; 109 | results.FDC = FDC; 110 | results.FDC_error_str = FDC_error_str; 111 | results.FDC_low = FDC_low; 112 | results.FDC_low_error_str = FDC_low_error_str; 113 | results.FDC_high = FDC_high; 114 | results.FDC_high_error_str = FDC_high_error_str; 115 | 116 | end 117 | -------------------------------------------------------------------------------- /TOSSH_code/calculation_functions/calc_Sawicz.m: -------------------------------------------------------------------------------- 1 | function [results] = calc_Sawicz(Q_mat, t_mat, P_mat, T_mat, varargin) 2 | %calc_Sawicz calculates signatures from Sawicz et al. (2011). 3 | % Sawicz et al. (2011) use 6 signatures drawn largely from Yadav et al. 4 | % (2007), that are chosen to be uncorrelated and to be linked to 5 | % catchment function. The signatures are used to analyze hydrological 6 | % similarity between catchments, and link the resulting clusters to 7 | % physical and climate attributes. 8 | % 9 | % INPUT 10 | % Q_mat: streamflow [mm/timestep] matrix (cell array) 11 | % t_mat: time [Matlab datenum] matrix (cell array) 12 | % P_mat: precipitation [mm/timestep] matrix (cell array) 13 | % T_mat: temperature [degC] matrix (cell array) 14 | % OPTIONAL 15 | % start_water_year: first month of water year, default = 10 (October) 16 | % 17 | % OUTPUT 18 | % results: struc array with all results (each signature for each time 19 | % series and associated error strings) 20 | % 21 | % EXAMPLE 22 | % % load example data 23 | % data = load('example/example_data/33029_daily.mat'); 24 | % % create consistent cell arrays 25 | % Q_mat = {data.Q}; 26 | % t_mat = {data.t}; 27 | % P_mat = {data.P}; 28 | % T_mat = {data.T}; 29 | % results = calc_Sawicz(Q_mat,t_mat,P_mat,T_mat); 30 | % 31 | % References 32 | % Sawicz, K., Wagener, T., Sivapalan, M., Troch, P.A. and Carrillo, G., 33 | % 2011. Catchment classification: empirical analysis of hydrologic 34 | % similarity based on catchment function in the eastern USA. Hydrology 35 | % and Earth System Sciences, 15(9), pp.2895-2911. 36 | % Yadav, M., Wagener, T. and Gupta, H., 2007. Regionalization of 37 | % constraints on expected watershed response behavior for improved 38 | % predictions in ungauged basins. Advances in Water Resources, 30(8), 39 | % pp.1756-1774. 40 | % 41 | % Copyright (C) 2020 42 | % This software is distributed under the GNU Public License Version 3. 43 | % See for details. 44 | 45 | % check input parameters 46 | if nargin < 4 47 | error('Not enough input arguments.') 48 | end 49 | 50 | ip = inputParser; 51 | ip.CaseSensitive = true; % to be able to use t for time and T for temperature 52 | 53 | % required input arguments 54 | % Please input time series as a cell array of the following format: 55 | % {x_1; x_2; ...; x_n}, where each entry (1, 2, ..., n) corresponds to one 56 | % time series, e.g. from one catchment. For one catchment only, please 57 | % input {x}. Example: {Q_1; Q_2; ...; Q_n} for streamflow. 58 | addRequired(ip, 'Q_mat', @(Q_mat) iscell(Q_mat)) 59 | addRequired(ip, 't_mat', @(t_mat) iscell(t_mat)) 60 | addRequired(ip, 'P_mat', @(P_mat) iscell(P_mat)) 61 | addRequired(ip, 'T_mat', @(T_mat) iscell(T_mat)) 62 | 63 | % optional input arguments 64 | addParameter(ip, 'start_water_year', 10, @isnumeric) % when does the water year start? Default: 10 65 | 66 | parse(ip, Q_mat, t_mat, P_mat, T_mat, varargin{:}) 67 | start_water_year = ip.Results.start_water_year; 68 | 69 | % initialise arrays 70 | Total_RR = NaN(size(Q_mat,1),1); 71 | Total_RR_error_str = strings(size(Q_mat,1),1); 72 | FDC_slope = NaN(size(Q_mat,1),1); 73 | FDC_slope_error_str = strings(size(Q_mat,1),1); 74 | BFI = NaN(size(Q_mat,1),1); 75 | BFI_error_str = strings(size(Q_mat,1),1); 76 | QP_elasticity = NaN(size(Q_mat,1),1); 77 | QP_elasticity_error_str = strings(size(Q_mat,1),1); 78 | SnowDayRatio = NaN(size(Q_mat,1),1); 79 | SnowDayRatio_error_str = strings(size(Q_mat,1),1); 80 | RLD = NaN(size(Q_mat,1),1); 81 | RLD_error_str = strings(size(Q_mat,1),1); 82 | 83 | % loop over all catchments 84 | for i = 1:size(Q_mat,1) 85 | 86 | [Total_RR(i),~,Total_RR_error_str(i)] = sig_TotalRR(Q_mat{i},t_mat{i},P_mat{i}); 87 | [FDC_slope(i),~,FDC_slope_error_str(i)] = sig_FDC_slope(Q_mat{i},t_mat{i}); 88 | [BFI(i),~,BFI_error_str(i)] = sig_BFI(Q_mat{i},t_mat{i}); 89 | [QP_elasticity(i),~,QP_elasticity_error_str(i)] = sig_QP_elasticity(... 90 | Q_mat{i},t_mat{i},P_mat{i},'start_water_year',start_water_year); 91 | [SnowDayRatio(i),~,SnowDayRatio_error_str(i)] = sig_SnowDayRatio(... 92 | Q_mat{i},t_mat{i},P_mat{i},T_mat{i}); 93 | [RLD(i),~,RLD_error_str(i)] = sig_RisingLimbDensity(Q_mat{i},t_mat{i}); 94 | 95 | end 96 | 97 | % add results to struct array 98 | results.Total_RR = Total_RR; 99 | results.Total_RR_error_str = Total_RR_error_str; 100 | results.FDC_slope = FDC_slope; 101 | results.FDC_slope_error_str = FDC_slope_error_str; 102 | results.BFI = BFI; 103 | results.BFI_error_str = BFI_error_str; 104 | results.QP_elasticity = QP_elasticity; 105 | results.QP_elasticity_error_str = QP_elasticity_error_str; 106 | results.SnowDayRatio = SnowDayRatio; 107 | results.SnowDayRatio_error_str = SnowDayRatio_error_str; 108 | results.RLD = RLD; 109 | results.RLD_error_str = RLD_error_str; 110 | 111 | end 112 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_Autocorrelation.m: -------------------------------------------------------------------------------- 1 | function [AC, error_flag, error_str] = sig_Autocorrelation(Q, t, varargin) 2 | %sig_Autocorrelation caculates lag-x autocorrelation of flow. 3 | % 4 | % INPUT 5 | % Q: streamflow [mm/timestep] 6 | % t: time [Matlab datetime] 7 | % OPTIONAL 8 | % lag: time lag at which autocorrelation should be calculated (default = 9 | % 1 timestep), can also be a vector 10 | % 11 | % OUTPUT 12 | % AC: lag-x autocorrelation [-], can also be a vector 13 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 14 | % (error in signature calculation) 15 | % error_str: string contraining error description 16 | % 17 | % EXAMPLE 18 | % % load example data 19 | % data = load('example/example_data/33029_daily.mat'); 20 | % Q = data.Q; 21 | % t = data.t; 22 | % AC = sig_Autocorrelation(Q,t); 23 | % AC = sig_Autocorrelation(Q,t,'lag',1); 24 | % AC = sig_Autocorrelation(Q,t,'lag',[0:length(Q)-2]); 25 | % 26 | % References 27 | % https://en.wikipedia.org/wiki/Autocorrelation 28 | % 29 | % Copyright (C) 2020 30 | % This software is distributed under the GNU Public License Version 3. 31 | % See for details. 32 | 33 | % check input parameters 34 | if nargin < 2 35 | error('Not enough input arguments.') 36 | end 37 | 38 | ip = inputParser; 39 | ip.CaseSensitive = true; 40 | 41 | % required input arguments 42 | % time series have to be numeric and either a (n,1) or a (1,n) vector 43 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 44 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 45 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 46 | 47 | % optional input arguments 48 | addParameter(ip, 'lag', 1, @isnumeric) % lag for autocorrelation 49 | 50 | parse(ip, Q, t, varargin{:}) 51 | lag = ip.Results.lag; 52 | 53 | % data checks 54 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 55 | if error_flag == 2 56 | AC = NaN; 57 | return 58 | end 59 | 60 | if any(lag>length(Q)-2) || any(lag<0) 61 | error('lag must be between 0 and must not exceed the number of observations minus two.') 62 | end 63 | 64 | % calculate signature (different methods use different toolboxes) 65 | AC = nanxcov(Q,Q,max(lag),'coeff'); 66 | AC = AC(max(lag)+1+lag); 67 | 68 | % AC = autocorr(Q,max(lag)); % from Econometrics toolbox 69 | % AC = AC(lag+1); 70 | 71 | end 72 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_FDC.m: -------------------------------------------------------------------------------- 1 | function [FDC, Q_sorted, error_flag, error_str, fig_handles] = sig_FDC(Q, t, varargin) 2 | %sig_FDC calculates flow duration curve (FDC). 3 | % 4 | % INPUT 5 | % Q: streamflow [mm/timestep] 6 | % t: time [Matlab datetime] 7 | % OPTIONAL 8 | % plot_results: whether to plot results, default = false 9 | % 10 | % OUTPUT 11 | % FDC: Flow duration curve, i.e. exceedance probabilities [-] 12 | % Q_sorted: sorted streamflow values [mm/timestep] 13 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 14 | % (error in signature calculation) 15 | % error_str: string contraining error description 16 | % fig_handles: figure handles to manipulate figures (empty if plotting is 17 | % not requested) 18 | % 19 | % EXAMPLE 20 | % % load example data 21 | % data = load('example/example_data/33029_daily.mat'); 22 | % Q = data.Q; 23 | % t = data.t; 24 | % [FDC, Q_sorted] = sig_FDC(Q,t,'plot_results',true); 25 | % 26 | % Copyright (C) 2020 27 | % This software is distributed under the GNU Public License Version 3. 28 | % See for details. 29 | 30 | % check input parameters 31 | if nargin < 2 32 | error('Not enough input arguments.') 33 | end 34 | 35 | ip = inputParser; 36 | 37 | % required input arguments 38 | % time series have to be numeric and either a (n,1) or a (1,n) vector 39 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 40 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 41 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 42 | 43 | % optional input arguments 44 | addParameter(ip, 'plot_results', false, @islogical) % whether to plot results 45 | 46 | parse(ip, Q, t, varargin{:}) 47 | plot_results = ip.Results.plot_results; 48 | 49 | % create empty figure handle 50 | fig_handles = []; 51 | 52 | % data checks 53 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 54 | if error_flag == 2 55 | FDC = NaN(size(Q)); 56 | Q_sorted = NaN(size(Q)); 57 | return 58 | end 59 | 60 | % calculate signature 61 | % get ranks as a proxy for exceedance probabilities 62 | Q_tmp = Q(~isnan(Q)); % remove NaN values 63 | Q_sorted = sort(Q_tmp); 64 | Q_ranked = [1:length(Q_tmp)]'; % give unique (random) rank to every measurement 65 | FDC = 1 - Q_ranked./length(Q_ranked); % flow duration curve with unique ranks 66 | 67 | % add warning for intermittent streams 68 | if ~isempty(Q_tmp(Q_tmp==0)) 69 | error_flag = 2; 70 | error_str = ['Warning: Flow is zero at least once (intermittent flow). ', error_str]; 71 | end 72 | 73 | % optional plotting 74 | if plot_results 75 | fig = figure('pos',[100 100 350 300]); hold on 76 | hold on 77 | plot(FDC,Q_sorted,'linewidth',1.0) 78 | ylabel('Q [mm/timestep]') 79 | xlabel('Exceedance probability [-]') 80 | set(gca,'YScale','log') 81 | fig_handles.FDC = fig; 82 | end 83 | 84 | end 85 | 86 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_FlashinessIndex.m: -------------------------------------------------------------------------------- 1 | function [FlashinessIndex, error_flag, error_str] = sig_FlashinessIndex(Q, t, varargin) 2 | %sig_FlashinessIndex calculates Richards-Baker flashiness index. 3 | % Flashiness index defined as sum of absolute differences between 4 | % consecutive (daily) flows following Baker et al. (2004). 5 | % 6 | % INPUT 7 | % Q: streamflow [mm/timestep] 8 | % t: time [Matlab datetime] 9 | % 10 | % OUTPUT 11 | % FlashinessIndex: Richards-Baker flashiness index [-] 12 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 13 | % (error in signature calculation) 14 | % error_str: string contraining error description 15 | % 16 | % EXAMPLE 17 | % % load example data 18 | % data = load('example/example_data/33029_daily.mat'); 19 | % Q = data.Q; 20 | % t = data.t; 21 | % FlashinessIndex = sig_FlashinessIndex(Q,t); 22 | % 23 | % References 24 | % Baker, D.B., Richards, R.P., Loftus, T.T. and Kramer, J.W., 2004. A new 25 | % flashiness index: Characteristics and applications to midwestern rivers 26 | % and streams 1. JAWRA Journal of the American Water Resources 27 | % Association, 40(2), pp.503-522. 28 | % 29 | % Copyright (C) 2020 30 | % This software is distributed under the GNU Public License Version 3. 31 | % See for details. 32 | 33 | % check input parameters 34 | if nargin < 2 35 | error('Not enough input arguments.') 36 | end 37 | 38 | ip = inputParser; 39 | ip.CaseSensitive = true; 40 | 41 | % required input arguments 42 | % time series have to be numeric and either a (n,1) or a (1,n) vector 43 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 44 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 45 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 46 | 47 | parse(ip, Q, t, varargin{:}) 48 | 49 | % data checks 50 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 51 | if error_flag == 2 52 | FlashinessIndex = NaN; 53 | return 54 | end 55 | 56 | % calculate signature 57 | FlashinessIndex = sum(abs(diff(Q)),'omitnan')/sum(Q,'omitnan'); 58 | 59 | end 60 | 61 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_HFD_mean.m: -------------------------------------------------------------------------------- 1 | function [HFD_mean, error_flag, error_str] = sig_HFD_mean(Q, t, varargin) 2 | %sig_HFD_mean calculates mean half flow date. 3 | % Calculates day since start of water year on which the cumulative 4 | % discharge (default: October) reaches (here: exceeds) half of the annual 5 | % discharge. 6 | % 7 | % INPUT 8 | % Q: streamflow [mm/timestep] 9 | % t: time [Matlab datetime] 10 | % OPTIONAL 11 | % start_water_year: first month of water year, default = 10 (October) 12 | % 13 | % OUTPUT 14 | % HFD_mean: mean half flow date [day since start of water year] 15 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 16 | % (error in signature calculation) 17 | % error_str: string contraining error description 18 | % 19 | % EXAMPLE 20 | % % load example data 21 | % data = load('example/example_data/33029_daily.mat'); 22 | % Q = data.Q; 23 | % t = data.t; 24 | % HFD_mean = sig_HFD_mean(Q,t); 25 | % HFD_mean = sig_HFD_mean(Q,t,'start_water_year',1); 26 | % 27 | % References 28 | % Court, A., 1962. Measures of streamflow timing. Journal of Geophysical 29 | % Research, 67(11), pp.4335-4339. 30 | % 31 | % Copyright (C) 2020 32 | % This software is distributed under the GNU Public License Version 3. 33 | % See for details. 34 | 35 | % check input parameters 36 | if nargin < 2 37 | error('Not enough input arguments.') 38 | end 39 | 40 | ip = inputParser; 41 | ip.CaseSensitive = true; 42 | 43 | % required input arguments 44 | % time series have to be numeric and either a (n,1) or a (1,n) vector 45 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 46 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 47 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 48 | 49 | % optional input arguments 50 | validationFcn = @(x) isnumeric(x) && isscalar(x) && (x >= 1) && (x <= 12) && floor(x)==x; 51 | addParameter(ip, 'start_water_year', 10, validationFcn) % when does the water year start? Default: 10 52 | 53 | parse(ip, Q, t, varargin{:}) 54 | start_water_year = ip.Results.start_water_year; 55 | 56 | % data checks 57 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 58 | if error_flag == 2 59 | HFD_mean = NaN; 60 | return 61 | end 62 | timestep_days = days(timestep); % adjust for timestep 63 | 64 | % calculate signature 65 | % get individual years 66 | [year_vec, month_vec, day_vec] = ymd(t); 67 | year_start = min(year_vec); 68 | year_end = max(year_vec); 69 | year_list = [year_start:year_end]'; 70 | 71 | Q_temp = Q; 72 | % Q_annual = NaN(year_end-year_start,1); 73 | % Q_daily = NaN(365,year_end-year_start); 74 | HFD = NaN(year_end-year_start,1); 75 | 76 | % extract years 77 | error_tmp = false; 78 | for y = 2:length(year_list) % since we use water years, we always start in the "2nd year" 79 | try 80 | year = year_list(y); 81 | Q_water_year = ... 82 | [Q_temp(year_vec==year-1 & month_vec>=start_water_year); ... 83 | Q_temp(year_vec==year & month_vecQ_half_sum); 88 | HFD(y-1) = HFD_aux(1); 89 | catch 90 | error_tmp = true; 91 | end 92 | end 93 | 94 | if error_tmp 95 | error_flag = 1; 96 | error_str = ['Warning: Years containing NaN values are ignored. ', error_str]; 97 | end 98 | 99 | % get mean half flow date 100 | HFD_mean = mean(HFD,'omitnan')*timestep_days; 101 | 102 | end 103 | 104 | 105 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_HFI_mean.m: -------------------------------------------------------------------------------- 1 | function [HFI_mean, error_flag, error_str] = sig_HFI_mean(Q,t, varargin) 2 | %sig_HFI_mean calculates mean half flow interval. 3 | % Calculates time span between the date on which the cumulative discharge 4 | % since start of water year (default: October) reaches (here: exceeds) a 5 | % quarter of the annual discharge and the date on which the cumulative 6 | % discharge since start of water year (default: October) reaches three 7 | % quarters of the annual discharge. 8 | % 9 | % INPUT 10 | % Q: streamflow [mm/timestep] 11 | % t: time [Matlab datenum] 12 | % OPTIONAL 13 | % start_water_year: first month of water year, default = 10 (October) 14 | % 15 | % OUTPUT 16 | % HFI_mean: mean half flow interval [days] 17 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 18 | % (error in signature calculation) 19 | % error_str: string contraining error description 20 | % 21 | % EXAMPLE 22 | % % load example data 23 | % data = load('example/example_data/33029_daily.mat'); 24 | % Q = data.Q; 25 | % t = data.t; 26 | % HFI_mean = sig_HFI_mean(Q,t); 27 | % HFI_mean = sig_HFI_mean(Q,t,'start_water_year',1); 28 | % 29 | % References 30 | % Court, A., 1962. Measures of streamflow timing. Journal of Geophysical 31 | % Research, 67(11), pp.4335-4339. 32 | % 33 | % Copyright (C) 2020 34 | % This software is distributed under the GNU Public License Version 3. 35 | % See for details. 36 | 37 | % check input parameters 38 | if nargin < 2 39 | error('Not enough input arguments.') 40 | end 41 | 42 | ip = inputParser; 43 | ip.CaseSensitive = true; 44 | 45 | % required input arguments 46 | % time series have to be numeric and either a (n,1) or a (1,n) vector 47 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 48 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 49 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 50 | 51 | % optional input arguments 52 | validationFcn = @(x) isnumeric(x) && isscalar(x) && (x >= 1) && (x <= 12) && floor(x)==x; 53 | addParameter(ip, 'start_water_year', 10, validationFcn) % when does the water year start? Default: 10 54 | 55 | parse(ip, Q, t, varargin{:}) 56 | start_water_year = ip.Results.start_water_year; 57 | 58 | % data checks 59 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 60 | if error_flag == 2 61 | HFI_mean = NaN; 62 | return 63 | end 64 | timestep_days = days(timestep); % adjust for timestep 65 | 66 | % calculate signature 67 | % get individual years 68 | [year_vec, month_vec, day_vec] = ymd(t); 69 | year_start = min(year_vec); 70 | year_end = max(year_vec); 71 | year_list = [year_start:year_end]'; 72 | 73 | Q_temp = Q; 74 | % Q_annual = NaN(year_end-year_start,1); 75 | % Q_daily = NaN(365,year_end-year_start); 76 | HFI = NaN(year_end-year_start,1); 77 | 78 | % extract years 79 | error_tmp = false; 80 | for y = 2:length(year_list) % since we use water years, we always start in the "2nd year" 81 | year = year_list(y); 82 | Q_water_year = ... 83 | [Q_temp(year_vec==year-1 & month_vec>=start_water_year); ... 84 | Q_temp(year_vec==year & month_vecQ_25_sum); 90 | HFI_aux_75 = aux_index(Q_cumsum>Q_75_sum); 91 | if isempty(HFI_aux_25) || isempty(HFI_aux_75) % if there is no flow 92 | error_tmp = true; 93 | else 94 | HFI_25 = HFI_aux_25(1); 95 | HFI_75 = HFI_aux_75(1); 96 | HFI(y-1) = HFI_75 - HFI_25; 97 | end 98 | end 99 | 100 | if error_tmp 101 | error_flag = 1; 102 | error_str = ['Warning: Some years have no flow. ', error_str]; 103 | end 104 | 105 | % get mean half flow interval (ignoring NaNs) 106 | HFI_mean = mean(HFI,'omitnan')*timestep_days; 107 | 108 | end 109 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_QP_elasticity.m: -------------------------------------------------------------------------------- 1 | function [QP_elasticity, error_flag, error_str] = sig_QP_elasticity(Q, t, P, varargin) 2 | %sig_QP_elasticity calculates streamflow-precipitation elasticity. 3 | % Calculates streamflow-precipitation elasticity, the sensitivity of a 4 | % catchment's streamflow response to changes in precipitation at the 5 | % annual time scale. Start of water year can be defined. 6 | % 7 | % INPUT 8 | % Q: streamflow [mm/timestep] 9 | % t: time [Matlab datetime] 10 | % P: precipitation [mm/timestep] 11 | % OPTIONAL 12 | % start_water_year: first month of water year, default = 10 (October) 13 | % method: choose method to calculate elasticity ('Sawicz','Sanka'), 14 | % default = 'Sanka' 15 | % 16 | % OUTPUT 17 | % QP_elasticity: streamflow-precipitation elasticity [-] 18 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 19 | % (error in signature calculation) 20 | % error_str: string contraining error description 21 | % 22 | % EXAMPLE 23 | % % load example data 24 | % data = load('example/example_data/33029_daily.mat'); 25 | % Q = data.Q; 26 | % t = data.t; 27 | % P = data.P; 28 | % QP_elasticity = sig_QP_elasticity(Q,t,P,'start_water_year',10); 29 | % 30 | % References 31 | % Sankarasubramanian, A., Vogel, R.M. and Limbrunner, J.F., 2001. Climate 32 | % elasticity of streamflow in the United States. Water Resources 33 | % Research, 37(6), pp.1771-1781. 34 | % Sawicz, K., Wagener, T., Sivapalan, M., Troch, P.A. and Carrillo, G., 35 | % 2011. Catchment classification: empirical analysis of hydrologic 36 | % similarity based on catchment function in the eastern USA. Hydrology 37 | % and Earth System Sciences, 15(9), pp.2895-2911. 38 | % 39 | % Copyright (C) 2020 40 | % This software is distributed under the GNU Public License Version 3. 41 | % See for details. 42 | 43 | % check input parameters 44 | if nargin < 3 45 | error('Not enough input arguments.') 46 | end 47 | 48 | ip = inputParser; 49 | ip.CaseSensitive = true; 50 | 51 | % required input arguments 52 | % time series have to be numeric and either a (n,1) or a (1,n) vector 53 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 54 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 55 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 56 | % time series have to be numeric and either a (n,1) or a (1,n) vector 57 | addRequired(ip, 'P', @(P) isnumeric(P) && (size(P,1)==1 || size(P,2)==1)) 58 | 59 | % optional input arguments 60 | validationFcn = @(x) isnumeric(x) && isscalar(x) && (x >= 1) && (x <= 12) && floor(x)==x; 61 | addParameter(ip, 'start_water_year', 10, validationFcn) % when does the water year start? Default: 10 62 | addParameter(ip, 'method', 'Sanka', @ischar) % which method? Default: Sanka 63 | 64 | parse(ip, Q, t, P, varargin{:}) 65 | start_water_year = ip.Results.start_water_year; 66 | method = ip.Results.method; 67 | 68 | % data checks 69 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t, 'P', P); 70 | if error_flag == 2 71 | QP_elasticity = NaN; 72 | return 73 | end 74 | 75 | % calculate signature 76 | error_flag_tmp = error_flag; % temporarily store error flag from data check 77 | error_str_tmp = error_str; 78 | % aggregate time series to get annual sums 79 | [Q_annual, ~, ~, days_per_year, error_flag, error_str] = ... 80 | util_AggregateTimeSeries(Q, t, start_water_year); 81 | [P_annual, ~, ~, days_per_year, error_flag, error_str] = ... 82 | util_AggregateTimeSeries(P, t, start_water_year); 83 | if error_flag == 0 84 | error_flag = error_flag_tmp; 85 | error_str = error_str_tmp; 86 | end 87 | 88 | % calculate elasticity 89 | switch method 90 | % use year_length to adjust for leap years and incomplete years 91 | case 'Sanka' 92 | dQ = Q_annual./days_per_year - mean(Q_annual./days_per_year,'omitnan'); 93 | dP = P_annual./days_per_year - mean(P_annual./days_per_year,'omitnan'); 94 | case 'Sawicz' 95 | dQ = diff(Q_annual./days_per_year); 96 | dP = diff(P_annual./days_per_year); 97 | otherwise 98 | error('Please choose one of the available methods (Sawicz or Sanka).') 99 | end 100 | 101 | QP_elasticity = median((dQ./dP)*(mean(P,'omitnan')/mean(Q,'omitnan')),'omitnan'); 102 | 103 | end 104 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_Q_CoV.m: -------------------------------------------------------------------------------- 1 | function [CoV, error_flag, error_str] = sig_Q_CoV(Q, t) 2 | %sig_Q_CoV calculates coefficient of variation (CoV) of flow. 3 | % Calculates CoV, i.e. standard deviation normalised by mean. 4 | % 5 | % INPUT 6 | % Q: streamflow [mm/timestep] 7 | % t: time [Matlab datetime] 8 | % 9 | % OUTPUT 10 | % CoV: coefficient of variation [-] 11 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 12 | % (error in signature calculation) 13 | % error_str: string contraining error description 14 | % 15 | % EXAMPLE 16 | % % load example data 17 | % data = load('example/example_data/33029_daily.mat'); 18 | % Q = data.Q; 19 | % t = data.t; 20 | % CoV = sig_Q_CoV(Q,t); 21 | % 22 | % References 23 | % https://en.wikipedia.org/wiki/Coefficient_of_variation 24 | % 25 | % Copyright (C) 2020 26 | % This software is distributed under the GNU Public License Version 3. 27 | % See for details. 28 | 29 | % check input parameters 30 | if nargin < 2 31 | error('Not enough input arguments.') 32 | end 33 | 34 | ip = inputParser; 35 | ip.CaseSensitive = true; 36 | 37 | % required input arguments 38 | % time series have to be numeric and either a (n,1) or a (1,n) vector 39 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 40 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 41 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 42 | 43 | parse(ip, Q, t) 44 | 45 | % data checks 46 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 47 | if error_flag == 2 48 | CoV = NaN; 49 | return 50 | end 51 | 52 | % calculate signature 53 | CoV = std(Q,'omitnan')/mean(Q,'omitnan'); 54 | 55 | end 56 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_Q_mean.m: -------------------------------------------------------------------------------- 1 | function [Q_mean, error_flag, error_str] = sig_Q_mean(Q, t) 2 | %sig_Q_mean calculates mean flow of time series. 3 | % 4 | % INPUT 5 | % Q: streamflow [mm/timestep] 6 | % t: time [Matlab datetime] 7 | % 8 | % OUTPUT 9 | % Q_mean: mean flow [mm/timestep] 10 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 11 | % (error in signature calculation) 12 | % error_str: string contraining error description 13 | % 14 | % EXAMPLE 15 | % % load example data 16 | % data = load('example/example_data/33029_daily.mat'); 17 | % Q = data.Q; 18 | % t = data.t; 19 | % Q_mean = sig_Q_mean(Q,t); 20 | % 21 | % References 22 | % https://en.wikipedia.org/wiki/Arithmetic_mean 23 | % 24 | % Copyright (C) 2020 25 | % This software is distributed under the GNU Public License Version 3. 26 | % See for details. 27 | 28 | % check input parameters 29 | if nargin < 2 30 | error('Not enough input arguments.') 31 | end 32 | 33 | ip = inputParser; 34 | ip.CaseSensitive = true; 35 | 36 | % required input arguments 37 | % time series have to be numeric and either a (n,1) or a (1,n) vector 38 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 39 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 40 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 41 | 42 | parse(ip, Q, t) 43 | 44 | % data checks 45 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 46 | if error_flag == 2 47 | Q_mean = NaN; 48 | return 49 | end 50 | 51 | % calculate signature 52 | Q_mean = mean(Q,'omitnan'); 53 | 54 | end 55 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_Q_mean_monthly.m: -------------------------------------------------------------------------------- 1 | function [Q_mean_monthly, error_flag, error_str] = sig_Q_mean_monthly(Q, t, month) 2 | %sig_Q_mean_monthly calculates mean monthly flow of time series. 3 | % 4 | % INPUT 5 | % Q: streamflow [mm/timestep] 6 | % t: time [Matlab datetime] 7 | % month: month(s) in which mean flow should be calculated (can be vector) 8 | % 9 | % OUTPUT 10 | % Q_mean_monthly: mean flow in specified month(s) [mm/timestep] 11 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 12 | % (error in signature calculation) 13 | % error_str: string contraining error description 14 | % 15 | % EXAMPLE 16 | % % load example data 17 | % data = load('example/example_data/33029_daily.mat'); 18 | % Q = data.Q; 19 | % t = data.t; 20 | % Q_mean_monthly = sig_Q_mean_monthly(Q, t, 8); % August 21 | % Q_mean_monthly = sig_Q_mean_monthly(Q, t, [10:12 1:9]); % full year 22 | % 23 | % References 24 | % https://en.wikipedia.org/wiki/Arithmetic_mean 25 | % 26 | % Copyright (C) 2020 27 | % This software is distributed under the GNU Public License Version 3. 28 | % See for details. 29 | 30 | % check input parameters 31 | if nargin < 3 32 | error('Not enough input arguments.') 33 | end 34 | 35 | ip = inputParser; 36 | ip.CaseSensitive = true; 37 | 38 | % required input arguments 39 | % time series have to be numeric and either a (n,1) or a (1,n) vector 40 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 41 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 42 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 43 | % month has to be numeric and either a (n,1) or a (1,n) vector 44 | addRequired(ip, 'month', @(month) isnumeric(month) && (size(month,1)==1 || size(month,2)==1)) 45 | 46 | parse(ip, Q, t, month) 47 | 48 | % data checks 49 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 50 | if error_flag == 2 51 | Q_mean_monthly = NaN; 52 | return 53 | end 54 | 55 | if any(month<1 | month>12) || any(floor(month)~=month) 56 | error('Month has to be a vector containing integers between 1 and 12.') 57 | end 58 | 59 | % calculate signature 60 | date_vec = datevec(t); 61 | Q_mean_monthly = NaN(length(month),1); 62 | for i = 1:length(month) 63 | Q_mean_monthly(i) = mean(Q(date_vec(:,2)==month(i)),'omitnan'); % always ignoring NaNs 64 | end 65 | 66 | end 67 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_Q_n_day_max.m: -------------------------------------------------------------------------------- 1 | function [Q_n_day_max, error_flag, error_str] = sig_Q_n_day_max(Q, t, n_day) 2 | %Q_n_day_max calculates n day maxmimum of flow time series. 3 | % 4 | % INPUT 5 | % Q: streamflow [mm/timestep] 6 | % t: time [Matlab datetime] 7 | % n_day: window over which maximum should be calculated 8 | % 9 | % OUTPUT 10 | % Q_n_day_max: n day maxmimum of flow [mm/n_day] 11 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 12 | % (error in signature calculation) 13 | % error_str: string contraining error description 14 | % 15 | % EXAMPLE 16 | % % load example data 17 | % data = load('example/example_data/33029_daily.mat'); 18 | % Q = data.Q; 19 | % t = data.t; 20 | % Q_n_day_max = sig_Q_n_day_max(Q, t, 7); 21 | % Q_n_day_max = sig_Q_n_day_max(Q, t, [1:7]); 22 | % 23 | % Copyright (C) 2020 24 | % This software is distributed under the GNU Public License Version 3. 25 | % See for details. 26 | 27 | % check input parameters 28 | if nargin < 3 29 | error('Not enough input arguments.') 30 | end 31 | 32 | ip = inputParser; 33 | ip.CaseSensitive = true; 34 | 35 | % required input arguments 36 | % time series have to be numeric and either a (n,1) or a (1,n) vector 37 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 38 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 39 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 40 | % n_day has to be numeric and either a (n,1) or a (1,n) vector 41 | addRequired(ip, 'n_day', @(n_day) isnumeric(n_day) && (size(n_day,1)==1 || size(n_day,2)==1)) 42 | 43 | parse(ip, Q, t, n_day) 44 | 45 | % data checks 46 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 47 | if error_flag == 2 48 | Q_n_day_max = NaN; 49 | return 50 | end 51 | 52 | if any(n_day<1 | n_day>length(t)) || any(floor(n_day)~=n_day) 53 | error('Month has to be a vector containing integers between 1 and length(timeseries).') 54 | end 55 | 56 | % calculate signature 57 | Q_n_day_max = NaN(length(n_day),1); 58 | for i=1:length(n_day) 59 | Q_n_day_max(i) = n_day(i)*max(movmean(Q,n_day(i))); % returns value in mm per chosen window n_day 60 | end 61 | 62 | end 63 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_Q_n_day_min.m: -------------------------------------------------------------------------------- 1 | function [Q_n_day_min, error_flag, error_str] = sig_Q_n_day_min(Q, t, n_day) 2 | %Q_n_day_min calculates n day minimum of flow time series. 3 | % 4 | % INPUT 5 | % Q: streamflow [mm/timestep] 6 | % t: time [Matlab datetime] 7 | % n_day: window over which minimum should be calculated 8 | % 9 | % OUTPUT 10 | % Q_n_day_min: n day minimum of flow [mm/n_day] 11 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 12 | % (error in signature calculation) 13 | % error_str: string contraining error description 14 | % 15 | % EXAMPLE 16 | % % load example data 17 | % data = load('example/example_data/33029_daily.mat'); 18 | % Q = data.Q; 19 | % t = data.t; 20 | % Q_n_day_min = sig_Q_n_day_min(Q, t, 7); 21 | % Q_n_day_min = sig_Q_n_day_min(Q, t, [1:7]); 22 | % 23 | % Copyright (C) 2020 24 | % This software is distributed under the GNU Public License Version 3. 25 | % See for details. 26 | 27 | % check input parameters 28 | if nargin < 3 29 | error('Not enough input arguments.') 30 | end 31 | 32 | ip = inputParser; 33 | ip.CaseSensitive = true; 34 | 35 | % required input arguments 36 | % time series have to be numeric and either a (n,1) or a (1,n) vector 37 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 38 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 39 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 40 | % n_day has to be numeric and either a (n,1) or a (1,n) vector 41 | addRequired(ip, 'n_day', @(n_day) isnumeric(n_day) && (size(n_day,1)==1 || size(n_day,2)==1)) 42 | 43 | parse(ip, Q, t, n_day) 44 | 45 | % data checks 46 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 47 | if error_flag == 2 48 | Q_n_day_min = NaN; 49 | return 50 | end 51 | 52 | if any(n_day<1 | n_day>length(t)) || any(floor(n_day)~=n_day) 53 | error('Month has to be a vector containing integers between 1 and length(timeseries).') 54 | end 55 | 56 | % calculate signature 57 | Q_n_day_min = NaN(length(n_day),1); 58 | for i=1:length(n_day) 59 | Q_n_day_min(i) = n_day(i)*min(movmean(Q,n_day(i))); % returns value in mm per chosen window n_day 60 | end 61 | 62 | end 63 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_Q_skew.m: -------------------------------------------------------------------------------- 1 | function [Q_skew, error_flag, error_str] = sig_Q_skew(Q, t) 2 | %sig_Q_skew calculates skewness of flow time series. 3 | % 4 | % INPUT 5 | % Q: streamflow [mm/timestep] 6 | % t: time [Matlab datetime] 7 | % 8 | % OUTPUT 9 | % skew: skewness [(mm/timestep)^3] 10 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 11 | % (error in signature calculation) 12 | % error_str: string contraining error description 13 | % 14 | % EXAMPLE 15 | % % load example data 16 | % data = load('example/example_data/33029_daily.mat'); 17 | % Q = data.Q; 18 | % t = data.t; 19 | % Q_skew = sig_Q_skew(Q,t); 20 | % 21 | % References 22 | % https://en.wikipedia.org/wiki/Skewness 23 | % 24 | % Copyright (C) 2020 25 | % This software is distributed under the GNU Public License Version 3. 26 | % See for details. 27 | 28 | % check input parameters 29 | if nargin < 2 30 | error('Not enough input arguments.') 31 | end 32 | 33 | ip = inputParser; 34 | ip.CaseSensitive = true; 35 | 36 | % required input arguments 37 | % time series have to be numeric and either a (n,1) or a (1,n) vector 38 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 39 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 40 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 41 | 42 | parse(ip, Q, t) 43 | 44 | % data checks 45 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 46 | if error_flag == 2 47 | Q_skew = NaN; 48 | return 49 | end 50 | 51 | % calculate signature 52 | Q_skew = skewness(Q); 53 | 54 | end 55 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_Q_var.m: -------------------------------------------------------------------------------- 1 | function [Q_var, error_flag, error_str] = sig_Q_var(Q, t) 2 | %sig_Q_var calculates variance of flow time series. 3 | % 4 | % INPUT 5 | % Q: streamflow [mm/timestep] 6 | % t: time [Matlab datetime] 7 | % 8 | % OUTPUT 9 | % var: variance [(mm/timestep)^2] 10 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 11 | % (error in signature calculation) 12 | % error_str: string contraining error description 13 | % 14 | % EXAMPLE 15 | % % load example data 16 | % data = load('example/example_data/33029_daily.mat'); 17 | % Q = data.Q; 18 | % t = data.t; 19 | % Q_var = sig_Q_var(Q,t); 20 | % 21 | % References 22 | % https://en.wikipedia.org/wiki/Variance 23 | % 24 | % Copyright (C) 2020 25 | % This software is distributed under the GNU Public License Version 3. 26 | % See for details. 27 | 28 | % check input parameters 29 | if nargin < 2 30 | error('Not enough input arguments.') 31 | end 32 | 33 | ip = inputParser; 34 | ip.CaseSensitive = true; 35 | 36 | % required input arguments 37 | % time series have to be numeric and either a (n,1) or a (1,n) vector 38 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 39 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 40 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 41 | 42 | parse(ip, Q, t) 43 | 44 | % data checks 45 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 46 | if error_flag == 2 47 | Q_var = NaN; 48 | return 49 | end 50 | 51 | % calculate signature 52 | Q_var = var(Q,'omitnan'); 53 | 54 | end 55 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_RR_Seasonality.m: -------------------------------------------------------------------------------- 1 | function [RR_Seasonality, error_flag, error_str] = sig_RR_Seasonality(Q, t, P, varargin) 2 | %sig_RR_Seasonality calculates seasonality of runoff ratio. 3 | % Ratio between summer and winter runoff ratio (i.e. fraction of 4 | % precipitation that leaves the watershed as flow). 5 | % 6 | % INPUT 7 | % Q: streamflow [mm/timestep] 8 | % t: time [Matlab datetime] 9 | % P: precipitation [mm/timestep] 10 | % OPTIONAL 11 | % summer_start: month when 6-month summer is deemed to start, default = 4 12 | % (April) 13 | % 14 | % OUTPUT 15 | % RR_Seasonality: ratio between summer and winter runoff ratios [-] 16 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 17 | % (error in signature calculation) 18 | % error_str: string contraining error description 19 | % 20 | % EXAMPLE 21 | % % load example data 22 | % data = load('example/example_data/33029_daily.mat'); 23 | % Q = data.Q; 24 | % t = data.t; 25 | % P = data.P; 26 | % % example for northern hemisphere when summer season starts in April 27 | % RR_seasonality = sig_RR_Seasonality(Q, t, P, 'summer_start', 4); 28 | % 29 | % Copyright (C) 2020 30 | % This software is distributed under the GNU Public License Version 3. 31 | % See for details. 32 | 33 | % check input parameters 34 | if nargin < 2 35 | error('Not enough input arguments.') 36 | end 37 | 38 | ip = inputParser; 39 | ip.CaseSensitive = true; 40 | 41 | % required input arguments 42 | % time series have to be numeric and either a (n,1) or a (1,n) vector 43 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 44 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 45 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 46 | % time series have to be numeric and either a (n,1) or a (1,n) vector 47 | addRequired(ip, 'P', @(P) isnumeric(P) && (size(P,1)==1 || size(P,2)==1)) 48 | 49 | % optional input arguments 50 | addParameter(ip, 'summer_start', 4, @isnumeric) % month when 6-month summer is deemed to start 51 | 52 | parse(ip, Q, t, P, varargin{:}) 53 | summer_start = ip.Results.summer_start; 54 | 55 | % data checks 56 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t, 'P', P); 57 | if error_flag == 2 58 | RR_Seasonality = NaN; 59 | return 60 | end 61 | 62 | % calculate signature 63 | % get summer timesteps 64 | summer_months = mod([summer_start:summer_start+5],12); 65 | summer_months(summer_months==0)=12; 66 | summer_index = find(ismember(month(t),summer_months)); 67 | winter_index = find(~ismember(month(t),summer_months)); 68 | 69 | % get summer and winter runoff ratios 70 | SummerRR = mean(Q(summer_index),'omitnan')./mean(P(summer_index),'omitnan'); 71 | WinterRR = mean(Q(winter_index),'omitnan')./mean(P(winter_index),'omitnan'); 72 | 73 | % ratio of summer and winter RRs 74 | RR_Seasonality = SummerRR/WinterRR; 75 | 76 | end 77 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_ResponseTime.m: -------------------------------------------------------------------------------- 1 | function [ResponseTime, error_flag, error_str] = sig_ResponseTime(Q, t, P, varargin) 2 | %sig_ResponseTime calculates catchment response time. 3 | % Calculates the catchment response time given a rainfall and a 4 | % streamflow time series using the DCMA method from Giani et al. (2020). 5 | % 6 | % Notes: 7 | % Works best for sub-daily data. 8 | % Can be slow if time series are long (e.g. long hourly time series). 9 | % 10 | % INPUT 11 | % Q: streamflow [mm/timestep] 12 | % t: time [Matlab datetime] 13 | % P: precipitation [mm/timestep] 14 | % OPTIONAL 15 | % max_window: Maximum window [timestep] tested. Set it sensibly according 16 | % to the resolution of your data (e.g. for hourly data, 17 | % max_window = 300 means that time of concentration can be maximum 18 | % 300hours/2 = 150hours =~ 6days). Default is 15 days. 19 | % 20 | % OUTPUT 21 | % ResponseTime: catchment response time [timestep] 22 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 23 | % (error in signature calculation) 24 | % error_str: string contraining error description 25 | % 26 | % EXAMPLE 27 | % % load example data 28 | % data = load('example/example_data/33029_daily.mat'); 29 | % Q = data.Q; 30 | % t = data.t; 31 | % P = data.P; 32 | % ResponseTime = sig_ResponseTime(Q,t,P); 33 | % 34 | % References 35 | % Giani et al., 2020. A Practical, Objective and Robust Technique to 36 | % Directly Estimate Catchment Response Time, submitted to WRR 37 | % 38 | % Copyright (C) 2020 39 | % This software is distributed under the GNU Public License Version 3. 40 | % See for details. 41 | 42 | % check input parameters 43 | if nargin < 3 44 | error('Not enough input arguments.') 45 | end 46 | 47 | ip = inputParser; 48 | ip.CaseSensitive = true; 49 | 50 | % required input arguments 51 | % time series have to be numeric and either a (n,1) or a (1,n) vector 52 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 53 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 54 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 55 | % time series have to be numeric and either a (n,1) or a (1,n) vector 56 | addRequired(ip, 'P', @(P) isnumeric(P) && (size(P,1)==1 || size(P,2)==1)) 57 | 58 | % optional input arguments 59 | addParameter(ip, 'max_window', [], @isnumeric) % maximum window [days] 60 | 61 | parse(ip, Q, t, P, varargin{:}) 62 | max_window = ip.Results.max_window; 63 | 64 | % data checks 65 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t, 'P', P); 66 | if error_flag == 2 67 | ResponseTime = NaN; 68 | return 69 | end 70 | 71 | % adjust max_window to time step 72 | if isempty(max_window) 73 | max_window = 15/days(timestep); 74 | elseif max_window < 3 || max_window > length(Q) 75 | error('Window size cannot be smaller than 3 times the timestep or larger than length of time series.') 76 | elseif max_window*days(timestep) > 100 77 | error_flag = 1; 78 | error_str = ['Warning: Window size is very large. ', error_str]; 79 | end 80 | 81 | % calculate signature 82 | P = P'; 83 | Q = Q'; 84 | P_int = cumsum(P, 'omitnan'); % cumulating rainfall time series (Eq.1) 85 | Q_int = cumsum(Q, 'omitnan'); % cumulating streamflow time series (Eq.2) 86 | len = length(P); % length of the time series 87 | 88 | % todo: intialise arrays? 89 | 90 | for w=3:2:max_window 91 | P_mean((w-1)/2,:) = movmean(P_int, w); % moving average on the integrated rainfall time series (Eq.5) 92 | Q_mean((w-1)/2,:) = movmean(Q_int, w); % moving average on the integrated streamflow time series (Eq.6) 93 | 94 | flutt_P((w-1)/2,:) = P_int-P_mean((w-1)/2,:); 95 | F_P((w-1)/2) = (1/(len-w+1))*... 96 | sum((flutt_P((w-1)/2,w-0.5*(w-1):len-0.5*(w-1))).^2,'omitnan'); % squared rainfall fluctuations (Eq.3) 97 | 98 | flutt_Q((w-1)/2,:) = Q_int-Q_mean((w-1)/2,:); 99 | F_Q((w-1)/2) = (1/(len-w+1))*... 100 | sum((flutt_Q((w-1)/2,w-0.5*(w-1):len-0.5*(w-1))).^2,'omitnan'); % squared streamflow fluctuations (Eq.4) 101 | 102 | F_PQ((w-1)/2) = (1/(len-w+1))*... 103 | sum(flutt_P((w-1)/2,w-0.5*(w-1):len-0.5*(w-1)).*... 104 | flutt_Q((w-1)/2,w-0.5*(w-1):len-0.5*(w-1)),'omitnan'); % bivariate rainfall-streamflow fluctuations (Eq.7) 105 | rho((w-1)/2) = F_PQ((w-1)/2)/(sqrt(F_P((w-1)/2))*sqrt(F_Q((w-1)/2))); % DMCA-based correlation coefficent (Eq.8) 106 | end 107 | 108 | position_minimum = find(rho==min(rho,[],'omitnan')); 109 | if isempty(position_minimum) 110 | ResponseTime = NaN; 111 | error_flag = 3; 112 | error_str = ['Error: Response time could not be calculated. ', error_str]; 113 | return 114 | else 115 | ResponseTime = position_minimum; 116 | end 117 | 118 | end -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_SnowDayRatio.m: -------------------------------------------------------------------------------- 1 | function [SnowDayRatio, error_flag, error_str] = sig_SnowDayRatio(Q, t, P, T, varargin) 2 | %sig_SnowDayRatio calculates snow day ratio. 3 | % The snow day ratio is defined as the number of days that experience 4 | % precipitation when the average daily air temperature is below 2 degC, 5 | % divided by the total number of days per year with precipitation (see 6 | % e.g. Sawicz et al., 2011). 7 | % 8 | % INPUT 9 | % Q: streamflow [mm/timestep] 10 | % t: time [Matlab datetime] 11 | % P: precipitation [mm/timestep] 12 | % T: temperature [degC] 13 | % OPTIONAL 14 | % T_threshold: temperature threshold, default = 2 degC 15 | % 16 | % OUTPUT 17 | % SnowDayRatio: snow day ratio [-] 18 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 19 | % (error in signature calculation) 20 | % error_str: string contraining error description 21 | % 22 | % EXAMPLE 23 | % % load example data 24 | % data = load('example/example_data/33029_daily.mat'); 25 | % Q = data.Q; 26 | % t = data.t; 27 | % P = data.P; 28 | % T = data.T; 29 | % SnowDayRatio = sig_SnowDayRatio(Q,t,P,T); 30 | % 31 | % References 32 | % Sawicz, K., Wagener, T., Sivapalan, M., Troch, P.A. and Carrillo, G., 33 | % 2011. Catchment classification: empirical analysis of hydrologic 34 | % similarity based on catchment function in the eastern USA. Hydrology 35 | % and Earth System Sciences, 15(9), pp.2895-2911. 36 | % 37 | % Copyright (C) 2020 38 | % This software is distributed under the GNU Public License Version 3. 39 | % See for details. 40 | 41 | % check input parameters 42 | if nargin < 4 43 | error('Not enough input arguments.') 44 | end 45 | 46 | ip = inputParser; 47 | ip.CaseSensitive = true; 48 | 49 | % required input arguments 50 | % time series have to be numeric and either a (n,1) or a (1,n) vector 51 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 52 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 53 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 54 | % time series have to be numeric and either a (n,1) or a (1,n) vector 55 | addRequired(ip, 'P', @(P) isnumeric(P) && (size(P,1)==1 || size(P,2)==1)) 56 | % time series have to be numeric and either a (n,1) or a (1,n) vector 57 | addRequired(ip, 'T', @(T) isnumeric(T) && (size(T,1)==1 || size(T,2)==1)) 58 | 59 | % optional input arguments 60 | addParameter(ip, 'T_threshold', 2, @isnumeric) % temperature threshold 61 | 62 | parse(ip, Q, t, P, T, varargin{:}) 63 | T_threshold = ip.Results.T_threshold; 64 | 65 | % data checks 66 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t, 'P', P, 'T', T); 67 | if error_flag == 2 68 | SnowDayRatio = NaN; 69 | return 70 | end 71 | 72 | % calculate signature 73 | if numel(T_threshold)~=1 74 | error('Temperature threshold has to be a single number.') 75 | elseif T_threshold<-10 || T_threshold > 10 76 | warning('Threshold should be somewhere around 0°C.') 77 | end 78 | 79 | NP = sum(P>0); 80 | NS = sum(P>0 & T for details. 44 | 45 | % check input parameters 46 | if nargin < 3 47 | error('Not enough input arguments.') 48 | end 49 | 50 | ip = inputParser; 51 | ip.CaseSensitive = true; 52 | 53 | % required input arguments 54 | % time series have to be numeric and either a (n,1) or a (1,n) vector 55 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 56 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 57 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 58 | % time series have to be numeric and either a (n,1) or a (1,n) vector 59 | addRequired(ip, 'P', @(P) isnumeric(P) && (size(P,1)==1 || size(P,2)==1)) 60 | 61 | % optional input arguments 62 | % months has to be numeric and either a (n,1) or a (1,n) vector (default: winter months northern hemisphere) 63 | addParameter(ip, 'month_range', [10:12,1:3], ... 64 | @(month_range) isnumeric(month_range) && (size(month_range,1)==1 || size(month_range,2)==1)) 65 | addParameter(ip, 'plot_results', false, @islogical) % whether to plot results 66 | 67 | parse(ip, Q, t, P, varargin{:}) 68 | month_range = ip.Results.month_range; 69 | plot_results = ip.Results.plot_results; 70 | 71 | % create empty figure handle 72 | fig_handles = []; 73 | 74 | % data checks 75 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t, 'P', P); 76 | if error_flag == 2 77 | SnowStorage = NaN; 78 | return 79 | end 80 | timestep_days = days(timestep); % adjust for timestep 81 | 82 | if any(month_range > 12) || any(month_range<1) 83 | error('month_range has to consist of values between 1 and 12.') 84 | elseif ~all(diff(month_range) == 1 | diff(month_range) == -11) 85 | error('month_range has to consist of consecutive months.') 86 | end 87 | 88 | % calculate signature 89 | % get average year 90 | [Q_avg,t_avg] = util_AverageYear(Q,t,'start_water_year',month_range(1)); 91 | [P_avg,~] = util_AverageYear(P,t,'start_water_year',month_range(1)); 92 | 93 | % calculate maximum difference between cumulative sums 94 | P_cumsum = cumsum(P_avg,'omitnan')./timestep_days; 95 | Q_cumsum = cumsum(Q_avg,'omitnan')./timestep_days; 96 | PQ_diff = P_cumsum - Q_cumsum; 97 | is_month = ismember(month(t_avg),month_range); 98 | [SnowStorage, index] = max(PQ_diff(is_month)); 99 | 100 | % TODO: other approach using inflection point in Horner et al. (2020) 101 | 102 | % optional plotting 103 | if plot_results 104 | day_of_year = 1:365; 105 | fig = figure('Position',[100 100 350 300]); hold on 106 | area(day_of_year(is_month),P_cumsum(diff(is_month)==-1)+0.*day_of_year(is_month),... 107 | 'basevalue',0,'FaceColor',[.8 .8 .8],'FaceAlpha',0.2,'EdgeColor','none'); 108 | plot(day_of_year,P_cumsum,'b','linewidth',1.5) 109 | plot(day_of_year,Q_cumsum,'r','linewidth',1.5) 110 | plot([index,index],[P_cumsum(index),Q_cumsum(index)],'k x-','linewidth',1.0) 111 | xlabel(strcat('Day of water year (starting in month',{' '},num2str(month_range(1)),')')) 112 | ylabel('Cumulative flow [mm]') 113 | legend('Considered months','P mass curve','Q mass curve','estimated snow storage','location','nw'); 114 | fig_handles.SnowStorage = fig; 115 | end 116 | 117 | end 118 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_StorageFraction.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/TOSSH_code/signature_functions/sig_StorageFraction.m -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_TemplateAdvanced.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/TOSSH_code/signature_functions/sig_TemplateAdvanced.m -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_TemplateBasic.m: -------------------------------------------------------------------------------- 1 | function [ExampleSignature, error_flag, error_str, fig_handles] = ... 2 | sig_TemplateBasic(Q, t, varargin) 3 | %sig_TemplateBasic calculates [Enter brief description of the signature]. 4 | % [Enter a more detailed description of the signature, possibly including 5 | % relevant references and information about different options.] 6 | % 7 | % INPUT 8 | % Q: streamflow [mm/timestep] 9 | % t: time [Matlab datetime] 10 | % OPTIONAL 11 | % opt_param: optional parameter 12 | % plot_results: whether to plot results, default = 0 13 | % [...] 14 | % 15 | % OUTPUT 16 | % ExampleSignature: example signature [-] 17 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 18 | % (error in signature calculation) 19 | % error_str: string contraining error description 20 | % fig_handles: figure handles to manipulate figures (empty if plotting is 21 | % not requested) 22 | % [...] 23 | % 24 | % EXAMPLE 25 | % % load example data 26 | % data = load('example/example_data/33029_daily.mat'); 27 | % Q = data.Q; 28 | % t = data.t; 29 | % ExampleSignature = sig_TemplateBasic(Q,t); 30 | % [...] 31 | % 32 | % References 33 | % [...] 34 | % 35 | % Copyright (C) 2020 36 | % This software is distributed under the GNU Public License Version 3. 37 | % See for details. 38 | 39 | % check input parameters 40 | % [Change if there is a different number of required inputs.] 41 | if nargin < 2 42 | error('Not enough input arguments.') 43 | end 44 | 45 | ip = inputParser; 46 | ip.CaseSensitive = true; 47 | 48 | % required input arguments 49 | %[Delete the input parameters you don't need.] 50 | % time series have to be numeric and either a (n,1) or a (1,n) vector 51 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 52 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 53 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 54 | % time series have to be numeric and either a (n,1) or a (1,n) vector 55 | 56 | % optional input arguments 57 | addParameter(ip, 'opt_param', false, @islogical) % optional parameter 58 | addParameter(ip, 'plot_results', false, @islogical) % whether to plot results 59 | 60 | parse(ip, Q, t, varargin{:}) %[Delete the input parameters you don't need.] 61 | opt_param = ip.Results.opt_param; 62 | plot_results = ip.Results.plot_results; 63 | 64 | % create empty figure handle 65 | fig_handles = []; 66 | 67 | % data checks 68 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); %[Delete the input parameters you don't need.] 69 | if error_flag == 2 70 | ExampleSignature = NaN; 71 | return 72 | end 73 | 74 | % [Add warnings/errors to indicate potentially problematic inputs here.] 75 | if opt_param 76 | error_flag = 1; 77 | error_str = ['Warning: You have set the optional parameter to true. ', error_str]; 78 | end 79 | 80 | % calculate signature 81 | ExampleSignature = NaN; 82 | % [Add well commented signature here.] 83 | % ... 84 | % ... 85 | 86 | % optional plotting 87 | if plot_results 88 | fig = figure('pos',[100 100 350 300]); hold on 89 | plot(ExampleSignature); 90 | fig_handles.TemplateBasic = fig; 91 | end 92 | 93 | end 94 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_TotalRR.m: -------------------------------------------------------------------------------- 1 | function [TotalRR, error_flag, error_str] = sig_TotalRR(Q, t, P) 2 | %sig_TotalRR calculates total runoff ratio. 3 | % Fraction of precipitation that leaves the catchment as flow. 4 | % 5 | % INPUT 6 | % Q: streamflow [mm/timestep] 7 | % t: time [Matlab datetime] 8 | % P: precipitation [mm/timestep] 9 | % 10 | % OUTPUT 11 | % TotalRR: total runoff ratio [-] 12 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 13 | % (error in signature calculation) 14 | % error_str: string contraining error description 15 | % 16 | % EXAMPLE 17 | % % load example data 18 | % data = load('example/example_data/33029_daily.mat'); 19 | % Q = data.Q; 20 | % t = data.t; 21 | % P = data.P; 22 | % TotalRR = sig_TotalRR(Q,t,P); 23 | % 24 | % Copyright (C) 2020 25 | % This software is distributed under the GNU Public License Version 3. 26 | % See for details. 27 | 28 | % check input parameters 29 | if nargin < 3 30 | error('Not enough input arguments.') 31 | end 32 | 33 | ip = inputParser; 34 | ip.CaseSensitive = true; 35 | 36 | % required input arguments 37 | % time series have to be numeric and either a (n,1) or a (1,n) vector 38 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 39 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 40 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 41 | % time series have to be numeric and either a (n,1) or a (1,n) vector 42 | addRequired(ip, 'P', @(P) isnumeric(P) && (size(P,1)==1 || size(P,2)==1)) 43 | 44 | parse(ip, Q, t, P) 45 | 46 | % data checks 47 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t, 'P', P); 48 | if error_flag == 2 49 | TotalRR = NaN; 50 | return 51 | end 52 | 53 | % calculate signature 54 | TotalRR = mean(Q,'omitnan')./mean(P,'omitnan'); 55 | 56 | end 57 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_VariabilityIndex.m: -------------------------------------------------------------------------------- 1 | function [VariabilityIndex, error_flag, error_str] = sig_VariabilityIndex(Q, t) 2 | %sig_VariabilityIndex calculates variability index (VI) from FDC. 3 | % VI is the standard deviation of the common logarithms of discharge 4 | % determined at 10% intervals from 10% to 90% of the cumulative frequency 5 | % distribution (flow duration curve, FDC). Low variability index shows 6 | % higher water storage (Estrany et al., 2010). 7 | % 8 | % INPUT 9 | % Q: streamflow [mm/timestep] 10 | % t: time [Matlab datetime] 11 | % 12 | % OUTPUT 13 | % VariabilityIndex: variability index [-] 14 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 15 | % (error in signature calculation) 16 | % error_str: string contraining error description 17 | % 18 | % EXAMPLE 19 | % % load example data 20 | % data = load('example/example_data/33029_daily.mat'); 21 | % Q = data.Q; 22 | % t = data.t; 23 | % VariabilityIndex = sig_VariabilityIndex(Q,t); 24 | % 25 | % References 26 | % Estrany, J., Garcia, C. and Batalla, R.J., 2010. Hydrological response 27 | % of a small mediterranean agricultural catchment. Journal of Hydrology, 28 | % 380(1-2), pp.180-190. 29 | % 30 | % Copyright (C) 2020 31 | % This software is distributed under the GNU Public License Version 3. 32 | % See for details. 33 | 34 | % check input parameters 35 | if nargin < 2 36 | error('Not enough input arguments.') 37 | end 38 | 39 | ip = inputParser; 40 | ip.CaseSensitive = true; 41 | 42 | % required input arguments 43 | % time series have to be numeric and either a (n,1) or a (1,n) vector 44 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 45 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 46 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 47 | 48 | parse(ip, Q, t) 49 | 50 | % data checks 51 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 52 | if error_flag == 2 53 | VariabilityIndex = NaN; 54 | return 55 | end 56 | 57 | % calculate signature 58 | % get ranks as a proxy for exceedance probabilities 59 | Q = Q(~isnan(Q)); % remove NaN values 60 | Q_sorted = sort(Q,'descend'); 61 | 62 | % percentiles required are 10%, 20%, ..., 90% 63 | percs = [10:10:90]; 64 | 65 | % get the corresponding rank of the FDC values 66 | indices_percs = round(length(Q_sorted).*percs./100); 67 | 68 | % get the flow value at each rank 69 | flow_percs = Q_sorted(indices_percs); 70 | 71 | % variation needed if some flow percentiles are zero for an intermittent 72 | % stream - exclude these from the calculation 73 | recs = flow_percs > 0; 74 | 75 | % add warning for intermittent streams 76 | if ~isempty(Q(Q==0)) 77 | error_flag = 2; 78 | error_str = ['Warning: Zero flows excluded from calculation. ', error_str]; 79 | end 80 | 81 | % VI is the standard deviation of the common logarithms of discharge 82 | % determined at 10% intervals from 10% to 90% of the cumulative frequency 83 | % distribution 84 | VariabilityIndex = std(log10(flow_percs(recs))); 85 | 86 | end 87 | 88 | -------------------------------------------------------------------------------- /TOSSH_code/signature_functions/sig_x_Q_duration.m: -------------------------------------------------------------------------------- 1 | function [x_Q_duration, error_flag, error_str] = sig_x_Q_duration(Q, t, type, varargin) 2 | %sig_x_Q_duration calculates various kinds of flow durations. 3 | % Calculates various kinds of flow durations, e.g. no flow duration, 4 | % high flow duration. Typical metrics can be chosen from a standard list 5 | % (no, high, low), or created manually (e.g. 0.5*median(Q)). 6 | % 7 | % INPUT 8 | % Q: streamflow [mm/timestep] 9 | % t: time [Matlab datetime] 10 | % type: type of flow duration (no, high, low, custom_high, custom_low) 11 | % OPTIONAL 12 | % threshold: flow threshold above (below) flow duration is calculated 13 | % (e.g. 9*median(Q) for high) [mm/timestep] 14 | % 15 | % OUTPUT 16 | % x_Q_dur: x flow duration [timestep] 17 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 18 | % (error in signature calculation) 19 | % error_str: string contraining error description 20 | % 21 | % EXAMPLE 22 | % % load example data 23 | % data = load('example/example_data/33029_daily.mat'); 24 | % Q = data.Q; 25 | % t = data.t; 26 | % x_Q_dur = sig_x_Q_dur(Q,t,'no'); 27 | % x_Q_dur = sig_x_Q_dur(Q,t,'high'); 28 | % x_Q_dur = sig_x_Q_dur(Q,t,'low'); 29 | % x_Q_dur = sig_x_Q_dur(Q,t,'custom_high','threshold',9*median(Q,'omitnan')); 30 | % 31 | % References 32 | % Addor, N., Nearing, G., Prieto, C., Newman, A.J., Le Vine, N. and 33 | % Clark, M.P., 2018. A ranking of hydrological signatures based on their 34 | % predictability in space. Water Resources Research, 54(11), pp.8792-8812. 35 | % 36 | % Copyright (C) 2020 37 | % This software is distributed under the GNU Public License Version 3. 38 | % See for details. 39 | 40 | % check input parameters 41 | if nargin < 3 42 | error('Not enough input arguments.') 43 | end 44 | 45 | ip = inputParser; 46 | ip.CaseSensitive = true; 47 | 48 | % required input arguments 49 | % time series have to be numeric and either a (n,1) or a (1,n) vector 50 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 51 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 52 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 53 | % type has to be char and only one word 54 | addRequired(ip, 'type', @(type) ischar(type) && size(type,1)==1) 55 | 56 | % optional input arguments 57 | addParameter(ip, 'threshold', [], @isnumeric) % flow threshold 58 | 59 | parse(ip, Q, t, type, varargin{:}) 60 | threshold = ip.Results.threshold; 61 | 62 | % data checks 63 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 64 | if error_flag == 2 65 | x_Q_duration = NaN; 66 | return 67 | end 68 | 69 | % calculate signature 70 | switch type 71 | 72 | case 'no' 73 | no_Q = Q==0; 74 | % find consecutive timesteps with no flows 75 | start1 = strfind([0,no_Q'],[0 1]); 76 | end1 = strfind([no_Q',0],[1 0]); 77 | interval_lengths = end1 - start1 + 1; 78 | 79 | case 'high' 80 | Q_high = 9*median(Q,'omitnan'); 81 | high_Q = Q>Q_high; 82 | % find consecutive timesteps with high flows 83 | start1 = strfind([0,high_Q'],[0 1]); 84 | end1 = strfind([high_Q',0],[1 0]); 85 | interval_lengths = end1 - start1 + 1; 86 | 87 | case 'low' 88 | Q_low = 0.2*mean(Q,'omitnan'); 89 | low_Q = Q 1 97 | error('No/wrong custom threshold specified.') 98 | end 99 | custom_Q = Q>threshold; 100 | % find consecutive timesteps above x flows 101 | start1 = strfind([0,custom_Q'],[0 1]); 102 | end1 = strfind([custom_Q',0],[1 0]); 103 | interval_lengths = end1 - start1 + 1; 104 | 105 | case 'custom_low' 106 | if isempty(threshold) || numel(threshold) > 1 107 | error('No/wrong custom threshold specified.') 108 | end 109 | custom_Q = Q for details. 39 | 40 | % check input parameters 41 | if nargin < 3 42 | error('Not enough input arguments.') 43 | end 44 | 45 | ip = inputParser; 46 | ip.CaseSensitive = true; 47 | 48 | % required input arguments 49 | % time series have to be numeric and either a (n,1) or a (1,n) vector 50 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 51 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 52 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 53 | % type has to be char and only one word 54 | addRequired(ip, 'type', @(type) ischar(type) && size(type,1)==1) 55 | 56 | % optional input arguments 57 | addParameter(ip, 'threshold', [], @isnumeric) % flow threshold 58 | 59 | parse(ip, Q, t, type, varargin{:}) 60 | threshold = ip.Results.threshold; 61 | 62 | % data checks 63 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 64 | if error_flag == 2 65 | x_Q_frequency = NaN; 66 | return 67 | end 68 | 69 | % calculate signature 70 | 71 | len = length(Q(~isnan(Q))); % total amount of non-NaN values 72 | 73 | switch type 74 | 75 | case 'no' 76 | x_Q_num = length(Q(Q==0)); 77 | x_Q_frequency = x_Q_num/len; 78 | 79 | case 'high' 80 | Q_high = 9*median(Q,'omitnan'); 81 | x_Q_num = length(Q(Q>Q_high)); 82 | x_Q_frequency = x_Q_num/len; 83 | 84 | case 'low' 85 | Q_low = 0.2*mean(Q,'omitnan'); 86 | x_Q_num = length(Q(Q 1 91 | error('No/wrong custom threshold specified.') 92 | end 93 | x_Q_num = length(Q(Q>threshold)); 94 | x_Q_frequency = x_Q_num/len; 95 | 96 | case 'custom_low' 97 | if isempty(threshold) || numel(threshold) > 1 98 | error('No/wrong custom threshold specified.') 99 | end 100 | x_Q_num = length(Q(Q for details. 33 | 34 | % check input parameters 35 | if nargin < 3 36 | error('Not enough input arguments.') 37 | end 38 | 39 | ip = inputParser; 40 | ip.CaseSensitive = true; 41 | 42 | % required input arguments 43 | % time series have to be numeric and either a (n,1) or a (1,n) vector 44 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 45 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 46 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 47 | % x has to be numeric and either a (n,1) or a (1,n) vector 48 | addRequired(ip, 'x', @(x) isnumeric(x) && (size(x,1)==1 || size(x,2)==1)) 49 | 50 | parse(ip, Q, t, x) 51 | 52 | % data checks 53 | [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 54 | if error_flag == 2 55 | Q_x = NaN; 56 | return 57 | end 58 | 59 | if any(x>100) || any(x<0) 60 | error('x must be between 0 and 100.') 61 | end 62 | 63 | % calculate signature 64 | p = 1 - x./100; % transform to get exceedance probability 65 | 66 | % get ranks as a proxy for exceedance probabilities 67 | Q_tmp = Q(~isnan(Q)); % remove NaN values 68 | Q_sorted = sort(Q_tmp); 69 | Q_ranked = [1:length(Q_tmp)]'; % give unique (random) rank to every measurement 70 | FDC = 1 - Q_ranked./length(Q_ranked); % flow duration curve 71 | 72 | % find x-th flow percentile 73 | indices = 1:length(FDC); 74 | bound_x = NaN(size(p)); 75 | for i = 1:length(p) 76 | % if flow is highly ephemeral, FDC might not be well defined 77 | if isempty(max(indices(FDC >= p(i)))) 78 | else 79 | bound_x(i) = max(indices(FDC >= p(i))); 80 | end 81 | end 82 | 83 | Q_x = NaN(size(p)); 84 | Q_x(~isnan(bound_x)) = Q_sorted(bound_x(~isnan(bound_x))); 85 | 86 | % add warning for intermittent streams 87 | if ~isempty(Q_tmp(Q_tmp==0)) 88 | error_flag = 2; 89 | error_str = ['Warning: Flow is zero at least once (intermittent flow). ', error_str]; 90 | end 91 | 92 | end 93 | -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/nanxcov.m: -------------------------------------------------------------------------------- 1 | function [xycov,lags,nanp] = nanxcov(x,y,option1,option2) 2 | 3 | % NANXCOV Cross-covariance function estimates. Skips NaNs. 4 | % XCOV(A,B), where A and B are length M vectors, returns the 5 | % length 2*M-1 cross-covariance sequence in a column vector. 6 | % 7 | % XCOV(A), when A is a vector, is the auto-covariance sequence. 8 | % XCOV(A), when A is an M-by-N matrix, is a large matrix with 9 | % 2*M-1 rows whose N^2 columns contain the cross-covariance 10 | % sequences for all combinations of the columns of A. 11 | % The zeroth lag of the output covariance is in the middle of the 12 | % sequence, at element or row M. 13 | % 14 | % The cross-covariance is the cross-correlation function of 15 | % two sequences with their means removed: 16 | % C(m) = E[(A(n+m)-MA)*conj(B(n)-MB)] 17 | % where MA and MB are the means of A and B respectively. 18 | % 19 | % XCOV(...,MAXLAG) computes the (auto/cross) covariance over the 20 | % range of lags: -MAXLAG to MAXLAG, i.e., 2*MAXLAG+1 lags. 21 | % If missing, default is MAXLAG = M-1. 22 | % 23 | % [C,LAGS] = XCOV(...) returns a vector of lag indices (LAGS). 24 | % 25 | % XCOV(...,SCALEOPT), normalizes the covariance according to SCALEOPT: 26 | % biased - scales the raw cross-covariance by 1/M. 27 | % unbiased - scales the raw covariance by 1/(M-abs(k)), where k 28 | % is the index into the result. 29 | % coeff - normalizes the sequence so that the covariances at 30 | % zero lag are identically 1.0. 31 | % none - no scaling (this is the default). 32 | % 33 | % See also XCORR, CORRCOEF, CONV, COV and XCORR2. 34 | 35 | % Author(s): L. Shure, 1-9-88 36 | 37 | 38 | 39 | % skips NaNs, P. Sturm, 10-Nov-2008 40 | % outputs isnan vector of skipped NaNs, P. Sturm, 9-Nov-2009 41 | 42 | % References: 43 | % [1] J.S. Bendat and A.G. Piersol, "Random Data: 44 | % Analysis and Measurement Procedures", John Wiley 45 | % and Sons, 1971, p.332. 46 | % [2] A.V. Oppenheim and R.W. Schafer, Digital Signal 47 | % Processing, Prentice-Hall, 1975, pg 539. 48 | 49 | nanx = isnan(x); 50 | nany = isnan(y); 51 | if nargin == 1 52 | x(nanx) = []; 53 | mx = size(x, 1); 54 | [xycov,l] = xcorr(x-ones(mx,1)*mean(x)); 55 | nanp = nanx; 56 | elseif nargin == 2 57 | x(nanx|nany) = []; 58 | y(nanx|nany) = []; 59 | mx = size(x, 1); 60 | if ischar(y)||(~ischar(y)&&length(y)==1) 61 | [xycov,l] = xcorr(x-ones(mx,1)*mean(x),y); 62 | else 63 | my = size(y, 1); 64 | [xycov,l] = xcorr(x-ones(mx,1)*mean(x),y-ones(my,1)*mean(y)); 65 | end 66 | nanp = (nanx|nany); 67 | elseif nargin == 3 68 | x(nanx|nany) = []; 69 | y(nanx|nany) = []; 70 | mx = size(x, 1); 71 | my = size(y, 1); 72 | if length(y)==1 73 | [xycov,l] = xcorr(x-ones(mx,1)*mean(x),y,option1); 74 | else 75 | [xycov,l] = xcorr(x-ones(mx,1)*mean(x),y-ones(my,1)*mean(y),option1); 76 | end 77 | nanp = (nanx|nany); 78 | elseif nargin == 4 79 | x(nanx|nany) = []; 80 | y(nanx|nany) = []; 81 | mx = size(x, 1); 82 | my = size(y, 1); 83 | [xycov,l] = xcorr(x-ones(mx,1)*mean(x),y-ones(my,1)*mean(y),... 84 | option1,option2); 85 | nanp = (nanx|nany); 86 | end 87 | if nargout > 1 88 | lags = l; 89 | end -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_AggregateTimeSeries.m: -------------------------------------------------------------------------------- 1 | function [X_annual, X_monthly, year_list, days_per_year, error_flag, error_str] = ... 2 | util_AggregateTimeSeries(X, t, start_water_year) 3 | %util_AggregateTimeSeries calculates annual and monthly sums of time series. 4 | % Start of water year can be specified so that the average is taken over 5 | % a water year. 6 | % 7 | % INPUT 8 | % X: time series - should be continuous (e.g. Q, typically [mm/timestep]) 9 | % t: time [Matlab datetime] 10 | % start_water_year: first month of water year, default = 1 (January) 11 | % 12 | % OUTPUT 13 | % X_annual: annual sums [mm/year] 14 | % X_monthly: monthly sums [mm/month] 15 | % year_list: corresponding years 16 | % days_per_year: amount of non-NaN days per year 17 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 18 | % (error in signature calculation) 19 | % error_str: string contraining error description 20 | % 21 | % EXAMPLE 22 | % % load example data 23 | % data = load('example/example_data/33029_daily.mat'); 24 | % Q = data.Q; 25 | % t = data.t; 26 | % start_water_year = 10; 27 | % [Q_annual, Q_monthly, year_list, leap_year] = ... 28 | % util_AggregateTimeSeries(Q, t, start_water_year); 29 | % 30 | % Copyright (C) 2020 31 | % This software is distributed under the GNU Public License Version 3. 32 | % See for details. 33 | 34 | if nargin < 3 35 | start_water_year = 1; 36 | end 37 | 38 | % default setting reads as good data 39 | error_flag = 0; 40 | error_str = ''; 41 | 42 | % get years and months 43 | [year_vec, month_vec, day_vec] = ymd(t); 44 | 45 | if start_water_year == 1 46 | % calendar year 47 | year_start = min(year_vec); 48 | year_end = max(year_vec); 49 | else 50 | % water year always corresponds to the last day of the water year, 51 | % e.g. water year starting from 1 October 1999 is water year 2000 52 | year_start = min(year_vec)+1; 53 | year_end = max(year_vec); 54 | end 55 | year_list = [year_start:year_end]'; 56 | 57 | if month_vec(1) ~= start_water_year && day_vec(1)~=1 58 | error_flag = 1; 59 | error_str = ['Warning: Time series and water year do not match. Incomplete years possible. ', error_str]; 60 | elseif month_vec(end) ~= start_water_year-1 && day_vec(end)<28 61 | error_flag = 1; 62 | error_str = ['Warning: Time series and water year do not match. Incomplete years possible. ', error_str]; 63 | end 64 | 65 | X_annual = NaN(year_end-year_start,1); 66 | X_monthly = NaN(year_end-year_start,12); 67 | days_per_year = NaN(size(year_list)); 68 | 69 | % extract years and months 70 | for y = 1:length(year_list) 71 | year = year_list(y); 72 | X_water_year = ... 73 | [X(year_vec==year-1 & month_vec>=start_water_year); ... 74 | X(year_vec==year & month_vec for details. 29 | 30 | % check input parameters 31 | if nargin < 2 32 | error('Not enough input arguments.') 33 | end 34 | 35 | ip = inputParser; 36 | ip.CaseSensitive = true; 37 | 38 | % required input arguments 39 | % time series have to be numeric and either a (n,1) or a (1,n) vector 40 | addRequired(ip, 'X', @(X) isnumeric(X) && (size(X,1)==1 || size(X,2)==1)) 41 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 42 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 43 | 44 | % optional input arguments 45 | validationFcn = @(x) isnumeric(x) && isscalar(x) && (x >= 1) && (x <= 12) && floor(x)==x; 46 | addParameter(ip, 'start_water_year', 1, validationFcn) % when does the water year start? 47 | addParameter(ip, 'plot_results', false, @islogical) % whether to plot results 48 | 49 | parse(ip, X, t, varargin{:}) 50 | start_water_year = ip.Results.start_water_year; 51 | plot_results = ip.Results.plot_results; 52 | 53 | % create empty figure handle 54 | fig_handles = []; 55 | 56 | % calculate average year 57 | months = [start_water_year:12, 1:start_water_year-1]'; 58 | n_days = [31 28 31 30 31 30 31 31 30 31 30 31]'; 59 | 60 | X_avg = NaN(365,1); 61 | t_avg = NaN(365,3); 62 | index = 1; 63 | 64 | % loop over months 65 | day_vec = day(t); 66 | month_vec = month(t); 67 | for i = 1:12 68 | m = months(i); 69 | % loop over days 70 | for d = 1:n_days(m) 71 | % X_avg(index) = mean(X(day_vec == d & month_vec == m),'omitnan'); 72 | X_tmp = X(day_vec == d & month_vec == m); 73 | X_avg(index) = sum(X_tmp,'omitnan')/length(X_tmp); 74 | t_avg(index,:) = [0,m,d]; % dummy year 75 | index = index + 1; 76 | end 77 | end 78 | t_avg = datetime(t_avg); % dummy year 79 | 80 | % optional plotting 81 | if plot_results 82 | fig = figure('pos',[100 100 350 300]); hold on 83 | plot(t_avg,X_avg,'.') 84 | xlabel('Day') 85 | ylabel('Mean on that day [mm/timestep]') 86 | fig_handles.AverageYear = fig; 87 | end 88 | 89 | end 90 | -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_ExtractSubPeriod.m: -------------------------------------------------------------------------------- 1 | function [X_sub, t_sub] = util_ExtractSubPeriod(X, t, subperiod, option) 2 | %util_ExtractSubPeriod extracts subperiod (months) from time series. 3 | % Extracts certain months from time series, e.g. the low flow season and 4 | % the high flow season. See also Euser et al. (2013) who use May to 5 | % September as low flow season and November to April as high flow season. 6 | % 7 | % INPUT 8 | % X: time series - should be continuous (e.g. Q, typically [mm/timestep]) 9 | % t: time [Matlab datetime] 10 | % subperiod: subperiod to be extracted, e.g. [11:12, 1:4] for November 11 | % to April or [5:9] for May to September 12 | % OPTIONAL 13 | % option: option to delete values outside subperiod ('delete') or assign 14 | % NaN to values outside subperiod ('nan') 15 | % 16 | % OUTPUT 17 | % X_sub: subperiod time series 18 | % t_sub: subperiod time 19 | % 20 | % EXAMPLE 21 | % % load example data 22 | % data = load('example/example_data/33029_daily.mat'); 23 | % Q = data.Q; 24 | % t = data.t; 25 | % subperiod = [11:12, 1:4]; 26 | % [Q_sub, t_sub] = ... 27 | % util_ExtractSubPeriod(Q, t, subperiod); 28 | % 29 | % References 30 | % Euser, T., Winsemius, H.C., Hrachowitz, M., Fenicia, F., Uhlenbrook, S. 31 | % and Savenije, H.H.G., 2013. A framework to assess the realism of model 32 | % structures using hydrological signatures. Hydrology and Earth System 33 | % Sciences, 17 (5), 2013. 34 | % 35 | % Copyright (C) 2020 36 | % This software is distributed under the GNU Public License Version 3. 37 | % See for details. 38 | 39 | if nargin < 4 40 | option = 'delete'; 41 | end 42 | 43 | % get months 44 | [~, month_vec, ~] = ymd(t); 45 | 46 | if strcmp(option,'delete') 47 | % option 1 - delete values outside subperiod 48 | t_sub = t(ismember(month_vec,subperiod)); 49 | X_sub = X(ismember(month_vec,subperiod)); 50 | elseif strcmp(option,'nan') 51 | % option 2 - assign NaN to values outside subperiod 52 | t_sub = t; 53 | X_sub = X; 54 | X_sub(ismember(month_vec,subperiod)) = NaN; 55 | else 56 | error('Subperiod option specified incorrectly, the options are delete or nan.') 57 | end 58 | 59 | %{ 60 | figure; hold on; 61 | plot(t,X); 62 | plot(t_sub,X_sub,'--') 63 | xlabel('Date') 64 | ylabel('Flow') 65 | %} 66 | 67 | end -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_FitBrokenStick.m: -------------------------------------------------------------------------------- 1 | function [err, fittedlines, slopes] = ... 2 | util_FitBrokenStick(breakpoints, x, y, zero_intercept) 3 | %util_FitBrokenStick fits two or three part broken stick fit. 4 | % Fits two or three part broken stick fit (segmented regression) with 5 | % known break points. Returns norm of residuals to be used for 6 | % optimisation. 7 | % Adapted from online example by John D'Errico. 8 | % 9 | % INPUT 10 | % breakpoints: breakpoints of broken stick (1 or 2 breakpoints) 11 | % x: independent variable 12 | % y: dependent variable 13 | % OPTIONAL 14 | % zero_intercept: should the intercept be 0?, default = false 15 | % 16 | % OUTPUT 17 | % err: norm of residuals 18 | % fittedlines: start points and break points of fitted lines 19 | % slopes: slopes of the linear segments of the broken stick 20 | % 21 | % EXAMPLE 22 | % x = [1:10]'; 23 | % y = zeros(size(x)); 24 | % y(1:5) = 2*x(1:5); 25 | % y(6:10) = y(5) + 0.5*(x(6:10)-5); 26 | % breakpoints = 5; 27 | % [err,fittedlines,slopes] = util_FitBrokenStick(breakpoints,x,y) 28 | % 29 | % Copyright (C) 2020 30 | % This software is distributed under the GNU Public License Version 3. 31 | % See for details. 32 | 33 | if nargin < 3 34 | error('Not enough input arguments.') 35 | end 36 | if nargin < 4 37 | zero_intercept = false; 38 | end 39 | 40 | breakpoints = breakpoints(:).'; % make breakpoints into row vector 41 | 42 | breaks = [min(x),sort(breakpoints),max(x)]; 43 | nx = length(x); 44 | % which points lie in which interval? 45 | xbins = discretize(x,breaks); 46 | % breakpoints cannot be in the same interval 47 | if numel(unique(xbins)) < numel(breakpoints) + 1 48 | err = 10^6; 49 | fittedlines = NaN(length(breakpoints)+2,2); 50 | slopes = NaN(length(breakpoints)+2,1); 51 | return 52 | end 53 | 54 | % write the problem in matrix form 55 | if zero_intercept % intercept is zero 56 | if numel(breakpoints)==1 57 | A = [x - breaks(1),(x - breaks(2)).*(xbins == 2)]; 58 | elseif numel (breakpoints)==2 59 | A = [x - breaks(1),(x - breaks(2)).*(or(xbins == 2,xbins == 3)),(x - breaks(3)).*(xbins == 3)]; 60 | else 61 | error('Function brokenstick only works for 1 or 2 breakpoints.') 62 | end 63 | else % intercept will be optimised as well 64 | if numel(breakpoints)==1 65 | A = [ones(nx,1),x - breaks(1),(x - breaks(2)).*(xbins == 2)]; 66 | elseif numel (breakpoints)==2 67 | A = [ones(nx,1),x - breaks(1),(x - breaks(2)).*(or(xbins == 2,xbins == 3)),(x - breaks(3)).*(xbins == 3)]; 68 | else 69 | error('Function brokenstick only works for 1 or 2 breakpoints.') 70 | end 71 | end 72 | 73 | % solve matrix 74 | coef = A\y; 75 | err = norm(y - A*coef); 76 | if zero_intercept 77 | coef = [0; coef]; 78 | end 79 | 80 | % unpack the coefficients 81 | c1 = coef(1); 82 | s = [coef(2:end)]; 83 | css = cumsum(s); 84 | s = [s;s(end)]; 85 | css = [css;css(end)]; 86 | bi = [breaks(1:end-1).';breaks(end-1)]; 87 | fittedlines = zeros(length(breaks),2); 88 | slopes = zeros(length(breaks),1); 89 | fittedlines(:,1) = breaks.'; 90 | fittedlines(1:2,2) = (c1 - breaks(1).*s(1)) + s(1).*breaks(1:2).'; 91 | fittedlines(3,2) = (c1 - breaks(1).*s(1) - breaks(2).*s(2)) + (s(1)+s(2)).*breaks(3).'; 92 | if numel (breakpoints)==2 93 | fittedlines(4,2) = (c1 - sum(breaks(1:3).'.*s(1:3))) + sum(s(1:3)).*breaks(4).'; 94 | end 95 | slopes = cumsum(s);slopes=slopes(1:end-1); 96 | 97 | end 98 | 99 | 100 | -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_FitExponential.m: -------------------------------------------------------------------------------- 1 | function [gamma] = util_FitExponential(Q, t, fitting_type) 2 | %util_FitExponential fits an exponential function to recession segments. 3 | % Different types of functions and fitting options are available. 4 | % Q = Q0*exp(-gamma*t) (either linear regression in semilog space or 5 | % nonlinear fit) 6 | % Q = b*exp(-gamma*t) (nonlinear two-parameter fit) 7 | % Q = a+b*exp(-gamma*t) (nonlinear three-parameter fit) 8 | % Note that the non-linear fitting methods are much slower. 9 | % 10 | % INPUT 11 | % Q: dependent variable, typically streamflow in [mm/timestep] 12 | % t: independent variable, typically time 13 | % OPTIONAL 14 | % fitting_type: what kind of exponential function to fit ('semilog', 15 | % 'nonlinear', 'nonlinear2', 'nonlinear3') 16 | % 17 | % OUTPUT 18 | % gamma: fitted parameter of exponential function, typically [1/timestep] 19 | % 20 | % EXAMPLE 21 | % t = [0:10]'; 22 | % Q = exp(-0.1*t); 23 | % [gamma] = util_FitExponential(Q, t); 24 | % 25 | % Copyright (C) 2020 26 | % This software is distributed under the GNU Public License Version 3. 27 | % See for details. 28 | 29 | if nargin < 3 30 | fitting_type = 'semilog'; 31 | end 32 | 33 | t = [0:length(t)-1]'; % start of recession equals start of exponential 34 | 35 | switch fitting_type 36 | 37 | case 'semilog' 38 | Q = Q(:); % make sure that Q is a column vector 39 | gamma = -t\(log(Q)-log(Q(1))); 40 | 41 | case 'nonlinear' 42 | ExponentialObjective = @(para) Q(1).*exp(-para(1).*t) - Q; 43 | para0 = [0.1]; 44 | options = optimoptions(@lsqnonlin,'Display','off'); 45 | para = lsqnonlin(ExponentialObjective, para0, [1e-6], [100], options); 46 | gamma = para(1); 47 | 48 | case 'nonlinear2' 49 | ExponentialObjective = @(para) para(2).*exp(-para(1).*t) - Q; 50 | para0 = [0.1 0.1]; 51 | options = optimoptions(@lsqnonlin,'Display','off'); 52 | para = lsqnonlin(ExponentialObjective, para0, [1e-6 1e-6], [100 100], options); 53 | gamma = para(1); 54 | 55 | case 'nonlinear3' 56 | ExponentialObjective = @(para) para(2) + para(3).*exp(-para(1).*t) - Q; 57 | para0 = [0.1 0.1 0.1]; 58 | options = optimoptions(@lsqnonlin,'Display','off'); 59 | para = lsqnonlin(ExponentialObjective, para0, [1e-6 1e-6 1e-6], [100 100 100], options); 60 | gamma = para(1); 61 | 62 | otherwise 63 | error('Please choose one of the available fitting types: a or b.') 64 | end 65 | 66 | 67 | % plot 68 | %{ 69 | figure; plot(t,Q,'o'); hold on 70 | switch fitting_type 71 | case 'nonlinear2' 72 | b = para(2); 73 | gamma = para(1); 74 | Q_est = b*exp(t.*-gamma); 75 | case 'nonlinear3' 76 | a = para(2); 77 | b = para(3); 78 | gamma = para(1); 79 | Q_est = a+b*exp(t.*-gamma); 80 | otherwise 81 | Q_est = Q(1)*exp(t.*-gamma); 82 | end 83 | plot(t,Q_est) 84 | %} 85 | 86 | end -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_FitLinear.m: -------------------------------------------------------------------------------- 1 | function [a, b, R2] = util_FitLinear(x,y) 2 | %util_FitLinear fits linear function and returns parameters and residuals. 3 | % y = a + b*x; 4 | % 5 | % INPUT 6 | % x: independent variable 7 | % y: dependent variable 8 | % 9 | % OUTPUT 10 | % a: offset parameter 11 | % b: slope parameter 12 | % R2: residuals 13 | % 14 | % EXAMPLE 15 | % x = [0:5]'; 16 | % y = 1 + 2*x; 17 | % [a, b, R2] = util_FitLinear(x,y) 18 | % 19 | % Copyright (C) 2020 20 | % This software is distributed under the GNU Public License Version 3. 21 | % See for details. 22 | 23 | x = x(:); % make sure that x and y are column vectors 24 | y = y(:); 25 | 26 | n = length(x); 27 | SSxy = sum(x.*y) - sum(x)*sum(y)/n; 28 | SSxx = sum(x.^2) - sum(x)^2/n; 29 | b = SSxy/SSxx; 30 | % a = mean(y) - b*mean(x); 31 | a = sum(y)/n - b*(sum(x)/n); 32 | y_hat = a + b*x; 33 | R2 = 1 - sum((y - y_hat).^2)./sum((y - sum(y)/n).^2); 34 | 35 | % A = [ones(size(x)), x]; 36 | % P = A\y; 37 | % a = P(1); 38 | % b = P(2); 39 | % y_hat = a + b*x; 40 | % R2 = 1 - sum((y - y_hat).^2)./sum((y - sum(y)/length(y)).^2); 41 | 42 | end 43 | -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_FitPowerLaw.m: -------------------------------------------------------------------------------- 1 | function [a, b, error_flag, error_str] = ... 2 | util_FitPowerLaw(Q_rec, dQdt_rec, fitting_type, weights) 3 | %util_FitPowerLaw fits a power law (to recession segments). 4 | % dQ/dt = -a*Q^b 5 | % Different options are available (e.g. linear fitting in loglog-space, 6 | % non-linear, or fitting a fixed slope). 7 | % 8 | % INPUT 9 | % Q_rec: streamflow (recession periods only) 10 | % dQdt_rec: corresponding flow rate gradients 11 | % fitting_type: specifies fitting procedure: linear, non-linear, linear 12 | % with slope 1, linear with slope 2 13 | % weights: weights to fit curve 14 | % 15 | % OUTPUT 16 | % a: scaling parameter 17 | % b: parameter of non-linearity 18 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 19 | % (error in signature calculation) 20 | % error_str: string contraining error description 21 | % 22 | % EXAMPLE 23 | % % load example data 24 | % data = load('example/example_data/33029_daily.mat'); 25 | % Q = data.Q; 26 | % t = data.t; 27 | % flow_section = util_RecessionSegments(Q,t,'plot_results',true); % get recession segments 28 | % [dQdt, Qm, flow_section, R2] = util_dQdt(Q, t, flow_section); % get flow rate gradient 29 | % rec = ~isnan(Qm); 30 | % [a, b] = util_FitPowerLaw(Qm(rec), dQdt(rec)); 31 | % [a, b] = util_FitPowerLaw(Qm(rec), dQdt(rec), 'fitting_type', 'linear', 'weights', R2(rec)) 32 | % 33 | % Copyright (C) 2020 34 | % This software is distributed under the GNU Public License Version 3. 35 | % See for details. 36 | 37 | if nargin < 2 38 | error('Not enough input arguments.') 39 | elseif nargin < 3 40 | fitting_type = 'linear'; 41 | elseif nargin < 4 42 | weights = ones(size(Q_rec)); 43 | end 44 | 45 | % default setting reads as good data 46 | error_flag = 0; 47 | error_str = ''; 48 | 49 | % data checks 50 | if all(isnan(Q_rec)) || all(isnan(dQdt_rec)) 51 | a = NaN; 52 | b = NaN; 53 | error_flag = 1; 54 | error_str = ['Warning: Some recessions consist only of NaN values (possibly because eps > 0). ', error_str]; 55 | return 56 | end 57 | 58 | if strcmp(fitting_type, 'linear') % weighted linear regression in log log space 59 | 60 | A = [ones(size(Q_rec)), log(Q_rec)]; 61 | P = (weights.*A)\(weights.*log(-dQdt_rec)); 62 | a = exp(P(1)); 63 | b = P(2); 64 | 65 | %{ 66 | linFcn = @(p,x) p(2).*x + p(1); 67 | p0 = [0.1, 1.0]; 68 | fit_nonlin = fitnlm(log(Q_rec),log(-dQdt_rec),linFcn,p0,'Weight',weights); 69 | a = exp(fit_nonlin.Coefficients.Estimate(1)); 70 | b = fit_nonlin.Coefficients.Estimate(2); 71 | %} 72 | 73 | elseif strcmp(fitting_type, 'nonlinear') % weighted nonlinear regression in lin space 74 | 75 | powerFcn = @(p,x) p(1).*x.^p(2); 76 | p0 = [0.1, 1.0]; 77 | fit_nonlin = fitnlm(Q_rec,-dQdt_rec,powerFcn,p0,'Weight',weights); 78 | a = fit_nonlin.Coefficients.Estimate(1); 79 | b = fit_nonlin.Coefficients.Estimate(2); 80 | 81 | elseif strcmp(fitting_type, 'slope1') % linear regression in log log space with fixed slope 1 82 | 83 | A = [ones(size(Q_rec))]; 84 | b = 1; 85 | B = log(-dQdt_rec) - b*log(Q_rec); 86 | a = exp((weights.*A)\(weights.*B)); 87 | 88 | elseif strcmp(fitting_type, 'slope2') % linear regression in log log space with fixed slope 2 89 | 90 | A = [ones(size(Q_rec))]; 91 | b = 2; 92 | B = log(-dQdt_rec) - b*log(Q_rec); 93 | a = exp((weights.*A)\(weights.*B)); 94 | else 95 | error('Invalid fitting type.') 96 | end 97 | 98 | end 99 | 100 | 101 | -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_FitSineCurve.m: -------------------------------------------------------------------------------- 1 | function [A, phi, k] = util_FitSineCurve(x, y, w) 2 | %util_FitSineCurve fits sine curve to time series. 3 | % y = A*sin(w*x + phi) + k; 4 | % 5 | % INPUT 6 | % x: independent variable (typically time) 7 | % y: dependent variable (typically flow) 8 | % w: angular frequency 9 | % 10 | % OUTPUT 11 | % A: amplitude 12 | % phi: phase 13 | % k: offset 14 | % 15 | % EXAMPLE 16 | % x = [0:5*365]'; 17 | % w = 2*pi/365; 18 | % y = 1 + sin(w.*x + pi/2); 19 | % [A,phi,k] = util_FitSineCurve(x,y,w) 20 | % 21 | % Copyright (C) 2020 22 | % This software is distributed under the GNU Public License Version 3. 23 | % See for details. 24 | 25 | % create matrix 26 | M = ones(length(x),3); 27 | M(:,2) = cos(w*x); 28 | M(:,3) = sin(w*x); 29 | 30 | % change NaN values to median for linear regression 31 | % y(isnan(y)) = median(y,'omitnan'); 32 | 33 | % solve equation system 34 | b = M\y; 35 | 36 | % get estimated sine curve parameters 37 | phi = atan2(b(2),b(3)); % get unambigous value for phi 38 | A = sqrt(b(2)^2+b(3)^2); 39 | k = b(1); 40 | 41 | %{ 42 | % get estimated sine curve 43 | y_hat = A*sin(w*x + phi) + k; 44 | figure; 45 | plot(x,y); hold on 46 | plot(x,y_hat,'r --') 47 | %} 48 | 49 | end -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_LyneHollickFilter.m: -------------------------------------------------------------------------------- 1 | function [Q_b] = util_LyneHollickFilter(Q, varargin) 2 | %util_LyneHollickFilter estimates baseflow using the Lyne-Hollick filter. 3 | % Estimates baseflow using the Lyne and Hollick recursive digital filter 4 | % (Lyne and Hollick, 1979). 5 | % 6 | % INPUT 7 | % Q: streamflow [mm/timestep] 8 | % OPTIONAL 9 | % filter_parameter: filter parameter, default = 0.925 10 | % nr_passes: number of passes (default = 1; forwards) 11 | % threshold_type: how to threshold resulting time series (default = at 12 | % end of all passes (end); other options are after each pass (pass), 13 | % or after each timestep (timestep), or no thresholding (none)) 14 | % 15 | % OUTPUT 16 | % Q_b: baseflow [mm/timestep] 17 | % 18 | % EXAMPLE 19 | % % load example data 20 | % data = load('example/example_data/33029_daily.mat'); 21 | % Q = data.Q; 22 | % t = data.t; 23 | % Q_b = util_LyneHollickFilter(Q); 24 | % Q_b1 = util_LyneHollickFilter(Q, 'filter_parameter', 0.925, 'nr_passes', 1); 25 | % 26 | % References 27 | % Lyne, V. and Hollick, M., 1979. Stochastic time-variable 28 | % rainfall-runoff modelling. In Institute of Engineers Australia National 29 | % Conference (Vol. 1979, pp. 89-93). Barton, Australia: Institute of 30 | % Engineers Australia. 31 | % Su, C.H., Costelloe, J.F., Peterson, T.J. and Western, A.W., 2016. On 32 | % the structural limitations of recursive digital filters for base flow 33 | % estimation. Water Resources Research, 52(6), pp.4745-4764. 34 | % Ladson, A.R., Brown, R., Neal, B. and Nathan, R., 2013. A standard 35 | % approach to baseflow separation using the Lyne and Hollick filter. 36 | % Australasian Journal of Water Resources, 17(1), pp.25-34. 37 | % 38 | % Copyright (C) 2020 39 | % This software is distributed under the GNU Public License Version 3. 40 | % See for details. 41 | 42 | % check input parameters 43 | if nargin < 1 44 | error('Not enough input arguments.') 45 | end 46 | 47 | ip = inputParser; 48 | ip.CaseSensitive = true; 49 | 50 | % required input arguments 51 | % time series have to be numeric and either a (n,1) or a (1,n) vector 52 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 53 | 54 | % optional input arguments 55 | addParameter(ip, 'filter_parameter', 0.925, @isnumeric) 56 | addParameter(ip, 'nr_passes', 1, @isnumeric) 57 | addParameter(ip, 'threshold_type', 'pass', @ischar) 58 | 59 | parse(ip, Q, varargin{:}) 60 | filter_parameter = ip.Results.filter_parameter; 61 | nr_passes = ip.Results.nr_passes; 62 | threshold_type = ip.Results.threshold_type; 63 | 64 | if filter_parameter>1 && filter_parameter<=0 65 | error('Filter parameter must be between 0 and 1.') 66 | end 67 | 68 | if floor(nr_passes)~=nr_passes && nr_passes<1 69 | error('Number of filter passes must be an integer larger than zero.') 70 | end 71 | 72 | % Baseflow separation is problematic with NaN values. Therefore, we set NaN 73 | % values to median, apply the filter, and then set baseflow to NaN where 74 | % streamflow is NaN. If there are a lot of NaN values, we encourage the 75 | % user to either interpolate these values or to calculate the signature for 76 | % each block individually and then calculate a weighted average. 77 | Q_tmp = Q; 78 | Q_tmp(isnan(Q)) = median(Q,'omitnan'); 79 | 80 | % calculate baseflow by applying RDF several times 81 | Q_b = LyneHollickFilter(Q_tmp, filter_parameter, threshold_type); 82 | for nr = 2:nr_passes 83 | Q_b = LyneHollickFilter(flip(Q_b), filter_parameter, threshold_type); 84 | end 85 | 86 | % set baseflow to NaN where streamflow is NaN 87 | Q_b(isnan(Q)) = NaN; 88 | 89 | % constrain baseflow not to be higher than streamflow (see also Ladson et 90 | % al. (2013)) 91 | if strcmp(threshold_type,'none') 92 | else 93 | Q_b(Q_b>Q) = Q(Q_b>Q); 94 | end 95 | 96 | end 97 | 98 | function Q_b = LyneHollickFilter(Q, filter_parameter, threshold_type) 99 | %LyneHollickFilter Helper function that runs the Lyne-Hollick filter. 100 | 101 | % define thresholding method 102 | threshold_timestep = false; 103 | threshold_pass = false; 104 | switch threshold_type 105 | case 'end' 106 | case 'timestep' 107 | threshold_timestep = true; 108 | case 'pass' 109 | threshold_pass = true; 110 | case 'none' 111 | otherwise 112 | error('Not a valid thresholding method. Choose either end, timestep, pass, or none.') 113 | end 114 | 115 | n = length(Q); 116 | Q_f = NaN(n,1); 117 | Q_f(1) = Q(1) - min(Q); % initial condition, see Su et al. (2016) 118 | 119 | if threshold_timestep 120 | for i=2:1:n 121 | Q_f(i) = filter_parameter*Q_f(i-1) + ((1+filter_parameter)/2)*(Q(i) - Q(i-1)); 122 | if Q_f(i)<0 % constrain after each timestep 123 | Q_f(i) = 0; 124 | end 125 | end 126 | else 127 | for i=2:1:n 128 | Q_f(i) = filter_parameter*Q_f(i-1) + ((1+filter_parameter)/2)*(Q(i) - Q(i-1)); 129 | end 130 | end 131 | 132 | if threshold_pass 133 | Q_f(Q_f<0) = 0; % constrain after each filter pass 134 | end 135 | 136 | % calculate baseflow 137 | Q_b = Q - Q_f; 138 | 139 | end 140 | -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_RisingLimbs.m: -------------------------------------------------------------------------------- 1 | function [flow_section, error_flag, error_str, fig_handles] = ... 2 | util_RisingLimbs(Q, t, varargin) 3 | %util_RisingLimbs identifies all rising limbs. 4 | % 5 | % INPUT 6 | % Q: streamflow [mm/timestep] 7 | % t: time [Matlab datetime] 8 | % OPTIONAL 9 | % rising_limb_length: length of rising limbs [days], default = 1 10 | % eps: allowed decrease in flow during rising limb, default = 0 11 | % minimum_peak: minimum peak to be counted as rising limb (peak size is 12 | % defined as difference between end and start of rising limb) 13 | % plot_results: whether to plot results, default = false 14 | % 15 | % OUTPUT 16 | % flow_section: n-by-2 array where n is the number of rising limbs 17 | % columns are the indices into the flow array of the start and end of 18 | % the rising limbs 19 | % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 20 | % (error in signature calculation) 21 | % error_str: string contraining error description 22 | % fig_handles: figure handles to manipulate figures (empty if plotting is 23 | % not requested) 24 | % 25 | % EXAMPLE 26 | % % load example data 27 | % data = load('example/example_data/33029_daily.mat'); 28 | % Q = data.Q; 29 | % t = data.t; 30 | % flow_section = util_RisingLimbs(Q, t); 31 | % flow_section = util_RisingLimbs(Q, t, 'rising_limb_length', 2, 'plot_results', true); 32 | % 33 | % Copyright (C) 2020 34 | % This software is distributed under the GNU Public License Version 3. 35 | % See for details. 36 | 37 | % check input parameters 38 | if nargin < 2 39 | error('Not enough input arguments.') 40 | end 41 | 42 | ip = inputParser; 43 | ip.CaseSensitive = true; 44 | 45 | % required input arguments 46 | % time series have to be numeric and either a (n,1) or a (1,n) vector 47 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 48 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 49 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 50 | 51 | % optional input arguments 52 | addParameter(ip, 'rising_limb_length', 1, @isnumeric) % length of increasing flow in days to be declared a rising limb 53 | addParameter(ip, 'eps', 0, @isnumeric) % allowed increase in flow during rising limb 54 | addParameter(ip, 'minimum_peak', 0, @isnumeric) % minimum peak to be counted as rising limb 55 | addParameter(ip, 'plot_results', false, @islogical) % whether to plot results (2 graphs) 56 | 57 | parse(ip, Q, t, varargin{:}) 58 | rising_limb_length = ip.Results.rising_limb_length; 59 | eps = ip.Results.eps; 60 | minimum_peak = ip.Results.minimum_peak; 61 | plot_results = ip.Results.plot_results; 62 | 63 | % create empty figure handle 64 | fig_handles = []; 65 | 66 | % default setting reads as good data 67 | error_flag = 0; 68 | error_str = ''; 69 | 70 | % identify all individual rising limbs with length > rising_limb_length days 71 | % how many increasing timesteps depends on length of timestep 72 | len_increase = rising_limb_length/days(t(2)-t(1)); 73 | % hind timesteps with increasing flow 74 | increasing_flow = Q(2:end)>(Q(1:end-1)-eps); 75 | % start on a non-increasing point 76 | start_point = find(increasing_flow==0,1); 77 | increasing_flow = increasing_flow(start_point:end); 78 | % find start and end of increasing sections 79 | flow_change = find(increasing_flow(1:end-1) ~= increasing_flow(2:end)); 80 | % reshape into x by 2 array (columns = start, end of decrease) 81 | flow_change = flow_change(1:(2*floor(size(flow_change,1)./2))); 82 | flow_change = reshape(flow_change,2,[]).'; 83 | % find sections 84 | flow_section = flow_change((flow_change(:,2)-flow_change(:,1))>=len_increase,:); 85 | flow_section = flow_section+start_point; 86 | flow_section(:,1) = flow_section(:,1); % move start point n days 87 | % remove rising limbs which have a peak lower than minimum_peak 88 | % flow_section((Q(flow_section(:,2)) < minimum_peak),:) = []; 89 | % remove rising limbs which have a peak lower than minimum_peak 90 | flow_section((Q(flow_section(:,2)) - Q(flow_section(:,1))) < minimum_peak,:) = []; 91 | 92 | if numel(flow_section)==0 93 | error_flag = 3; 94 | error_str = ['Error: No long enough rising limbs, consider setting eps parameter > 0. ', error_str]; 95 | end 96 | 97 | % optional plotting 98 | if plot_results 99 | fig = figure('Position',[100 100 700 250]); hold on; 100 | h1=plot(t,Q,'k','linewidth',1.5); 101 | for i = 1:size(flow_section,1) 102 | h2=plot(t(flow_section(i,1):flow_section(i,2)),... 103 | Q(flow_section(i,1):flow_section(i,2)),'r-','linewidth',1.5); 104 | end 105 | h3=plot(t,minimum_peak.*ones(size(t)),'k--'); 106 | title('Selected rising limbs') 107 | legend([h1 h2 h3],{'Full flow series', 'Selected rising limbs', 'Minimum peak threshold'}) 108 | % datetick('x') 109 | xlabel('Date') 110 | ylabel('Flow [mm/timestep]') 111 | fig_handles.RisingLimbs = fig; 112 | end 113 | 114 | end -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_UKIH_Method.m: -------------------------------------------------------------------------------- 1 | function [Q_b] = util_UKIH_Method(Q, varargin) 2 | %util_UKIH_Method estimates baseflow with UKIH method. 3 | % Estimates baseflow UKIH "smoothed minima" method (UK Institute of 4 | % Hydrology, 1980). 5 | % 6 | % INPUT 7 | % Q: [mm/timestep] 8 | % OPTIONAL 9 | % n_days: length of data blocks, default = 5 days 10 | % 11 | % OUTPUT 12 | % Q_b: baseflow [mm/timestep] 13 | % 14 | % EXAMPLE 15 | % % load example data 16 | % data = load('example/example_data/33029_daily.mat'); 17 | % Q = data.Q; 18 | % t = data.t; 19 | % Q_b = util_UKIH_Method(Q); 20 | % Q_b90 = util_UKIH_Method(Q, 'n_days', 90); 21 | % 22 | % References 23 | % UK Institute of Hydrology (Great Britain), 1980. Low Flow Studies 24 | % Reports. Institute of Hydrology. 25 | % 26 | % Copyright (C) 2020 27 | % This software is distributed under the GNU Public License Version 3. 28 | % See for details. 29 | 30 | if nargin < 1 31 | error('Not enough input arguments.') 32 | end 33 | 34 | ip = inputParser; 35 | ip.CaseSensitive = true; 36 | 37 | % required input arguments 38 | % time series have to be numeric and either a (n,1) or a (1,n) vector 39 | addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 40 | 41 | % optional input arguments 42 | addParameter(ip, 'n_days', 5, @isnumeric) 43 | 44 | parse(ip, Q, varargin{:}) 45 | n_days = ip.Results.n_days; 46 | 47 | if floor(n_days)~=n_days && n_days<1 48 | error('Filter window must be an integer larger than zero.') 49 | end 50 | 51 | % Baseflow separation is problematic with NaN values. Therefore, we set NaN 52 | % values to median, apply the filter, and then set baseflow to NaN where 53 | % streamflow is NaN. If there are a lot of NaN values, we encourage the 54 | % user to either interpolate these values or to calculate the signature for 55 | % each block individually and then calculate a weighted average. 56 | Q_tmp = Q; 57 | Q_tmp(isnan(Q)) = median(Q,'omitnan'); 58 | 59 | % calculate baseflow 60 | [Q_b, t_ind] = UKIH_Method(Q_tmp, n_days); % 5 is the default parameter 61 | 62 | % use minimum baseflow to fill in missing values at the beginning 63 | B_tmp = min(Q_tmp)*ones(size(Q_tmp)); 64 | B_tmp(t_ind) = Q_b; 65 | Q_b = B_tmp; 66 | 67 | % set baseflow to NaN where streamflow is NaN 68 | Q_b(isnan(Q)) = NaN; 69 | 70 | end 71 | 72 | function [Q_b, t_ind] = UKIH_Method(Q, n_days) 73 | %UKIH_Method Helper function that runs the UKIH method. 74 | 75 | n = length(Q); 76 | Q_min5 = NaN(round(n/n_days),1); % 5 day minima 77 | min_i = NaN(round(n/n_days),1); % corresponding indices 78 | ind5 = 1; % minima counter 79 | TP = 0; % turning points 80 | t_TP = 0; % corresponding time/index 81 | indTP = 1; % TP counter 82 | 83 | for i = 1:n_days:floor(n/n_days)*n_days % divide in non-overlapping n-day blocks 84 | [Q_min5(ind5), min_i(ind5)] = min(Q(i:i+(n_days-1))); % find minimum 85 | if ind5 <= 2 % need at least three minima 86 | elseif Q_min5(ind5-1)*0.9 < Q_min5(ind5-2) ... 87 | && Q_min5(ind5-1)*0.9 < Q_min5(ind5) % check if baseflow ordinate 88 | TP(indTP) = Q_min5(ind5-1); 89 | t_TP(indTP) = i - n_days - 1 + min_i(ind5-1); % get corresponding index 90 | indTP = indTP + 1; 91 | end 92 | ind5 = ind5 + 1; 93 | end 94 | 95 | t_ind = [t_TP(1):t_TP(end)]'; 96 | if t_ind == 0 97 | t_ind = [1:length(Q)]'; 98 | Q_b = NaN(size(Q)); 99 | else 100 | Q_b = interp1q(t_TP',TP',t_ind); % linear interpolation 101 | Qt = Q(t_ind); 102 | Q_b(Q_b>Qt) = Qt(Q_b>Qt); % constrain B, so that B is never larger than Q 103 | end 104 | 105 | end 106 | 107 | -------------------------------------------------------------------------------- /TOSSH_code/utility_functions/util_WaterYear.m: -------------------------------------------------------------------------------- 1 | function [water_year] = util_WaterYear(t, varargin) 2 | %util_WaterYear gets the water year associated with a date. 3 | % 4 | % INPUT 5 | % t: time [Matlab datetime, scalar or array] 6 | % OPTIONAL 7 | % start_water_year: numeric month in which water year starts 8 | % 9 | % OUTPUT 10 | % water_year: water year in which date falls 11 | % 12 | % EXAMPLE 13 | % % load example data 14 | % data = load('example/example_data/33029_daily.mat'); 15 | % t = data.t; 16 | % water_year = util_WaterYear(t, 'start_water_year',10); 17 | % 18 | % Copyright (C) 2020 19 | % This software is distributed under the GNU Public License Version 3. 20 | % See for details. 21 | 22 | % check input parameters 23 | if nargin < 1 24 | error('Not enough input arguments.') 25 | end 26 | 27 | ip = inputParser; 28 | 29 | % required input arguments 30 | % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 31 | addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 32 | 33 | % optional input argument 34 | validationFcn = @(x) isnumeric(x) && isscalar(x) && (x >= 1) && (x <= 12) && floor(x)==x; 35 | addParameter(ip, 'start_water_year', 10, validationFcn) % when does the water year start? 36 | 37 | parse(ip, t, varargin{:}) 38 | start_water_year = ip.Results.start_water_year; 39 | 40 | % % timestep checks 41 | % if isnumeric(t) 42 | % t = datetime(t,'ConvertFrom','datenum'); 43 | % warning('Converted datenum to datetime.') 44 | % end 45 | 46 | % get month and year of each datetime 47 | water_year = year(t); 48 | month_vals = month(t); 49 | 50 | % get months associated with previous year and subtract 1 from year value 51 | % water_year(month_vals=start_water_year) = water_year(month_vals>=start_water_year) + 1; 56 | 57 | end 58 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/_static/README_example_data.txt: -------------------------------------------------------------------------------- 1 | Data contained in this repository are taken from the following data sources. 2 | 3 | The three daily datasets (33029_daily.mat, 39020_daily.mat, 73014_daily.mat) are taken from CAMELS-GB (Coxon et al., 2020), which can be obtained from https://doi.org/10.5285/8344e4f3-d2ea-44f5-8afa-86d2987543a9. 4 | CAMELS-GB is available under the terms of the Open Government Licence (https://eidc.ceh.ac.uk/licences/OGL/plain). 5 | 6 | The 15min datasets (33029_multiple.mat) were provided by the Environment Agency and were aggregated to hourly and daily time series. 7 | These data are available under the terms of the Open Government License (http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). 8 | 9 | References 10 | 11 | Coxon, G., Addor, N., Bloomfield, J. P., Freer, J., Fry, M., Hannaford, J., Howden, N. J. K., Lane, R., Lewis, M., Robinson, E. L., Wagener, T., and Woods, R.: 12 | CAMELS-GB: hydrometeorological time series and landscape attributes for 671 catchments in Great Britain, 13 | Earth Syst. Sci. Data, 12, 2459–2483, https://doi.org/10.5194/essd-12-2459-2020, 2020. 14 | 15 | Coxon, G.; Addor, N.; Bloomfield, J.P.; Freer, J.; Fry, M.; Hannaford, J.; Howden, N.J.K.; Lane, R.; Lewis, M.; Robinson, E.L.; Wagener, T.; Woods, R. 16 | (2020). Catchment attributes and hydro-meteorological timeseries for 671 catchments across Great Britain (CAMELS-GB). 17 | NERC Environmental Information Data Centre. https://doi.org/10.5285/8344e4f3-d2ea-44f5-8afa-86d2987543a9 18 | 19 | Copyright Information 20 | 21 | © UK Centre for Ecology & Hydrology 22 | 23 | © University of Bristol 24 | 25 | Contains Environment Agency information © Environment Agency and/or database right 26 | 27 | Derived from UK bedrock hydrogeological mapping and UK superficial productivity mapping, BGS © UKRI -------------------------------------------------------------------------------- /docs/_static/addor.csv: -------------------------------------------------------------------------------- 1 | Signature;Function (click for code);Unit;Description 2 | Q_mean;`sig_Q_mean.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Q_mean.html>`_ ;mm/timestep;Mean streamflow 3 | TotalRR;`sig_TotalRR.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_TotalRR.html>`_ ;--;Total runoff ratio 4 | QP_elasticity;`sig_QP_elasticity.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_QP_elasticity.html>`_ ;--;Streamflow-precipitation elasticity 5 | FDC_slope;`sig_FDC_slope.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_FDC_slope.html>`_ ;--;Slope of the flow duration curve 6 | BFI;`sig_BFI.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_BFI.html>`_ ;--;Baseflow index 7 | HFD_mean;`sig_HFD_mean.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_HFD_mean.html>`_ ;day of year;Half flow date 8 | Q5;`sig_x_percentile.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_percentile.html>`_ ;mm/timestep;5th streamflow percentile (low flows) 9 | Q95;`sig_x_percentile.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_percentile.html>`_ ;mm/timestep;95th streamflow percentile (high flows) 10 | high_Q_freq;`sig_x_Q_frequency.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_frequency.html>`_ ;--;High flow frequency 11 | high_Q_dur;`sig_x_Q_duration.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_duration.html>`_ ;timestep;High flow duration 12 | low_Q_freq;`sig_x_Q_frequency.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_frequency.html>`_ ;--;Low flow frequency 13 | low_Q_dur;`sig_x_Q_duration.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_duration.html>`_ ;timestep;Low flow duration 14 | zero_Q_freq;`sig_x_Q_frequency.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_frequency.html>`_ ;--;Zero flow frequency 15 | -------------------------------------------------------------------------------- /docs/_static/basic_set.csv: -------------------------------------------------------------------------------- 1 | Signature;Function (click for code);Unit;Description 2 | **Magnitude**;;; 3 | Q_mean;`sig_Q_mean.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Q_mean.html>`_ ;mm/timestep;Mean streamflow 4 | Q5;`sig_x_percentile.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_percentile.html>`_ ;mm/timestep;5-th streamflow percentile 5 | Q95;`sig_x_percentile.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_percentile.html>`_ ;mm/timestep;95-th streamflow percentile 6 | Q_mean_monthly :sup:`a`;`sig_Q_mean_monthly.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Q_mean_monthly.html>`_ ;mm/timestep;Mean monthly streamflow 7 | Q_7_day_min;`sig_Q_n_day_min.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Q_n_day_min.html>`_ ;mm/timestep;7-day minimum streamflow 8 | BFI;`sig_BFI.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_BFI.html>`_ ;--;Baseflow index 9 | CoV;`sig_Q_CoV.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Q_CoV.html>`_ ;--;Coefficient of variation 10 | **Frequency**;;; 11 | high_Q_frequency;`sig_x_Q_frequency.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_frequency.html>`_ ;--;High flow frequency 12 | low_Q_frequency;`sig_x_Q_frequency.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_frequency.html>`_ ;--;Low flow frequency 13 | zero_Q_frequency;`sig_x_Q_frequency.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_frequency.html>`_ ;--;Zero flow frequency 14 | **Duration**;;; 15 | high_Q_duration;`sig_x_Q_duration.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_duration.html>`_ ;timestep;High flow duration 16 | low_Q_duration;`sig_x_Q_duration.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_duration.html>`_ ;timestep;Low flow duration 17 | zero_Q_duration;`sig_x_Q_duration.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_x_Q_duration.html>`_ ;timestep;Zero flow duration 18 | **Timing**;;; 19 | HFD_mean;`sig_HFD_mean.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_HFD_mean.html>`_ ;day of year;Half flow date 20 | HFI_mean;`sig_HFI_mean.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_HFI_mean.html>`_ ;days;Half flow interval 21 | **Rate of change**;;; 22 | AC1;`sig_Autocorrelation.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Autocorrelation.html>`_ ;--;Lag-1 autocorrelation 23 | FDC_slope;`sig_FDC_slope.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_FDC_slope.html>`_ ;--;Slope of the flow duration curve 24 | BaseflowRecessionK;`sig_BaseflowRecessionK.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_BaseflowRecessionK.html>`_ ;1/d;Exponential recession constant 25 | -------------------------------------------------------------------------------- /docs/_static/custom.css: -------------------------------------------------------------------------------- 1 | .wy-side-nav-search, .wy-nav-top { 2 | background: #d3d3d3; 3 | } -------------------------------------------------------------------------------- /docs/_static/euser.csv: -------------------------------------------------------------------------------- 1 | Signature;Function (click for code);Unit;Description 2 | AC1;`sig_Autocorrelation.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Autocorrelation.html>`_ ;--;Lag-1 autocorrelation 3 | AC1_low;`sig_Autocorrelation.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Autocorrelation.html>`_ ;--;Lag-1 autocorrelation for low flow period 4 | RLD;`sig_RisingLimbDensity.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_RisingLimbDensity.html>`_ ;1/timestep;Rising limb density 5 | PeakDistribution;`sig_PeakDistribution.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_PeakDistribution.html>`_ ;--;Slope of distribution of peaks 6 | PeakDistribution_low;`sig_PeakDistribution.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_PeakDistribution.html>`_ ;--;Slope of distribution of peaks for low flow period 7 | FDC :sup:`a`;`sig_FDC.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_FDC.html>`_ ;--;Flow duration curve 8 | FDC_lowa;`sig_FDC.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_FDC.html>`_ ;--;Flow duration curve for low flow period 9 | FDC_higha;`sig_FDC.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_FDC.html>`_ ;--;Flow duration curve for high flow period 10 | -------------------------------------------------------------------------------- /docs/_static/groundwater.csv: -------------------------------------------------------------------------------- 1 | Signature;Function (click for code);Unit;Description 2 | TotalRR;`sig_TotalRR.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_TotalRR.html>`_ ;--;Total runoff ratio 3 | RR_Seasonality;`sig_RR_Seasonality.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_RR_Seasonality.html>`_ ;--;Runoff ratio seasonality 4 | EventRR;`sig_EventRR.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventRR.html>`_ ;--;Event runoff ratio 5 | StorageFraction :sup:`a`;`sig_StorageFraction.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_StorageFraction.html>`_ ;--;Ratio between active and total storage 6 | Recession_a_Seasonality;`sig_SeasonalVarRecessions.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_SeasonalVarRecessions.html>`_ ;--;Seasonal variations in recession parameters 7 | AverageStorage;`sig_StorageFromBaseflow.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_StorageFromBaseflow.html>`_ ;--;Average storage from average baseflow and storage-discharge relationship 8 | RecessionParameters :sup:`a`;`sig_RecessionAnalysis.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_RecessionAnalysis.html>`_ ;--;Recession analysis parameters approximate storage-discharge relationship 9 | MRC_num_segments;`sig_MRC_SlopeChanges.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_MRC_SlopeChanges.html>`_ ;--;Number of different segments in master recession curve (MRC) 10 | First_Recession_Slope;`sig_MRC_SlopeChanges.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_MRC_SlopeChanges.html>`_ ;mm/timestep :sup:`2` ;Steep section of MRC = storage that is quickly depleted 11 | Mid_Recession_Slope;`sig_MRC_SlopeChanges.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_MRC_SlopeChanges.html>`_ ;mm/timestep :sup:`2` ;Mid section of MRC = water retention capacity of the catchment 12 | Spearmans_rho;`sig_RecessionUniqueness.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_RecessionUniqueness.html>`_ ;--;Non-uniqueness in the storage-discharge relationship 13 | EventRR_TotalRR_ratio :sup:`b`;`sig_EventRR.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventRR.html>`_ / `sig_TotalRR.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_TotalRR.html>`_ ;--;Ratio between event and total runoff ratio 14 | VariabilityIndex;`sig_VariabilityIndex.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_VariabilityIndex.html>`_ ;--;Variability index of flow 15 | BFI;`sig_BFI.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_BFI.html>`_ ;--;Baseflow index 16 | BaseflowRecessionK;`sig_BaseflowRecessionK.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_BaseflowRecessionK.html>`_ ;1/d;Exponential recession constant 17 | -------------------------------------------------------------------------------- /docs/_static/images/FDC_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/images/FDC_example.png -------------------------------------------------------------------------------- /docs/_static/images/SDSUprimary3Crgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/images/SDSUprimary3Crgb.png -------------------------------------------------------------------------------- /docs/_static/images/TOSSH_logo.svg: -------------------------------------------------------------------------------- 1 | Toolbox for Streamflow Signatures in Hydrology -------------------------------------------------------------------------------- /docs/_static/images/hydrograph_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/images/hydrograph_example.png -------------------------------------------------------------------------------- /docs/_static/images/logo-full-colour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/images/logo-full-colour.png -------------------------------------------------------------------------------- /docs/_static/images/toolbox_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/images/toolbox_structure.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/TOSSH/TOSSH_code/calculation_functions/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Index for Directory TOSSH\TOSSH_code\calculation_functions 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
< Master indexIndex for TOSSH\TOSSH_code\calculation_functions >
17 | 18 |

Index for TOSSH\TOSSH_code\calculation_functions

19 | 20 |

Matlab files in this directory:

21 | 22 |
 calc_Addorcalc_Addor calculates signatures from Addor et al. (2018).
 calc_Allcalc_All calculates all signatures in the toolbox.
 calc_BasicSetcalc_BasicSet calculates basic set of signatures.
 calc_Eusercalc_Euser calculates signatures from Euser et al. (2013).
 calc_McMillan_Groundwatercalc_McMillan_Groundwater calculates various groundwater signatures.
 calc_McMillan_OverlandFlowcalc_McMillan_OverlandFlow calculates various overland flow signatures.
 calc_Sawiczcalc_Sawicz calculates signatures from Sawicz et al. (2011).
23 | 24 | 25 | 26 | 27 |
Generated on Tue 02-Feb-2021 09:27:04 by m2html © 2005
28 | 29 | -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/alpha.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/c++.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/c++.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/c.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/demoicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/demoicon.gif -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/down.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/fortran.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/fortran.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/hp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/hp.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/left.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/linux.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/m2html.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: white; 3 | color: black; 4 | font-family: arial,sans-serif; 5 | margin: 0; 6 | padding: 1ex; 7 | } 8 | 9 | div.fragment { 10 | width: 98%; 11 | border: 1px solid #CCCCCC; 12 | background-color: #f5f5f5; 13 | padding-left: 4px; 14 | margin: 4px; 15 | } 16 | 17 | div.box { 18 | width: 98%; 19 | background-color: #f5f5f5; 20 | border: 1px solid #CCCCCC; 21 | color: black; 22 | padding: 4px; 23 | } 24 | 25 | .comment { 26 | color: #228B22; 27 | } 28 | .string { 29 | color: #B20000; 30 | } 31 | .keyword { 32 | color: #0000FF; 33 | } 34 | 35 | .keywordtype { color: #604020; } 36 | .keywordflow { color: #e08000; } 37 | .preprocessor { color: #806020; } 38 | .stringliteral { color: #002080; } 39 | .charliteral { color: #008080; } 40 | 41 | a { 42 | text-decoration: none; 43 | } 44 | 45 | a:hover { 46 | background-color: #006699; 47 | color:#FFFFFF; 48 | } 49 | 50 | a.code { 51 | font-weight: normal; 52 | color: #A020F0; 53 | } 54 | 55 | a.code:hover { 56 | background-color: #FF0000; 57 | color: #FFFFFF; 58 | } 59 | 60 | h1 { 61 | background: transparent; 62 | color: #006699; 63 | font-size: x-large; 64 | text-align: center; 65 | } 66 | 67 | h2 { 68 | background: transparent; 69 | color: #006699; 70 | font-size: large; 71 | } 72 | 73 | address { 74 | font-size:small; 75 | } 76 | 77 | form.search { 78 | margin-bottom: 0px; 79 | margin-top: 0px; 80 | } 81 | input.search { 82 | font-size: 75%; 83 | color: #000080; 84 | font-weight: normal; 85 | background-color: #eeeeff; 86 | } 87 | 88 | li { 89 | padding-left:5px; 90 | } -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/matlabicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/matlabicon.gif -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/mex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/mex.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/pcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/pcode.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/right.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/sgi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/sgi.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/simulinkicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/simulinkicon.gif -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/solaris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/solaris.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/up.png -------------------------------------------------------------------------------- /docs/_static/matlab/TOSSH_code/windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/TOSSH_code/windows.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/TOSSH/example/functions/data_loading/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Index for Directory TOSSH\example\functions\data_loading 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
< Master indexIndex for TOSSH\example\functions\data_loading >
17 | 18 |

Index for TOSSH\example\functions\data_loading

19 | 20 |

Matlab files in this directory:

21 | 22 |
 loadCAMELSGBstructloadCAMELSstruct Creates struct file with CAMELS data.
 loadCAMELSstructloadCAMELSstruct Creates struct file with CAMELS data.
 loadCatchmentCAMELSloadCatchmentCAMELS Loads hydro-meteorological time series (P, PET, Q, T).
 loadCatchmentCAMELSGBloadCatchmentCAMELSGB Loads hydro-meteorological time series (P, PET, Q,
23 | 24 | 25 | 26 | 27 |
Generated on Tue 02-Feb-2021 09:27:15 by m2html © 2005
28 | 29 | -------------------------------------------------------------------------------- /docs/_static/matlab/example/TOSSH/example/functions/plotting/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Index for Directory TOSSH\example\functions\plotting 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
< Master indexIndex for TOSSH\example\functions\plotting >
17 | 18 |

Index for TOSSH\example\functions\plotting

19 | 20 |

Matlab files in this directory:

21 | 22 |
 makeScatterPlotmakeScatterPlot Makes scatter plot to compare all CAMELS signatures.
 myupdatefcnCustomizes text of data tips
 plotMapUKplotMapUK Plots UK map with dots coloured according to an attribute.
 plotMapUSplotMapUS Plots US map with dots coloured according to an attribute.
 saveFigsaveFig saves figure as PDF.
23 | 24 | 25 |

Subsequent directories:

26 |
    27 |
  • Shapefiles
28 | 29 |
Generated on Tue 02-Feb-2021 09:27:15 by m2html © 2005
30 | 31 | -------------------------------------------------------------------------------- /docs/_static/matlab/example/TOSSH/example/functions/plotting/myupdatefcn.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Description of myupdatefcn 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Home > TOSSH > example > functions > plotting > myupdatefcn.m
16 | 17 | 19 | 20 |

myupdatefcn 21 |

22 | 23 |

PURPOSE ^

24 |
Customizes text of data tips
25 | 26 |

SYNOPSIS ^

27 |
function txt = myupdatefcn(~,event_obj,ID,index)
28 | 29 |

DESCRIPTION ^

30 |
 Customizes text of data tips
31 | 32 | 33 |

CROSS-REFERENCE INFORMATION ^

34 | This function calls: 35 |
    36 |
37 | This function is called by: 38 |
    39 |
  • makeScatterPlot makeScatterPlot Makes scatter plot to compare all CAMELS signatures.
  • plotMapUK plotMapUK Plots UK map with dots coloured according to an attribute.
  • plotMapUS plotMapUS Plots US map with dots coloured according to an attribute.
40 | 41 | 42 | 43 | 44 |

SOURCE CODE ^

45 |
0001 function txt = myupdatefcn(~,event_obj,ID,index)
46 | 0002 % Customizes text of data tips
47 | 0003 pos = get(event_obj,'Position');
48 | 0004 I = get(event_obj, 'DataIndex');
49 | 0005 txt = {['X: ',num2str(pos(1))],...
50 | 0006     ['Y: ',num2str(pos(2))],...     
51 | 0007     ['i: ',num2str(index(I))],...
52 | 0008     ['ID: ',num2str(ID(I))]};
53 | 0009 end
54 |
Generated on Tue 02-Feb-2021 09:27:15 by m2html © 2005
55 | 56 | -------------------------------------------------------------------------------- /docs/_static/matlab/example/TOSSH/example/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Index for Directory TOSSH\example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
< Master indexIndex for TOSSH\example >
17 | 18 |

Index for TOSSH\example

19 | 20 |

Matlab files in this directory:

21 | 22 |
 workflow_1_basic% TOSSH workflow 1 - basic workflow (also shown in online documentation)
 workflow_2_advanced% TOSSH workflow 2 - advanced workflow
 workflow_3_time_resolution% TOSSH workflow 3 - comparison of time series with different resolution
 workflow_4_CAMELS_US% TOSSH workflow 4 - calculation of signatures for CAMELS US catchments
 workflow_5_CAMELS_GB% TOSSH workflow 5 - calculation of signatures for CAMELS GB catchments
23 | 24 | 25 |

Subsequent directories:

26 |
    27 |
  • example_data
  • functions
  • results
28 | 29 |
Generated on Tue 02-Feb-2021 09:27:15 by m2html © 2005
30 | 31 | -------------------------------------------------------------------------------- /docs/_static/matlab/example/alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/alpha.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/c++.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/c++.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/c.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/demoicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/demoicon.gif -------------------------------------------------------------------------------- /docs/_static/matlab/example/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/down.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/fortran.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/fortran.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/hp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/hp.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Matlab Index 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

Matlab Index

16 |

Matlab Directories

17 | 19 |

Matlab Files found in these Directories

20 | 21 | 22 | 23 | 24 | 25 |
loadCAMELSGBstruct makeScatterPlot saveFig workflow_4_CAMELS_US
loadCAMELSstruct myupdatefcn workflow_1_basic workflow_5_CAMELS_GB
loadCatchmentCAMELS plotMapUK workflow_2_advanced
loadCatchmentCAMELSGB plotMapUS workflow_3_time_resolution
26 | 27 | 28 |
Generated on Tue 02-Feb-2021 09:27:14 by m2html © 2005
29 | 30 | -------------------------------------------------------------------------------- /docs/_static/matlab/example/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/left.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/linux.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/m2html.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: white; 3 | color: black; 4 | font-family: arial,sans-serif; 5 | margin: 0; 6 | padding: 1ex; 7 | } 8 | 9 | div.fragment { 10 | width: 98%; 11 | border: 1px solid #CCCCCC; 12 | background-color: #f5f5f5; 13 | padding-left: 4px; 14 | margin: 4px; 15 | } 16 | 17 | div.box { 18 | width: 98%; 19 | background-color: #f5f5f5; 20 | border: 1px solid #CCCCCC; 21 | color: black; 22 | padding: 4px; 23 | } 24 | 25 | .comment { 26 | color: #228B22; 27 | } 28 | .string { 29 | color: #B20000; 30 | } 31 | .keyword { 32 | color: #0000FF; 33 | } 34 | 35 | .keywordtype { color: #604020; } 36 | .keywordflow { color: #e08000; } 37 | .preprocessor { color: #806020; } 38 | .stringliteral { color: #002080; } 39 | .charliteral { color: #008080; } 40 | 41 | a { 42 | text-decoration: none; 43 | } 44 | 45 | a:hover { 46 | background-color: #006699; 47 | color:#FFFFFF; 48 | } 49 | 50 | a.code { 51 | font-weight: normal; 52 | color: #A020F0; 53 | } 54 | 55 | a.code:hover { 56 | background-color: #FF0000; 57 | color: #FFFFFF; 58 | } 59 | 60 | h1 { 61 | background: transparent; 62 | color: #006699; 63 | font-size: x-large; 64 | text-align: center; 65 | } 66 | 67 | h2 { 68 | background: transparent; 69 | color: #006699; 70 | font-size: large; 71 | } 72 | 73 | address { 74 | font-size:small; 75 | } 76 | 77 | form.search { 78 | margin-bottom: 0px; 79 | margin-top: 0px; 80 | } 81 | input.search { 82 | font-size: 75%; 83 | color: #000080; 84 | font-weight: normal; 85 | background-color: #eeeeff; 86 | } 87 | 88 | li { 89 | padding-left:5px; 90 | } -------------------------------------------------------------------------------- /docs/_static/matlab/example/matlabicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/matlabicon.gif -------------------------------------------------------------------------------- /docs/_static/matlab/example/mex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/mex.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/pcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/pcode.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/right.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/sgi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/sgi.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/simulinkicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/simulinkicon.gif -------------------------------------------------------------------------------- /docs/_static/matlab/example/solaris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/solaris.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/up.png -------------------------------------------------------------------------------- /docs/_static/matlab/example/windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/docs/_static/matlab/example/windows.png -------------------------------------------------------------------------------- /docs/_static/overland_flow.csv: -------------------------------------------------------------------------------- 1 | Signature;Function (click for code);Unit;Description 2 | IE_effect;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;--;Infiltration excess importance 3 | SE_effect;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;--;Saturation excess importance 4 | IE_thresh_signif;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;--;Infiltration excess threshold significance (in a plot of quickflow volume vs. maximum intensity) 5 | IE_thresh;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;mm/timestep;Infiltration excess threshold location (in a plot of quickflow volume vs. maximum intensity) 6 | SE_thresh_signif;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;--;Saturation excess threshold significance (in a plot of quickflow volume vs. total precipitation) 7 | SE_thresh;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;mm;Saturation excess threshold location (in a plot of quickflow volume vs. total precipitation) 8 | SE_slope;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;mm/mm;Saturation excess threshold above-threshold slope (in a plot of quickflow volume vs. total precipitation) 9 | Storage_thresh_signif;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;--;Storage/saturation excess threshold significance (in a plot of quickflow volume vs. antecedent precipitation index + total precipitation) 10 | Storage_thresh;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;mm;Storage/saturation excess threshold location (in a plot of quickflow volume vs. antecedent precipitation index + total precipitation) 11 | min_Qf_perc;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;%;Minimum quickflow as a percentage of precipitation 12 | -------------------------------------------------------------------------------- /docs/_static/overland_flow_Wu.csv: -------------------------------------------------------------------------------- 1 | Signature;Function (click for code);Unit;Description 2 | R_Pvol_RC;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;--; Pearson correlation between total precipitation volume and quickflow, related to saturation excess overlandflow process 3 | R_Pint_RC;`sig_EventGraphThresholds.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_EventGraphThresholds.html>`_ ;--; Pearson correlation between precipitation intensity and quickflow, related to infiltration excess overlandflow process -------------------------------------------------------------------------------- /docs/_static/remaining_signatures.csv: -------------------------------------------------------------------------------- 1 | Signature;Function (click for code);Unit;Description 2 | BaseflowMagnitude;`sig_BaseflowMagnitude.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_BaseflowMagnitude.html>`_ ;mm;Difference between maximum and minimum of annual baseflow regime 3 | ResponseTime;`sig_ResponseTime.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_ResponseTime.html>`_ ;timestep;Catchment response time 4 | FlashinessIndex;`sig_FlashinessIndex.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_FlashinessIndex.html>`_ ;--;Richards-Baker flashiness idex 5 | PQ_Curve :sup:`a` ;`sig_PQ_Curve.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_PQ_Curve.html>`_ ;--;Slopes and breakpoints in cumulative P-Q regime curve 6 | Q_n_day_max;`sig_Q_n_day_max.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Q_n_day_max.html>`_ ;mm/timestep;n-day maximum streamflow 7 | Q_skew;`sig_Q_skew.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Q_skew.html>`_ ;mm :sup:`3`/ timestep :sup:`3` ;Skewness of streamflow 8 | Q_var;`sig_Q_var.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_Q_var.html>`_ ;mm :sup:`2`/ timestep :sup:`2` ;Variance of streamflow 9 | RecessionK_part;`sig_RecessionParts.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_RecessionParts.html>`_ ;1/timestep;Recession constant of early/late (exponential) recessions 10 | SeasonalTranslation :sup:`a` ;`sig_SeasonalTranslation.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_SeasonalTranslation.html>`_ ;--;Amplitude ratio and phase shift between seasonal forcing and flow cycles 11 | SnowStorage;`sig_SnowStorage.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_SnowStorage.html>`_ ;mm;Snow storage derived from cumulative P-Q regime curve 12 | -------------------------------------------------------------------------------- /docs/_static/sawicz.csv: -------------------------------------------------------------------------------- 1 | Signature;Function (click for code);Unit;Description 2 | TotalRR;`sig_TotalRR.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_TotalRR.html>`_ ;--;Total runoff ratio 3 | FDC_slope;`sig_FDC_slope.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_FDC_slope.html>`_ ;--;Slope of the flow duration curve 4 | BFI;`sig_BFI.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_BFI.html>`_ ;--;Baseflow index 5 | QP_elasticity;`sig_QP_elasticity.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_QP_elasticity.html>`_ ;--;Streamflow-precipitation elasticity 6 | SnowDayRatio;`sig_SnowDayRatio.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_SnowDayRatio.html>`_ ;--;Snow day ratio 7 | RLD;`sig_RisingLimbDensity.m <./_static/matlab/TOSSH_code/TOSSH/TOSSH_code/signature_functions/sig_RisingLimbDensity.html>`_ ;1/timestep;Rising limb density 8 | -------------------------------------------------------------------------------- /docs/_static/usages/params_overlandflow.csv: -------------------------------------------------------------------------------- 1 | ws_code,min_termination,min_duration,min_intensity_day,min_intensity_day_during,max_recessiondays 2 | 1,72,24,7.2,7.2,8 3 | 2,72,24,7.2,7.2,8 4 | 3,72,24,7.2,7.2,8 5 | 4,48,24,4.8,4.8,8 6 | 5,48,24,4.8,4.8,8 7 | 6,48,24,4.8,4.8,8 8 | 7,48,24,4.8,4.8,8 9 | 8,48,24,4.8,4.8,8 10 | 9,48,24,2.4,2.4,8 11 | 10,48,24,2.4,2.4,8 12 | 11,48,24,2.4,2.4,8 13 | 12,72,24,4.8,4.8,8 14 | 13,72,24,4.8,4.8,8 15 | 14,48,24,4.8,4.8,8 16 | 18,48,24,9.6,9.6,8 17 | 20,48,24,4.8,4.8,8 18 | 22,48,24,4.8,4.8,8 19 | 26,48,24,4.8,4.8,8 20 | 27,72,24,4.8,4.8,8 21 | 28,72,24,4.8,4.8,8 22 | 30,48,24,4.8,4.8,8 23 | 36,48,24,4.8,4.8,8 24 | 39,48,24,4.8,4.8,8 25 | 90,48,24,4.8,4.8,8 26 | -------------------------------------------------------------------------------- /docs/_static/usages/params_recession.csv: -------------------------------------------------------------------------------- 1 | flow,recession_length,n_start,eps,filter_par 2 | normal,5,0,0.08,0.925 3 | low,10,0,0.02,0.925 4 | -------------------------------------------------------------------------------- /docs/_static/usages/ws_code.csv: -------------------------------------------------------------------------------- 1 | 01,North Atlantic slope basins 2 | 02,South Atlantic slope basins 3 | 03,Ohio, Cumberland, and Tennessee River basins 4 | 04,St. Lawrence River basin 5 | 05,Hudson Bay and Upper Mississippi River basin 6 | 06,Missouri River basin 7 | 07,Lower Mississippi River basin 8 | 08,Western Gulf of Mexico basins 9 | 09,Colorado River basin 10 | 10,The Great Basin 11 | 11,Pacific slope basins in California 12 | 12,Pacific slope basins in Washington and upper Columbia River basin 13 | 13,Snake River basin 14 | 14,Pacific slope basins in Oregon and lower Columbia River basin -------------------------------------------------------------------------------- /docs/code/Code_documentation.m: -------------------------------------------------------------------------------- 1 | %% Creates code documentation using M2HTML toolbox 2 | 3 | % add directories for functions to path 4 | % (you need to be in the directory above TOSSH) 5 | if exist('./m2html') == 7 6 | addpath(genpath('./m2html')); % Matlab to HTML 7 | else 8 | error('M2HTML toolbox needed. Can be downloaded from https://www.artefact.tk/software/matlab/m2html/ and should be in a folder named m2html in the same directory.') 9 | end 10 | 11 | % check which Matlab version and which toolboxes are installed 12 | ver 13 | 14 | % create HTML documentation 15 | m2html('mfiles','TOSSH/TOSSH_code/',... 16 | 'htmldir','TOSSH/docs/matlab/TOSSH_code',... 17 | 'recursive','on') 18 | 19 | m2html('mfiles','TOSSH/example/',... 20 | 'htmldir','TOSSH/docs/matlab/example',... 21 | 'recursive','on') 22 | -------------------------------------------------------------------------------- /docs/code/Matlab_toolboxes.m: -------------------------------------------------------------------------------- 1 | %% checks which Matlab toolboxes are used in TOSSH 2 | 3 | % you need to be in the directory above TOSSH 4 | files = dir('./TOSSH/TOSSH_code/*/*.m'); 5 | 6 | i = 0; 7 | for file = files' 8 | i = i+1; 9 | nameList{i} = file.name; 10 | [fList,pList] = matlab.codetools.requiredFilesAndProducts(nameList{i}); 11 | fList_all{i} = fList'; pList_all{i} = pList'; 12 | end -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'TOSSH' 21 | copyright = '2023, Sebastian Gnann' 22 | author = 'Sebastian Gnann' 23 | 24 | # The full version, including alpha/beta/rc tags 25 | release = '1.0.1' 26 | 27 | 28 | # -- General configuration --------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [ 34 | 'sphinx_rtd_theme' 35 | ] 36 | 37 | # Add any paths that contain templates here, relative to this directory. 38 | templates_path = ['_templates'] 39 | 40 | # List of patterns, relative to source directory, that match files and 41 | # directories to ignore when looking for source files. 42 | # This pattern also affects html_static_path and html_extra_path. 43 | exclude_patterns = [] 44 | 45 | 46 | # -- Options for HTML output ------------------------------------------------- 47 | 48 | # The theme to use for HTML and HTML Help pages. See the documentation for 49 | # a list of builtin themes. 50 | # 51 | html_theme = 'sphinx_rtd_theme' #alabaster 52 | 53 | # Add any paths that contain custom static files (such as style sheets) here, 54 | # relative to this directory. They are copied after the builtin static files, 55 | # so a file named "default.css" will overwrite the builtin "default.css". 56 | html_static_path = ['_static'] 57 | 58 | html_logo = "_static/images/TOSSH_logo.svg" 59 | html_theme_options = { 60 | 'logo_only': True, 61 | 'display_version': False, 62 | } 63 | 64 | html_css_files = ["custom.css"] -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. _index: 2 | 3 | .. figure:: _static/images/TOSSH_logo.svg 4 | :align: center 5 | :width: 100% 6 | 7 | |license| |zenodo| 8 | 9 | .. |license| image:: https://img.shields.io/badge/license-GPLv3-blue.svg 10 | :target: https://github.com/TOSSHtoolbox/TOSSH/blob/master/LICENSE 11 | 12 | .. |zenodo| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.4313275.svg 13 | :target: https://doi.org/10.5281/zenodo.4313275 14 | 15 | 16 | TOSSH: A Toolbox for Streamflow Signatures in Hydrology 17 | ======================================================= 18 | 19 | This documentation gives a technical overview of TOSSH: A Toolbox for Streamflow Signatures in Hydrology (Gnann et al., 2021). 20 | TOSSH is a Matlab toolbox that provides accessible, standardised signature calculations, with clear information on methodological decisions and recommended parameter values. 21 | 22 | 23 | .. toctree:: 24 | :maxdepth: 2 25 | :caption: Contents: 26 | 27 | p1_overview 28 | p2_signatures 29 | p3_examples 30 | p4_usage_notes 31 | p5_contact 32 | 33 | 34 | 35 | Download 36 | -------- 37 | 38 | https://github.com/TOSSHtoolbox/TOSSH 39 | 40 | 41 | 42 | Credits 43 | ------- 44 | Gnann, S.J., Coxon, G., Woods, R.A., Howden, N.J.K., McMillan H.K., 2021. TOSSH: A Toolbox for Streamflow Signatures in Hydrology. Environmental Modelling & Software. 45 | https://doi.org/10.1016/j.envsoft.2021.104983 46 | 47 | 48 | License 49 | ------- 50 | This software is distributed under the GNU Public License Version 3. 51 | See https://www.gnu.org/licenses/gpl-3.0.en.html 52 | 53 | .. 54 | |UOB_logo| |SDSU_logo| 55 | 56 | .. |UOB_logo| image:: _static/images/logo-full-colour.png 57 | :width: 25% 58 | 59 | .. |SDSU_logo| image:: _static/images/SDSUprimary3Crgb.png 60 | :width: 25% 61 | 62 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.https://www.sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | 37 | :: Building the Documentation Locally before pushing to GitHub 38 | 39 | :: (A) [Recommended] Steps to Enable Real-Time Updates 40 | 41 | :: (1) Install sphinx, sphinx-rtd-theme, and sphinx-autobuild in your conda environment 42 | :: (2) Navigate to the docs directory 43 | :: (3) Run the make.bat file with the html option: make.bat html 44 | :: (3) Start a local HTTP Server ``` sphinx-autobuild . _build/html```. This starts a server at http://127.0.0.1:8000 45 | 46 | :: (B) Build it static 47 | 48 | :: (1) Install sphinx and phinx-rtd-theme in your conda environment 49 | :: (2) Navigate to the docs directory 50 | :: (3) Run the make.bat file with the html option: make.bat html 51 | :: (4) Navigate to the _build/html directory 52 | :: (5) Start a local HTTP Server ``` python -m http.server ```. This starts a server at http://localhost:8000 53 | -------------------------------------------------------------------------------- /docs/p5_contact.rst: -------------------------------------------------------------------------------- 1 | .. _p5_contact: 2 | 3 | Contact 4 | ======= 5 | 6 | If you have any questions or feedback, or if you spotted an error or bug, please create an issue on Github (https://github.com/TOSSHtoolbox/TOSSH/issues). 7 | Alternatively, email Hilary McMillan (hmcmillan@sdsu.edu) or Sebastian Gnann (sebastian.gnann@hydrology.uni-freiburg.de). 8 | 9 | Please read the :ref:`documentation ` and go through the :ref:`examples ` first. These might already contain what you need to know. 10 | 11 | -------------------------------------------------------------------------------- /example/example_data/33029_daily.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/example_data/33029_daily.mat -------------------------------------------------------------------------------- /example/example_data/33029_multiple.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/example_data/33029_multiple.mat -------------------------------------------------------------------------------- /example/example_data/39020_daily.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/example_data/39020_daily.mat -------------------------------------------------------------------------------- /example/example_data/73014_daily.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/example_data/73014_daily.mat -------------------------------------------------------------------------------- /example/example_data/README_example_data.txt: -------------------------------------------------------------------------------- 1 | Data contained in this repository are taken from the following data sources. 2 | 3 | The three daily datasets (33029_daily.mat, 39020_daily.mat, 73014_daily.mat) are taken from CAMELS-GB (Coxon et al., 2020), which can be obtained from https://doi.org/10.5285/8344e4f3-d2ea-44f5-8afa-86d2987543a9. 4 | CAMELS-GB is available under the terms of the Open Government Licence (https://eidc.ceh.ac.uk/licences/OGL/plain). 5 | 6 | The 15min datasets (33029_multiple.mat) were provided by the Environment Agency and were aggregated to hourly and daily time series. 7 | These data are available under the terms of the Open Government License (http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). 8 | 9 | References 10 | 11 | Coxon, G., Addor, N., Bloomfield, J. P., Freer, J., Fry, M., Hannaford, J., Howden, N. J. K., Lane, R., Lewis, M., Robinson, E. L., Wagener, T., and Woods, R.: 12 | CAMELS-GB: hydrometeorological time series and landscape attributes for 671 catchments in Great Britain, 13 | Earth Syst. Sci. Data, 12, 2459–2483, https://doi.org/10.5194/essd-12-2459-2020, 2020. 14 | 15 | Coxon, G.; Addor, N.; Bloomfield, J.P.; Freer, J.; Fry, M.; Hannaford, J.; Howden, N.J.K.; Lane, R.; Lewis, M.; Robinson, E.L.; Wagener, T.; Woods, R. 16 | (2020). Catchment attributes and hydro-meteorological timeseries for 671 catchments across Great Britain (CAMELS-GB). 17 | NERC Environmental Information Data Centre. https://doi.org/10.5285/8344e4f3-d2ea-44f5-8afa-86d2987543a9 18 | 19 | Copyright Information 20 | 21 | © UK Centre for Ecology & Hydrology 22 | 23 | © University of Bristol 24 | 25 | Contains Environment Agency information © Environment Agency and/or database right 26 | 27 | Derived from UK bedrock hydrogeological mapping and UK superficial productivity mapping, BGS © UKRI -------------------------------------------------------------------------------- /example/functions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/__init__.py -------------------------------------------------------------------------------- /example/functions/data_loading/loadCatchmentCAMELS.m: -------------------------------------------------------------------------------- 1 | function [P, PET, Q, T] = loadCatchmentCAMELS(ID,path_mod,path_obs,area) 2 | %loadCatchmentCAMELS Loads hydro-meteorological time series (P, PET, Q, T). 3 | % We use the modelled time series (typically from October 1980 to 4 | % December 2014) to load P, PET, and T data (P and T are copied into 5 | % these files, but are observed values). We use the observed flow series 6 | % to load Q, which need to be converted to mm/day and adjusted as they 7 | % differ in length compared to the other time series. 8 | % 9 | % INPUT 10 | % ID: catchment ID 11 | % path_mod: file path used to load P, PET, and T time series 12 | % path_obs: file path used to load flow series 13 | % area: catchment area (Gages) 14 | % 15 | % OUTPUT 16 | % P: precipitation [mm/d] 17 | % PET: potential evapotranspiration (adjusted using standard coefficient 18 | % of 1.26) [mm/d] 19 | % Q: streamflow [mm/d] 20 | % T: T [degC] 21 | % 22 | % Copyright (C) 2020 23 | % This software is distributed under the GNU Public License Version 3. 24 | % See for details. 25 | 26 | % check input parameters 27 | if nargin < 4 28 | error('Not enough input arguments.') 29 | end 30 | 31 | foundID = false; % search through all folders until catchment is found 32 | i_str_list = ["01","02","03","04","05","06","07","08","09","10","11",... 33 | "12","13","14","15","16","17","18"]; 34 | i = 0; 35 | while foundID == false 36 | i = i+1; 37 | i_str = i_str_list(i); 38 | try 39 | % modelled time series 40 | file_ID_model = strcat(path_mod,i_str,'\',num2str(ID,'%08d'),'_05_model_output.txt'); 41 | txt_data=fileread(file_ID_model); 42 | % model parameters 43 | file_ID_parameters = strcat(path_mod,i_str,'\',num2str(ID,'%08d'),'_05_model_parameters.txt'); 44 | txt_para=fileread(file_ID_parameters); 45 | % observed time series 46 | file_ID_flow = strcat(path_obs,i_str,'\',num2str(ID,'%08d'),'_streamflow_qc.txt'); 47 | txt_flow=fileread(file_ID_flow); 48 | foundID = true; 49 | catch 50 | disp('') 51 | foundID = false; 52 | end 53 | end 54 | 55 | % NOTE: NOW version 05 of Newman dataset 56 | % YR MNTH DY HR SWE PRCP RAIM TAIR PET ET MOD_RUN OBS_RUN 57 | data_model_cell = textscan(txt_data,... 58 | '%f %f %f %f %f %f %f %f %f %f %f %f', ... 59 | 'Delimiter', '\t', 'HeaderLines', 1); 60 | 61 | data_parameter_cell = textscan(txt_para,... 62 | '%s %f', ... 63 | 'Delimiter', '\t', 'HeaderLines', 0); 64 | PET_coefficient = data_parameter_cell{2}(41); 65 | 66 | % GAGEID Year Month Day Streamflow(cubic feet per second) QC_flag 67 | data_flow_cell = textscan(txt_flow,... 68 | '%f %f %f %f %f %s', ... 69 | 'Delimiter', '\t', 'HeaderLines', 0); 70 | 71 | Y = data_model_cell{1}; 72 | M = data_model_cell{2}; 73 | D = data_model_cell{3}; 74 | date = datenum(Y,M,D); 75 | 76 | % Q_temp = data_model_cell{12}; 77 | Q_temp = data_flow_cell{5}; 78 | % cubicft/s to mm/day: Q = (q/35.3146667)*(86.4/area) 79 | Q_temp(Q_temp==-999) = NaN; 80 | Q_temp = (Q_temp./35.3146667).*(86.4/area); 81 | % remove values before start of P, PET, and T time series 82 | Y_Q = data_flow_cell{2}; 83 | M_Q = data_flow_cell{3}; 84 | D_Q = data_flow_cell{4}; 85 | date_Q = datenum(Y_Q,M_Q,D_Q); 86 | Q_temp(date_Q for details. 18 | 19 | % check input parameters 20 | if nargin < 2 21 | error('Not enough input arguments.') 22 | end 23 | 24 | file_ID = strcat(path,'CAMELS_GB_hydromet_timeseries_',num2str(ID),'_19701001-20150930.csv'); 25 | 26 | % date precipitation pet temperature discharge_spec discharge_vol peti humidity shortwave_rad longwave_rad windspeed 27 | data = readtable(file_ID); 28 | 29 | date = datenum(data.date); 30 | Q_temp = data.discharge_spec; 31 | P_temp = data.precipitation; 32 | PET_temp = data.pet; 33 | % PET_temp = data.peti; % with interception correction 34 | T_temp = data.temperature; 35 | 36 | Q = [date Q_temp]; 37 | P = [date P_temp]; 38 | PET = [date PET_temp]; 39 | T = [date T_temp]; 40 | 41 | end 42 | 43 | -------------------------------------------------------------------------------- /example/functions/helper_TOSSH_with_python.py: -------------------------------------------------------------------------------- 1 | import matlab.engine 2 | import numpy as np 3 | import pandas as pd 4 | from datetime import datetime, timedelta 5 | 6 | 7 | def run_tossh_function(data_path, function_name, eng, *args, **kwargs): 8 | """ 9 | Calls a MATLAB function with specified arguments and options. 10 | 11 | Parameters: 12 | - data_path: Path to MATLAB toolbox or folder containing the function. 13 | - function_name: Name of the MATLAB function to call. 14 | - eng: MATLAB engine instance. 15 | - *args: Positional arguments to pass to the MATLAB function. 16 | - **kwargs: Additional options: 17 | - 'nargout': Number of output arguments to retrieve from the MATLAB function. 18 | - Other key-value pairs are passed as varargin to the MATLAB function. 19 | 20 | Returns: 21 | - Result(s) from the MATLAB function call. 22 | """ 23 | # Add the specified path to MATLAB's search path 24 | eng.addpath(eng.genpath(data_path), nargout=0) 25 | 26 | # Convert positional arguments to MATLAB-compatible format 27 | args = [convert_to_matlab(arg) for arg in args] 28 | 29 | # Extract 'nargout' from kwargs (default is 1) 30 | nargout = kwargs.pop('nargout', 1) 31 | 32 | # Convert remaining kwargs into a list of key-value pairs for varargin 33 | varargin = [] 34 | for key, value in kwargs.items(): 35 | varargin.append(key) 36 | varargin.append(convert_to_matlab(value)) 37 | 38 | # Get the MATLAB function handle 39 | func = getattr(eng, function_name) 40 | 41 | # Call the MATLAB function with args and varargin 42 | return func(*args, *varargin, nargout=nargout) 43 | 44 | 45 | def convert_to_matlab(obj): 46 | """ 47 | Converts Python objects into MATLAB-compatible types. 48 | 49 | Parameters: 50 | - obj: Python object (e.g., DataFrame, NumPy array, list, bool). 51 | 52 | Returns: 53 | - MATLAB-compatible object. 54 | """ 55 | if isinstance(obj, bool): 56 | return matlab.logical([obj]) 57 | 58 | elif isinstance(obj, pd.DataFrame): 59 | return {col: convert_to_matlab(obj[col].values) for col in obj} 60 | 61 | elif isinstance(obj, np.ndarray): 62 | if np.issubdtype(obj.dtype, np.datetime64): 63 | # Convert numpy datetime64 to Python datetime 64 | python_dates = obj.astype('M8[ms]').astype(datetime) 65 | 66 | # Convert Python datetime to MATLAB datenum 67 | matlab_datenum = [ 68 | (d - datetime(1, 1, 1)).days + (d - datetime(1, 1, 1)).seconds / 86400 + 367 69 | for d in python_dates 70 | ] 71 | return matlab.double(matlab_datenum, size=(len(matlab_datenum), 1)) 72 | 73 | elif np.issubdtype(obj.dtype, np.bool_): 74 | return matlab.logical(obj.tolist()) 75 | 76 | return matlab.double(obj.flatten().tolist(), size=(len(obj), 1)) 77 | 78 | elif isinstance(obj, (list, tuple)): 79 | if all(isinstance(x, bool) for x in obj): 80 | return matlab.logical(obj) 81 | return matlab.double(obj, size=(len(obj), 1)) 82 | 83 | elif isinstance(obj, (int, float)): 84 | return matlab.double([obj]) 85 | 86 | elif isinstance(obj, str): 87 | return obj 88 | 89 | return obj 90 | -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/great_britain_50m.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/great_britain_50m.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/great_britain_50m.dbf -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/great_britain_50m.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/great_britain_50m.sbn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/great_britain_50m.sbn -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/great_britain_50m.sbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/great_britain_50m.sbx -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/great_britain_50m.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/great_britain_50m.shp -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/great_britain_50m.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/great_britain_50m.shx -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/united_kingdom_50m.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/united_kingdom_50m.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/united_kingdom_50m.dbf -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/united_kingdom_50m.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/united_kingdom_50m.sbn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/united_kingdom_50m.sbn -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/united_kingdom_50m.sbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/united_kingdom_50m.sbx -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/united_kingdom_50m.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/united_kingdom_50m.shp -------------------------------------------------------------------------------- /example/functions/plotting/Shapefiles/united_kingdom_50m.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/functions/plotting/Shapefiles/united_kingdom_50m.shx -------------------------------------------------------------------------------- /example/functions/plotting/myupdatefcn.m: -------------------------------------------------------------------------------- 1 | function txt = myupdatefcn(~,event_obj,ID,index) 2 | % Customizes text of data tips 3 | pos = get(event_obj,'Position'); 4 | I = get(event_obj, 'DataIndex'); 5 | txt = {['X: ',num2str(pos(1))],... 6 | ['Y: ',num2str(pos(2))],... 7 | ['i: ',num2str(index(I))],... 8 | ['ID: ',num2str(ID(I))]}; 9 | end -------------------------------------------------------------------------------- /example/functions/plotting/plotMapUK.m: -------------------------------------------------------------------------------- 1 | function [] = plotMapUK(lat,lon,z,varargin) 2 | %plotMapUK Plots UK map with dots coloured according to an attribute. 3 | % Options: 4 | % - various plotting options, e.g. axes limits 5 | % - save plot as PDF 6 | % 7 | % INPUT 8 | % lat: latitude 9 | % lon: longitude 10 | % z: attribute to be coloured in, e.g. BFI 11 | % OPTIONAL 12 | % attribute_name: name of attribute 13 | % ID: catchment ID 14 | % colour_scheme: name of colour scheme 15 | % flip_colour_scheme: flip colour scheme? 16 | % c_limits: limits of colour axis, e.g. [0 1] 17 | % c_lower_limit_open: is the lower limit open? 18 | % c_upper_limit_open: is the upper limit open? 19 | % nr_colours: nr of colours used for colourscale 20 | % figure_title: title of plot, e.g. '(a)' 21 | % figure_name: name for saving, e.g. UK_BFI 22 | % save_figure: save plot true/false 23 | % figure_path: path to folder where figure should be saved 24 | % figure_type: figure type, e.g. -dpdf or -dmeta 25 | % 26 | % OUTPUT 27 | % plot and saved figure 28 | % 29 | % --- 30 | % 31 | % Sebastian Gnann, sebastian.gnann@bristol.ac.uk (2020) 32 | 33 | if nargin < 3 34 | error('Not enough input arguments.') 35 | end 36 | 37 | ip = inputParser; 38 | 39 | addRequired(ip, 'latitude', ... 40 | @(lat) isnumeric(lat) && (size(lat,1)==1 || size(lat,2)==1)) 41 | addRequired(ip, 'longitude', ... 42 | @(lon) isnumeric(lon) && (size(lon,1)==1 || size(lon,2)==1)) 43 | addRequired(ip, 'attribute', ... 44 | @(z) isnumeric(z) || islogical(z)) 45 | 46 | addParameter(ip, 'attribute_name', @ischar) 47 | addParameter(ip, 'ID', NaN(size(z)), @isnumeric) 48 | addParameter(ip, 'colour_scheme', 'parula', @ischar) 49 | addParameter(ip, 'flip_colour_scheme', false, @islogical) 50 | addParameter(ip, 'c_limits', [min(z) max(z)], @(x) isnumeric(x) && length(x)==2) 51 | addParameter(ip, 'c_lower_limit_open', false, @islogical) 52 | addParameter(ip, 'c_upper_limit_open', false, @islogical) 53 | addParameter(ip, 'nr_colours', 10, @isnumeric) 54 | addParameter(ip, 'figure_title', '', @ischar) 55 | addParameter(ip, 'figure_name', 'no_name', @ischar) 56 | addParameter(ip, 'save_figure', false, @islogical) 57 | addParameter(ip, 'figure_path', '', @ischar) 58 | addParameter(ip, 'figure_type', '-dpdf', @ischar) 59 | 60 | parse(ip, lat, lon, z, varargin{:}) 61 | 62 | attribute_name = ip.Results.attribute_name; 63 | ID = ip.Results.ID; 64 | colour_scheme = ip.Results.colour_scheme; 65 | flip_colour_scheme = ip.Results.flip_colour_scheme; 66 | c_limits = ip.Results.c_limits; 67 | c_lower_limit_open = ip.Results.c_lower_limit_open; 68 | c_upper_limit_open = ip.Results.c_upper_limit_open; 69 | nr_colours = ip.Results.nr_colours; 70 | figure_title = ip.Results.figure_title; 71 | figure_name = ip.Results.figure_name; 72 | save_figure = ip.Results.save_figure; 73 | figure_path = ip.Results.figure_path; 74 | figure_type = ip.Results.figure_type; 75 | 76 | %% plotting 77 | index = [1:length(z)]'; 78 | 79 | fig = figure('Name',figure_name,'NumberTitle','off','pos',[100 100 350 500]); 80 | ax = axesm('MapProjection','mercator','MapLatLimit',[49 60],'MapLonLimit',[-9 3]); 81 | states = shaperead('great_britain_50m.shp', 'UseGeoCoords', true); 82 | geoshow(ax, states, ... 83 | 'DisplayType','polygon','DefaultFaceColor','white','DefaultEdgeColor','black') %geoshow 84 | hold on 85 | % grid on 86 | 87 | % create colormap 88 | % if flip_colour_scheme 89 | % colour_mat = flip(brewermap(nr_colours,colour_scheme)); 90 | % else 91 | % colour_mat = brewermap(nr_colours,colour_scheme); 92 | % end 93 | 94 | % plot 95 | % h = scatterm(lat(isnan(z)),lon(isnan(z)),'x k','linewidth',1.0); 96 | h = scatterm(lat(isnan(z)),lon(isnan(z)),20,'linewidth',1.0,'markeredgecolor',[.5 .5 .5]); 97 | % h.Children.MarkerFaceAlpha = .5; 98 | scatterm(lat,lon,25,z,'filled') 99 | % xlabel('Latitude [km]'); ylabel('Longitude [km]') 100 | set(gca,'Visible','off') 101 | title(figure_title) 102 | title(figure_title,'Visible','on') 103 | axis equal 104 | % colormap(colour_mat) 105 | colormap(colour_scheme); 106 | if flip_colour_scheme 107 | cmap = colormap; 108 | colormap(flipud(cmap)); 109 | end 110 | c = colorbar; 111 | title(c,attribute_name) 112 | x1=get(gca,'position'); 113 | x=[0.65 0.5 0.02 0.2]; 114 | set(c,'Position',x) 115 | set(gca,'position',x1) 116 | caxis(c_limits) 117 | if c_lower_limit_open 118 | c.TickLabels{1} = ['<' c.TickLabels{1}]; 119 | end 120 | if c_upper_limit_open 121 | c.TickLabels{end} = ['>' c.TickLabels{end}]; 122 | end 123 | 124 | % update cursor 125 | dcm_obj = datacursormode(figure(fig)); 126 | set(dcm_obj,'UpdateFcn',{@myupdatefcn,ID,index}) 127 | 128 | %% save fig 129 | if save_figure 130 | fig_name = strcat('map_UK','_',figure_name); 131 | saveFig(fig,fig_name,figure_path,figure_type) 132 | end 133 | 134 | end 135 | 136 | -------------------------------------------------------------------------------- /example/functions/plotting/plotMapUS.m: -------------------------------------------------------------------------------- 1 | function [] = plotMapUS(lat,lon,z,varargin) 2 | %plotMapUS Plots US map with dots coloured according to an attribute. 3 | % Options: 4 | % - various plotting options, e.g. axes limits 5 | % - save plot as PDF 6 | % 7 | % INPUT 8 | % lat: latitude 9 | % lon: longitude 10 | % z: attribute to be coloured in, e.g. BFI 11 | % attribute_name: name of attribute 12 | % ID: catchment ID 13 | % colour_scheme: name of colour scheme 14 | % flip_colour_scheme: flip colour scheme? 15 | % c_limits: limits of colour axis, e.g. [0 1] 16 | % c_lower_limit_open: is the lower limit open? 17 | % c_upper_limit_open: is the upper limit open? 18 | % nr_colours: nr of colours used for colourscale 19 | % figure_title: title of plot, e.g. '(a)' 20 | % figure_name: name for saving, e.g. CAMELS_BFI 21 | % save_figure: save plot true/false 22 | % figure_path: path to folder where figure should be saved 23 | % figure_type: figure type, e.g. -dpdf or -dmeta 24 | % 25 | % OUTPUT 26 | % plot and saved figure 27 | % 28 | % --- 29 | % 30 | % Sebastian Gnann, sebastian.gnann@bristol.ac.uk (2020) 31 | 32 | if nargin < 3 33 | error('Not enough input arguments.') 34 | end 35 | 36 | ip = inputParser; 37 | 38 | addRequired(ip, 'latitude', ... 39 | @(lat) isnumeric(lat) && (size(lat,1)==1 || size(lat,2)==1)) 40 | addRequired(ip, 'longitude', ... 41 | @(lon) isnumeric(lon) && (size(lon,1)==1 || size(lon,2)==1)) 42 | addRequired(ip, 'attribute', ... 43 | @(z) isnumeric(z) || islogical(z)) 44 | 45 | addParameter(ip, 'attribute_name', char(), @ischar) 46 | addParameter(ip, 'ID', NaN(size(z)), @isnumeric) 47 | addParameter(ip, 'colour_scheme', 'parula', @ischar) 48 | addParameter(ip, 'flip_colour_scheme', false, @islogical) 49 | addParameter(ip, 'c_limits', [min(z) max(z)], @(x) isnumeric(x) && length(x)==2) 50 | addParameter(ip, 'c_lower_limit_open', false, @islogical) 51 | addParameter(ip, 'c_upper_limit_open', false, @islogical) 52 | addParameter(ip, 'nr_colours', 10, @isnumeric) 53 | addParameter(ip, 'figure_title', '', @ischar) 54 | addParameter(ip, 'figure_name', 'no_name', @ischar) 55 | addParameter(ip, 'save_figure', false, @islogical) 56 | addParameter(ip, 'figure_path', '', @ischar) 57 | addParameter(ip, 'figure_type', '-dpdf', @ischar) 58 | 59 | parse(ip, lat, lon, z, varargin{:}) 60 | 61 | attribute_name = ip.Results.attribute_name; 62 | ID = ip.Results.ID; 63 | colour_scheme = ip.Results.colour_scheme; 64 | flip_colour_scheme = ip.Results.flip_colour_scheme; 65 | c_limits = ip.Results.c_limits; 66 | c_lower_limit_open = ip.Results.c_lower_limit_open; 67 | c_upper_limit_open = ip.Results.c_upper_limit_open; 68 | nr_colours = ip.Results.nr_colours; 69 | figure_title = ip.Results.figure_title; 70 | figure_name = ip.Results.figure_name; 71 | save_figure = ip.Results.save_figure; 72 | figure_path = ip.Results.figure_path; 73 | figure_type = ip.Results.figure_type; 74 | 75 | %% plotting 76 | index = [1:length(ID)]'; 77 | 78 | fig = figure('Name',figure_name,'NumberTitle','off','pos',[100 100 600 300]); 79 | ax = axesm('MapProjection','mercator','MapLatLimit',[24 52],'MapLonLimit',[-130 -65]); 80 | states = shaperead('usastatelo', 'UseGeoCoords', true); 81 | geoshow(ax, states, ... 82 | 'DisplayType','polygon','DefaultFaceColor','white','DefaultEdgeColor','black') 83 | hold on 84 | % grid on 85 | 86 | % create colormap 87 | % if flip_colour_scheme 88 | % colour_mat = flip(brewermap(nr_colours,colour_scheme)); 89 | % else 90 | % colour_mat = (brewermap(nr_colours,colour_scheme)); 91 | % end 92 | 93 | % plot 94 | scatterm(lat(isnan(z)),lon(isnan(z)),'x k','linewidth',1.2); 95 | scatterm(lat,lon,25,z,'filled') 96 | % xlabel('Latitude [km]'); ylabel('Longitude [km]') 97 | set(gca,'Visible','off') 98 | title(figure_title,'Visible','on') 99 | axis equal 100 | % colormap(colour_mat) 101 | colormap(colour_scheme); 102 | if flip_colour_scheme 103 | cmap = colormap; 104 | colormap(flipud(cmap)); 105 | end 106 | c=colorbar; 107 | title(c,attribute_name) 108 | x1=get(gca,'position'); 109 | x=[0.8 0.2 0.01 0.25]; 110 | set(c,'Position',x) 111 | set(gca,'position',x1) 112 | caxis(c_limits) 113 | if c_lower_limit_open 114 | c.TickLabels{1} = ['<' c.TickLabels{1}]; 115 | end 116 | if c_upper_limit_open 117 | c.TickLabels{end} = ['>' c.TickLabels{end}]; 118 | end 119 | 120 | % update cursor 121 | dcm_obj = datacursormode(figure(fig)); 122 | set(dcm_obj,'UpdateFcn',{@myupdatefcn,ID,index}) 123 | 124 | %% save fig 125 | if save_figure 126 | fig_name = strcat('map_US','_',figure_name); 127 | saveFig(fig,fig_name,figure_path,figure_type) 128 | end 129 | 130 | end 131 | 132 | -------------------------------------------------------------------------------- /example/functions/plotting/saveFig.m: -------------------------------------------------------------------------------- 1 | function [] = saveFig(fig,figure_name,figure_path,figure_type) 2 | %saveFig saves figure as PDF. 3 | % 4 | % INPUT 5 | % fig: figure 6 | % figure_name: name of figure 7 | % figure_path: path to folder where figure should be saved 8 | % figure_type: figure type, e.g. -dpdf or -dmeta 9 | % OPTIONAL 10 | % 11 | % OUTPUT 12 | % saved figure 13 | % 14 | % --- 15 | % 16 | % Sebastian Gnann, sebastian.gnann@bristol.ac.uk (2020) 17 | 18 | % check input parameters 19 | if nargin < 3 20 | error('Not enough input arguments.') 21 | elseif nargin < 4 22 | figure_type = '-dpdf'; 23 | end 24 | 25 | set(fig,'Units','Inches'); 26 | position = get(fig,'Position'); 27 | set(fig,'PaperPositionMode','Auto','PaperUnits','Inches',... 28 | 'PaperSize',[position(3),position(4)]); 29 | figure_name = strcat(figure_name); 30 | path = strcat(figure_path,'\',figure_name); 31 | print(fig,path,figure_type,'-r500'); 32 | 33 | end -------------------------------------------------------------------------------- /example/results/CAMELS_GB_signatures.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/results/CAMELS_GB_signatures.mat -------------------------------------------------------------------------------- /example/results/CAMELS_signatures.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/results/CAMELS_signatures.mat -------------------------------------------------------------------------------- /example/results/README.md: -------------------------------------------------------------------------------- 1 | Files are stored locally. -------------------------------------------------------------------------------- /example/results/images/TOSSH_scatter_plot_GB.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/results/images/TOSSH_scatter_plot_GB.pdf -------------------------------------------------------------------------------- /example/results/images/TOSSH_scatter_plot_US.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/results/images/TOSSH_scatter_plot_US.pdf -------------------------------------------------------------------------------- /example/results/images/map_UK_EventRR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/results/images/map_UK_EventRR.png -------------------------------------------------------------------------------- /example/results/images/map_UK_RecessionK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/results/images/map_UK_RecessionK.png -------------------------------------------------------------------------------- /example/results/images/map_UK_Recession_exponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOSSHtoolbox/TOSSH/ccd9cdb9de90a18ec35cc27fde7eb85d59b10754/example/results/images/map_UK_Recession_exponent.png -------------------------------------------------------------------------------- /example/workflow_3_time_resolution.m: -------------------------------------------------------------------------------- 1 | %% TOSSH workflow 3 - comparison of time series with different resolution 2 | % 3 | % This script shows how to use TOSSH with example data from the same 4 | % catchment but with different time resolution. 5 | % 6 | % The example datasets used in this workflow were provided by the 7 | % Environment Agency, see README_example_data.txt for more information on 8 | % data sources. 9 | % 10 | % Copyright (C) 2020 11 | % This software is distributed under the GNU Public License Version 3. 12 | % See for details. 13 | 14 | close all 15 | % clear all 16 | clc 17 | 18 | %% Add directories to path 19 | % We navigate to the TOSSH directory and add it to the Matlab path. 20 | % If we already are in this directory, we can use the pwd command: 21 | mydir = pwd; 22 | % Alternatively, we can specify my_dir manually: 23 | % mydir = 'D:/Sebastian/Documents/MATLAB/TOSSH'; 24 | cd(mydir) 25 | addpath(genpath(mydir)); 26 | 27 | %% Load data 28 | path = './example/example_data/'; % specify path 29 | 30 | % Daily, hourly, and 15min data from the same catchment. 31 | data = load(strcat(path,'33029_multiple.mat')); % load data 32 | t_daily = data.t_daily; 33 | Q_daily = data.Q_daily; % streamflow [mm/day] 34 | t_hourly = data.t_hourly; 35 | Q_hourly = data.Q_hourly; % streamflow [mm/hour] 36 | t_15min = data.t_15min; 37 | Q_15min = data.Q_15min; % streamflow [mm/d15minay] 38 | 39 | clear data 40 | 41 | %% Plot data 42 | % When we compare different time resolutions, we can see that some of the 43 | % small peaks are smoothed out in the daily series. 44 | figure('pos',[100 100 350 200]) 45 | hold on 46 | plot(t_daily,Q_daily,'b') 47 | plot(t_hourly,Q_hourly*24,'r-') 48 | plot(t_15min,Q_15min*4*24,'g-.') 49 | xlabel('Date') 50 | ylabel('Streamflow [mm/day]') 51 | xlim([datetime(2015,10,01) datetime(2016,09,30)]) 52 | legend('Daily','Hourly','15min','location','best') 53 | 54 | %% Compare time resolution 55 | % Different time resolutions have an impact on the calculation of 56 | % hydrological signatures. We again calculate the BFI and the slope of the 57 | % FDC, but now for the same catchment with different time resolutions. 58 | BFI_daily = sig_BFI(Q_daily,t_daily); 59 | BFI_hourly = sig_BFI(Q_hourly,t_hourly); 60 | BFI_15min = sig_BFI(Q_15min,t_15min); 61 | FDC_slope_daily = sig_FDC_slope(Q_daily,t_daily); 62 | FDC_slope_hourly = sig_FDC_slope(Q_hourly,t_hourly); 63 | FDC_slope_15min = sig_FDC_slope(Q_15min,t_15min); 64 | RLD_daily = sig_RisingLimbDensity(Q_daily,t_daily,'eps',0.001*median(Q_daily,'omitnan')); 65 | RLD_hourly = sig_RisingLimbDensity(Q_hourly,t_hourly,'eps',0.001*median(Q_hourly,'omitnan')); 66 | RLD_15min = sig_RisingLimbDensity(Q_15min,t_15min,'eps',0.001*median(Q_15min,'omitnan')); 67 | % We can store the results in a table to print them in the command window. 68 | VarNames = {'BFI','FDC_slope','RLD'}; 69 | RowNames = {'1d','1h','15min'}; 70 | T = table([BFI_daily; BFI_hourly; BFI_15min],... 71 | [FDC_slope_daily; FDC_slope_hourly; FDC_slope_15min],... 72 | [RLD_daily; RLD_hourly*24; RLD_15min*(24*4)],... 73 | 'VariableNames',VarNames,'RowNames',RowNames); 74 | disp(T) 75 | % From the results displayed in the command window and from the plots we 76 | % can see that the BFI is sensitive to the timestep. This is because we 77 | % always used the default method, which is the Lyne-Hollick filter with a 78 | % parameter value of 0.925. The slope of the FDC is insensitive to the 79 | % timestep. No parameters need to be specified. 80 | 81 | % We also need to be careful with the units. For example, if we want to 82 | % compare mean flows we need to adjust the time series so that they have 83 | % the same units (e.g. mm/day). 84 | Q_mean_daily = sig_Q_mean(Q_daily,t_daily); 85 | Q_mean_hourly = sig_Q_mean(Q_hourly,t_hourly); 86 | Q_mean_15min = sig_Q_mean(Q_15min,t_15min); 87 | VarNames = {'Q_mean','Q_mean_adj'}; 88 | T = table([Q_mean_daily; Q_mean_hourly; Q_mean_15min],... 89 | [Q_mean_daily; Q_mean_hourly*24; Q_mean_15min*4*24],... 90 | 'VariableNames',VarNames,'RowNames',RowNames); 91 | disp(T) 92 | 93 | %% Further information 94 | % Further information can be found in the online documentation: 95 | % https://TOSSHtoolbox.github.io/TOSSH/ and in the other example scripts. 96 | --------------------------------------------------------------------------------