function [recon,eofnumb]=eiv_recon(targt,startyr,proxynorm,proxystart,targmin,targmax,runmax,retvar,nohyb)
%      EIV_RECON a single function call do perform a hybrid/no-hybrid 
%      reconstruction of targets based on a database of proxy values
%
%      Input:
%        TARGT      temperatures (e.g. index or set of PCs)
%        startyr    first year of temperature index  
%        targmin,   targmax years to define calibration interval   
%        PROXYNORM  array of proxies
%        proxystart first year of proxy availability    
%        runmax     year to end reconstruction interval (incl. cal period)  
%      
%      Options:
%        retvar: retained variance requirement in assessing the regpar
%                variable for the low-freq component reconstruction.  
%                Default=0.5 (50%), 0.33 can also be used.
%
%        nohyb: if =1 return reconstruction without frequency splitting
%
%      Output:
%        RECON reconstruction array [ Years from startrun to endrun, recon]
%        EOFNUMB  number for regpar in low-f, high-f and nohyb cases
%
%      Calls: lowhighsplit, normalize, newregem, eigenselect
%             (center, nanmean, nanstd, nancov, peigs, pttls, etc) 
%
%      Note: maxit/stagtol parameters for RegEM in the lowf case may need 
%      to be edited for real world proxies.
%
%      Based on Mann et al 07/08, coding from Zhang/Miller/Rutherford/Mann
%      Adapted by Gavin Schmidt (Jan 2010)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% load temperature

[nt,mt]=size(targt);
targt = [(startyr:startyr+nt-1)',targt];  % add years

% choose limits for target (years targmin:targmax inclusive)

sel=targt(:,1)< targmin | targt(:,1)> targmax;  % years to discard
temp = targt(~sel,2:1+mt);
		 
[tempnorm,tempmean,tempsdev]=normalize(temp);
		 
% set calibration period and full run period (calibration + reconstruction)

[np,mp]=size(proxynorm);

startrunyear = proxystart;  
endrunyear   = min(runmax,proxystart+np-1);
startcalyear = targmin;     
endcalyear   = min(targmax,proxystart+np-1);

% convert years to rows in the matrix

startrunyear = startrunyear-proxystart+1;
endrunyear   = endrunyear-proxystart+1;

startcalyear = startcalyear-proxystart+1;
endcalyear   = endcalyear-proxystart+1;

ntot = endrunyear-startrunyear+1; % total number of years in run
ncut = startcalyear-startrunyear; % split for verification/calibration periods
ncal = endcalyear-startcalyear+1; % number of calibration years
ncols=mt+mp;                      % number of columns in final matrix 

instpcstokeep=mt;                 % number of target indices 
keptpcs=temp(1:ncal,:);

% combine the targets to be reconstructed and the pseudoproxy network

merged(startrunyear:endrunyear,1:ncols)=NaN;
merged(ncut+1:ntot,1:mt)=keptpcs(:,:);
merged(startrunyear:endrunyear,mt+1:ncols)=proxynorm;

% Normalise target temperature over calibration interval

[xc,xm,xsd]=normalize2(merged,ncut+1,ncut+ncal+1);		 
merged(:,1:mt)=xc(:,1:mt); % targets only
		 
if nohyb==0      % then do frequency-based hybrid method

% split the matrix into high-frequency and low-frequency bands

  [highf,lowf]=lowhighsplit(merged,20);

% Using the full data matrix, over the calibration period, 
% figure out the ttls/regpar settings in regem

% do svd decomposition for lowf (U's are the PCs)
 
  [U,S,V] = svd(lowf(startcalyear:endcalyear,ncols-mp+1:ncols),0); 
  lowfevalues=diag(S.^2);
  lowfpctvar=diag(S).^2./sum(diag(S).^2); % that gives the pct for each pc
  cumlowfpctvar=cumsum(lowfpctvar);

% for lowf, set ttls truncation to retain "retvar" of variance. 
% It may be better to err on the side of picking one than calculated
% depending on your application, but you may want to reinstate the 2nd line.

  ttlslowfpar=length(find(cumlowfpctvar<retvar));
  %ttlslowfpar=ttlslowfpar+1

% do svd decomposition for highf (U's are the PCs)

  [U,S,V] = svd(highf(startcalyear:endcalyear,ncols-mp+1:ncols),0); 
  highfevalues=diag(S.^2);
  highfpctvar=diag(S).^2./sum(diag(S).^2); % that gives the pct for each pc
  ttlshighfpareigen=eigenselect(highfpctvar)

% save regpars for output

  eofnumb(1:2)=[ttlslowfpar,ttlshighfpareigen];

else
% do it for original data for non-hybrid case

  [U,S,V] = svd(merged(startcalyear:endcalyear,ncols-mp+1:ncols),0); 
  allevalues=diag(S.^2);
  allpctvar=diag(S).^2./sum(diag(S).^2); % that gives the pct for each pc
  ttlsallpareigen=eigenselect(allpctvar)

% save regpars for output

  eofnumb(1)=ttlsallpareigen;

end

% perform reconstruction

recon=NaN*ones(ntot,1+mt);
recon(:,1)=[proxystart:runmax]';

% standard RegEM options:

weight=[];
OPTIONS.regress = 'ttls';           
OPTIONS.inflation = 1;
OPTIONS.disp = 1;
OPTIONS.relvar_res = 0.05;
OPTIONS.minvarfrac=0;               

if nohyb==0      % then do frequency-based hybrid method

% low-frequency
  OPTIONS.regpar = eofnumb(1)
  OPTIONS.stagtol = 1e-4;         % for real world, may need to loosen
  OPTIONS.maxit = 400;            % try stagtol=5e-3, maxit=100 
                                  % as used in Mann et al (2008) 
   X=lowf;
  [X, M, C, Xerr, Xmis, dXmis] = newregem(X, OPTIONS, weight);
  lowfrecon=X(startrunyear:endrunyear,1:mt);

% high-frequency
 
  OPTIONS.regpar = eofnumb(2)
  OPTIONS.stagtol = 5e-2;
  OPTIONS.maxit = 40;
   X=highf;
  [X, M, C, Xerr, Xmis, dXmis] = newregem(X, OPTIONS, weight);
  highfrecon=X(startrunyear:endrunyear,1:mt);

% splice together and scale single step recons

  recon(:,2:1+mt)=(lowfrecon+highfrecon)*tempsdev;

else

% non-hybrid

  OPTIONS.regpar = eofnumb(1)
  OPTIONS.stagtol = 1e-4;
  OPTIONS.maxit = 400;
   X=merged;
  [X, M, C, Xerr, Xmis, dXmis] = newregem(X, OPTIONS, weight);
  allrecon=X(startrunyear:endrunyear,1:mt);

% scale single step recons

  recon(:,2:1+mt)=allrecon*tempsdev;

end

% done