*! version 1.0.2 PR/PS 08May98.
program define stbtcalc
version 5.0
st_is
local varlist "opt ex none"
#delimit ;
local options "Window(int 0) Increment(int 0) CLuster(string) noHR
 Level(integer $S_level) Robust noSHow SMooth COEF(str) SE(str) *" ;
#delimit cr
local if "opt"
local in "opt"
parse "`*'"

if "`coef'"=="" {local coef BT}
if "`se'"  =="" {local se BS}

local id : char _dta[st_id]
local t  : char _dta[st_t]
local t0 : char _dta[st_t0]
local d  : char _dta[st_d]
local id : char _dta[st_id]
local w  : char _dta[st_w]
local wt : char _dta[st_wt]

quietly {
	tempvar touse dead
	mark `touse' `if' `in' `w'
	markout `touse' `t' `t0' `d' `varlist'
	markout `touse' `cluster' `id', strok

	if "`wt'"=="pweight" {
		local robust "robust"
	}

	if "`robust'"!="" & "`cluster'"=="" & "`id'"!="" {
		local cluster "`id'"
	}
	if "`cluster'"!="" {
		local cluster "cluster(`cluster')"
	}

	if "`t0'" != "" {
		local t0 "t0(`t0')"
	}

	if "`d'" != "" {
		gen byte `dead'=`d'!=0 if `d'!=.
	}
	else {
		gen byte `dead'=1
	}
	tempvar wdead wevents
	gen byte `wdead'=`dead'
	local D "dead(`d')"
	local d "dead(`wdead')"

	st_show `show'

	if "`id'"!="" & "`t0'"==""{
		di in red "id not currently supported without t0"
		exit 198
	}
	if "`w'`wt'"!="" {
		di in red "weights not currently supported"
		exit 198
	}
	cox `t' `varlist' `w' if `touse', `robust' `cluster' `t0' nocoef /*
	 */ `options' `D'
	tempname beta
	matrix `beta' = get(_b)
	local vars : colnames (`beta')
	if "`vars'"!="`varlist'" {
		noi di "Some variables not used by cox regression " /*
		 */ "(presumably due to collinearity)"
		noi di "The following will be used by stbtcalc: "
		noi di "`vars'"
	}
/*
	Set up _b() and _se() variables
*/
	parse "`vars'", parse(" ")
	local nv 0
	while "`1'"!="" {
		local nv = `nv'+1
		local var`nv' `1'
		tempvar b`nv' s`nv'
		gen `b`nv''=.
		gen `s`nv''=.
		global B_`nv' = _b[`1']
		global B_`nv' = "`1' ${B_`nv'}"
		mac shift
	}
	local j=`nv'+1
	global B_`j'

	count if `dead'==1 & `touse'==1
	local ndead = _result(1)
/*
	Set up "windowed" survival times and censoring indicator
*/
	gsort -`touse' `t'
	gen int `wevents' = sum(`dead'==1) if `touse'
/*
	Calc Cox model for moving windows each containing `window' events.
	Default window size is 10*(#covariates).
	Default increment in #events aims for at least 50 estimated b(t)'s.
*/
	tempname oldest
	est hold `oldest'
	if `window'<=0 {
		local window = max(20, int(10*`nv'))
	}
	if `increme'<=0 {
		local increme = max(1, int((`ndead'-`window')/50))
	}
	local midevnt = int(1+`window'/2)
	local i 0
	tempvar touze
	gen byte `touze'=`touse'
	while `i'<=`ndead'-`window' {
		noi di "." _cont
		local index = `i'+`midevnt'
		sum `t' if `touze' & (`wevents'>`i') & (`wevents'<=`i'+`window')
		replace `touze' = `touze' & (`t'>_result(5))
		replace `wdead' = cond(`t'>_result(6),0,`dead')
		cox `t' `vars' `w' if `touze', /*
		 */ `robust' `cluster' `t0' `d' `options' nocoef
		local j 0
		while `j'<`nv' {
			local j=`j'+1
			cap replace `b`j''=_b[`var`j'']  if `wevents'==`index'
			cap replace `s`j''=_se[`var`j''] if `wevents'==`index'
		}
		local i=`i'+`increme'
	}
/*
	Create new variables from coefficients and confidence limits.
*/
	cap drop `coef'*
	cap drop `se'*
	local j 0
	while `j'<`nv' {
		local j=`j'+1
		mkname1 `var`j'', prefix(`coef')
		local B $S_1
		mkname1 `var`j'', prefix(`se')
		local S $S_1
		if "`smooth'"!="" {
			running `b`j'' `t' if `touse', gen(`B') rep(2) nograph
			running `s`j'' `t' if `touse', gen(`S') rep(2) nograph
			local smooth "smoothed "
		}
		else {
			rename `b`j'' `B'
			rename `s`j'' `S'
		}
		lab var `B' "`var`j'' `smooth'coefficient"
		lab var `S' "`var`j'' standard error"
	}
	est unhold `oldest'
	noi cox
	global S_1 `window'
	global S_2 `increme'
	global S_E_cmd "stbtcalc"
}
end