-
Notifications
You must be signed in to change notification settings - Fork 5
/
remove_season.m
152 lines (133 loc) · 4.08 KB
/
remove_season.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
function [anom,clim] = remove_season(array,tnum,varargin);
% function [anom,clim] = remove_season(array,tnum,[dimtime,lenseas,season_type,period]);
%
% remove seasonal cycle from array
%
% input - array : data array
% - tnum : time axis in DATENUM FORMAT (see datenum.m)
% - dimtime : dimension of time [default = 1]
% - lenseas : length of seasonal cycle [default = 12]
% - season_type : (1) 'tropical' (Apr-Mar) OR (2) 'calendar' (Jan-Dec)
% [default = 2]
% - period : 2-element vector specifying the reference period
% default = [min(year), max(year)]
%
% output - anom : anomaly array
% - clim : average seasonal cycle
%
% History:
% =========
% Startged by Julien Emile-Geay, USC, Oct 2011
% Modified by N. Mirnateghi, Jan 2012
%
% based on remseason.m by G.Krahmann, LODYC Paris, Mar 1998
%
% modified to include non-January-to-December endpoints & specific
% reference period for the computation of the climatology.
% NB: assumes time runs from old to recent, unlike most paleoclimate records
%
% Further modification: using global month variable in order to make sure
% starting at the correct monthly cycle
%
% updated 9 Jan 2011 - nasim@earth.usc.edu
% ===================================================================
% time axis
tvec = datevec(tnum(:));
year = tvec(:,1);
month = tvec(:,2);
% check input
if nargin == 6
dimtime = varargin{1};
lenseas = varargin{2};
season_type = varargin{3};
period = varargin{4};
elseif nargin == 5
dimtime = varargin{1};
lenseas = varargin{2};
season_type = varargin{3};
period = [min(year),max(year)];
elseif nargin == 4
dimtime = varargin{1};
lenseas = varargin{2};
season_type = 2;
period = [min(year),max(year)];
elseif nargin == 3
dimtime = varargin{1};
lenseas = 12;
season_type = 2;
period = [min(year),max(year)];
elseif nargin == 2
dimtime = 1;
lenseas = 12;
season_type = 2;
period = [min(year),max(year)];
else
error('Thou shalt specify some arguments!')
end
% prepare output arrays
sd = size(array);
sn = sd;
sn(dimtime) = lenseas;
anom = repmat(0,sd);
clim = repmat(0,sn);
% shift dimensions to get the wanted one to the left
array = shiftdim(array,dimtime-1);
clim = shiftdim(clim,dimtime-1);
anom = shiftdim(anom,dimtime-1);
sds = shiftlr(sd,dimtime-1);
sns = shiftlr(sn,dimtime-1);
% calculate climatology
mRes=ceil(12/lenseas);
mgrid(1,:)=month(1);
for c = 2:lenseas
if mod(mgrid(c-1,:)+mRes,12)==0
mgrid(c,:)=12;
else
mgrid(c,:)=mod(mgrid(c-1,:)+mRes,12);
end
end
mgrid=sort(mgrid); % for Jan-Dec years
if season_type == 1 % for May-Apr years (Tropical Years)
while mgrid(1)<5
mgrid=circshift(mgrid,-1);
end
end
% fixing the start and end of the years to have a proper and complete
% seasonal cycle
month_c = month; % month_c has the complete years (Jan - Dec or Apr-Mar)
year_c = year;
i=1;
while month(i) ~= mgrid(1)
month_c(i)=[];
year_c(i)=[];
i=i+1;
end
i=length(month_c);
while month_c(i)~=mgrid(length(mgrid))
month_c(i)=[]; year_c(i)=[];
i=i-1;
end
for imon = 1:lenseas
mon = find(month_c == mgrid(imon)); % indices matching that particular month
nm = length(mon);
mon_p = find(month_c == mgrid(imon) & ismember(year_c,[period(1):period(2)]));
clim(imon,:) = nmean(array(mon_p,:),1);
anom(mon,:) = array(mon,:) - repmat(clim(imon,:),[nm 1]);
end
% calculate anomalies
if isint(sd(dimtime)/lenseas)
anom = array - repmat(clim,[sd(dimtime)/lenseas,ones(1,length(sd)-1)]);
else
ind = [1:floor(sd(dimtime)/lenseas)*lenseas];
res = [1:sd(dimtime)-floor(sd(dimtime)/lenseas)*lenseas];
anom(ind,:) = array(ind,:) - ...
repmat(clim(1:lenseas,:),...
[floor(sd(dimtime)/lenseas),ones(1,length(sd)-1)]);
anom(ind(length(ind))+res,:) = array(ind(length(ind))+res,:) - clim(res,:);
end
% reshape and reshift results
anom = reshape(anom,sds);
clim = reshape(clim,sns);
anom = shiftdim(anom,ndims(anom)-dimtime+1);
clim = shiftdim(clim,ndims(anom)-dimtime+1);
return