*! version 1.0.7  15dec2022 JM. Domenech, R. Sesma
/*
scct: Stochastic curtailment (immediate command)
*/

program define scct
	version 12
	syntax anything(id="argument numlist"), /*
	*/	Alpha(numlist max=1 >0 <50) Beta(numlist max=1 >0 <50) [CP1(numlist max=1 >=50 <100) nst(string)]

	local n : word count `anything'
	if (`n'!=3) print_error "t, cp0 and cp1 are needed"
	tokenize `anything'
	local t `1'			//Percentage of information accrued
	local cp0  `2'		//Conditional power under null hypothesis
	local cp1  `3'		//Conditional power under alternative hypothesis

	confirm number `t'
	confirm number `cp0'
	confirm number `cp1'

	if (`t'<=0 | `t'>100) print_error "invalid t -- 0 < t <= 100"
	if (`cp0'<50 | `cp0'>=100) print_error "invalid cp0 -- 50 <= cp0 < 100"
	if (`cp1'<50 | `cp1'>=100) print_error "invalid cp1 -- 50 <= cp1 < 100"

	*Compute results
	local t = `t'/100
	local z0= invnormal(1-`cp0'/100)
	local z1= invnormal(`cp1'/100)

	foreach i of numlist 1/2 {
		local za`i' = invnormal(1-`alpha'/(`i'*100))
		local zb`i' = `za`i'' + invnormal(1-`beta'/100)

		local ztr`i' = (`za`i'' - `z0'*sqrt(1-`t'))/sqrt(`t')
		if (`i'==2) local ztr2n = -1*`ztr2'
		local ptr`i' = (1-normal(`ztr`i''))*`i'

		local zta`i' = (`za`i'' - `z1'*sqrt(1-`t') - `zb`i''*(1-`t'))/sqrt(`t')
		if (`i'==2) local zta2n = -1*`zta2'
		local pta`i' = (1-normal(`zta`i''))*`i'
	}

	*Print results
	di as res "STOCHASTIC CURTAILMENT: Clinical trials"
	if ("`nst'"!="") di as txt "{bf:STUDY:} `nst'"
	di
	di as txt "Risk: Alpha= {bf:`alpha'}%    Beta= {bf:`beta'}%"
	di as txt "Conditional power: under H0= {bf:`cp0'}%  under H1= {bf:`cp1'}%"
	local t = `t'*100
	di as txt "Accrued information= {bf:`t'}%"
	di
	di as txt "{hline 6}{c TT}{hline 23}{c TT}{hline 22}{c TT}{hline 25}"
	di as txt " TEST {c |}" _col(16) "Z value" _col(31) "{c |}" _col(41) "P value" _col(54) "{c |} DECISION"
	di as txt "{hline 6}{c +}{hline 23}{c +}{hline 22}{c +}{hline 25}"
	di as txt " TWO  {c |}{bf:+infinity} to" _col(21) as res %9.5f `ztr2' " {c |} 0" /*
		*/	as txt _col(41) " to " as res %7.6f `ptr2' as txt " {c |} STOP: Beneficial effect"
	if (`zta2'>0) {
		di as txt "SIDED {c |}" as res %9.5f `ztr2' as txt " to " as res %9.5f `zta2' " {c |} " /*
			*/ %7.6f `ptr2' as txt " to " as res %7.6f `pta2' as txt " {c |} CONTINUE"
		di as res _col(7) "{c |}" as res %9.5f `zta2' as txt " to " as res %9.5f `zta2n' " {c |} " /*
			*/ %7.6f `pta2' as txt " to " as res "1" as txt _col(54) "{c |} STOP: Lack of power (H0)"
		di as res _col(7) "{c |}" as res %9.5f `zta2n' as txt " to " as res %9.5f `ztr2n' " {c |} " /*
			*/ %7.6f `pta2' as txt " to " as res %7.6f `ptr2' as txt " {c |} CONTINUE"
	}
	else {
		di as txt "SIDED {c |}" as res %9.5f `ztr2' as txt " to " as res %9.5f `ztr2n' " {c |} " /*
			*/ %7.6f `ptr2' as txt " to " as res "1" as txt _col(54) "{c |} CONTINUE"
	}
	di as res _col(7) "{c |}" as res %9.5f `ztr2n' as txt " to {bf:-infinity}" _col(31) "{c |} " /*
			*/ as res %7.6f `ptr2' as txt " to " as res "0" _col(54) as txt "{c |} STOP: Harmful effect"

	di as txt "{hline 6}{c +}{hline 23}{c +}{hline 22}{c +}{hline 25}"
	di as txt " ONE  {c |}{bf:+infinity} to" _col(21) as res %9.5f `ztr1' " {c |} 0" /*
		*/	as txt _col(41) " to " as res %7.6f `ptr1' as txt " {c |} STOP: Beneficial effect"
	di as txt "SIDED {c |}" as res %9.5f `ztr1' as txt " to " as res %9.5f `zta1' " {c |} " /*
		*/ %7.6f `ptr1' as txt " to " as res %7.6f `pta1' as txt _col(54) "{c |} CONTINUE"
	di as res _col(7) "{c |}" as res %9.5f `zta1' as txt " to {bf:-infinity}" _col(31) "{c |} " /*
			*/ as res %7.6f `pta1' as txt " to " as res "1" _col(54) as txt "{c |} STOP: Lack of power (H0)"
	di as txt "{hline 6}{c BT}{hline 23}{c BT}{hline 22}{c BT}{hline 25}"

end


program define print_error
	args message
	display in red "`message'"
	exit 198
end