--- a
+++ b/R/accrual.R
@@ -0,0 +1,164 @@
+#This file contains the generator functions for recruiting extra subjects 
+#into a predict from data simulation. It also contains the code for
+#estimating k in the accrual cdf G(t) t^k/B^k from recruitment data.
+
+##' @include eventData.R fromDataInternal.R
+NULL
+
+##' A class to allow additional subjects 
+##' to be recruited onto the study
+##' @slot f A function with 1 argument (the number of subjects to be recruited)
+##' which returns a vector of recruitment times (of the required length)
+##' @slot model A string, name of the accrual procedure used  
+##' @slot text The summary text to be output when printing the accrual procedure
+##' for example "a poisson process with rate..."
+##' @seealso \code{\link{show,AccrualGenerator-method}}
+##' @export
+setClass("AccrualGenerator",
+         slots=list(f="function",
+                    model="character",
+                    text="character"
+         )
+)
+
+##' @name show
+##' @rdname show-methods
+##' @aliases show,AccrualGenerator-method
+##' @export
+setMethod("show","AccrualGenerator",function(object){
+  cat(paste("Accrual model:",object@model,"\n"))
+  cat(paste("Model Description:\n"))
+  cat(object@text)  
+})
+
+##' Create A Poisson process accrual generator
+##' @param start.date The start date for the recruitment process
+##' @param rate The rate of the required Poisson process.
+##' @return An \code{AccrualGenerator} object which can 
+##' be used when recruiting subjects with a Possion process
+##' with given \code{start.date} and \code{rate}
+##' @export 
+Generate.PoissonAccrual <- function(start.date,rate){
+  if(rate <= 0) stop("rate must be positive")
+  start.date <- FixDates(start.date)
+  f <- function(N){
+    start.date + ceiling( cumsum( rexp( N, rate=rate ) ) )
+  }
+  
+  r <- if(rate < 0.01) r else round(rate,2)
+  
+  text <- paste("a poisson process with rate=", 
+                 r, " and start date=", start.date,".",sep="")
+  
+  new("AccrualGenerator",f=f,
+      model="Poisson process",text=text)    
+    
+}
+
+##' Create An AccrualGenerator using a power law recruitment
+##' 
+##' Subjects are accrued according to the c.d.f 
+##' \code{G(t)=t^k/B^k} where \code{k} is a parameter, 
+##' \code{t} is the time and \code{B} is the recruitment period. 
+##'  
+##' See the predict from data vignette for further details  
+##' @param start.date The start of the subject accrual period
+##' @param end.date The date the last subject is accrued so \code{B} = 
+##' \code{end.date} - \code{start.date} unless \code{rec.start.date} is used see 
+##' below
+##' @param k The non-uniformity accrual parameter
+##' @param deterministic Logical, if FALSE then the recruitment times 
+##' are non-stochastically chosen so that their cumulative distribution function is \code{G(t)}
+##' otherwise they are generated by sampling random variables with a cdf \code{G(t)}
+##' @param rec.start.date If this argument is used the subjects are still recruited between 
+##' start.date and end.date but they follow the cdf \code{G(t)=(t^k-L^k)/(B^k-L^k)} where
+##' \code{t} is in \code{[L,B]} and \code{B = end.date - rec.start.date} and \code{L = start.date- rec.start.date}.
+##' @return An AccrualGenerator object which generates the required subject accruals
+##' @export
+Generate.Accrual <- function(start.date,end.date,k,deterministic=FALSE,rec.start.date=NULL){
+  start.date <- FixDates(start.date)
+  end.date <- FixDates(end.date)
+  rec.start.date <- if(is.null(rec.start.date)) start.date else FixDates(rec.start.date)
+  
+  # Length of recruitment period
+  B <- as.integer(end.date - rec.start.date)
+  L <- as.integer(start.date - rec.start.date)
+  
+  if(L < 0 || k <= 0|| B <= L){
+    stop("Invalid arguments")
+  }
+  
+  if(deterministic){
+    f <- function(N){
+      as.Date(((1:N/N)*(B^k-L^k) + L^k)^(1/k)-L,origin=start.date)
+    }
+    stext <- "non-stochastic"
+  }
+  else{
+    f <- function(N){
+      ans <- ((B^k-L^k)*runif(N) + L^k)^(1/k)-L
+      ans[order(ans)]
+      as.Date(ans,origin=start.date)
+    }
+    stext <- "stochastic"
+  }  
+  
+  text <- paste("a ",stext  ," allocation following G(t)=t^k/B^k, where k=", 
+  round(k,2), " and B=",B," days is the recruitment period [", rec.start.date, ", ", end.date, "].",sep="")
+  
+  if(L!=0){
+    text <- paste(text," New subjects will be recruited after ",start.date,".",sep="") 
+  }
+  
+  new("AccrualGenerator",f=f,
+      model="Power law allocation",text=text) 
+  
+} 
+
+##' Generic function to estimate non-uniformity accrual 
+##' parameter \code{k}
+##' 
+##' Note The estimate produced assumes recruitment has completed.
+##' @docType methods
+##' @param object An \code{EventData} object
+##' @param ... Additional arguments to be passed to specific method
+##' @rdname estimateAccrualParameter-methods  
+##' @export
+setGeneric("estimateAccrualParameter",function(object,...) standardGeneric("estimateAccrualParameter"))
+
+
+
+##' @param start.date The startdate for recruitment, by default the date 
+##' the first subject is recruited. If subjects are recruited on start.date, it is
+##' assumed they are recruited on the following day to avoid log(0) in the 
+##' maximum likelihood estimate.
+##' @param end.date The end date for recruitment, by default the date 
+##' the last subject is recruited. 
+##' @return A maximum likelihood estimate for k, see vignette 
+##' for further details    
+##' @rdname estimateAccrualParameter-methods 
+##' @aliases estimateAccrualParameter,EventData-method
+##' @export
+setMethod("estimateAccrualParameter", "EventData",
+  function(object, start.date=min(object@subject.data$rand.date),
+           end.date=max(object@subject.data$rand.date)){
+    message("Note this estimate assumes recruitment has completed")          
+    
+    start.date <- FixDates(start.date)
+    end.date <- FixDates(end.date)
+    
+    B <- as.numeric(end.date-start.date)
+    if(B <= 0) stop("end.date must be after start.date")
+    
+    recs <- (object@subject.data$rand.date-start.date)
+    recs <- ifelse(recs==0,0.5,recs)
+    
+    if(any(recs< 0 | recs > B)) stop("Subjects recruited outside of recruitment period")
+    
+    return(MLestimateK(B,as.numeric(recs)))
+    
+  }
+)
+
+
+               
\ No newline at end of file