*! version 2.0 April 15, 2008 @ 21:12:57
*! Author: Roger Harbord, University of Bristol


	/*
		Plot probability contour ellipse on ROC plot
		with Rutter-Gatsonis axes,
		then corresponding probability contour on SROC plot.
		Also plot SROC line / curve from R-G model.
*/

	/* parameters from gllamm estimates as run in bivariate.ado */
	/* NB variance-covariance of (thetaa,thetab) added to variance params
	to give predictive variance */


program define metandiplot, rclass
version 8.2
	syntax [varlist(min=0 max=4 default=none)] [if] [in]  ///
	  [aweight fweight pweight] ///
	  [, Npoints(integer 500)  ///
	  Level(real `c(level)')   ///
	  noTRuncate ///
	  PREDLevel(numlist  max=5 >=10 <=99.99 sort) ///
	  CUrveopts(string asis) SUmmopts(string asis) COnfopts(string asis)  ///
	  PRedopts(string asis)  STudyopts(string asis)  ///
	  XSIZe(real 4) YSIZe(real 5)  ///
	  addplot(string) by(string) ///
	  * ]	// any other options passed on to end of twoway

	tempvar n sens spec curve x curve phi
	tempvar confA confB confsens confspec n

	marksample touse

	if inrange( `: word count `varlist'', 1, 3) error 102  ///
	  // Too few variables specified

	capture assert e(cmd) == "metandi"
	if _rc !=0 error 301 /* last estimates not found */

	if "`by'" != "" {
		di as error "option by() not allowed"
		exit 198 // invalid syntax
		}

	preserve
	quietly {

		/* initialise legend counter */
		local li 1

		if "`varlist'" != "" { // varlist given containing 2x2 table vars
			tokenize `varlist'
			local tp `1'
			local fp `2'
			local fn `3'
			local tn `4'

			/* study circles */
			if "`studyopts'" == "off" local studyopts
			else {
				if "`weight'" == "" {
					gen `n' = `tp'+`fp'+`fn'+`tn' if `touse'
					local exp "= `n'"
					}
				gen `sens' = `tp' / (`tp'+`fn') if `touse'
				label var `sens' "Sensitivity"
				gen `spec' = `tn' / (`tn'+`fp') if `touse'
				label var `spec' "Specificity"
				local studyplot `"scatter `sens' `spec' if `touse' [aw `exp']"'
				local studyplot "`studyplot', msym(oh) mlcol(gray) mlwidth(thin)"
				local studyplot `"`studyplot' `studyopts' ||"'
				local legend `"`legend' label(`li' "Study estimate")"'
				local order "`order' `li++'"
//				local ++li
				}

			} // if "`varlist'" != ""

		tempname covmuAB sAB rconfAB sepredA sepredB rpredAB
		matrix V = e(V)
		scalar `covmuAB' = V[1,2]
		scalar `sAB' = _b[sAB]

		/* derived params */
		scalar `rconfAB' = `covmuAB'/(_se[muA]*_se[muB])
		scalar `sepredA' = sqrt(_b[s2A]+_se[muA]^2)
		scalar `sepredB' = sqrt(_b[s2B]+_se[muB]^2)
		scalar `rpredAB' = (`sAB'+`covmuAB')/(`sepredA'*`sepredB')

		if "`confopts'" !="off" | "`predopts'" != "off" ///
		  range `phi' 0 `=2*c(pi)' `npoints'


		/* summary point */
		if `"`summopts'"' == "off" local summopts
		else {
			local sensbar = invlogit(_b[muA])
			local specbar = invlogit(_b[muB])
			local summplot `"scatteri `sensbar' `specbar', ms(S) msiz(*1.4) `summopts' ||"'
			local legend `"`legend' label(`li' "Summary point")"'
			local order "`order' `li++'"
			}


		/* HSROC summary curve */
		if `"`curveopts'"' == "off" local curveopts
		else {
			tempname b Lambda minse
			scalar `b' = (_b[s2B]/_b[s2A])^.25
			scalar `Lambda' = _b[muA]*`b' + _b[muB]/`b'
			range `x' 0 1 `npoints'
			gen `curve' = invlogit( ( -logit(`x') /`b' + `Lambda') / `b' )
			replace `curve' = 0 if `x' == 1
			replace `curve' = 1 if `x' == 0

			/* truncate curve outside region of data if given */
			if "`varlist'" != "" & "`truncate'" == "" {
				summ `sens' , meanonly
				scalar `minse' = r(min)
				summ `spec' , meanonly
				replace `x' = . if `x' < r(min) | `curve' < `minse'
				}

			local curveplot `"line `curve' `x', clpatt(solid) `curveopts' ||"'
			local legend `"`legend' label(`li' "HSROC curve")"'
			local order "`order' `li++'"
			}

		/*
			/* truncate curve outside prediction region */
			replace `x' = . if ///
			( ( logit(`x') - _b[muB] ) / `sepredB' )^2 + ///
			( ( logit(`curve') - _b[muA]) / `sepredA' )^2 - ///
			2 * (`rpredAB') *  ///
			( logit(`x') - _b[muB] ) * ( logit(`curve') - _b[muA])  / ///
			( `sepredB' * `sepredA' ) ///
			> `croot'^2 * (1 -(`rpredAB')^2)
*/


		/* confidence region */
		if `"`confopts'"' == "off" local confopts
		else {
		// const. for contour level
			tempname croot
			scalar `croot' = sqrt(2*invF(2,e(N)-2,`level'/100))
			gen `confB' = _b[muB] + _se[muB] * `croot' * cos(`phi')
			gen `confA' = _b[muA] + _se[muA] * `croot' * cos(`phi' + acos(`rconfAB'))
			gen `confsens' = invlogit(`confA')
			gen `confspec' = invlogit(`confB')
			local confplot `"line `confsens' `confspec',clpatt(dash) `confopts' ||"'
			local legend `"`legend' label(`li' "`level'% confidence" "region")"'
			local order "`order' `li++'"
			}


		/* prediction region */
		if `"`predopts'"' == "off" local predopts
		else {
			if "`predlevel'" == "" local predlevel `level'
			foreach pl of local predlevel {
				local i = `i' + 1
				tempvar predA`i' predB`i' predsens`i' predspec`i'
				local croot = sqrt(2*invF(2,e(N)-2,`pl'/100))
				gen `predB`i'' = _b[muB] + `sepredB' * `croot' * cos(`phi')
				gen `predA`i'' = _b[muA] + `sepredA' * `croot' *  ///
				  cos(`phi' + acos(`rpredAB'))
				gen `predsens`i'' = invlogit(`predA`i'')
				gen `predspec`i'' = invlogit(`predB`i'')
				local predplot  ///
				  `"`predplot' line `predsens`i'' `predspec`i'' ,clpatt(shortdash) `predopts' ||"'
				local legend `"`legend' label(`li' "`pl'% prediction" "region")"'
			local order "`order' `li++'"
				}
			}


		} // end quietly

	twoway `studyplot' `summplot' `curveplot' `confplot' `predplot'  `addplot' ///
	  || , aspect(1) xsc(range(0 1) rev) ysc(range(0 1))  ///
	  xla(0(.2)1, nogrid) yla(0(.2)1, nogrid) ///
	  xti(Specificity) yti(Sensitivity)  ///
	  legend(  ///
	  /// colfirst  position(6) cols(2) ///
	  /// order(`order' ) ///
	  `legend' ///
	  ) ///
	  xsize(`xsize') ysize(`ysize') ///
	  `options' ///
	  /* plotregion(margin(zero)) */

	restore

end

	exit