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

 

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