Code covered by the BSD License  

Highlights from
Get El Niño Southern Oscillation Index values

image thumbnail

Get El Niño Southern Oscillation Index values

by

Chad Greene (view profile)

 

15 Oct 2012 (Updated )

Get SOI (or ENSO) values as a time series from the year 1866 to present.

get_soi(start_date,end_date)
function[soi_ind,soi_dates] = get_soi(start_date,end_date)
% get_soi retrieves monthly values of the standardized Southern Oscillation 
% Index (SOI) computed by UCAR using the standardization approach outlined 
% by Trenberth (1984) to maximize the signal.  Note that SOI values prior 
% to 1935 should be used with caution. There are questions regarding the 
% consistency and quality of the Tahiti pressure values prior to 1935.  
% 
% SOI or El Nino Southern Oscillation (ENSO) is a climatological pattern
% measured by pressure anomalies in the western Pacific Ocean. High
% positive values indicate a La Nina year, and low negative values indicate
% an El Nino year. 
%
% Matlab function written by Chad A. Greene, October 2012. 
% 
% ********************************************************************** %
% INPUT ARGUMENTS: (optional)
% start_date = beginning date of range in Matlab's datenum format 
%              (e.g. datenum(1936,4,1) for April 1, 1936). Valid for 
%              Jan. 1866 or after, however values before 1935 are
%              questionable. start_date is an optional input and can be 
%              used without declaring an end_date. 
% 
% end_date = ending date of investigation period in Matlab's datenum 
%            format. end_date is an optional input. 
% 
% OUTPUTS: 
% soi_ind = Standardized southern oscillation index time series. 
% 
% soi_dates = corresponding date vector in Matlab's datenum format. 
% 
% VALID SYNTAX INCLUDES: 
% soi_ind = get_soi; % (indices only, full historical range)
% [soi_ind,soi_dates] = get_soi; % (indices & dates, full historical range)
% [soi_ind,soi_dates] = get_soi(datenum(1936,4,1)); % Apr. 1936 to present
% [soi_ind,soi_dates] = get_soi(datenum('April 1, 1936'),datenum('March 28, 2010')); % April 1936 to  March 2010.
%
% ********************************************************************** %
% EXAMPLE 1: 
%
% [soi_ind,soi_dates] = get_soi; 
%
% figure
% plot([soi_dates(1) soi_dates(end)],[0 0],'k'); hold on
% plot(soi_dates,soi_ind,'b')
% datetick
% xlim([soi_dates(1) soi_dates(end)])
% box off
% text(0,.9,'  La Nina years','units','normalized')
% text(0,.1,'  El Nino years','units','normalized')
% ylabel('Standardized Southern Oscillation Index')
% 
% ********************************************************************** %
% EXAMPLE 2:
% % (This example requires the Signal Processing Toolbox)
% 
% [soi_ind,soi_dates] = get_soi(datenum('April 1, 1936'),datenum('March 28,2010'));
% 
% figure 
% subplot(2,1,1)
% plot([soi_dates(1) soi_dates(end)],[0 0],'k'); hold on
% plot(soi_dates,soi_ind,'b')
% datetick
% xlim([soi_dates(1) soi_dates(end)])
% box off
% text(0,.9,'  La Nina years','units','normalized')
% text(0,.1,'  El Nino years','units','normalized')
% ylabel('Standardized SOI')
% xlabel('year')
% 
% [Px_soi,f_soi] = pwelch(soi_ind(isfinite(soi_ind)),2^9,2^8,[],12);
% subplot(2,1,2)
% semilogx(f_soi,10*log10(abs(Px_soi)))
% xlim([f_soi(1) f_soi(end)])
% set(gca,'xtick',1./[10 7 5 4 3 2 1],'xticklabel',[10 7 5 4 3 2 1])
% xlabel('oscillation period (years)')
% ylabel('power spectrum (dB)')
% box off
%
% ********************************************************************** %
% REFERENCES: 
% Trenberth (1984), "Signal versus Noise in the Southern Oscillation"
% Monthly Weather Review 112:326-332.
% 
% UCAR website http://www.cgd.ucar.edu/cas/catalog/climind/soi.html
%
% ********************************************************************** %

soi_ascii = urlread('http://www.cgd.ucar.edu/cas/catalog/climind/SOI.signal.ascii');
soi_ascii = strrep(soi_ascii,'-99.9','NaN'); % replaces missing values
soi_struct = textscan(soi_ascii,'%n %n %n %n %n %n %n %n %n %n %n %n %n'); 
soi_mat = cell2mat(soi_struct); % converts cell structure to matrix


% Regrid data from calendar format to time series:
soi_dates = NaN(size(soi_mat,1)*12,1); % preallocate variable
soi_ind = NaN(size(soi_dates));        % preallocate variable
k = 0;                                 % initializes counter
for m = 1:length(soi_mat); 
    for n = 2:13
        k = k+1; 
        soi_dates(k) = datenum(soi_mat(m,1),n-1,15);  
        soi_ind(k) = soi_mat(m,n); 
    end
end


% If input arguments (start and/or end dates) are used, rewrite time series
% data to include only dates of interest: 
if exist('start_date','var')==1 
    if start_date<datenum(1866,1,1)
        warning('Historical pressure data record begins in January 1866.')
    end
    if exist('end_date','var')~=1
        end_date = datenum(date); % uses today as end_date if not specified
    end
    soi_ind = soi_ind(soi_dates>=start_date&soi_dates<=end_date);
    soi_dates = soi_dates(soi_dates>=start_date&soi_dates<=end_date);
end

Contact us