program define extweo
*!  By M. Over                               Version 1.3 April 14, 2011
*!  Called by -aidsproj.ado- version 3.49 and greater to extrapolate macroeconomic variables
*	Expect the WEO data in -long- form
*	Extrapolate -varname- variable to the planning horizon, such that each country
*   converges to regional average by 2025 or -cnvrgyr-
*	Replaces (i.e. censors) extreme values beginning in 2025 or -cnsryr-
*	With option -rate-, convergence is of the country rate to the median regional rate
*	With option -level-, convergence is of the country level to the median regional level
*   Growth rates outside the regonal interquartile range are set to the 25th or 75th percentiles
	version 10.1
	syntax varname [, cnvrgyr(integer 2025) cnsryr(integer 2025) level rate]

	local index `varlist'

	if "`level'`rate'"=="" | "`level'`rate'"=="levelrate"{
		di as err "Must specify either -level- or -rate-, but not both"
	}

*	Define temporary variables.  Suffix: c=country, r=region.
	tempvar lnindex indexgrwthc indexlevelc indexgrwthr indexlevelr indexlastvalc indexmaxyrc
	gen `lnindex' = log(`index')
	gen `indexgrwthc' = .
	gen `indexgrwthr' = .
	gen `indexlevelr' = .
	gen `indexlastvalc' = .   // Holds last value present in data for the index variable
	gen `indexmaxyrc' = .     // Holds last year present in data for the index variable

*	Estimate the average growth rate or level of -index- for every country.
	sort code
	levelsof code, local(allcodes)
	foreach c of numlist `allcodes' {

		local cname : label code `c'
		di _n as txt "The country is " as res "`cname'" as txt " with code " as res "`c'"

		summ year if `index'~=. & code==`c', meanonly
*			replace `indexmaxyrc' =r(max)  if code==`c'
			//	In version 1.1 of extweo, allow convergence to begin before end of projections
			replace `indexmaxyrc' = min(`indexmaxyrc', r(max)) if code==`c'

		replace `indexlastvalc' = `index'     if year==`indexmaxyrc' & code==`c'
			summ `indexlastvalc'              if code==`c' , meanonly
			replace `indexlastvalc' = r(mean) if code==`c'

		if "`rate'"~="" {
			capture reg `lnindex' year if code==`c'
			if _rc==0 {
					mat def eb=e(b)
					local slope = eb[1,1]
				replace `indexgrwthc' = exp(`slope') - 1 if code==`c'
			}

		}
	}

tab cntry, sum(`indexlastvalc')  /* DEBUG */

*   Replace outlier individual country-specific values with 25th or 75th percentile values for the region
	sort rgn code year
	sum rgn, meanonly
	local maxrgn = r(max)
	foreach r of numlist 1/`maxrgn' {
		if "`rate'"~="" {
			summ `indexgrwthc' if rgn==`r', detail
        	    local rp75 = r(p75)
        	    local rp50 = r(p50)
        	    local rp25 = r(p25)
    	    replace `indexgrwthr' = `rp50' if                          rgn==`r'
    	    replace `indexgrwthc' = `rp75' if `indexgrwthc' > `rp75' & `indexgrwthc' ~= . & rgn==`r' & year > `indexmaxyrc'
    	    replace `indexgrwthc' = `rp25' if `indexgrwthc' < `rp25' & rgn==`r' & year > `indexmaxyrc'
    	    replace `indexgrwthc' = `rp50' if `indexgrwthc' ==.      & rgn==`r' & year > `indexmaxyrc'
		}
		if "`level'"~="" {
			summ  `index' if rgn==`r', detail
        	    local rp75 = r(p75)
        	    local rp50 = r(p50)
        	    local rp25 = r(p25)
    	    replace `indexlevelr' = `rp50' if                             rgn==`r'
    	    replace `index' = `rp75' if `index' > `rp75' & `index' ~= . & rgn==`r' & year > `indexmaxyrc'
    	    replace `index' = `rp25' if `index' < `rp25' & rgn==`r' & year > `indexmaxyrc'
    	    replace `index' = `rp50' if `index' ==.      & rgn==`r' & year > `indexmaxyrc'
		}
	}

*   Replace any remaining missing values by the median over the entire sample
*   (Values should only be missing at this point if a country was not assigned to a region.)
	if "`rate'"~="" {
		summ `indexgrwthc' if year > `indexmaxyrc', detail
   	    replace `indexgrwthc' = r(p50) if `indexgrwthc' ==. & year > `indexmaxyrc'
	}
	if "`level'"~="" {
		summ  `index' if year > `indexmaxyrc', detail
   	    replace `index' = r(p50) if `index' ==. & year > `indexmaxyrc'
	}

*   Add the country-specific estimates of growth rates to the data set
	if "`rate'"~="" {
		gen `index'grwthc = `indexgrwthc'
		    label var `index'grwthc "Growth rate used to project `index'"
	}

*   Project the future values of -index-
****************************************
*   Assume that all country-specific levels or growth rates converge to the region mean by the year -cnvrgyr=
	tempvar cwgt
	gen `cwgt' = max(min((`cnvrgyr'-year)/(`cnvrgyr'-`indexmaxyrc'), 1), 0)
	    label var `cwgt' "Wt on country's historical `rate'`level' to project future `rate'`level'"
	    tsset code year

*   Project future values of -index- using projected growth rate
	if "`rate'"~="" {
		replace `indexgrwthc' = `cwgt' * `indexgrwthc' + (1 - `cwgt') * `indexgrwthr'  if year>`indexmaxyrc'
		replace `index' = (1+`indexgrwthc') * L.`index' if L.`index'~=. & (`index'==. | year>`indexmaxyrc')
	}

*   Project future values of -index- to converge from last value to regional average levels
	if "`level'"~="" {
		replace `index' = `cwgt' * `indexlastvalc' + (1 - `cwgt') * `indexlevelr'  if year>`indexmaxyrc'
	}

	sort code year

end    /* End of program extweo */

*	Version 1.0 written on  July 6, 2010
*	Version 1.1 modified with addtion of option -cnsryr- to allow convergence to begin before end of projections
*		by beginning the censoring of extreme values in whichever year is earlier between the specified
*		convergence year and the last year of the projections
*	Version 1.2 fixes bug in the -level- option