R/powerGUI.R

Defines functions pbat.power fireUpdatePower powerGrid fireUpdateAF_recalc fireUpdateOR_recalc fireUpdateAOR_recalc fireUpdate_recalc_updatePens getMOI fireUpdatePen_recalc fireUpdateAF fireUpdateOR fireUpdateAOR fireUpdatePen fireUpdate createContsAscertainmentGUI createDichotAscertainmentGUI createPowerGUI newframe dblGrid choicesEntryEmpty choicesEntry newSlider getPowerVSafe getPowerT getPowerN getPowerV getPowerSafe getPower setPower

Documented in pbat.power

####################################################################
# Thomas Hoffmann                                                  #
# CREATED:     05/29/2007                                          #
# MODIFIED:    06/09/2007                                          #
#                                                                  #
# DESCRIPTION:                                                     #
#  The major pbat-gui interface for power                          #
####################################################################

####################################################################
#                                                                  #
# CONSTANTS                                                        #
#                                                                  #
####################################################################
SLIDER_LENGTH <- 500
POWER_TEXT_LENGTH <- 80

FIRE_UPDATE_PEN <- 1
FIRE_UPDATE_AOR <- 2
FIRE_UPDATE_OR <- 3
FIRE_UPDATE_AF <- 4

FAMILY_MIN <- 1 ## for debug, maybe 20 otherwise?

####################################################################
#                                                                  #
# SET UP THE GLOBAL VARIABLES INTERFACE                            #
#                                                                  #
####################################################################
powerEnv <- new.env();
setPower <- function( x, value )
  assign( x, value, envir=powerEnv );
getPower <- function( x, mode="any", ifnotfound=NA )
  get( x, envir=powerEnv, mode=mode, inherits=FALSE )
getPowerSafe <- function( x, ifnotfound=NA )
  mget( x, envir=powerEnv, ifnotfound=ifnotfound )[[1]]

getPowerV <- function( ... )
  return( tclvalue( getPower( ... ) ) )
getPowerN <- function( ... )
  return( as.numeric(tclvalue( getPower( ... ) ) ) )
getPowerT <- function( ... )
  return( tclvalue( getPower( ... ) ) == TRUE )
getPowerVSafe <- function( ..., default=NA ) {
  res <- getPowerSafe( ... )
  if( is.na(res) )
    return(default)
  return( tclvalue( res ) )
}
####################################################################
#                                                                  #
# Graphical helper functions.                                      #
#                                                                  #
####################################################################

## Creates a slider, etc.
newSlider <- function( text, default, min, max, step=(max-min)/100, grid, update=fireUpdate, state="enabled" )
{
  sliderVal <- tclVar( default )
  ##sliderValLabel <- tklabel( grid, text=as.character(tclvalue(sliderVal)) );
  sliderValLabel <- tkentry( grid, width=10, textvariable=sliderVal )
  slider <- tkscale( grid, from=min, to=max, resolution=step,
                     showvalue=FALSE, variable=sliderVal, orient="horizontal",
                     length=SLIDER_LENGTH )
  tkgrid( slider,
          tklabel(grid, text=text),
          sliderValLabel )
  tkconfigure( sliderValLabel,textvariable=sliderVal )
  if( state=="disabled" ) {
    tkconfigure( slider, state="disabled" )
    tkconfigure( sliderValLabel, state="disbled" )
  }

  ## bind the update firing
  tkbind(sliderValLabel, "<Return>", update)
  tkbind(slider, "<ButtonRelease-1>", update)

  #tkgrid.configure( slider, sticky="news" )

  return( sliderVal )  ## return the tclvariable corresponding to the new object
}

choicesEntry <- function( main, label, choices, defaultChoice=1 ){
  ## Create a frame for everything
  frame <- tkframe( main, relief="groove", borderwidth=2 );
  tkgrid( frame );
  ##tkgrid.configure( frame, sticky="news" );
  tkgrid.configure( frame, sticky="nws" );

  ## The label
  lbl <- tklabel( frame, text=label );

  ## The choices
  rb <- list();
  rb.lbl <- list();
  rb.subframe <- list();

  ## Create the subframe for each choice
  for( i in 1:length(choices) )
    rb.subframe[[i]] <- tkframe( frame, relief='groove', borderwidth=1 );

  ## grid the subframes
  if( length(choices)==1 ){ ## Not really a 'choice' then, but necessary
    tkgrid( lbl, rb.subframe[[1]] );
  }else if( length(choices)==2 ){
    tkgrid( lbl, rb.subframe[[1]], rb.subframe[[2]] );
  }else if( length(choices)==3 ){
    tkgrid( lbl, rb.subframe[[1]], rb.subframe[[2]], rb.subframe[[3]] );
  }else if( length(choices)==4 ){
    tkgrid( lbl, rb.subframe[[1]], rb.subframe[[2]], rb.subframe[[3]], rb.subframe[[4]] );
  }

  ## Create the variable
  rbVal <- tclVar( choices[defaultChoice] );

  ## Create each choice
  for( i in 1:length(choices) ) {
    rb[[i]] <- tkradiobutton( rb.subframe[[i]] );
    tkconfigure( rb[[i]], variable=rbVal, value=choices[i]  );
    rb.lbl[[i]] <- tklabel( rb.subframe[[i]], text=choices[i] );
    tkgrid( rb[[i]], rb.lbl[[i]] );

    ## how about binding the fire event?
    tkbind( rb[[i]], "<ButtonRelease-1>", fireUpdate )
  }

  ## Return the variable
  return( rbVal );
}

## sort of clean-up code if you will - it sets the tclvariable, but doesn't draw it
choicesEntryEmpty <- function( main, label, choices, defaultChoice=1 ) {
  rbVal <- tclVar( choices[defaultChoice] )
  return( rbVal )
}

dblGrid <- function( main ) {
  f <- tkframe(main, borderwidth=0 );
  f1 <- tkframe( f, borderwidth=0 );
  f2 <- tkframe( f, borderwidth=0 );
  fblank <- tkframe( f, borderwidth=0 );
  tkgrid( f );
  tkgrid.configure( f, sticky="nws" );
  tkgrid( f1, fblank, f2 );
  tkgrid( tklabel(fblank,text="    ") );
  return( list(f1=f1,f2=f2) );
}

#newTE <- function( tclVar, option, helps=NULL, width=10, gridframe=form ) {
#  frame <- newframe( borderwidth=3, gridframe=gridframe );
#  but <- NULL;
#  if( !is.null(helps) ) {
#    but <- tkbutton( frame, text="?",
#                      command=function(){
#                        msgText <- paste( option, "-", helps[1] );
#                        msg(msgText)
#                      } );
#  }
#  lab <- tklabel( frame, text=option );
#  entry <- tkentry( frame, width=width, textvariable=tclVar );
#  if( !is.null(but) ) {
#    tkgrid( lab, entry, but );
#  }else{
#    tkgrid( lab, entry );
#  }
#}

newframe <- function( gridframe, grid=TRUE, relief="groove", borderwidth=2, sticky="nws" ) {
  frame <- tkframe( gridframe, relief=relief, borderwidth=borderwidth );
  if( !grid ) return(frame);
  tkgrid( frame );
  tkgrid.configure( frame, sticky=sticky );
  return(frame)
};


####################################################################
#                                                                  #
# Drawing the main form.                                           #
#                                                                  #
####################################################################
createPowerGUI <- function( mode="continuous" )
{
  ##require( tcltk )
  main <- tktoplevel()
  setPower( "main", main )
  tkwm.title( main, paste("Power calculations (",mode," trait)",sep="") )

  ## newSlider( text, default, min, max, step, main )
  f <- newframe( main )
  setPower( "gNumOffspring", newSlider( "Number of Offspring", 1, 1, 20, 1, f ) )
  setPower( "gNumParents", newSlider( "Number of parents", 2, 0, 2, 1, f ) )
  setPower( "gNumFamilies", newSlider( "Number of families", 500, FAMILY_MIN, 10000, 10, f ) )
  setPower( "gAdditionalOffspringPhenos", choicesEntry( main, "Phenotype non-proband offspring?", c("TRUE","FALSE") ) )

  if( mode=="dichotomous" ) {
    f <- newframe( main )
    f2 <- dblGrid( f )
    setPower( "gAscertainment", choicesEntry( f2$f1, "Ascertainment", c("affected","unaffected","na") ) )
    tkgrid( tkbutton( f2$f2, text="Additional offspring ascertainment", command=createDichotAscertainmentGUI ) )
  }

  f <- newframe( main )
  setPower( "gTrait", choicesEntryEmpty( f, "Trait", c(mode,mode) ) )

  if( mode=="dichotomous" ) {
    #tkgrid( tklabel( f, text="Dichotomous trait options" ) )
    f2 <- newframe( f, relief="sunken", borderwidth=5 )
    tkgrid( tklabel( f2, text="Option 1: Genotype penetrances" ) )
    setPower( "gPenAA", newSlider( "AA Penetrance", 0.8, 0, 1, 0.001, f2, fireUpdatePen ) )
    setPower( "gPenAB", newSlider( "AB Penetrance", 0.5, 0, 1, 0.001, f2, fireUpdatePen ) )
    setPower( "gPenBB", newSlider( "BB Penetrance", 0.3, 0, 1, 0.001, f2, fireUpdatePen ) )

    f3 <- newframe( f, relief="sunken", borderwidth=5 )
    tkgrid( tklabel( f3, text="Option 2: MOI, one of AF/OR_het/AOR, and population prevalence (must select AF/OR_het/AOR first)" ) )
    if( !powerDisabled() ) {
      setPower( "gModelGen", choicesEntry( f3, "Genetic Model for Data Generation", c("additive","dominant","recessive") ) )
      setPower( "gModelTest", choicesEntry( f3, "Genetic Model for Testing", c("additive","dominant","recessive") ) )
    }else{
      setPower( "gModelGen", choicesEntry( f3, "Genetic Model for Data Generation", c("additive") ) )
      setPower( "gModelTest", choicesEntry( f3, "Genetic Model for Testing", c("additive") ) )
    }

    f4 <- newframe( f3 )
    #setPower( "gAF", newSlider( "Allelic Genetic Attributable Fraction", 0.2, 0, 1, 0.0001, f4, fireUpdateAF ) )
    setPower( "gAF", tclVar(0.2) )
    setPower( "gOR1", newSlider( "Heterozygous odds ratio", 0.2, 0, 50, 0.01, f4, fireUpdateOR ) )
    setPower( "gOR2", newSlider( "Homozygous odds raito", 0.2, 0, 50, 0.01, f4, state="disbaled" ) ) ## Want this _disabled_
    setPower( "gAOR", newSlider( "Allelic odds ratio", 0.2, 0, 50, 0.01, f4, fireUpdateAOR ) )

    f5 <- newframe( f3 )
    setPower( "gPopPrev", newSlider( "Population prevalence", 0, 0, 1, 0.001, f5 ) )
  }else{
    #f2 <- newframe( f, borderwidth=0 )
    #f3 <- dblGrid( f2 )
    #tkgrid( tklabel( f3$f1, text="Continuous trait options" ) )
    #tkgrid( tkbutton( f3$f2, text="Additional offspring ascertainment", command=createContsAscertainmentGUI ) )
    tkgrid( tkbutton( f, text="Additional offspring ascertainment criterion", command=createContsAscertainmentGUI ) )
    setPower( "gHeritability", newSlider( "heritability (h^2)", 0.1, 0, 1, 0.001, f ) )
    setPower( "gContsAscertainmentLower", newSlider( "Lower ascertainment criterion", 0, 0, 1, 0.01, f ) )
    setPower( "gContsAscertainmentUpper", newSlider( "Upper ascertainment criterion", 1, 0, 1, 0.01, f ) )

    f <- newframe( main )
    if( !powerDisabled() ) {
      setPower( "gModelGen", choicesEntry( f, "Genetic Model for Data Generation", c("additive","dominant","recessive") ) )
      setPower( "gModelTest", choicesEntry( f, "Genetic Model for Testing", c("additive","dominant","recessive") ) )
    }else{
      setPower( "gModelGen", choicesEntry( f, "Genetic Model for Data Generation", c("additive") ) )
      setPower( "gModelTest", choicesEntry( f, "Genetic Model for Testing", c("additive") ) )
    }
  }

  f <- newframe( main )
  setPower( "gUseOffset", choicesEntry( f, "Offset", c("default (population prevalence)","manual") ) )
  setPower( "gOffset", newSlider( "Offset", 0, 0, 1, 0.001, f ) )

  f <- newframe( main )
  setPower( "gAfreqDSL", newSlider( "DSL Allele Frequency", 0.1, 0, 1, 0.001, f ) )
  setPower( "gIsDSL", choicesEntry( f, "Marker is DSL", c("TRUE","FALSE") ) )
  setPower( "gDiseaseAlleleGivenMarkerAllele", newSlider( "P(Disease Allele|Marker Allele)", 1, 0, 1, 0.01, f ) )
  setPower( "gAfreqMarker", newSlider( "Marker Allele Frequency", 0.1, 0, 1, 0.001, f ) )

  f <- newframe( main )
  setPower( "gAlpha", newSlider( "Significance level (alpha)", 0.01, 0, 0.1, 0.0001, f ) )
  setPower( "gNumSim", newSlider( "Number of Simulations", 1000, 100, 10000, 100, f ) )

  f <- newframe( main )
  #setPower( "gPower", newSlider( "Power (Monte-Carlo simulation)", 0, 0, 1, 0.0001, f) ) ## would be _really_ neat if could alter the sample size
  setPower( "gPower", newSlider( "Power (Monte-Carlo simulation)", 0, 0, 1, 0.0001, f, fireUpdatePower) )

  ## NEW - ITERATIONS before giving up completely
  f <- newframe( main )
  setPower( "gITERATION_KILLER", newSlider( "Max Gen Draw Iter before halt (0 disables)", 500, 0, 10000, 1, f ) )

  ## new - how about a status window?
  f <- newframe( main )
  gStatus=tclVar("")
  statusEntry <- tkentry( f, width=POWER_TEXT_LENGTH, textvariable=gStatus )
  tkgrid( tklabel( f, text="Status" ),
          statusEntry )
  try( tkconfigure( statusEntry, state="readonly" ) )
  setPower( "gStatus", gStatus )
}

createDichotAscertainmentGUI <- function()
{
  numOffspring <- as.integer(tclvalue(getPower("gNumOffspring")))
  if( numOffspring==1 ) {
    tkmessageBox( title="No additional offspring", message="No additional offspring to alter the ascertainment status of.", icon="info", type="ok" )
    return(invisible())
  }

  main <- tktoplevel()
  for( i in 2:numOffspring )
    setPower( paste("gAscertainment",i,sep=""), choicesEntry( main, paste("Ascertainment",i), c("affected","unaffected","na"), defaultChoice=3 ) )

}
createContsAscertainmentGUI <- function()
{
  numOffspring <- as.integer(tclvalue(getPower("gNumOffspring")))
  if( numOffspring==1 ) {
    tkmessageBox( title="No additional offspring", message="No additional offspring to alter the ascertainment status of.", icon="info", type="ok" )
    return(invisible())
  }

  main <- tktoplevel()
  for( i in 2:numOffspring ) {
    setPower( paste("gContsAscertainmentLower",i,sep=""), newSlider( paste("Lower ascertainment criterion",i), 0, 0, 1, 0.1, main ) )
    setPower( paste("gContsAscertainmentUpper",i,sep=""), newSlider( paste("Upper ascertainment criterion",i), 1, 0, 1, 0.1, main ) )
  }
}

####################################################################
#                                                                  #
# Called on the update of any variable to recompute power.         #
#                                                                  #
####################################################################
fireUpdate <- function()
{
  ## New, we need to fix up things according to what was last done!
  if( getPowerV("gTrait") != "continuous" ) {
    updateLast <- getPowerSafe("updateLast", ifnotfound=FIRE_UPDATE_PEN)
    if( updateLast==FIRE_UPDATE_PEN ) fireUpdatePen_recalc()
    if( updateLast==FIRE_UPDATE_AOR ) fireUpdateAOR_recalc()
    if( updateLast==FIRE_UPDATE_OR )  fireUpdateOR_recalc()
    if( updateLast==FIRE_UPDATE_AF )  fireUpdateAF_recalc()
  }
  ## fires an update to the power call
  ##print( "fire in the hole!" ) ## debugging

  ## get all the global values
  numOffspring <- getPowerV( "gNumOffspring" )
  numParents <- getPowerV( "gNumParents" )
  numFamilies <- getPowerV( "gNumFamilies" )
  additionalOffspringPhenos <- getPowerT( "gAdditionalOffspringPhenos" )


  ascertainment <- rep(0,numOffspring)
  ascertainment[1] <- getPowerVSafe( "gAscertainment", default="na" )
  if( as.integer(numOffspring) > 1 ) {
    for( i in 2:as.integer(numOffspring) ) {
      ascertainment[i] <- getPowerVSafe( paste("gAscertainment",i,sep=""), default="na" )
    }
  }
  modelGen <- getPowerV( "gModelGen" )
  modelTest <- getPowerV( "gModelTest" )
  trait <- getPowerV( "gTrait" )

  penAA <- getPowerVSafe( "gPenAA", default=0.0 )
  penAB <- getPowerVSafe( "gPenAB", default=0.0 )
  penBB <- getPowerVSafe( "gPenBB", default=0.0 )

  offset <- "default"
  if( getPowerV("gUseOffset")=="manual" )
    offset <- getPowerV("gOffset")

  heritability <- getPowerVSafe( "gHeritability" )
  contsAscertainmentLower <- rep(0,numOffspring)
  contsAscertainmentUpper <- rep(0,numOffspring)
  contsAscertainmentLower[1] <- getPowerVSafe( "gContsAscertainmentLower", default=0.0 )
  contsAscertainmentUpper[1] <- getPowerVSafe( "gContsAscertainmentUpper", default=1.0 )
  if( as.integer(numOffspring)>1 ) {
    for( i in 2:as.integer(numOffspring) ) {
      contsAscertainmentLower[i] <- getPowerVSafe( paste("gContsAscertainmentLower",i,sep=""), default=0.0 )
      contsAscertainmentUpper[i] <- getPowerVSafe( paste("gContsAscertainmentUpper",i,sep=""), default=1.0 )
    }
  }

  afreqDSL <- getPowerV( "gAfreqDSL" )
  isDSL <- getPowerT( "gIsDSL" )
  diseaseAlleleGivenMarkerAllele <- getPowerV( "gDiseaseAlleleGivenMarkerAllele" )
  afreqMarker <- getPowerV( "gAfreqMarker" )

  alpha <- getPowerN( "gAlpha" )
  numSim <- getPowerV( "gNumSim" )

  ITERATION_KILLER <- getPowerV( "gITERATION_KILLER" )

  ## fix up some things
  if( isDSL==TRUE )
    afreqMarker <- NA;
  if( trait!="continuous" ) {
    heritability <- 0.0
  }else if( heritability == 0.0 ) {
    heritability <- 0.0001 ## It can't be zero, or it won't do continuous...
  }

  ## and update the power
  tkconfigure(getPower("main"),cursor="watch")
  newPower <- pbat.powerCmd( numOffspring, numParents, numFamilies,
                             additionalOffspringPhenos,
                             ascertainment,
                             modelGen, modelTest,
                             afreqMarker,
                             penAA, penAB, penBB,
                             heritability, contsAscertainmentLower, contsAscertainmentUpper,
                             diseaseAlleleGivenMarkerAllele,
                             afreqDSL,
                             alpha,
                             offset,
                             numSim,
                             ITERATION_KILLER )
  tkconfigure(getPower("main"),cursor="arrow")

  gStatus = getPower("gStatus")
  if( newPower<0 ) {
    if( newPower==-1 )
      tclvalue(gStatus) <- "ERROR: Invalid parameters. Generally this occurs when marker allele frequency is not possible."
    if( newPower==-2 )
      tclvalue(gStatus) <- "ERROR: Too many iterations without viable family. Try changing some of the parameters to be less extreme."
    newPower <- 0
  }else{
    tclvalue(gStatus) <- ""
  }

  ggPower <- getPower("gPower")
  tclvalue( ggPower ) <- as.character(newPower)
  #cat( "Power", newPower, "\n" )

}

fireUpdatePen <- function() {
  setPower( "updateLast", FIRE_UPDATE_PEN )
  fireUpdate()
}
fireUpdateAOR <- function() {
  setPower( "updateLast", FIRE_UPDATE_AOR )
  fireUpdate()
}
fireUpdateOR <- function() {
  setPower( "updateLast", FIRE_UPDATE_OR )
  fireUpdate()
}
fireUpdateAF <- function() {
  setPower( "updateLast", FIRE_UPDATE_AF )
  fireUpdate()
}

fireUpdatePen_recalc <- function(do_AOR=TRUE, do_OR=TRUE, do_AF=TRUE, do_pop=TRUE) {
  penAA <- as.numeric( getPowerVSafe( "gPenAA", default=0.0 ) )
  penAB <- as.numeric( getPowerVSafe( "gPenAB", default=0.0 ) )
  penBB <- as.numeric( getPowerVSafe( "gPenBB", default=0.0 ) )

  afreq <- as.numeric( getPowerV( "gAfreqDSL" ) )

  aor <- allelic_OR( penAA, penAB, penBB, afreq )
  or <- calc_or( penAA, penAB, penBB, afreq )
  ar <- calc_ar( penAA, penAB, penBB, afreq )

  gAOR <- getPower("gAOR")
  if( do_AOR ) tclvalue( gAOR ) <- as.character(aor)

  gOR1 <- getPower( "gOR1" )
  if( do_OR ) tclvalue( gOR1 ) <- as.character(or[1])
  gOR2 <- getPower( "gOR2" )
  tclvalue( gOR2 ) <- as.character(or[2])

  gAF <- getPower( "gAF" )
  if( do_AF ) tclvalue( gAF ) <- as.character(ar)

  popPrev <- getPower( "gPopPrev" )
  if( do_pop ) tclvalue( popPrev ) <- calc_popPrev( penAA, penAB, penBB, afreq )
}

getMOI <- function() {
  model <- getPowerVSafe( "gModel", default="additive" )
  if( model=="dominant" )
    return( MOI_DOMINANT )
  if( model=="recessive" )
    return( MOI_RECESSIVE )
  if( model=="additive" )
    return( MOI_ADDITIVE )
  if( model=="multiplicative" )
    return( MOI_MULTIPLICATIVE )
  stop( paste("getMOI(), moi (",model,") misunderstood!",sep="") )
}

fireUpdate_recalc_updatePens <- function( pen ) {
  penAA <- getPower( "gPenAA" )
  penAB <- getPower( "gPenAB" )
  penBB <- getPower( "gPenBB" )

  tclvalue( penAA ) <- as.character( pen[1] )
  tclvalue( penAB ) <- as.character( pen[2] )
  tclvalue( penBB ) <- as.character( pen[3] )
}

fireUpdateAOR_recalc <- function()
{
  moi <- getMOI()
  afreq <- as.numeric( getPowerVSafe( "gAfreqDSL" ) )
  popPrev <- as.numeric( getPowerVSafe( "gPopPrev" ) )
  gAOR <- as.numeric( getPowerVSafe( "gAOR" ) )

  pen <- pen_allelicOR( moi, afreq, popPrev, gAOR )
  fireUpdate_recalc_updatePens( pen )

  fireUpdatePen_recalc(do_AOR=FALSE,do_pop=FALSE)
}

fireUpdateOR_recalc <- function()
{
  moi <- getMOI()
  afreq <- as.numeric( getPowerVSafe( "gAfreqDSL" ) )
  popPrev <- as.numeric( getPowerVSafe( "gPopPrev" ) )
  or1 <- as.numeric( getPowerVSafe( "gOR1" ) )

  pen <- pen_or1( moi, afreq, popPrev, or1 );
  fireUpdate_recalc_updatePens( pen )

  fireUpdatePen_recalc(do_OR=FALSE,do_pop=FALSE)
}

fireUpdateAF_recalc <- function()
{
  moi <- getMOI()
  afreq <- as.numeric( getPowerVSafe( "gAfreqDSL" ) )
  popPrev <- as.numeric( getPowerVSafe( "gPopPrev" ) )
  af <- as.numeric( getPowerVSafe( "gAF" ) )

  pen <- pen_ar( moi, afreq, popPrev, af );
  fireUpdate_recalc_updatePens( pen )

  fireUpdatePen_recalc(do_AF=FALSE,do_pop=FALSE)
}

powerGrid <- function( pseq, power ) {
  powerCalc <- rep(0,length(seq))

  gNumFamilies <- getPower( "gNumFamilies" )

  for( i in 1:length(pseq) ) {
    tclvalue(gNumFamilies) <- pseq[i]
    fireUpdate()
    powerCalc[i] <- as.numeric( getPowerV("gPower") )
    if( powerCalc[i] > power ) {
      if( i==1 ) return( pseq[i] )
      return( mean( pseq[(i-1):i] ) )
    }
    #Sys.sleep(0.01)
    tcl("update")
  }

  return( max(pseq) )
}

fireUpdatePower <- function()
{
  power <- as.numeric( getPowerVSafe( "gPower" ) )
  numSim <- as.numeric( getPowerVSafe( "gNumSim" ) )

  ## okay, first set numSim a little coarser (if possible)
  gNumSim <- getPower("gNumSim")
  tclvalue(gNumSim) <- as.character(numSim/10)

  ## coarse grid search (by 100?)
  pseq <- seq( from=100, to=10000, by=100 )
  grid <- powerGrid( pseq, power )
  tclvalue(gNumSim) <- as.character(numSim/5)
  pseq <- seq( from=grid-50, to=grid+50, by=10 )
  grid <- powerGrid( pseq, power )
  tclvalue(gNumSim) <- as.character(numSim)
  pseq <- seq( from=grid-5, to=grid+5, by=1 )
  grid <- powerGrid( pseq, power )

  ## set the best
  gNumFamilies <- getPower("gNumFamilies")
  tclvalue(gNumFamilies) <- as.character(ceiling(grid))

  ## and make sure didn't fall off the face of the grid
  fireUpdate()
}

###########################
## The exported function ##
###########################
pbat.power <- function(mode="continuous")
{
  ## 04/17/2008 -- bringing in the additive routine
  ##if( powerDisabled() ) stop( "Coming soon!" )

  if( mode!="continuous" && mode!="dichotomous" ) {
    tkmessageBox( title="continuous/binary", message="mode must be 'continuous' or 'binary'", icon="info", type="ok" )
    return(invisible())
  }

  createPowerGUI(mode)
  fireUpdate() ## set some defaults accross the board
}

Try the pbatR package in your browser

Any scripts or data that you put into this service are public.

pbatR documentation built on March 7, 2023, 5:59 p.m.