*! version 1.00 January 15, 2007

program define midas_binsse, rclass byable(recall) sortpreserve
version 9

syntax varlist(min=4 max=4) [if] [in], Method(string)[ LEVEL(integer 95) SCHEME (string) ///
FUNnel REGplot Graph TEXTScale(real 0.50) ZCF(real 0.5) ///
POINTopts(string asis) REGopts(string asis) *]

tokenize `varlist'
global tp `1'
global fp `2'
global fn `3'
global tn `4'

/* Check syntax */

if `level' < 10 | `level' > 99 {
di as error "level() must be between 10 and 99"
	exit 198
		}

if !inlist("`method'", "d", "e", "h", "m", "p", "r", "s", "t") {
	di as error "method() must be one of: d (Deeks), e (Egger), h (Harbord),"
	di as error "  m (Macaskill), p (Peters), r (Rucker), s (Sterne), t (Stanley)"
	exit 198
}

if "`scheme'" != ""{
 set scheme `scheme'
  }
  if "`scheme'" == ""{
  set scheme s2color
  }

local alph = (100-`level')/200

qui {

nois di " "
nois di " "
nois di as text "{title:STATISTICAL TESTS FOR SMALL STUDY EFFECTS/PUBLICATION BIAS}"

tempvar  n1 n2 nt ESS zero lthetai thetai sethetai xb yb stpred logn pubwgt
tempvar zc_tp zc_fn zc_fp zc_tn
tempvar zz ll2 ul2 vl z mmm vvar w wl swl
tempname oe sw
gen `zc_tp' = $tp
gen `zc_fp' = $fp
gen `zc_fn' = $fn
gen `zc_tn' = $tn
gen `zero' = 0
replace `zero' = 1 if $tp == 0 | $fp == 0 | $fn == 0 | $tn == 0
replace `zc_tp' = `zc_tp' + `zcf' if `zero' == 1
replace `zc_fp' = `zc_fp' + `zcf' if `zero' == 1
replace `zc_fn' = `zc_fn' + `zcf' if `zero' == 1
replace `zc_tn' = `zc_tn' + `zcf' if `zero' == 1


gen `n1' = `zc_tp' + `zc_fn'
gen `n2' = `zc_tn' + `zc_fp'
gen `nt' =  `n1' + `n2'
gen `ESS' =(4 * `n1' * `n2')/(`n1' + `n2')
gen `logn' = log(`nt')
gen `lthetai' = log((`zc_tp' * `zc_tn')/(`zc_fp' * `zc_fn'))
gen `thetai' =.
gen `sethetai' =.
gen `pubwgt' =.
gen `xb' =.
gen `yb' =.

if "`method'" == "d" {
replace `thetai'=`lthetai'
replace `sethetai' = sqrt(`ESS')
replace `xb'=1/sqrt(`ESS')
label var `xb' "1/root(ESS)"
replace `yb' = `thetai'
label var `yb' "Odds Ratio"
local xxtitle "xtitle("Odds Ratio", size(*.90))"
local yxtitle "ytitle("Odds Ratio", size(*.90)) xtitle("1/root(ESS)", size(*.90))"

replace `pubwgt' = `ESS'
nois di " "
nois di " "
nois di as text "Regression of Log Odds Ratio on Inverse Root of Effective Sample Size"
local ptitle: di "Deeks' Funnel Asymmetry Test"
nois di " "
}
else if "`method'" == "e" {
replace `thetai'=`lthetai'
replace `sethetai' = sqrt((1/`zc_tp') + (1/`zc_fn') +(1/`zc_fp') + (1/`zc_tn'))
replace `xb'= 1/`sethetai'
label var `xb' "1/Standard Error"
replace `yb'=`thetai'/`sethetai'
label var `yb' "Odds Ratio/Standard Error"
local xxtitle "xtitle("Odds Ratio/Standard Error", size(*.90))"
local yxtitle "ytitle("Odds Ratio/Standard Error", size(*.90)) xtitle("1/Standard Error", size(*.90))"
replace `pubwgt' = 1
nois di " "
nois di " "
nois di as text "Regression of Odds Ratio on Inverse Standard Error"
local ptitle: di "Egger's Funnel Asymmetry Test"
nois di " "
}

else if "`method'" == "h" {

tempvar V rootV Z
gen `V'=(`zc_tp'+`zc_fn')*(`zc_tn'+`zc_fp')*(`zc_tp'+`zc_tn')*(`zc_fn'+`zc_fp') / (`nt')^3
gen `Z'=(`zc_tp'*`zc_fp'-`zc_tn'*`zc_fn')/`nt'
gen `rootV'=sqrt(`V')
replace `thetai' = `Z'/`rootV'
replace `sethetai' = `rootV'
replace `xb'= `rootV'
label var `xb' "rootV"
replace `yb' = `thetai'
label var `yb' "ZoverrootV"
local xxtitle "xtitle("ZoverrootV", size(*.90))"
local yxtitle "ytitle("ZoverrootV", size(*.90)) xtitle("rootV", size(*.90))"

replace `pubwgt' = 1
nois di " "
nois di " "
display as text _n ///
"Regression of Z/sqrt(V) on sqrt(V)," _n ///
"where Z is efficient score and V is Fisher's information." _n
local ptitle: di "Harbord's Funnel Asymmetry Test"
nois di " "
}

else if "`method'" == "m" {
replace `thetai'=`lthetai'
replace `sethetai' = `nt'
replace `xb'=`sethetai'
label var `xb' "Total Sample Size"
replace `yb'=`thetai'
label var `yb' "Odds Ratio"
local xxtitle "xtitle("Odds Ratio", size(*.90))"
local yxtitle "ytitle("Odds Ratio", size(*.90)) xtitle("Total Sample Size", size(*.90))"

replace `pubwgt' = 1/((1/(`zc_tp'+`zc_fp'))+(1/(`zc_tn'+`zc_fn')))
nois di " "
nois di " "
nois di as text "Regression of Log Odds Ratio on Sample Size"
local ptitle: di "Macaskill's Funnel Asymmetry Test"
nois di " "
}

else if "`method'" == "p" {
replace `thetai'=`lthetai'
replace `sethetai' = 1/`nt'
replace `xb'=`sethetai'
label var `xb' "Inverse Sample Size"
replace `yb'=`thetai'
label var `yb' "Odds Ratio"
local xxtitle "xtitle("Odds Ratio", size(*.90))"
local yxtitle "ytitle("Odds Ratio", size(*.90)) xtitle("Inverse Sample Size", size(*.90))"

replace `pubwgt' = 1/((1/(`zc_tp'+`zc_fp'))+(1/(`zc_tn'+`zc_fn')))
nois di " "
nois di " "
nois di as text "Regression of Log Odds Ratio on Inverse Sample Size"
local ptitle: di "Peters' Funnel Asymmetry Test"
nois di " "
}

else if "`method'" == "r" {
replace `thetai'= asin(sqrt(`zc_tp'/`n1')) - asin(sqrt(`zc_fp'/`n2'))
replace `sethetai' = sqrt((1/(4*`n1')) + (1/(4*`n2')))
replace `xb'=`sethetai'
label var `xb' "Standard Error"
replace `yb'=`thetai'
label var `yb' "Arcsine Difference"
local xxtitle "xtitle("Arcsine Difference", size(*.90))"
local yxtitle "ytitle("ArcSine Difference", size(*.90)) xtitle("Standard Error", size(*.90))"
replace `pubwgt' = 1/`sethetai'
nois di " "
nois di " "
nois di as text "Regression of Arcsine Difference on Standard Error"
local ptitle: di "Rucker's Funnel Asymmetry Test"
nois di " "
}
else if "`method'" == "s" {
replace `thetai'=`lthetai'
replace `sethetai' = sqrt((1/`zc_tp') + (1/`zc_fn') +(1/`zc_fp') + (1/`zc_tn'))
replace `xb'= `sethetai'
label var `xb' "Standard Error"
replace `yb'=`thetai'
label var `yb' "Odds Ratio"
local xxtitle "xtitle("Odds Ratio", size(*.90))"
local yxtitle "ytitle("Odds Ratio", size(*.90)) xtitle("Standard Error", size(*.90))"
replace `pubwgt' = 1/`sethetai'^2

nois di " "
nois di " "
nois di as text "Regression of Log Odds Ratio on Standard Error"
local ptitle: di "Sterne's Funnel Asymmetry Test"
nois di " "
}
else if "`method'" == "t" {
replace `thetai'=`lthetai'
replace `sethetai' = `logn'
replace `xb' = `sethetai'
label var `xb' "Log Sample Size"
replace `yb'= log(abs(`thetai'/`sethetai'))
label var `yb' "|t-statistic|(log scale)"
local xxtitle "xtitle("log(|t-statistic|)", size(*.90))"
local yxtitle "ytitle("log(|t-statistic|)", size(*.90)) xtitle("Log(Sample Size)", size(*.90))"
replace `pubwgt' = 1
nois di " "
nois di " "
nois di as text "Metasignificance Testing: Regression of log_|t-statistic| on log_Sample_Size"
local ptitle: di "Stanley's Meta-significance Test"
nois di " "
}

sum `xb', detail
local xbmax=r(max)
sum `yb', detail
local ybmax=r(max)
local ybmin=r(min)
mylabels 1 10 100 1000, myscale(log(@)) local(xlab)
regress  `yb' `xb'[weight=`pubwgt'], level(`level')
estimates store stbias
scalar intercept = _b[_cons]
scalar se_intercept = _se[_cons]
scalar rmse = e(rmse)
scalar df = e(df_r)
scalar p = 2*ttail(e(df_r), abs(return(score_bc)/return(score_se)))
nois matrix define vcov = e(V)
nois matrix define b = e(b)


if "`method'" == "d"| "`method'" == "m" | "`method'" == "p"  | "`method'" == "r" | "`method'" == "s" {
matrix colnames b =     Bias Intercept
matrix rownames vcov =  Bias Intercept
matrix colnames vcov =  Bias Intercept
}
else if "`method'" == "e"  | "`method'" == "h" {
nois matrix colnames b =     Slope Bias
nois matrix rownames vcov =  Slope Bias
nois matrix colnames vcov =  Slope Bias
}

else if "`method'" == "t" {
nois matrix colnames b =     Slope Intercept
nois matrix rownames vcov =  Slope Intercept
nois matrix colnames vcov =  Slope Intercept
}
local yvar : variable label `yb'
nois matrix post b vcov, dep("`yvar'") dof(`e(df_r)') obs(`e(N)')
nois ereturn display, level(`level')
nois di " "
nois di " "
if "`method'" == "t" {
nois di in green "If intercept > 0 there is genuine empirical effect"
nois di " "
nois di " "
nois di in yellow "If intercept > 0 and intercept < 0.5 there is"
nois di in yellow "both small study bias and genuine empirical effect"
nois di " "
nois di " "
nois di in red "If intercept < 0 there is significant small study bias"

}


estimates restore stbias
predict `stpred'
local _ropts = cond(!missing("`regopts'"), "`regopts'", "clpattern(dash) clwidth(vthin)")
local stline "(line `xb' `stpred', `_ropts' )"
local _ropts2 = cond(!missing("`regopts'"), "`regopts'", "clpattern(dash) clwidth(vthin)")
local regline "(line `stpred' `xb' , `_ropts2' )"

if "`graph'" != "" {

if "`method'" == "d" | "`method'" == "p" | "`method'" == "s"{

#delimit;
nois twoway `stline'(scatter `xb' `yb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options'),
legend(label(2 "Study") label(1 "Regression" "Line") order(2 1) pos(2) col(1) size(*.75))
ylab(, angle(horizontal) labsize(*`textscale') format(%7.2f))
subtitle("Funnel Plot-Fitted Regression Line", size(*.90))
xlab(`xlab', labsize(*`textscale') angle(horizontal)) `xxtitle' title(`ptitle', size(*.90));
#delimit cr
}
else if "`method'" == "m" {
#delimit;
nois twoway `stline'(scatter `xb' `yb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options'),
legend(label(2 "Study") label(1 "Regression" "Line") order(2 1) pos(2) col(1) size(*.75))
ylab(, angle(horizontal) labsize(*`textscale') format(%7.0f))
subtitle("Funnel Plot-Fitted Regression Line", size(*.90))
xlab(`xlab', labsize(*`textscale') angle(horizontal)) `xxtitle' title(`ptitle', size(*.90));
#delimit cr
}
else if "`method'" == "h" | "`method'" == "r" | "`method'" == "e" | "`method'" == "t"  {
#delimit;
nois twoway `stline'(scatter `xb' `yb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options') ,
legend(label(2 "Study") label(1 "Regression" "Line") order(2 1) pos(2) col(1) size(*.75))
ylab(, angle(horizontal) labsize(*`textscale') format(%7.2f))
subtitle("Funnel Plot-Fitted Regression Line", size(*.90))
xlab(, labsize(*`textscale') angle(horizontal)) `xxtitle' title(`ptitle', size(*.90));
#delimit cr
}
}

if "`funnel'" != "" {
if "`method'" == "d" | "`method'" == "p" | "`method'" == "s"{

#delimit;
nois twoway (scatter `xb' `yb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options'),
legend(label(1 "Study") pos(2) col(1) size(*.75))
ylab(, angle(horizontal) labsize(*`textscale') format(%7.2f))
subtitle("Funnel Plot", size(*.90)) xlab(`xlab', labsize(*`textscale') angle(horizontal))
`xxtitle' title(`ptitle', size(*.90));
#delimit cr
}
else if "`method'" == "m" {
#delimit;
nois twoway (scatter `xb' `yb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options'),
legend(label( 1 "Study") pos(2) col(1) size(*.75))
ylab(, angle(horizontal) labsize(*`textscale') format(%7.0f))
subtitle("Funnel Plot", size(*.90)) xlab(`xlab', labsize(*`textscale') angle(horizontal))
 `xxtitle' title(`ptitle', size(*.90));
#delimit cr
}
else if "`method'" == "h" | "`method'" == "r" | "`method'" == "e" | "`method'" == "t"  {
#delimit;
nois twoway (scatter `xb' `yb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options'),
legend(label(1 "Study") pos(2) col(1) size(*.75))
ylab(, angle(horizontal) labsize(*`textscale') format(%7.2f))
subtitle("Funnel Plot", size(*.90))
xlab(, labsize(*`textscale') angle(horizontal)) `xxtitle' title(`ptitle', size(*.90));
#delimit cr
}
}



if "`regplot'" != "" {
if "`method'" == "d" | "`method'" == "p" | "`method'" == "s"{

#delimit;
nois twoway `regline'(scatter `yb' `xb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options'),
legend(label(2 "Study") label(1 "Regression" "Line") order(2 1) pos(2) col(1) size(*.75))
xlab(, angle(horizontal) labsize(*`textscale') format(%7.2f))
subtitle("Linear Regression Plot", size(*.90))
ylab(`xlab', labsize(*`textscale') angle(horizontal)) `yxtitle' title(`ptitle', size(*.90));
#delimit cr
}
else if "`method'" == "m" {
#delimit;
nois twoway `regline'(scatter `yb' `xb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options'),
legend(label(2 "Study") label(1 "Regression" "Line") order(2 1) pos(2) col(1) size(*.75))
xlab(, angle(horizontal) labsize(*`textscale') format(%7.0f))
subtitle("Linear Regression Plot", size(*.90))
ylab(`xlab', labsize(*`textscale') angle(horizontal)) `yxtitle' title(`ptitle', size(*.90));
#delimit cr
}
else if "`method'" == "h" | "`method'" == "r" | "`method'" == "e" | "`method'" == "t"  {
#delimit;
nois twoway `regline'(scatter `yb' `xb', sort `=cond(!missing("`pointopts'"), "`pointopts'", "ms(O)")' `options'),
legend(label(2 "Study") label(1 "Regression" "Line") order(2 1) pos(2) col(1) size(*.75))
xlab(, angle(horizontal) labsize(*`textscale') format(%7.2f))
subtitle("Linear Regression Plot", size(*.90))
ylab(, labsize(*`textscale') angle(horizontal)) `yxtitle' title(`ptitle', size(*.90));
#delimit cr
}
}

}


end