sig_BFI calculates baseflow index (BFI). Calculates BFI, that is the ratio between baseflow (volume) and total streamflow (volume), with different baseflow separation methods (Lyne and Hollick, 1979; UK Institute of Hydrology, 1980). INPUT Q: streamflow [mm/timestep] t: time [Matlab datetime] OPTIONAL method: which baseflow separation method should be employed ('Lyne_Hollick','UKIH'), default = 'UKIH' parameters: specify filter parameters ([filter_parameter nr_passes] for Lyne Hollick, default = [0.925 3]; [n_days] for UKIH, default = 5) plot_results: whether to plot results, default = false OUTPUT BFI: baseflow index [-] error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 (error in signature calculation) error_str: string contraining error description fig_handles: figure handles to manipulate figures (empty if plotting is not requested) EXAMPLE % load example data data = load('example/example_data/33029_daily.mat'); Q = data.Q; t = data.t; BFI = sig_BFI(Q,t); BFI_LH = sig_BFI(Q,t,'method','Lyne_Hollick','parameters',[0.925 3]); BFI_UKIH = sig_BFI(Q,t,'method','UKIH','parameters',[5]); References Lyne, V. and Hollick, M., 1979. Stochastic time-variable rainfall-runoff modelling. In Institute of Engineers Australia National Conference (Vol. 1979, pp. 89-93). Barton, Australia: Institute of Engineers Australia. UK Institute of Hydrology (Great Britain), 1980. Low Flow Studies Reports. Institute of Hydrology. Copyright (C) 2020 This software is distributed under the GNU Public License Version 3. See <https://www.gnu.org/licenses/gpl-3.0.en.html> for details.
0001 function [BFI, error_flag, error_str, fig_handles] = sig_BFI(Q, t, varargin) 0002 %sig_BFI calculates baseflow index (BFI). 0003 % Calculates BFI, that is the ratio between baseflow (volume) and 0004 % total streamflow (volume), with different baseflow separation methods 0005 % (Lyne and Hollick, 1979; UK Institute of Hydrology, 1980). 0006 % 0007 % INPUT 0008 % Q: streamflow [mm/timestep] 0009 % t: time [Matlab datetime] 0010 % OPTIONAL 0011 % method: which baseflow separation method should be employed 0012 % ('Lyne_Hollick','UKIH'), default = 'UKIH' 0013 % parameters: specify filter parameters ([filter_parameter nr_passes] for 0014 % Lyne Hollick, default = [0.925 3]; [n_days] for UKIH, default = 5) 0015 % plot_results: whether to plot results, default = false 0016 % 0017 % OUTPUT 0018 % BFI: baseflow index [-] 0019 % error_flag: 0 (no error), 1 (warning), 2 (error in data check), 3 0020 % (error in signature calculation) 0021 % error_str: string contraining error description 0022 % fig_handles: figure handles to manipulate figures (empty if plotting is 0023 % not requested) 0024 % 0025 % EXAMPLE 0026 % % load example data 0027 % data = load('example/example_data/33029_daily.mat'); 0028 % Q = data.Q; 0029 % t = data.t; 0030 % BFI = sig_BFI(Q,t); 0031 % BFI_LH = sig_BFI(Q,t,'method','Lyne_Hollick','parameters',[0.925 3]); 0032 % BFI_UKIH = sig_BFI(Q,t,'method','UKIH','parameters',[5]); 0033 % 0034 % References 0035 % Lyne, V. and Hollick, M., 1979. Stochastic time-variable 0036 % rainfall-runoff modelling. In Institute of Engineers Australia National 0037 % Conference (Vol. 1979, pp. 89-93). Barton, Australia: Institute of 0038 % Engineers Australia. 0039 % UK Institute of Hydrology (Great Britain), 1980. Low Flow Studies 0040 % Reports. Institute of Hydrology. 0041 % 0042 % Copyright (C) 2020 0043 % This software is distributed under the GNU Public License Version 3. 0044 % See <https://www.gnu.org/licenses/gpl-3.0.en.html> for details. 0045 0046 % check input parameters 0047 if nargin < 2 0048 error('Not enough input arguments.') 0049 end 0050 0051 ip = inputParser; 0052 ip.CaseSensitive = true; 0053 0054 % required input arguments 0055 % time series have to be numeric and either a (n,1) or a (1,n) vector 0056 addRequired(ip, 'Q', @(Q) isnumeric(Q) && (size(Q,1)==1 || size(Q,2)==1)) 0057 % date time series has to be numeric or datetime and either a (n,1) or a (1,n) vector 0058 addRequired(ip, 't', @(t) (isnumeric(t) || isdatetime(t)) && (size(t,1)==1 || size(t,2)==1)) 0059 0060 % optional input arguments 0061 addParameter(ip, 'method', 'UKIH', @ischar) % which method? Default: UKIH 0062 addParameter(ip, 'parameters', [], @isnumeric) % which parameter values? 0063 % addParameter(ip, 'threshold_type', [], @ischar) % how to threshold Lyne-Hollick filter? 0064 addParameter(ip, 'plot_results', false, @islogical) % whether to plot results 0065 0066 parse(ip, Q, t, varargin{:}) 0067 method = ip.Results.method; 0068 parameters = ip.Results.parameters; 0069 % specify when to threshold (default: after each pass) 0070 threshold_type = 'pass'; % ip.Results.threshold_type; 0071 plot_results = ip.Results.plot_results; 0072 0073 % create empty figure handle 0074 fig_handles = []; 0075 0076 % data checks 0077 [error_flag, error_str, timestep, t] = util_DataCheck(Q, t); 0078 if error_flag == 2 0079 BFI = NaN; 0080 return 0081 end 0082 timestep_factor = 1/days(timestep); % adjust for timestep 0083 0084 % calculate signature 0085 0086 % pad time series to compensate for warm up effect (Ladson et al., 2013) 0087 if length(Q)>60 0088 Q_padded = [Q(30:-1:1); Q; Q(end-29:end)]; 0089 else 0090 Q_padded = Q; 0091 error_flag = 1; 0092 error_str = ['Warning: Very short time series. Baseflow separation might be unreliable. ', error_str]; 0093 end 0094 0095 % obtain baseflow 0096 switch method 0097 0098 case 'Lyne_Hollick' 0099 if isempty(parameters) 0100 filter_parameter = exp(log(0.925)/timestep_factor); 0101 parameters = [filter_parameter, 3]; 0102 elseif length(parameters) == 1 0103 parameters(2) = 3; 0104 elseif length(parameters) > 2 0105 error('Too many filter parameters.') 0106 end 0107 0108 if isempty(threshold_type) 0109 Q_b = util_LyneHollickFilter(Q_padded, ... 0110 'filter_parameter', parameters(1), 'nr_passes', parameters(2)); 0111 else 0112 Q_b = util_LyneHollickFilter(Q_padded, ... 0113 'filter_parameter', parameters(1), 'nr_passes', parameters(2),... 0114 'threshold_type',threshold_type); 0115 end 0116 0117 case 'UKIH' 0118 if isempty(parameters) 0119 parameters = 5*timestep_factor; 0120 elseif length(parameters) > 1 0121 error('Too many filter parameters.') 0122 end 0123 Q_b = util_UKIH_Method(Q_padded, 'n_days', parameters(1)); 0124 0125 otherwise 0126 error('Please choose one of the available baseflow separation methods (UKIH or Lyne_Hollick).') 0127 end 0128 0129 % remove padding 0130 if length(Q)>60 0131 Q_b(1:30) = []; 0132 Q_b(end-29:end) = []; 0133 else 0134 end 0135 0136 % calculate BFI 0137 BFI = sum(Q_b,'omitnan')/sum(Q,'omitnan'); 0138 0139 % check if 0<=BFI<=1 0140 if BFI<0 || BFI>1 0141 BFI = NaN; 0142 error_flag = 1; 0143 error_str = ['Warning: Estimated BFI outside allowed range (0 to 1).', error_str]; 0144 end 0145 0146 % optional plotting 0147 if plot_results 0148 fig = figure('Position',[100 100 700 250]); hold on 0149 plot(t,Q) 0150 plot(t,Q_b) 0151 xlabel('Date') 0152 ylabel('Flow [mm/timestep]') 0153 legend('Streamflow','Estimated baseflow') 0154 fig_handles.BFI = fig; 0155 end 0156 0157 end