-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRDF.m
77 lines (63 loc) · 2.34 KB
/
RDF.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
% Yiwen Mei ([email protected])
% CEE, University of Connecticut
% Last updated on 10/6/2022
%% Functionality:
% This code implements the recursive digital filter (RDF, Eckhardt, 2005) and
% the filtered UKIH method (FUKIH, Aksoy et al. 2009). In the second case, the
% UKIH-based baseflow time series must be provided as an optional input.
%% Inputs
% Q : streamflow time series for a basin (m3/time step or mm/time step);
% BFIm: maximum baseflow index;
% a : recession constant (note that a=exp(-Kt))
% Qb0: initial baseflow time series of the same size as Q.
%% Outputs:
% Qb : baseflow time series of the same resolution and unit as Q;
% BFI : long-term baseflow index of the basin based on RDF;
% N_bp: number of time step with negative baseflow and baseflow larger than streamflow.
function [Qb,BFI,N_bp]=RDF(Q,BFIm,a,varargin)
%% Check the inputs
narginchk(3,4);
ips=inputParser;
ips.FunctionName=mfilename;
addRequired(ips,'Q',@(x) validateattributes(x,{'double'},{'vector','nonnegative'},mfilename,'Q'));
addRequired(ips,'BFIm',@(x) validateattributes(x,{'double'},{'scalar','<',1,'>',0},mfilename,'BFIm'));
addRequired(ips,'a',@(x) validateattributes(x,{'double'},{'scalar','<',1,'>',0},mfilename,'a'));
addOptional(ips,'Qb0',[],@(x) validateattributes(x,{'double'},{'vector','nonnegative'},mfilename,'Qb0'));
parse(ips,Q,BFIm,a,varargin{:});
Qb0=ips.Results.Qb0;
clear ips varargin
%% Determine the segments
TSi=~isnan(Q);
k=Run_Length(TSi,true,Q);
k=reshape(k',2,length(k)/2)';
k(k(:,1)==1,1)=1:sum(k(:,1));
TSi=Run_Length(reshape(k(:,1:2)',size(k,1)*2,1),false,[])';
%% Baseflow for every segment
Qb=nan(size(Q));
for i=1:max(TSi)
q=Q(TSi==i);
if length(q)>1
% Without initial baseflow (RDF)
qb=nan(size(q));
if isempty(Qb0)
qb(1)=BFIm*q(1);
for j=2:length(q)
qb(j)=((1-BFIm)*a*qb(j-1)+(1-a)*BFIm*q(j))/(1-a*BFIm);
end
% With initial baseflow (FUKIH)
else
qb0=Qb0(TSi==i);
for j=2:length(q)
qb(j)=((1-BFIm)*a*qb0(j-1)+(1-a)*BFIm*q(j))/(1-a*BFIm);
end
end
Qb(TSi==i)=qb;
end
end
N_bp=sum(Qb<0 | Qb>Q);
Qb(Qb<0)=0; % baseflow must be greater than 0 and lower than total flow
Qb(Qb>Q)=Q(Qb>Q);
%% Calculate the baseflow index
k=any(isnan([Qb Q]),2);
BFI=sum(Qb(~k),'omitnan')/sum(Q(~k),'omitnan');
end