surveillance/0000755000176200001440000000000014615346213012753 5ustar liggesuserssurveillance/NAMESPACE0000644000176200001440000003331014615162374014176 0ustar liggesusers## refer to all C routines by their name prefixed by C_ useDynLib(surveillance, .registration = TRUE, .fixes = "C_") importFrom(Rcpp, evalCpp) # see vignette("Rcpp-package", package="Rcpp") ## although Rcpp is only used on C-level we need to "ensure that Rcpp is loaded ## so any dynamic linking to its code can be resolved. (There may be none, but ## there could be, now or in future.)" (B. Ripley, 2013-09-08) ############### ### IMPORTS ### ############### ### Import all packages listed as Depends ### (for utils and polyCub: only selected methods are imported) import(methods, grDevices, graphics, stats) ## sp classes & utilities (bbox, coordinates, dimensions, overlay, plot, ...) ## (we "Depend" on package sp since it defines essential data classes & methods) import(sp) ## we define own methods for generating xtable()'s, which we want to be usable import(xtable) ### required generics for own methods (that's why we "Depend" on these packages) ## importFrom(stats, coef, vcov, logLik, nobs, residuals, confint, AIC, extractAIC, ## profile, simulate, update, terms, add1, drop1, predict, as.stepfun) importFrom(utils, head, tail, toLatex) ### required functions from utils and stats ## importFrom(stats, pnorm, cov2cor, ks.test, formula, rnorm, runif, step, dist, ## update.formula, terms.formula, rpois, rnbinom, setNames, ## na.omit, as.formula, pnbinom, qnbinom, qnorm, sd, glm, optim, ## poisson, ppois, qpois, predict.glm, summary.glm, quasipoisson, ## glm.fit) ## and many more... importFrom(utils, packageName, packageVersion, modifyList, capture.output, read.table, data, setTxtProgressBar, txtProgressBar, sessionInfo, head.matrix, str, flush.console, write.table, as.roman, tail.matrix, methods) ### sampling from mv.Gaussian for OSAIC weights (twinSIR) and iafplot (twinstim) importFrom(MASS, mvrnorm) ### disProg-specific importFrom(MASS, glm.nb) # for algo.glrnb ##importFrom(msm, msm, hmmPois, viterbi.msm) # for algo.hmm() ##importFrom(spc, xcusum.arl, xcusum.crit) # for find.kh() ## (packages msm and spc are now "suggested", not imported) ### hhh4-specific importFrom(MASS, ginv, negative.binomial) importFrom(Matrix, Matrix) importClassesFrom(Matrix, ddiMatrix) importMethodsFrom(Matrix, coerce, forceSymmetric) ## sparse matrix methods provide a significant speed-up in marFisher importFrom(nlme, fixef, ranef) export(fixef, ranef) # we define corresponding methods for "hhh4" models ### twinSIR-specific # for use in computing OSAIC weights by simulation #importFrom(quadprog, solve.QP) # moved to "Suggests" ### twinstim-specific importFrom(spatstat.geom, area.owin, as.im.function, diameter.owin, disc, edges, inside.owin, intersect.owin, is.polygonal, as.polygonal, bdist.points, owin, ppp, shift.owin, spatstat.options, vertices) importFrom(spatstat.geom, marks) export(marks) # we define an epidataCS-method importFrom(spatstat.geom, multiplicity) export(multiplicity) # we define a Spatial-method importFrom(polyCub, polyCub, .polyCub.iso, polyCub.SV, polyCub.midpoint, xylist) importFrom(MASS, kde2d, truehist) ############### ### EXPORTS ### ############### ### general exports export(surveillance.options, reset.surveillance.options) export(animate) # new S3-generic export(R0) # new S3-generic export(intensityplot) # new S3-generic export(formatPval) # yapf -- yet another p-value formatter export(anscombe.residuals) export(magic.dim, primeFactors, bestCombination) # similar to n2mfrow export(isoWeekYear) #extract ISO 8601 date export(formatDate) #format.Date + %Q and %q formatting strings export(refvalIdxByDate) export(ks.plot.unif) export(checkResidualProcess) # for twinstim and twinSIR export(plapply) export(clapply) export(fanplot) # spatial utilities export(discpoly) export(unionSpatialPolygons) export(nbOrder) export(poly2adjmat) export(polyAtBorder) export(layout.labels) export(layout.scalebar) # randomly break tied event times or coordinates export(untie) # new S3-generic #export(untie.default, untie.matrix, untie.epidataCS) S3method(untie, default) S3method(untie, matrix) S3method(untie, epidataCS) # intersection of a polygonal and a circular domain export(intersectPolyCircle) S3method(intersectPolyCircle, owin) S3method(intersectPolyCircle, SpatialPolygons) # little helper: multiplicity of points S3method(multiplicity, Spatial) # list coefficients by model component export(coeflist) S3method(coeflist, default) S3method(coeflist, twinstim) S3method(coeflist, simEpidataCS) S3method(coeflist, hhh4) # Spatio-temporal cluster detection export(stcd) # tests for space-time interaction export(knox) S3method(print, knox) S3method(plot, knox) S3method(xtable, knox) S3method(toLatex, knox) export(stKtest) S3method(plot, stKtest) # PIT histograms export(pit) export(pit.default) S3method(pit, default) S3method(pit, oneStepAhead) S3method(pit, hhh4) S3method(plot, pit) # calibration test for Poisson or NegBin predictions export(calibrationTest) S3method(calibrationTest, default) export(calibrationTest.default) export(dss, logs, rps, ses) # nses ### sts(BP|NC)-specific export(sts) exportClasses(sts, stsBP) export(linelist2sts) export(animate_nowcasts) # conversion of "sts" objects S3method(as.ts, sts) export(as.xts.sts) S3method(xts::as.xts, sts) # delayed registration S3method(as.data.frame, sts) # see ?Methods_for_S3 exportMethods(as.data.frame) export(tidy.sts) # more S4 generics, some with an equivalent S3-method, see ?Methods_for_S3 exportMethods(dim, dimnames, year, epochInYear, "[") S3method(plot, sts) exportMethods(plot) S3method(toLatex, sts) exportMethods(toLatex) S3method(aggregate, sts) exportMethods(aggregate) # methods for accessing/replacing slots of an sts object (cf. AllGeneric.R) exportMethods(epoch,observed,alarms,upperbound,population,control,multinomialTS,neighbourhood) exportMethods("epoch<-","observed<-","alarms<-","upperbound<-","population<-","control<-","multinomialTS<-","neighbourhood<-") # methods for accessing/replacing slots of an stsNC object exportMethods(reportingTriangle,delayCDF,score,predint) # plot variants export(stsplot_space) export(stsplot_time, stsplot_time1, stsplot_alarm) export(addFormattedXAxis, atChange, at2ndChange, atMedian) #for time axis formatting export(stsplot_spacetime) # old implementation of (animated) map S3method(animate, sts) # S3-method for an S4 class, see ?Methods_for_S3 export(autoplot.sts) S3method(ggplot2::autoplot, sts) # delayed registration # outbreak detection algorithms (sts-interfaces) export(wrap.algo, farrington, bayes, rki, cusum, glrpois, glrnb, outbreakP, boda) # FIXME: rogerson, hmm ?? export(earsC) export(farringtonFlexible) export(categoricalCUSUM, pairedbinCUSUM, pairedbinCUSUM.runlength) export(nowcast, backprojNP) export(bodaDelay) # sts creation functions export(sts_creation) export(sts_observation) ### disProg-specific export(create.disProg) S3method(print, disProg) S3method(plot, disProg) S3method(aggregate, disProg) export(sim.pointSource, sim.seasonalNoise) export(LRCUSUM.runlength, arlCusum, find.kh, findH, hValues, findK) export(estimateGLRNbHook) export(algo.compare, algo.quality, algo.summary) ## outbreak detection algorithms (old disProg implementations) export(algo.bayes, algo.bayes1, algo.bayes2, algo.bayes3, algo.bayesLatestTimepoint, algo.call, algo.cdc, algo.cdcLatestTimepoint, algo.cusum, algo.farrington, algo.glrnb, algo.glrpois, algo.hmm, algo.outbreakP, algo.rki, algo.rki1, algo.rki2, algo.rki3, algo.rkiLatestTimepoint, algo.rogerson, algo.twins) ## auxiliary functions for algo.farrington (FIXME: why export these internals?) export(algo.farrington.assign.weights, algo.farrington.fitGLM, algo.farrington.fitGLM.fast, algo.farrington.fitGLM.populationOffset, algo.farrington.threshold) S3method(plot, atwins) S3method(plot, survRes) S3method(print, algoQV) S3method(xtable, algoQV) ### conversion between old disProg and new sts classes export(disProg2sts) export(sts2disProg) ### twinSIR-specific export(cox) export(as.epidata) S3method(as.epidata, data.frame) export(as.epidata.data.frame) S3method(as.epidata, default) export(as.epidata.default) export(intersperse) export(twinSIR) export(stateplot) export(simEpidata) S3method(update, epidata) S3method("[", epidata) S3method(print, epidata) S3method(summary, epidata) S3method(print, summary.epidata) S3method(plot, epidata) S3method(animate, epidata) S3method(plot, summary.epidata) S3method(animate, summary.epidata) S3method(print, twinSIR) S3method(summary, twinSIR) S3method(print, summary.twinSIR) S3method(plot, twinSIR) S3method(intensityplot, twinSIR) export(intensityplot.twinSIR) # for convenience S3method(profile, twinSIR) S3method(plot, profile.twinSIR) S3method(vcov, twinSIR) S3method(logLik, twinSIR) S3method(AIC, twinSIR) S3method(extractAIC, twinSIR) S3method(simulate, twinSIR) export(simulate.twinSIR) # for convenience S3method(residuals, twinSIR) S3method(intensityplot, simEpidata) export(intensityplot.simEpidata) # for convenience ### twinstim-specific export(as.epidataCS) export(glm_epidataCS) export(twinstim) export(simEpidataCS) export(siaf, siaf.constant, siaf.step, siaf.gaussian, siaf.exponential, siaf.powerlaw, siaf.powerlaw1, siaf.powerlawL, siaf.student) export(tiaf, tiaf.constant, tiaf.step, tiaf.exponential) export(epidataCS2sts) export(epitest) S3method(coef, epitest) S3method(plot, epitest) export(getSourceDists) S3method(nobs, epidataCS) S3method("[", epidataCS) S3method(update, epidataCS) export(update.epidataCS) # for convenience export(permute.epidataCS) S3method(head, epidataCS) S3method(tail, epidataCS) S3method(print, epidataCS) S3method(subset, epidataCS) S3method(summary, epidataCS) S3method(print, summary.epidataCS) S3method(as.stepfun, epidataCS) S3method(animate, epidataCS) export(animate.epidataCS) # for convenience S3method(marks, epidataCS) export(marks.epidataCS) # for convenience since its a foreign generic S3method(plot, epidataCS) export(epidataCSplot_time, epidataCSplot_space) S3method(as.epidata, epidataCS) export(as.epidata.epidataCS) # for convenience S3method(print, twinstim) S3method(summary, twinstim) export(summary.twinstim) # for convenience S3method(print, summary.twinstim) S3method(toLatex, summary.twinstim) S3method(xtable, summary.twinstim) export(xtable.summary.twinstim) # for xtable.twinstim S3method(xtable, twinstim) S3method(plot, twinstim) export(iafplot) export(intensity.twinstim) S3method(intensityplot, twinstim) export(intensityplot.twinstim) # for convenience S3method(profile, twinstim) S3method(coef, summary.twinstim) S3method(vcov, twinstim) S3method(vcov, summary.twinstim) S3method(logLik, twinstim) S3method(extractAIC, twinstim) S3method(nobs, twinstim) S3method(simulate, twinstim) export(simulate.twinstim) # for convenience export(simEndemicEvents) S3method(R0, twinstim) export(simpleR0) S3method(residuals, twinstim) S3method(update, twinstim) export(update.twinstim) # for convenience S3method(terms, twinstim) S3method(all.equal, twinstim) export(stepComponent) S3method(terms, twinstim_stependemic) S3method(terms, twinstim_stepepidemic) S3method(update, twinstim_stependemic) S3method(update, twinstim_stepepidemic) S3method(add1, twinstim) S3method(add1, twinstim_stependemic) S3method(add1, twinstim_stepepidemic) S3method(drop1, twinstim) S3method(drop1, twinstim_stependemic) S3method(drop1, twinstim_stepepidemic) S3method(residuals, simEpidataCS) S3method(R0, simEpidataCS) S3method(intensityplot, simEpidataCS) export(intensityplot.simEpidataCS) # for convenience S3method(print, simEpidataCSlist) S3method("[[", simEpidataCSlist) S3method(plot, simEpidataCSlist) ### hhh4-specific ## main functions export(hhh4) export(addSeason2formula) export(makeControl) export(zetaweights, W_powerlaw) export(W_np) export(getNEweights, coefW) export(oneStepAhead) export(scores) export(permutationTest) ## S3-methods S3method(print, hhh4) S3method(summary, hhh4) S3method(print, summary.hhh4) S3method(nobs, hhh4) S3method(logLik, hhh4) S3method(formula, hhh4) S3method(terms, hhh4) S3method(coef, hhh4) S3method(vcov, hhh4) S3method(fixef, hhh4) S3method(ranef, hhh4) S3method(confint, hhh4) S3method(residuals, hhh4) S3method(predict, hhh4) S3method(update, hhh4) export(update.hhh4) # for add-on packages S3method(all.equal, hhh4) S3method(simulate, hhh4) S3method(plot, hhh4) export(plotHHH4_fitted, plotHHH4_fitted1, plotHHH4_season, getMaxEV_season, plotHHH4_maxEV, getMaxEV, plotHHH4_maps, plotHHH4_ri, plotHHH4_neweights) S3method(quantile, oneStepAhead) S3method(confint, oneStepAhead) S3method(plot, oneStepAhead) S3method(scores, default) S3method(scores, hhh4) S3method(scores, oneStepAhead) S3method(calibrationTest, hhh4) S3method(calibrationTest, oneStepAhead) ## methods for simulations from hhh4 fits S3method("[", hhh4sims) S3method(aggregate, hhh4sims) S3method(plot, hhh4sims) export(as.hhh4simslist) S3method(as.hhh4simslist, hhh4sims) S3method(as.hhh4simslist, list) S3method(as.hhh4simslist, hhh4simslist) S3method("[", hhh4simslist) S3method("[[", hhh4simslist) S3method(aggregate, hhh4simslist) S3method(plot, hhh4simslist) export(plotHHH4sims_size) export(plotHHH4sims_time) export(plotHHH4sims_fan) S3method(scores, hhh4sims) S3method(scores, hhh4simslist) ## internal functions for use by add-on packages export(meanHHH, sizeHHH, decompose.hhh4) surveillance/demo/0000755000176200001440000000000014615167606013706 5ustar liggesuserssurveillance/demo/cost.R0000644000176200001440000001565514531322004014773 0ustar liggesusers## need a writable figs/ directory to save selected figures OUTDIR <- if (interactive()) tempdir() else "." stopifnot(dir.create(file.path(OUTDIR, "figs"))) ################################################### ### chunk number 1: ################################################### library("surveillance") options(width=70) options("prompt"="R> ") set.seed(1234) opendevice <- function(horizontal=TRUE,width=7,height=4,...) { #Do it for postscript instead -- who uses postscript these days?? args <- list(...) args$file <- file.path(OUTDIR, sub("\\.pdf$",".eps",args$file)) args$width <- width args$height <- height args$horizontal <- FALSE do.call("postscript",args) par(mar=c(4,4,2,2)) } ################################################### ### chunk number 3: ################################################### opendevice(file="figs/002.pdf") data("ha") plot(aggregate(ha),main="Hepatitis A in Berlin 2001-2006") dev.off() ################################################### ### chunk number 4: ################################################### sps <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) ################################################### ### chunk number 5: ################################################### opendevice(file="figs/003.pdf") plot(sps,xaxis.years=FALSE,legend.opts=list(x="topleft")) dev.off() ################################################### ### chunk number 7: ################################################### ha.b662 <- algo.bayes(aggregate(ha), control = list(range = 209:290, b = 2, w = 6, alpha = 0.01)) opendevice(file="figs/hab662.pdf") plot(ha.b662, firstweek=1, startyear = 2005,legend.opts=list(x="topleft",horiz=TRUE)) dev.off() ################################################### ### chunk number 9: ################################################### cntrl <- list(range = 300:400, m = 1, w = 3, b = 5, alpha = 0.01) sps.cdc <- algo.cdc(sps, control = cntrl) sps.farrington <- algo.farrington(sps, control = cntrl) ################################################### ### chunk number 10: ################################################### opendevice(file="figs/farringtoncdc.pdf") par(mfcol = c(1, 2),cex=0.8) plot(sps.cdc, legend = NULL, xaxis.years=FALSE) plot(sps.farrington, legend = NULL, xaxis.years=FALSE) dev.off() ################################################### ### chunk number 12: ################################################### opendevice(file="figs/hacusum.pdf") kh <- find.kh(ARLa=500,ARLr=7) ha.cusum <- algo.cusum(aggregate(ha),control=list(k=kh$k,h=kh$h,m="glm",trans="rossi",range=209:290)) plot(ha.cusum,startyear=2005,legend.opts=list(x=30,y=5.5)) dev.off() #Extract coefficients beta <- coef(ha.cusum$control$m.glm) ################################################### ### chunk number 13: ################################################### print(algo.quality(ha.b662)) ################################################### ### chunk number 14: ################################################### #This chunk contains stuff the reader should not see, but which is necessary #for the visual block to work. control = list( list(funcName = "rki1"), list(funcName = "rki2"), list(funcName = "rki3"), list(funcName = "bayes1"), list(funcName = "bayes2"), list(funcName = "bayes3"), # list(funcName = "cdc",alpha=0.05,b=2,m=1), # list(funcName = "farrington",alpha=0.05,b=0,w=6), list(funcName = "farrington",alpha=0.05,b=1,w=6), list(funcName = "farrington",alpha=0.05,b=2,w=4)) control <- lapply(control,function(ctrl) {ctrl$range <- 300:400;return(ctrl)}) #Update range in each - cyclic continuation data("k1") range = (2*4*52) + 1:length(k1$observed) aparv.control <- lapply(control,function(cntrl) { cntrl$range=range;return(cntrl)}) #Auxiliary function to enlarge data enlargeData <- function(disProgObj, range = 1:156, times = 1){ disProgObj$observed <- c(rep(disProgObj$observed[range], times), disProgObj$observed) disProgObj$state <- c(rep(disProgObj$state[range], times), disProgObj$state) return(disProgObj) } #Outbreaks outbrks <- c("m1", "m2", "m3", "m4", "m5", "q1_nrwh", "q2", "s1", "s2", "s3", "k1", "n1", "n2", "h1_nrwrp") #Load and enlarge data. outbrks <- lapply(outbrks,function(name) { data(list=name) enlargeData(get(name),range=1:(4*52),times=2) }) #Apply function to one surv.one <- function(outbrk) { algo.compare(algo.call(outbrk,control=aparv.control)) } ################################################### ### chunk number 16: ALGOSUMMARY ################################################### res <- algo.summary(lapply(outbrks,surv.one)) ################################################### ### chunk number 17: ################################################### print(res,digits=3) ################################################### ### chunk number 18: eval=FALSE ################################################### ## setClass( "sts", representation(week = "numeric", ## freq = "numeric", ## start = "numeric", ## observed = "matrix", ## state = "matrix", ## alarm = "matrix", ## upperbound = "matrix", ## neighbourhood= "matrix", ## populationFrac= "matrix", ## map = "SpatialPolygonsDataFrame", ## control = "list")) ## ################################################### ### chunk number 20: ################################################### ## import shapefile as "SpatialPolygonsDataFrame" shp <- system.file("shapes/berlin.shp",package="surveillance") if (requireNamespace("maptools")) { # archived on 2023-10-16 map <- maptools::readShapePoly(shp, IDvar = "SNAME") } else { # replacement code map <- sf::as_Spatial(sf::st_read(shp, stringsAsFactors = TRUE, quiet = TRUE)) row.names(map) <- as.character(map$SNAME) } ## convert to "sts" class ha.sts <- disProg2sts(ha, map = map) ## or simply load the prepared object from the package: data("ha.sts") opendevice(file="figs/ha-1unit.pdf",width=7,height=7) par(mar=c(0,0,0,0)) plot(ha.sts,type=observed ~ 1 | unit) dev.off() ################################################### ### chunk number 22: ################################################### opendevice(file="figs/ha-timeunit.pdf",width=7,height=5) ha4 <- aggregate(ha.sts[,c("pank","mitt","frkr","scho","chwi","neuk")],nfreq=13) ha4.cusum <- cusum(ha4,control=list(k=1.5,h=1.75,m="glm",trans="rossi",range=52:73)) #ha4.b332 <- bayes(ha4,control=list(range=52:73,b=2,w=3,alpha=0.01/6)) plot(ha4.cusum,type=observed ~ time | unit) dev.off() surveillance/demo/biosurvbook.R0000644000176200001440000002170613433736567016410 0ustar liggesusers###################################################################### # Demo of the code used in the book chapter # Hoehle, M. and A. Mazick, A. (2010) Aberration detection in R # illustrated by Danish mortality monitoring, Book chapter in # T. Kass-Hout and X. Zhang (Eds.) Biosurveillance: A Health Protection # Priority, CRC Press. # # The data read by csv files in the chapter are found as data("momo") # in the package. Courtesy to Statens Serum Institut for making # the mortality data public. # # Author: Michael Hoehle # Date: 13 Oct 2009 ###################################################################### #Load surveillance package library("surveillance") #Load Danish mortality data (see book chapter for CSV reading") data("momo") #Create a plot of the data as in Figure. 1 of the book chapter. #Note: The year is determined by the ISO week, not the date plot(momo[year(momo)>=2000,],ylab="No. of deaths",par.list=list(mar=c(4,2.2,2,1),cex.axis=1.5), type=observed ~ time | unit, col=c(gray(0.3),NA,NA),xaxis.tickFreq=list("%G"=atChange),xaxis.labelFormat="%G",xlab="time (weeks)") par(mfrow=c(1,2),mar=c(4,4,2,1)) plot(momo,ylab="No. of deaths",xlab="time (weeks)",legend.opts=NULL, type=observed ~ time,col=c(gray(0.3),NA,NA),xaxis.tickFreq=list("%G"=atChange,"%m"=atChange),xaxis.labelFreq=list("%G"=atChange),xaxis.labelFormat="%G") plot(momo[,"[0,1)"],xlab="time (weeks)",ylab="No. of deaths",legend.opts=NULL,col=c(gray(0.3),NA,NA),xaxis.tickFreq=list("%G"=atChange,"%m"=atChange),xaxis.labelFreq=list("%G"=atChange),xaxis.labelFormat="%G") par(mfrow=c(1,1)) #Monitoring starts in week 40, 2007 phase2 <- which(epoch(momo) >= "2007-10-01") s.far <- farrington(momo[,"[0,1)"], control=list(range=phase2,alpha=0.01,b=5,w=4,powertrans="none")) cntrlFar <- s.far@control upper.ptnone <-s.far@upperbound cntrlFar$powertrans <- "2/3" upper.pt23 <- farrington(momo[,"[0,1)"],control=cntrlFar)@upperbound cntrlFar$powertrans <- "1/2" upper.pt12 <- farrington(momo[,"[0,1)"],control=cntrlFar)@upperbound ## plot(s.far,ylab="No. of deaths",xlab="time (weeks)",main="") ymax <- max(s.far@upperbound, upper.pt12, upper.pt23)*1.2 #par(mar=c(4,4,1,1)) plot(s.far,legend.opts=NULL,ylab="No. of deaths",main="",xlab="time (weeks)",ylim=c(0,ymax),col=c("darkgray",NA,gray(0.3)),lty=c(1,1,1),lwd=c(1,1,2),dx.upperbound=0,alarm.symbol=list(pch=24,col=1, cex=1)) lines(c(1:nrow(s.far)-0.5,nrow(s.far)+0.5),c(upper.pt12,upper.pt12[nrow(s.far)]),type="s",col="darkgray",lwd=2,lty=2) lines(c(1:nrow(s.far)-0.5,nrow(s.far)+0.5),c(upper.pt23,upper.pt23[nrow(s.far)]),type="s",col=gray(0.1),lwd=2,lty=3) legend(x="topright",c("none","1/2","2/3"),col=c(gray(0.3),"darkgray",gray(0.1)),lwd=2,lty=1:3,horiz=TRUE) #legend(x="topright",c("none","1/2","2/3",expression(hat(mu)[t[0]])),col=c(gray(0.3),"darkgray",gray(0.1),1),lwd=c(2,2,2,3),lty=c(1:3,1),horiz=TRUE) #Median of predictive distribution lines(c(1:nrow(s.far)-0.5,nrow(s.far)+0.5),c(s.far@control$pd[,2],s.far@control$pd[nrow(s.far),2]),type="s",col=1,lwd=3) text(nrow(s.far)+2,tail(observed(s.far),n=1),expression(hat(mu)[t[0]])) alarmDates <- epoch(s.far)[alarms(s.far) == 1] par(mar=c(4,4,2,2)) surv2 <- s.far surv2@observed <- 0*surv2@observed surv2@upperbound <- 0*surv2@observed plot(surv2,ylim=c(-0.05,1),ylab="Quantile",xlab="time (weeks)",legend.opts=NULL,main="",dx.upperbound=0,alarm.symbol=list(pch=24,col=1, cex=1)) lines(surv2@control$pd[,1], type="S") lines( c(1,nrow(surv2)+0.), rep( 1-s.far@control$alpha/2, 2),lty=2,col=1) s.far.all <- farrington(momo, control=list(range=phase2,alpha=0.01,b=5,w=4)) ## s.far.all <- farrington(momo, control=list(range=phase2,alpha=0.01,b=5,w=4)) ## plot(s.far.all,type = alarm ~ time,xlab="time (weeks)") par(mar=c(4,4,1,1)) plot(s.far.all,type = alarm ~ time,xlab="time (weeks)",main="",alarm.symbol=list(pch=24,col=1, cex=1.5),lvl=rep(1,nrow(s.far.all))) ####################################################################### #Negative binomial GLM modelling using the population size as covariate ####################################################################### phase1 <- which(year(momo) == 2002 & epochInYear(momo) == 40):(phase2[1]-1) momo.df <- as.data.frame(momo) m <- MASS::glm.nb( `observed.[75,85)` ~ 1 + epoch + sin(2*pi*epochInPeriod) + cos(2*pi*epochInPeriod) + `population.[75,85)`, data=momo.df[phase1,]) mu0 <- predict(m, newdata=momo.df[phase2,],type="response") ci <- confint(m) kappa <- 1.2 s.nb <- glrnb(momo[,"[75,85)"], control=list(range=phase2,alpha=1/m$theta,mu0=mu0,c.ARL=4.75,theta=log(kappa),ret="cases")) alarmDates <- epoch(s.nb)[alarms(s.nb) == 1] plot(s.nb,dx.upperbound=0,legend.opts=NULL,ylab="No. of deaths",main="",ylim=c(0,max(observed(s.nb))*1.1),xlab="time (weeks)",col=c("darkgray",NA,1),lwd=c(1,1,2),lty=c(1,1,1),alarm.symbol=list(pch=24,col=1, cex=1)) lines(mu0,lwd=2,col=1,lty=2) lines(exp(log(mu0) + log(kappa)),col=1,lty=3,lwd=3) legend(x=20,y=100,c(expression(mu[0,t]),expression(mu[1,t]),"NNBA"),col=c(1,1,1),lty=c(2,3,1),horiz=TRUE,bg="white",lwd=c(2,3,2)) set.seed(123) ###################################################################### # P(N_c <= 51|\tau=\infty) computation ###################################################################### #Number of simulations to perform. In book chapter this number is #1000, but for the sake of a speedy illustration this is drastically #reduced in this demonstration nSims <- 10 #1000 ###################################################################### # Simulate one run-length by first generating data from the negative # binomial model and then applying the LR NegBin CUSUM to it ###################################################################### simone.TAleq65 <- function(sts, g) { observed(sts)[phase2,] <- rnbinom(length(mu0), mu=mu0, size=m$theta) one <- glrnb(sts, control=modifyList(control(s.nb), list(c.ARL=g))) return(any(alarms(one) > 0)) } #Determine run-length using 1000 Monte Carlo samples g.grid <- seq(1,8,by=0.5) pMC <- sapply(g.grid, function(g) { mean(replicate(nSims, simone.TAleq65(momo[,"[75,85)"],g))) }) #Density for comparison in the negative binomial distribution dY <- function(y,mu,log=FALSE, alpha, ...) { dnbinom(y, mu=mu, size=1/alpha, log=log) } #nMax <- max(which( dY(0:1e4, mu=max(mu0),alpha=1/m$theta) >= 1e-20)) - 1 pMarkovChain <- sapply( g.grid, function(g) { TA <- LRCUSUM.runlength( mu=t(mu0), mu0=t(mu0), mu1=kappa*t(mu0), h=g, dfun = dY, n=rep(600,length(mu0)), alpha=1/m$theta) return(tail(TA$cdf,n=1)) }) par(mar=c(4,4,2,2)) matplot(g.grid, cbind(pMC,pMarkovChain),type="l",ylab=expression(P(T[A] <= 65 * "|" * tau * "=" * infinity)),xlab="g",col=1) prob <- 0.1 lines(range(g.grid),rep(prob,2),lty=3,lwd=2) axis(2,at=prob,las=1,cex.axis=0.7) legend(x="topright",c("Monte Carlo","Markov chain"), lty=1:2,col=1) m.01 <- MASS::glm.nb( `observed.[0,1)` ~ 1 + epoch + `population.[0,1)`+ sin(2*pi*epochInPeriod) + cos(2*pi*epochInPeriod), data=momo.df[phase1,]) mu0 <- predict(m.01, newdata=momo.df[phase2,],type="response") #Correct for past outbreaks #omega <- algo.farrington.assign.weights(residuals(m.01, type="deviance")) #m.01.refit <- glm.nb( `observed.[0,1)` ~ 1 + epoch + `population.[0,1)`+ sin(2*pi*epochInPeriod) + cos(2*pi*epochInPeriod), data=momo.df[phase1,],weights=omega) #mu0.refit <- predict(m.01.refit, newdata=momo.df[phase2,],type="response") #Results from the previous Farrington method mu0.far <- control(s.far)$pd[,2] ###################################################################### # Simulate one run-length by first generating data from the negative # binomial model and then applying the LR NegBin CUSUM to it ###################################################################### simone.TAleq65.far <- function(sts, alpha, mu0, size) { observed(sts)[phase2,] <- rnbinom(length(mu0), mu=mu0, size=size) res <- farrington(sts, control=modifyList(control(s.far), list(alpha=alpha))) return(any(as.logical(alarms(res)))) } #Determine run-length using 1000 Monte Carlo samples res.far <- replicate(nSims, simone.TAleq65.far(momo[,"[0,1)"],alpha=0.01,mu0=mu0.far,size=m.01$theta)) (pTA65.far <- mean(res.far)) #Run CUSUM kappa <- 1.2 s.nb.01 <- glrnb(momo[,"[0,1)"], control=list(range=phase2,alpha=1/m.01$theta,mu0=mu0.far,c.ARL=2.1,theta=log(kappa),ret="cases")) alarmDates <- epoch(s.nb.01)[alarms(s.nb.01) == 1] mu1 <- kappa*mu0.far #Show as usual plot(s.nb.01,dx.upperbound=0,legend.opts=NULL,ylab="No. of deaths",main="",xlab="time (weeks)",col=c("darkgray",NA,1),lwd=c(1,1,1),lty=c(1,1,1),ylim=c(0,max(s.nb.01@upperbound))*1.15,alarm.symbol=list(pch=24,col=1, cex=1)) lines(1:(nrow(s.far)+1)-0.5, c(mu0.far,tail(mu0.far,n=1)),lwd=3,col=1,lty=1,type="s") lines(1:(nrow(s.far)+1)-0.5, c(mu1,tail(mu1,n=1)),col=1,lty=3,lwd=3,type="s") legend(x="topright",c(expression(mu[0,t]),expression(mu[1,t]),"NNBA"),col=c(1,1,1),lty=c(1,3,1),horiz=TRUE,bg="white",lwd=c(3,3,1)) surveillance/demo/fluBYBW.R0000644000176200001440000001773014531325151015277 0ustar liggesusers################################################################################ ### Demo of hhh4() modelling of influenza in Southern Germany - data("fluBYBW") ### based on ### ### Paul, M. and Held, L. (2011): Predictive assessment of a non-linear random ### effects model for multivariate time series of infectious disease counts. ### Statistics in Medicine, 30, 1118-1136. ### ### RUNNING THE WHOLE SCRIPT TAKES ~20 MINUTES! ### ### Copyright (C) 2009-2012 Michaela Paul, 2012-2013,2016-2019 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ library("surveillance") ## Reproducibility set.seed(1) # affects initial values for ri() terms options(digits = 5) # avoid machine-specific output ## Weekly counts of influenza in 140 districts of Bavaria and Baden-Wuerttemberg data("fluBYBW") # data corrected in surveillance 1.6-0 # -> minor differences to original results in the paper ################################################## # Fit the models from the Paul & Held (2011) paper ################################################## ## generate formula for temporal and seasonal trends f.end <- addSeason2formula(f = ~ -1 + ri(type="iid", corr="all") + I((t-208)/100), S=3, period=52) ## settings for the optimizer opt <- list(stop = list(tol=1e-5, niter=200), regression = list(method="nlminb"), variance = list(method="nlminb")) ## models # A0 cntrl_A0 <- list(ar = list(f = ~ -1), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose = 1) summary(res_A0 <- hhh4(fluBYBW,cntrl_A0)) # B0 cntrl_B0 <- list(ar = list(f = ~ 1), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1) res_B0 <- hhh4(fluBYBW,cntrl_B0) # C0 cntrl_C0 <- list(ar = list(f = ~ -1 + ri(type="iid", corr="all")), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1) res_C0 <- hhh4(fluBYBW,cntrl_C0) #A1 # weight matrix w_ji = 1/(No. neighbors of j) if j ~ i, and 0 otherwise wji <- neighbourhood(fluBYBW)/rowSums(neighbourhood(fluBYBW)) cntrl_A1 <- list(ar = list(f = ~ -1), ne = list(f = ~ 1, weights = wji), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1) res_A1 <- hhh4(fluBYBW,cntrl_A1) # B1 cntrl_B1 <- list(ar = list(f = ~ 1), ne = list(f = ~ 1, weights = wji), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1) res_B1 <- hhh4(fluBYBW,cntrl_B1) # C1 cntrl_C1 <- list(ar = list(f = ~ -1 + ri(type="iid", corr="all")), ne = list(f = ~ 1, weights = wji), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1) res_C1 <- hhh4(fluBYBW,cntrl_C1) #A2 cntrl_A2 <- list(ar = list(f = ~ -1), ne = list(f = ~ -1 + ri(type="iid",corr="all"), weights=wji), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1) res_A2 <- hhh4(fluBYBW,cntrl_A2) # B2 cntrl_B2 <- list(ar = list(f = ~ 1), ne = list(f = ~ -1 + ri(type="iid",corr="all"), weights =wji), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1) res_B2 <- hhh4(fluBYBW,cntrl_B2) # C2 cntrl_C2 <- list(ar = list(f = ~ -1 + ri(type="iid", corr="all")), ne = list(f = ~ -1 + ri(type="iid",corr="all"), weights =wji), end = list(f =f.end, offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1, start=list(fixed=fixef(res_B0),random=c(rep(0,140), ranef(res_B0)), sd.corr=c(-.5,res_B0$Sigma.orig,0))) res_C2 <- hhh4(fluBYBW,cntrl_C2) # D cntrl_D <- list(ar = list(f = ~ 1), ne = list(f = ~ -1 + ri(type="iid"), weights = wji), end = list(f =addSeason2formula(f = ~ -1 + ri(type="car") + I((t-208)/100), S=3, period=52), offset = population(fluBYBW)), family = "NegBin1", optimizer = opt, verbose=1) res_D <- hhh4(fluBYBW,cntrl_D) ########################################################### ## Exemplary summary of model B2 ## (compare with Paul & Held, 2011, Table III and Figure 5) ########################################################### summary(res_B2, idx2Exp = 1:2, maxEV = TRUE) ## Note: as of surveillance 1.6-0, results differ slightly from the paper ## (see penalized log-likelihood), because a superfluous row of zeros ## has been removed from the fluBYBW data .idx <- c(113, 111, 46, 77) plot(res_B2, units = .idx, names = fluBYBW@map@data[.idx, "name"], legend = 2, legend.args = list(x = "topleft"), legend.observed = TRUE) ###################################################################### # Compare the predictive performance of the models by computing # one-step-ahead predictions to be assessed by proper scoring rules ###################################################################### ## do 1-step ahead predictions for the last two years tp <- nrow(fluBYBW)-2*52 verbose <- interactive() ## for this demo: only calculate pseudo-predictions based on the final fit ## to avoid the time-consuming sequential refitting at each step. TYPE <- "final" ## use "rolling" for true one-step-ahead predictions => TAKES ~8 HOURS! val_A0 <- oneStepAhead(res_A0, tp=tp, type=TYPE, verbose=verbose) val_B0 <- oneStepAhead(res_B0, tp=tp, type=TYPE, verbose=verbose) val_C0 <- oneStepAhead(res_C0, tp=tp, type=TYPE, verbose=verbose) val_A1 <- oneStepAhead(res_A1, tp=tp, type=TYPE, verbose=verbose) val_B1 <- oneStepAhead(res_B1, tp=tp, type=TYPE, verbose=verbose) val_C1 <- oneStepAhead(res_C1, tp=tp, type=TYPE, verbose=verbose) val_A2 <- oneStepAhead(res_A2, tp=tp, type=TYPE, verbose=verbose) val_B2 <- oneStepAhead(res_B2, tp=tp, type=TYPE, verbose=verbose) val_C2 <- oneStepAhead(res_C2, tp=tp, type=TYPE, verbose=verbose) val_D <- oneStepAhead(res_D, tp=tp, type=TYPE, verbose=verbose) ## compute scores vals <- ls(pattern="val_") nam <- substring(vals,first=5,last=6) whichScores <- c("logs", "rps", "ses") scores_i <- vector(mode="list", length=length(vals)) meanScores <- NULL for(i in seq_along(vals)){ sc <- scores(get(vals[i]), which=whichScores, individual=TRUE, reverse=TRUE) ## reverse=TRUE => same permutation test results as in surveillance < 1.16.0 scores_i[[i]] <- sc meanScores <- rbind(meanScores,colMeans(sc, dims=2)) } names(scores_i) <- nam rownames(meanScores) <- nam print(meanScores) ## Note that the above use of "final" fitted values instead of "rolling" ## one-step-ahead predictions leads to different mean scores than reported ## in Paul & Held (2011, Table IV). ## assess statistical significance of score differences compareWithBest <- function(best, whichModels, nPermut=9999, seed=1234){ set.seed(seed) pVals <- NULL for(score in seq_along(whichScores)){ p <- c() for(model in whichModels){ p <- c(p, if(model==best) NA else permutationTest(scores_i[[model]][,,score],scores_i[[best]][,,score], plot=interactive(),nPermutation=nPermut, verbose=TRUE)$pVal.permut) } pVals <- cbind(pVals,p) } return(pVals) } pVals_flu <- compareWithBest(best=9, whichModels=1:10, nPermut=999, # reduced for this demo seed=2059710987) rownames(pVals_flu) <- nam colnames(pVals_flu) <- whichScores print(pVals_flu) surveillance/demo/v77i11.R0000644000176200001440000004342514531323206014762 0ustar liggesusers################################################################################ ### Replication code from Meyer et al. (2017, JSS), ### illustrating the spatio-temporal endemic-epidemic modelling frameworks ### 'twinstim', 'twinSIR', and 'hhh4'. The full reference is: ### ### Meyer, Held, and Hoehle (2017): ### Spatio-Temporal Analysis of Epidemic Phenomena Using the R Package surveillance. ### Journal of Statistical Software, 77(11), 1-55. ### https://doi.org/10.18637/jss.v077.i11 ### ### Changes to the original replication script are marked with a "##M" comment. ### ### Copyright (C) 2017-2019 Sebastian Meyer, Leonhard Held, Michael Hoehle ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ ##M use old RNGversion to reproduce published simulation results in Section 3.4 RNGversion("3.3.3") # sampling has changed in R 3.6.0 ##M reduce printed precision for less machine-specific output options(digits = 5) ################################################################################ ## Section 3: Spatio-temporal point pattern of infective events ################################################################################ library("surveillance") # you should also have installed the suggested packages ## 3.2. Data structure: 'epidataCS' data("imdepi", package = "surveillance") events <- SpatialPointsDataFrame( coords = coordinates(imdepi$events), data = marks(imdepi, coords = FALSE), proj4string = imdepi$events@proj4string # ETRS89 projection (+units = km) ) stgrid <- imdepi$stgrid[,-1] load(system.file("shapes", "districtsD.RData", package = "surveillance")) imdepi <- as.epidataCS(events = events, W = stateD, stgrid = stgrid, qmatrix = diag(2), nCircle2Poly = 16) summary(events) .stgrid.excerpt <- format(rbind(head(stgrid, 3), tail(stgrid, 3)), digits = 3) rbind(.stgrid.excerpt[1:3, ], "..." = "...", .stgrid.excerpt[4:6, ]) imdepi summary(imdepi) par(mar = c(5, 5, 1, 1), las = 1) plot(as.stepfun(imdepi), xlim = summary(imdepi)$timeRange, xaxs = "i", xlab = "Time [days]", ylab = "Current number of infectives", main = "") ## axis(1, at = 2557, labels = "T", font = 2, tcl = -0.3, mgp = c(3, 0.3, 0)) par(las = 1) plot(imdepi, "time", col = c("indianred", "darkblue"), ylim = c(0, 20)) par(mar = c(0, 0, 0, 0)) plot(imdepi, "space", lwd = 2, points.args = list(pch = c(1, 19), col = c("indianred", "darkblue"))) layout.scalebar(imdepi$W, scale = 100, labels = c("0", "100 km"), plot = TRUE) ## animation::saveHTML( ## animate(subset(imdepi, type == "B"), interval = c(0, 365), time.spacing = 7), ## nmax = Inf, interval = 0.2, loop = FALSE, ## title = "Animation of the first year of type B events") eventDists <- dist(coordinates(imdepi$events)) (minsep <- min(eventDists[eventDists > 0])) set.seed(321) imdepi_untied <- untie(imdepi, amount = list(s = minsep / 2)) imdepi_untied_infeps <- update(imdepi_untied, eps.s = Inf) imdsts <- epidataCS2sts(imdepi, freq = 12, start = c(2002, 1), tiles = districtsD) par(las = 1, lab = c(7, 7, 7), mar = c(5, 5, 1, 1)) plot(imdsts, type = observed ~ time) plot(imdsts, type = observed ~ unit, population = districtsD$POPULATION / 100000) ## 3.3. Modeling and inference (endemic <- addSeason2formula(~offset(log(popdensity)) + I(start / 365 - 3.5), period = 365, timevar = "start")) imdfit_endemic <- twinstim(endemic = endemic, epidemic = ~0, data = imdepi_untied, subset = !is.na(agegrp)) summary(imdfit_endemic) imdfit_Gaussian <- update(imdfit_endemic, epidemic = ~type + agegrp, siaf = siaf.gaussian(F.adaptive = TRUE), ##M set F.adaptive=TRUE for replication with surveillance >= 1.15.0 start = c("e.(Intercept)" = -12.5, "e.siaf.1" = 2.75), control.siaf = list(F = list(adapt = 0.25), Deriv = list(nGQ = 13)), cores = 2 * (.Platform$OS.type == "unix"), model = TRUE) print(xtable(imdfit_Gaussian, caption = "Estimated rate ratios (RR) and associated Wald confidence intervals (CI) for endemic (\\code{h.}) and epidemic (\\code{e.}) terms. This table was generated by \\code{xtable(imdfit\\_Gaussian)}.", label = "tab:imdfit_Gaussian"), sanitize.text.function = NULL, sanitize.colnames.function = NULL, sanitize.rownames.function = function(x) paste0("\\code{", x, "}")) R0_events <- R0(imdfit_Gaussian) tapply(R0_events, marks(imdepi_untied)[names(R0_events), "type"], mean) imdfit_powerlaw <- update(imdfit_Gaussian, data = imdepi_untied_infeps, siaf = siaf.powerlaw(), control.siaf = NULL, start = c("e.(Intercept)" = -6.2, "e.siaf.1" = 1.5, "e.siaf.2" = 0.9)) imdfit_step4 <- update(imdfit_Gaussian, data = imdepi_untied_infeps, siaf = siaf.step(exp(1:4 * log(100) / 5), maxRange = 100), control.siaf = NULL, start = c("e.(Intercept)" = -10, setNames(-2:-5, paste0("e.siaf.", 1:4)))) par(mar = c(5, 5, 1, 1)) set.seed(2) # Monte-Carlo confidence intervals plot(imdfit_Gaussian, "siaf", xlim = c(0, 42), ylim = c(0, 5e-5), lty = c(1, 3), xlab = expression("Distance " * x * " from host [km]")) plot(imdfit_powerlaw, "siaf", add = TRUE, col.estimate = 4, lty = c(2, 3)) plot(imdfit_step4, "siaf", add = TRUE, col.estimate = 3, lty = c(4, 3)) legend("topright", legend = c("Power law", "Step (df = 4)", "Gaussian"), col = c(4, 3, 2), lty = c(2, 4, 1), lwd = 3, bty = "n") AIC(imdfit_endemic, imdfit_Gaussian, imdfit_powerlaw, imdfit_step4) ## Example of AIC-based stepwise selection of the endemic model imdfit_endemic_sel <- stepComponent(imdfit_endemic, component = "endemic") ## -> none of the endemic predictors is removed from the model par(mar = c(5, 5, 1, 1), las = 1) intensity_endprop <- intensityplot(imdfit_powerlaw, aggregate = "time", which = "endemic proportion", plot = FALSE) intensity_total <- intensityplot(imdfit_powerlaw, aggregate = "time", which = "total", tgrid = 501, lwd = 2, xlab = "Time [days]", ylab = "Intensity") curve(intensity_endprop(x) * intensity_total(x), add = TRUE, col = 2, lwd = 2, n = 501) ## curve(intensity_endprop(x), add = TRUE, col = 2, lty = 2, n = 501) text(2500, 0.36, labels = "total", col = 1, pos = 2, font = 2) text(2500, 0.08, labels = "endemic", col = 2, pos = 2, font = 2) ## meanepiprop <- integrate(intensityplot(imdfit_powerlaw, which = "epidemic proportion"), ## 50, 2450, subdivisions = 2000, rel.tol = 1e-3)$value / 2400 for (.type in 1:2) { print(intensityplot(imdfit_powerlaw, aggregate = "space", which = "epidemic proportion", types = .type, tiles = districtsD, sgrid = 5000, col.regions = grey(seq(1,0,length.out = 10)), at = seq(0,1,by = 0.1))) grid::grid.text("Epidemic proportion", x = 1, rot = 90, vjust = -1) } par(mar = c(5, 5, 1, 1)) checkResidualProcess(imdfit_powerlaw) ## 3.4. Simulation imdsims <- simulate(imdfit_powerlaw, nsim = 30, seed = 1, t0 = 1826, T = 2555, data = imdepi_untied_infeps, tiles = districtsD) table(imdsims[[1]]$events$source > 0, exclude = NULL) .t0 <- imdsims[[1]]$timeRange[1] .cumoffset <- c(table(subset(imdepi, time < .t0)$events$type)) par(mar = c(5, 5, 1, 1), las = 1) plot(imdepi, ylim = c(0, 20), col = c("indianred", "darkblue"), subset = time < .t0, cumulative = list(maxat = 336), xlab = "Time [days]") for (i in seq_along(imdsims$eventsList)) plot(imdsims[[i]], add = TRUE, legend.types = FALSE, col = adjustcolor(c("indianred", "darkblue"), alpha.f = 0.5), ##M no need for scales::alpha() subset = !is.na(source), # exclude events of the prehistory cumulative = list(offset = .cumoffset, maxat = 336, axis = FALSE), border = NA, density = 0) # no histogram for simulations plot(imdepi, add = TRUE, legend.types = FALSE, col = 1, subset = time >= .t0, cumulative = list(offset = .cumoffset, maxat = 336, axis = FALSE), border = NA, density = 0) # no histogram for the last year's data abline(v = .t0, lty = 2, lwd = 2) ################################################################################ ## Section 4: SIR event history of a fixed population ################################################################################ library("surveillance") # you should also have installed the suggested packages ## 4.2. Data structure: 'epidata' data("hagelloch", package = "surveillance") head(hagelloch.df, n = 5) hagelloch <- as.epidata(hagelloch.df, t0 = 0, tI.col = "tI", tR.col = "tR", id.col = "PN", coords.cols = c("x.loc", "y.loc"), f = list(household = function(u) u == 0, nothousehold = function(u) u > 0), w = list(c1 = function (CL.i, CL.j) CL.i == "1st class" & CL.j == CL.i, c2 = function (CL.i, CL.j) CL.i == "2nd class" & CL.j == CL.i), keep.cols = c("SEX", "AGE", "CL")) head(hagelloch, n = 5) par(mar = c(5, 5, 1, 1)) plot(hagelloch, xlab = "Time [days]") par(mar = c(5, 5, 1, 1)) hagelloch_coords <- summary(hagelloch)$coordinates plot(hagelloch_coords, xlab = "x [m]", ylab = "y [m]", pch = 15, asp = 1, cex = sqrt(multiplicity(hagelloch_coords))) legend(x = "topleft", pch = 15, legend = c(1, 4, 8), pt.cex = sqrt(c(1, 4, 8)), title = "Household size") ## 4.3. Modeling and inference hagellochFit <- twinSIR(~household + c1 + c2 + nothousehold, data = hagelloch) summary(hagellochFit) ##M Note: OSAIC is 1244.9 (with quadprog <= 1.5-7) or 1244.8 (with 1.5-8) exp(confint(hagellochFit, parm = "cox(logbaseline)")) prof <- profile(hagellochFit, list(c(match("c1", names(coef(hagellochFit))), NA, NA, 25), c(match("c2", names(coef(hagellochFit))), NA, NA, 25))) prof$ci.hl plot(prof) par(mar = c(5, 5, 1, 1)) plot(hagellochFit, which = "epidemic proportion", xlab = "time [days]") checkResidualProcess(hagellochFit, plot = 1) knots <- c(100, 200) fstep <- list( B1 = function(D) D > 0 & D < knots[1], B2 = function(D) D >= knots[1] & D < knots[2], B3 = function(D) D >= knots[2]) hagellochFit_fstep <- twinSIR( ~household + c1 + c2 + B1 + B2 + B3, data = update(hagelloch, f = fstep)) set.seed(1) AIC(hagellochFit, hagellochFit_fstep) ##M Note: OSAIC values slightly changed (abs. diff. < 0.2) with quadprog 1.5-8 ################################################################################ ## Section 5. Areal time series of counts ################################################################################ library("surveillance") # you should also have installed the suggested packages ## 5.2. Data structure: 'sts' ## extract components from measlesWeserEms to reconstruct data("measlesWeserEms", package = "surveillance") counts <- observed(measlesWeserEms) map <- measlesWeserEms@map populationFrac <- measlesWeserEms@populationFrac weserems_nbOrder <- nbOrder(poly2adjmat(map), maxlag = 10) measlesWeserEms <- sts(observed = counts, start = c(2001, 1), frequency = 52, neighbourhood = weserems_nbOrder, map = map, population = populationFrac) plot(measlesWeserEms, type = observed ~ time) plot(measlesWeserEms, type = observed ~ unit, population = measlesWeserEms@map$POPULATION / 100000, labels = list(font = 2), colorkey = list(space = "right"), sp.layout = layout.scalebar(measlesWeserEms@map, corner = c(0.05, 0.05), scale = 50, labels = c("0", "50 km"), height = 0.03)) plot(measlesWeserEms, units = which(colSums(observed(measlesWeserEms)) > 0)) ## animation::saveHTML( ## animate(measlesWeserEms, tps = 1:52, total.args = list()), ## title = "Evolution of the measles epidemic in the Weser-Ems region, 2001", ## ani.width = 500, ani.height = 600) ## ## to perform the following analysis using biweekly aggregated measles counts: ## measlesWeserEms <- aggregate(measlesWeserEms, by = "time", nfreq = 26) ## 5.3. Modeling and inference measlesModel_basic <- list( end = list(f = addSeason2formula(~1 + t, period = measlesWeserEms@freq), offset = population(measlesWeserEms)), ar = list(f = ~1), ne = list(f = ~1, weights = neighbourhood(measlesWeserEms) == 1), family = "NegBin1") measlesFit_basic <- hhh4(stsObj = measlesWeserEms, control = measlesModel_basic) summary(measlesFit_basic, idx2Exp = TRUE, amplitudeShift = TRUE, maxEV = TRUE) plot(measlesFit_basic, type = "season", components = "end", main = "") confint(measlesFit_basic, parm = "overdisp") AIC(measlesFit_basic, update(measlesFit_basic, family = "Poisson")) districts2plot <- which(colSums(observed(measlesWeserEms)) > 20) plot(measlesFit_basic, type = "fitted", units = districts2plot, hide0s = TRUE) Sprop <- matrix(1 - measlesWeserEms@map@data$vacc1.2004, nrow = nrow(measlesWeserEms), ncol = ncol(measlesWeserEms), byrow = TRUE) summary(Sprop[1, ]) Soptions <- c("unchanged", "Soffset", "Scovar") SmodelGrid <- expand.grid(end = Soptions, ar = Soptions) row.names(SmodelGrid) <- do.call("paste", c(SmodelGrid, list(sep = "|"))) measlesFits_vacc <- apply(X = SmodelGrid, MARGIN = 1, FUN = function (options) { updatecomp <- function (comp, option) switch(option, "unchanged" = list(), "Soffset" = list(offset = comp$offset * Sprop), "Scovar" = list(f = update(comp$f, ~. + log(Sprop)))) update(measlesFit_basic, end = updatecomp(measlesFit_basic$control$end, options[1]), ar = updatecomp(measlesFit_basic$control$ar, options[2]), data = list(Sprop = Sprop)) }) aics_vacc <- do.call(AIC, lapply(names(measlesFits_vacc), as.name), envir = as.environment(measlesFits_vacc)) aics_vacc[order(aics_vacc[, "AIC"]), ] measlesFit_vacc <- measlesFits_vacc[["Scovar|unchanged"]] coef(measlesFit_vacc, se = TRUE)["end.log(Sprop)", ] measlesFit_nepop <- update(measlesFit_vacc, ne = list(f = ~log(pop)), data = list(pop = population(measlesWeserEms))) measlesFit_powerlaw <- update(measlesFit_nepop, ne = list(weights = W_powerlaw(maxlag = 5))) measlesFit_np2 <- update(measlesFit_nepop, ne = list(weights = W_np(maxlag = 2))) library("lattice") trellis.par.set("reference.line", list(lwd = 3, col="gray")) trellis.par.set("fontsize", list(text = 14)) plot(measlesFit_powerlaw, type = "neweights", plotter = stripplot, panel = function (...) {panel.stripplot(...); panel.average(...)}, jitter.data = TRUE, xlab = expression(o[ji]), ylab = expression(w[ji])) ## non-normalized weights (power law and unconstrained second-order weight) local({ colPL <- "#0080ff" ogrid <- 1:5 par(mar = c(3.6, 4, 2.2, 2), mgp = c(2.1, 0.8, 0)) plot(ogrid, ogrid^-coef(measlesFit_powerlaw)["neweights.d"], col = colPL, xlab = "Adjacency order", ylab = "Non-normalized weight", type = "b", lwd = 2) matlines(t(sapply(ogrid, function (x) x^-confint(measlesFit_powerlaw, parm = "neweights.d"))), type = "l", lty = 2, col = colPL) w2 <- exp(c(coef(measlesFit_np2)["neweights.d"], confint(measlesFit_np2, parm = "neweights.d"))) lines(ogrid, c(1, w2[1], 0, 0, 0), type = "b", pch = 19, lwd = 2) arrows(x0 = 2, y0 = w2[2], y1 = w2[3], length = 0.1, angle = 90, code = 3, lty = 2) legend("topright", col = c(colPL, 1), pch = c(1, 19), lwd = 2, bty = "n", inset = 0.1, y.intersp = 1.5, legend = c("Power-law model", "Second-order model")) }) AIC(measlesFit_nepop, measlesFit_powerlaw, measlesFit_np2) measlesFit_ri <- update(measlesFit_powerlaw, end = list(f = update(formula(measlesFit_powerlaw)$end, ~. + ri() - 1)), ar = list(f = update(formula(measlesFit_powerlaw)$ar, ~. + ri() - 1)), ne = list(f = update(formula(measlesFit_powerlaw)$ne, ~. + ri() - 1))) summary(measlesFit_ri, amplitudeShift = TRUE, maxEV = TRUE) head(ranef(measlesFit_ri, tomatrix = TRUE), n = 3) stopifnot(ranef(measlesFit_ri) > -1.6, ranef(measlesFit_ri) < 1.6) for (comp in c("ar", "ne", "end")) { print(plot(measlesFit_ri, type = "ri", component = comp, col.regions = rev(cm.colors(100)), labels = list(cex = 0.6), at = seq(-1.6, 1.6, length.out = 15))) } plot(measlesFit_ri, type = "fitted", units = districts2plot, hide0s = TRUE) plot(measlesFit_ri, type = "maps", prop = TRUE, labels = list(font = 2, cex = 0.6)) tp <- c(65, 77) models2compare <- paste0("measlesFit_", c("basic", "powerlaw", "ri")) measlesPreds1 <- lapply(mget(models2compare), oneStepAhead, tp = tp, type = "final") stopifnot(all.equal(measlesPreds1$measlesFit_powerlaw$pred, fitted(measlesFit_powerlaw)[tp[1]:tp[2], ], check.attributes = FALSE)) stopifnot(all.equal( ##M identical() fails on some systems measlesFit_powerlaw$loglikelihood, -sum(scores(oneStepAhead(measlesFit_powerlaw, tp = 1, type = "final"), which = "logs", individual = TRUE)))) SCORES <- c("logs", "rps", "dss", "ses") measlesScores1 <- lapply(measlesPreds1, scores, which = SCORES, individual = TRUE, reverse = TRUE) ##M for replication with surveillance >= 1.16.0 t(sapply(measlesScores1, colMeans, dims = 2)) measlesPreds2 <- lapply(mget(models2compare), oneStepAhead, tp = tp, type = "rolling", which.start = "final", cores = 2 * (.Platform$OS.type == "unix")) measlesScores2 <- lapply(measlesPreds2, scores, which = SCORES, individual = TRUE, reverse = TRUE) ##M for replication with surveillance >= 1.16.0 t(sapply(measlesScores2, colMeans, dims = 2)) set.seed(321) sapply(SCORES, function (score) permutationTest( measlesScores2$measlesFit_ri[, , score], measlesScores2$measlesFit_basic[, , score])) calibrationTest(measlesPreds2[["measlesFit_ri"]], which = "rps") par(mfrow = sort(n2mfrow(length(measlesPreds2))), mar = c(4.5, 4.5, 3, 1)) for (m in models2compare) pit(measlesPreds2[[m]], plot = list(ylim = c(0, 1.25), main = m)) ## 5.4. Simulation (y.start <- observed(measlesWeserEms)[52, ]) measlesSim <- simulate(measlesFit_ri, nsim = 100, seed = 1, subset = 53:104, y.start = y.start) summary(colSums(measlesSim, dims = 2)) par(las = 1, mar = c(5, 5, 1, 1)) plot(measlesSim, "time", ylim = c(0, 100)) surveillance/demo/00Index0000644000176200001440000000117113112020363015013 0ustar liggesuserscost Code from the first paper about the R package surveillance (Hoehle, 2007, Comput Stat) illustrating some methods for aberration detection biosurvbook Code from the book chapter on Danish mortality monitoring (Hoehle and Mazick, 2010) fluBYBW Code from Paul and Held (2011, Stat Med) to illustrate hhh4() model fitting and predictive model assessement with proper scoring rules: an application to weekly influenza counts in Southern Germany v77i11 Replication code from Meyer et al. (2017, JSS), illustrating the spatio-temporal endemic-epidemic modelling frameworks 'twinstim', 'twinSIR', and 'hhh4' surveillance/data/0000755000176200001440000000000014006051226013653 5ustar liggesuserssurveillance/data/influMen.RData0000644000176200001440000000274312376633551016372 0ustar liggesusersBZh91AY&SY#Sǀz¥Fi 12i2dh&CM440C0i0&44iM44bjyG=1&ii /dZB PQx)dh 3 #(Fn MmȄpqsPB  U F)&HIJIL'6Z[\]]^_`abcd7ef׽~.7eFm/N'!:x$ *(xpB$H֗10ȞQR,QQC(Eˎˀ`N$3Do>%orU|4Բ$?cBzEW-5 /ayPI0@Hf t2f^$0sݩ<ֹHkj" 1A! !0I jHRE*\c2KYh2(SU{!Ė$"󽰁q \d @$>VwP $YMEeUP @jIx,AEQETX(4R*SE"ȡ]$|UT3wKrj=8e͂N^'{wG##`WC]w?>0 FLX80(FC8z8+A @180c˺8bxp !ErAjU7(,IP) }Lx@")d-BI@B$2S$ esrE8P#surveillance/data/momo.RData0000644000176200001440000002102612376633551015557 0ustar liggesusersBZh91AY&SY)9#@P}T7>* X z$(( jbQ=Mj~ Ml!mFF4FOSji&&L&M2dѐM4&SS&14ɀd*SC@iF@5M0h=G ~zhC6GT=&ꞑ@ =1L=54jm 4@SA $Jh1 F24@ 4da`##@@шEPO61M&i3ISjiSGڙ4P44hSM4POP44F6M4="a24ڏ)0ɉ44L@=FLM1=Fhhz4C@d2b6&OP h>AAݞr9(XwC'L}OMtg)U].vL Ij;-}rI~_fk|dK)l6?wqyRs?AGMZ+Y|u:|7{sSs[\\u~^?'5uzwRSSUz+klݭ\vwACE㥦*y;[uwW}Memwac첳Wsuwxmu A`v;O_;?տ|sED&vl9o&-.kn[P(RX[:mk*UͶJ9Kur]cunt6eV,P\5k5Kۨ/m;wwiפ2H*ݳ-Z-ͻX5UZiVٻr.lގ9y"FI,e'K.7lV^ZWlNZl($TMe$2bnŗٽ++٬ "b>I$/e:8r^6e屍R%n^f͖['ܹ50m Krƪ47s]Ng8g,WbۻHTܴ͈VɶTs:ztz'hJD L Lf!IX#Z/M\D6ɻnKwv哖y[Ӎt:x%tjj<"Tx! =8ݜVUEGMnڈ Q ȥ2V (#(Ae,!X{6xF$B$BD5" *$-z/hE`$"pT R`%4<*PX9^LyJ#*/gDF*2ZFLE BVJ#hH <9:ğQi=PE8Td51[Y48@cL` Ra psBF MI*Fv3ȉgКH3|\!Z'trI@ @ӱlR`dKte*נN5XmXAF"NڼA!fTWj TE+R7/_2 2EJ/Tg2X Sa  ^RTƔ+❂uV&8N"T _d+Xa:a4(PI1 1x@ W@?QQ&f _^) #(;Fo_C5ZDZpMUfxۅ(N0 <BR0!݆B >{h`@`mJ8mGkK wf{1@=dQx+ßGǿEgz!)~5҃5KvIռIu$/[~%MJu902IO\[TSMUkÁ7[B`APAq)aA(QJ&XFHp7P (46 p6ą..}[Z,JC1ظOO 'q,""*Z3SX&q"c܍%8w! QadNGD@@CL4B "@ T za{X#t]#i8;ƭ k0=Š=#Bh$$0Х(TB4Q ThY(:MJqz 1$D3SHBAJCnI &bjIN@I(baɞ(\ΘR 9G  `MDhD wnZG,|.P81&$VBЃ'İD)/fWMQ?NQ`9x)BpǼCRu>'yX9P~in1=WuákWXɩZ$߯M{X۳MIWVaV VqS4H6ϭW?E ;acª v8h6TST ԕ {$Iij\ج|RiSWm\Sl76={0clYQ6omxǼ3).BE,20f%6L0PYyL:)Wy0@[wqihL]B?z0 @7 Dzmi-Uؿ٧^ kbV/pקTowY8 d.OG5?Rz9`~I h͢qԫp'7#\\8"$gn.$^쿿CUh N h!2xr%cR{|8L`4o{[ιrr'mW?;Jjƾ$svv F'oG&;7^/%[g,q!RSHKs85Z+^:P&Ri~l- 1y‘TUm+5z$0Co̧Ǥ7{Zٹs)dr)ҿq8j|$~'Nƫ V`b})Vs$D+ۓ/ ߍgɝZQc򼛲 :fS*U-r@8qQĎCw]oo<׽;*J;>pYkDWRkI}{LV)}^;s6M:G3 {lV pr6\.uXs,R1c ӯ>_#H3右COG_WݿJ>E:,F|2< l :CYέz7jA{2ph>H#싆v6Ŕ?q fW w`sSEB-,-4 >1@:Q?%WbWIǥ6-H̪:έM9g@|5ڧ#{_2m)$+.N, ʍ *IN4n@)Ͽa jXU"Q%Lln)L ށmcr/pݕYWéhD\.EU߶%j=eCQtG:@I&>ESߢS(KJSE1ZW- (Z1-!ctZHh=M*|EQbKPg@]seMdP$$Yגd?_ҋ%b_EQ4^Q~j-4]__2KB_ K:;AA<#6Pn֠Ƞ2_+QoZue_t֋5TZQ|/I|eC҈?vH\D%LlZ%F0YmeJ2q%b ̩2h|V4G]4 ib ypΤ,HTʐHDHfI'UaT0c a EI<ےԻc by1i()<ɡ<||u]i^_.TxTtEXD m$N*4%Q5hKJK4g:?v,y "_TvQ] +mk<^%;nssxLE1ݮq[ SV-%=)y-Img KtVҒKvtLIvn7Z%\>DsҒq.MEH1hR1!o1l%.8qz/%<> ȧ{/DKoOKˉQ㢛GE7< ]`:"YA:s\};nϪ[k$_|_>Ad5V Ԉ0?ei+ -۱K Uf5@ iku߿aRG۰ݻ8d[nN8mF`)`kmyܐF1li[K{"X, ߽iK@޽zp'h B߿z,+h iȌchJ^><ܻЗ<68ltvi;#jFQ*lG>*2NӴ:`] USL'FpFT VD1X]u:aw(J@G˪@izG=j~Ջ AB@F11s!_ǔ`ܐ_NBSM4 1u8i^KRi8GNP]už_"^]//wyЖs^<=ȗ9ւ>R܌ p#9. vχ1<]fg{l 40G/GqeQ Pkpΰ~^vw$Ashk/^.%aÂʟי١ ke7$ol RY0XDoŰί'ڭlK[p8+&$@]aPy` :1.a܊g-t򍍛qkv_[e5d~ObPF~&;Ijlv8lPGK%,dan;GYI [t2p`zU]3!|mۂr).yӜ<\g;Gڒ.8v۷܂0#O9O\f7SGŋ,]Nkii㪿/9O~T&<H&y+n<]g6::?s^*E}[MN\*Yx߯t{^ZYf˲-MOsyz|ns;cĹd{.yqnn\ #tcc(Z> #o5FuguU]cڗdnK4P J2zNh6yia?FQ0  0A/!k^bnj1O*N-*KM)*.I,IrXҊR $JЍLI, jS2Ӂ p4 surveillance/data/k1.RData0000644000176200001440000000051610636320360015110 0ustar liggesusersVKN0;NZJAEH.@]B 4 ħ"aM8Ψ& ~ҫ=mr5#"d![MXpJT: 60BX/U]e- 4B@VerX 1ƞ'sQOL! cJtR|\RyG6L􎵗#ZC}w}nvzN}v]{93opHo_3^32222 <2ӋHӷJ/GosxZ9Q׾i_:mۼҔ7הe`q/]~1Mp surveillance/data/measlesWeserEms.RData0000644000176200001440000002375414006051226017707 0ustar liggesusers]@IM`A,`AD򂠰 ! PE{ł=E.;AwD={|=ucX,MK]u֊ ㄉ]BW|"KMB-a82QqnjXU@\ 6b7U<:b}澚BlqmuE\ F `#6AFlBlF#n)bK7Gbk6["Elq+;!n bWm!n11 #@'b/w@1⎈ D qgA +nCwG8q{"X7HQ~*s^V?`Q寪[6 M >0hM [xeЎAA'}k|B}V̇Oű硒3P;(ˀA;_5\|/:w 9=o[W*}*}_dEr""A0ʊ,m%Mm+[; {Vr8W(_|*ph-,"wd+!'OUx1IA|H!B"D!B"D!B"DЏûj,'DS'(0a„ &L0a„ &L0a„ &L0a?ɉO4d5rxYi/%H A $H A $H A $H A $H A $H A $H AMH>;g5D>1ɒC4RjfOɌNjpBY[GC5ȳ|>Y\;0W\:r?4䞡.w|S{GSbU5b=_SűWWHgx<ߣ =, _V~ۣp1PD9 UUlbGo 7Q|9_q|Pg)Rl*RYq+uEgކ,ۀN*.O5 qXD-Ra: VgHcf V7]ez AUMj .J?p AUǪ'@ *M9KL $Xܐ$XOyy$X\.^7pM *5$^A *&˳2$H }$H x`Ik $X\QC#6$H 9mèj$H 8ٲL  v$_CxAKMBfO!4xaK+<<1{&5Xg#<2甤bV :  X})*]=A"되$Q|lO"S1NhQ6N,'HZD v@{F Ҋ$Duz4uR( '#TxzbkGㅢʅ{v 耪3GMP,хC3s+= '?8#K⢨Bq0)6 $\r2rjٮUk+{g{Z ?/!>a$.""S>;HBs+[|~^AEP]k4]\\ZU &$cqVrtA{WbXFB(HLΞ^"*~S{T=X+HB%I1l<8$+LzP@0dQ?x\u̫OfbkemlkݣdneqGD: A}ĢDFH UIS`2j*h z'T fi>Z>v@])kC^ebq¤ǒ~_Y*D3V(JEEŒDFՖ-N 5&`0ka`8><ϟ߶4K-K|2uL:bGz`өFP?h\鵜cmۊ,'X<=fiy߯Bmʖ6?el fm@7Kt~WVE](Qq&͛t hN=-vյ`s=4"}/Dk?4U T9%ůsULTbc CL k8SO~|ȦW>}}φPU>r^FGDK{7%pk@ﮱpG9tt=`oo%+.eڽ~ms_ /n@hl~rh?t=fx:nvyO{Ծ;y%vf-h ?t? G C&1MDzmW^l ۖExTL+0&eSwt5v0FI`\jݴ۬k|/"ͱu#WxKN_i:ޕЀ|S 5޾hM,0鿪@i@z=;s*K&T_.X{!W]ycd11$_@_ndW*H;%h[tQ_}؋ơ ˪v|S0/|HN_K۔vql`Z}gLeBKZL4ޚذW^h!tm)oƹ׮ve@']kt& Q ),k[הEQ d۹<56㪷j̈^Jeu9skEJд!@9>sjs{Bt^z$_jP~.TnWVtnʹZϏ5N86-ʊNCgo+#4랱!kk9h[[}YQms sIlC[d3䴃n{ rlc}ӁN(OsN- 88zPG#Wj5-lX$.K(O3k{>v$K x teb7hqͻzX3ЮCfj@k>^۵N^!sKЃlD9=ly+S@,jUwWN G={Kn\AheGa%jc/D%aV5]^<޷(x , X`d0,pGn^;% l-۳G'`FI-θNXT~ۇG3?ӿ L=>LuuMsfeƮEb0ձr>:U 섍wll֏9 lLvZ;Fiӱ ޝ$C1?3p-`}}c0-YvXs*G-K:nR  ,PXa4ze&^7%G-h;Q.m)@6wvsNՃ}\v8{ořkG l{~<0y)9?Lşw&}iuL4y2񡹯mk[0ξV朣 &N[ƅ^=K``ڒ~J` /x :^ l` fg "?JwOgs˗nf3j&6C ~MƄ?eS}vo@K%~vwJ?;{Q_5[[ bINO^UX(:}yv\C]Ho RMu [(55^飚UQenn- RH"[7j cc[]r6tߢ|~<:%9/ ޻H\ Leg-uO3=y'e 9^>îE;l c[SB]<4fm[mY} Sߒ `1|]*?'8&Vc} JoaXPiU``[`5j0>Ub4ݤyICi9a+L':;|6Q<23"Dr*4_UJjm=-m~:|CvC7ުo4[e`*N@^؋}q/~{0ȿk"Gu q3*d*BzOY͓}Bz81(mtvuă:۰g?vh? PY-4< D$cp 1:Dl?ԩ{LsQ[:dq 3lZ[3 Sژ=]O I[C ="zGdt_Ä0;dDO}7c͎w,¥v\3@Ǜ=eeMĮO ŮQ*8(EÈcq^ѷ$OCx[|/L`*P-_hRhۇ1 wt_U2>>ʲü;R7ⅫJN>bΡchgqx@Qƒwɾ֌@<(>P F d+Ps xBM͈je#AIJ-:=PwO^f3D@urg 5[!eA [6ˁ;p wo%pzu:YwO>1J3qfwSb…]!`,XK&dJc4q&18|218&eBNY}4L9(sN:L"sb.vb/g03}J&gEѤ`}w,RS_v h5/g2\v~rtMOͻlnw7xR-uU޸l]PKFKl+z[m|Hvj:ot6N?h]5@k_9کsxqcju<9%)šgg^YhG]sN=!ű8ǶJc]q+ebcq,ű8Lcg=oڱms֎h̳zWZƮfzƮhgIlTX`ŪJ!V._V?Y앹ZpG=JM=v9oVQ,ޯo OjNE df/jѩjsi2Ǖ@-i +T` +d +t|y/>Ƈ[XȰ-6R%L|QSĽzLAAJv?y]™{p6]얱IP + +0а \|{/> -.laSU& R0l<::{jq'"-qVn{Jʂif\@[#+YifgUCWLdiEcmS5o-t 3##cq 51ೝS|]!xg"kwіgϸK5ھ֓r~X{t9Qi``JK羋<zKhݼmhˉʽsV l!2l[K&>6o gPk&`lJg9ll1m4 ]JP;8i` DO}ļ@k>h;LeH\1+ 2,ռg0Tm|B=@ym;|}^|%EJeU<kWF&6ד_ Fԫ^ʁ{"F~]1*_?SvWV)ݺ4ps`YY|VnY.>gq5f"qd4RGnHnٍ#o . g"ť8Nc||fp.>g kq4Ƒ8GZk#q4rƑ8G~HpYq`TNڍ>5IJ6WWJ挋18z&N9 L73;s ^~;k1]0}v!rteZm(]50cW֖!5%[3.}]*8f"o-  T07C΍*+xCձjuк})-L&@4OB}wW01B™5d ^EJըZ+ |%% C֧hB73ɫTRq̋&3Z,}f I0dT3ȗ E1bIbJGqwV"-Q$-IFc PbظTcb`?_/ DQ8"-Yۂʼn*=Gϯ-r7VT^+O3Bi$At!%cB~BDNE#cɚU( $҆WHMJOF S6QM^g6nso珮-Ͻ>Ѝw jyf qonzu3ٙWh,@?ROfN~{fU1A~(ioQ7;SLyh/`A*w;x2P1ӟoS9 >b>ʛ&n|L ]x]~%#TX }lxWbqq&+{ybfwxw,Z/8u\^ECxf]o+RJ(!oyz[7{\_R5qTmy%1QuLyR _ރy h=7E ԮnB=};/=qWry[bV8^(㑧Lq啪ue$1xg3x%QEB /g/Oq:Q>{6JA~Mw_nƻ7d wEe9[<ލWҋJnlx܋wo niˣxw۳O96w7xmμqy}Ӌx8Af[iMݙ#`F]% osU&k/k*~Kn`@`?'DFF#mmWfb)E|+O f-AmQhD$sكF4LmG*nǀK$ԥG(`XPL]D=:dKM-2 D G~RqjQYj LQqIbI*ÒVZ$QTndrNb1HPdO,(O20 surveillance/data/fooepidata.RData0000644000176200001440000014531412420322610016707 0ustar liggesusers7zXZi"6!X5ʍ])TW"nRʟXdG>@jtA'r̆a{ i-Ny0vPrWnUXkL-ˣ@4:,Ⱦ}@Dbq%J)6=%mP"`/{}$[X,>x hLY KX g:Hxw$d{-_BqZz)w!p] jdZBL^K'̌CEb;:e2 Mw( ǟ4c4oXܸ4yI'u _C"׹Q6S5nwX^ u7$D&&O_"5 T61K'W7$ Ay ,%Y s|I:M2 KAsTeYDOo>**nOc+PPӺWRSG"NL-x F=_AZ)H۔@<l|v\ؠ`9< q0. 3_i,4@x UD­6TgE~q O{)|/P7x¸ʟbS[Pbu%HI6Hɷ('jx҉kAYb^gHjRO? A7 R+DR#oZEzS{|%RF?a*9I'PVtdыfq[cgNIv|JmuS?xdl4g(vZx{N\*JseƼ>:$x8R*[1M;LJKs!mlqIMAzu:(ۋXsh9sj$5 HEOc}1N DۊeU(Mrۤ+e +?N E1 Yy`g9DgaE~#vY,vn#E[s91jY`a "!`Cxڬm߉-xB!a QG$=KPơʩW_aDo ]Zm^I3 8p笠>rIF{龙,$QD#BĖS?$9UOzG l`rx1mO.ubZ66-oF~q-ݢ`[]zDWxlgN}U&9),Q i°qb 1S' fjM! <"tv]r[mC֬3Gu_!7?3 IX%lcŪ I=,Np3\q~~Y'c ੇlȵ']eDyvNۭ`jR4{G@M\v?VH9f# 4^oQ}]hW_* H]Y%@d}?T#P){ÒcBH6 ȩtTyhXw08@6:JןNz~ M䒘I(@#e m1ocs7:x무z?/YZ:.X1/w{M9;)T1z*W7rjϦzci%+,[?E%7k@K-JWX-.>O*|@Zn\3z' er+V"ccRQg"{w3a0C}9.pdoòPRlݔ c%:jc-t|" YpR0OwŖu$0߸nPe <ߧ (Q2Yݎԍ7vt% Q^V!ߖ&({rI-^ICYtk#8W6͋!\i񊪨 |F%veɡzT&2:mQ^GҐ]dDqraV̠tH,Y}Lk|V{ iB .e\B˺~"F ;Nge_o5WHR8p ,)x2NHJ2BsyG/87e|~/])K.]1Sݝg-mUnqwymO}UtxrkģONz(ryw|ˑ$-|VXKY%5czKI:jKzzmLb&CR' y7%!h4bͶ1Bf>$Mw^\j[ޡc2g಻ DQ"%SʻQF`4q2wC_p` a]t%m$!m<[,*_2^J1V<T{{h7zd}(_L_ /%yON:SlRC3D O5 ljjo+=F><@f_5ȏVd@9&TCd~0 s¢iUV]ayt9ݗ+&M/~[Sjwm|2rN/LͥE@1t sBKf[SIY_ZX vdKCH*;NH3R!TIȀd {A:@tb L9f <ޡFn;W1+Xj.1׍@l"Z/+s SZ\kc st#PBþA-*UwO<~zb^,[{k^@LC/BWd&N8Gfqk^&p rbph7gU>k"ӥԾ[Tt2 (wASMnz[,/#'[ҍ[*>E޹'rɦT~E[ǽ+TnѽΖy\7"L|}$:֏4v GphJcRhuMH7"0k7}&r,qMW9h6:i05tnҿuUOG~rx<3OB=.ym1<)}?%R!2;?503Y_@Mn X[͍mENݚVvR#6g -/V$7we]fU]Nn(~X*yL(4E+m[nldYZ#t-eWXêI(Q+=QNGA~/UF# Q9ߌ)OVY@ZTv U7=f qyxKjҼH40N_ԖM 3>׾mvY[ڭ:ra?m:M{LhS{ W;W27h\K >]#Z?\"*hͪEGڒ<{>r/`$@Pz^(חHY/CO$OJz3T{#U3X7UCMQuyk⼛^S+}YN fmHZ$#;8WgKoN?{ٱ/"7yeMqǏA{ ӵ4Qϝ0GK+KOpY?+޲ O~eMwRVVyPݼ+N~|\@글 ^ qC:Ԭ\Oy%D0]|b2(#N휨ggSdm2TtG2oѭ᪤ y;@ Mf 8ݜȱz&?р5(N8b.P$.^(_DTXϑ q4ce"g[m_H6&i$(1~.ހv##|ޭJC^p]J1?">^Ͽmi2x958}0GRC;3˞yQJcdb0 Wg@ujept :?7>J\gbMM .^0(JHWYj+fB{|pp-Ss{Fwh_m߲5&lDp+׆F8YFL'H؁JWe͝Չ0eaJ&(} qrjSX%K C>z`U Aօ@=ŝ kn dw$k%bX3 Qr)IM/R|"]ڨ6hBRm0Ը =)-JF 5, G.3ޠ(QmI;D㑙5AO΂3f6ᙪUH + & :B'\ XM@ňO#H!+V^Jh>ȼNK>2I޵V,S%@Pw4l0c}@M 7ru:F'Eʯ-%ۤG]2<'o_ofEKFkcuEIp B&3v{vRߛT;/mN"f31F僔#O"*%> WH LŒ[D*מ͓m0fcv3$Q,#,J/,U̸6N7*Tz!wj׆*wRˉKMWeY׫Jql`.fOȇPQVCC5 `DzW2Kq$u:-k!84&PυD%X3[ dw}޴c UxT@L)$Uh ՘8v2nWn1ۚ6_c(7 jmژE@1w>vBYjOD= 53γLEPdDU:C\V gz1p.ZdOS ?OE#p"oq *aDԭ8i[pT=MWze=?3Gޓ,^ g&6J2u yshvu텣Շlw0xTs CkǩP^f w_U[aʭ.X߈ShE/qʛJiM>o5 ͺ9qu5B~LlQ,)'I1a*eaÇ{FB ? ^'F򦏸ٛ=9)A~iCov82Rf,I}35%Kn-ďU+ =w`7& Y۶0ܲ'{z $G)P`*NL{mA& cU]VK^Hs<ډ|^H0#]&.&1$?/ ;4 WC^7 nff(-.ԻzG.` 줟wN0| PPRB1$5cm+)Ct,f!>%KmAM9ge#Nb{b{8k|߅ RK8A.Xc|UncIjTJ;z\zh<S#iUZ~k]T0] W>ܨ!¢i)Q^ H@f)hG碈,+P|#3l).\JE1h}?̼>oGvzk9_-\vøApX) y4_֏!͑?@Cv 58&N6T!Q-!.*Og",4&D.!eᮛ0X,Bݸ)KjњԞc".d"%^ŐIKa3;¼pSTOͷBaCVNp( $Zi<&_a̮w8'B'?]Cp@RO"$C 7TF'`j D7m #s9;YA`H*{Vq%MMx^aSԚrxN -<ΰPH`8bQh&̴ٽVQաx1{Vs zW {Ƭ*Ul^ڛ$,)AgӬVSZ*=ҵ v4AL@Zɧ\HoCx-xnlP85VSB7gQE~Uؘ5GD1wMDְW08HluS0d􋂏q+;f,(l!sCvk'-i ,Zf茈&U0eH!L(2r ʻQح.<\]FpWE.MGj;O(?T))5t^tRশdPgHX8 ,nRB`2[]ŋqKuǪagg{ 64oIsR1^f"swMQw  )-_|afh!;CDG" lNE=744H4bwt^:×W26ap½`=xbwzn}JW&אY5m+&=pJovmTɌf:{ /W>h]57y! Gl|6-C`/7x_k48ԣx#:85"Ǵ Ֆbibqf.Kݐ$$Vu7we$DUSr%!ڣ!CX`0G#3'SMDH cJ wCL$XVӔ+/l?Ij4V/jw{MEE+.v`j"PFͱYnY6#{ M+èGi4k:_>nO[n``lK 42Iz*͝O5n ;qK'޽E ,)t}8=궃"''- ?K\p uaS[! KV̏K( l[OEsZk4r %1o —>;! Y$!hՀjm.J1CŒFME22t~,nkc"q)2 {R6H]j'tUƼ-@3nJ lԚE63SR6dy\X=zJ ³+vn=a Ϊ(-9U]6iMШrј`C"I!1jip2,qAdgR_eĄ5 7jD߂c*D~j+<(ux_/|R,܄Z̶Se{lʑAߐ a鿱MYFBJnE&sgkch)k2N2ZpaaV_L`j["]0w+FL\h 2~qog6ucs,kzF4 b"#ҩ+$@OB{TuucjdI'-X+.DHHZ<&͏ԣJ7bXSshvw>у~9"w8ȁRU";3_k4o\D8 , N^8Ef,9Gꇋ;d!gMHOfe.ALUTdR~*o"6N)8%vk- d:0VQTeJOs6GYn&zXC-Hp1AýwR+0sFv"Y亪!+I ӦQ,'gomY++~9ZQw0z5v^9=ۜ YrvLjn{|YcOAV#v!e{A%{t[~6 ud[a]a9@b[ ]Ao@Y켗p4Ӟx U8Ng.՜פ ^̫wxy&{!(FJiLf36'"G)c_uvn./v Vk38=%s4U0{. 79?EDõVU :ħlA1$L&жc|gKgI(LMp?\dBA>t@S7!WYpcgm$ɟ@_ G cR. %.$8O5 rv9g̴mkb8Noo3ʋAy_.nO']_hu'B3cX[_Զq/~Jj29K(1UBa@\r%+R =?Ұ@19Oz fls Ap9sm+ͩ*o-HƻgOν}pGG_ЬQÉQt_^ٴpH_h}UG Rj}[g>0gҮL~);HwJJpq:%DX4o! ?&5 ӻSߘIӆ!GŜJ/Uqbp#ίMb,_H=6pf ~c7HBk&Ԡx Tظv ?)eR*a^C,UeI|ē9wk v0K]A:'QVsnbm`dP+ބrѡ, -эZÝT9:~mN^:بv=Kh$}U cѯ(,̹̌E%N hoڢ+CLp'6FW['.8dK[sfʉNހǙ|AXGxkqUvȾQ8ŏ0LEe 1ib=7%|$.d{a">mgEVxDcFԃ~q-iG/d`$QyH`gi;$(AtUT ~o8&uU;GGV2>k{=vJhORQ \v&h`=4(eGl"d$OxĂ&O\$i>$,\c0\@>4yc>wEQ젍Mc`)geM˟^np"lOt]d޻naH*c&^T.oE8D=7Ô \AVpJ3$v.\A@R`0KE?84W) 2F>DH-%2Mw}ޙ D% BF!&2d\f#n@旐A"4! !f YϿ ")D z-ua$+W[<чUJjXM?\ - t\L@Lfu+O>fJX _e'ϋO>`g;Ή \ ȧ8\C1u'"n{@-[9 Ÿr5<K]x›ELL]H`p4O{iO@v$;#jZ|Ĕ,(vXI>H-˃lRAiXjpsþ{21bSv`kpVywXnje3sgr9v 'c4+@aHȿ/z5m %+\>tGT6vn#RGuiQe{҇}^Vynuٖ2itp2]3ZkCuƞg…?S\ 0Qiѓ7p?۪O|\˩3?bWG ]S9ptQc{5ekD O]ɝۡXp?n b"M.Rg[/A w} 崯?g%]V xe"̣KΑwTF1/Fˡ1q~K PȰ2}r} e+ , ? vm&'g+X[+F@%/cq8 Tw4\qѥz*XgLܴk9d)!u| lH8.\Skz~.c?U;.(j\va .-5ƛVMEeHP+FEi kQ1$Dڻ^gJ0INQe4ha H8C§#,\h`=ߪԘ 1qN҈/D'J2yw?(9e%(ݓΠ S эXh.t&_gmʀ'($ep{"ׯ;`c-:}5^[֌0=Σ&7RMc(B NN?+9KPЛN0[0ê1LErhCx֧^|s, T)Xg1CJ{00 ;mv K@XhC.rT?rx sz.}STYz_!ED;EIp& ئ9O-ZUTJAģw"yJB;5d}CjDϴf:@mwTqy*UzXi#TS1a |h#v7Z ʩc\n)7RL?XT{ eGQȟ7AFYkƶԐ&ONx/%\4ex2b+u?Q &g hn5yro|U}bč/ & k>!N%F8+Yh[iGH"He85Uaᾚ1 *׮;qe$4E_$-985 TFM`2E.ROngƦVD[h%{V*}k1WuMkcyhIsܜ5:3ͬv rBIuI I+6k@zνxë:ڎB`QN60sWA\sMGt *s&XZ(8]?s#;Z |6W.%N)A@ [c#8%?DL"ԝ*g4cBjH 2Dެzn't$o&x>DYLccMqNJ 5)< :lcwWEkdpYw!J́*w;`̗zzZْS?6H ;jD$x_1J^}T ⴳ+ YHeP S&p_-5D-~2UiT(`ј~G+(vch @k'E3ؚ~+iY=P#"a8Ρ%*"hs6enMc.60Zc !?5=7q̱=轥Z$5؝^1 KfU+ΐʌ5JMZca DO?/~{oڒ|);&|@(4!n`:㔵aPqodT=CQWEtEX"4 Ֆ[ByńDֳ[ihZr{@fO:st ΘfDn@̳/rȂokN'SW|2GTD:J nM !m/0K ԰UƜ'hKagn9YIxsg[r9vFZ? D,~ړssi|~./uuJʡB\PpyG#W(J*K*֎b Ogk xa:7T]qˇ92!W?Hm m ߚ p_V{ AB/rC.{OmLa :== z\y"lTxǦ8xYɻcaNAvsŸ!#_!2Xg^eS>g|MT ϋׇfp-A7tPٴ3֊~Ѿ?O$hh-LC5ÛtSNtL.*kpFCg҅ u̓I `b]TaHq^[n0j&[f8 Zor^r_%eǻ9偛 2i K&yz\ eFkN5>]H 9>@@,j  gS FʉɎ]`K-/ bJFvq&Q3m ;KSWC(eGUŲ)zB9Pu=&[GB.lTEbz?M~g~F R>#j;x _A)pW,s.$.jn|va{U_&F郈7Q?$ u쫱c?"At#ZwjS#朜m@Q\'.9xN5~.x3 rGL> sf@7{TQ`z-_m=LJGŋqJB;*ߜ0}{FE i|8*!DH~؈T)_*2+<ܾ;0lA#5ͩ"wa@9dt/r? Qz v=r(>&喐q}"5WPyȢLO 0ۊtL1,Hg$z^s.qh@#9 "x,Bf /J%ID.a ƌ֗c&/Ƹ_@tGv`TllaE. .CTtkِGlH\4@pU5yFSZ3R';6Ο9 WUH. ١ze4jϒ${v8h`Icqʠ2;&B=Y;sY lP TMj[JYOC l3D!S<:Rc%RviA)e|B";u)]]SO (f_wD/s (~6s +i&]"l?LAk/cYO8 y79hgiO6+ D.'n-Yu@mjNǑӰſJMw ~w0SAo7!.q `i|-g:p[ywS(ᐕp^յ`8a"gw{X@(uO0LnMn@CaA ydVv U1G"jj[C,*p<!t{)Z=J ޿[V:49T$3 a&tkq9 Z4 D]k^xjb9ͦ8 ŘhwQ<8>]oGؕa>gt4>Dl0M_Jyj 8=!TT٤1fȱ1,DB/U9:9aiywUn3yjñ ikĔD`uX*?)u؞&@U;kx˗U̚4 1ÜV(#T[bQ4;za뻅Ø@0j9q1vr7?S|PV$’F{{\+IZ(V@ޝ]P/C9/yޢ{b*Bڐ\&~{bԉm`םf@1*x-CWZ\V?zKMf;>.FR% qIpWLy?? \TLxc"08(rV`L iz|$ su9/zO 27"uأsNӕ b[TջNMA'"1 ?ALЏh Vh4Vr LpR`Ċ 5d%RZos?(/M`C+vK S>t8]I)ΑΎO NOݒm唖XDj/`N6ÐK8b4u*3ӟ-PH@m$^=v7phG:Gɻ.KX,'"iTf̯cEP:x_Br; M%)I$zsγ{ b+>bHWdw% &o{3gx!(*: $s̚7 ct'a?evε!xU;Wh兙Z2dH*tYRt BYq_Ny7^%@mCI)~ Ԧ O1fppx΁.QuuR61KmӋ^ϝWwa~k OB"µQg87`dԭڿ*LIӅd5xSɄ+lANv3x_B:s=žC)Dy|q!\T6>"R1Vg2H[daz2"%j_{ܒ)#|lũJ.De(?@qǟ휜p ږA'Rjݪ !Y@fY {{FJO6>=wv=kJgS  lxӵjax{(zVDRk5dp q:+^$FK4@o`S|Gw8}:^ _"oYڻV 8Ɨ@ ڈ_y͘>} Di! Q 2lz\aFUW]'DztON(lSxot cVW:!ɉ2v{YdrɒXo* WΪe5'D4 rL6>Zamug &Y4J0F$A/hN '"UbU ^]wKN;AՅnV>(8,P Zan8grӓy_qp i\ܺ_lq-ܮ .gY 8Hupy }/=/+ʨӦfOGfQMXf!ܿ*8 I?p )JpK6> hM9:k5<Mb }R#>:W,H][tl[לN7/LC`f-M ĘLWY<FnE [x78$ViGl=¼€hJӄ{PJ@YI<A!: 3|uF;XG]08Omn4`tqN~噳k 3qvmb*Et0؀ɻgYx \TpLawu>!g6Ti+X}|V^/+%kMi0ZvH \ aDd)=,WٻKD,qAXf]zF#ߡFAg)a^  I}QK>;|͵@&**E|0FX8x0.s\}hӬ mj)~3FehӚ23N IgazM(~D KBbG*u|"cw4^4,;Bcr+IWqEpY7i m)C5{V ޡ ó- `>;+Zd.2ݨ?ǔFt#+,|ܜn^7 ۂ&`BwO2Onv&7nUccȾ;Ja@zyy|RN۬|Sk lڈZ5kDHeƂ)\rdqyfo<e|M78hAs6LHcʴ7pyL8ƅ{TJk ¿ȼ;2[?8ˍѳ&fg)8Q(^!*ʎGDrC@ZϷz]!}F8Ef0ڕpz@`43HёԔ.ˈd'~ݴ (8DbJ*X4)?Súq@Ҥ$ȟrpKҀbeo+M7|ՠ5dr,!{[T:>~'jGibmkY8o #8~k✱OsMD\L9$k 6%B;K22cbjp~w Q)sdc\gWPQg;S̟¨ dԝn5 =2fjK#IYPK"b{;q W1ɴ!-˒\ߥ\zAT,52Z`?).3,&uz*k,e"31vO6+RWKߺsk)go369I$s[IYXn4(@me%솢g?{ ~}^{d3Nƌa_|MP"&fD"O1أt^y 2uA:Tn+YgƑu۟}9?[>z<u "OCH1k({VbrmG}] VemZ >o৮:xf'B,j ފ% +J{J݃g8Y-E6hͭCX9NmҳWo#^.MJOAU,g"91vG+,F5p`=&E1&ɕ^c𧛧 _(/_Y_?'=fҟMt5aѾ^DоNˁ\\Ԝ O {[ȯ΍W^GHl!#Bg_-`xiu sA o5_ԣцJ)6=d4]BdVhRzSMpټm;!LO, ߐ\֐[vWRꍧ׬ŷk/ԎɴY@@`eπ:c^W]8 _%ղ]*NI#r| 7ꛅ~ {|Z~ĴDoj %S C-̉*\ U@e#N̤ܞeVBE*/46T7u*mn7 (DU|ȾhZ[b \XeقvZE=GXDh'cA.qZDe=>Ք 6B,<[Bg%q/)Y96`MӸkr;yg"Ə lt1D ܜ|cwSBL8?j?9?*AC)RW%A  Rئ}8KF1\a^ rL.O8vص&|"9\`'s&V9;7F_Cp}Z1.MѧAP,1 \<fT1!9+9"塁QM{If[xqjO]=ë[ͪt.h?ZBaAq^DSܼnp/܏YWD d 5/|NqS# jxDIp=ڎ۔UIUFHN8|ٙ(WOMp~Ā֚b~`Q+?0P+vD!v]"?#p;ٵf-?"~wTK !“aGq/0UUyN[q2T/ |ݪU.gB8J R,EkXD6,1)܂q&edE&$~\ Z #;+oM;&ࣖ62xвT22%~|Ε5`.%TcFU7]'%Ł+L9[Ao.s5W8G62m4|雹M.&VI?+< n cQR|6%Lhx/@} Wę[o(t?ZpZjm'D [qzB+]F'@ E`G$J>ޗE7N:ngCm)KIZ6ڸ,ʸ`xu˨ʔ$C:*0A20r%p7Kmx0.U Tx<.Yg<}=·S*M.KX@W49x>hJc d4~ ѳW"ttآ ~|$W'?#tiA`8s5 k揬0TOslbeG,nkJ.4q8"q={VJ08 j]]i58{jclHMBx)WmMX/(NbloRSr6O8>^ 4T{ -*35M=yVI7*;gb1ӦaIPR;ͩiϩn.K5Z@c <ȶB}?\gc1ζYd+WPiOz1u3(oNA)'25;57)oPh6>1 &_1tN cymS-rp_G|ET3ܼ]d,E5Co/A,H}.+=UfVi<\I?jJsf=lrmU|F,)J#sC7,߶s1 v7.ǎ OǯV*'R.hE0($[䥮.e@ "Vdo[i>c_餔/R3j}#ʮӶz\L=T;$AZ8y&f4%3 NDy   KXt@\0FwvwoWZA59HGľZp%FVֽAw T40b[X 3Mr<Q"hziS~Y.k֡"j#w4[eDi#s>a8JO2k4gQ6|7 yEF )]#J]TThj^dُ&g>O ͯ2bMjzI3Bk;}Kl@8G!=aQul8l 2 v%J3"vijV7r ,7T]~\Wk*%f8Ϟ a0:nϰ(!AKS[9 v/Mj[L׭" w5'mD#tJc>e;e.?~:7zoLi9`$j;+ 񷩛5NPٰS(+n*fПu#'$lZ׌&}Z$<~!fGFR7>2KT+6bڈ̬Nո_L׬29,R"ٳLoSsf[( H8JzEn#?я6p$ #6jȵ-BszelN W_=BQp"Ɵ!?U 2pRK]剠NVFWK}}q-xL:G_u+iȬ*(x=~#5mhqĎr5xXn_Z/pzMY硌s1o d`j VƳ8=#=/z"A`#zәo9>F#̈jw(0*" ?Nfy?vm(0[gt".S:m= fYHdl pن gpS/%a)~sIfΥbzqP!yO^cԴFRR v7vG5sE`\Dg`}t[u/.UCm>9;ss=}Zۏ g:S%62 =-朖Q: }0eoOYg$]Z-(oQ*erv&J[pO> sP1uEn$m?Tx,xPMv_W-<~B&)dGm]`8TbKKM'_:nCJ_c1^"ذE1tgol e!uس9cJ?;pS]q'.2G xgl[UlZlHc#?_: pR/-ed&]Qc5{S=f\eܝY[&2pOg){dY[bŅ]ɤ yuƩ %7}/om?}? 5ȼb 1ͬb3*BP,!Y]9@#b9=i \=:@qy&@dOdy\S)߸u\ _VJ?in%@68S yZ1oאKgYY}1euWbҋuN)kN U,JUE ) ~@]%m4cPT8 #vYJ! DE;n_GG tau$|nvT\"5M7-߬m(q\W˭htxVj ~ܲk,y3yWRhz<Tm3(ѝ6ƿ@͒pR;pr--rڽݔ"{ +B' 5VD/5?B2 eFG Ľd0뼔P) a Hba‡?A4:P\Px CA28+nƂ3'/I*8S aqK! $I HԒm!WJ'##wbV T N8WPv+F+vPHN8$!} PbA^>`@N/|Tux__>)_$#-`R  I[|͡@@s3/{_h854&OV8>@n +Q^d@QNdìu;R 媐uL&twHyv [wɇaA0᷼hx?Fɀ*lmf5*a |`\Yl7U'TShJQBrkj\}N!'Q9wj|~(]L&.(LqFq"KsZ#1+}1+ 3]œuSͦ1{qw+r&4T K{n+!hY+#RcBE^f35i|Pzp f|'7^|U LmkJӸ>MHcf]Tq^&9hYϑWL!x>-k`C-pldʩ68Ҷ>+"G%G(Ryd-*rwTJ6MHt<ͻ.q`Zlf$ǹ\D|+%(͚v'!BGVIZY3@ )[e|f**MQo G5M[o"n[wXKG34ةG\=Bh!3& 0@g;CR ȶl;5y PyY$k%],ټ,ƀ?sw,#=DOMlaPC~8G@.Ҙ+Tv=Ug)̀EDoYNV/.Ϸ)tMkHu=O\!em6 ې >6՚?gw $2 G-Tq :%O:8ς40^l`kO>TaP/_IG?fX!|(ۭ1s3EHfu2=_κ"/y/? ^z3zQ$*j&zD^[])N!C-h:k>?BExA@f3pV*p>竟;u6mC=(.:C"[6FgʝVI*05_\R9cr>ꤟlcᎬ\V[iGIDzr,*عPY?heK.QӖ9#YZ~/Q`cd(^mKem&v+/*p'czQ2t[toOt)C[KVRvmp3w>Exji \)ߟg-x1 s~n*/ +wANl5Su?=n&&#Iܢť8eܰ`2ZqWrA`~VM^Mk*w#P|{"d]`\+@BLbUs?R\O$9k sYDmؕ'&.{MYC*C&]0H uꚮHa!0]M"Ɓm̱׀p|o#Ï0L/ݺ{>¦0+PB|t4kdZYHںއ0K7.W="ÆZ`Yeѻ$$bVc+{6Sci oOo#؍0O}~ƚ7ՙ"w)<>@:6}XAp>J'cSkAé{$#Hp`b g}M[[ USK"muԜVxLbdeu:).#(?I! h]l &?v i}ںQ*q"Vޙ&8?n%p3՞_뒾HMHMQ0{ws'D.`l2%Й۫7˴Poۢ !F&i}Q4֯ZnU쓛w,.4maxh !lf{mLf35{2D.Nei̠<L:0v*H$Gndt@8{`Xܮb4[4F:>tM QxR ğ]/YX,!VQM4S'lDwۆuLWH #]n_F~Ũ8GM(G6L~6⎈)zR0g׿#1ڳZ$Z[*Fښ&~lv̳~ӸLrs =XȸP}U+kr/P{a/8dƦ9g xbDL%+wN DUHՓD~ ezףXٽ ʓj==Vf1{]MK'>3Wzq]QrX4B7~aU)1XZnhSCcxTpD?Fl\ yU꭬p{-EJTn<49# -84{III<$uUj挧aQ\FS31,+dA1;-"˿/C "k]"|~O,nK͇l6CTL'G_cj$ ⷗cU=K[1]ktwϴmǟ9ir c¦:kB1'R6Glk8_]V8W=4 % 1w]gnE^^81Uj,3ldܙ} 9 B_W o> D(y5K/9Io;)Bn/@xcHEP rj,2{P$FA7 n-?:7=Q5Xʜ׈Hn{G o [tr2FMs>~:ad`K|$P'v@ rKKp7J0cr1@ow*xEh _PNkhyIY~aQY0|F+啑#SȲ+'Iz۞6_y>}/רSu U c"5/g :*?͸l0"pe|Nz8զP: %(7 ];tY4wJlOë .\М/=VE@JȔWG2K.$yB?s_fnGscq v!ȏ%2lƀ孹"GLCi 7uhmLKژ$[Cu`@}Kq䧈M[PY ݬnݰ,!d+GB*Ɍי*Bo0b#"su"h^Ѥ?cߛ#Vi|=`'a'lK)u/cT7krkβ!wy%#}3=R7+VPO”'=C.[3!ĘRIfQQM;s:v{BU3X-mg!:s]`5" a4'lSe (Sff@؊+F|aΫ*6JH>ZPci; gsr;KˁlUn1Nǖ|mE<^qb(t5r+4I$j'CRż㵧qͭ}`jM[}/pL :Yk %O/%+,)y2ƣG!_%ջ~m9܉H*Gfo2j:)0\.vlZ#Tý:חV鞕aIJUDqE ȿ4àV]Y.R8a-)o0GtnY#tˡ OuX!?aOڛm"b_dw-%S -?r\&ytሹtADv=Uuڄ?E-#3>Ǟ $"h!TI?8op&`}N,jǏQ;A0>RxRO ;"8YZ^ޙp`b'Ρ㻉sii|  dw]2iӜ%u#3md$E/?]v)| $F(~ ۿXSѣpu'o@/ӏM/Jջ,XQsi$AY-~Sk0 8)k^0 AJA?+6{o~oQl3  *WJ!~G3"ӿs #h; xCl3ӡwǦw槣MĻفd9U\QPY.Q7caX$l % {m,؛Z@].V? {osG;E|z듂UVHܲhi,o1%,ze}1-+zIf"=# dnn S]5 CU 8%X9'Jx^ȃG_1 ,^ȊXxJuN,at#6Lk(0aAU֕yWN+B"oLQF bw^eߨ]PT E\S[\A$rDՀ4) 4)Ǣ#ۡv/ 2HJs2ed*I3UWd9$^0A0C\`mkxx@<Of Κ!jJ]8ʓv? ^g[FKC`T]+i ;#W.C8C Jwl`gbPFVkS1K?. g:Nd; (Y ^BҽX鎵Jen3>vwZx"P"F=*2C]& tP㟮0^+Hg1#ie,t4ߒ!ҩ!2-pj[J۸4.cm9`46 +Sw-˱b~ p$$U{ng%곺2Z\ ?=<%9i#Ojϰ̷KuڜVu|g_;/gֺa|KG?DxJ/c~1ыyV<Rûhc]ڲD*sXiSQ y"E{}@lgX}2% :4(g5)WK="Ts%_ axk}ps{`'.̫&~( miӱgh"ӌޣ)K=X(Vy[<^Z\3)wM% >uĂ+- N4 ~C7p eT+{# Uv.lj3c!)[C9@h0 8'rp%UWz' Q_ `=D&5AyT=R%ĿNL֑j갸?v;*2 l+m"0JeY r`,-"6 hP Ά}B޴cMR9ԇ-WBdg:~(`ԥ0=BuA|3 PVvpvM*{Hv;_UaIgH(50a.̣uĶ$RdI|d4/rw4i]ǧ`ISe<*5V{]w@u/hm*& E QNԣEj&!x6W z9`B<$zC;\>, D&O%%zH~&nM[m+EM $6oVL齜s<׃Og߅gtk|E-2FW*G,oFs}NoWw58Sv obHnk{~F :8yPb^hWvӑwMaBdi5ÒWl lhu ֩5? =x'r1 (]u^j?SpYm>_q+~LUk_7H_u[,z"obz2*1ݯJ#^T\381^(]@t7RO(ǃnkkGZH/o`/GT= c-jmEMS@.d9({++Qi.@7z{^zU2N? !P<[6,1F&P0[^4|=ݡ4Cլ-Ni`v2QYcۮq/>`+e0SqKIiqˢ]ɬnSţvQ_8_f7jXC2I~iKʭ.Q_$?v*(  2jXugDoEc\]hOOcTe8^%YxLf4P̐eK^ׂ8NM..i ={`5 ~9B&ߛy<%0Ϟ>`P<@̫53f/$L#qodwУ[e_ h~k˅kT[ۧR"/ o$w7ؚzu9}uTAZyvO Ўr\DYH iզ|Lǭ,u)]ظU D?NPzmds3gߨ gd'u2`{0y&𱄫3j* )(>Gz!|~dWs!^QySPC~nS?;_xܧ'`B-oI`[:g<3q8'G&:Ѽ~(M0f2 sXc>ݛ{ 0(Z"GCz؊vlh!Gv;?޿;jz2@aŽSΉ`QXDD"pкlKwMȘOcA9Nf/V}f'0W{Zomg컏;Y{mgRVǘҚY|`z>bȄֆpX$zcOHE%?t8N$] "e C6gŴI;J^M3{s^,CJq(i1? OVIvTtbP4sE-Qu,@!oÄ/:3߈ԛK0,A'L01#NTED(J`OY]z61b[>ֿ/(Q'ld^5MDp9͆o6hZ0o_?{Io,[{b8X[Oo -9!I"2$dL%HC\]䬥 ļA:x::ʿ@EI4[zܲ@OlWd _uX*'jF|1nMYa\ǹILR%YUlfu-0HwUu*:O^RKSL3n/AїP7yXy\WqDS#I)đ p6y\6/Y,EԊGI.TP7䏆#0Vb9 O#Z"vyTA|`> Zߞ] w+>֖c.J#P1{$B~$⑂ ;thdSkZJlA0T!6|M4 ưB1m] i!r|I5=# ϟcB)4l(U)0Nْ  u+lA\d {ݼv?)jQɮY7|sP+L1&%)b4% Nೖu#AWK*Pc]ϑχ8k-ݙz'jz.AŽ%X8u6/#hΝf_"`98~KlILg`(LS4oLV\5 * nT1BJdFS_올*a-\ cISM%#Eq dPLw=A(Ғ>~I_Hv7ce/u96.F[iL[_1dz\f -M9_@5 B Vu>B_si ڈRT[Ί=*2u>F]]3Ð̡SG mÌŻ /QA*WpXEX|x~Q~] Qw,>R؀Li2(j']6Q*+._7t<\Ey}؃72<Δ).å>~er )݂$B3eꚥM#hIG7ow!%T}?&p6M:Phخ8q S 8! D)٦13_Sػ#;Fg 2xKw P98&2*8 >'fuSY1S'6Z*;q' HqЛcs<% j͆yzko87&|ɈnOw@qYWJB; ', e vLoo ZSYiɴ?)- {CksX 96t:ͦJH0[_ΒguBK *v*j'AJ#?Ψ6Nװa_mh*P"z#Y* / zwBi-ȫGaWw|mLyz 7>?ݝXEw>9ssxtVV,Wn%UD.̧ZQ¸MN%¾6Uh=R* x&MQ[H^OB:^ ꨍӃ`$}!`ܤsKP2.|ŔaY_ir;QbK늯UX7󣋥 k鍊:"b͒Â˱'Bq%nV {z`n>I4^/q"B]Wlo>}zV;6q"7Z# _\|`GHp>s f>"po.'֮.ǹ7-ůFsҘJg?Q3†.KJ\pjٸ0ZWW&fZچ߭+|@Kb PhKF>]YoV0AlZZ:zLGy2^Ս 3(m*FDǕ3tff抆1^8 d20ɾТC-ds,8=3ս&*% *'-7$T廕ߞO:/=Rيi"Ov1Oԛ](gvA2iM+@Q*JdWLBR8jSN0IW\4n|3&%i:*1|d0݌bdbZ/L6lʦqSa SpY=yd?cʌiz?PO7\x( )NP 00 >C9\vOeCuy|@ğHqU_n mvlHbLΡв; d4,@cN@DIR9'SQOT)_\KpV9`iP}BUU)m84k&kP!k 9la7=-}Eo vd,|%۫t QKn!ɷ@^ͻ66v=Pi,dVo3M t&V)i_ɑ<֭Z4 qqx9t1"[e#EB2V$E߁IjrX(k#c [B86p4XFF T.K܆ΧGg4HH'ԐZ2~zLcGffiGB'sDZs2) ձ ;ՋռT$Vs^Qn)f0b#])c*B@b8vnOK1R5LY:zȋa ͺZMpDx֌Q$ڲww׹R-'ߢ9 =n&~, J6G!Hڂ_8HB)fk?xC[ @"\5H_vm{ݔfIv βYO #zõ?AZϑ9tsl_x); ć$X,]<\]Ls?6[X,]fdJٯhR(UV~AO iPR$yfY!K76dj1]yL|:<>W|(nðZBi`u f]y8DupFрts!V$9(/9ƵAO o~Q\Ps\DJia4dҸTy/!3ޜ::} ^KXQWZ3g~m׀L)5< V}M/n^͖bHɵb%*H`q'zvn^ iaca u' F71(S)~=П`X@*Ȇ mVrz@Q6ֿĮ./dAU[+l}4;.k*Z MS|(v_I 4˖5WC$ P &"j'3IR-jk r踇bMu@(qU7QˎHwL Aem _M* .V_ԥ4'qTtAȖ7+` nM1f4ǯK gvb1sBƖJּbu Y2_"AQ%ĸ0=r#a7{EɞQt}X20 e|'D!lauʆfxe&Lv_uQwLk8|t\[AyG錙MN+i>гdjz1pjwu-~AzK\iNKE.d^4vxirYT+s;wzZAn~@(.<gi7ٹv%C+V~u4rjѨs,_Ʋ֩DW^JX0[t)Uglܔp1 rau>s"lI^Z]3&5bCsMi/*/J{â]M(9<.maRH?# -U|7!dDdsR*]=ҀM)f[ϯ߅JX gtU"{o1Vuk;%ggYrzH ia?HJaf*иwl~ΦvKs\Fdď^M+vvB qG3sd]S`ڔbPQ *(~2MaE>- ݬvid"qm]0mc"͝x n&T[>zSn4֨]llD⺶T;њzTԜK6q;-j󒰙lSÅKoh"|ςFCQUB_o 6z농:p=*ÔŎ^ps3ᳫvȊJcS*l қ> p(H#2^D >jH?L8ۋ\e i31!M-)m+yK=(V`P;CҚaaGZ;=;w |"xvO dhD$WQ.M ! 뮿Ł?|( Q5JpAom. peʱ\Zpv}vs̮iĄ(')p/`o5m}e,B[1kH}Reëx.ouCxP;Y* }djEŚE%*gn&\n2-Mʆ ,ٿ׽zx}ZVRDot'2E:>o7R3%I7Z5 %Neyady4Qi#)bA"ETr#  wUdkudv373@3詁CQ(TблIY__J`'=f g:j͢a2oF:v+^m|B:7WB:/~nB*%Ywss!U]ҥ92[`MHڄ|덵>f13GmBl#4Oa6̦dMğ,K6:~/˲Ӄd}їIUBr  8_*䉂I=@yi0*AWd3=:?XB6نnP+g ׺u*U6>3o M0_K]gK6mS;#S\v,]N4PR* ںciKbaMgao2jc:Kßv'7D2iѷRZZx1'5i̼ BJnϺkZ>zYE -s,݅N@5,XEvc{ب;QbԾjgt]:9D'3IԦ^vs*ـ6Zk$Ok]!{t>OY|5R5Kʚ*#aPX+uxqlM 쒟-K9uڈHJG9ަN΅@Ea!glf%[_)Ϳ?K 5_Z;ӺD._2ɣa_m}Iz $AO*-McvmtN8 ys'n-=."A6Rtuh Smd)o|tfb}jaxXW>-Y?S/"q=k=~c'ݴŐg"0 7br=(x %] s'bĈͷ J>¨8h!A8fíccƹf3; Ye(1j[ ijnm6A_ƒ6czPOStq z'O4=?1=3gUX)#)\y#ͅϳW123M8(\ZN9\+pb19à!rj;#tp \qc$L&Z-TU+%S̵Ry6覀߮W4DӀi]weGz}šqr8 mAߡE o ӔWs2bW cmT G]P[,c\TG7TA*>V[ H/vwRآk.h/U#k n@+ߌ7S'VQ`1^r2Tԋݿ$ڭ2CjS8oE'^4PLj/sJ1e75N@j,Ӹdn_I}+,a%so>X\=qݎNXcl VLB#Q瑱_c1>9W"K_|TªN;A:-vaZ{ـO2M-kŪ3}l.u(4pőM.%:G h+2iC[L]pm?<Kmk@\)dZ.K>yY"5[C8_p;$]4F!GTc#&!ܐOX݃q\p|;(WhIa9<6#FP &D/k Qa ɗ_CmusAׄtT'eVܔzgRPjݯ+ |V25d#MK1Ddt\f6&~ ߡh_Dr&Ɵ%Hn w!,Rt5 ilխ?$,, vGXF?p"''cK޼Ve{( TsYإr P V.out`i+/ GB/nѐE1D~#`oƚ G-8kr'k3lRXnX{fJyD;r֨Yk3+6H5D|YZ jsp\n`SNH1h~n2`NȌ$3"%k02EQURmy&Is9yK=~e+},+tOyyr yWgf"\$"I&{tY!8~ ͕#'91?XPAY8\R.mbb|J W]wh>93u"uU\ t .<,|}"FԱ$cy񢾸Ʌ}Ɋ܍|D˷]~*qX07Z 7`v0b~o'rT?aJ|7DL)E3ЖӀOJd>)ר:1c S7B3pb([8PִEh5@҆yz- b (kd9鬀(h4̞)U.IF0؃O1SOYKbV͉fʊ᳥M*;aO3s:^pmICQel/>0 YZsurveillance/data/n1.RData0000644000176200001440000000051210636320360015107 0ustar liggesusersVJ@ JгŻ=I<$D-f3M|qf3K6K^/;e33b:\ @BSK|.+uD2r@m]}4Ǭs ١(lOȓ(We޿q=9i/{P>HhP(`;܋͡{ߢP-KE֧aQGqDD Zr [6|9;7l\u`hMi~-Ұ (8[n}H_fj ?_8" surveillance/data/s2.RData0000644000176200001440000000032610636320360015120 0ustar liggesusers r0b```b`bad`b2Y#'H؈Y$ ļ@|aA`3;p Ue? w08(Qz(У` @ a HO(Cּb Cܐ r'$B9,iEHE%F&$Ì@)E@?! surveillance/data/deleval.RData0000644000176200001440000000142511522016226016207 0ustar liggesusers R@mRA[6Yh#>6RVfܝt䷛_69t-#q 1h6٬DmwV0y||B;*DHn+A.Vۡ `7쁽80p 8 4~8 < p . :܀p pF`܅{pCx )?#2f02.|=(Up/]gDR7r2$JP}4YbtEYM-eM~surveillance/data/fluBYBW.RData0000644000176200001440000007403412672237564016074 0ustar liggesusers7zXZi"6!Xww])TW"nRʟbl$SJ !5?;'nY BjzR.h9VO{xʱ?GsoĊH`2kuR)uNLaj`#112{~WRj4>'9JYY?@Q]F!ڈǶI]=/UvYCt,P2)(^0m(HnzY5_)VH^b$AjMJ0'/~mB^|p/[EU@已\G’Iѥvo>TE/&?_ !v@Hdw =UjK. ߈|0=5O|Fag|5P~] Rg ".xᑬDSH@{R9KDs7PuZ#J(b/ћ%}K;Jٷ^cc!n)mJG#J~5R)&&NE+;mlѾ0hc^a挻d>TPBi?ZR!jPv;[NY1րMAVq2KETbkᠲӫ4(†2Oeӓd>po,>Zt]:9YG"b<ҲQѴ_TNvF @63nRpt~ OO{顎цbnȫ`ӁCyKߍFD*6&'OULjW%wc˭Ti%kqÐ7" Qsz%̷ (lzmP  $%?HgЯDK O A%Hlju2GסNr o9ZClqqI*α@]X俼O+Qzm]0lִ4 qtQaV8cұRbM;=EG k1˔moQyFjѧځj%x8p-ie;Q=U[l  ~~YrCUt4o9;e&&9c5>9øwVlh`_R\Kd NygFnOt !gE'sekt YMg#6:kRSuG>!W\6jO^ߑm8f_T 3BSۋ4H 5B!1|"i3p .P &v;젬4*iX\CS5M u9G^¸KIb(*㈧IXLsGwy*O1壞I&73o6:yMr1Fa+v^Wo~A-`|dM@j,Yy9P.+IBjm!? 4υ:m!'PB]ho!5se*%]=vYMwP3൙t Yq*u@ +\#sDR$GEse5 _P%dg0ktwlƭԏ1Yk(B} A[9~hF EfPJ~JdaFC1(Vb{ ĻF?:,x,;&\зŒ^>?0VE; :Cx S^GMALLE˦ktԥa%A紒DsF wXZ`4Zk_kqjr;O,=QiVv)RB.ĊgyWf" _W*w6l=c9$s FmQMcS|O0k/{F? =J*0?`'$[χw- whS}H=5񾕕Aw_鞂GBf `ffjqe4 cכmp J+'hGVtw:[Zczn&$ lJa_c7~1ۣŐ YViŭm*օ[e4c u]Y\w+NP|f% gfn:#ҽ⥀;YqGB1DQvz]0nR3Bͯ5ep%L +2ȮZ۶l:ϫHA=kR*g&!:[􋓊/.q >=15/EC>11yO0s.ChzlqsIՊkE>^$C/X9A([謝`z -sh_fw/QPSա[b_On%, !0(xJ}Z"_Avd" .aTEh}}S]ЂTw~z cvmwO8CJ2SeG|!3\+`M?=R-dxTBf ~߯4)G( K_!eƉ[s-<:(u>b K䲚1Fngve({vVSMaJ'CYżU}D1*;:α8 BBcD%:{h&ͷd?(Cc/@& lG* =-(G8Ŧ;h { N,A=XsB[^X42 b$:ie[Vp(wD B/SbsgM&7ppm}@5hp) }sMlMKd&\)| ۚt{k]`WlN96EE'5Hj}*v A;-n}Sh-``ŵL_ONGe"wz eܩȷ*J1̠41ĶZPMBe:S!zAW:j岈h6򎽵h_Q5 1J^S 8w2|&Ň|K"A&w:3 1SVgg1;k[#=oV_%} k>rͿq# _=Ƒ6'1MVcp_NbUK6OH%^7vqFyE>ܓ̪XTQ#Hޥ=S ̠ط,oWHmn8@# {HEiOדW7}g)B9iSQH WDo`Ӡ:=>RD߼MM+$R!snK=Wͷњ}ەaxg)gӻ> k)M}h,:B3S@\v?̗;"u9#=&)G?%ptRB"7\)` )T^xqdG6,3rF\%פc1~b1+< 4|ʃ}Ϝr[1Y.) q凜K"zfpdgYc'M'm ƈk:G䍏ygq!zɵ@D1_*rȸ:X.vp_\nҁ읧G La "(րā;TkE?OLQCHCC@s ~T]2*[?ǧ/?(pHpp@h  sO1Mn`!-fh M2{z_F~v+[-AMmO'ܕFk-@6̣g'GbmV\bQ6HLn9_v,A*K63{ aJRZ4%J!ct SyJ~.oB@\}턊201Gn\ o1qzGLH a;}xg~C⛌A/[ Z4ILny>fQ F Q0QHCnыo-JFQ R; ݚh qZy \v@u,82 5k>W 5bpsNjp$CAI )&h9*] '-@bE>Q ?"5||duFnNe]0EvVna &+\v2-bs%}ky~<hh =G *K9\.]?b_};yRK'=`T_:Kg'S zLoUY3 bɰi'P$M0#X;o*UZeO耎t`wkTc&4AX'}}v{uʼn~*;ŧˌ#sÒpk!w)I xz]=ӱ[~.2o2 >?zJ'Tֽ U?`XT'9̨93~}\ IB E/&r;!z9~p79 7pVjIGwwe$/zxN1M~\$NiԼ5 ^:&2BI\gmǸB+A4:-ê,DL;m_O w8̎dxqL\GM.7k"5qR]/ `u{ZHt>^`H7N8 [.a4|O {G0o zbl(/y) 1G3>29wEW%s@%Ж8C'f *?`sYgVhpt儕(eRD5(fuα&# 1JtDS6ڂl!LQwM|GS Mv&<>w:pn N||3U6!r"Gm,C+u+d҈GJA֯z BѾƆrOF%vRXWXb-y3c.3b{83~hщn5-t||~j=] Zh5H ޴xH)Y"OxW=A ":\=?y PQ zwn ieYy:i97q!uk&s7i*v˦3ROzU·;86Q=]28{MJחVy{#;0;Uʐ!RJ8}ܤ18\oz>'vP%lz,QM 8]KQ-M`rПN2dsi~sp(DVH O.r̬R\5~[04KYT{T8ԯ8 F@;a><]~95$(ӎN?݂pQV3ƟpUN2y\B^ooj'S=Z!pc#ƺk{od]JBcpMψ= n/EKrrp.b*+ cԺ4.BPs%fQN}pX:q"6)՗emŪeNE L8;8@<-½/#X.>2&򲧀|lmF'I*ĝy:D*wUX q-4 Uģ`'OG!P\`Kv][D:Jڢ^aWxQsYM^zMC'jhy*؍ ~C$x]j@W+ک^`F-K3ꞣ|em~V+7{D檛v9 |iDJQݰqv3v£A (8n> eWMp sB`uH[<8% 7Y*rj}eCXj[ƽ ;p2 y e- s+Hz*irs,lߖVna_ >].hڨ+[!;F>7r.L/sFVeg} op hB6ōɅ:u=,^5H dd3AT;4 z+Pםlu}M~=EZa<3]c0[15[H8=[_DuRSN\@t< bjG*bRNj<+ܰ|V;{;Jei#I9R1TX+CS@ ꮉQ::֡$0GĆf 𩥯$úz\U*\쩳]W|bFR(mSXP ŮRgKK|8Эn|+l_e/T&@Z f":#ױ;)jLv"VDZ0 Q]WD#jt Ra%% ogy`k4)L[:iD}JGpW5fg//tM4oCf=x.B#,2oU|ᆰYsZ'*5|CCªl#zgr?wGD4RB;۵R3襐ngR i/8R\|$i؝زrA䑨}߉J>O]  ͓ǡ1i,}0T"r1HtXeQLR?ЄNG,ʽ +:a>8/YR@nNY%/ݮsOvZ)W22#jHVWSŴ[xS۔u7"\fk.Sz#oRk,GN2j?drLaI7h&Y6yDV9 sl #n~kkϚ`>:l+`JWd$~Pu?1E@* 5J"{nFIMa/-(5(0އ~<(V\N.w!? *8,?JmTm6Td 6VB.k_Pīeǩ2sBN&l؄x 1\M<+$VNmpLYiԪQOpwl!6tU BvQ~~'eyi-{^ {ލXcX  *|8,6-7VH,kb Q <1 &&SzYugEM9!?+i ϳ8k#\3D4 E(h8HTPpt|#l]ÄE6X 'vt+p>5dp:}y'ҺvOm WI#AI*1-qytѨu2ZR;"||'Y}_]b^iaZw_ 3Dxݭ4K42]fiz_w"H @dQ(M(l(g/sƐc E%ЅN`z3|GM^HM@b)BSƬ y3mWUP|^)7H󪶺fd47?pe%.VPe#(q{D5=uA$ R7}u5G=ߩ{#dр-hNGg(w7κgAGr{6h?/`L9uأ]hd~/}̃yMrBW>J v=09qirK#ak?ӻR%:_Dj4Ӱ΄F2 F&gҒtynC>.[QDgdFpy&'s;@b!-]"@u'87ENT-YQ߬*_?g<7|%JTgX;ஶŠ^!_ a,z_^X̌ARtڟ;/)"XYJlkU%ϑ-~ gd*ׂ]KwiJ/] ,ޡ 5P}L:R½9%`)S;Z)ҽ_TA =xf ( ŔB)|JqK;,& ٪GgN 1|L'8 xq>k-/֛O/J`6#?W%dPMS(/ Do^r~ >t.*hاPgqx+3D#aVcL&>rw=OItC⼟br""=dFux φQ)p<8j%&8[0yJ%o"eKeFb{`p AhaLZ tf5Xܚrx̘R3{ k#U/3g`),?Zd閟2gm{ױvvvp@3ޏCd. &&1x k ҽ-dhiwK^Ǔ9ږ qHJT{ԑU%鏎  &;_K G{u(Ymr&S!11\RF,ޓ:ȝMu}#z`~փ:Fؠ`eKQ})>GJ e0d5Eu-WS[cIJ]S549&#- crK\Z^au}ΪƆddi=ksa9?Z%Pix,Ƃ**'iL vF)CIN[DV >PD ;#OM).[ZQKCo#b)O(1( Foc4myUoe,&2 nԒW1!#՞LSxKFJ`i M]IzBN w_t^w0IW wY\Q8TAC &Tܒص9KCZ=Px'V G.x nO}Ut4qz=gW{N[9P%.Ba^%.ɬ+Qߎ&PtGlH|˅&QDpGA;a6VԘ#;'dBH,$Nt;'0b+m뤷Po,.qC7ES9\y)'7xeW-ٝ- .;,1{@R>p.4&ۓz"? Z9&Fy;Ġ*^)60R91:7C&w|5%NX-c%IzRcueuIb.2:rhD HpoF2⨾SX9ܾimaG#vi}*^퀔&!>3O07Qnh@{Ly=oYY|Ή~m#Q ki|2אB ^ĒDm1%bw4z}{kC'oWk&}01efvh0Q%FhAQ mFȄd*pbmA\&6QvS!jVKW~5<W70XD.C'ў.^[ voR=* zrdO5B,цܡu(]ٰ4ah\!~.S;_2 LȻQ_xH:D1'֞7s2rm"JÚ)>c'ǶCu K\]UyKl_ %<4,dUH~5-+l1TG ӉX~|v0OF8C{rAY.7 :Rǐ-$x߾T87׵3vڕPItv_߱%,SD}!J;>4FI6t.}{fFG ':m&Hr%P q\^Ke nx9e~~=?J6f17h1\'uY"8?"Kˤ$dtYiրF a[]H-NHq8@=cUܺsh@9G"7\ND+( 8t<$WU 嶇(%qft3O(#W/vvok.0g"k-J^] #f7.HKQ 72Ր>kю.vG?>"Kk#-Id1 ث)ĐSF5ԬsYH;nՔ 壾N;O!r0Kfλ^Sf֍⼭ϧwæݚ6۸s"6axjևu% v2|nu.4- gWL5{.7  -'ʎ}{'VޅxDFU' xX -,3/pN3( :V嶵)H˜3UA# wV䡀R\7+IX%ÃJ0w&R_Yn:* UBJƆ LsG5č*./v;V@EZauݾCI[gС BW<%4$.-ivMm<BSݒf T~ۑٝcģHFx0׌m75="B:Ɋ X+2ˬ38,~R?CTG#e8frh3f$j3\j٪=GI'"wG (h-|"?͐y=͈\̢ l6:?&ܛlkc*bw-b-dhr+vӣƢC?'P{ozUb6i&RMłoKǣg| ;"WRPH?2"$_o?pgӧepyl r[g$=˯ިB6;VTVș>Zu˗}.-_UJOD;_ Ty_>:,ȭMEWRTZ5p,wv/}5nMw[z>_Ʉ͗T}t?lk+1Syx8 SP2x#ai?|m q}c:gx|zuu &8eL o} 8M5ijT/dI$D- Sn`\a7.ýuE~?W<>=>КډZ}_ 6 i}TRž'n 9%L"MRdD_|BakQssD=@6YۉEc? xBߊuK QxA6n I9zfw,UuO"d-Vv3fS7_9g<ǀm dML R ];jiGcCEN=GywӺ⫒,i1?f~.OZh &XzHAZwbP㒦oQ/H: roT|?GK֥m+ :W<$^cMpWȉezpado4b/;Xņr Uq! :̝,;{<՟}[d`SŐZj1܌9JD~{"y\?M~4>$tx 8_w: vd$bH3z6QdpkG/ۦBRX;'%E5YF9M+Ĺ?Vdx{ 5Nq$`1e|Xz\vwd7I~W5_[o&Wwyf*T/9&h>o&̹{bV=^/ugQh(h_s"$"Y14߯-infÝTdV**TӞEH:WB`:yz,my4^!H8pqZH-/zVY˶sV PlLݫ@hP_U!ЎRb( v*j3X͂J`<::f~̋B!ȗ5x.u;N|_Px/f+z\ݝ5cDb"#08V(r00\K7}Pk;k#?15zwS_<8}=4ƪ_-m-qO~ڦ&&t+'T-X t3H/MlZ38' ogSU~%!uAgEE[XSXЦ|M>@U/l .v'³fVMPV-^R c6_z&:Z\d⣡ع!y^_T9R{-Y?4Jxq+k)~=jľ.ףa-4,{_\x3#́AY??~'\2:Z'EcBt :h2? ,'KDĖte?O_ ߎ؄pVTʿM(&.3X{t8Īw5J` fz]x~<^ωOwjGodoiK0 kHG؈8 dk-q뷚E?O4C0C: ~IT"%ץcr; + U"fiB;!v #`M6lD $hawҰEƳ$cM҉Ƅi/CVUGӕ2V)UZ^QjΩCS\oM8@&]ofaE7ɸ}O5+5X-a\xX04#Ov[v'+!$ qГj0}-8›yG5t!VvɮMK9of~=8}}r17  Qqʢ=6@3T2c?G !@_ua"ߜHf<'_3ynޢ#pt _~:Zg|'T` ~̻ fd{HFu1OI.NنɩFѶYc9mwҸ)4f ~:+ˑp\5#^:ދ7,bShiq0",BԪ8É-fia*^Uԙ,gOy_vN n;Ȳpr %a4v%|d;Dg,.:|叹Szd`Y(oj&3+Dz}n.:OB.`,>A_-QY>τPTE?i]qqw:gY}$?' N%R:]+V쭩mXK*ܪV2sǚ?՞aarK<\ξx!HTŌx7_8yzBmrk ߠlIkزw< I}By{xUq3-I`# .Tf>زɌoF)3ХYɷXted&:34 _W}Se,#QVElĆlZdk;W İ^ӬI[qp6;.WhW5_ryjɪ# mGJQv-O>۬e~E|yKn'?]QfM6ˇ[{惆D략y)BDuc@%Rɬw.+30@vTw>næ%p- 2@뜙 xBh Ů:c{i8VňI-,1KdCv((_؅"ocG4gD +YEf19,OȍLg!w"]4y2)o+kh6iY{d#]ne Nĺ2*l) CG֘8DA)}QJ< QREEAPۋ描O0UJr4  |+/ z?+aȨ ==\ػwCPZDzd ^lM9ؒj&WScQJfF/"v?kEtP:bsֽ nڜ!>pAƄnxWcZ!~f׃RFy#~OƪphӍ|ԇEL8O՚dIo0vH7REu]DGXaa0b10H=DiXd_5c҈{$Cw} e{!{\&QAȍ4'0$Ŕ U=ӵoU5fkYCs]cJ~e^\WdK$a /fX^1LB25ѷ,k!S.Mz Oy];3掣I”fy+iM F7ʷb#pƕ k&uv̝3LH#]'Ќ`n3.pF5` s\A^nO*EiYK0~ޙ6,m %|7Uуc}2Z1 r1_JB @  Wh%i1շsm^B# *1o"Qdl+d6ujَEbgFy00rW x}fXrt Ct߇2woAKʵ3UMPWAΚ+ 2FkZRMwdnF I:)w}^/Mg6=o}UCB6 &0ybqwWc p@яt-(=g+"E뙯v{π1ȈTYR\g.[P%)&V}s]#_0^A Im[+_!S"2fQfB0Pe5џb/dX([U,g%lR[/|?|][d杪1 {,-nR`BqFxԧ~EwU~q<7h$=5ߌ Ҟ%u>j)A_ߞfg5p#@ăeSo4E% gHZAb=h &$ҽM?Sxm x{}~;]eD$`쏮$3b=r&#̵yxsaC&#eV_WHR.95 mo?7N)>N. ȳaZ齯*uC>K&P?)1V :Vv$dV[nC~Y3sr}\CG;=D$\{m鶟DlK(zg6Ml=OuE_dfkh@'&Lܲڦg-kYD fbNt7d'WD~BkgB&CMRmyQ. ܙUFY#LĪM{I'^uª-똾ZwbUӝjϘ S2P>O GB}VmP+HF 7$Z]XdIN}q)ja[iOm 3IL@Y]q_B&6Wï m`PKs|)7zm@h !h[NEN_}maNWrM;>r v:CD{\+~VBƆh" zԋS5\zi?F?Eb>)^15`H6dCs8 @ h%D)0.Ҟ))z n(c>:ɉqЎWt%ozm'Gk~óACwS1(6(xc&3m}ϡhfVEz9 O(MW,^n"Y b@|vs`=5 AjE2t݃Zb%bS7w3(q{mP@~YuhaXLFЃĊ- %U@/MċE$*lbbRtl<L>>NiH(ߜG3dE So# RAδKLmg(=m$C(&vHN3&=eۃ ϏWugyӽl2bʸU|6GSt3tb)ڶZCx3e4uҴXYۘ)x|60M!G(Z0E#lMI%] @RNc-s YrĶ sd,vtVf{ڙo5+X;ۙ۠I@΢\|*gzLz? ̆ hFu) , lx bQ%Xb]J@BK>~)@ðNwlm}(cҊ !Je ,6-Z.s8ڥY%є"xD_`X^W@)#n:h۵6mGWH}Ԋz|`m CFimmnWss'cq%N5sEMl#ͭ]Jde'ڄrrQ[0c( <&ĭAmK̜F"ٮ8/  )m6%M;"XMӧ;=3e eTv,;YNgg;R VS+}Ao5`zı ˷165s1]s#g7l8??-ZP NÁ$Gha&S_8}Os& 2j['xKDq3ko4EyjmpG}4"Y+gX!9`@+jA ņ=36¨HM5Q4ievR)<*Ek[NwO~NB4aJ #'BH50<{S&>>pNjO~W"ߵy- '6i|xmk^1iE:QfY:fBՌo02_YoPS?Xfo@#Ǻmhn1ҍ7"o2qeG?aB]Yo./_G&źnY67NN}[tΗCޓPAw(,7.{Ϩ?,EeQ1h0labE;UWOm~N r[ !2A_HdY}Le z\vՌ bCt^=piG ;m{`B}={TG*b<CY3t`E)A'rmauk^zZZ&$ҥe5ͦ}N1 \vԑ`Yr͟?A]ZV ٤N0VB͚K#A֞q\5 nr0wILH ӽ~ŧ-VQ-fH9xY7C9w=bmːTnK=~tx݆T_/Ȏh=bL߹el!Z8kH';&[NN@fx{$1+7onhrԩځÊ) x/m9!nkџ?N`**ܱN﮽@Acd(sfwy"eÿ4ԟUZl8"+)uѷN!k.I@" J9s4˔w!GS6f)V3 ێe^ˉsYsЫ]c^O4_[9N B'.?:eXX.;lln^R /dnbLkR1:w@6pMS.?/2jK0+:PaJ)]Ӛz\*‘:swQW,$pH02>Ii+n;'o5. l_ nG Xٕ)h=gAȾ ۏg9_zdknؾʊ+ts^طíݶpctz/MY2_/{-iI*e/S?Q¾L']YQ$aɯnЋ3<^URސvU6=Vl"r=>Pj' $%;&] @*1+=iğ};ͪ?DdEa`R$?y;ZɈl9{bȒ#k yCHڡ |fjw?Zmd{S"Us7 ~tyi #O gEbJ2:;#4+;bwS,9&ŕb).q!N-,&o69`@lh*KZ7Ӯ>u_I}?K#ViU .oAEX8hƤh1^ ăZ,Ǜф,yP=/?ڑȴh\ aMTMG>p%-z&Ht^,Qү͂hs=kءWb`g6n3NꡎPB. rڛ;DKt Zx Q95zw nYx~aB~rϟrL+4Tuek^Fy IQ_Uה!kr>9 ELB7&fZ0)y է^"۠zȜ qFj˹;9oĶ)Є˙̝Xui)euX5` H:g0h$ޫ 4&ԭnEwHb RUDf&48 ].Y"@r.sgDL&(ς׊1"t9nֳCUsi3ŎaGeB}]~V,IB+I- tڿB=&~-StͫP(wn`[ Lzۍ!b8bTd1exS"eA @a!򦤣YP eanDk M&I_Xנ`Z8(*$U_e (H~ n]-=}LJ`Z_ac}dd:I^2 Vot !Ƭa.QIIJa@c頬Jp Qt;)+B,@8'!VGHd}шCu߁|7 8_R 럂>Lž>O8ણ _~!c+&\~"eؠOBIؾh Nt6=1#Z?0o.y ;ww7X‡>%d=H.>&F-ц^v/>iy?I ,V}q8'eZ53ԛ'.^Sw5r_Da7K,mTNrꕆPՃq:W.9eO":y >S$HQnw=Lഥm(OCJVQ90}Qh%FJBuۻ*x)Xh~ cث6J8mxmV" 3pzcQ A)6xl"'zQUw{ϲ;wՁ+?۫bTY˶Wh^:k,cyfZיZ%I*AdRQ&##Chirƶ,hN?ƻZH^f39iӮX\N@A D1Hp.Eġɰհ ]ܜ̷Ž}_]!KqfXqR g%D P B9z}nam7Yn!rϾE,TFGƊ/57,8O"kHښ7^Ǟf$>mU=)})_ KuNVElRD~FR25m^o\`^`T ?ep?PAqn5ok-x9W:䛇bE ( 5fE WמؕFVNAy,滍r|/=ڹ:\k;NU{i[6 xן<PBif?x}x2{ @7 UQ"W;&\ZS.VTٮUMX\3  c/x~3\?Y,6 ,8i_=Ar.9 {ds08Yx$ꅷ+Q?Ӧvuà>ac+>}{)v~7M5n0|D&66,4 #UM-}ȏ[#STrbx(PJ.)ىc-WUBtг>qJ Jlachh$ 03#ƥ]7Oч'J`i>ϱ;3V`&KUgO+P;[1PqcEm(CX, l&uX)qLK/|>0 YZsurveillance/data/m3.RData0000644000176200001440000000042110636320360015107 0ustar liggesusers r0b```b`bad`b2Y#'H<טY$ ļ@|8E!a PM 6ıabHvK"<K1(d@, 3@aÆvV(fڅl'es(.@|^KQ0 F  0Ac(Cּb Cܨ r'$B9,iEHE%F&$Ì A•t rb surveillance/data/abattoir.RData0000644000176200001440000000300411522016226016373 0ustar liggesusers sEgw 75"P# w=(A2]8;E""w0b!Uxyɜonw1ZEVmWOw>}z&YY40. ~- G %Vyv5B{qǎ!S:|Y|0 20X wa`8FQNppƀAPc`x< 'x$x < *3`&ɠLς`f` 怹U5`> @X` X +Ahρ*V` x ^ 4(8X ZN IRx <6l7f&x 2.x`+>)v]`7 {` | oapqpiѓJ"u\ 5Ӟzb65#qݜ8oiNŢ EWd@KZΖ:UK\_"ZoVI,ѥuMN5 o[g~ƅZ#KھBڼoi>P0RK?D+Di~L!:A\5?7P@ϭjj=̮_sroUǝ8jyN_Qฮ@O_`G3qgmUs]u~9w]2U>?SO=羏^`8ӿY=y;:GfGޫwf}yΗzqp[7|L2~u.&Ͳ@(u\~.s):+үq>#\UG.3-W-0y~[1#7r[շne>2w{&6fC-3Fp@.HzБñ2ǵU=7j`m-龛&4}#A+vz%.v{ݿNnjS9I[⮄G7(Y_r /ٵ7VРojΗ+TuaڻJ oq+Y/`o?B5HvsdW_Tt!mI/ScCP D^:HD2i^>Q`surveillance/data/imdepifit.RData0000644000176200001440000004237013514362332016556 0ustar liggesusers7zXZi"6!XМD])TW"nRʟxq5(7.zfmY y nl,e۟bqɊfd)5י^wʾ#t^Zkم%na7 s:'$gI ;pB:ZhEz>Rd7(Y96䮯V`aan< 9S\w9nx5#*xųԹ;, Yw="ϖo՟Ɨc'[ɾ^LC5C7$Sڒ Dt ֙ '4)g(¶xt''[ ÝH磎j?(bglB3za8'\J?Xa`rsZl?1~Ecdl缼wz0јe j'N^\Bv2лy:ophm nkkHSrY6=y,xVŋwۖ\z#RVk(SbyK5fM쑜EIU?uǘhK/*Jvj- W(F_JG[ `> ?{SDOrѡY׋d2x\4 #al)~߰^sWSӁUPB;X?R1))f;p-|>w8NRg쓟mU\('$ '躌S<]wX@` *BCDlg7σw%O,׎Vq_\+HƏK؞.=V(\Asr߀0\0È@,+PbĥlulZMx{Ku9iϺz{k{d1NWMb z/U/Jj}Hy2Xa;._&@j\]o${PG;3c:BUʵeUqS[g]?mb_%]wrg[ݽRk6y\ːOFt lcxs Yټs̨QdqXWQsEvM75אzEѸ2peJgy!ިqgH`J‰Huy z1t=p//C>:P5C%a0 &=- PZɛT`0j"-#?`PPB/V%kj&<[Ta̸Yx(m"_E)]-Vi~^\i}e^4c.|oLfS iRGPVWHT%}uMhgu0mu<.ky jӵ\^ !~ia#c3qClZ4tנ`k$˫QH,>~5ry;-hPc\z@N~o.nۣzEe3>1h {InMuqMElnD[b7/j|`+"@(:eڮ}[_I;>1VN*GJd·}g/@v\I1ݶJD) D `&݋wa `X;~UPwtT-Ztb;kF`VYLi]7e1AaT5xi]+K1DK ->&QHӕ[yB58ꃗ@㕁r0q@ώ9~0i)1KƂ0y(Cd\3jn X hpzU$;n$FEB@"yTBWׄqU G=۱ ݲZzl-e.h Cx}zep]#ޫ-dX*_ >oZ,^?ucAAehZ)6͙Jw6(G?Lfa|wɻ]‰[N׆] ʩ J3_Z:bp(SʁwfDu˒+֨Lg7ytu)mgE+e3ċ/22Fdڍ\"ಙD[E?W-g쭪C2^ eQm+<rpF, }D"vX,ْu`΅QڟrG&zN1Ms`?reMj}=n&f*2Y8$ %~q9f<T7Ǥ-l!8 ְa~+caeeNmgfHe_%]+wX^ haOSG|?׶܀ xDzs!w#)BV2UJQi4sl*-=<Ɨl]R/}3q<[e ֔^ن@M?+K\n/͗5P6um'L?wjGNC&`:l?%+U}SCD) qU!+X|zj(h=K7U-}%f1t7m66Q^PS&,</* c w"ɌҿY>WlTN `B#쫆{G9(g5\XA^ y@5z'yU:R ?/Rk0~Βuu`ܩϴאVHD;{ӕ6y{l_a 93Tqv0/*9L]kO>ĥd JֳY /)=QGL/Trh/SwS );Utyf^~[QVZe@t9;6,7΋=)nd4Axi!s'3^W PD(ڌtޣ6X9-&?c"K3U('MOt.(YĠ)r*fAwhS' CߧC$t=hemCs1(ZPtO 4h u2D,V&[eYNK ^A -د#3=]`+ױѲAIA%CoFo8yq'iU̖ i1GLJC׻{\B;J9N@%~=jOhB4ʖRU tG}rOC6g7 D&xee]KbdW}bőnQ~fqMldm4,1 8S&ʭ㛗Gc¢ ji=*kڎNFWeI_؈ԧqq-\3aP(ռO', .X'kEP͝$ F:O&B<*X+1*g]3NH e dܕjveNF/0^;l_񝆘@E 8Qcκ{$Zu0º2RLtڂ@*f*F&JavgJiQf8ltBѤGں;l?NZ]dxPyoRcA׎촌Y>0j1Sv;_w[&@7fƸd)B7 >ڿiS-Q^K~H~ts7le|~|nngqS @y0+JQ&$ƴGpeW-:;â%)a9H틒1\9B6V_ QVmT^`~S[U%)7nDrʝ}'s㖋G[EQ<;\t=+lFյs#O,!vOJ.;%,2B(_|^RБA޸RQX#F2{1]NZkMX#W,C~pb֏݃?|\gM8ڈZ~],#Vx &B#ZcȅiX&'|-Ho"i er:F5r.#Mt.qVq^sӮoOTc'`0$VnDʄ/;:8Tm(Hh4 %b1 Sn!@_60-'^8Sf:6MQ4vj[aRa9ukv@9`~-@9Ea_nAFj<#l4bzB삿[>Z5V= `%dR^w5h|ǻave^Tn'R{ 2i2X}a9G=󧓌7H@ CgK]^c͖LBfEdeh{u%54oS|!-YVW &:hV) ͭL-r`PN=Odx\b Q $  4vXG4$EM9f&ERg]$!O>Woྤ/19_@E#}IG[v qEWΪI p oA`4 >fQr(:X@:# N2Zo5QOGl'PBxGK`K|~U,txR@z̈́a*^Z UAXҾvy155)0{ p_ٗMZq|Fc0]  z i(5N- -Yt m%X3 kt̶Du 4-~/6b*;W^, \-wM7o|R}+2Gae}z48Kkp3>EgcÔ7A"\ EiΣ&oBqZG_$V.ŸX&ݺ.-]4 Gч'br+ ;0M,xЁ.G9FQS55xupK$3Qa6xLV6De XQ䔀%?6FDj!uRK;>EZJaM˧Iy.j_)̇l]Nrϳ=AkJ^E:~sи7{.wԠ]\†J"KC2GjХrˊNjaHu,\+b:WkQa"aFsҨC*AwDƒB`*˃ ;oA^3DZ^|_1'~Jb K| ͋IKSӴY|`c[yzV=o:y).$}(V愀Sz-`7 428^bB(\.~ȐwlR!Pa`qO_xȶT ڄf pA:tc#3WfqDW G7ݚ6Ҁv0&l>KZ* L(6Gr.?N@94IΎjkGFV5.p4% ? ~x3|nj %'G+۔j4 ӟB@U5Z[h8PD.ͩ$o C>S%RpE՛}!Qp`T*ʐ~-"'~^Wr]&uqMN%GْB'#tgN?ZzEPlq/謿?o;er[jc30N* T- x P: :Bԍ8dd4w_w3Sܓ.c'K2-]y'6ƥ4%GCJ>,D%2G׳ rܛXhNx hBeO!T=3dSC`ރcLEY( l.Nò\DJy\`[ i߃1l綏ZWv~'Yf-'ӇDmk e`Zc 9{thk3j{;*oZ 2wp?Lʷ 9>wUuMCpE7yҦ7͒r#mk&Q8Otgraa=bw93о^2k^Hڳa0%԰-ئs-"mTeW'`y?Ma3hF5SMفP[+0! fIЛ;]wg]KuIew y#^1F+te)|b k[ ;OV_dn󤢎;bЍ@Ԝ_хb s6ܕe;~ OT [ "DAWkfxw!Ek^1jhi|\v5vz"" He:w-Vim/U(rҜ;x!K1Oby4zP&kE ;w[L_x f3u!mD/W8?;B!T'NwVqNs('m,$:3 җvH}z;ws: YuZ?~(. > `n:r^C]"wwlV$D3?Gt֌^Yôͨrq _Րk\vs+淍_[;w,qK>KZ72Jaox:Ai9D3MM^ ƞ9=<2]P1Ԛrz>/.R -أ—gfxb6dV8 ~>>"hKK;XW"O! JI)w=*{J,$JؕQ>;A3N SHۍoxqFwVa-Zw~5F$ݟq&O|G.AXD(f[mP H> 0og_x@p72'![˚Q2U&8ti%h@ƒ!b@wl+[g  iHM*l:Gdzwo;߱{%qEhi+t\[+["rN 礼Q2k<7z%sO%[^"JvOdw%#2)(Nu]m8U^mWzMqii{%fC}cCij 9/Έ)`wG˩@oō6(x򟔓v01Z4ggGcfK8)ϿgjO .Z#P? h [MF 5m;xq R^nB g֤m_E5IY4VE rI3M#jEA re'Zyy??wQ" {U[Z(XƝ32}+ 6 OjA-ZlNF>55ΊXe :Bs-5GTlɰs.`3$)=(%5}PT>4Bj\UO*{+AQb0.袓>9 Xuamu$6`s^/a-K=8[w$D j[q1g1d hSn"hb6ҝduC(xń*&Pͼ6}\}TPTS?xX27a: -IoCcvlplKDs0~u 17SU$ʋNHkz9\YkA 4ڹ6W,۬WXB:'9Ӯ[\{?7|1 l 45R 6D#$f1gwPyKCrB&z]3}_@j?Ak@8TL lI\gI?+uVOԴ>8*ά:?֠Ppe7\#ihȹPL^'Y_j6U~k&mnw "Z.ૺQWW5ɩa<*Cd#o /\2~AOi&iK}tM>j /_~$-ޮv4/**?yqH#$[ a]Fq=E1)48-%x^Q*{ Kؓ*095W1*ޫckbBV!d)_&rA `ZxNH/OI'sO6ձxu1X._ӓ9 f݀*8DI3즃FmHApv|۵Ӛ/DNcv=BK0_9?ra[[Y^kaitUq;2c}~I# йay%#w$E|xjj2jb˞Pli"J-$Vʿz2㓰 QgH/ѿz*m0UKGZIA2ys %4m"Rh1<dn>ztE+]1v_OV\::Gwk'z!} .&t0f܎Tɑ`Oi2u0oS2|XCr{yи u,xbc—oMhɝ[HdGԆx'|0m5 / Pְ a:o0yhO!&]Ooz^@+-?sۄX?/b2'00Lǰx qT3zB_& qS ޫ &$+N$'K}gtAk,`@e _j΢ <"wW٩F݇~xeV+5_p$xhxiώUX>κpؗn_اAʜrQL S4 sOiVE5%tڈNtnFUDTuO44xє2%aA4WXۗ iP:q4?#<= f.% {DUdQЎflGd:FTXuӽ]TלgX^|G>1Aw.ZK8m_`m -y'F9ߥ?I jb<2vFt+03)G1ZtoZmX|jjrl?z,x y)uJRQDqBo@>bP"1)JF%ֲY1U[WXR1}2^ɘn<; (NeWFޅXDjL3E0jq$kCJK;gug2zeb͟ٵS PEI$HP6aL(+YM=q؏)S ؕ}2l#5B/IGo}Ƣ9{є3Z| 'zE+iOH`%^K/a ?ʺ^O~DMЗp8ekAIPqy; Zͥb̨vOɫ}@eď(V@a`JX9\!4G):ްS:֍Kxwclld f]kiҙ+DM@Hf'|c(%O"Un_ssjBm8F!Hn1dKy#&!7w J_hmŞ|}ǥl4EVLoɒtU̥:q|=*`T_ :rR ߓ!(HF|3s[?3ma|mY]p)D>,4dBܤ.Xb`.+mHR B#z׹ ,ڷ|Hw?}`yKj]ۍUmՒ[7:>JmWZU[#|N,B-F삹m\>׾c_h " ԡjIz !quA XV<$?Փ0BjqT 68'4*ܵ(QF + ;o$@EH< cMXX 嶒ReEff<*cYBS]=)A8#<+j=mV?X"=Et5y>w,JYiVն5; ӆVg HVW,dS-jnnW և#[xŎ=$Lq8:!ouL5 rc`wPuphڣ.9%;20bf #c0eWK|e8þNxnQ<\碔t^Vk%-u: uՄ}5pyB5JE2m\ j1)uyOӜw>ԂJ:o6b6< +UJA16no6$x16ʎ-eрm,3IO_{ƬhuHS ֓rh2 }Bg4 ?挳'!x~T SR8 v?L1!J[Y (ߦ~!ZGôџ{yR3!vW w~]I6^%@{lr(fk2R`2f0R[h쟖 adZ^oQT(UL*\&V5_GCs}Ki_k4~bƒ q a7t4 dX'GH1a"Oo=<WN1!يk"J~I؏g0$hS5WlVҕ@]n dܘ2+Ute$!4eN%QK{i+-vh8nG\D!rKѦ\K p~1*CKd;T`Ƈ9üF y+Q<)I>g~"h]¡|)6tQ!= FJԝR*wՃ0DQ=X7Nv^D}LkFDE6^`(i/ MhՉ|d &]+z GCX8S+Sս>rL;Z$DnYǛBkOEtU&͆[yQ( `cRKw7dX+\wGRDwH\ y Ճӿݵh.i/w)lTVйD BNCֆ<9ιR`UV{.] yy<]5 ,<=?`d]Q8w~_8A7!d 4;Sgsj,zJ@ RkсM *N[ƘvVQw ZJ2|7qxwR:G8n#F^|+Tj8iiIxL)chEv8/5(B^?> FP*)a]I oQqA*rx?3u9i$r0wPȟ³Vkԁžʆ3- ؜B]\)O"ڋTJpO_Xx}s{NMJ3Df/0c<,r&[a `P{fչfǭ1 /A1|CB\i]P7 e5f*àN Nj51/ Vcsw21Q'JMhv+qݮL\%=r5Iݓfo>4I!=y뺺㿦gm^( JբijߺA3&&s\kYPʔY8j*\VQpIwڒ%3d2޴l6pGͷ 'K7jG+俈{MW+h<Ms0p;} [beeī[8~m>*E[dKWB`t61˜8Ly\O;)`/rse,PE+AӂǶ:!+7mZm18cG E6"b:rXޯq nj(A j6 1ܑF.iK`,(^ee޵9Nbh`(d<@ $c!6UX_-ػj(9rُhRmĄ5^U䀨4ҿ;YVYI]h(>e"KYpmJc{MsЦ|/򽷥'Ij%φzj76|D36Abݓ h?[:b)LWilq\WA_Ђ_\9c ʠab\׆ǂ2p@IO EβT 0 YZsurveillance/data/imdepi.RData0000644000176200001440000224713414006036350016055 0ustar liggesusers7zXZi"6!X=Q])TW"nRʟ#ߨaTYd{8O!]z9N}BQLmH7g9pVeJՄv>e#M]) Pޭ;RQg,Zn @U,sI!Ge܃JM)Xe)7X8fMٙ 0Oj?{c$*wXX@xcP_t>˰$<6]].˻'";fNW`cwۨtc_A9zE˄_Ah4dNfR gM[j52k UIfRDxb8RՐAN_!9/YR&M;A> o4}Maеnߡty^6VVPS%l!I9cϧ 㶃\7 9)CLxSqs_bvOj{mc%nߎc}tBv!A\RO\;9B2V'4$聰^aVj>|FS wz/@:v.eK]ܰe F.c@PiTFƱ)rsy:-ʹKB6(M"ݼT7w2yqT4wtM-@ykŎYɸ[[jҕZO8uRbvIb!aI#$Π%p/~y|;+IܴB0aɽUٕD\$EGsi-8pEe L KX{bzyPƃk' Cn킊uVb$^+ބC՜*@ڡ7Iþʧ>n3/Ǻv޾-t})JLuq+HϐFQլ"@?&Ny,ZtQHhZli3QCt7G];Oo mhr%n DL6d4Jz .q^(V䠦W1̙Ev7NBpt4ɿ4'JOY"t6ͥ& R5%X;X,VH*|AOlEU|ų>oZ+,- +:[$Պ3U0oDh., &UE** oF}3R< } ]0ГrO1Q/+KM-tW5f1tʾmu>27P!O<.d1cOJ (le3ʺqel7xYi {jIm!:?p&@EK^c{(‰_]%88b4>TPFxUmKr35;Pl ',P+AeaC)} N7;̰xN[LC/{hV E 5TGz,`[u˻ct2v?w"wH0:.",RO6/ӿ#,",wRsUނmGld >\Dޣ^Ch3y)ȸQZڥ`> 4>[y'9_\yM.J]* ]X^'eA/e*r0%<ac%E}z'Zl[>zV߫m{1mFb~ -3|%j@1 Dh%t{Bl[9DjyluƆ譩h3ܺX(39Eh!GWYQJ}`LS,-:DZVR ʽf[s^L/$Ax(CO[c(vGLHmѶPpo1; W/ϩF9>$nG$t{i0;նఄwL%)&VǸ Xn[Pg7MԄڣhė|/+uGZZXKm1F3>h8宂]; ~M :> TM 8tP9A7~xbc]ZN u'>O n[b&d{yAZ5{mn@750 =Aē&HUS]1CI_AkB `#> FrN;NS7ʴc2tы8qē=c܌X}|(3ə|7y& 'kvjɘ|,=06 q0Gy yK+L74`ş>4R/k%ݙVF?&9T>Z|P0U յI`dį>xowt냀wOeN& \w]&i$d`LSXέ k&x%&Z6y8|jNSjǭÚF/)la#h&ayswΈ7nN[ۖ]Q{ޔĻ l#&uVKԒiþܶj< q=nZ9T͉5DK>m0/]䅠qSXkBQ`%bvA7xi)t,oN7k'N/wqg̷qcndޕlq 颶Npce 1(+:B##=#yq-pig~VN4οs0k1 snFfJ59 7'k]-B{XfZ$1af;%*Don#`>`C+1CMC"@=_MAnL_oF&62>Ph%N-WQX/ ]p/Rspҍ &^;![ о@B\"XTFe{* ø,#S5Lɨ1(FHxZ+C @M L e?knT0jO2"[j=LV׃`ig%W299$qϢЈ=+&vhvXYU)5.?BZ;yj^G(n:.| C!ҶzOBaZ[&~[=Uiقؕ!?h-qNKRѿYo,٩O|XȜRz[_x-I$AIsyRu+1XVUHB΄hUMclӖ zp %-UԏBa)?MƲEUHا_uAh Bd;"E80?3ʪ4EP>陶i4>čz=vb[&uO#^J ޛ`=$Pɝ}ܴ%M23f&X0AeqA2|e#c{ BaS엤*戬/o>u3JFikcHۙYgufkzS̢?SjK1,5% 7U"ghW7YJ<ޱV`TrC9UEMK} C2?F\Ol:F,pdC7^*zЉV9=L⣄J,D UC:1ěِsuQv9 !}Y Ny_lB`5*'̓K~Hz봎"]D`8^xW̬SuL*0 _q)=Jn- =xhΙePJwd0q,1Kxl2ؗl ch"g?Kpccx!iEoy)T$#"cE|@|WTm=rp(N[Z8Pf`@ .ƒ^0iJ0t5íE  vqW;HvxcM'+r1̜h"C~ow!ҶeL)fzyFi{wCZ1,Pm¥Tk=@BLAn[gm=O"X3u' YsR{͓ge?`S0Ъ1%4!"trN-c( Xz"(.ѦXsYG/gV~Z]&"&b>C#.#JG8# ?P"E:YJK:+^I 79_TfRjrʝ"1'3X@t͠:i-w37R D~kW3bFZ[PpNG@0+ia@H8[tu!_@˛5^j7#7nvȁ+Z;K? XFtNcxq\CybJx_i/LN\[ T@QXq2mͳUI# /S0mb2w@8QYwx;Pb]P T "=93cȴۼsMV> "sE(V`ufQ3 VaSF#>| oXbϸJUUNc2m7~^BTxo݊ɖY.D]ɔ@Y?n.б\-H*-i;?Ώ_1'ڗ8lIp, ;'T փ=8_+'W=!V;,Ig!m武{ Zx /sE~3g/5B<@,xE}s o%'fdS '1AfiCM7@wWBGBy#ZLsTMOmto toy@s3.iMZ҇4]r1qmO>!ϐEap Mm^Z`5h.&YbGrp*dsz]wTZS>ưHi)Zٮf&yݧ,c6D z1ÜLڏeU^OjF-*$z-~Zl\(P>%,Iط=ݒpd&魀47$< M FM!"YbdXMXK)ɬ@Sv}z 05/~f0^UڔLis,q/i- I.S|P,AM -*4-2qxdi}3 W:5Hѭpj=zd䬚q*_HJ)c88aÒix.sW[$o[1HCSIܖA`x iwH"d~/e"4R (&x|;Y}2,Q#يTNӔҮC6&/,& $ /X;6M'ֺݐw)z֍NV*?T[؜VG\4뜶_l\qHT"S?Xtb•<,k8scmC3d{잼wpz"ޖVX4VEl壉_OnrZ(٫%0;m/dhSD.c` m Mty-e}0\msBgkXb4h}tw,م\#$@ ~_HG]h5=ym[& ! >C}P nΨ2H]o~,OBt| j ͜ߒG $+k0)oH W~pgNY# .O v -3RY*XkgЃH鏔{ɢdL7@`~ڗurK4 rxޔɳp21y԰CaV'$U0Z-{~TAeFyV!nEV\ЖsLc:)h  lJBR2qu"/tX 2r33U}3X}*',w ]»Zoָ+ &':lJѽڟ@A?L y4|ƸcucI9(?x%хi ۿίdv &`VK:ûDӑ%L$#vVp{]RjկМ9 GZ`C,09#c.H74.y>ɳ-2x" j_)ol K~4嗥6Zw('尿4%%~!K 4o$8$j%hY\&nWT>nׂ؝UNsI|cȳ@C93KڝMi4=5aaJ _, 2F7tEB(3Pymo{>&Rv0{NdIhCJu+#z9;'U:H0/0(P"\lػpZx{k Ѫ_'w(0C_8|w^ƹ{LOǘ2%ssV\e@BEְ[yxw&!*MBv{#1*1]V8,Q/>{:df~15%$z'AjFrzڜA,K Q!-fgA5x'9·'tF[ QË:zYҧ xDcVgOąE`+GcY-2ݨu dB0\CF't5 0F0ґ1fQ_rz]jGK)JzHnN h;`DHsrR\8lG>2OB)U)R n&;TZR'Sb]Dw(,Hƅװ -"͖H6%˛nNcqݩxiҧ&Y$ 74vdjlP/n27y D~x9XёҖGrq"+zr2ާ8S 23'TdkrC։bv~0[$|ij{)U>[NpMLc2:U)E8 F'"u s0lt0W/alYKD0emOYdq*ȚWJT_=j2H$K6r*u| 퐌 ҫ!R8ǘH+s `#A~_`3oշ3C\ҽ^߱)p񥈼zm,X$,SKPĺpNސ]PNݦT?UFo(u#W(=k+hn''u7 ) nD~܀ƻ֊lB( )*Ԉ Dhz36ϋl:6FCzț9$bE.0e.1B|!;I3vpu5 B_Ȅn!x637Ujd_3y/ڳA9wm,m;ԛsSn#zWCB!^&ge՟lM]ΈRBs/;GF2HahLP)5ަmڛ1592Uz97D!V3N4_.3 y4Ӑ nmr *nV`CS!l_C 6V终*_#i+U%7U#c?Dg[V/ȅ;Fʿ1(kƲ<We~L;%8V7bߚr`U4%*WwCۭz{fsC[=fX5e̩ cS+U/[?̤cB3hӐyLE6kҏg<:; XQiDڪyH1?GgBHk:t{%wIP^jx3nvõ_d$Wg /qI\Shj ABvB]Yw4J۾΃^}yFAO* _zB |%Q[p"="$zZd-&:vŸ2wq_vb*MФ?F)x3ݪQ[ǐ,g3}O;/KXUY+nثjy"Lo`-:4RcgЁ' DD ͐qY ŀ[E:Nn)تǾ>NL#&;rakO VHmU%MP/}Sz&(ed;CwCM95lc6mU)AݽK*Mb|).g$3x$)WG8⟋_m7;DQ9æ1?k$ckǬzpv<S2𘉹ԍMe(lMDsz/QR/fJ/XwCi3c?*nbզVGkUE zߔH75(vxHen !ߔao$5wW<* V6Dӑ?k2@my{^ϒ.ۦeH dWOFc'HÉE lO\I$*wH'7!:zډ8!c)?M2s)y+4~ɶ( |G6e$Aq-$V_W-XȂ( zFː")JnlRj ĹfP^CFm-NUpg-0 :+KXuSlI˼ сZ{Q_96d^\a±t9mZ:`MX^PμQogXӽRU!nWߣi %S!˒|ωXqL5Y_W3@&!^B`vKl!Y,+`R #Dgn1ArP /e|4gfۿxu޸y%_w{)0[ZߚlS)h3!޷R6,݇0g&gaV$٣+n$+gl'mq8[JNr.!QJqiȫ>a|da8\3|R2WQǔf g߲oW6fdE)tF򔠧 |I bŔ?z'=~asS8! är ^^"س߲T`(0 ܿZh19 5ͩ81E^^Q0 hхt7' j H,s愜ɓrGUIꥷ":)&e<^Ll'@Àjqqv 雼R/ xBӭ  ,|N#8I2!Y8Z ґ@iϞ54'lm$g '@?*:_bTP(;*B =+q >dAMHcf fi"b/V~lq ;vC@ ^ T%?rQ0 !_nCS{52y:ΆS t RuomP=(^SRI.Y6mbza@|5>}wQJJm*~-q+ *Qqd ̝TїoH AB;-Nw$F{"eIH3VI]rٴ{vƇ Qj%)x}C_Ax@4$3GjB(t X>Cv㦦g(`j^o](@AT:@7r*nVpۅq[=B?5שYH.=VVa-ӃhdeM g=#]fز?&L]uDtη{)y~|\uaJCo@F_䯝3$T  Z šM;mi;`h:P9p`(6tbZB|o7Y(Hwyqyc"-uzr} o jB8G7SEX^-iuJYa–2$o*[`32"

8Uv<w)#`usm}_hd~Jv[;eՂ:h/Fy %DA ݦ~_c*_hYT[[ a 1 u WV~N=/$;jO/m}or]-%@[ExL1w |P#,MGÚJͻw.RPMi g_KNgɟ+EhoJt! #Ԑ2^r^I29>4W ߟ /sm99*O=n+5}U#3L#0<6gyP+5ooDEU=FAPE9 `8zCTo]c +|qSLC^5}J膁]VNFbJ6Aƣu0 kSCj`"iMt(w4qَ e!#{P4"JEP¼0OC75J}1o,l% E&lD꽒dk* +XUF;/m[5װee~@r7LpG 8u 78=+J yBE9Zq pM,T0A[`s -昪KCy~/4zcir=:~axQ> | L5 zl+$̛ BKdWO&PdO:&*DuaTX*-f}v#Jj[xWߢ>{ zk ~GJZE| x̖ N}J|x~) )UW{=aIEvGndep.-Luv,F\tFv%"ݞ:䯞*{AF|X"5.Wǚɿ֍cn0i5;gRLf9AwTs: r)^C)G4߉~kbÛγ^遆8?Qz19J^^Yn˴d#h?^F7H竉ݵyR: sYIrj,.. syϨ|nR6UR(sHԠTA+O<[r+cVF[.lM%}WAlV9y Fx |HP1 _l=q}?ny@*%f +hpjҞ0Vr3@m'D69 ͻ s',6@Y`9J3D.+CIb ~el˪aJk&xmL.~e_;:``| P0SUȘmIuDRNa$1 |{7]0"dVɭTރm&V84aO"}ß\t*\$Q vw=c)BKf|'ӥ8J &\~)+gE^" O`iJ4Bq% 00XpГNN21e4~3&"Sec>(}5nխ}S iF)8/R&`9U Zq%JOŸ#;i2:l:Ik]sKQ9T|(JDۊ/ A[SlRt z~N~f'Hem\F6aF`YZD&[zQ+OĔ^̔ݒ?B̞kVЖ"E)poVݺ Dݒ~mx1'Pwu 0@jıJ9\MίWDarwf1XZm=T 5K>c:Q8wSa`݂ĮOa}ybEY4.>bì?#?%˰#)cd۶{kV]w޿CskjR(=\uL%' go_6|nYj@rW +vC;= T4 "C3U61Vt- ]LZNghf_cSǶE- /Z{n7LS+RʗiD͔V 0✶?t꣭{=L9[ҫ7^fϥ6,zw(xoWsfm 铦s^"oi .ޙC\[+ RĢm8L'L VBLIH `DD"7P [ſ{'"p~kE Y\%s2uJЦh#QYz|$5}stsPFhlgR]j\%P Λ5$ŋwqSZC귃wlPr:ݥ MnwTTH쐯<,XVӲ:\a8ra:@!˳w3ٶNkLrqόKscVte_ݦ.< ȧ_SY d] ' VmS{_`}f2YWO5RψSax]F*EI5?KN8 o3հJG8bRフ!/ס, Qv5F{Uߚm-6a;3պ˭CU8<v/)oAv3gPɧ"f/SzVXc$%ObL8d}XOpuR@ed =+"xQm| 4FRPZH5\e% Lr[e\8 V nЃ[c ѐOAQM ׿,a://l禮) sk?Pvb[9<В l[2G{-LxZFu1Ùb*w\rm˘Un;M7U #Aasno߅{  j ߳&()sSsum~܇Qh%O,3XHR-\3 :TU :?!P$ yrAa&vG52&g1ECS7[rSKČsZ6b< Z=@{!D|rfCry+DAhJB)-|֮=(|̎q)D.A7'BԠʿq4N%!NcتJǀZ%up.Y:]Ol;F߮W+p&O]A.@ E/sh;}(_úw$lzj-a+ .LDG'.7N~Lz^ w 2k?`qT{ =g\]rR:] j է0υ#wYvJPYp*YQLW Yhs*/x%Yr!(tdrtC2X8SҞ|JP{ i/ov/YJ3+s\3<0gbf^B;(-w#{L54pَsw?W Z9c0U5q]~ l=$IˇXV-IG>| .|_CgCS@/Zv8,1y->2GtBQZi!]dKm8,OxbbqZ'@v$o(WxGqB[6/U0q&Hl2HVd OtGIRy˜&vc" m,}d 0i)rǁyc^+t9PV+]}Y|7O[R赴^ HEd`븕CQաu mQK٠ݵ@^GP7oK2VxrMpwwѣA`BleAkQ;ƒ"psfI:pwse Fsf@2޹,WIF Jˁaofg$+b7_wV׋| ?԰){LBP}#+T8F[bz[E`aC\,?N(+}:BTM;u4,6_~NuKؒCPֽL>!_ǂCLR~Hd+^9Rm\?UP ]A w,v3&HZ{E )XCA39AI+ub8e̩ZfO̜\m17O8< v4p7=6R#_?Coc}'ĢƝB]۱knﭭ;j6bnI}\,> 9vBB̌w=D9avlieL^Y-x- X1otC>Zènt&~IUd XM͘ ~7T, &z`xj}w%>XPnkb틷Jr?"TWImDqXAy5ObK $ʧ%lX?q jq9'x\\H;^v\ThhYAy*5;VކL?J<)m.CvE 0( zsz$jzK_Fi^dկf"kN6 6ԝ$P"|X<}[7v&lre\g'.M Ȝ7A՞h G|l@Ҥ^bD^VrHU\7x|;7RhѪd"gmg]NB X C" P!胯#|O ;}GbvҎ Ƌ(¾UmbLeUPC d^JǷ\F[̌\ښk~=XA\vhRcf %6sr~ʽi1!M/NU?|s85b]rDI f +=^BwP0R9K3yv^D!3`2"no#~]U6 Pi5YIJcףUDZ K>Sͯ>+$ -4JiS=Q`Y۬]C[͛@)ha ]`FMx}^ 5Yk8աoS| klWp #d#qpϩ %%}JZ eC_銤W= 9,G; si<=0~#O0sR`:|ڙ0θ D3 -9t;LnYaP1Lv0' \؝!p*ylE}XO<-sQ $WY(ZZԂt$P5ӄ`lBr@ HD9BˠI݈X炭q~a_-)47k a`/1S_нFgN ,F߸^|QO 9_PY ]̂U[~OTTiơ(( 5w^N>L+UlaII`R +Iˌ]8S5 S.֦(u?x{(O s ZKSA_Ó`um6YW-H`"< xD/$Ƃ\!=xn\{\󡼼X^qx`ѻ̄.;GuݝL0 3!d$dɾNIU՚%;EnG%pO6oKRТrF<^Ōh:b v(vo;DхTM;uGhkݐ\ʌ>~P)co$q( AjP6oz+2K -AWqjt`HS3Pbd XVCWyk:6ZC>esIZN(zXcDtƢ? qVfe +q5!#LYB:;xOy*WO {ǀT5f# Aܟ*>]@Ouc掀s64>B˜'Gܳ'-`AJhDO䝇oT `5;I ǪFelR"lP >H_SN}vr{Z2ܰN禡:0:]<Q*tKl<{\q :HF@};%h^ fw\b Ҏ1U@S2u_Ga`x41^cD8. Uoߎp۵&jV>+wVfyL!]vA PvrnVSҗ쌝ϲz<"t("$*`gNN-t:P_3TF-~@ɕ9cd[bzCIdz24/>.ewZV}0@A;L3Lt1W1)2 Χ0`iyW %s źfvD-7 Z}UHsQ.J.-car'3 N-8J*ffYYOM `SfT+I+ k=0п8G7f]N/5M}/#4H:D8vC.IizBMlc^zWL#D;NqcPj@EDdaRx_īR!MI3܏9EsM{;pN{+r<\yE4I&H|s#kN"Z:%~ *ɂ=qy뱏W#S|{ita&WSn+ D E=V?A}vMq]"CǮH Td{ŚA}Th! y؎BrϤ׃;i*e|`+>FTD^<1 HR/]<!=U-Y;S/l`aJG;&sh;L?Q*+ћӷW1)PL&[Hw8߹7M+J܍݋K2#-37˗$LVE8dH TrXE>K9#hIsXc`в6s#R[f[Ci}@pJ.NkYBC'U:l-3rzKIGZCjT^F [DXC 4^ز| i1]d$|YG,O=By`>B`TP,)u=EC'E8[٣/8,k]7:Vbn(ؚ؍St&8hn9f_ ~o)dbnebD~몽9 .đ6ylώVzf,|kH31U%w9dyu̩עi/3X};6R]]oVC Y-J ϫ\< q*:9{qfjƊ $ {~3)Ac’@Bcna6Q3yME˱: EW:z ׿|k͐EDҌ@^mJM ^/x,vѻ v,L%w,Rzsat '[,sc"k >$);aYVK86>="Ȣ2qaDi%uƦ^A0<52j.ugxML6].a>,q)ޠsLgKfLmiD%b6"T(ptoxJS0+^9vPJjet8B^4 w ~nަv w\*ڝ /mocA\鈯OryMk+嘘!e_)u%Ĭ8.#%N?*>0'ŰU0b=a* Z[UhD<de7 ?cVMztT=׿~?advTN~kƉ9eቸ~_c#s)~jx=SR@Œ>Sm{Z͹|w"DYdtV Nph)G0ʙ&mC,́z\s{]'b<yEI7<} #EC!Ze6ݺD/ PrsfAIe}ZEqɳ)DZ}3p@_.)) "b7k$3E;nwe -d%ϧtM*̟.)H{9RIp;[l3wq`*f^Uua.`9Ez%sʋwOúj-ޣϮkO_@0J1LЛ%d hK'IMq̮>zz pфx#t);@]Ȯ኱QRn/3ұbzwD[Y;]V\qC&q8HsQ3 EJDaAm^h|Ańn%zC|őҶyT4o_gd6 N+;"@@%wXzX"]/?Lrsm0w6 ?ƙ-QmO2Sʩ?HX/2j3SQ3`x!8@^`4=sBq~;"MhnMliFhilwKe%Ѹ姽ɢ>jo27v5;u%cJM S:;ɰ pABz5aP&`Sݕ>[л߻l5 ('i#My Ȓ2z26' [&]0gNzO{99D4*sXo$|TaVǙXP*KbȪ) k>W<0Z[K-]1*WgN,G[4#l% #fYWːKL{DŽu0˦UCʿk-lpk I;HBtvNV|6ݷOG䤩(yQ N|6!ItFpë=a}3I]%<Ixj2}_JxĸC1i O:>B/ kzai>BOܑTFeLp?m:IF\K>T]+}va'J4h)hR7 [a?L}O5}J|\,Zx RcH$Q f`ִ:L,FP}-cc.]1vQu)?-D6.t.Tnj-ix@/ru.T#9RNyRU t~9ƺ)K=ҐȂJv'e$Gq/(me'L˳&[=(!@viBnȀ/EW"' Kأ+̿Zgfʄ;rD=Kƽ[h Лbxo 2KD Z/d PEF5iBZK0G>_:x}9fDݭ?Hb&Cl|sK{[txɏ7ͥd!N<6Dq~ߕaxO2bHMyʋ\XA_kZBQ!bkt[BW-q)ap{DLbup{x 6hqiQULq j?Gy'_~f&{s *ӫ|NGO5 +|W.6Z `PpuR7yXU>x0/Y%jЉle# @F٪N`c/OL(ZWf]~@~ofp ݇*v-i s"\TC]6ْùv5=b^t M\qf >P9U0 $bd DCW gXuQCN:V AWmƥf([ ~)zn,l.SPR[_⫚Af(/#8SAs׎彽RK i K jd$cІzw72V3лs?6KZ(Š8;MS-Iz0EX4h}K],ɞ53ВVcù}~ljÛU%+. (N]J6nT:bU ⸙r(hqZR:kh"3TJ& P&0F}  Sr5Ohb:/2 6::3֥NpEd#Y"T1JI}7}xdؓfgN ;G Beel%剸sA 32 D\ó@ޠ[&^n;*g$`ww_-rK]FcX.RRBjvѿ?=zC+ t)3?'UZO{M>1+%u=jǑe~A?0IҝKBmGD2:Z]R.3<5ƷA&9˖u5;x'EobG8²_# Q6- 7}OLfI.Wkdj!T%ۋFBvQRy}\n͡Ar=A7ry*=½A|Οݼr ۙ`eFfE,H} #93a/B/pуvVzx1aSW?|IOoV{Ljwq醴xGla\U&jrL\L" tYxnT=|-I!B:fh ("F^ ф4#}+ׯszk}lwf@-mM†>5Ϯȸ6+ӋDSF:AM򙎾=剤`!{.%3(b?6ņ-I>**w .a~\; '~jUΠ~(χH"9R!ƨ7ڋu4n+4+sbU[#hgSYklc` ]P&Yq>MAфRY>NBnlU ԋw`xsο (F=Q;_WQ)=kv_u3Y ~/~-3dlrҵֱnLxZ'!hL'V:u=t18TWBSa͝Mm$M6+MYtTC?&IfԵ*A=/UJ,~wGh 7(t5_&1vX}u1`Ux喓^4iXc CKIѤcd] ^QnOe ( U;4M4z J:A Zurb\,)F:ջJcuRFhsAUPEm9lߦؤpYz] Bn\/{`s+,p`ON06{\* J^ pM9" 6 $AmIЀ5Mu!]>sДxq'VJMҋW+2 _ݯfeŊƹ||HF;IKو e[bhjE@|Q0[NŽ8j:8is,C _HkVN^(%&aO)J2ڂ=w@;]ZDI;s7$5R#vv7=N=q!:Cab+"Psj]{<㥮ffxooX++'.hBu3`ww,AZ4LS4RZnH5{1a,TnqǮnY d B UU^q|yl1 J{`7Tx83iAI:Y^?3,[u (>F`H7lvhbgܖxWi'me@v[,v.˲OOY%n]f6y~G>^I 6|åߥz~=5ZoD4~^R:{1V@.r +jp.=o Ug[/gOMHE m} YHvlhW}LʢHuFgF?.()fEFubFr2t`t@, "hHTPA+R$߮| 5a>A۾ G 6֊/٦w0f}{nEc*n1]rRq-M8ms)!y95@4&&2Mbr6r|ށp5)Q3U晣EPfRw=2U C!`~dÃsI(}F#7M7؜=:m'TӶ}ch tKW϶o.HP<=.:iMj ٝF Y Q&0NGAͬdmƝ i3bG YY* COtSBhZ W7Ѻs@IjFoˣ;H.keo# &L5i#RtP9Yěw3̠TA=la4yTx RK, `{=W**J;0bkp(Ѕ7ChDWWqBQO dZCt_Agf{̳C_D=ц :N7]74 h)T /ߢ( J2 v`3@ ̈́1"%qPB8`w~o}nO&^ ,Dj-BբTOZk:CS>8j1B(TI"%U;Y"3X9ox|\Yvk`+HH `]-9NjSV//iwfΞtӽUF\o1tFb-z@P6\D[gqix0(< 2f'@p{8ѨV qXYĖhAxPm[ x_\;IrߟlB,r[ ??d 4X=I,WL liňYBzG$K E@}̙~TYz+O F|t v5p k63meÁasV<#6ye;⚲FuJtFB!ZJ ޹fj-L%_!'lMȔ0io:PKy`ɥvZW-#B΃Ue`I٬`쿈3d K3 K~ИK,`iSx􈸶;u0w͋tʁs ŃyY\N3G_'uj$Ob˄ZڨuGoW3||MF"&}!&S8sOkf!8}FEjϏ؛<:'c3GY\B0L-_Z8h\a-] ޘ* 0y?5h]P[rKtL2Y󋞋vIe]F9@$=|.:^v%=W6#W1] _R /BKs $sapĨHIYyx$7蹕S](%]BódMfs\W*w=@S:l$6i].G-aj=K/`.54j^JM-U94LRTǬ)Ryf3fgj]I#p%ǣ5dRӪZД; *r.pg) FIL5&B9p,qEU(x*C+MDk+)&[دrND~a@~ձUCSaG U ~  BBF{SFS<UuMl h'F!yC(E>xuVGGO /v'y~fĨvkpDg#G+ *ctͩ>0_8 2L4̆G'~icV$IVߋ:8^8jWa  jVgb,c(.`B]=kBC*-mbM H{9><(=lUȪϦf){R}-]l{LqG!ZHV+ .yJa) 5H+>@(??aP*!! fj۟C-Si)5?޴9ˌ2م`FU-ne);|':_5adzTfa a4 >PwB3Ufe:e@ޏ_`'붆\vxQP(hͲ}}I]ʱFfM-tr|3:Oܑ, eռ\^x;8o(2) MeHwv,?"9>e`M \#&V 9a#׊o0p!+Ɍl&z|-$(,R߷JDg#AV3H"wY#ϯj-:n><4h?"@92$[l; xavHSAVAJ* %dY6=l`%LK$ÄFRų"o*NIsQ e.C:zaGjrT޺ ?Yaj/dG VͧJeO}sm 39.MvɸgbEL҇ H%j%xpP?y _iMƕqbPx4m]Q$X=\8Cr4DMRmL/fDCDMmB};ʹLDybp7D 9+TaUW [okoF4 =3@:Y}B>9јCC22zsIT:X?2}' If$ػBlH.+쳢3kWHMHs`\XO|(m@{Qd)ʧL`t{*@8_b^ |67>_*5͐8ݖBЭ'(^y0gC ,ȴF%`O 6)+Z^Z-yF_FzArψ>jrhwor,ZEG2 U{JЩihj,] |d紘r-CDBc06W gjALMF@P_%v*,ydZQ?\NT?o]CU oV(J!Ƌ& r3^0 7"2zkG 5 ,.KKݬU @&*as݉mQ-["V6: nX3eP9#)K)Z(徱y>̇&gotjww=f_isJ]x33D꾲\:E5?vis?9$KVG;*t[[O=}-G6X]e~2SǢ=\6ʯr&{Gل)dhk o!),t厂7H"PdX 5Nv$e7~aA(Ieo=g@H wiގHYffwN*H{hz).i(Jz8p* _1޴0?/d4{Hre uZ\!X!|y kݣA712.5u>3wb)I=!QP-fY"Wψ:S VI9V. ^DN! 'm~g40Pc7d*L}_Ns0Ax̌ja&ry~*O߯1ݩmK(ǸhJA fKȀ% =%SSuи5C<? wEr ^#ǀ ˡ7(3II,-9Z_n, gym,nG(n+ #IT<*3_BaٮVjZܨN4kR6bWө%M85a.leưoWBCT8/9HhPһZI>REcbh\I{z!?odiӅ`_kVI2j?u5Q:09JG'>"Ɔ֊! $벛E}{6j\>:j@L]._ ŦUEJH_i3=IJ!mP:Ρ#o!I$lL4{,`B|l:Z& .A$3Y%o&8;T\-Q[yBwvi!HuKKIR+ZZL` J.5z}ܼZ Bd 4*mb>@XR^e ׭m_VAs4-N=q\C@=ZDYdUd(~ٕ~4.wYpsp"[ry؜mK{"B@2U2!==?I\Κ#pWLGOZCv$2M/in[z>Qc\968O6WN/nJR22KVBy1Ś}͢p rY)r(eZn{ɤѴ 4!1>227 ٕ˥;]Endi;VO!Roqٙ&mW;Sّ75`oϴi .KJeH&PwY*~" JAt7M9<.eD/Q'8dn;[Y "Yg+b3jgb)y4Cvw݂dvG-АȏD4.Xh`5U [jf ?KT*A>kH i3@39lm6`>ɣi^v\oǁYrf z(L`73\15,9|w/Ro3Hu#FF*Ykec+EIRsU7x马\duR,zgXzMG}]; u^4KҜ_xsl~<ܾdYUVp һx:zX oeϛ8sӪ Z! 43^yDaS`z:;?A(eAu'8#E D,]C/pIcA,e&whtcA8GAH[t \ڡd/=E.R#8Ѐ}魢\Pi%, '$^ xZ`vV_I6a(xNlbf/ Ghg隊c+][˼|'t<%@;kr!Z}U}:cӜtA5d9a'ťkW; :mсrUvKx?6VbΑٜȋTRMѲͧft )y99~hꠎ;W1-$^3E:o6 gZۖ;ݡʭL亇(]=-HS|@B)l/,Qy1L4Q0`#j/1ց7hFYI+aQi@„՞0Pܺ +cIiccX̄ Ԭ#|)fE2^F5c_1? #r1|3PAԴR{LfBbƚoݥfi57jPz”gLs[GHb3PǐO~zNUAw?919z۫K<-vӻ}l>ay8>&Dف QX{܅ɮ挳V(Ί_*Q7dߒk֬ ^R]zv'xY˽MzT.4 eƺJg<hp[8a1zd 8/s~S4qs03/b\f"0澟@BBp%h6%vIi]=>:kt4Zdi]=tVȡLos"LO_oŒF ;mش=rpa刔qkl2xhyYVP!q:D!HImgVPH(xHbLE4z2}o H:ťm[X֟j@T!vK}K?|ۭ[9 )vԭ\Fta>cih&"q|X 㫌 b^#hGTu36($g >QJ5Eo2\'S.aAM:KFL%p'_b.Bf1u}p[E4dR]fRhr-+h 7{Zތu^:D b>G#,&D`,2 N}qowa$&5ORh!KbtL}Wvrȗ> >b4'U~Z0JeQ7O ӻ]@LA]$3e?A,w\b|w1p9ɹXgҗ#e˕o29R߱?Ku>2+lQɎE r eZrY+cygV%Gfu ܼ17[eUmldѝ B!;E'\;kds5Y[XܡP~ V,C:+}cګMA 0{j&ETM}LO\'^roCn?pҲm+j7\:)_̴L*D^0jWpimH nWQ6.1JӡE?~Ad!(#6Q,LWZh8h\JYtT 7'H)΀* brXgfjP2lRƀKEOLJ#(pƂxŶQ*S]={`0m jsI7Qu7px94}2IAF&@zXe; |3LW\lCG ;x?Ї"D|ٴr/\k|WZ__wy7QA/~"@ғNfX9P_i7*?r3]b핪L^Cm荺 h30.Wa68lRdkBE k8ive"U'݄M-r9]6eV=misqzs3# ~Ԓ8hG{;F1޺\" jc֗\B{n0&ڻ,f۰hONEf3]gZThƄ&~%[~}qEўloѸ(T;"DbJ!s;Eޑ:01 ]h3` !0 wlM 俥Ā3$z a9[-/I0F-6 {SIcu~m^/NBAd>>1=h6k_xx$y)CDf &1 \i6THSYF$+=)95O\{g)Y+ $T߰,07m#j$ Bz&C'NdJIdij[[\Z3wi x<{j/LNbǝļӖCC]~9YFUǦ o'5H3jJ*sAl ?Ӕy0[DHSWuub`hY/9Oi_\0ANm1h8i{Vvv3'j~vhVyڲKR!s௙[rJ$xZމANlDѐ݉_B1>iPt䎏wQH^%>6]VhiGxxzg~(jTeu3jwDʚSPt\X}h0p(UVj+j,e2v .V.-k]a+΂[%WF4(s0ۇƍRH>K_ڋz h Ḧ́>8ߺ34W-I x9KC4>W:}츮x[dk% ]j" nC ৞AG#.vZ~=laAӰDąmyT$Q'v<>S՗N2:HW,(UTjpb,dv翎a}(s.8i;*e{W<D )Vn-ZYR=—/,=\r>[Cspe>MÍaӅfRtJ&]nFu-R C >S8b<܄RY#]0pT,D]kdedXz! Q敐z&$췴|![a=/4 آ冐X}?Wfd 3AT@QvvX v! b<̅aTҽMA ^%+T>kXBviW`{U " },mvJ+TwE#IWgeKH{gh;J?;:ֻ쉌x>ٮ}A|gjgmK[yP,& 'tZU1Bh:Nxh@>90`(yMEl_W޻z̨+)/j=KV|NPZ?cW7ί깙IJDْ l.P +V>ӈz[tצūλ?m#0n_/\Pz4B~_ǣ q2?U\ɜfVyjZ'GӨn?XiPrP]/\Ya;m=aoJ=N9vOMq;`tJRh3te,RBRxdžlIK{~8%X^u-/ 띺ݤM5rGNMS˴R%OT%㼶--تsi&3L*`;8*yƭD>3f C]>3"<܆b#l& sfڰX|:"_&*]jDtR[\I 6Z"ܜb5Co0?C|p =뒈E_kc Jcj+ ;=ݲn K$c*`({3ݤվ=(a>4,sxv@\GdH0N6Fx`6KuKawP|lCNCic('q(VIx@ip itǙ|IV4&'_( g|1M/! .רGsٸ9l}@wǖ=p FD]se0˒I%?'Av06XS!r #]ƕg?k7YY%Ac R}p,!4L7/`YVnK jXYS(On)jn}xe"ѳU)1EBM}j뫄`|Bfu'>I$)"9P$WB7[v3T꒚l>q<̯0wYeU׷if݄ +%?`<O~ o-UoslGIq?[Q%N"g *b(?; jpsYX A"o5aPqx]tҐuSqbk3v5pETT(B dضyl4uytcZh-+ e@=N*FFk9Լ78l;Ex7n= J8~St?mJ_WM ^Qmxdḷ62AU{*SU`[A1her)Vb]j34$/*c$Lթo}A~^I{WV`5Y?`u"㬔YnPS88t%3/H߽k< _ )7+VK";C {pF'[D#/^hg-5<7"~[>&8NV 0e0~3s] UlFrx CO?GCU<ҍ >6@rhC=oc3`NӞDQkF_N:&HeM\;cJX1tǕ2rSd+T0:1jID cK{ilҨYNCQaG< gE[)er~`;N%&hs2m|K"v T|;ԽvJUsmϊM *!`h,L#mkӀܒ.Aw|d~g]5q|=bGau)K4NRUjz|k ĩR&?ﴫ)J g>ڴ_?>İ*Q+}1.^ /VJ=ޚqzV_3 DB+"8ѱFrP XTW˓&l=yzCs)KJ<1Dfb#Y~O} =LבY]6E (v:Axuj/9_S?Z\]~$x`Rbv;N^;ЇԲ7ݺ d0xsM3VbAw2>\׫k־,xN#¿/fBw̻x5YoM MG >ޏJnO'wj߸D"P/b\ߕegBVk@@z vŸR (ȚX. l펨+:ʹ}Gz;Q\ޥn{>+ bOcyl=*Y>c 1ًMݰĚ 'ژ(s^]+CşiNU}{XplhRc*m ^|]c$Hn@3r[afp9dŘzOW-~G2k5Ӯ`z=Rݞy7zД=! h&bYV3FY9[ Cv]9MzN hT'yd% <8QOUUU2ތ#лBIMmѱR !H|!!{u&+Ih0d9b8 )^ifGXmPB6h}h<#OJ)XS< c,pJywg_^{J+6*m!tZ7RWS%)A2UcY%z {Z9v\):J>F^Xv/P"_I^2t_?IE0d J۬&؜GۿAp>$kXgm۪`P*]GGހQ.=-:- tll>ȼR]c1Bu8z>uKJ`cDP>ȥkl)`f_F[r&^Y8V[鉔m|"xZb*Iּb8<{u46e)r~m,ۆr6or>^@5+"^.lՂ´Wd-Z ?jn.I]_R,"\FSKzb!" zl2m+qЈ͸s@Ka,v]h`""ueԨ܊ߚQ&f[ lŇm1줄QAJB )s*}Yc;뛧ʤ_M"9e4Q|`>BmDboսIRnn'M,<>e1=3Rˑ'z@҇ /pDV `hzON}p1٣onp4^mI~i;Ԩd]~酰k!>}Y.k3ǻe`yKtoh/Զ^(5.c``no;)//aCm&d`ߋ 7RX-zpEO W 7o}0΅8GnGp_.sM)C KԮ]Hq2UX󌊡ha-梬8|SI`1V= R5,@ ć} s j/ޠ ^`'R2Z{,V4PiL/N0ElFX-rA*,n:6ohDZm1]3$64 e[;T˃"8ieg5Lf%琉 g{imFTgsB?6'n%ܘ "*PSīivK\nT*3K"%aG5B6U _)hï ^R^F֔;˒HTiry[g~snjU;-RtZCwᛙU\%I'jr731i\4>ڿl(u$Ui5L,zPxA,Zj6k9{fA}p \ 5˚#|.JHDO]ʮ4Ӭ+kJ*t!;N . lu5rQ.1Te[P@ǃ}gM0d:"yb9P'GiTzQb2MH|T0*o$`BBxu^ud@s\hϺ Rj-}s朦3{C/ml[ A%,bPZ4@k'_:B&>Fs܀1Na`9xDO]LJBChFkt5]Vv]69cWR955iWbk5R*x.T r* #Qwu2g~?44\ STUC:.}v$. 2il|P.4=s?r5X1i1= TwWߧ8x\ӡbܗ"lA6sw7*O "@pV/ǹA-*Iƣ $&TLWy:),ە pz!0EI\#!Ҹæhr"|Bm$e[ lKcy_]A<ڐ Gs/v˔`\A$%L{ CԖ=FfOKV )iH߇I`H<OsgLcNgHFƈ= l- ރ)sS]aWK U{)'CxNh3!SH|~P\c* ^U'{}@@6u6՘ސշTsa uYw6G5ϛ@sS0Ay; ~Lt[LtIgKIc^ڟu!N80 w'b}@DSx'wi|ۑx p஧\j07_NSB޳adz.Hp .J*w|vYMU;M]`>4307j!?𛬚^_oMJVW#KNX -w(t OL- }IZꢣtlТpܭ˙ oVJ~Ww(am6^"u;Rgs֨Y)[wPlq2*h,4&0ӄ ZM59Mv8?sE )eZwϛ '5' {چۜ'zu Sμ|is< /炸ɊNB,_* 5pGܵ.t8V@ΒYP z"Iz\m^06Aiô\.1{A=tlϭL;3:DEG8Ûˠ@WR/fXLb T]"[,nmbWle<,, NSɻj:nYjyVic,_蕐9OroJ翳 Ql#Tu[_1m8ױ>( 4_=N']I/pјé_D1fŨCJ;k9YT{-}q-4\-äe%o%案e.a!ioWI%S-!qtj`̎C<9P "jSmV'W l 2=h@C"ae 0EtK#W|Yb.zCi#fi#̌Go3]!a%#|ۅnUػ̌r׫hvvqMZ8荱fkka,$ .K nfx6فRi4#®v8 #8sWFI:U&EFF;/~f?qN4yeh@n51C-4ggR~{>K8ّ}{׵zOa9.R#VA|qyZCJ׏#rTD LTpGQVԢqW&%pV#6!h(R%6sԄr2;F7&=E#.YCA[#ăJAŕH>(p]Ӯׅ1?PlYQ =ÕCZ,"d:A{@Y\: ^K_$c% ;Gp^yr}(LAΛΰ &z=__jys&755n=ט )[5=8)<ܨTλJzʏ۪ny»4IG9Jlpn0' pcӻNdD&<f"uI.[6kogHi?)CO@0_MS;a7b37ƲUY2>λ׎%w9$aH|v]nLXCď,_޽b>]ODy.Z ReR!W`5uP3 h6}raE%\^4<[Kb=>/Pj|ȬLcM Hf_9[MdmG(`9gQQ]3%GF,*]nyw|}(I/{ҮJKӚ̥zҦ UxxƼ.셞#L50p#Ɏ:Y\ @G? w}ZML(7WqZg=aFw4-s'~ú愲S[oXcr_S[i_S1(h~ԱbZXF`]jro\)}TRͮ\s_ +(xټzՋ5 ]l|{yX*[ƪ]\ޭs6Aiʃ 9;_eDspd=QAc;qnX1n:-`ݎA6p?XOĉƼ8Y{>I,{TZ̥],1qΎ2ف)dbjV9 ƫR|Ѡk9]>(v$3G.APdOP-,"$?k78YPu8j6bN*2#hW0'ږFQ}o ȹJ2 @:VXizVCVq`>('Sm?ܖ9C%r6BQgKU~L7\ \h}*G^G]!t:?vxl}%q* (SIAߛdl[k4A?u p"%0keݜ;5ݎL$){_~ZԞ1>T\ !]ePq?K-^􂀳N=Bc[ߔd*| a>rg;_tU'+p &V )/!zI?7 e>>TO0ܲn^2&C@sSDTh}&~A/91G`7i~aWǛ4`gyw97Z ZrEz0+dT%&t1'V_[ļ/;L*M*8d/2;Cf-B8`D]YcyCA'`WHǠ5dեoCNSviW:Lq^55:~.B>>8כ;>rZ!Jɇ3MCIUkzu KCC| #{s븚tɋ6P R_8$]I|\S~dId h"xK.TvZ!NVlF4iz?Pwh^Z/f-ucvԴ^Sw =JE6Ѥ{U;ߣ45r2ZU(e[ JiJkOEB[yi5yjbFz9ܫŊ20xzj^9 5zWF{jZy<Hĭ ,lW=Wry 2@j}Y`2( Gi|M56h3Ui3ekw$'FCIŸ߼ԅI[ZvqhA7.UZ80[q18ɚVYB__up*FV гJS9CڄWFA&eNV<*IR7wto&YH ~vn4^Z.w4 / q3jI:c>Yiá:&0F ˗?΂t[hOHI5~4yz+QNr潅^.k˳]@ Dssj|ur&˝^7!ppT~b ~RֳwEMSQ\2y@pKM+~$ЬB60c=AM傛/ 0aVv\p3o1r 5]ᴕ.d &(`O6cU]OCv{ ¶ / CZW\fp{TQE7xm4wAY D4vH驅!th⑙w龐Ֆ hZClQ 93j YqW{ ~5Y 9)JyGcqx-T@qL缓X00!>4٠4<@R|'u제=q<3޷:НsX?1Ap.8L:YʑVeܟb-ޗcPkX0nS[<;s`?#68./c`>)G/j-.>G0w5s؀ms#,.N=2e3t.nʫ@ܴZCYRW [A@a""}/ ܡ<5ZBXU 4dx?Olu\wd0;:A㾶reJɢ_UzCz #*[(’9o>rT\M+8fyUʿ_l:cStXߙȱi(eAz M[]KLj}*1 `EݛˎG?+Ǒb?,L1v8sD6-dޥ>c|oJd*pbm>z`-}Xwk-E*cYko\} pf+rgn'$9Qi]2ѪJhPGz7Sד01~ߜ(%^~d]29ĻES> g1cQ`>M| 3OZ5g]a/v/\a̍ :y^ˌ9P+薇ԖR=89_Δ+f9&R>[,ZɓLCgvUCI9XҌ,z VC *H,;H^@ Dn$BĤuc|K=-w |^%HnjRfI/,{ͼ`[]8hU ee?N4ס`_g_GXr&eBxdd'8𪩈3LOq-./mj~\7"7))G[ R]u>W_|Jу6qҿxNlS닶QF8V9 DzbxM~װus_k䵟sK!%a!GHUu]H UWv6 Kba i;= h.8!Np ưO_]m@ ACڧL#sP r–9; NUȧ6q<)Bz#|`2I. btHfOEGRy \ʘaadJ* d蹼Ư/ yx Oz, !*ì‘^R1Ѱg܏JgtPM_Ek}9=Xo;חރ $2X] FM3!5` S0BBnS蕭L?GrZi Qy$/bONnGޜ-oVɩ}!ቩPQtc! ]|3jbjv4d™BȌ˜E8rm5H>lBVƀ1o QEi͋7IVLWlx]! JU\@K*o" (y ~Q\#uDY2n([CVA3$,ު&_O%o}31 ^slqI1*j<9h8茬k|fA #NPB8h"@lf{.JNSZjFubд92kkR%͜"T?)UMժxER~p0$ްd;io~Æ};8O.oy$Z L=[tv' =lrU B4 ^J f%-vI{3 u!RA_O!!ߤKzgŷKdDMxJ0ɢ^ \!}S!_s!:k8BAzZ$%mw=tt$(:5'94K1UH 1%zyhK礃E7St`6Ѻ)zDMK7a/&SK?ԙp+ilM5SZ#æ8 #3pk<Ume),J߾ Tz!+iz[P̔"C,4h`2L0@-NU-@KNޟO UF Um(y!oqڍw$ˆbfFdVwHպ&L͔e+77J::Ҍs^ruR #TUNȉ _θ] Q6ڽoÞ,([A礍mٻ0, Z|KrȂC$q?\`nfYRRkz\kYu(%\MɄ#  _'`K~e*/ėJzvcO]kykt;nh!|P? X.KgP{̢ :%uo"SJ\. *,ztJѐu=\x~`7݈{b܆F? kpvom@>7@!w 7bBwi<roEozTNUrd .$ #S! }7|`DR442Ls z/(*8Q;ϫP*퇔0G"v|7)Q/.UQ9yskb0],0[:O,iJ)fiP=]gDբ21ÉηElghDI#bW.ù}o /h(b\8?U='>;N5GxmAGH5 髨½$v G%pݜ|Wjᚁ R¼j*Pb r6r y\ */}-A>c (Jr{pÛ,lu5!kVonI%W2~i%x@S]Ё04:aVyZO(Gq i(쇣j^ OiWEI YǮa ˜[=l)K{(`1VqQ\|.bBsa#<1oZQpvS\a|` j+%}HI"1qIrCիRZ|l@}T?5/*䶮37Ai8-GCT g"|@D;GA{PJqb#A8J!_.?J_*i.VqzS>iJVOoV{DN=l l4c(E?Qx[ 5AgފnB~} !tGZ%g_4*;UW}0Cx;WW)%9V )vőLoV]ӸE_ jvIOOpuY۲FWQ%UTx*ɐ]Sh~zj ԮTKǶmPZg汌3[j4YS,*3~nxtH4o&\SCOZ)JϿ4z ~PiQXB}QlyjnwOQVVЫ-aX7WY37Kקiu} {AZ&͹Z9֦|1ƚ6'gJW"VLqIA2jAFVTnT zzZ(ca)@SzIzٺD9')rl^J3&БAjnSvlT}#qsŤ!I,eX\b8ā $hʱUaq,iġGgDHh"wH) cL't, /PR5t7ɶz\`Ճd c1P|'Ͽ<7E_2s3y8ы=R@A"dU}oۧeqSÿX׹ #lw{7_ <EKgr[<֌bũnƻPtfg?~.7`b\ r.0rwƞ`&1w`13&tYQFlʢk|,YL=ݙ~Γ?OEf:XRo1> Z ۦe @5xws)9aO]G>(6Ŗ4tGn=L{B>Хgg ?C5<лfDKǙn9 $$ڳR]ĄQlض.5k~t6"ykNelR {ż1x foDF6}~俈.nEn`u.C\R;ho'jl-f @eFZ!֠U }D@\Lz3{y,Pxcyߕ"ƪ\<ֲ[գ 'tL7y:ݺL#3ɹZd+<`) 6q2+."Q NtLE0$(-lWӈ\i8!LOZ>ͅ5( fRf#kwb0:G+ r%O;aaV6Tgtߔ(-o]f^$H)vvZҴ.ӤyT0s(}lwa3+/֤9S.zsi!mhhTR6Mx{$_nR? J4$};Y!Pj[i%y7ň/DO4VI?Q>ʚ\(R58+->4!қ)rFv )f T}:VȂ. l1-ǖyS>2G)Y2Bz}\~vFM}m=;O 0b{ 8iȞk]_^"`8JWǡ&ŷ}lUޣ4A&  ٶ޿5-ᠩ NKs%?!E^ E+:+l!wͬ XVnš3@"ꙜO tgV~TQ3'7(I/ig$#翄Jȟ'*|{>Lpy)NHsrjQ6Z8#A`aS4xI_+jI0$q˽w5:t$vtz{B(lR*Qi{9|xrO]2_6k%tX8Q}nJRs~l1 :)F&[q|{<4Y6Y0r4n+Z+uBz.%-MGNe/Y`,rjy K1FjyIdj&`kk \mv'IxkFc*y I/q/A栞[y(NJ.sbqGH{h?k uWc$HA=jQ{>黗Z!k f>u5ǗUQU d*O>.C%n b\Cq觨S|S@oKJИ=3m|iK ׋B Qpʳ4IiuhG+oUb!#9VtP};W$/G09d[c{H}=uۡ}.pi$5Dâ@x.fRqW՞ꃦ_;NT|RN|g-V|bݳjMt)cM{WEیAe#Gu9} *ZvPe؛R*\1fc} BW!sUXj 6y0>1%ig-? L *tmDO̵]9q(թ"VXo6&7-K sZCͭ&S4ѳ&jH)oF5fPOB^/˙oиeeDUB-lBPɻzZDY'fx]wHvꁺ:,_uܪ_֠,HkGs#d֍'F9y81j^Cr$Ƅzܾ۠X2 QW2k=Qe@OZL̀PɅ+!x} bpp.? HtlpQ)n}M.Q|$, #SY'#lS#uouo#)%m<1t$)4FR]&%ӖMލܳB@daV6ƑAz%\#Gqg~CھR M{8?է%]KWRzctۊq&/ S$ ġ #p/PS )>ЗVTC1ᨩښz3S}Gi:&%bUEGDoT2{N%ڡl꾨q}'8-o:ҹ",S97@/|.g]1z?7(+F-4PĐ[@y>w{SImxlm@ƀQ!$˨c,%jѥYmjgֺF }JA~kH(Iǰ$ )LO~iu424"dV>èe0wSz&+5m9)Wl5ŬO=;bg P΁y7A +1z?[кM}o%zUͱ~4?hvL~Z^ۋ`]G~RhgZ?Mq+HOOi?J@EV =qCK^^#96i1OM"a#@᩻!`F=P<&|~-6jd`bFqWێ=*s xzkh+[[+))5-ͤ`U[!**V9#k]97kkEGӈ(~A:貑j}$վ7В,Oi2 _wlfk&>phEx۝ bcI][^Q.8Ex I wûYe967cVB>Xj/-=I(}raYoqodTYu=NqOM;BRe4[&OxMZU\9}aR [̈toN*ψk!}uCՐ 8iXK&% p]ƽjRlYzIhaR{ʵV\^v嵎>La_NUTf՚z-rW\Qys7jwq<᦮^f|ʊQ:N DQaxs{<o_q3< kf,~ DRK2_1,< 7C$5&l\hLP lxI8įVU^/xf}&  U*k&@YQf1T:=L8 8 o䴪h>`?ф:ha?kǭpO14'b|8uEwiSƉ}|_Cz2}iuՑ~-t> ~Aӭ) /YhT1786gxe5v=f\ zYO <35m+4-O$q7&uQI/<7KEjU$0՛"0-SU'HTIFhqcPᦘ Ӕi1"P7sN=$-1d !7RcY FU~r=93HT9V24S8 xtVR散zL^6BϲNH&RTJE([oF{0l)o ć@R`_ӚH'Mm*Y/A V$39fR{ "}ѥq ѪTh- ~-,_@%ֱүa]O~S@w뇣ƔFr:sjv.-q GoR}CV<fK0DNw&ٹ`bP'JJΫ?K~^[=D_Gk0#g+֬%t$즲c$Ӭ$ðW4"^ z?!?d=!5"$:q;F-=v 5!88!`+O? ol>8`>Qv?FٲuAJuWyCvgJ\t9{"L(yh 1Cds~k^:)gi cUM\&c2ϕcio(*d)QaJ﭅ೃ.N=)/-"VGڣ>MQ(K\dVXWj5W*Mϻ>ˉl)~дlOw:lhy'D[KϾ{&AaF BPM(sZA7&%庥G5@FrrάGjƮ /wfx%gߦF.rVe([goҽS¸}S4ZV>)֪OF PDmNQbj Qpcu5="9ޡ{Vd44P@Ubf=bԬUR*n-u&y\4𘸄#gKӳAE})¹Iܦ$V:Ϭ%[Tx^v2[{`aŎڧ%mzH]=3362aDF4ر` k_1M-O>/G1]] .C!\#16.3ެZYc4/y ;[> A1wtG3esx7Q@WwDTљK51${r at>t>g$$9mo$lxcʪ J&jLR|Uj$O8.0&{WWX_$'I1%Z305ߤ*Ǒצ.eEap@TP딾s@:O)[*cRm:YOxߜׅ}q@qIvRz+_R';9T||5=r{!b 'Tkfg (ftҰwG4j01,XLx)y[j d@Zp~rMs's~ gRG~"^rp6cVs;?d$8YӗXq ٚD\1dM񢁉YiN8TJ] 73Cek+ȼo0nA|^*&jlG>9lzuٚVbH,t5_eFĎHvU6'un>>mXPni*n7-kAg@q1l\ }$2grʢ%,փVZQR8>;5-nN~LW->r02[Nrj4'ZcLm2?O!y{QCNHݑ~J4T}r-Y#zTu6x=fcm*/PQٯ}\H ,Ҋ;u4H(/R/ #UR5&Vԭ~Sk0ʗaY0?tZDpʤ3+IA5 @F:aʔ[)S*U].5C&Ң,z=C̄p-nl[5oL^vkKj pRmI*J[D<YheuHs:.^=%g %ӄf9i| tnkK2ú:VF@?.qmw]`r~;J$"լ,lo.c ~Ńvq%H˹8-)Lj+@5cOxuFU4"{!)?L eR)>wi'] @@?L"pR[4](I}rڴ5+SLj(=-Xw*ˇ'{Hh[a6%ǟKUve.WCFI.&+QôVL9Tnj4^`b/$z<97?Ićk<3C a/`)b>M]{! n?o㊠/K7U|~Ow"P ʩTqnMMZNKW!){ pN/dYː@0''$,LIX[x"lDZ]I{d=C5iKpYy .4m6U E {]"  ,uigLAF]DhdKnO0TX © C 1!<]QiQyĐz^@ -h7<߫wv(v˒$2ϛr* h3VRERIO4"f!Ra2ki=y@EbLjE+NGU6qZ,ߚq ?~n$Kp8C*.Lۖ D$H!k5"14ALrIo@ݰqCಉJfZڠx0"x6VΔ\h3HnA\C6.D _Q'юU;O3@I= 7"jtW M)o>9Ƚh*<*fՊN*%+|Bځ:gy#,O#, 2cgjRN3}ymoZ9uKV.nLYx 䜙τ;JFS3Æ\!'v[!@fIի9NeY ?5X>G2zX츤:\#܀#JO亜C~{NZ.t~ 3D_/2a=y~u$,ZP|Gc,XXRюGϒn{S;3^mzpVqI x&A7l{f~3$U]Z6^++?l+'Q Fkڵ6=TH: .e000S%)UІٕ'+f ٪Ò`])a6#LkH3R) Q uIe cb%O_7-gPu ],B ]rWᕁq* iy;1ű @;~GFxY<,킬{&p&{2)}0Kҷ:jVWF\ŋ7F=#ʇL5RzfRα+ 2d+?h冷*83{Ĩ(Fy g&dYJ?jte°_qѮW$!|Da%HHfGz:,i\DK'Йʾe1HXδэVW`nuQU[cOHD]AݑFwApQ*UZ!lIkr|iYW&C)+}\{6M}ne& 2OiJO*xsRAK4֘wYK&yaNHJ|.> NTu b& \{9)=j+/ ړA+ّYgO{q dU! |^;9rU 5:e9Y YQa@jцNhW0Ɋp>NvHy$)[~;7p6tOͥ*$ʐfMc%˅p`Q d{=$3YȰNrquW)"Ѣ 0F S.$th* ϔI_r`\lcױlMԏ$WB:@BWf_ֈWW%G4]VOYcnƊZK| ϱh<0zל3b_FlU=6 u/uAҔՐ]pؠ/W$ ޑ-Ayi/wZc5t"ԥ&Xqm ( # 9&GF1-_x>>RQ,r(pW=H'j]Yug ,Qz8k!PʝCkhQw_<.V$r-oq?-%S6㡾=me\^EϽ@ fJFlr2}x5Qb $.I;$KW|ٚ0?}Y՞'۟|9hj  !^ZA?ғ7!?n鼝ى̡}t-o~D9G)E1t{P^j:yqN#,Qz܊&CR V;;ʋ\RIVp6Yz"+ aTڤqUA䎙pqRO{N$sSw?-c;Cn}avint_N5[8kcVef⍗qE盬#)Ȯ%D5s؈Ʌ);,]:g#MTt}>}_ wtLqu9ۯ8K,&]Sԧ[}U@9'/?Cճ!-'Ax{7f\"hR$D^6Nn[IT̡NH>O㺏XMtbKWZ21U.U؛_?JRՂ2]\>e}Ljh^%OtP{~} *ei;5໹E"C|]g?%8ƻ-cgIyA4ܹ\<֕ZD 6 4+.eet2'R7o+oz|W՛](d\J XñV?f$Zd(r`gr;3A6 ?Hb)s1:";ie)EkM#6y.EL 'P̧؀@Aý! yX7׺nB+lZRQy6@.K$A.MC!hRc+@EZH s=d*] 꿒K`ׂ/ GNaXo{ڊ/ f] avֆ±5 ʑ2>maM`nq^@U<(;x"nЮQ;3& #\ƸUu/rwPW3p :{ly K~<_/z܄2/i6yDL.9 ܛxv1N<V w;ܪo<8[Sܴnx3[z 3  .R&P6BFIlOr9H-WFYG\z;ɏGHZy)D>&u;UܐR`D}|&ECh9@ժhZIP&O8W[bc`$"M2@a,RuJv z*uA]n溮qŞP摍 ۖ䃮M UbsX"~lEЀ!X(ir .fm~U,:vF~d$_F4q\iU+H\Amr43PqhF/r;5Ĵ|1Ro7 ׬@ '=V'a8rWj0=]=)`P_ŲD 1$|I:#(plU{waYj((_Rg*'V!;{, +h=b#4$Dd`E=LWؚ/"t[W#1F3N~2V(|24!h;y&a*A[[v __l`h.=2?P+H{מQEyS9E(2`3K6A as2@EԊ2_}gc 4np?̪:˴,DΨϰH[ 1aK*b Lpg"nħspȒC.0 I6(̭K1@UUdp|vZq3>ݛg&bu w*\L:8d(C47TlF^2)}-G59'?6FNzXj>ilEB|۫lӌDcVt.78/Z(G$?_Ȓ 1TfvhPBy·ŗ\Јb-U'sl]gW;#$Јuzh-3U G]aGXEUlRDAh$rFC eր3g?c jRQb˩PFf߹Qio.pzSD=,&SMa{Y#ф'Te5| >>u8lcZoQYs?@9$Gԏ͢N`5jK& ǓHBa)DZNoӒdfZFRt-rVސЭxٮtTg^ʲ9*.Rn8]f"vRW?AAu/퇟AghɎ{Jq*]AFf{^ƶF6^i>SƀÍ7Z[nQ#nQf!ߏ\hDlwR :t#jN_m 2$eBދIImKg4 5K=]e& 8t;8H(z oUU(/|_Aiw~8 { pEO"$0-in:D)1ƽha$w!W xX/;P٧K|2%LO.B=5$ڽ%g3?TE9R%~s'j*7FDS*]=pw [!Կq-4Pʖ3-ӝ:U)T6p/Yps=nF\`)I0 VWx^o+{hC/rJ"ީmmӝօTQ~:pLxlW|5YL^]/$i xJ&b&p-F?!BA./[~ W+Xqza%I'xdܽ͡E,#3 Ɉ"8mDCƵgMksm1xsWh|O-d3s/ ճI[{ 2MYIt'=~bXאQ)6nnнpGͅg%[uU53-qK0{>40CWV~6'($n9ݑkq-{͖K&}AxC[t!j;$~YW H-2Ft* 0&`삡_O6ex 6?t2jʍ)B(B2)ԏ1g"[8 Q63t$Nn 4_D&%Cߠpk210=KodkƆSJu'ÐX!NmqfE%ɗq8hytM`^!ߤX|[p&"LulPX-fP=/P pD2171Fg\`05H&<ǥ_@fo"ҰzߤX07nv1`a4ro+ ]9՟h tYϛhX$3/g?pE2?LWЖymt}6%402m¬ X^#<~UtU nVK65<Ϻxu{Xas^06v4eȷH;J[u(mg>Yd]qK,/nlf 5qhR ?X;ԉt?ðހ3 sY~m}&\X'Oxk~fۿ=i%\-rΊ nuI=ŝg4o74)sgLpn!K& it9.c.Ch\kઙ">L%ʰ0<_\`vq.Xsb#-Òg\M& Y?uF?D pܵۋ~IJ~  UMiy'ǜt{()0a+4LΩ'?Wi[`*%,x^3/zR'08*\!jRG%t+k!5 ҄٤%#$-+XjufsTD6W7EQ;-:ۧY2I~-z琗Ub/g|YNx-~t( ˥+,Y@Feqz#P}% 6?u8ۭxjyJfaBdҐz@}oȺCl9ڀt¸$h^C۾Ca_^8}gɝ@ dQ<5XkU x_9ޚߎΧPKQ7Ip8,*pu~q h+; d5b]gd @R./Z`f˼X)aXd븨q¡9 Mb7PD.tK7x> Yր훕^Or5xZz;h-gY5 0yP G>޽E9$鳨+gԡ|:ݓ !H$|d~O>7`@{&;S?zŪ+Qp*u4 1뮛L:5<'criπ+`{~]᮷r&3c+e&ԙFtS6V>~q1 1k5`$3R* p[O8hl({&KG4 isž"i7Y* K4{ ΰƴF`eCXyhaaMn+6<蕵ıQ P|Jnۗ2 f m5Jr0y/47ʃpR5 Ae6eZ< Fk @)3|Ew'ugq'@8\|ߟ6xt(S*91wݫ+5>Rmczy~e,Y:}5o*yrt .2ʜvc^q}JaZyzmDSqYwoGaɔ ,YϕHA'<;"ը9U8 V IiH_\VpYb gSa]8E-j7&t t'-#熔F54Z1" CnDkpqRy1f"셵l<~"~v"HDR]5(GyrKTZזu[r@P0zzϳQ dEt2"&zn% U9heߚ8n6(!IjOOS T t\xcMsTj6Xϟ *$Z_;H\ch1kk.)4|J?˛@Edbș/?XxX&p,<4mRn {䖵t^̐q8yje!^K.YDm(A >fs@_,ả% Z8@E1lƕ:ݺj3zXKԆگ?./sߛv5[y0-l/kˡ 8,t7lSz@3`HXWcߟ(xھ:injڽ Tص½!p o8dWy(pܵujm͑=ĉ!۹ʼy owb"qhy?u#m% 'dw3@n'Y9bsNYD'?WNݵ:zmLc[ !O',9k#jp = H^,j2ex.*]CD2[Oi|frJUnFj;G2/jΰTR/x<J0E ׆rxqGkzO+j.>V1nKLn=;I$-Е Yn6t:q͝t R:6oP*q@8-]TC7敞 j,cK1Bªi]WnFǑf\ǜu0b^)MdwB-昧v-ZtQ$\bDX9" pώl㜖 xCS; Y E$?3ސsYsyo,Y,fnLTgn(@=Ɋr")|tR^vD$RǁxGAm#*G97jYԂ>[!)A[cԊ4xMMO5'@07@(s-w-bf62=i#مո򆂓r?* Qbpd|g,&^HS(yCw?$wY;ohO6?!'ٸ;{Fc8,XzqxmQq,xtqMcp?əzSHڹ$g1W3fKUkn"rxTgds1.EH,wMDD uLFWm{@)&ǯ/d4曢 vbF t|5 ),$io2ވ3!d_0<#7csVN2u*?'JaW@&sش8K]̨_M{R}A:墒5C+_9 FyOwNyO" [2Ie'mbIHx/6rMdaV#[EcgjdP{g+k8񞤮_dY$q*t`-`yb5gªlgw$ص>-*ZTɁ~MN,=hOIe1eC|J@Nr=WDq'J$x07gxAp8;qz",6+\G#VzsTE Jf&99e>e)Ѵ%_ kxۂy|y눿}g$VBSJ%9m>gԇ-FV!F[K#Xjh~NS^ M-%u蠾WqEFx׳KUXm-?r d ݹkⲡV3 K*P0q)t\6fHsGO &b`}HQwǏ-]mFHD CZ`g#3˝,1ǘP}whx m,>^yYw+{@D(>ݎqF4@ք#Ee$ԥ'~)џa6ߡHj,΃++ ȥ>譱b/}/VsÊ']b ѽ5y aePg]&Mj,qI1sJ;S,@qxh`B8 &%ߊٿʾ# ߱rKzqOAtc d]E TĢ1q8Q}G­`;J\hHBR#"jh0K5ָ7wrI5pfwq}.BDSB*pzԋlĤ4w yg7 p,i3 R7uq9@@0\'/3\Kꏆ'Y&E߉\r})lI_ch5ȴmJr~y6SN(tM;,Eh0b V97)-x/"G*[$2.}5Y2ISdVq)H@f*qztq!2!s_~. '- X4詏۴b\?B y¹N}*(IXGx HUOI5%g/s4x+me(wP7&gl_ZǨdZ.DNŀ}9.N0x#y&AM =T}J ~̮_]5/N'Hg:guS04%jE}[F#Bsl?{cvPY!j 譕ȴl)' oQkA2tO"^XqxhD4{9% g)NbTe+SS̪;%4"FMς)'9s9 c]*-ˎ[ЮcE߆E/1gi,c'"Fߧ(J LV!ϗ+ľă%z%}5mЋ0r^_{/:(?Pc{˧o2p(kZOܽB.U2'*cWRz:Aľ.{FN6 aYFt ,,e$3we 9_@AL*T{V7 !M#qE7k::*ʢɜ3,l:,'Q18&x1va6RC׳a=#ˇ<3jj&6\ROۏ0"A@R_ӱ4Sgo1fQX :WcBpְ]`x~jnyx0HKûJ)UYaɺe rT{P80),hEd'>'#3 G8_x:uLaYAo)ћ &i6"&zH RYv'Wl~n,a[7nAj~ #NIS/N={hwǘ"٤qޔ[Aa`yU:XƣFztK>?)&M V]q6%R1hjFQ$M*(2 5j mmݡ:@1(NrӓulRh BgNhoA&tA0,28Lv5$dSC}9dZ}(m{Er`J ef z=Q!-Ѽ)wj0mڍ۱؊CքdQW3ɥSs)I1p2^GMPv6 Ȱ{ފXG":mQ٨o)BDhA#nu~kVv@.[KKK:4pe8 \OԆ' ˣ#0'Zl@4bgZ񨫳4o eSHG+W9I? ɎJLx|b!XsPT5#:@6U2mi;zmlFy$$ܗ#.RrƸA`F+yKXWFVP8OzFV쳋i*Q7q2AĈ[ KmkCRvF4Mf! \Y0xC݇#(.$"]8\h%)zϺ)ZcD*V>0D9Ȕ+1(P<@LITt pc3W`֌^deojsFgK_['MKqfsAŗ:H龕H\݋?svS0MI[:_P]EAEk /|=x6ws$Q>DU:̘aU֎]Ҭf+NLʇu|~z|׭Ba KF65e2yrS Dki&_Jx#Ǭ|!krZGpWQC5J@.E27 FQXC?Ϙ<=S>w`︗"\L1z V^6]WnpQ?B` ;:oմ]r`̈́ Bo^~kgDw4nyikbPMh/w"5S &k:Ҟ'!W0j/Ϙ>wu>m6871N"hG=3xkH$MπRKx1won>Od;~Q_n [-FRk0=kD*ӒiH:O;-/aLjHwq::_8 a'{{Zxl1ZEH}fR1W٨R3: f F~i~Mbt:st=-8%\ݗ/&)t EHAN(y GR}sI*9J87@kLҐ^VuxVHym3|$]nTZ?;3i#%4Ỏ<.sNq[5¶2M3{q<=7}-:"0y(VkVZf-{cjr?r0l$T{Nx|9]c(P_ռ>c̾2ʸf=/zdJA/Tj0F`)e9`i˄8T b 7ca~*voAW"3YO"^J QVwrz d TpGώ{"PՈ!ݰ!Ce&iQxD2V`fJ_\Ic,.6{HSjs,bU83_ %%d\c{6V!48c93Ew3 %Su A x~CɎ(èYGnJMi&cN[4/{n3ΓS"&B*_^eG:j84Y<L4O,$t5l I F\652ޞcǣ4TGP})Wsaͥ|JwB8Ju ܈mBo{eR#_`(wOݬ.sB~_΃+tƯ}HQYkKVԌ(e0W1 1^dz/3my-xI-]1!#+t,pJ/sʟJ'qD9`&IU9~F8,d>ϸݕ7YM#m* ^hlw^ҾֽAq:=n S_?86@ 3Y(c]Jx'$"zh4j= ^iXꇯM2&>MJ=;\ucY.'DbA[IegWkppqBz_i(&+W7gBR3Y@%>XF!p4805Lvr3 4 .Cs뛤X1EԹ1S#QQׇVY _h>% їh=tJ4=bȐ5*6ڹ;FL8iU/:^q.L 4TnEAe|q5'$фt:6t~"5odg&l؋1,ϡbqrC{U\ZAգft2glS`'E:B{٣ Q+[F|lN˙ywW%iR-TCeX  ԍ KңK\ɤB<ĉ0USdKK }/]Ԃ5&NB[/o;D4&U@ s+aVfBCb6"VI~?/ ȃveOX2|N#dP ⯓a?~j!CDje`b`3Y4&eX9@r&nЊpy%ͫ'_)Tg6Dƌu-h{u(4z3SmTg/C&HB::7YS3r*ᆩ%JIYYC%]Xѣv1}\/Ge|B}u"&HgDznjrk02jE{~s^U0J"Dkg[4`4(!cGE_)T/ ΨM] @uC(Ƒ}O?֫ts'ybZM7}f;A&,IohdM%_rh^ºm{vg#?ݎen[6T(e>L {椚e17znZK)t0`Q#.S$֞$(cӀnK?i\9NKW/a_6#׸]j94S_շ)xXZ.&S`P/߆_<|d¬|1W6t[:8(\;ia] ^}5s:C3-SG넖unqkn%CyռsRMT{nN(Gk RJmװe wga壟5]C1O ; 5paKs/xh1ez7q22a rcuᲈe6:\Ӟ_M/ld->pZn bnI7bͭ$z}6u{$@uii\ ;r>FMv;'U1XvgZ yoI8^ӾV 㒆?,TK7bPl'^h3_^~W}wiYet=+8xs^Ge U@d?v!:֔UEң;^ǓL091 "oGї(˞!gܛ}Yیyc7A.'tT#K=(@f9l&9&/V(0ŎnQX61*Z̑F juBrsOoA8!^0Oy4Fʋ~1Xҷpm˱=} HtalRn`z}aִ< ,xƌ9g=0p?4;5W#qT7(v[>3o:FBw^xe-%HKF!wf /[ ӔJ{>&,Kz. n$tZ~֏E邥zdN b?-RbSMF7PU̥.NL@3!OVñvY-D3‘r)UcƊEddEB s)TF},. @+-(Cx_{G>y#uT탧dϤ._%w(F6g3dnZS^G\AQ?Z:t$F G=n*K*p1jfULv L$76 p>v+ZݝUrdR6'\""48I4KRYbVq02SKPħi1QлG/SZ߾D!lyw |5ʉT<}Ib&i@k_54`v[mRP@Ev` T6Á[`8\ ͗[ʝҕe`0vcJ -{_8PGnHAԍMTVc/H/TʗYbU5ˆ#٫I1K}#!|8x$7Ssǂ?SE9OUrɟX@y%!ܦ{R??׏,y;],#$&j" IaI4B㹴ShBi͆é@vy5|)ё ,+ɰW_%@x!nͫ05y6=Y!oȀm=鰽~NsI) PR<>>n=!8uBFB*|(lԶ %2D}%"4p{0LE2 }>lƊ|-l6ʀE|-4xSc~hxg^";2cצFjslvf+p:6||(.忎.fJz}[Z^};j)u{\`csն#a4ƼXf4 p\nZ:cS K] h`kD/_bL yZ$nVU!P#_,׊ .[OUˠ`] /aCWx4JrViߚe'c 5lz#glFOZmFblf=4‡BQ(Ǥ|t?j!׈XG!ZS v-%J) Smb(~xr#3P6 & 2YBaf_2h* N~rÇ;%FyB8Z\M<$@2]TCJDž@F {)b=QKBqx>ſ[0d*%XGp >7".\J6,]j , 0eAwZX: zͽ:ƹamw$o~j6B^lVOP(nErrX~-'|39EVנJZz{|4-yi,Fڣ;ȧg9(wC';('(TZ'mGt O!?F w-J*%FtU!اcY|y/:&J6_hp ?dUW4U2 cXat%P]zE4j(hߧ(GpX%2+ñGj6=0@Ѥ&ʾ0>-oϓ?;cC>V+p dP- @;>LC0 CnB“]+27>:@k#mz6x iB`i P{DD?5W9fӯ$p4_QchI)^I:*{WEe [Xa&26qp%{|nmbQ{W 2J OZ@":fF\)aï.PAy> ٶh4L%kdk4bL}+Zm@9ė矖N0R_ D$Z~'3g8Z{BRE7S'eY~yeTkϔinȱ6跘ubLJ(ʼnH3%f1S~4%|le>bnj?V9cF&qHZo'6Rd_@=SO<%P\EdKH0K5x#3/fCy9C,;n%^~#zMY ̪tτV|;d*BCcc5F$T-=۬3*ֵ"R:΍_blJIJwIQ/SW݉*4/4!Yjo:! į,_8ؕ{^c .kM*/Ԙ\zxZ޵B(?HXp+Im- lYa֬֙^(8#&?Vmo8~0Ohp+W 85c .0S_kIQONn[AL( OSc˝\TȿR5*43sp,ly7Λ3c:NhҬ`ٟƧ\+{ ؖAT?FX~+[1* PΉ> PNŋ[v1l,޻~RH|`_ʲR =ptKCdbq[k p%BFa+>k T!\&uJ%R UNXٮ,ЉnbɛDQъoupH z<('K $9( _)"=Qh3 ] o[Q%+5TyN9_+Qu^م2={'"N^P:@n?ɩ[iw GV׬2W,+L P;͹^xU aF?C1p_iUŋ&ZyQ2nwj="@Iи!;nbE 5Kt=#]):Y_" 섞R: cﭓj9C?dZ!\ʁ1McZřbb"-)8U# Nt3[JG8mWu'`rzH"CP˰SȼEM8+3@<:ļ>}ş?p HqIX7kQGIa wgW0ZS9n1~X {p {5e-#ζu˓RȌ5$#;ytTpQ+3G! fmIQDq t+~4v7b/k?s mi TʝR?1}phV9ExQnk9F$?i}3pXӣ*Je+&{2 Pr.`USHSZHBDgp4" B(z&g #9r3"/AX,NWBy,2iȄZQmZ Թk^{LetdTMgeu$v0jfHS9bm˩BM{ўr4c}=96Uth{? T-U[7a 4NܐŞTvUGx){]x4JaCQ 3%ga=ഢpD tWoϟ>$h쾤~u$2ip6JCh)XX.?9%\l?x R4w [=E +!Q˱kjV?6 U+%VHƠzqlVVP]j2If% iCMp 9}رϞ=j4I@x{ 'C~i ׶ծ|jP v"va@Ig%kN{_-LrtKp"9,j8jͿ}ڸG)vLq]`Nz±%:$׭ @ UII'3[zo"9ƙ=kf|,XB㥔yKEwGli{[Tۣui=.7N1G@BMevfC{ E0>"E^J2ֺJϼ:¤]ZXKNCʄ#Gs<o7kqoTr"HHп)<0㭙B`L J^mzYKے1s}'^=[rqScmMĽ$_ii?,,У*)6I;LLuK4%Kyj[p4F@7+'axk/]^Q 5J] 'Q$3ˬD~>b): nKs_HTtDSIǸ0G!ƕ1ӜJp0|ÅX[I?Gta-KGRE@db%iD"!ZQ6+z@"9&+}"~ }+WܗPcҏBoĜ܏/U'Sg% |#H7#['\iKdn" |>Nu?(ZfSZq+ p;`(Z2: -D-Ljs/BLpr>u,*A/دA ecnW'a +obώ/,A /Ķ9 8a O+0SehA{]pK3 e[b;5cYgg[^`h E&= Դ7]\ pzlj3;7({Sa"i*W:׸RyƥM=@g8Crbq\vLJUPmC AÎ:!1 qdAG_ixT5 Ȣ*kqD _]9¶ qȤ7PAlr.#'1^d;&cf%a=?r쬓+㧋7tKlxӪyR_X d̙zU8 ;Ժ"?6/a손KζFm!śɍּl{q zQ߉x>jۨףBfݭ-3OajATD Ƅvn}\[*淎M$CUfݯ5oC[*lch[_ȕ%ZMgˎj )*:$% \G!?;m6`DR} Կc(2(_軴1;xֆAvKoKIy* sE3I|q﯁^YcB"3DÓ-I&N )Ddxs,g-q[n.f8O`P2.!]xϮ& J5xvK\NȢϬO![k@ ZY܃J%u `<~UQρ&wB݈r+gqՅ @5Q=? @r6FjTw @x=\Ì PcPv"eB$@2]™Vrj(o+rY?DuqEN3;qXM]NԏLإ`T.ARn*?8PJ΋P{WOq|GC-iʫ;o^a#`![:&~q910h4J=cVTJ_E^}i7mGKc{MAJtc}F<[S ڙ{ 6ɩDz(/qlU暕g*&/s/%cBWOu` 6ulA0wW K%Nn9; y *Gf|gWRPb!0iְJWy-=,Cҽ KsÀ)<1q#[=xS\\o]0ܠ |uE6T 9Vdlpi.> l7[;"6Ș\SN5t ' 04FV5c[H\IsOĥ[ @/د OܣWx V6kkNhi}ìLj|5g[ RT1p{fc*}i:) Z0`2}qN՗LTb3}nihrkQ9tNtU([BU_7es:穹W2ޝF M M^Q>9z> )'r*QEa[u R{AS]Dn ừ';K~a{{m`7p61} 7>SqsXIUq,A̗ uK'mbamŲ9sh[?N;v)ŻV1k(TJ ȸYC>{lՋQ q"1t"2nj٢la!5X_:fGIf; saV]ZZP}/ud(/ @~qNra·brDY&p&s|elL;.Tmss\b3l@m!YͩJPSAݣ;LF+_ OO=Сm}@V_~θ)D1a9F|DGAQVwQS%YB/> B XUojQf{סl;R 9t8/{vd+4J*pNP&N0-#d@X_C,ߩs%w}GuZd+$ӛ[%}yaxa$5^jRXZ#q'>~lJ7/qš7"d8Um9~6B ƅ ɷD9]ne)sTIetĻXA_n^k.l;}:`S=9av%/F3L|hh^e-HMa#1Jw@"އChլ ;}ZBFQ!dlkHGw+)ib 7* ۓ%Vۚ]| m4ơ/&[=*k?1 ~'عMx,jc;ߘ$~18 k/ ưO\:-,cdv,KZ 'VP kCC!&k7~} 7-[-l {`E *^(jyyxci7ԗFk˟KR,'df._0Lä3? D,+gO}`ugYs##_4wumqM:A<:Qc9:`e<#mӒ]vxEhŕb+WQ1G29\KT"eh]f^!\(`"UX?7~FsXʦs XQhyaQ=vҿr6w©b&F$ ~OB> K1}1Syt]R0B hP";jwmD*X!>UNx$hjP$>`lz6tMY(lk8{d&TUF49XrkȯP'1{J?-߁瞜kRF})NG{G]: !vw\ˎ ,YHР7+K>wB|T^4t%xu*W;Gm[MiS;BĄGn-WJ'ndgi]8/Vb:fLucYF!ˬ 7yY"aS#ЗE펎۹JsTjAъ>E70ԏK!0\->ύ1CQnղ~""9(YTix :LboAwʛ*]. ($?B) i8s]ST FfΔ6M c;ljfÃث(ۿՇskjdNn U{Ųݿ{x+NY`ڐ{C|Ch(>CBuϣHe;^5ȍ#B0*fjK2؜e<1w1ȾH_X,?7o(:0c|ijv#뎈z#|9eV6S{M|`)Qn<$2ħ=J||BKf yx_qZX:/H!4< EӍ7#V@;t90,ު i5y2ĂݿqN)pB@&ҁ|bV|Nkt#6:hU\C!mVZvIbQ:K?]|俷zF6bమ5#Ϙt02uۄ@v %1BF(~ 75bi?WOn jL9cӜMI*uZ< ~ a:kYzQzl.˅r0ؼCm):NAMyv"U`l; Zʵy!%IU鳚Pkwh֥I-e9 %$s*:(@PJw\/x%͇@k`wfaV ^g_D&hDV}l{J<*5Z e[ikThU#)̷─C6By &)DL/v`U$B̥a6†mvIK\^ͳc(D֭r7c@oIm @3U9JT1WԽ;h1D7N4b y,Wz8M3/Gx[=.-;t% WAEZ6OQ^0% lQ*%߿_4< Gsi1_ ^݁ x;^< fv/!|_R/ `|-(qĮDwKuH2A0K{!uYM[u$R[8cT>y[3neԟ$`rOvKv v} /sjZ:>-: @Zcxl4\S|iLcӢp}MY=U`{TǼ[SeZѮsiW iWx#聠~{ o(9{oL< <5O#2 nP5HaE) ҇Bhv؁ y܌97 J7 mg,~rfn>Yδ{aB&4jeiXMGHS=fqE4Lv9Ю cM|oeiTbskU?_l ꫡ7>ݐ%J}zLvF1Cop'hD7^~]9Nv9Fg ZvK- ,FDͭebCX8ar2` *rD+6(XXqj 9 W} 4%?vё{F6 zƻ):k֬?mwj֍񢦱 |v|}Ae6]Z^5&=m*!َmM9$4 E(.ۘtk6عI1`(}esꀣvoZiC嘶G.ݚdNQR8 ɂ8171Q~OBU7{f^ "8ՇP dQ2Pɦ#puҖ΁a+t?YE 4Yôeܪ߿}±5T4i,4b킿>Q"R%e`Ydƛ.1:U#/ȕQ{- eپi66hH),@T%Ow _t\FMeh,?-у5F;O0g2 > ޗyYa~O+(`Ыfz`%J%wbTLUP5ާGKD'ϡDaY^P<ͮ;d]5^fGs[T-$[pWl}pG|)q'͛Wbk-"Vt0I| W=jȨ4lHa`Kcp1hFȜf 46S,|ݞBNftd@{D~.B-E^Tb1:؍0f-d!ۘT,f #Ƿ.Zq"w&hCP"s̶c>**ۯIK>A܄6/`_"cNM6}L9uDțܹ,U$%VGQQ$*.tZZ$N]^4Zo .fNpcGwItz@_8y<3Ywۓ?_?U"hӂI`6U\^ZΝCQF!N(.&u3Ѱ 56O-x2/̟N^<%$ۈmAr bF-l`;Q-6ypO\ɂa i=z 󺫪Q'T)kʡl `KBbJz֛C<(*"@h{hUu>6 e:Gy+zG`j|#@GC26?`yN5x1BYEG[U2B<(__`+6ͨhSˍm~ƃhz~LoTX9jk9 σe$#Rо2utyqcw=meE9$aboѶc˫aܒNJ"|\';ym95! +Pg ·-ͮO[ nP0vr,3_1r#q!!{{hχ3i6 .H{!|e"C̍%]! GCFtM@TKدB0pǥS#OLR+nsBB; Nk6νʖ:J EbLd&+} +j6Kj߲6i夢b#Dҁ|MH!}| y. ؼKFo;rIfuޏIΗ(+TPʢ ql@3-čN M@UZEGs攘c+P6ɏ6Zg;~mng"87#j `&%1AXb9% M`]D:Y)7w[ykO{(H=)Q^i%D/lg?i'Ժ:o\)"uԖ;\Q9y E!Ӯd*.C&v l[ .2Qd?rv{"zl6m~cpur?Okcچp#h]khs&@Cᡓ~!c:Q\TYX4K7&`MItڬÌӣvp04H|2̡<пلɯ$9EZYxEe6x!w,fyuMa ^yOTɘW6F\5L٘R@e#%WY/I l),V4ߩC-]Y˅T)\&e7S3ɖnj)#\0;MegOKDi9ҽXUcvA6\1pScDAA[ɂ<pyh,x$w/(\!"´˙N0WC?{Q~b@P|['>(7P(ϓ1؛~lA "|[dY}H 8Jfu"v:d3gtPK-Z/~(&1J#͓nQ:ƫVJ3ObM0U.5DleugφAÁ<3yA4Lc# ';·D6݄WYt(G@,TRsDJfV%ow]Ң& zDa96mĵqf9Cfu5H%@w!'v[*`* c8 t_o}~w菀֜S>mѷq}ֿJ.9Ã1Wֳ q&gA*PR0FiXq|$aW{t*>/;{ghJJh_/@ ]=s3#7xHT3n T]Yho #<dΉQm$V!7> L55t%n'0BDe2{cJO%7uMs^Yp"8@TBj_݁29u;Qf8L.E;"u&*DZ1R8;>mP}4oVzŒƕد%rjÒ[!jݟ+(0*) S'ԥ5n#bmCI{yac;GHMe@A3`JS i[1AOkCY#WR g1o+DZcJ1Ί[(7[]"?:v MnǟJp_"Y6OD,U>4\ $vdvN$O#jJqu͠XjHav.Z\NpQt/IIXB ΫMI!I9_jT˶GV;LǓ'LiGCG8*v\G?K಑Â˭mi{v*pw]<#΁R25?r7(,IYh X9 ׫ihZHD!'t%ތ"*DOڇ"!?57XԠlCslSa_DQ<:h MN ]VDM7SX!u2Ap0ئ*aG`Zc<ꀣ9wa87( 4,:՝IWP6K8,h1E'0-YU D1FwdXs"L# 3DfbXH¶Q "7EF$R!]^w߿E!*l!<:THw.Jvrl[Ä )qI}"@ʅemh-gt h1D z+%`gGq>\abϙg=_eǾ,h eshZH5PI5lg[W391̫$'}|'xKfO/DFVtn HE8i>i{+ɝ KS>m MStz !jBwXXROa lTT ^aMv kUNvt6I^22;"mntrcF[PE"ySFaOg"Ki.8rɌ˫Dz@iR#I;+E1։'㦺*Evj&hg}vaYÙ}$˵@sS;̳_G2"X[C :6ul\Ӥji yEUQSu_^ N] A~ce~x-ƏypȓO7CbFDaЯz 4%ÒBنpC|dbMl; ResmR2P#xȽIRK#YΨ(7/96hEH|ztX3zߔ(сcϪ'n5VC5MC/\1X6PoP|ǹDv;wB |j=T 0R+Yv5ʘ#{^&+NMbFg0sGB` &d'G˚n zPh.oGv=gPCt{^_k|^BXvh=PMl( *PƣV0.WP')ۓJu.JR!:}yE`W%) r%H )6NԹ<$yxq%BcC},i<j,;2eh61f'N]p)^$we?df $K}#7;=dJ36Ф?ڒ9v4(n`a.:5l C:07ɐR/X|2bg-=ڨ6QG2#vt{XXXETy:/Wʂ'lkVnG"8Y1Udg,P~q?_4^i-K?9\6UK :m\Aφ[ۡ3H}בmL2o83\$6xi#lMhE Ͽͷ>ZsbW)'Fާ}@ngN&Iͤ}pgho;ݷt4l-l_ϧ`ឡp ~y5H4ƈ P3ಌDݏ6j@29 &/oTY0-rۙ\:C4I,:qBUs/!b\(H/}N7$<RG6U)3NRw`H[xPzٺ\z]/YmRKXkla{^G9jdR%)ee41{fu o\)ْJ\9ol2VXXPzߪ˧5D'؎H[w0 \ilLE@T8l^qiY>ORּq$&TfIl1eG'( MB˂g~{L\hBؾ6ؽ\MTFuN`x>ߊj* ﮳ 1&d4eW%ve ON󙕿: !Cy+v_uήѧ̩Ӎ5UWhuWH?L9}K+MCcLúP) ǿ|. e[ŗQ#ژh)7$!/QN+a1k_DR 7b^|%5ކ ZܓC:% a l$4Wn&Bpց_̋HT O3e,aA Tp{ǰ-n!RhLYf50Eކ2 P4Vd\}i4<1Uxc|9)h2Zsoٮq"n'N5)fv*[DKDP`8F\Jyׄ{!d5shvy^03}{e *N3,829̊,Ʒ۟YN&tJ^V#' OkvnkFxK>m[Ds3(,%)ĕ}l)d4O8bIGر5#(勞U`jrl_j(Q b'Gi`Ap%'OIAoQYgsQ,3gP"DMRjvNJ.Qs\-c&sJcCBFuT剡"dZ~Ǎ8t{K`3uJjwT]O)*m}1Gr 6dlх X"Q*R滸֯>_v Rc8".!ڪ\ױn;pV/%C%w 8)r15n9׺,ZCC;nq V =>#:XYD0[X\Sq%G ٮ8dt6:3eFH ˫/,mJYs. %fbl/.nW[_z'&rRGC7N'4'Z!0r"R+f{wO=H0^L~RUhUr,eʫ-W$kҤd";{k""Gifii#[tH_KJ4Ğfy&K}^"w _F8 6o85PuUcfF]cH=ٲD h+k`]-Ҁb%NӬՒs$ۣAGTx-"xS³\Iov;+V_VRZ=wZ߮c/>Jv& qćEr[.kԘLsDz|y:R Ȩ5trs%y4E/O o96XSċ="n[L*&R f_'>I0-mU6Xk_kLPdoc`X)ZBf+#Oe-f[f.nz,Q8_иbaơxJrfM0K˻)Ђ%QbseCT7J *<%ᶚ _}ޗ{H#cZVUjaث 3y!vB+$'CVyBq>*vb|%_oRQďe>s d H W0!PTC;GjF\jQouO;Ŷwc6"#W1"?0wV\A+c0Ʉ|nѯ.N Q|`sLHFRE∏տeeY#[aKh@0*-`0[7% lSQg[b1tYRLFIUaj8 C|{ W6iD1U58 wUDN]\4Vv4eQ=-zN;uB7\ksofZq$'e.I\ Y(l{q~,dg .g8Q^;-I{ r[Dpi=l"-%bBǻDl Zt&IH¯Cao[r㗸?Òi*PB/ֵ; ABED4<(8,JڡaC -#HA&*|Cykq3k*$̨x`RF؂ݦ"w&g.AsFVQY9a!vÍ`q-p 1dHDհBhBE5m$N,&,b!Uy[I|[6pcK!!d?SXm>EȊIfQ莡օA*Yz]&3|,6ƑH'V({?G0S8hxԆorG|͚]r?*+"ɞ&!:ބ@W1ʜݾHgbH_Lp㪄@=n ֛Cm6l̐`kB75Xə5 ,X_[[CTh1ahxb}AI1 d.}.O6`-).QV9~Y~<%#c]a1(w+ue\Lߧх0U:ilk\|!d?_eAQP }2tL'Um̄iPwx<>ҩؖWYJ+oGПA{wgvs[i [D#3,i^7tQ9E :K qՓekfH=)sET?5ںKOE+*簃<'UBV.A=(j&͝`6>sr#+}.y`$dB-EԖbO(!١7]&QZ쎗B7/.zuHyZ`K`ZInRq|76L(s_vDJ;y+tLլPm[B%&vRǻfɂ>;I(G'F[㔷Co+F?4#6Ȕ4rG/ԊvNGN-Hl{ t_OXM(ƕȵNե:P Qؔ0Lʉ:>#,:) 5[?|+cNZbkr&l|J&F ,2PlNJm=NϻZ2?w6 <6LG6Ra8S+(()%ns홚Of!(Mqٓ]ɽ Z-Oܯ$ acdدEr]4T~>@]3(wXy=j8'"$wG|m#$_\#2g7fV%B#OYi/%Kf aƦba|WD}KJ&{TpG9up8CzN)|6 Ɓ"%zpr#4]Vx(vp0F,16zw}̬rr`0K_rԒ&֤G.5i:6~r"ߞ:af~^,.-Xwu݃"񉳻\No>U?ZE<&>P]3>}.́/Qc*B =Q JHYU(ُta26ɧH&3fhb]hd,Of=Я֞,pR  z j“!AVZ9xt<+NbWF9~5߇rNC* \]8~dTJ^1%̡<,ȔcD=6Lx9zr'_L#~&Ͼ2~gs 53@sp¹kkzNӼ-9J9=s杳Pl < aB-tE=no0*p)m#Ej'cC֮u3V{PX ܔC(v jTn>%R> ]osQѼ- dkvAM(g\ ?Ul_B;]/xy. E-V91jWf *^0S1:}9}T̍>ƽIuhȔkޙW Q.6\8 E%b!wZa"?ݲQ()EV!W~ڲ.Jn:ў6qT%j\C#eDTVJU//YnTRqLb+Z5(&jYQ20% {%_׉c i?h|/,Q%DAR(6>PG-F|*( ;%ʳM3t8GܔgR7SPĦyc}i'Kޅ!YLX\KY0[(F; & z-3[W-i=vOg fw{? 3`>~Z2sť!Nopӛyl40Jl%mS6Eϙ?3XǙYZR }B6t$=νk=΄ E[oWK6~kgˠ丷>yCq4%  r jBi62tHqǭ2t<%ޣ>_ xMm`j-lWEH֫#Urz_bH $鄴)p>|he:\:6ahcLڿՕT|Q6W ]lhZD17aw Yk.Z'*[`#eCTU0ƎGѻup!Xd\+7{ᘭjZOAԤy{(,J6 x5,Ӥ"x޾obJƻ-eDcISH=e9ikP{W -&`&5,!9Ecide{IO]FQ)y!@u7SҭeEj@ht~9 J*N}蟸 ɌxJC#1]VlX[jn &t6B}TwܥnɆs+줰,}:&p,: 0A AwdaUˈd#h}eO8i_%ȒcN{!9!wD[/Bڎ[32bPu(TYlBꘊ}nqu3o &c?a֕Ꙃ% b `Ě3 R%&W|qvby|!"-!!czP+U/v2O>$-4d%]6H W¯%ꢾs3ə y6|->=Cp r]kZqTf kӚ)hC2TYaPjzx^>Y//UxxA *2-yMnHI6{c{^ }g⋤uCo{*a)N+pbgT (j0k:4at¼`CD_OўW71KH` rl Z"P T3g9 r+y?oc t+W|KK)64Jፃ.րBh<֑}[.K"A쥰aKDmǻsC+T24{]H2Lx`b/CS`<{M,aK lb"x$wfR l*Y]K6C*δ՝9" bJKA| 28y]uJB}N_SӪ Ԯ)ťsQV?:_"te22 ¹Hp{9gytڗC" t* ba(nKkLՆi0 *wxìKvY<vE%\5F=kIJ&Ou >txoI<"T~4m#oDctq599d2kq o˲„b GL)604RXi/3xU8.`劧M5tuE }Rڕ0||eAXg|ٗMi(Y8HTe.E-"=|P4tlm kgUxN jYȎc\N \JPT7黥@*75S,mY]c9LY#G('. , 9Wpeg.vD!m`;Q8huܗkj[4~&9v&NLd4 ọn`uxԋU;66lpmYO J27xT]^b( i [1r?@ʍ1O8uma(oAUދV9}=lV5TX/hgy+$[SYJc=\|=< Ք.*Ox:/S۶ե=uJ-[|*CBn=m;p}!aiO.wd:v_b+SgZGKŅ|˱eFBu3ODQ;.sj ,DH7A8>DFx[(jd@eg$ܱ2hMטɤ`f~SD.BB(, pRߓ3H>g{ սq#vZw٣,|zd oCϞ7-VXTUmL,ab 9`pSoa/9x]CG4ȽK@oXP"b++5OmqJ]%Q/ Fhj`heF&OQSB,ե $S(aʊGً~[ kt޼ڞ,c 3!ZNA%$zq̓Zv+C`Rf(]4+ B5 J~TG.vꟂyU0\#x _OÑmMP; O3BK?2PK@Z9>կ">PqbbNf!ܴ:(a A D-cyOϺ>1\/غ% @@G;$~G'5"Rػ}кޯH\2k<5i9(/G(ɹI9 ,*cV3m(HC,cdtMC>?X? ya1n @ aYi@ɯOr~pW,uDvE=ZS9΄8O@2ec=Jdb$V %bE-Xf L4/{\zFt}J8KKY R)IKG5o8X"x# AĀpyKĜVmS?(t:8$Ojt~rvg =R2٦:PjJPb{"_b*Uҍi/VUp-Q,MP/{<тTE<-DZrkM&F/XFp~P),|&g"M3zĨs TPD(<(Kaoւ fË+(xSlQg]0t-b|@VTK:fMZ@}$(ے'8m"N_8`n`XZG1P֛Kk×=2cC/GHՖ*h6!T0V,_EN9Q)]% 9/ue xΏ0vG@/Ѽ5֞a߁\m$)P1]pIT۴N9 om( +kk>EW2h`Arʟ 4 L)m`auuIZjodM8p\U] ]ãC0.èM#[$&XMCB\ GNU#mb pSƁ7dI+RNm zR{ԤOS>zgEƞ@`?@SV HK/sEg5*/k=.^L̪MPRR< ,*4RwnuGkuݏS]T=i_U9ahO_ / ,aV=HX"scEJ9ECL s?1ɜ鞩OڞȼksTb`\w@Fa&p4] Ԁpw4nBpDB.8QFt-I]v&XI^< YKQ R-I*t-h䜭 .\f~緷mYu-AH1z:%Ulk.Ļ\:| !>+O!Y"~ƭr<`w@+7az@wAqalNF w4/ӄ>+͞juCc5. F:\wq[W!x%Nѭo2"q4,\AI@X\1KuI,:pZ+Y?疭e }Q3:I;3Bл3 zf**~Qymq FY$'ڢ[g/4BhG6r.NߙInސ\IfF2~P&P^g(sjm]kp:ګ1+FѕAH+ĊaU^C59./eᙱ H*BP57 dn79e6z@"/zdH᪸ҍl^ʼn Y{FTߝ :68(j1[hʩD`Ar:JxhIOm>19;&f]sMVG[;hV3(}S W1[ 89I{3c}RԹm5ƛ&-ykܟ+t< )pO.ʸ ]]s`)gztKRD]T#du{a\  `Arܑ6ԩߞbQ8W9Z+畒g ]Ӑ1ސ prUSŘewŅAh.la |[ϨAȘ]Men`#|ӪwMf' G_CnH:ӭ!hC׬I U"A{1&A8(DyXh;G1 ]Pק9ؽY3 .B=$PPú]N'sXf˝4!k)k1 Hz!V\,ۜ)ug,)5BP3> gG*Y/\38k&,ti*eY_C:y.Ow[=l~EaF*#|Zap++ ܆ZҁPA0u"q BepA7@VKHe)A^iv%%47WmwR tOw]G ("q}uUsdS83ou##i7tKq \ Sc#,pŗ [`Z ::@ I;A0^J%&3Usճ ZD߅nE~μ:*!& ڍ}4qfq~IXzQJAh^X.y|qA24,8?9:JbWbZ%X佗U°cW7yh͗ydnPߠ ;.ԇZj :yDjҕkh,9ݩ%;*+U빈:aֵ߭+^!1X)*}w> WN W}8'|g*^q=ȟ܃?MO7EER,/lRں۩aZ^ ꧶]ró~Ɂk N>\8-yh.6:(ILR> o[4| ǿ|˻F&5>Pq]ړ5q4VJzꄍt^O秴N8)?N`jY/HHs)faUix?„zDS) @|}l/R8r)T r22[f\UU=E_o!r㱵ib\k6ma4g#bi$S*c@QZ{-a+G`!b0\X/0;#JV"<=@ %O;!LrOTm7zW(Kݎ^z]=0,tPҊ67[}V&-j20J8>4KDAV#5YB(mz`Wzdp3&nخ!Ob)IG'Kd A3$7XZzO֞B2EP6ћg|TOKgRC-14p;(0:~W=QX}JG]UQ6K2^:"TlX=_LmҫZދ%M$n4rzWRQX->&o WQY܋,G_Bı`TBT9/N!˷]xr۰T8{ߛpυ`CF'Or57@;Poй[DR"#ň_=c&Z`?63u17L̯tV,:b:9R>"FpD{-u)\QF:= T_cs5qڬ,\rrUƔADj|N둋gM7,OK,6 _PWxgn2a'̩5C@qO{6>6_a^ M=ӚZaV .(f}Ȗk'Uhpuc,B2*R8neү~* 5cvkS9ٞcUafnq!K?MLNLBQ#}J!>cB3 耛U[G'cN0k8E+[4Ze-5{yHd+_[[2U!76zP W?=7WLU~?ݴ O7&} #/RPz+3(&vߧ8Nk6o$6٧0`d=J0.qK$yBARr^+D{8•*[Ru 1^ @"{ZJ \*֢Kt8VrN\cC/\/LE [Gl*PԌDcj37!-!֟zZXGGDO4 ЁNறbD4 sX<&\$} *AIRVUHL)lRt-ʍ*B,}B'287m~2r"r!6=bio)KqGs[ϫҤ'~髑[}d V_tt:SxF8.?vD}4J3x fOzl9IǢa rL nD@Nq"DN M#{mlo,Os4JCg^߀.nqc4F)/YV{]FBfC K!@7*#TY-C_J㠗:VVU3Dv?!1 4 ̸B63aLa{|oSj@J[3x@5P){Q4c#Ȃ@Py}HU&_xN5rU*b; ۘݲbZM%9@bf }i(54 VEKTD A0z(_]wkǐ|8XN[c#fq*8Q,+1f0VduaSQ|A?:竦}ԹTu\ ü?JyV"o)vS4#y&|LFjid/V/!z [4khahpUEҞQH6اa7ݤFHZK&<ů>E1(Xo_IaE24=5W[-ԧjQY8mY AzqaN{˒bFS<hO"F I,; ȖPE$?D<^W.$!"?U{%uC`O%Mqqm*"Q_Zs$k*iØ)iymM8ZWT*'%7 ^a < TBޛr)&bܔܿ(9$I~DsNeKݫ6OVve{h#(V.wia盵%{uye}$1+¯>.$&ǀ 8$g<"[\U.sH7} t6sw %=k>&LkzBZy۪rlBs߽B:Z Sd- %x8yexWO4]}FthAu!5˕6¬݋Hse:$0@s- ]uwԡAf~a~pbYAp/1˶i^3MʷD"aI, $8z!6kkeɽM :YfгI]<Vwj #+$² ڌ=魿0=8Eaġ]I6g/U}`Wد1Y}$p4j$TLz8T*qA `}lLԡ&JCVZngxrGvGƘ;۶s8h* (;ѩPΖ|MۮaQBtMsSgIk)7d~荳vsaމn7\.l7tq.*&VYh$z3WLsa1>ng}(IsD4г u ֨qPN&5QOx@G9w4sSOEawQ oσۨ\)K ĕ<˸PwۧU-Ѥm-٩HqO dpy [BY}rڳ1!u 8R^u24ʑ-A)%Kex^W~ T/SOy<k9C]plZ P٠b0GHK&05.^޳hȱVE-ƾj%7%BѣdGhca"?l2c>;cF|Ph= FQidR}Y˴M Li(C5˨g1Um<_u`ꤾPfLJC*Q;J)@m?uvb!B ULX ^:M]a7e= @xc H.z-i ?{D-\&O!$3nR_ۮ$qMH}h&heQ^"W9WtɽN15/.a$VfKe-᥍OD{'OӄˍB"jq.ת +Ժm񞥃cZ:'gLk-vکHFN|k*ݒ1%9NXk٪ܛYNfCJ4U6,׈^FEc|叒InZl A!'s91ɨC 1X¾Y'I-EiHD2qjr0٦89=_㕔Ň,t؏i."m3%GǂKN極 h2m m|̂PotPF`} v,S-ҁLPrpюvTqgIi 'ヷLJT.rbq@g^񦤴Le0 I9XKB}%Ӿ g5Dhnp|Fi;P뷕);kxF\]tV:۶õKOf |Ы&c\Ĉh'TDXlP9u)m| q3\7_ϡt$I.FUu-iWcUxn1dMږ u_i|UH~t;nOfVƶ"`Èo}mh X4v<b}'o0X5YN@$PlGo|Fd~)b'ZD-%,@aB)tRba:^$V0w9bp㮩r7)m% EKA($p3ś";~@{'%27 {.n̺jju^`cQٕ DxB;7~_M|&JZ4u._G:W Yr[ LG bՁIo-U|rNWTfŧz]K R*=wUp۳Ҫeziӯ9x> Iz?uW!HoXIn(5 !%I-fǖڹl]ę7(KY~q*1TnWb8?k\'$oq\o~}y_R3Dd J}f݅$:Ƶk}*NբuY8!vNӪͻ"m&~_[dyaF@n(^^˔[Kw; >w[IG;nS'rDAmr"{TS̆ N{tlA3T;2<* IbudzwH;a"vՊxZ.]/KU"7*ŷKwL/riNj20*?k`jE\)1Dt%O|ezZ|$Gk$oR?L0I #*z3?.Tg4bG'Xt8NBnRp(L%Nh ?l|[d}#~Yg386n8cN~{ sAn]H.j͕^ː|E yOu-!by% $Heh%& d(sMpXcbh!~7N9Z U(=xN&@{b܋+Y،T fqF5(GJ=@xa͒jhI;,/,MCuxXcx,CsAϧ2괁IbWߧ#@j**z++kx/,tYqKJx5->ZL%I"eiB4YG4mH?RSJ[ɶ/7.O0K4DL*!̶1 P]{{<{ө=m;PdڨܬFE!=8|i -o9Pv!5I+to71B;Us]! `*Zn*.bΘbaHaxgw:^0@wlJt,"gVV8ȥt9~^,kf d@T>E&v1Ss'AWp|e8̳יPI z]EV{0T?#7wDj$%_(c&-Ir͇D!4~]fvcD}Y^߫cw1$B o 'F/Š7".‡iMu{TK84VCO`װ o)ճ,%Dܾa4}P_5fªti2֤ gv龩<_=h;pEeT ❌z}Ǽ,s/ @G'9ڥY[.^tQeԪ^pNg/yr>}菕3\*й?'RdWܮOF?ěΚ0͌%#.t?zi5_ҏb4xp+ ^a 8F+..*獸\-l, *4_zk6ʥ X9iM.˨V b9H;v)Ec6i y7ߌ߬?]0Dō/19̾VN%Q_@)e ;H6idsraf3S(!!-m5)4?%V;g' %NҘxVDtHB9O% 泼::KHKY?Um["LŢ4>3F";; 2kЌya;z~,FI!-"As4u Qi=2DNPwJpbUpZ(rQ 18,O깃RM=gܬw Mo/NW2Itn>L.F9Yn!}5ai]@!Pq$е\'UD) '2LW;ńuדweҀ%RexUs7%>rӮ},Q+8{ #eyTM@(ۙq^V|x{p*?2 VGv(fi8lZPheC8 oڕ)RlSRWB-7i%eK _Ugiek {=_Vã˞S?*-DS1Cj0t^:XH 8L93'zeѻlO8cm9neCʘ{ UL>6}\8 2Si刷0P{/=~L'͝^UQ*ƞ9MGތER.9`|]:Z \P~\|9Ţ G*]921L!vT)T5 w@'$0kȉ2mFy* E(93&@Qյ*Dc}H.3BS\8 Ѥk5>sHdhn1|0^9vcW)];긌q)V: wW7 @~"# o , \r 94˸Xt z#ZMS M!^KnS0eULӧc!+6dw,Z|Dz; |_838%̎QYT{%1H"Dw|OAסrEoá!̋ck.e.ra(Wj*Vtb,Þ]d7d;|JR 2\($rGy)l.su =2T861c,e^ݔho}`f #G23M=,Pl ݐd Fr.V_ڄsY3_UF{|FGVt.KBz,)GӼ;}= 7eRn Fw#?'.cn;ݼ; &4 yrKù3D'Ig7ܶZ'a 9˃Ρ܃*ĘEq4ÇWb? '|>h=&hXkQkp NcFR"p$x=)C'tBB@T2 'zʹ{ŝFW̥pDδݍJrOF۽z4G/p:_J(Q;wVG H/*]:_SOT?;+p*삪.N)!4!𿋒wY7h$Ƀ[! g*т#8kn] Blz &琉u,8sBs$9.V0'J~jv^gsr zȘq?祝/ R2.;= >a2=HD[ >i!C+.isum,y9Ⱦ)lZe#)^++6ѿrݙ t/LA?"pHC%q{3ۍm#"H-ޘ]p 3/tD?}=0;G=RpAUIk)B& ¾ H5FLC+[5w@z&ݑl|Zc$ʇ3IʳXI) 'BϩpcN"/*x8,Ye\̂Nx,L?xjh%HN]z&wtB>=ҵXn49gRni9ZtTȱڞ@y#;PtR.YV%%@ U- $KY{|mm1"p@F6Ruv| i3wKUz{"G6n%2uXC%c6YgO<)ғ%)]Fb Y%q\~qIq?[="1Yg!yDE\ŸA]< hNO/_oQDVfy`}/A}?hFUr]R O CA,Vg>+B~F⑽ρ s:\('vI~bT՟uUMU;19b="  Z n]HG"cFG\¦Q,`DHIL;) Rc2Ć9~AsN6)Z$&u|W(a#9^[dGd;o_7WW9Z^Wc놲?X*pUr5n+b2|D^W, sw;rLp9c@&4ܘ晡(d_˙E QK\,37z}\8L$սta<FIN;7TFYa!ŮO.ТBσx+Y9v%XJkVVg,Ȣk B!xwﰄOsgP fXdCD?2"ʷzc+MHe t9}p-#{R)V be(F w`Ew*3U6yؤdq´ոK$2#Etኲf!ئ$G C;:)RU6wյEuW0^@R%8~5sxQqHQ:VJU?i;\)6wiw!spƂ(xu>g /9pc 1Q'LBM`Dʰ`<0a\ E8`Lˌ,s}_HUHE9~;~Asܑ8ȁ%mZ1 ]4~6WF-jw)FUg6Z.>F&CLZy= G;OƓqg/RvYeJIeܲƱXKqk ew:e@\}/6:k6{aR(|i%[~FAϠeAQku!@}!G'!pLJ3z0"Ǹ3>͉Y .Ē K{)K}Sc{蹔÷I x)1c=2 kHgdɽϧp`unK@+;ZZ<xh. nt@*> ي0ʹe4yǔk"ITC 8 g\sR*o|ec̏sQ5QC[.TrubXZW@+쭣98^3s3K/B#Ɵ@=E]lu%εŚrx#g#訍9L`CfYWR{ԁ0V\ƙ=xRy*::g|y> r' k"gQHZ؊ƚ9igXbS <3k>-Lnjp1:bB"=3 7QE kbC&t#%\bᄑzWV>ފ @u3[ HMk AKݺk >F׈ `n[EsI! 2^jp>5Vv\[k k^'䑭x+!@:J/N |G-*Q y4 ռ[QSșY}=AJFB:mBbr7"{a%f~F!Hǀ S?,pp)eFCQ u5CV+6": 'ifx6p6\9VZ2)=[r'Ւܶ-V$pҍ]NӯwgM !VLCZц]KwOLV$bb˱*PGK5WͰPHgf7qrҢSȗ^Kp[RC\A.P95,>d?` ^0X$L!c9}/VotJ܂|Kgk< "G: # ~0Ywla+X!#б&+o9K=f! R`ls6 iF_wZSZ[\1'۲\r7ّ&`iX|I8nJˡM(hĨBTf08m%Tv.꧂; JZyP2b61W^Fo7hmGn0Щz#ܫ@b-0 G1p I9Ӆw"eԑ/ m!j-lMYAi4~}8cڶn#]7z)@dͧ=$9V/C Bj&"jhJɺkCגcΦI{]pPzTYWaWv%dvfr֒YlҞۧm _$cVkb 4dF +uR(.FL!zbΕ9ƭ='y_gbT^^EHh0ɌTAzHpyHL2ɦ0 >tp< !R(1Ϳ`6ipB4Y};E O8} c0#)~KwNT;H}6'+YjW3VᄇsU˘3 i=>Rq|^-#.uE'+xYtsPiCn5VDHBD6Lژ! Rͅko[;YcdM4=QN_&L2'Us^ [2NO kx_~Ձ9 sиht>JUFWȜ#UJ#xy,:M~1=WOboEZNb=v3, I0ðQX$GԱ}`o ၙUl(t ߌ$^g&!H|nuᄌݱn꠲2& kO4%.3&]x.j4@}usmBk]Nx$ͼ7|q>$n`-z`U=ЏrVn\Hl)g}WnޑhEpQ))tߛNFpdD9@EL# Ɨp"Y ^sռ*IuE}QٛhC+@W,'jB'aQ΍aQ[$sRnlXĒhèH~$ű,3VU\a4Zt ;1*J}U6pTXFY ɂ[3 Z'[\b(׎c'tq?&VR}$6mZYܰOC!fMӯư7ꝼt;$x)AvJxFMǢ$^"Y-wlp_!;/`a|\cпC߀$H ,>?Bs,aJ=qӵ截#Vv<6=$VƊ6+EmMC-o\UWoT))90b(,y,f3bVG)2*"*:GsaRBdvP%Wv)X] D}u*Wdg1@Ye;1j@Ta@56E~>G:'K4. (\Wz&[j?e޹1(^_^l '!!Hhb673y./AHMO)?kY$st.cZL"BLpKRGH$jd vk\ݿ)`D[\ҫ\23Y[:~"Nu`[P"&O CWD}oY$a)bŊ1s>'EJ6%_"t- $bϸ؀ 7uIf [xPt`cQDX2#o0L (kQ4H4VWs".pm/a4;K7 q4U>ݎRГ  t3u;mi\9Z"` ouZuHc],d&w M7ʸ9Lh5y"`8QK7s^qvB*4m-`_1_n7]#l-z3|'4쮅g"F?b(aPዌ<8rl}u:QQ; Vr\\#\97,p4@ih-rӞ :da) ؀b+tm?OX Z ʁIhUJihN7%qNji7W1e794c⫿2M+ 9gXlQ@)R=C#{@ni |XnևTjC>khw)Z'^=#l|*'.%$|' 7.}`s76k9j[+bs5eBT.8/]*ePAэs(F88 =;mGvNӟiv#.s5r&%G&\kpIR"T Eطù8x[=;$ߜ|[gώPszSzdϗ__jC1ՇK5w__PɂPf[l履l՚jf_\qQK ލ^65eKx879ac 7lbD/gC~2y [Ι@*c{+qtKO0!49g*B#_ q;`sJzeV\W;yQFQʩ ݳs o=rsp^zjZ -4Gp h#Ac~?=V u䣢A 5lʋ=->ٛe`,6qco@F-]nG@N`g_vHѠ wծ :G*nhE(/>B.)!CiM Spv ھ=/mL~!#{:!O!mZЀd|arWf_}\]8Ќ<탹4ì0 OC4m }VeƂ0юۆ<  鏮Ӻ{nl2G/MW}Vʔ^e2Ek[*E 9$ï{>8 JWXy9N[k. (ùַ y"H-X-DW۴i;S͠q1d(>(4˘qFBL+j9N!;R IDz!F∺1' m訃l>,\Oy49p[ =q3gΊMA9>R|/lH!=ZDaD)J{g76Wf!pj^t  IHO4etO:E5 42<¤Rg4:T8#MFB{ ^uhśOg}rcXqʃ I:-s-d`s6t(DC`NV']/ Yd~kL:usr)9 $)Hl<{ٙm2φ 3hc([}'@p3̞̃&OC\nc|\7!C SZEED4(^0}ռܤW'P9?"[ͼalSҸ'cd>YoG_(m]ދ_ ,-)'0@  :"_U[nvkuYH%7*D2y!6' d>}F`#}͉l qCW(MA8vY ; Vս)` OɁȬ1Gߎmf~+ . -x;]"Ƽ`b P7I%i9jAAr-tU=@Dr4}k ;{Ь,DN9OQ3* óϛ;M,˴WJC.2ֺp}!qur>1ڝ!'f!7fr&xKʰǎ'Y(5>6 YzG&˥RSp4h_5r9#}M)B3a6(H׿J }@\m+n[I T;R?/M}l~Ѡ/@4FJ'~c  [>+^|Zyq&G-՜Zn,Pא_IW/bFGO!TiL'6P:`p 趎F]>5XorT9DXFDP9€`; ,=OѮ[h׿kT7>vvRJp=QtCP֮3^bR &kvָ5#^l:R0h ؋TT\9_z-:QiL*]po3Xq2: ך(/,3QFe E "{q_idnH)ܱEW!ۦ1/qiX&o}P٭}KD)<h͓Q{ؒߥ / RFZHRJ 9jfe[LBԨ5e_$}̕g=S:A̋;:~ť]`W1сsM m7{gOGu"Ǯx%Ae<1&zΕ( +@*VVNhqŖLk5v9+_%s3#j7ΙӜ,j]8rskZ3ג}ճv*Yqdʃ:s lҥAZ>uTQ#%uCv0y$b *?=P=ʵ O :#ȆdpŹnٸ2K"|ᅧpt͝*̎, JX9fZ%<+,I*K|jRB. 7ܽ"ߔUMT@Eޠ L!R_#dF"HX}L|ΥwTEg3c\1'ǵJ;ҒmV7;^VYovA{?`wO|U% TT$Rtw:ţzKr{ӎ 

&-U]6Չai[r>T(9 G3Am o*_7#0M],dhKM$j=ֶ 8{}9#6F4U/CԝJ &/O/47~P$GQ -\0F,X˥3d%Apb,9xGWX~FYx]19hy8q2l[JŐF0cz|J~c-D:d+|ՐH,]qnfN& 7 'Cvr] C^ Y6ml58Z(>NYE 1-T+*_-BġL{2#1?Ųi.Z5 ZLhEJSHi~+_5ѿK#+ &xwO 3qxj9oW\H%S1.ϖG%* b "â 8Cd|ǯY2ЦRI icBs9n c{iQoդZhŘo.\3(' >429!LSneca.HY260 7Kubh) Lg'[%n*Q1;|UG41'~c.UTksA3%:*׈-a:w:rqhB"M Ic 5u|G9"[R|5f:S"C|ɷc#D]JaP7-z'QtmՑ8ƇLI0A*#[W*_ UlZ]6)(96jr7_C\ev dlO4X^Q:S!l1O3&iwr]`忚D<#UwOJM15:´ ڹ\V_qt:5w08|,' UH6'*;map&Amyt? oiJ'`5=Ci׬;ϼ{Z`od#t/'uDnҠ鶑0+@)̆͠ Ŕ` O_a+zh@O(I!ޛwY׉'8[DDU~Nı=ffkkX=g1cN`%kQ;C k0t+@k0''8kcƱ4+f76$䤪8WQ,H5j.M])0`G@qM:?L(%H0D6 W>š'n=q ~iTg>WNIפvT[w4"*=? m;cP&~360Td${"6ċ$qJ%x!+^g}tM6ί? /io{,8[x? |:ٶL8X4݌6lV8ĺ3)|p&|ٹ.|;iVMw{<6};1mQF|9uщ%\ Hb͍(djv.[3]G%aX9UK+G>lwfwiK݃Ƃ  eF 9εŁw -{4yM^.Uc:-o$UN!ܭ/6 \=I{ί az7d{TO~a&.B/uNm] h4)ih`+ |7 y@,& 3u:[MiZ\RozΉAyV돸) ~R#OULsδIͻ*^^! d)  s泷ɆD䳜3(bzP-rAVl ؈ +w@ki k'=͞r]{K>mu'RPg\ &$J43\4ԅݜ $"Ir-uBH|X%) PR5럷KXxc& Ṷ. V<kPxW^,*C=+fS~ IUa Qrdv4v#U[rމ%7~F-_R6)jSA6ݐhlv˜hW.D56dyhi@GKKIMqXcKZD  1[S$S\fo,y4]C^}* m, 8ff}$nLWG%M5/B7SKuH5N(6:s)W9َ:Ga8 *Z*5n@LTrkӎȰH4% 䥊{谥9 $=rX1:L'b2V(PzuUz5 p! КdO] ęaATͳklYxZ-Uƭe0>gOUq hQKکYQk#MLPY gۻuק'e0PdaW<-f{7LJJYīrېTw/۶~NZEĀEFhIrl"5j̣I w,>T!ɂVC9G.zH,5#Վs3#Bܨ%Gb"7NfEdɟ^!>M㿪fTU! g=a_Ѡ--e| +UiBFAiN*Ivą>|ƠRfdn1tsҁb!Xe`^*ˎz?Q@ԚVn$QQ5ebki2-QG-'1\綬< dm e7"Ԏܐ{b釽kvM%ztBQ0׺?(0s_:h0aB$ZyFw`Lk%g4+Y5tSMHG F>֓m-zjE8gCi|\uŚi^̾|I%V\KM»çk)١' A I}aެ:c?Ŀuzm9FgLDDvimG'O#Fdq9Me$˅Z~k9 KMB&s +QJtC"wi%9ѭĖHl2_^\o<Ӽ 1D$̕.V apD,Ὄswv;{[)V=}a{e\}Wc@u#{rA %d:.t*5j ZiI &߷ā5 @ӗeANMxʒ%Ccd>L|Дn?P!gP]h~.XNEq=LI#EOB&SJ'=.Iώ d 4DIhwզieCcAos6ҟzU  2r}gMK G7f#wƬ)tħIq*m9Qe5J7?\Gqru8oבS'Y>+R[-XXnAOIt%AA"=Q] ;&+$WagD ;Pv- h)3R:ȹ:rfO}P/wkb*'tިT_dTڸn?V1T>R(osteTzǩ`߻+U ˔e>Sgg[D'U r`Ma'Sp ګQD=Eqmy6t-@8F?Anᗨ%t &.,at\qpB]+^DE>@FijZF_t׭b $X/ )E%>@}ѹWd@H:| e< SNԎ76Rpi^rK;[#U÷`}A)/"bhĐRTυK悡ErS.=B323eeڑ澠6=ӓg[[Ra 'Y nqŠM`U& [[D`)o,ѽ$O#JO_[^ӆ3xFql<[ YˮPtN1͍mZ-Q5NW oukDSosܓMt qHr!yDZ.DS^̩H(kI-Xܰ()s烶^vORS*ww|7e]f-oC3ǤU0?,dߵ['ӆNo MV߬X56^ m;plΰF?y Hu܏r9Iҳ8ޏX ?yGK|T@-{hҋ C/c,d}"L9aI Fq*@{=[cN?FI45w[h{&r(2'J # R>Ha*5iFa v΂F^J0P3?4꒏RI|,#seFdL:DRi㱔@BRf }T`#)pl y!$"@;j^/YtHjN͛]`(Tdg8Z>N/$Xps%mKo+JR9dc]ZGDK=P7՜f= 4[oYTG6Ñ^aj nw`M"o9ՔEsOQ:4i}:r0W8~Rz.鸟kC僷& ,{!%!XUݏx:= N{)-6-ߜ9h41AxufeeXs A< ac@ɲF G\ UT0Ʉ=IYeh?6<1ߟsu=5姫;*@]Z,4L3Im ȧ`jj7|:* #%/&hݣ5])ذ`El) 4peO 5 ЋTЯ'pMS\u1!ZMKx)%0s8]85(@(vDw8ƚ񙖝 `\IJg=hoxS+$#D4Z8>uՌPdťiciȷFΣc볳t"/8RQLTBA~>Z:;vt,qj!%\RÎLZ жˈs E 5×eq5 j}1qn]Ex̜\tm`A 1m|sM tg5ĥU*>2@! 䖅V-v(%t4iu2A֥_-/ZWStFh,Z-c<\ofšܡ@9Q ihg.79paޣIT2<g}@,n60 e sh. d,>Awf. \§Xpt䅷<#(UT^;\/Űt8 }?[HE"r0#JߢN2$;j2xOm+5.j)*M޿D`yS|3,H`(Q7ɨG6O~;M"_llY'WF2B bo S%Oe1"wzO+Rd 5c6m{g=,Grt `CiTڪ#A /lAjK&) t{ oO [U)O볢C3{OR&ɈjEA+II< 6T Ww \P4z@ ɠˇfuqV3JfUIaC`eq,d>e-&ںuO ~;0q\7@"qHr٤}x/^^І)p˪l@=l`oKw挈gptXo^?pߖAt ܨƎie!ہhE5Qd">) +D "eV e4Hߞ.{xך.'DkW_i8ʌ $}JVC'#vSH9o6R}#*pb + 'mg2-1sv|"7 @1#Zh#K`LXZ yկ>1tBvߥ]ҍ&@V:L \sF܈Ē%neQ' MrmԳq|E Dg\Rk6/Vw"ih o9g3y#'Wj>36 # q& rLFNz}KohY6ߨ\htNneB!h(U&S b+%=<8jYHJV cA AWFyk"S+z6$ )ԹcsYD$aasl+a39K afa09l z?sۯcPXטK^I$r3lͲ56舫Bmnr-C8" 2TJG.lOK 5ڦks杒B(kqCU2Lߘo"% b9l| @b0l'lt(:0k"N[ mךqc$EژuX *\D{3]AɊmdH הYgUs…1? B bw]f 'ώROH >{O>HV@YD YKAqrĬme^W]WL[.OmLqmj5,Fx-0MD~`AdǏ ('' W|FO ]e[Q3l Jcg!qkkR >6סּD>=U:S,Sެr"fv1%}MR(d/賂^VzΆj ԾT eI9YZ 4t+ݕlG `ʏZLqNB\h]L^K'DSBW+b}Z=?]G iye,bƛE"/q);؋RX=Wa\bF5̓xi`UEg\;'_ `+ߞ@ 2`%6Sd3cUu 0kȻ9ܶy F}j >6"282Yc ^ *PdXc*oiB%*,D5Cų.=J).3~Uw<;sP"]P%ץ<ӝNegUt=5Nb5S# k{*_BE}A_mG!4kMqf{1*$YMlqr#ڸG20z61 S<-Ido͌d>;|lh#6,铽`!òvgQ NA7]mյߩOPcı+ĎI~M&Km !nYO!'lrE$m͊s@5?h;TH]Go>,0'H6@0΁,lV Y !{ Bu'GJY,eh|jK*.U١Ъp;~3A~tp?p ~w8!#pQh ,Qw\0n̲" X]NʶƑLm[v`]!ג;8ZyӶ_ҽ囩kg;C |#ZVː֢}\:Nzճ[.,0E^~,Kh}YRW4S}|rč rM/%5}{4n+x*D=/ŝa2$s:sHӎ1G@('21%E{MnnUGdgu;RX&f$eni/F%ҍCi h/4AfE#qSrVDO$Lk>~,k{We2Յ5) g&(7 VCj7$1r/0D/k=zخȒo؇gz@FŮ;8hukT ("q𥮉P" 3VdXn"-6!wa˚RWv./3{Ճ|+ =.~iT2zQ@ Y<1i`_Q^C5zúJ->g5t[TK2%]ىQzÒ5<´]-n8e٨Bnw USEewT3x&p )p-qw«9,b]G>`y(t?jP9eyt@z9*U|J|IDM[s+NGuP[p9Pw7̮Onu~,xkzT*-`ĕ W'7qsIc-?!(&:'DE&51y5]H0 XeM[S:6 7Y,:JfR D^ViT*W$TI̵`8ehR&Q`@jl#LVD{AVE|NfP`e^6Ir Ybw?̋Wzg٫zK pLZtؘ2E{+tc0&Ia~Z[Ç>{/mv_DZe/\Щ;|mdXs,F3q]1GeFe> sЯwՆ4?4LҶ7c6Bl_zlM_ Z x: ~DGB%pM(zcm#.Beeak1cuXУVY^!#L4(3pI ׫? | .׵ODFBX"IGȲzCf)|Yʶ'.ME9?6 _`g5r!4ԍDNǕ61.q >~|-olsbj~0o}B%1 mBv Cwt,$HuڎoeԃFy y̸Sb~F9K[V#SfYL1D[tI~Z^R|B-8@7Diqccn+ʴMA`#JՈ=c@ 5ZTl9 tr׌M)7Ŵ܆$sQ;N'rU(-3# u&~-HQ \nwufX 2$5!ȚhX 9]PԱVbw Y`cS]1 k|Oo_z0i[)) B0y#yU;%N ,h9"%o? )/nevԪh29QE҇IS^n#g );λL5 <Ֆn+s{2L|:GͶ^@&wG3SJEAc&[LY0V?"Ӷo8Sr%M{ J5TƩ´1 }3L&o31ow)$4ț{" Pp4|1Q$hBh"p+"VhMuɟpC}o a~n;g_'23P :-*98=d;~}1bAZK:owMʯQl`gzCEv {F&!jCVVSx$:z}F: ˘Ԕ-)3Ooh}=pu;K~C}Q'߲C\X&aM+Њͧp?mclE٧(J<%Mi$HwW 2%s1vqsфtU4`͖9A{#OZb8pE_/G`enx09@_٥Ygr _$).C&$'jw%3GE1~ZmQXVw@l&tH;]@I' a mS D ;+/תԯj\*B=&y@ #۰ H/ FSJ oMUk4RɽX^Y rԬ)RQ 7G+{_{A/xo]j BbUΌ #,6,EâogU+2P诘|yHȈ#W+[Q||(y5B )46Eяa]岁r *G9MpXI !d }ׅ#/yr5v^^% 6{H{M$s~/RqZY"H:aq7LB{C rۤYDPůOECWI5(V\ U̙R$,> AՈQa'RLFg1t]eLKwM;6?\*Ae̠[xYoEmq3'Uτv෦; cAŌ$~ǭPKH7^WD!c'lb(o9%qV=aŵz%= C|o>P`,+gu ނkz*p+ Ap J hTPoY#coq!+ۻpC[OƝrY;CDzRdʛ`'ţm'T@,x-> \8}*5B飮nEEhL|Pk E1ű Atݍ 99jksrh$W]ZV f"+laOla"M; )hqq׊jiNS{"TEK UICf"P-A6 Q悔:\Yofw}&A֥ٖʐEd[ex!\ n*-sX^$?e- AgZTKg!NDfwE;UZPf6F"T]:ڡR{W#R1"xBq[0pFmiM6jU*BS-ً;a00OΜ;Uxv44Fx-,"@kοՈVP/Fv8#ϻСʲKzۈHD̏.pqrSb}hL.K\Y4sD>/-OpGbTw#R63=ߩ[ۃW$㊎S]7hS֗AI $z:ЦD 쫈uj3K_d sVOY?H+*+x_mDkv[eclq@$Q@On0|C?.TY% \4v!Y8$kR]Jֈ,tcbbrNt?P=!Gb#Dblۅ2}oqS'-ָMBƨTiGn<ԅkt U&0sD~.?d& 8l"A8y(whxci0<^kִ&Ԩ";;A5)_+_/̜"u2/Qqpf.no T87%~ 2a[\FMås9׉?aƵfvG] F n(uhD4Zj7+ 0=#Yr#beQZƎqY _d>/GIM zOr4cx I7T7StSRx5CeL(i>5=B9te6#.db?f}@=ϠBK݇@Oj_! ݃c )leխ}?:*Rei|Lo=Z.f__aX\2_ P>ygحUd/C-R0 1s;gFϙgQH찟- SOzM+_>b3O4FyGc'Ͽx7q&'o_ga&ueí\Uh ᗷhbV7=*1x'AWأƒж;Cӗ?TOkqnje%[2oMr2[OO: `Y_pk%q :EZ5F6Pdǵ!iA 0u5#@5;V @Iw|^~H*l (o7#bӎ|9\nysF#Q'\_7]aOH_BCZ42!h+|TDW~p*N~`r̹7ߕU*S֟*pp,dE!3U9& 1LF-zh" R 84,3UC'Jڌ\GMU{4dHf \A"*2ރ[(;!!F&~sT!.&f'V$)]K(u_Uy\#ֻ W69z[fdD A~Ro$х/P Aȏ6KݢSn#U Xw'Mu陿G]WّQT֑:_7e. (6- *.oE ̩ZKϾ۵Ȗ0y QS ';ac`iumow/qގʮtY@9^!PɋZ"XhK=:M$'8+Y 3&]hpHm'3-KCwe'C\ h3\GxU\< O*DP `W"(ol̊z8vM&0*Oŏ wJ,i% j\bmǾ ôw`-J3Bٽϧz3%ShZG}eO ؾ8291uZy7i* ؖ&i bNUu%.\/V\\匼3^NZh zR(J6=yvۯxb-x)W%ةr7:r)!_찬8FgϠhg%A^Ea5-]P@[>$(;;U =Ezj`2؁M}Hf\ry^F ÖݚL!E&0lC`IaK{!=;$xx7%Ug#厲d$.cw+ :ӧCV5 piے<>ca@ OwF2flE>ABR갔%DLo 7N2ʔZմ4`?E^ل}Y^g~Wq"7%`Ca)8>.NK3}"cM+ےCo9)V: sx-CZy;4IdQ* 5y 4HQfSiV)+ބ2qU|[z '~mNb=lԚ=M,enwUZКm˭!:۸)h%3_vA/e\ڪPO֔[Zy\ENP5z N]Bia+dh j8[ɹHn=v9Է}W+jL1g9v5Gy/1IUn=m}n/J|V%K'S_mg2jy]撎ħ{*Er}خtCFʕwv0 '"٥G|{6ƚJ^b1d( ًeu:iHdMSyO/-Y)RNjg|蓽F|?1p͈ʴO-XD,|i쏢H\(aL6s(I:FH'΃- V U u}ΰ:DK;}i0T37$#yD^Ơ'ڐHI(JzTu'p="n–7 v4 ]5J7+LPC5ΐ2htt ſ܂C4Zȫ?f?yl<(AH?MO6G?*3mJMkj*C9`eQb|9uQ!p铲[)/L6|sW?9 ]`D (wAlፊﭽ6Xn }V[`@!=_X`߅NͶtȚ| UAvhM$ 4vJ\-Rf2Y53l'h~itDxb?v ` Mq_ET6{Y[{©CSjuӤ 4>D9±iT $(ʁ)#nJHwživ[oie?Ā#rpuE0>ĄS$O[ ?Fxb85x#KO8+ lFbQdWs+R7Ov_8<9m٪1ڱ[]ϻ11J# 'yovAsoMaQ9o}`䇹h1CA%𓒨-9Ǭ-1)/?DGc~a#$Ef{U~AfӀW~8}N=$U|{h 0V00@]Ie_-E,:^%bTc=+ۭ*J}V^E*5d%_1w/KtPɆf_(.& *\dV@ wt+9=o-qX㍜Sҳf'Rp[[TULF,BNly tP7 eGVKw%nVF\lɬ F%hB'hTЃ61ۃPtH=U%WÙ-ʞEfZ\Ҋ4+i Tc:#y~ }WelKxCHG #~W޵ض5!oZgt-w@g3j?|,* FIԧ2>:Kzj;ˑS(U ~O{b]5-K]p![k`N`of ۑ_2E{z`O˜ T!7YLG@, ŗ8Оq ֻRr;,s E^KỰA>9!8D4RӶ\B=r~GcUި!}w9+&j|tU)zT+1\rtEQ}հv!tC$'}#*-YᮐLyOS"+ _HiG.W[sH}K]vs$alm&dzF|D{~A]$5LnfvSo*=^N,Dy |^?6nϭ@w3rNĥ{]Fit?`Lr#%'EB{g2?s7gUlCC,@0hW]сN͛d/D*_%% A;(#H.*r?cCLD U^&bI/ lq(~] y`8d epA2 %;<98h,])3l-hm}ܾÈekY 62cj`n|?m0}s:]!CVe< ter_+}p_ ĸq~G`UU/+NN}-f#ε| 詒Ѭ5AM\E$G\ mR7ç!x`!VxC1hO 8nI ?9U[ۣB*]_j~R|AUyWD8>oKDQu֩1\= BGvz6l=ȯL+zD 4uY>Q3矍qŽ #YTMrrvZp0Y)̊-2iO R?_}-2zlka #PBn'qf_#l֢9D}W~7#.Vns1FYok'87V!2 /̄ݜ]oVh)!EQ|(w/Mɦ~?ݢFHk1ǮPjY%cS eAyf)}C=3էZ[?"o]Ua8k$i5iVl~E9lI̐"<9\jᗀ:WnY-POj[X#W TK\L ǽH9(i;ߔ9u ` s$I(' D]baLίяqmAZ7 |^OPOC?ԡZx*"Ff|&0bUTKɗ&k1`cѴ8ۊd!ewҰPYٖC]_B27qʗZ[:*gk{[Ґ\}279x-Nx\j^Z6}2*5}\nBК yD*ZkLa\5vH4 &@ʸb#~#$LiEQ멗?k6ݘGkھDXs`*&.jP9A~^=4_ Ѱ\-T!>R7~`SFָD,zUk7ހ%)YA2͓lJϻҮ4T'3ׯ~4+I%%Pѳac3px/ )YTouYu\ݨve9n*RI^IB-/ 7/G#ᾗ៍1_O^]] 1L2tAFdk"(.rZy?NBѾx V΀C+y-R22O2][NuGnx 6ae#29M!ep7 6,\%t%AjMF&1 G{ Lw.P{+JTiш"d18,O? ,b@6e&"YvwCw)rӫ$rӳH`7N8PL&3 0[j-鳌[LV^U-K@sk}X+c~vV*u fWfM)ǩE7y{wuZ'hl?wqr$Qyҹ\|[_oi@$2hS/N.-|ӿydg&UnnaL H@|EJQn9ďBHk72Π1 υ ͱZidNRvq})zuBv|Bm_UGvHm"t/SRog23cU*~ ."I[KGxSX_>ES =qcOv)ySkfz6ݓ"-)͌ @g5=e'7ެdeqo>fy_.B~ɦAi fq?^@րg,R=~Z? `173j E$Z")ݑol돋me _,k7R$ґZ݊n2i;#fiWBK 30[i|EI \tZ+DG> L.eKd2IÍ?ayCdHf'nXV8lF-my P |0& $Nᔗ)ހPs˘뼦8^ ;pS8^2%yUJoAvx$K#.?E7])J^ Ώt/ Wˈl'F\w,ߙ7C df0|[>Ԛ#6x͛''nw V㽸+ز2r"-~#2G2̍:mXx{_q0><]G/# .4ˍ@c[趌V4&%U1oZ״e_g0yQ|5%rꫵN߇lC3s粫$U>J鬺Sҳqy{-Xa4Ul/rlKAb JX%u NA\ {s0OӌeD||I:쾦|£gzX&fA~/2} \%fu>&F]Kc_x$Q7gU!hU`ׇ>q')13ZJ'ɩD9I,YT[ zѣq!ѯN.`;VX h+tIߟwo q:LG 2G;=pQ>3bh녭у[]_2KR#0^uFl}^:OӫR5^f3oO뿆I|,feѹ7'"w>$dKt3w>t{ XUAT n2P^)8OJB9izmG26oi"|P&e!YNSUxdx1$ bm  wlb_y؞ilFOT#svլW9C x2w]W ORb` :S%T"#aCi4%INE2ϱ&5g,ߩ< _wL:j3&0_ 9v\i5cbYĻ(ڦ&DYW+ht4;x %. C(AUr;>hJEq,jGn)< Vfe*q' or XA qO 9 [h#Dd@'X(|s0au05ݾR4Ay$&e:NST M\Lu7rz P*%NuW'DX́I=cYdž Ql,5Pf ņB@u ~AIJQ pzN1gS3MNN?~8p=Vyf,] ZRxTJT&Ɛ rؐTؾf[ܰ$ p0Vh7h]Wx*F](uX-1i^yp Sq" N,97xt[[lqg~V7ANɕZI%5…ӰU]t7/\ os| Wz"#bmmn i]2,&4UX;ʬ™R\lŶ ;[Xth>ouAL͑1pK$՗T36'j4nIOWp`s 9$qZsS|GF1X/ {p7c:nC9w< 6vFwaC7W5e|'8q` IG/:uM=КL|~0pW.I{)vt[}3/tƥ"_/̧axKͳE$h^)051Nf/(+МXبb%V@g &uh@t?ٝ~dEw u$BA_ϕ圄@f 6h+n.,iz>)ZwO ;U @BK\ w+=قDS u$dF ľi|5TR@'xT2oL3JZ&N $~gSz>OxZ4knSmnulj8c }^[nI&e~\JNAkIsE:Pv m\~Rbh𾓹w6DiQ_Uo{es#E)%g܀ˁFQwb-:ĵX!;^_a?Կ6'`P7SYJG1%8 ysĩ?܌CF#PCMyE5iيp.=0w(Q#Q9Oˬ[ 榦HQܐ.p/u RM&/dN2*K{?I (%<;NkB !1H]ȗ$}lrf2E: ;GqY9QyE2 S) HM.?Q*15Ɣ2!@Dv:Ix*,BNUag Nj &/<&` Z[kV ^b=]ھ:CpuN]b8 ?}.R뎷Vx ?-n&c9YK [4r{=rUd5^\ #p ,߲q{~Oqߖ@F,)@=[7yYf/!Q{{­qfE" -$<;45DFwL AeݺMOZٸ 7wf19%GoeZ4E785'98v:jņ~+ӽ٫H> {֔'ZQM Э׬")<\g5Y}Zn#BjX6+s<ԕ[4M4sw0(΍il XV"/wrV]M)vӘpdqsFK8t=>3DHqNc# K@m%x+ܫqr  VvT@){ִV`J>H%Rኜ|MÚ ߍCmrVZRg[WtºZ2^D>f[)I'sDT*l~-`aėv e@ŻAPYKK񠏼˝t,; >\`hL'cGwd6U?ȉB zbf._e%4]V1Oz54XjI}>3_,b]ڠ4-oD5$\IX7_;t\.;7W1Y @?oT:$hͱ GȐ>)M|r/W"W; yy~ey#6^kX d 6p8 i8y&daOԶhn[#0rrvY_57duO˜')y< zMd;Zp3pQ'/+50#{=ɓ /0e;SjP 0@';.ՔHZxfz"[xdp|*m Q9~tX\%67\!QlNzˌM^h> 6p ,ɗu7 ܾenuJDb|?S>`QΒ@2]kG+Dݙ-EKd)B:Gdo yrC_oCLqrtU[BT"ڕp6r9vHakxI~WLc)OGPGd4衻\-8/!4L_&WVZ9Z&Dj "ò3 o|OQ36?A-8fSU&Y0)$Q/GO){RJ%Y FG:\lhTW#cfʍ/1Ê7H?` n/!S/mJS\ `טf|=LlB= t]B- ,)vlkMUǗ~ eM?CR4 6,O1\w'Y@r|#]kN}]߆yq綁8jI)Ւ5ISZ0}TtЍJǕ-F Vz?} SעHE b4N$b/yPeB-v08L5t`ȮLheWct+s,iPJ[j-tKyre`PLόdg{,1 =)d;<|U֧o& %Kgޡ@K 4 t[P >D˃e/o@Ztػ/ ɱEf` HbrlW'Nx*m⢷zv#:m)U4HJEX07+u!ψd ߺFwfd8[b/wy@ ʍqŠtA`HTld(8 ki!ot?r 4?զe>ԾbT=R:7L\4 0]1=c?XQYէD<@&"sY^ޅ;{|^LVx@Cuq{G Ef|B2U/( 5!h]!y*]1Cb䬧&Vb-fzd2.N`PAsl1O[GG-z LD\l {.[E"LW a@K.q@Ã6t:w)n[o\ZFXɩPn( JcB:Êǯh}jhn8=2WHYZa"Cn0EؗtuW Zqex&Q|2db.ahXm}턘x\=jEԥ8.#V|0(G!ʆkKEKǎ9+nVm, 愯fu%y|veW^4ڬԁ<*ǵ @OKx9Yۨy㰉`]t5]{qa𬞾C;f*$ |v`/M=gA3NvnbK=xυ'rݍi“d7caaKy\=U++DmALv86Koɖ0Ť\!5E~繨[*avHWbE:\q0`v'龍Š{a{w쬜O6XXX_@lzydM-3JRM,@?۵ !~X΁Sos Þ+ g}'! uurm]B/>  {2_&]{KtoџH[^ZTBb 2,I14Kѻ<섏cr^"B&V|Nf)[ z~5}3#٭@;ėDʇ9+p9/>k eag-ܝ$$59x ?~]x ˤo.pS/kIڟuYsx=]w޸a7֧P|_*2FQt#(Hי XA,n.Az+SX 9 yC4S  \ℷ&>VC@,|վ ig}Ū3nXs7rZZnsetu`5V$\RcejdJ ^(U*UFlyvC_R+-tUs:m4YMJ=[M۝q캁|ET(wuAr:_>I%#va缜=LsF9lQ^O>|P![ KiJk ]Sb%g;@vAQvC`7Aٺ;RE02XAP:;+}l| 7:<Nub6rY^n͉[azřct;o=g(O܋ [!4!nA27-xYG6fViO^Nz"|u ݢ9Bx-PyGn;KRz$XY|18/v>e% (׫cK:' eɃНK܏dj&(9 +(>{7iBUPߛccЬ lO?aqNϮ W\+ZgVf09_P;JAYG! ]z8Z+ohJ 8oQU_zz'ʹW ˭ELUJ`UQ % jU?*̩pQuD[ˌq:1An_x^LS3JVxKǺűe۫*a#wC3+f)k&~X.#+n˶/|I0mԖYG8ΉZi'1۳/]bY)en,*(ÃC4$nQ6:P \y٢g!)xQUo\5WUX?9H~*:ViAcv%E3)C9bMgW]*K pZC Kg_s9*==NUT:r{í xŜ 5f.yLlW)HIE@2ay-ڎ8il !MK)V})@ (fê3G=i>?sJ9[.oEi$Z¿dmiB;VKW%PRDŗȴŹ5k8^ʏ$H(ՑithU"X4v#i&jۇ_34J^wq!7~j6ΡT$z% 1*<_ H ڥ#(%veRBY:sA6^M[?Zjhf}?(SN23fYi!˿}vʼn/0C4 e iLo׸ଵG U#,J7zV]7 U'xGmG&=[CX-2S?+h:!5np2.{M{MmR,Pg,!>S.`%i/[Sd35#y1f{أ>MJUXz+D ج2PuX5qUDc VJ\X2ˠ_% X)S-1*R)k}fs x3䶹mNZ䮞EƝAJ"뵒7#oZxÕPvD mkT };Mrag`Or2 ɋX4%tNcjE!,cSgl?oz$6 Ꝅ.@If.P?~M> }p K6>PѨAY36-}?a+! %V8AT,-!ɮ)= 3nte-@"LQ]Lq @ţSE5='хf=E |3J f.A0# x6b5:x2narDn,Prk7`M; 3RBo4h}^F-\3c_ P^圸kӭa Rz+9yuY-*8\Tb{6vSs8;aB':n8 }ヲm:{>Og(wpDFy/e/A\&*\Xx\O"+~dG_FqZh|DZ3PW˲Ҵ0(dLpqlY&%?Vqg_=|ń߰POWԕVVgV+0U-Mk?dVM O0o "D:φ{>xkd+GJN$V"7$P3UGoXk&½>DODhSrҮltB%ݣtE ".;`Iw}[7:c"27fB8>YVq71{@7Z6MgJ;zѓf/'6L1Qm"RrFvB%ѭco28Z\W^E!Ofelr;ۼɌCv=),hurp@imңwkEC؇ )ya `,~"BH1b,Hn5АL{X.,cl(\hFN5$PUeָ{zӜD%?ъz@H: 'R]<ڙc3D﷿s&kj)cIB34ɖSi'("ˍ bͯ/(|/Uu)#AaэVQѹ=@q 4jFfEt]rcv  YΚ|GGkn! &S|luxII6C2lREsO%[{q3 KY| WR/-U[^K!:m " /ܽ>0#,0^H-c, l hia"1kz oK2rN "DPS:91q%1Jv wf]8:~PyN[EHd6|jjA⫾@&l5'$ pHgA~n`qDsSi&s̝6Er4bŶ[AgLf.~%RWc loCu?{;Tu12Tnv\J;;\a}`7C,tS 45`Vw=)F8.7Vw+5}KY4j;KY`HbK9z7(YQKa"f M_f1UL~?a82N լVRm31ʨMw&s.UIhRuޓEsQNO\FvTaj7ǡWs;~H7xGAIɳG`" N0\ m*s Yb2I I‘ 5'1-l'PX;464?j q +hc@O:;6O o>[{6 ^K̴pvW xO>תo<@} sC){:Ax'tsvuNIv3*oB/}2dńk-$%PJ03Jd漾a:iBW/d7FZ/ʀLi)2y}S8uꉐ9#%2kȻϤ0D/Dћ9Qj<ͦ^vPn :2po\d VDˋR4Q+҅&1./|<ڝ7j<5ZWh#Zc=_i%`̻fx Xo4Nt-v;G}6ubqG:dϥU}ĘBUAp&\JHm\q]5Hb#fyi7;qוlR肐u(5N## m%F SČ\ cj(wԗ҃бX9}$[2:GΟn^; 7U7;P4G`ftfmU9WIPNN|ʴ2gb?V(q F"ĄWjӟ/&jxo<[tX_܏^!/!8*a'$Ҹ'2cKrVf WKi1w7dmsnfKo[*?4}H*O8|EqnI9qo`?ʤ*=d诩aTb rڌ ܞC7G p5"8t:(nm)HW\6E"Zg50Ne"?. e)H:mkv R,eL`5̽lnO *..컓OXq`A~N(Us#.'C0͌730гoG!;g|h_R~h'i6>u-i+W.3pZo#n Er sƇU}҈?P_|ڶ9T1ǽ b~):J;A7ueH]"?xETÂ7Biʩq%˻JR\)=) ݲgsrF6-CD 6rUٝB,Ce4r`I,O|5C2F}xO (HZ.Q(3gHϽl_V/6ѫ0foAA,)巴#zأKp2j祑nLCǔ&e_fIWee>s8ܳQ`&D`u\"-ߌN` !G<)cysK[]H@V%UMfސۂ@ XUM[loiFmw&y]rпJF M3Zb8BF%N1 5 FnME/d3s9۬@nۧs*RC( U]3bj51 D?jyI35z&4.+$ܞsӟj߭IuDQ3҄QͤA][l8Pε2D[鯆ݹfL3YnS*4q)c 1% "aMev+ 5.Ug{m:񏫄"^.0t[ۜ,+c `|+#=ܡju+hI"Z?P/K oރ h2R;x5nPO}pY xF1)K,_1rE ]9xCS3 @<d0(,^mSddBo͓_WrI |9l'JSkO`D)o@Jqk|Q. *_d%!F}0LSPMK  ;/@I]w댅>0&K׮Ilܪj*pF3M}ЋPE'$2 R޷2F;~'¡Q!Hd oǁ?X¯GnFSM'֋tw"A]]0H}wXI(FFU˻J̬wήA DgM Xw"\3(R3Ⱦo(ȧAT\<|&f1#c "՛  hTEY33!;uiD{kJ2X $aԇ|!(^iz1ҩMiỺA⊡Wy/ NICEiĐ8]jvUF1Y bS#$D8QtypW5E'ª"sYџDy? sByȭR3Fʿ{l_qdnϩj2oڜIR+f  Kaˍ?G͌]HZudzUV h*E';U~O+e76ڄLb xB#$K+QoϜ,a)29]hi5z\6?fH2cs;VErT}! 7 4u.}/ ]kᕚ 5Ϋ`+N…dw{ qg{ޗ U(맑؂,"U&-1·r8f |k|juO\Om^|t',/5'<›1`Nm[LNE*I]KK/b0֩M>~! ͪJ Y%Y$y߰LwQG):ZSg^ ?_?R\_9 b[n9mO`nSdIiǁ1$$_̫wsKG;zE_K7Nۍ9KhQe-uVaY AvVaI!wMew˭~%>Us=U{2X8Qp/erڞz0k} F7~%099]goL67Bto0xEjA;bN*6DIP@!>(0@IhSIƞqk``܆^F }`:Ugs<~Qx;+b5_uKfartùd `(j\œ!@q*tƭ"iu_"PQߨJH[I݇l.ęv̋mrzh(G> BEIȆ@ΠGCFp;f\YFƠ F&KO+5/ ;N/}~:CB^I[162yImƂz_,T9:7Oڱ3[Vp~yYT]n޾_LjG9l\BOr^Q#)ȴFEĔ }M=@q92=D=T~~P {e)q&c' QD 06\8]I*@YDPKg0fFKu7nLW OcQk"$#n`V&n ATZvxV XOrz tKk^#Hv "dAxuDUm=)ssp~唩ܳk\X^]B'Tvaѩ=>o%AA+ 뮩 8[Dz[*>H݇H4,`+KWM9oϡ*"pL>QQ8@r6xSIJZO?:A*ѝ"D!qixi l{5_tfZA E)E5E{)+.ebI] ^794<fU==w縫V6!O&ody?:7{^JM|pRzHY=gT50^NNAaS1f\>^; Jo%{2I@b]t'w.=Zʜ.6spQrT3@&b(o<(v4S-Y$6n3&几9+4? uGo\gê?($z'8i荳q+]p(]8nLZ<#sxZ@>3C^u\ L juEimi7SK/Ězn{&u3\X4*TKp6#?}JT:02hа80uk^|v:6oķLUEBdz)_)&U"*">E.EbKI- mENQaP(O>8XN#oן&{'{uЩIYU}{`qp<̑^/Z _"rIUh8~{))}{9=$ݩ;KA O9 mqp1>81 %]jc"sNjJ"4c1'ֈ<)0WܥNo19-ۊe-dJ2K ط%u)ȉhM21եѭ|rs|bQˉ$S& nKB̞P_/ybϋZ4\q#)tc:ˣ} zk9/˴rh}C x^~rsHPJ9Hm3,+ҝѺb|Cj^==i_Ů 8b<%|9炷Z7/@|a|m9%ř;GH,2R1b.hBfXyDNP0e0 $1z5|z+c8 +>g(cw0d"SF-lwJDN~jP&N,!D"0jhڻs(YT2@Th6v @n<~NdLό :߄_X,U!rLK',a"@+#+iM*Zʒ$r)xϋcl8"}\ˆ7ټq1bcy[.$[|K*J.tډuG1Ayۯ\͗&h-DxM!@v# EVW5b'=dYPz|1k(ÊE߽nkNYK.~LBݞ$sds)8*tU8}ش_#vj`@ ]w.\vЙ4^ҿ{Mh0#.Qm VkpcZ KE1 lع & 3t1h4:(nID|޹0\VJ`wq=1'Fr7cUd?tQ2/tЇIr[z?w0$eT˾rr .X9ps0X j[85Fj3 (P!:<H Wtѻ /׬?vb\ D=8&gY)IS2F lmR04qǞ(cU؊Xa~j38ps\̮[D9?3Vo|ѬbLYP?ZT.y.M{V`.:7:[Yɦ0u[!vx}e t۱8{O:T9̍{ui_n=S[!N.#fq@lev#~%a.#M^A;35sl-%1l2o$t,D +LM;xD0Ca&cHAʱ~z;/cQK "ϞT%`I->|{ .Q]{r<f1͔ )a}*m]V7;@w<=Zu6J,D s:F|sDMQW0jFPx.( QHؘ1l];4F w Fy`]ԕ"6ٿB%2> 脼J',`~ԃ0W H& )XOͼ-jn5qBr"نe z(ߩ@o(t[Bۯ@rEl`^$ ReGRWZN~jǕ:H_]W[k ZpG29^~D7똔ᜎ:8*[\79sw(p)(+Ywڼ՞߽#FӼ) yD0遍~QL< DZj.PGF\SSMxtvwOm{92ZL\4LSܤ!"U jhі)Np%+~Z}_Dz{Ew@=O(蚟ȽBUu4;4{l36 y HE$vq=Ŵ AtuuٶR $O"$$IC*\!\#jL}<W 1 zEAKE .NYT]hVMG&&TXp4㙺G#Tnn/{+Uڐ GsU )8Sn0H_/al5Z9@d^iKT+.zB ?00v/EpR';ϩQdv%i _K@aH H-IfE?7IƭC&A.Ⱦia' ڦ-r̪u+qynt^b̹^D]VIX_] th0A86n{x)jgඛWp$(,]ә y6dHVҩc\+ _;W!K.*R |~qͻ#Q6U|CAnò_$}K"n50-o"KBUyC=:PqwEI(俬^aO0{Q_lvaW:Km @f⧁'3攑~&6hΔ`3x0er(0 6{6:vi<"#q1NF BTm u X )b4{^^<;lOv.g-?%tx~NE1Kެ';0+hw_]?3:cm `J)H!ۋ˻@D+@=|%%}BY:R5B]VE#n:yYJˋ(笵g-23QJCꬓ u;SD5~YcB5>p~#@*FOܴAwwkɆ|'g HgSÞwι OZ5Yv$dɅjܽ#EX\xfY,ȉ)aEXXv-pL-\Ra1\Li#{X&/ 2L~y Y{%R8ۂ>{ѨmG V7vI0{.X Z ae65\q .z=T$/ u糱1lnZ'5VzZ 퓁=ӐRshAq>}v."Y]mܫBdd^Oލ%ەc2Cx3M/K}f2gQ>jpP!}tcSb>:Hר-*g, BWukYz7%jHKi`q5ϗ$a48r0\ΆԓoTk&ǯHj" gQ_zIFwwpT#>S-EoϒFJ3f ,zD݄o3s҅EOm?V)@"-d&c@R;ۡJ.RW)a6a5! (JS-jsL5{ Xyvaw/.u4DQÌ!K@٦_t7uaOfs$9A t#4Έ)NDLt I}Q/d+s4~ Տ v铚&M"\T}Rx\{=[ίQlqq3] Ÿĸ*wP'JHZDZ4T_Q6_eLjY=pe9݃cVȓ8t,bGlOƜӃgOiDqn&4QA; Z9j;0L@\Z@͐YKo-NP2 sCκOt ,Esd΢c=M$Gd!ang=˛Pݒ+m|PRBX!uժc(qұaI%5aa,NNtOlϩȘCW+8"Dj$0h~7sHM@2x@ǘZCv:1˩vBwvTzT-J4RZv16 191b+ŀnZdj8%X0%ouiTB)3C\©x sy7Y:u;g9}ώ;H"^}_9#mUͅz}dMGr:vK W >|ޫm!ȷO3M-,/X}Y\vv4ƽo#WE^y[6X)jWc`ɕXSr 2*;R\o(E+z@磚|'SBM9#7}A4 Lx=@ w2/UaO4t F[C3gPSlsՉ`#.)5 0_mهZ[K ?l=z>lǨ6u/܋, ';kiKQ5mu"gN+Rcy eHJeM13)qYY齧BSrQiWQ)GxyYj2@&4cXw;ߌyr\^áX$}o{e5+K{ӃT}QBHVs^]Z#f% g^or5KHH{ml5WRa'jryKxZ߲mg&&GMsY5oqߩ7aN`Xj`F|'oΦ$\RFhNm߿5ߏ!Y]fGM=Fp p &ٓr@aצiEWz^.vg"3 @ Zr&9;"AmxG<~F=9I:8M_w’f{9xf?\H(t.1P&㩂"pҸJ9ߋ[oH2{=7ڂR:yliK2SY$b-Ƃ3<%m3=!tnxr vA&2&}\I8ʅO7f` Ah~l:g"va;*:Y߽ DMC!-t,ctm=.L~S a`xaE1{f KS O8oB7/I>@pp*%3ImNom 6m[n;wl>zcn7g5e>~%8_%/EF0\}3&rk!# ? VƭheA"9ן\53 q)xu _=v4 ^iUS- >[nFSH$'tdaL}QcS.ZRbDE =R}z(:{-F# +/N.T6>P%8wp<-2t!,;5{ѣ寍0i4?%YqEL{1aؓ8{Ui^e,K`RH(3+ks4ݜ'TOƭYN^+8;Rͻ^a_hUA5˒\aJOJTl|Yt@QwdO3)3G;Kntd@e~XC91ls^@ h K>jy1ֻS-b^[jAD\'( f܈z i+ƽyPi Lt9Ϫ[,  7x yCz96*w,OR0@Y Qz.+oH\V@׻O0"elGʶ9dI 6H:hpKd2غD-YB5 9/Mk\g㼉O18@X"qfT\ 8E ?u1\vR^\-sjķ=W^~*<,[>炝hsoS#SFPJ9uS@̒I% TEK 3"KDj1)S s.7%5B Qu7Jn Cc_.6TQ' o/.rc42Yۂ]pNH'οa 6.vCmԬ x GգWytOp6{j)w;-k,6ŕTN7:%l~\7O~*舡(daZشW)l@`rݢaTZבUjʌJI.v'w}ai&J!OAc\^`\-YW,*3^{p3SRVR|v.d)#}M~-Q YpN(@j/k@MĹv-$P?X@RƜ\tbhr9*_gS,fo.GP|rIM D7OCrP{ J4r2+vϯ v}fD-^@zst)+wֈ:TwXEzNorscr d凜?zEtȲ)X\1@\B-2R/6u+4@Lyw`n,8"tfvgx!l>C @΅ 9SC2 "U:OP9)66!)x€p:ƭ$hOk Tt&p j휴,wD0yI,!RZCXp2Ŝ{SLި<4dNԗW<Ǥ%YAj-Ws\1 K/%.U5"͝~RߣZ y>@rCu抑>UEǰO2٤Fɻ*7gp)stЉx1zIs$ӧ0i>H{a`x`e8o %QeƬiW9ymZȑY;I~`|Rsp AOZz3ݩZr5w *b8y͑q˯+eJeZ&,˷%#uO^{(JZ_Ůz`p4&9/f7:$,,ނy}iNV*o`Fe)en߸Y EupfW&OUA+N8joxt@|]#k9! BSLԷ5 <쫍D~sU&2ʴt&pײtA;^*Rl&O%\V8fXal`K fpd >j/଺z'^Z̸gIt!V|8?田qvݶE:ZÁڴxJ,'<',{'9 qݫ8^o#Jd bha,s$Ks xpd9I5ei͐B ]6 !#.fIm*ovE93/WٍigLK m'pv>Ls1GNȞN [;'P^ky#UU~M Ċ;#Mx0רhb=Z}d ?fXF+#锛}tIYd\"1ޚm[U9|%:'{nae {+\)%il*(Tks+F4 $][k3!Qd)E☏E7=Z9~7QE! )3j#D L!yWvwm79?&RK;ߨz=tƥ6:K|(̹:#!bAj.%Qp0#äaĞ346ܦŜG>ҁT$i2Ģ:=? @B^c!j5{-UW~,;GsƓFţsp5wh;OsKfo&'*HWKySlִ׽QjI3$mDZe%I5f*}Ff2dfO; 0^ +gθU1iK 6nCxCx[0{xAlT\YϠ>@Sn:vހ~Ltۚ-籓IHH|g4@^i,ri pFcp# 'E0 4I,1KW>QFhϓ dҌ18!3_BCiqT)+Μ$;x:ulI@7_~4ad{Uy @mp2 0ldg%O-DQvr|nl-ə-L kB˔O`D 0-zZo]X ?of<W} sV̠xց +D +َ&LfX z?]W.#s2>!P?\x}GJ\3;ؘmPC*!U/o:.CI=~Q4V/OYy/^MmX siثyʇt _gD`G{2j >B'kzvbn%S&,s:~yRjn 9%'F1im?J8PAӘ>T4\J-zǬ !(T+ ;.cuJ~nHj{GOEHr9Pԅ9c0V>?P5t"A3 @͚l3ߍ0#DG]\Y9f&wJX|le-Uҟ4#I-l%x$p:.:_bߌ5qVpe.eu 벃0f GJ]+᠜Xh\E(Pz*Nōay6oO,[UxmiǝWB֤V~"Ľ(&Y愤} ;hd4vdml$3Tp!%cqrۿtL/)Jgh,7 R-Sy/{͠QO>U:"x U)Ƀ<`-ȡ'!4.Cġi1gok즵?`_h6TMsI1ܐiEw9Wuo- L&AS)O{e"'"T՗Ω;VD!ׇ;ϥx=_LxW?I%%L)iaҭu,jTuUHL+l[>hρ O1PR$\;yB^-gW=#M/u1gYp tYv zElU7'FX`A (\)[`лpXcXy^Ieid")g.XFfm9?/+!w{YsW;_.ueaL>djd̠v - тKUűSV?9#l!3^>u\Pȧ4*~Bץ'¶syR5UXN s?%Zh¶+vl`m,KVj)fW)teiN;7Y-R3 ʡCH֔| prL7QzmE(V Cä@ x8iop1)d=dOlyg=1Go6kS΁ɺGC'l#qOhWµɓ vYf:&ҤEg3/\k6.T*҄~:sy zte+*CR}qﲄ8XN4 X{]r WIVWN%vД-}6궭#yI$4e5kgSi,n#ڮö>̪PaA;Ɍ)ΊԒ:~V+3 8kSJFYbs:+CEZYb҂z r&ka݂}sQΤIRV'0 5zݘiso ʂYfO^j(#snY4_C`ӟwRl)ǎsWoH+.P,Eqs Dj`N:Cmxrc|2g0W"—L̎/奮@%;O'\њܤ Z9֋t*_Ȃrj-׀ lU [,6rn:p!I cft `ShǗ>H*r BPYudA9jq$n$z &0>|P""?sg_ˎ$O7hg +xrW]] . i* K~Z4Ğ2:|QP5Xj۔#|("܈Y:whUލ֊cLw%> D`k5Ljv[f]_%@''\pv5X#tr/E}Z7v.sz^'|Qz/~I+ my ʫtR `PvviDy[ΓgZ b _. ds zv;u|q %Nv0򺚜ѺS/YJ 8.E=֒C*<2<-_ɍW.psajz3m[hS8)ƑţyZ*]qouֳOkVxF ]X\ΠK8Pҗ f).d[[o@}j"t\:b:!O4]jF4on./#t0 /uJ sD gq~s,;%>@݊K)G2/xy2E ߘB' r/WpӭtVR+:vw2ʬ7],4W|TRŇQ?ɚ4x$Ê=y6,9"Fv @%*Q4O9#AvNb? يSpG)6::ulE6傿zqϹ"9`f״'%!ftgƦ+)*eް%TBXOIE_wBjPT"2Dڀ#!2RXbO+Y5G13zTWkIP󆨶_gbWnQU'p: ϴwϤ+=I]ǁ:խJ(#=L%)6I!SOk~˜yl&'LZgw_ެ4샢Ľ0vIXѱAI~iE4m\B=5%|?Ɣ]՝rR _6*0*)ͷ23ic(@wpFjr.SEh㇠նxʦ;ae-*j@:ͧb KRA=BTia1x"C=j$l˼yE\6yza5]tE]O5[:oTa7|{BsICC)7We(z.jp_Uvk\qyø訩/'hGh=iei*ߥh1*K̝-f Xӧf6ݐOoF쫭 fUW mHN5i 'WM@!&{(liG:plc#sA*t33H,D#2Z*n_r#KD[Kn>^ie~o2mqXAlF^-CMlˠWp#`f,ҥ>5OoIyEؙ|O1:h.[Aw|_6j#c}b S`E}\kn)nEjt38`tm#O5#;NX؆;YYI~V0mJ#`ʃ>"Jzǝ^IɁ& [;@ ;~P-H3 V i]=; k(f7AQDw#3.}4샥D7[b C|ڻL},<ُ :+~i ;K >b+ߤju h c̅`bX9m +OeSopp݃~%vHMofy?/l3o Aaİߛ#QNYK ϯG&ѵf`m?k~Gcf!-2 &_HԺMj9M*b6OcKQODt7#NTQhݵ(ҋJe](qy*͛02*}'3߅q}r`jp'W+6y"P"t.>}J=+P}4[e5s: 2#)k꠵K9:knN1!dYGl0xʯw2sr z7vT ٳ\"tef̗Zrm0сaGsQaQWlg1Sdk%=lidm? n%h&(bW 4L>R%2CG<';B`i9|DJ:EkS?ߩAonX<3g-[H?4l):f)|M<`k5ho,E哖JbEqgD1)_I ɺw :93+xuR* }&F!P;C=H2(t'fY'P_Ƚ/yqqb[R;sA32t@|u vgxZ}6F@be bj}u;~JC~ۢzh!_d}@|"Hxm]j8WӾzy$!rRHE"tF30.-#tld6o\ٜ8-κZTQ{+VH=Zf_S!Ld::$ѳɟƍ?uwԝRC}4E)%M}.,oB5B_DEB+9]5c]PUzo~f`3,yQחM%m,^VcRKEFƄi(Q#W[fVhܪB!|!xu#=fŌ,ELhLYY}Fo6o1dJ]![NBQP@f/Io#_3H1/iq"YFfdx VU隯ZaN=i30 ]4ZлYm!֎,KI;l^а )rl)i^7q/Sh`K3)s{i^NeGEPF˕ҟ/Aa)>ߦ `evD_"IpmY|p.շá~ 6Z4%>~bAgҜȧ`KG LcV}}ʐ>Ö+}0CrU(_iۃ-mC}i)x ބɉ[+\e gė 0 k놚JLl8HT"im;A85愯$B=/{֦1:"Lfg"۰k;lw~^M2PޑG? @2+L(=kLœJk+ Jshsw𧟗Z`}cӌENO01}ƫqdSjBjpӨhdևN){v&Mx!']LSN.%4$BW"u{qz O ntlyj1vZ24?XV.X{? N.CbRi̔{>x2I':bHL(W[kS\D68\KkﰀOiLY\I Plz?,Is}gyZK_YU:\e|ڥG@u}$P!U:V` BH}{11@2yѻɐ8K0fYޜmKV~yG-&C\ '޴ &3"})J##,"GB[B&NHBR,~{3eO$x+?_ L_58fovu[wcGR}d&Xa?o̓pNw[LJR'O"{:!LJ:c1x+me%f7;Wzjaĕf3B$+wE$eJ'@Z)moPY꥓?lz6ΘW:I%T` DؽaCf̨SR-tPڽ(y+'͜%m,j QmND2&lY?8b;dIA3-8!!d7lj$?" bU.u2t(%uG9+]@J/-ZBz\m0[ l{Oz`+r!{7q}5Z:nXoi*E-[wZc>%>u?7%l:y3K;9BNCqV d_$)C 4:\ TܪJN*cq8sl@I7Rlq ,ܬFu4▬Uu ݄%=ewgckSJa^f i 8 Au~{~exMK儊5~u#S%&>Qn Z;/&K`)=?0DZK 1*4~ W,'=0>ApG ʗWYGFOSv(0H.K{ֽ\ "4a9.]DTթK#5 ݽՒTۂ9LGͣE@![赍xrRS`/.& YW U2N8iu %J)Sήm=F.#u^cQEGz\2CE T!#[#B{@36S4K/?߯nX R(zJF\Jk?̎c&&83o#ɾ] "NQa^B% Qq6hT)xݧCP͔H4.0K>S+GvTϣTvuGW9>/I# %^6!bu[(2w#E@o2yӮVF_𦄣KF5k Kx6 ~69 FDè` '6]ո Q^mmr{!`n;?2qsl6sCr O.fu>z9@C30˼> qߔBTqSTEwG!Wd2jU A>ˍGM\f 荠U$<̷@8HyӨv a\6CkNhe u֣_wV(ܾdqp^iF"'_} HY Б n DTAB NY.< te[b!6"CgHBb5RL~$鷸䳔0Ƹf~:Y[Q5|q[c=;9u '_uN걝aV3C5!lMO8S;4q^ +x A2l:!J:å]mcMݿsML3.8̹Jϭ!z6.#\Z!=1!S]j e >vKō.EBdvV TߤZ<"r.H2kϢ|Ls)P`hG+-sU֘j3ujogޫ'5)_Xzo8יvjOWaQO|mpQ 7z ++j3J(+4^ Um,~2t;۸+?nnv ("q[&QS.F#2a7^}ҚG-*ֆ3DDc=_ E|$$I!NbI NY1E7z>-`<BnZn{66̬9؝%8.3 - p2yXcܛmg#UTn |w"06" X\ \/U.FX< d-1oi(a^ n:qİ!mg*ve}?= |P|QwS)ojj"  6y-v^rV'B?_}ny"!$n٢t'>[v @`zu~" =q*;לO j+ m;r.z\:#LKsT<|Y@qtTWr͖&bOǕbL_3US+GLvphvau 2\cfEcDhmRi7xmxUaW@ld(3譱, v@@@w=)zЕVmLEs84E6ɡfS uAYuԹ+?++8< *..mf"Ƨp8 ns05>0iMs6HD E?lc8ODGaI.#å㾱x{ ^. t5`TBur\XXfvbFE٣~ywJZnbinIܟC ^$:}T׵͏)z:fQ 6.S j:Ġ{xЇxvuBt(z4+xd^\f3,0\ $SG#t>tp+<ynk q롏O= tůk +=[=oa$U7RUvKsF0_:v@|6@~慊&+ъkg=:6:/uݐyAKهV7f^3{*AwkQre \B9 JY$Il(W!kb$7]T.dUSڊ_MQW9m,Ж%"DcscKB&HX4 Wz+DuJJѩ#}xCP;ڣ1#9޾xpt#=1A^nxD.y%pxIx7'tզ]>İZe+9A*Ƥ# WwIw)&V mĤƛj^~mT8щNqPu5-S&U-^~ 6Kh;*#\}qć)]ȼCF# }~֦[%-P o[*1vT<^K^J(rb dޡkȔ{wN.r.d<=%I2y O5ɚ&t%:0+zԬ r.zD/{6Zl!PdTa = _~Kr9Z5ux4uI>k%Y"f.IV挘iLâ}kcd0(0ᩄŢqڤ >3whIl#2pqL|I]CWm<7 Jc|Y{idi  >}e8``Gl!L@-txdM. +JME<?s;(5"6OLU/Vڢ6O L: n6m`̗C@m5^,GPs a ۀ@f ( e~d˲i%*Wqu@'Tao)fc<4'ZUĘvg ?7P&֙9fCH"Ğnm7=+gBx7Bٌ=ܙDgla/`ߟƔSP.'ew'YoKy,zPDF`Nf+Xt<" >pFdDt' E}p{ l[ǡܨ "zJyT鄬P#?G!q:SZ 吚ny>?yA hǡMQ˭zҿX.AA{¤lH hwƕ'd vYmKev3G#8z,V3C n ~(!;p (rb9硃ŷ PK܁9N#s>svaJh[jW5?NU >_,uFX; !YˁU`~DpHjpcޠy$wNn jtbq)4Q/ ֺYZ@t/@F EV,41ފ JXD&GD",nO:8vY|$s~RbMiģpލN"$>I   BHyݳWDQ抸4D&$Gx9&f5ԏM s&D/ktƏE5aNJ3 Vb#-zSH@d xZțqzBMz*91::?%hps?2@ZR|&JNrS@DfE>;IJrti?־;OD0!3}^Ήh?Ҩi FkRt.,fjp8~ia02$ʜ%wtlͮ9ju FV3)[wM/՞" 4tp(U r & _CHmmAAWF ى0=K~p4࿝!²Y&T(.dS( d4f@4緼6[3ddgNYxJ rxm-F㊣|=ʫVE)LS%0tb`iɬz 'k  P%w:;7ǑW)B>JxKs ) ,O~4c]O@, C@v 5_mP|ܴ'Fz2UDՂCN.ߐ5'"@}:Vx(y0<.BX 4jÓءހX% :[Ь7߹0,rc"־8qrMdTG]Ff9B2P{z \Kyӓnԩ/My͹vu"I?YfXf?ԃ)#b>O1'Kk"^n2+G:SJ*c_9%(˺)(8~տ4!jx{ gW;$`Emf ќ&O|&05˽H$$IfW/5[xh2[Y0liQC=rvX``e1a%\ <wY\9]%ѫƛ-vF8xg i{Iʦwn_~l:bǂe62HzlGAaG.5&KHPÙ^ɼ>S n\407vRKHqZwR.:&I0Y\ Ov@fYW"s8+4̓gX& ;pz߫%+ݴ NIFv  }"LxLM <ΉZ QŮbY0 ]oԞ8z--5y*D[^x^[`d٣QV## 6X ʢcL^Tם84Tl: AvF(]Y=Y#\RAL.19g4Ӄ jb$rpĻl_k17E eQ^>6vZ'^)y.r/dFFDL4Q 29!0O Ӯ\!.Јl̿NB͛IF-<"r q̄1:=l4-dP6y;‘09%'+ agOfiWv#uE?!Σd ӷw(ld) 󲻛ʅB5먒BCz߬zh⇍ /we:EQMsq 2|W m my-a?j+8)7//Z)Κ)>q Xlֈk݆C8±LP[~ߥLܿ %%[J)S~H{ `rm+Iߦ =w<"4B^~'D|k_^aȩ7\o"&;9G-#X=[Q|ұTѺw$xQ ~\ԑ|n!*sjR8k@2b;kհO;,A Ψ?<} GK'Fȹr'H_Փ(*pn0?PB(Jj$jmWRbq+_XKI]^͙|m_[oz,y=:lEjX}k]VqqRB\99o5+ݢ\x7g(sCrQ(WI2ި iD`/]ĵ@TRŭwa-㣿mI3Dr?y5n}wu<-sx$ Z)CO6&gyL]HUa-O >] 4ݚ|ֲjiACƞQx4_݆sY=ӢR{rD gYB8Ҫ0? z{#a4ﲍLlk$Y${bTFڴݤ Wea9z͛\[auCvz8|dqoZ*=[%5BkgDtzH>%B*F7(J@{L#$ phฐýrBq֮CFxH9T 3qQʤ<id{KrB sAjC9n5$A@Ou"E,ױX;j]IBnfNɼC|xi-Z1G$`8{vI"J[Qs!METb &PIEM4۸9w=ŊnV CF~&%ƑNDJhd%@ H^]XPI_'̆YT8WNnǰmD:.λb1PP=<.J]!\o5tf?%)6tWxe"jQ>NQrS`U:WԄ_ 705LXJ.5) S^`Q~V&G7d9hwYF.P)?lۑ2/NHoĦ鼎cbܸϲη&.Jd Ӂ=H愱)rcS\y$S{ia~L0 7ljJDzq$3" 蹉i\`37e#ew zwRX-K῎<7Ec/Zf o;g8^x 2XUKكfUn2 GEnulğ'z6h|(AZ S,j)?CI]c(,lץzCj &dnc$.%]#Q`>R?bm;DBmcFͶaմi~~kJű7I @evIWi+ " \aw]V4amZj{o!]sLR[]^2-$8u'va-<C߼^\{cI[+ WBGQf:~Kk{ͯH韻 E?[QCt=A) O]ܨ+PmD]'uwրЗC2]<J.>*˶(ZKX&hMX ^pu'XW]P_wk珢%up|T> yl| UҌM ;`KK:č$ӏ D} _dt: k MDg`-i&ylVG?*w:U1M(;*8 zMZe1^5c!;nj2 ӷ'(+`uV!}4-B<""I$жU-KTiQuxq 0p3t-|H7NlR ""LWK|X@B;Ge4(LDep4дwPQS]}XCQCzm"bF0r[:,Mz`)PCջMYˆp'-H0,{Qwv-s*bTÅ&}weQl44ͥѻ z'Tx`~j?HJAO/W(+JOs, : XѻVӡEVpW1B!pJ'a̪cnJ4ʢqlƊc%4iHFm񁩰Ŕ1>͆?eV~% c9n >ΓP28u4ڒ~\Kw(] Z+e/coa=O"|a3㡧p0jN[HA-\Fp5~e,Kz uS V B7Ȕ2` wcԐTbN^7,+6 C7c@5KzOk,mҷ>3 !Kマ8y mkkӫ *5ȱ,l|CG{J/`,6:4d{啺gq5-xN~m>)8 dicOI͇ FZK;8晲L3HH/dhq%n%TForGbԿ) 0FzŲcdsSObNݠ?* 5K YKJtY$,+y"Ӗ4wmyi~`o{X ˉZOB/O$?+kxyKЬZ)CN\5uT/Xk]>O-AR3K%vT0C9Z7$遒 rgs[4Gnأ.8=iXh):1d3"22+* KvBw{ I' m?Ql> .%?~y-&OFO(>y)ןCPc=3́>Y-b49SPhnwΜ;ϵ B}^{'ϔ&h&衏 MIzy; CwRa.5qICvTș}`;\'$ p6@g a]ͦ_=;k{2q; 1'h%r4f:"(a9 UG^w-+9 eC0'E5.N 믮48k-.7[Ha(2OF\- gXwłNA14/e.$`G>ݝI.U?S[*jV.g*]P-拯 d ߣ֔`Fmǘ+旤FΚ,ûe,(@lY]rdx޸X6d^l_K ~/cOv~ЃXD5PB~:0ZO~jIPz?Ew?C qE0hӔn,䴩VEF&2<"ubjRۭ4p<<>Ag5y ?1*\ $lsU1UAgҪ'gC%M)`D7$"ćհCM}jXͪ3=i~_~q8L)vP0!HSY[=WsAeǕLzVI14hk".t[Ի"EQZؑOwU OFadLZkӝ !^h򇹼4jiǝC|4Ot.j t5}r$Ef!-%^9] CRAZpXS TˈEjPU7dʰ,Z;qN&vH|4hO>-c}_RNRsG.-ޖx7򁵻We[>1Yt'"@̨Azw"bF`<-8g ?o$>INҳFZQ7u2~G'ۮ|F$:a׮kLbڛK"5FfMvر1rHZo[ n~1IWkE3y%(_QW ηTf.oce"DY1IqE[@xohS  puoJ3rǠ]R7hWG5{kXXЀDZVKs3 cۖMd XĽ=џI `'.Րx8%[qN9k{k\(AK Z'!x[r Ndd I>0190k;?lv`T8'٬Շj5sAa?" bzw35ԄH87r9 MmNz sHBl+9 fl$A"h͒'GI&=oOB%fR] ;"g^Lװ(*.mp ?uhy_#?ʞ[ AE!|IˁNџ߶gv.n}r=/,]& zRLSFaniN8恂 1|wz8[ޝ#f-@"d6ezgVԏ/cO1mfJJEf]~ڗkR/ =sG oK geÒ ?.[38d}t޽ 3>]UNs]fe-Is*Apo\I#{?iсԔ@CfMY/՞ pHX+h嵌u5unyzEMP+`Κ@7JL%wKߪ;J3#O7<_[]͔y> 3o&ՠ)O\m-Vh=N}x6 :ح6EifS}q_RsQξX#qCjNR2'{a fsͱRth1NSi]}yIs멞_ȗ`[%Wn˧TD+(<5?en5V Dmyy`WYV_h_]ΕrƷ%tf4Ew AtS|^hYM;-QM午"#PLIsb44&?iƎtI (&r@jظ?$m~FL;БOZ02,AG ޹LhXN8c`( 743t 4@:ލ+@ }-] Р!J`Q5%bk868[ݙtiivj;%tPL,K8n`^[-;H8g_zq V*b5lؐpv`5=@PG yFIt*<BBs̉L,#X'ArRc*C=E0N%tIqB"Z h^ULBq!|ݭRO_HX84_ՉNIJO2fQ\>q (|vṚ;ӑoM&5$BД)45K)bRէF6ҚB1@ %]5A.;Y q&4T /jj}ҭiئ{MD+Au`趵M \|ےB5 Rls^j9 &kdL򜥘V+lM4QU8 B@UT/!z~"8$#E4)Y!"_tq@"9JhkܠÊ;rcfpF\ݻDIUQovi`G[xq LJx 2%L;υ eױsdt#`T.J6c/s<fDZsgZRVרЇ!l+Mf54#D2FsK8篈_wˑ4D1i, 8-1s nT5/CX0څpF3CGK = S!Ⱥv2qmfFa:jjt+NJF8۳Hvn7Ҟgr`&0`ef@5##xɒ(o,ڪ4Hdck{"Zο=hD2n+`B4MQᥒ \/Zo췠'nM瀜־ю`CwTN'bvDF h$Ec`[|tG}@3،FKB,쓓GpϬ5q1&#ZQsYqCEX7p}Iz9_c_Yhqh3TR ġi)}a|h*&I#gKyl{@x%ߧSF5o ;2uGA>]`r´GDW@&gΉLZNo=i<˭NW[k@zPit_ppUx^'ɦR2SCnǛopuut2=`BL8 N[j6f8Vs<4DAK( Yы?D;ټ*ukߨx-*ԛbizeV>~-WٿҐ"Ģl}P9 ~<~hR$&(QtymƠ%4k SiUY&4- Ru<4Yޮuؔ6F٨bQ%Og|A@)!A\oDTMV{TBVjǣ O1TXmړ,];i@2µ7x⇉Zq.p] oGt.;|QEʷ}&`\ǽlSH%/O% 1-86z6an18rwRa~n\1QBK|o~taJkB ZìtPcId4-M`WH fޞ6 Zc^3&Ç]!pe2o31 (SZbT9ΫBeqsׇ/ 9mu)!a&<]CMyDQ.߀ 4,P|Xz $pЬU_L L<5-/Av։Xd;e?Tylҭy>B7,&?e跎g(JaN\ U~g=v3I'Vw0F3`4Dz:y{.!UggC4h|1 UPpo<}64&n;'qu)Mv x^h*WRb.lbIl`:Iv)kiqqt}Q+C$Hp@FG1̿ATRf`%R ӡloZhrK)߱::p֧,")0rxص׏YhtSgsxn;|erQt9ܭ\*.9\<!8 d˻<(s)Y.tA ږ I'%5֭*$ |T9 Opg|g|iyEG5/ 6dX~2Uy[w,=$rz}_O흠S  w؆IoZD~i=<'"ua-B-FSEyMj*smNRWkDtۭrknx>l 4p?C#`)wcd(46uY6./wLD8? i{op)~GoZ7q}a⨉uBE`2ky@JkWy!b=vA3,TVˡ_^@mဖJ~ &[y2/3/f=#>q^Ϥ%@%Xϗgcn& pn̚)A}Kԫ [;( |=-dfAi?VjCEdc=S/AG6ӣkFw+ FT\i=J*N[& ϡEj9e>ϭ3%/XJIkv8(S,8N7~IYb= %8/\@YwCQA# &ŔFfu+jKH 5 1ti&^ү3ퟛx~y+žEf?ӄ  œ"-g'4?;Ҧjt{empVr+z`lj>1RD5L$uq[%sQ9e i] xo ZA16.E;ZdMhRUPO3 ަr *g+ȼD`i,jOZI'j ;b,={LVh9+U!P*?xc- bU?g z֏Q2N/67h5|›+'Gl @dnڠ(_ Bb sk Ҏ8VGC(t5S)/'UUkNsXVR擯z$*9XF%rw.sչ 8׶Qz8U69uy#Q0Y?/hnSd<ׁnX[3[>r"hD~q7⡨-g)0(RХFOGb!&) _;FMxE}Nٳ]Tn1*q}:в tuȄtz܃} F`GfnR4F& ~ڕ_$ϑ!˙P]cO]3-ᢺuP`A۷(RD51m>.w&bVhBIvq\X61|5ޏFɹR\ vp*ӥT3jG)Df !)n "mo3]_9ԛ ߇\ګng>M0 MMToJfvuϚ0ll¹hr|9+{k Sd rbn _B߀0:WxV2Nqeʪ\`/xbxXRqkЏ@Me>?3zcjԉhγbɼrfh(!JsYJB'D0fMt-x`}lE&"PwGRrB50pJ3DoQbH{,ڢR>nYM'Z!]+C0QT3 P{2~ى5H7z>oulĔ?hbFoDQwAr_帤LXRZ3**78J 69l#Y]>LKi"%46VOjF& aNdIО.[\eZ yn=߀o~Ÿ˚&&4i[4.'2I*41x6\w jAd4`'""Tidg8U`GK ;<[!qp\Ewjy[TVk 򠚴}LR ckCj%'[әy[帲E1Sah%Դq,~NUvbY}/{ɧlw9 AqbfB&'@L+Af-KdžՁM$D(ν r֫1ZMլs̄ZhbBd>~4u.(4F3447UN5LgJ>` kl!4)/$yH]Z* 9Ta,uV]:?D-q)QDmʟo0^_e;Q``RM&Dh\*|I< Fmʱ׃&@ /&@xdxc8ElE܁ )RekYtBr$*wW rV`}Ak5Pb| #`jtGf`8 `kb!k'~|\wi)F F ']𩌜_?v.jt#7Km^_LֱsʖWJr21IQF-s6X|8e(ÜBMs}r)L5{{'z}2BpV!?h$&ڮSLxVys} fgCvVKԾ=tVYPф6 &t7yJؼw}=:6~ܙ6\ !Y`U@}Ed1Fp5VnP*yp,+9e[%Q8r+7{GRt#qQCqlx &\?(Koc|&$XYeQ1 A4Q<1M02LJ'5Ƽ9L~tf/8HTAsEwoƸEsNjbIQpo}VK: ^P}Q3شN\29}<sȿKJåky\,O{Ӻp5I=?,WzԒdM贃P d:|T.{|q8<,`T LcS>FRXe,CycLh f܌:\jѵG1<:&@|s$,b9Ď%OԶ{Qm2P]F3\C9td%:FtO͝ &Fk٘[Ev'׸v^ļd!-GuZQm=zIh*\ 2?_}fTOgm9TeqV,!G}|Ws'9u7j]#dWAgeL6OS_9ėdW J:b{!ˤ'fA &0zLぃmR}$qFRm(K`rUlY`n>,'lD;!A\ :ba 쌗t xThՄ$2?Mѡ7LƺXqZ΂w3*Ә@l[iISg{ yބ|@7^+tX1Lt.]H:Qݰu.tO 4Y z3O T@&mɦjmlhn?Q' 6 tK^R-}<M t2Q\òz6ٴGH"(t( Q()6XAUKuF -vѷmfM/Kd)|bVri} AvC(hU+C`TPSI~{V2)RDX#PɆ G -mw]p[Y릁iǶ})ᕾ:pl j1$ΛџbĮ)S/7Bg+Kj*O WǷyc2 tP\vf/ij%>D a`VMaf%aS|LU^HȆ}$U`tɝzƒ?lR7ԋm(>`kN>%׃8jP\v#[/,l0BьML&p+^*ns!Y@8ãm:.:~=t7x Q]f{VjMژ %Bn.2B)S\LKVXnU|;[og`ɄQN'6pVз(N@shx4*)~?k՘WѰO r&ہAUox:%@80[2ݷŲ]7;wf+) ӈ<%!Ua&gfi߅.2ך,!xufWm.eơQrx*7!{}oE6A?1Dj&h_J~nfIrޡG' Ȱv%gb}ƛӳ"/ejY m+"LuŮ&G"NLw5.hoa\W6Vm[ڣLR0sjwq~_i]ШCc$~;DMK/۩6)zҢ,U/66oc6J{K'c-AP8:*H\_u{-;TTHV!S:7Xد˻ݬ HґD`FSͻwVLagoDbܞ+c?3} H=RD-Q|zog?7TV5Jr@I .e|#77Uu_Zs 7܏!9>՚m3p*x@c(1Vki[r.ZB}% D`8LiT;@9S`nԭBHh 6{]e"Xr^\WE\Јk"E^^c~cfiF@$A[T<}<z"&S>5k+a~/羀*<~2^|~Z+p[(I]Kj+ 9&S9w̵T9,W;h&cocmӻ@tE_]SmQ@'_(I7QFVԈ :6df+7"99?MMV u0i{:2hGQ. ɗ$ܚս]4UWf2 }Wythk<rf*Rf07s0\&]->#lKJ FK!PyJ!w¿qY`0 DhѾ`TGLi`Z M9wE·\>ycs"f^*ƢIqXt۶Z(73{7ߧs2mwԧ]$8"dp4uf9,b7! N?'NE+2%;ɏh)0 !_dZc.b]VIHb [-(a6@MsyρBxТJ B_4<#T$5[5VJf]i K в'ʁ6 'Q֩NZ*GGőQ)pфF T pАAAu@({O((̎2w{XȈԏ:INc,/ (dAQ[%}x3Ǩ!+,ST vRIG%8VI R4^eaA=ApWq3%fb7ꯟx=p]f;;[W.{!@+EpFE)>rqPyR\ߠq25fKwNx*TDx GhBd)캻I}MU E`grp)]6l;E$w.eФ ek:hNRmaL>cuB03{ \X(}Astp7VmxV>?JcKȘY5b# ZxGPW1m,Lv^9rWc0FkT4E~uAj|yu` E, bWFTh XD,uMt'܃/U =8$uƜ^4!++^tuNCM*w.Qʛ5G$eتC-|/?tK9ӗ*([j]b6j7 OZx\2 n̟0q/ +V<'gq+=&׀ЃT f:1r ,OOr)MVW/>8zeXfaE탓Qƭq!p)Dx:diDwd>7I|Ǚs1B9B t:o\t8.Xs¿ XF f}^JZ̰0꜖5TB\4 5!Adͧ,l3<)NJc,6׳KOQ$`!-僯HgXwNݕ/UJ&Tf]Mʹ"GT$!y=qBhO"DRW.cq.1=ksKrB^ ^M:c]<({6rsZ~{Mɓ xP#Q"}S}JQBht{̄AI9qYD:yvb}fQ3PNn;`K= 0MtP4c*Nz?'#Xl- rqO-S]mάWBt2ہԼa)%8|?Kپ2s$ZdC7q4Ƀ Dj/lSBh]@ \ٓH- O=āX'nNp&$q_qA  e h7-qB`Bf7-p:u q%TsyO) &*x׿ͱ6 7h2j(a/loJ+0"`t$"<U_V(|y=y/, x'=Іx0Ɛ ҨSb f!_ջKΙt$9>93%{$` i/2A OKȟ&A#l l9spre23=n4B/ kŅ{1x/szba]v1b;5S/s=@`ǎCN<:oDT"VĩWP2F.8\mroN v%'~Fy u|iX5J}ݯZ[;[ަS|"zGpGs*6V8A2Mb"IrA *%Ѥ.۬ToZTX0 M-e5ڽ!;=jk =xKѢ YJ!1na.t`'C.V@$;3ʞyT"دG)m} nҶ¯ЂQWA|6PRiKݟ41"4\wv*& u`Jaȋ -Apפ xH%r#m~eq"Bͥ·K%P@(xGDL/QlQ.bCJ-n^+h=4aO@ĸ r$OgkĪl&Г *%]N"xd-|}jFM"FV8ߪ`FCpz Ie ?(rC9(=xnל[=0aY ƿ12~,(~gNL_5RT·=!$NWqט8eVؑ8'=uw3$jl_]H" (Uh/ʱ{$.f|Q-wV؍ه32< tW{'T."@Nŕn躇́K{1 لwK오\, _?)DϜxS-!ѱ[C>yuI& YxuhdfwT.)8M5]v4`ה%exzE}DӘM3&zl T63 , `"QAVJ`cp('E$l[' w;s5j/4s⻮_P/ :؈]狖|< (VHy-7,G.{j OܥerMJ\ -}~W B=I2ud;v- 7SD=J$i/]mLmw?ƒJo8n..D:CP+U䐒mnQI037:N<Faᶗ㕨0`,ހg=>H8?DjdEejYd-(Ғuv~ln&фuo ThLQ˪);H<[U d"XԪެd6f@MR9 VT(` 'Qt9R<`cD^;o$"2C3y5WZ 8F8޾ud7Oд^m&J£ ?r[@G oؽGwguҊO:3k]<˔:\{qEf՜=8 _ӈpp.,b' %W!I䑪@A%._Oݔx9#-UX_aGnU'sHk7m9/eJ|;G v aM F6H]F+=꺣\Z o_oD>9v<^qKxcjI9Hi?q0ayn@#}I {*F{ x;"WKX=JMv/ e)3  !3n㪕VĢڬcmBX8Cj*xG @&Iy?CGqmVLoK~je[oɜ;u01]Z֢ڔS]bBlyHfE19w<4^pRq!w[yL5%0AǗsNF <?fSbO)|1(guU!,"=w7Ե3PtrM['8T6E׿JXHu3'IzfXVV&$y6z+&Up(;]i~& sPQb].HV/3tME{o :dwArV S' /v1_ 4d^}.Z]I%XR 9MQh_x_.Lj;4ujԮ52}F?+B-d+y!}ܶ,Ǻ\$&SlmQJ lg730!/x0s:H.,K+eѝb$;gebb)ƅMiAE[fR"XGڗxŠqwSc& W8Ѱ՘#tMAC}hnz/m(쌲q÷vEгD+xYP\o\+.-t7fۆO14"}@(U0lLלь:bm- @h-\Es{qo6=҇k/HI_G6Ovxk_ wbƍQc.P\Dעt"H--ㆤO.#ij]V!wqx++Ѳuf=ǚ>du|Q)a@ᣌ"5%)@ver2}"DJ07 Ә.׈CT`S6MētrMDd]]ޢH N?XRmc\9ibTd 4@2TjG!]gMB@Aa P;]wE%>G'ܳ} ;!-dW#% k9a˗ȹDBWGy<ƹ*#3,ϖ _ɭ$k5Z۽y6Z=:q5թz{1Gqmg5z:3L~A$PV! WP22GoE0o5ms<cEF&D5DRWD ^$HW"MSf{ǝv˘5q96JåxG!{t 4Jpr0h?K۔f$Or}je&j[ Ƃ`߹Y0Zw0abY`ՃK9~[T;* 'GB[`u}JqΣaq]Ǥؚp_&iLkѠH[<56˒UMlhL(P:PURy: 6XKic5 :8@z p~ZBhy(ZhӞ$ˈ]AB=wT[tbK Vܾ(e`a~|Hv~&)JE*C98c<f^mhay>W󵏰xd'=̯O3mfRߺ"jt.Cߕ$c Bb4?¤:{tчMM1fMf7"]"r pqt#4-C   @+aB7Ra36Qb?au62l^,;A>H^WX+^ѕ ѣ̑|Pן]3WCj߅¹P ~ qvVξ.] pfE I[zXSkzUY06 .uɪ ,N.-F grd9d[OEq'!&: o/x36+ H]I5 LfdJNY$easUaDLyC1VrsݭR:sUGBW̿W+ԾѤG=kUN2CĕӓJ9 5v|ڽŬͯz78a"s &n?qQݸ)WӮڸy64E'hS4o%)?u[k$ղ?Y'jcԿy_^d?kh ]}VݞYm3`{6n,T/ڷ[z>Vb Dl =Q?W#馨=$*j;^m z-t0^Œ/!5Ębg7kM0pj9 sMuUCT&jJP$2߅eVX.-/8WU"jx%tX5Vy\1*7.̚u!LQpf7|lªXehAnt>jžnV [*m3o2 ghΗ-k?(S=?jWՎ5 TRlIZeJUwx159F#rrAU;"HPUzJpu KkHч>va1 \YLB o><߶^vն<, #]mBc!REQkهc ֒&ޝ +ssu%5Pa˩-YMny|$Q cVU~.?h_9WdujXdR-Sri񋟵'D~hkMN8"P O[Bd`ɌS֑~n_QLA܋s:}V&h+ek^=]xgWhOLZr|~9E{i@2 i_#˃tIdצ(ⴛͷ^ZWAיB\<5 ЏɴȌ}cA|8kӵ|󙹢wZ~6౹yԗ)ea F[O;94~՗[)~ԯ>K{@.A_<^7su4ҝ+e[5&$~2y@ܗ dbc~^u5)dKul~IxS$/rLe"er*;#%LX|XݚoB48A.9C# HٮQYg09ݰV )`#\Ssx6p~g"ɯf~h4ϗtDCx1&kr)Fk4`65sFcD:wk2̸#l$.\6ųӽxSn  X'R nAG}Fٛh ^~xzi-!~ KD0Nc:RjFA^My$&GF ]!P-Y3'7@V:n!Rr5wfźt4H+HjMtǰ+H!CjO^&2!uػbgJ1 d+U#T4Tdh &wblxK* _HC7=cISwYmb=!..= +\Eyxk᱇\iI'-T uXѣ/$6ݮBI.H%ΗK׆8AKl䳘^j9w/\8,g7cBt\Ey-Ut _l|e,xV`=Z ':fhO)s]e|<'Fڔ{nѪ]LaiBB0t:-[?T(! $%*1u %!@R-m G;vq(!"Q TR-IG,#ܧ X8x3Fq۸7a1*+U0 3#NᤛCԶܹA3e̅݌K| ?c\zѠt㑝Z@1rgX{ӎ=Cy_&RP?j3j%`pl?NpB6uDVh1M²Lh{^>'TZ/,KɩFqE8 (#c; iUkod^8y kA1ο|yBk /ܭ̡OpTOR460ux`nM ?`)$̏}dn(ȃD#}_Qɒ5x>zc3vz2Uxn4a}M>Q5>K BgmkPWAٺ @G: b׾iq0); +=Ū +vBRt?AU~D.}fȮ%,ʛ {qƙ EL'xz}t" OM[L/fNw؝%!ݜ!~<4wTa:?:t 8&꾔6&sE@QfFy U >3rZp F)#jEcr7/.Wc;TZЌ.~rp/^41=A2 EkHX.h+u;"1Qz[*CvAJ*ϞØU19׊$0q,Y:j'sRm= M'H Уa4Cv?מI1=>)[{ntdR-ŒQވ]_(+nR >{^P҈_.a. SJ;{nG͆6Sk+T}D:?/Y)JCO ]XiӼ */- +?/2[M}cT=&2R9+o&]_qZݬ7rB;SõEbK_G 0oAUA$Ui疗, |Bp32E5C+2BI>J %=($&m3QIhg0#v]6B8G#|%UD1))+#7au6- `UF7 .s@I3 #/o y5QUf\kbBJdwܷA]p,wȨ@ϣfN ޶]f4Y?EVf*(ioVw6w{ 7DὧZ޷0%t/񋱼 Ͽ[+SQH@wd`P{xl(Pa5gZ_?* 4Byr% MXSVE]V=`dB`j\[H<@Z ,ߚ!In!ęFFue\V(y!VZUV5 \P'@iʟ]flbYܚ!3YCL ACZ1/P7Id%uL<"HY@ʳ=E]],[$p* Va~'Fw M0}:R3{R/ ~m~$ OO=TׁdpgT5&G٬E/~gu@?3KIE%b+([ 2k xmLjҾ6Ho! v\E! 1"9Zx!t zlN}uQa޲"z_k +H9FI?|^YԎݟ nG9Gne!λ YH hsON0 5TV3YCf@!Mo%ͱ!PmX?d6M+`FKـư|_oٯ[D(zGyPTGi{ D@.Q\qÂZcGAvpOnpZ#5P&(fC/kxW>mC ԮYכt՘S,QJ>gzoL{OC]=Qc4dت7F׷R9G;9lMG؟K|u3a\3t-h'k1~A_PdBYv'D&~knGoM07=LiEK@9lmQ<mS[~`-H-P7h=5 "$(r]%)4}8H-Ww#jD8;ʘɣT/agEs6.WH;C ?,D}a,?<]:&J1ݍC|O G?;7★y"Az =+q>fLHf߅ilV^pE UmrXAlOSƺ$t}A2s+mYQnv"/ji>{mPH>u"_< @P7)3c1ixC:GVEl$TqHg`@[m zA ^Fg7> Zգ iz Ufl/=Hbk|_^ . @6U)9IV8{dpK&'OwSCDK-cMvo[p Lw5f$0׉O9V.([ qL`Ϩ 'DAmoլw[fm;b𿾒[g٣C ȯ~n5U)ٹ+Gc_ *,dz4 cURgAڬ=(dj.b^@C~ҲCM᭧)>XrŭYT$l+uY6؆SE#R ' ,M4ޏ/\E=?9k˦*)tUmw,[mY;%ˆ1zȗScKnL|+JY5ᢛ1g/x7&WIŖ1C#Y@sXN}C ; "pڙ>u^pzԲ+qDL2$WDbx `{GF 8Glt6T(2"騾FI [^x|RkozdF與`'߫,PɁu*=y T_ANn pYK]:A|.Җ!$UayeuAdkH7ͪZlZV-IUMta,,VbҮOvyEi@jҽOHvtAHr_I{PH_k>a_ڧ,MjX[JN3ŠӬxgeLx,7j_W$kl 0b{}85G zޤbD.B]nG}JA;!-t;ϥc {X ċ{%f{M Pa;Yd1܆j87zp,&ONY֦ww|TeiWZ*W!'6 ;e]C҂C>pq.Z,..-c ~QZ)h6[yCOC/4F5M ,dhӾL27j􍥸 /l'3)F|(  )0ъ"; V4ZS0>>*Ã}4} Do(MSy)RV{Sj=+**hZ#UXһb'^k @ӉD2oX'Qlc SR^0۸VkbC1^'N:kir2_svqԑE -T} Lc :<:Ґj8Vh.~VX\iw !*6XO ErDv??X5^B"8GȑR+Xpy{u&P޸w0_b1Ӹ-M]3lZ^MbpVgQ-fn g:FS@,{h131updap9lh5T]6n!n\>$MpHV)t؊./k2ѱd:eA?.8/6JTG -Ȍ kiTc'q6w;##l+vFޑu4QumB1XATQEcZGlṪ^AxNu1% 1\pWCzs2D 䖯. g5Ycwڽi@Lq8װy7-$"XW5۩ٶըhJiu!ˎΤ2C?D?K?(:N[9cM"am2kRv*V=ZUpH9' L;{MAA xLZSm[Iocsmx 38:jL^S>!xB,(ΩהE"2.t<$~۪Q&?.K[-ER T')"EȒ>$C _SP_-yds QY6/!mɢ8IO&/w0i HCVboGڝ??l3$.?{ۤ$~U_臏I5NijpP=Tg"ȯm9ܙ^=0ُi۟n-NB1DD"_5,B҆ 2ErÔlPq+5)T)(V:vuwa@1 HZ7CXf96Sk0WS}8"$!b 5E"WUGDv}s;x*^d1'hgňlqOа3$vCA8ڹ.D.p xP)57rwPmAǡQ5bXl0v<>}vd][n9%ILUDƪʎ'| j5|9hvg:k0:367$z(W̛9h=T'VsjK#?B yp8e<RԤ%gWK"׿}ضZ> %_橆7䤏Jsxd<AF.jHKJ{^gQ'bcRm/JK+$ߘOty9狫pQAwg1D}/ޝ8:~aF[gٹƓ[P_6d=^R-NLQ_N"c9&ↅ3|pz>*DH$Qqd:P}FQ_7uBx&kdFVYmik!sW%2H5dh%U,n[j-ׁ-}x2g w6cr+>Xl,G5.='CVCI%-1 q>HanO/S}yA*YH]҄NK%}zZ ~Н,D=kZmBt FVaz=?es KlAR" _NBf(v?r| #ɪ#6 P)]cٛꑝ.9 L|(?l6项 >) ĻZWkq &U:dX#/\*;b"p>}U[0]dQz_,>lz-?|I %43y"KQJQ MF!' rج_ > |/ٽ*ÿ55V_(!p&X/e25+[yU.<0G:s -h~waZ F۶WgAs,V)",Tɗ+xb&Wͭ{Di7@৐}1-6d P|)(XJrrA( ;SU.p/_ Z7Vѳ4 OBg[$RE20%V/o-ƿDsghA $cnK =y 8nyh?Q}gprGA?C|uuN3^/M:z*!b%H09|mċo̎-tCΜYFQ7]Rq^ ?BA_i40΅RDx@&z䒅rxX4K%ˤ5+\汐 :p &XG ޱI,7N%ݍjMF̦MT9ՙpA^7BVD1id3*"}մO/AFA8&iGJR4yt5ˇx#l@#^a?Z";g!kc Y")B.q85Id#'Ȝ@b{>4 a3H#c|˴R|tM:cn7os㇮-ZڍU `y>^# w`~C7mKCa[a"pǗO0 x踳1~A韔]?pEʼnq'{j} 3HYM>yH7R   ,@]FҠlS9wP"| 7Z;PMV*ƞo_2*;0HЛ٣v0G^%4N vMBOl]pnwhh %!~¹>=yӚ$` G됭! R u":ὕ Ɲ _8>rȚ!}0`Q0}>+t%Ti;^twCh.S8ww?Q(vMRrN_2%:e-C)MoQH|hnE᭎]!Ֆۍ'840Mp;|.b'Q?"#׉'ISQ8`!rT5-E #|ǻĘhe~i.`tf3gptm~ jY:R/zC/Tqh.p=XT V rh J1P"kc-JPO'UI5g轓Kd'\17/{^]6]lQk5+֊95~RZ .QL3w*~X% ::rMæ_JZo<9TN0+iŜ#GR-'3ǂúkN\eG;{`OPb퇙Q&X<ޞh^L^%vf ΎJp+a4D,sȜP)P̏Dd'Ȭ۾GJ0I<=uNԴ<+<}`p*3砹Ah˶mpe)|ϰ(ɻE_"t:jG&n'2O>CR'8Q0TzTmE^D{Cs2|bOg"ɻmf:O#C746FAK5!l/zr?jlA4 LotzԖ:AyGuI¨.*B%A~v󹡺9yشWLYϞػgWM#f{N^f:uv&!F9o:4n vILyO7#\ʛDqDvDl#i2贰-Sޭӏcs^(0k#,o]aQ_M7HzD8-t->RBZYWϜ l{;gRɓּOk˿掱 Džؾ@يtgY$R uזjY3Nj<74B;a[uF]0 5D-$ԅXPJ|4cY/b?}EM# ï8"B5jlBE8 7`?hP (`ߑMO4Mss!3eKwKe?b(&!_ItYf"g#LI+M1 \' 9J "IN(bNB)\zN9&ǩ_c?CRn{a!폠 LEԊhԩ/R~^9qr/} v>K\֍ X>4qa[&ZAOW4t@3*ܨ`Z$W0{繛a]sbvE1GiQ{=ɵhNj<ʯ)cZg]z'ݕgu#D%)1略J)oC5 d,hF݄^ ̜s]{Fغ0AnH]&G~7gDmTc~i_UCE_M}OFu{ wJ%7hd7vsqf]LR$^XKpCtV-] W.oOTIr4|\e*) Kf8d%/ $ӯɓ ﵝƱ_z-?)72јVΏ}'hFFtgQ{b1"MfЫ`;ߧo\3 -ʖpDTI7lH>+`]8E"}h깵$0=+Xgl|ʲ <ֲ}ΗJni{@3//n0F}g?; Ӑg#_P n"X?9 3xLSmޝG5=f=<ɹPJp+ V, Nh  6\v]lMǷ9缛S2OWzYX\ Gfnr/v O:޺ "jѱѲ촊>K$ !f_̚E7 9JO/yzI6>꧀ul @*dB8{gQЊ*E<6c!6}usMc_0_hކeQj ^̪~YbE.g'.1o}b}ďli[pM65env'%VЃ37l}5GS|es`Xc \h&쟖 KlFm#&MX#s̝#62Hg"y_eQfXM+Ǣ1>if5c/bMg>dk5A%-/*J`T>sܰpH~%}iOͰi/wB=m,o4H4Ɛ 5:B&ĵʁĘ OaeFIUkP y -Z? Z(im'6hȶnϸ<@\wG<5 V<UVX3%|ޚ!iCǵj&(c"v+h?[UdmUyӺـw!\f{E`)xGLFsʬ21}BᜈAUT-]:%#7B<4BF͉eED|CPE-"2۴hK?}@?0;_FwHXѹ|!rRg:ig<~E*6?)due2j6[vHI/wfw$>prz<!Y%#ds*!Y7C1^]*)`m)!3vʆp 2P <Bc l2?ou_xs[d^POĭ 5 15~AO1ovG̹10 3+c:h2x.mxjgGh eܹTA\+ (!S]Ӷk׍:-@?ڶX2H>]HWeL`A])4jOK2<`ɪ_$zl.`D]Lp =j]0r%,:i^+8hZ88˄"v1itTwrLW}l4w'j+d-.,&IiIxkl3>kšP+W8W:_/>CKݸ6G@:_ an^,ty)QF2kɈ 489{X@!8fs&dL(n:RK\0%JG[sKG&xXҏW8hp"I3gÏL S&o\GB ܔ"[eDz0s"ltŜŇj<-?|(U߸jdkIK7drj^wƀr.3V?js}β)Wky*)前F|fŅh0C]~)a!+Rn8 o ) \?X`nր4Bh q!?#ؓ딫a?(ɷ]oaM1L)m 0P~S6}}9DCTqe9xbo1[npinv~BMj+h*3>ߏI$\`Ÿ-mhK?Xb/"eJ]lVI^oˌ'@},ׄWڭOmHe\ aQO(]Y^ y\4 "(( ZkTGزS '4 F7 HEDImnVjZ (?BA1J;FG]%l^Q?C{a `o/܀A8)os$P|N㫎#Klzfm|@W٨s LCHpƧD{Ŵ1 GlE j9K?BM?M6VzgeP&V>a L#zT"UgyL`[ޣ,[6^ugLo4e:pFz3e /mvm 5/{;-B#)=6:f|%4f@>o%(w2'*vO8YUrJ4c%rlCyHqp)]?Kwz3Ժ qK__' ˀ]Ј2ScW-T._җP#S|&JgfDzSjAcxyǸfIb5VZ$z#͆Y*4%O =)9V'pIXD/0cytKFv8l7:iid\q:S펧 ?څ[D֡Ʒx9XӬQ,cߢ+!7{P "Kv?;b1NwL>'~t^C3D |lK{'_6ʾ/(mY|dK}}FV?3K/)iQ- Ɩ!oYuGK^,{pMasuy ce`咮 ]1i AeK YZVɧ^f۾nC%Mj}F0@gLNbqw$0\Wƍj{}ɍ giuׂ#~Cn\d [`qŲy^rr9:9`Цt x8Mn8&l= 6(;ޗQU_#P/|cU|kbb{92n+L++?_9B4\Q4ّWVJNWv5R?RD^},p";L}w=8-Eɤݰ"Zu0-QY+L7Otb,!r/\DCTEkE~o3xk}$!9QGym8YNI PL0GhXX+;50H=N[rf9닛.;~m{8J\/h/\gs2yNBd^8(3yEj#tM#2VQ -:Y HlX4}DZf¦‡FqFvA+ʧ=kQB:fJ ̉ ys_J-JT$q)O-zO?{~?*^ȑ+g1UW}AP9p\3 cg?*aIw]8ȱF4}IUN ۋ ^7/meq ǥo{x[isiz!A 8-]H#NGsSU<}OǦ2avjbN$F=wWBB^iUphВ?$FF[( g7-J99q%2^ÕS$Nݯ< c/)'aF=8g9d ݽቭUѣHG W5ayǐrǯ.Dj6DATrjj [Rc&vo He?So>@S|ehHHtajKx'R(JR ot"qYų`_}!}ӊ@ٝ7lp:] څ-G[1qQWa/Q}j_-մ (Q)2B17|=php17|hs?O頾 ւSV욤 I{*>c UB 1:sfYJ.kV~Ew# '!=AР-b& qKk,]5XGV~C䍥CY\ 5jfi,&,^ٯln`9+C@j>\"50V6A=pR.47'YeXka sfW 50~LO,Eucz r|!>GA&@(u}Y^AUT^+%jzߕvfG蓡Ee 0B;(;3"ݥ"*dQ 2[xKOR=FܿS$ Нt';f;ǯPzr̒BLD{Kb"֙(MBJJX Ict/1 ~/.k]b9RpaF"Xq}kLoЋuYnpx ?>Wτswg+ݚAN[YS 9'R:ƫ!?!%3tx@v;Taݗ^1Ps72J3L_v@<%1"jL٩B69z:LLmG2ljo__ liM+YNXͲ2 ]}}u$r*E~7ayoo+t;A{U;1`n\d}?͐xw5|8)_EWl `}+ M(Txtfa+}!Cf<V]_HIk GQ3P-t`w-qFT^_;:QhXÖ߬߀X,?N[NJk}>[,s%鉨Y7}S88(vBJ 7"g罡odY{W^CiwsRE|LgL?1Q|RkjFX0n}, .pZ1=oTFaKW.+@N4.{$ Y^h2^gPgbXɬ¶ t©W}M{-%@͑1'F8s=4 .g@'? 8iiAǼܭxZ~i0wE?φ=kϩ;zeuK~JgDg/oT[nF,jG$ڢ;ϊ|W@ 2d+H0K'ΟGwl{_侠Q'q3{nb\m֣Dy4$|{??+뽕 ot]/ (ETix-eBØ=VIjie3BU"K, ܆dehXД.\)a0aߢe?rS;*K}gu:X{o*%%ͱ>#ꋈv>p_~?4f.G1cZG *[nV%qA=omexz??ƶ0ST+?|PUNvGu[\z]J|2AQ%AXkufK&o*Fx0dp'FcߦC5ѱ.ŏC)"G4ޔsL񂗄<|lI/<CKVAڶ4_15@pp\^[Jhph EфX?sb=ˑV)/}1lXU鑜TCRxUOPHfʓ=†3n'N⤬cR;nP݌2PܪODK 376@OPLg'J"3[*Ib¾X՚3=_@d^}[Y ~g(x}l#Re@jF00i:99P%Ls; ;8r`ɀX":vEJf˛v+ܿ:? &O+jJ}ӣsbQChb=IlC%EhnA,Nzۓ+S[K"rz.Up~ W>K P̞bԘpIj#~27@^Ez(=0{+S 200WênV7VYCI=FuUá62ډ~IAib"Y6ELH /QFJ ѷǣ9RЎ"J!'fӼ [XG,޵;V@!e(;6_xQ!$Ho0vwoz}"o*` nmF$XZ1;z<7>p9Tu0{req3T lj7 m̃҄pDNݢnaezZpvvq-{6͠jib!p1ݥ%h"z|KB ;,~Gql tRr;H}x 7~FH~HƹksvVw#xduZm9  "eEq3Mk0qzʖDda*4O]>Xބe\$Ⱥ:D2 B49RzΰsjAzZ_$q`$V͗ q[&s3̃) F8ѐ/L%{yqE)W'|Z9(|u$VaO +%: L1.poR+EvH;= MȦ} ޑd&e3.> WYx(ۙZ=2VJMa^J>:_Ӻۻ<>:iooP]*=+oyvIUϐgL 4}D!RH}ef*J#oޣ.+;Qv\3%ʦDSz1}>>Q}ֆߵ[s,c.P3)#5*,oJ%^> lo #< ^jx5UM [ҕt϶"j$0߶s|zA 挈N`AMDԝ!^ 4rwwEWo2V/q}rsqP_5Zwо$4Ǣ)4MC jJS]("P'yLR9G8GC:7i9I(y.XgW<7,83nq%_γ:v_7Ezo,d"S42^ި3K^l.e9ُ$m4r>Yd݆j^OӃt:jwXjjYn<6;.c5NIE}Bekqv14OtT8ls*Im wPl ds0&W\;ď-"}%)hZ]xqz۸94p۵F `qdI[-j1:o"3ؠP@W iR`*$9gmb18|olm䋝DTDq+1.~;zƭPiV[YLM зJl\QKI5s/,NrI܈9iz6R!'(ʦur@mG=NJ0Zr7TtG,{}M+ ݊ⶻbCm\sһK9A"HzPBقƧbj n۫ܧQrfN+0:{*ʴTG@χJ^PxEn"yc~лT355CQڬP Sطx/{d|kHa2.U}kV4Yя.*IjՇ%*&ʤSb(vȐ!m:C­XWVqpښ%p%&bҟ 9b~4ô 8u)=ع*={]7̝MpNYH1<`^otG}Qق k$-Z4NN%ܸ4Z+_&>S})NJl:*iK([GWIpVḵjCXяkJ"2k]cA]8+PEgqisj,g6KK$o R\{rtс%"G܌w$χz)/DŰ"> ѯp{܀D}nlc8ό՜){"ӛ'-֐ŇǽA^ LZRJdKGz5 'Ai 'X*u;5/ahį‰0D3(FVZt3#E{DQ7}vC&k(_[؍=Vj(6 3&x8 Z)Q%8=_0g3y(O-.75j%xWhI &HtÞ0S?HCǨE5 )?*si5{8v& 5e Kf!%言\*q\Hnmo^8/%x veɡJWc@ +IkX;BϻZm'' 7M~N\Z'3ChB-Q-Nzlt9jC nF]kS/x,M>A}ȸ2"험W@`"HM/©7@e ؼ_R٦$#^|7QW=3ZIWcnmmyv|nD{o`zWQ&c=)a?e 릱õ27E{"f= %b ce=v+Y'%i>e4bZ⯣>JnĉՅk ͬ5۱`\ wP}qώz;R`{٘%H2+k,1d{PA}C riqIuz ?OBl'!#E)I8vwuÅ36g۽k-fBTd Tcn8d 8LRe:Ӂi';or Fˊ]{q/vjs&.![`geEgИZU&:T`] Xt`4u1"F3s[ Ī243yaҟYA>;f))Z[U89[&^{ҕUaƴo7yuU 2˔2^ #e#b8ݑ-Ȫ]?U6dS;&~x0v;lXg/:5߷1 ?AۻdKx=iv_ܨW Y`[?q^Ypo\BhE('jrjK0ŸʰVrY\*ŽTui7F|| U!g}})%y,=v01 O82r_cH5_ e`Qf-rʴ%Kg)n<նy 0v7Xg0jjIN!`Bld D"SO!{=)Op/r %| wv <ӷEl҂`+l+Î+Ǟzիjzx,QR{` Kkq>ҏihFy c.c^K hdmxp+oR!zZʘCI\l' C:O ҙ,< ik~j؃ iN7bsKTd{X–Sҷt"^M 4E?Y6]n' %ۈ#q~\k XeKW_ ;GH(iJKIF#g,}.Sܔ/HH:/TfKT+JՅ*Ȟa{7pXodK)wAOa]͞t8ZF@g;J _u"mBU(-QDͦ&:6dKHʁܜejG-u-L+R2sz2Z'0;덴t,zaWrn8|~vRzDjRp LNx׶GRy@Э.I) ?KGDl^cWg_}gY0@hS ~ mCDnTKtm to.܉%̲_m6GJ]Bsޟ*ºd^{]m!Af"\g3FGa'|RXju^.`voLזQ_H\z+αK)fu& >!~i̐6nN,h^m9p6,x; 9(Xiyb=MK,U3% "TrjԚ2E$d`q/%B݋,$l4QU[@2!g`A@{Ã$w4F97mCf S9P.Ta8MW%ZuHN5AOʠc٬ŋ_'X&gS$?|0/vxWDG}e8v#};wl slwLrc~+eNES>ޢjF>|*a&._/O=6TyG_)XF&8& ,3qw^?A0lP+$O3Ge'OޚTb9j4kdύNZ>iol>z8tm8H Ȕ2VXͧ}RE+%[֎qjB4ןMUr!hbqH[2w@=-to6E-*.QY2 |oK.u(j7Q*\ 8Ţ'0-'SSx簨*b2m\{z݂auQKCf<'$Y`2B7suBr;d~:'ѴBB/ 7y*Cy`h$ ~?DvgApCog]#hu=0{4V G+aPleݢx;YP:B4x6ԳA*2eXNkSkEN6p`#`"2j7QZtOGӂ!'V׀"¾M:yJ:gDSB7Z ?];C&S;S%k؄`YJn@$ZGPg KVZ2x  ['z?.ۥ v/F!j{w)\t{7/Qv-&tF=r޹tc}-*++fL; vNߓ8PRG _nU6 y'4L_>ztaROqAT+Ɔ 6zΈ1"S$!D&O,Ơ"CeYl4d% b ҜF>T20H)CoW1;"E)5^kC5[(-ϧJ1zEPR{wByr^F2H<_MXa&#~9XZHR%OZz9=Iʓڏ.5-II^A|Vh.u !M j#~q~kiA>.r-uMܗ [vVr u!Z z7)7> ෋a]~(>oU%ĞZ"sݷo4b;`~ X*T D=YG-O(o _X㵤H{E"1􅉈?탵'|nQQ rv/+Oaf}8-Խں03*y/d)SU /H¯gf@6.x9_Y02s떌{-]xq%&Ҭ2n>2 vD7`H[&5Bk^"8..LЯ]}3ȗ>jau?Nj¬,µX.z$Gt Wsf0JNwJZWHg͹\Ikc "D*Mu5tUg9M&th.? ;i[ Fjf@ Q9Hw5,zq??=3f~cǾγ^FkDE,zd{"!*qPؔA7B#{vg"~X$2xKO ƌ(F?HvM<ka1Na;0hOZtQ1ϓa{pouVYF;3>z_R: 1<ɀ[Vku`~ ;#igp ' G6 yzu 6`_f8|%j5QS.sOep"KUcSڈNIjaw0g\Mt>&PJF Et Qc9cd&<-qaU&r#,Gi/QL!dPr@:D;i5$ʄm>4zT-ߔdc)Z|bj8G=F1Oܼ:iHO) ׇC&Byp\*ܪe4t6a娙9<=}6*L^PcMh]M"fW|L-s)5OH^b$wqW 8W/댹P j8#E&EIFmKϥ*ܓ]PŤJ 0d#;S 1IVȍ. 6A}'t@)LJv _|n . 0vFBU6h@ ѰIb8Ye[whD'ʄvRV=Ž҇Tj298LF\s'r oK[aP Vz_:ev YhjyC*6Dp?g9n͇rQ0oFr+QޏQU6JC_L3ԫY€LGTH)"=shZR ^4;8݁IFͻxGaQbY2GBۤ*MQK˫(]tۿ` MNlj-g4df-;|ÇB%0xW<GR+wV@,dEEN؇rjO|{xwQnCBjs} E \l;P΄w:ԼD[&RC/5ke~OJa#M(Nಧo?cSA'ƝW-l$3\O-kG ve82N՟kJI`h(%Lj>B@HDٸurb g&KQ/_HѤm# %^z[3 IqOG`H5{C!/d3*gͺ.6 s9C@beX"U .ѽpM痬 I|ۭDk` v0FX)!sJR&.f6WorJ?lK b"ɝ~1l(Zh}2Y`ȧq*s-(ŵH?7. [Xʿ*`#MEYL#vӤ2Vt2[7(+:~{[Ph\ ]>j 6^0i t֯5v_&CHq蝵lVyLԧqSgffG+2+[m 9\?oO:mnWQuU$=:ԶPK;~TQC6|9򹙼 Qk\KI&@mϱ]Zښ/hIa+h!a*hœ%ȵ/&< U(W]ymI0|e&Y[g gza^h/ECK7RoĄlVpLrMwLQ,:>]spe!ǹ%NFiYu"}qh93܍SzC0F Ax-GBho͐2 @RIנQW Ɂ;x{߶kV( (P[3Of\;H$]f<t~y}&NUi܈}(41mӄb9w5 81Sb,<[^'S_s4v z/`V;8MH&G+\,&/poKuǷٯb=JON,>4Mz)*@f2S ͠+C1^i_Jq(6 Kk c83]k'Jq.[0Y^<#8%߰܈+ٰ%]{*-Q]զI'PqYF\\Ke<dIoZ]cY yΥtJkǞmw1 1/E}XEiȖoZNVys8s&= @8;%^Y5;NPDG J  ,)m[e2'S<д ]4P[P*HUl}Jr.ZH|;ls$ĝ}7|]qtaD#lBUdLƱIEPIToUEk"[0᷋{T'WW+g9Җ2I)Ϣ {.g,?oqW͝Zo|b#$agQܙj/`P(-Cj>? y^p9V$#ȖW<(ؘHa$b 2˟ }W Y]f(vHBIAN5 ( 4q p 2ytiIʶWmfTAHs W~ڒs,y?\qB@7-3 i "K?`>QR(_]..Nxg]T6yR޹%_qr roԴ0/FJk@š'|9>_2:~Uic1j3~ `fy3te:e`.cYI'TNi"/=lˆ`~CtYYnޔ{p3`Hm&8cY&sƐv&dڭGuMj# z;&&' _a_0|t\mRìIx,8E3Rwc`y Rbxyj $K ނLdZu`ԴrnK'Xy1曯V65vcꘄW@2._|eBYfI%q8"n=rtՋPBC0+:fݒ} ]$f2>m b],&A)s`=q20l{%| )4YJ:鮥'-|GH{N|AX^3[^kj_`<~KD{|Kw&\ W:Ýbn9CW'6xRx6SWdFN+KhAS&t~ n==GO@5犒g'F/ej&GM=_҉ѶRۏyC]GZ@I>ޖvD:վ/ńe!w 9Cۮ7Ow[ BNkr0ȁ;{<0)N'Ez #LnT2kΕg\bg3cDG/7PgJX3}O74"cnzօ/r?ԃTS4{ubNG0hPBLhy6>|Ko9קd8zp@clUy4<^8W%V6x,=jo!kHcy-"Zi+“u>dC]i8\4ӳ*?iu8')y65YA5N,Y^KA:7ob=T/dG*QG,"?>e-)7CiT{:-k'G m ${VɄR_!t(r%+_NM{.mq{R(K}*MrCO# \!?.OY{|0 퐰fZ@Șya%ؚgAuz[ϵٙMkOySQk5( R3ZyU[IQx͠Z,3ڨ :`'|ACfVZӚY0HJv܏;*M}<%~G6o7c!)Ob{N!K Xʡ;rsI9ԽO;rV80Ý?(@_o<[h=~Q;Y^3(4 m szIF?4ϣ~$.}IRU}Oqٙ\1^.%5#,"qW/9M[(01htzN:F\Obbh ;X꟝?}ޛ1-njTx!Ifr4Kz=_)gҠyam(yT1"*A?/]kHXմ9N+ўҠLRO4dOg}E7ę,HL69ڧJc+27r68 { q%I(]R^J̑ApNOJӒXϊi7tW7lĵǣO0+ ͸x(J\zLPr0{UfTW`A?eͿ]fL jH"&[Nۑ]'ɵP[Љhy} a)}* 1 jXs! g|zAu_}`8FL711rx<"J<VABϼAB5IEFͽ]sIx*UVI{:Yub4eWq`|E7g:H2;ԐUb-'Nњ≉|>"\,v#qfH.v+<"*BgA3ΚPP9&51X;koY|IIQ-Ryf y&)oL6 qUplx'`Rg[و;@! `(7N2bORH+x:lRVq䈙h{ӗLOZƛ)MH@'Ǧ~kԞ#џ/?VyzfMYY<>p'ٵ s6T:!dBExp"ahܧ-9/ҭNMDXQ޵7CqĨÇu[f-zĠ ϊ27Zޣ~Zygߞ'e.L/B 1⩑WsIlZݛks>WtȚ < "&hxdbu5JOIk*SiUsz:j[q # эwE&jf|U~˾ˉP?g? n09p񿬗j|͢\Ksg`#qvprn'1RDjJeeuDቧvxNߙu&-ezTPBG.he;/FqX)h*aO b1=3w]ץʸgY;YlC<(|%t21GW]};mXC^Po_˷MzSw㔌byMB[a{6aE8dc[ ¨] #)®` sPE?=z<3cx e7T+c t"a>@abOr) VטMv_Lj*@/ ³DUIXCf+JB(Hx\Uox'ph`~WC'aЊ"x^pD$ɼPٵ#Xq{sl%0r}9K$XUU,3p(w3gFH\MoŠz•fHT>KTPTu}g ឩy߳(D*Ǽ:0z`uG,LoVVu6 sy1׌G3]_N`7Фmǝ[Jӻ9ao?cn>--s$2#G0i`/gxeW:?0)_/P^ 幬=5"A ߤnD:Gh,;AN-?0ZMqʎmw{ u*n!\UfV,hN*~柰LnOkp~}V0zxerIf5<ŜXƾD s1Êc\ _\";S>MxwGd>Q+ۼw7ՐMS =[JH>:h h38ŀ*'WӺg(e3cΖ83{Ҫ=2 -I@V;.mqONpU1oA?4>,te,AZ-cp߄T,_CsY]T\bibHEI)#2Xr8W Efi(z`݀9Ҹ9P:ruN,HlHUuj4^?.y/ >|לDd>{dwt^|RP8Va S 4|>pVLMvtsw@Z'EڝodhhSmYVX`$hK)N}(~@dg*jz,jD11_09uFY̰/bm9=P~HlяsAoz8'LGK>[X}c5k:ۢ3^.&/Tk(3/ʊρ*?bԷQ6EA jIpǃL}|wI=$ GwtyF)G؆v1[Pw :)I](41Q-DfLv=PzUDcxrk$(t}X] Oi Z|$UX_es̕)Gc{/k ~K" e˗C zsfّ[^pK7#Rٮnlazkpy<ٮ+{q< 'w[f{OR^EU?g5 h pI?-caù'} /'fܑZm$kTVaP.$c:egkI$ 鍭yB%4`M\$EHŜ| q4;RtLYyJ\1߾ 3+y.ߧkd'3rҎ5.F(]|JH"k`X/}\ypBJ@z*Ih$o4A z'7[{i»;G.nRBc4S[Ti(9$_WB<+Hy4٥Lxm=MܸƼJzn>` JO޳n1b"2ԘL0RC <;~DqLƔ _(ꇶه_jZ$ۈdl]Yan.TF ||\4h[^t6R SciT8Ĉ̪?)eO?+25kgcC Ą%;;=Ia*fV10P^Wt 7. W,IՂ+f Q?yC.6rELQPܩ2>s)/Z6swD#1TX,=Hv=Th $F}̝*ذ+N_Mx>AHiZ <0`_:]x}>*~+L<):6~^٠3i/ 5piE+|G~Dj?&.AX\iR{U8z)g1I~"VkkɼVo@~Y;rsـul"gDy]WtNdgHSi2]&@/4%!*c@F 5YPBKIyLTp'׭T)w»#v>PfK`뵊p3C|I;.. ƨ܈_2 6,ܚuY\+k,4S,SDCg9ʼ% W=䎘ڒksUQs$ĥ>+ nXg sqکٓFF-ie@8Mۡ{{,>kXTvώ •ziW(ݸeS~״]~D""dd^y;)Ȱ MvsYo[5 O.QUK+ 'G㶳Gq򇯷m9/*ʳ*7c!U )’y%*.Œ.2aKՂG*Ƚ%(2H(ssOyBY5rs hZu֔LތXT&-[NyFHNEɗԩL9 #׈R |yx]|6 $R>3u8ㄲ;4v}bdT}Ѿ6Q$֮35T&[;,t%C=QXyH_>Ϩ\/ex^gt2Cllr؇JRD[@up g> QI_ zhUQ8TUN+6|+pu2sITglʎꜭujR"`O+GqŁj9xG..=bY@yisDQ|}RhRtp $a$%}DY9{lX5keUma4ZQ-XS~#ڬ& `,s).9`ic*Sx"415yGQߺxBs޺uU H%2~zy)1wףg*%-YO -"zMl9ӫ-/wJ*jPQUgyF•fm!."݌pSOiPOƨ@;E">]}J$tt&hpq\uTE$zU `I[kGd<%r:)yBx|kQ8ȰV3n1{2j`>_.yQPJ4e<{!7n]: a+ 11LA7Suu&FFv$v BȞoTh1zJ`wR1fs`Bn/\$Uxتl\a$)~H-'+Zj &Canϥ Hi; B @ _Q[t4+=ZeDDW8Ҽ_TEjveYb[lua˖e1Mt5l7Т&7lnm@aޢ]NMRpP<{餻 ]ppSXi2#^qz}2O_K}*/*Ep 4]WQ4lnnrzɽ& P$`ُ$p8z Cv?'R-CA 9 /ԚW81Ψ-RMPשi@C 67MmMgd(p<}pKgm| T\cGٲ>,̽N@6& f*kR ';cg/FV4=9Ʒ׊(IURdvwKs K(a B37b:AZJh,ɻ]x1cnjÀ P Ǟ4䛎VKֆ"I8%b=+p$}3Eyf-C&ctXL$ruǙXݱ)W[6s̈4)Y@CK{#{vH)>S;?*⌂6EFs*5d壌b; [Y+Y G<Vt @Nqex@\84k;~A 1KT>eH|TDM|f1^-xGj* !wwdg1NyY kRYo)ǟV@AtkG<#M]8o%)O kd:MC39kO"GV2)x-O5XܫΘB >ݢgoy%hg ;#t0vg pk3'"S)gljF?$_*)g/!!u1bIakTXKg/I|OPjGVZ{YiJZp5אx.6yrOktC\eVISD*8hFel_fxgUB`cK-);wITngkePco*sq tKA VkSpKEmԬ=yMۉ#튭p+J}W$$rLڸv xp]Umtf]Og'  Yςk݅@mD.ՁuWlӀBD<' }XVr E_vC#@E/Y3Kל&rxI'["ˎhmdO7\,!Q/syFyT_=ӥznGNPQA8")ʁ:K<!BoXSo|)[g ̞~E7!"Q^%wNq4Jţ>ݻ l]qP:C,`[/o=򭻝p@]CONOI@-s6nmx׻tHC }ӵe .ۇQq+ښEeO__MvNXfFF~Vp',|]65RGP^֒Gės:3%H]O+zPP9EH#W?VPoPaIqi꘾U4S'A?&"CqT.>M&n>Ip7o<*|ػ{IY-?-C\]KR/Zia\qyɛ9"E./CMM 0eܒo_-\lr/O]a=*COf6^:CuGOqLV\ QQ(xjT_@}[&38 >Ch>cFPrCt1;MHC~S@'nmFC-afڗVisר^Nni*~͇}1_?M 3 ϙn9e`ݻ;kE!]П0 {w8ҔeNfQsꊳu'*~ʐ8a5ZH0}8.՛x5  :Ԡ\9K5aK21:h/ <:*MCM0M#(J)tWBATߊ{sݞ&؂@5WNg 9[xY@iL_hJw(;zaE5Fe]-wQ 7a1{'/E%sg'9? Orõ-l}rs1}fwuř4-@ih.JBGiG&٣Ղ#*I/1 G bMj H& 48aG Q5EV9H$[ol2Y<-3*_jFċ)ܰۃA|"򒬲D(q1EOZA$5xٕ${m_JEEɃ<e >$*IW%a; 't7>u#E+q#'54+p,jG/hX6\R^U Q]5vTV^}k]w>zSBX|(Fq SvV`۬nc6L_hCြP :OL J6{NJO|`KWQLlgVN+t|7OW8~I+*ўrSwvlxm D5ql]x$&7v ?7$IfCLIY;HqMѢQGxW^{M̆AC|$D[ZLNKϚyR·&Mg8lq(/li9:աbK>tJJc5~X0T>4ZZCDUQ_־zWEj4U%s!U/7vEyA\7{d); ]<2—yiE.gֶ/} ve ?ؖEP|-n<va64Ac@ Fȹ41v[-gffS.5U]PPSZQy3y$JZd {]J +hL iJ/^%EHu5U׬Npo0n0]ȭwˀf.TO+dǪ-8-_jgCC ř an7+ B K"@HNfDcv`Y K .6gtfuLD9Hv52HN4Oyݿ.kV⾱FKD2c'T꯿MV3ax8gdkλ(Bx!?l^aJ81R Y.,*@%\"'EŰi?AswG۵~=aUk< KB:jy~^%w_򣣔V1`+=:I`69gD(PFV!$d;z[˵* =K8ک!ߟujbvd's@ŝ+Z76kw\Q,0h)&cI7u-%SmJqx0B <ΰ)m1o@X_#m0g"*$`4>u1Rj,puFL*k92k.8ևŋ 70Q׼ZG:م/4xuo|u^PMɔo>G//VN_lgGckwo.(b7th: ]"GtȇTO^;" ԗH:P 9M"&X:8 hMW42(֛n/!87=lZ`@MCVu\uFp@B±cyiiIUK@v3_L0)\`pEy{gߔ#^ǥo䗪;Տd`[NUЁ<lE*)[pU}&1Sr͂m-aW&A><~.SQ/Wt l!}!.|=I7ZRn҇u38JVw'.¼qrss :!Ա}89bũykBtIW{P&rݛ89Wzmli}g;1 h&z!سFvpM(6m6x/QGHZ{ծ(;.rN+[5v?8;b蟈0^A_N@KA&)y%]wÄuauA3?żU,.;+ypV6Y|J=7…}'׵pw%]rbxkHG\t3NM/$6z^hNh[Ox’A!-Yiו?s=?36odTX(̾BY8w)P*O8AO[oԵp3F܃U*hKԤ5jET%#ӛn4A3Ec} DdMCC\ 30}/6]~tBWpk0oP?KTSJVe6? a:5v6_-{ֽjOՍ/'g1 7"xGv*sPL"&גPXb yQ~}nMTT{Pנt]CCps H v2k>auũgRۼ'ޔĄwHY2fLet&T#P"2\"PZ\Oi::zϰ%I";bM?&149؎OZ} Ǭro5yG"{P>Y ʎukT {@ <_=_s(/ZGJP DžtM]^\'נ46 PI:Rߎ|BXTuΔ; l;-"e4p TMb-L v䄾k\a # ~<Z 7澨Bd](Kkp0wAM-MNQD>+EKyfrzO #lE6]ܓBcWpFѳȽ 3HDɊU!me L"^%!^"(\]R~}}z? kg1(y!(`'X޾']W\HSal?Ra eXf@vF_y+XRQN?ִ}z6FSӍs ڶUhBi ܑ82oO."Əoh鹫h=([9gIqTB ة|I* !~UGގ:#y+lT攤Jf46d-Rz47>}S\wa'SF0YP-iQ=p{ !<_),O| O|c@OA\ĬAg^_[?7:p4`ރ|:Uq}~p8s_>5by$G~]Y3.#u-;R:zkFuZ=}K#!$%1Y*ob8Fgu]]9t_}bqCy2aL [BZd{מ3dl7zyE>_G]zY> K6=ߝ+gqWlI Yj6 ag$ AKK-K*|ӄ`%HOe z,9 7,fsq`WVeF)WOpܨ]S͌Fnu4%T4 *S#%* Oމz"OP}(D7MXiib&@D8a0sñ>12K:dz^ QfbX\3)"8~N;^ VT7+k7[e+ʾ ux[; 1IS¼du1 Y\~50Uڹ_Bw,S# uFL JD:ڱ h0~ ˷&Ú?gokT]O>^ i,yG\pefX. |fwWGcTp1v̀(U@V {o9%#I䞬'Og͂.(󫼟v+%|%]є͑67wlm ^@%-XEoҩ|Ckdjk.2]; .7{*m씡{\qz8)=Uzh`:{s"G~ 9R7hmsH)Tߩ. 5e"g}xݽf x`!;J>e˷h?Nű7}~&tTN'O W0}l q(޻l{H)9>#FѩDXJgq 4'[R ;{+o{O/Drh&UZxŽx']#XTbz[|`#c)婆1iq5bq d)}CZV>ϑ7iO[R~Z?sT2t {|WP_#Tw22;ud7yBR^";,D#tFĭǜ#J!~vY_~yA~"a^D¹+FnҿPr 27!V_>^&([ds^6i(p6uTdx-"48JƙtZFuze>>)m6 ~ʠ)DgW6Oy/nc AG=P 'Pc'%7i-m (-GUFw>i֊lopL'w<|s`O7rB}Lҷ`g;T(U`@ޭSϴ e),V/ L%Vrq"EE\ l ")TI]bSbS @JjHx=pFNKQPJ-}?AH*`:nfi,DG֙h=ZIsa hYvhfUw8;?>, ˋf' zeCޮ_#(C= ~R G2 D8<+"w6LNV=3$.vb-.#zlz/e"u!ӭXg$Per$ƒσjd,B[4rz  2%†@&h#(w\>DU>˅!`Ȭ ˘ږGl*RF׾w=sΑ25068"9&yCb12޹Ḛ.軚&?UnwkK"iRէ^2 F88ϐ\WCWX4z kY@,+Io#KhE`IK&h6nBJyi@<>1[Ϟ =FjLJrheg1Rd(+TEEhrLUSˑ3([xFW|tnY}whh JTA-~{,ǡA)%/ ;պF{S6 X{6!Zut7Nhh}?hS`4ڶFݡ@ yM0~˸?'ex ֛+/OVnY]gh Vńȯ:d2mg_WӢ^kCbJ,wC+í}0R95 O#N'"V<ƨsa%\]!#m,yƄU&*!IDcf<⫄jң_$OE?YXma# {=KYosb]y->HGɝ1)|t!npxT`S>)Kkk/[m}Sbݝ|7Tdn<h. /VǓR|S\=ׅZR~!W_ JZB\=Тl߼.pD&JNP$Oh+ 8Mt~g_ɿR<]ɜpHh/Gҭ `2 9Pkڲ,9*ZV`LA 61 ]U+N>m G>aB g/l2Be+2MAޞ^e8$ ȆybMiX4jCЖ ڡib 5bu 9/ȤÔ,h8;MMNfb'ݴPos6D9j_n,qyxHߦ 픧kXK}|NKL'Z]빞ˎBK];z utﶓH|e$97A0'Jy#Fn3IV&EsntV_Z[YTGi A JJ0F)Be-U*mas# \1 _'4! 9ͻIRS30WiB[WQƔ"8lSS=x6a-yMg{z72 ,ߧ)j옓Ix\ a89nR0r\+wﳐqDf%B?+Mÿ>^V-BLAwpw2Z/<4k&*4M ?(*ݍV@me΢HTTue=(FCT*`7;׊$ĔHdХ[Xy C-`n# pr\H&KL{]2.!r~,9^U7M#1Z#ʕ>z;THSdϮK6^tOfvϷ${pI4n'w/% #8P3P./PU•\ίfR]tm#gXgKtVsB{h0*ñr`YT_ 0)M ȊE=yKO:;Tv( otc*1Ҥ_sh?}M)a Lq?dd}]WW•tD G 'y$}4^PR̳1U!oJ^]T9^Bhʅ)`[:uiJSUvg~VrR\YD :!n؅8qX$Z8/ ,GP:Pmt@2$_ pATAЁNu%;:f܄(5*@~ `%`-ׂثQY[%0 pV&Gţܪg ׳->BM }ދ;B>ʾ9੡ZA4?ڜv&Z_vJzcY1uMT k)B@X7 _&  $O!3-U kx;obiwk |q }p$WjO4T,Oa|QL :4mP:rcNTrG凸CmZ]P@gL:W\x4ur,}S9befm:CT+$n8Ȯf-.o,lWN"ގhTRmwS܆{bѵyY py1fq ]ਖ਼tfTJe?/rtIE}6?;FeW^56 ֡rNDA`dK7%k+Pq kh#[ J i 9۳&U3]S io횲>)^A 3W\O~2GjDlErqjqRlEvl_,j'zTzxQ%g<5r q2J"#?NK 9P\-5G(v8Yȑ3UnnmxFbĻ6\< G#ZfXߴZ-x8)[a .X{3Ĭf ʙ3ӦHMu=z,b.o_<=d^LzkKmwynf=yS@pX֒^`h6FdqąYDC_&wt ܗ[/Rv>Y15K \,@m6@I Q5uwҽy8Rlڍ{ԭMbclfb]n >9tӱ+^Q얭@WLWbp] >#6jXR)@c6^}Q -!p2\ K3kb1'cKt;\>\4eg}+sC>ZEK)|j ^c 'fZ]K.,=8qnƓrAVjʧjL>9F,T˙ 81uXg(S(. d@GuIB"Z ;$Ҵ2CKZ{R칂60Pg{=Ĩ:A91ԀCs6|UOqt\NzȬ%D)-}oL}B5z "LxRC4[%/`ѓ5z,i W)*&ƶr(5i#%0Lc|lot},R6VeZq Rm:4 ھSv+̓{1ƇPRQIXuEChWC`qm;x3R3n^9і%"K[Z_AJqՂm+t _)]Ti*.3?y-.%TtY,#B]Px4tyO < A26CMD% >*y[jAh2.F[d?_z Ek̛x4ӂI2뺭?92GJW}3~O>%t qBT0WR.T)lJQ`hÎ8fIJM#TK9  >$x#Iwt-'eS/9'|HNa (:tX_*CRC] u@'8r5;ŬC'^d+MOfclܗ  D 4`9{ݎy4 T$Ab!U Bq?xI[i[q4ҍSI#; oӐݵ%s ɢXs*d <Sc#xvl΂2Q#x7^_@\MTqyqW|Hs30yb~̸%b0ÄV`t /_ TqLPF"ژbŎ O}n]`m4L1׮2VH{?7\rt@'䩻$s}D-3Qד=괝.2(}jIJvg̭Z`1.¸>^P/s }z۞=(w~#ͤ+ZfpKT0qA6`Ȼd"ŵS9*- Fw]apU4,AͮiD@bdRcvgM^DA<3%$Xq۩z$gKY4ߐf<X)gdNk[¡1CvLEo-/cs8K[uJpt4PeG{ Ejz}yiX}u@cv%i}ӵQ%5*<@6`]0,?`UbOz4 n8- OͲ2+X:papuyɎS/._n G>(eS ǦI8wQTЇyAlPjlM4u9:|"\ (WFՒNCbmN 2#iQE^XqŖ}!A٥䤤l`9xp0ųi؉~5;!yX tٟ~"zZ5,$*)Kɨ0`67Qkx^{݋, M_U6Z,T~X" j? /qS̽u3 rș摭P$ͺOVvF,XM&/`_Ε=ե3~~<io% ߻A&!=-= l:Qx^\^5v߶%q`0+5UkeP#cSR|XZ[K?\4o|k XmDupdH`Md12HUPk6(VF.uh7$k ʛUiU#\?S`DžX8 ﻽,ig#vFs9me$` _c{5uh%Ba#r.6[b VrD1|Pf͠J{L-}Ce o(*V(~嗽![_aҝ54,uqz5L̓No&. ̡vuidC7Z%}_l 9M>mU$2p'"5?D.n (PjД-\.xܑ:{=xSlҝrbS`O'G)2=Y8r&w!Uߐ7]:R}$dWXMS82= $~=7c^ɨȨgiuʟudܬ 1O|#wQ?1.zxRm3|f=لk4]Rh "pƳ'єsZ߈dFW>ˣp?؀j۔̷_dBgWFEzKKNk_/,W>tzRQelHyGIgifz ~މ3Z ꜒X oVjM wزr S!c0tgEu`0ѵaL$yf)9Ə jBJS픵Bg9rÍk'r8lH -/wX"\謣n&XK󟇥 Q0tccL_ܾNz-!i^a4fYF 泜X6U]ˆ mԌ"k~t2ST+ s#|.3_d+TBJץv|gB %Teq{^ fnh 'R2yˬto_ oI-BROq@3k@?3 ݪ8>JaZ2fĦɳ.VnجGLOΌ3]LX S2EEeBM]4XLNNQ6,|8evG߄|S" o*KL6D?蟨~r=ۄB8Lךtm&}ڀbxjU pc7I JL \pRb Di,";ۖ9jgR}Vo19G#}:fbH 2 h#,mcVZWj+bugjXfg b 53^Zt>CH>U·ΔE[ᾕ +wb@J^*@TESTq]#qX Fv {5=7NO@ޅ㻿ESoHmRMNTn HbڿD>$> KܑHk Ll[!McqD.[vo#JlI<ym cj) RHif'JGoDSBNI|vdۙdى)X*-ǩ2D۝9+9TQ%;v 4#{X?̠ШlivA2^ˠCWWf/ipљ-UxNN"B"ZC:i~qG# xQ[;VXĈՃ_q$p[;ȁx_{vygX+5aP^{hl/@Źb0Ȋt-Zcx "6egDNNdtf1>1LОAݎTː[^5/zhPӄ h#+u+YV<0Z;P>xvG@ʹ.p{ Cl=qXCYl`?׃t{* {l[+y;bdgߺLZzm{c$,dF| U M ٮp+`h I|nK/Cr~O z3<%,CK> {ѽIȒ8ȓFR~Z"%jz[o$5yCކv3a 6Y6x4naIŠ4{Ƞ*:<},LHZJRpzpx'pHW^q9%ņi1Xkmܪ-98ͣPft;NJ+|aːءos0o}=v_K+RJ=irVz.9HnB k|4l-Clbֿ '͛>sNNi: E&GLoJX TM`ҁ}&,,#{vp'5#=48|ïaZ2RxvB`!TFr=kUOжPfWCC6Xet6liS fumh-]qȉ@l? 7?yUv&e?xLحA̺'5Z<.~UIj {B˰SD:vRf?ȩj 2ɣEG>f{Uo>Pceyc Z̔ Q`N=u掴"qb_ej1P̯[yL5A;LgX+ZY8U/ I

?̘Co~[xŸp,EE۵0)Ooc ucRUIfV?և2Mڽ/\]$? =Fު8䊭nK`B)$*Op]e*? Gg[x/ O3HˍF[z*yEU{k4!);}"2C2Ɛbo/p:f淎j^fІ2:6&"`b}OXM+蚋)+J?wQX;FabAK{B@QJЧfu;C?@)9>C~6[R )A)QI뻟hz Ie`iJCAgY?~hZTxHqJˋs55wCζ?* ki.K! odn#u!_.#vf{O*Pxr []O |gC >IosXd0BuJ!k8z"CYŐFwr :}LR| ]; cǖC+ MU/He"|-l$oJ&NijO~NVEF Ly+r2W) *؜Y{ y-ڂ W=ĔqwT HlSZ;b7e2U7b=/qr=|ea9 "͙5๣<܌V-;\5 (~\Sd`PCYʚ&4}3i4挞XKjU~kC<:>t4gVBxZGO JP9;ۥ›u7w|'W]ʉ%@_h68[PEӉbov |)o';Q n[ތՀ ,]QCTLy e #z'渶]!Mڜvw:d+VGx \x :#rLԘ/dƓqʞ 0TPȄ63n+\ cPWP`9L s+RBplOZgD1ؓ-h`~)Qr+ki cV *w9N`7K@s`y+[FK U&NàUX@NRnj[ 3.=}G5>%VZ7m'Nu}€_ds"닦4-R ڬFh: O4L*w{fzاw}Ɣź+m8t~f: ZzVbo],kq{ aA9z=03)!tK4B-ӀJ.UFM0֐Eeo@?$.[QePgAcp0f#n֩ᆭŦUĉx=(ZKy}̴/zbw]nH–^! {,(Cȁ(qI?kMP+zUC,'!nE2 (s|VO R)}`D>1#'Ȝ_{k8-WbVxX4ʹ;'`$QwJsm {ٵM#Lrԏ0qZH )@ГglCBS3LK^K{G72]}#%n_fj>I|8PQ}\RfPb=xx&f<Haz)9F[滝䌺JuE\r!UI.BN"D1OJҹ% 6Md[!d·m&9rvq%fPH>jn5i=cWX> -d`i:=zEmioUj pѤ(+a"9b`͙;/a.}:4UI I,sڻ-d#g{/HcHP{*t#NLI T23 5 a R&\}N4-4F&hllhqJLJr#⦿Ij5)m+O^iGW§}Ty &O+_]K{l)$z! .{&U3>j ^{OCEqo j]]XBnCI(ف>E:3>2s=_s}8wbj&zIPc8d$ JOkpjX-0Es `-čPޅ {GF~pn7qMD|e{h1$!/ǝ\#?ݢoeC xUZvP݅꿎 ool' r`"Ȅ{33|Ch}GȈz1/F: se57[ d,՘{2j,CH #- X*iz27HwU>N G&$ nTIrB߉.wo/y_'N_׫Nômutl^!P3 +XFQ9Ny)M 0encX y"ِկu]#6jW7֧#״$g&$P.. U&"hPa@n X1/+zRr{3i5K˷PqJѩOu+S{UoAG.k+@go lS77x" z ӕe Y JpK+sO8\הof6쿎+k@ 7(Su!;.̦ͻAgv6(BZ婺I=$*ΠH'|a /S=(-;QEGG=W# -56oU'C LBYq#;yzV\I;](3T8u7z;.<^*L7P,vƥ#ʼSl+iJmf eJP;6/,cwV=SY;+zu,oh vy%6(*|?8(ir@Ϊ]Q]`TA=1jnE?i/$AAtxod*MR|ůgqj0ޖu)z"/Nңb+J om1M/*1pkdž1''ހ($'i+r89\wȄ% L3z<㯐.t ?rÉŐ%Qa*&<ʆ=b׮86ޡ8 }$:ih:,lđȨZ8,Y._畢p17[pǮф׳/}*X,tEhRV1ؼ TԪzXՈ)X3-V@y]&;d@icB$EEҡ["x0oU< )]ƕO,˝𙈁~t$jngDK{˽ ʤ6';B$"Idi|Qc9+x?:+FO9gELi&sᎪ@޺rEwSum.`Oa?=?&__^>X a#[t4x;AJFF-(ǝDu.G23$3&US,gʩq[mP5i O)\: {(%ॕ@A~s _7X5 & e\x"穡a:J|6J֩(nIfuQLYxS?$iݡo:sLX{ +h%"G3UED Oi\pcl[:i7{ͬy,N0f j+h8:1!BitRZ*F̬^dkYS^-91J[𻡇{rt/iUESehV&_eCbX Z<;ګ9bHAHu|$6Vx&GM+V$@b3}a;3bT{`=9ġtޮ=OjB2/R\~î6~}?:} )gزx _P1 j6!lݽnQ ?>,^دh,Iviyq0Pa}>AkQl||(b$1x՜6`?(_U]l Md.UH@uu`gvDm~V7iv%Ga/t5YS +&U8 B25bq) "ɞ #f#:H.l:&k6 GDuv^ !U,gJ9n&yr 8 YJ^Lʰ053YJQl^і8d{FM |/3Mi ]51\hgW )~ hgg>Ԭ~^^lq$_mCe:W)c,H|d"V|x+1ԕCUd#Ɇ1h:屇/lzq:A.`,,GUi~i0v{G__H=0Mޢ em3pͰ-Q$^Nm<"c3 c?P.\)x^ i (/*mz%:h'sv#I<_qCtzE7> ;*bn@:R=й&՝BAЪ]Vr ]>ʼ$fąhٗꗨu\|dt5x3`ϱ~ 5Ay>'ll Yu )S%,a*Jm=AA[z9DNL)ݑſjn|cՀƉ'(N0a*)? P1,͐;1揶3A`e/9K QtpM^pu7d*㑥PqQ|Xb + +3ifuX͎T4-~R Omv/_~vPEJѓ OKt4rTR俏pY{»Z1NILhOȃ(+ (tx,əU>~c;*,=7V?g+= jv@eWVjVA}tˡg;}3=-l mLNRTJlX(>DUrş%#p7L4\<|v(8yさ˥$R:Xfg:5B]'uD9yz>Ei!8fȮBaB~}U l\GDy\q%;F%Tv>c=[73чOy;e__m`w<>27d2E=GDgo .j3ܐ>v!H+ⅲN j^;oi VAj;#;Kq_QÒV{nK /219@i* b~j(P#ƁS#.l;&5%zRC)* e:ƷoI w$YB@毳ngUI%{HvFљ9THL'o+#s/P#NGqjk3f"5( n|l>Ÿr,HT6%Hot`Fwme3e[ 5ZNHS۶~F)ѿDBhblzYvxx1W u|*QryCQj`ghA$F@F''n.v5|ꘄy# /hm3[zƳ{\]j yU&ND͗&^[@Ai$ռqиydz*V]TAї;>YRP/ d.'=BO#cgh^+LK]שy4JB›^kN$=r%[d\^ HT^{>NN>D _<*3fo,!JFXA^܎vܽ`O s~MU4_QvoW\RJWcѽmyKoYSy4ӱh$ %b։8C7g#;풓H%Hַ(*"T) Bpq-J)!QTI;Vpc]azjQAxTUǪ/dv"ty-#{5BcWܰSK-X 192oyoAz R>kL)x $iDAf,^yng3&1xWl!@i]oY8u=bwz֞$+3$aLD|T׈ÊLbwX$<{88j`3D(B/@dT<fY4C{U'3R\B4zmE-*BXӃ0uR;S38U 5NlnX?H)i}1_LbU, >)(pÃ(C/+f Pm6*`]Hl$ؙܛ.?-ɿ~Bl|uHˆp)bZC_ӷHҥԫ4#FOM[1zPdTGۉ5=`(~>X`#-XjpQhp>ze ni^ r1TA횵J@ #&Yi/ei6%|Z=j&ۭ MH2`!@W2Wm "dϴCݷ\c+ES13ʱw?QQ8n-rFc73+,DgTfF}=UH0Η]|#WA/U q8Qt{-^o^{bx8'No9ŨuX 0,,帷_XEHz7;OLBQIHSK7}] c? k9F!"̂XW1p q^b CJRzǘs?ZF4.GX>:0pm8eڻ$!Dnh ֦ Xt2akr`4;GWv,SUQze=˹!wiڋZQ9ykl%{AK6'/!}BǦ[(CC]XP" pWܘm̫kMs08tKr0Ub] ) Z ƻD3qK`Jz54,@|VtUk(nMJcIB?|0%{'`#s&IXmٜuG ,\7VP 0Q˻n OBCB];s-pŽ ec@&csv1IתpFlcNa(wv2 pj֥5n$ ?]rI9uw"XX3xyA=a @2Q_-^[f )&l2ΐЍƷdk8BM `FޘfK`lF=ALtH8ԃ/:.Z" kAV4eB1 2 ndL,\bz Y7lX{3or(젿EP>ܑd:~X 6d'pe ^ *o%m1jsqWZH<6]:f; Mdz[L':;s>\ٵWwܷ.ōę:EST>aU)KOg ƅFvʮf:e㬌?wŃ5Z@h c᷻Ag'GRg8k q)`ִV/uVa ɌVή%@MЕf ,]& ~%؛[׷#UϷu&8~[gz쫶VT+4VQXTgﮉzv)wDԈ`OXlT(R!fu䊤@9_U@wbv6J.[EX@oMvWh.DEg=n#1†yQwt`1f5oPˬW6ڣ!7gš(p.PIk eՑ&͉\' zo٦2NL>KBAhO<%!D q~ yVh5-JMhN[QO!z^<8sC@3#ثuܛEo)aCzYZf1<.g#9' ˂G*sx=T3@C{X;aR6YY!&*өcW-2~~ 3X\O6uq:JbaX=yٵ 5bTާXךWyW%ZbTqQuNRۂW2 /v۝ty[V%ji:Bza&ki/p+^v `QApx.^V&J2c(Eb=A\%Dnk8Zds~ŋٍ'Յ쫖OGJP=U[@!s[Bc2-,ϳM=EBVbP2:gԚ@ZȂ3DXХp@kf&!Qs.B!44ԄX{AqNjTt` fA˷832Z@U#J@Aۓ6  Qfզ@kK+8>S?D#jSQia>.Ķmp ty";)W1n玽wC&[Z)!ʳ@T6kH}y䴯A3qqҨ6.(p+:p!Ct˕"˪X|f'ɧX:Qayt@r bߝ;0+FKCl5gzi_Tv9aga'ށ:U Y :1Fi&}'~q%'y`᷑GS׳ZpK 83 8=mrg8%tXlY)EcwFJbb BoPMI  FvU@:s}"/*Ƞg xfG:T p'Wya4 r02#m&p[A}rv+rqpMv`鈪]z=o$DpϬbl9Up%"1N,^=O:?ـYՍu/Yg%ÒS,E~][e`8l`YLάOqqgMrBkȧ2IAygApX'эqmKC@Mvɴ E )b-PN a2CSw+FHrھp$(frGW?:؉b;q* 4r+H{muٞq =XQ'8d]2<Ef ?:qs.ga k#Py>B}.ҒV [[ ƾ:"b>uO+~pl@ij6$#׮ KܾAM-*lKQ˲aOA;<5rGV;0])% ]"nOY| Qn{j2wEG#jdyFB}>}qU~X ĂTApL.Pu.xtͷ[W{4b.ʬ|m UG[U$b3fKԻ4'4 \Nlu~Ϲ1'Tki<=2cp꒴BnGҾTR2MQJd:7P ƆS&R|~Kq-Gb>Գ%)If3Q|cup?J+}TxbJu2{0!uz !?'٢+``7zdG\µp)+aR]8N^‰'>E+qg:^1WxQ2cELP\Rh\{FIfEm.wCf7-N{^wrzJ<@'T䏨نpW0C @ֆB,\L_[ Wk cGdszDt7]&w"pfc :sBT2BQVlZffPgǹ }HC](*TKg!X5nLO֐!v J-PՈ3l$g40Tq 3D`Z #T|Ƶ$MC^C^k򙤞CHԄaz iۑ%Udw{i M,x!!>~BZa_m1AF? 7|3aZ,~wJo|a*.jr-u5#י!l]ini"Vrms^g j2:ƃ{K:eLAY>3_1vfj˟-I-FtGڪ O J S*q\tu6")k5w^pQ.-uM;}^32p1T>?Ըַ;rZ`^i8"v&TSD*Qd(>{ҡ`$i:I岋G@' WaR穡Nv\0%bP򕻺dۿ/ g_\,VX zҧh򩟝6blSշڮ*%63N+*};I>WYl8;w@ k#?MFJ0M-J%*d1.+Z#,PhlOGrgdÞ)w$JYW!(*+N3(C>w3jJ4֫2M{ j-*H>ҏd"K?咕O!(e1\ԙ)z -Fe^\5Į#P*t ǜoѲN:a.Y<-m};/|wsROc(wV7 e Uv: μw/Z؁ZUkR@[Kpcf5hsa`[ftVH2 n7}=q}rB|cHw"=,JF7]k?{̽$dpq~V\ɪqr\~U 'qW]s=+eb߱TҢgvAt<9=lB|2]_77ze}g~$EUɦ(3^ѽaƑmP+m` H/gI0:rO٧$]f$'}ٟRՊqxdl.}%Ў VXȶ_fTǻ vBѩ5:g_Sr,TT~ưzjKKgs2؟D ;bڅ`~+/Kc}o~X t^QÆ It{NxS^>l*1X=Ch3#'c BY%-HZa4[$Lx/oE%r8MPkM%/^Trq^NRhmʲc#VcY!fU>M0W,oOibxT̚7; ; =UԌk_KurxH?xq3rTE>JBm+nǫ_UT+'ej)MT0PLe-I'0eF>©m~;n0f#Ғum Wd?w_CU.ΖN.< xK~?&v#u{{5beǯa"5<3z.*+憬Qڥ"Rz74$6~[-R-% xVs Tp# >/+@1HAZ7DqzƩN k8"Jljb,( t~Ǧ_Es$T 21` a&=3qα`϶[*ʿ)Ot"8tPtzO: G6W:XGf,ɀR`bDrosoE"s}VBM x?)Qqr\ [N-pϫ=SkBͩkJۆϚb+͑JfYOOnEP3$@Ѝ!xoUaa~zW`o-0",AbDi&0g K7'b i =0VP_((~vfo.W4}'א#(QD_xZ2'%3^#tB>$dZcV'`3JjlUȉy>Q')~О_i~!ud `*˔nџxʈ7-bb }{d׫-sV3V S 3 ri~Z|B.O`@v$VҡvcA52WGH@EW!~hwDz Ǚ٬Šʙ~jWn֭^@JUpDj Ix I9w.XcW%׍/[&6rq>״ٹ`*TTkW$ɀyPMcImKԛ)AܠT&(2'|0ukS4xÚn$h HJ %lYlM4:r_oAȲAv*鹥^kF 'EA$4yɚeog͔$ڗ ĿSRD:=J &q0v(hՏ!͋cy 38DyRT>QQWk3=-@}/&OgP # YZ ]H2q2٤؁)%][RV'F;IҜݰ xV̂g`Y aD܎P|S^a.YDRT!7O~ jT%#hG+Fj{( Dn * ΅!-mCI `V뀦ԴG: %W*3I_L _% f-뛐 A*(ˡrcIu c9 : B~nN +BՈ/>f1GA%,nKSlo@I/]kCgDrt)8B'jBjn|a "Eo8ۃs#Z_ӈ!qȤt}z>#D˕ņ-:$W\ GIzYK[j38=}`PF[0 , ,wsqzg JrGr]b {uoC<ձZH3nV  ?[ZUiiL* I{@(G1> >CB{5ߎ׬@" $u'SO\8_Gݧ̢{<堧Ϙiy'%ZVH\M˗_vffl!$!M`ۈt{*yFRJЕrUAa2J!ۊQKw߳<,xESQcYC3N'Ն&%d)FYlaK.ŷywrW'Yd712˦U&ioטC+|u7 nLVBdw2qbV3XBY8]dObG{]:wZ uC>!o sr1=?0ﯿƜfq b'8[X_ ݜ:ݥOq?XXU$tp6oe 46CP3fK-s.9΢A^JW+XYĩfeʉwU06kr!l F?f nM3"d^ANy gFq8Ƕsjtfb˃yjɈϖ &䜬2 "6׫*W/\%.u@=Ti3D (˾o-Ƅ ê㞮~Y- uAb1F+/ޚsGn`Wq#|1H7贮c)r僩CI2Yl0}s{4 E ipxN.F6Z滛o(]U.ɖNPSTIŃJɽ&A g7WpZpF+o0(T7# 3j]?ڼgF=xoV 8NTÂ@`Y3UsK:zoՖR;#"ؾ3bsh>Ք_VG6!=6]s"f$-t|4 ڞ>jdfy})IAʀǜ5BHhT*boD1\QnВB7Q#E(Z,"D# RQ8"o(I o!VQbQВ(FWywlU;*si Qǃ }4I]P-'C, #¹B <ξ):)K"=wG?7?}~o"ogNSO56p6)5.Q(u3 !8yt-)=럘vRu Vr8$u~7Xщ)8ͷ݀=f"pIͬ|tGPkW a_}BcxSh2RktOJ#r0xO/K[=^` Jy :V.|mTv6gK(kSc`E2=7"Umf7 2rFX2P(v,1YeȮxOit JMDGMPURcnUݗQMF<Е%X";ˍm "BXV WpZY1xWG(Nn1 )RͿU>NJGqދ._xoLǎوoJ>:[ԣXUNbOce=0-i l8CÇA@0 dzMowIeD (uxS;`ZC#-9{!hs6 CwNW:#gʡ`2B yw8]v=y*NϞ{gi}/kg2/`oɄtO64ITZ<쑃Re= ]Xw7d@1~_COO'Fualzp cE;(,r'Xģ\T 6RDl?89):Xļ>a1 b;{u 7V> .AA9˚6I CR׭mcly=3=< MhO&S]=q:Fh|ﻝ͑Kұ1/(zk<|x` (uF9Q ]Z|Sq9 h},i;4^i8m.*9}TxT!pÉc8䍼 %1!zep'AB)m3A7ksĞoz6`ԅ@<7}oUln=q,٠ș}?gj֦uu,$Z2.H FVY\4 /Rґt W. ej^USD15X ]FNH ?_ :'Y8nduei(B.Y'τxz9@|3仫M@q–!Ak5cK=Ôs"6?9Yh"Hґ,8SUUVTj#0k=! gҪb?h˷ r‰n\<)7&%vdb FR^fS9*;%YeF7e/1&Umt%g'IJ~~p. 2xX` N(f* ڏg<,28TN͜_m0;2Py{,W(/A]R.Qor>t2_\M ܁mE4n)9 *i: oHğf $_]k;MXﵭF3>&;8O(xӻG=pީGoXan螅oViTҞb[ߵJgd6]99,ٗY0뫢¸pa6r+JfR+04:rc[vG*4tMK2)(!|3HW_l?dhTqU1S-koY^~?<0h0&' ,r E+mx#5J_b"{owD,<9 2XۘHj/f|(f+wD 4p>Sm} nZKndo›4[GGiNf@jOƒm ,5ãZ xV]DMm-%B)ȹ2'9ZV=?"\S#mZ2 eس?'iT vù-TIV;{kv? I7#;t+'HbZT'(l-pߓkz :!&'wz *`/B̧X\Q'.Bháj Ȇa˯¹54I+Ǔr=t0LP{4f-Ҩ"hgpiX3)5F$dN6r uDe\uBvaCi&8#6/QvWoCynt$w$$|:ڑڧ;{SJG_^-jA@cJjb]'Fd.9Ża9}t)1}rsiG1C,tK)m^YT-3EJ['N[<9㩾 K[F5}8Py]|Q;'Hd/Q9)!,ȵG#eΦfbOyMzx[^ίNXB^hS`T7|\m8Od E`,Z8O@&o3lm % Q\*կ55RƬ,pcJA@[N?d[`[LݵR"+Ul5ZdЧ`[]+Kdr| pLꟓU7,*SN2,iM$T͗׌;b!['*MgzjF[C&z_fL6ۇq'cv?ߩ[>C[- %v'FmaH-Ֆ@'սBInw>Á|z޻Cl)xGcp ^؝d:9niLˬ!oTلT̳-ˆ~2-k4t//e5?dH&.4Edv<٥ƪT?p  '%NyoWTQH'נ9*rZo܅ЧY`2,9@߭ jd)Fc'x>Z`n+\~AH1|ϱ=\a[{r/GGA0'S@ 3P[z?$/F'UTf^E5]ǟqC9[ .H%wo|4ެԾ픤p^ &գ}$maJWm6k}:DrS$NX 3#|RNc&TMl)&BV.r28TX}wDN^O+o4~GB6dW{-w *437,֛9gWU GCV<|nqMizvB?EnJDB04ۿ+uOg. "ą/wތ6>7xޑ$7[ c'.COcL {Iz໵[ 0=ypp&3+hjLg3qB~@&+<̰zOI^ۏûOLgJ'K P0v].iqL\ix-|#.;vB.)4Huƿ dYΗ⭤Y1f>8?,;ھc0`*T;ŏBdpԳ9eGr\cxkjgRp dk+U iǩ-s;%5-w?j|ٴd>5V~6f/V%Fuf6x޸T$!C!uqki#Wu?2Pq-~}ĩ_+:R/̌7P?BCO\$ɌU.s1 .npa@+N%#oPP- )QeLv-uh`#~*5WvS+fAjf# QWOUɤݕwd􌩨;,љbqP/FfJv7МfiҏFFjEjhW#mUЕ!@;aoߎ ,L:v/@X.K'LWz$w$7Rr*0|nwNN4@8!=$JZ'm6@r$y!])^_ =]ll C*ّ Ƃo_Hr[8U6L-EwVlUuݵc;wmom5S i-2CVAj낮'6 *zcC-ž,TGxJF軧sF 혬c~N{*^k/xyAƌ*L_0m&ǶQ&inTG?DFq^N4v\qlj5>w/ I>%$nlq 1W]϶]_:୞0`G--`R ;C )mX( U\^?VC+YbkU7kؿ!|H|}|&Ԅ 8wlR{A[V"PWLtRCT\p՘,E`w#heqp/]o=XqU旷_R̥}9~!fʹ-!}\j2!nEX`YSh>_QJ63]vXC|{s$+W ljI$لWѽS]lKaY7U\mDI)a@뇧֛E8Q]BCC5jU5$$|P:&0$v$m ?uSS\boпv>1%0&x;l C7PmћE_9HmnzoPƈP̀VM lͲrAt! ʤ -p?tT Tirqr),EtHlE]y##g޾&dDh4l)z nX3ci5o,k@ScjKQJ/hec  szR9YT njS0s]Lx@CɮApcDdI^G @HoԸt\-+"E,Iҭ -Ѓb&憲nI=0`Ix|)A9Bxm֡DD (X}.6M2'/4R{uLt'f^T~) bɼ}nLEτT YW%J7@TocpQФ$s;@YWd~f o?ҥɕ%ar&cnOQJٸ }¼,ó JFS+<5ꓶH&Jd"1a6 OEq#1P&t198.|#^M{\G*]}.m|XY l A$sm}cO9ǰ0B]Kԅ 쮇b3LૼvęQ2'SZ;ل]^M|{+Z[%nTYv4?J09E< nZ+f,(X.f.>1/rs E3˗9,u7P՚AM_rW%6Mi_.0g ̖m=1v[gIΙ6ߊ 1t"kC:e>Z\Љqm1[0^h1tQ)VD`ANMN Gr:e!k x;;D53K"ּϦ8,ί|cí<c/ 7| [N pMk5꘴]`Fk8>6Ӵ\|Ǎ.(sT ?ҶgOD4B+Rk3'T0 &+k~P!˓Iǃ+Z{#O9J5C֘N/zev5G߼uaBu'UlFwB<6Td WKJO+cl zDz!PAqQ{tq3CؘTcdEϘ`}#ŽWWXmPv#?[56{N4'%GkL~k? ,Â1 ׁ a_^@rlW 9 Z濠r^ MA[jwȀGh]I's֩%fجH06s zB*]\t4."=Ľk6 e+juo4ZN:fwµ4=70B 8[F않&RހO;(-CzN*vB?4-t+y?D0a"$YI@6)hnz%vϨ5Hݩ 6..8hh>6wGp6H<' p@xsc[6Kb.D!y`j19F}buGfrѲ5jG]F'p~kFHR` :|zEZBbX:HzW@G7QgOCƃjP/s[=x| Zp$KeA9y] oQz\ħԛ?ER\8f`f +Sg }2eQЏ8cX[( H1P1AꅮҒ=Eb "q2-HVik ߉L%%#02503^0pvhFba9Q9Zdsi@;V:5Y:_ITbX20WwfL9v- 6(cisCM~'\aPr}V֘@jYiS`(°|i:%_&ɣuj Cm`mgq!D/,W2'M?Q2F,MK%3Wh6sQ'no\d!qbXٴ\7iәy܇JV3Ϊt*͊sǝ$0IVA2[Ql42ٱ:ivT l26 ,?S^{ O _B)Ey5yY-K`*? z+"x`:Wr x<)$ƦaR@qh:P`]l@q ;h/)8nkbJp+Hx;#FL7RRوּ~5sqW<1ٯev-/Mo7+1L9=;n ::=KhB:Yh[گ!+[F;ޙF 3?il=9ywk*R$ɲ2 ;^yH[Ė|jG/l=svR~6+YP;fzZ+b i_"ؽdNNǵ._hU2Jd}[=[a FRKԋXU߈?h4d%/[+XR]q LiU[MDzz_mT 9W4!G,B2tXĚhYvƙ/d؈133bl-' Ɲ܂Nd e 趶!Stf)Ōܷ GgZH T|i:|怠fT[.Y9W#6Z[K5_|3>E旦ĺ&{w׵4X/+~O>4+#4H_r0 8ȴr~-W{y,pFn=GAQJzK¼\#wZyFv&lHw:ƚJxc՟,l`0;f1|yN wJ~1]X=J賖WH 2eOM$h|vϵ- ,`+IPSWxDraSޯɋ8FgW[aЇ^8\T5gV\e%BXr! yp#܀i1ӯ6TS-VEV0\ƶQwDxFxR8|cePlQo5KY}~e#F([<7Eh`M }v^~.]+~?Z"\b"5'jo_y(*g Jpv%́T#DWd?nւN@ N tgٴޗQĠC,j!Z5| ~7Ew3踹= v[6Q3D.\cCqRuL#yf -)O`po%Y5ivIgK,41lM=G>z elon5Dv&+]0*_>, "NkAD0#Sjjw,8֬|1~j(oJD-⤠Tk=C ]#fl./iz5F=91a^Z݆&qU5YC3zpT7j_h\iϹ\^'/s-3n5 w a)3DbR"kaQKDž@1cvoe44"GOW2d\I0!t0MМ&.7 5lg h.h(x`wKƩqkdžULUNR:?W+g%=`QUv#r[[:9b/a2%1ܒ"VD FQ]߮oo=R+yMvUpq~d[xb[YH6Ј9n6 b,2E_/a[Ǒ-HmxH;c5SO=$:xF(MRa Wy+"~ 8&a}JKw0*v@`$*~"u<ˌҕ[xOVWVXg.>hYh Lx۠x?{gǶz(iC(')T(2 MM?6gdη7i# ߟ"3bnK'Q]3F&hURW]%"59 E(d(taoua3(UiNqb]y* mS HPW\f'$^ݟuWxMcP7}ȟxd 8@wdZ \aYl B hG@%Z_tc;ᕓ+aUly>XKw_ R3-\ONJG0GL7p#$iJ$uFtMxG WQ^j Evw&v~Ƿ mȍ0u&fC,__9ߎ]!o7y7\~3:=r^t&e,%4M>l5C-2:'9"@=@j]522 GA? @ M3.f ")Ϗ᜖9  وtx`5̗&7K6:x 2Lk||Ojd>z&YCridVL.޵ҹQv}4!A~#lGLe\DIoowNGF}}/רȧNR[QR:z&ШM|*Ǯ!C݃&8cOCm\U:uqdhjө"tZّxR Q;E!h/v:Rx}d K"Chz_ GNA%QV}g<ܫ}{h Ofp">p(PKpBQ{DkxC@/v{;Q'fᦥ0"<4/INT :hH`sOQq紊<=bv RhROIA6Pю@\?͗h*&>s٠x,YP\ v7I_k];4W6'#-@]3vsdmURƐTz5֪~ M15A4!pmAGa~d /Rጉ?*%GJ6lH3V7 8>aP̗*Ieɝ`$`xMFau;)\-t4=pJNc)0j^_2H֏*%*8J6Ǹ/A3B K#DMZKŴfߨs^x0E CᲓ5_"My!KLg~-3̛S:=-  T‚B<&ii02ޝ TSm-/ q&D^84$=;cd1mƃ^7|6F{fA9}8yYxw \<ӣ +kz/~?^NwvfDr۰MЄ @X>yH Kqm{"1L.ؠBu( |7[~R W[wEoY~I;7Ko٢TV^H*&LǜPi57a.D% va8VRXKx)@h;S=?i783j)ۇHoⰊk|Xq#H\iZ].Zc![ W(Y2sh9\rCxW1YF'7?ڄſA0:^"̚W5]0(+]8KP 7BL_ڸz- n0[5[d5sFYfyñPb+Ao1B zJUjCm't*pDDH~] *鲝G*UGwx5hc59kc=2n(ڤ=`11B6<-42w(κ'_ˏ;BkN^@~pj9w{ 'uX[h3'M4;JWс}\-'L5f,l+063N:Gp})+mZ9Fݚ"^E#Aml +^囟Q5`ycbfϦE$գiSɖ>tK Y9] hx/{h 1͢'*[w ,3&1iQnCD/H5G@9N<[)ANW@`!g"ھV 01[e/(wH{~:IƝB3nGXPϔB8j79W[n 98BJAy?"#3/k*O')r͋mR)89,_XLrkWQF@&tӶ{ vك$#…& ֖V@*QfsM3HR4* txDi_15JaL +y~ %^][3L$i% )Zu;d&TK38c$K=P\DOͮH5.\ fn)eJ?hs)snv3`_a䷞ orL"Oq|dI J6H$Vh6͐]uEkIQXT{K© p ڜ%, 2DSӜ'HUƿS-P@1 DED5,b8Ig!MgĹO]0Ҳv(djIfv۹HO/p`h@3Hſ7>%0T>"P 0.j°;n0-Ξ*3`{Xw~R`Jymyy:ju(w%+s iwc'+ ՞efcRlڜ5eJihdR^[缕u!B>~|Pɢ>?жvIp7dxE  )~g a1FbƊ,:QZ;;1}bN2`WƑlK1.sc6/k3j__3Պ=BCA(_Do8dp9 kKaQ\40u~@^3ALGSh{cl,V< TCttUedKKPۑGD!1[fI!,|ܡR;_8mFlԯZ6Q`*[aQm"P>+SRjd3׺1j]?]}5鲍4Kԩ/ܞ;ú&|h%E1eKE=Ysṁ8n&?{ZElj^>17nxsxX;\'2' TjmX#i}Rh|L /oӜ^AEoC=w{ )1{c`Je*'뉜b߮C#)MΣJEFqЙyTIm].2DzֺyK'-в7pjڔ9& 3Xyh!X+/j}kU2ڧe6ZO톈³"w[{tG@R9gEiC,T,.褧9Bkun=pi8"i&BI r;`cSEčθ:UiPQMbBLzwY&|+1*İe8Ϳ|eD`/[~+&͡i<8Z;~ߎ ษeYsnpu7ZDMvn6j3 spRN`p$mMS46sqHѹ|>Ó97s([DnKV+^hFlydwF=Zg*b*Dox?VonEƼ%z$O~Q0,om# ]d\Ipja9xa[b~LP^'R]TLJWH}AC=롸#}hk:𒣔+57?npH]9fJ >5iۚ̈́x9mx"ĉol>{[ NXL+ɟw,QOe|qɇ7W] ױE:O ?,L QF9-uLk`j)ߝvlGRqYomxYb*1-rt7<<8eg^x[GVl+?5+(i:d7 ]1֯Ws0 $E_b||s_>XKu#6}Z@'Q\}.LC'FފxEG ȳٗus_%{/µ)}kQ_zm:idN ןzYv4G۔90aәţ_Q,]+>3pT;8Ad\`3!D5#YIYh" XVt ؖ34z[M)c% Z!-i/BrU9 #~ǹ @ŝ@?39ڟx1r*bkq:s?-8\6;Q ;HiMa;$t5fBe5%qo?6^>PM6&Úኩ5'Rw6ց)Sƣ?XYӇo k#}bj>5\u*'ݙS&(6Ψ^;y#y)&+>aVLw9XtisK\Tٜ6inq\NrC]<[FO#P$ û6aY$(ɠsHYn,[ ፶^mpiZ1:RRF% ΚfMm`>Q* lOxTr&, ^@:?^qڝ=tTu`iAEj%n|j\tQCZF*ZVI]n6~{cj 8Sr 8I/9BahoyTl{c"C,%򿐕C>_5H+ohՓ2EpQ*'0n9mdQY8p'ܡW3hsHcx׋ dbRxxJd$达(26N1BsQoK˥9'Mr>Λk@gmX?kλĴ?Z%"Xd7 6bz4ϜHA骎*Iz͍J|=W,@$x* w'KdJuq~1Haow螄ɍݨbO Ik,lǕ1cYȱ)=-h?QQDn b brs!ICwZ}A=)sk9 S*upm\{|bu1@ zVP'oR2V-"v\pCr <ˤp&n}iu%Fĵ;g)|u e9ҵ{ݨ0A\Yb?zH98Au3 JAaFS+u4aT84fO~XҸP~PZ4,y^(*(>A'Փш>ZX$%,.'N/E'3Vgvǻfy:`ke1pۣI8 W$ wp'mY^#|U!nQcYzMX S:?hŊj/D^dӝ{lSt qKI2I:'LݒδI;Q\ܪ盧i7%r`oM7ARV@<߁h>C7^8iFٲî'ZE'^$[ZOEnrEX.|١.Ӊs"^W6D!$X䭡VM1u_\<ӟ\2K&!DMfVɕ5I;fST[6k ;}o-qϲ(i`rX3J.,C"CC`>dV`00Jsm~!y l?l蓲&3CPę3%-(Jjˤy47t81ЁOguCڈn+#7X9`ͳ\"%jBTr]3P$)}lukaڦ%R~{= ;sJAIFϊ-dê0^]1~1Q.g# {"gkН+f*gZͰyLb%; D5e f*/_枼/tyӴ!S[JpXaחgvN8Kin Ċiz{҈fiVYV䭐s^F>']D vVB.7ͯ|ܱ[ZtݹZ`#|<9]iiɱ%OfoaN hS4@y 88(P%FXhKD6 3M>΅qkӗ nwtLzA.8)HM\S5 .F\ %KYM =Su^r±v[D!K`~$Ud Ö„cB"n}{|X$w7̓vWhB ⧼!S< u Æ|`OKJ's9, po`mwta_X0.9K2_.wrѠv^+e8%ngnAsL (LSKX$U^3[N ov'p]|trV {:Vo_U1Y v,ơe fu;x88G`,HF?V1k_IJf-.`fٰ1U$6E/,H i _Wt]9^x7?k Tյ{$3o .&lV\sIt8|ȻׁxJmN686β|s(oQz /g§{f-tST4 F~z7~d-G <Ҵbޚp$>z=6-Pwi^+[jl`?#j0dv٢*NL2y6wE$Yї=ݚ.6C >I5=(- 2zSqVxCZ<ԤsHS~ZkīlH\R>5G!o6͢3N[b6^dQqwj" d,e}˯޹,mu m?,@HޕkP*p^nѡ:OJ$k=~dLE33Sb|>BeF%k!L:|vwY!#W,JHk01)eNly>NtwW[d _l yrس u0ٹbNv!a3j&T q;!.!yOL5,\\j|Fd<)4Ì]aPVQڹ,8JoxXÁ}DUF$v=_Z<{g$ ~ U=iJ%%}էŵ[>Te1Fn3{XyJMΗ8zVxv'wgDѕ|J=9gG 1) >`-?X8߶ (Qs  n2)^4e:Fnһ0߼OcM)Tu_j{?-ۯd1T*L|?Q&L6TVG@ǟ^e-Oc(t$4$'uh">cJ~V_65r,]X{YZ_=""}{<7Ϗ*` #Y RX[l6.oOT3vS׏̬[mUۼ|yVoUeH;iE*|iXA '7e'Vlu'T@G2B/ NftN@ʓ1X_\7rH’tWAq`vW)nSɑ{ cT%]5Q%ȨeG)J=rkAx}:^x;E=USlHSX0#o{^"PIǰ[<+zFCd M'8W 8ЬG-k&ES-#c3eLS8+-fD__UǙ` ab^\f.XE6KP)"15e L=~nvI/Mcu]/۝|#CRٹ+ ]$0B4H^D|AVQ>U&9 ÚVQb$b˵W`I{zŽ0+k7;<vȻmEŠ)H6zrpDF4XU^ MU/8vtIWrn.Yڠ:qY8#0M큺~PCCi*/P4~G")̡_Umwh4[ Lq`v+Ye_o.RtQhtj&R8O&3PrcL>crFJj"O@@JFG3#oR? uQoE CBpzn,v{*Ed+azdO<\Se;d;B3 35%XznC}@N \Z0U|ή=l*uS+cPA##J/ȚbWyCyߎy( Fź8 s'TihNmsuu? snyj97ˏ2 1;ѧn([(0! ]i?d e%- hMr}QS; :Uq?Sl^ֽ>|5U6R#-Y+ͯX1nKے4`u|_N l3dؽo{Zb^oyDiyKC'!X!@Q".p<8 Z;)TIWgΚI/@d,.l#B3Ep^fc@'g6&8&86jOl f JV\n&=:=}d:πSq1S`,"ߋ 94a_jک(k3^~E9zLJ؅(tbׄfŎuiab@+ChxA36e݀b o7̛ W?_V]'0M5^&֓O6<:)Ve u; aV IO_{.:{' m/@n/'"Ib1AYta!J^HB#{EjxN&E$t&ZE"Gݲ?aXVkkָ5[>#l7[sA%J'Ɏ$$1d|mdl ڦ(7NafHa }?d"oPhe%(4<>&9IۿeIM:z&Im$h4lHQgؠbDrNz ;| :]?2/oރ38qa#7~Er+P:a,(hbÉ#fN_OlA rVP-k+2zOkϟLtYxB҉8E4mߜ?A߯($<M`ߦJ /j'c`!=i[pd aPp7Fq/8"Ef7hѤuo/I%鯬*2Lhu1쬵TB:@k 5:pQ^CB/ ꎣ#1 )9da`]zyHnchpԔdjOE.m1ª4/yv]"-E^32|73G Q2 $ӤyЯ=eAk!c[ D2gI 1z$/( Njt;٩:N/i>bjk= V Z8r8%d{ji0&` ٭t}u^܇R 7tWYS_ZCX Ib;W\CsPϿ{h,>/} 2Jd06c@i#t06}wTB]^f_5>mSpLcG!  ,,>$hƼ/0)q(Ό`e$Ztb:O&L)Jn$5i&uUL͵pܔ+={T!;s?"`K g>El.W!4mYR>,Lvr3kERVU% J{ƤMrv|6|Wc;DHHV"9Mu1*AjĪZ֟Tk ԙy*7FCZO6ϔrw/+@:W>\6.Lj?'eC)K~Aran\h]tK\6q^/fBD+ V}|dt<|WܦVXkw`=,yk:I4U[G`_{w!KaQ;Q]V!}USԑ*]sq_^F]3ȁ,<~ed ex-} JHҢύhVEނe:v%6ak󮠵=c:ɃuɩY.q%8d[+n.{%9-;O K&.1}@F{<: @Qٹ-<&٨flP-+1yzG3ϒ^Wtp;| h.AvZ`U&>#Sd*P)bU<"P$kE2˾҇N!*Ǻ$/:ZCswu56xߣ ?8mK.={U=l˷&} PǕA1G&`]w2CTˇf9gm$}ԘhXe2N5: "0f3m/H{M~8Skܺi,b^l ƎB~0r,T\͡-~nŠz3j&E VPRc4DWf8񧛻8ZyƝBCO$9{/$|%h;n_sX"jl*$b,DAH9^އoESU&`ylSxC'4]"pf!h># {'RwJ)z83r>M۷;aejNRaH˛[R>=HK3#߼hrflk,/ ܘ9sHa\ =Clf>{;s(+DI?='ǐpH㤭KVpf 9L,=ԓ\QXWT{s?nZ3DX8VG]AC!6a+wg(/=ZGEꞘ֘Lfx0:XqZX1k?X&y}}HE%)13s"hkz9<f8:3.$k?֫糒g<ڋl-C3HmYC d(3P VGLeyM^i8=5C'e!$ֺ"qi|Ȼ®n Ыe&A@) 5mɈVy<>8vF*`6<ãbeygS/P^,B0SM?MSB6";>Qapp:p3bhv< .-Td@^NsS&n.v*Zݺ΍@QISUyTE":oՉL=12LF6N/,h}Ί_"8ȭ)Qm|m畮q\h8_.[yw❝[ү*A-s?piI胊<.$ LceAn!{ if8Ru#Mݗw6ƕ ^.h:sK%!ch}8MfQ@JARZ܋AwG@:YP Ul6wq$<<@N<* ٕ~jEPy^]fAiBZr w ѣ$fBqAg)d M42ګ펩׼⤬O[סKC+Rh ;8DU e pKqQV0baؕD`506x~$O3S+SS2s7N7),;MufJ7IFjQ J+ߛ_DӶ/C37F͒E<;Uf}p53&|©S[2N^? _bF3YMԦp[)u5UC?VޠgTij-tBZ_/fZ+)E" jB'/ׂ&9Ck+v 7<ĖprGLC56{?0ch*)DhwBJ~)oOBjX};K54JZpy>PΡsRڗ/abaia,i DgCKR"vL;6]D/ \G s۸p-oπZBeGI$*@ nbU!*KGue)]wW04Č2B[+M/ڧl[3C|_ZDޟwLlwA=b'ѷrZxC3 5xY)܁CVSuGatāos\"dq( $f(K\An RDi8x}\5-w+ zǽU_Sun- 2aVX,AvV'9=^Le|WY"GAծe]A6! qr;&@"ڈ:*s9:R7iV0Yf3o-lj8.s0ήڔ@m;Aeb%  uXp,>ޝf˪d_80q7#.w$$wWߩ`:Z=-|iVtkRckRh܇L1ߊy!i6*\-?vkQmCg{ur@B 7[#dB@%RU+ʵː[!=L$E#TU!_8. a)h1ail0׈]'GVn.mDPiFPWc!Ĉ'$n*j求)5M$HDN"txV&zSfwNv,?7W Ust)o,2N+`+{*LՖ~\Do`XNR3Èh 0MV,B^Eadq(05!nPVPfn~M|EljU-|(fXG]70哽 ؙW/{J3#t%<.8Q/◂wnnTRQºocvq~MO~R rR%d4(W.=%WGG'9 A yl^AW8)|~XB{(S1/m r4qw`oR<$]6I/&1K‚v>3;dIbٷPYwafz˨3k]S\g{eۉ<< .Mί}rҎZ˶n%a0T'$i[bQ-w9ϖH-ЅMp>󭩃'*e0݀l f]A 4#HԼLCaSIOMIx˻q shMRwq0AGeСJnԏT͡X"nF[Mљtɸ>1>5,P =m8B̔X]z8 8fO9RK:kvDtIF_P%c/mv¨h̷?֒Ya&oi3#j qp[#*pobϠ/5E.ڣ(6Ph E& V1GI퐨]-̀1,q?beЦ)/H?wnÍTa8)#|\*;en1+UB8I衠\87Ǝh-":.g3 FJFڧfb8Q2˚ grB1-װzE`*xŤJ$ w9LTM![iˮ YFWM?եu(jSn"mGŝr?тֆw#[^06Bx^Fɱh o !l"rSY*єOcN( ͐>ރg W9|tRbuk/3[_ WS*XZM|єҶGp^JkGC>ard6K$q4y. jւo]mo xlzJ}?ףA=&_R~#[U@s#UP~0rP,`UٙT1x0SxQv} fE0ClO*ϯ*'0X+a݁'e1*NT3Vh4AGTB[,T)*8M0vNYgJbdĆyxnz*c0!Sݦhnܬ&c"ˈĦh;s3MC̫f첽!Vmz'ʀH^’w/9h+4}Y\y1 `; ;P4%a4"jSCsmD8 y'MtJʣ)0 N{Z~+dP}߳@^pH ݺxG>A&`TFwhɀs{_U`:Bg!O–uYɵ7/%_1{,j a]۟(a.-]M(/,Te<&iG\7TRyF`cGM ̞cثݤYxܯҐo_svYw왇y(2=@`'w|2^]ΆіK9Eؔrlܩ=;s|[&w'>K!Eq__ԉdJTߏ%E;U?#ax.LfTRXԈ73wg {rƙ9? Q5rLe.uM=6uw2jV6)hʊ[%>FT;tU9v}u"Vc 7Щl)jիvg1H¿ԏdpOb .bz+Gypi3{pCNf$v{%00\雄WYP5Y@nu/AQW{ILǟyI9(L1D \(ǰR*g7c!g,)NŭTUj6tVI)`c6`5R-8Q_a%e0F},1/l.3mE.cuN9#U< iI:$zIW:ֵ `5r;_0,oX 4(e&${y'R, :̥H| AC!eSc#.ڤR q?@(yp`(To}AY4YYSƅM ^$?YaƢ1鄥=d<Q40u!0+7c ƒqN#cd>=jے `%V"%ꀴ"0<=Hefz_3rhCxEd{iw$c*P0be2y/u1U q"x'; qaEG /ci .72}R4 SsdT.??2Z=LO wd|`כm۝a;2I7@%G9 RT,! Mq4 '2A[oN?&[Q 5 f( %޺Ȅ߮q2) _'aS4Xc}T0&oԦBz2j]5ad Q}:iS c DDV|;dA/4Ic}AФtțyv!⯳"6dSvAtAbU\O$'ۜhټ#LE B}Y)ADNXF/lِ]_' ى E-ӫTw-E"8eD7wB_mڤ4lU8a/NeYJ}{;l!Ñ34J!M/uQ%iz\XP_|)39j%/uK|LJ4P7&؉?6q|jd/:S* [f?zEr,jվ֯E DRmvGDJE |aC,9[n+Ӓ嫯>(C@S2?G0AMU 5,Q`,*%;~yh_@iH SAߩDiq9@Ʌ rOQ/$Zh]>5 B5bC&>Y2f%7œ[S) {h-_b%5?ʵcO Ë=TBd1<8Vim|WlUȴU/DnSaNjuEs2iET)68h!8P!M3}ZgA5PC.+P.)):fuGڏ(|0f3Auڢh 9` -:E:^Thũ~Nq?h}LM>+]k+ Rn]M ;/%p}Ly5q30p ,}iۣbۤע $.Lȓ~!Ң5oiF2BImćE#&N|Z:){]^?bA$l5q3:'s?ȯZFyι & 0eKBdl}S{]}(SULh$Q%ܐ2nAj+_8yNeFn vluj39Hxym QCsOrep*24`@f̲{MSF>ٓYM%WQ&e/ƺ;`CQսQ/?QEjj 遛o&= .`yIv*B κj_$#^KlxU>XZdv3P-1 vu X&XQ85!e څGj `W rf$"DIv#!b_jF/gўb~D-(+E]bP^\t( Ŝ!P|l]Nk1+yfݏ<7٦gcX: A'6dMn($ Y ^͒'?v^ț^W;dl:9}(eyQۂqי1؇ͣ *VHb3:Vs \Ou Byafp0{Գ -sa\A@v"))*0˼d+Y"i/?RfO*E/MjW=!u6 q1a,Lz3Ͽ4Bjb쑧{z `ShI`3K%pww.6{g[]E G w"LeɩQVL@C0%4'̀J)ެdV¼>s$:*P$_HB gpR3]_ˆ |ǥ fi:tno w"qRi\wU+ KNzWW$ eu+y7P B4%$xPX \ tDMbLk|"%:q vDt_S 8ϝ56}"٩hk1o/ csyy 6x'8v =؋b"s LJQ3$«$N:ĠUѴĥ20 Pz Ӏ!s_& ":%b>l;bdCv2|UX(vShLg]RjsfZyFRV4WX1:gw:FBl ?/[[PmS"ZᚴX,֍ҸF&@7:W+\S1 W.QTAxfz;Ms5n@׊{dD4m00֚F+b,E KykyĔ2GH)px7S-n͈0*@N=Mczx[uҾhfaՈɎn}'_m}b8рeNO5w.iL1#֦lR c({3{mq+ə(g `#*:(NIXu,;¢l ]+ v&b} ]keA3=VΰNtz?w)kqtvG#rN<8 k"\V& t|ԓ.ySqTgɲkWsCbcJlpa<=lݕ<,Y3* >ԭҤyt`W-KFbg#-TO1 ,?{ňS7slW5.qX[H>8Rw;#tV*vH'Ե:o}>%6GED7=-fw9`5RI@F- dCPk<AXFNbs [˗[2mp~o?2~J:Q}=:]خcܴ7,O"9'LԁBA#ϊ]qvv9CهWaI}uw g^a㮽 Xڢ켭π909Psp%0;hML*&. 3fq{=c>rR8H{?S; P}$,@)rӺ/ kp4=rU&dďRb}Qbi$A*q"fhVű"*EH'+KǶqUŸ[-5R!A`a$͖LwNznJPc0^ˏ~ҫ?ϊd$EذGϏk#MVYa'{v p &~v+3x-rvMT@=  fiYd^]j:ttQf!˸֖ ]Cz*CorkN!¸l뒶:e1q*aak(>U ED`/Nߵq-IqFۄa .% s>V;bI)ŬIqOx; TPg~x}yf^+Χ`*TUL4 nJ4Tӓp*C)4ѓ~BR3ݿldp^ o7ɌI СHy %9`zst1ׂOF|627+_xJ_\WSX_Ș]K]BQǷZw Kls+1=!`U@⫲A(#"~ 0SϯMcHri\Y1q;V3Ũ؀&ly +>!2}SJCF%ư &zc(#+-d!(M,MSP a\( 3\u:jfj| 4f .=8H3g]wjEw{}Dž2A7dOVWVe#GݖZJچlBV4Q44;iP!T[k}!:6sbXQ}ݠ~9%L1)Oҋ t;ƶFgnc;:j_AgMgtѻƇ8-M{8{AsΣѸf|:Kk}Ϟj-Z&'"+Ļ$QN&%$GWGƞQ~mge@EzH.- ¸Hl-Ȏ2$LFxfMFU(_~?#lԉt!{$;m \BqyV meN X}.ehGa>iVRGO w |.|>(_kc6 U9j~؝8_YA=x4\1-bȫCf!Î0LW`c`#0|ktM&Q˺3_B3`Φ0\?*tҸX'Ku`&΄vP7+:8qU2Mɛ nѴҦQ7or Rc.XQ;Y}!(פ5o&-yrG,!DFɍ.#::Rf%,СO Ow :$N"o€qwU&k1CBs,il(k# ltΤew,܉)o<o\"67.y^]Ĺ8-JRC/gP۲\vrR1$+saZfVt=$Ba:eLo7Hb㚢^BB4n^)d9G%32@bZHI=X*}'^e:2^ ?; DOH0 `9Z;N3mYP"I`kt= ͜*5&*˥%h,sO% '~B$CSM)|p~ιy6 6E_R:/91.p>0L8ڎ8crAPEkOZ ^#^0\;l'kͳ|^b@| 攸f9jPq$_G[aDE nmXp5_ʚl ư`ۂ|{eTj[qH4"}r{H7pE%_ǫ@ /qO>s|Wh%ܯ/LT=.G@%# |e S;Y駵 <+N0 FW_Ze+.szXǼ%fbK"Vo=&DӓySvUW;L ]տ@ em:14KXE #Э Z^&DЩ3,s8yȾqWxoEIxLQ^l/@;+ /ٛ%I߿fLCs}‚_ $;&0A}|3K!\>&%JFX}䂫 |"Fx`k>[-pc-`3Fs $~s{_ Pime(FᶶY!{..`& p̓8vߵ%<&( Y>[!=Yl&$B|% z'f8\(x=Fb+]pX'D ֑,˱Yt2-jѳ{D VR"Taʦ6w%s+CvnkÕPӐ_Pw 8G [bsPe(?}y!Cnu,WWk,q\uk-o=b@&y?n ު"gOjt]$lfb4/7mVHl!;] 竣ةأ?‡kE!pb{Ƴ^wsߦ$]Pd@Zm׭Kоu撰|]~Bɘ|NVDJ~j,&{$GJgJ4߲e U5KHl?֘Lxmr䟀X{f}e' 94ls1'&/5Mjz>X)X5pTWm>{#a^ Do ƗY]fӛYKۇ='4׹JkT"A/S@> C.nM:>-n&Ld)|Q r߳AM]I :-l\oN}9V<갰ծf\+Z506s7EkUDR_nP']k8Zd܃AeY* _RSgS^G@] c݃I|9Uq\l>JsP=j4;?wFL\6&ti:Z:GL_Ɨa?(ڳxLZ_'?Rnju!t4G9Rrn?Y^Nk:w8ۖ}ڨFԢ#c<طq/kO$& ŪY\B5ĮRN] xKfJT>7r ДLԩg[#(^! Hb/MDզ e6-B0X_wGvvLMxMhˎCVt{O|vYpl8p=]# _(XxG@џg%^u,fb7{<Əj>Nэ7璕̻X¾&ﵴ2EDG%z- _#)j1T K8 P辕ieʦR _ۿb)WT.VHN 5NF*=xfp{t-UaX3c1@3mCOu4[s-I.? *1 Èh-Q̀tiޏ]yc uNPp?c͒7{P3hG֌PuCvwӯ#zG~pk1G!c8~(D-QVn(u>{O5Ϭ~]E#K(*ȑN3} :d2UBbR<{M #8o5${LEq / |A x@m}o>9גj3M7yT Ź*ΎT@ғ9|6b4` O2Ω6[6cv9ݯ7?$抃¯rTل}:!mZ5A+I^YPW#e'mb]k;w]]#m, k[*{ .}7 ,edLM`/!l |1!J_aWz5v(EjFM" =I;E/G`t}0G8?|.AO`JowbE16/:ZS$\4O_\ae*7'OmySMxfQf# KԜ B ]BSe'V2C,gC(Jé"[}^!Y4ULJsϥD_GZL|W.6uq#>vl9709 >7q4TԿfeغ< Y3zl8.V VQ %4Zj }ѳy4Eѯڞ!5y*6۪5f"qLʚS Ny!m%j~CfYqlg2>=gw_{nm3n:B*+ysD6얮 ]و&uMHNYqr7e`ΎȚfyv, wNzκ|!Gռ+EOgFRR2Sj?X 2պna1h=:BÝ@azbO7 8ϱg]׺~#Jx^f^2BM>`# [_q^?[Ul5`v7he|ۤŠ@}.:YJojS1űUnƑ5*2sP&/-x2S11q!͟eޜq^dC-gצN8}0ަ {ePwuOeau.[Y`N-cOϓFVuIX'AcZ, K 4 'Iqjʻp.c890w)ɐl] .vM^`wMcb:z{sza_z+KŊcIS9E D׭$ZiKITdVﻫ !Lc ˨6ޛNb%gQn۽.!X>pɉ$ګq쀛㦚Q@ m BK~oosp"Y~Aj/" ȡ_dnԘV4 XPg?_Bo2&Ҡ'w>ٜÖl`j:>72KYbɛJ;0?6klGG*k?Juԁ ѫʟj[aF'"م agLM5!ڃ*&=_wpIؕIdD{ Fa11FBd-Ek_㻙D̶ 6cG8YᤘM"vG5FmLZΛ%M,~6$j!3+#+^Fl>LP{oL!ҸXӦktQRVq0UNJHJ/cfg;s+`3z_$ڞA]u(="4PK$7]2 6Zr >jgIʮiLjiseHm8 5'ޥR 5Lư;"';l@?pp lx 9ib"̿uĶi!FZf&+}FBg!"5l(U[(Xp8f)t A8e H3BNa @z"PAG|AZfzD%:A`HoHUs6~4kJ 32>섥\/&MEL*w!=H"Pt}4&~n|C+=Uz^*BSh";3a#jVZK7GEfo2?o5棜I A[}~V,\d5KfDoWP2s=?P#S&|9}tCdtR԰ѮĔ\#Vs+9B`뀾#ҁh% ,5Vyq(/Eu1@+*"cPh=ON<Ǖ$r.<)i6&6E.鴙NƦO1f@,",<)k#NjwFkRVG^e9c@!$^S#,?.`iSB7ѓK(\C}둅Au rquˤ%4wU$ЍpŒF/ǵyvJY8azf<)-Im4Y X^t dgG˳ۘt`jjwV(e`O `48dm{ڤҋ]iRsrإ#xz:cȤEIc+6 X*boG\N!'/kwBuOj_ejG؄N> Ti#UX z4.5$6Xjs[! -אƝu2?!j.Mj'9/IuJx{fJ=ejBd 0 HR`𯫂liW*(x~@1X Oid?dFKS~TBB Vg"-RdBtQ'vpj9%33D2B3@lh"% m$q-V;^6t2>] <%l3w !2Ҿ̕@$U2NڝaŃmF&RHIej NzngȚou=U 3ꕡ";h7:3x׷L/l0tk]'#‰wy<,7ϝ4|=8K|Ǒ jJ$wPn`Mm3a%/(,.@û]:|{r2pk]I8V:*yn,%…54RA#~g+DbMm7 Ily{wg+Ƙ-1I‰Mpw^GRXYMfgy*5k 9:rsqʍ4nL+0fk'6yW"lVGZ\ךh,…[nཀྵ)_ee$i.V#U$@s[$>(3wAe|;?ekVi\c{%"ld $ H:%lf f.y*l&8 FQ g RU <<7c^F3S)]$PW"1Lk1x.&Wpp ]8 >[5b^85(GXA}ow/ì29⅘Ċ*D^*d0FLH\ M؂ŷ1J.Pb'qRwb*)b'_N:.lWDał<qeHv(Ѹ,*۬g%FEdI{w fceCcuFNs9#It`SPd> +4 V2 8≎+fXQrxv.nsc6-emx-!Mkz:5{GH"Q/Q>YWⵙ4h@koBf.V3>M(yD}F"F'Q6Tay 8DѠ-6f@;jHZǍvhO5Xq` 40I!\IԱ݂=M+h~=yLNξa!:߂R\vur8e\W}kɰj[*MRߌPNAl1]xf7"5CB聏] &wӗEj Fոm[Sabzw-idȑ,hPm h>!9&g;>(@B#irad|,hu惃P`@b墯dg=z ]vS^7\GueCTA?/{qr m_uMQv̼4;0>ԃm2ْ^1)|s\R\$YlQeнa)QsdƠC-mK0 Ɯn sz+J64< ڟP##$P  Y#S }c4 Xttm{pGqA-yMٙ(.CW?ǛM*S@}ٽbjuݨd<©Hc6J?m)%φ,UOKvNy3֒Hr[xl"KFv/s'-Mlz >6[͉> TBHVQ\7vYF!dJ&Jm?PՌ2q P.BEu1sToLSBPP::ӭH.y6Mހ }Mu[=#K@B"]Cq@悫'MhKPn}#/Wu_-MSfeb8Iǒ`h4Fc{Bqy':.ȁ VٱGAgv'7Q-sq,rU <=oـTx=H/d BOȩb$p698QL48nm VbD@3Iv4/JN#x͇ ŕHE͑Z.Fзu *qL}-.0>,W*r7̗xX 2lfYا9CHCVs[ If7aܦC^S)P'"ϣq SwWl!K|Kf!q #5y+2 ˦: σ1f ZT]R@ϔ%g 43Ԃ_L+O^^Tezx7 s 1 ~:j>q3&5ak H't`%VSXvF_G_ytw0Q+I.G<K>=:roDTaTl] 7KI<3 (P${.TtTÏta|653yS$6$1|BJI8EmGH@+#| 'BFerSpS>"BX}NmY3b@"W [(ߊ39E9XF"|sK=g5YWJHGSE N#jƚvi6Y*ݲ{4 9D7vۖomjDsrxvSac-j84>/"r)50?K6DpQ vv 7E6xٟI"ҫ |lKvX3@f$~txmNd{R Iz$<+ܿyEVN3B@gmհl j˞OG3FG!r:o:[AY Zi?GƼΐx puNZTd*2T3۫o;*>gVLdz~o;-KeFYaۀz-zNt>-̡".T?ܐqDp&2"`$yUE.֘֍;VҥΙM|z TwT&M*M :#hH.vOfŀFIUajF[麃$iBAo[ym" Y grւ9qN Z gctZ|:#̫$_'n*cҿ.,xɻoztcjVdmހ:Ct~v#ē(`Ѷ\]p5=Fgafn[< ['Qp&3H;nE *Za&<0"KB%g.3vȝ^ d Kn?)PۤZe)B ֥û0kD`DG2Gד654]3njr+6Ao+>`ݳ_:ouNa刡zx<]}>wAH|92 .D).mO/"p.V L~XQgA7b(_rfͥuef5&3`¤ |GӾd,tx;acGd\0z: M%`bM,Ȟ@Z>7a qQI? Vj_𒇂?~9P.Z=K[b;|P+L02AH_l0fB&t= [4XtK~oO ZԪ?vx ؄ooɺ~ }>mCYuXg[]mV}VbJ+@ݢC؍Nn"fyCYo. IӢ/Q# : ~tfzKc^|"ClQ/V+z]խ aBFATxgцSجLhoI֐#!xߚpSӴlt[+AkDށ9b/;YW]2\ K` /c=Fj_5*_H_09-u`Ԉs}^*R.ْ/+_4()kBUtyH7tʲ#G ,FmbS'% ˱+ƅj7ayONKY8*Ŝ`8aK/Ѽw ;G$+9Fj$:r!ؾ3ٝ(3A}F{Ûn{#cib=Mi6=)NLXF?6[3@K%jo=P d!D̛ %_N'R4`Y_Wɭ+~"1-iܤh:>eC%QtHœ"%x+i@\ ~ݺQWC;ApaW=s}RbqEU].b |>lW Vۙ4A\6e|f5\Qls%r R cBM"6*'D\ ΧqFw+n;hQA+x8)t2AԽ6t)w1{/mA#JGTh89`۫*F |hcYi+ܯ~,O; ]2چv m<&N4Nb=Go l;i~qK F3W^”S)Er{ɪ]ù~/dgl_)i (Xeta2D2|>J?ZCUJ " aҶ" ˵"*ɸ!V2TXD;ys$1OZ'6*j'FX@?mOҊ/laQݻ|[f[ 6gGIxXμ0nu N!ˮBݻ!B1SG9U諟WQ1A "HdH5{W&S6EwH l?t f1M3C'5{+YZ{&N{bR+b/u= Ӡhsh ]D|l@BXruzl^{68\|݇H,bܕ(D Ӷ:י?ZbieGf#4VctDL;9RnTΖwG_X;7tlpEhJu|`(Faah6•Tݴ~EvgK6z1No|:6y$s C%PR\]ˈ6gjF!{vCQ(2lA)KhntKKFB.Wnbo¼9Ip#CG&ϴ^ +As7K@"M!`+vMP{L>%C̰$C$GPRMG5UÛ+lU`f rƼSaZvu/hю( W=$ S&'#^.5J\1cR ) @u#7L?N4u%el]~`0b7<EΉքN,|NN(Dz>q^y_3 RkfXT(|d'W1D&ܮC5<ʥ_Ec$plG!SLvI)D E]iM?(I=ˊS_?mh;kc+!Q U@AaDȦc%ѯª 90eűCCOAD\f$U < 8Q&HeN*+* )K#HxnQ~ PС P0rnቺhdުq77y0p2Z^d W& J֘;L72KvwIo2 GSu!KcQGWPpXAz>O\Y s9aߠwI;^(m],/`ieC߄r'@EMdDZu]9p.Z D{Jg>8 euP\>Ͻ!׃un gHr\@2SY`6nsO ~;SyM !gr`|&Q?ĺ_ĵnD'/f r?ڰʚ8pT fan%FXSgi8r0oQ_-A>1%/ݣu`{?`h;ct}yԆp>"B5@Y8m!5gawPl]=8=i{ʺedHhwcDDH; U0ς :3[ %gFjX,tP73-0]2?)ͳs!t. rk37lsZZU:! xFW$ sul" E!)KԅOewFIHI.T3A'42Br„=Q&.XCJ A֒G]~h7?6<Б[%),Тr"qnǝ#2)OA%NϦXxA`P$YKhh5uAu6u؝A 3(Lv,hJ\*T/~QZy! \b/ c k"8xagͰw{u_ 6t]Ǻn!31FE60h?`T&m'#ܑc**wP7tHUFւzf2^OyjAc~ or9nDEp&iZvu\s]';  #5ge[gbEqEH7$> '=3pqN2\%Z.HHn[vP1jlkibjNn@ ej5ZrƳwT[i#Ds`pAӕ%ɝhW9bv b}b8]j7^f4G"jC(EĪG3]$-Ac4[Y+)tvU*FJLm)rdsLJvXkj\Fggrv'!ߝ6:+l$Yб]m@jub~|NBϠ$Hy}TXL .0N&ѰQ!9nN4dԃMiCEքFJ4ugtyr шr`ًCprA{>!0a(ζ6dִ_Sm< Cw靘ev&&Gٞ}] s6A􆴂hYƻ[ɎtFG.%@DW_vS 1^.rHR3Up29:Ks3Z8,Zy6ZѦq35e+(ǔw#\IS\wo"/*XGNFss$v}7uO^/Or+ hҧƊ)YGz+|[#BEq[ r3wlT5KEs劮5ES;F nd#S )&&e;/uA[6A4&h8ikh^`W?[eҕ|e[d>i<&c*~azd?a7s5Kf(p'5, ˉUv+ubd\HX!IL1oy[y%k 5"Qy? >^RMjZς.P~cmwhUyF J/ 1N ݐYxjiځi B/lLJ1[2S,YY1'vQxʕN?KF ˹Sml>m* 6/Uᮅ728 _5ڒ~:cHSpBUuqqA2h紁}e8#kjV2 hBA`x*J Rԍ q3|l9E뾭W)7&bJ0G'^/\I٬2fF"[1$![kw ch`Ds˗r흎Gp_'Wcw~p?S3d]V79m,wn[3z ?+zzȳIES@Mv(NB/%- I+hאq!VÆT[|0 |񏹒rjm@ wN"1@wREs|{x#vY\(I"`sa#"8Fʉ􈸨 D*y_0wK:NfR#S4ZFJ ;8(*۝h7roaM*8h&{g/;`nZʘQl+'V\Σڌ莕 i-p >O;Ubdk7BV ]%JɥCqWsT'MDBGe=;YIJّes5Dұ2x_LS !bʥrE6"*[^1FR_6e/;tń!/'|LW0GCwH09*C;q$rȐ1((j'Áur E*:irf_8Vr@ ua 'NP\t[< 'pSVgMEҜn2"C#pۆ*KbHn(<5ۈG"ԧ/}rD'N`4 F{˨Y%1(ADVckȸ! Q|P(` SIWXS3֒͐a~t)\hX@ rJ =\Ř _8+`~^`e"{wzNKna3\ĝa?/{ |eo^)dFp7%g~ᣨFUM$<ͥu~c/.is0[ t>x*ð [Y9$1i TB Q_aX.;4Qdom]Zo u*%ipV<`k/3kLm `21QC.G='u`}f|rԝ\,ر`liXФNlcsCyYG;)[TС[, ?(K$E]-SL"t$@ik(Pt'*lz*]c( V9sq 3"Z-3@s)ckMnioQe}>OHeTfY3~ ܀ IIewO'Fm Rϗֻ0TdsOw%=y>=rOBD0CJ.B%;.f%5 d٢kҩF\^Gx{ŏe0]J󞑩LMJQ#۟.[>gOYr,~}>:JE=2b{*qj/z)Z81!O] 05'#8/D\gVPre :KXB=f}I$Ⱝ+` Dk^qul'< JcF2^Ѽw՘;~xg}LO6q.g1_hf/dTTQwH1_o=R> HLϐ w9w^Z Bs+uZln+8]ů<0_.{hjC/ 5tv9PQ[17lMT ǚo^68h>qۨ2CS?ᅂ}"b#%_O43YW=a(y`e0 ִ#k 2q,վjIZڠ2(/"z}W JcͥN% &-+ƾ=ʹh\Ņc1r\Rk*NAe݂%IQ(J`YSe4g4\(> =eͲ5Bz\ nR:_pK yxl#2_ig'y"tl(w,(&]( u9U}*O%}#8* Eqi5_5A< :a%EL0&{N$F+&].-X9x>S#GW:~4QO~2o|uDdu9?FUEX*"jQ8^ZJŷvq kD1l!ٍ v*}x=(A0tVT;ZQ h&80+Cb^PBg&| #sp'xhnF &ݩM$-k "kBx4P> ·晰xb{nwLޏkӪ .z Ntm+˿C[ YVYO y0j͂40&c rBZC97݉ց;kj7$na[<&3mB6*6z@lZVK!i`5N /p# `r^g,k:ؘOݕAhK6^5l;X^jvO3pЈXjSv"Tol;^![axG bW-ve/9Fz 8=1lJWS(}v\P]O{ yz`~UA`M&FW0N*"6=+rе_h4\J TذA9g̷D0keŕz3d(+1:oYALX~䏑1.b`>"D});#$#(])V0yۊFxs)kk?(v;ƎYxAd6xUӖ#33M Plz'!mހXFT4;s& ·rzP] wM7[n6p0+f쏻P.,nRTtΥuӮˆ^ ;7RE+5qg6n8K&7аP\r ij2 NlU~3JL ãdƇ9a2PWWMTѿ0gs11- EO";C6gKGCԲY/H{j[eMf` J 0 INi žZm2d.(nͻ6T ݹ-wɡ{H8r; $Csc%E^ORw4@$fdŠ(v:JYq%X+<uZ4E(cїWhFu9"_FvZ?H "> iڽ`'k2$a WR^ĐVvX:"5 &OG=:~~1%C H6@-m&,{!zrR'JVb # tP2 Jyr(6fEz= J!Hf]7m#<Nk~4qвa,RC`sCPzm./9!cI蘖\ ҥ9d3,_c)eBSX@WcÄOpj =3KϳMy!딤MqixE"۵mfڪx|D7؁4_G6"d=qS 0XM<"2oضsz{P,R5kHLa3p\BV1JfU3QxJ)=(P#Kc|Z6v"{Hj*?*5fϿԕyYeq.ƝMrI.-v'XQޛ nA^߻]/an̺ox*+lSs~|I}rMO:6,P9s~-eVrնša!PaSe4 uOh&*SJN0F=_(]$X5TIC0L!H[dEn%;MQ!0ɬ[c,FI@G8Ա}Xlo=CzIO,##=D{̮7>F7e^©}RNH#y?̰T")X+u9{턾֢# ;"8␏T8i?|6%V;ފeB"~u7ڂ2xp/P7iꔫckЉ Vm0[>,Gq8@e!31@8JLɚ&2¤lt=ĵ;bQ;6?`mwwϗ ȦF(R_݂2PC_!+Y`aJ)gMKV͈VuxI]Avzh{w'GsЩwny65xn<2fò AicۆXQ l>?%e#ϯ'dD AdGuT@>$HAr{qJX8WtMg1L{vxɻ+V<A"r]AqH5;Ћ(䲬X@.y#TFlo&fפq3wzk]]$ѝ1?:~*LNm= arO`+׾#XlveavG`h\4B譞3=nZ850V)ݚOM5rZZTT۫t6k𦀩;-i9P[^f,m }! ȟ>\8|volI, CCDtN(9GEϽeP3/'3hFw戏IBŽ0^峆U/!f7pde f&ҹᴮI7==S6@&8]oY{,(*1]43k/Ӽ5׻R=*h1F˺cB񈙁b`O eEZJF 6ք֑p [_zr<-$`fL'ۖ"z`yŒV֧>Jzp*,بp8Nk5s kz%vم MnX@si6r5Y@d~;:sv Tӧ]S{k4DgBlıEx,,X;!n1)H^CO_l<ۭ!1ݫeeGQmఖy0t]}}NĢF>M T-S P~5fϵEE r?O%VЃm٣:Lsڸ hw75W#fF|jK[aYEafMiky[/Nk*&Q!%Q8'x\Yk*+iD5e,^# UْMݶ>ۦ aOCetLba7n@".^l~dz\a 1[ċ? ?42;<@@=!ۤ~aiG\ܔ1PC4;} `GV㤨ЗEa.@`sMY%ܒ;` 5$N 8B{S-8M[IgL51YI D8Y8hQD%c _ϐ6iwv6fL(`,pdi拏:YԞ؃ӵy}&'1)QfOCc^V0˭,߲ou5"Y8T:!(6$'sBqr+lëcР^>fRe4 IPNJW`•s#vk"@TB*{N|JD#rat $`e2EXGqL@7aW30o=uELVs~ E4*s[Ovx ^MH_4XSi՛`_=Mrh&/4}?AkG0,7;88 )+X 0i"N^ sD):r쿖[{y> 0U Ƴ=ٽ>84%?b+FcGX,kd df,0"|@͈_e1\ |r}W{gTsM}Lt.XM:7N)=~BM;z2=S8W.-w˵n $UI)ŻRxLejtuܹgA{Z t/;br](Ζ'rC.M'y;X!9|!4Qsˑ&Y W gsk(r}WgSϨb袥7S]5`wM~+U{@@4mTI j<@}A:ѽ;sP{ϨpIOk)Ǘ,P!ᗀڬ .y^*&JM8||0ڝqlJj'0>?9VfI<[q<0'R{*C ϲǝʢVݮILv]>>@3_SB/\Tޝ4 *qOu[r#!fGi:"wSxNLd' lKt:*;ɘSJG@j כʡo($ًA%,Gc;bVC?6t>F4 _*MgUg26e#U>)NCzE튀 !*l;}! bKHuN*s{fK%q HXQ zH?LDn=LډOJkN{>f-^w0>V8*N]ALz2!.ԫebHϦGEqhVfkwvpaG>[ L `ъr@؏ErrB"Ñ?[irOT ai*3f cԁ0$F(b/+fS<6zV[\;2ngkS/U'f <2 &1$("Bx!P-H?(C ]Qgxe]`n$rAEň JYȑ$zc3,뉆^r]-M]D+|Af |I0p3r?5"5}Y{oy =^/< 7&ndrPE/s3(ECz scfP}_ĖBK]ۺkP-qؤ_8ؖm P텥xgeaɹ;M8B{/BODejG )1_:EyK$ t!<493ނ|aX!BfƌK˾5`gOkn( }%L''(^A5"0NFp]oR&VvWi1ζUw'0U1JT(U\08l8*GA@)zXȀ & 3k>5-sHгq{ZhL]򿊼8>i%i}aI:R m1qi:!dvr:0w,c%Pdžb.C O+SXƏiHN*Sp /v4f{DUU5ܼ XBgnP);^+6]@[g_%3m/CgYq|U6<Eaݛ[R>K"d^Eh?Ly7o5uMވS8 ɑ VÛ3܂hvC6|%RJ~[Q* &P]jlV lg!٢h6~lIӇ+*MF;.6P!SC#}g|%lxXhdQǷ, /$_|Y6zcU=8Sұ#}B@ÿ}d_Pmaf{-$Oe3+h頇'{ˌߔU!|G6@KbX+Դ%*AzWӵ;\76G7?y[W5zcowF&Șת15̝롖*t/ GU1kQ#V"90> k.~fޥ~3J6C+Oi|C2z|_7,=+huVxއEq÷R=_uZNR$9`_DǾk8YYMD<@nxy4'|~)s! !}UJe# =h&u8%YQ;3gC'q˹8f?* =jE<ᭂp_J(h ?1y8Di+nSUdbDa N3u~VMO1DV$|Ui>̩8]_ɰrw;GzB/ckeG(KE Q?gΣm'%=+sgLTĞ0<29kgZCa.k%?9MDeɉnUXE0d+bS作 b;ZE#|Hƙgbo _@X`vPnR# $}GͰ *f\ڥǫLǜv@@{aSnڦ iEr=:GyԘF,񛚊fj@ǝt{_t`E/b`ahId/䐰+e1σV^JIm"lQ<Kδ0EعS98b-/ HmUK,llF梥 grO8A@`2\B'|;m~=hޞB,Yi<[f}Ð;ӌhHĖg HGaLQsr1u,iJ brAwL_;C3<>sIzzch/i TQ1zGK62}q,@r upFQeaTpN{UӍw- OCcFǷQCG% mҔ~/Aɯ_'{~4kfo} Ōa:(M!AӐLqv--iA'!rVPVOBDZXϨ:LNy>kGϤ!!~آsDӢg ꯘZ%/(W</&t@$=}%ęnq$,wtnhSxq-&%Nhqn[ݝA}b.q\:n̯exv, =|L$ d=lHjsҰY' ?>R]NM&̧$ZX1r҂u$ysi6{QgR9`EżTI4 HkQonY±Q$ Q0Ze)NMTՠ)wjQdGgkԅ'I|Rjz^i`.9R$+\ Ҭ9M64[]pO\p u@AHAy1ˠpWchHfhl^ۀB~9["ݛA7ɳ>Vt]4iE,Tbg5B&#mz YȨ<:̫zBQ$JqL|%q?Ŭ[2? \*v70^(L#pL8PTO8K6R%k<՗1Fu%sW 1vtm7溽vvf@`#olϒD"bx{qaMT+; 2'vQfsjNTuGLYS3pR\uo   8)sU>.uca2' ,v\y{V4~R5,1I8\ag@A琑mi7u5nzbBj.6ԧ =W !xv0lE FBͅz盩.SFD=J#5z7E4׾<;xg@{[k@ 䵢L6S;pUyF!X!TD'tse|zݙgw> fżЕB-y3?l7Ëצwr>i2*Y3]'>^\zwcme?pH %p=O+T  MѧO]M%!J2tA 1Id5m9)l;swm^^߾pA9䯇X~ߴ(x:Vި>Kn,.^ pJ R-LRÃ-^Z8mϗ9?EI  )`wu[lyū<y<0Ye{2o?9a/@%ŝeS0 }.r)=R:_D?vwSpP!\u֩Wn8$2^q?@'@Cr('m;$.M0=<^<'5ff_T!_%rٟPl}NܮZY7t4?eIB:ieD՛] }uWz5l'@ɃOi. ~݅^1*`=hq?$]~S6UY|X tdjO Y(b}d7c^t^밥}g-%|SOXR5Zmg`~̟0_}$*VZeNhTn ed(o^ ux @BB3::foAϜlq5WڽGaP<3$-Y,yI{C\v)t*;|ʷsjKv Nw _kؤϷa%GtDE:~6lew@ˡ֢)x5n(cϫBr]hghl"IP˵fGT%Pń"iEtH"ӍoYU[slj /!2ؠJ I:~ ?Njd+ b2qvaG5듐lAsʉd۫Ecb%URGXL;krs- Ԯ"Ska];UĢQs&j$ Fٮ1M`r5BDG ko2OQY5 jo#w OKb&ϏNKlA*,sȑ=ܟ?ktLo;=6%QA蛕Ug`\ -K:5p+TJ_Ȇ=2]@Ņrzh5ߟ`Ӕߺ# e@'\Aݬ1PcLyə" %PWq/5TDO5ۧ&UhKD 0=|\os5jK5*UwU&Z_\-% ~G7"vXB{zn265&4 zOE4nyiOMd@PYVou l:!UڣKyمg?:C b1Y%h|t\ŧԎ'%9Ǐ5ag5g|wp#YSi"YT'Yw<4mH)(4k7Z,CSmkkQ]4f EYՖ^J%﹃^yayO\( EN[n`i*{C˄B?0#D,3MU;|PgTg1 _ ICϰ7/a)AIޑҵu<#MI[՗FbCV]nF XAV J5_wNa=xY0F>UAz=;/jQ56׽UkȻIEQ]^o|^ EYcj$)h Q=@y|CKR=a;d 0M./A{,my4M_"j"YJQd#ˆFj֒{{FmՌ@-$Τm쯤 Rgn>yۤ:B⏫7T8]GRl6@SJipX<l(wBMb;+1ًpkƂNǷb@zeꅷ}Fؒeb^"c`rȓ.[g_ŶJNJ85Pu/`0~II}h2g3N&\L Ym|:Se`)bM]88N&h/XrQ.2=ԿLFiX)7Py>ic`3}J4:Bwf2APYʮwީo`-n^ɦ;zCspv鍪(a՜+קj1tjߙFpE CWɫs(٘BPP mX]3_A6$}}&QU9Ȁ #jHA1,#o 6leבIf}Khnה-߷n߃r} >q.FL*3jBzJuqAx{K#˟˖in6Ǿ2EVT-(cY^F, KvnYUdb6>QaG7T|A1g4cp<߷ߏ&g7r18QNA>)PY(oV{;X.tF,oO\zs/j4hh<2l~ v383V4OfFUiѭPi.F2 1y_ dI#WP EMz:M |NFN(j m1]HY'|x%kΣ:R5GM̮cj^59; ӄ\I+$C+]D_6˯<"aݔvPI6`)#A١D$_C` 9!DԺDі FDqd1@MQUeYk΂1X4gq9t\Gb4w"[)4=UnA64qVDUJzbh,GR׀)5HA` ɦ-a4 ?2GIDR3lHX֧5s*H&۩\>Vner&͡K|Ě؜FGmw0Q.xҙϚ\#Fs4@"M@?yEy3 NoD;U+Ӹ|HT (zg0wUDV ; +\sus5qVvZ~'NZ^}M˩a5]&3;A6=E(R+(ŹQ-=H-RQh PS۫=fqEKx /dibM(t\&m!5oC]{Yl ᾹH#5%3a(Hqg50㤭/lEneFDख'1qnogըOc`NX6<4K5b Xa <zbB^YmW9CrVu{Z8FG^:}]]QD;R }C"f:V&+0f3.Kwf g+(\Eѳ2TFdd^4ӏW8Hy_Qh-4T:J_h쌹Ux0lN,A : ?8Xb όAC"/}fI-_H97 Wv~5E1dWM4 |\' &bP ragN<)1Bk&Ld%:@AR)(ZR;ȵd)l+ƤafecHW+!.q|.}"ve+Gd]éh=4"XbP^[K#:D.qݦka R&IIPGt,1 8g:"]aA{;Cޏ@6>%<%"iu8JE~ >'E3^ Hsܗn lU 'zVj+#l wlݣc,d}r|mvF9,P< _C?G{\]drbM zav i&[>F=j- M镂9A`O7x\q^@d7_L@zˡK*.'/MݖHT h3Hbk^e>iG^)-ꤑڷ7ryX%SҜ /Q@\ p\fv0!B-%3KdKe-}#"4񉜆G! DJNRZ{3Efl+ڠ G$wF^՛ QZ9عflnO򽪪OAӅ&3rJzL&Cc W|myppp VJfF9kh In~aUq1Cf<5~Jvh&rR6y T 2b$[" U_4W=팷 l4@b-;A@dloqj-2 }{u^0݈ հ^{Fl۟1pVvf$:s'nulGl>TۙmZV e6.U4̻3fz|~Ihx%@:C 3鄢o =>ߒ@vs{C܌;@n@i6w6YkTa lnzP^RW5;@HXc1lL2U%a%@1<!X\[oy˖ h)ԙ+2Me޹,fXd#K^!bA]?[? 8߆3 ! tw)w|-K ?!Ap"f(G~3nέi rRm5Rq*2#/k:5ʅSB#NhWIiAb 7\S1Z%qN~uBe1GfYu [; ʫXEIU"{D8S]cdmʝSE,)I.\LzAQ0$YE*|@$\ѡ7-sfzkB$Lq;/߹qdf4! --" 'zgw!3%*PAZf]ƊMh8An0)Eۈ0]-LVX".aF`!6,9*lD7WcfHA+ļ9lP4YH[3(rEX f_U#'޺",mcjhrQfR#5=SQ6Cc," !rm]Y۵`[T bdmFRGU4<ܒUUIzر{y"RF<"⡳+?ݪx オXrYwH074B+àJbcd-GĺσK~k4ObG30{Fg+r;ڕ:w6V9dP7/0t%nX#Q1 7^2gE'VQ^^E6 v't̿0UM+w} - $T)3#Gɠ/a [?FzMB13ȏ;bAK mn{E$iHrقlLjHdwI^`#Z [iC qq+C.Di.!K08gSh%'!h&5µl.C>P\"j\>\HQ/6f+:9("7 ^!y;Z)\}dBBR _P4>r(4$Dk@eH"~ð$/ejCܨa:ߝkσ0[;Tw\fY(MUpT^bmcfV֥@\+dd!fk^v|&@)6^&1B!nwFY*6 Qŗ/)".W(=h$Y+A0S{E?㬜 <}dͱb-`m#:,f?){*^ *ːnĀHi/J}~'!KZ'E`,Z5LM@溬ŵ&6Ky2 \>Eݷ[h('fNE; VpQ~o:GВ6 L[>cojZ,(`4N) 2r8`^Lk,8Nn5״8=viO#/Vk*3xԐzgV~zasgS|prX jKP3&C|,:U,)ZO*V:h.|%&kfwtl}m+ )B Mɼ\-P[0e 0?uOzN|~o? 0 i6Tʐt8@v*сbɥ=un>?HnvKϳ5@eb- |q)G-7 𒨺KzַKb>ǫP/-F*|C<%ˉNqʲп} ~v; iNq60’ڒ9v>OⰺHObgyqޠ&mGW&Ec@Mkc2X/#`j%6(b r <' -\ fq:>l`'|fC٣s@4d{9u_ߧauNqaY"AUzHߪ=8C3JShkR==4MMdҶrs ^4?k'XyJl"jFSjWy#LEJ^hk;u88ǓkbA~m1&]bGṦ]7{R6F2纒aNiކtvB( K_z>!ůf #EՑb_9\VLS"jjG@s6vA43TY:vΞ {aJJV"Z['Q@;s  ;a}PS~Z{3Lg܈qP ̠m\T%=y>EIn vKꚯc(s~YwÇd yy~4#!Vji*$o*|M^Ϗ_-ozU 1I7t+-2) #Gd+*Hi%FEn dXc9SzQTCc s9wgaGZhS]U:q<-/uTxMB\LZ @:lM4 ͩ($1G# ZEiN*ҿa]u3YAfp]x@ F([F*¥8!R6X%qyKo34~ .T+۔ʦp(v5kWB$ ¥jBsϩISDXՁ5wOa}eApI{ Gb8B'Ca+X <$x`0.ż[a[4,aZZ%W gF`(}åmτDa%DK#zՋ:}t1[o{:b*<)J$+?".t%>~:Z 5JX鑹MHS!ҥ߬Ky}ȏ_MwjXIBM@ki<>8>Nynm$udot@n&ҙ1j0/8[[nOWsk!iOԋ65]U&He0z!5C~ֲ}Aߧ*zڍ#_18PYQB cTo PxXU҂P\ˈVD\M/#e@&ɿ(Q8آ,ukj9'ƿ$>0ؒft. YYE#妁 xaTfPo /­{n-}Y{ ܄kZ k2/^MCscGdl޹훊**ᇞ>c>Z2qS]9R?!;x7 Mn˦Uܠ+IoR`띴$s\g!P ՛Ug+3)&[JҮF{|:_PE_s$'?puM2QƟ&kp-T/}-4Ethe&$yMmAiA8&4LJnYo`[g՝J T6ۿiy?CDo9 +Č!80^idaʬ7Xj$WJg/'wK,8wL qx:P;:}s0> ?LsXI@ y ~p*(ɿ\7ѐGB[m*E4*QܺMg'de"*0Ӑ? h8gf˗7~ gĮ$,=M.VU &DNP =f5qv"J=RObMIהbҬd ^:[)hk??qYtO]`ee.[Q?.VOUģ0nq?N6Gc@UU_KkγfQwkgӝ F@J11!AyTe=.DrLpn|3Zz!,؛OXkDT铚iz)">,EÑY@Uϫ=%h_j Sz1!׾/NH}!ĹgC{4iuJ(ӑ|`FwЯy2qG۩nET"Gml^QNy4ZzxKk$܎XH'JV8鸮,5i8Q7XUSFn Mnճ\Mf5<[pv:hԂ3Y7»`%j)ftPqe235yB7"wܘ. HhjTZF< Ѧ:_pE4xz2Lc:zCS̮]K a08x]'|^%ne8S uRSuvI#`RzN$B xijʿ+2;inZ0zߕ\@=ȴowD4-r3f];*X owsez=ɩ} L1q6ҧ ڄ#VS$~W^aoP`b4nieK+U׼SL[j$/b99v$Z5!x (Jmal>$|lpKȢ^r:S4V"= W0yv15lƷLSk!gv`ת GE< N=FZ~}T^d Ӆ~ iDlao)d+])"Op·x|403tةLnMܧLb59 E8` L[ugĝw/n0Qf$Q?O?9IaILeeȋYBI w"Y;b nac0`&7%MBĒb•pB%30h-l?ˋ;"M^X^$5[Ǜ>{^q6V="k2N;cdxe5oHxfMtthNsJNz3ihu1QQ_Z6}i>l\ڛ= 5R՝ih˟Zߖ+Q]^1D9,z2(݂fˊQ6@_ l3{y!6}Gx$sf l.}IxQHUSJ,b;)m4DDWռYz;vY rD+򇼰dZU h]8Qݭ vU mϰ!YF`:c? D͌[ƫQJI4Ql6 @M8>zQs'ʚchcPW֍ ;5 5YVn1 j)[yƘHQ[%Y$ŬLd1zx\c>1iWQt -pYdwOyȑ*p>GDK(F;4H;Y5xwl'Ǩ*Nm Q8'6X Th )a@9[*|#m'T˔jG3 }p|5#OOɴXh Ezt?3Kȗ*4D+k>]mL 57&>f_J{~ԟ 7cBlRCqk( +u( ߕm-6.QH?_Pzs[ k< kW֗0JeGa]gyp*KhBJPd)kZaxqy90Jj,-9#_RkʡwQ:8R3“Ɉ#+?o7C 28]MM3ٖKeWb7e 9M:sۙ9ċ.-ij=f9[ G??@׉՝ʖT^w*QAIJrYdELu_"@#u;vN8Uc; 'ifX^ Xܺ%%tK"U aEyESI($+8S}{;ZZ IY|)Z+1)jԶc]"iO[\b$\U4eת<%x5` e^ &wnpP0ofW#0S|݉@)ӁYZ0Z\!܅AՆ=":rWgǵBs $,!WK B T=Sx\3tN,0)* b7nzӥ3rVs]uL1ѤD!H=SP5syo"fK| n>yW"JإhwT\eє#t"X l:lÅ 3sO.#kZZ6G$1:ct7_7Sjq#Y7wV3jZŝ^ ZlFI|n-)d%K?/JhKEU^*:pڷMX[I+╗ C"xW; 1^BPԷ2,KƔ5 5Zl=DJ0BYz`WX))-j3ј)⧣%)wL0%Yb\gpGG叝G!*%&S,zE(IҲBOA詏ymC8\{G(Uh/)xgY 3q&Zb)҈lwCGo~+oWmrÆ#kd)°:ɐ =Ά";0#NǂX'(!!?o(smAPQL\mo&-5j@)xT+4)W#B7 p@T9AidM2@O ъ'WySR2[ ^#w=SȆSđa.@CwiD's Y̼D_}c<i~|mTjY*_)7#0/mqI[ \—r \b#L R%ѠS]gwI+1O|1JA-=)GTTCpzpL2& W}[;:`p6|= .Y4 A1MYQ١C!x}EVqwx pe{ W`&ęz,2zE!16E|/_uvF}\Ƅ@"::>I]3MO긦XYd><[g=U 25g@IMWe㦶:{;ӣlaYm9FS8gI( 5iu "d3 ZwF ~8w6.m4xSh-39Xء+\Qs\5VP6 a8bS{e֯R88IDКDv԰ cAhΦL! D-L չ2|p5h8]QώJŃB | ʝ} 3{Q0=|Y :G{.p!Z !msTiFTVejARXC:[=ŋask_߃$bCޜ[Njj>Yo+ȭ[~,Wl6qVUu5NSkfOt& 8c)ɧ'm,'}{jg g5NjCCMi2v8 ޣ}AoVI92DŽIb}M^&/;l,J^ω7:rli*홌%<ǠpN!P'Ȳb"#D$>9k%$U|[۞Gj'VukKp2[gGGZ{UnKٽm9/py+[XhxnE@&å@t8#-5 4k 7+@NQRhσU(I&-Ɖz#d'4\hD77p| -PjM75yMӥ8=\o'{,/3S8@* 9W8@J,zan4U\mxJ P @!DB@ջ+4ඔy~">N~u4t(-m5P2; hzKb "=KpXKf\Y,b I| iBYW.h72nj"*pFGw&xU j|-♬ {tSO $ysneG\D<쫕N;ߕ*{0&Nj^if*)2~ϖM#9E~(;φ6% MvPșS S,f}\8"5pҲt.* toTIt( qwऔ錆(8eKq-7iy}DϦCR9C>xg y?$nGD2LSNPdyv6inZyBR2u!s v`]XROЄYu"3^ \l,D1PU\3犋6HP9=f7VI;~TUYv( nK{_@9D B~~LIU +x_ RB$-L@Lg<)|̡PZ9x.MwRwvSE|zwD^,HR55Pم,M#dج %wz<yK_5&{"# \x]p?c6_8Ӹ +漗˾kD`92U `ٵPl.90r=/FnD ?OCR/oʩ4Oz}fq+}B<}*Duzep;SBaEb)m@^l/i]Wޡ#B,Cԉx.XWsjJ&]'3 WL~L))eݓwG %q*e 'ǼGȽ,޲ :ydfR8\VNE9V-5 d^SzɅ f{T?"L GKhWS3Qtb],<Ae Re pta '^04TLZb˼ HV!Ի6@-S^x[ u VyZO)6C rq\'؆i 'A뻑6;nOT NCMjk ڞ'X@qyǵ)f@H"NLd;'_z3~Lf{#ZC˅ҘL"n~H_ LV. NivC(D"̨\<R|Y:nAL0^qyi# ܫ<@6|^H7:N, W;}$fٝ;qDfMןRA=wtna╿!;v\(!+ #-7 ki:'k3q{ȗݫ+?dRuAgحʒRpIR7;2v/0+5=찷ܬۃ01R0 FM' 6 ayV9N~˧PGDWJ%h<ĝhl{A Roe8~${ ] i::.M {byˉ޾gڂ4 <hME*D, Gs|w݂ќ'5Bx䅐y+QC97%%s^q1yc")3c$< RM]<|7Ej|t?%&Ysrg梨 {kɌ=t$%9{85'@) 5~ m6-D4WJ * N|(.7 azVeVέL յtZ)H퐻sOaǑ޹Ǒ[I#$%^$$We.!@K%ٺ}wgFIia@X]6f+ʁc)y*7#B\.͖3c(j:862rt_O>'Oi. A/ALj{,M ig8UߊDk;JS{ I]_dEa u'Ha˫0ZXp,L5f~G,E^?ɞ*e~0{I%U0 -SwB4MeT#.`~M{P^9OV}*"?p ?>hlH3XxrQXƬX/.e_k:P6>ZH37A 0c#/\;-Һb$SZK'0sir٣ˉ>߃ 0TG+I9 ފgXTv>̥F5宛W.Jul$ZbX>1 #-vє_/4+'UΪ*Z[I΂ 5's:t.L9`Tq3*x9Z6я/ Ovmڣ&=+\CƕBPE3}[BdmT/üWު- yFz5{ Ũne[Տ/~ 8/?[m%m̎6BB}ri߻ E'3gb_W*qߠޢ6%+ ? >(Ml8?3>-i@ғ c;vC,Ym䴊`պE4dV cy=ƥ@ `gq5UG]?SatCP4 oC2 RoX[9Z%ھl0aI]t _A+R;X!cmoXIcB`O)H_#b4\ -`E\S5ߗ%faO,1xe@w~U{M=XFRbO 23&%x~.݂ԕ#NyF`ލtMѐ&m8oJ _!UR< 7L9J4n(@ӢdKMo)_kQnER"li f5Y3lwH7a Kpx3lr+DBp@y#T5FS|é<6q,7?|M$ДkagF^Nr2=u*־Gف(I2m:y:im/~zlJ:/tBB `:? =ҢV겄?Qr(OJvoKL._8\\V.pmꕌ.k3[E.Ug~@N 3 RU6\IXUQC9gDW M˧k "Iѐ;FiFӫs*gv 7T2}B{J,^g>7Dz#c!Wna|]T2f%0zO历Y vE՘a`f̻Yo;nbXuߨX{PQTwꢼh4xy-t!Q=NF&s $e4c"*?iB4 d91ˤrCMAtl~U}H>18kr6ԍ?A OsI./ x b ŅT:d\;5A=6`M(i6Ll8r ʥ{!(p['"f$n?;mVxʞ te_QjInY{n}AEO-S O[OGs{Cdt 8 >Q_kHxt0.lő5{4%[M6$Ycib]^ ~V7PmU#:00~"$8ߢfi 4=!sZ sןݯ>HPSUonǦ:4H]gkZR`wM)W[d=QxQ?0ٔT֦FvbnRW/ašJwzl1%b@h(xcZ('4Ȕ*y(靅v68rW&~h [W9xK1"j aSQ{~׬7gUoUjŒeFM}8]Յz6v( e}p K(ҚdE%٥fc]U?u%NQ=٦ RcBpv ';RIۺ5eD!uKCYP#6fET- }<{-KmKxMWG(uY6BIr nj?UF;Z`˸<S]m;YvVKR'dքz9K94 *+w 1o?4J|wx)cJp (#a03ԄL2g양Jrx+;y\ּ$KApnvt46Ha+.QioǏ#du*y y|A;)..-6hnAa7b&$ܩ7s a) T_d1QAⓥIm|dq'qq29w%>PݦzETL,i17ឞ@6O9R5XS1B*ٜ?q5pɵ#8*(VCWOsaWX}(P {$y"lZe pB-d晟PFz-X?c"3Sۆ [7 䪄Q`#jEKCj*D-7>y\Խ4ZbƇJـ?p!7 qZMpۇVBnI>q:SLWMt02 eZYg)b T9~fi, Y^k~x$O"dj+ ZWU p>.?׸I=N?Y ཝo,prؔ#}z4q0̌KXtSwgSM.-,7edЌid~zA)@ζGj2jQ 킃MR.yA>a.F [M V*CAK>YSťR,HPN4S'/66=s)S»OC+KE $f =vcA YT]bBn @%gvʰB އ5Gn<3!-5h*nXwɎN^3An7H]zbI-0EG.;cYų/i7C +5f'@yCJ0{644,+ҙI5O8ob;iffO8“L[)=h{"nF溪5(}? nZ۪ß#5́R[$<> 5{^gГ1)y^c83 P&EEᴤ+o4 l7A7, PGCiiǵn'FjcFx|(e?qJ}bKܧ˓w2*tbt|<2Zy#N~@I"f 9Zl"[;`1#@Ub0ذ@hb*y4e' j/̊s$r>͒z׎E_06cb,u!u^'0B!Xw&ec_~~Dk `fzAxneMxh.JNiTG=.|f)`{D9smP6ĐZz'KCHR/~!faFLJfۮ EodR'W#.]67T(6-z& F =yC~  VKfN3BYU @ ٰiB{ò}0Pk_{o/d{}-xjMu'e+I'vh)M* kĨZ7 I{+0U%m%9&B9:F[ң̓ffM mQ1E?8RnX۰"ܑGN 6ţFo/VnJ# 9 K?&I 瞗UZ7 ]w9%_{"lj'@iiyҺ1WPʝou2rh|v0FZ=' l \]C/Xp6r**|wOomNjdo{CJD\o^l]mX˙;ALdY> : &]#3ãѪ.rc¥j\W6gmAO>hFax0؅I!䶔,MK ! b8ׁT9Z",laعAf-#%ZaWY>_S'N@x>+⑈ygn[[RpJEvXɝb.'x鷼dIN.N3,6 f/2=$\3lFN'TA=ؼ$, 4A4Z&1Ω dpWщss?ꨘŠaƪ[3*eWR%4N Kc5/bt3f#^9@f=D<8-( (5;P"P*÷Q:z2?U̽1nbp& -( {w~k7*mK({RmQרּw+j".dFB4 yDK| Qp*$sgmmLo,Ԡh՟f l*~{ZU|v%uT֜Xq)eCM13.H&뵂[2/ '6NRz`A65- ՃRcM>rh@(i G#Ni(4jpȫQ`kLC;M||T/]6D~-ҭb­2FګWyl7́<0 M~'hϊ vߑ̪Z߫iN5gp[JfzWLȩStE^@NAߒ-΋Ic"Z vrE_'W:\:88~/wL0ڽ+ R{&gL*v%Arp=I1zyt*owX#uDjfh;K?%oʌo)>IzpƾC]ۅ{UQ,=eaJXaS%\fj򌫡i £ (UlW,8督 Qkqiu©ha>jߧf0, o0dɼE QoW/*jLXQCwe2@ahhS@-"C6n+t!Ky[P_^urm $6KW( $o{(j2|:v~e=(T̨g$Gr1nI$RWǁ *任|2S&<hDAᰶ?sWrhFU=~lQ 7R}ưsF>~-Ujdz֓he< O Qh&ФoDw E-W[.m|_(!#zpU)06,{z&`Պ^Ų$BmuW6DS;qO\^"^SP vPrCi&H#T)̄@c0EͲNnK (K|0BWw‡2j63K4^oT;K[DրH;@fiתG-r?8!p62%0ڎD!CI[H|y|«m >N8EJ##K!ApVIKugJ*Wh` #onc5mMs蝌 [X,R T5ٚ-X&0aV S\ftE4EIHa0@P2;VrCg,ݮc~f߇ |"s2M&Ki9}sy1ӜAK&&KG>N ]{6h!%l_Yn9~|^IarR#èh$xnUE^ W/x~sLk5Pd2LpT4 C$O'wӌz+jSsCD"lA'CȝDVb ACE,xZ!*iy n"9T[<)NtY7]&8D ݒF~4qFpa1* VLUJ,;.:pÂZ[44g՗n^#",lAQ(^T+Y3u\QggcZ)wK|£Vj$+31K\E 85Ml;1 nZH `sD() Դ=kY_YX@\]}}JWK{ ~9H' IzƉKe}߽ILsYtEǚ^*X+5D,-7U~>|H.$ Vse1~!^i@k m|d7.٨o"Jn1?Hj^F^Pn_f6û"I\_40̋%2CqW7k6ߎ<2Gio:E3pN6!k {b4IaLxy>lxϠn4˂:P kcΥ뻙L{8sYKs+TEu-B䃑;3)y\L&ddeA2L:m`H( TrHd?hkr]$zҾ4 $q& Q%h >b%@z3-R-\,T,`mc.Jĕht~$hXzI`OcOpq,ܪ Hp *Cdנ TMhڕ  Iw|qY~jV:'%f(wc+OjDf̜vۭ3dߚN)>Heiih݅vh1E+/ C0Y蔽MNʝ { 󳨵%u$zļ~oF`׺]lǙ K*z Qt /ė(~,y8ڷ !) B DL#.nmK8dh @̿əMf7A.[$/u˷'WClW% Nj;97YU{oOI$0tH["х_̝ O͑f%ua|:˩`\>t~>$+{\`Θ8Z2+`}֞9NĄ,6hZYnk*'0F>'#x̭*Y׎k&f߫\QS;/EL?JUgCF{]4$ 8dގ!k)$ZRLލ($lG墲f kl9 խrL0Ud &±1wGȬg }k?zY=aNTweEfz &_!`kM5VV3Kդ<2z7,S{bƋ ZGwq_z^N<ߐąvf Py6^N[v9'h2lݓ6Mэ]ϰ" ٿlU" D{+=G^P)[3[*l A;N bdI[/txHN |1kjw4qf}!Q'LkuI TSS=C Go;GZ*.\pg}If_6(3*Qog\ݕqG{*ZV/%*|*k'PThSP(\O>cvA;*gBP4ޭñS# f?z%%|7bN7f+S2 DӒꀄkiH(5Bw)"ge@ؤqKMs[ѤG!xJ瀞\h^(n^*VS-w# mjx:i?]mnoziX1` z+(J fQNeKI|oMRONm6uQlgg.Dd|2*ajg)jnƳ?*K{_h.O*b [ J^|QDwaa̞v}94ZoBU¼ބGI O0 ]f]DE%NK%煂y{=j#@F_1X =e–p1q#LNQ&"c:p'ā4*r+ v]yxץz3se}?BX:DKKRҽ@UG\t5`J@SI I:DtFZKr%>9}mH{‰p \,;ǥ?'9.ĺZF9G?Hk '0pwfĸzs l@p'5xXW'-D>F:{-z! &97:.Y,(o_ 祖E I}Z-\;]0I6{ xY | '0|G"PŶKLgm(R#B;L&!k{!o \ϲeVQ/ !ECRС(*&ſHH(T'٠6=E W Ա-C{TIgd8`2s>9hpefˁ/CIE͡hF㨭 6u^6wI>oڭC7j`*'o B$'M5P^I4g b7Fr80LDz /pYw1>IJJeϻHrr #hYo'>iEM5,y|EŃ)$)~i@['ZI9_S9 }61csH*J%\'"'mwvjDݐk!*e$YÁ` ;pJLnޅ%KJڸcN\ h-Mq MO(5k]WYe:wEG pFTw29=\?0cH+ ‚S1Q䲑+ 2EzȻH"D7/J1vވ)rc-i*"!_kX sԕ.ߠꘉ4>?TYr*WTyqeE Լb͟zIPPv|}R*)^_1p4ڢ&]6dV2tPzc©ͥmIs/LccꯍTOAg3jNC+tQ ךQ<6~y Ct/>mOЙM\ٶnz3fS[).N/?WkdNQ#ln&4KÐJ.$0 6 e|K%M>Ĥ. W?Tԝdh\Kw}#SY;|-}{Vvayᣔ+X$1W wGPiL~3~yWb(cu"e 8*>48Uy*{dZXClnpP'Od j"n~v*wهaPԦSZ%+gĕt bՕ]QhB{īI-\oq*';n cys;(Kÿ$yj`p8og8nJe:o{@oބ5v b%`ceA_R_Æ芣on0jEU>~׏y:Tm0NPryNƪe!7[A*o]\QlWӝpk:]u>EK.ȴu^V\gJS _f,K OtVڟ|6_]~m&_[+4ƗW҅^9}*ٛըff;PUapuxkS<6GG紘26cNfBsKkt%S":3ՠ?yspq3nRUC[=vO|ԔoZτ %ԝI/Xj &s`;KM͐KJʉv0vMy3OENٰoiefIާՙ=@6vRWd`3vdxDJGx/yX"񫲅 ܂=wb"SarԆ]UGڭx'a-CjDо?sm@"bؓ(52껗P00GĨ(&4|hWPrgbfsɑrr* j阑$1 H}O>R5׿j@r˂JY-؈}c դ+)7_`t_aFU6k1aR].(A%`aCaXs_-<XѪ WЁf'?:Ψ;mG t| /N a,^Iv̉_Ӹ/Ep)}o6O;$5D)Oϳ|5}K?dQ߽4(&AZªQ @UfuŊ Y P|cŬln^!Q`0dfs/CboBN=umB+;b{<]t{cev}Wa.yO;n|6V"4f#]}}u6d_[8Oj= NTiLk:e>6ޚU}ޅPIrEu$Q)o5noAXr-JSNC Td  /ˆt3 dH,w16~%ո⣝?TҎ4pP@y ܩXpISzGV²O=( prn(_:qӶ8#-8_CΛ@ebƃt`|Xwu!qEk|ުG4ZI2L;,J (H915 :"ӭ1}WuW|ے0(Ym,UbsDς|^6$0GVI N`hg= ؁T4Pix+(M% /~ ӹ{Cddfo1TؑM\)iM=xvT?<5(ml_-hY \\@oQI,K?̋Rԭ 1FC[GHuwͨ؉XcczF_^;e$gq`ӡlP <@X^3,XZqq>b'zyi\%\v0巳$9!ޗUޑK; ]0ojxx];gWwq\Sf *zkg*30Ê?K̰5"K2֠lL]*Th|xJ17 Uyx~UD MN̊i@$R0Aet&P=)ssUq4i)#Fr” [?Cm&Q: .o &#|^0+,;6*~#ٴFY>+NF|qޛu!]9VZ]$Af^7g,&7R.R ~XBR%RU?K pgJ|U+|ߥs%ءGBS#ZwHXN)h`biޏb_g# $V^J˸Po4Zs~ݩ3NF&pM$z7G %`PI*Q4HPu&bENol{{]`hC3H^j"a4o+_] npDFQnv9,Ō>}^2&=A!Н{t4bfZYV&O}>bxW*>"@Jp_ %İhaJnkMshU]Oj6R5Bl6g ^ 0z4j߻`LoCV0]?H JaUШ[܄q-/}Dv3R[TW?^(4x'eޠ YZǰG Lo54*Ћ5hNBt`װ:rMzfrќ@z"Z# ƓӨ U>]$*ں)aH(M.fЎQjySsg]DoIBuP(-~^E4A"J^hBw{d9Ίv_/'x,ϻ7" k~p)SOrܸØdz,k ȔV7o )?kH}0f2v$8)fܼ?$X'vi+o7 z u%WJ.wܿ 6{E> ND%؂tV.29YGI)E0蟃Szt-tT73W>V!,<V#ܼOBL_ nM)Rm(S XlOe48/Q6uSnI< +xab_-ΩA0/ι*(j彚Ĝ=nI=G9^G &aތ@p!*3E<)\UZ#!՚[8v{ y>8ym%kh\c"~&)Cﰮ4@;B˝t%w})}Y3eTfQgxĘo--_uGf,˿J*7Oӳ%TMX,2 pձZ`&hes5F4"?f?aq:`Yi {[߿\- mb=1VibCO8`+ z*M>ڇN6sVX$M,;NAX 5plO;@˯b="6s9$JyY?&;9Dիq$W~B+~˲ezIWnGUG͘t@ RRD9a&x#>ZF1"c'~kuyۂI~j<FGBI+;v@0O t޻rҘ~p1 GzI^tqAgӽJT[ J"f1¬>jv'g6iZo ;H|~?~xrJFo7C:83,~#iH[uS/`%rjhweD%37<]HI7o_xi~\oqTG:ₜn˝$2ۤѐ*_eF=N֝-KnQS=#ҭ'\/0өxW`]~A |C c.r<;=OhyMtE0 JLQxKFPWW*6am:p>Z3{߻g9JJq)u /F΋^P^\ϗeS*|!nbш>i~r/636ɩ^/- {:{4˼V{D(vRIa8Ca)?Eys۽SLIes7]L @J_̦qyY]e?̒S P) )+gh'4ԓĽIfcVEswX&[FVfJW1Fپ!~z19dA{ }X Sy[X\GE-Vh7X<7|BW+31 v+yd*_:濬\ߏrFG CcgԘ>;}f_2ʈ|F1T4$&u*Kd[ wXHo_c$#d2[8¾;L~\+PzUXm$ydL|҂c Xx*R: mBKbf|[PkR~"ԥ6䜦{ypzB)\;le˟ik5(žJd q n۷D3 eT6:U1"'remT;Efmʩd8e}FyBti'ɥ8!;Hސr+j2OuSqKn߂e*TEB"K-xI2nHp>Rr!ʤӟe%"=qy,\N0:BBdbie]!cMSaC ,R%Eu>"̅۠MٞhkuCԖAmH 256/cx1@XL.95(K ?Qyu*BGzm" ]h[I>d _PaO#Bb :}D枯-o= HBE F U:nzG%KU<{ņ|uqVw@e{kDӂ&-ZJ!sύ*Ϯm:{@^Yԝ6>',\RʹYӚMb(oO<9w1hK: ʤ,]ɘmF4p *|etDv>z;>Nѹ] Gq;01~0 WߎreZQIti3 hK~}]^7&H@Є ⩾fC6HaU*>}_d7+5Qho'$I3+&ng5JS``3{8Z0pZ4+Ҥ ?LZ OȊ#gAݥps6\ 'pƣH/c[vXσ(1\3nz|C1r:k?ZQdוDyp4j3jno(I1hx2$Bp'\|@[.QTV9ԇѐN(L)iFSô23Cj5©) 8ѴVRSʨ?h,卄]83}dF;~u9) lnujV9)o8.a4b@o<7%1QΝ=;*H4,Z$#&*~ t6EB$X"b62ϵoQ |-V0_}lgi#p4*]܁u0xUaSUnֻ`ּt#}D0إC[OTIwmMk6gع@z;&h1 ґ^H$kS0ZM:yvR4vӴzcXl1<&d5mXKE?1Q$k *)KxKNf&85VBq.ƈ}Cx (S%$(L8^kw, {ݐg?F8NJV[j/`tw# l%EO9,zt?SpBj'ad-.Ƚl*5e-C]V*.ӂ/z tVҽN Ei^k޼h)C0Pn\9IQpވ3P8(|~U7^3Vn8Ax- &څs7tW{cplL5vmzTYa2D)yLfgQX.xTQDCLxuziI vs$[79qOt vP*8chЪy-EٮN TOa]@UHI|&$j'1~h TM}]RX2|ۮr!bf58yL.BRE}jhޛ HrcC OI';\&63 V!2-+- ͣ.Jl,/p}԰z*(T!gter#+R$M  Y 5TwI;ރi҅ Jz>P y!텸k& e ܗf(~މ:FV3 ~)H:qۿ`,uꀆkҮϕnEL+ܦBM{XdR91ۇᢎgzeA \`hΨYAvkLs3.횈GY:]JN- bTq+sL^n EY_(ŻOQwݐK,t;,%Yv44,ƿg-'ݏ]Aa hp֭h0NH6ovL UfodZqbמsL q>.A}:Ar>7?fy,~9ٚUCL G~"S7$lTDJ\RғrĤJ.~@HYTo#;Yqs+<]oJ ş?չpJҩ G)KT# oKqbu*o"csx-iUH ~dp4 ;V=-~kWYq XH#L`9sŗRc Bѐ#9tc68<:Ύ!ܑ $?[NJ:֧;6r \} ;V\Uu jfU%.3*_2/Z5}rA |76K,42<}s*F#C$Rj9 , $]hsZ83]z U}BrUˆdthhDkIijf/kG J+b6GmZ+\IW W$92>6l/iVk2OZ4<DinPY;/ņ\ W%T8MX.Q|{@VE]"G< Ѽ A:ܯ22HbxqT;y}\˖0cx0Cv]_wŴ{|TK˚@Q/onĆQM8OA4vRr、eWAͪtǧN=UuOExU|S_#<9;yUBMi䚈|H)OTkU^ k{f)kZ9** 5sQ{G8߃h/6zEb9]x{SDջ~oPev9BFtA{MҲ9?Gw=.q>L~%iuga60ePJcsf$w{UU9U>UBݯ:B\m,7*'I:Þ$$ eh@U ?W]<ҟ.I -lf2bm4"/nJBmn퇑^Vp듨Lɱ<S\mf7x@'g#R€A-[?V1ٚz@gT8Dڼgn *AG EV69 ʣVP(uǾ nf'/`#Y7*.|x~E3(dm׀i>: ی8חdC-; e>AjƁeflsp)'c3zK4ϭZp4 T LK|@2 Js2"k)$gJhC{dZ9J}>bdDC c-ڹ_;HjLMuBdГNAݺ^NՍĹ"1&yA5'd,/Ǣ:茷7g)Z$W.Ԏ3tg M ty(rRF1^,0!<>Km,̛*)V Q-H?7yz# 2q Һ.tR'.LQl*В> (QJ֠v2 㔇/|O/jh`ϪojUK(To"ݬ~_TCR$o0~iS+wEF *_|[yIw2j\r.(b2Oґфa1L N='5eP{Zv4_|uaؓ h343 Bܢ/rOKPQLK ɍpevE,VEzBādBLCqz2$涭QQo;iQx}M Ie ſbEw9DyL*;s 5dAKkXJqXCyy-QwPR#;  JT|U+g.mq,uPtm1gEjSP~eɒ*'vQmKr>[M%IA"Y{5ݔO"m'Z|¦f-y;")v N'#'E9ʷw8n =5[Cp :%4RB٦ˍqoMDdѼˈY"z@ĮFG)r!cz-2 cyFo*=U3cApdR)>QEUNdȪlOxr*=„3kx'B4 p[><>x"/&RVc({nX.kzn)usA]"Ҷh-WMb\=Ҋv?y7@]ܮ+lY$_0lu$-1vR,dFd(0p%8 lڎ;_QilUϊI|S¥Sp溫vywcˋ1vGt2U(=xC e8fM84C˄m":߰`3w>j z4+ib~{;yT헅@^0Y@P|zS& 5~hy*O1d6(YC9II) p8KǪQηlrb!m2KՏ\ Ɉ'g{Qw]bDaUh2 JS w5!Ŧ`3k)\?KpC҇4?):DE,zyϡ64MSfC=^u +D,W3vcz3l-}p|7qSvc.g@zyl>]ťQ a`bDUst|Jw9YFUI BC=jK SkrTIJ+`):VUv2M3|Kܱ(Yr\zX~NyNSUӼɱ=xm|s-0#̂hj@ܱd;\RRqxwQlW(Ǥg TvpX?~"J>xX%{~Gh/x`=XNf&&6 ,F;Eyr菔NCh4WkٽD}D 9m:܊% :I(:,wjSOͯ*uB*G2J8cvIծՊPN\PNFnxåL` l${Mb9aMU{+md @γ ^g˗t/2y*khC9q"K2><4 ?3m M6u!R$BZ睐.NId0tTY[/T&%%}<妸ƬȨ k8/̌W;öc!_$#:ՠ%+Dt:}[螊ڔ= ,2a\,)Q`)H4$cooՔUȡzV\6F|j;8BnೲQ-9 1qn^_ (SCeyY9=Wne!~x1VRzTա:/@Pfy͛_stz%LLKcnKWGT.((Dž +IkhD>lLc$_;#?Yo4۱JQr8!k> $btn?*E`="ћX w`N1JYn4EQr2XX.k _{ZگkMPy9B,%ş IU"[ s7 [$\~ϑmT)-̄=c:R#)U Jeotz B^e,RqWx{ U3=r@ujX.֔o&>&gFGH1G"+jJg8C*(OEjc~PG(v6[ `,8we*,91fsi: };MOyᝠ6*FdVȍb;-D!ETMx 03B[c8ۜUKXXϑhX*)D TH E"ǭ;)E8@9$ּ1|_erY5"nc(:1fz>Z1.bgt-N93s]sP z6Z渓MWml;).Nø) z$Y"F (׷jLUxClg\>mrc|,RI 27-Kы &7ʂcOꈮxS9(mbٙ| bt ~I<ɘ>. 'S@_t$zX,)LfF8#~ʃvs !vcN"gAXb5„f~1p4: r$b8i0MW5S(_cAmtL |`A+E'YX+e;Jy{ϐP75|({q#IqXrF}L 7d<-qCPJ8l 1Z<%vޢc x1G ,b"'Mv+:ws=c ˻(i@mȺ[ZQ3 0lcow'@R":$o 7-2I *qs12=JEreE:TS),|u\a-VU\B@;} 0z KdӦ+AɲQi㎐g>%-Kͅ67s4kVd,6_}AAXn+:E?ߩ)]C99Iuҗ,2/m:,-1EbTݤ$F3y-(5ƽf>E - Gz)mGӴsKv=6ADd8 slWy<)*ʽ܍{#voo3vYOtm7%Oі.GA˛L,x 8 ]fd&Ւ]߰em~WU)D=u8+i0[*!&=.ظq f'&ΰΏTC*؃Dt*X:,pWa^xL5 350 #ԙ:D^`qDp%󓋴jéji9MpPN 9=&5LUZF9`jNVYdaHo q [V5|65)eTg4Uԯ/]ƹ ޭK)3R U`w1C=Wȿ8Ԕ(%|e 7hjٽyhdBp6aVNv .ٳf'7. uruh$ -D_Q%RZþ ruGм}ߌyK)rg% ]f6Eh(ó美"z\󬭆kWMAoX$Wܶ R4k3w] 5Skgz;"C67`! k^L&R20;3lȧGe}QޮQ%$l JMWU}ee 68']a՚d=ultH5!U6:_J}&5Z?V:f<D_+Tڃ8tTh~U񉉼 T; )lxɔE{,*a;tP>L=|9EC%lyuE:xiEIS2Jy/3MҸqGTN#~qOj;j>\'ąqcd/p'}Ⱥћ~gXvW;?nDbz8NQ,v6_ga\;]`b&+)*x)hH5x1CHFifJ椃'ÈWi(-8s aFvF鷺 ^͗^)b_cl.Fs w_W(/{9$ctTmO b:-qiHGTN΄;=n@Cj4Ӧ{fu/WbvIkg2OsNyK(< Jp4/ 2;IMv:aVh1Q$N p,H׀(A7t[2"yCOܢad0[mDQ0'"7dxn)$!#4`_S*9? ).̈p8M U21S-hp W@nR#QG~P);6āNMF's䉱tٶW&jgŀ[׸4c1z"( wC`%.M 8Tj}B&bԚ&LX,8gWFTk]zkӫvF?=VpzN oκ5;/8x~UGȬqYp*#UQtk'dm̤a6"|D`(w 4 z2gSB'yywNb0m@D ILg\[*n`whp *ȢU2ھ |X xlu¯\ދQsk󏉫H(T'@?!<7pġ${w-O/֝H[]d$ Ԑ8'Y:mm"eD~ih>MgLatW>EC@D!pq~VT/_' zlj9 ]_ T٭~*G0Q և:_KZci #+ys s%_eR }\E 4K֟l6suM)P+lɅ_s2ykjsY$XudҌِ{0 qu6[}r=|qaL9>\. bLױkԝӐ+}6grC#hWikW4Θ>i?ͬ|&_ g8>a"Wh7_C# x@%LΥi񞿡SVVb#D;[TωayR&_"p~ o 3?fp_~q(܂g#f =~֍Fi|/e$o(H2:Oa 041WX$n ?3+ L)18$ G;W'Xyӕ>!ӴJ(zaAzp!/VktZ- m kH Zp63>7.: Pà@iOOgMmd5tfb0B"Ƽ\g0#Jl 5J:"PO{Hζ|@:ou\.Xv^8[Uj(z">7 `^3,Ne0R`03pIR&Gp GĎ4M'<-sp)ڭz oP5x&ƫG/'b@0??PGtOtscR? B;}bVw,IMmYQ ,#YNho On@m'(i\I }K]+!Ѣegw*URǗq?T _S%?=ƽo[1%o ӫiR ܣKf/$ b4#]>|G K: .6}d~I Um2f~QJ<%ɔͼjIcmkO[j}k x5*t}1EJˆ&{￷6X`oq5<:]&+࠯x*,t5柹W]w-|g*.TZxVhq1F&9o dOk0;Ic۰.4&$$Luz6€qE,ȵ)>S-.dϦ!E!:R*w 9Y|y.9zt⚀nb.!v!36ν_o9RmT%#7,SD f$-naKh5V#u:.$Dh[u*LI 4ߋ%!`@-nШBՂ/m/)==cp)mGǩVd`͊wb gN&plv@&6&L$؜ǐdAk834|+g&.른9 N"vT Zk1Z|;E3kVgyRut=aǔ:stc7 L<j>Wud)1ƵRjΤ !mawY_Ɣ7l9!k eƕf]#5^.]r#<7_Jg &^GUcFj._NҝBo_͗4XP؊&B]0 a~q&v(*ke\]Fv7k]g9Gj0b9ƼEӊ(@5*_0ךEy[;0 Z&QþwzV+C(u{)߱RH[ $Ս 5ҋCukEf`ȓ&x)1='z&d:H`\pmdk!C;dku.\`MnTc.}Ck2Sڗe "?Soe!&/y&prvDsrV'K9U l0ڽ%)TH0wI_"jWf KFO~e ˮHtkiux=h_L!$F<4ԸV"bQ: r#YB*ES)3x+dzPZM"([TnhrJ"б9Sl;z|g=[VaJ/.JNZQFN aoMYѵZ|vL&P'ݢrclChCP2GB~7$z. ~y?m8ڙONm;2o 9<P\2BK].dԺ;$$rW 2 UZ| Zygdon9HY*U{I!:hFUԻ?_I*RbJE'ɳ5{6ppٴ!)hp L Ȃ-Xȵ#EzɢOߩ|@$S0)n^+F7Jhv0\ps<:3[`H5I8Jc_}o㏰`?WOdDADŞ*):O9RRn'I+FVGgޠƲ5| ]*ô%}qӭ:Of#cZ~4BA#b O}mZ&%P1a Y30NG)f"W}>z$ZYj#-u+&5o Djg\(2{g79ާJflB/[Nr'iH(vX0YXs,>365l<.vZb2/`D3-5:W$9*A (nJB sQSi^-ђvS=+ ڟ"o|(Lf3T)G3MdSgRf{b0Q}*qCwk Wr Am6'[ S}gyx_ပfH r)X!|f,Nd\G#DRU3П5C$e'4gjCl)qqvc+{/Ϊsc@㷎N6XOj!*ž:O_I>@zov26ڷߏfʜӴI3=K*ɣ;T8b?i_l IJ }7熶? qwL:qmU LǼꗥ>!L^R]/zYî1d]Щ'Bg.!^ J^UΚ_ _*4RǬ5Z .L\mbc2:DN#bj2#sPBbH0bWK3Tr# :̤?D fP[æe()R '' S<͊h|L2\m hfC c g7i!)>Ϲ%A>IqZ_#(],P{(J޹S0d/%L(>:юJȕHQ2;[T'I{o#Zm. OĶHg)$_8Y̓᜺qԤ9:D>4!RGj$+w`2%\;ze0rV'v.v;\In={?i0\yqJo w(<Kw%1dHU<0u߷ bAͩgEqhSOj6袯Zr})W%[.r,nќ.^`T r;ߨQCQYY'ڬP ޿m74h׌cZJn^+U#N2Spkw;0wx,썦EN4+Ei \$}Lrqxl;xi @D6% F6ʩpVdJ$~V)]6yیN,1ƝxGhYYY4Wh9X-E@ND u(@=g 5g "ZB>Lk\H*:+ʹw~X D}2 WԖ2_I>K?&:fbPiF:G,^i *Qׅ珽 j!ZWBf7D}P8W{ fRls>2|J!ӄv>޾v@l,yx)!=s\r!}12TFRp[$rRDy]!:[!t ˺l[D#-+{.`qi7< ÉF;ʧ }w44 Y,'VyMHhOxr}X%FW9й$^ ,-^㟒KGo˛ ™d)Ğ;.WDO{s2}hؐ`5ɲx61E3d^!W'w2R2؈rԇs]vAYSA%~Pؑ"..Psq\2 D uR E?2! J<_eJ Pb b{g.EKe6ڰ䧊表 7"XσSuH00İ$*8w3-TSKvpW=FH Q1mp޸%i[,ο+QH:HpSڃ8r$8sfwT]ծoN\H } BT W_ðqP fvbQe;N#}d2L6ѬE=@~̪i P)M4mAVquO卆k -:zEVIF^5ĝ_$v`c@b'М"jI$~hbLK? pςm+LСAշgBoIj.6, }2Wd,. #.ML!9:ݢW*pn=y*+ YɾW%`m3gJ0NLǏ@m3M(dNFrxJvFFR;=A7?9vi WWs|+WYƖ\4ADI`Z mO*۫$XK[F䠢*se1_T} w|o J?]eNlH =Q1%tq=mkvQp!靠c9M}XE,7MF!k2WFh}e_Y̎F [c8CΦ#,I/܁oarQFB`Dg  : >YoW f/Huq}סB2݇V4NZyH>A'3GW6oǫB]͏·HO'p$x>WFod{ P)[\D⎤qG篲6uD]_#n.#B&U1\3Qs*a+ۯ|;G'GiҾiZb43أ<S?N?)yN";ݫn}#QM Z9_6J7+FLhe(AYsՇOeki*N̂"5Xm*._Vie;i!`R,gԬ֣&dNӵ'M[ר0V [`Ėy7[իU\9Yx.k6Y8aH8etT2oLBa.E 4Z:3 ܡIbR% eOEZ7cZ*xkԛ1}WB+o;gTljO6슰^BM#ig#XbT! ߡG(YNF$gֽMj-RO9ΒKV&HIkk<@ eF]ژQ~ol}^F]zu]KO\A)n[(ϵ#\և(!c/suw.U"6s1$rFSo  6k(_ RqF"xJ6GX:}"y 0G*NW\2$KN,{J6m 5fd$H{xe6K5ǍAh 0: ]GSіPh<}InL3?r* 5~;^hz;h !0%`LK XЈpVk9 mK"%_̞[T .}>O„DSv#Fҕ|(l?i0T<6.N&ߎ~+|5a@`kl>E-Z7"wkR(WWחZ`?|֕>a>` Z.0m=Z=);;w75wW?` v|<@ԼQU_ŽM79ZˀS;nEډ;hԬoOA}[$Z?Csi^.d ?ol}I,~ǁFwLsZAZcG>>XԱzѰ[o/f/Úʱ}|L Ȯlv-}b };c~nEy*h{g}AV&~$]Qž{aq0ߥ d˭eTU\'.)x}W '#n;r*9PÛVbn[V;Q:-$v05XhF!$^eL#m n pZ CPVߣAx0.#(:/j8[e&8]f}KU0!|ͬlpv,YQBpCPnK0^f9y.-bz ] H{P-s%sٝ߅?y4Mq: #Yߋ<ݛt__^prS,>3DaaL$Dϔ_$T+@ Scp(WH FJ d0dݐPբԪ;Ca6@4n5e5 3IWZwwx̸A \i;e 2@kTv+J}mlP"Z=*P\xog/Z1DFĸFeqQF$EpQʂih:eQO`#ƐmW#܄Gh' ӛIM1kZmY8tF*'>:x5(bnÖC-Y4lL>l#ZDq@` z=zEy)k|9u:Ti?@0T RXP󀲃ҹTR~гHOv8B:.nfm;Yx zY MQ5LpB+n8LpYxq_>/]UwdCS>)ΐ)l$GؼڂxJLcR^YtWNf3=}cؓUo0bO+'H,I,5@Ƥ(ünx.#ʴbJ!cIw>A[E`F W#S>zt~7&!. -~$ѨG{ț{ 8NÂ#^OR6!UcTa}SLS7:Wn-Wس( cx<]AD Mdӻ7֜J@'jjTUJ ,Huf&b帜z L-G"pmo2mKN;:ʎC>_OKJ: 6:.OpTP;)w#RcQ$DT;mHğ&A3!NZR iK*lPS$GAP#z, l:EmW.O(&f0nޣ/2kIV˗VsB9ʘk+FiB%Rhָ+ЃpDLtR }Rzk_V~S;J!ļBQq$/._:IGɺHklRT۳xg$ ( o1^#o.ympNۂ;HS<e|}@HJ5,]ucԫZ[2)뇃_gEE3#їMүWE:ϔ>^$ if-W5٘CдOSOWBfY\f1HUH[E@#dKc(^űj2eE ˫o9)3c"+ 0a뗌ǧD]cĽIH40nѕ= Ȇ߅= Б) _R@fV)r TbPIhǶA[:5Vf& Ŵ8y.cor(9/{V0{+Z ƜSŃҫc R"GTmse*=BfڮP*dN@N)W5$==ow;X-;r[Ij\X\p%jo  ~vfp6ibБ]=vSe`nxOE% eG΋cuvu;럐a&"biB֢ /lh5=}_\P#){#-3}Vޓ(ǣDQЙ_}ZܴWzS_+ED˒iY\h>e8(ʞZ1үuYBM)H ^/S \'rN1,) jDzx-{fayT:@0nU79*B 񉍊P׎q hQQ?-N=ӻjd3lӧ=y{QU7_uxhocx7%G^=t-Phs})=vgVkp:E FO!(SGEHy@Yt2oU){ 3*IRdRFϩ1 hJN0'}eW#.F@5K7Ѐѯ6ſ.  %*c5gJ &U|'1}yqG׾SYL; o }B7M嗓%b11z>"5{|7>sʹ&RwC\'Y՚30iF2vTTI`07ra@k='Ê@NɒK"87yMO/M[;#'4F"<}~z+KBfO7j'@vW!hݬ[= UΑu]QP7ԑgyKl p|oЫwLif=CZ"/OAMM~#&R ZԞWG5x=`cuth3>u{Qn kQnlFݵUe^qbuhp'ߤ|sEQfCVW)HXĤ@VWPL'Y|du$3׵H_9zSkQD/E !eRkHN1737=K-d%1 B@+!{-E%nwҿlF!pD29ʟcTvf~x~%Y{3c*-Vi";M8"c-S6J#/]"[`'%_ 2pczksP]c6q={5}]N ;ˡuЊ[xծR]3YTRM6$0aJ!Bpf# ;IG|;,sL2uЗɎ R9 ˠYd;;w_(p f~tZ`;-5tKՏkWHXԶKӓt,1Ғ\?\ڹvTr&CDlIߋ"r,!~pf!PJd2hd]{4ILK\NJy*B_It~뿐b^ uh(] ZM\JA1\G " j*ɰlJ ipٻP.~f+3R+qѨհǯ1WQ]kxAOA#e+KQ7:SMeJr6X!srl)͉&5w )ÞdkEE c[N:.;P==E3 W=(_sgKU62 tri0ǗeB0UH.'=ڞM CaV4B{_=b $U׼f]}@5'x5@ kzWp͛* k{pQvnt ӳu ?љ\b2G-+Mr>?_L?dž^Kŏݕ yb5/1_KA ߜHWo`dA[Jgؒ" Sl?]Ĉ;ήQmuLrXRTs>v#@BS$۪t!W);>Y=6 M G䗄tPLiY|qg@$.xj4/yUtSkdӋWLch K\6*enQEźWϼZV)Vwv]/r (6mD8fi ƶlA|8H<%8rV;Q\/Aoԙ͊ ~ˁ"#y>%YHf7I Uy7d;cəzF۱HbNG /i.44Y/ <̲7$W1w5VGGW 116hol7z-b9s9\e{SAO/F3s>7v9k(߰;ŝr$Poy0F-=Yg4jVUm sSv:cRgĽ=';nN?ԛcx6 ]w=阐2KCNzi+&;Q"({f,}hbC26}6qj D1 XqD@kh!4-ICGVOĴޝV\V˪*H%q8Hn'4x}ؒtUHCeXn"-#݂{ g:CA/. طfi?vYվAO5UԹǬnxg I:,/Sڙ$i 2&j 6吸CWp,tV;t E5рW|@Ji|?oЀG?.Тw<^esZ 8Fk?J[LV<#Ac!b+bd`ʲ^M{t3"~!f.6tPcRңEc4lɬGjLB+ 9>c9!hW#if\TYɁ4U^"|jej _C,^p!mD9\r7­u0%5{}" WA2OD *.!u3i>? @HqeUF/SMej4 =bKtuΑoh@@Rf6|T_禍41c8.yC6-EYٷ$JOIM񎟷.왉Ԃ,01ZBh\XYEE;fw٫mCOpn^9-xg:%( G"nٚ+d^aCJl$ @NɄ}o0'H5^=sZTm.Wo3Gr>۬ZQbS!MޚȜ,jͥ)kg:|hݕ6˫Ł{Rؒ d^i ŒjnXi 6yGKW#hF.וEϾP%ijRo{hg[2ҵ<J^l.g]rrHG,1IŲ&ǩ ^UQAP눃G+. v[%m O5@/Ĝr97W'ey6 Ě$K5%YH@J%XnSz/t]&WF Q=7TSMOmP\/'jmWzmYODp pXDCd#Rzi >0yX!ΘlN`9~R|[SN_7&:*f:q c|\?N.">? '#v!g;s,Kb!J^K0)]dvĻ6H\܀D.6nɌ0+mAI| c50xFz xIAdD?rJɃ0nJFwn#ʔDCd|$?E_{8õ(?u# a'e&mF3>Hg|N}Æ3=nDȭ\.ġra։4I4 v0tPs !Lv: Z$q%du-`r;ϯE { .6`s j }ʌqsB!WQEw!q9!Tmv@ .}&kIvוÙU*g㨋d-: Ȃ:Y>F '%"UQ>[DU躒eYImTݗdQB ;\|G嗿'0[W{F}Vw7l n/eu"uyY RU0y5S3!>HkUQF+] eKS>JgQa}=O-W-\:@tf6Æhek xh+Dαv5AdO6<pOTu;X̯i^qK-Cqi ECY oT@ e r/v>b8AYR&K&,b0Uư@ gqѡгtll {Rh1uV#;UBwg"vmy!ڊ0"uE&e`}J׌}Pʳ[f9uoڊLc3AR mlX0ze5|[#8&c]2=>Ox8o$fs!sc UX" th:i Kgr8 -E |鐝Ӆq%1eԛZ$]wUsr8[dV 'FKߌ8`9P6M*i +6mig M^2p8ERBO#Ne:Kqc4xlma7 .8~ w"@q-g +:}cE$A^swC(|:n}N|p8Fg#pIM$c2g;Q*RKNѳ,/?ٷrfk;b؋%8Y)I17_%ꜞ!:m FTaTոR>;3רW @(yxgvpvO@T+nq4(.lVՍx^gv#IEe*7ė#VQ-6^q@!.?%Pӈgf)GHZҵ?dWiDaΎqF2q1ʮM +J|g)B5Cޙj'') Hә9ArB?+,.(vE{"$\1XJBe?=q& ُ/ #µunOV# .w+$w,M3Tśÿfų5RC' 1Ю4';JnxG,'Yes<(cѾ JLU//"pa.7rfmlj8WdY141O%hj OF׈_&뜊ՂENѣxZ|#1Gq'BGgd藽,7nCy{!HZԛΐvO GwV- )hyUBoP,'+ύ"_Uk9Dua&Ck rO-/x;*0}4!my'C>Tܗr8?;L MNX畢 z .}ohRŤ+0h3s+y*Lv&gK֠ ccCt)\ǩour zFNd c忱QR۱{bg(C.;u0nAO**W0Uf .2rK˼txoM8_N9t7vI~ѧYڼ+&CxZ2ɸ`w唵 u(9=1,2)j i#EDDۜH4p_$IOR'9*8Khv':?%,z? in&#J^;sv[ Ch‹kL(buy@* G<\t#BX*F}U:7pSrHY&6H?g>&'*W}~"3M?s߱9d-$мj :o} Uik=*V/YcuL8/ƃRZ1o^+ N0(.Z<;Qnׯ[FF^5V˱|JAuwԥke3}N3m 01F G*MT^x׳a ߰ʲb͛1Ma[2#Jap5 Ω$D[\{- =KlR`C?m\#=P]"SqrQedԦa'Ht רbQ>d)}nNR ȳn(P6gFk$zٝF<X?kN폣 (uNά["jN HZS!"oXM6ndxd \&oY6DQS}=yky?DDJ;4m6vlrM%>a`6 /fc)f.:MFDx% Q~rW8i6Yj_u:mjrȧ/?EqҮfD,~oy5M8i;gD^;MK޵De,*j9ZbyGG+}TPf<}:j8ܼ-c*>`:A.r3B` ]+N̑ Xɥ)} b>OϧЄoNsq,72j>hD{LQ=Z 6mruyM2Td+oIp, K?B7,[ܺ7.{maL}}g@9nMBMɑEd}*^ஶf)NOC4)axj#S %VABf7g-“xxt8=/jRsK) eZpas kADR}≨9G.uuIO{ RTT I<6 k>)v"T8]0k: Yfz뺿 bpd~ZfW?ǔe(\ϽA:&g Ve2Mo@ wINaۦMw}Rp}n٣ ױObl%\^3^4t4nCB%/odc RN1t8g(N%sF~H `ׅ'YhfZi8Lq [y[bΧ:_X1eb3vQx6'4Z(xR/ٙG.P?ܜS$gCE w?V.Rc 7Dc? fFFunobβXSNzU?dc@~$ml.7*Z2FmiV5C)3GP^k%(”!1L> vuk vۉ̝+{8cb};G' 9gċ`hvD­39pl#U)Y#sF5%LuPI = p{Ub4~< `R.S 9\3>=@o*ǚsA{:gXk /gt휤bw -K\$j,3 m(ǓX-0h˜$!j:K4 #]+ ,2$LJ-襾( 40ޞkߤhLݖ[q)v.Zy3{@z;lLW(}>١nn',3P+VLREu00(%/ds|!X.>OY[0@]nۈӷ+[ F@ӚeV9tuP|u˴=%#>׼PYrnnA?8*j^U*œ J}ůb^2hC[#?)xr!OiT6pp!oDkyy?Rcov߻iاsxR䄀-{^is6c:6 (6b ϑJ^$ [ҷ᦮ 7 o%m_[-$! Iپq gG#e[Gl'}f}Hrw-lK^8+NIα8u#bbyƞgioW8OqT,{KjN ?>cC[HJ9/=_ q',P2Qv69@{2Awc>tD-aJ)r(SWѰ9qcNttT( wSRZRj[TRߝu{2$p Kg\-b%NLڦD1^@«.&ήMDFjACٚ5Ԭ^:PCo=5w.zQ}-psS&?Jd`y\hDPl X563g}oјώ ];>=)l#4[\c,`Wžs!dK|c:)Ԛ_n)MхfNVh|^rs-B,|<Y|N*WEK rnhir(s `pũ9lUBmވQ/ڙkb>+Q*ʨ3A*@l伢x2"?;3&_"r "Kb*GZkS.ksS{e %U8PH\N`'kauF)IAQ o{-$m&.'z@c%;aa-T ֝ K4 ~(LvǽtQŽ#e/pP`D©WDE ~ŏ5M1p22ϘpΤA$TZ^d)EܤdV"%Q=;?[rA+E=( "PH*rϹIVq-P0ΐU: {!H5 ꋟJ Bҽ4etk6w \o#.XyBLQkXd^&DAȇɾHU¸(iCCqTщ[k[jR]]@qX-3#8VV_،s=F Y]-e$uqM34WЍ$4~հ+ &`~Q +@6 *aVP;}k3XZ$QW2c^=ĶMggI&R/+z'N^L;fxjzorvuUf8i]Rr4K3q?!#^jJ5X(fZ"sA\iݨH@|-[(vY,$*=(+lRERΖ*{޳K) 3ؽ 9PB|II 8vCa&Άe!K JaI|Pߴk٩U:cqg PTt.IĚc-At0] ͛ia cdyR+#AA$f g!-t)wUּYxBӳۤidm y.}O:Z$a OX *}38Dro[./5UY?khs:ZjegCAT`Sd LsN0xwFWZ% 8PNDBܥMݥds$]sV^w]xwˆ)=JRߡNeU H`4GpA(Һ-XƘ}zN0bij C&[0Wv">DipqVs 7vs?B蝂Na؆0=[M#[. NNyUy FECV h"0rg8zɽ";7Y_Vr'ϔ藍u)?Ӯ:'a$2SL"Ke[HUV]Sv;si 4i]8-` 4{F oTArUe''a3U] VTޡ%($b×?MϤnyh sĎLWcqJO}k[cs)<:'f I3uAY7J[ƣ!3J5ŭK2Th}sMyȢXJ%lzi\ e eR9DթxvBnYM9Kj\vɕ)e?BCr/'E# $мa7 3∊RDD: +ny;ڨ79viQ+ )ۮN[:j"B@`FLtl\YBAa,`74s!1Չҝ)\U,ZW/YvTAD8u(0 ׸t̆{lVP% ;YWGl9R7LhsjpsH!stwj$mWW|wcZ/j0V0xiRNrAS VD!q1.hɅ"6Uq phZW9jQ”p 2` T,QLՖ~Tvؚ}y{Yp2Qoȓ{&2GV{ߞn.I0fC,ŦC+nl Iba$BgS9S؆i{!-}Z_vtrRR%&1ਣ̹0"aGz ooJw8ff:1?`Sp-SE9'@6|@шżSW &?s"a-}2>;;ZpN@-)J~I+(H yh;{1hH,a*feKsXrsUn?8[1AzW_6}p/4EJae-G@a,y%eC('ȜڥՑw(?aټh_ nI,RE x0 v ߀X P8F>x+fqXxd~|ϫ#,'ǍP띕rY{ ȩ @!^(8tYȲ8S[J _!i0t_,{$'1ZZ~b꩝;! 6PNP"7x#BPgE_,Tl{SԱk;ˮ fS5W S*LiEl9 elwf2 ЍGM?.mC4g1嗓 y\~s3eQWW\fAٚ86%E`] M^Ȭ>Q,I1Ya؞l]x*T*/gjM h {3\Pw"`87,~cE%.VAJ"wI1'^#W_F%!$𪾆[d )X=_d̖tvq2[\[EƒdάhddsqgoI3ܠ)kmł&(qph>(;ZֽVVWPTdrINY(K ed䶎nH֦Ugfm+JT1Ӛ TSz$u7y)WcIlą_sIFJWɂڇq( {a5N@IJZ>@L\Ҭ#E#~{ f0-Vv26)MZ[8? |hi6*,}MifH\C?Zacl{;[> Ócɽ%(#|_/0 xp6ڽ]|^J]oT'K%[(}eeD}uE߬ꑥXĪ!) ˼ayiV Ofi;(v}f "N'h:**>Q@j9F5aN-*jJr-s[s{=&nN+-" W5@q!"xKbP*n1ui2bָg-;O[::S/区M:.x͏N%jELlU Lݲ | 4tY2?G~;1arմ&j7i8aۍ CpiG~ O?]6y.~giKU R[7 R~r,ec)UV\И`+>u܏EbH ^R U#ȓNZﱻF_1~6-p=*``xwgUqCA٘2-/MA|TecZ &lvժ&cI 袽H>O+m^Т(2. ~:I3sK}ZŠX6#ՙ&+*4k7ˏb=[,khd FPp2+r|:跷.V~/mXy' 4? YV[>UAsc)$;ɸSknPuA^֯$o^8%d!m('!ȍ kP:FΥ)?n@VGc0D4rCF1$oHь֦iOfz[PzO#hsMx5p mC R-~ L=zУ"{&3#^eC$@hE@|ofAOY,I 5(yf0c!7j ,ΎX*Ǖ$yQ2rPao% F#k`^QBH+~~ٔj9LĘK1#E/`QaS`Lumgy}uӷ糕*:\bF\wm` \{ '(*/pP59^]q"LԇƇ9EAN97KX|},Nh7_iW5;0;*anKRyvۭc Rj 8B?eʓ)c7>]MA=mZrv﯍EMsM HkO}۵F!E‘'E6oNÒB (粎UwoF!95]^'C+ir?4U`&2CXdHWVi^Dq ' 2r A4zv0foحalIWlw0Zzl$ *NI)3-8BwהslMbēi6@{^'//64/WO8w(6.faFxpz j+üܙ}mN9hPXXgD$}yleK|s?T%.7}is(oT ;j"OG|.GڦI-S_oU~Iݦ31L~U B}|dC7 d4BR<W!Y +NV-+IF$Hé@S?>n5UIY׀ cdž$q$ok` g~΍|lH 9o*ׂ#5נn{&N*1 w7PbkIQVdYդaNGlUBspFMϫ=R'&Xm&f9{)xk#|x-(J GSq\ rL^7wA, uB1T_e:-zL%yVGSۚzHae]1;:  ڬE.h  1!f^(ZqVu9eu("=[?'Ws+L<%j98&Dܲ'B&}t &Rg7:#+If?e)< ɾzi!_IjP+,̌.5 9p]0[(c k: w\dEaͩw Yߢ/݀h#r/W3рb5IMVwSdI~nC(a@U;࠽rsӃ |QaKTJ^k@P6mbmo{4<" P.S' \P{9,Z4q*Gj2.[_7Aaӿb/ :? enj]F[׽C=a>Tǧc=6EK  5Vlq c,G^L!ZbS"`ȣєTg+t*{:MkQìm$LspwHCiKbc <$|w顭#=@jEևIVx&kH0脂u2]fFaG[V ԵrAc%>wz3دoDzPq8%ׁ<Xj[`'QcL!nǒcZ:Gi6-܏.*^m/͌du,Sa]^&Y4S"IA𺲴w5l T&yݴ r4]Da1/An1wpAHPUS cO&b6x1uXEG;d9QKqU]l{)(:B NS]J ?|>g3о@t\`'MR}KwB#{'hH`qDnvLY8fLJȌg9@OR%a6~Iܞ\bR$b;!&+\Fe̛wT$r,LW0a8V T`FsUE"hs]1Pw aOdo h-CvE LVP"/+ҌFQ W&7w7T%&ٍ$D&QcWz});r)+RHc{_>5m"P,tmE <Vip[Pt5Yz"/'J 9(0ui\+s { V|lUq.e ?rj&.ˀkg$D2IEԾ[ۦVc_8*Hf#U߂MiFh  "ϿlXnuY&om(*V?hLGQtslmǶzUO:~nBeEstrRGvkԒWJ2:sdG$MTψEpۇT5܅}$c[.)cE}U,Mh.:/۱f2и@1'{5t,?l8D#z7x=.LSEXov=Q)qϔ]s!m1aQ%R\ᔜ‡ɠLBЎoX3B9~FwS-tY2R{3JAF%aQs:n:bfLlnhC ͇-<{Ԫ2_q(P{(FqoLbdKsŇ=$t*,X08 ήɞ&t7݋ PH6XIjH\کcn)neG*U\TZ<ɿ Aρz$xa2K:E#4T+ umMc١J̘T^b4"?O]lsuq_X9Xm\[:61@~Tә!](}3GdU*e{zF'cYm:l,Фh9 Xk|")2c9V֦HG?)=#k}<@3RQ;y-SNkcڮwd)jk,I&v6MOp{Z`'@7:Y.ǐ CT\Hwԡ oݧ:xي)31 9P{?`IA.N å{lG }麥(Ɲȱأ& gW vNfI%u% g.X+*ʅ2RÆd@Sڬ :?9MTS mجmFl\yTi`"81H A)hsili;']Lm";~0 2\5ӎLw~ KꐯF1vQmB{ww,1KYHpJx!b7ZB~.iO" 2"^>e`_uRc,w{!s8BEО.&"Om$yKL}l("iM &ݲa "0"W',2/a Pc㭡63bv%N66;6ǽ=rR}M/IRkIqj!@lTe2FUPU M<2 pId#T:XwD˱ѵ&$ExkbA`Lox;%?*gt`ksl21v:2dHz,~q?$gC~\.l8vX$uIʨ{N\,쩝CQ<ی44MD$)?@s{y"P6ـz:7Jc=IeXB_kyr)4V(U <ޖyvN0k^C00L1ݵcgD0/VMHwͶX-bvvJ#뼴\a+ƥC)Q x{ .afֵlƄ,4Yc/d;K7Z4d۬&/}Ĩs)[{ 6^X޸w- %WFRz_5 ~ DE8H0T E&O%\o<ADj6[}!/:}{ሓy-&|R|,K?ԐjWNk̨*pD[ϭ /cEy:7>^(Ujj`PcL/DT(Ñ x5:&5s] h %J%R)bSg9Ё~iH~cNbtGtr+h2k?mjāвG)3A^ZraV7jFUdEjjlJ6~ȉW=rb֚8{hb$@ ylܲD{o;`WL4hrь̴k r,~MGOvjai |$! MBi_h@%,YI{9[<#0EVTYwa 8nL5'bPw_ȩ:E`$aWHVkDcze]h=$!9_Ksp0f^/Pm8;.SuPl@@ xTXb7F[j, _b3:##DЇ*yI唍]$| pd+B?dlH6qQ$dc\8?OȔ| N?o}s!TOb kU#K(hcM)(݄νL&j}t*?DN:Cس=UVtP6^{f'١N-TMϛݴ,X[T 6gԲy 3TKj'BOa۴a Y暃:4L%FgEJ3yD| )yWܪ5/P;Gʝ |HRAu'zESp9f#.H!Z"<*y(e4*#: y/q ð+"QR8(i|簝t Ps(Jj̃2b~ ?Y 0N%~`Z,  j^ On;]ܜm%E-*OG ъI̴PFvN&DAQZȠ3p*Z ^&l33h zQ8P:~D]# E4 ͔ٯ:4c:P b]>gOpy/vid#Ȃ)7SvhCY6TR#ضyNۃpn\ ͦ\2BtQLj`(<4)^7 Y$!Vw, i=|Nd 마!B&UVU6R0rKei'bxf"H7;;eüʹD5C)Z=y}_ۀ-'_9{9ѤR ` c3~ȒDY Pqcxă"Z5_a ?G 8Tw)_Ana֦q8`}8Ycn{܊6 2>q?$5&,$\AwZBI={/PUɣy CM#)a>_+DQخnc:.Za#)ϠZat=>Cxp`-!4zdC< 7 {_{Y}i}*k|Sز3RbD-^p ⋌,6; ͂\Dc%R=C2_v?j.[IKcNᶆ2mi<#O;6xcd= p茳 ;~g!i~ayn[ؔDOA-Ǩ]sNJr{z=6s'ԸbxQcэE!xb-aڮ_wQG (YoTkn|1@,-sz3N5[ OMrdJLzu Nn}!<,[ζj>lSPÃŚ7}JW;=Wc%AA>QLY<Y&WA3OIVoz@ ߊajB^)zO[k,9݊qh_aމ*{')]Z`:7u!不jxzZ^ygFbV__"2c54{~nc{[dW-M4":Dyk@w1i10 i6i;U54گ(tuBsX-=dhaіjo @H%eɞgoAUQ/S9(  iլ/P]t}XG-~R .q:t0J}߻>'6j~\ěb- T_WuRd+6#ؒ]R>[F03)5[L?:GUIr9rP=&0񴎛,fN,Mvx݂ 9D5\~.k{s/ ig3R'fJP& /ՖU _o0)1?2_j.k_ae kPt$ x%^?TNWgħ.D^2GV؉䀾E]y*h:4 8տ#ۆдu|<5Q> lf)"< hEwMrKJ 1skXɤXK2Wi^a|a÷H5LQK^2 ]n sU>iz;-ڍ7j$$E~,!ϋg@vn<1]cM˥^듏m_iIݮ{P6(uwc\ WڅzW!y$ٻNO)JDeڱHh&V+kcU:K➥^(NV=G afdmWרe"9\-,Uz?6c M{NG-7Qc؋?U0aKlg!zD m'+9z}hPTowӿ< +Qj#G\( S^LـCjIDJ6H$x_0s|I}5)Y/Ab]fT "cNk=\:!њ?J tA^H=VU;5PsǺM &E6W89x0JMUm9q:T-^մw x+HHf b~i~6 q˂{]q_]."3Z(fu ..rzq}4.YB'ge`bђa2uTy%ci@WOrz#DBS0/@3#ϢmPPnok͕ܵ*:\$YNI8_IOH@SF&z&aK[=!ϰySef9M8F*ƽ3hRN 1K y ʿR'_LGnGmUicw;% Eҳp"0^vadIfWp@AJ - A?od۴,G.߉bi Yy(. |j& 5󳥫dq߽$ėJ^$zGE76kQ,‘N$/.pA#SG LCa~n4O}G$Nnkocr*RD癄|iB7)A1yIsVTvzɬD#;g=тl((..rS6`kurYo t4%bZl§$NQyl3i !EGX[Ixhi O@@-:dd$Jv{J`-f0ȤUk_ͣNvUU|'iڡ8r@2Y_h |IՖF+RJF1sG\:U_&oәχ]`أQLDTQX 2^7rb>s&hO5"vB% 2G3xۙ "'#&ɤhrO6#7+˵ lxscY:w~ :!>DL}+b=ԺׂEUt=#M!!am+(C9Rq@K9RKːSݍJa%"#99 jX|=kPe׽nLGAT9weKxC!R"/x/ ob̼2U~9dtZp:yh5?Z $i3CtESw]zy S4'oVc: NƠ(2d hw~y_VT^K ~I<zȋ&BOsi20Rf,fCt֙}[^~jDfIiJgpV-3 Vl!P[&c.xd pv%LxJ ƑFDkuIzyI-a>2mvWKjg;uvA6Q*aDŽIU(ɯسU~)db4JQqN_nnWk;<|;s UϜFk;Cge?B%Ƨ*@SfLn Gpouna Mfj;  6~aZ1ezUq 3w{L_(SW;C3 k4 P#¯b^*Utf#S{X7mTÅØ-·~|OE0/ 7*o>TCS&5ƚ/~0hml"@cg9[D㯀]N%.C0P ,|Eܱ!^#a?]N>%5VJƣKso1^A[TSc0iumD璐"R(p~OH*~?D%"jvrGɈ E.s GJQ+Rponu"1c*JG0Fk_p;*]"740J׶'=goi=m򏕤u?\; la'ҫbҐIoW<#i TpD)g[ m߬W&?s?[vO=YRcafZm{iDv{}44uD.hi/WTn{s4:pJv61@J(7P@?҄\9#7_ǝI6&ԫaNɍ;ahnĂބ- buh~ _Wgߝ'E} CUkQ δ[%R bsBWݰM0gdt@!!V&4H=;8)6m'X 1!/zt0 4/b9\u'7ͦ(L`, qEExb#I=ơΘ1p<6ش `f5p2 0>ezʑ !էw{V+k`[ ˲S 9|vEER[۩U0[~.2DօJkH49b6+ 磊PהRX%$ `}+Jt,BRF2,q ,E(Se>0c`3}>}d ZmK$ n ϶@lSއ0f:e8)隹(j$%9(0.F$w3H1މ]j30Kzd9~]S!P֎:@Zd+WJrZ<Ɠ@N`zQ KI.~Gwag4>ǃ,^9N,ꓮ*0"GNP0L|?\[/Ձ^ܒlW&w,.U)_ 57@CH.|sHc%]\nIKGd&\D[&(3a94.fn{v~6U9jTl[([ٔ)%NlT U$Cj)8-dgM}0:e/"TM YhBk%ɷSBLi4/fVE XDF6+FK=ڢ卬l1Ӧ;,WCAs/hO@"+kWJ!QSe`GgƖnMԚzP30Cp@ f$NOx;[z [Ȗ6 b`lȻlSWlaiKOCZɼ?:| I4ک.+SfIQ!6gw2k 5q "7;E:{ ]et^ŋ6E SY]헨f#⚚~q}ix3zrhbX_!>" &uyy\9oEp!y-.z7ȿhXG ^ɛ]7h T !g +VU'i^ EB|ODcyIGukOwgݲVCK5`gL2wGԇfh1I<羧֒Q*)}!ixk&jT0gz!Rt `lA̔E(rh6+g~=`FLV^0fL`K3_eh[vVԕw8Cc azҦ9.`oot[֯{@\t!ҭ|Ё&1R7fA5_"#ʲOC}EgvyiOe7MU< "7RqU]ʞ(~ǁsxo?z@kd}(?ĔMv/HEJ Fw |g(t9' <#KGICj_qX*YxB_#(0Mf J=@0yqH2LŬVG-\b Áۏѷ\9.AmVoW?+g>MB: :w@l< dsT&0IH֚P'_^M*.{u)wM6gfqأF1 (6Pej*4u7=P9LL%'R tb5Qj$ɿ@d@*I3í/4~Wvfjz/ExׇY'a֫Ug<~a8 %]m%"D̙w79xT@ WRxȪ*fIjbrqkZ$I+`Hxů>g&&p1g2=^FTt SSj;},@q3Q]z'~Et Wp[`|-fw:m*6畅׈XݫuL24|;[WAc+SNj3/ `$ơ4]3jE1@,[#;!_B=Ij3PX缏l1*͆(~%-yU[Qw22ohdG|/}HXaz sys7ȿ襖JޫP|svZ<0bـ T0]-ϫJV` w];gluajNN+W-J7!3JtD]-h\V*C/*'͖,51?b\h=qFP^֭C9iSOzQ\AR_ +!@)s{u筋:S|(Tʸ@UkY3zT ;i &)gc&&g*Z=pD+UkQ\9&`76E"&zz]bO)a L41yƧ$,Xus]4xx:1Eym 'j!| +f_m| 2f HO}g:w*j(l>4 8RgrGCn&@_8&mK׈]-PZ1r>1 )%kO[ubͩև uԺZJlPb|kv+LXNC5 ṙt?~~=s87pN禱'BB>-vd{Kcq~8Ҧ[Q*ݶ%Kr몤-S`%D ARҳ4z}<zu*-RJPa# o.`p~U(Ț)H|!W/qɢw5q^cs;otHm*}|j*Ud/=acG|gFu-Ͽt[4>@~B,5G]T@D*A&2p ެw4Eqbp=U_H n[B ~>'Mqf ;H'ƃ) *(뙴?#qoO r?j^P٘,ZϹ)DlJL֢Kz֛{WH \~ A cR2fbWfzNc4(a2t?Y>0AȂ}G\cJL[)]͞׽S m.(AvX2[M}FXi" \Da`]KUo,.92nr[@ĽgR42ctNN]޾sT>b\(> }vj3qJu*z }MLZ\-k|coYWEi9g <ߐr)iV9i1"_)d6͊Vf%O&=L M@M/g׹lfWX`_yXI92~ҁ9y;ľq2z%#Xj>ѝZuHNRYˀFـ:KMP⒜gδT7jZ4! f㪎Xpbg!dn0frL5 (ƽP'튇E$7{@5)u &qĆ=2 nA%Q:>y gΛ`-9hiBL"uprIo*u]O; j,'DCQɈؕJ<"2JB+c*{>#0Q(bɦڑPvlf =I܋7AP4"9GN/*}n-ըJpP?,~ ޲v!ȡP^v] gռ9=qV&-5 QRKw3jraN- ^`pnnj >`R-7u]q/`جڵ ݈0 #MU'+CVE 7uϴăV$`w;s9KֈYu"UוY;ڭ#3_ %"Bf;?i vQ hnǎHuԭ|{aRi쨠r7opET&־VWDYk8K%* ? FԂ>kg@R\ɽۅ r5^;op$oL鲍ҵcFE}k[_1Woj1h^$Ct ;%R(rUu2(nf̟N9!)`B)3yzl}rڰ&K= 1gyh(fUaz>|Eb.M"7-Ց7(]9&bLj `B6VDb 4Lm[U$l,2377HԜTzJdm"l rH$+|X= {'|Q' OHH oaZ6.UL¬b+.,.ԥdUzT J%BMHi(1i@ʻJ +*icRiH'2E*s<2/ V NhZW ԟj7{֜wxGPI+Hε2;%P`Xuݗh˖ ulo|y9?dž^`qF.T"Vٓ8Vģ胊_ʒ[ciPqC6fpu?uF (0*UM%ըˮ@Z65Ɠxor,EF4#FПgZ=~j3u,hCF&][Ӏ:}9E:I0Q$ŧRYjb_ޱRP(έq^A/qkN6Tbo߉ВĠ> \5IMy]R Ұ3<}c/J'v+Ndou I0LZJM~*A*J. nv4ӥ(K'fII,R1c@{M~ vr?3%*T:Phzz45uVgRᒀ7Q7c޷5.%bHv% Q:_()_ 񃅢Wj@ŦcꜩqU[);|K@@zeXp6xΜ_Xg3$:+K1{ J~AQiirJvCDF{ag_u s6T[v>6-Lj1\T`7>+YW$r̝2+r&9hM/|aV$>N>eW!^I (d6j0X;IIn/}BztE.@${DM'0B$Y޲ 4vvsSZ{.n|p Bt HF QR+KT$#Ve Sog- lpwny<+rp^lS/FKo#Sr.1;!-i\@ب[z8t#quzjg KDMFgLrn8ݠ@l%HY G}f{ Q"r*?λ'y EL$gSkи=e-yVqtpi6T^gbəYgC-Eե{Y H585KD}use8̴J0b&2E/ O.7s,ѱ FI)K{QǚE@4۾ !U$/&a8}K^ k|E6@yZ U 3tۃ{EDZK\<$>HMk/$~XM9`2*#?33NL[-Ko/װ9l11bʕNfN4K.189$a64ӊreʃҪ1r*mJvFl3ߒzzUq.hBJMG+!bgQ.l]tP!!be9/= ^ߞJe SO|Fv 7iYU$qkqzqvWX|6yQ4ӣ^h(n3\<()wJܹ֞\@`(ߺ0Wks-?W?=~!d$g.(a#>dŖMx4yz\obg3B3?a;/Q͒O XѿopNk*\\q * z0{|7^"y EK 9$0DO/6CE$_J-ĕ+Ɏٖ~ci}2O.gpG2tɦ: wR/Ճ).A!XvX(:_1C3 FN(Kh%ܥ{y1E0Xo2&tvBh9BQu 0;-.˦S^ca!I[ND,1a״? ._ȷתTPdM9%NN_9L\k lDL4"C螋 @ l3U8)gkT鶈Ԯy.3| 1Ž,mQ?lgQQk*ٛ'ȜQdIIґH2..w{}2o'GtȨXNBDJKWe(n|>m+ ˺X#Q1PuKۡ7}mܛ`7ҿ)F^jV6ӟk!6߽a< tIv.s`9CSM9%k`I KȜȑz^nКdlAb!יgV'gM*jiJm e eȈ!LQ&"|tw%x! t?lCT8JE i5W[Kk,y)i,E&H,NYuOR.2xE`! NںG3;Uٮ,njue2P/?.FJ2*95zϱ:ޤJ9 88 >ӡ+TV0^&kbuR!!  &3`yf 4[ȓ"A5Y1JZX} KRCYQܤ8-d}@>0+Agʕv}!g0ߧN\ ݩ݈@X%ܛ$ 05LeOVđn2(m;Tي!%b]򇾰L>47"T2z B4 Oӈ.[k3 켈]Vz%yͯw~tUV\~ lP`ג٨z_v|Sg7/,z[Ϊ'@m>Yap.I>.,e'SUvZh> +o}q1 n ~a W% >.2n (Z6\= w3 6_֖ilA;$ӇFz6 ]ezŰ⌜ONk_$>&L&ZmfͤNXs5ץ[8]}cjŜୡv\z]^#=Nk2n|޾D>=:$[-HqN+vR4e_:&t݈iԣth?}_F,O;k**rAŖ?vCkp5g )*>ϰ%~Ɔˎr'^pZO*C|?[~<賺*嫢o A+WSN0_j:TtgadnM&u?MC9ӄN7 b` i46tK(mj:@(_\E"@Y+*,y 8\FJ; uZ'sƋߔǘ#|bpf/ű[g$c|ӶJ6t)b?,@F`s C/w7MP|W,M Zqo:џzω7lԇA:,7`㲼j1HA3 Yn["C5phR ϋVn0_:JSfg*ztF:Y)*!(_/ȡ7sӨ_Y1p{ 1n̲HouN:ږg ۂ.d_˩kB.{ݐ|7vF{=2¼"}?79ٔL>ё$%܄A QAs2FD,qQu8K^ R|]Gn#Q֬. )5.t8bȿ Ƶ+km箅Tg/C=wT>)9<7tmLi&85<ǿ@sAvYАFGFҙc@6|PM5χ=+GJ &Bcİ$*74#D^yl| *(%e#ظn C #"]ti?8=sw4|xwk'4B{(~j\lv]U'o\oP~y>qBRY^p+ "˧%sF`glO*gX"<%tf(qP\]-SAB6ͭ6F~BZ_dĤ> BsQlQDjU3ԁ4{`$g̻M"RHyGٍ2vh{eL쮚~Tp}ڞWI{]mcmܿ?kOm o\&B1k?*CWbh7!zzMY%wKVۈ4 l% 5!z'/^#Bw9vEty[ӣ0ޤWw}GY,1t˽yټ{ tz쪧w #s8`;Y}Ú֑&N:Ăq"uX{H)M-vv^#@o&vT͗QzI ]%*IMHnTPJ󜫌UoʟS$Jo%ߢ^ ZY*+{0oE d2$O^3W3| P!'^{PPZz ǕuJ=$[\ӗ6+0QM-T&'>.HZb)OxwuJ?T_4ˈЉpBWLU" ߫KES0͵++6QsG>{ꉷJD - 5QZ }ۍXjκy͆Y&~~Re]-@/h)763'xr,83L.R=8 4*Fl)% u!ޑqvwtY;x ˷M;lI YMr iR}]XZOQ&5iܽ&(DHX\mbE{:{i;j zŅ*)Q5kX'P2A !:PuD{Wܸ.4kc܌g""tr*m+״Gqq oh?^q.ޛnY|eV֠_~+L<'xeO~n8 ' bɛZu{0{y-aY*V?DI@,$У*P S7jPjCFA8eΟy_H_oǛgJt~"#!Dpx,eui aU|QOR7J4ۛ&1,CwQԹH6C+mKռ7@tSJq95"C||l:g*@.1MNK)w%fR 6Fez3ld׌18NqJ muMXQ.0~?.LfnyaV/u~2' "^\fPUpx:v0uy3x=6a@'O1` `R@M&Ah( K.:B ҰэSJ_S<j[?4|'rCLOˬڹ- 7V}`q1 G9 -1sWZVʫ@ ;CHWÔR_t54Hkd!cc6橽+zi(ٓ+ow&]c ̐Y>^zZJA@NeɩakU3h)Q o0>J%ʏqe5 <#&zsK߉# mfF lYl+B`L}>.]>5Uql{*9,Uŷ8R9zb5Q(T"Xd\XfIKc^P@ 39&w,{H&IkpIV&xq0K}M#zxipQnyx5ߥ)ۯuV'V-هlf>< of@2Y5 }rRV9mК^dUtX;w\{'n}|H_1\ *΍a~Z:6*m#P <q_5I*g}p岦_>! VτT3QΊ)+:Mo^($Jl85䋚 )QW %GS <~6n{2Iu)w<'[z"JK 8|5YLF.[ :RF'W\"ДBeM.8;ѣ\x2'j  `[g5Dvҗ;q7H*B8 C< cmYpz˂cKdݣY4΅9i2  x*Qrs01\];t=+)uD|ep=Rf&6i-a_V,ckUNy"ͼk*4'޿j- MnoP7#xvj/,qkr 6bNʲoyQlɗ.y0bgm)oeS))9HD#QCK-|PZ64`}8eX'GOiF*"hU8ot*F5')=н^Gse.sq'Y>jǖN6GL}Cory8T~V߱-}ӣ-k`IO}ޢ9tpGeKE8|Lt‡EaFls.GtKIjˣeNZDg C1zy1w` -.m-"s#L߃znF.miVOGztq?Ыچsʆﱜuȍa@9a0[9%f5.c_ zkfd(`!!Mq̋_".Rf&{"&4{T L#ݰeONBPN2-YқϫPf61,-l &a2@y-!AD^gKis܂[YgH\/;j1/DM}Ni}Q%;ȺQD]$pᆭ _=ߗc?KȤQ MY>"JvpPB{Cg2fpVF1-R?D-&3H un+M-=e-Y2wDX(X^E%WwU'"iIù$rꂥ> V-Bqu{X/Jjq,^'3ѵ60q^W@iС/Ϗ}i]9Q`e:&g{h<1ƑӇתgٱwS0xAf`Tw3$*"k(4{~E?}K@7Ŗug_,1 `HNJQЩ*X7Ôܚ ٯ >ŝC2M4$ֺF0fYZj?l_pj;ISdHs}C*j!ఖit X&\5w.o|*~RUº:&DeAAM.#W7xP *--7"Tˡn*a ,f}*\uDY;=JA_ϑqk.k2EƤI Nz%8@XN~-4^꨺BK5*LSZt1P!T(/׼FOG ۅ{XǹDj+voV;S3g :(X )f]1cL *'n n_{hBKvN85e)p`ԲU49raG>Y{禳zZ$Z=˯˫v|*NexC6I1y&yM ϯl s=9Rn@8o񑡲3)WK mEa 1E$ss۲Ř@Qhfd6/ڢ+4<QRȤ xZ-4meuuN3h+7ٽbj UVKa3-8-؋3+vMQA*:rhP !'3MQzfbgˡ"dW㿧輣1NoE5B50#cb E^oMΜқJgA_Q7rxtXL)ަԟ` McBs_ A1.U\il[kn ̐嶪Cgp;ljW[ʍ:XwN3<gX꩖v \4qa&EdGSd(3 aBjMoA:yx49x$:;^WX\0eR!6mp_DZ2z|atq?b >e4ߥeᱮ2m'hK^R?ua.Wj5|EݕiD&:Vb"7XtEqʝG=X_UA"8 L3pk[bGCK`W4K`H́LtBN?uN|T6p[zp\7T.|ѰĻ+x^kۧ:;g)_frtP]~9VZ;;[.utv )AB]}r7y qOYcյc.+MG|*4;5P#<$-1߆ Ve/vnN'j I:4Nv#YB&w`ŜƂszjX2\5 1OۙS;f0:2Qz{qmmԇ^i)Q]S;QHG~`՚r>/݀y*he)aLQgB;iLQ0P["-*8ZYODð9=92T\IM` 1kBT_w3]>'udQɅWD^z.nK˦DaKÀ "fąHq9ҧ2K PXoArQa枠bFnn59s<^ZtnkԌf:ߍ[ ֶ8;tvlCQ#T^Y)r~6`l'/V`1Rm7Te.󨺫@p~83щlF9DKy i頒 X:K7O-[ͻr;Ti!lvg7n~ +5./RՁT\J R"|OrN?:Rqp眰: <܏^=k\u#siRHM:kaʈ*Q:% UmQʳ<̝\3JDrq 1etR\7e(ʭ\ޠqbMY K 06=?6/d]՝~r:EH;s܂͏~n3'D<ǫc6p!D׌b;Vןk+ |ĕK PkZOtP`&_, :j47ŅR}4\'~34oHi xT%{[{)û;E9#ҪlTMC?ʟ;Lz#kE*~ۦ8::r$$:,_ǢAYT˅)'`{Rn* mkkՖSp4KPϨGOWEX,oZj_j5MYnX\O}/tYQЏUC6fFbDžPlPe*c LvUqCB761[ Sly747ΌȊeP8" cǘ, p_Yό$oLkc[07;}(As),F޼Z{ &g-go? m Jݰ7yiCZGiM#)iGQU;9U/ f*vyBb +|ݽc@y`D3x,# 90z6P.Nq"Q^G̢fvw6Qip2JŅ>B rarbuG0ln&P;7usmlsV Тlm]f&f$n'ȿ59E.vj!M? .%`2l6M[tJB59SFiП:my|1F\)cB\B֩ :a$~9ܓᖆJc`R*`dg ))ns*{o{AZ ϳMVFUO- h"?07ٳC|i洡^ReB;`ҳ[pڴuBS[p)v(v˂W}! F[e0P,iKR2$\ RO>iCdz[_q&Vjb}3~wA`JƩyѤh458A#_A#^TK/ǵ[Y춷 frԌm5& If?)8?uS`Ի| LnJhs2 AxSDUkܔIxGV/113NMi3U6م؄ww"6o8Al*R X,ChBas1a&[8jFl3J#]c!ժؓ)\RD|3TcQ&.T9;5fy HS?MFQc_7ܥUP]X\m){w$S{5YeJÆT!4ڟxNS[.MF|V[)y<\t.OPo ]όQ{yLu=E΍{|qٙ% ȭFy%>6կ^D7IniuI$rm?X5-C49lL)2b,tz9i04qg#qs$2Ft6td%Pr6]4k@o3tE%G?U%_l\Uy3YC^74\CJ TS w]Et;Ԕ WYeaߚ򊧏sx\"}>>gZ\U?m 5>G3&"iCTZ (U+?v-oK0rC|-ʼk 00&)л ޭ3;ri8WS[qb42NV #2}9~7p&2Vx*s$Uq < . nxVtIt/"eAn j~H3[)F# ujNlF2e =Ǐ ]z)8g˱,{DUȊ!~ k鱷!p%J2."'ofBsu.lZ}bUF,>jpPdY9рPDS=.fL?cdO DDa+ػ*#SxSuvn> GӐi21̪x8eɰ/bH0x5(,dr@7ͯ 2oڷ4^[s}ESgUЂNQPVI5RwNDݼt>%!NiNHMe@9B]7Eΰq;c Rl%|~m'ԇ@VFx&8s a+ի=_kr@R6}:[GZ wE;hb 'ʴ9s6g. N'L%g$ .Zoqdޢgq|P9FPNB[T6|\}"+Mx g3\iw Aӈ$+>}Yq؃B`zALmsIo9ak*d1Wk ]u b[^vuÚ| 9Cq~ynu;Izͼ#*nX\3>`GZzAĩsv pц}hL}0o9P5Yg <rE/RhM#d,UG˖< xLxBUϮWN/B?_,>b?kuq_pJiÈGCENaFOV~D-]Fqs6.v O=܃v /,1/?,~1`! _ d5O$faim (噶hsN.ZFWP79yc 6}WHc=MRR\ q_ҋ CY3P*[|g4R@I3BuȪ ^.yO_v+2 V%{'ndhWW: `C`9=|8m mnƲ4ex *e.R>xKGD gP/?`ˇ Z!/ni0:t7ޙD w%>Ko <Df2t ys,, #|f+{U=IUQc3ӊJfܙo/5{\\u l+-5"chQxd׋Gx+>a S;fV%eH8BqQ_N XSx%h@.EE5&,!%:qlgW(I/jr#2O 8h1hs`-8]uM18‹!(Ғmg Q*m~NXTȳ kvbʻ@=+EƹgSFC–,Ge*}(k^d J/{ ])l@7ZC~{rH3e&O?Z ?=̚D0 iB^-!WO﬍-d:KXIq(lմ8TҜ%(1ߊaޗrfN)3ֻ*Xh$FVH5kOWa. z6P+5,GqtFg#vlI>vTkB`KËHb0)ʝEa@z ef7eAnx-9?!H5ݦWnG|&>L&6"-uǝ.L-)ʳ*r|ijVk'mm Se Gj p`3EU<5PЄH`L|Z>-}"EsAw(Zʊ %[97fi)n zEƦ|]۶*#ln<Ŭ4$^бkv?[%pNʈxjJ*]%JxO*ËKW =5zmY"7{u N < %Q+CsH{@/d_? *!K*  rb=X-N7o;c t0d`YP^JU@+W>7x#NZR _n9KAD"u<`A[tÎ˲C\Dj" O2O,W$uVrձs)Tt"J8-\U9 OyP/xZEUyC3E`5bi Y )ӭ[( x*Yv9Dm Zn ʶZ=&+HξE" ƞAiZwl% Ad]~Y iw̺Њ>Uv? ֏(Ih/8NmN& 9֟}4yC 1|&U)$8wK7҂n"ī@ڰk;5^e]ujfA'9hS :^/kR4cf8Wd,U;BZ{NQҖ{ oUz)bFIEPcrn[ӡ[x6#vQNQ8d /]gU͌ D_dh[BaɺT̲RWE_9_ zɑ&^0IʲOo{b]u%IKP~,ݖu&ѿz.]?=qoxMu}.CO62i`sPU|6-Ht)91^Le6KC~AAObAIDH@8i5I==^<殛j`2; ` % 6ދ@})\3x'KM$bͪLk8w͍u3z҂ '? wإ6ĭ*eۻ9Y\֊6t/k.-r=63,E{^Z\حΨ==](>RԟK8# wWLw1)(gθ /{ څ(F ES\!Xv~RH:Q^P^ F1 Tł H'ܸm)` :\i-s7,etMޝ,b&nJR&Pvoe1_(^MAl5UɛͽoxB/y,pB h4;Y|"2cˀ/-S|yg\vV.zc ѽ4HQ/x:FH@pai))^F&SOV>6ΏpA\O`[܅NXO3E^uoua& P័r4q"ȴhكF\pl KbUQGa|$=,hH[ũMj2L(x1ߡ5)o8r2 {?ϡJ9lNΤ> |Ad*&x]_1O-2Lk1%eoj;EcL@ ;avH`SxT 3z: .f<m@5t}N׉%XFtΣ~_WnY+1:tp4ʔOouܸr<$ls Y\T!K$KC5ܞAg9N,|}B*֎1:H󙡓~=dy{>3YGeBU59]?s=w4g뙮Mat1KcIC iʖ~n!X&MwV ]u7q*U["Q:NG}mh]4:T(cQ r ia 0N|Yɬ> J\XwE츋-YYrG+?$1J5?_l/Z6f-ac`ߜS*?:QMc 'C<{;nS)KN a(# މj{7T]{A}\D#TJ"*~Eǣ=2ꏭ.~Pi76V\WYVV2d,tշH8?)ˮ̆h;̞Z$%SGGsRT6Rhi*IZRžl|8$h9XSh4J*$wK|zrvcq J79m"ݾ+Lna,fD,+b#c4qpZEu _k |"dK_.(aju,SZQ@sv@n5YPRwc βG8Ԧa=꒢FS18y7҆ˈG_Y9lQ^b;U 1\xdE؂.NyB bkb^Br:;ݍ)s͖.PJwNMMIM`'5cp&+\pLEWsۆ[~ߺ*k<|) pQѣŞSБ*YT\q_d=/6t(PUQ|I%H\=|?b ](D$'پps:k,N ( lݦpL2n -Wxc85<Ч4Xz~ jB٫?a)R{`V A0)t{Z(e^C8-6"YĜ5b5SO[MWB[p}?Ḧx j(4:%3 <%/$ټU2j<$ '±F$i!SJ_hU;bY(;gh=c `] &AB@XZa1 \~kz2{@`jNؽh~Xnzxm%{ uVQ+68,9[RGrs>T' h'؜=c{1D321+eq:=U~Tid Qn' TpVޖSYa>kڞ 9LuV,&߲(.H@J27u?8ېi(OqZ.BTR.[_Hb7ڱ) kQnT2F #VP:Sem.9wTV([n T;?lǂCF!Cp$0>w,noWƻmD9`T:R4(SADCql^u]Ӂ _㒯565y%,|A4q+2|c"q:mGW[<<'OKָz,i>.,d?ַyF-GyzObw'{pta:cYIԣt[4;ehN޲'9vNmf SIt3mB)e mkg70vlPnuؐHBR7k 8 39Vk0Pw`4᪂]ҹ"[mHe0S!c2 Ì))/)q1E<l7Ϩ1h&jX|f`OPCO.!BOOHgyq4eD8dUȳߧWʪ />`l V)/0]Q58 _{6y>h|#+29Y.(wI:fots(hԓõG_WA8(w FbzZ.CN$a*nM;z4b}N:}'rɟ p?@/2JʘLCUIed1\rwB^Z9MV9 (Uh7"2,U 6y3#N&y Gf'x{|*Ѐzt~XI5әjT/c_Idpn91/mwY6cuVxYOb\B~*{_nw'zjv7 z VlQkC` JKKjg^+LM"@lV4IAz>_~}h)^ԹŚ5&30ZGzcA1,LG $+ȜrA;@U.IS>Xgۜ@ ~Q[@-@͐>>w{(`y}XjTrXJ--Ya pFrZ؋I%^ac 6;.#[^1>4M>H@%~ {&-/'8i?0NtV&xp\SxWUe54!ԠVe LrkTs@(0JܠLK0ȣH%[|?IUc6t1G6qLQNU5`nU9;oОGv83F;O{n&辬$gбfګx&6{lNm@3kaMN9s dTkŤDFw[={qf0M8ߴ&5a8Tk>X.927(OL.2%,jl؂ȹh`ZSQ"ƍ0I {yzfϵSH[Պ_C9ʵd)I$)unHj;a~8R{ C*I&y 0cJ^\3 $ޡnƆFVDAfgXN9jZ$1뗜N?gL#tzV78C{F*, lnfNzZX3WYș1yǧJx4.qǩWй؄$\C ޶L= [x)HϕԀ}S0goawIB noB45]a3E ՞4&$CA_ D1c;!&dv jAXan ;UPҟ33Td:MLJ9cªd۞՜G׽)k 81>(z?]LE@m'Wʲsn v˿'M-vJaq jb^<dDjtd[%ufZwGŞy A'MޣN)/ִ$v m)n͗$϶6 TQoYm=q?<>qeۑWEXI1x 7jF6Mu_&O2 BAmb1Kkeo<[͡vYu#f1 Ӝ֒xQdOzP${wthdhl,2Ɋ8l7[ "v߁&ğWx$W#&ϩ]h_?,aOs}atQo>øKJ9.c-sK.8b/h;",N`6 Q^=I/<|RY-w?[//8ަ(+tUمW&@j^:|镪*M)4]>A:\lj;Ś8V-! E !S Z^;17tƒq3(.,XfZ8NC^!RYq+qr[,ZتjWJU1 VI3A@9K.њwJY0nlX_D)vb6/JFXNSO=gx(t'(oa[/GN@iQ&b"е"2;i'|gb> c]"62==Xr0P >1>Mֲvw\j*ՍC)&hxռM;IV"ª"+n,* jUܴӾq3)eMږrs9nE3  e^S8a!ȟu-+Qfy+ɨTUUѝ]7&ۏU]M&j~-}!A̐%S>~̄x}U:ۀ;I R83PH0ư8XQ_a7L~䠍 L ~TdTτ޽<+%Qp Oo^ 窨yw8*^RVA`c;:,XqE o͖5StѮ]D~fJ`GϗXz oH]NZR-}=,Q?A(, fX8.%<[ CSIxOsK_<f}N#!+.~z\eI1m0B}@ڦXX ~Z#IC)9.T|6nMnߩ N^U7~́|`$.xUe58J2YѮfeo]P=uqA@;6>gQώh(DKQם 'O,ʭ|a>h@{]AkdjَL ?<@!&f㦘Pt(}!!chz EL.ŵm;ƞX86't^8sZF)dOdsqCnȦf ,]>j =$} VJws$, %̒ږqW1h%-\x!juyoҙzw.ΪTtǛ2(IN x{1ӛ] ]habv 0{a^؋B#2AJ駋ʝm21nM6y eǏ|SGϮFK$J6ĴZOm@a[$t?B{T-Ԣh'L65'puj 03,=hy Z<׻̾)b[ļ'SûIS8=pE'46鶬(劸 ][5&f _UjC$ -5+IEfۃRe jȓ{Ȅ a1bɛ'*9֦̇zK&#c$)u`҂Uv[nŻUmgA[%2T1b-ԨJiɓj8>`Pu$p7 L|Իm[&%*O[!ؒ;2Dž9Vc{(a$|:"\CA:gӦwmʤ0qmP"c{!/*lW`Yj]FXL Dt7'uAkW?4asDUBM?J3-DLm[ȯnx0 N4϶j%ʆ |IҹSp'qܦ·}/u FmXqա, .U5gZЖ!c MOjXV y!zgsTOuw79v*LLYǶu(or+"S+ 86xAV&VNL`uFŠ&*|SO=](3┌.(pc6#?KI]F w"§ݽ"7#^'i]CNDQZr Q2p+/I:~YNc'M`||=?2A5nlC9M \Ͳ֐mE]rjN+rN8%+8oi#LkzKj 䆢2`m |\qݑ.+;J;t`_sM#+ե=^V%EB6yD 8T3l/W`!N ]Ҽ}f˟Rx^CŸpJ@&.G>92-e~׆+M~^D)҄iZ5waU0W). i8O k*:M5QP!8dbx<6ԛ sd+hKx,*erPV\ZIkxA+,)SRZYs!rt8GzMȩrBhw9ݱA&j48" -nt@ V뮩ތڽ7]zJ-}*nh>INS3(ѦgA~<&єb13' W5`_+񵢸1b37DJ򶇨sdBEw~Ss-"G5 r7Z 2f-\dYb釅ZY1N k{_C[+e;Xxp(@-"z6=ٲMx87 T$$`PUtΗD#3<S ^ݍ!ٕO6ۈk?/Oz?)7\wġeE(  &Paȡ4yN 2ًC6p y־/lT+jkO(!A "怎N|kG$$&ods;We]?jri<# >О~x:kZB+ Vwcq?lR%d͆|2쇐)FVO*zQRoyWI;0f1%sגluO_/Q(?%'YK[/#^cO&ȤEtYc8{{qk.nQt*-UIߑTR!0Z "̠&A[mmP<[Н{NIuYɃae/t@$qR1]6:O=ert/ې8Z|Th Vڬ`Rvl9y1z FSou8ڼuΡnώ;9uDLٯeCTJG}@ȆeQ b҄ >U& 4s==oBwɌJ7FFDۘEt}aЩ6Z5rFaVJjKr&PijT7N [| ߠ#F!]⥸e R&MpOk e z|瘮ŜӘYqT q5zgV`$&U$s#.*Vb+%_.7#5b0S"EUS:*[䡵'Coja#8gVlTb{ uԾwcy>!ȹAɒ1R )aS,&l..%Uv ]BREp|[$;Up-}(:^e[B\s+mx1?I!W=WoH?mˋLDk/t=1]I@ןk<߈L>.w2<|6 :akp0 N0b VU%x=lG̷6 *fZXQWЈ0&>Yo]gllNa>t7*277/ʵBBF9,)0)h3B&߅jw,WpwN5,w)Rҳ'8Vy-7&AMiQpr zS?L~mYLQ}ު$ae4)!b:_4Jۋ?^ɐGELgn@NnL Kz)q\hp&mo㲡AdoLZN" 0gJ:wˮXt *ǐ-b7DI+E8Rxv{„tganY3W13sEv:O:y2SA/VZp\;O!1`CZ" 3cstKIT:QNNsɵB4SLq@#)Ӟ,q^uc#ћ7nόƖhx$Z;h5'1.21lU4K\-` -O>H?zIkqm$ǿ> P {R@Y8Qghm)*N<x+ÿ\ds( F]+~tJ?<N%\zۢTgTr]} #P;uZ|3&6?TMw"`5XmFZCr㯌 _PA.<fH螦'm0*:0O)'bh -08tll؊VlVlvXr5?. RuPRi>m55yM?)V8cEվ嵱wvFW^2;Yu<˶27bpI)m83Uu/9ʐ<ਠ940"׀~z!͚ջ(#PpNfcSO QJejMWS6 b\m0CVE %"Ӕn'K=\齈BPN.ݍ|Yv#'M <#ΥsG~vqw' .ڪ;à;ܐa&K{&3c <Y\Z*-)>E*uQLF?!Pya!!_KhV?GIizui:T^ӛWn+3~ZW3[N2~{%Z]ߵl,dCV‹D4J3gS Ulp]崒Ǝ 1v+%;F304 ;(Nk8nW#/6J)3@zST׈lg e Vp%Q? "B?oyzKĉ[{+E ]SYFA~U2TxYC#g* V2wd-~7Sfx5%|i{Mb(myP7[K_ RY RLmWn6_ml_4pE%3I:?A[U)ش`x "Ts<S5zkŜ `YXJ1(Y:'] !_"۵z/b?:gz]yt;/@N7j7"yGnS&}V뵌Rt'|n N;/U^Fќo fˏMrI-:u,.͵7!!42i})L =%f´ Iٳ[oa-ہ:kb΢O>jf%mmJ>"Oį]ךZޭ5!hmA[{-,8UM+<~!Ag@rl2:WLVYhmu9Jy]ȋ<, E\Aɂk/5>HP54ͷ~ArPvIG>=k~5,2?dyi74YjHbt~ >)vw| 4Q VZJB\%go<}xUvG&XIs1YyDZlp7G ,rU~A} yˏDR|QRa_1w7Yh_! !Ɲ9O,zO)vroF%Fed4 5SFMS˾)]HPw *Qs^ĸDWwd-4嶇P8/}6HXЌ3ff,w8amɣǣ S^Ah ,,kP RGr$_]0abKԳQiEq\ Suud9?pGMkVtF?:q f'`=_B>DR`b=Jad=񜯡 6,J>\,H;`ozxg^ik1[;8Г( ΁:1Ck}kR,;|[SIM<mnʾr+3mFy~ą#a" efO*Rln6FGu"^B[8e읺ҵ}_5b135J{ݒ|8傗 ֏AJ<֫K rE HVT\&61u&igrc 9ƨGS4>땨n mHNl7sÑܼb㽵v;pAM7|P ԲDP<ҎS^KLu<ŪgҌ#s)VX4٘9eoh-Mýz*kOđ` 0,LI%UqYJ%d2P6SADVĖi~$I+Dۢ =DWZ.ǪrQyܨklG,"<9J$+gMeV1Kcw `wc3qtr'Vp/%f13Guyc!]U|Rn\ь\i|UudT,݂[#NOZ82FGFyD/8@#4p7ivPTR4fө8U]9|qUhC0k#?#"bQw9:5hd/F|a1`T6*3R~ߕܦyH I=2Wk69:ȑP;KjC>5=Jlq~kЫtwC`k E\dWzqp~[)?%1ܡ8AWVPxBDPNZdK*8˼E\XN 0gu gV-Mgk{0ݭ<"pMXׅ(Eg!!Xp,AdL~ho~HdFnis3W>囵auㅮ)'giVQ`M;T{p,ErΖ2Mٽry4Tj%h&Y>)Uu0@:Y@Tc\~t(8JKteJ͗.%qOUW&5pb,UUsֺ$#VWZ)?*^"  \2EJ#/ "+㦵W}4@XemSvKbWBFy\씭UE>lH&M~! Q)*mn٧XUQB%Ÿ0udPI#):o`(VeGUuܰ7d/MH{SESh=$oDm{: @k]ACpye NZ02v3tv]ɐ Qrk"ۜAw - ν˞`~k֔Ȏ`Z4i)õ_*{ +LZfFOHGwм#xp=fZK-缜#L~F8U{¦ q}:§)24N,@AM G{["awܜ}Ȑ[r+,:VWDf 3p "Ha~JtqM_KAZ0Q;=冶`t*]V+hX K_"T_>\o2PKE$0pl& 1H3 ΍QO|?m30I<1xyHks iG!F;+! KeY l<@c%W/m0ΖxY~yeӸ`jiDx.Ql\@3o0=xv/{9nk } f?wmKJ~OxJ[n"sDZhncZעJfE9oy]Hֹ FVx9XAcگ= L|px/\]9X/$t':bB7Ŀ^!!~(RX/qjŹ4:6SD] > !;8j8\74ʙq! t,q+X"Zj*¤wFh )U7#+|?Cv-tvN!|QiWBEͥM{w,aΪD\V\r`Θ [q["=H"m9WUݩ R+>7ˬW^,O fv6~lꯁ,r.)U[EFЗ.v*se,:(Vn$sG_>h޺wf'"岚1[Vq溜/{mϷxXYFҁ1P{V7d*@gI(rB:@%󷫙#ր) 7^"r:nkRߴNhY8_ }6|8PJrҘH>T;Gn$CU-'{hYJ@?G s.aIz(\"s {x\5MH6.:UBrg?D#Yu(V]fHQHٿP-Y*hyoWS뾒Oc#|^JmF Z 5J/+?7DNȢaY-&zsF ųv 8*۰~q`O 6I(LP8fe 9 3$tkdΌ?_Ju'bF7+ZbWrF%D2\n{x[w)rO{E=M5m OlT9gژHVC9.B o9bUmsx6ϕz#u<ދ!*"~WT_ ; /ucC+K)aѸ<eX2?KHlRTop7Pe!Lv| tvژPc.>eCb &'nRV7ڙ$4ϐF:?T {]/UЦY^3OD.Dj!}ܷg(>mE8{T<5X[+A)VCZL5檩"a5Ue虴k |I.ijCd{wIґ%H3tKg(\!> (YOjdeDF5V-'#0 1c=y$d >kzszF(4_8N*N u]g#̰̊xl vu@ۖ|>O>[ϝ:ӕ7`3Ԭ\ݓM.)Cvsm/J V_>Kjs޶uP/i?%|!vEq\ bk-P嘬R]Q{hA LlDT#5 S_4k*{An粫wR9}IAS +̜HU2#JWպb#GֈgEjrtlv˂e=rBj$)tviT1}<17Æ_K^ĦڤDTwf5UsWѯ2zezIL*$yEKxmLqN&r_tWja_ 1^%`u p}h/h:<'ƮT?Ƚؗ"'{a9HP3y.L7rWBlIMVWCN9|^u_pV5}V7s2>FD%\]SvdgT57sl{f[1[* 'ֽC^^.Q=,m*  4ƞ(W=C,Fw Q:, ĥr,VzUvpO_/ LQPe/4d_>׫? vODSJ5BָfN3&cj5;{ª~t6 !U`s'FJ([v2UΊ׈M~ -2z4E1Ulã4p $)?ZJ)ύkֈjfnd6j-6gJ9- ʹ`':DI51ijr 2)B#9tϟOO)4.4dHd6FGG53~}.L"S-7tVcP~GZs\y/Bcg0ȓ-ʩh/♤oC n?4~?..\yR?LiiD8#Z9 By@3/a!ԲDJ'Nr&`xY*n$]q-yxꁏ)x7N¢JR_J}a) ܟJFM\{p?PSMԥ*CS'BBtuuК yZv Qw)ԑA]CB"iEwX6PĀxv!02*Gu;:`Op;9UZtqOZU~6;8!7t?sWe fa-O>'93mjw(\ާ lSv#`{D(=fЪLQ(X('Drhwx Ibw1֪zKe=8 JMcg~5XEMLe.``}7T+@is ̱]>C104 .3@gD?*0{^g785})n%GNė{VfQYmH{UIoQe~2Q:o d`Z$/b}_9X& ʼn'EinQ0/#Gd ѝb-ͼB3Ju8ljݐ^tm5gegDu+yPZb' XwAʴU^9>_qR D=g)؛JGڨ\XKqlsKއR$uRRu(x :PBs1&6|' $OپA& И'aPpw6KD{|N\ #LrD7!1L緧klsE XO_9EťD "q6#{ |dv f%4^@^< )R+@qW'S U58|MPƆe=YWE h+^B1V-i\h0R/{ Dɦ:\g<#H4K-#i00hUv<N ^LyP3)>ux@'۲Um}"" P,#x0h;!0`FUOt.zC|~5W r;YZ8B42ec  Y1zEGIG+3ܰ2$2gj; 5Wxn=x$6.+"=>)7s*)kyC yk7 s&tH!^^b)_o HP샅:e^#ZssyPj9$,PY+mSDiWyVM :%yeK'Q- ٲ D 0 کxyyu^bW6V[./%+lC1 9MS4!q?ndbWCS*] H6K3G ;[ܫ{Ef9^q퐵*%]ʧc|#R?H?aE@vʂ5mLluE67s*+1/^:ˡ5BQI%UEE Ϸ?(̭Od}#WG #LD:-`CEbR}X^1c=~}?IrK @2/Zb'<:DK3@-舆~?v47% x#ԗyq 8_+4iV|کg !LU#82'#ӄyC֎T|pv"aHbwZn$y,XC}!5a9(ˡ=l|2yٌB`4ID7<+ mb"KzW-۵a8!M]lHE(\l~өx n}N%X/($}i/<-@Ŵ1noz_#cHOq .@-|#1CWg)ӆQ ? y~1 t΋Q H/&m6i(rYAd/+ /QL6 GōnyChj/k88]so(FC Ň;lݑ_BBZ]kgy)8?sd]rlBˋ/% }aU0;fBԼ@.4Qmhn(*9,c2__` ~@qxpmdAky62j:r@񸇱ӈvزրb4!ttz9ݝ8s7|m0H4v8t}1D" lS=tokܻSNOMf_J:жvnŶI7]\`Lr q%%99_c9'0:]7yPה! ܦ#\=iWN'h os0+Lj'pWBܔnaO j0m9b|fټ0LS3x<+ YY[ZGSx3t>1bĮeIn4D xriXz-"L7]|m%vhAHOVx"5׭r\A[VQUKïZ` oj& yH_I C] jRK2Y Roҙ x5mzhTj;yT8SjFOㅒEFR\0,|>'ZZʴ@Dch$T)4BjySܭf$7g8sa^ h~ &[,%c=6;;8*}兦*l0X bfq[|""@}npc(oI ߲A@jv^_uzJ3:_^C>P"Ot` T#V/-ǡMAkG1uN\A+լe8n`LƊY~ =$G $B{/1p, SDa;8ۻo<ܽ~"BUcqNP* 4(_S0HZ嘢.q^x萵Bۙ-r=n`!tՓm!V;RT:NU0v17YA'#gk o"CDcu8:䁠ޔD‡ 95; f{Ƹ>dEdi7ۆIk迿Zu CwҊ8c P|zX"DX3R]f`ctgS)yXP&/:j1D͚3lƱ.ÔѺD(f;")| Ht Rtgc0-.zB:}C6fZv]9~(#ÂJXP"IH*NDpos;xn{=4Y&Om2#b Z5@A P _c;;یȽM/\d=LDGa?X0\MWsmy!3gK:_ep~0ܮ4djw}n;5.(AwR8͖쏛zSHMd}uy㻽(usRQ0 ůMpЫԣHWz*dx_4,;W-13T H+aѲΫ`ixm$< Wx"ڨzYdwI*s} MTUDbv}^fp[`v8MECS  UC= p} ;Yӌf ?V`5VVU`Lsnŝo#ÅFWya@|L.]ܼ3AP霰{& utbu!MR}*xWw:SʘECA09?bM@CH#ܣBbhNFŹ^.{r,<]j]w,HǿC$XDa'QQ/g^!V4htP\%}R & Qp76[MZi?B fw bz+'DWlegֶ9]ڌ/2=ʶXc[K^0mۅ2J*0nU.x$vdnVͻ:Lo=NhEL&+3]q<ޅ;fJ2>2h:&bbс/:uĠg#!eK,Zi/d]9O4W= _{-*Du6b YJcm zZ~ŀ>Z^??V'`:ךþNbo5o3.ɠmLUO0f2G*|aWt8.4?-1 H|e:%x2@"RNEALk 36U xKXWJ7hu8^~VhuqR=U;Z(Cɺc1Z1qxR]fD_L!Ο 1#Dؾ2D(/˧1G(5Wm~;m:[[!֊ʜ"`.7JX{9 5։f J N&Dt$=q/_*JٸK$A_~JSunH#ʹsbc~Ċ(BtS+iTHV3*Eqw54fM(eR!3D8b؉@c#.7hՊ 2v y)hgv+gz!%Ad .l8,pD3)IF&z{xTԧQya-_c7_ }#zޭXM}&QP nh0Jt!zg,؀vǨ,6c9H)Xi>#\e$P+%-:ؘs)NZR c*8vuf,KZ&r 9$p#_(˅ѕߊ Esεm`/z7/[kLS='{gׄ12/ddi?/sЌ`WU~�z1rQBf;q>F@IHX2YTӀdv.dٝɇ(oڤjSHQ1 ul dTcvjސsdD1r=XTƠCVQcR٦dBqR'cw\[; v'hEPh<:LXS|K|>rjdl xRkhE>\̿e3ԙ [" -{q dK^Yw?ekT+x;-:e]7gI7-hɅLbt6Y[,MMު%1 AWMIR*}4 ͡`} (ǐ ?*'Etpy ) [ {'֯ P<\:uҳi&Uk/[ ď٪mDŽl_jjTQNLݯm1#$ҾÉ!NDK TX7ILheͫ1Oa3q[}e+, 1NbI?lr4\yA F( rf"_88T87HoTl\G yߠ$?ϝnrNf<1Qm-ea L>:ZDM3gM @} &ǿYqi{TCUÍvӴUw'7qWъ$~DbEWb,J\Q$/Eh0'%UA}D7 p8oQ"-ߔc In>cۥu ?;5N_D.jP>L7xhY'%<>eNSÌC]Yh^n^,_XsT;DPSF6g#yR)j)J`\ 먶&Tśޫᄤ@Vi˲55C&M$Bo* g-b6ܳUxCx\w߅iöqؔ+}oFIhؑoN՜~fxIr$zIE6Ml \?+]ZM5Шt]]\`c7ཚF B4K@MUnen=B09 AJBq{pGG)fLP/ ܦ7 9F@bY }₀xn5l;_{|< eIR oJ-%z~[JD`bbH1mW~$TtAX\84Y @f'@ %˦ ӎ*a@mQWLa`;*ޛ;TYRg~Th3Dw`2Dp-'Cr+ \F@0 ڀ@ʘ%& TCڅ2pTCECkMS7K=P[4;=,'c1ǯ0$!!ݠd]NL?UR(|-FU愄IqJ eLȺ_-Ddw),v)5)I)*|hFw#Y qpy:[ÈQ`qa,0==ʻ> /vD&/#Fڰq'sL ,Kg>0rFP?ꚗyiNSin̾)F&5V}Dsr&􊕟,\b|1bl"CL`} r 1Nh0 Ⲟ.=(*f-YMS\[zEp v *+5瀠kXr)6Vo͋ aU{:urVK5)?|)yZcuOƭ>{"!߽AWT/%R_NgΥګE^᭜wa>Bc̝lenh+'PJ9r)޽NaϭGsy"սc *2$rLtbobOg ;IȍigzW&A4\S+ d嶋 ^=Bc}qUWp(H?L[ Hdc>N.xUtC=3ۉo? &l} k7VsfisHnÇDT/xZu'`}Ȫ{b{0(M] MP ,kK-]to)0n:3WjX/j/ᅲ;K+oVJ\1abcP z||8ђ}@5R#I~nbEbgW)[ Xy9!`OC+^ꑸ_ڀG5}4.q/5!uN7֝ԡަ2Mÿ{ǟ9!kxտd`"]@;zwF}9aqLtO%y` ɷ/d0o' A4TA3 oڿfFrD楻.+Lcu7Ȓ-@@6 )h4pRA Ta4 =A,3|e5wgbmpcW(~|ejdƽV,') *121U-oj 0uJ։ωx1pETym ,X-۫%3]e~YkX6Q"8p8}WFyz)b]Qj~z;|ztj+;9zlZ)fhZqw}vFyAO\s(*󓆺$w=9~8GZ q.aklH8”@ˋftOlJ޾SToy/fTRa֪F`q'Lo7T\XtVQSZg-{fY*Աl[v4U N Lg zq>zH-г/ (;~-(X_,ISsebC&uiGϦV1jq9a&~mWqm7䜁Mv/yY(j6x%1FalY,::yRS$ɧxbrm&_Y-!p|N.:] _$ͨD$MgTǷN#+~l4>A3&8 X߇>e9SsTC`CU%?3t|U\ZefJUd\ ՚TѓFQ~FDRʯv&3 =ef~`l)=w;4evqX*; E7mN$[|_M /PvZQ^ Pb~'^&1eTԅK4a{Gj7j%*5@6`]FbT֦+*;D^^DjƦ쁳sR:~z92-|@Tɭ|?_!ⅶX'ILJ1iL/V (E|Ob~⢕\/Š)Bkny$ ;;9)\.f"z*Цa{_/uTTV;cC"XGj6=֕PIUwcV1BȗpylNǧɮލkZn7 upwx_ܳEOz2RHC- V,z2v7{cyt݁6ٙA~nW:Snr X4 mRV=Z)fS'{+m - !<亪?W+S^OȐFv%vݫvD`]N]?`IMpڕza,ߊZnm'-[c(ewiSkh8SlǕY CVeM/67FP='Pc-Xjߓ>c^ϰ*x;ځ}(Us/80"W%9䞌0c/-28'ؚ ,H :!K3;0W`:+RQz-6үyIFYn:+.4Qi8i)TA&zFq8w&c0eU,ZŽkwϷ7?_|:ջaֹ? O6Ί_}]@ !:ZF$$ ryĚR4>Y}YGl/N*ZIdlNbüQWsNVJ\ڥDUs2]s~|[c xV skJ}'7Se|:M;D3Ԥʇ|{,p\=&&Zl&VwYgqP?|GRFG*+J_泦 aa< 8pW68m=rt0'ŊЅʸX6#4Z+]CQ?!ƉD %% J^W5O`·)Z?+Rfl2]-ήb)-u:>~.kFDokn!4 !v.wpUlԕ5kjBAV I”&_):;Чm~ak#\Xmn !l] #G}̜WUqV##g.'س`Ez#,?Wέ%zz5Ej si fkH<'2)u7*/Mխrq^rxQ"Q/O_tL ko!`E>ߚ׵ &K74ue-%ҺF ,}QNhӎ%sяDHe H#UR!PuKYWhk ݇#F6Q#zw[،tblAgX ۝VkF p2~ڲ/U*1-SGER?uu:]Ϡ )H&U 2on Z]!7Wuv5!2|r86I Jd.I&cq 0Znz6M"W CKO4PiQMi%Ƣ:Q@YZsurveillance/data/measles.weser.RData0000644000176200001440000000311210716603245017352 0ustar liggesusers]oU?s7nmA P,TAJ.6,xlS/AbG$O>H1>vηәvml~ɏ73g9辮^saB!2a !.sa_ B͸8X*(p{MA VZmvR2 ֻx'.{+| p%!U5G>|vMt0 |p iV`'m.snv]{{=/_< < | :0<}q@H8MxBD9s sIku[jFqNFm~8sW#>bⳠ1}eQccjDLQώTQPpQe}?Ê`~o8/=y`V&mEAz9nT[ C"<2q}VQוUMj>K'j[5~u0 YNU9JԾ9>Գ~ztĽQ&hzp5L*ENF(4SNZli]3Zh3z;Zjr줵XuRek?0 `0 `0 `0 `0 `0 `TՐO9ǟ#BTJŊgTf$i_JJ$*.c9]W&ܯJӸ};ƕqŵfOzN=?s[AZVVنϵ&K#Vv]geeMԯWYYYWk5~51G Gʚ@?]\deeM _>}YVVz\zXYY腷txs++kʚ@?cXYYoʚ@nϗt_deeu`A*!PYJ0T/ ya C\*Bv)ȤȢȦ(CCKGyaI&yaI&yaEyXaEyXaEyaM6yaM6yaG<(FRʍI6m$HJf#)FR鐇Cy8ᐇCy8ᒇK.yᒇK.yᒇKyxᑇGyxᑇGyx%,yd#KYȒG<%Hu尣*hT9\ht ,;w\Z=o5?؆oV67u+~ڡ8%'cS|^h=?yj87:?]:7: 犪%FнbO!?< ݈surveillance/data/husO104Hosp.RData0000644000176200001440000000125312625315364016601 0ustar liggesusersn1LJMj= ^W$* 円UWӆR_`O[O=N!e(kZ-Ƞ>YClf 4aIwo4nOB+Tǰr1[n LBMAxX)11&?@b-u6$ċ܁X~"g WpPhrP07%1<珉vVڻi.46WAGGE_q'ڣ$U H ^ӖRp~M$.a#8X`u٬*I[xN0V0u龢~S3|HO_I}: -=Yz+r%%I ˒Ǚ h7N<9ס~7$λ.g2Os.v_˓qz-h癮4h^Qv~'m+$}qsT vx}LuK /QχtgtWC=b?p LCp(8G(cp,f8p"N843p&8<"\Kp).W*\kp-7&܌[p+nw.܍{p/x!_+|o-?'_+~/0/_!_!_!{nB /俐B /俐B /俐B /俐BK 俐B /ċϦwa㼳4F~c}ԱF.0Z?j7qLvz>1ޞVE[W޶t~dKLvE/Nx?zN_g_ߟ,+ݏ* ug-Ao}wOmۢ-)Q+Wߑ<\y뾰Q?U=o]r7<ϡJu巽=Fyζ?J9>>@~ }FGg1zJW-կWt%Wvbئ*?ӚKe5 KX%,a ,,2ߔ]Uy] |"Wa Vbz01a cѽ+x ma;4Ң3R)6]PXRLO#-ug{:tk|6fǜMMټI[g"ggbl?y0E"surveillance/data/MMRcoverageDE.RData0000644000176200001440000000151112004012605017140 0ustar liggesuserseTkHQ>l4Qq2b4lGt:[3rg^D~"(GDDdЃGE"":w489N]Ubq8Ji̥e^ȃ4ukUi.9U ,` I!s^DR9#GBdZ^TnD7ra1`3^>U.,h&PƓD[vӃ:։ct}1ᡒQ?h1ݖW4[h[6ޤQڒFs!i3]cb+:d- 516@ih`Ch׻K.@Nn40w1hY v@Ήk~D۫dt4qssqgc?x?:o-z~3ԡ{IBg^4~[֥o_f[яNݼ)'{1Sn9Vq܆fd?t<DD}f֫*`&v@_6ЃVtW\~^녋%K#{ 1 KZsc.LvTL^߯#{Mm5u>jԴ/ݟҳ \q4l=}}`\>9??P68{;WA.k PPiǔ%gwfOӅ surveillance/data/salmonella.agona.RData0000644000176200001440000000065510636320360020014 0ustar liggesusersVKN0Np +V@C6"W'p&<(wOS%"FXu2ܷˡnݮitZ^ vs=H~9ڜb՟P|h Kgu.VsmF2/_t\ 8jz5/4$'j+ȇ5ε>ن@x%saaT+S>xi%Fb\k$/cbc|sZw`.I!r.aMW&fI.jJ~G3Ŝ.o C>F+sL2$UμfhlVa ǟY<4GFаk߼ߧ/m=2X߆w+ surveillance/data/stsNewport.RData0000644000176200001440000001213412645666575017013 0ustar liggesusersBZh91AY&SYoEJ~= B@p 1@q{0ْI"!2`#F<4FԏI=C7 2zGɦS=SzdM=MSFFM1i| _Wg`yow~?m޻_67?+mzK}8\>'6|3mn7;ߣz~}'w[G{7^+?cq8n?#<_33鯰5==^DDitd(PH*@$) 1J &U!$X")j02Uc !bYsT1f0c;l%d HTЩJ0*UQ ȓ Ild*5HT!KeIeId-BUIP2UKPUEQ9B&q4lZ(LCAEDS@c(sHb & +8dhTgHCc"HBj* Z Y) I3Le!% U`RJbH!f.Y-bblk{)bْ^YT08BbґUar1l0XV5̃&B%1< ߶7V1$d -iʘhB@fK7iJQK$f!yoJV+I@K? Hї f5[emક$䭻7 c,d8eo,S !klպ2G9\ed*Mƙ-$cvbyf%4 qMfi3WnI ٍei3x[Zgbu!FJeQ2o9·&gawCen1dM~bCbHc-, 0g[&zlbq޸e]10cO/IТ*ov564hȄ&0Ā7s.wiKm0yb^lXoοn+鷓2imfm=.3ɽq6.klgJkՇ9iٜ@D Ĺ[%6O<뮸8n8t//+tZ/)JR)VRRY|M|nJRxV_.})W7]Zuw]?h޺y5` ht@<4> Pvx0ky v{ma88#(o,Xbŋ  118 88ܐ <$^H0eyxvUO@\'5:$I$UUUUY$I" $I#RI$i$IUUUeI$Y$I"'{ϟ>||;wwwwwwww}zׯ^.!4 4!4!i"C^"ׯC\+BֽTZ׵^ֽUUT*I$H$I$I#/$ĒI$$M{ZֵꪪHԒI$y$Hֶ١{UK$aCܑN$ [u@surveillance/data/measlesDE.RData0000644000176200001440000000442511532744762016456 0ustar liggesusers[lWg/_M[%N-m@ۄؐ tx7 )-ƝBUUܞZ U'xUU_*PA(cή㍽}736gΜ93Z?rC~qNr0$SXL''^yv'L C)CԢ^u6q ` `\+Up ׂ:V6vN.n`xx?>n7G-V{>0nv| LOO;.p$Yp| >.0

snaqmEǙV1o$i5o0uu VauX}ԹMW-;24+|5o[%7X^aaX\#90=F@Qi%fal5Λ&,K}sۦ.GTY/5GjZEosYvݪz9jwY6JݬU>50eߣVJՍ[IwGr>KK튫g9`r="7m~Xg29f 5,Ηr@OdS_i9ZN{Z_I3.m_4GT^r:vhX1G=aQ /;;Ny"/V%l2YSėzxwK A^@Ky"/]d!sz|!c ;\ojݜ66lk53NCЯͪ[jY)mZgq.jÞkKmw:L/J1  *0\׆w C#cSfps\|"b _W=b* _ _7#x,|?<~ Og'x_w [ӡa8ׂww C#cF)pS:fffffff^VLmQU )-5{M&HM+z4 {5 z T{{P5l͏|'0[g+͎ln^ao4;vZ!92VNU'Fu4; uivK$"zrw1QMNYC" f$[IXkbN٭ٌZi|V7LȶVlQbS4BFR+l,K\R*&ezFX7R:?WH+RW5PGY ivpF^\3籞iym$YԕavYvʿ\9u|RjIJM:XU|ec|l>j>0vM'c`췺Y/MG !Y]ȇp* 7Ҋԩ=|i'N4qZ Y;͊tlv2<ͤmتޜE.&^lU9;zrwiKǒ[3HmF7 86a+%O~ ٌon3t_Y[^k4ی X7o>-֑֮,f>뛭{Lު׬,B?Cuhkj#6[V$ 1Ah6r$uno6_ݛ${Celof]Jy[_9{)y/>iur|l4;uv ea`oa/%O}xjj_[6[6{)O)s'.wSIHmmFٷa^y_Pd.V3fS)A}43W2)Ssjw#{d=G#{d=9vƣb=R eUVYeUVY]jd,(/)NV**UdfI&+󕐫<`Z%iU_HV2,Gˊ%礢;:HHyERP/=*,%] RT5n?[*VIsePWJ3gwi|t |b۟ UU*-u<86KgZX:Ui|*#U 罍lH%Rsi7IJS~_VOҳGJ9Iqψ҈}{ IeQ]9*ל4LZ7 ]k#"#K+C{Jʆd|S7/.NuFIO~l{~Y0~31EzQڪɞղtp9\Ro:_/]{I*HeodtIHkVQ݂ TGHʳ7MzM2tD:S:ZGS[..|_qXVaKP]崓9rN4X.]<(*1Ie^jd˧"Jϰ O^od{mOy!|޻vYGIJJ׫|$ʥ9YZϩ~õ%{XFNo+k7" 9WOGVDa#J/ 8ᡒ?C_+_a%yo׭ tOIJؓ|f˯AW`۫m;:}tߪו?ʟ_E:W;dz,3Nշ4OC9xE9&~OOn_dūsɇ.Y 6IoKjodWNS6}S?ӧ%-{ N)~<|TOTf6ԞO ̞gy^k}`!`?>1jBb%fv!eS>[~F}rޓ cڀ_Z//<7J2|og2e oS\Em'[?'qJէ=^b4~Dwth>m'Gzc0UKNcSԧS(SZ?ƞ̷};3>ߩC7|`>O;<*ڕSd]y9[Â|f|; Q웊$4O]4NyݰʾՃ;]Sm ھ"ײf\/&+[*Ἴ̜} Jvܧ'SKRE%VnGS;c*:*Z~sp."$Џ "-0R[1mEc؎ a;R\qU؅ \kp-؍p#n͸6܎;p'ݸ>܏ x1<=xO)_k|o?g_?^vGe"k-nb&7)_YWZؤ|+ߠw+_k,+*KxUfK_oZI;vD8^84Ev^˷xWԼ4z^z^U^X:kxWzzͷ8ϫy]ObO8(O+Q;բNu^EOo5U~l)_*/K׹ǯݢGֺwQשK85\>QWvC hyu}qh>jOW_7F=t|.+(ݿ~_뫨yx+L ZlyEEfPd4-|6̶r\IW(&3;a^sb|}7F,'mA^(}*(F1Q~諸돻 _~>qdr_al.K$S-v}h254ܟ Ӫ:k,=6>ȥңĀ?DV# $ 3pnߟܲ`nsurveillance/data/ha.sts.RData0000644000176200001440000001761211746064472016016 0ustar liggesusers\Sf+(bDY`N݈n%QZ(V:jm݊V8q m= }rϽ·ߗp8z>4 Z`y(u_'H00j o7}1FxHFy2E^mDZ@bC)T@|TF UjHu$HMF u' Wi4Fw ""DH)x"HsiF m/⍴G: NHg tE!ݑ/F }~Hd"G$Q H= @$ G"%|(DD#d02 C##Qhd 2G& Idd LE!ӑL$F sy|d,DEb$Y,E!ˑ${dYF kuzd#لlF [mvdم$#=H هG /ȯAr9E~C!ǑIwr 9E! Er!WkuDA2[mrG2CB Ogs \p\.?Es\n^E .?Es\.?EsՐ7:)@"]3\YԛYZRk [,<_B5H'`>S-i)}yBimyoQmyPqԅtb}Wcϵ|J1>g bKg K֯tc},ƷKwvS s ]߷ץ$s{Xok9~2%=VQgϩ*k}yzUNƜƹ͙*y5cWRQ׫ss|RTq,Bo=?|oK=RjAxW57𮱤83UE<_~̹-mJh:mJ1פkޯ(_ }x[OuxL? $ͼgg{լ#jX$B{U ^<@{^˃!j5{^G#U: ?`*ô+kjU =V`-J|D"H$ҿNx%H$D!D"H_("H$!D"H_("H$!D"H_("H$!D"H_("H$!D"H_("H$PޏrthqiUXo~ޏw             /CtHO@OAAAAAAAAAAAAA|G3P)UJa:O}7%Qt:y:ZlCTry6Ȓ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%K,Ydɒ%߷џ[Gr m8 lb^GMUGfsU|uB*ztŐk 7XGM#UP(*$"HGyyUAQs\Tra(,'x4Sq-5-rݬM"Ôꎪa[f׶E _*R:׼'+k[z_X?ӣPNTѡr ^.s5j9[b֟ĝW.q=㽛ⵂVI3Q?7 '=n@|^0{ ^@M?r󤪵3@Rmœ] O}+%ݿ4;?b$^vėv)]x[ ┞j@h^NN>Xm|7nSg=ʫT z=hZhM0u3țUι8Vwe  K h̶?vؕ;6$<S/;+L/ݷϣnnW`5l瀉J#gT`ⴿôX5VTcAU*W1CLC"?gs ,䣆TP7}!pXJhbMMIxJvB Z $oLH#= *dlv}A}݋An7$í:g= .mmnɪ滚ɮNv ^۞ Iq=Xf~E JqO. vIĖۘ[r|7bn܌]yW^qN%q|C{% iz|JM|w q>QI 7v4h8wCH:L^rf5G2#Ijǁ;׺;@(/~74'=,nU,8ڴ.1\f. L;7-I F`/[; x=g kuG+vxm sm5`bkzuz0$y1mBZO榋ʬ|: W*e ?q޵z 0vu`;&8}僪+deգnPzN׫u5֝u:Haw~xĻF/mX.r#+麭AV"{FW7I^>}/l(4Jœxf3ŠLc}@2e A2=6k)~A/FQ\=/Bm2|C`? rotg0PD0z^2N5js7MNr$ms3f禘Q)\p M~w/O65 v?q=t=q,'gL V2x衫vE6=U<ܪNJ mk+;qUwwOZ-)k]u8GqϴeGnX5GR6e^06y/%^ ;$-k^َ13uw d|F(̕6f s&[w]Wn6>$ÖIWs ܈J,wb˭46b,7cS$)6FM6*QooJ6h~^ ?3M.:el;Ʀv41=^Gw Pyւ@8ywp̌'A8,; 9a<_l@a͸GE6JQlTe,[Qg+lŝkV voA|pz lgAx/*wA{CaB0Rn:0LN!wfc7ӋCrak`:`] WJeީ;ŞN?;WRb\;V^qGLCq^Q׎QV}}V?N67CgүI _|#AʡRNy%,e0``-ܤVJ6æz bSC"6u],ϳz#[dl[B[.dtZ ^. ]* =⧮/A4)}Yζ7+QW0)-̣*hs"l!]_,<*Yto{h Hs; ,3H-K5 ).S3z>5 *%[tya ]lHLY9h {ݪC'{8Nw.s$Os@m[ǛɊN&~~l*Mm.6Ŧ*cSgl*M;nS`-8v[| Wg78(/Z9ҪkCD vFë4FpldϫKA0[Xxیx,.7ZdU5#7;I]qo1 ]kzݫw쁑Nn^=r_4Y#nqOOd/r.;ON˲yn$dՋ({b5nLtK|e>e-ˎW>o1C A~w5.+^<}jW#۟Z/A2?Wr=%?p/Ч?^utҲNuvPWpy\A-֭?.,<{x'];&\ :(ۺZh EHX<__kNXʽsurveillance/data/s3.RData0000644000176200001440000000047110636320360015122 0ustar liggesusersVN0 utI |; qڵw&/@$U,^i&$/_c-қD:?hyȞth?Hހ3Բ}xY㒏ikXQz7+h`1m ؛}5{}i:q*'=u^KȵPSUVgNϙ}Ve=>8K&L8\~u"Gfu5y|V/ͳYR96o5ρo+mK=5AJ;>vݯdJI surveillance/data/campyDE.RData0000644000176200001440000002031012625315364016121 0ustar liggesuserswPY۷9=3$ 9d3n#9GYfŜ,b+`T VŜPyso}ϳ>_oU\\Ϲu[F0oonbb"Ȉ$"D11ëgLLd`)ZtZ؄_o3c~K"03r0rlll\َّمُٝٛ|8s&Y9̗11f3Eo?0ff&F>0--2cvdvfvgbcdag\:s-37enܚ=s'n=0g<9y<$)302/b^Ƽ'̛2dNg|1L3癳/1_ec|S2a~512ْٜ s9ffgf7f/f_@`pUk1a܈)ss;1weܛ? x '1OfNf"+0gļys:^̿0c>|99"U̷029̯3b\b /h͙K3aev`31{22031Wd\s=FM3bnܑ+sso~̃2`|W\י 1?d~;KWo?2an\a\ )s)f+ff;f'fffof̡̕1`&h1̱-0w`ܝ's_C1b<9y*s , 3/g^żym?3f|(qSgea\?.sy\eMAq# +7Ұ0҆"_qd<eDe+$j;3 W+a!a֕^%_$Ǧ݆!cu)XX Hmv`ף$ N®IN[Z.%^`-0-c60Vd2dIV+< v ڲF;Z f v#H9㸓r 6:$:\2fkόcACR%3|2]lzdW^1eK{lG<}5|Yaǧp.cGZ{|NsYɢ``A*;>Ƈ7fn{! }yJ195!lqΓ^ 8ʞ/exŽkVBy|`|jyc^ՎU܋_[m_/[sa^Y!-~Os8 c@k"ssdqn+cFJ[x0IXHx8gd1an6\|Y}2G%^Zy^S9FGZj_{.S9TZ[%vxLA {l`gqn)1^%O`(9_6E<-32V52ߗ aKpAd|׼-XS<0vL1ޚa'j ))/:ESLqOM3C?1VsC9K9ZL5JY$c$FS&ƹNmjSԦ6MmjSԦ60dM_"g'SDky~!y2yXkp.l;L(~Fqw:}֢Ȃw+3E|Z:߆^ z\z–dLػ`&uN[NRn=)L5iH: _72ظ~|W{zn=) qgTؤ_8]vS\Ƕ٘ǣ헷VN$uKm>Ωny0ŵ < yfLNțLVɱa^+P7OoL+[G.DՆL&wOdAs#J"+<.OMr+5ij>Rw곃yYq$EWpkr3V]uٮ4=wnV;y:9sfq]^9'.yQȧw-f⫍^]K𬓿rT#(|f'RR|3(x3)$aTspAOЭY o.8r*q~^[ *u2ZG&/7TEobi΄DR&xF&Mvt@~m{~";Av0k1m9N*:I1 9=퇭N҅1ܡmd?q}n)rR$TkNvQǛ\FNZk=)'Tnc^&cW_cll9:wzQ:M6W"~Xorg ?.*!1ӯ;\{%$pM!M߬|~?z+?ȻϑIɳ͠A~qS ?HGL>+Ǝ1l Xu{JTWwPh-4-|@a%_HaԹ]M҇G^>{.v0?fOsӥpvfa34ծ6 Iݰݷj Ao=:f9gItٖV۟ lQ>hF#ܖLyU)9+YX#׶x)뭤蚘ڹvYo6n%5gp_P~F;YgxK*3+2w.x*^SjRr)yϛ:F/r)C-&+ёSȫKeL!ע{NI>N\>Ԃ|-j;Ty,ۿu#?=ww N,7*>'Xy M>KAmZÎ~;QFM{:]\K 9 "?}ݩAE v>? u[MNaI1}gP J$GnuJ7?_G>er6(K{UZ8;[L!L辑Ԯ jEv/XE d 뫾419ŏ;^,\s,L }⠉cL69,?M?ڜdyWC"zނL_TDeNywYt/O,%ml;&Ѯd;|i$ҵ*'Y##ֻGN.֞F R]3<ꑗތ!{Vگ"'#"^OWuUs'<&_7kQ1U6SoGF 3-_-?l9pҬsRīSJ>дFJsm ]K'(S}0k-o  Iji ?O!["#\9%xג؊ۿ7/~&?%w덛Z-&?u ȳʇ 3:7W$,ޥ"ZO,2R> ,Zǃ#&/!9ffN5B*& #]W-=ߝ_{ؾjz-*ՈUlu\Lzٌ\N&unOǍ(r|p;+}m䷸Z '晻'5vkXHQܣIm\Rԕ;SX Lm3jeY5Iu'uɠAle*-v>K(ejQ{)a+_ z-Ȧ{΄Wo.iT^k'ܹ3/zʦ3>Q$;wneY\[E^-w6UO9J%/|L/zI[(r5`yK*sYьad(ac ׉λȽ]' sϱnMK eю{מ#ۣ kƹ#+&{D]+O_r/5,o)e(ݻk9Mr7:G`!c<7\Nn#3Vv@}mم3O_HA_6Sȭ{V)N)xΨs !sOKPHd(xk祩c(\Īmf uDUpiW D1VS.PUnk(8GQH}"S4äG6T㰦ogꬮ\Dm"*kt,};V2|_G^S͋@ŕζ>3uus|&vy{ 3$$m?{f!59Užƿsݔo_&*G:!ۘe!9569?DW7;n8lwlپ"* 6y>>ܸ_ȷϰ IKo:P@@Q?)Ԫvz@ mx^=*Mr3}=O QzԥKc(}Mz`J(,wSSXLb)dhߕ(pVoA3߲v0y[sj˛,9{w\/E_:ۙ7\@>RvQ|sxr-\u]]wdYn߿D O~no};*{^nr1W:BrhӲ֤z=!RVA)1Y/WJV{H[D6G=B`ǶjdޱoU-˶С笉EiōO>Nż=u=ߩG'.#(z; ]佣Ts&:'*y^ yE Jjp”Q3PU| k-Z?:Sx~ٍ<*Ppˍ?K^aqx}x,E앶 1:}iDHWs?GI?\\D|/czsyE-ڜ㦑wR1;QJ˶i=-_o_sMx8t rZ6Iw["|WnuY/Z_P j}A/Z_P j}?/Z_P j}A/Z_P j}A/Z_P j}A/Z_P j}A/T_ j}A/Z_P j}A/Z_P ]}?+Z_P j}A/Z_P j}A/`dWc7~Ϗ?;O?vSnjMUWPl??vSnjM󿣩c7~Ϗ+MmjSԦ0"u| fÇ& {4/$*!*HUD!ՑHMFREzH}i4Fb&HS$i4GZ -VHk iG: NHg tGHOE!@<#CH<2 Hd2I@ cqxd2$"Idd 2$#)tDf!9\d2IE Ebd Y,GV +Ujd YG &d3IC"ېd'3 IGv#{>d?r9B# GHr 9@N")4r9Cȯ$Ar%2r\C#7_Dn!rG C7y5N~987 {xW!}58>qM</bvhsurveillance/data/salmNewport.RData0000644000176200001440000000575412376633551017135 0ustar liggesusersBZh91AY&SY$? |0<0>AJ=M4h hhiAAAIL2112d40SFd``@oTziT+M5'iz=5hh@JJF"d"z&M)h ~U@F0LF#iIDdCSLSLE40i 2h@ @d R!UMb8<>@"JLϢF>Io>̬-mNoDcdiQZ\)^nwL_iꁃA!)17AIQX*3t{.n/Pp(Y$Uu6Sxݞ`=HtD1qO2߹ 4TU-ʓCDD}23S_TUu,lmҦN:JZz$uu -kk))8qq$?cJR)HB+H$# jU (*2TI@@I!$Ye2B$2*eEdH B[H$HH,0-[!!"Ki)2# HTjYRH222$ @KQ BEH@?\0P J%J" d `[$XFP*.T2 2Nrb20UBI$D C  #UY$Sr(Q"5AZK`d/ ;IUAU M xpLVa jmR Gف ` 0`XMV^Îw]qxBՐXn(ba9Vt %#By2Eʪ54j[۠b0  UFX@U5 X"YNit.XX똷U "Gϊ>RAo,.1BD)GndS9c%M=iJ]78ג /#I!AOyȇ1XIu%|AS `bŕm(a: tK g\W4BUQt#h20j*rxS AنNZ$R`Q䫀 +hc]!d6(`n2{$·fӲ֮8aN`By$2tq[59*66> N=ur2|oնJ#\E Rt-x,wz!y/L0!rs1ۋC,5}H&ꮩZքiY^&.Q2 .][w)m()Y9|Thr"tG;% kQWRLbH 94귍˟*#3U/{ITu s%( e D M,)0[UIVRD ZA2 f3kW?iBD.xY$JlZG*X 1M1Cr6ު"C`[L<$vL vG,oCDr[rL;#>fš>3mcPx {ӧS!Է$-СT9+S1ЂZB`Ejw"jA6qDq_@(_.-xD11/c }KI$/Ku.`{sys0 pg3z-֗Lɓ&K//ŋzu]v뮺 AUT1;fhB"6 Dw $@` K0v쟡sĺ!W 9 Ȩr G0 s%߀E$ 篭6m$ c90""\}}]y}9oK]6./06f^[@ڮ-MmnBɟv+W4]} E]^qu`,\uW4q/B,\^.x;w[ \KWi[뜾;}o(.^[Z-qq¶UǶ],-Q5tz8uL˴[.j.k[Fp bZl[̹l`֗+Vqd.(:O3p|_曇6ly+y1su2?C͈nVt3rl)OE$ ]-d4y寎?@ݟU10q^([/+h7l{JцlxjuW}c:MW'_TkF9_^j,kUܗb'9fceI@$}(ɽ5^~ Mr/fNdxzə8t~b 2m&\UOY9Ss}%%uN۬_9`&Y\RHs,e5ދhyoĚnK\FWl}FgfqTm[e[-Kme>QoqwA3oCb|~X%c~:=j=` ?vuX3qf=,P.痵B; >299sjguc}N&΃܋\cp}e+T^F#~=˪I30^Κ{ak_@!==ǘxe̬+sXg~w~i~C;9ޓUq^T?hLbOnΉ{لJ*\d_SD,=K$(;$p620MuWWJ\s5\s5\s5\s5\sm՚a0kwn=r7qۘon't5'^9N:䚓?>uI'\sSN:3ֿ>Zso;?M3̀?ؔaw/ٞ\:iްX_ҊRgݦFu=4[_l[{;)߉*Ŵ'Szaͅ}vC"<'%^{ 7surveillance/data/hagelloch.RData0000644000176200001440000010602412625315364016534 0ustar liggesusers7zXZi"6!X{L])TW"nRʟXdG>@jtA69z^n G䷾ V8oۼ)J?(]a$%!OKiVu@d= <+$i t#BU< Tɷmv=`.χhncHp;-ym ]>?QesrMU%" uvi.7* 70&oC0ez32P_9ɩ6cYVx8bC( zL %TIXl% inHԟyD1O Oem]bܻGMz5f>`*/_U* ބL;xsgpR^a1l!3-Ӏښ1 Jf<KL})Ьwߓ\6x&peHlQ#>#6Yk)aIdَ9R3|\oe7^%+4iH=z^h&6Ӊ}Wxqq #]XRט d}*-MS2'_P8z7:\L].\:qkzOEXGuir7Ǥg2m&XL"ƭ:[n|f#m A(gX-YR|]UJmv>ZJ;m! ]HS?@^y5PO; 2땾fD/ܫ"cw(z1] 6][X {ݠ'p/ͼ(6'kX::M13" > +H6lEgا"=Nƛh;B%. !ۯ1Gl{rć&ڲPFU iڻ/%a'`+[yrKf,SLpj'#uxkn攕l?@R8/ە& cB4^%euGq~ih=eꪀA(HL/0;Is"V!% |d{FL`ȵf&qw ?I. Ҧn. תYxo pCJ5}%F~gQ5{n74ІWJ~4iF>quS LۭAH8ZhIkL= ^ |EB^*wȩekpRBaVZrKdey3%k.  *_S %ǁ\(;+VGǁmiAґ d~_n@fʊN¨.|7e I Սȉ,XV/iq&#4*Gy-] 8z_bFe>ߓz@$_BĀ)(09||g=HAҿŸNځ`6׫;s,U~!JG%1muauű0ЈvsyeA/s1L Ϊ|SV:{Y˩$NJ>y|TH`\Cn.P$#?L+gvoຏ5+e=?FJ9غгJ ˽3.o4%k0L,ٔIOhݥan6K}gIdѦ*~ h |K4ՃR&m]\^܅P߹/p?ay81 Xg_ z ljeܥMuϸ~!Cݵщc1gAy^?c]kA}n+/Fz'C3snS\Yzʼ@J7t=*cZVmu 7P9/!9{eye&$#M U[gD+n -jb"Yg7R-e?]Tхأ+1랻W ^5}oUoWaY#ȽjGf:ꦱzgwM *5$M Jrp~/ \*~s|Iz~rD1[8 S@ maC6s뮄?D^jik;6T :҃Imt+@^S*5||V|/Q\'LVWҠ7z1Oq0@gҖ&]5ƏNwD{c_4B^e1rKcV7.27vNjQG?Pd*Ԥ[gRi3FDz- 47Y>  ^ 9\VqwS( ťCKk6`٬ px{5m;bB=G.} T+(.w!sfƒF9Ф1!=KB oRR2ۖ-U=ȊC`yMt^B(3KoIniL(%dM}2!Yk}'0OT^E 侃",ث6Cwkk ^A@hvw\W,r\wuvBI1pT+WӾ?,[ֶcRTj(%94) %E;>0|`9`tt.u<6dШC.+hqX=SrrT&ޜ ~@{EEI:8)٣ L&tiae߲Ttb⮥mg"{JIMB|Հ"933q.ަQo pӳhޡbQ}ѽ)ɟ^ov;MA}.I(vcN6MM&=tK<,Fj]HIN;9_a0u|\Aڥ|_C)t*PnYp@}8>fٹ].qSPiȲo#`97qՒnt7?w®Kp^z;L$Tc/6}k\cxjW珂yG%qN*t59D6ry&?Q5MVApYٯ?u *ҌT`㕉Zb#]y i5,~}Q *4^5T"I:gS B0m1u"r +|J c`Wi8RT)DΩaBmқlK`qRVneov,:gB6V̈zn–qk~z:=Bl"(j)5[ڥQF6dژ2f4 ZE Dz=WoAJIAQY \>&ȵ~|˹.`{ؕjUX3nLB{ H@̏32X E?Ҝ[!dѮd mvGwn NU)l20Rw y$2 P͟? $4JZ:LV[#]}vpFR5[+bc<;m|V7h)^[}Ŗ]z-5ac(R[Z߂Lx/1UR׷pS;E_`|u2n7tl{棰y@ &ύ X 3@o08XS>&V8.>X%]6NHҿS']Hy|*1M+(CLTB+pw%퍄B1TTD& V G~Q sCo)5QҸ-5ܭ3Awjf/h>~REjbSxt<">l A [_,:-sG94UE즀kR=uc䀹&Kv+'D ™hCoۦwQqf J,wTxCB'?!Ebqܤ@̤AIZuGR@ٶ:s:Ewg2xfsW\6o- ۫"顷1f1DhhuΘ5ݤD`,̭]XrhmW>l@ۣ\XWWnY G\OVs_is|ntW%zS tI r7r: h]$WcԬ<5@^'F^&Y/Q"zɷp8R$iQwZ7 ?+k=!iNkNOneRIDK˛Ce8GuL|!Usnfq7GcDMG]'͋g[b~8؛1؜J6ymá3HҙE̖^Gʡ1hp/Uv웣j{W KhύK ټؠarrVavw<_WG I{2Bx.\1pK" %-K+i 2dG7{v~Wh8N-aUo FޯC;Ky1U"wX놝]*^4E#n-%궨arI c-_<%B(1/s_b w˥b g8 N+&&4DtmqTgQIAЌ~,DomH(SR{x#UlM#w+6SÙc܊l] jkYyZ(ߗA痆5˞K%'Ԏ接 aR=A 8O)FY+V{c=RdX`Te1+~NZ ۟c .VlCOWxKR[^5.*}yK4Hm43pt, ~\Km֐p_{>薝 #bV=նQ}|~GPA[rRʱX:/xRP fORc~x΁nd&[畀C_{z?ԉIR *Z&r 9$p#_(˅ѕ~*'uMدՐ%S/۪yݰ4l|q3QzqRp ek&wx [#*"PEӊ:5;{zX8y3*.4,6H+Zh>i?āx$\_Y&GXSbvY[ڭR+t[ BS=)d ;*lߵ;÷W eh"ɦlQ[b#\F &k#WIdl?> Ϙ9;̣Rz ^vZu;+^9$p#_(˅ѕ~*'uvv%C&JL S] }w$4Ԩ<% *rjKFIUoLAl?,yCjOoTSLO 2cn"QzL4A|R@4j8) ?H3&a(GQsv~Ut-LglQzjff*ŋ@p,&~w?8)L$\,fޖF<=iؒ#Iw$A{{JtBOmJϸn&|Χ?=)Lg;"a◣P˟O6PTIH)U*YaZ̲ʜ&ܜ Oi8l q HHAA- ^CG[G[h7QU} E 78MrܳA2Mn":-qx,/;ߜŀ@6ss#X=)/܁5,N5fSǨʫD:<4z:롽)۬KL*`g)qC'rIh'pkaPf'9r|P{]qgN8f:^v0Ԟ`7bj$kI8Y\Uܪw}pWJ v>Ӥ|x#7 Oxnx:DN 8#heJ2{gK}r e`r-1QG:jlYޚ`”~zj*S(15FdQ'7oT(c#ILa3험KgTV N/.>q~ֽJ-B&{hޕ-U5wiM!#7ה6Ӿvl }t3ec:}\Cp֓ņp %Н n.*gWncLmE);n(f냽w¸'۲Ui>B:#=%p 6El h}HF"fTB>NysGԳ: lN'ўTVP}a/Ur PGSM/((qD86 7+Զd!紵޻A *]G(D`M#džΑQ/8TYθor^~Rekj^7U4 M^\lVAԯaW e!9ZhlwW=ؓZB`u.ZSJ#1a\[Qhɠ`{&Hn7|N6b5-(\*gG-]{7JE.pBGmonT>eYWڈ;w 5Ӓi:GF4da+I/7cГKvԩUs\8B2a5*hU -`VeYdSͭvĠ$B6ಷάt vR zj [6awOVzDKP4Gp^9\;sF6G좐މlr. 6Eaqvg9n0z,$ῑtRtX:}%GSyysѧ|{T 쁎mwle~`^fe5E0`hUvuR$ghHFL~Z™dFsrx_z@\= XbaEɾwQ~AV[O6GW(%N73Evl+.m=BݴB\-ͭI_ k9,#"=పޕ ;<-uz8~,S"TmcX>rANRQ9}RL{r}Y>:0C~]xx~u)r/8ˋW|:+}%Gў! ,(R{j[MUI"@h<l-K?!~'b:MحYT.2vNԤ] CF雈iLoa a"m-難R9vEDSǀg3_Ukz?_?bƘy[hwQ!Vm3!6ó5. kC+VUiy2yf՝@ۀ XiO`Kln/u+ 46,@m(K)v'l$1ZrסqF'n#PiF jCLff4 q[;kFU؋zCilw:r2~q?Pc伽$݇#?<Էx)_4‰S7Ӿ׭w >^|idUMqy|ط:8KA&v6K' ,4IOXq铗W[ 6`3jNeԧ?i VmC^G|QWF⇚L'd2 DۣHAQPhr*%--ր3ǰU(zGkЦ3@4|j%5P,tjܷFH!fqg, Qj[`LأڗVoLPbt-&M2UCVԹ93U2` \v%İK0H%iIAktn/0PcPA'Tco @ȯ' }|pg!}8o|mU5.-1p$}[gc'V0BTp{$"`qЧն+S<7xvJ_#b%FSU.ЏEQYo]⃘L[R?Ob{U@ұIs~ zoO Is7n,F n)\-Z(K(D`M2)5]&1-9G=p%Fq?sDc+0yJo.na'8Q@Ѹ~#ܟj~L(qM"/NƁąЬkJ;fğCAcu2XVa1jc4lw<жZp4;Z8#@)sAp_=kb] $妗RzVӋnUPgV:{Y+`/UU!=r(/!R-Ӛ MҶZ`exNr 8d&2l5J<@>w$.+'9wOՀgb,\#\*Ib򈪞"086|QE ]-/oU.ֲdL%VL>HY&`F{Z,Qm,qUȸۑO.53X#3&&w9a9ke0TĈG*`vlaY}uҮz弖`Tgo a Ϭ !Kp{Q$blW Ԕ!nWO^mݑ>tL'B 7 +1 Fb >j55RaS/z 5/tUɢt,X w[ζNeLsIUp js|aRF`e,lU)huVd*%-ɇl| A "۠m8DQ([jJNW "FqhJ"vU`Iՠh2B&u}hRDer=_x`)vW/Up5q+:]/:4;31eTۯ &}D?lG<'pCuI"tӰ\|dGg6a('6H[ ?-γ@Rˠmp掑`?D䁷 [ew`ؼK9LH,9́j"vwIï؀m[KJ''g)j@ j1_li^^-Kys 5=Veu2\?$L!x<Ɋ0A UHb >m:cR/X]m@l>Pyrtb>`w'D)u'[wy# B Jd|$*3j,7: -$fjIz|qDԻ"=Ocb?G82h囈d,EG;`|!i V$,p~9G,y]! QC|ϦDft#\ :'ifNs$4v,PelzyDF(=vS ]9Cծ752mZ<ҋ(gP0 YgCfy:gdi_9 @g[!ˢGͶ#9r 6ԩ:daK& n3kUb-܋q9~^}y;Y,;q/;e*;Q4A Qoɾ3;)֋+( ۛ^~J7]*zt8'uːJ ,EɮI#5qyh xs!j![€Z);hd %›$ dfު xFh"2" /BQJ'$È* `Y+:x9C⦪81n"`iفoO!OmxE\3PjN ql}rp15 #Ay}Hۓ]Ъs#ֱ!x`6.)QQЯ+Ƅj{`P=tؗ]+Yp(FeҥwkAq\?Cڂ;ook zIگ8u]SBD(3t,'1nQW R*KTo͂u 'x@$b { T\ =4Ԭ3;Cae[zDKq14p`VF% ?kKTAHǤX/`,,G[o9R\uAHJ ,n;2Mqh P"akavc8үAG05A/IP}_ XbBn9KhŞ*p,*[k# $(?Y6h?`${p}4`! F4eЪ@uF4nNꧦzy`(3LX%l/xIC.uvC̀΃G&{ORBՌS۸,kys3}Bf/dD EbI9])r%jpn6Xxd\g"EA&+5O ڛ(l\vV<5.QˆM{y.Z>(Ml)5ҋ~- (} $SrPÁG' ,xv*5|+O2 ,+kig4pMaE .!"9+@mK&]qH\GU'4:U!F6HKrhOM\o[^ -xIFK,-5 9@$O3ݦj"o8 ˞ &HW*fk_=$> ,䦱HT$ 6׹Z9hyїAs*ՙyM?_2u4ՙhwy!.̓eTY <9Ι(; A=$'VmX̳2U(i1XN {ݓe ^ T.q^[=*9&LH^ۭ (^͓Be½MYQգq+quObu&Hú#Gm2w߫o}Շ1x?vN`)9{ qϸwT1'F'HR)0~Io')%GFdf%]^)_Ճ$ 5˾'*e #ڴ<;)epCxoN\h,,/ Lo4Cw_IBl`!ц) (NUwyC' A$Ҭ wp o`iFs5=/5W"98"\OU'ƾ^uomP9{ ǔUX($ğx"$DJ8 ~Qhyduvz^epV)r)؜J4c0iQ=M-CdȋC/BC Q$2N`N{ؠVLvȎ@nz,#ƚ^ԝQk/i9?x2q7W~u#ge>k~Evd67T~zеI/\-4vǏh'; TES+إXO3h>ks/ccVoImƶ7( U-URX2s-Ng;w-V5dENb.hja_&PLߚA",J س:@_UoE(' N;[àxtR3T#WNEF F8*^׳)'$7Ƒ19Lsx2  B*|A,ma,Nif3|ͽ}aؖ齐VYb/VG2D\Nw%$/TCy^[HkW:$ [7KĀiIF8'F,@&0[ŧ aΥF$-ˢTG%BQ*#zyq+$S_Hek-ꂎ929[x6v^'- I1d}3,U:2Oj 6TKFQI< $pj;v?LB})a*Mfs^h>XNWB=ogm2O ؓX9+ T|Yb MdOsVᩐc.׉!~'lg7t0,pZG4F {\RVDB~n2d0fSoggIsGG;Sx(␶)~e|)O!"1G hLECM/77N}XkŲ=yAyς)l ù8Gi[M3*ص፡8[Yr6fތVh~4IE8||p7>qChZo59`fTLFHY3 mgAYF7^"WLj=5HW@.ܣT%eḔjR=rcF*fyb IM(dXDN6k+lWM͖^ߏ{uIptMٗr aP2@/Fo!#vKD /B"%'=É$dn# wgD1`/CTtNNrZٹcpa3Jl8!Owpw^ -dAfK08 g+ woU36)oZ6RnwF3i{C4jC w C{E6tjI>j֡Lʱ<,#|zu&F.ԇ~H-UL+~9gRĨf^F9&_F5?W,_P 8 5~\lAfSQD#y@^$P*(˺qઃL,RBqϢ^[ %Ohh\V3j˜ȗCxn`"sQ^qSq`Vu,X|U=qUQ$= Y kXrS DK \UidV`7yNhC~]Й'ogzTIZO;73iu楗 BXEmuoT2lGԘ@k 0Ar ̪R~Q7 ޟ&ι߹jDԪ EL={M}ĖjI1Aj[Musf-o;,\a"wMS7tBbp+@;">}zy"}I7݂pcNJ)m3T`G"1On5ԄƳ:w4q`SR+B[,h6=3VX=`7V:0& TrwȬBշBNqe?$J%ፎK6E"=h"O*kNkU" ه|:zo2x ͡Ŝ5>+GoE{7̀3/n:Kf ekM P4" #.eKX~wP[\^!"ByYqMq9G<αIq񭟩i/[ktT"؄y)O>ڜr19 ՚P|OI"̇o9)xW`F] J^L}&?¿!Hʬ?Vm;$1s'OO7?74gӴ3]HAH͡nnwKK^L܍3?c:_٢BDGmyA;uJg̏dnd 8.psZ6 P#\Q!Xk9AByXKދز?g19s- .cȥ?a!층s|7( ں@4q:ؼ)8cp*EAD Rf)%euA5ύM]uʓSV/HK^pmnBFpg,wi7aQ0)Ksu/iWy_A 2ի')Cw<*yp77H, ¼qZGPCjcsi%<a$ӑx쵃傍E xd*MMAE 5;b) e:g[Bx1 [Rǰ4+JBp?{`@N%g}(w #mb;ߖ.cڻv#רZ84J4/$W ݳ>Hy }_[]KgKp;1Oh"m)k96L.A풊)q ~P:nޓ#aY, ̥F_<,RQ0Q$/A?VK,ԅNdQ8pɷ0zV(4lD@x-uE4קމ tGui)FPs +z@+ÇE /(.)D%6Y&%%# 1bWϯ†oAWNH?c3BIJ7 o <+كϑO lժ_~p*킂y,4$ ]xŠHS?f>mAY26yBɉG؎,.hص2oߏI),KIzQv zFbS$'XpQ՘BCTr AXʷFhޝ3bc WegEjs&Ӣ},|cm_J X<>G)RFڎ␑и6l 4ڄטSR#ԧм7:8uk 4MiI[k$;VooAr1а1&%+8kgDLJrUn &,彸75q-vM;~3Y͵K Gyya㚧D)_Yl̬KEĴ|yqM"h%[ +B2_kcO {puڇ6c]mD?y ]_\Lio1wwcF{!w^ yF#&9#!2&0Mzq*CKNZ ffF*!y[S6L,I8^IOޕon=%5rö4TIiM}{Jkޯ[61Q?)㚙[.g<464Īմ~PLߒeuq?O 1bS]VmNECҰ-3qM}9]M<1gLD{>`V~BEj-+A3LXF|[̎fS|iX|ej¿j3 3k}rܴՈr2GwNϤ30Fv>>Կ샵g}.?[_Ym=R4C@-B%z,{晭ƗL ٕG?" d#2s#aҏ4D›XQyt9҂_$rãAZq ݤvkˇ$a[TZaˑ.Yn eoA SPl.yI- :/`!u?c,QQͼ!}r[= pJ(woV_à{k hwa?v'D6gH9S_PjF0GU-i'uYj> lVƛY\(ƘU:vMZ8qs4i D0 .pNHTH Sʓ؆u3=MI@!.ڐc7ЖBmYޜh03ᛶBH\^Pg;Oc536UQH(ۀEiWBhȤ~XWV7a8P&X {n#fPF9ù&s-y%~2$|$vOT/VfO*F-i)Wb bf5 S'`Y-+Qd/Tʌf UEG|Q֦D%C#qquݳ$g(+ l\r'r}lh )-0yZj}&&YME МnRO?)-XR4Dc oo._"hf!) S Z`m3ǻ{#/̆T S< yΌTV4ƴZmǺH{YN.ϭT6_^Щ^ў쐴fμqO*w1CZAҠ* #=,hHlj" o`U͚Lq-,q}$L[=UC3. p>kz-ul&{>6?Butϼ\)5p3vF E0߽ì U8ő˽]\A+ k= }dM\o 1OT\KJZ;g$&6, Qb|&Mc-u0{:zOwjCnW8H>-^5L0HEb yPiG,|r3:ۭRt$rU6ұ@1Ne*m{( vJx\tU掽.w AшTm02fh*J)2gҌ\DL0I}Xp|01c3byhZbԨ~dO!MfO7yq!posj/_NNqu aR\BK|5٦{ÁܥJl#W]7 pd| +y!K^3<@`Senp1n/Gc1UeVI fͱT5+mw!$@#i 8cȀ!eor ;{fM {} 02PX<.pёWϤwDmNdч@+y]w8PbJW3QVIo'sLTm­8,C6_3~o&.@5%4ψmދ+t7bHk_L]?uƄW gX0lwKSgX󥮨5aT"  2X3XyC ~,IUybT8Dc.+}$4Q߼)~LryC%{cěN#T~bk~y @63L-1"KwPn^fqc̒E.3c5 ه6A>F]K`9~w͐EM_cK CLidٳGɵ+##M]aii 3QMk_1֩2w֎Sؒ/$by@R0ai0jӘU*dm5!͓q8 ?duyޝd'e3|BSD{蚮E)sjJ[j#'i@T:zo{g%;MJ+*a=P?rˆs[MDd5,NHmǡ삯΂u1g1 ͼOl[Oӎݟ/+g>S<Ӓ0Vƛ3__S5V]UhY ڙ)G/$td2O_^!n [wspL%9ba0yRґ`EIBJ4K#]%փ-wixiCJ<{*pV$`_|UMb.ٽil~f^հlk\( >t&E[=hw1[dlt]0_Y,hnS=N͗M@7o|ʃh=AbA\Y6]c<5Trya5H*QV-s)4; XRyP=ĂeS,uXV!OJu23u~ -Ꝑ 7R ߧ{,LN-npZ$m&ۺf1cV&W@_^]m7m0/Uj[ e($wηV_r~ưTSÖ dnM;vX\Jlvégv6}\eX8GneHܲ_ +}7J~2E#]YDڌ->dp'XH|< +bH_^Z %?*֚X0oq.L15;yˢ=2i6\"`aZ @EAU L>I,; eisCf2FY`t֐EBVx6 Eb5/ ֈ~!RZwMLj$J`~*w>g!{3[nOʞ, ;s {-܄d@ *T^Tv #!㓟Ω,M|qEKC/߿ϑ1O1^eՇ cqQ>"Zo.빗[|V,8!/]A I3SiI "  PM╃ŝX?eD^eՑ:ZѶNX$Ѵ:J!f9zA9l1V]phQ`nزssAkzf uzgbE]I7y,t4({Ix SYYp~A<⅄[4e$b쯗ےf Gы%Dzv`F?)M &-:j(5uq kdm#6ݎ¾vB|9;Jɖx5%[-T)߃̝3]sdl !U*@bҼ]e.r)сdR<[>zj(qZ/(D<G4Kݑ o^O uȞyQ9+Y'.yvxh >8YD* 0߸:Im]L_lt']2G2#wjòtj{{i5zX(M -;fV7BY;LT?nR}u&ND6|d` `˪R(^3mpCwu1[u57#iD-5_9IJݯ"C+ P 13u]|3sgHe[&Ɣ Z~_KxhB=gD7-`rFTu,0PT"]*"Z:I->Q޸ %МQ X `?I> V1E;h:5A$Cn҉=l6Tۨٴue@Dq3cPwmMBǩX "JS/Q H-s#lZӍT4qV dYkh1iWo4Kۃ,l7?׽YGu{-{ҸGHdEr="oMyy> W>xjӪ_i"3Oم ԞiߗVM =Xy^ XW Ƙ5T ('Z>bQhVJ0Y0#zy<5[E##Pҳ Mr*oO}::GdbT@v~aɥzav|SɝZ$D /Ozj =# F_YP=cVd92.#fvw[Xʎ+ YGh~gBr^GHHʻ<8}{qWAXby)%gދX%GG]:zRp0f@ݥoM| |74)>su$7*&~t!j5, ?3Q2>iGY1NdNs"#b /ؒ/HR_/1ηD9_SI hBS &(QzT '6F8cIyO &짷]W\q|}27{Nk:5W@推8@ hpvu/B.iS-HX(?'$J|K5ϡ*4Q Nak ֔ԕ'VA})! ]@$S>{Yl IX)wp}~q ,wC}&:Cέ5t%gH K!GKH')C DfAᣳ5r (%P=FA8K8/7نw`DR>7$6^|uhAS7 /v-"/2Vv΍=)v"./ė# G_`-,Z4b1CI_#r#\0+/Sz2oڰJ$XB05n!姥X'}mhvٲMZ.>"w sUy#cw>[iCۅd<$9ոTv$8Y}`8%C:^n͚]5{M8;rJϐA*`7I]61]2+>83iSˏ룓,fq COod4_7N]jΣxtRsBoӍ)B !]?x&K̡J yWʥhl!Mu_EمnM? Tvyӿ ٦BڢIdKL4~VCث ƵB)=^A]0? IƝЂ78$ft?RQs$14L- nG9zW5=\d3BP9_-sm( GB''Rľw.ݲ()սCP%<)xȚПn dIc*H.j~oo=K^7B.r mu>lyed6bL;28$C&oDMUlt͑e+(#B15fn  GI+eĻ.5vttljc^ r F`*dob!_Ө'*ش-cWLRcoȣeh,pz*X6L1:aE\M3RIBWm ˁ4_ECW-wl%z-DR*]"9z\6o}dnnaTqRWGCs=o$jaEHԓȁqd͞3QEkg6.>"EB*2<ի%lۑ(`<GL3s -X]t/Fg1֩'ey}͒Vl 43wZCw*zufiZea}U@pݽ%XdMGbSЋ"{m K^}d5iuQ[,~ ΊY FEZL}'E<^ڽ>i:"aj@T^읔hG<^3yB`VW>Qk4Jct؆. Rh[Ig%DP9 ql"ܽbO 7d(p+bLҧ1AD6=F߀;-s(KUq&p]a' G(tM9d>R$Jd^n%ls]x]Ml>m>p@7.b.hߘ.A; #[k;bX+x){#Е ӹ[VGk] *?`lȲ#,(!8' ow7tFD֫butxD%%4$F+#$ʀs6MwPtr;v4W $wnZ fmgsNnדK.mM!;l͸cٕ"D١h dzjXK~2TtIɐH:/VeiaΜˁqruMhj8DGA[IK{i$ʧa'CJ:kr{;Jv$YWeBɾӶ8p$V/-qW7[?WNu>!B~*4GQEԇ&P4j࡞*(N-Mu%CQi'HC}Aa#2s3ZϑWʸ(5VrB2*~3kk1rn^mW;{՝8CVu<6<.C^R<fUS&װE8.8&HXzM.&7ds~8/Dlʞ#0oR B48L>QxQM @ @e~dW!j׉C؏6zh.2ĸUQUk!S#fL=\V;6֒ǩB6@H3հ!4BkO|:nNCrE{g7e1.=bp}o/`i/6̯ud}!-a?ێJME/;;ۣVb8].5PO3 +qTMnH F"KvaH;KURuU4ĆNQIqp#t>~CCεw^a %l:;G$/ɩI_ iiю QtI]ӤJr-^5M11 TzP?[Ӧ <Vu pķl*QD]Q(ŎLh0E?.0lc6^%wUsqNHU=8㪄LcQIxCNn*~-Qz{F~U{(š!ҹ2ԺA#sF(f`]="I%h|ugΰa,Ti~y@[x#q':}u;sMRl/_FbPCO<~3)ҴXRHTu1تo'iu;lw4(^P?ì.N06 z*]7B|ߠkYpK(v$~zcWBP4mtnx+3d8b@%V`WŸ irN˴3r1t˨Ty#5loOd`o:n^jgO ˫L׈ijl?3׬5d9b<3fŗ͛ⳮC{k*=Zy!@ua#`9u90Hc hnJON/Q4$ rT>NDxb3ۂjyp-nb HaRˣyM?wj(;GAji)$ ?]?*I8pNé6ѽVŎ/Ess]j| >QC'7@,CYNrIGl$}@S!!bLU'PՖQ{0̈́gs5CwO?OE6g8FG#([Ŕ)Q-~MX1|KSa=e [dD{et+~6'O6ױԙ%0!"nᅠjov,&Ġ`'N{ػBb"'pz ǭ c^K?_A/]*_cgی),aO1#4pLK0 vHhg-Tͯx[p :\D׏Б&@pGv:Ip`tG$qESrhVk$t*n\;DŽpPB ֌L\fێDF pv>Ow{um095jX74J7;F[p'7?00{Pf)Io >qV;S>-]oEC5u$<($< Vwv/7He98=};N4#tpRV r:V^!&@ ٙ>yK1iQX<̴Ol3|z= (s@9}I+,f;YFェFÒow1G"@99XFaܩ\@dzġpliPă腞/'BXC#EBә0J ѥj]x(AlT!V`':/B!\虭r C@V1"hܺBA3|ҊOIDdsǹWYNʱ >_Vy_u8ª 4G :stbhx'͢|2Ӷ x~̇5~ ;8`nEv;:4נ]`2XJ[rn>`:'(#NnŠ/2ZYN?KR4)#flCJ~r#5M,]zm *VȰxU*ռt-xJܾpuAss&jӝ}´:v[`SdqNް9/[>ezQZ^er XHD{e/ֺ?BNKsFGd+r1Q1iۖ'8tyƬ2g`ȉ~L2K Q3 ډ)_2 qlԬXGuxAu.&:Y%d Y!~fz7x X(qL4VhhgCc`_OsLH<߽菶H=l SsٯZIˉ<<[/ %VPA.Ff,_k*0FuAX1w-7Kv\d# L>r!Auz5Au)Y::${)(` iN-=)qĻPG-:H [qIWd:zbC䳨z!)<N33h7"j:r<w6yYwYT ,UwS#.} -K0%3.B,GԸӜ ;3yW+ݞTKؑ^`{4O܉hA\iȊL.sc 1k^ 7*>܀4d&sU4}Zw2Xk]OKhҝp"5pw;>._uMlL2v{jŽՃN#G Z9Dxc*ȿ>ӧbI-͛R 45;״c+%ȶZn_mU,S|R[YDJkP?v\x޸B{ Gj*FJH h!F!~׊23{H_~宄'|0חzwGSZS#$KҘgAY^ЄPFxgxon>K?}T#]^ߵמdq =i?9oA Yi~уmIAN}B٥RnO9Eéxl8a=Fvuoiq3'¹lşԈՂIqT"@ŴBy 9 浮kFzd-B*FkZb(pMp_]XL13=xcEa Daj)I'_f`)Eo/ 4˘k~45eGm}pOeY`1Gy:ڪrS=@Ȝ=; E(5i% 2PIY@:7fԽ!.*j:kdi,K8LԮw,c_'{d{F3`Lv(/v r drMYQe|u^q$ǣ<!vBBҸ1oQR<^}01Lx҉#_ e.A- gcgw i d^7L&>Ӯ: O 1"KCWa[&PuܛQ@YZsurveillance/data/q2.RData0000644000176200001440000000030010636320360015106 0ustar liggesusers r0b```b`bad`b2Y#'HЈY$ ļ@|apF$g`FQ1 4hQ0 F($P}gr W!k^bnj1!n 9SRS`KKRB$t#saFQ A•t ; surveillance/data/rotaBB.RData0000644000176200001440000000447412305624556015766 0ustar liggesusers\ l\}l&v &$1qBCc@ۃmӤlP"6! ,jUZ$(*ml8 jQ+@UtB{-ZxO:{[ɝ 7/)\r 8.RaUBK܆7tCٹ%s/G4{CZ8O!8瑿4C5R~>CSkҿkՒΧL/ iYבFR=H_ok"]Hy;*7P~5ҝ?DM@~uO(#-䗑|iϑA#OP0?%'J9Zbɯ#_n_%}HH/ȿE: &-m%]Az^Iv[(HEW(:t4xʓ+)?eʯ!2\'Aw# oSE4KH(t 97|?Kkm-?ur-?Lt .6~jPgJ'/·.|kJדO[}P^+D9 ɮ3 4e9j\' |_-ǀa]CYVYlȈ AT>l!mYi E q^W m.=KpBoԻu q#`W AZvB{ ` b^祐e7|݌M"Ww;F@p Dy';&K_V[;ϻKa>ۨ odEp|YD* e;s8&_a(?2rQciUŶ3Kl~.elee'e[WQ`++L()6%Cu܀fSDt.u*ٶx1ukc8U_-u8#>)3e_ߦn93sQpL;f_2&gbnI{ cWα`=_Ӿ+Cj&&+g%&)ikU05klbeT&WcS7k. %Vҙ$k YH2P,[<站k1/L}AĬzV,P8k}T:/g?p7--Sغ>J?}}4PzF9q^*quѦ)uQ.g󣀜W짲6uʹ"gW>}=c93q(jxWҏcX-cf֯c@[Ň/nf}3 'dOy+Ŭgg/W\Y{fk3NB3wv/7;{>}UUFMI&N'Sz.1.vv(}a;v<$j;n'NzkF'gfϠ~3d ;QW-}J fQ_ژ[rvhwa|J65Ϋ}2bdk}hM.7L[mM[GR]\:󠀏^'b-b-b-b-b-attLM7OeR')#J1 q/~7{ Gž*nc|dDXyR߇ᮁoW1\>6c珝?vc珝?v|}rSYƯ/bZ˝=o ]ٞ/) ߟgşC)GZTJNuUKbTUxsZsԾxl&[/e~_gxP3Vb̌R c%^/[4Tbw11yh8SzC0ecG Z3T7=az_qcOsurveillance/data/ha.RData0000644000176200001440000000233512376633551015202 0ustar liggesusersBZh91AY&SY* ͘XȿȀ@8- SLM ~O)&'CM hb4ChAdDORUIPU)6Ꚕ2 A 0@)OP=)jiК2d<=! z4=FS @H@^H2 ] dZ2WRȤR%DP*TR)  ]z sidq6)!`d܀tV06DB:9ƳA~ƈaTv<<ƹ /3<'+<ހ㮺뮺wwwwwww`݀{}k6(7dB{` @+fB3Qن!-A6?w-S?8Ж)qaIgAA"Dݥm/ydu[q_oe=pkL/Yb@n^!f)䍝8+ߚ֤tr _λJby8ջU5Mn@|ˢ1$G[ x} 2hˆ`$`D ւ DIt I^Gwwwqqq.9ss\V5]u]yRIX4VIX$TbI+$JI%brmm _xV*I1U$JI%bRI$TV*I+1\997mww*6]ҀWqj뙙UUUU@k)FUUUUv*ȈUY UUUUU[.-XX)JYb@ v໻wiiiZi9sUp`H ]ڸ߁P~?1<C3%"ʮpf4IK|, ]Ba-Z / ,5SFm}?੒56pbվ1ȑj s!=̆&n. C9l^la"(Hޕasurveillance/data/n2.RData0000644000176200001440000000047210636320360015115 0ustar liggesusers r0b```b`bad`b2Y#'H<ψY$ ļ@|"  $>Ѐ %Ę@p"F V @ @LPsXg`@MɭqV:f$145HldA3B qԀAg eF>^f03"g@2fͤcQ0 F(+J@ a H'(Cּb C\I9SRS`KKRB$t#saFa {Jfq@Q~: surveillance/data/h1_nrwrp.RData0000644000176200001440000000043510636320360016335 0ustar liggesusers r0b```b`bad`b2Y#'0+*/*```I1/_d@F ccˌfEӋF6Đ1AM6w2"ɀĊGW˄f':B=> . sC7T-{ aǀF(`X 0AJ5/17`7 ԢĒT(%(Ib:$ȞYPda o surveillance/data/m4.RData0000644000176200001440000000037710636320360015122 0ustar liggesusers r0b```b`bad`b2Y#'H<ׄY$ ļ@|xH<#:FꙡY3&@7] %EX -ʖby bvZN4Bb@r6r@w(c -/CQ0 F  0Ac(Cּb C@ r'$B9,iEHE%F&$ÌQ@)E@?Ÿ surveillance/data/salmAllOnset.RData0000644000176200001440000004155212630575752017215 0ustar liggesusers}yGq;dz:l˷|5Ooa6l [ K$s`pq!$@HHBv$9H$!@ïT|~O=[5=uuuU>u]vBZy|m,ô\ٲozǞ{C:lݵ!m{BHTg>py#E/%WD)o%|;; ?s $~ ~9W~ %Hao#N!˄?H&/^$% -'$?Lϴ O>J« JpG^OD§>Y7'X› _HR—o$|3~: ?3 M{ ? }_Fg [;/ _%'Y_$<$s_'7?g#A"϶ O>W>ᄏ" O!|:7~,_H—o |3'~:?6wEx/~>+ ?Hu_O[ U¿N'g  ?!焿Fo?6> P-“>*‡^G(>ɄO'pAxp9#|K?𕄯!|?Fx+mEx /$bi¯$j¯#s :(/ ?!U_#ׄA[MO 7F~2+":G>O&| 7%\>/ |15'|[?[ Ex;ᝄ~6 /&R?M_M#N]G?DÄ?Bw'  W1KM?.%#<_ IO#|&ፄ{K!|. _L2WHO%",; &l#O~C@M!EOWo#IŸ&y D 1?#&"JCxr3>!|JLg##|>_F &|'~$,;&|/IO~9C?L { 2_!ko#iŸ#@x~ Eo ?!oFx!BW^CPGf /0_` /0_`V/0_` /0_` /0 /0_` /,f /0_`Մ6f?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?0 300000000000000000|0!!!!!!!!!zf?d?d?d?d?d?d?d?d?d?d?d?|0!!!!!!!!!!!!!!!!! 322222222222_ ^>,v6+SϺrg}`q%NY/Xs<8g=bq3_>>O}+}-}/o}1g,>c]ýlh?cV8V(#ٳwo~?v޶ggo2_rH0. 4(5OKvܒ?,1ϖ/M2\eg%%bk=(WdmIّ#qR" '$wrQ wJ"ih{Z")&%H yBVFuċw&ϖ%YqKL)ɔiѴ<-zޗID0-O35':M9ms[mӒu|'he {yfKviu)wyggm珗&Qi~PW|j]#MjNȮ?!wre-΄ds" &3Nl$,cRVD{\d-[g.;ek&rEmx&tJ֐gQvSlbtȾ/W dkD?ƾdr4ȼx&yk-;)ʰjH:v.4M\mq‡dhwɌ&ΎG-zhK+MFK\2\\ew$d 3\䙋 gEF/Kgoe"Md}TI_!M ݹЗF[Bk[Y["޶2m-K&v$[.; Y[Gl-Qw[2Nsl̖ג59se.L\䙉_&Qy&r$;~8A&{&Is_c*}nc?!^ev[BoKւёu~;ӄB2 &$✐(#6)oi.:(@В`+$sZMBh;ƵU.T{DoqMgyF. -6Z+ZS:qGtّɆ;HuёcB3) Kȱ-h[l2-֣dD쏥o`+bWIGH2W+dϡɚ$ Ddyy[/~-k-;d[H[l-|xmY7>۲"זH ؒ&/ށ#6} .;Y\Й15˄8˴ˋmd"|/!G)GgOmb"\_ܒ=%t$jo#T&|%; *ӤAޒUgL +Md]e/&~1{fVEg> /GqkOb Wr?JJoWR33i&Jfq"kA%k=- AwWP5s Q5|?t2~?K$CddLQ.ɯ ~>sor=?̗=tsX' B5J/S?!B[]P&{` ܃O2]߇h+fe'X|.^@$Ω+^i|fed3-Tϐq<ʱnP >P6}v d{|0k{K$l &wIlN8T{̏`?o㼰À5(TşeǓ7T~/\]VLQב/ӲQgXeP<3?N@+*x#2n D oPx y~ aMDF>?HQIۿ!mp){g&53QNYI0?IL&3*syC&=x+Y?3j^J-7nIZ rx?3 ؎@kuL)oU O82CmS?S/Q6Lf{[;Q^=?- GR6hܵ\4'1ϖ;{6MKFm{kVݷW]3 7CH: )'KVgJG'kFiw˿O+z?{?c?m7&vN,&Fc>ۇ߇ˆSMiUySשVhX;ۮe|~jef}Kc2&=CZAi9ُ| :\+O9ۡ ewK嚻Kő`GR8 G23^- G>AvK, K- dvK1I8ǽ&N8ZisnG8:|Իc8xi'8p xiǹOdwybՓv4=Nqt=ҞCp}חq N sy|'_gl~' Gqld瓟9}a\vSPo8mp$9jrN!";E4{gSWgpF^0 -CYmf9Bi7Q[B!(k{8>up}p<f=ȺI^ ]ҴIZA˱өsTI|9\J v#?܎|;yFڡ#YVi8Bv.z:w2i?ב]w (CXkX%5PDp/8S!qQ8^xB\w}7.ByCIYw)W9x齙2y"e/|(׷~30y8&-T"T};0qr8bǔ8u$;Rl"?͇gg ^aǰއNΡ<^vyi !t">ŔV~s@⧙GO~ZFޛH7x]@~=O}`Q`WXkBM[)g77Iyf)K װQe2&󤯤Ol s o|\m1=?toa]w~.s,:Y z??|@OXw3!+{,%UamcB~nj;úXG}@Jd>r:z8%h'qT3l1샣qǏǰw؛ >W:&}X (x#'v\xz;縀2~Ͼ'>o/yx1/44f9S8GxaSCu`p?|4S.Ww}\wɞMlD#!{z_pP×N$[ P  !R8Lӿ*_U4y!58(&XE?x8:/np6\8tHzrguI{m/{?" X-[=VA?82+ip#WnCC=LҞC|oD1-hH_ǡOkN_*>͒:l!%8q7C<ԗA2guĥs^p^U`T oxx/y%6a|\.|+l$ꣲo;cLؾJ8 ~oW{>i?cR-P ]8 U/Zu5.Cph% >^83=l>{;<8: b='pz:沇TJz6v?9!EºB+,n?IU})IΒ?@? ru;}T~鮸Sҧ:VCu-x_|# _XW$fYX;ߢ?|5叜Ox }ʹOY;≿ZM|au):L }C{vXfO2m c)7e_6_W4oazy~ ~'_G(u }|.qF&~:dqUzġfaW ,Vu\g46C>z _%»yZoFi\[ߤ}e;W5qGIۻiM!C ~ q W]:p_l~;#gz}ykk>mCC~=^ ޿"겒$aB9xr=|vO㘟!ZB ]cY{2N<#Ե<^+B\k.Nu'dzA.R _.#C]o{OıRZCww.rΝ N-ca=r~?A>aQ>H~LY=tC:`?g\D]ޛ ?8yl +r{z1(|Y XSBHj=?''XO#=.LC )] ;<]$w[(_þcWQAvr}}$B+y`ǢoB ||ec%.弙F;$eO߷)k:lYb:T]tȧgq8h>!Mhb҄zS>?l|C?B|}_wC<4- f̼9XZ|Uu",6:,!~%u%PG{bͪIE#%&C;?L~XX߈밷O:pqr<䌈EՁGW1Tt˚C>u\rܿ^0b2%=Vu|_G*y@.C/JZ8}^=(ё?v>g&>:å _P&: { I;t1#=?oWw?|zD[u);T#U~E~ՁRwPfDUDN}~n[T:B6 m뽡; ~>{s tVBjO9@uU.#?wgE.DzOd/x#ꨊC!CX)jI{-m :s7a ;Þp#]j"_+`!-9p:)ޫqW0)zY@;McބwxR=Xw>/&O7QVwR'~GBOvP?z=!^{iG綨JN#|-u##]GQ]I* 1 PAwzo0Y\ t\By^vV߻l g!'<4 PGv,É_mx9+9g9Ncrw=i q9|^>>`CjsI׏sֆ GC;(˩\0kPmPv@7~bX Be;Ԙ>> qL3WlKX~)F8'rE:jN?|c>~m΅9 'XW wUkh;iCL~/>/2l##㸏b_x 7/1y:'W5'g~n/HO?=?G<@?XW2-|6|"ʿO_Ob}PF|d*,NEm9Y"CGꙡ! l;ˉC ϯ!UkLޟǾ;)[ĕLӴGf>!3kC>t`o?s{!o ?r qx;*Կi's^[BwB!g6ČC ~ruB@Ɩa9Bw|Yԁo@溑}|3 gBXDr5e#zi5gyvv y_H=A^@1U=1~,ur{B!\ sWSWQN?7Եysn WGK er uOgs3lt#yVylri>K:;2{:YV}Rw)Ǒ9(ν)Կo359W:Q? }83FFnNyG.W~AKwLmvJ~_xt-y[q+yojSuz:>;Կ6]\O%k5qveSߕ#q<8j-4{}9AL$#s$:_E5^WY/ זqUm6P~PP~cy;CwsutW`{$J΃"^8y~\안 6߀y!^HzO2i\ׇ3pz?ޅ51=$mm]Nz#BW!lWG/Oh}$ ߰ nx42f;g<jv"ylC1rue!zg>|# 6z,uCGX;e ^$'8vóN!s!ϝ N A;4I]J uLsjܠ1 PG3k64V?-Կ X8~_OKY®<49u}P﹫Y3]>jSp| u-KIJPpօz]-IT?2>r) CQaݞmfBww:tD{6|(ᕔ!͐&#?cֆ^քN4~ MFr^[s 3QF058AsB34<&ԾV9t}m u">[㐉Pm湆?)#eFgB{Vo4\/xuj?A56՘+#+:quLy cN9y]8ֵ6껑3(k<9lkCg`zlר-Xӎs֒s1et"fTBw߳i?9m5iIUxH3]6/ֽE}F#ޱ~/9j>*Եq#iPgz926_|Ϝ}۔K}l X_kw+yɡ/ z%(͸T׊w-ԿwA:2kN'SISaR,x;!S޺wiJjwZ߫{̲P+J]kB] 6v$NxqU|]jGԏƨ6fQڡ7Yg5z1A)w'C]k]j?txߕkl*kv-&rнv{6Ugv׺>kG Wʳ1]>Qk{y'qd ƣ8*nSz5~ջխVn2cTj8t2W15ҹ27n6FShimƇk [գ޷n|urӬ앾`t6qwK}/zB)}P+AmN\ʟ՗AQ1cm2iG:N;1yPZgEna} 龫פֿ u-Ij43.Twxh9t?֘m r`~?,U.τ|<:oJڭL&U^*/ilMөu/PCW_Ջa"Y:<(4PoԼI2Wք:V:W':`dv8?'wf>Y>5ָw _BW}V[޵nkJ׌&8-Φ NmM׀ְׄz=,^w9Wuуl,eWedvֺ{Ѩ|5!:Gճ*fNˋi>v}t}z%l,zP ac6 }}Aizi|y3a P^oOՕ'LytxkJ>/Yzl_onjm{[n`˿GUWt-Zj0Z>-w}u O6EpWWl|ϲv6+Qv0œo/ '}N'`/6ĸ^cFPcB~5սBhAhXl^T5Sv6NcB;k6]7*''z74&Q1C]?w76WhmT9>[ԵklkL}_<ƾ}fѸ֮1[bmSk[ߪ:h_s'(*[3Ə֧8фncmb#!f kcs;_ќ7Y]tͩ qEh2]Kt>'u-7/@6 ^~_va緲ڝ@c6+?KƧv=[OX`܍稘'k c]y87uN٘ƆʫIV~u>*vChg}-1f~j+W~ڝ=o1ZvWeie& {vÔfk3 K`8#X|_C!4mfخ,Kٓ)/>[-k~>ϟiKl}~s}w L#TuSċk|ꚬiv=׳XzyvSG}&=aڢ_J>KXS_kc/;4wģ5w4ްaדD־^k63!o0F&YZKU{]Y~@6>Thvݏ :vX^҂^gi]>8*ڢZ7{Pn`X_|=>No}`{;RzۮE^\#Ǟ~ {۴8yԾisNY^lՏ|XoKk8kT93*VuH76/U+?>&~.5x\nG>G1ga;G٦(c:#ЏճqMy4maQ>:мKD,n=1Zӭ64)h6[opH3F߼"f`ד*M3V>뛴*, uN`;>kkwvnXLl]f MS{K53G*hBM).Mz^ڵy8/_ؘۇ]^oW=?K];ܨߎXxv| ~^h;>ci}&]?'& oe'|eipZ& ei_1Ecɨϼ(c &mʧ8^`) ouqVL2Y] q L1[cVWaɨuu:1E`Q VtcE᭮(VWN,'4TuM0鍘a:1dTC:FLcNsMFLcdT`|ʄ2L8-NM0zLq:$n2۔&q ̼8- ouE᭮(VWt=EsZt=EnS ku$UC{LVW yz1SW]_&fcdT꺾\t}8btQ R31لللللfe)b:1&YYH0ɨOpZ& eipOtOtOtOtڬ,EL1$M1})6yL`qqV*KU"q*K9mV,ELzDLiV"(L2au=ˆyz<"iFLz{897[1: eipZ& FLM0ɨO{L<הma8u-$)ˆqV~[1o ǩma48-S61ΓjXݬG1O# pMF5t:+ӰY_sL̼ɨncN˄2L8-N):4+=HFu )WgLLS>1\8bչ 01}q 01M1 +ӰML̼ɨm`b=1Oz7 p=&:+ӰM1]'fɨn78 eipZ&6+SlL0ɨ pMFuqq*U"%V.v߼qbof۴ooߔ͢7]Ȉr=Gَ?t7W޺kvym[vܹ}i>um52λm~cs֞{⭵{۶o߲vRk0surveillance/man/0000755000176200001440000000000014615167606013535 5ustar liggesuserssurveillance/man/salmonella.agona.Rd0000644000176200001440000000126013122471774017232 0ustar liggesusers\name{salmonella.agona} \alias{salmonella.agona} \docType{data} \title{Salmonella Agona cases in the UK 1990-1995} \description{ Reported number of cases of the Salmonella Agona serovar in the UK 1990-1995. Note however that the counts do not correspond exactly to the ones used by Farrington et. al (1996). } \usage{data(salmonella.agona)} \format{ A \code{disProg} object with 312 observations starting from week 1 in 1990. } \source{ A statistical algorithm for the early detection of outbreaks of infectious disease, Farrington, C.P., Andrews, N.J, Beale A.D. and Catchpole, M.A. (1996). , J. R. Statist. Soc. A, 159, 547-563. } \keyword{datasets} surveillance/man/hhh4_formula.Rd0000644000176200001440000000602313122471774016401 0ustar liggesusers\name{hhh4_formula} \alias{fe} \alias{ri} \title{ Specify Formulae in a Random Effects HHH Model } \description{ The special functions \code{fe} and \code{ri} are used to specify unit-specific effects of covariates and random intercept terms, respectively, in the component formulae of \code{\link{hhh4}}. } \usage{ fe(x, unitSpecific = FALSE, which = NULL, initial = NULL) ri(type = c("iid","car"), corr = c("none", "all"), initial.fe = 0, initial.var = -.5, initial.re = NULL) } \arguments{ \item{x}{an expression like \code{sin(2*pi*t/52)} involving the time variable \code{t}, or just \code{1} for an intercept. In general this covariate expression might use any variables contained in the \code{control$data} argument of the parent \code{\link{hhh4}} call.} \item{unitSpecific}{logical indicating if the effect of \code{x} should be unit-specific. This is a convenient shortcut for \code{which = rep(TRUE, nUnits)}, where \code{nUnits} is the number of units (i.e., columns of the \code{"sts"} object).} \item{which}{vector of logicals indicating which unit(s) should get an unit-specific parameter. For units with a \code{FALSE} value, the effect term for \code{x} will be zero in the log-linear predictor. Note especially that setting a \code{FALSE} value for the intercept term of a unit, e.g., \code{ar = list(f = ~-1 + fe(1, which=c(TRUE, FALSE)))} in a bivariate \code{hhh4} model, does \emph{not} mean that the (autoregressive) model component is omitted for this unit, but that \eqn{\log(\lambda_1) = \alpha_1} and \eqn{\log(\lambda_2) = 0}, which is usually not of interest. ATM, omitting an autoregressive effect for a specific unit is not possible.\cr If \code{which=NULL}, the parameter is assumed to be the same for all units.} \item{initial}{initial values (on internal scale!) for the fixed effects used for optimization. The default (\code{NULL}) means to use zeroes.} \item{type}{random intercepts either follow an IID or a CAR model.} \item{corr}{whether random effects in different components (such as \code{ar} and \code{end}) should be correlated or not.} \item{initial.fe}{initial value for the random intercept mean.} \item{initial.var}{initial values (on internal scale!) for the variance components used for optimization.} \item{initial.re}{initial values (on internal scale!) for the random effects used for optimization. The default \code{NULL} are random numbers from a normal distribution with zero mean and variance 0.001.} } \seealso{ \code{\link{addSeason2formula}} \code{hhh4} model specifications in \code{vignette("hhh4")}, \code{vignette("hhh4_spacetime")} or on the help page of \code{\link{hhh4}}. } \note{ These special functions are intended for use in component formulae of \code{hhh4} models and are not exported from the package namespace. If unit-specific fixed or random intercepts are specified, an overall intercept must be excluded (by \code{-1}) in the component formula. } \keyword{regression} surveillance/man/find.kh.Rd0000644000176200001440000000247112375711212015336 0ustar liggesusers\name{find.kh} \alias{find.kh} \title{Determine the k and h values in a standard normal setting} \description{ Given a specification of the average run length in the (a)cceptance and (r)ejected setting determine the k and h values in a standard normal setting. } \usage{ find.kh(ARLa = 500, ARLr = 7, sided = "one", method = "BFGS", verbose=FALSE) } \arguments{ \item{ARLa}{average run length in acceptance setting, aka. in control state. Specifies the number of observations before false alarm.} \item{ARLr}{average run length in rejection state, aka. out of control state. Specifies the number of observations before an increase is detected (i.e. detection delay)} \item{sided}{one-sided cusum scheme} \item{method}{Which method to use in the function \code{\link{optim}}. Standard choice is BFGS, but in some situation Nelder-Mead can be advantageous.} \item{verbose}{gives extra information about the root finding process} } \value{ Returns a list with reference value k and decision interval h. } \details{ Functions from the \pkg{spc} package are used in a simple univariate root finding problem. } \examples{ if (requireNamespace("spc")) { find.kh(ARLa=500,ARLr=7,sided="one") find.kh(ARLa=500,ARLr=3,sided="one") } } \keyword{models} surveillance/man/backprojNP.Rd0000644000176200001440000002546314431140532016050 0ustar liggesusers\encoding{latin1} \name{backprojNP} \alias{backprojNP} %Internal functions %\alias{backprojNP.fit} %\alias{naninf2zero} %\alias{em.step.becker} \title{ Non-parametric back-projection of incidence cases to exposure cases using a known incubation time as in Becker et al (1991) } \description{ The function is an implementation of the non-parametric back-projection of incidence cases to exposure cases described in Becker et al. (1991). The method back-projects exposure times from a univariate time series containing the number of symptom onsets per time unit. Here, the delay between exposure and symptom onset for an individual is seen as a realization of a random variable governed by a known probability mass function. The back-projection function calculates the expected number of exposures \eqn{\lambda_t}{lambda_t} for each time unit under the assumption of a Poisson distribution, but without any parametric assumption on how the \eqn{\lambda_t}{lambda_t} evolve in time. Furthermore, the function contains a bootstrap based procedure, as given in Yip et al (2011), which allows an indication of uncertainty in the estimated \eqn{\lambda_t}{lambda_T}. The procedure is equivalent to the suggestion in Becker and Marschner (1993). However, the present implementation in \code{backprojNP} allows only a univariate time series, i.e. simultaneous age groups as in Becker and Marschner (1993) are not possible. The method in Becker et al. (1991) was originally developed for the back-projection of AIDS incidence, but it is equally useful for analysing the epidemic curve in outbreak situations of a disease with long incubation time, e.g. in order to qualitatively investigate the effect of intervention measures. } \usage{ backprojNP(sts, incu.pmf, control = list(k = 2, eps = rep(0.005,2), iter.max=rep(250,2), Tmark = nrow(sts), B = -1, alpha = 0.05, verbose = FALSE, lambda0 = NULL, eq3a.method = c("R","C"), hookFun = function(stsbp) {}), \dots) } \arguments{ \item{sts}{ an object of class \code{"\linkS4class{sts}"} (or one that can be coerced to that class): contains the observed number of symptom onsets as a time series. } \item{incu.pmf}{Probability mass function (PMF) of the incubation time. The PMF is specified as a vector or matrix with the value of the PMF evaluated at \eqn{0,...,d_max}{0,...,d_max}, i.e. note that the support includes zero. The value of \eqn{d_max}{d_max} is automatically calculated as \code{length(incu.pmf)-1} or \code{nrow(incu.pmf)-1}. Note that if the sts object has more than one column, then for the backprojection the incubation time is either recycled for all components or, if it is a matrix with the same number of columns as the sts object, the \eqn{k}{k}'th column of \code{incu.pmf} is used for the backprojection of the \eqn{k}{k}'th series. } \item{control}{A list with named arguments controlling the functionality of the non-parametric back-projection. \describe{ \item{\code{k}}{An integer representing the smoothing parameter to use in the smoothing step of the EMS algorithm. Needs to be an even number. } \item{\code{eps}}{A vector of length two representing the convergence threshold \eqn{\epsilon}{epsilon} of the EMS algorithm, see Details for further information. The first value is the threshold to use in the \eqn{k=0}{k=0} loop, which forms the values for the parametric bootstrap. The second value is the threshold to use in the actual fit and bootstrap fitting using the specified \code{k}. If \code{k} is only of length one, then this number is replicated twice. } \item{\code{Tmark}}{Numeric with \eqn{T'\leq T}. Upper time limit on which to base convergence, i.e. only the values \eqn{\lambda_1,\ldots,\lambda_{T'}} are monitored for convergence. See details. } \item{\code{iter.max}}{ The maximum number of EM iterations to do before stopping. } \item{\code{B}}{ Number of parametric bootstrap samples to perform from an initial k=0 fit. For each sample a back projection is performed. See Becker and Marschner (1993) for details. } \item{\code{alpha}}{(1-\eqn{\alpha}{alpha})*100\% confidence intervals are computed based on the percentile method. } \item{\code{verbose}}{(boolean). If true show extra progress and debug information. } \item{\code{lambda0}}{Start values for lambda. Vector needs to be of the length \code{nrow(sts)}. } \item{\code{eq3a.method}}{A single character being either \code{"R"} or \code{"C"} depending on whether the three nested loops of equation 3a in Becker et al. (1991) are to be executed as safe R code (can be extremely slow, however the implementation is not optimized for speed) or a C code (can be more than 200 times faster!). However, the C implementation is experimental and can hang R if, e.g., the time series does not go far enough back. } \item{\code{hookFun}}{ Hook function called for each iteration of the EM algorithm. The function should take a single argument \code{stsbp} of class \code{"\linkS4class{stsBP}"} class. It will be have the lambda set to the current value of lambda. If no action desired just leave the function body empty (default). Additional arguments are possible. } } } \item{\dots}{Additional arguments are sent to the hook function. } } \details{ Becker et al. (1991) specify a non-parametric back-projection algorithm based on the Expectation-Maximization-Smoothing (EMS) algorithm. In the present implementation the algorithm iterates until \deqn{\frac{||\lambda^{(k+1)} - \lambda^{(k)}||}{||\lambda^{(k)}||} < \epsilon} This is a slight adaptation of the proposals in Becker et al. (1991). If \eqn{T} is the length of \eqn{\lambda} then one can avoid instability of the algorithm near the end by considering only the \eqn{\lambda}{lambda}'s with index \eqn{1,\ldots,T'}. See the references for further information. } \value{ \code{backprojNP} returns an object of \code{"\linkS4class{stsBP}"}. } \references{ Becker NG, Watson LF and Carlin JB (1991), A method for non-parametric back-projection and its application to AIDS data, Statistics in Medicine, 10:1527-1542. Becker NG and Marschner IC (1993), A method for estimating the age-specific relative risk of HIV infection from AIDS incidence data, Biometrika, 80(1):165-178. Yip PSF, Lam KF, Xu Y, Chau PH, Xu J, Chang W, Peng Y, Liu Z, Xie X and Lau HY (2011), Reconstruction of the Infection Curve for SARS Epidemic in Beijing, China Using a Back-Projection Method, Communications in Statistics - Simulation and Computation, 37(2):425-433. Associations of Age and Sex on Clinical Outcome and Incubation Period of Shiga toxin-producing Escherichia coli O104:H4 Infections, 2011 (2013), Werber D, King LA, \enc{Mller}{Mueller} L, Follin P, Buchholz U, Bernard H, Rosner BM, Ethelberg S, de Valk H, \enc{Hhle}{Hoehle} M, American Journal of Epidemiology, 178(6):984-992. } \author{ Michael \enc{Hhle}{Hoehle} with help by Daniel \enc{Sabans Bov}{Sabanes Bove} for the \pkg{Rcpp} interface } \note{ The method is still experimental. A proper plot routine for \code{stsBP} objects is currently missing. } \examples{ #Generate an artificial outbreak of size n starting at time t0 and being of length n <- 1e3 ; t0 <- 23 ; l <- 10 #PMF of the incubation time is an interval censored gamma distribution #with mean 15 truncated at 25. dmax <- 25 inc.pmf <- c(0,(pgamma(1:dmax,15,1.4) - pgamma(0:(dmax-1),15,1.4))/pgamma(dmax,15,1.4)) #Function to sample from the incubation time rincu <- function(n) { sample(0:dmax, size=n, replace=TRUE, prob=inc.pmf) } #Sample time of exposure and length of incubation time set.seed(123) exposureTimes <- t0 + sample(x=0:(l-1),size=n,replace=TRUE) symptomTimes <- exposureTimes + rincu(n) #Time series of exposure (truth) and symptom onset (observed) X <- table( factor(exposureTimes,levels=1:(max(symptomTimes)+dmax))) Y <- table( factor(symptomTimes,levels=1:(max(symptomTimes)+dmax))) #Convert Y to an sts object Ysts <- sts(Y) #Plot the outbreak plot(Ysts, xaxis.labelFormat=NULL, legend=NULL) #Add true number of exposures to the plot lines(1:length(Y)+0.2,X,col="red",type="h",lty=2) #Helper function to show the EM step plotIt <- function(cur.sts) { plot(cur.sts,xaxis.labelFormat=NULL, legend.opts=NULL,ylim=c(0,140)) } #Call non-parametric back-projection function with hook function but #without bootstrapped confidence intervals bpnp.control <- list(k=0,eps=rep(0.005,2),iter.max=rep(250,2),B=-1,hookFun=plotIt,verbose=TRUE) #Fast C version (use argument: eq3a.method="C")! sts.bp <- backprojNP(Ysts, incu.pmf=inc.pmf, control=modifyList(bpnp.control,list(eq3a.method="C")), ylim=c(0,max(X,Y))) #Show result plot(sts.bp,xaxis.labelFormat=NULL,legend=NULL,lwd=c(1,1,2),lty=c(1,1,1),main="") lines(1:length(Y)+0.2,X,col="red",type="h",lty=2) #Do the convolution for the expectation mu <- matrix(0,ncol=ncol(sts.bp),nrow=nrow(sts.bp)) #Loop over all series for (j in 1:ncol(sts.bp)) { #Loop over all time points for (t in 1:nrow(sts.bp)) { #Convolution, note support of inc.pmf starts at zero (move idx by 1) i <- seq_len(t) mu[t,j] <- sum(inc.pmf[t-i+1] * upperbound(sts.bp)[i,j],na.rm=TRUE) } } #Show the fit lines(1:nrow(sts.bp)-0.5,mu[,1],col="green",type="s",lwd=3) #Non-parametric back-projection including boostrap CIs bpnp.control2 <- modifyList(bpnp.control, list(hookFun=NULL, k=2, B=10, # in practice, use B >= 1000 ! eq3a.method="C")) sts.bp2 <- backprojNP(Ysts, incu.pmf=inc.pmf, control=bpnp.control2) ###################################################################### # Plot the result. This is currently a manual routine. # ToDo: Need to specify a plot method for stsBP objects which also # shows the CI. # # Parameters: # stsBP - object of class stsBP which is to be plotted. ###################################################################### plot.stsBP <- function(stsBP) { maxy <- max(observed(stsBP),upperbound(stsBP),stsBP@ci,na.rm=TRUE) plot(upperbound(stsBP),type="n",ylim=c(0,maxy), ylab="Cases",xlab="time") if (!all(is.na(stsBP@ci))) { polygon( c(1:nrow(stsBP),rev(1:nrow(stsBP))), c(stsBP@ci[2,,1],rev(stsBP@ci[1,,1])),col="lightgray") } lines(upperbound(stsBP),type="l",lwd=2) legend(x="topright",c(expression(lambda[t])),lty=c(1),col=c(1),fill=c(NA),border=c(NA),lwd=c(2)) invisible() } #Plot the result of k=0 and add truth for comparison. No CIs available plot.stsBP(sts.bp) lines(1:length(Y),X,col=2,type="h") #Same for k=2 plot.stsBP(sts.bp2) lines(1:length(Y),X,col=2,type="h") } \keyword{models} \keyword{optimize} surveillance/man/isoWeekYear.Rd0000644000176200001440000000200714307577435016255 0ustar liggesusers\name{isoWeekYear} \alias{isoWeekYear} \title{Find ISO Week and Year of Date Objects} \description{ The function \code{isoWeekYear} extracts the year and week of a \code{\link{Date}} according to the ISO 8601 specification. } \usage{ isoWeekYear(Y, M, D) } \arguments{ \item{Y}{year(s) or a Date/POSIXt object. Can be a vector.} \item{M}{month(s), only used if \code{Y} is not a Date/POSIXt object.} \item{D}{day(s), only used if \code{Y} is not a Date/POSIXt object.} } \value{ A list with entries \code{ISOYear} and \code{ISOWeek} containing the corresponding results. } \note{ As from \pkg{surveillance} 1.17.0, this function simply calls \code{\link{strftime}} with format strings \code{"\%G"} and \code{"\%V"}, respectively, as this is nowadays (\R >= 3.1.0) also supported on Windows. } \examples{ dates <- as.Date(c("2002-12-31","2003-01-01","2003-01-06")) isoWeekYear(dates) ## the same using numeric inputs: isoWeekYear(Y = c(2002, 2003, 2003), M = c(12, 1, 1), D = c(31, 1, 6)) } \keyword{chron} surveillance/man/momo.Rd0000644000176200001440000000506214200471656014767 0ustar liggesusers\name{momo} \alias{momo} \docType{data} \encoding{latin1} \title{Danish 1994-2008 all-cause mortality data for eight age groups} \description{ Weekly number of all cause mortality from 1994-2008 in each of the eight age groups <1, 1-4, 5-14, 15-44, 45-64, 65-74, 75-84 and 85+ years, see \enc{Hhle}{Hoehle} and Mazick (2010). } \usage{data(momo)} \format{ An object of class \code{"\linkS4class{sts}"} containing the weekly number of all-cause deaths in Denmark, 1994-2008 (782 weeks), for each of the eight age groups <1, 1-4, 5-14, 15-44, 45-64, 65-74, 75-84 and 85+ years. A special feature of the EuroMOMO data is that weeks follow the ISO 8601 standard, which can be handled by the \code{"sts"} class. The \code{population} slot of the \code{momo} object contains the population size in each of the eight age groups. These are yearly data obtained from the StatBank Denmark. } \source{ \emph{European monitoring of excess mortality for public health action} (EuroMOMO) project. \url{https://www.euromomo.eu/}. Department of Epidemiology, Statens Serum Institute, Copenhagen, Denmark StatBank Denmark, Statistics Denmark, \url{https://www.statistikbanken.dk/} } \examples{ data("momo") momo ## show the period 2000-2008 with customized x-axis annotation ## (this is Figure 1 in Hoehle and Mazick, 2010) oopts <- surveillance.options("stsTickFactors" = c("\%G" = 1.5, "\%Q"=.75)) plot(momo[year(momo) >= 2000,], ylab = "", xlab = "Time (weeks)", par.list = list(las = 1), col = c(gray(0.5), NA, NA), xaxis.tickFreq = list("\%G"=atChange, "\%Q"=atChange), xaxis.labelFreq = list("\%G"=atChange), xaxis.labelFormat = "\%G") surveillance.options(oopts) \dontshow{if (surveillance.options("allExamples")) \{} ## stratified monitoring from 2007-W40 using the Farrington algorithm phase2 <- which(epoch(momo) >= "2007-10-01") momo2 <- farrington(momo, control = list(range=phase2, alpha=0.01, b=5, w=4)) colSums(alarms(momo2)) plot(momo2, col = c(8, NA, 4), same.scale = FALSE) ## stripchart of alarms (Figure 5 in Hoehle and Mazick, 2010) plot(momo2, type = alarm ~ time, xlab = "Time (weeks)", main = "", alarm.symbol = list(pch=3, col=1, cex=1.5)) \dontshow{\}} } \references{ \enc{Hhle}{Hoehle}, M. and Mazick, A. (2010). Aberration detection in R illustrated by Danish mortality monitoring. In T. Kass-Hout and X. Zhang (eds.), \emph{Biosurveillance: A Health Protection Priority}, chapter 12. Chapman & Hall/CRC.\cr Preprint available at \url{https://staff.math.su.se/hoehle/pubs/hoehle_mazick2009-preprint.pdf} } \keyword{datasets} surveillance/man/hhh4_methods.Rd0000644000176200001440000001452114071043451016370 0ustar liggesusers\encoding{latin1} \name{hhh4_methods} \alias{print.hhh4} \alias{summary.hhh4} \alias{nobs.hhh4} \alias{formula.hhh4} \alias{logLik.hhh4} \alias{coef.hhh4} \alias{vcov.hhh4} \alias{fixef.hhh4} \alias{ranef.hhh4} \alias{coeflist.hhh4} \alias{confint.hhh4} \alias{residuals.hhh4} %% internal methods without need for documentation %\alias{print.summary.hhh4} %\alias{terms.hhh4} \title{ Print, Summary and other Standard Methods for \code{"hhh4"} Objects } \description{ Besides \code{print} and \code{summary} methods there are also some standard extraction methods defined for objects of class \code{"hhh4"} resulting from a call to \code{\link{hhh4}}. The implementation is illustrated in Meyer et al. (2017, Section 5), see \code{vignette("hhh4_spacetime")}. } \usage{ \method{print}{hhh4}(x, digits = max(3, getOption("digits") - 3), ...) \method{summary}{hhh4}(object, maxEV = FALSE, ...) \method{coef}{hhh4}(object, se = FALSE, reparamPsi = TRUE, idx2Exp = NULL, amplitudeShift = FALSE, ...) \method{fixef}{hhh4}(object, ...) \method{ranef}{hhh4}(object, tomatrix = FALSE, intercept = FALSE, ...) \method{coeflist}{hhh4}(x, ...) \method{formula}{hhh4}(x, ...) \method{nobs}{hhh4}(object, ...) \method{logLik}{hhh4}(object, ...) \method{vcov}{hhh4}(object, reparamPsi = TRUE, idx2Exp = NULL, amplitudeShift = FALSE, ...) \method{confint}{hhh4}(object, parm, level = 0.95, reparamPsi = TRUE, idx2Exp = NULL, amplitudeShift = FALSE, ...) \method{residuals}{hhh4}(object, type = c("deviance", "response"), ...) } \arguments{ \item{x, object}{an object of class \code{"hhh4"}.} \item{digits}{the number of significant digits to use when printing parameter estimates.} \item{maxEV}{logical indicating if the summary should contain the (range of the) dominant eigenvalue as a measure of the importance of the epidemic components. By default, the value is not calculated as this may take some seconds depending on the number of time points and units in \code{object$stsObj}.} \item{\dots}{ For the \code{print}, \code{summary}, \code{fixef}, \code{ranef}, and \code{coeflist} methods: arguments passed to \code{coef}.\cr For the remaining methods: unused (argument of the generic). } \item{reparamPsi}{ logical. If \code{TRUE} (default), the overdispersion parameter from the negative binomial distribution is transformed from internal scale (-log) to standard scale, where zero corresponds to a Poisson distribution. } \item{se}{logical switch indicating if standard errors are required} \item{idx2Exp}{integer vector selecting the parameters which should be returned on exp-scale. Alternatively, \code{idx2Exp = TRUE} will exp-transform all parameters except for those associated with \code{log()} covariates or already affected by \code{reparamPsi} or \code{amplitudeShift}.} \item{amplitudeShift}{logical switch indicating whether the parameters for sine/cosine terms modelling seasonal patterns (see \code{\link{addSeason2formula}}) should be transformed to an amplitude/shift formulation.} \item{tomatrix}{logical. If \code{FALSE} (default), the vector of all random effects is returned (as used internally). However, for random intercepts of \code{type="car"}, the number of parameters is one less than the number of regions and the individual parameters are not obviously linked to specific regions. Setting \code{tomatrix} to \code{TRUE} returns a more useful representation of random effects in a matrix with as many rows as there are regions and as many columns as there are random effects. Here, any CAR-effects are transformed to region-specific effects.} \item{intercept}{logical. If \code{FALSE} (default), the returned random effects represent zero-mean deviations around the corresponding global intercepts of the \emph{log}-linear predictors. Setting \code{intercept=TRUE} adds these global intercepts to the result (and implies \code{tomatrix=TRUE}).} \item{parm}{a vector of numbers or names, specifying which parameters are to be given confidence intervals. If missing, all parameters are considered.} \item{level}{the confidence level required.} \item{type}{the type of residuals which should be returned. The alternatives are \code{"deviance"} (default) and \code{"response"}.} } \value{ The \code{\link{coef}}-method returns all estimated (regression) parameters from a \code{\link{hhh4}} model. If the model includes random effects, those can be extracted with \code{ranef}, whereas \code{fixef} returns the fixed parameters. The \code{coeflist}-method extracts the model coefficients in a list (by parameter group). The \code{\link{formula}}-method returns the formulae used for the three log-linear predictors in a list with elements \code{"ar"}, \code{"ne"}, and \code{"end"}. The \code{\link{nobs}}-method returns the number of observations used for model fitting. The \code{\link{logLik}}-method returns an object of class \code{"logLik"} with \code{"df"} and \code{"nobs"} attributes. For a random effects model, the value of the \emph{penalized} log-likelihood at the MLE is returned, but degrees of freedom are not available (\code{NA_real_}). As a consequence, \code{\link{AIC}} and \code{\link{BIC}} are only well defined for models without random effects; otherwise these functions return \code{NA_real_}. The \code{\link{vcov}}-method returns the estimated variance-covariance matrix of the \emph{regression} parameters. The estimated variance-covariance matrix of random effects is available as \code{object$Sigma}. The \code{\link{confint}}-method returns Wald-type confidence intervals (assuming asymptotic normality). The \code{\link{residuals}}-method extracts raw (\code{"response"}) or scaled (\code{"deviance"}) residuals from the model fit similar to \code{\link{residuals.glm}} for Poisson or NegBin GLM's. } \seealso{ the \code{\link[=plot.hhh4]{plot}} and \code{\link[=update.hhh4]{update}} methods for fitted \code{"hhh4"} models. } \author{ Michaela Paul and Sebastian Meyer } \references{ Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \keyword{methods} \keyword{print} surveillance/man/stsplot.Rd0000644000176200001440000000517614614640226015536 0ustar liggesusers\name{stsplot} \docType{methods} \alias{plot.sts} \alias{plot,sts,missing-method} \alias{plot,stsNC,missing-method} \alias{stsplot} % for convenience \title{Plot Methods for Surveillance Time-Series Objects} \description{ This page gives an overview of plot types for objects of class \code{"sts"}. } \usage{ \S4method{plot}{sts,missing}(x, type = observed ~ time | unit, \dots) } \arguments{ \item{x}{an object of class \code{"\linkS4class{sts}"}.} \item{type}{see Details.} \item{\dots}{arguments passed to the \code{type}-specific plot function.} } \details{ There are various types of plots which can be produced from an \code{"sts"} object. The \code{type} argument specifies the desired plot as a formula, which defaults to \code{observed ~ time | unit}, i.e., plot the time series of each unit separately. Arguments to specific plot functions can be passed as further arguments (\dots). The following list describes the plot variants: \describe{ \item{\code{observed ~ time | unit}}{The default type shows \code{ncol(x)} plots, each containing the time series of one observational unit. The actual plotting per unit is done by the function \code{\link{stsplot_time1}}, called sequentially from \code{\link{stsplot_time}}.\cr A \CRANpkg{ggplot2}-based alternative for this type of plot is provided through an \code{\link[=autoplot.sts]{autoplot}}-method for \code{"sts"} objects. } \item{\code{observed ~ time}}{The observations in \code{x} are first \code{\link[=aggregate.sts]{aggregated}} over units and the resulting univariate time-series is plotted via the function \code{\link{stsplot_time}}.} \item{\code{alarm ~ time}}{Generates a so called alarmplot for a multivariate \code{sts} object. For each time point and each series it is shown whether there is an alarm. In case of hierarchical surveillance the user can pass an additional argument \code{lvl}, which is a vector of the same length as rows in \code{x} specifying for each time series its level. } \item{\code{observed ~ unit}}{ produces a map of counts (or incidence) per region aggregated over time. See \code{\link{stsplot_space}} for optional arguments, details and examples. } } } \value{ \code{NULL} (invisibly). The methods are called for their side-effects. } \seealso{ the documentation of the individual plot types \code{\link{stsplot_time}}, \code{\link{stsplot_space}}, as well as the \code{\link[=animate.sts]{animate}} method. } \keyword{ts} \keyword{spatial} \keyword{hplot} \keyword{methods} surveillance/man/isScalar.Rd0000644000176200001440000000101512143464746015561 0ustar liggesusers\name{isScalar} \alias{isScalar} \title{ Checks if the Argument is Scalar } \description{ The simple helper function \code{isScalar} just checks if its argument is a scalar, i.e. a numeric vector of length 1. It is implemented as \code{length(x) == 1L && is.vector(x, mode = "numeric")}. } \usage{ isScalar(x) } \arguments{ \item{x}{an \code{R} object.} } \value{ A length-one logical vector. } %% \examples{ %% isScalar(TRUE) # FALSE %% isScalar(1:10) # FALSE %% isScalar(pi) # TRUE %% } \keyword{internal} surveillance/man/poly2adjmat.Rd0000644000176200001440000000316014614160257016244 0ustar liggesusers\name{poly2adjmat} \alias{poly2adjmat} \title{ Derive Adjacency Structure of \code{"SpatialPolygons"} } \description{ Wrapping around functionality of the \pkg{spdep} package, this function computes the symmetric, binary (0/1), adjacency matrix from a \code{"\linkSPclass{SpatialPolygons}"} object. It essentially applies \code{\link[spdep]{nb2mat}(\link[spdep]{poly2nb}(SpP, ...), style="B", zero.policy=zero.policy)}. } \usage{ poly2adjmat(SpP, ..., zero.policy = TRUE) } \arguments{ \item{SpP}{an object inheriting from \code{"\linkSPclass{SpatialPolygons}"}.} \item{\dots}{arguments passed to \code{\link[spdep]{poly2nb}}. Its \code{snap} argument might be particularly useful to handle maps with sliver polygons.} \item{zero.policy}{logical indicating if islands are allowed, see \code{\link[spdep]{nb2mat}}.} } \value{ a symmetric numeric indicator matrix of size \code{length(SpP)}^2 representing polygon adjacencies. } \author{ (of this wrapper) Sebastian Meyer } \seealso{ \code{\link[spdep]{poly2nb}} in package \pkg{spdep} } \examples{ if (requireNamespace("spdep")) { ## generate adjacency matrix for districts of Bayern and Baden-Wuerttemberg data("fluBYBW") adjmat <- poly2adjmat(fluBYBW@map) ## same as already stored in the neighbourhood slot (in different order) stopifnot(all.equal(adjmat, neighbourhood(fluBYBW)[rownames(adjmat),colnames(adjmat)])) ## a visual check of the district-specific number of neighbours plot(fluBYBW@map) text(coordinates(fluBYBW@map), labels=rowSums(adjmat==1), font=2, col=2) } } \keyword{spatial} \keyword{graphs} surveillance/man/formatDate.Rd0000644000176200001440000000163614431621313016102 0ustar liggesusers\name{formatDate} \alias{formatDate} \title{ Convert Dates to Character (Including Quarter Strings) } \description{ An extension of \code{\link{format.Date}} with additional formatting strings for quarters. Used by \code{\link{linelist2sts}}. } \usage{ formatDate(x, format) } \arguments{ \item{x}{a \code{"\link{Date}"} object.} \item{format}{ a character string, see \code{\link{strftime}} for possible specifications. Further to these base formats, \code{formatDate} implements: \describe{ \item{\code{"\%Q"}}{the quarter as a numeric} \item{\code{"\%OQ"}}{the quarter as a roman numeral} \item{\code{"\%q"}}{the day within the quarter} } } } \value{ a character vector representing the input date(s) \code{x} following the \code{format} specification. } \seealso{ \code{\link{strftime}} } \examples{ formatDate(as.Date("2021-10-13"), "\%G/\%OQ/\%q") } \keyword{chron} surveillance/man/untie.Rd0000644000176200001440000001075614614160257015153 0ustar liggesusers\name{untie} \alias{untie} \alias{untie.epidataCS} \alias{untie.matrix} \alias{untie.default} \title{ Randomly Break Ties in Data } \description{ This is a generic function intended to randomly break tied data in a way similar to what \code{\link{jitter}} does: tie-breaking is performed by shifting \emph{all} data points by a random amount. The \pkg{surveillance} package defines methods for matrices, \code{"epidataCS"}, and a default method for numeric vectors. } \usage{ untie(x, amount, ...) \method{untie}{epidataCS}(x, amount = list(t=NULL, s=NULL), minsep = list(t=0, s=0), direction = "left", keep.sources = FALSE, ..., verbose = FALSE) \method{untie}{matrix}(x, amount = NULL, minsep = 0, constraint = NULL, giveup = 1000, ...) \method{untie}{default}(x, amount = NULL, minsep = 0, direction = c("symmetric", "left", "right"), sort = NULL, giveup = 1000, ...) } \arguments{ \item{x}{ the data to be untied. } \item{amount}{ upper bound for the random amount by which data are shifted. \code{NULL} means to use a data-driven default, which equals the minimum separation of the data points for the non-symmetric default method and its half for the symmetric default method and the \code{matrix} method. } \item{minsep}{minimum separation of jittered points. Can only be obeyed if much smaller than \code{amount} (also depending on the number of points). \code{minsep>0} is currently only implemented for the spatial (matrix) method.} \item{keep.sources}{ logical (\code{FALSE}). If \code{TRUE}, the original list of possible event sources in \code{x$events$.sources} will be preserved. For instance, events observed at the same time did by definition not trigger each other; however, after random tie-breaking one event will precede the other and considered as a potential source of infection for the latter, although it could just as well be the other way round. Enabling \code{keep.sources} will use the \code{.sources} list from the original (tied) \code{"epidataCS"} object. Note, however, that an update is forced within \code{twinstim} if a subset of the data is selected for model fitting or if a different \code{qmatrix} is supplied. } \item{constraint}{ an object of class \code{"\linkSPclass{SpatialPolygons}"} representing the domain which the points of the matrix should belong to -- before and after jittering. } \item{giveup}{number of attempts after which the algorithm should stop trying to generate new points.} \item{direction}{ one of \code{"symmetric"} (default), \code{"left"}, or \code{"right"}, indicating in which direction vector elements should be shifted. } \item{sort}{ logical indicating if the jittered vector should be sorted. Defaults to doing so if the original vector was already sorted. } \item{\dots}{ For the \code{"epidataCS"}-method: arguments passed to the \code{matrix}- or \code{default}-method (\code{giveup}). Unused in other methods. } \item{verbose}{logical passed to \code{\link{as.epidataCS}}.} } \details{ For numeric vectors (default method), the jittered version is the same as for \code{\link{jitter}(x, amount=amount)}, if \code{direction="symmetric"} (and \code{amount} is non-\code{NULL}), and otherwise uses \code{x} \dQuote{+-} \code{runif(length(x), 0, amount)}. For matrices, a vector uniformly drawn from the disc with radius \code{amount} is added to each point (row). For \code{"epidataCS"}, \code{amount} is a list stating the amounts for the temporal and/or spatial dimension, respectively. It then uses the specific methods with arguments \code{constraint=x$W}, \code{direction}, and \code{sort=TRUE}. Note that this implements a simplistic approach of tie-breaking where all events are assumed to be subject to the same amounts of censoring, and the default amounts may not be sensible choices. } \value{ the untied (jittered) data. } \author{ Sebastian Meyer } \seealso{ \code{\link{jitter}} } \examples{ # vector example set.seed(123) untie(c(rep(1,3), rep(1.2, 4), rep(3,3)), direction="left", sort=FALSE) # spatial example data(imdepi) coords <- coordinates(imdepi$events) table(duplicated(coords)) plot(coords, cex=sqrt(multiplicity(coords))) set.seed(1) coords_untied <- untie(coords) stopifnot(!anyDuplicated(coords_untied)) points(coords_untied, col=2) # shifted by very small amount in this case } \keyword{utilities} \keyword{manip} \keyword{dplot} surveillance/man/algo.rki.Rd0000644000176200001440000001000113165505075015515 0ustar liggesusers\name{algo.rki} \alias{algo.rkiLatestTimepoint} \alias{algo.rki} \alias{algo.rki1} \alias{algo.rki2} \alias{algo.rki3} \encoding{latin1} \title{The system used at the RKI} \description{ Evaluation of timepoints with the detection algorithms used by the RKI } \usage{ algo.rkiLatestTimepoint(disProgObj, timePoint = NULL, control = list(b = 2, w = 4, actY = FALSE)) algo.rki(disProgObj, control = list(range = range, b = 2, w = 4, actY = FALSE)) algo.rki1(disProgObj, control = list(range = range)) algo.rki2(disProgObj, control = list(range = range)) algo.rki3(disProgObj, control = list(range = range)) } \arguments{ \item{disProgObj}{object of class disProg (including the observed and the state chain).} \item{timePoint}{time point which should be evaluated in \code{algo.rkiLatestTimepoint}. The default is to use the latest timepoint.} \item{control}{control object: \code{range} determines the desired timepoints which should be evaluated, \code{b} describes the number of years to go back for the reference values, \code{w} is the half window width for the reference values around the appropriate timepoint and \code{actY} is a boolean to decide if the year of \code{timePoint} also spend \code{w} reference values of the past. As default \code{b}, \code{w}, \code{actY} are set for the RKI 3 system. } } \value{ \code{algo.rkiLatestTimepoint} returns a list of class \code{survRes} (surveillance result), which includes the alarm value (alarm = 1, no alarm = 0) for recognizing an outbreak, the threshold value for recognizing the alarm and the input object of class disProg. \code{algo.rki} gives a list of class \code{survRes} which includes the vector of alarm values for every timepoint in \code{range}, the vector of threshold values for every timepoint in \code{range} for the system specified by \code{b}, \code{w} and \code{actY}, the range and the input object of class disProg. \code{algo.rki1} returns the same for the RKI 1 system, \code{algo.rki2} for the RKI 2 system and \code{algo.rki3} for the RKI 3 system. } \details{ Using the reference values for calculating an upper limit (threshold), alarm is given if the actual value is bigger than a computed threshold. \code{algo.rki} calls \code{algo.rkiLatestTimepoint} for the values specified in \code{range} and for the system specified in \code{control}. \code{algo.rki1} calls \code{algo.rkiLatestTimepoint} for the values specified in \code{range} for the RKI 1 system. \code{algo.rki2} calls \code{algo.rkiLatestTimepoint} for the values specified in \code{range} for the RKI 2 system. \code{algo.rki3} calls \code{algo.rkiLatestTimepoint} for the values specified in \code{range} for the RKI 3 system. \itemize{ \item \code{"RKI 1"} reference values from 6 weeks ago \item \code{"RKI 2"} reference values from 6 weeks ago and 13 weeks of the year ago (symmetrical around the comparable week). \item \code{"RKI 3"} 18 reference values. 9 from the year ago and 9 from two years ago (also symmetrical around the comparable week). } } \seealso{ \code{\link{algo.bayesLatestTimepoint}} and \code{\link{algo.bayes}} for the Bayes system. } \author{M. \enc{Hhle}{Hoehle}, A. Riebler, Christian Lang} \examples{ # Create a test object disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 208, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) # Test week 200 to 208 for outbreaks with a selfdefined rki algo.rki(disProgObj, control = list(range = 200:208, b = 1, w = 5, actY = TRUE)) # The same for rki 1 to rki 3 algo.rki1(disProgObj, control = list(range = 200:208)) algo.rki2(disProgObj, control = list(range = 200:208)) algo.rki3(disProgObj, control = list(range = 200:208)) # Test for rki 1 the latest timepoint algo.rkiLatestTimepoint(disProgObj) } \keyword{classif} surveillance/man/knox.Rd0000644000176200001440000001546214531107643015003 0ustar liggesusers\encoding{latin1} \name{knox} \alias{knox} \alias{plot.knox} \alias{toLatex.knox} \title{ Knox Test for Space-Time Interaction } \description{ Given temporal and spatial distances as well as corresponding critical thresholds defining what \dQuote{close} means, the function \code{knox} performs Knox (1963, 1964) test for space-time interaction. The corresponding p-value can be calculated either by the Poisson approximation or by a Monte Carlo permutation approach (Mantel, 1967) with support for parallel computation via \code{\link{plapply}}. There is a simple \code{plot}-method showing a \code{\link{truehist}} of the simulated null distribution together with the expected and observed values. This implementation of the Knox test is due to Meyer et al. (2016). } \usage{ knox(dt, ds, eps.t, eps.s, simulate.p.value = TRUE, B = 999, ...) \method{plot}{knox}(x, ...) } \arguments{ \item{dt,ds}{ numeric vectors containing temporal and spatial distances, respectively. Logical vectors indicating temporal/spatial closeness may also be supplied, in which case \code{eps.t}/\code{eps.s} is ignored. To test for space-time interaction in a single point pattern of \eqn{n} events, these vectors should be of length \eqn{n*(n-1)/2} and contain the pairwise event distances (e.g., the lower triangle of the distance matrix, such as in \code{"\link{dist}"} objects). Note that there is no special handling of matrix input, i.e., if \code{dt} or \code{ds} are matrices, all elements are used (but a warning is given if a symmetric matrix is detected). } \item{eps.t,eps.s}{ Critical distances defining closeness in time and space, respectively. Distances lower than or equal to the critical distance are considered \dQuote{"close"}. } \item{simulate.p.value}{ logical indicating if a Monte Carlo permutation test should be performed (as per default). Do not forget to set the \code{\link{.Random.seed}} via an extra \code{.seed} argument if reproducibility is required (see the \dots arguments below). If \code{simulate.p.value = FALSE}, the Poisson approximation is used (but see the note below). } \item{B}{ number of permutations for the Monte Carlo approach. } \item{\dots}{ arguments configuring \code{\link{plapply}}: \code{.parallel}, \code{.seed}, and \code{.verbose}. By default, no parallelization is performed (\code{.parallel = 1}), and a progress bar is shown (\code{.verbose = TRUE}).\cr For the \code{plot}-method, further arguments passed to \code{\link{truehist}}. } \item{x}{ an object of class \code{"knox"} as returned by the \code{knox} test. } } \note{ The Poisson approximation works well if the proportions of close pairs in both time and space are small (Kulldorff and Hjalmars, 1999), otherwise the Monte Carlo permutation approach is recommended. } \value{ an object of class \code{"knox"} (inheriting from \code{"htest"}), which is a list with the following components: \item{method}{a character string indicating the type of test performed, and whether the Poisson approximation or Monte Carlo simulation was used.} \item{data.name}{a character string giving the supplied \code{dt} and \code{ds} arguments.} \item{statistic}{the number of close pairs.} \item{parameter}{if \code{simulate.p.value = TRUE}, the number \code{B} of permutations, otherwise the \code{lambda} parameter of the Poisson distribution, i.e., the same as \code{null.value}.} \item{p.value}{the p-value for the test. In case \code{simulate.p.value = TRUE}, the p-value from the Poisson approximation is still attached as an attribute \code{"Poisson"}.} \item{alternative}{the character string \code{"greater"} (this is a one-sided test).} \item{null.value}{the expected number of close pairs in the absence of space-time interaction.} \item{table}{the contingency table of \code{dt <= eps.t} and \code{ds <= eps.s}.} The \code{plot}-method invisibly returns \code{NULL}. A \code{toLatex}-method exists, which generates LaTeX code for the contingency table associated with the Knox test. } \author{ Sebastian Meyer } \seealso{ The function \code{mantel.randtest} in package \pkg{ade4} implements Mantel's (1967) space-time interaction test, i.e., using the Pearson correlation between the spatial and temporal distances of all event pairs as the test statistic, and assessing statistical significance using a Monte Carlo permutation approach as with \code{simulate.p.value} here in the \code{knox} function. To combine information from different scales \code{eps.t} and \code{eps.s} while also handling edge effects, the space-time K-function test available via \code{\link{stKtest}} can be used. Function \code{\link{epitest}} tests epidemicity in a \code{"\link{twinstim}"} point process model. } \references{ Knox, G. (1963): Detection of low intensity epidemicity: application to cleft lip and palate. \emph{British Journal of Preventive & Social Medicine}, \bold{17}, 121-127. Knox, E. G. (1964): The detection of space-time interactions. \emph{Journal of the Royal Statistical Society. Series C (Applied Statistics)}, \bold{13}, 25-30. Kulldorff, M. and Hjalmars, U. (1999): The Knox method and other tests for space-time interaction. \emph{Biometrics}, \bold{55}, 544-552. Mantel, N. (1967): The detection of disease clustering and a generalized regression approach. \emph{Cancer Research}, \bold{27}, 209-220. Meyer, S., Warnke, I., R\enc{}{oe}ssler, W. and Held, L. (2016): Model-based testing for space-time interaction using point processes: An application to psychiatric hospital admissions in an urban area. \emph{Spatial and Spatio-temporal Epidemiology}, \bold{17}, 15-25. \doi{10.1016/j.sste.2016.03.002}. Eprint: \url{https://arxiv.org/abs/1512.09052}. } \examples{ data("imdepi") imdepiB <- subset(imdepi, type == "B") ## Perfom the Knox test using the Poisson approximation knoxtest <- knox( dt = dist(imdepiB$events$time), eps.t = 30, ds = dist(coordinates(imdepiB$events)), eps.s = 50, simulate.p.value = FALSE ) knoxtest ## The Poisson approximation works well for these data since ## the proportion of close pairs is rather small (204/56280). \dontshow{.opt <- options(xtable.comment = FALSE)} ## contingency table in LaTeX toLatex(knoxtest) \dontshow{options(.opt)} ## Obtain the p-value via a Monte Carlo permutation test, ## where the permutations can be computed in parallel ## (using forking on Unix-alikes and a cluster on Windows, see ?plapply) knoxtestMC <- knox( dt = dist(imdepiB$events$time), eps.t = 30, ds = dist(coordinates(imdepiB$events)), eps.s = 50, simulate.p.value = TRUE, B = 99, # limited here for speed .parallel = 2, .seed = 1, .verbose = FALSE ) knoxtestMC plot(knoxtestMC) } \keyword{htest} surveillance/man/estimateGLRNbHook.Rd0000644000176200001440000000131013122471774017274 0ustar liggesusers\name{estimateGLRNbHook} \alias{estimateGLRNbHook} \encoding{latin1} \title{Hook function for in-control mean estimation} \description{ Estimation routine for the in-control mean of \code{\link{algo.glrpois}}. In \R < 2.14.0 and \pkg{surveillance} < 1.4 (i.e., without a package namespace) users could customize this function simply by defining a modified version in their workspace. This is no longer supported. } \usage{ estimateGLRNbHook() } \value{ A list with elements \item{\code{mod}}{resulting model of a call of \code{glm.nb}} \item{\code{range}}{vector of length as \code{range} containing the predicted values} } \seealso{ \code{\link{algo.glrnb}} } \author{M. Hoehle} \keyword{internal} surveillance/man/hhh4_internals.Rd0000644000176200001440000000352314273167411016733 0ustar liggesusers\name{hhh4_internals} \alias{meanHHH} \alias{sizeHHH} \alias{decompose.hhh4} \title{ Internal Functions Dealing with \code{hhh4} Models } \description{ The functions documented here are considered \emph{internal}, i.e., not intended to be called by the user. They are used by add-on packages dealing with \code{\link{hhh4}} models. } \usage{ meanHHH(theta, model, subset = model$subset, total.only = FALSE) sizeHHH(theta, model, subset = model$subset) decompose.hhh4(x, coefs = x$coefficients, ...) } \arguments{ \item{theta,coefs}{numeric vector of \emph{untransformed} model parameters, i.e., the \code{coefficients} element of the \code{"hhh4"} object.} \item{model}{the model terms as returned by the \code{\link{terms}}-method for \code{"hhh4"} objects.} \item{subset}{vector of time points for which to compute the component means. Defaults to the fitted time range. For \code{sizeHHH}, \code{subset=NULL} means to return the vector of dispersion parameters.} \item{total.only}{logical. Should only the total mean (epidemic + endemic) be returned in a \code{length(subset)} x nUnit matrix? Otherwise, a list of such matrices is returned, giving the values of the various model components separately (as well as the total).} \item{x}{a fitted \code{hhh4} model.} \item{\dots}{unused.} } \details{ \code{meanHHH} computes the components of the mean returned in \code{length(subset)} x nUnit matrices. \code{sizeHHH} computes the model dispersion in \code{\link{dnbinom}} (\code{mu}, \code{size}) parametrization (it returns \code{NULL} in the Poisson case). \code{decompose.hhh4} decomposes the fitted mean (extracted via \code{meanHHH}) in an array with dimensions \eqn{(t, i, j)}, where the first \eqn{j} index is \code{"endemic"}. } \author{ Michaela Paul and Sebastian Meyer } \keyword{internal} surveillance/man/sts_tidy.Rd0000644000176200001440000000204313751225541015656 0ustar liggesusers\name{tidy.sts} \alias{tidy.sts} \title{ Convert an \code{"sts"} Object to a Data Frame in Long (Tidy) Format } \description{ The resulting data frame will have a row for each time point and observational unit, and columns corresponding to the slots of the \code{"\linkS4class{sts}"} object (except for \code{populationFrac}, which is named \code{population}). Some time variables are added for convenience: \code{year}, \code{epochInYear}, \code{epochInPeriod}, \code{date} (the latter gives \code{NA} dates if \code{epoch(x, as.Date=TRUE)} fails, i.e., for non-standard \code{x@freq} if not \code{x@epochAsDate}). } \usage{ tidy.sts(x, ...) } \arguments{ \item{x}{an object of class \code{"\linkS4class{sts}"}.} \item{\dots}{unused.} } \author{ Sebastian Meyer } \seealso{ \code{\link{as.data.frame.sts}} } \examples{ data("momo") momodat <- tidy.sts(momo) head(momodat) ## tidy.sts(stsObj) is the same as as.data.frame(stsObj, tidy = TRUE) stopifnot(identical(as.data.frame(momo, tidy = TRUE), momodat)) } \keyword{manip} surveillance/man/anscombe.residuals.Rd0000644000176200001440000000101512665561746017610 0ustar liggesusers\name{anscombe.residuals} \alias{anscombe.residuals} \title{Compute Anscombe Residuals} \description{ Compute Anscombe residuals from a fitted \code{\link{glm}}, which makes them approximately standard normal distributed. } \usage{ anscombe.residuals(m, phi) } \arguments{ \item{m}{a fitted \code{"glm"}} \item{phi}{the current estimated overdispersion} } \value{The standardized Anscombe residuals of \code{m}} \references{McCullagh & Nelder, Generalized Linear Models, 1989} \keyword{regression} surveillance/man/surveillance-defunct.Rd0000644000176200001440000000724214607740561020151 0ustar liggesusers\name{surveillance-defunct} \alias{surveillance-defunct} \title{Defunct Functions in Package \pkg{surveillance}} \alias{compMatrix.writeTable} \alias{correct53to52} \alias{enlargeData} \alias{makePlot} \alias{readData} \alias{test} \alias{testSim} \alias{toFileDisProg} \alias{algo.hhh} \alias{algo.hhh.grid} \alias{create.grid} \alias{qlomax} \alias{inside.gpc.poly} \alias{intersectPolyCircle.gpc.poly} \alias{scale.gpc.poly} \description{ The functions listed here are no longer part of \pkg{surveillance}. } \usage{ ## Removed in surveillance 1.17.0 compMatrix.writeTable(compMatrix) correct53to52(disProgObj, firstweek = 1) enlargeData(disProgObj, range = 1:156, times = 1) makePlot(outputpath, data = "k1", method = "rki1", name, disease, range = 157:339) readData(abb, week53to52=TRUE, sysPath=TRUE) test(data = c("k1", "m5"), range = 157:339) testSim(p = 0.99, r = 0.01, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K, range = 200:400) toFileDisProg(disProgObj, toFile) ## Removed in surveillance 1.18.0 algo.hhh(disProgObj, control=list( lambda=TRUE, neighbours=FALSE, linear=FALSE, nseason=0, negbin=c("none", "single", "multiple"), proportion=c("none", "single", "multiple"), lag.range=NULL ), thetastart=NULL, verbose=TRUE) algo.hhh.grid(disProgObj, control=list( lambda=TRUE, neighbours=FALSE, linear=FALSE, nseason=0, negbin=c("none", "single", "multiple"), proportion=c("none", "single", "multiple"), lag.range=NULL ), thetastartMatrix, maxTime=1800, verbose=FALSE) create.grid(disProgObj, control, params=list( epidemic=c(0.1, 0.9, 5), endemic=c(-0.5, 0.5, 3), negbin=c(0.3, 12, 10) )) ## Removed in surveillance 1.20.0 qlomax(p, scale, shape) ## Removed in surveillance 1.22.0 inside.gpc.poly(x, y = NULL, polyregion, mode.checked = FALSE) \method{intersectPolyCircle}{gpc.poly}(object, center, radius, npoly = 32, useGEOS = FALSE, ...) \method{scale}{gpc.poly}(x, center = c(0,0), scale = c(1,1)) } \details{ The trivial function \code{compMatrix.writeTable} is no longer used (it did nothing more than generating an \code{\link[xtable]{xtable}} of its input). The ancient test function \code{makePlot} is no longer used, nor are functions \code{readData} (the datasets are still available via \code{data(\link{m1})} etc) and \code{correct53to52} / \code{enlargeData} (which both only worked for old \code{"disProg"} objects with non-matrix elements). \code{enlargeData} is still exemplified in the old \code{vignette("surveillance")}. \code{test} calls of outbreak detection algorithms applied to the old SurvStat datasets can be found in \code{vignette("surveillance")}, and \code{testSim} is provided as an example in \code{help("\link{sim.pointSource}")}. Functions related to the old \code{"\link[=create.disProg]{disProg}"} class are no longer needed. The effect of \code{toFileDisProg} could still be achieved via \code{\link{write.table}} of \code{as.data.frame(disProg2sts(disProgObj))[c("epoch", "observed", "state")]}. \code{algo.hhh} was an early implementation of the HHH regression framework for multivariate time series of infectious disease counts. An improved and considerably extended implementation is provided by the \code{\link{hhh4}} function since 2012. A \code{qlomax} function is provided in package \pkg{VGAM}. Long unused methods for \code{"gpc.poly"} objects have been removed; the corresponding package \pkg{gpclib} has been unmaintained on CRAN. } \seealso{ \code{\link{Defunct}} } \keyword{internal} surveillance/man/twinSIR_profile.Rd0000644000176200001440000000453213433452530017075 0ustar liggesusers\encoding{latin1} \name{twinSIR_profile} \alias{profile.twinSIR} \alias{plot.profile.twinSIR} \title{ Profile Likelihood Computation and Confidence Intervals } \description{ Function to compute estimated and profile likelihood based confidence intervals. Computations might be cumbersome! There is a simple \code{plot}-method for the result. } \usage{ \method{profile}{twinSIR}(fitted, profile, alpha = 0.05, control = list(fnscale = -1, factr = 10, maxit = 100), ...) } \arguments{ \item{fitted}{ an object of class \code{"twinSIR"}. } \item{profile}{ a list with elements being numeric vectors of length 4. These vectors must have the form \code{c(index, lower, upper, gridsize)}. \describe{ \item{\code{index}:}{ index of the parameter to be profiled in the vector \code{coef(fitted)}. } \item{\code{lower, upper}:}{ lower/upper limit of the grid on which the profile log-likelihood is evaluated. Can also be \code{NA} in which case \code{lower/upper} equals the lower/upper bound of the respective 0.3 \% Wald confidence interval (+-3*se). } \item{\code{gridsize}:}{ grid size of the equally spaced grid between lower and upper. Can also be 0 in which case the profile log-likelihood for this parameter is not evaluated on a grid. } } } \item{alpha}{ \eqn{(1-\alpha) 100\%}{(1-alpha)*100\%} profile likelihood based confidence intervals are computed. If \code{alpha <= 0}, then no confidence intervals are computed. } \item{control}{ control object to use in \code{\link{optim}} for the profile log-likelihood computations. } \item{\dots}{ unused (argument of the generic). } } \value{ a list with profile log-likelihood evaluations on the grid and highest likelihood and Wald confidence intervals. The argument \code{profile} is also returned. The result has class \code{"profile.twinSIR"}, for which a simple (undocumented) \code{plot}-method is available. } \author{ Michael \enc{Hhle}{Hoehle} and Sebastian Meyer } \examples{ data("hagelloch") fit <- twinSIR(~ household, data = hagelloch) gridsize <- if (interactive()) 35 else 5 # for fast tests prof <- profile(fit, list(c(1, NA, NA, gridsize))) prof$ci.hl plot(prof) } \keyword{htest} \keyword{methods} \keyword{optimize} \keyword{dplot} surveillance/man/refvalIdxByDate.Rd0000644000176200001440000000211513122471774017034 0ustar liggesusers\name{refvalIdxByDate} \alias{refvalIdxByDate} \title{Compute indices of reference value using Date class} \description{ The reference values are formed based on computations of \code{seq} for Date class arguments. } \usage{ refvalIdxByDate(t0, b, w, epochStr, epochs) } \arguments{ \item{t0}{A Date object describing the time point} \item{b}{Number of years to go back in time} \item{w}{Half width of window to include reference values for} \item{epochStr}{One of \code{"1 month"}, \code{"1 week"} or \code{"1 day"}} \item{epochs}{Vector containing the epoch value of the sts/disProg object} } \details{ Using the Date class the reference values are formed as follows: Starting from \code{t0} go i, i= 1,...,\code{b} years back in time. For each year, go \code{w} epochs back and include from here to \code{w} epochs after \code{t0}. In case of weeks we always go back to the closest Monday of this date. In case of months we also go back in time to closest 1st of month. } \value{ a vector of indices in epochs which match } \keyword{chron} surveillance/man/linelist2sts.Rd0000644000176200001440000000722413430572401016453 0ustar liggesusers\encoding{latin1} \name{linelist2sts} \alias{linelist2sts} \title{ Convert Dates of Individual Case Reports into a Time Series of Counts } \description{ The function is used to convert an individual line list of cases to an aggregated time series of counts based on event date information of the cases. } \usage{ linelist2sts(linelist,dateCol, aggregate.by=c("1 day", "1 week", "7 day", "1 week", "1 month", "3 month", "1 year"), dRange=NULL, epochInPeriodStr=switch(aggregate.by, "1 day"="1", "1 week"="\%u", "1 month"="\%d","3 month"="\%q","1 year"="\%j"), startYearFormat=switch(aggregate.by,"1 day"="\%Y", "7 day"="\%G", "1 week"="\%G","1 month"="\%Y","3 month"="\%Y","1 year"="\%Y"), startEpochFormat=switch(aggregate.by,"1 day"="\%j", "7 day"="\%V", "1 week"="\%V", "1 month"="\%m", "3 month"="\%Q", "1 year"="1") ) } \arguments{ \item{linelist}{ A \code{data.frame} containing the line list of cases. } \item{dateCol}{A character string stating the column name in \code{linelist} which contains the event occurrence information (as a vector of \code{Date}s) which are to be temporally aggregated. } \item{aggregate.by}{Temporal aggregation level given as a string, see the \code{by} variable of the \code{\link{seq.Date}} function for further details. } \item{dRange}{A vector containing the minimum and maximum date for doing the aggregation. If not specified these dates are extracted automatically by taking \code{range(D[,dateCol])} and adjust these according to \code{aggregate.by} (e.g. always first of a month). } \item{epochInPeriodStr}{\code{strptime} compatible format string to use for determining how a date is placed within the epoch. This is, e.g., used to move the \code{dRange} epochs to the beginning of the period. Example: In case of weekly aggregation the "\%u" determines which day within the week (Monday is day 1) we have. See \code{\link{strptime}} for further details. } \item{startYearFormat}{\code{strptime} compatible format string to use for determining how the \code{start} entry of the \code{sts} object is generated. Usually the provided defaults are sufficient.} \item{startEpochFormat}{\code{strptime} compatible format string to use for determining how the \code{start} entry of the \code{sts} object is generated. Usually the provided defaults are sufficient.} } \details{ The date range is automatically extended such that the starting and ending dates are always the first epoch within the period, i.e. for aggregation by week it is moved to Mondays. This is controlled by the \code{epochInPeriodStr} parameter. Please note that the formatting strings are implemented by the \code{\link{formatDate}} function, which uses \code{\link{strptime}} formatting strings as well as formatting of quarters via "\%Q", "\%OQ" and "\%q". } \value{ The function returns an object of class \code{"\linkS4class{sts}"}. The \code{freq} slot might not be appropriate. } \author{ Michael \enc{Hhle}{Hoehle} } \seealso{ \code{\link{seq.Date}}, \code{\link{strptime}}, \code{\link{formatDate}} } \examples{ #Load O104 outbreak data data("husO104Hosp") #Convert line list to an sts object sts <- linelist2sts(husO104Hosp, dateCol="dHosp", aggregate.by="1 day") #Check that the number of cases is correct all.equal(sum(observed(sts)),nrow(husO104Hosp)) #Plot the result plot(sts,xaxis.tickFreq=list("\%d"=atChange,"\%m"=atChange), xaxis.labelFreq=list("\%d"=at2ndChange), xaxis.labelFormat="\%d \%b", xlab="",las=2,cex.axis=0.8) } \keyword{models} \keyword{optimize} surveillance/man/bodaDelay.Rd0000644000176200001440000001510613433744455015713 0ustar liggesusers\encoding{latin1} \name{bodaDelay} \alias{bodaDelay} \title{Bayesian Outbreak Detection in the Presence of Reporting Delays} \usage{ bodaDelay(sts, control = list( range = NULL, b = 5, w = 3, mc.munu = 100, mc.y = 10, pastAberrations = TRUE, verbose = FALSE, alpha = 0.05, trend = TRUE, limit54 = c(5,4), inferenceMethod = c("asym","INLA"), quantileMethod = c("MC","MM"), noPeriods = 1, pastWeeksNotIncluded = NULL, delay = FALSE)) } \arguments{ \item{sts}{sts-object to be analysed. Needs to have a reporting triangle.} \item{control}{list of control arguments: \describe{ \item{\code{b}}{How many years back in time to include when forming the base counts.} \item{\code{w}}{Window's half-size, i.e. number of weeks to include before and after the current week in each year.} \item{\code{range}}{Specifies the index of all timepoints which should be tested. If range is \code{NULL} all possible timepoints are used.} \item{\code{pastAberrations}}{Boolean indicating whether to include an effect for past outbreaks in a second fit of the model. This option only makes sense if \code{inferenceMethod} is \code{INLA}, as it is not supported by the other inference method.} \item{\code{verbose}}{Boolean specifying whether to show extra debugging information.} \item{\code{alpha}}{An approximate (one-sided) \eqn{(1-\alpha)\cdot 100\%} prediction interval is calculated unlike the original method where it was a two-sided interval. The upper limit of this interval i.e. the \eqn{(1-\alpha)\cdot 100\%} quantile serves as an upperbound.} \item{\code{trend}}{Boolean indicating whether a trend should be included} \item{\code{noPeriods}}{Number of levels in the factor allowing to use more baseline. If equal to 1 no factor variable is created, the set of reference values is defined as in Farrington et al (1996).} \item{\code{inferenceMethod}}{Which inference method used, as defined in Salmon et al. (2015). If one chooses \code{"INLA"} then inference is performed with INLA. If one chooses \code{"asym"} (default) then the asymptotic normal approximation of the posteriori is used.} \item{\code{pastWeeksNotIncluded}}{Number of past weeks to ignore in the calculation. The default (\code{NULL}) means to use the value of \code{control$w}.} \item{\code{delay}}{Boolean indicating whether to take reporting delays into account.} \item{\code{mc.munu}}{Number of samples for the parameters of the negative binomial distribution for calculating a threshold} \item{\code{mc.y}}{Number of samples for observations when performing Monte Carlo to calculate a threshold} \item{\code{limit54}}{c(cases,period) is a vector allowing the user to change these numbers.} \item{\code{quantileMethod}}{Character, either \code{"MC"} (default) or \code{"MM"}. Indicates how to compute the quantile based on the posterior distribution (no matter the inference method): either by sampling \code{mc.munu} values from the posterior distribution of the parameters and then for each sampled parameters vector sampling \code{mc.y} response values so that one gets a vector of response values based on which one computes an empirical quantile (MC method, as explained in Salmon et al. 2015); or by sampling \code{mc.munu} from the posterior distribution of the parameters and then compute the quantile of the mixture distribution using bisectioning, which is faster.} } } } \description{ The function takes \code{range} values of the surveillance time series \code{sts} and for each time point uses a Bayesian model of the negative binomial family with log link inspired by the work of Noufaily et al. (2012) and of Manitz and \enc{Hhle}{Hoehle} (2014). It allows delay-corrected aberration detection as explained in Salmon et al. (2015). A \code{reportingTriangle} has to be provided in the \code{control} slot. } \examples{ \dontrun{ data("stsNewport") salm.Normal <- list() salmDelayAsym <- list() for (week in 43:45){ listWeeks <- as.Date(row.names(stsNewport@control$reportingTriangle$n)) dateObs <- listWeeks[isoWeekYear(listWeeks)$ISOYear==2011 & isoWeekYear(listWeeks)$ISOWeek==week] stsC <- sts_observation(stsNewport, dateObservation=dateObs, cut=TRUE) inWeeks <- with(isoWeekYear(epoch(stsC)), ISOYear == 2011 & ISOWeek >= 40 & ISOWeek <= 48) rangeTest <- which(inWeeks) alpha <- 0.07 # Control slot for Noufaily method controlNoufaily <- list(range=rangeTest,noPeriods=10, b=4,w=3,weightsThreshold=2.58,pastWeeksNotIncluded=26, pThresholdTrend=1,thresholdMethod="nbPlugin",alpha=alpha*2, limit54=c(0,50)) # Control slot for the Proposed algorithm with D=0 correction controlNormal <- list(range = rangeTest, b = 4, w = 3, reweight = TRUE, mc.munu=10000, mc.y=100, verbose = FALSE, alpha = alpha, trend = TRUE, limit54=c(0,50), noPeriods = 10, pastWeeksNotIncluded = 26, delay=FALSE) # Control slot for the Proposed algorithm with D=10 correction controlDelayNorm <- list(range = rangeTest, b = 4, w = 3, reweight = FALSE, mc.munu=10000, mc.y=100, verbose = FALSE, alpha = alpha, trend = TRUE, limit54=c(0,50), noPeriods = 10, pastWeeksNotIncluded = 26, delay=TRUE,inferenceMethod="asym") set.seed(1) salm.Normal[[week]] <- farringtonFlexible(stsC, controlNoufaily) salmDelayAsym[[week]] <- bodaDelay(stsC, controlDelayNorm) } opar <- par(mfrow=c(2,3)) lapply(salmDelayAsym[c(43,44,45)],plot, legend=NULL, main="", ylim=c(0,35)) lapply(salm.Normal[c(43,44,45)],plot, legend=NULL, main="", ylim=c(0,35)) par(opar) } } \references{ Farrington, C.P., Andrews, N.J, Beale A.D. and Catchpole, M.A. (1996): A statistical algorithm for the early detection of outbreaks of infectious disease. J. R. Statist. Soc. A, 159, 547-563. Noufaily, A., Enki, D.G., Farrington, C.P., Garthwaite, P., Andrews, N.J., Charlett, A. (2012): An improved algorithm for outbreak detection in multiple surveillance systems. Statistics in Medicine, 32 (7), 1206-1222. Salmon, M., Schumacher, D., Stark, K., \enc{Hhle}{Hoehle}, M. (2015): Bayesian outbreak detection in the presence of reporting delays. Biometrical Journal, 57 (6), 1051-1067. } surveillance/man/MMRcoverageDE.Rd0000644000176200001440000000361213122471774016402 0ustar liggesusers\name{MMRcoverageDE} \alias{MMRcoverageDE} \docType{data} \title{MMR coverage levels in the 16 states of Germany} \description{ Coverage levels at school entry for the first and second dose of the combined measles-mumps-rubella (MMR) vaccine in 2006, estimated from children presenting vaccination documents at school entry examinations. } \usage{data(MMRcoverageDE)} \format{ A \code{data.frame} containing 19 rows and 5 columns with variables \describe{ \item{state}{Names of states: the 16 federal states are followed by the total of Germany, as well as the total of West and East Germany.} \item{nOfexaminedChildren}{Number of children examined.} \item{withVaccDocument}{Percentage of children who presented vaccination documents.} \item{MMR1}{Percentage of children with vaccination documents, who received at least 1 dose of MMR vaccine.} \item{MMR2}{Percentage of children with vaccination documents, who received at least 2 doses of MMR vaccine.} } Coverage levels were derived from vaccination documents presented at medical examinations, which are conducted by local health authorities at school entry each year. Records include information about the receipt of 1st and 2nd doses of MMR, but no information about dates. Note that information from children who did not present a vaccination document on the day of the medical examination, is not included in the estimated coverage. } \source{ Robert Koch-Institut (2008) Zu den Impfquoten bei den Schuleingangsuntersuchungen in Deutschland 2006. Epidemiologisches Bulletin, \bold{7}, 55-57 } \seealso{\code{\link{measlesDE}}} \references{ Herzog, S.A., Paul, M. and Held, L. (2011) Heterogeneity in vaccination coverage explains the size and occurrence of measles epidemics in German surveillance data. Epidemiology and Infection, \bold{139}, 505--515. } \keyword{datasets} surveillance/man/intersectPolyCircle.Rd0000644000176200001440000000266214614717045020015 0ustar liggesusers\name{intersectPolyCircle} \alias{intersectPolyCircle} \alias{intersectPolyCircle.owin} %\alias{intersectPolyCircle.SpatialPolygons} # defunct in surveillance 1.22.0 \title{ Intersection of a Polygonal and a Circular Domain } \description{ This is a unifying wrapper around functionality of various packages dealing with spatial data. It computes the intersection of a circular domain and a polygonal domain (whose class defines the specific method). Currently the only supported class is \code{"\link[spatstat.geom]{owin}"} from package \CRANpkg{spatstat.geom}. } \usage{ intersectPolyCircle(object, center, radius, ...) \method{intersectPolyCircle}{owin}(object, center, radius, npoly = 32, ...) %\method{intersectPolyCircle}{SpatialPolygons}(object, center, radius, npoly = 32, ...) } \arguments{ \item{object}{a polygonal domain of one of the supported classes.} \item{center,radius,npoly}{see \code{\link{discpoly}}.} \item{\dots}{potential further arguments (from the generic).} } \value{ a polygonal domain of the same class as the input \code{object}. } \author{ Sebastian Meyer } \seealso{ \code{\link{discpoly}} to generate a polygonal approximation to a disc } \examples{ letterR <- surveillance:::LETTERR # an "owin" (internally used for checks) plot(letterR, axes = TRUE) plot(intersectPolyCircle(letterR, center = c(-1, 2), radius = 2), add = TRUE, col = 4, lwd = 3) } \keyword{spatial} \keyword{manip} surveillance/man/sts-class.Rd0000644000176200001440000003061514614160257015737 0ustar liggesusers\name{sts-class} \docType{class} \alias{sts} \alias{sts-class} % methods to access and replace slots \alias{alarms,sts-method} \alias{alarms<-,sts-method} \alias{upperbound,sts-method} \alias{upperbound<-,sts-method} \alias{control,sts-method} \alias{control<-,sts-method} \alias{epoch,sts-method} \alias{epoch<-,sts-method} \alias{observed,sts-method} \alias{observed<-,sts-method} \alias{population,sts-method} \alias{population<-,sts-method} \alias{multinomialTS,sts-method} \alias{multinomialTS<-,sts-method} \alias{neighbourhood,sts-method} \alias{neighbourhood<-,sts-method} % other access methods \alias{dim,sts-method} \alias{dimnames,sts-method} \alias{year} \alias{year,sts-method} \alias{epochInYear} \alias{epochInYear,sts-method} % conversion methods \alias{as.data.frame.sts} \alias{as.data.frame,sts-method} \alias{as.ts.sts} \alias{coerce,sts,ts-method} \alias{coerce,ts,sts-method} \alias{as.xts.sts} \encoding{latin1} \title{Class \code{"sts"} -- surveillance time series} \description{ This is a lightweight S4 class to implement (multivariate) time series of counts, typically from public health surveillance. The \code{"sts"} class supersedes the informal \code{"disProg"} class used in early versions of package \pkg{surveillance}. Converters are available, see \code{\link{disProg2sts}}. For areal time series, the class can also capture the spatial layout of the regions, where the data originate from. The constructor function \code{sts} can be used to setup an \code{"sts"} object. Conversion of simple time-series objects (of class \code{"\link{ts}"}) is also possible. The slots of the \code{"sts"} class and available methods are described below. } \usage{ sts(observed, start = c(2000, 1), frequency = 52, epoch = NULL, population = NULL, ...) } \arguments{ \item{observed}{a vector (for a single time series) or matrix (one time series per column) of counts. A purely numeric data frame will also do (transformed via \code{as.matrix}). This argument sets the \code{observed} slot, which is the core element of the resulting \code{"sts"} object. It determines the dimensions and colnames for several other slots. The columns (\dQuote{units}) typically correspond to different regions, diseases, or age groups.} \item{start,frequency}{basic characteristics of the time series data just like for simple \code{"\link{ts}"} objects. The (historical) default values correspond to weekly data starting in the first week of 2000. The \code{epoch} and \code{epochInYear} methods use the ISO 8601 specification when converting between week numbers and dates, see \code{\link{isoWeekYear}}.} \item{epoch}{observation times, either as an integer sequence (default) or as a \code{Date} vector (in which case \code{epochAsDate} is automatically set to \code{TRUE}).} \item{population}{a vector of length the number of columns in \code{observed} or a matrix of the same dimension as \code{observed}. Especially for multivariate time series, the population numbers (or fractions) underlying the counts in each unit are relevant for visualization and statistical inference. The \code{population} argument is an alias for the corresponding slot \code{populationFrac}. The default \code{NULL} value sets equal population fractions across all units.} \item{\dots}{further named arguments with names corresponding to slot names (see the list below). For instance, in the public health surveillance context, the \code{state} slot is used to indicate outbreaks (default: \code{FALSE} for all observations). For areal time series data, the \code{map} and \code{neighbourhood} slots are used to store the spatial structure of the observation region.} } \section{Slots}{ \describe{ \item{\code{epoch}:}{a numeric vector specifying the time of observation, typically a week index. Depending on the \code{freq} slot, it could also index days or months. Furthermore, if \code{epochAsDate=TRUE} then \code{epoch} is the integer representation of \code{\link{Date}}s giving the exact date of the observation.} \item{\code{freq}:}{number of observations per year, e.g., 52 for weekly data, 12 for monthly data.} \item{\code{start}:}{vector of length two denoting the year and the sample number (week, month, etc.) of the first observation.} \item{\code{observed}:}{matrix of size \code{length(epoch)} times the number of regions containing the weekly/monthly number of counts in each region. The colnames of the matrix should match the ID values of the shapes in the \code{map} slot.} \item{\code{state}:}{matrix with the same dimensions as \code{observed} containing Booleans whether at the specific time point there was an outbreak in the region.} \item{\code{alarm}:}{matrix with the same dimensions as \code{observed} specifying whether an outbreak detection algorithm declared a specific time point in the region as having an alarm.} \item{\code{upperbound}:}{matrix with upper-bound values.} \item{\code{neighbourhood}:}{symmetric matrix of size \eqn{(number of regions)^2} describing the neighbourhood structure. It may either be a binary adjacency matrix or contain neighbourhood orders (see the Examples for how to infer the latter from the \code{map}).} \item{\code{populationFrac}:}{\code{matrix} of population fractions or absolute numbers (see \code{multinomialTS} below) with dimensions \code{dim(observed)}.} \item{\code{map}:}{object of class \code{"\linkSPclass{SpatialPolygons}"} (or \code{"\linkSPclass{SpatialPolygonsDataFrame}"}) providing a shape of the areas which are monitored.} \item{\code{control}:}{\code{\link{list}} of settings; this is a rather free data type to be returned by the surveillance algorithms.} \item{\code{epochAsDate}:}{a Boolean indicating if the \code{epoch} slot corresponds to \code{Date}s.} \item{\code{multinomialTS}:}{a Boolean stating whether to interpret the object as \code{observed} out of \code{population}, i.e. a multinomial interpretation instead of a count interpretation.} } } \section{Methods}{ \subsection{Extraction of slots}{ There is an extraction (and replacement) method for almost every slot. The name of the method corresponds to the slot name, with two exceptions: the \code{populationFrac} slot is addressed by a \code{population} method, and the \code{alarm} slot is addressed by an \code{alarms} method. \describe{ \item{epoch}{\code{signature(x = "sts")}: extract the \code{epoch} slot. If the \code{sts} object is indexed by dates (\code{epochAsDate} = TRUE), the returned vector is of class \code{Date}, otherwise numeric (usually the integer sequence \code{1:nrow(x)}).\cr By explicitly requesting \code{epoch(x, as.Date = TRUE)}, dates can also be extracted if the \code{sts} object is not internally indexed by dates but has a standard frequency of 12 (monthly) or 52 (weekly). The transformation is based on \code{start} and \code{freq} and will return the first day of each month (\code{freq=12}) and the Monday of each week (\code{freq=52}), respectively.} \item{observed}{\code{signature(x = "sts")}: extract the \code{observed} slot.} \item{alarms}{\code{signature(x = "sts")}: extract the \code{alarm} slot.} \item{upperbound}{\code{signature(x = "sts")}: extract the \code{upperbound} slot.} \item{neighbourhood}{\code{signature(x = "sts")}: extract the \code{neighbourhood} slot.} \item{population}{\code{signature(x = "sts")}: extract the \code{populationFrac} slot.} \item{control}{\code{signature(x = "sts")}: extract the \code{control} slot.} \item{multinomialTS}{\code{signature(x = "sts")}: extract the \code{multinomialTS} slot.} } } \subsection{Other extraction methods}{ \describe{ \item{dim}{\code{signature(x = "sts")}: extract matrix dimensions of \code{observed}. This method also enables \code{nrow(x)} and \code{ncol(x)}.} \item{dimnames}{\code{signature(x = "sts")}: extract the \code{\link{dimnames}} of the \code{observed} matrix. This method also enables \code{rownames(x)} and \code{colnames(x)}.} \item{year}{\code{signature(x = "sts")}: extract the corresponding year of each observation.} \item{epochInYear}{\code{signature(x = "sts")}: extract the epoch number within the year.} \item{[}{\code{signature(x = "sts")}: subset rows (time points) and/or columns (units), see \code{help("\link{[,sts-method}")}.} } } \subsection{Transformation methods}{ \describe{ \item{aggregate}{\code{signature(x = "sts")}: see \code{\link{aggregate.sts}}.} \item{as.data.frame}{\code{signature(x = "sts")}: the default \code{as.data.frame} call will collect the following slots into a data frame: \code{observed}, \code{epoch}, \code{state}, \code{alarm}, \code{upperbound}, and \code{populationFrac}. Additional columns will be created for \code{freq} (potentially varying by year for weekly or daily data if \code{x@epochAsDate} is \code{TRUE}) and \code{epochInPeriod} (the epoch fraction within the current year).\cr Calling the \code{as.data.frame} method with the argument \code{tidy = TRUE} will return \code{\link{tidy.sts}(x)}, which reshapes multivariate \code{sts} objects to the \dQuote{long} format (one row per epoch and observational unit). The tidy format is particularly useful for standard regression models and customized plotting.} \item{coerce}{\code{signature(from="sts", to="ts")} and \code{signature(from="ts", to="sts")}, to be called via \code{as(stsObj, "ts")} (or \code{as.ts(stsObj)}) and \code{as(tsObj, "sts")}, respectively.} \item{as.xts}{convert to the \CRANpkg{xts} package format.} } } \subsection{Visualization methods}{ \describe{ \item{plot}{\code{signature(x = "sts", y = "missing")}: entry point to a collection of plot variants. The \code{type} of plot is specified using a formula, see \code{\link{plot.sts}} for details.} \item{autoplot}{a \CRANpkg{ggplot2} variant of the standard time-series-type plot, see \code{\link{autoplot.sts}}.} \item{animate}{see \code{\link{animate.sts}}.} \item{toLatex}{see \code{\link{toLatex.sts}}.} } } } \author{Michael \enc{Hhle}{Hoehle} and Sebastian Meyer} \examples{ showClass("sts") ## create an sts object from time-series data salmonellaDF <- read.table(system.file("extdata/salmonella.agona.txt", package = "surveillance"), header = TRUE) str(salmonellaDF) salmonella <- with(salmonellaDF, sts(observed = observed, state = state, start = c(1990, 1), frequency = 52)) salmonella plot(salmonella) ## these data are also available as a legacy "disProg" object in the package data(salmonella.agona) stopifnot(all.equal(salmonella, disProg2sts(salmonella.agona))) ## A typical dataset with weekly counts of measles from several districts data("measlesWeserEms") measlesWeserEms ## reconstruct data("measlesWeserEms") from its components counts <- observed(measlesWeserEms) map <- measlesWeserEms@map populationFrac <- population(measlesWeserEms) weserems_nbOrder <- neighbourhood(measlesWeserEms) ## orders of adjacency can also be determined from the map if (requireNamespace("spdep")) { stopifnot(identical(weserems_nbOrder, nbOrder(poly2adjmat(map)))) } mymeasles <- sts(counts, start = c(2001, 1), frequency = 52, population = populationFrac, neighbourhood = weserems_nbOrder, map = map) stopifnot(identical(mymeasles, measlesWeserEms)) ## convert ts/mts object to sts z <- ts(matrix(rpois(300,10), 100, 3), start = c(1961, 1), frequency = 12) z.sts <- as(z, "sts") plot(z.sts) ## conversion of "sts" objects to the quasi-standard "xts" class if (requireNamespace("xts")) { z.xts <- as.xts.sts(z.sts) plot(z.xts) } } \keyword{classes} \keyword{ts} \keyword{methods} surveillance/man/hhh4_predict.Rd0000644000176200001440000000436214273227667016402 0ustar liggesusers\name{hhh4_predict} \alias{predict.hhh4} \title{Predictions from a \code{hhh4} Model} \description{ Get fitted (component) means from a \code{\link{hhh4}} model. } \usage{ \method{predict}{hhh4}(object, newSubset=object$control$subset, type="response", \dots) } \arguments{ \item{object}{fitted \code{\link{hhh4}} model (class \code{"hhh4"}).} \item{newSubset}{subset of time points for which to return the predictions. Defaults to the subset used for fitting the model, and must be a subset of \code{1:nrow(object$stsObj)}.} \item{type}{the type of prediction required. The default (\code{"response"} or, equivalently, \code{"mean"}) is on the scale of the response variable (mean = endemic plus epidemic components). The alternatives are: \code{"endemic"}, \code{"epidemic"}, \code{"epi.own"} (i.e. the autoregressive part), and \code{"epi.neighbours"} (i.e. the spatio-temporal part).} \item{\dots}{unused (argument of the generic).} } \value{ matrix of fitted means for each time point (of \code{newSubset}) and region. } \note{ Predictions for \dQuote{newdata}, i.e., with modified covariates or fixed weights, can be computed manually by adjusting the control list (in a copy of the original fit), dropping the old \code{terms}, and using the internal function \code{\link{meanHHH}} directly, see the Example. } \author{Michaela Paul and Sebastian Meyer} \keyword{methods} \keyword{models} \examples{ ## simulate simple seasonal noise with reduced baseline for t >= 60 t <- 0:100 y <- rpois(length(t), exp(3 + sin(2*pi*t/52) - 2*(t >= 60))) obj <- sts(y) plot(obj) ## fit true model fit <- hhh4(obj, list(end = list(f = addSeason2formula(~lock)), data = list(lock = as.integer(t >= 60)), family = "Poisson")) coef(fit, amplitudeShift = TRUE, se = TRUE) ## compute predictions for a subset of the time points stopifnot(identical(predict(fit), fitted(fit))) plot(obj) lines(40:80, predict(fit, newSubset = 40:80), lwd = 2) ## advanced: compute predictions for "newdata" (here, a modified covariate) mod <- fit mod$terms <- NULL # to be sure mod$control$data$lock[t >= 60] <- 0.5 pred <- meanHHH(mod$coefficients, terms(mod))$mean plot(fit, xaxis = NA) lines(mod$control$subset, pred, lty = 2) } surveillance/man/permutationTest.Rd0000644000176200001440000000511514221271063017217 0ustar liggesusers\name{permutationTest} \alias{permutationTest} \title{Monte Carlo Permutation Test for Paired Individual Scores} \description{ The difference between mean \code{\link{scores}} from model 1 and mean \code{\link{scores}} from model 2 is used as the test statistic. Under the null hypothesis of no difference, the actually observed difference between mean scores should not be notably different from the distribution of the test statistic under permutation. As the computation of all possible permutations is only feasible for small datasets, a random sample of permutations is used to obtain the null distribution. The resulting p-value thus depends on the \code{\link{.Random.seed}}. } \usage{ permutationTest(score1, score2, nPermutation = 9999, plot = FALSE, verbose = FALSE) } \arguments{ \item{score1, score2}{ numeric vectors of scores from models 1 and 2, respectively. } \item{nPermutation}{ number of Monte Carlo replicates. } \item{plot}{ logical indicating if a \code{\link{truehist}} of the \code{nPermutation} permutation test statistics should be plotted with a vertical line marking the observed difference of the means. To customize the histogram, \code{plot} can also be a list of arguments for \code{truehist} replacing internal defaults. } \item{verbose}{ logical indicating if the results should be printed in one line. } } \details{ For each permutation, we first randomly assign the membership of the n individual scores to either model 1 or 2 with probability 0.5. We then compute the respective difference in mean for model 1 and 2 in this permuted set of scores. The Monte Carlo p-value is then given by (1 + #\{permuted differences larger than observed difference (in absolute value)\}) / (1 + \code{nPermutation}). } \value{ a list of the following elements: \item{diffObs}{observed difference in mean scores, i.e., \code{mean(score1) - mean(score2)}} \item{pVal.permut}{p-value of the permutation test} \item{pVal.t}{p-value of the corresponding \code{\link{t.test}(score1, score2, paired=TRUE)}} } \author{ Michaela Paul with contributions by Sebastian Meyer } \references{ Paul, M. and Held, L. (2011): Predictive assessment of a non-linear random effects model for multivariate time series of infectious disease counts. \emph{Statistics in Medicine}, \bold{30} (10), 1118-1136. \doi{10.1002/sim.4177} } \seealso{ Package \CRANpkg{coin} for a comprehensive permutation test framework. } \examples{ permutationTest(rnorm(50, 1.5), rnorm(50, 1), plot = TRUE) } \keyword{htest} surveillance/man/wrap.algo.Rd0000644000176200001440000000471314145025164015711 0ustar liggesusers\name{wrap.algo} \alias{wrap.algo} \alias{bayes} \alias{rki} \alias{cusum} \alias{glrpois} \alias{glrnb} \alias{outbreakP} %% FIXME: hmm and rogerson are currently undocumented and unexported %\alias{hmm} %\alias{rogerson} \encoding{latin1} \title{Multivariate Surveillance through independent univariate algorithms} \description{ This function takes an \code{\link{sts}} object and applies an univariate surveillance algorithm to the time series of each observational unit. } \usage{ %This is the main function wrap.algo(sts, algo, control,control.hook=function(k, control) return(control),verbose=TRUE,...) %Derived functions fixing the control object and the "algo" argument bayes(sts, control = list(range = range, b = 0, w = 6, actY = TRUE,alpha=0.05),...) rki(sts, control = list(range = range, b = 2, w = 4, actY = FALSE),...) cusum(sts, control = list(range=range, k=1.04, h=2.26, m=NULL, trans="standard",alpha=NULL),...) glrpois(sts, control = list(range=range,c.ARL=5, S=1,beta=NULL, Mtilde=1, M=-1, change="intercept",theta=NULL),...) glrnb(sts, control = list(range=range,c.ARL=5, mu0=NULL, alpha=0, Mtilde=1, M=-1, change="intercept", theta=NULL,dir=c("inc","dec"), ret=c("cases","value")),...) outbreakP(sts, control=list(range = range, k=100, ret=c("cases","value"),maxUpperboundCases=1e5),...) } \arguments{ \item{sts}{Object of class \code{\link{sts}}} \item{algo}{Character string giving the function name of the algorithm to call, e.g. \code{"algo.farrington"}. Calling is done using \code{do.call}.} \item{control}{Control object as list. Depends on each algorithm.} \item{control.hook}{This is a function for handling multivariate objects. This argument is a function function of integer k and the current control object and which returns the appropriate control object for region k.} \item{verbose}{Boolean, if \code{TRUE} then textual information about the process is given} \item{...}{currently ignored.} } \value{ An \code{sts} object with the \code{alarm}, \code{upperbound}, etc. slots filled with the results of independent and univariate surveillance algorithm. } \seealso{ \code{\link{algo.rki}}, \code{\link{algo.farrington}}, \code{\link{algo.cusum}}, \code{\link{algo.glrpois}}, \code{\link{algo.glrnb}}, \code{\link{algo.outbreakP}} for the exact form of the \code{control} object. } \author{M. \enc{Hhle}{Hoehle}} \keyword{classif} surveillance/man/stsBP-class.Rd0000644000176200001440000000203014221271063016137 0ustar liggesusers\name{stsBP-class} \docType{class} \alias{stsBP-class} \alias{coerce,sts,stsBP-method} \encoding{latin1} \title{Class "stsBP" -- a class inheriting from class \code{sts} which allows the user to store the results of back-projecting or nowcasting surveillance time series} \description{ A class inheriting from class \code{sts}, but with additional slots to store the result and associated confidence intervals from back projection of a \code{sts} object. } \section{Slots}{ The slots are as for \code{"\linkS4class{sts}"}. However, two additional slots exists. \describe{ \item{\code{ci}:}{An array containing the upper and lower limit of the confidence interval.} \item{\code{lambda}:}{Back projection component} } } \section{Methods}{ The methods are the same as for \code{"\linkS4class{sts}"}. \describe{ \item{coerce}{\code{signature(from = "sts", to = "stsBP")}: convert an object of class \code{sts} to class \code{stsBP}. } } } \author{M. \enc{Hhle}{Hoehle}} \keyword{classes} surveillance/man/twinSIR_simulation.Rd0000644000176200001440000003470414131034603017616 0ustar liggesusers\encoding{latin1} \name{twinSIR_simulation} \alias{simEpidata} \alias{simulate.twinSIR} \title{ Simulation of Epidemic Data } \description{ This function simulates the infection (and removal) times of an epidemic. Besides the classical SIR type of epidemic, also SI, SIRS and SIS epidemics are supported. Simulation works via the conditional intensity of infection of an individual, given some (time varying) endemic covariates and/or some distance functions (epidemic components) as well as the fixed positions of the individuals. The lengths of the infectious and removed periods are generated following a pre-specified function (can be deterministic). The \code{\link{simulate}} method for objects of class \code{"\link{twinSIR}"} simulates new epidemic data using the model and the parameter estimates of the fitted object. } \usage{ simEpidata(formula, data, id.col, I0.col, coords.cols, subset, beta, h0, f = list(), w = list(), alpha, infPeriod, remPeriod = function(ids) rep(Inf, length(ids)), end = Inf, trace = FALSE, .allocate = NULL) \method{simulate}{twinSIR}(object, nsim = 1, seed = 1, infPeriod = NULL, remPeriod = NULL, end = diff(range(object$intervals)), trace = FALSE, .allocate = NULL, data = object$data, ...) } \arguments{ \item{formula}{ an object of class \code{"\link{formula}"} (or one that can be coerced to that class): a symbolic description of the intensity model to be estimated. The details of model specification are given under Details. } \item{data}{ a data.frame containing the variables in \code{formula} and the variables specified by \code{id.col}, \code{I0.col} and \code{coords.col} (see below). It represents the \dQuote{history} of the endemic covariates to use for the simulation. The form is similar to and can be an object of class \code{"\link{epidata}"}. The simulation period is split up into \emph{consecutive} intervals of constant endemic covariables. The data frame consists of a block of N (number of individuals) rows for each of those time intervals (all rows in a block share the same start and stop values... therefore the name \dQuote{block}), where there is one row per individual in the block. Each row describes the (fixed) state of the endemic covariates of the individual during the time interval given by the start and stop columns (specified through the lhs of \code{formula}). For the \code{simulate} method of class \code{"twinSIR"} this should be the object of class \code{"\link{epidata}"} used for the fit. This is a part of the return value of the function \code{twinSIR}, if called with argument \code{keep.data} set to \code{TRUE}. } \item{id.col}{ only if \code{data} does not inherit from \code{epidata}: single index of the \code{id} column in \code{data}. Can be numeric (by column number) or character (by column name).\cr The \code{id} column identifies the individuals in the data-frame. It will be converted to a factor variable and its levels serve also to identify individuals as argument to the \code{infPeriod} function. } \item{I0.col}{ only if \code{data} does not inherit from \code{epidata}: single index of the \code{I0} column in \code{data}. Can be numeric (by column number), character (by column name) or \code{NULL}.\cr The \code{I0} column indicates if an individual is initially infectious, i.e. it is already infectious at the beginning of the first time block. Setting \code{I0.col = NULL} is short for \dQuote{there are no initially infectious individuals}. Otherwise, the variable must be logical or in 0/1-coding. As this variable is constant over time the initially infectious individuals are derived from the first time block only. } \item{coords.cols}{ only if \code{data} does not inherit from \code{epidata}: index\emph{es} of the \code{coords} column\emph{s} in \code{data}. Can be a numeric (by column number), a character (by column name) vector or \code{NULL}.\cr These columns contain the coordinates of the individuals. It must be emphasized that the functions in this package currently assume \emph{fixed positions} of the individuals during the whole epidemic. Thus, an individual has the same coordinates in every block. For simplicity, the coordinates are derived from the first time block only. The epidemic covariates are calculated based on the Euclidian distance between the individuals, see \code{f}. } \item{subset}{ an optional vector specifying a subset of the covariate history to be used in the simulation. } \item{beta}{ numeric vector of length equal the number of endemic (\code{cox}) terms on the rhs of \code{formula}. It contains the effects of the endemic predictor (excluding the log-baseline \code{h0}, see below) in the same order as in the formula. } \item{h0}{ \emph{either} a single number to specify a constant baseline hazard (equal to \code{exp(h0)}) \emph{or} a list of functions named \code{exact} and \code{upper}. In the latter case, \code{h0$exact} is the true log-baseline hazard function and \code{h0$upper} is a \emph{piecewise constant upper bound} for \code{h0$exact}. The function \code{h0$upper} must inherit from \code{\link{stepfun}} with \code{right=FALSE}. Theoretically, the intensity function is left-continuous, thus \code{right=TRUE} would be adequate, but in the implementation, when we evaluate the intensity at the \code{\link{knots}} (change points) of \code{h0$upper} we need its value for the subsequent interval. } \item{f, w}{ see \code{\link{as.epidata}}. } \item{alpha}{ a named numeric vector of coefficients for the epidemic covariates generated by \code{f} and \code{w}. The names are matched against \code{names(f)} and \code{names(w)}. Remember that \code{alpha >= 0}. } \item{infPeriod}{ a function generating lengths of infectious periods. It should take one parameter (e.g. \code{ids}), which is a character vector of id's of individuals, and return appropriate infection periods for those individuals. Therefore, the value of the function should be of length \code{length(ids)}. For example, for independent and identically distributed infection periods following \eqn{Exp(1)}, the generating function is \code{function(ids) rexp(length(ids), rate=1)}. For a constant infectious period of length c, it is sufficient to set \code{function (x) {c}}.\cr For the \code{simulate} method of class \code{"twinSIR"} only, this can also be \code{NULL} (the default), which means that the observed infectious periods of infected individuals are re-used when simulating a new epidemic and individuals with missing infectious periods (i.e. infection and recovery was not observed) are attributed to the mean observed infectious period. Note that it is even possible to simulate an SI-epidemic by setting \code{infPeriod = function (x) {Inf}} In other words: once an individual became infected it spreads the disease forever, i.e. it will never be removed. } \item{remPeriod}{ a function generating lengths of removal periods. Per default, once an individual was removed it will stay in this state forever (\code{Inf}). Therefore, it will not become at-risk (S) again and re-infections are not possible. Alternatively, always returning 0 as length of the removal period corresponds to a SIS epidemic. Any other values correspond to SIRS. Note that \code{end} should be set to a finite value in these cases. } \item{end}{ a single positive numeric value specifying the time point at which the simulation should be forced to end. By default, this is \code{Inf}, i.e. the simulation continues until there is no susceptible individual left.\cr For the \code{simulate} method of class \code{"twinSIR"} the default is to have equal simulation and observation periods. } \item{trace}{ logical (or integer) indicating if (or how often) the sets of susceptible and infected individuals as well as the rejection indicator (of the rejection sampling step) should be \code{cat}ed. Defaults to \code{FALSE}. } \item{.allocate}{ number of blocks to initially allocate for the event history (i.e. \code{.allocate*N} rows). By default (\code{NULL}), this number is set to \code{max(500, ceiling(nBlocks/100)*100)}, i.e. 500 but at least the number of blocks in \code{data} (rounded to the next multiple of 100). Each time the simulated epidemic exceeds the allocated space, the event history will be enlarged by \code{.allocate} blocks. } \item{object}{ an object of class \code{"twinSIR"}. This must contain the original \code{data} used for the fit (see \code{data}). } \item{nsim}{ number of epidemics to simulate. Defaults to 1. } \item{seed}{ an integer that will be used in the call to \code{\link{set.seed}} before simulating the epidemics. } \item{\dots}{ unused (argument of the generic). } } \details{ A model is specified through the \code{formula}, which has the form \code{cbind(start, stop) ~ cox(endemicVar1) * cox(endemicVar2)}, i.e. the right hand side has the usual form as in \code{\link{lm}}, but all variables are marked as being endemic by the special function \code{\link{cox}}. The effects of those predictor terms are specified by \code{beta}. The left hand side of the formula denotes the start and stop columns in \code{data}. This can be omitted, if \code{data} inherits from class \code{"epidata"} in which case \code{cbind(start, stop)} will be used. The epidemic model component is specified by the arguments \code{f} and \code{w} (and the associated coefficients \code{alpha}). If the epidemic model component is empty and \code{infPeriod} always returns \code{Inf}, then one actually simulates from a pure Cox model. The simulation algorithm used is \emph{Ogata's modified thinning}. For details, see \enc{Hhle}{Hoehle} (2009), Section 4. } \value{ An object of class \code{"simEpidata"}, which is a \code{data.frame} with the columns \code{"id"}, \code{"start"}, \code{"stop"}, \code{"atRiskY"}, \code{"event"}, \code{"Revent"} and the coordinate columns (with the original names from \code{data}), which are all obligatory. These columns are followed by all the variables appearing on the rhs of the \code{formula}. Last but not least, the generated columns with epidemic covariates corresponding to the functions in the lists \code{f} and \code{w} are appended. Note that objects of class \code{"simEpidata"} also inherit from class \code{"\link{epidata}"}, thus all \code{"\link{epidata}"} methods can be applied. The \code{data.frame} is given the additional \emph{attributes} \item{"eventTimes"}{ numeric vector of infection time points (sorted chronologically). } \item{"timeRange"}{ numeric vector of length 2: \code{c(min(start), max(stop))}. } \item{"coords.cols"}{ numeric vector containing the column indices of the coordinate columns in the resulting data-frame. } \item{"f"}{ this equals the argument \code{f}. } \item{"w"}{ this equals the argument \code{w}. } \item{"config"}{ a list with elements \code{h0 = h0$exact}, \code{beta} and \code{alpha}. } \item{call}{the matched call.} \item{terms}{the \code{terms} object used.} If \code{nsim > 1} epidemics are simulated by the \code{simulate}-method for fitted \code{"twinSIR"} models, these are returned in a list. } \references{ \enc{Hhle}{Hoehle}, M. (2009), Additive-Multiplicative Regression Models for Spatio-Temporal Epidemics, Biometrical Journal, 51(6):961-978. } \author{ Sebastian Meyer and Michael \enc{Hhle}{Hoehle} } \seealso{ The \code{\link{plot.epidata}} and \code{\link{animate.epidata}} methods for plotting and animating (simulated) epidemic data, respectively. The \code{\link{intensityplot.simEpidata}} method for plotting paths of infection intensities. Function \code{\link{twinSIR}} for fitting spatio-temporal epidemic intensity models to epidemic data. } \examples{ ## Generate a data frame containing a hypothetic population with 100 individuals set.seed(1234) n <- 100 pos <- matrix(rnorm(n*2), ncol=2, dimnames=list(NULL, c("x", "y"))) pop <- data.frame(id=1:n, x=pos[,1], y=pos[,2], gender=sample(0:1, n, replace=TRUE), I0col=c(rep(1,3),rep(0,n-3)), # 3 initially infectious start=rep(0,n), stop=rep(Inf,n)) ## Simulate an SIR epidemic in this population set.seed(123) infPeriods <- setNames(c(1:3/10, rexp(n-3, rate=1)), 1:n) epi <- simEpidata( cbind(start,stop) ~ cox(gender), data = pop, id.col = "id", I0.col = "I0col", coords.cols = c("x","y"), beta = c(-2), h0 = -1, alpha = c(B1=0.1), f = list(B1=function(u) u<=1), infPeriod = function(ids) infPeriods[ids], ##remPeriod = function(ids) rexp(length(ids), rate=0.1), end = 30 # -> SIRS ) ## extract event times by id head(summary(epi)$byID) ## Plot the numbers of susceptible, infectious and removed individuals plot(epi) ## load the 1861 Hagelloch measles epidemic data("hagelloch") summary(hagelloch) plot(hagelloch) ## fit a simplistic twinSIR model fit <- twinSIR(~ household, data = hagelloch) ## simulate a new epidemic from the above model ## with simulation period = observation period, re-using observed infPeriods sim1 <- simulate(fit, data = hagelloch) plot(sim1) ## check if we find similar parameters in the simulated epidemic fitsim1 <- update(fit, data = sim1) cbind(base = coef(fit), new = coef(fitsim1)) \dontshow{if (surveillance.options("allExamples")) \{} ## simulate only 10 days, using random infPeriods ~ Exp(0.1) sim2 <- simulate(fit, data = hagelloch, seed = 2, end = 10, infPeriod = function(ids) rexp(length(ids), rate = 0.1)) plot(sim2) ## simulate from a different model with manually specified parameters set.seed(321) simepi <- simEpidata(~ cox(AGE), data = hagelloch, beta = c(0.1), h0 = -4, alpha = c(household = 0.05), f = list(household = function(u) u == 0), infPeriod = function(ids) rexp(length(ids), rate=1/8)) plot(simepi) intensityplot(simepi) ## see if we correctly estimate the parameters fitsimepi <- twinSIR(~ cox(AGE) + household, data = simepi) cbind(true = c(0.05, -4, 0.1), est = coef(fitsimepi), confint(fitsimepi)) \dontshow{\}} } \keyword{datagen} \keyword{models} surveillance/man/multiplicity.Rd0000644000176200001440000000065214614160257016551 0ustar liggesusers\name{multiplicity} \alias{multiplicity} \docType{import} \title{Import from package \pkg{spatstat.geom}} \description{ The generic function \code{multiplicity} is imported from package \pkg{spatstat.geom}. See \code{\link[spatstat.geom:multiplicity]{spatstat.geom::multiplicity}} for \pkg{spatstat.geom}'s own methods, and \code{\link{multiplicity.Spatial}} for the added method for \code{"\linkSPclass{Spatial}"} objects. } surveillance/man/epidata.Rd0000644000176200001440000003773514334522617015445 0ustar liggesusers\encoding{latin1} \name{epidata} \alias{as.epidata} \alias{as.epidata.data.frame} \alias{as.epidata.default} \alias{print.epidata} \alias{[.epidata} \alias{update.epidata} \alias{epidata} \title{ Continuous-Time SIR Event History of a Fixed Population } \description{ The function \code{as.epidata} is used to generate objects of class \code{"epidata"}. Objects of this class are specific data frames containing the event history of an epidemic together with some additional attributes. These objects are the basis for fitting spatio-temporal epidemic intensity models with the function \code{\link{twinSIR}}. Their implementation is illustrated in Meyer et al. (2017, Section 4), see \code{vignette("twinSIR")}. Note that the spatial information itself, i.e. the positions of the individuals, is assumed to be constant over time. Besides epidemics following the SIR compartmental model, also data from SI, SIRS and SIS epidemics may be supplied. } \usage{ as.epidata(data, ...) \method{as.epidata}{data.frame}(data, t0, tE.col, tI.col, tR.col, id.col, coords.cols, f = list(), w = list(), D = dist, max.time = NULL, keep.cols = TRUE, ...) \method{as.epidata}{default}(data, id.col, start.col, stop.col, atRiskY.col, event.col, Revent.col, coords.cols, f = list(), w = list(), D = dist, .latent = FALSE, ...) \method{print}{epidata}(x, ...) \method{[}{epidata}(x, i, j, drop) \method{update}{epidata}(object, f = list(), w = list(), D = dist, ...) } \arguments{ \item{data}{ For the \code{data.frame}-method, a data frame with as many rows as there are individuals in the population and time columns indicating when each individual became exposed (optional), infectious (mandatory, but can be \code{NA} for non-affected individuals) and removed (optional). Note that this data format does not allow for re-infection (SIRS) and time-varying covariates. The \code{data.frame}-method converts the individual-indexed data frame to the long event history start/stop format and then feeds it into the default method. If calling the generic function \code{as.epidata} on a \code{data.frame} and the \code{t0} argument is missing, the default method is called directly.\cr For the default method, \code{data} can be a \code{\link{matrix}} or a \code{\link{data.frame}}. It must contain the observed event history in a form similar to \code{Surv(, type="counting")} in package \pkg{survival}, with additional information (variables) along the process. Rows will be sorted automatically during conversion. The observation period is split up into \emph{consecutive} intervals of constant state - thus constant infection intensities. The data frame consists of a block of \eqn{N} (number of individuals) rows for each of those time intervals (all rows in a block have the same start and stop values\dots therefore the name \dQuote{block}), where there is one row per individual in the block. Each row describes the (fixed) state of the individual during the interval given by the start and stop columns \code{start.col} and \code{stop.col}.\cr Note that there may not be more than one event (infection or removal) in a single block. Thus, in a single block, only one entry in the \code{event.col} and \code{Revent.col} may be 1, all others are 0. This rule follows the point process characteristic that there are no concurrent events (infections or removals). } \item{t0,max.time}{ observation period. In the resulting \code{"epidata"}, the time scale will be relative to the start time \code{t0}. Individuals that have already been removed prior to \code{t0}, i.e., rows with \code{tR <= t0}, will be dropped. The end of the observation period (\code{max.time}) will by default (\code{NULL}, or if \code{NA}) coincide with the last observed event. } \item{tE.col, tI.col, tR.col}{ single numeric or character indexes of the time columns in \code{data}, which specify when the individuals became exposed, infectious and removed, respectively. \code{tE.col} and \code{tR.col} can be missing, corresponding to SIR, SEI, or SI data. \code{NA} entries mean that the respective event has not (yet) occurred. Note that \code{is.na(tE)} implies \code{is.na(tI)} and \code{is.na(tR)}, and \code{is.na(tI)} implies \code{is.na(tR)} (and this is checked for the provided data).\cr CAVE: Support for latent periods (\code{tE.col}) is experimental! \code{\link{twinSIR}} cannot handle them anyway. } \item{id.col}{ single numeric or character index of the \code{id} column in \code{data}. The \code{id} column identifies the individuals in the data frame. It is converted to a factor by calling \code{\link{factor}}, i.e., unused levels are dropped if it already was a factor. } \item{start.col}{ single index of the \code{start} column in \code{data}. Can be numeric (by column number) or character (by column name). The \code{start} column contains the (numeric) time points of the beginnings of the consecutive time intervals of the event history. The minimum value in this column, i.e. the start of the observation period should be 0. } \item{stop.col}{ single index of the \code{stop} column in \code{data}. Can be numeric (by column number) or character (by column name). The \code{stop} column contains the (numeric) time points of the ends of the consecutive time intervals of the event history. The stop value must always be greater than the start value of a row. } \item{atRiskY.col}{ single index of the \code{atRiskY} column in \code{data}. Can be numeric (by column number) or character (by column name). The \code{atRiskY} column indicates if the individual was \dQuote{at-risk} of becoming infected during the time interval (start; stop]. This variable must be logical or in 0/1-coding. Individuals with \code{atRiskY == 0} in the first time interval (normally the rows with \code{start == 0}) are taken as \emph{initially infectious}. } \item{event.col}{ single index of the \code{event} column in \code{data}. Can be numeric (by column number) or character (by column name). The \code{event} column indicates if the individual became \emph{infected} at the \code{stop} time of the interval. This variable must be logical or in 0/1-coding. } \item{Revent.col}{ single index of the \code{Revent} column in \code{data}. Can be numeric (by column number) or character (by column name). The \code{Revent} column indicates if the individual was \emph{recovered} at the \code{stop} time of the interval. This variable must be logical or in 0/1-coding. } \item{coords.cols}{ index\emph{es} of the \code{coords} column\emph{s} in \code{data}. Can be numeric (by column number), character (by column name), or \code{NULL} (no coordinates, e.g., if \code{D} is a pre-specified distance matrix). These columns contain the individuals' coordinates, which determine the distance matrix for the distance-based components of the force of infection (see argument \code{f}). By default, Euclidean distance is used (see argument \code{D}).\cr Note that the functions related to \code{\link{twinSIR}} currently assume \emph{fixed positions} of the individuals during the whole epidemic. Thus, an individual has the same coordinates in every block. For simplicity, the coordinates are derived from the first time block only (normally the rows with \code{start == 0}).\cr The \code{\link[=animate.epidata]{animate}}-method requires coordinates. } \item{f}{ a \emph{named} list of \emph{vectorized} functions for a distance-based force of infection. The functions must interact elementwise on a (distance) matrix \code{D} so that \code{f[[m]](D)} results in a matrix. A simple example is \code{function(u) {u <= 1}}, which indicates if the Euclidean distance between the individuals is smaller than or equal to 1. The names of the functions determine the names of the epidemic variables in the resulting data frame. So, the names should not coincide with names of other covariates. The distance-based weights are computed as follows: Let \eqn{I(t)} denote the set of infectious individuals just before time \eqn{t}. Then, for individual \eqn{i} at time \eqn{t}, the \eqn{m}'th covariate has the value \eqn{\sum_{j \in I(t)} f_m(d_{ij})}{\sum_{j in I(t)} f[[m]](d[i,j])}, where \eqn{d_{ij}}{d[i,j]} denotes entries of the distance matrix (by default this is the Euclidean distance \eqn{||s_i - s_j||} between the individuals' coordinates, but see argument \code{D}). } \item{w}{ a \emph{named} list of \emph{vectorized} functions for extra covariate-based weights \eqn{w_{ij}}{w_ij} in the epidemic component. Each function operates on a single time-constant covariate in \code{data}, which is determined by the name of the first argument: The two function arguments should be named \code{varname.i} and \code{varname.j}, where \code{varname} is one of \code{names(data)}. Similar to the components in \code{f}, \code{length(w)} epidemic covariates will be generated in the resulting \code{"epidata"} named according to \code{names(w)}. So, the names should not coincide with names of other covariates. For individual \eqn{i} at time \eqn{t}, the \eqn{m}'th such covariate has the value \eqn{\sum_{j \in I(t)} w_m(z^{(m)}_i, z^{(m)}_j)}, where \eqn{z^{(m)}} denotes the variable in \code{data} associated with \code{w[[m]]}. } \item{D}{ either a function to calculate the distances between the individuals with locations taken from \code{coord.cols} (the default is Euclidean distance via the function \code{\link{dist}}) and the result converted to a matrix via \code{\link{as.matrix}}, or a pre-computed distance matrix with \code{dimnames} containing the individual ids (a classed \code{"\linkS4class{Matrix}"} is supported). } \item{keep.cols}{ logical indicating if all columns in \code{data} should be retained (and not only the obligatory \code{"epidata"} columns), in particular any additional columns with time-constant individual-specific covariates. Alternatively, \code{keep.cols} can be a numeric or character vector indexing columns of \code{data} to keep. } \item{.latent}{ (internal) logical indicating whether to allow for latent periods (EXPERIMENTAL). Otherwise (default), the function verifies that an event (i.e., switching to the I state) only happens when the respective individual is at risk (i.e., in the S state). } \item{x,object}{ an object of class \code{"epidata"}. } \item{\dots}{ arguments passed to \code{\link{print.data.frame}}. Currently unused in the \code{as.epidata}-methods. } \item{i,j,drop}{ arguments passed to \code{\link{[.data.frame}}. } } \details{ The \code{print} method for objects of class \code{"epidata"} simply prints the data frame with a small header containing the time range of the observed epidemic and the number of infected individuals. Usually, the data frames are quite long, so the summary method \code{\link{summary.epidata}} might be useful. Also, indexing/subsetting \code{"epidata"} works exactly as for \code{\link[=[.data.frame]{data.frame}}s, but there is an own method, which assures consistency of the resulting \code{"epidata"} or drops this class, if necessary. The \code{update}-method can be used to add or replace distance-based (\code{f}) or covariate-based (\code{w}) epidemic variables in an existing \code{"epidata"} object. SIS epidemics are implemented as SIRS epidemics where the length of the removal period equals 0. This means that an individual, which has an R-event will be at risk immediately afterwards, i.e. in the following time block. Therefore, data of SIS epidemics have to be provided in that form containing \dQuote{pseudo-R-events}. } \note{ The column name \code{"BLOCK"} is a reserved name. This column will be added automatically at conversion and the resulting data frame will be sorted by this column and by id. Also the names \code{"id"}, \code{"start"}, \code{"stop"}, \code{"atRiskY"}, \code{"event"} and \code{"Revent"} are reserved for the respective columns only. } \value{ a \code{data.frame} with the columns \code{"BLOCK"}, \code{"id"}, \code{"start"}, \code{"stop"}, \code{"atRiskY"}, \code{"event"}, \code{"Revent"} and the coordinate columns (with the original names from \code{data}), which are all obligatory. These columns are followed by any remaining columns of the input \code{data}. Last but not least, the newly generated columns with epidemic variables corresponding to the functions in the list \code{f} are appended, if \code{length(f)} > 0. The \code{data.frame} is given the additional \emph{attributes} \item{"eventTimes"}{ numeric vector of infection time points (sorted chronologically). } \item{"timeRange"}{ numeric vector of length 2: \code{c(min(start), max(stop))}. } \item{"coords.cols"}{ numeric vector containing the column indices of the coordinate columns in the resulting data frame. } \item{"f"}{ this equals the argument \code{f}. } \item{"w"}{ this equals the argument \code{w}. } } \author{ Sebastian Meyer } \seealso{ The \code{\link{hagelloch}} data as an example. The \code{\link[=plot.epidata]{plot}} and the \code{\link[=summary.epidata]{summary}} method for class \code{"epidata"}. Furthermore, the function \code{\link{animate.epidata}} for the animation of epidemics. Function \code{\link{twinSIR}} for fitting spatio-temporal epidemic intensity models to epidemic data. Function \code{\link{simEpidata}} for the simulation of epidemic data. } \references{ Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \examples{ data("hagelloch") # see help("hagelloch") for a description head(hagelloch.df) ## convert the original data frame to an "epidata" event history myEpi <- as.epidata(hagelloch.df, t0 = 0, tI.col = "tI", tR.col = "tR", id.col = "PN", coords.cols = c("x.loc", "y.loc"), keep.cols = c("SEX", "AGE", "CL")) \dontshow{if (surveillance.options("allExamples")) { ## test consistency with default method evHist <- as.data.frame(myEpi)[,-1] myEpi2 <- as.epidata( evHist, id.col = 1, start.col = "start", stop.col = "stop", atRiskY.col = "atRiskY", event.col = "event", Revent.col = "Revent", coords.cols = c("x.loc", "y.loc") ) stopifnot(identical(myEpi, myEpi2)) }} str(myEpi) head(as.data.frame(myEpi)) # "epidata" has event history format summary(myEpi) # see 'summary.epidata' plot(myEpi) # see 'plot.epidata' and also 'animate.epidata' \dontshow{if (surveillance.options("allExamples")) \{} ## add distance- and covariate-based weights for the force of infection ## in a twinSIR model, see vignette("twinSIR") for a description myEpi <- update(myEpi, f = list( household = function(u) u == 0, nothousehold = function(u) u > 0 ), w = list( c1 = function (CL.i, CL.j) CL.i == "1st class" & CL.j == CL.i, c2 = function (CL.i, CL.j) CL.i == "2nd class" & CL.j == CL.i ) ) ## this is now identical to the prepared hagelloch "epidata" stopifnot(all.equal(myEpi, hagelloch)) \dontshow{\}} \dontshow{if (surveillance.options("allExamples")) { ## test with precomputed distance matrix D myEpi3 <- suppressWarnings( # from overwriting existing f columns update(hagelloch, f = attr(hagelloch, "f"), D = as.matrix(dist(hagelloch.df[c("x.loc", "y.loc")]))) ) stopifnot(identical(hagelloch, myEpi3)) }} } \keyword{spatial} \keyword{classes} \keyword{manip} surveillance/man/multiplicity.Spatial.Rd0000644000176200001440000000307014614160257020142 0ustar liggesusers\name{multiplicity.Spatial} \alias{multiplicity.Spatial} \title{ Count Number of Instances of Points } \description{ The generic function \code{multiplicity} defined in \pkg{spatstat.geom} is intended to count the number of duplicates of each element of an object. \pkg{spatstat.geom} already offers methods for point patterns, matrices and data frames, and here we add a method for \code{Spatial} objects from the \pkg{sp} package. It is a wrapper for the default method, which effectively computes the distance matrix of the points, and then just counts the number of zeroes in each row. } \usage{ \method{multiplicity}{Spatial}(x) } \arguments{ \item{x}{ a \code{"\linkSPclass{Spatial}"} object (we only need a \code{\link[sp]{coordinates}}-method), e.g. of class \code{"\linkSPclass{SpatialPoints}"}. } } \value{ an integer vector containing the number of instances of each point of the object. } \seealso{ \code{\link[spatstat.geom]{multiplicity}} in package \pkg{spatstat.geom}. See the Examples of the \code{\link{hagelloch}} data for a specific use of \code{multiplicity}. } \examples{ foo <- SpatialPoints(matrix(c(1,2, 2,3, 1,2, 4,5), 4, 2, byrow=TRUE)) multiplicity(foo) # the following function determines the multiplicities in a matrix # or data frame and returns unique rows with appended multiplicity countunique <- function(x) unique(cbind(x, count=multiplicity(x))) countunique(coordinates(foo)) } \keyword{utilities} \keyword{spatial} surveillance/man/algo.cusum.Rd0000644000176200001440000001171414137000756016074 0ustar liggesusers\name{algo.cusum} \alias{algo.cusum} \title{CUSUM method} \encoding{latin1} \description{ Approximate one-side CUSUM method for a Poisson variate based on the cumulative sum of the deviation between a reference value k and the transformed observed values. An alarm is raised if the cumulative sum equals or exceeds a prespecified decision boundary h. The function can handle time varying expectations. } \usage{ algo.cusum(disProgObj, control = list(range = range, k = 1.04, h = 2.26, m = NULL, trans = "standard", alpha = NULL)) } \arguments{ \item{disProgObj}{object of class disProg (including the observed and the state chain)} \item{control}{control object: \describe{ \item{\code{range}}{determines the desired time points which should be evaluated} \item{\code{k}}{is the reference value} \item{\code{h}}{the decision boundary} \item{\code{m}}{how to determine the expected number of cases -- the following arguments are possible \describe{ \item{\code{numeric}}{a vector of values having the same length as \code{range}. If a single numeric value is specified then this value is replicated \code{length(range)} times.} \item{\code{NULL}}{A single value is estimated by taking the mean of all observations previous to the first \code{range} value.} \item{\code{"glm"}}{ A GLM of the form \deqn{\log(m_t) = \alpha + \beta t + \sum_{s=1}^S (\gamma_s \sin(\omega_s t) + \delta_s \cos(\omega_s t)),} where \eqn{\omega_s = \frac{2\pi}{52}s}{\omega_s = 2\pi/52 s} are the Fourier frequencies is fitted. Then this model is used to predict the \code{range} values.} }} \item{\code{trans}}{one of the following transformations (warning: Anscombe and NegBin transformations are experimental) \describe{ \item{\code{rossi}}{standardized variables z3 as proposed by Rossi} \item{\code{standard}}{standardized variables z1 (based on asymptotic normality) - This is the default.} \item{\code{anscombe}}{anscombe residuals -- experimental} \item{\code{anscombe2nd}}{ anscombe residuals as in Pierce and Schafer (1986) based on 2nd order approximation of E(X) -- experimental} \item{\code{pearsonNegBin}}{compute Pearson residuals for NegBin -- experimental} \item{\code{anscombeNegBin}}{anscombe residuals for NegBin -- experimental} \item{\code{none}}{ no transformation} } } \item{\code{alpha}}{parameter of the negative binomial distribution, s.t. the variance is \eqn{m+\alpha *m^2} } } } } \value{ \code{algo.cusum} gives a list of class \code{"survRes"} which includes the vector of alarm values for every timepoint in \code{range} and the vector of cumulative sums for every timepoint in \code{range} for the system specified by \code{k} and \code{h}, the range and the input object of class \code{"disProg"}. The \code{upperbound} entry shows for each time instance the number of diseased individuals it would have taken the cusum to signal. Once the CUSUM signals no resetting is applied, i.e. signals occurs until the CUSUM statistic again returns below the threshold. In case \code{control$m="glm"} was used, the returned \code{control$m.glm} entry contains the fitted \code{"glm"} object. } \note{This implementation is experimental, but will not be developed further.} \author{M. Paul and M. \enc{Hhle}{Hoehle}} \examples{ # Xi ~ Po(5), i=1,...,500 set.seed(321) stsObj <- sts(observed = rpois(500,lambda=5)) # there should be no alarms as mean doesn't change res <- cusum(stsObj, control = list(range = 100:500, trans = "anscombe")) plot(res, xaxis.labelFormat = NULL) # simulated data disProgObj <- sim.pointSource(p = 1, r = 1, length = 250, A = 0, alpha = log(5), beta = 0, phi = 10, frequency = 10, state = NULL, K = 0) plot(disProgObj) # Test weeks 200 to 250 for outbreaks surv0 <- algo.cusum(disProgObj, control = list(range = 200:250)) plot(surv0, xaxis.years = FALSE) # alternatively, using the newer "sts" interface stsObj <- disProg2sts(disProgObj) surv <- cusum(stsObj, control = list(range = 200:250)) plot(surv) stopifnot(upperbound(surv) == surv0$upperbound) } \references{ G. Rossi, L. Lampugnani and M. Marchi (1999), An approximate CUSUM procedure for surveillance of health events, Statistics in Medicine, 18, 2111--2122 D. A. Pierce and D. W. Schafer (1986), Residuals in Generalized Linear Models, Journal of the American Statistical Association, 81, 977--986 } \keyword{classif} surveillance/man/twinstim.Rd0000644000176200001440000006032714610747661015712 0ustar liggesusers\encoding{latin1} \name{twinstim} \alias{twinstim} \title{ Fit a Two-Component Spatio-Temporal Point Process Model } \description{ A \code{twinstim} model as described in Meyer et al. (2012) is fitted to marked spatio-temporal point process data. This constitutes a regression approach for conditional intensity function modelling. The implementation is illustrated in Meyer et al. (2017, Section 3), see \code{vignette("twinstim")}. } \usage{ twinstim(endemic, epidemic, siaf, tiaf, qmatrix = data$qmatrix, data, subset, t0 = data$stgrid$start[1], T = tail(data$stgrid$stop,1), na.action = na.fail, start = NULL, partial = FALSE, epilink = "log", control.siaf = list(F = list(), Deriv = list()), optim.args = list(), finetune = FALSE, model = FALSE, cumCIF = FALSE, cumCIF.pb = interactive(), cores = 1, verbose = TRUE) } \arguments{ \item{endemic}{ right-hand side formula for the exponential (Cox-like multiplicative) endemic component. May contain offsets (to be marked by the special function \code{offset}). If omitted or \code{~0} there will be no endemic component in the model. A type-specific endemic intercept can be requested by including the term \code{(1|type)} in the formula. } \item{epidemic}{ formula representing the epidemic model for the event-specific covariates (marks) determining infectivity. Offsets are not implemented here. If omitted or \code{~0} there will be no epidemic component in the model. } \item{siaf}{ spatial interaction function. Possible specifications are: \itemize{ \item \code{NULL} or missing, corresponding to \code{siaf.constant()}, i.e. spatially homogeneous infectivity independent of the distance from the host \item a list as returned by \code{\link{siaf}} or, more commonly, generated by a predefined interaction function such as \code{\link{siaf.gaussian}} as in Meyer et al. (2012) or \code{\link{siaf.powerlaw}} as in Meyer and Held (2014). The latter requires unique event locations, possibly after random tie-breaking (\code{\link{untie}}) or imputation of interval-censored locations. \code{\link{siaf.exponential}} is a simpler alternative. \item a numeric vector corresponding to the knots of a step function, i.e. the same as \code{\link{siaf.step}(knots)} } If you run into \dQuote{false convergence} with a non-constant \code{siaf} specification, the numerical accuracy of the cubature methods is most likely too low (see the \code{control.siaf} argument). } \item{tiaf}{ temporal interaction function. Possible specifications are: \itemize{ \item \code{NULL} or missing, corresponding to \code{tiaf.constant()}, i.e. time-constant infectivity \item a list as returned by \code{\link{tiaf}} or by a predefined interaction function such as \code{\link{tiaf.exponential}} \item a numeric vector corresponding to the knots of a step function, i.e. the same as \code{\link{tiaf.step}(knots)} } } \item{qmatrix}{ square indicator matrix (0/1 or \code{FALSE}/\code{TRUE}) for possible transmission between the event types. The matrix will be internally converted to \code{logical}. Defaults to the \eqn{Q} matrix specified in \code{data}. } \item{data}{ an object of class \code{"\link{epidataCS}"}. } \item{subset}{ an optional vector evaluating to logical indicating a subset of \code{data$events} to keep. Missing values are taken as \code{FALSE}. The expression is evaluated in the context of the \code{data$events@data} \code{data.frame}, i.e. columns of this \code{data.frame} may be referenced directly by name. } \item{t0, T}{ events having occurred during (-Inf;t0] are regarded as part of the prehistory \eqn{H_0} of the process. Only events that occurred in the interval (t0; T] are considered in the likelihood. The time point \code{t0} (\code{T}) must be an element of \code{data$stgrid$start} (\code{data$stgrid$stop}). The default time range covers the whole spatio-temporal grid of endemic covariates. } \item{na.action}{ how to deal with missing values in \code{data$events}? Do not use \code{\link{na.pass}}. Missing values in the spatio-temporal grid \code{data$stgrid} are not accepted. } \item{start}{ a named vector of initial values for (a subset of) the parameters. The names must conform to the conventions of \code{twinstim} to be assigned to the correct model terms. For instance, \code{"h.(Intercept)"} = endemic intercept, \code{"h.I(start/365)"} = coefficient of a linear time trend in the endemic component, \code{"h.factorB"} = coefficient of the level B of the factor variable \code{factor} in the endemic predictor, \code{"e.(Intercept)"} = epidemic intercept, \code{"e.VAR"} = coefficient of the epidemic term \code{VAR}, \code{"e.siaf.2"} = second \code{siaf} parameter, \code{"e.tiaf.1"} = first \code{tiaf} parameter. Elements which don't match any of the model parameters are ignored. Alternatively, \code{start} may also be a named list with elements \code{"endemic"} or \code{"h"}, \code{"epidemic"} or \code{"e"}, \code{"siaf"} or \code{"e.siaf"}, and \code{"tiaf"} or \code{"e.tiaf"}, each of which containing a named numeric vector with the term labels as names (i.e. without the prefix \code{"h."}, \code{"e."}, etc). Thus, \code{start=list(endemic=c("(Intercept)"=-10))} is equivalent to \code{start=c("h.(Intercept)"=-10)}. } \item{partial}{ logical indicating if a partial likelihood similar to the approach by Diggle et al. (2010) should be used (default is \code{FALSE}). Note that the partial likelihood implementation is not well tested. } \item{epilink}{ a character string determining the link function to be used for the \code{epidemic} linear predictor of event marks. By default, the log-link is used. The experimental alternative \code{epilink = "identity"} (for use by \code{\link{epitest}}) does not guarantee the force of infection to be positive. If this leads to a negative total intensity (endemic + epidemic), the point process is not well defined (the log-likelihood will be \code{\link{NaN}}). } \item{control.siaf}{ a list with elements \code{"F"} and \code{"Deriv"}, which are lists of extra arguments passed to the functions \code{siaf$F} and \code{siaf$Deriv}, respectively.\cr These arguments control the accuracy of the cubature routines from package \pkg{polyCub} involved in non-constant \code{siaf} specifications, e.g., the bandwidth of the midpoint rule \code{\link[polyCub]{polyCub.midpoint}}, the number of Gaussian quadrature points for \code{\link[polyCub]{polyCub.SV}}, or the relative tolerance of \code{\link{integrate}} in \code{\link[polyCub]{polyCub.iso}}.\cr For instance, \code{\link{siaf.gaussian}(F.adaptive = TRUE)} uses the midpoint-cubature \code{\link[polyCub]{polyCub.midpoint}} with an adaptive bandwidth of \code{eps=adapt*sd} to numerically integrate the kernel \eqn{f(\bold{s})}, and the default \code{adapt} value (0.1) can be overwritten by setting \code{control.siaf$F$adapt}. However, the default version \code{siaf.gaussian()} as well as \code{\link{siaf.powerlaw}()} and friends use \code{\link[polyCub]{polyCub.iso}} and thus accept control arguments for the standard \code{\link{integrate}} routine (such as \code{rel.tol}) via \code{control.siaf$F} and \code{control.siaf$Deriv}.\cr This argument list is ignored in the case \code{siaf=siaf.constant()} (which is the default if \code{siaf} is unspecified). } \item{optim.args}{ an argument list passed to \code{\link{optim}}, or \code{NULL}, in which case no optimization will be performed but the necessary functions will be returned in a list (similar to what is returned if \code{model = TRUE}). Initial values for the parameters may be given as list element \code{par} in the order \code{(endemic, epidemic, siaf, tiaf)}. If no initial values are provided, crude estimates will be used for the endemic intercept and the Gaussian kernel, -9 for the epidemic intercept, and zeroes for the remaining parameters. Any initial values given in the \code{start} argument take precedence over those in \code{par}. Note that \code{optim} receives the negative log-likelihood for minimization (thus, if used, \code{optim.args$control$fnscale} should be positive). The \code{hessian} argument defaults to \code{TRUE}, and in the \code{control} list, \code{trace}ing is enabled with \code{REPORT=1} by default. By setting \code{optim.args$control$trace = 0}, all output from the optimization routine is suppressed. For the \code{partial} likelihood, the analytic score function and the Fisher information are not implemented and the default is to use robust \code{method="Nelder-Mead"} optimization. There may be an extra component \code{fixed} in the \code{optim.args} list, which determines which parameters should stick to their initial values. This can be specified by a logical vector of the same length as the \code{par} component, by an integer vector indexing \code{par} or by a character vector following the \code{twinstim} naming conventions. Furthermore, if \code{isTRUE(fixed)}, then all parameters are fixed at their initial values and no optimization is performed. Importantly, the \code{method} argument in the \code{optim.args} list may also be \code{"nlminb"}, in which case the \code{\link{nlminb}} optimizer is used. This is also the default for full likelihood inference. In this case, not only the score function but also the \emph{expected} Fisher information can be used during optimization (as estimated by what Martinussen and Scheike (2006, p. 64) call the \dQuote{optional variation process}, or see Rathbun (1996, equation (4.7))). In our experience this gives better convergence than \code{optim}'s methods. For \code{method="nlminb"}, the following parameters of the \code{optim.args$control} list may be named like for \code{optim} and are renamed appropriately: \code{maxit} (-> \code{iter.max}), \code{REPORT} (-> \code{trace}, default: 1), \code{abstol} (-> \code{abs.tol}), and \code{reltol} (-> \code{rel.tol}, default: \code{1e-6}). For \code{nlminb}, a logical \code{hessian} argument (default: \code{TRUE}) indicates if the negative \emph{expected} Fisher information matrix should be used as the Hessian during optimization (otherwise a numerical approximation is used). Similarly, \code{method="nlm"} should also work but is not recommended here. } \item{finetune}{ logical indicating if a second maximisation should be performed with robust Nelder-Mead \code{optim} using the resulting parameters from the first maximisation as starting point. This argument is only considered if \code{partial = FALSE} and the default is to not conduct a second maximization (in most cases this does not improve upon the MLE). } \item{model}{ logical indicating if the model environment should be kept with the result, which is required for \code{\link[=intensityplot.twinstim]{intensityplot}}s and \code{\link[=R0.twinstim]{R0}(..., trimmed = FALSE)}. Specifically, if \code{model=TRUE}, the return value will have the evaluation environment set as its \code{\link{environment}}, and the returned \code{functions} element will contain the log-likelihood function (or partial log-likelihood function, if \code{partial = TRUE}), and optionally the score and the expected Fisher information functions (not for the partial likelihood, and only if \code{siaf} and \code{tiaf} provide the necessary derivatives).\cr Note that fitted objects with a model environment might consume quite a lot of memory since they contain the \code{data}. } \item{cumCIF}{ logical (default: \code{FALSE}) indicating whether to calculate the fitted cumulative ground intensity at event times. This is the residual process, see \code{\link{residuals.twinstim}}. } \item{cumCIF.pb}{ logical indicating if a progress bar should be shown during the calculation of \code{cumCIF}. Defaults to do so in an interactive \R session, and will be \code{FALSE} if \code{cores != 1}. } \item{cores}{ number of processes to use in parallel operation. By default \code{twinstim} runs in single-CPU mode. Currently, only the \pkg{multicore}-type of parallel computing via forking is supported, which is not available on Windows, see \code{\link[parallel]{mclapply}} in package \pkg{parallel}. Note that for a \pkg{memoise}d \code{\link{siaf.step}} kernel, \code{cores=1} is fixed internally since parallelization would slow down model fitting significantly. } \item{verbose}{ logical indicating if information should be printed during execution. Defaults to \code{TRUE}. } } \details{ The function performs maximum likelihood inference for the additive-multiplicative spatio-temporal intensity model described in Meyer et al. (2012). It uses \code{\link{nlminb}} as the default optimizer and returns an object of class \code{"twinstim"}. Such objects have \code{print}, \code{\link[=plot.twinstim]{plot}} and \code{\link[=summary.twinstim]{summary}} methods. The \code{summary} output can be converted via corresponding \code{\link[=xtable.summary.twinstim]{xtable}} or \code{\link[=toLatex.summary.twinstim]{toLatex}} methods. Furthermore, the usual accessor methods are implemented, including \code{coef}, \code{vcov}, \code{logLik}, \code{\link[=residuals.twinstim]{residuals}}, and \code{update}. Additional functionality is provided by the \code{\link{R0}} and \code{\link[=simulate.twinstim]{simulate}} methods. } \value{ Returns an S3 object of class \code{"twinstim"}, which is a list with the following components: \item{coefficients}{vector containing the MLE.} \item{loglik}{value of the log-likelihood function at the MLE with a logical attribute \code{"partial"} indicating if the partial likelihood was used.} \item{counts}{number of log-likelihood and score evaluations during optimization.} \item{converged}{either \code{TRUE} (if the optimizer converged) or a character string containing a failure message.} \item{fisherinfo}{\emph{expected} Fisher information evaluated at the MLE. Only non-\code{NULL} for full likelihood inference (\code{partial = FALSE}) and if spatial and temporal interaction functions are provided with their derivatives.} \item{fisherinfo.observed}{observed Fisher information matrix evaluated at the value of the MLE. Obtained as the negative Hessian. Only non-\code{NULL} if \code{optim.args$method} is not \code{"nlminb"} and if it was requested by setting \code{hessian=TRUE} in \code{optim.args}.} \item{fitted}{fitted values of the conditional intensity function at the events.} \item{fittedComponents}{two-column matrix with columns \code{"h"} and \code{"e"} containing the fitted values of the endemic and epidemic components, respectively.\cr (Note that \code{rowSums(fittedComponents) == fitted}.)} \item{tau}{fitted cumulative ground intensities at the event times. Only non-\code{NULL} if \code{cumCIF = TRUE}. This is the \dQuote{residual process} of the model, see \code{\link{residuals.twinstim}}.} \item{R0}{estimated basic reproduction number for each event. This equals the spatio-temporal integral of the epidemic intensity over the observation domain (t0;T] x W for each event.} \item{npars}{vector describing the lengths of the 5 parameter subvectors: endemic intercept(s) \eqn{\beta_0(\kappa)}, endemic coefficients \eqn{\beta}, epidemic coefficients \eqn{\gamma}, parameters of the \code{siaf} kernel, and parameters of the \code{tiaf} kernel.} \item{qmatrix}{the \code{qmatrix} associated with the epidemic \code{data} as supplied in the model call.} \item{bbox}{the bounding box of \code{data$W}.} \item{timeRange}{the time range used for fitting: \code{c(t0,T)}.} \item{formula}{a list containing the four main parts of the model specification: \code{endemic}, \code{epidemic}, \code{siaf}, and \code{tiaf}.} \item{xlevels}{a record of the levels of the factors used in fitting.} \item{control.siaf}{see the \dQuote{Arguments} section above.} \item{optim.args}{input optimizer arguments used to determine the MLE.} \item{functions}{if \code{model=TRUE} this is a \code{list} with components \code{ll}, \code{sc} and \code{fi}, which are functions evaluating the log-likelihood, the score function and the expected Fisher information for a parameter vector \eqn{\theta}. The \code{environment} of these function is the model environment, which is thus retained in the workspace if \code{model=TRUE}. Otherwise, the \code{functions} component is \code{NULL}.} \item{call}{the matched call.} \item{runtime}{the \code{\link{proc.time}}-queried time taken to fit the model, i.e., a named numeric vector of length 5 of class \code{"proc_time"}, with the number of \code{cores} set as additional attribute.} If \code{model=TRUE}, the model evaluation environment is assigned to this list and can thus be queried by calling \code{environment()} on the result. } \note{ \code{twinstim} makes use of the \pkg{memoise} package if it is available -- and that is highly recommended for non-constant \code{siaf} specifications to speed up calculations. Specifically, the necessary numerical integrations of the spatial interaction function will be cached such that they are only calculated once for every state of the \code{siaf} parameters during optimization. } \references{ Diggle, P. J., Kaimi, I. & Abellana, R. (2010): Partial-likelihood analysis of spatio-temporal point-process data. \emph{Biometrics}, \bold{66}, 347-354. Martinussen, T. and Scheike, T. H. (2006): Dynamic Regression Models for Survival Data. Springer. Meyer, S. (2010): Spatio-Temporal Infectious Disease Epidemiology based on Point Processes. Master's Thesis, Ludwig-Maximilians-Universit\enc{}{ae}t M\enc{}{ue}nchen.\cr Available as \url{https://epub.ub.uni-muenchen.de/11703/} Meyer, S., Elias, J. and H\enc{}{oe}hle, M. (2012): A space-time conditional intensity model for invasive meningococcal disease occurrence. \emph{Biometrics}, \bold{68}, 607-616. \doi{10.1111/j.1541-0420.2011.01684.x} Meyer, S. and Held, L. (2014): Power-law models for infectious disease spread. \emph{The Annals of Applied Statistics}, \bold{8} (3), 1612-1639. \doi{10.1214/14-AOAS743} Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} Rathbun, S. L. (1996): Asymptotic properties of the maximum likelihood estimator for spatio-temporal point processes. \emph{Journal of Statistical Planning and Inference}, \bold{51}, 55-74. } \author{ Sebastian Meyer Contributions to this documentation by Michael H\enc{}{oe}hle and Mayeul Kauffmann. } \seealso{ \code{vignette("twinstim")}. There is a \code{\link{simulate.twinstim}} method, which simulates the point process based on the fitted \code{twinstim}. A discrete-space alternative is offered by the \code{\link{twinSIR}} modelling framework. } \examples{ # Load invasive meningococcal disease data data("imdepi") ### first, fit a simple endemic-only model m_noepi <- twinstim( endemic = addSeason2formula(~ offset(log(popdensity)) + I(start/365-3.5), S=1, period=365, timevar="start"), data = imdepi, subset = !is.na(agegrp) ) ## look at the model summary summary(m_noepi) ## there is no evidence for a type-dependent endemic intercept (LR test) m_noepi_type <- update(m_noepi, endemic = ~(1|type) + .) pchisq(2*c(logLik(m_noepi_type)-logLik(m_noepi)), df=1, lower.tail=FALSE) ### add an epidemic component with just the intercept, i.e. ### assuming uniform dispersal in time and space up to a distance of ### eps.s = 200 km and eps.t = 30 days (see summary(imdepi)) m0 <- update(m_noepi, epidemic=~1, model=TRUE) ## summarize the model fit summary(m0, correlation = TRUE, symbolic.cor = TRUE) ## the default confint-method can be used for Wald-CI's confint(m0, level=0.95) ## same "untrimmed" R0 for every event (simple epidemic intercept model) summary(R0(m0, trimmed=FALSE)) ## plot the path of the fitted total intensity plot(m0, "total intensity", tgrid=500) \dontshow{if (surveillance.options("allExamples")) \{} ## extract "residual process" integrating over space (takes some seconds) res <- residuals(m0) # if the model describes the true CIF well _in the temporal dimension_, # then this residual process should behave like a stationary Poisson # process with intensity 1 plot(res, type="l"); abline(h=c(0, length(res)), lty=2) # easier, with CI and serial correlation -> checkResidualProcess() checkResidualProcess(m0) \dontshow{\}} \dontrun{ ## NB: in contrast to nlminb(), optim's BFGS would miss the ## likelihood maximum wrt the epidemic intercept m0_BFGS <- update(m_noepi, epidemic=~1, optim.args = list(method="BFGS")) format(cbind(nlminb=coef(m0), BFGS=coef(m0_BFGS)), digits=3, scientific=FALSE) m0_BFGS$fisherinfo # singular Fisher information matrix here m0$fisherinfo logLik(m0_BFGS) logLik(m0) ## nlminb is more powerful since we make use of the analytical fisherinfo ## as estimated by the model during optimization, which optim cannot } ### an epidemic-only model? ## for a purely epidemic model, all events must have potential source events ## (otherwise the intensity at the observed event would be 0) ## let's focus on the C-type for this example imdepiC <- subset(imdepi, type == "C") table(summary(imdepiC)$nSources) ## 106 events have no prior, close events (in terms of eps.s and eps.t) try(twinstim(epidemic = ~1, data = imdepiC)) # detects this problem ## let's assume spatially unbounded interaction imdepiC_infeps <- update(imdepiC, eps.s = Inf) (s <- summary(imdepiC_infeps)) table(s$nSources) ## for 11 events, there is no prior event within eps.t = 30 days ## (which is certainly true for the first event) plot(s$counter, main = "Number of infectious individuals over time (eps.t = 30)") rug(imdepiC_infeps$events$time) rug(imdepiC_infeps$events$time[s$nSources == 0], col = 2, lwd = 3) ## An endemic component would catch such events (from unobserved sources), ## otherwise a longer infectious period would need to be assumed and ## for the first event to happen, a prehistory is required (e.g., t0 = 31). ## As an example, we fit the data only until T = 638 (all events have ancestors) m_epi <- twinstim(epidemic = ~1, data = imdepiC_infeps, t0 = 31, T = 638) summary(m_epi) \dontshow{if (surveillance.options("allExamples")) withAutoprint(\{} ### full model with interaction functions (time-consuming) ## estimate an exponential temporal decay of infectivity m1_tiaf <- update(m0, tiaf=tiaf.exponential()) plot(m1_tiaf, "tiaf", scaled=FALSE) ## estimate a step function for spatial interaction summary(sourceDists <- getSourceDists(imdepi, "space")) (knots <- quantile(sourceDists, c(5,10,20,40)/100)) m1_fstep <- update(m0, siaf=knots) plot(m1_fstep, "siaf", scaled=FALSE) rug(sourceDists, ticksize=0.02) ## estimate a continuously decreasing spatial interaction function, ## here we use the kernel of an isotropic bivariate Gaussian m1 <- update(m0, siaf = siaf.gaussian()) AIC(m_noepi, m0, m1_fstep, m1) summary(m1) # e.siaf.1 is log(sigma), no test for H0: log(sigma) = 0 exp(confint(m1, "e.siaf.1")) # a confidence interval for sigma plot(m1, "siaf", scaled=FALSE) ## alternative: siaf.powerlaw() with eps.s=Inf and untie()d data, ## see vignette("twinstim") ## add epidemic covariates m2 <- update(m1, epidemic = ~ 1 + type + agegrp) AIC(m1, m2) # further improvement summary(m2) ## look at estimated R0 values by event type tapply(R0(m2), imdepi$events@data[names(R0(m2)), "type"], summary) \dontshow{\})} } \keyword{models} \keyword{optimize} surveillance/man/plot.atwins.Rd0000644000176200001440000000415214326735553016311 0ustar liggesusers\name{plot.atwins} \alias{plot.atwins} \encoding{latin1} \title{Plots for Fitted \code{algo.twins} Models} \description{ Plot results of fitting a twins model using MCMC output. Plots similar to those in the Held et al. (2006) paper are generated. } \usage{ \method{plot}{atwins}(x, which=c(1,4,6,7), ask=TRUE, \dots) } \arguments{ \item{x}{An object of class \code{"atwins"} as returned by \code{\link{algo.twins}}.} \item{which}{a vector containing the different plot types to show \describe{ \item{1}{A plot of the observed time series Z is shown together with posterior means for the number of endemic cases (X) and number of epidemic cases (Y).} \item{2}{This plot shows trace plots of the gamma parameters over all MCMC samples.} \item{3}{This shows a trace plot of psi, which controls the overdispersion in the model.} \item{4}{Autocorrelation functions for K and psi are shown in order to judge whether the MCMC sampler has converged.} \item{5}{Shows a plot of the posterior mean of the seasonal model nu[t] together with 95\% credibility intervals based on the quantiles of the posterior.} \item{6}{Histograms illustrating the posterior density for K and psi. The first one corresponds to Fig. 4(f) in the paper.} \item{7}{Histograms illustrating the predictive posterior density for the next observed number of cases Z[n+1]. Compare with Fig.5 in the paper.} } } \item{ask}{Boolean indicating whether to ask for a newline before showing the next plot (only if multiple are shown).} \item{\dots}{Additional arguments for \code{\link{stsplot_time}}, used for plot type 1.} } \details{ For details see the plots in the paper. Basically MCMC output is visualized. This function is experimental, as is \code{\link{algo.twins}}. } %\value{NULL (invisibly)} \references{Held, L., Hofmann, M., \enc{Hhle}{Hoehle}, M. and Schmid V. (2006) A two-component model for counts of infectious diseases, Biostatistics, \bold{7}, pp. 422--437. } \author{M. Hofmann and M. \enc{Hhle}{Hoehle}} \seealso{\code{\link{algo.twins}} (with an example)} \keyword{hplot} surveillance/man/hhh4_W_utils.Rd0000644000176200001440000000211313117736473016362 0ustar liggesusers\name{hhh4_W_utils} \alias{getNEweights} \alias{coefW} \title{ Extract Neighbourhood Weights from a Fitted \code{hhh4} Model } \description{ The \code{getNEweights} function extracts the (fitted) weight matrix/array from a \code{"hhh4"} object, after scaling and normalization. The \code{coefW} function extracts the coefficients of parametric neighbourhood weights from a \code{hhh4} fit (or directly from a corresponding coefficient vector), i.e., coefficients whose names begin with \dQuote{neweights}. } \usage{ getNEweights(object, pars = coefW(object), scale = ne$scale, normalize = ne$normalize) coefW(object) } \arguments{ \item{object}{an object of class \code{"hhh4"}. \code{coefW} also works with the coefficient vector.} \item{pars}{coefficients for parametric neighbourhood weights, such as for models using \code{\link{W_powerlaw}}. Defaults to the corresponding point estimates in \code{object}.} \item{scale,normalize}{parameters of the \code{ne} component of \code{\link{hhh4}}.} } \author{ Sebastian Meyer } \keyword{utilities} surveillance/man/twinstim_iafplot.Rd0000644000176200001440000002205313100434734017405 0ustar liggesusers\encoding{latin1} \name{twinstim_iafplot} \alias{iafplot} \title{ Plot the Spatial or Temporal Interaction Function of a \code{twimstim} } \description{ The function plots the fitted temporal or (isotropic) spatial interaction function of a \code{twinstim} object. The implementation is illustrated in Meyer et al. (2017, Section 3), see \code{vignette("twinstim")}. } \usage{ iafplot(object, which = c("siaf", "tiaf"), types = NULL, scaled = c("intercept", "standardized", "no"), truncated = FALSE, log = "", conf.type = if (length(pars) > 1) "MC" else "parbounds", conf.level = 0.95, conf.B = 999, xgrid = 101, col.estimate = rainbow(length(types)), col.conf = col.estimate, alpha.B = 0.15, lwd = c(3,1), lty = c(1,2), verticals = FALSE, do.points = FALSE, add = FALSE, xlim = NULL, ylim = NULL, xlab = NULL, ylab = NULL, legend = !add && (length(types) > 1), ...) } \arguments{ \item{object}{ object of class \code{"twinstim"} containing the fitted model. } \item{which}{ argument indicating which of the two interaction functions to plot. Possible values are \code{"siaf"} (default) for the spatial interaction \eqn{f(x)} as a function of the distance \eqn{x}, and \code{"tiaf"} for the temporal interaction function \eqn{g(t)}. } \item{types}{ integer vector indicating for which event \code{types} the interaction function should be plotted in case of a marked \code{"twinstim"}. The default \code{types=NULL} checks if the interaction function is type-specific: if so, \code{types=1:nrow(object$qmatrix)} is used, otherwise \code{types=1}. } \item{scaled}{ character string determining if/how the the interaction function should be scaled. Possible choices are: \describe{ \item{"intercept":}{multiplication by the epidemic intercept.} \item{"standardized":}{division by the value at 0 distance such that the function starts at 1.} \item{"no":}{no scaling.} } The first one is the default and required for the comparison of estimated interaction functions from different models. For backward compatibility, \code{scaled} can also be a boolean, where \code{TRUE} refers to \code{"intercept"} scaling and \code{FALSE} to \code{"no"} scaling. } \item{truncated}{ logical indicating if the plotted interaction function should take the maximum range of interaction (\code{eps.t}/\code{eps.s}) into account, i.e., drop to zero at that point (if it is finite after all). If there is no common range of interaction, a \code{\link{rug}} indicating the various ranges will be added to the plot if \code{truncated=TRUE}. If \code{truncated} is a scalar, this value is used as the point \code{eps} where the function drops to 0. } \item{log}{a character string passed to \code{\link{plot.default}} indicating which axes should be logarithmic. If \code{add=TRUE}, \code{log} is set according to \code{par("xlog")} and \code{par("ylog")}.} \item{conf.type}{ type of confidence interval to produce.\cr If \code{conf.type="MC"} (or \code{"bootstrap"}), \code{conf.B} parameter vectors are sampled from the asymptotic (multivariate) normal distribution of the ML estimate of the interaction function parameters; the interaction function is then evaluated on the \code{xgrid} (i.e. temporal or spatial distances from the host) for each parameter realization to obtain a \code{conf.level} confidence interval at each point of the \code{xgrid} (or to plot the interaction functions of all Monte-Carlo samples if \code{conf.level=NA}). Note that the resulting plot is \code{\link{.Random.seed}}-dependent for the Monte-Carlo type of confidence interval.\cr If \code{conf.type="parbounds"}, the \code{conf.level} Wald confidence intervals for the interaction function parameters are calculated and the interaction function is evaluated on the \code{xgrid} (distances from the host) for all combinations of the bounds of the parameters and the point-wise extremes of those functions are plotted. This type of confidence interval is only valid in case of a single parameter, i.e. \code{scaled + nsiafpars == 1}, but could also be used as a rough indication if the Monte-Carlo approach takes too long. A warning is thrown if the \code{"parbounds"} type is used for multiple parameters.\cr If \code{conf.type="none"} or \code{NA} or \code{NULL}, no confidence interval will be calculated. } \item{conf.level}{ the confidence level required. For \code{conf.type = "MC"} it may also be specified as \code{NA}, in which case all \code{conf.B} sampled functions will be plotted with transparency value given by \code{alpha.B}. } \item{conf.B}{ number of samples for the \code{"MC"} (Monte Carlo) confidence interval. } \item{xgrid}{ either a numeric vector of x-values (distances from the host) where to evaluate \code{which}, or a scalar representing the desired number of evaluation points in the interval \code{c(0,xlim[2])}.\cr If the interaction function is a step function (\code{\link{siaf.step}} or \code{\link{tiaf.step}}), \code{xgrid} is ignored and internally set to \code{c(0, knots)}. } \item{col.estimate}{ vector of colours to use for the function point estimates of the different \code{types}. } \item{col.conf}{ vector of colours to use for the confidence intervals of the different \code{types}. } \item{alpha.B}{ alpha transparency value (as relative opacity) used for the \code{conf.B} sampled interaction functions in case \code{conf.level = NA} } \item{lwd, lty}{ numeric vectors of length two specifying the line width and type of point estimates (first element) and confidence limits (second element), respectively. } \item{verticals,do.points}{graphical settings for step function kernels. These can be logical (as in \code{\link{plot.stepfun}}) or lists of graphical parameters.} \item{add}{ add to an existing plot? } \item{xlim, ylim}{ vectors of length two containing the x- and y-axis limit of the plot. The default y-axis range (\code{ylim=NULL}) is from 0 to the value of the (scaled) interaction function at \eqn{x = 0}. The default x-axis (\code{xlim=NULL}) starts at 0, and the upper limit is determined as follows (in decreasing order of precedence): \itemize{ \item If \code{xgrid} is a vector of evaluation points, \code{xlim[2]} is set to \code{max(xgrid)}. \item \code{eps.t}/\code{eps.s} if it is unique and finite. \item If the interaction function is a step function with \code{maxRange= 1) to be in the palette.} \item{use.color}{logical. Should the palette use colors? Otherwise grey levels are returned.} } \value{ A character vector of \code{ncolors} colors. } \examples{ barplot(rep(1,10), col = surveillance:::.hcl.colors(10), axes = FALSE) } \keyword{color} \keyword{dplot} \keyword{internal} surveillance/man/stsplot_spacetime.Rd0000644000176200001440000000672314404102775017566 0ustar liggesusers\encoding{latin1} \name{stsplot_spacetime} \alias{stsplot_spacetime} \title{ Animated Map of Disease Incidence (DEPRECATED) } \description{ For each period (row) or for the overall period of the \code{observed} matrix of the \code{"\linkS4class{sts}"} object, a map showing the counts by region is produced. It is possible to redirect the output into files, e.g., to generate an animated GIF. } \usage{ stsplot_spacetime(x, type, legend = NULL, opts.col = NULL, labels = TRUE, wait.ms = 250, cex.lab = 0.7, verbose = FALSE, dev.printer = NULL, ...) } \arguments{ \item{x}{ an object of class \code{"\linkS4class{sts}"}. } \item{type}{ a formula (see \code{\link{stsplot}}). For a map aggregated over time (no animation), use \code{observed ~ 1 | unit}, otherwise \code{observed ~ 1 | unit * time}. } \item{legend}{ a \code{list} containing the following items used for coloring \describe{ \item{\code{dx}}{position increments in x direction} \item{\code{dy}}{position increments in y direction} \item{\code{x}}{position in x} \item{\code{y}}{position in y} \item{\code{once}}{a Boolean; if \code{TRUE} then only shown once} } If \code{NULL} then a default legend is used. } \item{opts.col}{ a \code{list} containing the two elements \describe{ \item{\code{ncolors}}{number of colors to use for plotting} \item{\code{use.color}}{a Boolean; if \code{TRUE} then colors will be used in the palette, otherwise grayscale} } } \item{labels}{Boolean whether to add labels } \item{wait.ms}{Number of milliseconds to wait between each plot } \item{cex.lab}{\code{cex} of the labels } \item{verbose}{Boolean whether to write out extra information } \item{dev.printer}{Either \code{NULL} (default), which means that plotting is only to the screen, or a list with elements \code{device}, \code{extension}, \code{width}, \code{height}, and \code{name} (with defaults \code{png}, \code{".png"}, \code{640}, \code{480}, and \code{"Rplot"}, respectively) to \code{\link{dev.print}} the plots to files (only works in interactive sessions). This option is more or less obsolete since the \pkg{animation} package provides better features for output to files. } \item{\dots}{Extra arguments sent to the plot function. } } \author{ Michael H\enc{}{oe}hle } \note{ The \code{\link{animate.sts}} method provides a re-implementation and supersedes this function! } \seealso{ Other \code{\link{stsplot}} types, and \code{\link{animate.sts}} for the new implementation. } \examples{ data("ha.sts") print(ha.sts) \dontshow{if (surveillance.options("allExamples")) \{} ## map of total counts by district (compare old vs. new implementation) plot(ha.sts, type = observed ~ 1 | unit) plot(ha.sts, type = observed ~ unit, labels = TRUE) \dontshow{\}} \dontrun{ # space-time animation plot(aggregate(ha.sts,nfreq=13), type = observed ~ 1 | unit * time) #print the frames to a png device #and do the animation without extra sleeping between frames imgname <- file.path(tempdir(), "berlin") plot(aggregate(ha.sts,nfreq=13), type = observed ~ 1 | unit * time, wait.ms=0, dev.printer=list(name=imgname)) #Use ImageMagick (you might have to adjust the path to 'convert') system(paste0("convert -delay 50 ", imgname, "*.png ", imgname, "-animated.gif")) } } \keyword{hplot} \keyword{dynamic} \keyword{spatial} \keyword{internal} surveillance/man/measlesDE.Rd0000644000176200001440000000250214026701226015651 0ustar liggesusers\name{measlesDE} \alias{measlesDE} \docType{data} \title{Measles in the 16 states of Germany} \description{ Weekly number of measles cases in the 16 states (Bundeslaender) of Germany for years 2005 to 2007. } \usage{data(measlesDE)} \format{ An \code{"\linkS4class{sts}"} object containing \eqn{156\times 16}{156 x 16} observations starting from week 1 in 2005. The \code{population} slot contains the population fractions of each state at 31.12.2006, obtained from the Federal Statistical Office of Germany. } \source{ Robert Koch-Institut: SurvStat: \url{https://survstat.rki.de/}; Queried on 14 October 2009. } \seealso{\code{\link{MMRcoverageDE}}} \examples{ data(measlesDE) plot(measlesDE) ## aggregate to bi-weekly intervals measles2w <- aggregate(measlesDE, nfreq = 26) plot(measles2w, type = observed ~ time) ## use a date index for nicer x-axis plotting epoch(measles2w) <- seq(as.Date("2005-01-03"), by = "2 weeks", length.out = nrow(measles2w)) plot(measles2w, type = observed ~ time) } \references{ Herzog, S. A., Paul, M. and Held, L. (2011): Heterogeneity in vaccination coverage explains the size and occurrence of measles epidemics in German surveillance data. \emph{Epidemiology and Infection}, \bold{139}, 505-515. \doi{10.1017/S0950268810001664} } \keyword{datasets} surveillance/man/ranef.Rd0000644000176200001440000000062112716552041015105 0ustar liggesusers\name{ranef} \alias{ranef} \alias{fixef} \docType{import} \title{Import from package \pkg{nlme}} \description{ The generic functions \code{ranef} and \code{fixef} are imported from package \pkg{nlme}. See \code{\link[nlme:ranef]{nlme::ranef}} for \pkg{nlme}'s own description, and \code{\link{ranef.hhh4}} or \code{\link{fixef.hhh4}} for the added methods for \code{"\link{hhh4}"} models. } surveillance/man/plapply.Rd0000644000176200001440000000731014614775012015501 0ustar liggesusers\name{plapply} \alias{plapply} \title{Verbose and Parallel \code{lapply}} \description{ Verbose and parallelized version of \code{lapply} wrapping around \code{\link[parallel]{mclapply}} and \code{\link[parallel]{parLapply}} in the base package \pkg{parallel}. This wrapper can take care of the \code{.Random.seed} and print progress information (not for cluster-based parallelization). With the default arguments it equals \code{lapply} enriched by a progress bar. } \usage{ plapply(X, FUN, ..., .parallel = 1, .seed = NULL, .verbose = TRUE) } \arguments{ \item{X,FUN,\dots}{see \code{\link{lapply}}.} \item{.parallel}{ the number of processes to use in parallel operation, or a \code{"cluster"} object (see \code{\link[parallel]{makeCluster}}). If a number, \code{\link[parallel]{mclapply}} (forking) is used on Unix-alikes, whereas on Windows \code{\link[parallel]{parLapply}} is used on a newly created cluster of the specified size, which is stopped when exiting the function. By default (\code{.parallel = 1}), the basic \code{\link{lapply}} is used. } \item{.seed}{ If set (non-\code{NULL}), results involving random number generation become reproducible. If using a cluster (see the \code{.parallel} argument), \code{\link[parallel]{clusterSetRNGStream}} is called with the specified \code{.seed} before running \code{parLapply}. Otherwise, \code{\link{set.seed}(.seed)} is called and the \code{\link{RNGkind}} is changed to \code{"L'Ecuyer-CMRG"} if \code{.parallel > 1} (see the section on random numbers in the documentation of \code{mcparallel} in package \pkg{parallel}). % no link to mcparallel since it is not available on Windows (R-3.1.2) If \code{.seed} is non-\code{NULL}, the original \code{\link{.Random.seed}} will be restored \code{on.exit} of the function. } \item{.verbose}{ if and how progress information should be displayed, i.e., what to do on each exit of \code{FUN}. This is unsupported and ignored for cluster-based parallelization and primitive \code{FUN}ctions. The default (\code{TRUE}) will show a \code{\link{txtProgressBar}} (if \code{.parallel = 1} in an \code{\link{interactive}} \R session) or \code{cat(".")} (otherwise). Other choices for the dot are possible by specifying the desired symbol directly as the \code{.verbose} argument. Alternatively, \code{.verbose} may be any custom call or expression to be executed \code{\link{on.exit}} of \code{FUN} and may thus involve any objects from the local evaluation environment. } } \value{ a list of the results of calling \code{FUN} on each value of \code{X}. } \author{ Sebastian Meyer } \seealso{ \code{\link[parallel]{mclapply}} and \code{\link[parallel]{parLapply}} } \examples{ ## example inspired by help("lapply") x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE,FALSE,FALSE,TRUE)) ## if neither parallel nor verbose then this simply equals lapply() plapply(x, quantile, probs = 1:3/4, .verbose = FALSE) ## verbose lapply() -- not really useful for such fast computations res <- plapply(x, quantile, probs = 1:3/4, .verbose = TRUE) res <- plapply(x, quantile, probs = 1:3/4, .verbose = "|") res <- plapply(x, quantile, probs = 1:3/4, .verbose = quote(cat("length(x) =", length(x), "\n"))) ## setting the seed for reproducibility of results involving the RNG samp <- plapply(as.list(1:3), runif, .seed = 1) ## parallel lapply() res <- plapply(x, quantile, probs = 1:3/4, .parallel = 2, .verbose = FALSE) ## using a predefined cluster library("parallel") cl <- makeCluster(getOption("cl.cores", 2)) res <- plapply(x, quantile, probs = 1:3/4, .parallel = cl) stopCluster(cl) } \keyword{iteration} \keyword{list} surveillance/man/epidata_intersperse.Rd0000644000176200001440000000333213433306243020044 0ustar liggesusers\name{epidata_intersperse} \alias{intersperse} \title{ Impute Blocks for Extra Stops in \code{"epidata"} Objects } \description{ This function modifies an object inheriting from class \code{"epidata"} such that it features the specified stop time points. For this purpose, the time interval in the event history into which the new stop falls will be split up into two parts, one block for the time period until the new stop -- where no infection or removal occurs -- and the other block for the time period from the new stop to the end of the original interval.\cr Main application is to enable the use of \code{knots} in \code{twinSIR}, which are not existing stop time points in the \code{"epidata"} object. } \usage{ intersperse(epidata, stoptimes, verbose = FALSE) } \arguments{ \item{epidata}{ an object inheriting from class \code{"epidata"}. } \item{stoptimes}{ a numeric vector of time points inside the observation period of the \code{epidata}. } \item{verbose}{ logical indicating if a \code{\link{txtProgressBar}} should be shown while inserting blocks for extra \code{stoptimes}. } } \value{ an object of the same class as \code{epidata} with additional time blocks for any new \code{stoptimes}. } \author{ Sebastian Meyer } \seealso{ \code{\link{as.epidata.epidataCS}} where this function is used. } \examples{ data("hagelloch") subset(hagelloch, start < 25 & stop > 25 & id \%in\% 9:13, select = 1:7) # there is no "stop" time at 25, but we can add this extra stop nrow(hagelloch) moreStopsEpi <- intersperse(hagelloch, stoptimes = 25) nrow(moreStopsEpi) subset(moreStopsEpi, (stop == 25 | start == 25) & id \%in\% 9:13, select = 1:7) } \keyword{spatial} \keyword{manip} surveillance/man/stsAggregate.Rd0000644000176200001440000000320513507405136016434 0ustar liggesusers\name{aggregate-methods} \docType{methods} \alias{aggregate.sts} \alias{aggregate,sts-method} \title{Aggregate an \code{"sts"} Object Over Time or Across Units} \description{ Aggregate the matrix slots of an \code{"\linkS4class{sts}"} object. Either the time series is aggregated so a new sampling frequency of \code{nfreq} observations per year is obtained (i.e., as in \code{\link{aggregate.ts}}), or the aggregation is over all columns (units). } \usage{ \S4method{aggregate}{sts}(x, by = "time", nfreq = "all", ...) } \arguments{ \item{x}{an object of class \code{"\linkS4class{sts}"}.} \item{by}{a string being either \code{"time"} or \code{"unit"}.} \item{nfreq}{new sampling frequency for \code{by="time"}. If \code{nfreq="all"} then all time points are summed.} \item{\dots}{unused (argument of the generic).} } \value{ an object of class \code{"sts"}. } \section{Warning}{ Aggregation over units fills the upperbound slot with \code{NA}s and the \code{map} slot is left as-is, but the object cannot be plotted by unit any longer. The \code{populationFrac} slot is aggregated just like \code{observed}. Population fractions are recomputed if and only if \code{x} is no \code{multinomialTS} and already contains population fractions. This might not be intended, especially for aggregation over time. } \examples{ data("ha.sts") dim(ha.sts) dim(aggregate(ha.sts, by = "unit")) dim(aggregate(ha.sts, nfreq = 13)) \dontshow{ ## population(ha.sts) are trivial fractions, aggregate() should keep them stopifnot(population(aggregate(ha.sts)) == 1/ncol(ha.sts)) ## failed in surveillance <= 1.16.2 } } \keyword{methods} surveillance/man/husO104Hosp.Rd0000644000176200001440000000535513234140561016014 0ustar liggesusers\encoding{latin1} \name{husO104Hosp} \alias{husO104Hosp} \docType{data} \title{Hospitalization date for HUS cases of the STEC outbreak in Germany, 2011} \description{ Data contain the date of hospitalization for 630 hemolytic-uremic syndrome (HUS) cases during the large STEC outbreak in Germany, 2011. Note: Only HUS cases which ultimately had a hospitalization date available/reported are included in the data set. The total number of HUS cases during the outbreak was 855 -- see \enc{Hhle}{Hoehle} and an der Heiden (2014) as well as Frank et al. (2011) for details. For each HUS case the attribute \code{dHosp} contains the date of hospitalization and the attribute \code{dReport} contains the date of first arrival of this hospitalization date at the Robert Koch Institute (RKI). As described in \enc{Hhle}{Hoehle} and an der Heiden (2014) the mechanisms of the delay were complicated and should be interpreted with care. For example, the case report could have arrived earlier, but without information about the hospitalization date. The resulting reporting triangle corresponds to Fig. 1 of the Web appendix of \enc{Hhle}{Hoehle} and an der Heiden (2014). This means that the reports which arrived with a delay longer than 15 days are set to have have arrived after 15 days. Altogether, this gives small discrepancies when compared with the results of the paper. However, as mentioned in the paper, longer delays were not very relevant for the nowcasting. } \usage{data(husO104Hosp)} \format{ A \code{data.frame} object. } \source{ Data were collected during the outbreak as part of the mandatory reporting of notifiable diseases in Germany (Faensen et al., 2006). Here, reports are transmitted from the local health authorities via the state health authorities to the Robert Koch Institute, Berlin. The resulting reporting triangle corresponds to Fig. 1 of the Web appendix of \enc{Hhle}{Hoehle} and an der Heiden (2014). } \references{ \enc{Hhle}{Hoehle} M and an der Heiden, M (2014). Bayesian Nowcasting during the STEC O104:H4 Outbreak in Germany, 2011, In revision for Biometrics. Frank C, Werber D, Cramer JP, Askar M, Faber M, an der Heiden M, Bernard H, Fruth A, Prager R, Spode A, Wadl M, Zoufaly A, Jordan S, Kemper MJ, Follin P, \enc{Mller}{Mueller} L, King LA, Rosner B, Buchholz U, Stark K, Krause G; HUS Investigation Team (2011). Epidemic Profile of Shiga-Toxin Producing Escherichia coli O104:H4 Outbreak in Germany, N Engl J Med. 2011 Nov 10;365(19):1771-80. Faensen D, Claus H, Benzler J, Ammon A, Pfoch T, Breuer T, Krause G (2014). SurvNet@RKI - a multistate electronic reporting system for communicable diseases, Euro Surveillance, 2006;11(4):100-103. } \keyword{datasets} surveillance/man/salmAllOnset.Rd0000644000176200001440000000130313234140561016402 0ustar liggesusers\encoding{latin1} \docType{data} \name{salmAllOnset} \alias{salmAllOnset} \title{Salmonella cases in Germany 2001-2014 by data of symptoms onset} \format{A sts-object} \usage{ data(salmAllOnset) } \description{ A dataset containing the reported number of cases of Salmonella in Germany 2001-2014 aggregated by data of disease onset. The slot \code{control} contains a matrix \code{reportingTriangle$n} with the reporting triangle as described in Salmon et al. (2015). } \references{ Salmon, M., Schumacher, D., Stark, K., \enc{Hhle}{Hoehle}, M. (2015): Bayesian outbreak detection in the presence of reporting delays. Biometrical Journal, 57 (6), 1051-1067. } \keyword{datasets} surveillance/man/arlCusum.Rd0000644000176200001440000000350313122471774015614 0ustar liggesusers\name{arlCusum} \alias{arlCusum} \title{Calculation of Average Run Length for discrete CUSUM schemes} \description{ Calculates the average run length (ARL) for an upward CUSUM scheme for discrete distributions (i.e. Poisson and binomial) using the Markov chain approach. } \usage{ arlCusum(h=10, k=3, theta=2.4, distr=c("poisson","binomial"), W=NULL, digits=1, ...) } \arguments{ \item{h}{ decision interval} \item{k}{ reference value} \item{theta}{distribution parameter for the cumulative distribution function (cdf) \eqn{F}, i.e. rate \eqn{\lambda} for Poisson variates or probability \eqn{p} for binomial variates} \item{distr}{ \code{"poisson"} or \code{"binomial"} } %ppois, pbinom \item{W}{Winsorizing value \code{W} for a robust CUSUM, to get a nonrobust CUSUM set %\code{W} is set to \code{W} > \code{k}+\code{h}. If \code{NULL}, a nonrobust CUSUM is used.} \item{digits}{ \code{k} and \code{h} are rounded to \code{digits} decimal places } \item{\dots}{ further arguments for the distribution function, i.e. number of trials \code{n} for binomial cdf } } \value{ Returns a list with the ARL of the regular (zero-start) and the fast initial response (FIR) CUSUM scheme with reference value \code{k}, decision interval \code{h} for \eqn{X \sim F(\theta)}, where F is the Poisson or binomial CDF. \item{ARL}{one-sided ARL of the regular (zero-start) CUSUM scheme} \item{FIR.ARL}{one-sided ARL of the FIR CUSUM scheme with head start \eqn{\frac{\code{h}}{2}} } } \keyword{models} \source{Based on the FORTRAN code of Hawkins, D. M. (1992). Evaluation of Average Run Lengths of Cumulative Sum Charts for an Arbitrary Data Distribution. Communications in Statistics - Simulation and Computation, 21(4), p. 1001-1020. } surveillance/man/influMen.Rd0000644000176200001440000000113113174706302015564 0ustar liggesusers\name{influMen} \alias{influMen} \docType{data} \title{Influenza and meningococcal infections in Germany, 2001-2006} \description{ Weekly counts of new influenza and meningococcal infections in Germany 2001-2006. } \usage{data(influMen)} \format{ A \code{disProg} object containing \eqn{312\times 2}{312 x 2} observations starting from week 1 in 2001 to week 52 in 2006. } \source{ Robert Koch-Institut: SurvStat: \url{https://survstat.rki.de/}. Queried on 25 July 2007. } \examples{ data(influMen) plot(influMen, as.one=FALSE, same.scale=FALSE) } \keyword{datasets} surveillance/man/marks.Rd0000644000176200001440000000055513777627613015155 0ustar liggesusers\name{marks} \alias{marks} \docType{import} \title{Import from package \pkg{spatstat.geom}} \description{ The generic function \code{marks} is imported from package \pkg{spatstat.geom}. See \code{\link[spatstat.geom:marks]{spatstat.geom::marks}} for \pkg{spatstat.geom}'s own methods, and \code{\link{marks.epidataCS}} for the \code{"epidataCS"}-specific method. } surveillance/man/hhh4.Rd0000644000176200001440000005640414405577351014667 0ustar liggesusers\encoding{latin1} \name{hhh4} \alias{hhh4} \title{Fitting HHH Models with Random Effects and Neighbourhood Structure} \description{ Fits an autoregressive Poisson or negative binomial model to a univariate or multivariate time series of counts. The characteristic feature of \code{hhh4} models is the additive decomposition of the conditional mean into \emph{epidemic} and \emph{endemic} components (Held et al, 2005). Log-linear predictors of covariates and random intercepts are allowed in all components; see the Details below. A general introduction to the \code{hhh4} modelling approach and its implementation is given in the \code{vignette("hhh4")}. Meyer et al (2017, Section 5, available as \code{vignette("hhh4_spacetime")}) describe \code{hhh4} models for areal time series of infectious disease counts. } \usage{ hhh4(stsObj, control = list( ar = list(f = ~ -1, offset = 1, lag = 1), ne = list(f = ~ -1, offset = 1, lag = 1, weights = neighbourhood(stsObj) == 1, scale = NULL, normalize = FALSE), end = list(f = ~ 1, offset = 1), family = c("Poisson", "NegBin1", "NegBinM"), subset = 2:nrow(stsObj), optimizer = list(stop = list(tol=1e-5, niter=100), regression = list(method="nlminb"), variance = list(method="nlminb")), verbose = FALSE, start = list(fixed=NULL, random=NULL, sd.corr=NULL), data = list(t = stsObj@epoch - min(stsObj@epoch)), keep.terms = FALSE ), check.analyticals = FALSE) } \arguments{ \item{stsObj}{object of class \code{"\linkS4class{sts}"} containing the (multivariate) count data time series.} \item{control}{a list containing the model specification and control arguments: \describe{ \item{\code{ar}}{Model for the autoregressive component given as list with the following components: \describe{ \item{f = ~ -1}{a formula specifying \eqn{\log(\lambda_{it})}{log(\lambda_it)}} \item{offset = 1}{optional multiplicative offset, either 1 or a matrix of the same dimension as \code{observed(stsObj)}} \item{lag = 1}{a positive integer meaning autoregression on \eqn{y_{i,t-lag}}} } } \item{\code{ne}}{Model for the neighbour-driven component given as list with the following components: \describe{ \item{f = ~ -1}{a formula specifying \eqn{\log(\phi_{it})}{log(\phi_it)}} \item{offset = 1}{optional multiplicative offset, either 1 or a matrix of the same dimension as \code{observed(stsObj)}} \item{lag = 1}{a non-negative integer meaning dependency on \eqn{y_{j,t-lag}}} \item{weights = neighbourhood(stsObj) == 1}{ neighbourhood weights \eqn{w_{ji}}{w_ji}. The default corresponds to the original formulation by Held et al (2005), i.e., the spatio-temporal component incorporates an unweighted sum over the lagged cases of the first-order neighbours. See Paul et al (2008) and Meyer and Held (2014) for alternative specifications, e.g., \code{\link{W_powerlaw}}. Time-varying weights are possible by specifying an array of \code{dim()} \code{c(nUnits, nUnits, nTime)}, where \code{nUnits=ncol(stsObj)} and \code{nTime=nrow(stsObj)}.} \item{scale = NULL}{ optional matrix of the same dimensions as \code{weights} (or a vector of length \code{ncol(stsObj)}) to scale the \code{weights} to \code{scale * weights}. } \item{normalize = FALSE}{ logical indicating if the (scaled) \code{weights} should be normalized such that each row sums to 1. } } } \item{\code{end}}{Model for the endemic component given as list with the following components \describe{ \item{f = ~ 1}{a formula specifying \eqn{\log(\nu_{it})}{log(\nu_it)}} \item{offset = 1}{optional multiplicative offset \eqn{e_{it}}{e_it}, either 1 or a matrix of the same dimension as \code{observed(stsObj)}} } } \item{\code{family}}{Distributional family -- either \code{"Poisson"}, or the Negative Binomial distribution. For the latter, the overdispersion parameter can be assumed to be the same for all units (\code{"NegBin1"}), to vary freely over all units (\code{"NegBinM"}), or to be shared by some units (specified by a factor of length \code{ncol(stsObj)} such that its number of levels determines the number of overdispersion parameters). Note that \code{"NegBinM"} is equivalent to \code{factor(colnames(stsObj), levels = colnames(stsObj))}. } \item{\code{subset}}{Typically \code{2:nrow(obs)} if model contains autoregression} \item{\code{optimizer}}{a list of three lists of control arguments. The \code{"stop"} list specifies two criteria for the outer optimization of regression and variance parameters: the relative \code{tol}erance for parameter change using the criterion \code{max(abs(x[i+1]-x[i])) / max(abs(x[i]))}, and the maximum number \code{niter} of outer iterations. Control arguments for the single optimizers are specified in the lists named \code{"regression"} and \code{"variance"}. \code{method="nlminb"} is the default optimizer for both (taking advantage of the analytical Fisher information matrices), however, the \code{method}s from \code{\link{optim}} may also be specified (as well as \code{"\link{nlm}"} but that one is not recommended here). Especially for the variance updates, Nelder-Mead optimization (\code{method="Nelder-Mead"}) is an attractive alternative. All other elements of these two lists are passed as \code{control} arguments to the chosen \code{method}, e.g., if \code{method="nlminb"}, adding \code{iter.max=50} increases the maximum number of inner iterations from 20 (default) to 50. For \code{method="Nelder-Mead"}, the respective argument is called \code{maxit} and defaults to 500. } \item{\code{verbose}}{non-negative integer (usually in the range \code{0:3}) specifying the amount of tracing information to be output during optimization.} \item{\code{start}}{a list of initial parameter values replacing initial values set via \code{\link{fe}} and \code{\link{ri}}. Since \pkg{surveillance} 1.8-2, named vectors are matched against the coefficient names in the model (where unmatched start values are silently ignored), and need not be complete, e.g., \code{start = list(fixed = c("-log(overdisp)" = 0.5))} (default: 2) for a \code{family = "NegBin1"} model. In contrast, an unnamed start vector must specify the full set of parameters as used by the model.} \item{\code{data}}{a named list of covariates that are to be included as fixed effects (see \code{\link{fe}}) in any of the 3 component formulae. By default, the time variable \code{t} is available and used for seasonal effects created by \code{\link{addSeason2formula}}. In general, covariates in this list can be either vectors of length \code{nrow(stsObj)} interpreted as time-varying but common across all units, or matrices of the same dimension as the disease counts \code{observed(stsObj)}.} \item{\code{keep.terms}}{logical indicating if the terms object used in the fit is to be kept as part of the returned object. This is usually not necessary, since the terms object is reconstructed by the \code{\link{terms}}-method for class \code{"hhh4"} if necessary (based on \code{stsObj} and \code{control}, which are both part of the returned \code{"hhh4"} object).} } The auxiliary function \code{\link{makeControl}} might be useful to create such a list of control parameters. } \item{check.analyticals}{logical (or a subset of \code{c("numDeriv", "maxLik")}), indicating if (how) the implemented analytical score vector and Fisher information matrix should be checked against numerical derivatives at the parameter starting values, using the packages \pkg{numDeriv} and/or \pkg{maxLik}. If activated, \code{hhh4} will return a list containing the analytical and numerical derivatives for comparison (no ML estimation will be performed). This is mainly intended for internal use by the package developers.} } \value{ \code{hhh4} returns an object of class \code{"hhh4"}, which is a list containing the following components: \item{coefficients}{named vector with estimated (regression) parameters of the model} \item{se}{estimated standard errors (for regression parameters)} \item{cov}{covariance matrix (for regression parameters)} \item{Sigma}{estimated variance-covariance matrix of random effects} \item{Sigma.orig}{estimated variance parameters on internal scale used for optimization} \item{Sigma.cov}{inverse of marginal Fisher information (on internal scale), i.e., the asymptotic covariance matrix of \code{Sigma.orig}} \item{call}{ the matched call } \item{dim}{ vector with number of fixed and random effects in the model } \item{loglikelihood}{(penalized) loglikelihood evaluated at the MLE} \item{margll}{ (approximate) log marginal likelihood should the model contain random effects } \item{convergence}{logical. Did optimizer converge?} \item{fitted.values}{fitted mean values \eqn{\mu_{i,t}}{\mu_it}} \item{control}{control object of the fit} \item{terms}{the terms object used in the fit if \code{keep.terms = TRUE} and \code{NULL} otherwise} \item{stsObj}{ the supplied \code{stsObj} } \item{lags}{named integer vector of length two containing the lags used for the epidemic components \code{"ar"} and \code{"ne"}, respectively. The corresponding lag is \code{NA} if the component was not included in the model.} \item{nObs}{number of observations used for fitting the model} \item{nTime}{ number of time points used for fitting the model } \item{nUnit}{ number of units (e.g. areas) used for fitting the model} \item{runtime}{the \code{\link{proc.time}}-queried time taken to fit the model, i.e., a named numeric vector of length 5 of class \code{"proc_time"}} } \details{ An endemic-epidemic multivariate time-series model for infectious disease counts \eqn{Y_{it}}{Y_it} from units \eqn{i=1,\dots,I} during periods \eqn{t=1,\dots,T} was proposed by Held et al (2005) and was later extended in a series of papers (Paul et al, 2008; Paul and Held, 2011; Held and Paul, 2012; Meyer and Held, 2014). In its most general formulation, this so-called \code{hhh4} (or HHH or \eqn{H^3} or triple-H) model assumes that, conditional on past observations, \eqn{Y_{it}}{Y_it} has a Poisson or negative binomial distribution with mean \deqn{\mu_{it} = \lambda_{it} y_{i,t-1} + \phi_{it} \sum_{j\neq i} w_{ji} y_{j,t-1} + e_{it} \nu_{it} }{% \mu_it = \lambda_it y_i,t-1 + \phi_it sum_(j != i) w_ji y_j,t-1 + e_it \nu_it } In the case of a negative binomial model, the conditional variance is \eqn{\mu_{it}(1+\psi_i\mu_{it})}{\mu_it(1+\psi_i*\mu_it)} with overdispersion parameters \eqn{\psi_i > 0} (possibly shared across different units, e.g., \eqn{\psi_i\equiv\psi}{\psi_i=\psi}). Univariate time series of counts \eqn{Y_t} are supported as well, in which case \code{hhh4} can be regarded as an extension of \code{\link[MASS]{glm.nb}} to account for autoregression. See the Examples below for a comparison of an endemic-only \code{hhh4} model with a corresponding \code{glm.nb}. The three unknown quantities of the mean \eqn{\mu_{it}}{\mu_it}, \itemize{ \item \eqn{\lambda_{it}}{\lambda_it} in the autoregressive (\code{ar}) component, \item \eqn{\phi_{it}}{\phi_it} in the neighbour-driven (\code{ne}) component, and \item \eqn{\nu_{it}}{\nu_it} in the endemic (\code{end}) component, } are log-linear predictors incorporating time-/unit-specific covariates. They may also contain unit-specific random intercepts as proposed by Paul and Held (2011). The endemic mean is usually modelled proportional to a unit-specific offset \eqn{e_{it}}{e_it} (e.g., population numbers or fractions); it is possible to include such multiplicative offsets in the epidemic components as well. The \eqn{w_{ji}}{w_ji} are transmission weights reflecting the flow of infections from unit \eqn{j} to unit \eqn{i}. If weights vary over time (prespecified as a 3-dimensional array \eqn{(w_{jit})}{(w_jit)}), the \code{ne} sum in the mean uses \eqn{w_{jit} y_{j,t-1}}{w_jit y_j,t-1}. In spatial \code{hhh4} applications, the \dQuote{units} refer to geographical regions and the weights could be derived from movement network data. Alternatively, the weights \eqn{w_{ji}}{w_ji} can be estimated parametrically as a function of adjacency order (Meyer and Held, 2014), see \code{\link{W_powerlaw}}. (Penalized) Likelihood inference for such \code{hhh4} models has been established by Paul and Held (2011) with extensions for parametric neighbourhood weights by Meyer and Held (2014). Supplied with the analytical score function and Fisher information, the function \code{hhh4} by default uses the quasi-Newton algorithm available through \code{\link{nlminb}} to maximize the log-likelihood. Convergence is usually fast even for a large number of parameters. If the model contains random effects, the penalized and marginal log-likelihoods are maximized alternately until convergence. } \seealso{ See the special functions \code{\link{fe}}, \code{\link{ri}} and the examples below for how to specify unit-specific effects. Further details on the modelling approach and illustrations of its implementation can be found in \code{vignette("hhh4")} and \code{vignette("hhh4_spacetime")}. } \author{Michaela Paul, Sebastian Meyer, Leonhard Held} \examples{ ###################### ## Univariate examples ###################### ### weekly counts of salmonella agona cases, UK, 1990-1995 data("salmonella.agona") ## convert old "disProg" to new "sts" data class salmonella <- disProg2sts(salmonella.agona) salmonella plot(salmonella) ## generate formula for an (endemic) time trend and seasonality f.end <- addSeason2formula(f = ~1 + t, S = 1, period = 52) f.end ## specify a simple autoregressive negative binomial model model1 <- list(ar = list(f = ~1), end = list(f = f.end), family = "NegBin1") ## fit this model to the data res <- hhh4(salmonella, model1) ## summarize the model fit summary(res, idx2Exp=1, amplitudeShift=TRUE, maxEV=TRUE) plot(res) plot(res, type = "season", components = "end") ### weekly counts of meningococcal infections, Germany, 2001-2006 data("influMen") fluMen <- disProg2sts(influMen) meningo <- fluMen[, "meningococcus"] meningo plot(meningo) ## again a simple autoregressive NegBin model with endemic seasonality meningoFit <- hhh4(stsObj = meningo, control = list( ar = list(f = ~1), end = list(f = addSeason2formula(f = ~1, S = 1, period = 52)), family = "NegBin1" )) summary(meningoFit, idx2Exp=TRUE, amplitudeShift=TRUE, maxEV=TRUE) plot(meningoFit) plot(meningoFit, type = "season", components = "end") ######################## ## Multivariate examples ######################## ### bivariate analysis of influenza and meningococcal infections ### (see Paul et al, 2008) plot(fluMen, same.scale = FALSE) ## Fit a negative binomial model with ## - autoregressive component: disease-specific intercepts ## - neighbour-driven component: only transmission from flu to men ## - endemic component: S=3 and S=1 sine/cosine pairs for flu and men, respectively ## - disease-specific overdispersion WfluMen <- neighbourhood(fluMen) WfluMen["meningococcus","influenza"] <- 0 WfluMen f.end_fluMen <- addSeason2formula(f = ~ -1 + fe(1, which = c(TRUE, TRUE)), S = c(3, 1), period = 52) f.end_fluMen fluMenFit <- hhh4(fluMen, control = list( ar = list(f = ~ -1 + fe(1, unitSpecific = TRUE)), ne = list(f = ~ 1, weights = WfluMen), end = list(f = f.end_fluMen), family = "NegBinM")) summary(fluMenFit, idx2Exp=1:3) plot(fluMenFit, type = "season", components = "end", unit = 1) plot(fluMenFit, type = "season", components = "end", unit = 2) \dontshow{ ## regression test for amplitude/shift transformation of sine-cosine pairs ## coefficients were wrongly matched in surveillance < 1.18.0 stopifnot(coef(fluMenFit, amplitudeShift = TRUE)["end.A(2 * pi * t/52).meningococcus"] == sqrt(sum(coef(fluMenFit)[paste0("end.", c("sin","cos"), "(2 * pi * t/52).meningococcus")]^2))) } ### weekly counts of measles, Weser-Ems region of Lower Saxony, Germany data("measlesWeserEms") measlesWeserEms plot(measlesWeserEms) # note the two districts with zero cases ## we could fit the same simple model as for the salmonella cases above model1 <- list( ar = list(f = ~1), end = list(f = addSeason2formula(~1 + t, period = 52)), family = "NegBin1" ) measlesFit <- hhh4(measlesWeserEms, model1) summary(measlesFit, idx2Exp=TRUE, amplitudeShift=TRUE, maxEV=TRUE) ## but we should probably at least use a population offset in the endemic ## component to reflect heterogeneous incidence levels of the districts, ## and account for spatial dependence (here just using first-order adjacency) measlesFit2 <- update(measlesFit, end = list(offset = population(measlesWeserEms)), ne = list(f = ~1, weights = neighbourhood(measlesWeserEms) == 1)) summary(measlesFit2, idx2Exp=TRUE, amplitudeShift=TRUE, maxEV=TRUE) plot(measlesFit2, units = NULL, hide0s = TRUE) ## 'measlesFit2' corresponds to the 'measlesFit_basic' model in ## vignette("hhh4_spacetime"). See there for further analyses, ## including vaccination coverage as a covariate, ## spatial power-law weights, and random intercepts. \dontrun{ ### last but not least, a more sophisticated (and time-consuming) ### analysis of weekly counts of influenza from 140 districts in ### Southern Germany (originally analysed by Paul and Held, 2011, ### and revisited by Held and Paul, 2012, and Meyer and Held, 2014) data("fluBYBW") plot(fluBYBW, type = observed ~ time) plot(fluBYBW, type = observed ~ unit, ## mean yearly incidence per 100.000 inhabitants (8 years) population = fluBYBW@map$X31_12_01 / 100000 * 8) ## For the full set of models for data("fluBYBW") as analysed by ## Paul and Held (2011), including predictive model assessement ## using proper scoring rules, see the (computer-intensive) ## demo("fluBYBW") script: demoscript <- system.file("demo", "fluBYBW.R", package = "surveillance") demoscript #file.show(demoscript) ## Here we fit the improved power-law model of Meyer and Held (2014) ## - autoregressive component: random intercepts + S = 1 sine/cosine pair ## - neighbour-driven component: random intercepts + S = 1 sine/cosine pair ## + population gravity with normalized power-law weights ## - endemic component: random intercepts + trend + S = 3 sine/cosine pairs ## - random intercepts are iid but correlated between components f.S1 <- addSeason2formula( ~-1 + ri(type="iid", corr="all"), S = 1, period = 52) f.end.S3 <- addSeason2formula( ~-1 + ri(type="iid", corr="all") + I((t-208)/100), S = 3, period = 52) ## for power-law weights, we need adjaceny orders, which can be ## computed from the binary adjacency indicator matrix nbOrder1 <- neighbourhood(fluBYBW) neighbourhood(fluBYBW) <- nbOrder(nbOrder1) ## full model specification fluModel <- list( ar = list(f = f.S1), ne = list(f = update.formula(f.S1, ~ . + log(pop)), weights = W_powerlaw(maxlag=max(neighbourhood(fluBYBW)), normalize = TRUE, log = TRUE)), end = list(f = f.end.S3, offset = population(fluBYBW)), family = "NegBin1", data = list(pop = population(fluBYBW)), optimizer = list(variance = list(method = "Nelder-Mead")), verbose = TRUE) ## CAVE: random effects considerably increase the runtime of model estimation ## (It is usually advantageous to first fit a model with simple intercepts ## to obtain reasonable start values for the other parameters.) set.seed(1) # because random intercepts are initialized randomly fluFit <- hhh4(fluBYBW, fluModel) summary(fluFit, idx2Exp = TRUE, amplitudeShift = TRUE) plot(fluFit, type = "fitted", total = TRUE) plot(fluFit, type = "season") range(plot(fluFit, type = "maxEV")) plot(fluFit, type = "maps", prop = TRUE) gridExtra::grid.arrange( grobs = lapply(c("ar", "ne", "end"), function (comp) plot(fluFit, type = "ri", component = comp, main = comp, exp = TRUE, sub = "multiplicative effect")), nrow = 1, ncol = 3) plot(fluFit, type = "neweights", xlab = "adjacency order") } ######################################################################## ## An endemic-only "hhh4" model can also be estimated using MASS::glm.nb ######################################################################## ## weekly counts of measles, Weser-Ems region of Lower Saxony, Germany data("measlesWeserEms") ## fit an endemic-only "hhh4" model ## with time covariates and a district-specific offset hhh4fit <- hhh4(measlesWeserEms, control = list( end = list(f = addSeason2formula(~1 + t, period = measlesWeserEms@freq), offset = population(measlesWeserEms)), ar = list(f = ~-1), ne = list(f = ~-1), family = "NegBin1", subset = 1:nrow(measlesWeserEms) )) summary(hhh4fit) ## fit the same model using MASS::glm.nb measlesWeserEmsData <- as.data.frame(measlesWeserEms, tidy = TRUE) measlesWeserEmsData$t <- c(hhh4fit$control$data$t) glmnbfit <- MASS::glm.nb( update(formula(hhh4fit)$end, observed ~ . + offset(log(population))), data = measlesWeserEmsData ) summary(glmnbfit) ## Note that the overdispersion parameter is parametrized inversely. ## The likelihood and point estimates are all the same. ## However, the variance estimates are different: in glm.nb, the parameters ## are estimated conditional on the overdispersion theta. \dontshow{ stopifnot( all.equal(logLik(hhh4fit), logLik(glmnbfit)), all.equal(1/coef(hhh4fit)[["overdisp"]], glmnbfit$theta, tolerance = 1e-6), all.equal(coef(hhh4fit)[1:4], coef(glmnbfit), tolerance = 1e-6, check.attributes = FALSE), all.equal(c(residuals(hhh4fit)), residuals(glmnbfit), tolerance = 1e-6, check.attributes = FALSE) ) } } \references{ Held, L., \enc{Hhle}{Hoehle}, M. and Hofmann, M. (2005): A statistical framework for the analysis of multivariate infectious disease surveillance counts. \emph{Statistical Modelling}, \bold{5} (3), 187-199. \doi{10.1191/1471082X05st098oa} Paul, M., Held, L. and Toschke, A. M. (2008): Multivariate modelling of infectious disease surveillance data. \emph{Statistics in Medicine}, \bold{27} (29), 6250-6267. \doi{10.1002/sim.4177} Paul, M. and Held, L. (2011): Predictive assessment of a non-linear random effects model for multivariate time series of infectious disease counts. \emph{Statistics in Medicine}, \bold{30} (10), 1118-1136. \doi{10.1002/sim.4177} Held, L. and Paul, M. (2012): Modeling seasonality in space-time infectious disease surveillance data. \emph{Biometrical Journal}, \bold{54} (6), 824-843. \doi{10.1002/bimj.201200037} Meyer, S. and Held, L. (2014): Power-law models for infectious disease spread. \emph{The Annals of Applied Statistics}, \bold{8} (3), 1612-1639. \doi{10.1214/14-AOAS743} Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \keyword{ts} \keyword{regression} surveillance/man/farringtonFlexible.Rd0000644000176200001440000002553614334522617017656 0ustar liggesusers\name{farringtonFlexible} \alias{farringtonFlexible} \encoding{latin1} \title{Surveillance for Univariate Count Time Series Using an Improved Farrington Method} \description{ % The function takes \code{range} values of the surveillance time series \code{sts} and for each time point uses a Poisson GLM with overdispersion to predict an upper bound on the number of counts according to the procedure by Farrington et al. (1996) and by Noufaily et al. (2012). This bound is then compared to the observed number of counts. If the observation is above the bound, then an alarm is raised. The implementation is illustrated in Salmon et al. (2016). % } \usage{ farringtonFlexible(sts, control = list( range = NULL, b = 5, w = 3, reweight = TRUE, weightsThreshold = 2.58, verbose = FALSE, glmWarnings = TRUE, alpha = 0.05, trend = TRUE, pThresholdTrend = 0.05, limit54 = c(5,4), powertrans = "2/3", fitFun = "algo.farrington.fitGLM.flexible", populationOffset = FALSE, noPeriods = 1, pastWeeksNotIncluded = NULL, thresholdMethod = "delta")) } \arguments{ \item{sts}{object of class \code{\linkS4class{sts}} (including the \code{observed} and the \code{state} time series)} \item{control}{Control object given as a \code{list} containing the following components: \describe{ \item{\code{range}}{Specifies the index of all timepoints which should be tested. If range is \code{NULL} all possible timepoints are used.} \item{\code{b}}{How many years back in time to include when forming the base counts.} \item{\code{w}}{Window's half-size, i.e. number of weeks to include before and after the current week in each year.} \item{\code{reweight}}{Boolean specifying whether to perform reweighting step.} \item{\code{weightsThreshold}}{Defines the threshold for reweighting past outbreaks using the Anscombe residuals (1 in the original method, 2.58 advised in the improved method).} \item{\code{verbose}}{Boolean specifying whether to show extra debugging information.} \item{\code{glmWarnings}}{Boolean specifying whether to print warnings from the call to \code{glm}.} \item{\code{alpha}}{An approximate (one-sided) \eqn{(1-\alpha)\cdot 100\%} prediction interval is calculated unlike the original method where it was a two-sided interval. The upper limit of this interval i.e. the \eqn{(1-\alpha)\cdot 100\%} quantile serves as an upperbound.} \item{\code{trend}}{Boolean indicating whether a trend should be included and kept in case the conditions in the Farrington et. al. paper are met (see the results). If \code{false} then NO trend is fit.} \item{\code{pThresholdTrend}}{Threshold for deciding whether to keep trend in the model (0.05 in the original method, 1 advised in the improved method).} \item{\code{limit54}}{Vector containing two numbers: \code{cases} and \code{period}. To avoid alarms in cases where the time series only has about almost no cases in the specific week the algorithm uses the following heuristic criterion (see Section 3.8 of the Farrington paper) to protect against low counts: no alarm is sounded if fewer than \eqn{\code{cases}=5} reports were received in the past \eqn{\code{period}=4} weeks. \code{limit54=c(cases,period)} is a vector allowing the user to change these numbers. Note: As of version 0.9-7 of the package the term "last" period of weeks includes the current week - otherwise no alarm is sounded for horrible large numbers if the four weeks before that are too low.} \item{\code{powertrans}}{Power transformation to apply to the data if the threshold is to be computed with the method described in Farrington et al. (1996. Use either "2/3" for skewness correction (Default), "1/2" for variance stabilizing transformation or "none" for no transformation.} \item{\code{fitFun}}{String containing the name of the fit function to be used for fitting the GLM. The only current option is "algo.farrington.fitGLM.flexible".} \item{\code{populationOffset}}{Boolean specifying whether to include a population offset in the GLM. The slot \code{sts@population} gives the population vector.} \item{\code{noPeriods}}{Number of levels in the factor allowing to use more baseline. If equal to 1 no factor variable is created, the set of reference values is defined as in Farrington et al (1996).} \item{\code{pastWeeksNotIncluded}}{Number of past weeks to ignore in the calculation. The default (\code{NULL}) means to use the value of \code{control$w}. Setting \code{pastWeeksNotIncluded=26} might be preferable (Noufaily et al., 2012).} \item{\code{thresholdMethod}}{Method to be used to derive the upperbound. Options are \code{"delta"} for the method described in Farrington et al. (1996), \code{"nbPlugin"} for the method described in Noufaily et al. (2012), and \code{"muan"} for the method extended from Noufaily et al. (2012).} } } } \details{ The following steps are performed according to the Farrington et al. (1996) paper. \enumerate{ \item Fit of the initial model with intercept, time trend if \code{trend} is \code{TRUE}, seasonal factor variable if \code{noPeriod} is bigger than 1, and population offset if \code{populationOffset} is \code{TRUE}. Initial estimation of mean and overdispersion. \item Calculation of the weights omega (correction for past outbreaks) if \code{reweighting} is \code{TRUE}. The threshold for reweighting is defined in \code{control}. \item Refitting of the model \item Revised estimation of overdispersion \item Omission of the trend, if it is not significant \item Repetition of the whole procedure \item Calculation of the threshold value using the model to compute a quantile of the predictive distribution. The method used depends on \code{thresholdMethod}, this can either be: \describe{ \item{"delta"}{One assumes that the prediction error (or a transformation of the prediction error, depending on \code{powertrans}), is normally distributed. The threshold is deduced from a quantile of this normal distribution using the variance and estimate of the expected count given by GLM, and the delta rule. The procedure takes into account both the estimation error (variance of the estimator of the expected count in the GLM) and the prediction error (variance of the prediction error). This is the suggestion in Farrington et al. (1996).} \item{"nbPlugin"}{One assumes that the new count follows a negative binomial distribution parameterized by the expected count and the overdispersion estimated in the GLM. The threshold is deduced from a quantile of this discrete distribution. This process disregards the estimation error, though. This method was used in Noufaily, et al. (2012).} \item{"muan"}{One also uses the assumption of the negative binomial sampling distribution but does not plug in the estimate of the expected count from the GLM, instead one uses a quantile from the asymptotic normal distribution of the expected count estimated in the GLM; in order to take into account both the estimation error and the prediction error. } } \item Computation of exceedance score } Warning: monthly data containing the last day of each month as date should be analysed with \code{epochAsDate=FALSE} in the \code{sts} object. Otherwise February makes it impossible to find some reference time points. } \value{ An object of class \code{sts} with the slots \code{upperbound} and \code{alarm} filled by appropriate output of the algorithm. The \code{control} slot of the input \code{sts} is amended with the following matrix elements, all with \code{length(range)} rows: \describe{ \item{trend}{Booleans indicating whether a time trend was fitted for this time point.} \item{trendVector}{coefficient of the time trend in the GLM for this time point. If no trend was fitted it is equal to NA.} \item{pvalue}{probability of observing a value at least equal to the observation under the null hypothesis .} \item{expected}{expectation of the predictive distribution for each timepoint. It is only reported if the conditions for raising an alarm are met (enough cases).} \item{mu0Vector}{input for the negative binomial distribution to get the upperbound as a quantile (either a plug-in from the GLM or a quantile from the asymptotic normal distribution of the estimator)} \item{phiVector}{overdispersion of the GLM at each timepoint.} } } \keyword{classif} \examples{ data("salmonella.agona") # Create the corresponding sts object from the old disProg object salm <- disProg2sts(salmonella.agona) ### RUN THE ALGORITHMS WITH TWO DIFFERENT SETS OF OPTIONS control1 <- list(range=282:312, noPeriods=1, b=4, w=3, weightsThreshold=1, pastWeeksNotIncluded=3, pThresholdTrend=0.05, alpha=0.1) control2 <- list(range=282:312, noPeriods=10, b=4, w=3, weightsThreshold=2.58, pastWeeksNotIncluded=26, pThresholdTrend=1, alpha=0.1) salm1 <- farringtonFlexible(salm,control=control1) salm2 <- farringtonFlexible(salm,control=control2) ### PLOT THE RESULTS y.max <- max(upperbound(salm1),observed(salm1),upperbound(salm2),na.rm=TRUE) plot(salm1, ylim=c(0,y.max), main='S. Newport in Germany', legend.opts=NULL) lines(1:(nrow(salm1)+1)-0.5, c(upperbound(salm1),upperbound(salm1)[nrow(salm1)]), type="s",col='tomato4',lwd=2) lines(1:(nrow(salm2)+1)-0.5, c(upperbound(salm2),upperbound(salm2)[nrow(salm2)]), type="s",col="blueviolet",lwd=2) legend("topleft", legend=c('Alarm','Upperbound with old options', 'Upperbound with new options'), pch=c(24,NA,NA),lty=c(NA,1,1), bg="white",lwd=c(2,2,2),col=c('red','tomato4',"blueviolet")) } \author{M. Salmon, M. \enc{Hhle}{Hoehle}} \seealso{\code{\link{algo.farrington.fitGLM}},\code{\link{algo.farrington.threshold}}} \keyword{classif} \references{ Farrington, C.P., Andrews, N.J, Beale A.D. and Catchpole, M.A. (1996): A statistical algorithm for the early detection of outbreaks of infectious disease. J. R. Statist. Soc. A, 159, 547-563. Noufaily, A., Enki, D.G., Farrington, C.P., Garthwaite, P., Andrews, N.J., Charlett, A. (2012): An improved algorithm for outbreak detection in multiple surveillance systems. Statistics in Medicine, 32 (7), 1206-1222. Salmon, M., Schumacher, D. and \enc{Hhle}{Hoehle}, M. (2016): Monitoring count time series in \R: Aberration detection in public health surveillance. \emph{Journal of Statistical Software}, \bold{70} (10), 1-35. \doi{10.18637/jss.v070.i10} } surveillance/man/twinstim_plot.Rd0000644000176200001440000000260512011140620016712 0ustar liggesusers\name{twinstim_plot} \alias{plot.twinstim} \title{ Plot methods for fitted \code{twinstim}'s } \description{ The fitted conditional intensity function from \code{\link{twinstim}} may be visualized in at least two ways: \code{\link{iafplot}} plots the fitted interaction functions (as a function of the distance from the host), and \code{\link{intensityplot.twinstim}} plots the fitted intensity either aggregated over space (evolution over time) or aggregated over time (spatial surface of the cumulated intensity). The \code{plot} method for class \code{"twinstim"} is just a wrapper for these two functions. } \usage{ \method{plot}{twinstim}(x, which, ...) } \arguments{ \item{x}{ an object of class \code{"twinstim"}. } \item{which}{ character. Which characteristic of the conditional intensity should be plotted? Possible values are the ones allowed in the functions \code{\link{iafplot}} and \code{\link{intensityplot.twinstim}}, e.g. \code{"siaf"}, or \code{"epidemic proportion"}. Partial matching is applied. } \item{\dots}{ further arguments passed to \code{iafplot} or \code{intensityplot.twinstim}. } } \value{ See the documentation of the respective plot functions, \code{\link{iafplot}} or \code{\link{intensityplot.twinstim}}. } \author{ Sebastian Meyer } \examples{ # see the examples for iafplot() and intensityplot.twinstim() } \keyword{hplot} surveillance/man/algo.glrnb.Rd0000644000176200001440000002362014310560071016035 0ustar liggesusers\name{algo.glrnb} \alias{algo.glrnb} \alias{algo.glrpois} \encoding{latin1} \title{Count Data Regression Charts} \description{ Count data regression charts for the monitoring of surveillance time series as proposed by \enc{Hhle}{Hoehle} and Paul (2008). The implementation is described in Salmon et al. (2016). } \usage{ algo.glrnb(disProgObj, control = list(range=range, c.ARL=5, mu0=NULL, alpha=0, Mtilde=1, M=-1, change="intercept", theta=NULL, dir=c("inc","dec"), ret=c("cases","value"), xMax=1e4)) algo.glrpois(disProgObj, control = list(range=range, c.ARL=5, mu0=NULL, Mtilde=1, M=-1, change="intercept", theta=NULL, dir=c("inc","dec"), ret=c("cases","value"), xMax=1e4)) } \arguments{ \item{disProgObj}{object of class \code{disProg} to do surveillance for. For new \code{\link{sts}}-class data, use the \code{\link{glrnb}} wrapper, or the \code{\link{sts2disProg}} converter.} \item{control}{A list controlling the behaviour of the algorithm \describe{ \item{\code{range}}{vector of indices in the observed vector to monitor (should be consecutive)} \item{\code{mu0}}{A vector of in-control values of the mean of the Poisson / negative binomial distribution with the same length as \code{range}. If \code{NULL} the observed values in \code{1:(min(range)-1)} are used to estimate the beta vector through a generalized linear model. To fine-tune the model one can instead specify \code{mu0} as a list with two components: \describe{ \item{\code{S}}{integer number of harmonics to include (typically 1 or 2)} \item{\code{trend}}{A Boolean indicating whether to include a term \code{t} in the GLM model} } The fitting is controlled by the \code{estimateGLRNbHook} function. The in-control mean model is re-fitted after every alarm. The fitted models can be found as a list \code{mod} in the \code{control} slot after the call. Note: If a value for \code{alpha} is given, then the inverse of this value is used as fixed \code{theta} in a \code{\link[MASS]{negative.binomial}} \code{glm}. If \code{is.null(alpha)} then the parameter is estimated as well (using \code{\link[MASS]{glm.nb}}) -- see the description of this parameter for details. } \item{\code{alpha}}{The (known) dispersion parameter of the negative binomial distribution, i.e. the parametrization of the negative binomial is such that the variance is \eqn{mean + alpha*mean^2}{mean + \alpha*mean^2}. Note: This parametrization is the inverse of the shape parametrization used in R -- for example in \code{dnbinom} and \code{glr.nb}. Hence, if \code{alpha=0} then the negative binomial distribution boils down to the Poisson distribution and a call of \code{algo.glrnb} is equivalent to a call to \code{algo.glrpois}. If \code{alpha=NULL} the parameter is calculated as part of the in-control estimation. However, the parameter is estimated only once from the first fit. Subsequent fittings are only for the parameters of the linear predictor with \code{alpha} fixed.} \item{\code{c.ARL}}{threshold in the GLR test, i.e. \eqn{c_{\gamma}}{c_gamma}} \item{\code{Mtilde}}{number of observations needed before we have a full rank the typical setup for the "\code{intercept}" and "\code{epi}" charts is \code{Mtilde=1}} \item{\code{M}}{number of time instances back in time in the window-limited approach, i.e. the last value considered is \eqn{\max{1,n-M}}. To always look back until the first observation use \code{M=-1}.} \item{\code{change}}{a string specifying the type of the alternative. Currently the two choices are \code{intercept} and \code{epi}. See the SFB Discussion Paper 500 for details.} \item{\code{theta}}{if \code{NULL} then the GLR scheme is used. If not \code{NULL} the prespecified value for \eqn{\kappa} or \eqn{\lambda} is used in a recursive LR scheme, which is faster. } \item{\code{dir}}{a string specifying the direction of testing in GLR scheme. With \code{"inc"} only increases in \eqn{x} are considered in the GLR-statistic, with \code{"dec"} decreases are regarded. } \item{\code{ret}}{a string specifying the type of \code{upperbound}-statistic that is returned. With \code{"cases"} the number of cases that would have been necessary to produce an alarm or with \code{"value"} the GLR-statistic is computed (see below).} \item{\code{xMax}}{Maximum value to try for x to see if this is the upperbound number of cases before sounding an alarm (Default: 1e4). This only applies for the GLR using the NegBin when \code{ret="cases"} -- see details.} } } } \value{ \code{algo.glrpois} simply calls \code{algo.glrnb} with \code{control$alpha} set to 0. \code{algo.glrnb} returns a list of class \code{survRes} (surveillance result), which includes the alarm value for recognizing an outbreak (1 for alarm, 0 for no alarm), the threshold value for recognizing the alarm and the input object of class disProg. The \code{upperbound} slot of the object are filled with the current \eqn{GLR(n)} value or with the number of cases that are necessary to produce an alarm at any time point \eqn{\leq n}{<=n}. Both lead to the same alarm timepoints, but \code{"cases"} has an obvious interpretation. } \details{ This function implements the seasonal count data chart based on generalized likelihood ratio (GLR) as described in the \enc{Hhle}{Hoehle} and Paul (2008) paper. A moving-window generalized likelihood ratio detector is used, i.e. the detector has the form % \deqn{N = \inf\left\{ n : \max_{1\leq k \leq n} \left[ \sum_{t=k}^n \log \left\{ \frac{f_{\theta_1}(x_t|z_t)}{f_{\theta_0}(x_t|z_t)} \right\} \right] \geq c_\gamma \right\} }{N = inf(... >= c_gamma)} % where instead of \eqn{1\leq k \leq n}{1<= k <= n} the GLR statistic is computed for all \eqn{k \in \{n-M, \ldots, n-\tilde{M}+1\}}{k \in \{n-M, \ldots, n-Mtilde+1\}}. To achieve the typical behaviour from \eqn{1\leq k\leq n}{1<= k <= n} use \code{Mtilde=1} and \code{M=-1}. So \eqn{N} is the time point where the GLR statistic is above the threshold the first time: An alarm is given and the surveillance is reset starting from time \eqn{N+1}. Note that the same \code{c.ARL} as before is used, but if \code{mu0} is different at \eqn{N+1,N+2,\ldots} compared to time \eqn{1,2,\ldots} the run length properties differ. Because \code{c.ARL} to obtain a specific ARL can only be obtained my Monte Carlo simulation there is no good way to update \code{c.ARL} automatically at the moment. Also, FIR GLR-detectors might be worth considering. In case \code{is.null(theta)} and \code{alpha>0} as well as \code{ret="cases"} then a brute-force search is conducted for each time point in range in order to determine the number of cases necessary before an alarm is sounded. In case no alarm was sounded so far by time \eqn{t}, the function increases \eqn{x[t]} until an alarm is sounded any time before time point \eqn{t}. If no alarm is sounded by \code{xMax}, a return value of 1e99 is given. Similarly, if an alarm was sounded by time \eqn{t} the function counts down instead. Note: This is slow experimental code! At the moment, window limited ``\code{intercept}'' charts have not been extensively tested and are at the moment not supported. As speed is not an issue here this doesn't bother too much. Therefore, a value of \code{M=-1} is always used in the intercept charts. } \author{M. \enc{Hhle}{Hoehle} with contributions by V. Wimmer} \examples{ ##Simulate data and apply the algorithm S <- 1 ; t <- 1:120 ; m <- length(t) beta <- c(1.5,0.6,0.6) omega <- 2*pi/52 #log mu_{0,t} base <- beta[1] + beta[2] * cos(omega*t) + beta[3] * sin(omega*t) #Generate example data with changepoint and tau=tau tau <- 100 kappa <- 0.4 mu0 <- exp(base) mu1 <- exp(base + kappa) ## Poisson example #Generate data set.seed(42) x <- rpois(length(t),mu0*(exp(kappa)^(t>=tau))) s.ts <- sts(observed=x, state=(t>=tau)) #Plot the data plot(s.ts, xaxis.labelFormat=NULL) #Run cntrl = list(range=t,c.ARL=5, Mtilde=1, mu0=mu0, change="intercept",ret="value",dir="inc") glr.ts <- glrpois(s.ts,control=cntrl) plot(glr.ts, xaxis.labelFormat=NULL, dx.upperbound=0.5) lr.ts <- glrpois(s.ts,control=c(cntrl,theta=0.4)) plot(lr.ts, xaxis.labelFormat=NULL, dx.upperbound=0.5) #using the legacy interface for "disProg" data lr.ts0 <- algo.glrpois(sts2disProg(s.ts), control=c(cntrl,theta=0.4)) stopifnot(upperbound(lr.ts) == lr.ts0$upperbound) ## NegBin example #Generate data set.seed(42) alpha <- 0.2 x <- rnbinom(length(t),mu=mu0*(exp(kappa)^(t>=tau)),size=1/alpha) s.ts <- sts(observed=x, state=(t>=tau)) #Plot the data plot(s.ts, xaxis.labelFormat=NULL) #Run GLR based detection cntrl = list(range=t,c.ARL=5, Mtilde=1, mu0=mu0, alpha=alpha, change="intercept",ret="value",dir="inc") glr.ts <- glrnb(s.ts, control=cntrl) plot(glr.ts, xaxis.labelFormat=NULL, dx.upperbound=0.5) #CUSUM LR detection with backcalculated number of cases cntrl2 = list(range=t,c.ARL=5, Mtilde=1, mu0=mu0, alpha=alpha, change="intercept",ret="cases",dir="inc",theta=1.2) glr.ts2 <- glrnb(s.ts, control=cntrl2) plot(glr.ts2, xaxis.labelFormat=NULL) } \keyword{classif} \references{ \enc{Hhle}{Hoehle}, M. and Paul, M. (2008): Count data regression charts for the monitoring of surveillance time series. Computational Statistics and Data Analysis, 52 (9), 4357-4368. Salmon, M., Schumacher, D. and \enc{Hhle}{Hoehle}, M. (2016): Monitoring count time series in \R: Aberration detection in public health surveillance. \emph{Journal of Statistical Software}, \bold{70} (10), 1-35. \doi{10.18637/jss.v070.i10} } surveillance/man/earsC.Rd0000644000176200001440000002014713020537177015056 0ustar liggesusers\name{earsC} \alias{earsC} \encoding{latin1} \title{Surveillance for a count data time series using the EARS C1, C2 or C3 method and its extensions} \description{ % The function takes \code{range} values of the surveillance time series \code{sts} and for each time point computes a threshold for the number of counts based on values from the recent past. This is then compared to the observed number of counts. If the observation is above a specific quantile of the prediction interval, then an alarm is raised. This method is especially useful for data without many historic values, since it only needs counts from the recent past. % } \usage{ earsC(sts, control = list(range = NULL, method = "C1", baseline = 7, minSigma = 0, alpha = 0.001)) } \arguments{ \item{sts}{object of class sts (including the \code{observed} and the \code{state} time series) , which is to be monitored.} \item{control}{Control object \describe{ \item{\code{range}}{Specifies the index in the \code{sts} object of all the timepoints which should be monitored. If \code{range} is \code{NULL} the maximum number of possible timepoints is used (this number depends on the method chosen): \describe{ \item{C1}{all timepoints from the observation with index \code{baseline + 1} can be monitored,} \item{C2}{timepoints from index \code{baseline + 3} can be monitored,} \item{C3}{timepoints starting from the index \code{baseline + 5} can be monitored.} } } \item{\code{method}}{String indicating which method to use: \cr \describe{ \item{\code{"C1"}}{for EARS C1-MILD method (Default),} \item{\code{"C2"}}{for EARS C2-MEDIUM method,} \item{\code{"C3"}}{for EARS C3-HIGH method.} } See Details for further information about the methods. } \item{\code{baseline}}{how many time points to use for calculating the baseline, see details} \item{\code{minSigma}}{By default 0. If \code{minSigma} is higher than 0, for C1 and C2, the quantity zAlpha * minSigma is then the alerting threshold if the baseline is zero. Howard Burkom suggests using a value of 0.5 or 1 for sparse data.} \item{\code{alpha}}{An approximate (two-sided) \eqn{(1-\alpha)\cdot 100\%} prediction interval is calculated. By default if \code{alpha} is \code{NULL} the value 0.001 is assumed for C1 and C2 whereas 0.025 is assumed for C3. These different choices are the one made at the CDC.} % } } } \details{ The three methods are different in terms of baseline used for calculation of the expected value and in terms of method for calculating the expected value: \itemize{ \item in C1 and C2 the expected value is the moving average of counts over the sliding window of the baseline and the prediction interval depends on the standard derivation of the observed counts in this window. They can be considered as Shewhart control charts with a small sample used for calculations. \item in C3 the expected value is based on the sum over 3 timepoints (assessed timepoints and the two previous timepoints) of the discrepancy between observations and predictions, predictions being calculated with the C2 method. This method has similarities with a CUSUM method due to it adding discrepancies between predictions and observations over several timepoints, but is not a CUSUM (sum over 3 timepoints, not accumulation over a whole range), even if it sometimes is presented as such. } Here is what the function does for each method, see the literature sources for further details: \enumerate{ \item For C1 the baseline are the \code{baseline} (default 7) timepoints before the assessed timepoint t, t-\code{baseline} to t-1. The expected value is the mean of the baseline. An approximate (two-sided) \eqn{(1-\alpha)\cdot 100\%} prediction interval is calculated based on the assumption that the difference between the expected value and the observed value divided by the standard derivation of counts over the sliding window, called \eqn{C_1(t)}, follows a standard normal distribution in the absence of outbreaks: \deqn{C_1(t)= \frac{Y(t)-\bar{Y}_1(t)}{S_1(t)},} where \deqn{\bar{Y}_1(t)= \frac{1}{\code{baseline}} \sum_{i=t-1}^{t-\code{baseline}} Y(i)} and \deqn{ S^2_1(t)= \frac{1}{6} \sum_{i=t-1}^{t-\code{baseline}} [Y(i) - \bar{Y}_1(i)]^2.} Then under the null hypothesis of no outbreak, \deqn{C_1(t) \mathcal \> \sim \> {N}(0,1)} An alarm is raised if \deqn{C_1(t)\ge z_{1-\alpha}} with \eqn{z_{1-\alpha}} the \eqn{(1-\alpha)^{th}} quantile of the standard normal distribution. \cr The upperbound \eqn{U_1(t)} is then defined by: \deqn{U_1(t)= \bar{Y}_1(t) + z_{1-\alpha}S_1(t).} \item C2 is very similar to C1 apart from a 2-day lag in the baseline definition. In other words the baseline for C2 is \code{baseline} (Default: 7) timepoints with a 2-day lag before the monitored timepoint t, i.e. \eqn{(t-\code{baseline}-2)} to \eqn{t-3}. The expected value is the mean of the baseline. An approximate (two-sided) \eqn{(1-\alpha)\cdot 100\%} prediction interval is calculated based on the assumption that the difference between the expected value and the observed value divided by the standard derivation of counts over the sliding window, called \eqn{C_2(t)}, follows a standard normal distribution in the absence of outbreaks: \deqn{C_2(t)= \frac{Y(t)-\bar{Y}_2(t)}{S_2(t)},} where \deqn{\bar{Y}_2(t)= \frac{1}{\code{baseline}} \sum_{i=t-3}^{t-\code{baseline}-2} Y(i)} and \deqn{ S^2_2(t)= \frac{1}{\code{baseline}-1} \sum_{i=t-3}^{t-\code{baseline}-2} [Y(i) - \bar{Y}_2(i)]^2.} Then under the null hypothesis of no outbreak, \deqn{C_2(t) \mathcal \sim {N}(0,1)} An alarm is raised if \deqn{C_2(t)\ge z_{1-\alpha},} with \eqn{z_{1-\alpha}} the \eqn{(1-\alpha)^{th}} quantile of the standard normal distribution. \cr The upperbound \eqn{U_{2}(t)} is then defined by: \deqn{U_{2}(t)= \bar{Y}_{2}(t) + z_{1-\alpha}S_{2}(t).} \item C3 is quite different from the two other methods, but it is based on C2. Indeed it uses \eqn{C_2(t)} from timepoint t and the two previous timepoints. This means the baseline consists of the timepoints \eqn{t-(\code{baseline}+4)} to \eqn{t-3}. The statistic \eqn{C_3(t)} is the sum of discrepancies between observations and predictions. \deqn{C_3(t)= \sum_{i=t}^{t-2} \max(0,C_2(i)-1)} Then under the null hypothesis of no outbreak, \deqn{C_3(t) \mathcal \sim {N}(0,1)} An alarm is raised if \deqn{C_3(t)\ge z_{1-\alpha},} with \eqn{z_{1-\alpha}} the \eqn{(1-\alpha)^{th}} quantile of the standard normal distribution. \cr The upperbound \eqn{U_3(t)} is then defined by: \deqn{U_3(t)= \bar{Y}_2(t) + S_2(t)\left(z_{1-\alpha}-\sum_{i=t-1}^{t-2} \max(0,C_2(i)-1)\right).} } } \value{ An object of class \code{sts} with the slots \code{upperbound} and \code{alarm} filled by the chosen method. } \examples{ #Sim data and convert to sts object disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 208, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) stsObj <- disProg2sts( disProgObj) # Call earsC function and show result res1 <- earsC(stsObj, control = list(range = 20:208, method="C1")) plot(res1, legend.opts=list(horiz=TRUE, x="topright")) # Compare C3 upperbounds depending on alpha res3 <- earsC(stsObj, control = list(range = 20:208,method="C3",alpha = 0.001)) plot(upperbound(res3), type='l') res3 <- earsC(stsObj, control = list(range = 20:208,method="C3")) lines(upperbound(res3), col='red') } \author{M. Salmon, H. Burkom} \keyword{classif} \source{ Fricker, R.D., Hegler, B.L, and Dunfee, D.A. (2008). Comparing syndromic surveillance detection methods: EARS versus a CUSUM-based methodology, 27:3407-3429, Statistics in medicine. Salmon, M., Schumacher, D. and \enc{Hhle}{Hoehle}, M. (2016): Monitoring count time series in \R: Aberration detection in public health surveillance. \emph{Journal of Statistical Software}, \bold{70} (10), 1-35. \doi{10.18637/jss.v070.i10} } surveillance/man/twinstim_profile.Rd0000644000176200001440000000704712677753025017434 0ustar liggesusers\encoding{latin1} \name{twinstim_profile} \alias{profile.twinstim} \title{ Profile Likelihood Computation and Confidence Intervals for \code{twinstim} objects } \description{ Function to compute estimated and profile likelihood based confidence intervals for \code{twinstim} objects. Computations might be cumbersome! WARNING: the implementation is not well tested, simply uses \code{optim} (ignoring optimizer settings from the original fit), and does not return the complete set of coefficients at each grid point. } \usage{ \method{profile}{twinstim}(fitted, profile, alpha = 0.05, control = list(fnscale = -1, maxit = 100, trace = 1), do.ltildeprofile=FALSE, ...) } \arguments{ \item{fitted}{ an object of class \code{"twinstim"}. } \item{profile}{ a list with elements being numeric vectors of length 4. These vectors must have the form \code{c(index, lower, upper, gridsize)}. \describe{ \item{\code{index}:}{ index of the parameter to be profiled in the vector \code{coef(fitted)}. } \item{\code{lower, upper}:}{ lower/upper limit of the grid on which the profile log-likelihood is evaluated. Can also be \code{NA} in which case \code{lower/upper} equals the lower/upper bound of the respective 0.3 \% Wald confidence interval (+-3*se). } \item{\code{gridsize}:}{ grid size of the equally spaced grid between lower and upper. Can also be 0 in which case the profile log-likelihood for this parameter is not evaluated on a grid. } } } \item{alpha}{ \eqn{(1-\alpha)\%}{(1-alpha)\%} profile likelihood based confidence intervals are computed. If alpha <= 0, then no confidence intervals are computed. This is currently not implemented. } \item{control}{ control object to use in \code{\link{optim}} for the profile log-likelihood computations. It might be necessary to control \code{maxit} or \code{reltol} in order to obtain results in finite time. } \item{do.ltildeprofile}{If \code{TRUE} calculate profile likelihood as well. This might take a while, since an optimisation for all other parameters has to be performed. Useful for likelihood based confidence intervals. Default: \code{FALSE}. } \item{\dots}{ unused (argument of the generic). } } \value{ list with profile log-likelihood evaluations on the grid, and -- not implemented yet -- highest likelihood and Wald confidence intervals. The argument \code{profile} is also returned. } \author{ Michael \enc{Hhle}{Hoehle} } \examples{ # profiling takes a while \dontrun{ #Load the twinstim model fitted to the IMD data data("imdepi", "imdepifit") # for profiling we need the model environment imdepifit <- update(imdepifit, model=TRUE) #Generate profiling object for a list of parameters for the new model names <- c("h.(Intercept)","e.typeC") coefList <- lapply(names, function(name) { c(pmatch(name,names(coef(imdepifit))),NA,NA,11) }) #Profile object (necessary to specify a more loose convergence #criterion). Speed things up by using do.ltildeprofile=FALSE (the default) prof <- profile(imdepifit, coefList, control=list(reltol=0.1, REPORT=1), do.ltildeprofile=TRUE) #Plot result for one variable par(mfrow=c(1,2)) for (name in names) { with(as.data.frame(prof$lp[[name]]), matplot(grid,cbind(profile,estimated,wald), type="l",xlab=name,ylab="loglik")) legend(x="bottomleft",c("profile","estimated","wald"),lty=1:3,col=1:3) } } } \keyword{htest} \keyword{methods} \keyword{optimize} \keyword{dplot} surveillance/man/LRCUSUM.runlength.Rd0000644000176200001440000001454314263775410017167 0ustar liggesusers\name{LRCUSUM.runlength} \alias{LRCUSUM.runlength} %% \alias{outcomeFunStandard} %% \alias{LLR.fun} \encoding{latin1} \title{Run length computation of a CUSUM detector} \description{ Compute run length for a count data or categorical CUSUM. The computations are based on a Markov representation of the likelihood ratio based CUSUM. } \usage{ LRCUSUM.runlength(mu, mu0, mu1, h, dfun, n, g=5, outcomeFun=NULL, ...) } \arguments{ \item{mu}{\eqn{k-1 \times T} matrix with true proportions, i.e. equal to mu0 or mu1 if one wants to compute e.g. \eqn{ARL_0} or \eqn{ARL_1}.} \item{mu0}{\eqn{k-1 \times T} matrix with in-control proportions} \item{mu1}{\eqn{k-1 \times T} matrix with out-of-control proportion} \item{h}{The threshold h which is used for the CUSUM.} \item{dfun}{The probability mass function or density used to compute the likelihood ratios of the CUSUM. In a negative binomial CUSUM this is \code{dnbinom}, in a binomial CUSUM \code{dbinom} and in a multinomial CUSUM \code{dmultinom}.} \item{n}{Vector of length \eqn{T} containing the total number of experiments for each time point.} \item{g}{The number of levels to cut the state space into when performing the Markov chain approximation. Sometimes also denoted \eqn{M}. Note that the quality of the approximation depends very much on \code{g}. If \eqn{T} is greater than, say, 50 it's necessary to increase the value of \code{g}.} \item{outcomeFun}{A hook \code{function (k,n)} to compute all possible outcome states to compute the likelihood ratio for. If \code{NULL} then the internal default function \code{surveillance:::outcomeFunStandard} is used. This function uses the Cartesian product of \code{0:n} for \code{k} components.} \item{\dots}{Additional arguments to send to \code{dfun}.} } \details{ Brook and Evans (1972) formulated an approximate approach based on Markov chains to determine the PMF of the run length of a time-constant CUSUM detector. They describe the dynamics of the CUSUM statistic by a Markov chain with a discretized state space of size \eqn{g+2}. This is adopted to the time varying case in \enc{Hhle}{Hoehle} (2010) and implemented in R using the \dots notation such that it works for a very large class of distributions. } \seealso{\code{\link{categoricalCUSUM}}} \value{A list with five components \item{P}{An array of \eqn{g+2 \times g+2} transition matrices of the approximation Markov chain.} \item{pmf}{Probability mass function (up to length \eqn{T}) of the run length variable.} \item{cdf}{Cumulative density function (up to length \eqn{T}) of the run length variable.} \item{arl}{If the model is time homogenous (i.e. if \eqn{T==1}) then the ARL is computed based on the stationary distribution of the Markov chain. See the eqns in the reference for details. Note: If the model is not time homogeneous then the function returns \code{NA} and the ARL has to be approximated manually from the output. One could use \code{sum(1:length(pmf) * pmf)}, which is an approximation because of using a finite support for a sum which should be from 1 to infinity. } } \references{ \enc{Hhle}{Hoehle}, M. (2010): Online change-point detection in categorical time series. In: T. Kneib and G. Tutz (Eds.), Statistical Modelling and Regression Structures - Festschrift in Honour of Ludwig Fahrmeir, Physica-Verlag, pp. 377-397. Preprint available as \url{https://staff.math.su.se/hoehle/pubs/hoehle2010-preprint.pdf} \enc{Hhle}{Hoehle}, M. and Mazick, A. (2010): Aberration detection in R illustrated by Danish mortality monitoring. In: T. Kass-Hout and X. Zhang (Eds.), Biosurveillance: A Health Protection Priority, CRCPress. Preprint available as \url{https://staff.math.su.se/hoehle/pubs/hoehle_mazick2009-preprint.pdf} Brook, D. and Evans, D. A. (1972): An approach to the probability distribution of cusum run length. \emph{Biometrika} \bold{59}(3):539-549. } \examples{ ###################################################### #Run length of a time constant negative binomial CUSUM ###################################################### #In-control and out of control parameters mu0 <- 10 alpha <- 1/2 kappa <- 2 #Density for comparison in the negative binomial distribution dY <- function(y,mu,log=FALSE, alpha, ...) { dnbinom(y, mu=mu, size=1/alpha, log=log) } #In this case "n" is the maximum value to investigate the LLR for #It is assumed that beyond n the LLR is too unlikely to be worth #computing. LRCUSUM.runlength( mu=t(mu0), mu0=t(mu0), mu1=kappa*t(mu0), h=5, dfun = dY, n=rep(100,length(mu0)), alpha=alpha) h.grid <- seq(3,6,by=0.3) arls <- sapply(h.grid, function(h) { LRCUSUM.runlength( mu=t(mu0), mu0=t(mu0), mu1=kappa*t(mu0), h=h, dfun = dY, n=rep(100,length(mu0)), alpha=alpha,g=20)$arl }) plot(h.grid, arls,type="l",xlab="threshold h",ylab=expression(ARL[0])) \dontshow{if (surveillance.options("allExamples")) \{} ###################################################### #Run length of a time varying negative binomial CUSUM ###################################################### mu0 <- matrix(5*sin(2*pi/52 * 1:200) + 10,ncol=1) rl <- LRCUSUM.runlength( mu=t(mu0), mu0=t(mu0), mu1=kappa*t(mu0), h=2, dfun = dY, n=rep(100,length(mu0)), alpha=alpha,g=20) plot(1:length(mu0),rl$pmf,type="l",xlab="t",ylab="PMF") plot(1:length(mu0),rl$cdf,type="l",xlab="t",ylab="CDF") \dontshow{\}} ######################################################## # Further examples contain the binomial, beta-binomial # and multinomial CUSUMs. Hopefully, these will be added # in the future. ######################################################## #dfun function for the multinomial distribution (Note: Only k-1 categories are specified). dmult <- function(y, size,mu, log = FALSE) { return(dmultinom(c(y,size-sum(y)), size = size, prob=c(mu,1-sum(mu)), log = log)) } #Example for the time-constant multinomial distribution #with size 100 and in-control and out-of-control parameters as below. n <- 100 pi0 <- as.matrix(c(0.5,0.3,0.2)) pi1 <- as.matrix(c(0.38,0.46,0.16)) #ARL_0 LRCUSUM.runlength(mu=pi0[1:2,,drop=FALSE],mu0=pi0[1:2,,drop=FALSE],mu1=pi1[1:2,,drop=FALSE], h=5,dfun=dmult, n=n, g=15)$arl #ARL_1 LRCUSUM.runlength(mu=pi1[1:2,,drop=FALSE],mu0=pi0[1:2,,drop=FALSE],mu1=pi1[1:2,,drop=FALSE], h=5,dfun=dmult, n=n, g=15)$arl } \author{M. \enc{Hhle}{Hoehle}} \keyword{regression} surveillance/man/discpoly.Rd0000644000176200001440000000416014614775012015646 0ustar liggesusers\name{discpoly} \alias{discpoly} \title{Polygonal Approximation of a Disc/Circle} \description{ Generates a polygon representing a disc/circle (in planar coordinates) as an object of one of three possible classes: \code{"\link[sp:Polygon-class]{Polygon}"} from package \CRANpkg{sp}, \code{"\link[spatstat.geom]{owin}"} from package \CRANpkg{spatstat.geom}, or \code{"gpc.poly"} from \pkg{gpclib} (if available). } \usage{ discpoly(center, radius, npoly = 64, class = c("Polygon", "owin", "gpc.poly"), hole = FALSE) } \arguments{ \item{center}{numeric vector of length 2 (center coordinates of the circle).} \item{radius}{single numeric value (radius of the circle).} \item{npoly}{single integer. Number of edges of the polygonal approximation.} \item{class}{class of the resulting polygon (partial name matching applies). For \code{"owin"}, this is just a wrapper around \pkg{spatstat.geom}'s own \code{\link[spatstat.geom]{disc}} function.} \item{hole}{logical. Does the resulting polygon represent a hole?} } \value{ A polygon of class \code{class} representing a circle/disc with \code{npoly} edges accuracy. If \code{class="gpc.poly"} and this S4 class is not yet registered in the current \R session (by loading \pkg{gpclib} beforehand), only the \code{pts} slot of a \code{"gpc.poly"} is returned with a warning. } \examples{ ## Construct circles with increasing accuracy and of different spatial classes disc1 <- discpoly(c(0,0), 5, npoly=4, class = "owin") disc2 <- discpoly(c(0,0), 5, npoly=16, class = "Polygon") disc3 <- discpoly(c(0,0), 5, npoly=64, class = "gpc.poly") # may warn ## Look at the results print(disc1) plot(disc1, axes=TRUE, main="", border=2) str(disc2) lines(disc2, col=3) str(disc3) # a list or a formal "gpc.poly" (if gpclib is available) if (is(disc3, "gpc.poly")) { plot(disc3, add=TRUE, poly.args=list(border=4)) } else { lines(disc3[[1]], col=4) } ## to only _draw_ a circle symbols(0, 0, circles=5, inches=FALSE, add=TRUE, fg=5) } \seealso{ \code{\link[spatstat.geom]{disc}} in package \pkg{spatstat.geom}. } \keyword{datagen} \keyword{spatial} surveillance/man/hagelloch.Rd0000644000176200001440000001576614310560071015752 0ustar liggesusers\encoding{latin1} \name{hagelloch} \alias{hagelloch} \alias{hagelloch.df} \docType{data} \keyword{datasets} \title{1861 Measles Epidemic in the City of Hagelloch, Germany} \description{ Data on the 188 cases in the measles outbreak among children in the German city of Hagelloch (near T\enc{}{ue}bingen) 1861. The data were originally collected by Dr. Albert Pfeilsticker (1863) and augmented and re-analysed by Dr. Heike Oesterle (1992). This dataset is used to illustrate the \code{twinSIR} model class in \code{vignette("twinSIR")}. } \usage{ data("hagelloch") } \format{ Loading \code{data("hagelloch")} gives two objects: \code{hagelloch} and \code{hagelloch.df}. The latter is the original \code{data.frame} of 188 rows with individual information for each infected child. \code{hagelloch} has been generated from \code{hagelloch.df} via \code{\link{as.epidata}} (see the Examples below) to obtain an \code{"epidata"} object for use with \code{\link{twinSIR}}. It contains the entire SIR event history of the outbreak (but not all of the covariates). The covariate information in \code{hagelloch.df} is as follows: \describe{ \item{PN:}{patient number} \item{NAME:}{patient name (as a factor)} \item{FN:}{family index} \item{HN:}{house number} \item{AGE:}{age in years} \item{SEX:}{gender of the individual (factor: male, female)} \item{PRO:}{\code{Date} of prodromes} \item{ERU:}{\code{Date} of rash} \item{CL:}{class (factor: preschool, 1st class, 2nd class)} \item{DEAD:}{\code{Date} of death (with missings)} \item{IFTO:}{number of patient who is the putative source of infection (0 = unknown)} \item{SI:}{serial interval = number of days between dates of prodromes of infection source and infected person} \item{C:}{complications (factor: no complications, bronchopneumonia, severe bronchitis, lobar pneumonia, pseudocroup, cerebral edema)} \item{PR:}{duration of prodromes in days} \item{CA:}{number of cases in family} \item{NI:}{number of initial cases} \item{GE:}{generation number of the case} \item{TD:}{day of max. fever (days after rush)} \item{TM:}{max. fever (degree Celsius)} \item{x.loc:}{x coordinate of house (in meters). Scaling in metres is obtained by multiplying the original coordinates by 2.5 (see details in Neal and Roberts (2004))} \item{y.loc:}{y coordinate of house (in meters). See also the above description of \code{x.loc}.} \item{tPRO:}{Time of prodromes (first symptoms) in days after the start of the epidemic (30 Oct 1861).} \item{tERU:}{Time upon which the rash first appears.} \item{tDEAD:}{Time of death, if available.} \item{tR:}{Time at which the infectious period of the individual is assumed to end. This unknown time is calculated as \deqn{tR_i = \min(tDEAD_i, tERU_i+d_0),}{tR[i] = min(tDEAD[i], tERU[i] + d0),} where -- as in Section 3.1 of Neal and Roberts (2004) -- we use \eqn{d_0=3}{d0=3}.} \item{tI:}{Time at which the individual is assumed to become infectious. Actually this time is unknown, but we use \deqn{tI_i = tPRO_i - d_1,}{tI[i] = tPRO[i] - d1,} where \eqn{d_1=1}{d1=1} as in Neal and Roberts (2004).} } The time variables describe the transitions of the individual in an Susceptible-Infectious-Recovered (SIR) model. Note that in order to avoid ties in the event times resulting from daily interval censoring, the times have been jittered uniformly within the respective day. The time point 0.5 would correspond to noon of 30 Oct 1861. The \code{hagelloch} \code{"epidata"} object only retains some of the above covariates to save space. Apart from the usual \code{"epidata"} event columns, \code{hagelloch} contains a number of extra variables representing distance- and covariate-based weights for the force of infection: \describe{ \item{household:}{the number of currently infectious children in the same household (including the child itself if it is currently infectious).} \item{nothousehold:}{the number of currently infectious children outside the household.} \item{c1, c2:}{the number of children infectious during the respective time block and being members of class 1 and 2, respectively; but the value is 0 if the individual of the row is not herself a member of the respective class.} } Such epidemic covariates can been computed by specifying suitable \code{f} and \code{w} arguments in \code{\link{as.epidata}} at conversion (see the code below), or at a later step via the \code{\link[=update.epidata]{update}}-method for \code{"epidata"}. } \source{ Thanks to Peter J. Neal, University of Manchester, for providing us with these data, which he again became from Niels Becker, Australian National University. To cite the data, the main references are Pfeilsticker (1863) and Oesterle (1992). } \examples{ data("hagelloch") head(hagelloch.df) # original data documented in Oesterle (1992) head(as.data.frame(hagelloch)) # "epidata" event history format ## How the "epidata" 'hagelloch' was created from 'hagelloch.df' stopifnot(all.equal(hagelloch, as.epidata( hagelloch.df, t0 = 0, tI.col = "tI", tR.col = "tR", id.col = "PN", coords.cols = c("x.loc", "y.loc"), f = list( household = function(u) u == 0, nothousehold = function(u) u > 0 ), w = list( c1 = function (CL.i, CL.j) CL.i == "1st class" & CL.j == CL.i, c2 = function (CL.i, CL.j) CL.i == "2nd class" & CL.j == CL.i ), keep.cols = c("SEX", "AGE", "CL")) )) ### Basic plots produced from hagelloch.df # Show case locations as in Neal & Roberts (different scaling) using # the data.frame (promoted to a SpatialPointsDataFrame) coordinates(hagelloch.df) <- c("x.loc","y.loc") plot(hagelloch.df, xlab="x [m]", ylab="x [m]", pch=15, axes=TRUE, cex=sqrt(multiplicity(hagelloch.df))) # Epicurve hist(as.numeric(hagelloch.df$tI), xlab="Time (days)", ylab="Cases", main="") ### "epidata" summary and plot methods (s <- summary(hagelloch)) head(s$byID) plot(s) \dontrun{ # Show a dynamic illustration of the spread of the infection animate(hagelloch, time.spacing=0.1, sleep=1/100, legend.opts=list(x="topleft")) } } \references{ Pfeilsticker, A. (1863). Beitr\enc{}{ae}ge zur Pathologie der Masern mit besonderer Ber\enc{}{ue}cksichtigung der statistischen Verh\enc{}{ae}ltnisse, M.D. Thesis, Eberhard-Karls-Universit\enc{}{ae}t T\enc{}{ue}bingen. Available as \url{https://archive.org/details/beitrgezurpatho00pfeigoog}. Oesterle, H. (1992). Statistische Reanalyse einer Masernepidemie 1861 in Hagelloch, M.D. Thesis, Eberhard-Karls-Universit\enc{}{ae}at T\enc{}{ue}bingen. Neal, P. J. and Roberts, G. O (2004). Statistical inference and model selection for the 1861 Hagelloch measles epidemic, Biostatistics 5(2):249-261 } \seealso{ data class: \code{\link{epidata}} point process model: \code{\link{twinSIR}} illustration with \code{hagelloch}: \code{vignette("twinSIR")} } surveillance/man/stcd.Rd0000644000176200001440000000733312014262005014743 0ustar liggesusers\name{stcd} \alias{stcd} \encoding{latin1} \title{Spatio-temporal cluster detection} \description{ Shiryaev-Roberts based prospective spatio-temporal cluster detection as in Assuncao & Correa (2009). } \usage{ stcd(x, y,t,radius,epsilon,areaA, areaAcapBk, threshold, cusum=FALSE) } \arguments{ \item{x}{Vector containing spatial x coordinate of the events.} \item{y}{Vector containing spatial y coordinate of the events.} \item{t}{Vector containing the time points of the events. It is assumed that the vector is sorted (early->last).} \item{radius}{Radius of the cluster to detect.} \item{epsilon}{Relative change of event-intensity within the cluster to detect. See reference paper for an explicit definition.} \item{areaA}{Area of the observation region A (single number) -- This argument is currently ignored!} \item{areaAcapBk}{Area of A \ B(s_k,rho) for all k=1,\ldots,n (vector). This argument is currently ignored!} \item{threshold}{Threshold limit for the alarm and should be equal to the desired Average-Run-Length (ARL) of the detector.} \item{cusum}{(logical) If \code{FALSE} (default) then the Shiryaev-Roberts detector is used as in the original article by Assuncao & Correa (2009), i.e. \eqn{R_n = \sum_{k=1}^n \Lambda_{k,n}}, where \eqn{\Lambda_{k,n}} denotes the likelihood ratio between the in-control and out-of control model. If \code{TRUE}, CUSUM test statistic is used instead. Here, \deqn{R_n = \max_{1\leq k \leq n} \Lambda_{k,n}}. Note that this has implications on what threshold will sound the alarm (CUSUM threshold needs to be smaller).} } \details{ Shiryaev-Roberts based spatio-temporal cluster detection based on the work in Assuncao and Correa (2009). The implementation is based on C++ code originally written by Marcos Oliveira Prates, UFMG, Brazil and provided by Thais Correa, UFMG, Brazil during her research stay in Munich. This stay was financially supported by the Munich Center of Health Sciences. Note that the vectors \code{x}, \code{y} and \code{t} need to be of the same length. Furthermore, the vector \code{t} needs to be sorted (to improve speed, the latter is not verified within the function). The current implementation uses a call to a C++ function to perform the actual computations of the test statistic. The function is currently experimental -- data type and results may be subject to changes. } \value{A list with three components \item{R}{A vector of the same length as the input containing the value of the test statistic for each observation.} \item{idxFA}{Index in the x,y,t vector causing a possible alarm. If no cluster was detected, then a value of \code{-1} is returned here.} \item{idxCC}{index in the x,y,t vector of the event containing the cluster. If no cluster was detected, then a value of \code{-1} is returned here.} } \references{ Assuncao, R. and Correa, T. (2009), Surveillance to detect emerging space-time clusters, Computational Statistics & Data Analysis, 53(8):2817-2830. } \examples{ if (require("splancs")) { # load the data from package "splancs" data(burkitt, package="splancs") # order the times burkitt <- burkitt[order(burkitt$t), ] #Parameters for the SR detection epsilon <- 0.5 # relative change within the cluster radius <- 20 # radius threshold <- 161 # threshold limit res <- stcd(x=burkitt$x, y=burkitt$y, t=burkitt$t, radius=radius, epsilon=epsilon, areaA=1, areaAcapBk=1, threshold=threshold) #Index of the event which.max(res$R >= threshold) } } \author{M. O. Prates, T. Correa and M. \enc{Hhle}{Hoehle}} \keyword{cluster} surveillance/man/calibration.Rd0000644000176200001440000000616113062247044016305 0ustar liggesusers\name{calibrationTest} \alias{calibrationTest} \alias{calibrationTest.default} \title{ Calibration Tests for Poisson or Negative Binomial Predictions } \description{ The implemented calibration tests for Poisson or negative binomial predictions of count data are based on proper scoring rules and described in detail in Wei and Held (2014). The following proper scoring rules are available: Dawid-Sebastiani score (\code{"dss"}), logarithmic score (\code{"logs"}), ranked probability score (\code{"rps"}). } \usage{ calibrationTest(x, ...) \method{calibrationTest}{default}(x, mu, size = NULL, which = c("dss", "logs", "rps"), tolerance = 1e-4, method = 2, ...) } \arguments{ \item{x}{ the observed counts. All involved functions are vectorized and also accept matrices or arrays. } \item{mu}{ the means of the predictive distributions for the observations \code{x}. } \item{size}{ either \code{NULL} (default), indicating Poisson predictions with mean \code{mu}, or dispersion parameters of negative binomial forecasts for the observations \code{x}, parametrized as in \code{\link{dnbinom}} with variance \code{mu*(1+mu/size)}. } \item{which}{ a character string indicating which proper scoring rule to apply. } \item{tolerance}{ absolute tolerance for the null expectation and variance of \code{"logs"} and \code{"rps"}. For the latter, see the note below. Unused for \code{which = "dss"} (closed form). } \item{method}{ selection of the \eqn{z}-statistic: \code{method = 2} refers to the alternative test statistic \eqn{Z_s^*} of Wei and Held (2014, Discussion), which has been recommended for low counts. \code{method = 1} corresponds to Equation 5 in Wei and Held (2014). } \item{\dots}{ unused (argument of the generic). } } \value{ an object of class \code{"htest"}, which is a list with the following components: \item{method}{a character string indicating the type of test performed (including \code{which} scoring rule).} \item{data.name}{a character string naming the supplied \code{x} argument.} \item{statistic}{the \eqn{z}-statistic of the test.} \item{parameter}{the number of predictions underlying the test, i.e., \code{length(x)}.} \item{p.value}{the p-value for the test.} } \note{ If the \CRANpkg{gsl} package is installed, its implementations of the Bessel and hypergeometric functions are used when calculating the null expectation and variance of the \code{rps}. These functions are faster and yield more accurate results (especially for larger \code{mu}). } \references{ Wei, W. and Held, L. (2014): Calibration tests for count data. \emph{Test}, \bold{23}, 787-805. } \author{ Sebastian Meyer and Wei Wei } \examples{ mu <- c(0.1, 1, 3, 6, pi, 100) size <- 0.1 set.seed(1) y <- rnbinom(length(mu), mu = mu, size = size) calibrationTest(y, mu = mu, size = size) # p = 0.99 calibrationTest(y, mu = mu, size = 1) # p = 4.3e-05 calibrationTest(y, mu = 1, size = size) # p = 0.6959 calibrationTest(y, mu = 1, size = size, which = "rps") # p = 0.1286 } \keyword{htest} surveillance/man/nowcast.Rd0000644000176200001440000003455414221271063015477 0ustar liggesusers\encoding{latin1} \name{nowcast} \alias{nowcast} %Internal functions %\alias{dist.median} %\alias{outside.ci} %\alias{logS} %\alias{RPS} \title{ Adjust a univariate time series of counts for observed but-not-yet-reported events } \description{ Nowcasting can help to obtain up-to-date information on trends during a situation where reports about events arrive with delay. For example in public health reporting, reports about important indicators (such as occurrence of cases) are prone to be delayed due to for example manual quality checking and reporting system hierarchies. Altogether, the delays are subject to a delay distribution, which may, or may not, vary over time. } \usage{ nowcast(now, when, data, dEventCol="dHospital", dReportCol="dReport", method=c("bayes.notrunc", "bayes.notrunc.bnb", "lawless", "bayes.trunc", "unif", "bayes.trunc.ddcp"), aggregate.by="1 day", D=15, m=NULL, m.interpretation=c("hoehle_anderheiden2014", "lawless1994"), control=list( dRange=NULL, alpha=0.05, nSamples=1e3, N.tInf.prior=c("poisgamma","pois","unif"), N.tInf.max=300, gd.prior.kappa=0.1, ddcp=list(ddChangepoint=NULL, cp_order=c("zero","one"), Wextra=NULL, logLambda=c("iidLogGa","tps","rw1","rw2"), responseDistr=c("poisson", "negbin"), mcmc=c(burnin=2500, sample=10000, thin=1, adapt=1000, store.samples=FALSE)), score=FALSE, predPMF=FALSE)) } \arguments{ \item{now}{ an object of class \code{Date} denoting the day at which to do the nowcast. This corresponds to \eqn{T} in the notation of \enc{Hhle}{Hoehle} and an der Heiden (2014). } \item{when}{a vector of \code{Date} objects denoting the day(s) for which the projections are to be done. One needs to ensure that each element in \code{when} is smaller or equal to \code{now}. } \item{data}{A data frame with one row per case -- for each case on needs information on the day of the event (e.g. hospitalization) and the day of report of this event. } \item{dEventCol}{The name of the column in \code{data} which contains the date of the event, e.g. hospitalization. Default: \code{"dHospital"}. } \item{dReportCol}{Name of the column in \code{data} containing the date at which the report arrives at the respective register. Default: \code{"dReport"}. } \item{method}{A vector of strings denoting the different methods for doing the nowcasting. Note that results of the first name in this list are officially returned by the function. However, it is possible to specify several methods here, e.g., in order to compare score evaluations. Details of the methods are described in \enc{Hhle}{Hoehle} and an der Heiden (2014). \describe{ \item{\code{"unif"}}{} \item{\code{"bayes.notrunc"}}{A Bayesian procedure ignoring truncation.} \item{\code{"bayes.notrunc.bnb"}}{A fast Bayesian procedure ignoring truncation and which calculates the adjustment per-time (i.e. ignoring other delays) using the negative binomial.} \item{\code{"lawless"}}{A discretized version of the Gaussian predictive distribution suggested in Lawless (1994).} \item{\code{"bayes.trunc"}}{Bayesian method based on the generalized Dirichlet distribution, which is the conjugate prior-posterior for the delay distribution PMF under right-truncated sampling as shown in HadH (2014).} \item{\code{"bayes.trunc.ddcp"}}{Fully Bayesian method allowing for change-points in the delay distribution, e.g., due to speed-ups in the reporting process. A discrete-survival model is used for the delay distribution. Details of the methods are described in HadH (2014). Note: This method requires that the JAGS program is installed on the system.} } } \item{aggregate.by}{Time scale used for the temporal aggregation of the records in the data \code{data}. See \code{\link{linelist2sts}} and \code{\link{seq.Date}} for further information.} \item{D}{Maximum possible or maximum relevant delay (unit: \code{aggregate.by}). Default: 15.} \item{m}{Size of the moving window for the estimation of the delay distribution. Default: \code{NULL}, i.e. take all values at all times. Otherwise: a positive integer equal to or greater than \code{D} such that only values from a sliding window are used. The shape of the window depends on the value of \code{m.interpretation}.} \item{m.interpretation}{This parameter controls the interpretation of the sliding window used to estimate the delay distribution. If \code{m.interpretation="hoehle_anderheiden2014"} (Default) then the sliding window is defined as a horizontal cut in the reporting triangle, i.e. the values for the delay estimation originate from reports occuring during \code{(now-m):now}. This means that the estimation of long delays is based on fewer observations than the estimation of the short delays, hence, the long delay estimates are subject to more variability. If for example \eqn{m=D} then the estimate for a delay of \eqn{d=D} is based on only one observation. The advantage of this choice is that one explicitly knows which time period all observations originate from. For details see Section 3 of \enc{Hhle}{Hoehle} and an der Heiden (2014). Alternatively, when \code{m.interpretation}="lawless1994", the cut in the reporting triangle is made such that each delay \code{d} is estimated based on the same number of observations (\eqn{m+1}). This means that in order to estimate the delay for \eqn{d} days, a sliding rectangle of length \eqn{m+1} containing the reports which occured during \code{(now-m-d):now}. See Fig. 2 in Lawless (1994) for details. Note: A warning is given is \code{method="lawless"}, but \code{m.interpretation} is not.} \item{control}{A list with named arguments controlling the functionality of the nowcasting. \describe{ \item{dRange}{Default: \code{NULL}. In this case the \code{dEventCol} column is used to extract the first and last available in \code{data}.} \item{alpha}{Equal tailed (1-\eqn{\alpha}{alpha})*100\% prediction intervals are calculated. Default: 0.05.} \item{nSamples}{Number of PMF samples in the \code{bayes.*} procedures. Note: Entire vectors containing the PMF on the grid from 0 to \code{N.tInf.max} are drawn and which are then combined. The argument does not apply to the \code{bayes.trunc.ddcp} method.} \item{N.tInf.prior}{Prior distribution of \eqn{N(t,\infty)}{N(t,Inf)}. Applies only to the \code{bayes.*} except \code{bayes.bayes.ddcp} methods. See example on how to control the distribution parameters.} \item{N.tInf.max}{Limit of the support of \eqn{N(t,\infty)}{N(t,Inf)}. The value needs to be high enough such that at this limit only little of the predictive distribution is right-truncated. Default: 300.} \item{gd.prior.kappa}{Concentration parameter for the Dirichlet prior for the delay distribution on \eqn{0,...,D}. Default: 0.1. Note: The procedure is quite sensitive to this parameter in case only few cases are available.} \item{ddcp}{A list specifying the change point model for the delay distribution. This method should only be used if detailed information about changes in the delay distribution are available as, e.g., in the case of the STEC O104:H4 outbreak. The components are as follows: \describe{ \item{\code{ddChangepoint}}{Vector of Date objects corresponding to the changepoints} \item{\code{cp_order}}{Either \code{"zero"} (Default) or \code{"one"}. This is the degree of the TPS spline for the baseline hazard, which is formed by the changepoints. Order zero corresponds to the dummy variables of the change-points being simply zero or one. In case a 1st order polynomial is chosen, this allows the delay distribution to change towards faster or slow reporting as time progresses (until the next change-point). The later can be helpful in very dynamic epidemic situations where a lot of cases suddenly appear overwhelming the surveillance system infrastructure.} \item{\code{Wextra}}{An additional design matrix part to be joined onto the part originating from the change-points. Altogether, the column bind of these two quantities will be \eqn{W_{t,d}}. This allows one to include, e.g., day of the week effects or holidays.} \item{\code{logLambda}}{Prior on the spline. One of \code{c("iidLogGa","tps","rw1","rw2")}.} \item{\code{respDistr}}{Reponse distribution of \eqn{n_{t,d}} in the reporting triangle. Default is \code{"poisson"}. An experimental alternative is to use \code{"negbin"}.} \item{\code{tau.gamma}}{} \item{\code{eta.mu}}{Vector of coefficients describing the mean of the prior normal distribution of the regression effects in the discrete time survival model.} \item{\code{eta.prec}}{A precision matrix for the regression effects in the discrete time survival model.} \item{\code{mcmc}}{A named vector of length 5 containing burn-in (default: 2500), number of samples (10000), thinning (1) and adaptation (1000) for the three MCMC chains which are ran. The values are passed on to \code{\link[runjags]{run.jags}}. The fifth argument \code{store.samples} denotes if the output of the JAGS sampling should be included as part of the returned \code{stsNC} object. Warning: If \code{TRUE} (Default: \code{FALSE}) the size of the returned object might increase substantially.} } } \item{score}{Compute scoring rules. Default: \code{FALSE}. The computed scores are found in the \code{SR} slot of the result.} \item{predPMF}{Boolean whether to return the probability mass functions of the individual forecasts (Default: \code{FALSE}). The result can be found in the \code{control} slot of the return object.} } } } \details{ The methodological details of the nowcasting procedures are described in \enc{Hhle}{Hoehle} M and an der Heiden M (2014). } \value{ \code{nowcast} returns an object of \code{"\linkS4class{stsNC}"}. The \code{upperbound} slot contains the median of the method specified at the first position the argument \code{method}. The slot \code{pi} (for prediction interval) contains the equal tailed (1-\eqn{\alpha}{alpha})*100\% prediction intervals, which are calculated based on the predictive distributions in slot \code{predPMF}. Furthermore, slot \code{truth} contains an \code{sts} object containing the true number of cases (if possible to compute it is based on the data in \code{data}). Finally, slot \code{SR} contains the results for the proper scoring rules (requires truth to be calculable). } \references{ \enc{Hhle}{Hoehle}, M. and an der Heiden, M. (2014): Bayesian nowcasting during the STEC O104:H4 outbreak in Germany, 2011. \emph{Biometrics} 70(4):993-1002. \doi{10.1111/biom.12194}.\cr A preprint is available as \url{https://staff.math.su.se/hoehle/pubs/hoehle_anderheiden2014-preprint.pdf}. \enc{Gnther}{Guenther}, F. and Bender, A. and Katz, K. and \enc{Kchenhoff}{Kuechenhoff}, H. and \enc{Hhle}{Hoehle}, M. (2020): Nowcasting the COVID-19 pandemic in Bavaria. \emph{Biometrical Journal}. \doi{10.1002/bimj.202000112}\cr Preprint available at \doi{10.1101/2020.06.26.20140210}. } \author{ Michael \enc{Hhle}{Hoehle} } \note{ Note: The \code{bayes.trunc.ddcp} uses the JAGS software together with the \R package \pkg{runjags} to handle the parallelization of the MCMC using the \code{"rjparallel"} method of \code{\link[runjags]{run.jags}}, which additionally requires the \pkg{rjags} package. You need to manually install JAGS on your computer for the package to work -- see \url{https://mcmc-jags.sourceforge.io/} and the documentation of \pkg{runjags} for details. Note: The function is still under development and might change in the future. Unfortunately, little emphasis has so far been put on making the function easy to understand and use. } \examples{ data("husO104Hosp") #Extract the reporting triangle at a specific day t.repTriangle <- as.Date("2011-07-04") #Use 'void' nowcasting procedure (we just want the reporting triangle) nc <- nowcast(now=t.repTriangle,when=t.repTriangle, dEventCol="dHosp",dReportCol="dReport",data=husO104Hosp, D=15,method="unif") #Show reporting triangle reportingTriangle(nc) #Perform Bayesian nowcasting assuming the delay distribution is stable over time nc.control <- list(N.tInf.prior=structure("poisgamma", mean.lambda=50,var.lambda=3000), nSamples=1e2) t.repTriangle <- as.Date("2011-06-10") when <- seq(t.repTriangle-3,length.out=10,by="-1 day") nc <- nowcast(now=t.repTriangle,when=when, dEventCol="dHosp",dReportCol="dReport",data=husO104Hosp, D=15,method="bayes.trunc",control=nc.control) #Show time series and posterior median forecast/nowcast plot(nc,xaxis.tickFreq=list("\%d"=atChange,"\%m"=atChange), xaxis.labelFreq=list("\%d"=at2ndChange),xaxis.labelFormat="\%d-\%b", xlab="Time (days)",lty=c(1,1,1,1),lwd=c(1,1,2)) \dontrun{ ### Using runjags to do a Bayesian model with changepoint(s) ### -- this might take a while nc.control.ddcp <- modifyList(nc.control, list(gd.prior.kappa=0.1, ddcp=list(ddChangepoint=as.Date(c("2011-05-23")), logLambda="tps", tau.gamma=1, mcmc=c(burnin=1000,sample=1000,thin=1, adapt=1000,store.samples=FALSE)))) nc.ddcp <- nowcast(now=t.repTriangle,when=when, dEventCol="dHosp",dReportCol="dReport", data=husO104Hosp, aggregate.by="1 day", method="bayes.trunc.ddcp", D=15, control=nc.control.ddcp) plot(nc.ddcp,legend.opts=NULL, xaxis.tickFreq=list("\%d"=atChange,"\%m"=atChange), xaxis.labelFreq=list("\%d"=at2ndChange),xaxis.labelFormat="\%d-\%b", xlab="Time (days)",lty=c(1,1,1,1),lwd=c(1,1,2)) lambda <- attr(delayCDF(nc.ddcp)[["bayes.trunc.ddcp"]],"model")$lambda showIdx <- seq(which( max(when) == epoch(nc.ddcp))) #seq(ncol(lambda)) matlines( showIdx,t(lambda)[showIdx,],col="gray",lwd=c(1,2,1),lty=c(2,1,2)) legend(x="topright",c(expression(lambda(t)),"95\% CI"),col="gray",lwd=c(2,1),lty=c(1,2)) } } \keyword{models} surveillance/man/measles.weser.Rd0000644000176200001440000001074014614160257016575 0ustar liggesusers\encoding{latin1} \name{measles.weser} \alias{measles.weser} \alias{measlesWeserEms} \docType{data} \keyword{datasets} \title{Measles in the Weser-Ems region of Lower Saxony, Germany, 2001-2002} \description{ Weekly counts of new measles cases for the 17 administrative districts (NUTS-3 level) of the \dQuote{Weser-Ems} region of Lower Saxony, Germany, during 2001 and 2002, as reported to the Robert Koch institute according to the Infection Protection Act (\dQuote{Infektionsschutzgesetz}, \acronym{IfSG}).\cr \code{data("measlesWeserEms")} is a corrected version of \code{data("measles.weser")} (see Format section below). These data are illustrated and analyzed in Meyer et al. (2017, Section 5), see \code{vignette("hhh4_spacetime")}. } \usage{ data("measles.weser") data("measlesWeserEms") } \format{ \code{data("measles.weser")} is an object of the old \code{"disProg"} class, whereas \code{data("measlesWeserEms")} is of the new class \code{"\linkS4class{sts}"}. Furthermore, the following updates have been applied for \code{data("measlesWeserEms")}: \itemize{ \item it includes the two districts \dQuote{SK Delmenhorst} (03401) and \dQuote{SK Wilhemshaven} (03405) with zero counts, which are ignored in \code{data("measles.weser")}. \item it corrects the time lag error for year 2002 caused by a redundant pseudo-week \dQuote{0} with 0 counts only (the row \code{measles.weser$observed[53,]} is nonsense). \item it has one more case attributed to \dQuote{LK Oldenburg} (03458) during 2001/W17, i.e., 2 cases instead of 1. This reflects the official data as of \dQuote{Jahrbuch 2005}, whereas \code{data("measles.weser")} is as of \dQuote{Jahrbuch 2004}. \item it contains a map of the region (as a \code{"\linkSPclass{SpatialPolygonsDataFrame}"}) with the following variables: \describe{ \item{\code{GEN}}{district label.} \item{\code{AREA}}{district area in m^2.} \item{\code{POPULATION}}{number of inhabitants (as of 31/12/2003).} \item{\code{vaccdoc.2004}}{proportion with a vaccination card among screened abecedarians (2004).} \item{\code{vacc1.2004}}{proportion with at least one vaccination against measles among abecedarians presenting a vaccination card (2004).} \item{\code{vacc2.2004}}{proportion of doubly vaccinated abecedarians among the ones presenting their vaccination card at school entry in the year 2004.} } \item it uses the correct format for the official district keys, i.e., 5 digits (initial 0). \item its attached neighbourhood matrix is more general: a distance matrix (neighbourhood orders) instead of just an adjacency indicator matrix (special case \code{nbOrder == 1}). \item population fractions represent data as of 31/12/2003 (\acronym{LSN}, 2004, document \dQuote{A I 2 - hj 2 / 2003}). There are only minor differences to the ones used for \code{data("measles.weser")}. } } \source{ Measles counts were obtained from the public SurvStat database of the Robert Koch institute: \url{https://survstat.rki.de/}. A shapefile of Germany's districts as of 01/01/2009 was obtained from the German Federal Agency for Cartography and Geodesy (\url{https://gdz.bkg.bund.de/}). The map of the 17 districts of the \dQuote{Weser-Ems} region (\code{measlesWeserEms@map}) is a simplified subset of this shapefile using a 30\% reduction via the Douglas-Peucker reduction method as implemented at \url{https://MapShaper.org}. Population numbers were obtained from the Federal Statistical Office of Lower Saxony (\acronym{LSN}). %\url{https://www.statistik.niedersachsen.de/} % curl status 400 ... Vaccination coverage was obtained from the public health department of Lower Saxony (\acronym{NLGA}, \dQuote{Impfreport}). %\url{https://www.nlga.niedersachsen.de/} % curl status 400 ... %% Nieders\enc{}{ae}chsisches Landesgesundheitsamt (2005): Impfreport -- %% Durchimpfung von Kindern im Einschulungsalter in Niedersachsen im %% Erhebungsjahrgang 2004. } \references{ Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \examples{ ## old "disProg" object data("measles.weser") measles.weser plot(measles.weser, as.one=FALSE) ## new "sts" object (with corrections) data("measlesWeserEms") measlesWeserEms plot(measlesWeserEms) } surveillance/man/epidataCS_aggregate.Rd0000644000176200001440000001336514614160257017671 0ustar liggesusers\name{epidataCS_aggregate} \alias{epidataCS2sts} \alias{as.epidata.epidataCS} \title{Conversion (aggregation) of \code{"epidataCS"} to \code{"epidata"} or \code{"sts"}} \description{ Continuous-time continuous-space epidemic data stored in an object of class \code{"\link{epidataCS}"} can be aggregated in space or in space and time yielding an object of class \code{"\link{epidata}"} or \code{"\linkS4class{sts}"} for use of \code{\link{twinSIR}} or \code{\link{hhh4}} modelling, respectively. } \usage{ ## aggregation in space and time over 'stgrid' for use of 'hhh4' models epidataCS2sts(object, freq, start, neighbourhood, tiles = NULL, popcol.stgrid = NULL, popdensity = TRUE) ## aggregation in space for use of 'twinSIR' models \method{as.epidata}{epidataCS}(data, tileCentroids, eps = 0.001, ...) } \arguments{ \item{object, data}{an object of class \code{"\link{epidataCS}"}.} \item{freq,start}{ see the description of the \code{"\linkS4class{sts}"} class. The \code{start} specification should reflect the beginning of \code{object$stgrid}, i.e., the start of the first time interval. } \item{neighbourhood}{ binary adjacency or neighbourhood-order matrix of the regions (\code{tiles}). If missing but \code{tiles} is given, a binary adjacency matrix will be auto-generated from \code{tiles} using functionality of the \pkg{spdep} package (see \code{\link{poly2adjmat}}). Since the \code{"neighbourhood"} slot in \code{"\linkS4class{sts}"} is actually optional, \code{neighbourhood=NULL} also works. } \item{tiles}{ object inheriting from \code{"\linkSPclass{SpatialPolygons}"} representing the regions in \code{object$stgrid} (column \code{"tile"}). It will become the \code{"map"} slot of the resulting \code{"sts"} object. Its \code{row.names} must match \code{levels(object$stgrid$tile)}. If \code{neighbourhood} is provided, \code{tiles} is optional (not required for \code{hhh4}, but for plots of the resulting \code{"sts"} object). } \item{popcol.stgrid}{ single character or numeric value indexing the column in \code{object$stgrid} which contains the population data (counts or densities, depending on the \code{popdensity} argument). This will become the \code{"populationFrac"} slot (optional).} \item{popdensity}{ logical indicating if the column referenced by \code{popcol.stgrid} contains population densities or absolute counts. } \item{tileCentroids}{ a coordinate matrix of the region centroids (i.e., the result of \code{coordinates(tiles)}). Its row names must match \code{levels(data$stgrid$tile)}. This will be the coordinates used for the \dQuote{population} (i.e., the \code{tiles} from \code{"\link{epidataCS}"}) in the discrete-space \code{\link{twinSIR}} modelling. } \item{eps}{ numeric scalar for breaking tied removal and infection times between different individuals (tiles), which might occur during conversion from \code{"epidataCS"} to \code{"epidata"}. Rather dumb, this is simply done by subtracting \code{eps} from each tied removal time. One should consider other ways of breaking the tied event times. } \item{\dots}{unused (argument of the generic).} } \details{ Conversion to \code{"\linkS4class{sts}"} only makes sense if the time intervals (\code{BLOCK}s) of the \code{stgrid} are regularly spaced (to give \code{freq} intervals per year). Note that events of the prehistory (not covered by \code{stgrid}) are not included in the resulting \code{sts} object. Some comments on the conversion to \code{"epidata"}: the conversion results into SIS epidemics only, i.e. the at-risk indicator is set to 1 immediately after recovery. A tile is considered infective if at least one individual within the tile is infective, otherwise it is susceptible. The lengths of the infectious periods are taken from \code{data$events$eps.t}. There will be no \code{f} columns in the resulting \code{"epidata"}. These must be generated by a subsequent call to \code{\link{as.epidata}} with desired \code{f}. } \value{ \code{epidataCS2sts}: an object of class \code{"\linkS4class{sts}"} representing the multivariate time-series of the number of cases aggregated over \code{stgrid}. \code{as.epidata.epidataCS}: an object of class \code{"\link{epidata}"} representing an SIS epidemic in form of a multivariate point process (one for each region/\code{tile}). } \author{ Sebastian Meyer } \seealso{ \code{\link{epidata}} and \code{\link{twinSIR}} \code{linkS4class{sts}} and \code{\link{hhh4}}. } \examples{ data("imdepi") load(system.file("shapes", "districtsD.RData", package="surveillance")) ## convert imdepi point pattern into multivariate time series imdsts <- epidataCS2sts(imdepi, freq = 12, start = c(2002, 1), neighbourhood = NULL, # not needed here tiles = districtsD) ## check the overall number of events by district stopifnot(all.equal(colSums(observed(imdsts)), c(table(imdepi$events$tile)))) ## compare plots of monthly number of cases opar <- par(mfrow = c(2, 1)) plot(imdepi, "time") plot(imdsts, type = observed ~ time) par(opar) \dontshow{if (surveillance.options("allExamples"))} ## plot number of cases by district plot(imdsts, type = observed ~ unit) ## also test conversion to an SIS event history ("epidata") of the "tiles" if (requireNamespace("intervals")) { imdepi_short <- subset(imdepi, time < 50) # to reduce the runtime imdepi_short$stgrid <- subset(imdepi_short$stgrid, start < 50) imdepidata <- as.epidata(imdepi_short, tileCentroids = coordinates(districtsD)) summary(imdepidata) } } \keyword{spatial} \keyword{manip} \keyword{methods} surveillance/man/coeflist.Rd0000644000176200001440000000207112476432506015631 0ustar liggesusers\name{coeflist} \alias{coeflist} \alias{coeflist.default} \title{ List Coefficients by Model Component } \description{ S3-generic function to use with models which contain several groups of coefficients in their coefficient vector. The \code{coeflist} methods are intended to list the coefficients by group. The default method simply \code{\link{split}}s the coefficient vector given the number of coefficients by group. } \usage{ coeflist(x, ...) \method{coeflist}{default}(x, npars, ...) } \arguments{ \item{x}{ a model with groups of coefficients or, for the default method, a vector of coefficients. } \item{npars}{ a named vector specifying the number of coefficients per group. } \item{\dots}{ potential further arguments (currently ignored). } } \value{ a list of coefficients } \author{ Sebastian Meyer } \examples{ ## the default method just 'split's the coefficient vector coefs <- c(a = 1, b = 3, dispersion = 0.5) npars <- c(regression = 2, variance = 1) coeflist(coefs, npars) } \keyword{models} \keyword{utilities} surveillance/man/twinSIR.Rd0000644000176200001440000003611214224035777015365 0ustar liggesusers\encoding{latin1} \name{twinSIR} \alias{twinSIR} \title{ Fit an Additive-Multiplicative Intensity Model for SIR Data } \description{ \code{twinSIR} is used to fit additive-multiplicative intensity models for epidemics as described in \enc{Hhle}{Hoehle} (2009). Estimation is driven by (penalized) maximum likelihood in the point process frame work. Optimization (maximization) of the (penalized) likelihood function is performed by means of \code{\link{optim}}. The implementation is illustrated in Meyer et al. (2017, Section 4), see \code{vignette("twinSIR")}. } \usage{ twinSIR(formula, data, weights, subset, knots = NULL, nIntervals = 1, lambda.smooth = 0, penalty = 1, optim.args = list(), model = TRUE, keep.data = FALSE) } \arguments{ \item{formula}{ an object of class \code{"\link{formula}"} (or one that can be coerced to that class): a symbolic description of the intensity model to be estimated. The details of the model specification are given below. } \item{data}{ an object inheriting from class \code{"\link{epidata}"}. } \item{weights}{ an optional vector of weights to be used in the fitting process. Should be \code{NULL} (the default, i.e. all observations have unit weight) or a numeric vector. } \item{subset}{ an optional vector specifying a subset of observations to be used in the fitting process. The subset \code{atRiskY == 1} is automatically chosen, because the likelihood only depends on those observations. } \item{knots}{ numeric vector or \code{NULL} (the default). Specification of the knots, where we suppose a step of the log-baseline. With the current implementation, these must be existing \code{"stop"} time points in the selected \code{subset} of the \code{data}, which is always restricted to \code{atRiskY == 1} rows. The intervals of constant log-baseline hazard rate then are \eqn{(minTime;knots_1]}, \eqn{(knots_1;knots_2]}, \ldots, \eqn{(knots_K;maxTime]}. By default, the \code{knots} are automatically chosen at the quantiles of the infection time points such that \code{nIntervals} intervals result. Non-NULL \code{knots} take precedence over \code{nIntervals}. } \item{nIntervals}{ the number of intervals of constant log-baseline hazard. Defaults to 1, which means an overall constant log-baseline hazard will be fitted. } \item{lambda.smooth}{ numeric, the smoothing parameter \eqn{\lambda}. By default it is 0 which leads to unpenalized likelihood inference. In case \code{lambda.smooth=-1}, the automatic smoothing parameter selection based on a mixed model approach is used (cf. \enc{Hhle}{Hoehle}, 2009). } \item{penalty}{ either a single number denoting the order of the difference used to penalize the log-baseline coefficients (defaults to 1), or a more specific penalty matrix \eqn{K} for the parameter sub-vector \eqn{\beta}. In case of non-equidistant knots -- usually the case when using quantile based knot locations -- only a 1st order differences penalty matrix as in Fahrmeir and Lang (2001) is implemented. } \item{optim.args}{ a list with arguments passed to the \code{\link{optim}} function. Especially useful are the following ones: \describe{ \item{\code{par}:}{ to specify initial parameter values. Those must be in the order \code{c(alpha, h0, beta)}, i.e. first the coefficients of the epidemic covariates in the same order as they appear in the \code{formula}, then the log-baseline levels in chronological order and finally the coefficients of the endemic covariates in the same order as they appear in the \code{cox} terms of the \code{formula}. The default is to start with 1's for \code{alpha} and 0's for \code{h0} and \code{beta}. } \item{\code{control}:}{ for more detailed \code{trace}-ing (default: 1), another \code{REPORT}-ing frequency if \code{trace} is positive (default: 10), higher \code{maxit} (maximum number of iterations, default: 300) or another \code{factr} value (default: 1e7, a lower value means higher precision). } \item{\code{method}:}{ the optimization algorithm defaults to \code{"L-BFGS-B"} (for box-constrained optimization), if there are any epidemic (non-\code{cox}) variables in the model, and to \code{"BFGS"} otherwise. } \item{\code{lower}:}{ if \code{method = "L-BFGS-B"} this defines the lower bounds for the model coefficients. By default, all effects \eqn{\alpha} of epidemic variables are restricted to be non-negative. Normally, this is exactly what one would like to have, but there might be reasons for other lower bounds, see the Note below. } \item{\code{hessian}:}{ An estimation of the Expected Fisher Information matrix is always part of the return value of the function. It might be interesting to see the Observed Fisher Information (= negative Hessian at the maximum), too. This will be additionally returned if \code{hessian = TRUE}. } } } \item{model}{ logical indicating if the model frame, the \code{weights}, \code{lambda.smooth}, the penalty matrix \eqn{K} and the list of used distance functions \code{f} (from \code{attributes(data)}) should be returned for further computation. This defaults to \code{TRUE} as this information is necessary e.g. in the \code{profile} and \code{plot} methods. } \item{keep.data}{ logical indicating if the \code{"epidata"} object (\code{data}) should be part of the return value. This is only necessary for use of the \code{\link[=simulate.twinSIR]{simulate}}-method for \code{"twinSIR"} objects. The reason is that the \code{twinSIR} function only uses and stores the rows with \code{atRiskY == 1} in the \code{model} component, but for the simulation of new epidemic data one needs the whole data set with all individuals in every time block. The default value is \code{FALSE}, so if you intent to use \code{simulate.twinSIR}, you have to set this to \code{TRUE}. } } \details{ A model is specified through the \code{formula}, which has the form \code{~ epidemicTerm1 + epidemicTerm2 + cox(endemicVar1) * cox(endemicVar2)}, i.e. the right hand side has the usual form as in \code{\link{lm}} with some variables marked as being endemic by the special function \code{\link{cox}}. The left hand side of the formula is empty and will be set internally to \code{cbind(start, stop, event)}, which is similar to \code{Surv(start, stop, event, type="counting")} in package \pkg{survival}. Basically, the additive-multiplicative model for the infection intensity \eqn{\lambda_i(t)} for individual \eqn{i} is \deqn{\lambda_i(t) = Y_i(t) * (e_i(t) + h_i(t))} where \describe{ \item{Y_i(t)}{ is the at-risk indicator, indicating if individual \eqn{i} is \dQuote{at risk} of becoming infected at time point \eqn{t}. This variable is part of the event history \code{data}. } \item{e_i(t)}{ is the epidemic component of the infection intensity, defined as \deqn{e_i(t) = \sum_{j \in I(t)} f(||s_i - s_j||)} where \eqn{I(t)} is the set of infectious individuals just before time point \eqn{t}, \eqn{s_i} is the coordinate vector of individual \eqn{i} and the function \eqn{f} is defined as \deqn{f(u) = \sum_{m=1}^p \alpha_m B_m(u)} with unknown transmission parameters \eqn{\alpha} and known distance functions \eqn{B_m}. This set of distance functions results in the set of epidemic variables normally calculated by the converter function \code{\link{as.epidata}}, considering the equality \deqn{e_i(t) = \sum_{m=1}^p \alpha_m x_{im}(t)} with \eqn{x_{im}(t) = \sum_{j \in I(t)} B_m(||s_i - s_j||)} being the \eqn{m}'th epidemic variable for individual \eqn{i}. } \item{h_i(t)}{ is the endemic (\code{cox}) component of the infection intensity, defined as \deqn{h_i(t) = \exp(h_0(t) + z_i(t)' \beta)} where \eqn{h_0(t)} is the log-baseline hazard function, \eqn{z_i(t)} is the vector of endemic covariates of individual \eqn{i} and \eqn{\beta} is the vector of unknown coefficients. To fit the model, the log-baseline hazard function is approximated by a piecewise constant function with known knots, but unknown levels, which will be estimated. The approximation is specified by the arguments \code{knots} or \code{nIntervals}. } } If a big number of \code{knots} (or \code{nIntervals}) is chosen, the corresponding log-baseline parameters can be rendered identifiable by the use of penalized likelihood inference. At present, it is the job of the user to choose an adequate value of the smoothing parameter \code{lambda.smooth}. Alternatively, a data driven \code{lambda.smooth} smoothing parameter selection based on a mixed model representation of an equivalent truncated power spline is offered (see reference for further details). The following two steps are iterated until convergence: \enumerate{ \item Given fixed smoothing parameter, the penalized likelihood is optimized for the regression components using a L-BFGS-B approach \item Given fixed regression parameters, a Laplace approximation of the marginal likelihood for the smoothing parameter is numerically optimized. } Depending on the data, convergence might take a couple of iterations. Note also that it is unwise to include endemic covariates with huge values, as they affect the intensities on the exponential scale (after multiplication by the parameter vector \eqn{\beta}). With large covariate values, the \code{optim} method "L-BFGS-B" will likely terminate due to an infinite log-likelihood or score function in some iteration. } \value{ \code{twinSIR} returns an object of class \code{"twinSIR"}, which is a list containing the following components: \item{coefficients}{a named vector of coefficients.} \item{loglik}{the maximum of the (penalized) log-likelihood function.} \item{counts}{the number of log-likelihood and score function evaluations.} \item{converged}{logical indicating convergence of the optimization algorithm.} \item{fisherinfo.observed}{if requested, the negative Hessian from \code{optim}.} \item{fisherinfo}{an estimation of the Expected Fisher Information matrix.} \item{method}{the optimization algorithm used.} \item{intervals}{a numeric vector (\code{c(minTime, knots, maxTime)}) representing the consecutive intervals of constant log-baseline.} \item{nEvents}{a numeric vector containing the number of infections in each of the above \code{intervals}.} \item{model}{if requested, the model information used. This is a list with components \code{"survs"} (data.frame with the id, start, stop and event columns), \code{"X"} (matrix of the epidemic variables), \code{"Z"} (matrix of the endemic variables), \code{"weights"} (the specified \code{weights}), \code{"lambda.smooth"} (the specified \code{lambda.smooth}), \code{"K"} (the penalty matrix used), and \code{"f"} and \code{"w"} (the functions to generate the used epidemic covariates). Be aware that the model only contains those rows with \code{atRiskY == 1}!} \item{data}{if requested, the supplied \code{"epidata"} \code{data}.} \item{call}{the matched call.} \item{formula}{the specified \code{formula}.} \item{terms}{the \code{terms} object used.} } \references{ \enc{Hhle}{Hoehle}, M. (2009), Additive-multiplicative regression models for spatio-temporal epidemics, \emph{Biometrical Journal}, \bold{51} (6), 961-978. Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \author{ Michael \enc{Hhle}{Hoehle} and Sebastian Meyer } \note{ There are some restrictions to modelling the infection intensity without a baseline hazard rate, i.e. without an intercept in the \code{formula}. Reason: At some point, the optimization algorithm L-BFGS-B tries to set all transmission parameters \eqn{\alpha} to the boundary value 0 and to calculate the (penalized) score function with this set of parameters (all 0). The problem then is that the values of the infection intensities \eqn{lambda_i(t)} are 0 for all \eqn{i} and \eqn{t} and especially at observed event times, which is impossible. Without a baseline, it is not allowed to have all alpha's set to 0, because then we would not observe any infections. Unfortunately, L-BFGS-B can not consider this restriction. Thus, if one wants to fit a model without baseline hazard, the control parameter \code{lower} must be specified in \code{optim.args} so that some alpha is strictly positive, e.g. \code{optim.args = list(lower = c(0,0.001,0.001,0))} and the initial parameter vector \code{par} must not be the zero vector. } \seealso{ \code{\link{as.epidata}} for the necessary data input structure, \code{\link{plot.twinSIR}} for plotting the path of the infection intensity, \code{\link{profile.twinSIR}} for profile likelihood estimation. and \code{\link{simulate.twinSIR}} for the simulation of epidemics following the fitted model. Furthermore, the standard extraction methods \code{\link[=vcov.twinSIR]{vcov}}, \code{\link[=logLik.twinSIR]{logLik}}, \code{\link[=AIC.twinSIR]{AIC}} and \code{\link[=extractAIC.twinSIR]{extractAIC}} are implemented for objects of class \code{"twinSIR"}. } \examples{ data("hagelloch") summary(hagelloch) # simple model with an overall constant baseline hazard rate fit1 <- twinSIR(~ household + cox(AGE), data = hagelloch) fit1 summary(fit1) # see also help("summary.twinSIR") plot(fit1) # see also help("plot.twinSIR") checkResidualProcess(fit1) # could be better # fit a piecewise constant baseline hazard rate with 3 intervals using # _un_penalized ML and estimated coefs from fit1 as starting values fit2 <- twinSIR(~ household, data = hagelloch, nIntervals = 3, optim.args = list(par = coef(fit1)[c(1,2,2,2)])) summary(fit2) # fit a piecewise constant baseline hazard rate with 7 intervals # using _penalized_ ML fit3 <- twinSIR(~ household, data = hagelloch, nIntervals = 7, lambda.smooth = 0.1, penalty = 1) summary(fit3) checkResidualProcess(fit3) # plot the estimated log-baseline levels plot(x=fit2$intervals, y=coef(fit2)[c(2,2:4)], type="S", ylim=c(-6, -1)) lines(x=fit3$intervals, y=coef(fit3)[c(2,2:8)], type="S", col=2) legend("right", legend=c("unpenalized 3", "penalized 7"), lty=1, col=1:2, bty="n") ## special use case: fit the model to a subset of the events only, ## while preserving epidemic contributions from the remainder ## (maybe some buffer area nodes) fit_subset <- twinSIR(~ household, data = hagelloch, subset = CL=="preschool") summary(fit_subset) \dontshow{ ## the eventTimes attribute was wrong in surveillance <= 1.15.0 stopifnot( length(residuals(fit_subset)) == sum(fit_subset$model$survs$event) ) } } \keyword{models} \keyword{optimize} surveillance/man/surveillance.options.Rd0000644000176200001440000000510014516240231020170 0ustar liggesusers\name{surveillance.options} \alias{surveillance.options} \alias{reset.surveillance.options} \title{Options of the \pkg{surveillance} Package} \description{ Query, set or reset options specific to the \pkg{surveillance} package, similar to what \code{\link{options}} does for global settings. } \usage{ surveillance.options(...) reset.surveillance.options() } \arguments{ \item{\dots}{ Either empty, or a sequence of option names (as strings), or a sequence of \code{name=value} pairs, or a named list of options. Available options are: \describe{ \item{stsTickFactors:}{ A named vector containing tick sizes for the \code{"sts"} x-axis relative to \code{\link{par}("tcl")}. Each entry contains the size at \code{\link{strptime}} formatting strings. See the help on \code{\link{stsplot_time1}} for details. \describe{ \item{"\%d"}{} \item{"\%W"}{} \item{"\%V"}{} \item{"\%m"}{} \item{"\%Q"}{} \item{"\%Y"}{} \item{"\%G"}{} } } \item{colors:}{ A named list containing plotting color defaults. \describe{ \item{nowSymbol}{Color of the "now" symbol in \code{stsNC} plots. Default: \code{"springgreen4"}.} \item{piBars}{Color of the prediction interval bars in \code{stsNC} plots. Default: \code{"orange"}.} } } \item{allExamples:}{ Logical flag queried before running cumbersome computations in help file examples. For \code{interactive()} sessions, this option defaults to \code{TRUE}. Otherwise, long examples will only be run if the environment variable \env{_R_SURVEILLANCE_ALL_EXAMPLES_} is set (to any value different from \code{""}) when attaching the \pkg{surveillance} package. This is to avoid long computations during (daily) CRAN checks. } } } } \value{ \code{reset.surveillance.options} reverts all options to their default values and (invisibly) returns these in a list. For \code{surveillance.options}, the following holds: \itemize{ \item If no arguments are given, the current values of all package options are returned in a list. \item If one option name is given, the current value of this option is returned (\emph{not} in a list, just the value). \item If several option names are given, the current values of these options are returned in a list. \item If \code{name=value} pairs are given, the named options are set to the given values, and the \emph{previous} values of these options are returned in a list. } } \examples{ surveillance.options() } \keyword{environment} surveillance/man/campyDE.Rd0000644000176200001440000000555614004512307015341 0ustar liggesusers\encoding{latin1} \name{campyDE} \alias{campyDE} \docType{data} \title{Campylobacteriosis and Absolute Humidity in Germany 2002-2011} \description{ Weekly number of reported campylobacteriosis cases in Germany, 2002-2011, together with the corresponding absolute humidity (in g/m^3) that week. The absolute humidity was computed according to the procedure by Dengler (1997) using the means of representative weather station data from the German Climate service. } \usage{ data(campyDE) } \format{ A \code{data.frame} containing the following columns \describe{ \item{\code{date}}{\code{Date} instance containing the Monday of the reporting week.} \item{\code{case}}{Number of reported cases that week.} \item{\code{state}}{Boolean indicating whether there is external knowledge about an outbreak that week} \item{\code{hum}}{Mean absolute humidity (in g/m^3) of that week as measured by a single representative weather station.} \item{\code{l1.hum}-\code{l5.hum}}{Lagged version (lagged by 1-5) of the \code{hum} covariate.} \item{newyears}{Boolean indicating whether the reporting week corresponds to the first two weeks of the year (TRUE) or not (FALSE). Note: The first week of a year is here defined as the first reporting week, which has its corresponding Monday within new year.} \item{christmas}{Boolean indicating whether the reporting week corresponds to the last two weeks of the year (TRUE) or not (FALSE). Note: This are the first two weeks before the \code{newyears} weeks.} \item{O104period}{Boolean indicating whether the reporting week corresponds to the W21-W30 period of increased gastroenteritis awareness during the O104:H4 STEC outbreak.} } } \source{ The data on campylobacteriosis cases have been queried from the Survstat@RKI database of the German Robert Koch Institute (\url{https://survstat.rki.de/}). Data for the computation of absolute humidity were obtained from the German Climate Service (Deutscher Wetterdienst), Climate data of Germany, available at \url{https://www.dwd.de}. A complete data description and an analysis of the data can be found in Manitz and \enc{Hhle}{Hoehle} (2013). } \references{ Manitz, J. and \enc{Hhle}{Hoehle}, M. (2013): Bayesian outbreak detection algorithm for monitoring reported cases of campylobacteriosis in Germany. Biometrical Journal, 55(4), 509-526. } \examples{ # Load the data data("campyDE") # O104 period is W21-W30 in 2011 stopifnot(all(campyDE$O104period == ( (campyDE$date >= as.Date("2011-05-23")) & (campyDE$date < as.Date("2011-07-31")) ))) # Make an sts object from the data.frame cam.sts <- sts(epoch=campyDE$date, observed=campyDE$case, state=campyDE$state) # Plot the result plot(cam.sts) } \keyword{datasets} surveillance/man/stsNewport.Rd0000644000176200001440000000126114026351202016173 0ustar liggesusers\encoding{latin1} \name{stsNewport} \alias{stsNewport} \docType{data} \title{Salmonella Newport cases in Germany 2001-2015} \description{ Reported number of cases of the Salmonella Newport serovar in Germany 2001-2015, by date of disease onset. The slot \code{control} contains a matrix \code{reportingTriangle$n} with the reporting triangle as described in Salmon et al. (2015). } \usage{data(stsNewport)} \format{ A \code{sts} object. } \references{ Salmon, M., Schumacher, D., Stark, K., \enc{Hhle}{Hoehle}, M. (2015): Bayesian outbreak detection in the presence of reporting delays. Biometrical Journal, 57 (6), 1051-1067. } \keyword{datasets} surveillance/man/stsplot_space.Rd0000644000176200001440000001513414614160257016705 0ustar liggesusers\name{stsplot_space} \alias{stsplot_space} \title{ Map of Disease Counts/Incidence accumulated over a Given Period } \description{ This is the \code{plot} variant of \code{type=observed~unit} for \code{"\linkS4class{sts}"} objects, i.e., \code{plot(stsObj, type=observed~unit, ...)} calls the function documented below. It produces an \code{\link[sp]{spplot}} where regions are color-coded according to disease incidence (either absolute counts or relative to population) over a given time period. } \usage{ stsplot_space(x, tps = NULL, map = x@map, population = NULL, main = NULL, labels = FALSE, ..., at = 10, col.regions = NULL, colorkey = list(space = "bottom", labels = list(at=at)), total.args = NULL, gpar.missing = list(col = "darkgrey", lty = 2, lwd = 2), sp.layout = NULL, %aspect = mapasp(map), xlim = bbox(map)[1, ], ylim = bbox(map)[2, ]) } \arguments{ \item{x}{ an object of class \code{"\linkS4class{sts}"} or a matrix of counts, i.e., \code{observed(stsObj)}, where especially \code{colnames(x)} have to be contained in \code{row.names(map)}. If a matrix, the \code{map} object has to be provided explicitly. The possibility of specifying a matrix is, e.g., useful to plot mean counts of simulations from \code{\link{simulate.hhh4}}. } \item{tps}{ a numeric vector of one or more time points. The unit-specific \emph{sum} over all time points \code{tps} is plotted. The default \code{tps=NULL} means accumulation over the whole time period \code{1:nrow(x)}. } \item{map}{ an object inheriting from \code{"\linkSPclass{SpatialPolygons}"} representing the \code{ncol(x)} regions. By default the \code{map} slot of \code{x} is queried (which might be empty and is not applicable if \code{x} is a matrix of counts). } \item{population}{ if \code{NULL} (default), the map shows the region-specific numbers of cases accumulated over \code{tps}. For a disease incidence map, \code{population} can be specified in three ways: \itemize{ \item a numeric vector of population numbers in the \code{ncol(x)} regions, used to divide the disease counts. \item a matrix of population counts of dimension \code{dim(x)} (such as \code{population(x)} in an \code{"sts"} object). This will produce the cumulative incidence over \code{tps} relative to the population at the first time point, i.e., only \code{population[tps[1],]} is used. \item [if \code{is(x, "sts")}] a scalar specifying how \code{population(x)} should be scaled for use as the population matrix, i.e., \code{population(x)/population} is used. For instance, if \code{population(x)} contains raw population numbers, \code{population=1000} would produce the incidence per 1000 inhabitants. } } \item{main}{ a main title for the plot. If \code{NULL} and \code{x} is of class \code{"sts"}, the time range of \code{tps} is put as the main title. } \item{labels}{ determines if and how the regions of the \code{map} are labeled, see \code{\link{layout.labels}}. } \item{\dots}{ further arguments for \code{\link[sp]{spplot}}, for example \code{col = "white"} for white polygon lines. } \item{at}{ either a number of levels (default: 10) for the categorization (color-coding) of counts/incidence, or a numeric vector of specific break points, or a named list of a number of levels (\code{"n"}), a transformer (\code{"trafo"}) of class \code{"\link[scales]{trans}"} defined by package \pkg{scales}, and optional further arguments for \code{\link{pretty}}. The default breaks are equally spaced on the square-root scale (equivalent to \code{\link[scales]{sqrt_trans}}). Note that intervals given by \code{at} are closed on the left and open to the right; if manually specified break points do not cover the data range, further breaks are automatically added at 0 and the maximum (rounded up to 1 significant digit), respectively. } \item{col.regions}{ a vector of fill colors, sufficiently long to serve all levels (determined by \code{at}). \dQuote{Heat} colors are used by default (\code{NULL}). } \item{colorkey}{ a list describing the color key, see \code{\link[lattice]{levelplot}}. The default list elements will be updated by the provided list using \code{\link{modifyList}}. } \item{total.args}{ an optional list of arguments for \code{\link[grid]{grid.text}} to have the overall number/incidence of cases printed at an edge of the map. The default settings are \code{list(label="Overall: ", x=1, y=0)}, and \code{total.args=list()} will use all of them. } \item{gpar.missing}{list of graphical parameters for \code{\link[sp]{sp.polygons}} applied to the regions of \code{map}, which are not part of \code{x}. Such extra regions won't be plotted if \code{!is.list(gpar.missing)}.} \item{sp.layout}{ optional list of additional layout items, see \code{\link[sp]{spplot}}. } %% currently hard-coded for simplicity (rarely needed): %% \item{aspect}{the aspect ratio, see \code{\link[lattice]{levelplot}}. %% Defaults to \code{"iso"} for projected coordinates.} \item{xlim,ylim}{numeric vectors of length 2 specifying the axis limits.} } \value{ a lattice plot of class \code{"\link[lattice:trellis.object]{trellis}"}, but see \code{\link[sp]{spplot}}. } \author{ Sebastian Meyer } \seealso{ the central \code{\link{stsplot}}-documentation for an overview of plot types, and \code{\link{animate.sts}} for animations of \code{"sts"} objects. } \examples{ data("measlesWeserEms") # default plot: total region-specific counts over all weeks plot(measlesWeserEms, type = observed ~ unit) stsplot_space(measlesWeserEms) # the same # cumulative incidence (per 100'000 inhabitants), # with region labels and white borders plot(measlesWeserEms, observed ~ unit, population = measlesWeserEms@map$POPULATION / 100000, labels = list(labels = "GEN", cex = 0.7, font = 3), col = "white", lwd = 2, sub = "cumulative incidence (per 100'000 inhabitants)") # incidence in a particular week, manual color breaks, display total plot(measlesWeserEms, observed ~ unit, tps = 62, population = measlesWeserEms@map$POPULATION / 100000, at = c(0, 1, 5), total.args = list(x = 0, label = "Overall incidence: ")) # if we had only observed a subset of the regions plot(measlesWeserEms[,5:11], observed ~ unit, gpar.missing = list(col = "gray", lty = 4)) } \keyword{hplot} \keyword{spatial} surveillance/man/epidataCS_update.Rd0000644000176200001440000000566114614536762017235 0ustar liggesusers\name{epidataCS_update} \alias{update.epidataCS} \title{ Update method for \code{"epidataCS"} } \description{ The \code{\link{update}} method for the \code{"\link{epidataCS}"} class may be used to modify the hyperparameters \eqn{\epsilon} (\code{eps.t}) and \eqn{\delta} (\code{eps.s}), the indicator matrix \code{qmatrix} determining possible transmission between the event types, the numerical accuracy \code{nCircle2Poly} of the polygonal approximation, and the endemic covariates from \code{stgrid} (including the time intervals). The update method will also update the auxiliary information contained in an \code{"epidataCS"} object accordingly, e.g., the vector of potential sources of each event, the influence regions, or the endemic covariates copied from the new \code{stgrid}. } \usage{ \method{update}{epidataCS}(object, eps.t, eps.s, qmatrix, nCircle2Poly, stgrid, ...) } \arguments{ \item{object}{ an object of class \code{"epidataCS"}. } \item{eps.t}{ numeric vector of length 1 or corresponding to the number of events in \code{object$events}. The event data column \code{eps.t} specifies the maximum temporal influence radius (e.g., length of infectious period, time to culling, etc.) of the events. } \item{eps.s}{ numeric vector of length 1 or corresponding to the number of events in \code{object$events}. The event data column \code{eps.s} specifies the maximum spatial influence radius of the events. } \item{qmatrix}{ square indicator matrix (0/1 or TRUE/FALSE) for possible transmission between the event types. } \item{nCircle2Poly}{ accuracy (number of edges) of the polygonal approximation of a circle. } \item{stgrid}{ a new \code{data.frame} with endemic covariates, possibly transformed from or adding to the original \code{object$stgrid}. The grid must cover the same regions as the original, i.e., \code{levels(object$stgrid$tile)} must remain identical. See \code{\link{epidataCS}} for a detailed description of the required format. } \item{\dots}{ unused (argument of the generic). } } \value{ The updated \code{"epidataCS"} object. } \author{ Sebastian Meyer } \seealso{ class \code{"\link{epidataCS}"}. } \examples{ data("imdepi") ## assume different interaction ranges and simplify polygons imdepi2 <- update(imdepi, eps.t = 20, eps.s = Inf, nCircle2Poly = 16) (s <- summary(imdepi)) (s2 <- summary(imdepi2)) ## The update reduced the number of infectives (along time) ## because the length of the infectious periods is reduced. It also ## changed the set of potential sources of transmission for each ## event, since the interaction is shorter in time but wider in space ## (eps.s=Inf means interaction over the whole observation region). ## use a time-constant grid imdepi3 <- update(imdepi, stgrid = subset(imdepi$stgrid, BLOCK == 1, -stop)) (s3 <- summary(imdepi3)) # "1 time block" } \keyword{manip} \keyword{utilities} \keyword{methods} surveillance/man/findH.Rd0000644000176200001440000000445313122471774015056 0ustar liggesusers\name{findH} \alias{findH} \alias{hValues} \title{Find decision interval for given in-control ARL and reference value} \description{ Function to find a decision interval \code{h}* for given reference value \code{k} and desired ARL \eqn{\gamma} so that the average run length for a Poisson or Binomial CUSUM with in-control parameter \eqn{\theta_0}, reference value \code{k} and is approximately \eqn{\gamma}, i.e. \eqn{\Big| \frac{ARL(h^*) -\gamma}{\gamma} \Big| < \epsilon}, or larger, i.e. \eqn{ARL(h^*) > \gamma }. } \usage{ findH(ARL0, theta0, s = 1, rel.tol = 0.03, roundK = TRUE, distr = c("poisson", "binomial"), digits = 1, FIR = FALSE, ...) hValues(theta0, ARL0, rel.tol=0.02, s = 1, roundK = TRUE, digits = 1, distr = c("poisson", "binomial"), FIR = FALSE, ...) } \arguments{ \item{ARL0}{ desired in-control ARL \eqn{\gamma} } \item{theta0}{in-control parameter \eqn{\theta_0}} \item{s}{change to detect, see details} \item{distr}{ \code{"poisson"} or \code{"binomial"} } \item{rel.tol}{relative tolerance, i.e. the search for \code{h}* is stopped if \eqn{\Big| \frac{ARL(h^*) -\gamma}{\gamma} \Big| < } \code{rel.tol} } \item{digits}{the reference value \code{k} and the decision interval \code{h} are rounded to \code{digits} decimal places} \item{roundK}{ passed to \code{findK} } \item{FIR}{if \code{TRUE}, the decision interval that leads to the desired ARL for a FIR CUSUM with head start \eqn{\frac{\code{h}}{2}} is returned } \item{\dots}{ further arguments for the distribution function, i.e. number of trials \code{n} for binomial cdf } } \value{ \code{findH} returns a vector and \code{hValues} returns a matrix with elements \item{theta0}{in-control parameter} \item{h}{decision interval} \item{k}{reference value} \item{ARL}{ARL for a CUSUM with parameters \code{k} and \code{h} } \item{rel.tol}{corresponds to \eqn{\Big| \frac{ARL(h) -\gamma}{\gamma} \Big|} } } \details{ The out-of-control parameter used to determine the reference value \code{k} is specified as: \deqn{\theta_1 = \lambda_0 + s \sqrt{\lambda_0} } for a Poisson variate \eqn{X \sim Po(\lambda)} \deqn{\theta_1 = \frac{s \pi_0}{1+(s-1) \pi_0} } for a Binomial variate \eqn{X \sim Bin(n, \pi) } } \keyword{models} surveillance/man/shadar.Rd0000644000176200001440000000114013174706302015251 0ustar liggesusers\name{shadar} \alias{shadar} \docType{data} \title{Salmonella Hadar cases in Germany 2001-2006} \description{ Number of salmonella hadar cases in Germany 2001-2006. An increase is seen during 2006. } \usage{data(shadar)} \format{ A \code{disProg} object containing \eqn{295\times 1}{295 x 1} observations starting from week 1 in 2001 to week 35 in 2006. } \source{ Robert Koch-Institut: SurvStat: \url{https://survstat.rki.de/}; Queried on September 2006. Robert Koch Institut, Epidemiologisches Bulletin 31/2006. } \examples{ data(shadar) plot(shadar) } \keyword{datasets} surveillance/man/bestCombination.Rd0000644000176200001440000000102513122471774017136 0ustar liggesusers\name{bestCombination} \alias{bestCombination} \title{Partition of a number into two factors} \description{ Given a prime number factorization \code{x}, \code{bestCombination} partitions \code{x} into two groups, such that the product of the numbers in group one is as similar as possible to the product of the numbers of group two. This is useful in \code{\link{magic.dim}}. } \usage{ bestCombination(x) } \arguments{ \item{x}{prime number factorization} } \value{a vector \code{c(prod(set1),prod(set2))}} \keyword{dplot} surveillance/man/algo.cdc.Rd0000644000176200001440000000627314310560071015467 0ustar liggesusers\name{algo.cdc} \alias{algo.cdcLatestTimepoint} \alias{algo.cdc} \encoding{latin1} \title{The CDC Algorithm} \description{ Surveillance using the CDC Algorithm } \usage{ algo.cdcLatestTimepoint(disProgObj, timePoint = NULL, control = list(b = 5, m = 1, alpha=0.025)) algo.cdc(disProgObj, control = list(range = range, b= 5, m=1, alpha = 0.025)) } \arguments{ \item{disProgObj}{object of class disProg (including the observed and the state chain).} \item{timePoint}{time point which should be evaluated in \code{algo.cdcLatestTimepoint}. The default is to use the latest timepoint.} \item{control}{control object: \code{range} determines the desired timepoints which should be evaluated, \code{b} describes the number of years to go back for the reference values, \code{m} is the half window width for the reference values around the appropriate timepoint (see details). The standard definition is \code{b}=5 and \code{m}=1.} } \details{ Using the reference values for calculating an upper limit, alarm is given if the actual value is bigger than a computed threshold. \code{algo.cdc} calls \code{algo.cdcLatestTimepoint} for the values specified in \code{range} and for the system specified in \code{control}. The threshold is calculated from the predictive distribution, i.e. \deqn{mean(x) + z_{\alpha/2} * sd(x) * \sqrt{1+1/k},} which corresponds to Equation 8-1 in Farrington and Andrews (2003). Note that an aggregation into 4-week blocks occurs in \code{algo.cdcLatestTimepoint} and \code{m} denotes number of 4-week blocks (months) to use as reference values. This function currently does the same for monthly data (not correct!) } \value{ \code{algo.cdcLatestTimepoint} returns a list of class \code{survRes} (surveillance result), which includes the alarm value (alarm = 1, no alarm = 0) for recognizing an outbreak, the threshold value for recognizing the alarm and the input object of class disProg. \code{algo.cdc} gives a list of class \code{survRes} which includes the vector of alarm values for every timepoint in \code{range}, the vector of threshold values for every timepoint in \code{range} for the system specified by \code{b}, \code{w}, the range and the input object of class disProg. } \seealso{ \code{\link{algo.rkiLatestTimepoint}},\code{\link{algo.bayesLatestTimepoint}} and \code{\link{algo.bayes}} for the Bayes system. } \author{M. \enc{Hhle}{Hoehle}} \examples{ # Create a test object disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 500, A = 1,alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) # Test week 200 to 208 for outbreaks with a selfdefined cdc algo.cdc(disProgObj, control = list(range = 400:500,alpha=0.025)) } \keyword{classif} \references{ Stroup, D., G. Williamson, J. Herndon, and J. Karon (1989). Detection of aberrations in the occurence of notifiable diseases surveillance data. Statistics in Medicine 8, 323-329. Farrington, C. and N. Andrews (2003). Monitoring the Health of Populations, Chapter Outbreak Detection: Application to Infectious Disease Surveillance, pp. 203-231. Oxford University Press. } surveillance/man/hhh4_validation.Rd0000644000176200001440000003476714531107643017102 0ustar liggesusers\name{hhh4_validation} \alias{oneStepAhead} \alias{quantile.oneStepAhead} \alias{confint.oneStepAhead} \alias{plot.oneStepAhead} \alias{scores.oneStepAhead} \alias{scores.hhh4} \alias{calibrationTest.oneStepAhead} \alias{calibrationTest.hhh4} \alias{pit.oneStepAhead} \alias{pit.hhh4} \title{Predictive Model Assessment for \code{hhh4} Models} \description{ The function \code{oneStepAhead} computes successive one-step-ahead predictions for a (random effects) HHH model fitted by \code{\link{hhh4}}. These can be inspected using the \code{quantile}, \code{confint} or \code{plot} methods. The associated \code{\link{scores}}-method computes a number of (strictly) proper scoring rules based on such one-step-ahead predictions; see Paul and Held (2011) for details. There are also \code{\link{calibrationTest}} and \code{\link{pit}} methods for \code{oneStepAhead} predictions. Scores, calibration tests and PIT histograms can also be computed for the fitted values of an \code{hhh4} model (i.e., in-sample/training data evaluation). } \usage{ oneStepAhead(result, tp, type = c("rolling", "first", "final"), which.start = c("current", "final"), keep.estimates = FALSE, verbose = type != "final", cores = 1) \method{quantile}{oneStepAhead}(x, probs = c(2.5, 10, 50, 90, 97.5)/100, ...) \method{confint}{oneStepAhead}(object, parm, level = 0.95, ...) \method{plot}{oneStepAhead}(x, unit = 1, probs = 1:99/100, start = NULL, means.args = NULL, ...) ## assessment of "oneStepAhead" predictions \method{scores}{oneStepAhead}(x, which = c("logs", "rps", "dss", "ses"), units = NULL, sign = FALSE, individual = FALSE, reverse = FALSE, ...) \method{calibrationTest}{oneStepAhead}(x, units = NULL, ...) \method{pit}{oneStepAhead}(x, units = NULL, ...) ## assessment of the "hhh4" model fit (in-sample predictions) \method{scores}{hhh4}(x, which = c("logs", "rps", "dss", "ses"), subset = x$control$subset, units = seq_len(x$nUnit), sign = FALSE, ...) \method{calibrationTest}{hhh4}(x, subset = x$control$subset, units = seq_len(x$nUnit), ...) \method{pit}{hhh4}(x, subset = x$control$subset, units = seq_len(x$nUnit), ...) } \arguments{ \item{result}{fitted \code{\link{hhh4}} model (class \code{"hhh4"}).} \item{tp}{ numeric vector of length 2 specifying the time range in which to compute one-step-ahead predictions (for the time points \code{tp[1]+1}, \ldots, \code{tp[2]+1}). If a single time index is specified, it is interpreted as \code{tp[1]}, and \code{tp[2]} is set to the penultimate time point of \code{result$control$subset}. } \item{type}{ The default \code{"rolling"} procedure sequentially refits the model up to each time point in \code{tp} and computes the one-step-ahead predictions for the respective next time point. The alternative \code{type}s are no true one-step-ahead predictions but much faster: \code{"first"} will refit the model for the first time point \code{tp[1]} only and use this specific fit to calculate all subsequent predictions, whereas \code{"final"} will just use \code{result} to calculate these. The latter case thus gives nothing else than a subset of \code{result$fitted.values} if the \code{tp}'s are part of the fitted subset \code{result$control$subset}. } \item{which.start}{ Which initial parameter values should be used when successively refitting the model to subsets of the data (up to time point \code{tp[1]}, up to \code{tp[1]+1}, ...) if \code{type="rolling"}? Default (\code{"current"}) is to use the parameter estimates from the previous time point, and \code{"final"} means to always use the estimates from \code{result} as initial values. Alternatively, \code{which.start} can be a list of \code{start} values as expected by \code{\link{hhh4}}, which then replace the corresponding estimates from \code{result} as initial values. This argument is ignored for \dQuote{non-rolling} \code{type}s. } \item{keep.estimates}{ logical indicating if parameter estimates and log-likelihoods from the successive fits should be returned. } \item{verbose}{ non-negative integer (usually in the range \code{0:3}) specifying the amount of tracing information to output. During \code{hhh4} model updates, the following verbosity is used: \code{0} if \code{cores > 1}, otherwise \code{verbose-1} if there is more than one time point to predict, otherwise \code{verbose}. } \item{cores}{the number of cores to use when computing the predictions for the set of time points \code{tp} in parallel (with \code{\link[parallel]{mclapply}}). Note that parallelization is not possible in the default setting \code{type="rolling"} and \code{which.start="current"} (use \code{which.start="final"} for this to work).} \item{object}{an object of class \code{"oneStepAhead"}.} \item{parm}{unused (argument of the generic).} \item{level}{required confidence level of the prediction interval.} \item{probs}{numeric vector of probabilities with values in [0,1].} \item{unit}{single integer or character selecting a unit for which to produce the plot.} \item{start}{ x-coordinate of the first prediction. If \code{start=NULL} (default), this is derived from \code{x}. } \item{means.args}{ if a list (of graphical parameters for \code{\link{lines}}), the point predictions (from \code{x$pred}) are added to the plot. } \item{x}{an object of class \code{"oneStepAhead"} or \code{"hhh4"}.} \item{which}{character vector determining which scores to compute. The package \pkg{surveillance} implements the following proper scoring rules: logarithmic score (\code{"logs"}), ranked probability score (\code{"rps"}), Dawid-Sebastiani score (\code{"dss"}), and squared error score (\code{"ses"}). The normalized SES (\code{"nses"}) is also available but it is improper and hence not computed by default.\cr It is possible to name own scoring rules in \code{which}. These must be functions of \code{(x, mu, size)}, vectorized in all arguments (time x unit matrices) except that \code{size} is \code{NULL} in case of a Poisson model. See the available scoring rules for guidance, e.g., \code{\link{dss}}. } \item{subset}{ subset of time points for which to calculate the scores (or test calibration, or produce the PIT histogram, respectively). Defaults to the subset used for fitting the model.} \item{units}{integer or character vector indexing the units for which to compute the scores (or the calibration test or the PIT histogram, respectively). By default, all units are considered.} \item{sign}{logical indicating if the function should also return \code{sign(x-mu)}, i.e., the sign of the difference between the observed counts and corresponding predictions. This does not really make sense when averaging over multiple \code{units} with \code{individual=FALSE}.} \item{individual}{logical indicating if the individual scores of the \code{units} should be returned. By default (\code{FALSE}), the individual scores are averaged over all \code{units}.} \item{reverse}{logical indicating if the rows (time points) should be reversed in the result. The long-standing but awkward default was to do so for the \code{oneStepAhead}-method. This has changed in version 1.16.0, so time points are no longer reversed by default.} \item{\dots}{Unused by the \code{quantile}, \code{confint} and \code{scores} methods.\cr The \code{plot}-method passes further arguments to the \code{\link{fanplot}} function, e.g., \code{fan.args}, \code{observed.args}, and \code{key.args} can be used to modify the plotting style.\cr For the \code{calibrationTest}-method, further arguments are passed to \code{\link{calibrationTest.default}}, e.g., \code{which} to select a scoring rule.\cr For the \code{pit}-methods, further arguments are passed to \code{\link{pit.default}}.} } \value{ \code{oneStepAhead} returns a list (of class \code{"oneStepAhead"}) with the following components: \item{pred}{one-step-ahead predictions in a matrix, where each row corresponds to one of the time points requested via the argument \code{tp}, and which has \code{ncol(result$stsObj)} unit-specific columns. The rownames indicate the predicted time points and the column names are identical to \code{colnames(result$stsObj)}.} \item{observed}{matrix with observed counts at the predicted time points. It has the same dimensions and names as \code{pred}.} \item{psi}{in case of a negative-binomial model, a matrix of the estimated overdispersion parameter(s) at each time point on the internal -log-scale (1 column if \code{"NegBin1"}, \code{ncol(observed)} columns if \code{"NegBinM"} or shared overdispersion). For a \code{"Poisson"} model, this component is \code{NULL}.} \item{allConverged}{logical indicating if all successive fits converged.} If \code{keep.estimates=TRUE}, there are the following additional elements: \item{coefficients}{matrix of estimated regression parameters from the successive fits.} \item{Sigma.orig}{matrix of estimated variance parameters from the successive fits.} \item{logliks}{matrix with columns \code{"loglikelihood"} and \code{"margll"} with their obvious meanings.} The \code{quantile}-method computes quantiles of the one-step-ahead forecasts. If there is only one unit, it returns a tp x prob matrix, otherwise a tp x unit x prob array. The \code{confint}-method is a convenient wrapper with \code{probs} set according to the required confidence level. The function \code{scores} computes the scoring rules specified in the argument \code{which}. If multiple \code{units} are selected and \code{individual=TRUE}, the result is an array of dimensions \code{c(nrow(pred),length(units),5+sign)} (up to \pkg{surveillance} 1.8-0, the first two dimensions were collapsed to give a matrix). Otherwise, the result is a matrix with \code{nrow(pred)} rows and \code{5+sign} columns. If there is only one predicted time point, the first dimension is dropped in both cases. The \code{\link{calibrationTest}}- and \code{\link{pit}}-methods are just convenient wrappers around the respective default methods. } \references{ Czado, C., Gneiting, T. and Held, L. (2009): Predictive model assessment for count data. \emph{Biometrics}, \bold{65} (4), 1254-1261. \doi{10.1111/j.1541-0420.2009.01191.x} Paul, M. and Held, L. (2011): Predictive assessment of a non-linear random effects model for multivariate time series of infectious disease counts. \emph{Statistics in Medicine}, \bold{30} (10), 1118-1136. \doi{10.1002/sim.4177} } \author{ Sebastian Meyer and Michaela Paul } \seealso{ \code{vignette("hhh4")} and \code{vignette("hhh4_spacetime")} } \examples{ ### univariate salmonella agona count time series data("salmonella.agona") ## convert from old "disProg" to new "sts" class salmonella <- disProg2sts(salmonella.agona) ## generate formula for temporal and seasonal trends f.end <- addSeason2formula(~1 + t, S=1, period=52) model <- list(ar = list(f = ~1), end = list(f = f.end), family = "NegBin1") ## fit the model result <- hhh4(salmonella, model) ## do sequential one-step-ahead predictions for the last 5 weeks pred <- oneStepAhead(result, nrow(salmonella)-5, type="rolling", which.start="final", verbose=FALSE) pred quantile(pred) confint(pred) ## simple plot of the 80% one-week-ahead prediction interval ## and point forecasts if (requireNamespace("fanplot")) plot(pred, probs = c(.1,.9), means.args = list()) \dontshow{ ## test equivalence of parallelized version if (.Platform$OS.type == "unix" && isTRUE(parallel::detectCores() > 1)) stopifnot(identical(pred, oneStepAhead(result, nrow(salmonella)-5, type="rolling", which.start="final", verbose=FALSE, cores=2))) } ## note: oneStepAhead(..., type="final") just means fitted values stopifnot(identical( unname(oneStepAhead(result, nrow(salmonella)-5, type="final")$pred), unname(tail(fitted(result), 5)))) ## compute scores of the one-step-ahead predictions (sc <- scores(pred)) ## the above uses the scores-method for "oneStepAhead" predictions, ## which is a simple wrapper around the default method: scores(x = pred$observed, mu = pred$pred, size = exp(pred$psi)) ## scores with respect to the fitted values are similar (scFitted <- scores(result, subset = nrow(salmonella)-(4:0))) \dontshow{ ## test that scFitted is equivalent to scores(oneStepAhead(..., type = "final")) stopifnot(all.equal( scFitted, scores(oneStepAhead(result, nrow(salmonella)-5, type="final")), check.attributes = FALSE)) } ## test if the one-step-ahead predictions are calibrated calibrationTest(pred) # p = 0.8746 ## the above uses the calibrationTest-method for "oneStepAhead" predictions, ## which is a simple wrapper around the default method: calibrationTest(x = pred$observed, mu = pred$pred, size = exp(pred$psi)) ## we can also test calibration of the fitted values ## using the calibrationTest-method for "hhh4" fits calibrationTest(result, subset = nrow(salmonella)-(4:0)) ## plot a (non-randomized) PIT histogram for the predictions pit(pred) ## the above uses the pit-method for "oneStepAhead" predictions, ## which is a simple wrapper around the default method: pit(x = pred$observed, pdistr = "pnbinom", mu = pred$pred, size = exp(pred$psi)) ### multivariate measles count time series ## (omitting oneStepAhead forecasts here to keep runtime low) data("measlesWeserEms") ## simple hhh4 model with random effects in the endemic component measlesModel <- list( end = list(f = addSeason2formula(~0 + ri(type="iid"))), ar = list(f = ~1), family = "NegBin1") measlesFit <- hhh4(measlesWeserEms, control = measlesModel) ## assess overall (in-sample) calibration of the model, i.e., ## if the observed counts are from the fitted NegBin distribution calibrationTest(measlesFit) # default is DSS (not suitable for low counts) calibrationTest(measlesFit, which = "logs") # p = 0.7238 ## to assess calibration in the second year for a specific district calibrationTest(measlesFit, subset = 53:104, units = "03452", which = "rps") pit(measlesFit, subset = 53:104, units = "03452") ### For a more sophisticated multivariate analysis of ### areal time series of influenza counts - data("fluBYBW") - ### see the (computer-intensive) demo("fluBYBW") script: demoscript <- system.file("demo", "fluBYBW.R", package = "surveillance") #file.show(demoscript) } \keyword{univar} \keyword{htest} \keyword{dplot} \keyword{ts} surveillance/man/ks.plot.unif.Rd0000644000176200001440000000434314244757706016366 0ustar liggesusers\encoding{latin1} \name{ks.plot.unif} \alias{ks.plot.unif} \title{ Plot the ECDF of a uniform sample with Kolmogorov-Smirnov bounds } \description{ This plot function takes a univariate sample that should be tested for a U(0,1) distribution, plots its empirical cumulative distribution function (\code{\link{ecdf}}), and adds a confidence band by inverting the corresponding Kolmogorov-Smirnov test (\code{\link{ks.test}}). The uniform distribution is rejected if the ECDF is not completely inside the confidence band. } \usage{ ks.plot.unif(U, conf.level = 0.95, exact = NULL, col.conf = "gray", col.ref = "gray", xlab = expression(u[(i)]), ylab = "Cumulative distribution") } \arguments{ \item{U}{ numeric vector containing the sample. Missing values are (silently) ignored. } \item{conf.level}{ confidence level for the K-S-test (defaults to 0.95), can also be a vector of multiple levels. } \item{exact}{see \code{\link{ks.test}}.} \item{col.conf}{ colour of the confidence lines. } \item{col.ref}{ colour of the diagonal reference line. } \item{xlab, ylab}{ axis labels. } } \value{ \code{NULL} (invisibly). } \author{ Michael H\enc{}{oe}hle and Sebastian Meyer. The code re-uses fragments from the \link{ks.test} source file \url{https://svn.R-project.org/R/trunk/src/library/stats/R/ks.test.R}, with Copyright (C) 1995-2022 The R Core Team, available under GPL-2 (or later), and C functionality from the source file \url{https://svn.R-project.org/R/trunk/src/library/stats/src/ks.c}, partially based on code published in Marsaglia et al. (2003), with Copyright (C) 1999-2022 The R Core Team, also available under GPL-2 (or later). } \references{ George Marsaglia and Wai Wan Tsang and Jingbo Wang (2003): Evaluating Kolmogorov's distribution. \emph{Journal of Statistical Software}, \bold{8} (18). \doi{10.18637/jss.v008.i18} } \seealso{ \code{\link{ks.test}} for the Kolmogorov-Smirnov test, as well as \code{\link{checkResidualProcess}}, which makes use of this plot function. } \examples{ samp <- runif(99) ks.plot.unif(samp, conf.level=c(0.95, 0.99), exact=TRUE) ks.plot.unif(samp, conf.level=c(0.95, 0.99), exact=FALSE) } \keyword{hplot} \keyword{htest} surveillance/man/primeFactors.Rd0000644000176200001440000000043613122471774016461 0ustar liggesusers\name{primeFactors} \alias{primeFactors} \title{Prime Number Factorization} \description{ Computes the prime number factorization of an integer. } \usage{ primeFactors(x) } \arguments{ \item{x}{an integer} } \value{vector with prime number factorization of \code{x}} \keyword{math} surveillance/man/twinstim_simEndemicEvents.Rd0000644000176200001440000000401414614160257021215 0ustar liggesusers\name{twinstim_simEndemicEvents} \alias{simEndemicEvents} \title{ Quick Simulation from an Endemic-Only \code{twinstim} } \description{ In \emph{endemic-only} \code{\link{twinstim}} models, the conditional intensity is a piecewise constant function independent from the history of the process. This allows for a much more efficient simulation algorithm than via Ogata's modified thinning as in the general \code{\link{simulate.twinstim}} method. } \usage{ simEndemicEvents(object, tiles) } \arguments{ \item{object}{ an object of class \code{"\link{twinstim}"} (with the \code{model} component retained; otherwise try \code{object <- \link[=update.twinstim]{update}(object, model = TRUE)}). } \item{tiles}{ an object inheriting from \code{"\linkSPclass{SpatialPolygons}"}, which represents the tiles of the original data's \code{stgrid} (see, e.g., \code{levels(environment(object)$gridTiles)}). } } \value{ a \code{"\linkSPclass{SpatialPointsDataFrame}"} } \author{ Sebastian Meyer } \seealso{ the general simulation method \code{\link{simulate.twinstim}} } \examples{ data("imdepi", "imdepifit") load(system.file("shapes", "districtsD.RData", package="surveillance")) ## Fit an endemic-only twinstim() m_noepi <- update(imdepifit, epidemic = ~0, siaf = NULL, model = TRUE, T = 120) # using a restricted time range, for speed ## Simulate events from the above endemic model set.seed(1) s1 <- simEndemicEvents(m_noepi, tiles = districtsD) class(s1) # just a "SpatialPointsDataFrame" summary(s1@data) plot(imdepi$W, lwd = 2, asp = 1) % to avoid sp -> sf plot(s1, col = s1$type, cex = 0.5, add = TRUE) \dontshow{if (surveillance.options("allExamples")) \{} ## the general simulation method takes longer s0 <- simulate(m_noepi, seed = 1, data = imdepi, tiles = districtsD) class(s0) # gives a full "simEpidataCS" with several methods applicable methods(class = "epidataCS") plot(s0, "time") plot(s0, "space", points.args = list(pch = 3), lwd = 2) \dontshow{\}} } \keyword{datagen} \keyword{models} surveillance/man/sts_animate.Rd0000644000176200001440000001132314614642005016321 0ustar liggesusers\name{sts_animate} \alias{animate.sts} \title{ Animated Maps and Time Series of Disease Counts or Incidence } \description{ The \code{animate}-method for \code{\linkS4class{sts}} objects iterates over time points, plotting maps of the current|cumulative counts|incidence via \code{\link{stsplot_space}}, optionally including a time series chart below the map to track the epidemic curve. It is worth using functionality of the \pkg{animation} package (e.g., \code{\link[animation]{saveHTML}}) to directly export the animation into a useful format. } \usage{ \method{animate}{sts}(object, tps = NULL, cumulative = FALSE, population = NULL, at = 10, ..., timeplot = list(pos = 1, size = 0.3, fill = TRUE), sleep = 0.5, verbose = interactive(), draw = TRUE) } \arguments{ \item{object}{ an object of class \code{"\linkS4class{sts}"} or a matrix of counts, i.e., \code{observed(stsObj)}, where especially \code{colnames(x)} have to be contained in \code{row.names(map)}. If a matrix, the \code{map} object has to be provided explicitly (as part of \code{\dots}). } \item{tps}{ a numeric vector of one or more time points at which to plot the map. The default \code{tps=NULL} means the whole time period \code{1:nrow(object)}. } \item{cumulative}{ logical specifying if the cumulative counts/incidence over time should be plotted. The cumulative incidence is relative to the population from the first time point \code{tps[1]} throughout the whole animation, while \code{cumulative=FALSE} computes the incidence from the current population numbers. } \item{population,at,\dots}{ arguments for \code{\link{stsplot_space}}. } \item{timeplot}{ if a list and package \CRANpkg{gridExtra} is available, a time series chart of the counts along the selected time points \code{tps} will be plotted next to the map. The list elements determine both the positioning of this plot (\code{pos}, \code{size}, and \code{fill}) and its appearance. The default \code{pos=1} and \code{size=0.3} arguments put the time series plot below the map, using 30\% of the total plot height. The logical value \code{fill} indicates whether to make the panel as big as possible (default: TRUE). An alternative to \code{fill=FALSE} is to manually specify an \code{aspect} (ratio) value in \code{timeplot}. Other list elements are arguments for the internal (and currently undocumented) function \code{stsplot_timeSimple}. For example, \code{inactive} and \code{active} are lists of graphical parameters (e.g., \code{col}) determining the appearance of the bars (e.g., default color is grey when inactive and black when active), and the boolean \code{as.Date} determines whether dates should be put on the x-axis (instead of the \code{tps} indexes). } \item{sleep}{ time to wait (\code{Sys.sleep}) between subsequent snapshots (only if \code{\link{dev.interactive}}), in seconds. } \item{verbose}{ logical indicating if a \code{\link{txtProgressBar}} should be shown during generation of the animation -- which may take a while. Default is to do so in \code{\link{interactive}} sessions. } \item{draw}{ logical indicating if the produced plots at each time point should be drawn directly (the default) or not. The setting \code{draw = FALSE} is useful if one would like to manually arrange the plots, which are always returned invisibly in a list of length \code{length(tps)}. } } \value{ (invisibly) a list of the \code{length(tps)} sequential plot objects. These are of class \code{"gtable"} (from \CRANpkg{gtable}) if the \code{timeplot} is included, otherwise of class \code{"\code{\link[lattice:trellis.object]{trellis}"}. } \author{ Sebastian Meyer } \seealso{ the other plot types documented in \code{\link{stsplot}} for static time series plots and maps. } \examples{ data("measlesWeserEms") ## animate the weekly counts of measles (during weeks 12-16 only, for speed) if (interactive() && require("animation")) { oldwd <- setwd(tempdir()) # to not clutter up the current working dir saveHTML(animate(measlesWeserEms, tps=12:16), title="Evolution of the measles epidemic in the Weser-Ems region", ani.width=500, ani.height=600) setwd(oldwd) } \dontrun{ ## animate the weekly incidence of measles (per 100'000 inhabitants), ## and label the time series plot with dates in a specified format animate(measlesWeserEms, tps=12:16, population = measlesWeserEms@map$POPULATION / 100000, timeplot = list(as.Date = TRUE, scales = list(x = list(format = "\%G/\%V")))) } } \keyword{hplot} \keyword{dynamic} \keyword{spatial} surveillance/man/macros/0000755000176200001440000000000014614160257015013 5ustar liggesuserssurveillance/man/macros/linkSPclass.Rd0000644000176200001440000000014114614160257017524 0ustar liggesusers%\linkS4class lacks an optional package anchor \newcommand{\linkSPclass}{\link[sp:#1-class]{#1}} surveillance/man/zetaweights.Rd0000644000176200001440000000300012316635114016341 0ustar liggesusers\name{zetaweights} \alias{zetaweights} \title{ Power-Law Weights According to Neighbourhood Order } \description{ Compute power-law weights with decay parameter \code{d} based on a matrix of neighbourhood orders \code{nbmat} (e.g., as obtained via \code{\link{nbOrder}}). Without normalization and truncation, this is just \eqn{o^{-d}} (where \eqn{o} is a neighbourhood order). This function is mainly used internally for \code{\link{W_powerlaw}} weights in \code{\link{hhh4}} models. } \usage{ zetaweights(nbmat, d = 1, maxlag = max(nbmat), normalize = FALSE) } \arguments{ \item{nbmat}{numeric, symmetric matrix of neighbourhood orders.} \item{d}{single numeric decay parameter (default: 1). Should be positive.} \item{maxlag}{single numeric specifying an upper limit for the power law. For neighbourhood orders > \code{maxlag}, the resulting weight is 0. Defaults to no truncation.} \item{normalize}{Should the resulting weight matrix be normalized such that rows sum to 1?} } \value{ a numeric matrix with same dimensions and names as the input matrix. } \author{ Sebastian Meyer } \seealso{\code{\link{W_powerlaw}}} \examples{ nbmat <- matrix(c(0,1,2,2, 1,0,1,1, 2,1,0,2, 2,1,2,0), 4, 4, byrow=TRUE) zetaweights(nbmat, d=1, normalize=FALSE) # harmonic: o^-1 zetaweights(nbmat, d=1, normalize=TRUE) # rowSums=1 zetaweights(nbmat, maxlag=1, normalize=FALSE) # results in adjacency matrix } \keyword{spatial} \keyword{utilities} surveillance/man/glm_epidataCS.Rd0000644000176200001440000000570513165513254016520 0ustar liggesusers\name{glm_epidataCS} \alias{glm_epidataCS} \title{ Fit an Endemic-Only \code{twinstim} as a Poisson-\code{glm} } \description{ An endemic-only \code{\link{twinstim}} is equivalent to a Poisson regression model for the aggregated number of events, \eqn{Y_{[t][\bm{s}],k}}, by time-space-type cell. The rate of the corresponding Poisson distribution is \eqn{e_{[t][\bm{s}]} \cdot \lambda([t],[\bm{s}],k)}, where \eqn{e_{[t][\bm{s}]} = |[t]| |[\bm{s}]|} is a multiplicative offset. Thus, the \code{\link{glm}} function can be used to fit an endemic-only \code{twinstim}. However, wrapping in \code{glm} is usually slower. } \usage{ glm_epidataCS(formula, data, ...) } \arguments{ \item{formula}{ an endemic model formula without response, comprising variables of \code{data$stgrid} and possibly the variable \code{type} for a type-specific model. } \item{data}{ an object of class \code{"\link{epidataCS}"}. } \item{\dots}{ arguments passed to \code{\link{glm}}. Note that \code{family} and \code{offset} are fixed internally. } } \value{ a \code{\link{glm}} } \author{ Sebastian Meyer } \examples{ data("imdepi", "imdepifit") ## Fit an endemic-only twinstim() and an equivalent model wrapped in glm() fit_twinstim <- update(imdepifit, epidemic = ~0, siaf = NULL, subset = NULL, optim.args=list(control=list(trace=0)), verbose=FALSE) fit_glm <- glm_epidataCS(formula(fit_twinstim)$endemic, data = imdepi) ## Compare the coefficients cbind(twinstim = coef(fit_twinstim), glm = coef(fit_glm)) \dontshow{ stopifnot(all.equal(coef(fit_glm), coef(fit_twinstim), tolerance = 1e-6, check.attributes = FALSE)) if (surveillance.options("allExamples")) { ## also check type-specific model: stopifnot(all.equal( coef(glm_epidataCS(~0+type, imdepi)), coef(update(fit_twinstim, endemic=~(1|type))), tolerance = 1e-6, check.attributes = FALSE)) } } ### also compare to an equivalent endemic-only hhh4() fit ## first need to aggregate imdepi into an "sts" object load(system.file("shapes", "districtsD.RData", package="surveillance")) imdsts <- epidataCS2sts(imdepi, freq = 12, start = c(2002, 1), neighbourhood = NULL, tiles = districtsD, popcol.stgrid = "popdensity") ## determine the correct offset to get an equivalent model offset <- 2 * rep(with(subset(imdepi$stgrid, !duplicated(BLOCK)), stop - start), ncol(imdsts)) * sum(districtsD$POPULATION) * population(imdsts) ## fit the model using hhh4() fit_hhh4 <- hhh4(imdsts, control = list( end = list( f = addSeason2formula(~I(start/365-3.5), period=365, timevar="start"), offset = offset ), family = "Poisson", subset = 1:nrow(imdsts), data = list(start=with(subset(imdepi$stgrid, !duplicated(BLOCK)), start)))) summary(fit_hhh4) stopifnot(all.equal(coef(fit_hhh4), coef(fit_glm), check.attributes=FALSE)) } \keyword{models} surveillance/man/findK.Rd0000644000176200001440000000213113122471774015050 0ustar liggesusers\name{findK} \alias{findK} \title{Find Reference Value} \description{ Calculates the reference value \code{k} for a Poisson or binomial CUSUM designed to detect a shift from \eqn{\theta_0} to \eqn{\theta_1} } \usage{ findK(theta0, theta1, distr = c("poisson", "binomial"), roundK = FALSE, digits = 1, ...) } \arguments{ \item{theta0}{ in-control parameter } \item{theta1}{ out-of-control parameter } \item{distr}{ \code{"poisson"} or \code{"binomial"} } \item{digits}{ the reference value \code{k} is rounded to \code{digits} decimal places} \item{roundK}{ For discrete data and rational reference value there is only a limited set of possible values that the CUSUM can take (and therefore there is also only a limited set of ARLs). If \code{roundK=TRUE}, integer multiples of 0.5 are avoided when rounding the reference value \code{k}, % i.e. the CUSUM can take more values.} \item{\dots}{ further arguments for the distribution function, i.e. number of trials \code{n} for the binomial CDF.} } \value{ Returns reference value \code{k}. } \keyword{models} surveillance/man/sts_observation.Rd0000644000176200001440000000146314431116166017243 0ustar liggesusers\name{sts_observation} \alias{sts_observation} \title{Create an \code{sts} object with a given observation date} \usage{ sts_observation(sts, dateObservation, cut = TRUE) } \arguments{ \item{sts}{sts-object we want to set at a previous state. Needs to include a reporting triangle.} \item{dateObservation}{Date for which we want the state. Needs to be in the reporting triangle dates.} \item{cut}{Boolean indicating whether to have 0 counts after the observation date or to simply cut the sts-object} } \description{ Function for creating an \code{\linkS4class{sts}} object with a given observation date. } \examples{ data("salmAllOnset") salmAllOnsety2014m01d20 <- sts_observation(salmAllOnset, dateObservation="2014-01-20",cut=FALSE) plot(salmAllOnset) lines(observed(salmAllOnsety2014m01d20),type="h",col="red") } surveillance/man/algo.farrington.Rd0000644000176200001440000001364614334522617017123 0ustar liggesusers\name{algo.farrington} \alias{algo.farrington} \alias{farrington} \encoding{latin1} \title{Surveillance for Count Time Series Using the Classic Farrington Method} \description{ Implements the procedure of Farrington et al. (1996). At each time point of the specified \code{range}, a GLM is fitted to predict the counts. This is then compared to the observed counts. If the observation is above a specific quantile of the prediction interval, then an alarm is raised. } \usage{ # original interface for a single "disProg" time series algo.farrington(disProgObj, control=list( range=NULL, b=5, w=3, reweight=TRUE, verbose=FALSE, plot=FALSE, alpha=0.05, trend=TRUE, limit54=c(5,4), powertrans="2/3", fitFun="algo.farrington.fitGLM.fast")) # wrapper for "sts" data, possibly multivariate farrington(sts, control=list( range=NULL, b=5, w=3, reweight=TRUE, verbose=FALSE, alpha=0.05), ...) } \arguments{ \item{disProgObj}{ an object of class \code{"disProg"} (a list including \code{observed} and \code{state} time series). } \item{control}{list of control parameters \describe{ \item{\code{range}}{Specifies the index of all timepoints which should be tested. If range is \code{NULL} the maximum number of possible weeks is used (i.e. as many weeks as possible while still having enough reference values).} \item{\code{b}}{how many years back in time to include when forming the base counts.} \item{\code{w}}{windows size, i.e. number of weeks to include before and after the current week} \item{\code{reweight}}{Boolean specifying whether to perform reweight step} \item{\code{trend}}{If \code{TRUE} a trend is included and kept in case the conditions documented in Farrington et al. (1996) are met (see the results). If \code{FALSE} then NO trend is fit.} \item{\code{verbose}}{Boolean indicating whether to show extra debugging information.} \item{\code{plot}}{Boolean specifying whether to show the final GLM model fit graphically (use History|Recording to see all pictures).} \item{\code{powertrans}}{Power transformation to apply to the data. Use either "2/3" for skewness correction (Default), "1/2" for variance stabilizing transformation or "none" for no transformation.} \item{\code{alpha}}{An approximate (two-sided) \eqn{(1-\alpha)} prediction interval is calculated.} \item{\code{limit54}}{To avoid alarms in cases where the time series only has about 0-2 cases the algorithm uses the following heuristic criterion (see Section 3.8 of the Farrington paper) to protect against low counts: no alarm is sounded if fewer than \eqn{cases=5} reports were received in the past \eqn{period=4} weeks. \code{limit54=c(cases,period)} is a vector allowing the user to change these numbers. Note: As of version 0.9-7 the term "last" period of weeks includes the current week - otherwise no alarm is sounded for horrible large numbers if the four weeks before that are too low.} \item{\code{fitFun}}{String containing the name of the fit function to be used for fitting the GLM. The options are \code{algo.farrington.fitGLM.fast} (default) and \code{algo.farrington.fitGLM} or \code{algo.farrington.fitGLM.populationOffset}. See details of \code{\link{algo.farrington.fitGLM}} for more information.} } } \item{sts}{an object of class \code{"\link{sts}"}.} \item{\dots}{arguments for \code{\link{wrap.algo}}, e.g., \code{verbose=FALSE}.} } \details{ The following steps are performed according to the Farrington et al. (1996) paper. \enumerate{ \item fit of the initial model and initial estimation of mean and overdispersion. \item calculation of the weights omega (correction for past outbreaks) \item refitting of the model \item revised estimation of overdispersion \item rescaled model \item omission of the trend, if it is not significant \item repetition of the whole procedure \item calculation of the threshold value \item computation of exceedance score } } \value{ For \code{algo.farrington}, a list object of class \code{"survRes"} with elements \code{alarm}, \code{upperbound}, \code{trend}, \code{disProgObj}, and \code{control}. For \code{farrington}, the input \code{"\link{sts}"} object with updated \code{alarm}, \code{upperbound} and \code{control} slots, and subsetted to \code{control$range}. } \examples{ #load "disProg" data data("salmonella.agona") #Do surveillance for the last 42 weeks n <- length(salmonella.agona$observed) control <- list(b=4,w=3,range=(n-42):n,reweight=TRUE, verbose=FALSE,alpha=0.01) res <- algo.farrington(salmonella.agona,control=control) plot(res) #Generate Poisson counts and create an "sts" object set.seed(123) x <- rpois(520,lambda=1) stsObj <- sts(observed=x, frequency=52) \dontshow{if (surveillance.options("allExamples")) \{} #Compare timing of the two possible fitters for algo.farrington range <- 312:520 system.time( sts1 <- farrington(stsObj, control=list(range=range, fitFun="algo.farrington.fitGLM.fast"), verbose=FALSE)) system.time( sts2 <- farrington(stsObj, control=list(range=range, fitFun="algo.farrington.fitGLM"), verbose=FALSE)) #Check if results are the same stopifnot(upperbound(sts1) == upperbound(sts2)) \dontshow{\}} } \author{M. \enc{Hhle}{Hoehle}} \seealso{ \code{\link{algo.farrington.fitGLM}}, \code{\link{algo.farrington.threshold}} An improved Farrington algorithm is available as function \code{\link{farringtonFlexible}}. } \keyword{classif} \references{ A statistical algorithm for the early detection of outbreaks of infectious disease, Farrington, C.P., Andrews, N.J, Beale A.D. and Catchpole, M.A. (1996), J. R. Statist. Soc. A, 159, 547-563. } surveillance/man/algo.rogerson.Rd0000644000176200001440000001051514310560071016566 0ustar liggesusers\name{algo.rogerson} \alias{algo.rogerson} \title{Modified CUSUM method as proposed by Rogerson and Yamada (2004)} \description{ Modified Poisson CUSUM method that allows for a time-varying in-control parameter \eqn{\theta_{0,t}} as proposed by Rogerson and Yamada (2004). The same approach can be applied to binomial data if \code{distribution="binomial"} is specified. } \usage{ algo.rogerson(disProgObj, control = list(range = range, theta0t = NULL, ARL0 = NULL, s = NULL, hValues = NULL, distribution = c("poisson","binomial"), nt = NULL, FIR=FALSE, limit = NULL, digits = 1)) } \arguments{ \item{disProgObj}{object of class \code{disProg} that includes a matrix with the observed number of counts} \item{control}{ list with elements \describe{ \item{range}{vector of indices in the observed matrix of \code{disProgObj} to monitor} \item{theta0t}{matrix with in-control parameter, must be specified} \item{ARL0 }{ desired average run length \eqn{\gamma} } \item{s}{change to detect, see \code{\link{findH}} for further details} \item{hValues}{matrix with decision intervals \code{h} for a sequence of values \eqn{\theta_{0,t}} (in the range of \code{theta0t}) } \item{distribution}{\code{"poisson"} or \code{"binomial"} } \item{nt}{optional matrix with varying sample sizes for the binomial CUSUM} \item{FIR}{a FIR CUSUM with head start \eqn{h/2} is applied to the data if \code{TRUE}, otherwise no head start is used; see details } \item{limit}{numeric that determines the procedure after an alarm is given, see details} \item{digits}{the reference value and decision interval are rounded to \code{digits} decimal places. Defaults to 1 and should correspond to the number of digits used to compute \code{hValues} } } } } \details{ The CUSUM for a sequence of Poisson or binomial variates \eqn{x_t} is computed as \deqn{S_t = \max \{0, S_{t-1} + c_t (x_t- k_t)\} , \, t=1,2,\ldots ,} where \eqn{S_0=0} and \eqn{c_t=h/h_t}; \eqn{k_t} and \eqn{h_t} are time-varying reference values and decision intervals. An alarm is given at time \eqn{t} if \eqn{S_t \geq h}{S_t >= h}. If \code{FIR=TRUE}, the CUSUM starts with a head start value \eqn{S_0=h/2} at time \eqn{t=0}. After an alarm is given, the FIR CUSUM starts again at this head start value. The procedure after the CUSUM gives an alarm can be determined by \code{limit}. Suppose that the CUSUM signals at time \eqn{t}, i.e. \eqn{S_t \geq h}{S_t >= h}. For numeric values of \code{limit}, the CUSUM is bounded above after an alarm is given, % at time \eqn{t-1}, i.e. \eqn{S_t} is set to \eqn{ \min\{\code{limit} \cdot h, S_t\} }{min(limit*h, S_t)}. %\deqn{S_{t} = \max \{0, S_{t-1} + c_t(x_t - k_t)\}. } Using \code{limit}=0 corresponds to resetting \eqn{S_t} to zero after an alarm as proposed in the original formulation of the CUSUM. If \code{FIR=TRUE}, \eqn{S_t} is reset to \eqn{ h/2 } (i.e. \code{limit}=\eqn{h/2} ). If \code{limit=NULL}, no resetting occurs after an alarm is given. } \note{\code{algo.rogerson} is a univariate CUSUM method. If the data are available in several regions (i.e. \code{observed} is a matrix), multiple univariate CUSUMs are applied to each region. } \value{Returns an object of class \code{survRes} with elements \item{alarm}{indicates whether the CUSUM signaled at time \eqn{t} or not (1 = alarm, 0 = no alarm) } \item{upperbound}{CUSUM values \eqn{S_t} } \item{disProgObj}{\code{disProg} object } \item{control}{list with the alarm threshold \eqn{h} and the specified control object} } \examples{ # simulate data (seasonal Poisson) set.seed(123) t <- 1:300 lambda <- exp(-0.5 + 0.4 * sin(2*pi*t/52) + 0.6 * cos(2*pi*t/52)) data <- sts(observed = rpois(length(lambda), lambda)) # determine a matrix with h values hVals <- hValues(theta0 = 10:150/100, ARL0=500, s = 1, distr = "poisson") # convert to legacy "disProg" class and apply modified Poisson CUSUM disProgObj <- sts2disProg(data) res <- algo.rogerson(disProgObj, control=c(hVals, list(theta0t=lambda, range=1:300))) plot(res, xaxis.years = FALSE) } \references{ Rogerson, P. A. and Yamada, I. Approaches to Syndromic Surveillance When Data Consist of Small Regional Counts. Morbidity and Mortality Weekly Report, 2004, 53/Supplement, 79-85 } \seealso{\code{\link{hValues}}} \keyword{classif} surveillance/man/epidataCS_animate.Rd0000644000176200001440000001363214614160257017356 0ustar liggesusers\encoding{latin1} \name{epidataCS_animate} \alias{animate.epidataCS} \title{ Spatio-Temporal Animation of a Continuous-Time Continuous-Space Epidemic } \description{ Function for the animation of continuous-time continuous-space epidemic data, i.e. objects inheriting from class \code{"epidataCS"}. There are three types of animation, see argument \code{time.spacing}. Besides the on-screen plotting in the interactive \R session, it is possible and recommended to redirect the animation to an off-screen graphics device using the contributed \R package \pkg{animation}. For instance, the animation can be watched and navigated in a web browser via \code{\link[animation]{saveHTML}} (see Examples). } \usage{ \method{animate}{epidataCS}(object, interval = c(0,Inf), time.spacing = NULL, nmax = NULL, sleep = NULL, legend.opts = list(), timer.opts = list(), pch = 15:18, col.current = "red", col.I = "#C16E41", col.R = "#B3B3B3", col.influence = NULL, main = NULL, verbose = interactive(), ...) } \arguments{ \item{object}{ an object inheriting from class \code{"epidataCS"}. } \item{interval}{time range of the animation.} \item{time.spacing}{ time interval for the animation steps.\cr If \code{NULL} (the default), the events are plotted sequentially by producing a snapshot at every time point where an event occurred. Thus, it is just the \emph{ordering} of the events, which is shown.\cr To plot the appearance of events proportionally to the exact time line, \code{time.spacing} can be set to a numeric value indicating the period of time between consecutive snapshots. Then, for each time point in \code{seq(0, end, by = time.spacing)} the current state of the epidemic can be seen and an additional timer indicates the current time (see \code{timer.opts} below).\cr If \code{time.spacing = NA}, then the time spacing is automatically determined in such a way that \code{nmax} snapshots result. In this case, \code{nmax} must be given a finite value. } \item{nmax}{ maximum number of snapshots to generate. The default \code{NULL} means to take the value from \code{ani.options("nmax")} if the \pkg{animation} package is available, and no limitation (\code{Inf}) otherwise. } \item{sleep}{ numeric scalar specifying the artificial pause in seconds between two time points (using \code{\link{Sys.sleep}}), or \code{NULL} (default), when this is taken from \code{ani.options("interval")} if the \pkg{animation} package is available, and set to 0.1 otherwise. Note that \code{sleep} is ignored on non-interactive devices (see \code{\link{dev.interactive}}), e.g., if generating an animation inside \pkg{animation}'s \code{\link[animation]{saveHTML}}. } \item{pch, col}{ vectors of length equal to the number of event types specifying the point symbols and colors for events to plot (in this order). The vectors are recycled if necessary. } \item{legend.opts}{ either a list of arguments passed to the \code{\link{legend}} function or \code{NULL} (or \code{NA}), in which case no legend will be plotted. All necessary arguments have sensible defaults and need not be specified. } \item{timer.opts}{ either a list of arguments passed to the \code{\link{legend}} function or \code{NULL} (or \code{NA}), in which case no timer will be plotted. All necessary arguments have sensible defaults and need not be specified, i.e. \describe{ \item{\code{x}:}{\code{"bottomright"}} \item{\code{title}:}{\code{"time"}} \item{\code{box.lty}:}{\code{0}} \item{\code{adj}:}{\code{c(0.5,0.5)}} \item{\code{inset}:}{\code{0.01}} \item{\code{bg}:}{\code{"white"}} } Note that the argument \code{legend}, which is the current time of the animation, can not be modified. } \item{col.current}{color of events when occurring (new).} \item{col.I}{color once infectious.} \item{col.R}{color event has once \dQuote{recovered}. If \code{NA}, then recovered events will not be shown.} \item{col.influence}{color with which the influence region is drawn. Use \code{NULL} (default) if no influence regions should be drawn.} \item{main}{optional main title placed above the map.} \item{verbose}{logical specifying if a (textual) progress bar should be shown during snapshot generation. This is especially useful if the animation is produced within \code{\link[animation]{saveHTML}} or similar.} \item{\dots}{ further graphical parameters passed to the \code{plot} method for \code{"\linkSPclass{SpatialPolygons}"}. } } %\value{ % invisibly returns \code{NULL}. %} \author{ Sebastian Meyer with documentation contributions by Michael H\enc{}{oe}hle } \seealso{ \code{\link{plot.epidataCS}} for plotting the numbers of events by time (aggregated over space) or the locations of the events in the observation region \code{W} (aggregated over time). The contributed \R package \pkg{animation}. } \examples{ data("imdepi") imdepiB <- subset(imdepi, type == "B") \dontrun{ # Animate the first year of type B with a step size of 7 days animate(imdepiB, interval=c(0,365), time.spacing=7, nmax=Inf, sleep=0.1) # Sequential animation of type B events during the first year animate(imdepiB, interval=c(0,365), time.spacing=NULL, sleep=0.1) # Animate the whole time range but with nmax=20 snapshots only animate(imdepiB, time.spacing=NA, nmax=20, sleep=0.1) } # Such an animation can be saved in various ways using the tools of # the animation package, e.g., saveHTML() if (interactive() && require("animation")) { oldwd <- setwd(tempdir()) # to not clutter up the current working dir saveHTML(animate(imdepiB, interval = c(0,365), time.spacing = 7), nmax = Inf, interval = 0.2, loop = FALSE, title = "Animation of the first year of type B events") setwd(oldwd) } } \keyword{hplot} \keyword{dynamic} \keyword{spatial} surveillance/man/algo.farrington.assign.weights.Rd0000644000176200001440000000123613122471774022050 0ustar liggesusers\name{algo.farrington.assign.weights} \alias{algo.farrington.assign.weights} \title{Assign weights to base counts} \description{ Weights are assigned according to the Anscombe residuals } \usage{ algo.farrington.assign.weights(s, weightsThreshold=1) } \arguments{ \item{s}{Vector of standardized Anscombe residuals} \item{weightsThreshold}{A scalar indicating when observations are seen as outlier. In the original Farrington proposal the value was 1 (default value), in the improved version this value is suggested to be 2.58.} } \value{Weights according to the residuals} \seealso{\code{\link{anscombe.residuals}}} \keyword{regression} surveillance/man/addSeason2formula.Rd0000644000176200001440000000461514442263115017371 0ustar liggesusers\name{addSeason2formula} \alias{addSeason2formula} \title{ Add Harmonics to an Existing Formula } \description{ This function helps to construct a \code{\link{formula}} object that can be used in a call to \code{\link{hhh4}} to model seasonal variation via a sum of sine and cosine terms. } \usage{ addSeason2formula(f = ~1, S = 1, period = 52, timevar = "t") } \arguments{ \item{f}{ formula that the seasonal terms should be added to, defaults to an intercept \code{~1}. } \item{S}{ number of sine and cosine terms. If \code{S} is a vector, unit-specific seasonal terms are created. } \item{period}{ period of the season, defaults to 52 for weekly data. } \item{timevar}{ the time variable in the model. Defaults to \code{"t"}. } } \details{ The function adds the seasonal terms \deqn{ \sin( s \cdot 2\pi \cdot \code{timevar}/\code{period} ),\; \cos( s \cdot 2\pi \cdot \code{timevar}/\code{period} ), }{ sin( s * 2 * pi * \code{timevar}/\code{period} ), cos( s * 2 * pi * \code{timevar}/\code{period} ), } for \eqn{s = 1,\dots,\code{S}} to an existing formula \code{f}. Note the following equivalence when interpreting the coefficients of the seasonal terms: \deqn{ \gamma \sin(\omega t) + \delta \cos(\omega t) = A \sin(\omega t + \epsilon) }{ gamma sin(omega * t) + delta cos(omega * t) = A sin(omega * t + epsilon) } with amplitude \eqn{A = \sqrt{\gamma^2 + \delta^2}}{A = sqrt(gamma^2 + delta^2)} and phase shift \eqn{\epsilon = \arctan(\delta / \gamma)}. The amplitude and phase shift can be obtained from a fitted \code{\link{hhh4}} model via \code{coef(..., amplitudeShift = TRUE)}, see \code{\link{coef.hhh4}}. } \value{ Returns a \code{\link{formula}} with the seasonal terms added and its environment set to \code{\link{.GlobalEnv}}. Note that to use the resulting formula in \code{\link{hhh4}}, a time variable named as specified by the argument \code{timevar} must be available. } \author{ M. Paul, with contributions by S. Meyer } \seealso{ \code{\link{hhh4}}, \code{\link{fe}}, \code{\link{ri}} } \examples{ # add 2 sine/cosine terms to a model with intercept and linear trend addSeason2formula(f = ~ 1 + t, S = 2) # the same for monthly data addSeason2formula(f = ~ 1 + t, S = 2, period = 12) # different number of seasons for a bivariate time series addSeason2formula(f = ~ 1, S = c(3, 1), period = 52) } surveillance/man/hhh4_simulate_scores.Rd0000644000176200001440000000672614430727511020143 0ustar liggesusers\name{hhh4_simulate_scores} \alias{scores.hhh4sims} \alias{scores.hhh4simslist} \title{ Proper Scoring Rules for Simulations from \code{hhh4} Models } \description{ Calculate proper scoring rules based on simulated predictive distributions. } \usage{ \method{scores}{hhh4sims}(x, which = "rps", units = NULL, ..., drop = TRUE) \method{scores}{hhh4simslist}(x, ...) } \arguments{ \item{x}{ an object of class \code{"hhh4sims"} (as resulting from the \code{\link[=simulate.hhh4]{simulate}}-method for \code{"\link{hhh4}"} models if \code{simplify = TRUE} was set), or an \code{"hhh4simslist"}, i.e., a list of such simulations potentially obtained from different model fits (using the same simulation period). } \item{which}{ a character vector indicating which proper scoring rules to compute. By default, only the ranked probability score (\code{"rps"}) is calculated. Other options include \code{"logs"} and \code{"dss"}. } \item{units}{ if non-\code{NULL}, an integer or character vector indexing the columns of \code{x} for which to compute the scores. } \item{drop}{ a logical indicating if univariate dimensions should be dropped (the default). } \item{\dots}{ unused (argument of the generic). } } \details{ This implementation can only compute \emph{univariate scores}, i.e., independently for each time point. The logarithmic score is badly estimated if the domain is large and there are not enough samples to cover the underlying distribution in enough detail (the score becomes infinite when an observed value does not occur in the samples). An alternative is to use kernel density estimation as implemented in the \R package \CRANpkg{scoringRules}. } \author{ Sebastian Meyer } \examples{ data("salmAllOnset") ## fit a hhh4 model to the first 13 years salmModel <- list(end = list(f = addSeason2formula(~1 + t)), ar = list(f = ~1), family = "NegBin1", subset = 2:678) salmFit <- hhh4(salmAllOnset, salmModel) ## simulate the next 20 weeks ahead (with very small 'nsim' for speed) salmSims <- simulate(salmFit, nsim = 500, seed = 3, subset = 678 + seq_len(20), y.start = observed(salmAllOnset)[678,]) if (requireNamespace("fanplot")) plot(salmSims, "fan") ### calculate scores at each time point ## using empirical distribution of simulated counts as forecast distribution scores(salmSims, which = c("rps", "logs", "dss")) ## observed count sometimes not covered by simulations -> infinite log-score ## => for a more detailed forecast, either considerably increase 'nsim', or: ## 1. use continuous density() of simulated counts as forecast distribution fi <- apply(salmSims, 1, function (x) approxfun(density(x))) logs_kde <- mapply(function (f, y) -log(f(y)), f = fi, y = observed(attr(salmSims,"stsObserved"))) cbind("empirical" = scores(salmSims, "logs"), "density" = logs_kde) ## a similar KDE approach is implemented in scoringRules::logs_sample() ## 2. average conditional predictive NegBin's of simulated trajectories, ## currently only implemented in HIDDA.forecasting::dhhh4sims() ### produce a PIT histogram ## using empirical distribution of simulated counts as forecast distribition pit(x = observed(attr(salmSims, "stsObserved")), pdistr = apply(salmSims, 1:2, ecdf)) ## long-term forecast is badly calibrated (lower tail is unused, see fan above) ## we also get a warning for the same reason as infinite log-scores } \keyword{univar} surveillance/man/algo.compare.Rd0000644000176200001440000000331314176013316016361 0ustar liggesusers\name{algo.compare} \alias{algo.compare} \title{Comparison of Specified Surveillance Systems using Quality Values} \description{ Comparison of specified surveillance algorithms using quality values. } \usage{ algo.compare(survResList) } \arguments{ \item{survResList}{a list of survRes objects to compare via quality values.} } \value{ Matrix with values from \code{\link{algo.quality}}, i.e. quality values for every surveillance algorithm found in \code{survResults}. } \seealso{\code{\link{algo.quality}}} \examples{ # Create a test object disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) # Let this object be tested from any methods in range = 200:400 range <- 200:400 survRes <- algo.call(disProgObj, control = list( list(funcName = "rki1", range = range), list(funcName = "rki2", range = range), list(funcName = "rki3", range = range), list(funcName = "rki", range = range, b = 3, w = 2, actY = FALSE), list(funcName = "rki", range = range, b = 2, w = 9, actY = TRUE), list(funcName = "bayes1", range = range), list(funcName = "bayes2", range = range), list(funcName = "bayes3", range = range), list(funcName = "bayes", range = range, b = 1, w = 5, actY = TRUE,alpha=0.05) )) algo.compare(survRes) } \keyword{classif} surveillance/man/sts_creation.Rd0000644000176200001440000000501613430612031016500 0ustar liggesusers\name{sts_creation} \alias{sts_creation} \title{Simulate Count Time Series with Outbreaks} \usage{ sts_creation(theta, beta, gamma1, gamma2, m, overdispersion, dates, sizesOutbreak, datesOutbreak, delayMax, alpha, densityDelay) } \arguments{ \item{theta}{baseline frequency of reports} \item{beta}{time trend} \item{gamma1}{seasonality} \item{gamma2}{seasonality} \item{m}{seasonality} \item{overdispersion}{\code{size} parameter of \code{\link{rnbinom}} for the parameterization with mean and dispersion} \item{dates}{dates of the time series} \item{sizesOutbreak}{sizes of all the outbreaks (vector)} \item{datesOutbreak}{dates of all the outbreaks (vector)} \item{delayMax}{maximal delay in time units} \item{alpha}{alpha for getting the (1-alpha) quantile of the negative binomial distribution at each timepoint} \item{densityDelay}{density distribution for the delay} } \description{ Function for simulating a time series and creating an \code{\linkS4class{sts}} object. As the counts are generated using a negative binomial distribution one also gets the (1-alpha) quantile for each timepoint (can be interpreted as an in-control upperbound for in-control values). The baseline and outbreaks are created as in Noufaily et al. (2012). } \examples{ set.seed(12345) # Time series parameters scenario4 <- c(1.6,0,0.4,0.5,2) theta <- 1.6 beta <- 0 gamma1 <-0.4 gamma2 <- 0.5 overdispersion <- 1 m <- 1 # Dates firstDate <- "2006-01-01" lengthT=350 dates <- as.Date(firstDate) + 7 * 0:(lengthT - 1) # Maximal delay in weeks D=10 # Dates and sizes of the outbreaks datesOutbreak <- as.Date(c("2008-03-30","2011-09-25")) sizesOutbreak <- c(2,5) # Delay distribution data("salmAllOnset") in2011 <- which(isoWeekYear(epoch(salmAllOnset))$ISOYear == 2011) rT2011 <- salmAllOnset@control$reportingTriangle$n[in2011,] densityDelay <- apply(rT2011,2,sum, na.rm=TRUE)/sum(rT2011, na.rm=TRUE) # alpha for the upperbound alpha <- 0.05 # Create the sts with the full time series stsSim <- sts_creation(theta=theta,beta=beta,gamma1=gamma1,gamma2=gamma2,m=m, overdispersion=overdispersion, dates=dates, sizesOutbreak=sizesOutbreak,datesOutbreak=datesOutbreak, delayMax=D,densityDelay=densityDelay, alpha=alpha) plot(stsSim) } \references{ Noufaily, A., Enki, D.G., Farrington, C.P., Garthwaite, P., Andrews, N.J., Charlett, A. (2012): An improved algorithm for outbreak detection in multiple surveillance systems. Statistics in Medicine, 32 (7), 1206-1222. } surveillance/man/twinSIR_intensityplot.Rd0000644000176200001440000001435714334522617020375 0ustar liggesusers\encoding{latin1} \name{twinSIR_intensityplot} \alias{plot.twinSIR} \alias{intensityplot.twinSIR} \alias{intensityplot.simEpidata} \title{ Plotting Paths of Infection Intensities for \code{twinSIR} Models } \description{ \code{\link{intensityplot}} methods to plot the evolution of the total infection intensity, its epidemic proportion or its endemic proportion over time. The default \code{plot} method for objects of class \code{"twinSIR"} is just a wrapper for the \code{intensityplot} method. The implementation is illustrated in Meyer et al. (2017, Section 4), see \code{vignette("twinSIR")}. } \usage{ \method{plot}{twinSIR}(x, which = c("epidemic proportion", "endemic proportion", "total intensity"), ...) \method{intensityplot}{twinSIR}(x, which = c("epidemic proportion", "endemic proportion", "total intensity"), aggregate = TRUE, theta = NULL, plot = TRUE, add = FALSE, rug.opts = list(), ...) \method{intensityplot}{simEpidata}(x, which = c("epidemic proportion", "endemic proportion", "total intensity"), aggregate = TRUE, theta = NULL, plot = TRUE, add = FALSE, rug.opts = list(), ...) } \arguments{ \item{x}{ an object of class \code{"\link{twinSIR}"} (fitted model) or \code{"\link{simEpidata}"} (simulated \code{twinSIR} epidemic), respectively. } \item{which}{ \code{"epidemic proportion"}, \code{"endemic proportion"}, or \code{"total intensity"}. Partial matching is applied. Determines whether to plot the path of the total intensity \eqn{\lambda(t)} or its epidemic or endemic proportions \eqn{\frac{e(t)}{\lambda(t)}}{e(t)/lambda(t)} or \eqn{\frac{h(t)}{\lambda(t)}}{h(t)/lambda(t)}. } \item{aggregate}{ logical. Determines whether lines for all individual infection intensities should be drawn (\code{FALSE}) or their sum only (\code{TRUE}, the default). } \item{theta}{ numeric vector of model coefficients. If \code{x} is of class \code{"twinSIR"}, then \code{theta = c(alpha, beta)}, where \code{beta} consists of the coefficients of the piecewise constant log-baseline function and the coefficients of the endemic (\code{cox}) predictor. If \code{x} is of class \code{"simEpidata"}, then \code{theta = c(alpha, 1, betarest)}, where 1 refers to the (true) log-baseline used in the simulation and \code{betarest} is the vector of the remaining coefficients of the endemic (\code{cox}) predictor. The default (\code{NULL}) means that the fitted or true parameters, respectively, will be used. } \item{plot}{ logical indicating if a plot is desired, defaults to \code{TRUE}. Otherwise, only the data of the plot will be returned. Especially with \code{aggregate = FALSE} and many individuals one might e.g. consider to plot a subset of the individual intensity paths only or do some further calculations/analysis of the infection intensities. } \item{add}{ logical. If \code{TRUE}, paths are added to the current plot, using \code{lines}. } \item{rug.opts}{ either a list of arguments passed to the function \code{\link{rug}}, or \code{NULL} (or \code{NA}), in which case no \code{rug} will be plotted. By default, the argument \code{ticksize} is set to 0.02 and \code{quiet} is set to \code{TRUE}. Note that the argument \code{x} of the \code{rug()} function, which contains the locations for the \code{rug} is fixed internally and can not be modified. The locations of the rug are the time points of infections. } \item{\dots}{ For the \code{plot.twinSIR} method, arguments passed to \code{intensityplot.twinSIR}. For the \code{intensityplot} methods, further graphical parameters passed to the function \code{\link{matplot}}, e.g. \code{lty}, \code{lwd}, \code{col}, \code{xlab}, \code{ylab} and \code{main}. Note that the \code{matplot} arguments \code{x}, \code{y}, \code{type} and \code{add} are implicit and can not be specified here. } } \value{ numeric matrix with the first column \code{"stop"} and as many rows as there are \code{"stop"} time points in the event history \code{x}. The other columns depend on the argument \code{aggregate}: if \code{TRUE}, there is only one other column named \code{which}, which contains the values of \code{which} at the respective \code{"stop"} time points. Otherwise, if \code{aggregate = FALSE}, there is one column for each individual, each of them containing the individual \code{which} at the respective \code{"stop"} time points. } \references{ Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \author{ Sebastian Meyer } \seealso{ \code{\link{twinSIR}} for a description of the intensity model, and \code{\link{simulate.twinSIR}} for the simulation of epidemic data according to a \code{twinSIR} specification. } \examples{ data("hagelloch") plot(hagelloch) # a simplistic twinSIR model fit <- twinSIR(~ household, data = hagelloch) # overall total intensity plot(fit, which = "total") # overall epidemic proportion epi <- plot(fit, which = "epidemic", ylim = c(0, 1)) head(epi) # add overall endemic proportion = 1 - epidemic proportion ende <- plot(fit, which = "endemic", add = TRUE, col = 2) legend("topleft", legend = "endemic proportion", lty = 1, col = 2, bty = "n") \dontshow{if (surveillance.options("allExamples")) \{} # individual intensities tmp <- plot(fit, which = "total", aggregate = FALSE, col = rgb(0, 0, 0, alpha = 0.1), main = expression("Individual infection intensities " * lambda[i](t) == Y[i](t) \%.\% (e[i](t) + h[i](t)))) # return value: matrix of individual intensity paths str(tmp) # plot intensity path only for individuals 3 and 99 matplot(x = tmp[,1], y = tmp[,1+c(3,99)], type = "S", ylab = "Force of infection", xlab = "time", main = expression("Paths of the infection intensities " * lambda[3](t) * " and " * lambda[99](t))) legend("topright", legend = paste("Individual", c(3,99)), col = 1:2, lty = 1:2) \dontshow{\}} } \keyword{hplot} \keyword{aplot} \keyword{dplot} \keyword{methods} surveillance/man/hhh4_W.Rd0000644000176200001440000001502114131034603015123 0ustar liggesusers\name{hhh4_W} \alias{W_powerlaw} \alias{W_np} \title{ Power-Law and Nonparametric Neighbourhood Weights for \code{hhh4}-Models } \description{ Set up power-law or nonparametric weights for the neighbourhood component of \code{\link{hhh4}}-models as proposed by Meyer and Held (2014). Without normalization, power-law weights are \eqn{w_{ji} = o_{ji}^{-d}}{w_ji = o_ji^-d} (if \eqn{o_{ji} > 0}{o_ji > 0}, otherwise \eqn{w_{ji} = 0}{w_ji = 0}), where \eqn{o_{ji}}{o_ji} (\eqn{=o_{ij}}{=o_ij}) is the adjacency order between regions \eqn{i} and \eqn{j}, and the decay parameter \eqn{d} is to be estimated. In the nonparametric formulation, unconstrained log-weights will be estimated for each of the adjacency orders \code{2:maxlag} (the first-order weight is fixed to 1 for identifiability). Both weight functions can be modified to include a 0-distance weight, which enables \code{hhh4} models without a separate autoregressive component. } \usage{ W_powerlaw(maxlag, normalize = TRUE, log = FALSE, initial = if (log) 0 else 1, from0 = FALSE) W_np(maxlag, truncate = TRUE, normalize = TRUE, initial = log(zetaweights(2:(maxlag+from0))), from0 = FALSE, to0 = truncate) } \arguments{ \item{maxlag}{a single integer specifying a limiting order of adjacency. If spatial dependence is not to be truncated at some high order, \code{maxlag} should be set to the maximum adjacency order in the network of regions. The smallest possible value for \code{maxlag} is 2 if \code{from0=FALSE} and 1 otherwise.} \item{truncate,to0}{\code{W_np} represents order-specific log-weights up to order \code{maxlag}. Higher orders are by default (\code{truncate=TRUE}) assumed to have zero weight (similar to \code{W_powerlaw}). Alternatively, \code{truncate=FALSE} requests that the weight at order \code{maxlag} should be carried forward to higher orders. \code{truncate} has previously been called \code{to0} (deprecated).} \item{normalize}{logical indicating if the weights should be normalized such that the rows of the weight matrix sum to 1 (default). Note that normalization does not work with islands, i.e., regions without neighbours.} \item{log}{logical indicating if the decay parameter \eqn{d} should be estimated on the log-scale to ensure positivity.} \item{initial}{initial value of the parameter vector.} \item{from0}{logical indicating if these parametric weights should include the 0-distance (autoregressive) case. In the default setting (\code{from0 = FALSE}), adjacency order 0 has zero weight, which is suitable for \code{hhh4} models with a separate autoregressive component. With \code{from0 = TRUE} (Meyer and Held, 2017), the power law is based on \eqn{(o_{ji} + 1)}{(o_ji + 1)}, and nonparametric weights are estimated for adjacency orders \code{1:maxlag}, respectively, where the 0-distance weight is \eqn{w_{jj} = 1}{w_jj = 1} (without normalization). Note that the corresponding \code{hhh4} model should then exclude a separate autoregressive component (\code{control$ar$f = ~ -1}).} } \value{ a list which can be passed as a specification of parametric neighbourhood weights in the \code{control$ne$weights} argument of \code{\link{hhh4}}. } \details{ \code{hhh4} will take adjacency orders from the \code{neighbourhood} slot of the \code{"sts"} object, so these must be prepared before fitting a model with parametric neighbourhood weights. The function \code{\link{nbOrder}} can be used to derive adjacency orders from a binary adjacency matrix. } \references{ Meyer, S. and Held, L. (2014): Power-law models for infectious disease spread. \emph{The Annals of Applied Statistics}, \bold{8} (3), 1612-1639. \doi{10.1214/14-AOAS743} Meyer, S. and Held, L. (2017): Incorporating social contact data in spatio-temporal models for infectious disease spread. \emph{Biostatistics}, \bold{18} (2), 338-351. \doi{10.1093/biostatistics/kxw051} } \author{ Sebastian Meyer } \seealso{ \code{\link{nbOrder}} to determine adjacency orders from a binary adjacency matrix. \code{\link{getNEweights}} and \code{\link{coefW}} to extract the estimated neighbourhood weight matrix and coefficients from an \code{hhh4} model. } \examples{ data("measlesWeserEms") ## data contains adjaceny orders as required for parametric weights plot(measlesWeserEms, type = observed ~ unit, labels = TRUE) neighbourhood(measlesWeserEms)[1:6,1:6] max(neighbourhood(measlesWeserEms)) # max order is 5 ## fit a power-law decay of spatial interaction ## in a hhh4 model with seasonality and random intercepts in the endemic part measlesModel <- list( ar = list(f = ~ 1), ne = list(f = ~ 1, weights = W_powerlaw(maxlag=5)), end = list(f = addSeason2formula(~-1 + ri(), S=1, period=52)), family = "NegBin1") ## fit the model set.seed(1) # random intercepts are initialized randomly measlesFit <- hhh4(measlesWeserEms, measlesModel) summary(measlesFit) # "neweights.d" is the decay parameter d coefW(measlesFit) ## plot the spatio-temporal weights o_ji^-d / sum_k o_jk^-d ## as a function of adjacency order plot(measlesFit, type = "neweights", xlab = "adjacency order") ## normalization => same distance does not necessarily mean same weight. ## to extract the whole weight matrix W: getNEweights(measlesFit) ## visualize contributions of the three model components ## to the overall number of infections (aggregated over all districts) plot(measlesFit, total = TRUE) ## little contribution from neighbouring districts \dontshow{if (surveillance.options("allExamples")) \{} ## simpler model with autoregressive effects captured by the ne component measlesModel2 <- list( ne = list(f = ~ 1, weights = W_powerlaw(maxlag=5, from0=TRUE)), end = list(f = addSeason2formula(~-1 + ri(), S=1, period=52)), family = "NegBin1") measlesFit2 <- hhh4(measlesWeserEms, measlesModel2) ## omitting the separate AR component simplifies model extensions/selection ## and interpretation of covariate effects (only two predictors left) plot(measlesFit2, type = "neweights", exclude = NULL, xlab = "adjacency order") ## strong decay, again mostly within-district transmission ## (one could also try a purely autoregressive model) plot(measlesFit2, total = TRUE, legend.args = list(legend = c("epidemic", "endemic"))) ## almost the same RMSE as with separate AR and NE effects c(rmse1 = sqrt(mean(residuals(measlesFit, "response")^2)), rmse2 = sqrt(mean(residuals(measlesFit2, "response")^2))) \dontshow{\}} } \keyword{spatial} \keyword{models} \keyword{utilities} surveillance/man/create.disProg.Rd0000644000176200001440000000331314200477705016667 0ustar liggesusers\name{create.disProg} \alias{create.disProg} \title{Creating an object of class \code{disProg} (DEPRECATED)} \description{ Creating objects of the legacy class \code{disProg} is deprecated; use \code{\link{sts}} instead. An object of class \code{disProg} takes a vector with the weeknumber (week) and matrices with the observed number of counts (observed) and the respective state chains (state), where each column represents an individual time series. The matrices neighbourhood and populationFrac provide information about neighbouring units and population proportions. } \usage{ create.disProg(week, observed, state, start=c(2001,1), freq=52, neighbourhood=NULL, populationFrac=NULL, epochAsDate=FALSE) } \arguments{ \item{week}{index in the matrix of observations, typically weeks} \item{observed}{matrix with parallel time series of counts where rows are time points and columns are the individual time series for unit/area \eqn{i, i=1,\ldots,m}} \item{state}{matrix with corresponding states} \item{start}{vector of length two denoting the year and the sample number (week, month, etc.) of the first observation} \item{freq}{sampling frequency per year, i.e. 52 for weekly data, 12 for monthly data, 13 if 52 weeks are aggregated into 4 week blocks.} \item{neighbourhood}{neighbourhood matrix \eqn{N} of dimension \eqn{m \times m} with elements \eqn{n_{ij}=1} if units \eqn{i} and \eqn{j} are adjacent and 0 otherwise } \item{populationFrac}{matrix with corresponding population proportions} \item{epochAsDate}{interpret the integers in \code{week} as Dates. Default is \code{FALSE}} } \value{object of class \code{disProg}} \author{M. Paul} \keyword{classes} \keyword{internal} surveillance/man/algo.farrington.fitGLM.Rd0000644000176200001440000000560313122471774020237 0ustar liggesusers\name{algo.farrington.fitGLM} \alias{algo.farrington.fitGLM} \alias{algo.farrington.fitGLM.fast} \alias{algo.farrington.fitGLM.populationOffset} \title{Fit Poisson GLM of the Farrington procedure for a single time point} \description{ The function fits a Poisson regression model (GLM) with mean predictor \deqn{\log \mu_t = \alpha + \beta t}{ log mu_t = alpha + beta * t} as specified by the Farrington procedure. If requested, Anscombe residuals are computed based on an initial fit and a 2nd fit is made using weights, where base counts suspected to be caused by earlier outbreaks are downweighted. } \usage{ algo.farrington.fitGLM(response, wtime, timeTrend = TRUE, reweight = TRUE, ...) algo.farrington.fitGLM.fast(response, wtime, timeTrend = TRUE, reweight = TRUE, ...) algo.farrington.fitGLM.populationOffset(response, wtime, population, timeTrend=TRUE,reweight=TRUE, ...) } \arguments{ \item{response}{The vector of observed base counts} \item{wtime}{Vector of week numbers corresponding to \code{response}} \item{timeTrend}{Boolean whether to fit the \eqn{\beta t}{beta*t} or not} \item{reweight}{Fit twice -- 2nd time with Anscombe residuals} \item{population}{Population size. Possibly used as offset, i.e. in \code{algo.farrington.fitGLM.populationOffset} the value \code{log(population)} is used as offset in the linear predictor of the GLM: \deqn{\log \mu_t = \log(\texttt{population}) + \alpha + \beta t}{ log mu_t = log(population) alpha + beta * t} This provides a way to adjust the Farrington procedure to the case of greatly varying populations. Note: This is an experimental implementation with methodology not covered by the original paper. } \item{\dots}{Used to catch additional arguments, currently not used.} } \details{ Compute weights from an initial fit and rescale using Anscombe based residuals as described in the \code{\link{anscombe.residuals}} function. Note that \code{algo.farrington.fitGLM} uses the \code{glm} routine for fitting. A faster alternative is provided by \code{algo.farrington.fitGLM.fast} which uses the \code{glm.fit} function directly (thanks to Mikko Virtanen). This saves computational overhead and increases speed for 500 monitored time points by a factor of approximately two. However, some of the routine \code{glm} functions might not work on the output of this function. Which function is used for \code{algo.farrington} can be controlled by the \code{control$fitFun} argument. } \value{ an object of class GLM with additional fields \code{wtime}, \code{response} and \code{phi}. If the \code{glm} returns without convergence \code{NULL} is returned. } \seealso{\code{\link{anscombe.residuals}},\code{\link{algo.farrington}}} \keyword{regression} surveillance/man/algo.call.Rd0000644000176200001440000000462514176013316015655 0ustar liggesusers\name{algo.call} \alias{algo.call} \title{Query Transmission to Specified Surveillance Algorithm} \description{ Transmission of a object of class disProg to the specified surveillance algorithm. } \usage{ algo.call(disProgObj, control = list( list(funcName = "rki1", range = range), list(funcName = "rki", range = range, b = 2, w = 4, actY = TRUE), list(funcName = "rki", range = range, b = 2, w = 5, actY = TRUE))) } \arguments{ \item{disProgObj}{object of class disProg, which includes the state chain and the observed} \item{control}{specifies which surveillance algorithm should be used with their parameters. The parameter \code{funcName} and \code{range} must be specified. Here, \code{funcName} is the appropriate method function (without '\code{algo.}') and \code{range} defines the timepoints to be evaluated by the actual system.} } \value{ a list of survRes objects generated by the specified surveillance algorithm } \seealso{\code{\link{algo.rki}}, \code{\link{algo.bayes}}, \code{\link{algo.farrington}}} \examples{ # Create a test object disProg <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) # Let this object be tested from any methods in range = 200:400 range <- 200:400 survRes <- algo.call(disProg, control = list( list(funcName = "rki1", range = range), list(funcName = "rki2", range = range), list(funcName = "rki3", range = range), list(funcName = "rki", range = range, b = 3, w = 2, actY = FALSE), list(funcName = "rki", range = range, b = 2, w = 9, actY = TRUE), list(funcName = "bayes1", range = range), list(funcName = "bayes2", range = range), list(funcName = "bayes3", range = range), list(funcName = "bayes", range = range, b = 1, w = 5, actY = TRUE,alpha=0.05) )) # show selected survRes objects names(survRes) plot(survRes[["rki(6,6,0)"]]) survRes[["bayes(5,5,1)"]] } \keyword{classif} surveillance/man/stK.Rd0000644000176200001440000001141314610747661014565 0ustar liggesusers\encoding{latin1} \name{stK} \alias{stKtest} \alias{plot.stKtest} \title{ Diggle et al (1995) K-function test for space-time clustering } \description{ The function \code{stKtest} wraps functions in package \pkg{splancs} to perform the K-function based Monte Carlo permutation test for space-time clustering (Diggle et al, 1995) for \code{"epidataCS"}. The implementation is due to Meyer et al. (2016). } \usage{ stKtest(object, eps.s = NULL, eps.t = NULL, B = 199, cores = 1, seed = NULL, poly = object$W) \method{plot}{stKtest}(x, which = c("D", "R", "MC"), args.D = list(), args.D0 = args.D, args.R = list(), args.MC = list(), mfrow = sort(n2mfrow(length(which))), ...) } \arguments{ \item{object}{an object of class \code{"epidataCS"}.} \item{eps.s, eps.t}{ numeric vectors defining the spatial and temporal grids of critical distances over which to evaluate the test. The default (\code{NULL}) uses equidistant values from 0 to the smallest \code{eps.s}/\code{eps.t} value in \code{object$events}, but not larger than half the observed spatial/temporal domain. } \item{B}{the number of permutations.} \item{cores}{ the number of parallel processes over which to distribute the requested number of permutations. } \item{seed}{ argument for \code{\link{set.seed}} to initialize the random number generator such that results become reproducible (also if \code{cores > 1}, see \code{\link{plapply}}). } \item{poly}{ the polygonal observation region of the events (as an object handled by \code{\link[polyCub]{xylist}}). The default \code{object$W} might not work since package \pkg{splancs} does not support multi-polygons. In this case, the \code{poly} argument can be used to specify a substitute. } \item{x}{an \code{"stKtest"}.} \item{which}{ a character vector indicating which diagnostic plots to produce. The full set is \code{c("D", "D0", "R", "MC")}. The special value \code{which = "stdiagn"} means to call the associated \pkg{splancs} function \code{\link[splancs]{stdiagn}}. } \item{args.D,args.D0,args.R,args.MC}{ argument lists for the plot functions \code{\link{persp}} (for \code{"D"} and \code{"D0"}), \code{\link{plot.default}} (\code{"R"}), and \code{\link[MASS]{truehist}} (\code{"MC"}), respectively, to modify the default settings. Ignored if \code{which = "stdiagn"}. } \item{mfrow}{ \code{\link{par}}-setting to layout the plots. Ignored for \code{which = "stdiagn"} and if set to \code{NULL}. } \item{\dots}{ignored (argument of the generic).} } \value{ an object of class \code{"stKtest"} (inheriting from \code{"htest"}), which is a list with the following components: \item{method}{a character string indicating the type of test performed.} \item{data.name}{a character string naming the supplied \code{object}.} \item{statistic}{the sum \eqn{U} of the standardized residuals \eqn{R(s,t)}.} \item{parameter}{the number \code{B} of permutations.} \item{p.value}{the p-value for the test.} \item{pts}{the coordinate matrix of the event locations (for \code{\link[splancs]{stdiagn}}.} \item{stK}{the estimated K-function as returned by \code{\link[splancs]{stkhat}}.} \item{seD}{the standard error of the estimated \eqn{D(s,t)} as returned by \code{\link[splancs]{stsecal}}.} \item{mctest}{the observed and permutation values of the test statistic as returned by \code{\link[splancs]{stmctest}}.} The \code{plot}-method invisibly returns \code{NULL}. } \references{ Diggle, P. J.; Chetwynd, A. G.; H\enc{}{ae}ggkvist, R. and Morris, S. E. (1995): Second-order analysis of space-time clustering \emph{Statistical Methods in Medical Research}, \bold{4}, 124-136. Meyer, S., Warnke, I., R\enc{}{oe}ssler, W. and Held, L. (2016): Model-based testing for space-time interaction using point processes: An application to psychiatric hospital admissions in an urban area. \emph{Spatial and Spatio-temporal Epidemiology}, \bold{17}, 15-25. \doi{10.1016/j.sste.2016.03.002}. Eprint: \url{https://arxiv.org/abs/1512.09052}. } \author{ Sebastian Meyer } \seealso{ the simple \code{\link{knox}} test and function \code{\link{epitest}} for testing \code{"\link{twinstim}"} models. } \examples{ if (requireNamespace("splancs")) { data("imdepi") imdepiB <- subset(imdepi, type == "B") mainpoly <- coordinates(imdepiB$W@polygons[[1]]@Polygons[[5]]) SGRID <- c(10, 25, 50, 100, 150) TGRID <- c(1, 7, 14, 21) B <- 19 # limited here for speed \dontshow{if (!interactive()) B <- 4} % for faster checks imdBstKtest <- stKtest(imdepiB, eps.s = SGRID, eps.t = TGRID, B = B, cores = 2, seed = 1, poly = list(mainpoly)) print(imdBstKtest) plot(imdBstKtest) } } \keyword{htest} surveillance/man/twinstim_intensity.Rd0000644000176200001440000002274414614160257020013 0ustar liggesusers\name{twinstim_intensity} \alias{intensityplot.twinstim} \alias{intensity.twinstim} \alias{intensityplot.simEpidataCS} \title{ Plotting Intensities of Infection over Time or Space } \description{ \code{\link{intensityplot}} method to plot the evolution of the total infection intensity, its epidemic proportion or its endemic proportion over time or space (integrated over the other dimension) of fitted \code{\link{twinstim}} models (or \code{\link{simEpidataCS}}). The \code{"simEpidataCS"}-method is just a wrapper around \code{intensityplot.twinstim} by making the \code{"simEpidataCS"} object \code{"twinstim"}-compatible, i.e. enriching it by the required model components and environment. The \code{intensity.twinstim} auxiliary function returns functions which calculate the endemic or epidemic intensity at a specific time point or location (integrated over the other dimension). } \usage{ \method{intensityplot}{twinstim}(x, which = c("epidemic proportion", "endemic proportion", "total intensity"), aggregate = c("time", "space"), types = 1:nrow(x$qmatrix), tiles, tiles.idcol = NULL, plot = TRUE, add = FALSE, tgrid = 101, rug.opts = list(), sgrid = 128, polygons.args = list(), points.args = list(), cex.fun = sqrt, ...) \method{intensityplot}{simEpidataCS}(x, ...) intensity.twinstim(x, aggregate = c("time", "space"), types = 1:nrow(x$qmatrix), tiles, tiles.idcol = NULL) } \arguments{ \item{x}{ an object of class \code{"twinstim"} or \code{"simEpidataCS"}, respectively. } \item{which}{ \code{"epidemic proportion"}, \code{"endemic proportion"}, or \code{"total intensity"}. Partial matching is applied. Determines whether to plot the path of the total intensity or its epidemic or endemic proportions over time or space (\code{which}) aggregated over the other dimension and \code{types}. } \item{aggregate}{ One of \code{"time"} or \code{"space"}. The former results in a plot of the evolution of \code{which} as a function of time (integrated over the observation region \eqn{\bold{W}}), whereas the latter produces a \code{spplot} of \code{which} over \eqn{\bold{W}} (spanned by \code{tiles}). In both cases, \code{which} is evaluated on a grid of values, given by \code{tgrid} or \code{sgrid}, respectively. } \item{types}{ event types to aggregate. By default, all types of events are aggregated, but one could also be interested in only one specific type or a subset of event types. } \item{tiles}{ object of class \code{"\linkSPclass{SpatialPolygons}"} representing the decomposition of \eqn{\bold{W}} into different regions (as used in the corresponding \code{stgrid} of the \code{"\link{epidataCS}"}. This is only needed for \code{aggregate = "space"}. } \item{tiles.idcol}{ either a column index for \code{tiles@data} (if \code{tiles} is a \code{"\linkSPclass{SpatialPolygonsDataFrame}"}), or \code{NULL} (default), which refers to the \code{"ID"} slot of the polygons, i.e., \code{row.names(tiles)}. The ID's must correspond to the factor levels of \code{stgrid$tile} of the \code{"\link{epidataCS}"} on which \code{x} was fitted. } \item{plot}{ logical indicating if a plot is desired, which defaults to \code{TRUE}. Otherwise, a function will be returned, which takes a vector of time points (if \code{aggregate = "time"}) or a matrix of coordinates (if \code{aggregate = "space"}), and returns \code{which} on this grid. } \item{add}{ logical. If \code{TRUE} and \code{aggregate = "time"}, paths are added to the current plot, using \code{lines}. This does not work for \code{aggregate = "space"}. } \item{tgrid}{ either a numeric vector of time points when to evaluate \code{which}, or a scalar representing the desired number of evaluation points in the observation interval \eqn{[t_0, T]}. This argument is unused for \code{aggregate = "space"}. } \item{rug.opts}{ if a list, its elements are passed as arguments to the function \code{\link{rug}}, which will mark the time points of the events if \code{aggregate = "time"} (it is unused in the spatial case); otherwise (e.g., \code{NULL}), no \code{rug} will be produced. By default, the \code{rug} argument \code{ticksize} is set to 0.02 and \code{quiet} is set to \code{TRUE}. Note that the argument \code{x} of the \code{rug} function, which contains the locations for the \code{rug} is fixed internally and can not be modified. } \item{sgrid}{ either an object of class \code{"\linkSPclass{SpatialPixels}"} (or coercible to that class) representing the locations where to evaluate \code{which}, or a scalar representing the approximate number of points of a grid constructed on the bounding box of \code{tiles}. \code{sgrid} is internally subsetted to contain only points inside \code{tiles}. This argument is unused for \code{aggregate = "time"}. } \item{polygons.args}{ if a list, its elements are passed as arguments to \code{\link[sp]{sp.polygons}}, which will add \code{tiles} to the plot if \code{aggregate = "space"} (it is unused for the temporal plot). By default, the fill \code{col}our of the tiles is set to \code{"darkgrey"}. } \item{points.args}{ if a list, its elements are passed as arguments to \code{\link[sp]{sp.points}}, which will add the event locations to the plot if \code{aggregate = "space"} (it is unused for the temporal plot). By default, the plot symbol is set to \code{pch=1}. The sizes of the points are determined as the product of the argument \code{cex} (default: 0.5) of this list and the sizes obtained from the function \code{cex.fun} which accounts for multiple events at the same location. } \item{cex.fun}{ function which takes a vector of counts of events at each unique location and returns a (vector of) \code{cex} value(s) for the sizes of the points at the event locations used in \code{points.args}. Defaults to the \code{sqrt()} function, which for the default circular \code{pch=1} means that the area of each point is proportional to the number of events at its location. } \item{\dots}{ further arguments passed to \code{plot} or \code{lines} (if \code{aggregate = "time"}), or to \code{\link[sp]{spplot}} (if \code{aggregate = "space"}).\cr For \code{intensityplot.simEpidataCS}, arguments passed to \code{intensityplot.twinstim}. } } \value{ If \code{plot = FALSE} or \code{aggregate = "time"}, a function is returned, which takes a vector of time points (if \code{aggregate = "time"}) or a matrix of coordinates (if \code{aggregate = "space"}), and returns \code{which} on this grid. \code{intensity.twinstim} returns a list containing such functions for the endemic and epidemic intensity (but these are not vectorized). If \code{plot = TRUE} and \code{aggregate = "space"}, the \code{\link[lattice]{trellis.object}} of the spatial plot is returned. } \author{ Sebastian Meyer } \seealso{ \code{\link{plot.twinstim}}, which calls \code{intensityplot.twinstim}. } \examples{ data("imdepi", "imdepifit") # for the intensityplot we need the model environment, which can be # easily added by the intelligent update method (no need to refit the model) imdepifit <- update(imdepifit, model=TRUE) ## path of the total intensity opar <- par(mfrow=c(2,1)) intensityplot(imdepifit, which="total intensity", aggregate="time", tgrid=500) plot(imdepi, "time", breaks=100) par(opar) ## time course of the epidemic proportion by event intensityplot(imdepifit, which="epidemic proportion", aggregate="time", tgrid=500, types=1) intensityplot(imdepifit, which="epidemic proportion", aggregate="time", tgrid=500, types=2, add=TRUE, col=2) legend("topright", legend=levels(imdepi$events$type), lty=1, col=1:2, title = "event type") ## endemic and total intensity in one plot intensity_endprop <- intensityplot(imdepifit, which="endemic proportion", aggregate="time", plot=FALSE) intensity_total <- intensityplot(imdepifit, which="total intensity", aggregate="time", tgrid=501, lwd=2) curve(intensity_endprop(x) * intensity_total(x), add=TRUE, col=2, lwd=2, n=501) text(2500, 0.36, labels="total", col=1, pos=2, font=2) text(2500, 0.08, labels="endemic", col=2, pos=2, font=2) ## spatial shape of the intensity (aggregated over time) \dontshow{if (surveillance.options("allExamples")) \{} ## load borders of Germany's districts load(system.file("shapes", "districtsD.RData", package="surveillance")) # total intensity (using a rather sparse 'sgrid' for speed) intensityplot(imdepifit, which="total intensity", aggregate="space", tiles=districtsD, sgrid=500, col.regions=rev(heat.colors(100))) % needs sf in longlat.scales # epidemic proportion by type maps_epiprop <- lapply(1:2, function (type) { intensityplot(imdepifit, which="epidemic", aggregate="space", types=type, tiles=districtsD, sgrid=1000, main=rownames(imdepifit$qmatrix)[type], scales=list(draw=FALSE), at=seq(0,1,by=0.1), col.regions=rev(hcl.colors(10,"YlOrRd")), colorkey=list(title=list("Epidemic proportion", cex=1))) }) plot(maps_epiprop[[1]], split=c(1,1,2,1), more=TRUE) plot(maps_epiprop[[2]], split=c(2,1,2,1)) \dontshow{\}} } \keyword{hplot} \keyword{aplot} \keyword{dplot} \keyword{methods} surveillance/man/scores.Rd0000644000176200001440000000726714431621542015324 0ustar liggesusers\name{scores} \alias{scores} \alias{scores.default} \alias{logs} \alias{rps} \alias{dss} \alias{ses} \title{ Proper Scoring Rules for Poisson or Negative Binomial Predictions } \description{ Proper scoring rules for Poisson or negative binomial predictions of count data are described in Czado et al. (2009). The following scores are implemented: logarithmic score (\code{logs}), ranked probability score (\code{rps}), Dawid-Sebastiani score (\code{dss}), squared error score (\code{ses}). } \usage{ scores(x, ...) \method{scores}{default}(x, mu, size = NULL, which = c("logs", "rps", "dss", "ses"), sign = FALSE, ...) logs(x, mu, size = NULL) rps(x, mu, size = NULL, k = 40, tolerance = sqrt(.Machine$double.eps)) dss(x, mu, size = NULL) ses(x, mu, size = NULL) } \arguments{ \item{x}{ the observed counts. All functions are vectorized and also accept matrices or arrays. Dimensions are preserved. } \item{mu}{ the means of the predictive distributions for the observations \code{x}. } \item{size}{ either \code{NULL} (default), indicating Poisson predictions with mean \code{mu}, or dispersion parameters of negative binomial forecasts for the observations \code{x}, parametrized as in \code{\link{dnbinom}} with variance \code{mu*(1+mu/size)}. } \item{which}{ a character vector specifying which scoring rules to apply. By default, all four proper scores are calculated. The normalized squared error score (\code{"nses"}) is also available but it is improper and hence not computed by default. } \item{sign}{ a logical indicating if the function should also return \code{sign(x-mu)}, i.e., the sign of the difference between the observed counts and corresponding predictions. } \item{\dots}{ unused (argument of the generic). } \item{k}{ scalar argument controlling the finite sum approximation for the \code{rps} with truncation at \code{max(x, ceiling(mu + k*sd))}. } \item{tolerance}{ absolute tolerance for the finite sum approximation employed in the \code{rps} calculation. A warning is produced if the approximation with \code{k} summands is insufficient for the specified \code{tolerance}. In this case, increase \code{k} for higher precision (or use a larger tolerance). } } \value{ The scoring functions return the individual scores for the predictions of the observations in \code{x} (maintaining their dimension attributes). The default \code{scores}-method applies the selected (\code{which}) scoring functions (and calculates \code{sign(x-mu)}) and returns the results in an array (via \code{\link{simplify2array}}), where the last dimension corresponds to the different scores. } \references{ Czado, C., Gneiting, T. and Held, L. (2009): Predictive model assessment for count data. \emph{Biometrics}, \bold{65} (4), 1254-1261. \doi{10.1111/j.1541-0420.2009.01191.x} } \seealso{ The R package \CRANpkg{scoringRules} implements the logarithmic score and the (continuous) ranked probability score for many distributions. } \author{ Sebastian Meyer and Michaela Paul } \examples{ mu <- c(0.1, 1, 3, 6, 3*pi, 100) size <- 0.5 set.seed(1) y <- rnbinom(length(mu), mu = mu, size = size) scores(y, mu = mu, size = size) scores(y, mu = mu, size = 1) # ses ignores the variance scores(y, mu = 1, size = size) ## apply a specific scoring rule scores(y, mu = mu, size = size, which = "rps") rps(y, mu = mu, size = size) \dontshow{# failed in surveillance <= 1.19.1 stopifnot(!is.unsorted(rps(3, mu = 10^-(0:8)), strictly = TRUE)) } ## rps() gives NA (with a warning) if the NegBin is too wide rps(1e5, mu = 1e5, size = 1e-5) } \keyword{univar} surveillance/man/surveillance-package.Rd0000644000176200001440000001356114517725527020122 0ustar liggesusers%\RdOpts{stage=build} % Not yet: in R 2.12.0 - 4.0.5, \RdOpts{} had no effect (PR#18073) \encoding{latin1} \name{surveillance-package} \alias{surveillance-package} \alias{surveillance} \docType{package} \title{\pkg{surveillance}: \packageTitle{surveillance}} \description{ The \R package \pkg{surveillance} implements statistical methods for the retrospective modeling and prospective monitoring of epidemic phenomena in temporal and spatio-temporal contexts. Focus is on (routinely collected) public health surveillance data, but the methods just as well apply to data from environmetrics, econometrics or the social sciences. As many of the monitoring methods rely on statistical process control methodology, the package is also relevant to quality control and reliability engineering. } \details{ The package implements many typical outbreak detection procedures such as Stroup et al. (1989), Farrington et al. (1996), Rossi et al. (1999), Rogerson and Yamada (2001), a Bayesian approach (H\enc{}{oe}hle, 2007), negative binomial CUSUM methods (H\enc{}{oe}hle and Mazick, 2009), and a detector based on generalized likelihood ratios (H\enc{}{oe}hle and Paul, 2008), see \code{\link{wrap.algo}}. Also CUSUMs for the prospective change-point detection in binomial, beta-binomial and multinomial time series are covered based on generalized linear modeling, see \code{\link{categoricalCUSUM}}. This includes, e.g., paired comparison Bradley-Terry modeling described in H\enc{}{oe}hle (2010), or paired binary CUSUM (\code{\link{pairedbinCUSUM}}) described by Steiner et al. (1999). The package contains several real-world datasets, the ability to simulate outbreak data, visualize the results of the monitoring in temporal, spatial or spatio-temporal fashion. In dealing with time series data, the fundamental data structure of the package is the S4 class \code{\link{sts}} wrapping observations, monitoring results and date handling for multivariate time series. A recent overview of the available monitoring procedures is given by Salmon et al. (2016). For the retrospective analysis of epidemic spread, the package provides three endemic-epidemic modeling frameworks with tools for visualization, likelihood inference, and simulation. The function \code{\link{hhh4}} offers inference methods for the (multivariate) count time series models of Held et al. (2005), Paul et al. (2008), Paul and Held (2011), Held and Paul (2012), and Meyer and Held (2014). See \code{vignette("hhh4")} for a general introduction and \code{vignette("hhh4_spacetime")} for a discussion and illustration of spatial \code{hhh4} models. Furthermore, the fully Bayesian approach for univariate time series of counts from Held et al. (2006) is implemented as function \code{\link{algo.twins}}. Self-exciting point processes are modeled through endemic-epidemic conditional intensity functions. \code{\link{twinSIR}} (H\enc{}{oe}hle, 2009) models the susceptible-infectious-recovered (SIR) event history of a fixed population, e.g, epidemics across farms or networks; see \code{vignette("twinSIR")} for an illustration. \code{\link{twinstim}} (Meyer et al., 2012) fits spatio-temporal point process models to point patterns of infective events, e.g., time-stamped geo-referenced surveillance data on infectious disease occurrence; see \code{vignette("twinstim")} for an illustration. A recent overview of the implemented space-time modeling frameworks for epidemic phenomena is given by Meyer et al. (2017). } %% Author information is dynamically extracted from the DESCRIPTION file \author{ \Sexpr[stage=build]{ pkgdir <- tools:::Rd_macros_package_dir() # support R CMD Rd2pdf pkg desc <- tools:::.read_description(file.path(pkgdir, "DESCRIPTION")) aar <- unname(eval(parse(text=desc["Authors@R"]))) authors <- aar[grep("aut", aar$role)] paste0(format(authors, include = c("given", "family")), collapse = ", ") } Maintainer: Sebastian Meyer \email{seb.meyer@fau.de} %\packageMaintainer{surveillance} % only R >= 4.3.2 knows about Authors@R } %% Dynamically extract contributors from the DESCRIPTION file %% and persons from inst/THANKS for acknowledgement: \section{Acknowledgements}{ Substantial contributions of code by: \Sexpr[stage=build]{ contributors <- aar[grepl("ctb", aar$role) & !sapply(aar$family, is.null)] paste0(format(contributors, include = c("given", "family")), collapse = ", ") }. Furthermore, the authors would like to thank the following people for ideas, discussions, testing and feedback: \Sexpr[stage=build]{ find_inst_file <- function (file) { # support R CMD Rd2pdf in source package if(dir.exists(file.path(pkgdir, "inst"))) file.path(pkgdir, "inst", file) else file.path(pkgdir, file) } ## internally, Rd objects are assumed to be in UTF-8, see parse_Rd() thanks <- readLines(find_inst_file("THANKS"), encoding = "UTF-8") toString(grep("^(#|$)", trimws(thanks), invert=TRUE, value=TRUE)) }. } \references{ \code{citation(package="surveillance")} gives the two main software references for the modeling (Meyer et al., 2017) and the monitoring (Salmon et al., 2016) functionalities: \Sexpr[stage=build,results=rd]{ paste0("\\\itemize{\n", paste0("\\\item ", tools::toRd( readCitationFile(find_inst_file("CITATION")) # gives marked UTF-8 strings ), collapse = "\n\n"), "\n}") } Further references are listed in \code{surveillance:::REFERENCES}. If you use the \pkg{surveillance} package in your own work, please do cite the corresponding publications. } \seealso{ \url{https://surveillance.R-forge.R-project.org/} } \keyword{ package } \examples{ ## Additional documentation and illustrations of the methods are ## available in the form of package vignettes and demo scripts: vignette(package = "surveillance") demo(package = "surveillance") } surveillance/man/twinstim_siaf_simulatePC.Rd0000644000176200001440000000316513612576410021030 0ustar liggesusers\name{siaf.simulatePC} \alias{siaf.simulatePC} \title{ Simulation from an Isotropic Spatial Kernel via Polar Coordinates } \description{ To sample points from isotropic spatial kernels \eqn{f_2(s) = f(||s||)} such as \code{\link{siaf.powerlaw}} on a bounded domain (i.e., \eqn{||s|| < \code{ub}}), it is convenient to switch to polar coordinates \eqn{(r,\theta)}, which have a density proportional to \eqn{r f_2((r \cos(\theta), r \sin(\theta))) = r f(r)} (independent of the angle \eqn{\theta} due to isotropy). The angle is thus simply drawn uniformly in \eqn{[0,2\pi)}, and \eqn{r} can be sampled by the inversion method, where numeric root finding is used for the quantiles (since the quantile function is not available in closed form). } \usage{ siaf.simulatePC(intrfr) } \arguments{ \item{intrfr}{ a function computing the integral of \eqn{r f(r)} from 0 to \code{R} (first argument, not necessarily named \code{R}). Parameters of the function are passed as its second argument and a third argument is the event type. } } \value{ a function with arguments \code{(n, siafpars, type, ub)}, which samples \code{n} points from the spatial kernel \eqn{f_2(s)} within the disc of radius \code{ub}, where \code{siafpars} and \code{type} are passed as second and third argument to \code{intrfr}. The environment of the returned function will be the caller's environment. } \author{ Sebastian Meyer } \examples{ simfun <- siaf.powerlaw()$simulate ## is internally generated as siaf.simulatePC(intrfr.powerlaw) set.seed(1) simfun(n=10, siafpars=log(c(sigma=1, d=2)), ub=5) } \keyword{internal} surveillance/man/algo.farrington.threshold.Rd0000644000176200001440000000225614615162374021113 0ustar liggesusers\name{algo.farrington.threshold} \alias{algo.farrington.threshold} \title{Compute prediction interval for a new observation} \description{ Depending on the current transformation \eqn{h(y)= \{y, \sqrt{y}, y^{2/3}\}}, \deqn{V(h(y_0)-h(\mu_0))=V(h(y_0))+V(h(\mu_0))} is used to compute a prediction interval. The prediction variance consists of a component due to the variance of having a single observation and a prediction variance. } \usage{ algo.farrington.threshold(pred,phi,alpha=0.01,skewness.transform="none",y) } \arguments{ \item{pred}{A GLM prediction object} \item{phi}{Current overdispersion parameter (superfluous?)} \item{alpha}{Quantile level in Gaussian based CI, i.e. an \eqn{(1-\alpha)\cdot 100\%} confidence interval is computed. } \item{skewness.transform}{Skewness correction, i.e. one of \code{"none"}, \code{"1/2"}, or \code{"2/3"}.} \item{y}{Observed number} } \value{ Vector of length four with lower and upper bounds of an \eqn{(1-\alpha)\cdot 100\%} confidence interval (first two arguments) and corresponding quantile of observation \code{y} together with the median of the predictive distribution. } \keyword{regression} surveillance/man/aggregate.disProg.Rd0000644000176200001440000000112314136341403017340 0ustar liggesusers\name{aggregate.disProg} \alias{aggregate.disProg} \title{Aggregate a \code{disProg} Object} \description{ Aggregates the observed counts of a multivariate \code{disProg} object over the units. } \usage{ \method{aggregate}{disProg}(x,\dots) } \arguments{ \item{x}{Object of class \code{disProg}} \item{\dots}{not used at the moment} } \value{univariate \code{disProg} object with aggregated counts and respective states for each time point.} \keyword{internal} % disProg is soft-deprecated \examples{ data(ha) dim(ha$observed) dim(aggregate(ha)$observed) } surveillance/man/epidataCS.Rd0000644000176200001440000004216114614160257015657 0ustar liggesusers\encoding{latin1} \name{epidataCS} \alias{epidataCS} \alias{as.epidataCS} \alias{print.epidataCS} \alias{nobs.epidataCS} \alias{head.epidataCS} \alias{tail.epidataCS} \alias{[.epidataCS} \alias{subset.epidataCS} \alias{marks.epidataCS} \alias{summary.epidataCS} \alias{print.summary.epidataCS} \alias{as.stepfun.epidataCS} \alias{getSourceDists} \alias{coerce,epidataCS,SpatialPointsDataFrame-method} \title{ Continuous Space-Time Marked Point Patterns with Grid-Based Covariates } \description{ Data structure for \strong{c}ontinuous \strong{s}patio-temporal event data, e.g. individual case reports of an infectious disease. Apart from the actual \code{events}, the class simultaneously holds a spatio-temporal grid of endemic covariates (similar to disease mapping) and a representation of the observation region. The \code{"epidataCS"} class is the basis for fitting spatio-temporal endemic-epidemic intensity models with the function \code{\link{twinstim}} (Meyer et al., 2012). The implementation is described in Meyer et al. (2017, Section 3), see \code{vignette("twinstim")}. } \usage{ as.epidataCS(events, stgrid, W, qmatrix = diag(nTypes), nCircle2Poly = 32L, T = NULL, clipper = "polyclip", verbose = interactive()) \method{print}{epidataCS}(x, n = 6L, digits = getOption("digits"), ...) \method{nobs}{epidataCS}(object, ...) \method{head}{epidataCS}(x, n = 6L, ...) \method{tail}{epidataCS}(x, n = 6L, ...) \method{[}{epidataCS}(x, i, j, ..., drop = TRUE) \method{subset}{epidataCS}(x, subset, select, drop = TRUE, ...) \method{marks}{epidataCS}(x, coords = TRUE, ...) \method{summary}{epidataCS}(object, ...) \method{print}{summary.epidataCS}(x, ...) \method{as.stepfun}{epidataCS}(x, ...) getSourceDists(object, dimension = c("space", "time")) } \arguments{ \item{events}{ a \code{"\linkSPclass{SpatialPointsDataFrame}"} of cases with the following obligatory columns (in the \code{events@data} \code{data.frame}): \describe{ \item{time}{time point of event. Will be converted to a numeric variable by \code{as.numeric}. There should be no concurrent events (but see \code{\link{untie}} for an ex post adjustment) and there cannot be events beyond \code{stgrid} (i.e., \code{time<=T} is required). Events at or before time \eqn{t_0} = \code{min(stgrid$start)} are allowed and form the prehistory of the process.} \item{tile}{the spatial region (tile) where the event is located. This links to the tiles of \code{stgrid}.} \item{type}{optional type of event in a marked \code{twinstim} model. Will be converted to a factor variable dropping unused levels. If missing, all events will be attribute the single type \code{"1"}.} \item{eps.t}{maximum \emph{temporal} influence radius (e.g. length of infectious period, time to culling, etc.); must be positive and may be \code{Inf}.} \item{eps.s}{maximum \emph{spatial} influence radius (e.g. 100 [km]); must be positive and may be \code{Inf}. A compact influence region mainly has computational advantages, but might also be plausible for specific applications.} } The \code{data.frame} may contain columns with further marks of the events, e.g. sex, age of infected individuals, which may be used as epidemic covariates influencing infectiousness. Note that some auxiliary columns will be added at conversion whose names are reserved: \code{".obsInfLength"}, \code{".bdist"}, \code{".influenceRegion"}, and \code{".sources"}, as well as \code{"start"}, \code{"BLOCK"}, and all endemic covariates' names from \code{stgrid}. } \item{stgrid}{ a \code{\link{data.frame}} describing endemic covariates on a full spatio-temporal region x interval grid (e.g., district x week), which is a decomposition of the observation region \code{W} and period \eqn{t_0,T}. This means that for every combination of spatial region and time interval there must be exactly one row in this \code{data.frame}, that the union of the spatial tiles equals \code{W}, the union of the time intervals equals \eqn{t_0,T}, and that regions (and intervals) are non-overlapping. There are the following obligatory columns: \describe{ \item{tile}{ID of the spatial region (e.g., district ID). It will be converted to a factor variable (dropping unused levels if it already was one).} \item{start, stop}{columns describing the consecutive temporal intervals (converted to numeric variables by \code{as.numeric}). The \code{start} time of an interval must be equal to the \code{stop} time of the previous interval. The \code{stop} column may be missing, in which case it will be auto-generated from the set of \code{start} values and \code{T}.} \item{area}{area of the spatial region (\code{tile}). Be aware that the unit of this area (e.g., square km) must be consistent with the units of \code{W} and \code{events} (as specified in their \code{\link[sp]{proj4string}}s).} } The remaining columns are endemic covariates. Note that the column name \code{"BLOCK"} is reserved (a column which will be added automatically for indexing the time intervals of \code{stgrid}). } \item{W}{ an object of class \code{"\linkSPclass{SpatialPolygons}"} representing the observation region. It must have the same \code{proj4string} as \code{events} and all events must be within \code{W}. Prior simplification of \code{W} may considerably reduce the computational burden of likelihood evaluations in \code{\link{twinstim}} models with non-trivial spatial interaction functions (see the \dQuote{Note} section below). } \item{qmatrix}{ a square indicator matrix (0/1 or \code{FALSE}/\code{TRUE}) for possible transmission between the event types. The matrix will be internally converted to \code{logical}. Defaults to an independent spread of the event types, i.e. the identity matrix. } \item{nCircle2Poly}{ accuracy (number of edges) of the polygonal approximation of a circle, see \code{\link{discpoly}}. } \item{T}{ end of observation period (i.e. last \code{stop} time of \code{stgrid}). Must be specified if the start but not the stop times are supplied in \code{stgrid} (=> auto-generation of \code{stop} times). } \item{clipper}{polygon clipping engine to use for calculating the \code{.influenceRegion}s of events (see the Value section below). Default is the \CRANpkg{polyclip} package (called via \code{\link[spatstat.geom]{intersect.owin}} from package \CRANpkg{spatstat.geom}). In \pkg{surveillance} <= 1.6-0, package \pkg{gpclib} was used; this is no longer supported, neither is \pkg{rgeos}.} \item{verbose}{logical indicating if status messages should be printed during input checking and \code{"epidataCS"} generation. The default is to do so in interactive \R sessions.} \item{x}{an object of class \code{"epidataCS"} or \code{"summary.epidataCS"}, respectively.} \item{n}{a single integer. If positive, the first (\code{head}, \code{print}) / last (\code{tail}) \code{n} events are extracted. If negative, all but the \code{n} first/last events are extracted.} \item{digits}{minimum number of significant digits to be printed in values.} \item{i,j,drop}{ arguments passed to the \code{\link[sp:SpatialPointsDataFrame-class]{[-method}} for \code{SpatialPointDataFrame}s for subsetting the \code{events} while retaining \code{stgrid} and \code{W}.\cr If \code{drop=TRUE} (the default), event types that completely disappear due to \code{i}-subsetting will be dropped, which reduces \code{qmatrix} and the factor levels of the \code{type} column.\cr By the \code{j} index, epidemic covariates can be removed from \code{events}.} \item{\dots}{unused (arguments of the generics) with a few exceptions: The \code{print} method for \code{"epidataCS"} passes \code{\dots} to the \code{\link{print.data.frame}} method, and the \code{print} method for \code{"summary.epidataCS"} passes additional arguments to \code{\link{print.table}}.} \item{subset, select}{arguments used to subset the \code{events} from an \code{"epidataCS"} object like in \code{\link{subset.data.frame}}.} \item{coords}{logical indicating if the data frame of event marks returned by \code{marks(x)} should have the event coordinates appended as last columns. This defaults to \code{TRUE}.} \item{object}{an object of class \code{"epidataCS"}.} \item{dimension}{the distances of all events to their potential source events can be computed in either the \code{"space"} or \code{"time"} dimension.} } \details{ The function \code{as.epidataCS} is used to generate objects of class \code{"epidataCS"}, which is the data structure required for \code{\link{twinstim}} models. The \code{[}-method for class \code{"epidataCS"} ensures that the subsetted object will be valid, for instance, it updates the auxiliary list of potential transmission paths stored in the object. The \code{[}-method is used in \code{subset.epidataCS}, which is implemented similar to \code{\link{subset.data.frame}}. The \code{print} method for \code{"epidataCS"} prints some metadata of the epidemic, e.g., the observation period, the dimensions of the spatio-temporal grid, the types of events, and the total number of events. By default, it also prints the first \code{n = 6} rows of the \code{events}. } \value{ An object of class \code{"epidataCS"} is a list containing the following components: \item{events}{a \code{"\linkSPclass{SpatialPointsDataFrame}"} (see the description of the argument). The input \code{events} are checked for requirements and sorted chronologically. The columns are in the following order: obligatory event columns, event marks, the columns \code{BLOCK}, \code{start} and endemic covariates copied from \code{stgrid}, and finally, hidden auxiliary columns. The added auxiliary columns are: \describe{ \item{\code{.obsInfLength}}{observed length of the infectious period (possibly truncated at \code{T}), i.e., \code{pmin(T-time, eps.t)}.} \item{\code{.sources}}{a list of numeric vectors of potential sources of infection (wrt the interaction ranges eps.s and eps.t) for each event. Row numbers are used as index.} \item{\code{.bdist}}{minimal distance of the event locations to the polygonal boundary \code{W}.} \item{\code{.influenceRegion}}{a list of influence regions represented by objects of the \pkg{spatstat.geom} class \code{"owin"}. For each event, this is the intersection of \code{W} with a (polygonal) circle of radius \code{eps.s} centered at the event's location, shifted such that the event location becomes the origin. The list has \code{nCircle2Poly} set as an attribute.} } } \item{stgrid}{a \code{data.frame} (see description of the argument). The spatio-temporal grid of endemic covariates is sorted by time interval (indexed by the added variable \code{BLOCK}) and region (\code{tile}). It is a full \code{BLOCK} x \code{tile} grid.} \item{W}{a \code{"\linkSPclass{SpatialPolygons}"} object representing the observation region.} \item{qmatrix}{see the above description of the argument. The \code{\link{storage.mode}} of the indicator matrix is set to logical and the \code{dimnames} are set to the levels of the event types.} The \code{nobs}-method returns the number of events. The \code{head} and \code{tail} methods subset the epidemic data using the extraction method (\code{[}), i.e. they return an object of class \code{"epidataCS"}, which only contains (all but) the first/last \code{n} events. For the \code{"epidataCS"} class, the method of the generic function \code{\link[spatstat.geom]{marks}} defined by the \pkg{spatstat.geom} package returns a \code{data.frame} of the event marks (actually also including time and location of the events), disregarding endemic covariates and the auxiliary columns from the \code{events} component of the \code{"epidataCS"} object. The \code{summary} method (which has again a \code{print} method) returns a list of metadata, event data, the tables of tiles and types, a step function of the number of infectious individuals over time (\code{$counter}), i.e., the result of the \code{\link{as.stepfun}}-method for \code{"epidataCS"}, and the number of potential sources of transmission for each event (\code{$nSources}) which is based on the given maximum interaction ranges \code{eps.t} and \code{eps.s}. } \note{ Since the observation region \code{W} defines the integration domain in the point process likelihood, the more detailed the polygons of \code{W} are the longer it will take to fit a \code{\link{twinstim}}. You are advised to sacrifice some shape details for speed by reducing the polygon complexity, for example via the \command{mapshaper} JavaScript library wrapped by the R package \CRANpkg{rmapshaper}, or via \code{\link[spatstat.geom]{simplify.owin}}. } \references{ Meyer, S., Elias, J. and H\enc{}{oe}hle, M. (2012): A space-time conditional intensity model for invasive meningococcal disease occurrence. \emph{Biometrics}, \bold{68}, 607-616. \doi{10.1111/j.1541-0420.2011.01684.x} Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \author{ Sebastian Meyer Contributions to this documentation by Michael H\enc{}{oe}hle and Mayeul Kauffmann. } \seealso{ \code{vignette("twinstim")}. \code{\link{plot.epidataCS}} for plotting, and \code{\link{animate.epidataCS}} for the animation of such an epidemic. There is also an \code{\link[=update.epidataCS]{update}} method for the \code{"epidataCS"} class. To re-extract the \code{events} point pattern from \code{"epidataCS"}, use \code{as(object, "SpatialPointsDataFrame")}. It is possible to convert an \code{"epidataCS"} point pattern to an \code{"\link{epidata}"} object (\code{\link{as.epidata.epidataCS}}), or to aggregate the events into an \code{"\linkS4class{sts}"} object (\code{\link{epidataCS2sts}}). } \examples{ ## load "imdepi" example data (which is an object of class "epidataCS") data("imdepi") ## print and summary print(imdepi, n=5, digits=2) print(s <- summary(imdepi)) plot(s$counter, # same as 'as.stepfun(imdepi)' xlab = "Time [days]", ylab="Number of infectious individuals", main=paste("Time course of the number of infectious individuals", "assuming an infectious period of 30 days", sep="\n")) plot(table(s$nSources), xlab="Number of \"close\" infective individuals", ylab="Number of events", main=paste("Distribution of the number of potential sources", "assuming an interaction range of 200 km and 30 days", sep="\n")) ## the summary object contains further information str(s) ## a histogram of the spatial distances to potential source events ## (i.e., to events of the previous eps.t=30 days within eps.s=200 km) sourceDists_space <- getSourceDists(imdepi, "space") hist(sourceDists_space); rug(sourceDists_space) ## internal structure of an "epidataCS"-object str(imdepi, max.level=4) ## see help("imdepi") for more info on the data set ## extraction methods subset the 'events' component imdepi[101:200,] head(imdepi, n=1) # only first event tail(imdepi, n=4) # only last 4 events subset(imdepi, type=="B") # only events of type B ## see help("plot.epidataCS") for convenient plot-methods for "epidataCS" ### ### reconstruct the "imdepi" object ### ## observation region load(system.file("shapes", "districtsD.RData", package="surveillance"), verbose = TRUE) ## extract point pattern of events from the "imdepi" data ## a) as a data frame with coordinate columns via marks() eventsData <- marks(imdepi) ## b) as a Spatial object via the coerce-method events <- as(imdepi, "SpatialPointsDataFrame") ## plot observation region with events (may require package 'sf') if (requireNamespace("sf")) {% https://github.com/r-spatial/evolution/issues/10 plot(stateD, axes=TRUE); title(xlab="x [km]", ylab="y [km]") points(events, pch=unclass(events$type), cex=0.5, col=unclass(events$type)) legend("topright", legend=levels(events$type), title="Type", pch=1:2, col=1:2) summary(events) } ## space-time grid with endemic covariates head(stgrid <- imdepi$stgrid[,-1]) ## reconstruct the "imdepi" object from its components myimdepi <- as.epidataCS(events = events, stgrid = stgrid, W = stateD, qmatrix = diag(2), nCircle2Poly = 16) \dontshow{if (surveillance.options("allExamples"))} ## This reconstructed object is equal to 'imdepi' as long as the internal ## structures of the embedded classes ("owin", "SpatialPolygons", ...), and ## the calculation of the influence regions by "polyclip" have not changed: stopifnot(all.equal(imdepi, myimdepi)) } \keyword{spatial} \keyword{classes} \keyword{manip} surveillance/man/twinstim_siaf.Rd0000644000176200001440000001253612665561746016721 0ustar liggesusers\name{twinstim_siaf} \alias{siaf} \title{ Spatial Interaction Function Objects } \description{ A spatial interaction function for use in \code{\link{twinstim}} can be constructed via the \code{siaf} function. It checks the supplied function elements, assigns defaults for missing arguments, and returns all checked arguments in a list. However, for standard applications it is much easier to use one of the pre-defined spatial interaction functions, e.g., \code{\link{siaf.gaussian}}. } \usage{ siaf(f, F, Fcircle, effRange, deriv, Deriv, simulate, npars, validpars = NULL) } \arguments{ \item{f}{the spatial interaction function. It must accept two arguments, the first one being a (2-column) coordinate matrix, the second one a parameter vector. For marked \code{twinstim}, it must accept the type of the event (integer code) as its third argument (either a single type for all locations or separate types for each location).} \item{F}{function computing the integral of \eqn{f(s)} (passed as second argument) over a polygonal \code{"owin"} domain (first argument). The third and fourth argument are the parameter vector and the (\emph{single}) type, respectively. There may be additional arguments, which can then be specified in the \code{control.siaf$F} argument list of \code{twinstim}. If the \code{F} function is missing, a general default (\code{\link[polyCub]{polyCub}}) will be used, with extra arguments \code{method} (default: \code{"SV"}) and corresponding accuracy parameters.} \item{Fcircle}{optional function for fast calculation of the (two-dimensional) integral of \eqn{f(s)} over a circle with radius \code{r} (first argument). Further arguments are as for \code{f}. It must not be vectorized (will always be called with single radius and a single type). If this function is specified, integration of the \code{siaf} over the spatial influence region of an event will be faster if the region is actually circular. This is the case if the event is located at least a distance \code{eps.s} from the border of the observation region \code{W}, or if the distance to the border is larger than the effective integration range (if specified, see \code{effRange} below).} \item{effRange}{optional function returning the \dQuote{effective} range of \eqn{f(s)} for the given set of parameters (the first and only argument) such that the circle with radius \code{effRange} contains the numerically essential proportion of the integral mass. For the Gaussian kernel the default is \code{function (logsd) 6*exp(logsd)}. The return value must be a vector of length \code{nTypes} (effective range for each type). This function is only used if \code{Fcircle} is also specified.} \item{deriv}{optional derivative of \eqn{f(s)} \emph{with respect to the parameters}. It takes the same arguments as \code{f} but returns a matrix with as many rows as there were coordinates in the input and \code{npars} columns. This derivative is necessary for the calculation of the score function in \code{twinstim()}, which is advantageous for the numerical log-likelihood maximization.} \item{Deriv}{function computing the integral of \code{deriv} (passed as second argument) over a polygonal \code{"owin"} domain (first argument). The return value is thus a vector of length \code{npars}. The third argument is the parameter vector and the fourth argument is a (\emph{single}) type and must be named \code{type}. There may be additional arguments, which can then be specified in the \code{control.siaf$Deriv} argument list of \code{twinstim}. If the \code{Deriv} function is missing, a general default (\code{\link[polyCub]{polyCub}}) will be used, with extra arguments \code{method} (default: \code{"SV"}) and corresponding accuracy parameters.} \item{simulate}{optional function returning a sample drawn from the spatial kernel (only required for the simulation of \code{twinstim} models). Its first argument is the size of the sample to generate, next the parameter vector, an optional single event type, and an optional upper bound for the radius within which to simulate points. The function must return a two-column \emph{matrix} of the sampled locations. Note that the simulation method actually samples only one location at a time, thus it is sufficient to have a working \code{function(n=1, pars, type, ub)}. } \item{npars}{the number of parameters of the spatial interaction function \code{f} (i.e. the length of its second argument).} \item{validpars}{ optional function taking one argument, the parameter vector, indicating if it is valid. This approach to specify parameter constraints is rarely needed, because usual box-constrained parameters can be taken into account by using L-BFGS-B as the optimization method in \code{twinstim} (with arguments \code{lower} and \code{upper}), and positivity constraints by using log-parametrizations. This component is not necessary (and ignored) if \code{npars == 0}. } } \value{ list of checked arguments. } \author{ Sebastian Meyer } \seealso{ \code{\link{siaf.gaussian}} for a pre-defined spatial interaction function, and \code{\link{tiaf}} for the temporal interaction function. } \keyword{utilities} surveillance/man/fluBYBW.Rd0000644000176200001440000000457614614160257015304 0ustar liggesusers\name{fluBYBW} \alias{fluBYBW} \docType{data} \title{Influenza in Southern Germany} \description{ Weekly number of influenza A & B cases in the 140 districts of the two Southern German states Bavaria and Baden-Wuerttemberg, for the years 2001 to 2008. These surveillance data have been analyzed originally by Paul and Held (2011) and more recently by Meyer and Held (2014). } \usage{data(fluBYBW)} \format{ An \code{\linkS4class{sts}} object containing \eqn{416\times 140}{416 x 140} observations starting from week 1 in 2001. The \code{population} slot contains the population fractions of each district at 31.12.2001, obtained from the Federal Statistical Office of Germany. The \code{map} slot contains an object of class \code{"\linkSPclass{SpatialPolygonsDataFrame}"}. } \source{ Robert Koch-Institut: SurvStat: \url{https://survstat.rki.de/}; Queried on 6 March 2009. } \note{ Prior to \pkg{surveillance} version 1.6-0, \code{data(fluBYBW)} contained a redundant last row (417) filled with zeroes only. } \examples{ data("fluBYBW") # Count time series plot plot(fluBYBW, type = observed ~ time) \dontshow{if (surveillance.options("allExamples"))} # Map of disease incidence (per 100000 inhabitants) for the year 2001 plot(fluBYBW, type = observed ~ unit, tps = 1:52, total.args = list(), population = fluBYBW@map$X31_12_01 / 100000) # the overall rate for 2001 shown in the bottom right corner is sum(observed(fluBYBW[1:52,])) / sum(fluBYBW@map$X31_12_01) * 100000 \dontrun{ # Generating an animation takes a while. # Here we take the first 20 weeks of 2001 (runtime: ~3 minutes). # The full animation is available in Supplement A of Meyer and Held (2014) if (require("animation")) { oldwd <- setwd(tempdir()) # to not clutter up the current working dir saveHTML(animate(fluBYBW, tps = 1:20), title="Evolution of influenza in Bayern and Baden-Wuerttemberg", ani.width=500, ani.height=600) setwd(oldwd) } } } \references{ Paul, M. and Held, L. (2011) Predictive assessment of a non-linear random effects model for multivariate time series of infectious disease counts. Statistics in Medicine, \bold{30}, 1118-1136. Meyer, S. and Held, L. (2014): Power-law models for infectious disease spread. \emph{The Annals of Applied Statistics}, \bold{8} (3), 1612-1639. \doi{10.1214/14-AOAS743} } \keyword{datasets} surveillance/man/polyAtBorder.Rd0000644000176200001440000000330614614160257016426 0ustar liggesusers\name{polyAtBorder} \alias{polyAtBorder} \title{Indicate Polygons at the Border} \description{ Determines which polygons of a \code{"\linkSPclass{SpatialPolygons}"} object are at the border, i.e. have coordinates in common with the spatial union of all polygons (constructed using \code{\link{unionSpatialPolygons}}). } \usage{ polyAtBorder(SpP, snap = sqrt(.Machine$double.eps), method = "sf", ...) } \arguments{ \item{SpP}{ an object of class \code{"\linkSPclass{SpatialPolygons}"}. } \item{snap}{ tolerance used to consider coordinates as identical. } \item{method}{method to use for \code{\link{unionSpatialPolygons}}. Defaults to \pkg{sf}, since \pkg{polyclip} uses integer arithmetic, which causes rounding errors usually requiring tuning of (i.e., increasing) the tolerance parameter \code{snap} (see example below).} \item{\dots}{further arguments passed to the chosen \code{method}.} } \value{ logical vector of the same length as \code{SpP} also inheriting its \code{row.names}. } \author{ Sebastian Meyer } \examples{ ## Load districts of Germany load(system.file("shapes", "districtsD.RData", package = "surveillance")) ## Determine districts at the border and check the result on the map if (requireNamespace("sf")) { atBorder <- polyAtBorder(districtsD, method = "sf") if (interactive()) plot(districtsD, col = atBorder) table(atBorder) } ## For method = "polyclip", a higher snapping tolerance is required ## to obtain the correct result if (requireNamespace("polyclip")) { atBorder <- polyAtBorder(districtsD, snap = 1e-6, method = "polyclip") if (interactive()) plot(districtsD, col = atBorder) table(atBorder) } } \keyword{spatial} surveillance/man/sts_ggplot.Rd0000644000176200001440000000503714334522617016211 0ustar liggesusers\name{sts_ggplot} \alias{autoplot.sts} \title{ Time-Series Plots for \code{"sts"} Objects Using \pkg{ggplot2} } \description{ A simple \CRANpkg{ggplot2} variant of \code{\link{stsplot_time}}, based on a \dQuote{tidy} version of the \code{"sts"} object via \code{\link{tidy.sts}}. It uses a date axis and thus only works for time series indexed by dates or with a standard frequency (daily, (bi-)weekly, or monthly). } \usage{ autoplot.sts(object, population = FALSE, units = NULL, as.one = FALSE, scales = "fixed", width = NULL, ...) } \arguments{ \item{object}{an object of class \code{"\linkS4class{sts}"}.} \item{population}{logical indicating whether \code{observed(object)} should be divided by \code{population(object)}. The \code{population} argument can also be a scalar, which is used to scale the denominator \code{population(object)}, i.e., \code{observed(object)} is divided by \code{population(object) / population}. For instance, if \code{population(object)} contains raw population numbers, \code{population = 1000} could be used to plot the incidence per 1000 inhabitants.} \item{units}{optional integer or character vector to select the units (=columns of \code{object}) to plot. The default (\code{NULL}) is to plot all time series.} \item{as.one}{logical indicating if all time series should be plotted in one panel with \code{\link[ggplot2]{geom_line}}. By default, the time series are plotted in separate panels (using \code{\link[ggplot2]{geom_col}}).} \item{scales}{passed to \code{\link[ggplot2]{facet_wrap}} (for \code{as.one=FALSE}). By default, all panels use a common \code{ylim} (and \code{xlim}).} \item{width}{bar width, passed to \code{\link[ggplot2]{geom_col}}. Defaults to 7 for weekly time series.} \item{\dots}{unused (argument of the generic).} } \value{ a \code{"ggplot"} object. } \author{ Sebastian Meyer } \seealso{ \code{\link{stsplot_time}} for the traditional plots. } \examples{ ## compare traditional plot() with ggplot2-based autoplot.sts() if (requireNamespace("ggplot2")) { data("measlesDE") plot(measlesDE, units = 1:2) autoplot.sts(measlesDE, units = 1:2) } \dontshow{if (surveillance.options("allExamples"))} ## weekly incidence: population(measlesDE) gives population fractions, ## which we need to multiply by the total population if (require("ggplot2")) { autoplot.sts(measlesDE, population = 1000000/82314906) + ylab("Weekly incidence [per 1'000'000 inhabitants]") } } \keyword{hplot} \keyword{ts} surveillance/man/hhh4_update.Rd0000644000176200001440000000663413162205245016216 0ustar liggesusers\name{hhh4_update} \alias{update.hhh4} \title{ \code{update} a fitted \code{"hhh4"} model } \description{ Re-fit a \code{"\link{hhh4}"} model with a modified \code{control} list. } \usage{ \method{update}{hhh4}(object, ..., S = NULL, subset.upper = NULL, use.estimates = object$convergence, evaluate = TRUE) } \arguments{ \item{object}{ a fitted \code{"hhh4"} model. Non-convergent fits can be updated as well. } \item{\dots}{ components modifying the original control list for \code{\link{hhh4}}. Modifications are performed by \code{\link{modifyList}(object$control, list(...))}. } \item{S}{ a named list of numeric vectors serving as argument for \code{\link{addSeason2formula}}, or \code{NULL} (meaning no modification of seasonal terms). This argument provides a convenient way of changing the number of harmonics in the \code{f}ormulae of the model components \code{"ar"}, \code{"ne"} and \code{"end"} (to be used as names of the list). Non-specified components are not touched. Updating the \code{i}'th component's \code{f}ormula works by first dropping all sine and cosine terms and then applying \code{addSeason2formula} with arguments \code{S = S[[i]]} and \code{period = object$stsObj@freq}. Note that this step of updating seasonality is processed after modification of the \code{control} list by the \code{\dots} arguments. } \item{subset.upper}{ if a scalar value, refit the model to the data up to the time index given by \code{subset.upper}. The lower time index remains unchanged, i.e., \code{control$subset[1]:subset.upper} is used as the new \code{subset}. This argument is used by \code{\link{oneStepAhead}}. } \item{use.estimates}{ logical specifying if \code{coef(object)} should be used as starting values for the new fit (which is the new default since \pkg{surveillance} 1.8-2, in case the original fit has converged). This works by matching names against the coefficients of the new model. Extra coefficients no longer in the model are silently ignored. Setting \code{use.estimates = FALSE} means to re-use the previous start specification \code{object$control$start}.\cr Note that coefficients can also receive initial values from an extra \code{start} argument in the update call (as in \code{\link{hhh4}}), which then takes precedence over \code{coef(object)}. } \item{evaluate}{ logical indicating if the updated model should be fitted directly (defaults to \code{TRUE}). Otherwise, the updated \code{control} list is returned. } } \value{ If \code{evaluate = TRUE} the re-fitted object, otherwise the updated \code{control} list for \code{\link{hhh4}}. } \author{ Sebastian Meyer } \seealso{ \code{\link{hhh4}} } \examples{ data("salmonella.agona") ## convert to sts class salmonella <- disProg2sts(salmonella.agona) ## fit a basic model fit0 <- hhh4(salmonella, list(ar = list(f = ~1), end = list(f = addSeason2formula(~t)))) ## update: Poisson -> NegBin1, component seasonality fit1 <- update(fit0, family = "NegBin1", S = list(end=2, ar=2)) ## compare fits AIC(fit0, fit1) opar <- par(mfrow=c(2,2)) plot(fit0, type="fitted", names="fit0", par.settings=NULL) plot(fit1, type="fitted", names="fit1", par.settings=NULL) plot(fit0, fit1, type="season", components=c("end", "ar"), par.settings=NULL) par(opar) } \keyword{models} \keyword{methods} surveillance/man/twinstim_step.Rd0000644000176200001440000000365713165517635016750 0ustar liggesusers\name{twinstim_step} \alias{stepComponent} \alias{add1.twinstim} \alias{drop1.twinstim} \title{ Stepwise Model Selection by AIC } \description{ \code{stepComponent} is a wrapper around \code{\link{step}} to select a \code{"\link{twinstim}"} component's model based on an information criterion in a stepwise algorithm. There are also stand-alone single-step methods of \code{\link{add1}} and \code{\link{drop1}}. } \usage{ stepComponent(object, component = c("endemic", "epidemic"), scope = list(upper = object$formula[[component]]), direction = "both", trace = 2, verbose = FALSE, ...) \method{add1}{twinstim}(object, scope, component = c("endemic", "epidemic"), trace = 2, ...) \method{drop1}{twinstim}(object, scope, component = c("endemic", "epidemic"), trace = 2, ...) } \arguments{ \item{object}{an object of class \code{"twinstim"}.} \item{component}{one of \code{"endemic"} or \code{"epidemic"} (partially matched), determining the model component where the algorithm should proceed.} \item{scope,direction,trace}{see \code{\link{step}} and \code{\link{add1}}, respectively.} \item{verbose}{see \code{\link{twinstim}}.} \item{\dots}{further arguments passed to \code{\link{step}}, \code{\link{add1.default}}, or \code{\link{drop1.default}}, respectively.} } \value{ See \code{\link{step}} and \code{\link{add1}}, respectively. } \author{ (of this wrapper around \code{\link{step}}) Sebastian Meyer } \seealso{ \code{\link{step}}, \code{\link{add1}}, \code{\link{drop1}} } \examples{ data("imdepi", "imdepifit") ## simple baseline model m0 <- update(imdepifit, epidemic=~1, siaf=NULL) ## AIC-based step-wise backward selection of the endemic component m0_step <- stepComponent(m0, "endemic", scope=list(lower=~I(start/365-3.5))) ## nothing is dropped from the model \dontshow{ m0_step$anova <- NULL stopifnot(identical(m0, m0_step)) } } \keyword{models} \keyword{methods} surveillance/man/algo.outbreakP.Rd0000644000176200001440000001217114404130217016663 0ustar liggesusers\encoding{latin1} \name{algo.outbreakP} \alias{algo.outbreakP} \alias{calc.outbreakP.statistic} \title{Semiparametric surveillance of outbreaks} \description{ Frisen and Andersson (2009) method for semiparametric surveillance of outbreaks } \usage{ algo.outbreakP(disProgObj, control = list(range = range, k=100, ret=c("cases","value"),maxUpperboundCases=1e5)) } \arguments{ \item{disProgObj}{object of class disProg (including the observed and the state chain).} \item{control}{A list controlling the behaviour of the algorithm \describe{ \item{\code{range}}{determines the desired time-points which should be monitored. Note that it is automatically assumed that ALL other values in \code{disProgObj} can be used for the estimation, i.e. for a specific value \code{i} in \code{range} all values from 1 to \code{i} are used for estimation.} \item{\code{k}}{The threshold value. Once the outbreak statistic is above this threshold \code{k} an alarm is sounded.} \item{\code{ret}}{a string specifying the type of \code{upperbound}-statistic that is returned. With \code{"cases"} the number of cases that would have been necessary to produce an alarm (NNBA) or with \code{"value"} the outbreakP-statistic is computed (see below).} \item{\code{maxUpperboundCases}}{Upperbound when numerically searching for NNBA. Default is 1e5.} } } } \value{ \code{algo.outbreakP} gives a list of class \code{survRes} which includes the vector of alarm values for every time-point in \code{range}, the vector of threshold values for every time-point in \code{range}. } \details{ A generalized likelihood ratio test based on the Poisson distribution is implemented where the means of the in-control and out-of-control states are computed by isotonic regression. \deqn{OutbreakP(s) = \prod_{t=1}^s \left( \frac{\hat{\mu}^{C1}(t)}{\hat{\mu}^D(t)} \right)^{x(t)}} where \eqn{\hat{\mu}^{C1}(t)} is the estimated mean obtained by uni-modal regression under the assumption of one change-point and \eqn{\hat{\mu}^D(t)} is the estimated result when there is no change-point (i.e. this is just the mean of all observations). Note that the contrasted hypothesis assume all means are equal until the change-point, i.e. this detection method is especially suited for detecting a shift from a relative constant mean. Hence, this is less suited for detection in diseases with strong seasonal endemic component. Onset of influenza detection is an example where this method works particular well. In case \code{control$ret == "cases"} then a brute force numerical search for the number needed before alarm (NNBA) is performed. That is, given the past observations, whats the minimum number which would have caused an alarm? Note: Computing this might take a while because the search is done by sequentially increasing/decreasing the last observation by one for each time point in \code{control$range} and then calling the workhorse function of the algorithm again. The argument \code{control$maxUpperboundCases} controls the upper limit of this search (default is 1e5). Currently, even though the statistic has passed the threshold, the NNBA is still computed. After a few time instances what typically happens is that no matter the observed value we would have an alarm at this time point. In this case the value of NNBA is set to \code{NA}. Furthermore, the first time point is always \code{NA}, unless \code{k<1}. } \source{ The code is an extended R port of the Java code by Marianne \enc{Frisn}{Frisen} and Linus \enc{Schiler}{Schioeler} from the Computer Assisted Search For Epidemics (CASE) project, formerly available from \verb{https://case.folkhalsomyndigheten.se/} under the GNU GPL License v3. %% A manual on how to use an Excel implementation of the method %% is available at \url{http://economics.handels.gu.se/english/Units+and+Centra/statistical_research_unit/software}. An additional feature of the R code is that it contains a search for NNBA (see details). } \author{M. \enc{Hhle}{Hoehle} -- based on Java code by M. Frisen and L. \enc{Schiler}{Schioeler}} \references{ \enc{Frisn}{Frisen}, M., Andersson and \enc{Schiler}{Schioeler}, L., (2009), Robust outbreak surveillance of epidemics in Sweden, Statistics in Medicine, 28(3):476-493. \enc{Frisn}{Frisen}, M. and Andersson, E., (2009) Semiparametric Surveillance of Monotonic Changes, Sequential Analysis 28(4):434-454. } \examples{ #Use data from outbreakP manual (http://www.hgu.gu.se/item.aspx?id=16857) y <- matrix(c(1,0,3,1,2,3,5,4,7,3,5,8,16,23,33,34,48),ncol=1) #Generate sts object with these observations mysts <- sts(y, alarm=y*0) #Run the algorithm and present results #Only the value of outbreakP statistic upperbound(outbreakP(mysts, control=list(range=1:length(y),k=100, ret="value"))) #Graphical illustration with number-needed-before-alarm (NNBA) upperbound. res <- outbreakP(mysts, control=list(range=1:length(y),k=100, ret="cases")) plot(res,dx.upperbound=0,lwd=c(1,1,3),legend.opts=list(legend=c("Infected", "NNBA","Outbreak","Alarm"),horiz=TRUE)) } \keyword{classif} surveillance/man/epidata_summary.Rd0000644000176200001440000000561613433274256017215 0ustar liggesusers\name{epidata_summary} \alias{summary.epidata} \alias{print.summary.epidata} \title{ Summarizing an Epidemic } \description{ The \code{\link{summary}} method for \code{\link{class}} \code{"\link{epidata}"} gives an overview of the epidemic. Its \code{\link{print}} method shows the type of the epidemic, the time range, the total number of individuals, the initially and never infected individuals and the size of the epidemic. An excerpt of the returned \code{counters} data frame is also printed (see the Value section below). } \usage{ \method{summary}{epidata}(object, ...) \method{print}{summary.epidata}(x, ...) } \arguments{ \item{object}{an object inheriting from class \code{"epidata"}.} \item{x}{an object inheriting from class \code{"summary.epidata"}, i.e. an object returned by the function \code{summary.epidata}.} \item{\dots}{unused (argument of the generic).} } \value{ A list with the following components: \item{type}{ character string. Compartmental type of the epidemic, i.e. one of "SIR", "SI", "SIS" or "SIRS". } \item{size}{ integer. Size of the epidemic, i.e. the number of initially susceptible individuals, which became infected during the course of the epidemic. } \item{initiallyInfected}{ factor (with the same levels as the \code{id} column in the \code{"epidata"} object). Set of initially infected individuals. } \item{neverInfected}{ factor (with the same levels as the \code{id} column in the \code{"epidata"} object). Set of never infected individuals, i.e. individuals, which were neither initially infected nor infected during the course of the epidemic. } \item{coordinates}{ numeric matrix of individual coordinates with as many rows as there are individuals and one column for each spatial dimension. The row names of the matrix are the \code{id}s of the individuals. } \item{byID}{ data frame with time points of infection and optionally removal and re-susceptibility (depending on the \code{type} of the epidemic) ordered by \code{id}. If an event was not observed, the corresponding entry is missing. } \item{counters}{ data frame containing all events (S, I and R) ordered by time. The columns are \code{time}, \code{type} (of event), corresponding \code{id} and the three counters \code{nSusceptible}, \code{nInfectious} and \code{nRemoved}. The first row additionally shows the counters at the beginning of the epidemic, where the \code{type} and \code{id} column contain missing values. } } \author{ Sebastian Meyer } \seealso{ \code{\link{as.epidata}} for generating objects of class \code{"epidata"}. } \examples{ data("hagelloch") s <- summary(hagelloch) s # uses the print method for summary.epidata names(s) # components of the list 's' # positions of the individuals plot(s$coordinates) # events by id head(s$byID) } \keyword{methods} surveillance/man/clapply.Rd0000644000176200001440000000124613117527513015464 0ustar liggesusers\name{clapply} \alias{clapply} \title{ Conditional \code{lapply} } \description{ Use \code{\link{lapply}} if the input is a list and otherwise apply the function directly to the input \emph{and} wrap the result in a list. The function is implemented as \preformatted{ if (is.list(X)) lapply(X, FUN, ...) else list(FUN(X, ...)) } } \usage{ clapply(X, FUN, ...) } \arguments{ \item{X}{a list or a single \code{R} object on which to apply \code{FUN}.} \item{FUN}{the function to be applied to (each element of) \code{X}.} \item{\dots}{optional arguments to \code{FUN}.} } \value{ a list (of length 1 if \code{X} is not a list). } \keyword{iteration} \keyword{list} surveillance/man/meningo.age.Rd0000644000176200001440000000162214136511642016203 0ustar liggesusers\name{meningo.age} \alias{meningo.age} \docType{data} \title{Meningococcal infections in France 1985-1997} \description{ Monthly counts of meningococcal infections in France 1985-1997. Here, the data is split into 4 age groups (<1, 1-5, 5-20, >20). } \usage{data(meningo.age)} \format{ An object of class \code{disProg} with 156 observations in each of 4 age groups. \describe{ \item{week}{Month index} \item{observed}{Matrix with number of counts in the corresponding month and age group} \item{state}{Boolean whether there was an outbreak -- dummy not implemented} \item{neighbourhood}{Neighbourhood matrix, all age groups are adjacent} \item{populationFrac}{Population fractions} } } \source{ ?? } \examples{ data(meningo.age) plot(meningo.age, title="Meningococcal infections in France 1985-97") plot(meningo.age, as.one=FALSE) } \keyword{datasets} surveillance/man/twinstim_update.Rd0000644000176200001440000000504513165520251017234 0ustar liggesusers\name{twinstim_update} \alias{update.twinstim} \title{ \code{update}-method for \code{"twinstim"} } \description{ Update and (by default) re-fit a \code{"twinstim"}. This method is especially useful if one wants to add the \code{model} environment (which is required for some methods) to a fitted model object a posteriori. } \usage{ \method{update}{twinstim}(object, endemic, epidemic, control.siaf, optim.args, model, ..., use.estimates = TRUE, evaluate = TRUE) } \arguments{ \item{object}{a previous \code{"twinstim"} fit.} \item{endemic, epidemic}{changes to the formulae -- see \code{\link{update.formula}} and \code{\link{twinstim}}.} \item{control.siaf}{a list (see \code{\link{twinstim}}) to replace the given elements in the original \code{control.siaf} list. If \code{NULL}, the original list of control arguments is removed from the call, i.e., the defaults are used in \code{twinstim}.} \item{optim.args}{see \code{\link{twinstim}}. If a list, it will modify the original \code{optim.args} using \code{\link{modifyList}}.} \item{model}{see \code{\link{twinstim}}. If this is the only argument to update, re-fitting is cleverly circumvented. Enriching the fit by the model environment is, e.g., required for \code{\link{intensityplot.twinstim}}.} \item{\dots}{Additional arguments to the call, or arguments with changed values.\cr If \code{start} values are specified, they need to be in the same format as in the original call \code{object$call$start}, which is either a named list of named numeric vectors or a named numeric vector; see the argument description in \code{\link{twinstim}}.} \item{use.estimates}{logical indicating if the estimates of \code{object} should be used as initial values for the new fit (in the \code{start} argument of \code{twinstim}). Defaults to \code{TRUE}.} \item{evaluate}{If \code{TRUE} (default), evaluate the new call else return the call.} } \value{ If \code{evaluate = TRUE} the re-fitted object, otherwise the updated call. } \author{ Sebastian Meyer Inspiration and some pieces of code originate from \code{\link{update.default}} by the R Core Team. } \seealso{ \code{\link{update.default}} } \examples{ data("imdepi", "imdepifit") ## add another epidemic covariate ## (but fix siaf-parameter so that this example runs quickly) imdepifit2 <- update(imdepifit, epidemic = ~. + log(popdensity), optim.args = list(fixed="e.siaf.1")) ## compare by AIC AIC(imdepifit, imdepifit2) } \keyword{models} \keyword{methods} surveillance/man/m1.Rd0000644000176200001440000000427614224035777014351 0ustar liggesusers\name{m1} \alias{m1} \alias{h1_nrwrp} \alias{k1} \alias{m2} \alias{m3} \alias{m4} \alias{m5} \alias{n1} \alias{n2} \alias{q1_nrwh} \alias{q2} \alias{s1} \alias{s2} \alias{s3} \docType{data} \encoding{latin1} \title{RKI SurvStat Data} \description{ 14 datasets for different diseases beginning in 2001 to the 3rd Quarter of 2004 including their defined outbreaks. \itemize{ \item \code{m1} 'Masern' in the 'Landkreis Nordfriesland' (Germany, Schleswig-Holstein) \item \code{m2} 'Masern' in the 'Stadt- und Landkreis Coburg' (Germany, Bayern) \item \code{m3} 'Masern' in the 'Kreis Leer' (Germany, Niedersachsen) \item \code{m4} 'Masern' in the 'Stadt- und Landkreis Aachen' (Germany, Nordrhein-Westfalen) \item \code{m5} 'Masern' in the 'Stadt Verden' (Germany, Niedersachsen) \item \code{q1_nrwh} 'Q-Fieber' in the 'Hochsauerlandkreis' (Germany, Westfalen) and in the 'Landkreis Waldeck-Frankenberg' (Germany, Hessen) \item \code{q2} 'Q-Fieber' in '\enc{Mnchen}{Muenchen}' (Germany, Bayern) \item \code{s1} 'Salmonella Oranienburg' in Germany \item \code{s2} 'Salmonella Agona' in 12 'Bundesl\enc{}{ae}ndern' of Germany \item \code{s3} 'Salmonella Anatum' in Germany \item \code{k1} 'Kryptosporidiose' in Germany, 'Baden-W\enc{}{ue}rttemberg' \item \code{n1} 'Norovirus' in 'Stadtkreis Berlin Mitte' (Germany, Berlin) \item \code{n2} 'Norovirus' in 'Torgau-Oschatz' (Germany, Sachsen) \item \code{h1_nrwrp} 'Hepatitis A' in 'Oberbergischer Kreis, Olpe, Rhein-Sieg-kreis' (Germany, Nordrhein-Westfalen) and 'Siegenwittgenstein Altenkirchen' (Germany, Rheinland-Pfalz) } } \usage{data(m1)} \format{ \code{disProg} objects each containing 209 observations (weekly on 52 weeks) \describe{ \item{observed}{Number of counts in the corresponding week} \item{state}{Boolean whether there was an outbreak.} } } \source{ Robert Koch-Institut: SurvStat: \url{https://survstat.rki.de/}; m1 and m3 were queried on 10 November 2004. The rest during September 2004. } \examples{ data(k1) survResObj <- algo.rki1(k1, control=list(range=27:192)) plot(survResObj, "RKI 1", "k1") } \keyword{datasets} surveillance/man/stsNC-class.Rd0000644000176200001440000000422314221271063016144 0ustar liggesusers\name{stsNC-class} \docType{class} \alias{stsNC-class} %New stsNC specific methods \alias{reportingTriangle} \alias{reportingTriangle,stsNC-method} \alias{delayCDF} \alias{delayCDF,stsNC-method} \alias{score} \alias{score,stsNC-method} \alias{predint} \alias{predint,stsNC-method} %Coerce method to convert to sts object \alias{coerce,sts,stsNC-method} \encoding{latin1} \title{Class "stsNC" -- a class inheriting from class \code{sts} which allows the user to store the results of back-projecting surveillance time series} \description{ A class inheriting from class \code{sts}, but with additional slots to store the results of nowcasting. } \section{Slots}{ The slots are as for \code{"\linkS4class{sts}"}. However, a number of additional slots exists. \describe{ \item{\code{reportingTriangle}:}{An array containing the upper and lower limit of the confidence interval.} \item{\code{predPMF}:}{Predictive distribution for each nowcasted time point.} \item{\code{pi}:}{A prediction interval for each nowcasted time point. This is calculated based on \code{predPMF}.} \item{\code{truth}:}{An object of type \code{sts} containing the true number of cases.} \item{\code{delayCDF}:}{List with the CDF of the estimated delay distribution for each method.} \item{\code{SR}:}{Possible output of proper scoring rules} } } \section{Methods}{ The methods are the same as for \code{"\linkS4class{sts}"}. \describe{ \item{coerce}{\code{signature(from = "sts", to = "stsNC")}: convert an object of class \code{sts} to class \code{stsNC}. } \item{reportingTriangle}{\code{signature(x = "stsNC")}: extract the \code{reportingTriangle} slot of an \code{stsNC} object. } \item{delayCDF}{\code{signature(x = "stsNC")}: extract the \code{delayCDF} slot of an \code{stsNC} object. } \item{score}{\code{signature(x = "stsNC")}: extract the scoring rules result slot of an \code{stsNC} object. } \item{predint}{\code{signature(x = "stsNC")}: extract the prediction interval slot of an \code{stsNC} object. } } } \author{M. \enc{Hhle}{Hoehle}} \keyword{classes} surveillance/man/intensityplot.Rd0000644000176200001440000000130712061471523016737 0ustar liggesusers\name{intensityplot} \alias{intensityplot} \title{ Plot Paths of Point Process Intensities } \description{ Generic function for plotting paths of point process intensities. Methods currently defined in package \pkg{surveillance} are for classes \code{"twinSIR"} and \code{"simEpidata"} (temporal), as well as \code{"twinstim"} and \code{"simEpidataCS"} (spatio-temporal). } \usage{ intensityplot(x, ...) } \arguments{ \item{x}{ An object for which an \code{intensityplot} method is defined. } \item{\dots}{ Arguments passed to the corresponding method. } } \seealso{ The methods \code{\link{intensityplot.twinSIR}} and \code{\link{intensityplot.twinstim}}. } \keyword{hplot} surveillance/man/algo.twins.Rd0000644000176200001440000001227314326735616016117 0ustar liggesusers\encoding{latin1} \name{algo.twins} \alias{algo.twins} \title{Fit a Two-Component Epidemic Model using MCMC} \description{ Fits a negative binomial model as described in Held et al. (2006) to an univariate time series of counts. This is an experimental implementation that may be removed in future versions of the package. } \usage{ algo.twins(disProgObj, control=list(burnin=1000, filter=10, sampleSize=2500, noOfHarmonics=1, alpha_xi=10, beta_xi=10, psiRWSigma=0.25,alpha_psi=1, beta_psi=0.1, nu_trend=FALSE, logFile="twins.log")) } \arguments{ \item{disProgObj}{object of class \code{disProg}} \item{control}{control object: \describe{ \item{\code{burnin}}{Number of burn in samples.} \item{\code{filter}}{Thinning parameter. If \code{filter = 10} every 10th sample is after the burn in is returned.} \item{\code{sampleSize}}{Number of returned samples. Total number of samples = \code{burnin}+\code{filter}*\code{sampleSize}} \item{\code{noOfHarmonics}}{Number of harmonics to use in the modelling, i.e. \eqn{L}{L} in (2.2) of Held et al (2006).} \item{\code{alpha_xi}}{Parameter \eqn{\alpha_{\xi}}{\alpha_\xi} of the hyperprior of the epidemic parameter \eqn{\lambda}{\lambda}} \item{\code{beta_xi}}{Parameter \eqn{\beta_{\xi}}{\beta_\xi} of the hyperprior of the epidemic parameter \eqn{\lambda}{\lambda}} \item{\code{psiRWSigma}}{Starting value for the tuning of the variance of the random walk proposal for the overdispersion parameter \eqn{\psi}{\psi}.} \item{\code{alpha_psi}}{Parameter \eqn{\alpha_{\psi}}{\alpha_\psi} of the prior of the overdispersion parameter \eqn{\psi}{\psi}} \item{\code{beta_psi}}{Parameter \eqn{\beta_{\psi}}{\beta_\psi} of the prior of the overdispersion parameter \eqn{\psi}{\psi}} \item{\code{nu_trend}}{Adjust for a linear trend in the endemic part? (default: \code{FALSE})} \item{\code{logFile}}{Base file name for the output files. The function writes three output files in the current working directory \code{getwd()}. If \code{logfile = "twins.log"} the results are stored in the three files \file{twins.log}, \file{twins.log2} and \file{twins.log.acc}.\cr \file{twins.log} contains the returned samples of the parameters \eqn{\psi}{\psi}, \eqn{\gamma_{0}}{\gamma_0}, \eqn{\gamma_{1}}{\gamma_1}, \eqn{\gamma_{2}}{\gamma_2}, K, \eqn{\xi_{\lambda}}{\xi_\lambda} \eqn{\lambda_{1},...,\lambda{n}}{\lambda_1,...,\lambda_{n}}, the predictive distribution of the number of cases at time \eqn{n+1} and the deviance.\cr \file{twins.log2} contains the sample means of the variables \eqn{X_{t}, Y_{t}, \omega_{t}}{X_t, Y_t, \omega_t} and the relative frequency of a changepoint at time t for t=1,...,n and the relative frequency of a predicted changepoint at time n+1.\cr \file{twins.log.acc} contains the acceptance rates of \eqn{\psi}{\psi}, the changepoints and the endemic parameters \eqn{\gamma_{0}}{\gamma_0}, \eqn{\gamma_{1}}{\gamma_1}, \eqn{\gamma_{2}}{\gamma_2} in the third column and the variance of the random walk proposal for the update of the parameter \eqn{\psi}{\psi} in the second column.} } } } \note{ This function is not a surveillance algorithm, but only a modelling approach as described in the Held et. al (2006) paper. Note also that the function writes three logfiles in the current working directory \code{getwd()}: \file{twins.log}, \file{twins.log.acc} and \file{twins.log2}. Thus you need to have write permissions in the current working directory. } \value{Returns an object of class \code{atwins} with elements \item{control}{specified control object} \item{disProgObj}{specified \code{disProg}-object} \item{logFile}{contains the returned samples of the parameters \eqn{\psi}{\psi}, \eqn{\gamma_{0}}{\gamma_0}, \eqn{\gamma_{1}}{\gamma_1}, \eqn{\gamma_{2}}{\gamma_2}, K, \eqn{\xi_{\lambda}}{\xi_\lambda} \eqn{\lambda_{1},...,\lambda{n}}{\lambda_1,...,\lambda_{n}}, the predictive distribution and the deviance.} \item{logFile2}{contains the sample means of the variables \eqn{X_{t}, Y_{t}, \omega_{t}}{X_t, Y_t, \omega_t} and the relative frequency of a changepoint at time t for t=1,...,n and the relative frequency of a predicted changepoint at time n+1.} } \references{ Held, L., Hofmann, M., \enc{Hhle}{Hoehle}, M. and Schmid V. (2006): A two-component model for counts of infectious diseases. \emph{Biostatistics}, \bold{7}, pp. 422--437. } \author{ M. Hofmann and M. \enc{Hhle}{Hoehle} and D. \enc{Sabans Bov}{Sabanes Bove} } \examples{ # Load the data used in the Held et al. (2006) paper data("hepatitisA") # Fix seed - this is used for the MCMC samplers in twins set.seed(123) # Call algorithm and save result (use short chain without filtering for speed) oldwd <- setwd(tempdir()) # where logfiles will be written otwins <- algo.twins(hepatitisA, control=list(burnin=500, filter=1, sampleSize=1000)) setwd(oldwd) # This shows the entire output (use ask=TRUE for pause between plots) plot(otwins, ask=FALSE) # Direct access to MCMC output hist(otwins$logFile$psi,xlab=expression(psi),main="") if (require("coda")) { print(summary(mcmc(otwins$logFile[,c("psi","xipsi","K")]))) } } \keyword{ts} \keyword{regression} surveillance/man/algo.bayes.Rd0000644000176200001440000001216413165505075016047 0ustar liggesusers\name{algo.bayes} \alias{algo.bayes} \alias{algo.bayesLatestTimepoint} \alias{algo.bayes1} \alias{algo.bayes2} \alias{algo.bayes3} \encoding{latin1} \title{The Bayes System} \description{ Evaluation of timepoints with the Bayes subsystem 1, 2, 3 or a self defined Bayes subsystem. } \usage{ algo.bayesLatestTimepoint(disProgObj, timePoint = NULL, control = list(b = 0, w = 6, actY = TRUE,alpha=0.05)) algo.bayes(disProgObj, control = list(range = range, b = 0, w = 6, actY = TRUE,alpha=0.05)) algo.bayes1(disProgObj, control = list(range = range)) algo.bayes2(disProgObj, control = list(range = range)) algo.bayes3(disProgObj, control = list(range = range)) } \arguments{ \item{disProgObj}{object of class disProg (including the observed and the state chain)} \item{timePoint}{time point which should be evaluated in \code{algo.bayes LatestTimepoint}. The default is to use the latest timepoint} \item{control}{control object: \code{range} determines the desired timepoints which should be evaluated, \code{b} describes the number of years to go back for the reference values, \code{w} is the half window width for the reference values around the appropriate timepoint and \code{actY} is a boolean to decide if the year of \code{timePoint} also contributes \code{w} reference values. The parameter \code{alpha} is the \eqn{(1-\alpha)}-quantile to use in order to calculate the upper threshold. As default \code{b}, \code{w}, \code{actY} are set for the Bayes 1 system with \code{alpha}=0.05. } } \value{ \item{survRes}{ \code{algo.bayesLatestTimepoint} returns a list of class \code{survRes} (surveillance result), which includes the alarm value for recognizing an outbreak (1 for alarm, 0 for no alarm), the threshold value for recognizing the alarm and the input object of class disProg. \code{algo.bayes} gives a list of class \code{survRes} which includes the vector of alarm values for every timepoint in \code{range} and the vector of threshold values for every timepoint in \code{range} for the system specified by \code{b}, \code{w} and \code{actY}, the range and the input object of class disProg. \code{algo.bayes1} returns the same for the Bayes 1 system, \code{algo.bayes2} for the Bayes 2 system and \code{algo.bayes3} for the Bayes 3 system. } } \details{ Using the reference values the \eqn{(1-\alpha)\cdot 100\%}{(1-alpha)*100\%} quantile of the predictive posterior distribution is calculated as a threshold. An alarm is given if the actual value is bigger or equal than this threshold. It is possible to show using analytical computations that the predictive posterior in this case is the negative binomial distribution. Note: \code{algo.rki} or \code{algo.farrington} use two-sided prediction intervals -- if one wants to compare with these procedures it is necessary to use an alpha, which is half the one used for these procedures. Note also that \code{algo.bayes} calls \code{algo.bayesLatestTimepoint} for the values specified in \code{range} and for the system specified in \code{control}. \code{algo.bayes1}, \code{algo.bayes2}, \code{algo.bayes3} call \code{algo.bayesLatestTimepoint} for the values specified in \code{range} for the Bayes 1 system, Bayes 2 system or Bayes 3 system. \itemize{ \item \code{"Bayes 1"} reference values from 6 weeks. Alpha is fixed a t 0.05. \item \code{"Bayes 2"} reference values from 6 weeks ago and 13 weeks of the previous year (symmetrical around the same week as the current one in the previous year). Alpha is fixed at 0.05. \item \code{"Bayes 3"} 18 reference values. 9 from the year ago and 9 from two years ago (also symmetrical around the comparable week). Alpha is fixed at 0.05. } The procedure is now able to handle \code{NA}'s in the reference values. In the summation and when counting the number of observed reference values these are simply not counted. } \seealso{ \code{\link{algo.call}}, \code{\link{algo.rkiLatestTimepoint}} and \code{\link{algo.rki}} for the RKI system. } \author{M. \enc{Hhle}{Hoehle}, A. Riebler, C. Lang} \examples{ disProg <- sim.pointSource(p = 0.99, r = 0.5, length = 208, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) # Test for bayes 1 the latest timepoint algo.bayesLatestTimepoint(disProg) # Test week 200 to 208 for outbreaks with a selfdefined bayes algo.bayes(disProg, control = list(range = 200:208, b = 1, w = 5, actY = TRUE,alpha=0.05)) # The same for bayes 1 to bayes 3 algo.bayes1(disProg, control = list(range = 200:208,alpha=0.05)) algo.bayes2(disProg, control = list(range = 200:208,alpha=0.05)) algo.bayes3(disProg, control = list(range = 200:208,alpha=0.05)) } \keyword{classif} \source{ Riebler, A. (2004), Empirischer Vergleich von statistischen Methoden zur Ausbruchserkennung bei Surveillance Daten, Bachelor's thesis. } surveillance/man/checkResidualProcess.Rd0000644000176200001440000000505414221271063020117 0ustar liggesusers\name{checkResidualProcess} \alias{checkResidualProcess} \title{ Check the residual process of a fitted \code{twinSIR} or \code{twinstim} } \description{ Transform the residual process (cf. the \code{\link[=residuals.twinstim]{residuals}} methods for classes \code{"twinSIR"} and \code{"twinstim"}) such that the transformed residuals should be uniformly distributed if the fitted model well describes the true conditional intensity function. Graphically check this using \code{\link{ks.plot.unif}}. The transformation for the residuals \code{tau} is \code{1 - exp(-diff(c(0,tau)))} (cf. Ogata, 1988). Another plot inspects the serial correlation between the transformed residuals (scatterplot between \eqn{u_i} and \eqn{u_{i+1}}). } \usage{ checkResidualProcess(object, plot = 1:2, mfrow = c(1,length(plot)), ...) } \arguments{ \item{object}{ an object of class \code{"\link{twinSIR}"} or \code{"\link{twinstim}"}. } \item{plot}{ logical (or integer index) vector indicating if (which) plots of the transformed residuals should be produced. The \code{plot} index 1 corresponds to a \code{\link{ks.plot.unif}} to check for deviations of the transformed residuals from the uniform distribution. The \code{plot} index 2 corresponds to a scatterplot of \eqn{u_i} vs. \eqn{u_{i+1}}. By default (\code{plot = 1:2}), both plots are produced. } \item{mfrow}{ see \code{\link{par}}. } \item{\dots}{ further arguments passed to \code{\link{ks.plot.unif}}. } } \value{ A list (returned invisibly, if \code{plot = TRUE}) with the following components: \describe{ \item{tau}{the residual process obtained by \code{residuals(object)}.} \item{U}{the transformed residuals which should be distributed as U(0,1).} \item{ks}{the result of the \code{ks.test} for the uniform distribution of \code{U}.} } } \references{ Ogata, Y. (1988) Statistical models for earthquake occurrences and residual analysis for point processes. \emph{Journal of the American Statistical Association}, 83, 9-27 } \author{ Sebastian Meyer } \seealso{ \code{\link{ks.plot.unif}} and the \code{\link[=residuals.twinstim]{residuals}}-method for classes \code{"twinSIR"} and \code{"twinstim"}. } \examples{ data("hagelloch") fit <- twinSIR(~ household, data = hagelloch) # a simplistic model ## extract the "residual process", i.e., the fitted cumulative intensities residuals(fit) ## assess goodness of fit based on these residuals checkResidualProcess(fit) # could be better } \keyword{dplot} \keyword{htest} surveillance/man/epidata_animate.Rd0000644000176200001440000001713314615162374017133 0ustar liggesusers\name{epidata_animate} \alias{animate.epidata} \alias{animate.summary.epidata} \title{ Spatio-Temporal Animation of an Epidemic } \description{ Function for the animation of epidemic data, i.e. objects inheriting from class \code{"epidata"}. This only works with 1- or 2-dimensional coordinates and is not useful if some individuals share the same coordinates (overlapping). There are two types of animation, see argument \code{time.spacing}. Besides the direct plotting in the \R session, it is also possible to generate a sequence of graphics files to create animations outside \R. } \usage{ \method{animate}{summary.epidata}(object, main = "An animation of the epidemic", pch = 19, col = c(3, 2, gray(0.6)), time.spacing = NULL, sleep = quote(5/.nTimes), legend.opts = list(), timer.opts = list(), end = NULL, generate.snapshots = NULL, ...) \method{animate}{epidata}(object, ...) } \arguments{ \item{object}{ an object inheriting from class \code{"epidata"} or \code{"summary.epidata"}. In the former case, its summary is calculated and the function continues as in the latter case, passing all \code{...} arguments to the \code{summary.epidata} method. } \item{main}{ a main title for the plot, see also \code{\link{title}}. } \item{pch, col}{ vectors of length 3 specifying the point symbols and colors for susceptible, infectious and removed individuals (in this order). The vectors are recycled if necessary. By default, susceptible individuals are marked as filled green circles, infectious individuals as filled red circles and removed individuals as filled gray circles. Note that the symbols are iteratively drawn (overlaid) in the same plotting region as time proceeds. For information about the possible values of \code{pch} and \code{col}, see the help pages of \code{\link{points}} and \code{\link{par}}, respectively. } \item{time.spacing}{ time interval for the animation steps. If \code{NULL} (the default), the events are plotted one by one with pauses of \code{sleep} seconds. Thus, it is just the \emph{ordering} of the events, which is shown. To plot the appearance of events proportionally to the exact time line, \code{time.spacing} can be set to a numeric value indicating the period of time between consecutive plots. Then, for each time point in \code{seq(0, end, by = time.spacing)} the current state of the epidemic can be seen and an additional timer indicates the current time (see \code{timer.opts} below). The argument \code{sleep} will be the artificial pause in seconds between two of those time points. } \item{sleep}{ time in seconds to \code{\link{Sys.sleep}} before the next plotting event. By default, each artificial pause is of length \code{5/.nTimes} seconds, where \code{.nTimes} is the number of events (infections and removals) of the epidemic, which is evaluated in the function body. Thus, for \code{time.spacing = NULL} the animation has a duration of approximately 5 seconds. In the other case, \code{sleep} is the duration of the artificial pause between two time points. Note that \code{sleep} is ignored on non-interactive devices (see \code{\link{dev.interactive}}) } \item{legend.opts}{ either a list of arguments passed to the \code{\link{legend}} function or \code{NULL} (or \code{NA}), in which case no legend will be plotted. All necessary arguments have sensible defaults and need not be specified, i.e. \describe{ \item{\code{x}:}{\code{"topright"}} \item{\code{legend}:}{\code{c("susceptible", "infectious", "removed")}} \item{\code{pch}:}{same as argument \code{pch} of the main function} \item{\code{col}:}{same as argument \code{col} of the main function} } } \item{timer.opts}{ either a list of arguments passed to the \code{\link{legend}} function or \code{NULL} (or \code{NA}), in which case no timer will be plotted. All necessary arguments have sensible defaults and need not be specified, i.e. \describe{ \item{\code{x}:}{\code{"bottomright"}} \item{\code{title}:}{\code{"time"}} \item{\code{box.lty}:}{\code{0}} \item{\code{adj}:}{\code{c(0.5,0.5)}} \item{\code{inset}:}{\code{0.01}} \item{\code{bg}:}{\code{"white"}} } Note that the argument \code{legend}, which is the current time of the animation, can not be modified. } \item{end}{ ending time of the animation in case of \code{time.spacing} not being \code{NULL}. By default (\code{NULL}), time stops after the last event. } \item{generate.snapshots}{ By default (\code{NULL}), the animation is not saved to image files but only shown on the on-screen device. In order to print to files, \code{time.spacing} must not be \code{NULL}, a screen device must be available, and there are two options:\cr If the framework of the \pkg{animation} package should be used, i.e. the \code{animate}-call is passed as the \code{expr} argument to one of the \code{save*} functions of the \pkg{animation} package, then set \code{generate.snapshots = img.name}, where \code{img.name} is the base name for the generated images (the same as passed to the \code{save*} function). The path and format (type, width, height) for the generated images is derived from \code{\link[animation]{ani.options}}. See the last example below.\cr Alternatively, \code{generate.snapshots} may be a list of arguments passed to the function \code{\link{dev.print}}, which then is executed at each time point of the grid defined by \code{time.spacing}. Essentially, this is used for saving the produced snapshots to files, e.g. \code{generate.snapshots = % list(device=pdf, file=quote(paste("epidemic_",sprintf(form,tp),".pdf",% sep="")))} will store the animation steps in pdf-files in the current working directory, where the file names each end with the time point represented by the corresponding plot. Because the variables \code{tp} and \code{form} should only be evaluated inside the function the \code{file} argument is \code{quote}d. Alternatively, the file name could also make use of the internal plot index \code{i}, e.g., use \code{file=quote(paste("epidemic",i,".pdf",sep=""))}. } \item{\dots}{ further graphical parameters passed to the basic call of \code{plot}, e.g. \code{las}, \code{cex.axis} (etc.) and \code{mgp}. } } %\value{ % invisibly returns \code{NULL}. %} \author{ Sebastian Meyer } \seealso{ \code{\link{summary.epidata}} for the data, on which the plot is based. \code{\link{plot.epidata}} for plotting the evolution of an epidemic by the numbers of susceptible, infectious and removed individuals. The contributed \R package \pkg{animation}. } \examples{ data("hagelloch") (s <- summary(hagelloch)) # plot the ordering of the events only animate(s) # or: animate(hagelloch) # with timer (animate only up to t=10) animate(s, time.spacing=0.1, end=10, sleep=0.01, legend.opts=list(x="topleft")) # Such an animation can be saved in various ways using tools of # the animation package, e.g., saveHTML() if (interactive() && require("animation")) { oldwd <- setwd(tempdir()) # to not clutter up the current working dir saveHTML({ par(bg="white") # default "transparent" is grey in some browsers animate(s, time.spacing=1, sleep=0, legend.opts=list(x="topleft"), generate.snapshots="epiani") }, use.dev=FALSE, img.name="epiani", ani.width=600, interval=0.5) setwd(oldwd) } } \keyword{hplot} \keyword{dynamic} \keyword{spatial} surveillance/man/runifdisc.Rd0000644000176200001440000000166013777627613016024 0ustar liggesusers\name{runifdisc} \alias{runifdisc} \title{ Sample Points Uniformly on a Disc } \description{ Sample \code{n} points uniformly on a disc of radius \code{r} in two-dimensional euclidean space via transformation to polar coordinates: the angle is sampled uniformly from \eqn{U(0,2\pi)}, the length is sampled uniformly from \eqn{\sqrt{U(0,r^2)}}. The sampled polar coordinates are then back-transformed to cartesian coordinates. } \usage{ runifdisc(n, r = 1, buffer = 0) } \arguments{ \item{n}{ integer size of the sample. } \item{r}{ numeric radius of the disc (centered at (0,0)). } \item{buffer}{ radius of inner buffer zone without points. } } \value{ A two-column coordinate matrix of the sampled points. } \author{ Sebastian Meyer } \examples{ x <- surveillance:::runifdisc(1000, 3) plot(x) } \keyword{datagen} \keyword{distribution} \keyword{internal} % not exported to avoid clash with spatstat::runifdisc surveillance/man/all.equal.Rd0000644000176200001440000000202412670511517015671 0ustar liggesusers\name{all.equal} \alias{all.equal.twinstim} \alias{all.equal.hhh4} \title{ Test if Two Model Fits are (Nearly) Equal } \description{ Two model fits are compared using standard \code{\link{all.equal}}-methods after discarding certain elements considered irrelevant for the equality of the fits, e.g., the runtime and the call. } \usage{ \method{all.equal}{twinstim}(target, current, ..., ignore = NULL) \method{all.equal}{hhh4}(target, current, ..., ignore = NULL) } \arguments{ \item{target,current}{the model fits to be compared.} \item{\dots}{further arguments for standard \code{\link{all.equal}}-methods, e.g., the numerical \code{tolerance}.} \item{ignore}{an optional character vector of elements to ignore when comparing the two fitted objects. The following elements are always ignored: \code{"runtime"} and \code{"call"}.} } \value{ Either \code{TRUE} or a character vector describing differences between the \code{target} and the \code{current} model fit. } \author{ Sebastian Meyer } \keyword{utilities} surveillance/man/animate.Rd0000644000176200001440000000111113167111527015424 0ustar liggesusers\name{animate} \alias{animate} \title{ Generic animation of spatio-temporal objects } \description{ Generic function for animation of \R objects. } \usage{ animate(object, ...) } \arguments{ \item{object}{The object to animate.} \item{\dots}{ Arguments to be passed to methods, such as graphical parameters or time interval options for the snapshots. } } \seealso{ The methods \code{\link{animate.epidata}}, \code{\link{animate.epidataCS}}, and \code{\link{animate.sts}} for the animation of surveillance data. } \keyword{hplot} \keyword{dynamic} \keyword{spatial} surveillance/man/ha.Rd0000644000176200001440000000201614350605347014406 0ustar liggesusers\name{ha} \alias{ha} \alias{ha.sts} \docType{data} \title{Hepatitis A in Berlin} \description{ Number of Hepatitis A cases among adult (age>18) males in Berlin, 2001-2006. An increase is seen during 2006. } \usage{ data("ha") data("ha.sts") } \format{ \code{ha} is a \code{disProg} object containing \eqn{290\times 12}{290 x 12} observations starting from week 1 in 2001 to week 30 in 2006. \code{ha.sts} was generated from \code{ha} via the converter function \code{\link{disProg2sts}} and includes a map of Berlin's districts. } \source{ Robert Koch-Institut: SurvStat: \url{https://survstat.rki.de/}; Queried on 25 August 2006. Robert Koch Institut, Epidemiologisches Bulletin 33/2006, p.290. } \examples{ ## deprecated "disProg" object data("ha") ha plot(aggregate(ha)) ## new-style "sts" object data("ha.sts") ha.sts plot(ha.sts, type = observed ~ time) # = plot(aggregate(ha.sts, by = "unit")) plot(ha.sts, type = observed ~ unit, labels = TRUE) } \keyword{datasets} surveillance/man/addFormattedXAxis.Rd0000644000176200001440000000637413234140561017374 0ustar liggesusers\encoding{latin1} \name{addFormattedXAxis} \alias{addFormattedXAxis} % helper functions for time axis formatting \alias{atChange} \alias{at2ndChange} \alias{atMedian} \title{ Formatted Time Axis for \code{"sts"} Objects } \description{ Add a nicely formatted x-axis to time series plots related to the \code{"\linkS4class{sts}"} class. This utility function is, e.g., used by \code{\link{stsplot_time1}} and \code{\link{plotHHH4_fitted1}}. } \usage{ addFormattedXAxis(x, epochsAsDate = FALSE, xaxis.tickFreq = list("\%Q"=atChange), xaxis.labelFreq = xaxis.tickFreq, xaxis.labelFormat = "\%G\n\n\%OQ", ...) } \arguments{ \item{x}{ an object of class \code{"\linkS4class{sts}"}. } \item{epochsAsDate}{ a logical indicating if the old (\code{FALSE}) or the new (\code{TRUE}) and more flexible implementation should be used. The \code{xaxis.*} arguments are only relevant for the new implementation \code{epochsAsDate = TRUE}. } \item{xaxis.labelFormat,xaxis.tickFreq,xaxis.labelFreq}{ see the details below. } \item{\dots}{ further arguments passed to \code{\link{axis}}. } } \details{ The setting \code{epochsAsDate = TRUE} enables very flexible formatting of the x-axis and its annotations using the \code{xaxis.tickFreq}, \code{xaxis.labelFreq} and \code{xaxis.labelFormat} arguments. The first two are named lists containing pairs with the \emph{name} being a \code{\link{strftime}} single conversion specification and the second part is a function which based on this conversion returns a subset of the rows in the \code{sts} objects. The subsetting function has the following header: \code{function(x,xm1)}, where \code{x} is a vector containing the result of applying the conversion in \code{name} to the epochs of the \code{sts} object and \code{xm1} is the scalar result when applying the conversion to the natural element just before the first epoch. Please note that the input to the subsetting function is converted using \code{as.numeric} before calling the function. Hence, the conversion specification needs to result in a string convertible to integer. Three predefined subsetting functions exist: \code{atChange}, \code{at2ndChange} and \code{atMedian}, which are used to make a tick at each (each 2nd for \code{at2ndChange}) change and at the median index computed on all having the same value, respectively: \preformatted{ atChange <- function(x,xm1) which(diff(c(xm1,x)) != 0) at2ndChange <- function(x,xm1) which(diff(c(xm1,x) \%/\% 2) != 0) atMedian <- function(x,xm1) tapply(seq_along(x), INDEX=x, quantile, prob=0.5, type=3) } By defining own functions here, one can obtain an arbitrary degree of flexibility. Finally, \code{xaxis.labelFormat} is a \code{\link{strftime}} compatible formatting string., e.g. the default value is \code{"\%G\\n\\n\%OQ"}, which means ISO year and quarter (in roman letters) stacked on top of each other. } \value{ \code{NULL} (invisibly). The function is called for its side effects. } \author{ Michael H\enc{}{oe}hle with contributions by Sebastian Meyer } \seealso{ the examples in \code{\link{stsplot_time1}} and \code{\link{plotHHH4_fitted1}} } \keyword{aplot} surveillance/man/twinstim_simulation.Rd0000644000176200001440000004633014615127323020144 0ustar liggesusers\encoding{latin1} \name{twinstim_simulation} \alias{simEpidataCS} \alias{simulate.twinstim} \title{ Simulation of a Self-Exciting Spatio-Temporal Point Process } \description{ The function \code{simEpidataCS} simulates events of a self-exciting spatio-temporal point process of the \code{"\link{twinstim}"} class. Simulation works via Ogata's modified thinning of the conditional intensity as described in Meyer et al. (2012). Note that simulation is limited to the spatial and temporal range of \code{stgrid}. The \code{\link{simulate}} method for objects of class \code{"\link{twinstim}"} simulates new epidemic data using the model and the parameter estimates of the fitted object. } \usage{ simEpidataCS(endemic, epidemic, siaf, tiaf, qmatrix, rmarks, events, stgrid, tiles, beta0, beta, gamma, siafpars, tiafpars, epilink = "log", t0 = stgrid$start[1], T = tail(stgrid$stop,1), nEvents = 1e5, control.siaf = list(F=list(), Deriv=list()), W = NULL, trace = 5, nCircle2Poly = 32, gmax = NULL, .allocate = 500, .skipChecks = FALSE, .onlyEvents = FALSE) \method{simulate}{twinstim}(object, nsim = 1, seed = NULL, data, tiles, newcoef = NULL, rmarks = NULL, t0 = NULL, T = NULL, nEvents = 1e5, control.siaf = object$control.siaf, W = data$W, trace = FALSE, nCircle2Poly = NULL, gmax = NULL, .allocate = 500, simplify = TRUE, ...) } \arguments{ \item{endemic}{ see \code{\link{twinstim}}. Note that type-specific endemic intercepts are specified by \code{beta0} here, not by the term \code{(1|type)}. } \item{epidemic}{ see \code{\link{twinstim}}. Marks appearing in this formula must be returned by the generating function \code{rmarks}. } \item{siaf}{ see \code{\link{twinstim}}. In addition to what is required for fitting with \code{twinstim}, the \code{siaf} specification must also contain the element \code{simulate}, a function which draws random locations following the spatial kernel \code{siaf$f}. The first argument of the function is the number of points to sample (say \code{n}), the second one is the vector of parameters \code{siafpars}, the third one is the type indicator (a character string matching a type name as specified by \code{dimnames(qmatrix)}). With the current implementation there will always be simulated only one location at a time, i.e. \code{n=1}. The \link[=siaf.constant]{predefined siaf's} all provide simulation. } \item{tiaf}{ e.g. what is returned by the generating function \code{\link{tiaf.constant}} or \code{\link{tiaf.exponential}}. See also \code{\link{twinstim}}. } \item{qmatrix}{ see \code{\link{epidataCS}}. Note that this square matrix and its \code{dimnames} determine the number and names of the different event types. In the simplest case, there is only a single type of event, i.e. \code{qmatrix = diag(1)}. } \item{rmarks}{ function of single time (1st argument) and location (2nd argument) returning a one-row \code{data.frame} of marks (named according to the variables in \code{epidemic}) for an event at this point. This must include the columns \code{eps.s} and \code{eps.t}, i.e. the values of the spatial and temporal interaction ranges at this point. Only \code{"numeric"} and \code{"factor"} columns are allowed. Assure that factor variables are coded equally (same levels and level order) for each new sample. For the \code{simulate.twinstim} method, the default (\code{NULL}) means sampling from the empirical distribution function of the (non-missing) marks in \code{data} restricted to events in the simulation period (\code{t0};\code{T}]. If there are no events in this period, e.g., if simulating beyond the original observation period, \code{rmarks} will sample marks from all of \code{data$events}. } \item{events}{ \code{NULL} or missing (default) in case of an empty prehistory, or a \code{\link[sp]{SpatialPointsDataFrame}} containing events of the prehistory (-Inf;\code{t0}] of the process (required for the epidemic to start in case of no endemic component in the model). The \code{SpatialPointsDataFrame} must have the same \code{proj4string} as \code{tiles} and \code{W}). The attached \code{data.frame} (data slot) must contain the typical columns as described in \code{\link{as.epidataCS}} (\code{time}, \code{tile}, \code{eps.t}, \code{eps.s}, and, for type-specific models, \code{type}) and all marks appearing in the \code{epidemic} specification. Note that some column names are reserved (see \code{\link{as.epidataCS}}). Only events up to time \code{t0} are selected and taken as the prehistory. } \item{stgrid}{ see \code{\link{as.epidataCS}}. Simulation only works inside the spatial and temporal range of \code{stgrid}. } \item{tiles}{ object inheriting from \code{"\linkSPclass{SpatialPolygons}"} with \code{row.names} matching the \code{tile} names in \code{stgrid} and having the same \code{proj4string} as \code{events} and \code{W}. This is necessary to sample the spatial location of events generated by the endemic component. } \item{beta0,beta,gamma,siafpars,tiafpars}{ these are the parameter subvectors of the \code{twinstim}. \code{beta} and \code{gamma} must be given in the same order as they appear in \code{endemic} and \code{epidemic}, respectively. \code{beta0} is either a single endemic intercept or a vector of type-specific endemic intercepts in the same order as in \code{qmatrix}. } \item{epilink}{ a character string determining the link function to be used for the \code{epidemic} linear predictor of event marks. By default, the log-link is used. The experimental alternative is \code{epilink = "identity"}. Note that the identity link does not guarantee the force of infection to be positive. If this leads to a negative total intensity (endemic + epidemic), the point process is not well defined and simulation cannot proceed. } \item{t0}{ \code{events} having occurred during (-Inf;\code{t0}] are regarded as part of the prehistory \eqn{H_0} of the process. For \code{simEpidataCS}, by default and also if \code{t0=NULL}, the beginning of \code{stgrid} is used as \code{t0}. For the \code{simulate.twinstim} method, \code{NULL} means to use the fitted time range of the \code{"twinstim"} \code{object}. } \item{T, nEvents}{ simulate a maximum of \code{nEvents} events up to time \code{T}, then stop. For \code{simEpidataCS}, by default, and also if \code{T=NULL}, \code{T} equals the last stop time in \code{stgrid} (it cannot be greater) and \code{nEvents} is bounded above by 10000. For the \code{simulate.twinstim} method, \code{T=NULL} means to use the same same time range as for the fitting of the \code{"twinstim"} \code{object}. } \item{W}{ see \code{\link{as.epidataCS}}. When simulating from \code{twinstim}-fits, \code{W} is by default taken from the original \code{data$W}. If specified as \code{NULL}, \code{W} is generated automatically via \code{\link{unionSpatialPolygons}(tiles)}. However, since the result of such a polygon operation should always be verified, it is recommended to do that in advance.\cr It is important that \code{W} and \code{tiles} cover the same region: on the one hand direct offspring is sampled in the spatial influence region of the parent event, i.e., in the intersection of \code{W} and a circle of radius the \code{eps.s} of the parent event, after which the corresponding tile is determined by overlay with \code{tiles}. On the other hand endemic events are sampled from \code{tiles}. } \item{trace}{ logical (or integer) indicating if (or how often) the current simulation status should be \code{cat}ed. For the \code{simulate.twinstim} method, \code{trace} currently only applies to the first of the \code{nsim} simulations. } \item{.allocate}{ number of rows (events) to initially allocate for the event history; defaults to 500. Each time the simulated epidemic exceeds the allocated space, the event \code{data.frame} will be enlarged by \code{.allocate} rows. } \item{.skipChecks,.onlyEvents}{ these logical arguments are not meant to be set by the user. They are used by the \code{simulate}-method for \code{"twinstim"} objects. } \item{object}{ an object of class \code{"\link{twinstim}"}. } \item{nsim}{ number of epidemics (i.e. spatio-temporal point patterns inheriting from class \code{"epidataCS"}) to simulate. Defaults to 1 when the result is a simple object inheriting from class \code{"simEpidataCS"} (as if \code{simEpidataCS} would have been called directly). If \code{nsim > 1}, the result will be a list the structure of which depends on the argument \code{simplify}. } \item{seed}{ an object specifying how the random number generator should be initialized for simulation (via \code{\link{set.seed}}). The initial state will also be stored as an attribute \code{"seed"} of the result. The original state of the \code{\link{.Random.seed}} will be restored at the end of the simulation. By default (\code{NULL}), neither initialization nor recovery will be done. This behaviour is copied from the \code{\link{simulate}.lm} method. } \item{data}{ an object of class \code{"epidataCS"}, usually the one to which the \code{"twinstim"} \code{object} was fitted. It carries the \code{stgrid} of the endemic component, but also \code{events} for use as the prehistory, and defaults for \code{rmarks} and \code{nCircle2Poly}. } \item{newcoef}{ an optional named numeric vector of (a subset of) parameters to replace the original point estimates in \code{coef(object)}. Elements which do not match any model parameter by name are silently ignored. The \code{newcoef}s may also be supplied in a list following the same conventions as for the \code{start} argument in \code{\link{twinstim}}. } \item{simplify}{ logical. It is strongly recommended to set \code{simplify = TRUE} (default) if \code{nsim} is large. This saves space and computation time, because for each simulated epidemic only the \code{events} component is saved. All other components, which do not vary between simulations, are only stored from the first run. In this case, the runtime of each simulation is stored as an attribute \code{"runtime"} to each simulated \code{events}. See also the \dQuote{Value} section below. } \item{control.siaf}{see \code{\link{twinstim}}.} \item{nCircle2Poly}{see \code{\link{as.epidataCS}}. For \code{simulate.twinstim}, \code{NULL} means to use the same value as for \code{data}.} \item{gmax}{ maximum value the temporal interaction function \code{tiaf$g} can attain. If \code{NULL}, then it is assumed as the maximum value of the type-specific values at 0, i.e. \code{max(tiaf$g(rep.int(0,nTypes), tiafpars, 1:nTypes))}. } \item{\dots}{unused (arguments of the generic).} } \value{ The function \code{simEpidataCS} returns a simulated epidemic of class \code{"simEpidataCS"}, which enhances the class \code{"epidataCS"} by the following additional components known from objects of class \code{"\link{twinstim}"}: \code{bbox}, \code{timeRange}, \code{formula}, \code{coefficients}, \code{npars}, \code{control.siaf}, \code{call}, \code{runtime}. It has corresponding \code{\link{coeflist}}, \code{\link[=residuals.simEpidataCS]{residuals}}, \code{\link[=R0.simEpidataCS]{R0}}, and \code{\link[=intensityplot.simEpidataCS]{intensityplot}} methods. The \code{simulate.twinstim} method has some additional \emph{attributes} set on its result: \code{call}, \code{seed}, and \code{runtime}. If \code{nsim > 1}, it returns an object of class \code{"simEpidataCSlist"}, the form of which depends on the value of \code{simplify} (which is stored as an attribute \code{simplified}): if \code{simplify = FALSE}, then the return value is just a list of sequential simulations, each of class \code{"simEpidataCS"}. However, if \code{simplify = TRUE}, then the sequential simulations share all components but the simulated \code{events}, i.e. the result is a list with the same components as a single object of class \code{"simEpidataCS"}, but with \code{events} replaced by an \code{eventsList} containing the \code{events} returned by each of the simulations. The \code{stgrid} component of the returned \code{"simEpidataCS"} will be truncated to the actual end of the simulation, which might be \eqn{ 1}) may have different \code{stgrid} time ranges. In a \code{"simEpidataCSlist"}, the \code{stgrid} shared by all of the simulated epidemics is just the \code{stgrid} returned by the \emph{first} simulation. } \note{ The more detailed the polygons in \code{tiles} are the slower is the algorithm. You are advised to sacrifice some shape details for speed by reducing the polygon complexity, for example via the \command{mapshaper} JavaScript library wrapped by the R package \CRANpkg{rmapshaper}, or via \code{\link[spatstat.geom]{simplify.owin}}. } \references{ Douglas, D. H. and Peucker, T. K. (1973): Algorithms for the reduction of the number of points required to represent a digitized line or its caricature. \emph{Cartographica: The International Journal for Geographic Information and Geovisualization}, \bold{10}, 112-122 Meyer, S., Elias, J. and H\enc{}{oe}hle, M. (2012): A space-time conditional intensity model for invasive meningococcal disease occurrence. \emph{Biometrics}, \bold{68}, 607-616. \doi{10.1111/j.1541-0420.2011.01684.x} } \author{ Sebastian Meyer, with contributions by Michael H\enc{}{oe}hle } \seealso{ The function \code{\link{simEndemicEvents}} is a faster alternative for endemic-only models, only returning a \code{"\linkSPclass{SpatialPointsDataFrame}"} of simulated events. The \code{\link{plot.epidataCS}} and \code{\link{animate.epidataCS}} methods for plotting and animating continuous-space epidemic data, respectively, also work for simulated epidemics (by inheritance), and \code{\link{twinstim}} can be used to fit spatio-temporal conditional intensity models also to simulated data. } \examples{ data("imdepi", "imdepifit") ## load borders of Germany's districts (originally obtained from ## the German Federal Agency for Cartography and Geodesy, ## https://gdz.bkg.bund.de/), simplified by the "modified Visvalingam" ## algorithm (level=6.6\%) using MapShaper.org (v. 0.1.17): load(system.file("shapes", "districtsD.RData", package="surveillance")) \dontshow{if (surveillance.options("allExamples")) \{} plot(districtsD) plot(stateD, add=TRUE, border=2, lwd=2) \dontshow{\}} ## simulate 2 realizations (over a short period, for speed) ## considering events from data(imdepi) before t=31 as prehistory \dontshow{## IGNORE_RDIFF_BEGIN} mysims <- simulate(imdepifit, nsim=2, seed=1, data=imdepi, tiles=districtsD, newcoef=c("e.typeC"=-1), t0=31, T=if (interactive()) 180 else 45, # for CRAN simplify=TRUE) \dontshow{## IGNORE_RDIFF_END} \dontshow{ ## check construction and selection from "simEpidataCSlist" local({ mysim_from_list <- mysims[[1]] capture.output(mysim_single <- eval("[[<-"(attr(mysims, "call"), "nsim", 1))) mysim_from_list$runtime <- mysim_single$runtime <- NULL stopifnot(all.equal(mysim_single, mysim_from_list, check.attributes = FALSE)) }) ## check equivalence of Lambdag from simulation and residuals via twinstim stopifnot(all.equal( residuals(mysims[[1]]), suppressMessages(surveillance:::residuals.twinstim(surveillance:::as.twinstim.simEpidataCS(mysims[[1]]))) )) } ## plot both simulations using the plot-method for simEpidataCSlist's mysims plot(mysims, aggregate="time") ## extract the second realization -> object of class simEpidataCS mysim2 <- mysims[[2]] summary(mysim2) plot(mysim2, aggregate="space") \dontshow{if (surveillance.options("allExamples")) \{} ### compare the observed _cumulative_ number of cases during the ### first 90 days to 20 simulations from the fitted model sims <- simulate(imdepifit, nsim=20, seed=1, data=imdepi, t0=0, T=90, tiles=districtsD, simplify=TRUE) ## extract cusums getcsums <- function (events) { tapply(events$time, events@data["type"], function (t) cumsum(table(t)), simplify=FALSE) } csums_observed <- getcsums(imdepi$events) csums_simulated <- lapply(sims$eventsList, getcsums) ## plot it plotcsums <- function (csums, ...) { mapply(function (csum, ...) lines(as.numeric(names(csum)), csum, ...), csums, ...) invisible() } plot(c(0,90), c(0,35), type="n", xlab="Time [days]", ylab="Cumulative number of cases") plotcsums(csums_observed, col=c(2,4), lwd=3) legend("topleft", legend=levels(imdepi$events$type), col=c(2,4), lwd=1) invisible(lapply(csums_simulated, plotcsums, col=adjustcolor(c(2,4), alpha=0.5))) \dontshow{\}} \dontrun{ ### Experimental code to generate 'nsim' simulations of 'nm2add' months ### beyond the observed time period: nm2add <- 24 nsim <- 5 ### The events still infective by the end of imdepi$stgrid will be used ### as the prehistory for the continued process. origT <- tail(imdepi$stgrid$stop, 1) ## extend the 'stgrid' by replicating the last block 'nm2add' times ## (i.e., holding "popdensity" constant) stgridext <- local({ gLast <- subset(imdepi$stgrid, BLOCK == max(BLOCK)) gAdd <- gLast[rep(1:nrow(gLast), nm2add),]; rownames(gAdd) <- NULL newstart <- seq(origT, by=30, length.out=nm2add) newstop <- c(newstart[-1], max(newstart) + 30) gAdd$start <- rep(newstart, each=nlevels(gAdd$tile)) gAdd$stop <- rep(newstop, each=nlevels(gAdd$tile)) rbind(imdepi$stgrid, gAdd, make.row.names = FALSE)[,-1] }) ## create an updated "epidataCS" with the time-extended 'stgrid' imdepiext <- update(imdepi, stgrid = stgridext) newT <- tail(imdepiext$stgrid$stop, 1) ## simulate beyond the original period simsext <- simulate(imdepifit, nsim=nsim, seed=1, t0=origT, T=newT, data=imdepiext, tiles=districtsD, simplify=TRUE) ## Aside to understand the note from checking events and tiles: # marks(imdepi)["636",] # tile 09662 is attributed to this event, but: # plot(districtsD[c("09678","09662"),], border=1:2, lwd=2, axes=TRUE) # points(imdepi$events["636",]) ## this mismatch is due to polygon simplification ## plot the observed and simulated event numbers over time plot(imdepiext, breaks=c(unique(imdepi$stgrid$start),origT), cumulative=list(maxat=330)) for (i in seq_along(simsext$eventsList)) plot(simsext[[i]], add=TRUE, legend.types=FALSE, breaks=c(unique(simsext$stgrid$start),newT), subset=!is.na(source), # have to exclude the events of the prehistory cumulative=list(offset=c(table(imdepi$events$type)), maxat=330, axis=FALSE), border=NA, density=0) # no histogram abline(v=origT, lty=2, lwd=2) } } \keyword{datagen} \keyword{models} surveillance/man/print.algoQV.Rd0000644000176200001440000000136313122471774016347 0ustar liggesusers\name{print.algoQV} \alias{print.algoQV} \title{Print Quality Value Object} \description{Print a single quality value object in a nicely formatted way} \usage{ \method{print}{algoQV}(x,...) } \arguments{ \item{x}{Quality Values object generated with \code{quality}} \item{...}{Further arguments (not really used)} } \examples{ # Create a test object disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 200, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) # Let this object be tested from rki1 survResObj <- algo.rki1(disProgObj, control = list(range = 50:200)) # Compute the quality values in a nice formatted way algo.quality(survResObj) } \keyword{print} surveillance/man/stsSlots.Rd0000644000176200001440000000126013507347337015661 0ustar liggesusers\name{stsSlot-generics} \docType{methods} \alias{alarms} \alias{alarms<-} \alias{upperbound} \alias{upperbound<-} \alias{control} \alias{control<-} \alias{epoch} \alias{epoch<-} \alias{observed} \alias{observed<-} \alias{population} \alias{population<-} \alias{multinomialTS} \alias{multinomialTS<-} \alias{neighbourhood} \alias{neighbourhood<-} \title{Generic Functions to Access \code{"sts"} Slots} \description{ For almost every slot of the \code{"sts"} class, package \pkg{surveillance} defines a generic function of the same name (and a replacement version) to extract (or set) the corresponding slot. See the \code{"\linkS4class{sts}"} class documentation. } \keyword{methods} surveillance/man/twinSIR_methods.Rd0000644000176200001440000001541713433460451017105 0ustar liggesusers\encoding{latin1} \name{twinSIR_methods} \alias{print.twinSIR} \alias{summary.twinSIR} \alias{AIC.twinSIR} \alias{extractAIC.twinSIR} \alias{vcov.twinSIR} \alias{logLik.twinSIR} \alias{print.summary.twinSIR} \title{ Print, Summary and Extraction Methods for \code{"twinSIR"} Objects } \description{ Besides \code{print} and \code{summary} methods there are also some standard extraction methods defined for objects of class \code{"twinSIR"}: \code{vcov}, \code{logLik} and especially \code{AIC} and \code{extractAIC}, which extract Akaike's Information Criterion. Note that special care is needed, when fitting models with parameter constraints such as the epidemic effects \eqn{\alpha} in \code{twinSIR} models. Parameter constraints reduce the average increase in the maximized loglikelihood - thus the penalty for constrained parameters should be smaller than the factor 2 used in the ordinary definition of AIC. To this end, these two methods offer the calculation of the so-called one-sided AIC (OSAIC). } \usage{ \method{print}{twinSIR}(x, digits = max(3, getOption("digits") - 3), ...) \method{summary}{twinSIR}(object, correlation = FALSE, symbolic.cor = FALSE, ...) \method{AIC}{twinSIR}(object, ..., k = 2, one.sided = NULL, nsim = 1e3) \method{extractAIC}{twinSIR}(fit, scale = 0, k = 2, one.sided = NULL, nsim = 1e3, ...) \method{vcov}{twinSIR}(object, ...) \method{logLik}{twinSIR}(object, ...) \method{print}{summary.twinSIR}(x, digits = max(3, getOption("digits") - 3), symbolic.cor = x$symbolic.cor, signif.stars = getOption("show.signif.stars"), ...) } \arguments{ \item{x, object, fit}{an object of class \code{"twinSIR"}.\cr For the \code{print} method of the \code{summary} method, an object of class \code{"summary.twinSIR"}.} \item{digits}{ integer, used for number formatting with \code{signif()}. Minimum number of significant digits to be printed in values. } \item{correlation}{ logical. if \code{TRUE}, the correlation matrix of the estimated parameters is returned and printed. } \item{symbolic.cor}{ logical. If \code{TRUE}, print the correlations in a symbolic form (see \code{symnum}) rather than as numbers. } \item{\dots}{ For the \code{summary} method: arguments passed to \code{\link{extractAIC.twinSIR}}.\cr For the \code{AIC} method, optionally more fitted model objects.\cr For the \code{print}, \code{extractAIC}, \code{vcov} and \code{logLik} methods: unused (argument of the generic). } \item{k}{ numeric specifying the "weight" of the \emph{penalty} to be used; in an unconstrained fit \code{k = 2} is the classical AIC. } \item{one.sided}{ logical or \code{NULL} (the default). Determines if the one-sided AIC should be calculated instead of using the classical penalty \code{k*edf}. The default value \code{NULL} chooses classical AIC in the case of an unconstrained fit and one-sided AIC in the case of constraints. The type of the fit can be seen in \code{object$method} (or \code{fit$method} respectively), where \code{"L-BFGS"} means constrained optimization. } \item{nsim}{ when there are more than two epidemic covariates in the fit, the weights in the OSAIC formula have to be determined by simulation. Default is to use 1000 samples. Note that package \pkg{quadprog} is additionally required in this case. } \item{scale}{unused (argument of the generic).} \item{signif.stars}{logical. If \code{TRUE}, \dQuote{significance stars} are printed for each coefficient.} } \details{ The \code{print} and \code{summary} methods allow the compact or comprehensive representation of the fitting results, respectively. The former only prints the original function call, the estimated coefficients and the maximum log-likelihood value. The latter prints the whole coefficient matrix with standard errors, z- and p-values (see \code{\link{printCoefmat}}), and additionally the number of infections per log-baseline \code{interval}, the (one-sided) AIC and the number of log-likelihood evaluations. They both append a big \dQuote{WARNING}, if the optimization algorithm did not converge. The estimated coefficients may be extracted by using the default \code{coef}-method from package \pkg{stats}. The two AIC functions differ only in that \code{AIC} can take more than one fitted model object and that \code{extractAIC} always returns the number of parameters in the model (\code{AIC} only does with more than one fitted model object). Concerning the choice of one-sided AIC: parameter constraints -- such as the non-negative constraints for the epidemic effects alpha in \code{twinSIR} models -- reduce the average increase in the maximized loglikelihood. Thus, the penalty for constrained parameters should be smaller than the factor 2 used in the ordinary definition of AIC. One-sided AIC (OSAIC) suggested by Hughes and King (2003) is such a proposal when \eqn{p} out of \eqn{k = p + q} parameters have non-negative constraints: \deqn{OSAIC = -2 l(\theta, \tau) + 2 \sum_{g=0}^p w(p,g) (k-p+g)}{% OSAIC = -2 l(theta, tau) + 2 sum_{g=0}^p w(p,g) (k-p+g)} where \eqn{w(p,g)} are \eqn{p}-specific weights. For more details see Section 5.2 in \enc{Hhle}{Hoehle} (2009). } \value{ The \code{print} methods return their first argument, invisibly, as they always should. The \code{vcov} and \code{logLik} methods return the estimated variance-covariance matrix of the parameters (here, the inverse of the estimate of the expected Fisher information matrix), and the maximum log-likelihood value of the model, respectively. The \code{summary} method returns a list containing some summary statistics of the fitted model, which is nicely printed by the corresponding \code{print} method. For the \code{\link{AIC}} and \code{\link{extractAIC}} methods, see the documentation of the corresponding generic functions. } \references{ Hughes A, King M (2003) Model selection using AIC in the presence of one-sided information. \emph{Journal of Statistical Planning and Inference} \strong{115}, pp. 397--411. \enc{Hhle}{Hoehle}, M. (2009), Additive-Multiplicative Regression Models for Spatio-Temporal Epidemics, Biometrical Journal, 51(6):961-978. } \author{ Michael \enc{Hhle}{Hoehle} and Sebastian Meyer } \examples{ data("hagelloch") # a simplistic twinSIR model fit <- twinSIR(~ household + cox(AGE), data = hagelloch) coef(fit) vcov(fit) logLik(fit) summary(fit, correlation = TRUE, symbolic.cor = TRUE) # AIC or OSAIC AIC(fit) AIC(fit, one.sided = FALSE) extractAIC(fit) extractAIC(fit, one.sided = FALSE) # comparing models via AIC fit2 <- update(fit, nIntervals = 2) AIC(fit, fit2) # the 2nd column should be named "OSAIC" here } \keyword{methods} \keyword{print} \keyword{htest} surveillance/man/formatPval.Rd0000644000176200001440000000152712536544321016135 0ustar liggesusers\name{formatPval} \alias{formatPval} \title{ Pretty p-Value Formatting } \description{ Just \acronym{yapf} -- yet another p-value formatter... It is a wrapper around \code{\link{format.pval}}, such that by default \code{eps = 1e-4}, \code{scientific = FALSE}, \code{digits = if (p<10*eps) 1 else 2}, and \code{nsmall = 2}. } \usage{ formatPval(pv, eps = 1e-4, scientific = FALSE, ...) } \arguments{ \item{pv}{a numeric vector (of p-values).} \item{eps}{a numerical tolerance, see \code{\link{format.pval}}.} \item{scientific}{see \code{\link{format}}.} \item{\dots}{further arguments passed to \code{\link{format.pval}} (but \code{digits} and \code{nsmall} are hard-coded internally).} } \value{ The character vector of formatted p-values. } \examples{ formatPval(c(0.9, 0.13567, 0.0432, 0.000546, 1e-8)) } \keyword{print} surveillance/man/algo.hmm.Rd0000644000176200001440000001577514431140532015526 0ustar liggesusers\encoding{latin1} \name{algo.hmm} \alias{algo.hmm} \title{Hidden Markov Model (HMM) method} \description{ This function implements on-line HMM detection of outbreaks based on the retrospective procedure described in Le Strat and Carret (1999). Using the function \code{\link[msm]{msm}} (from package \pkg{msm}) a specified HMM is estimated, the decoding problem, i.e. the most probable state configuration, is found by the Viterbi algorithm and the most probable state of the last observation is recorded. On-line detection is performed by sequentially repeating this procedure. Warning: This function can be very slow - a more efficient implementation would be nice! } \usage{ algo.hmm(disProgObj, control = list(range=range, Mtilde=-1, noStates=2, trend=TRUE, noHarmonics=1, covEffectEqual=FALSE, saveHMMs = FALSE, extraMSMargs=list())) } \arguments{ \item{disProgObj}{object of class disProg (including the observed and the state chain)} \item{control}{control object: \describe{ \item{\code{range}}{determines the desired time points which should be evaluated. Note that opposite to other surveillance methods an initial parameter estimation occurs in the HMM. Note that range should be high enough to allow for enough reference values for estimating the HMM} \item{\code{Mtilde}}{number of observations back in time to use for fitting the HMM (including the current observation). Reasonable values are a multiple of \code{disProgObj$freq}, the default is \code{Mtilde=-1}, which means to use all possible values - for long series this might take very long time!} \item{\code{noStates}}{number of hidden states in the HMM -- the typical choice is 2. The initial rates are set such that the \code{noStates}th state is the one having the highest rate. In other words: this state is considered the outbreak state.} \item{\code{trend}}{Boolean stating whether a linear time trend exists, i.e. if \code{TRUE} (default) then \eqn{\beta_j \neq 0}{\beta != 0}} \item{\code{noHarmonics}}{number of harmonic waves to include in the linear predictor. Default is 1.} \item{\code{covEffectEqual}}{see details} \item{\code{saveHMMs}}{Boolean, if \code{TRUE} then the fitted HMMs are saved. With this option the function can also be used to analyse data retrospectively. Default option is \code{FALSE}} \item{\code{extraMSMArgs}}{A named list with additional arguments to send to the \code{\link[msm:msm]{msm}} HMM fitting function. Note that the \code{msm} arguments \code{formula}, \code{data}, \code{qmatrix}, \code{hmodel}, \code{hcovariates} and \code{hconstraint} are automatically filled by \code{algo.hmm}, thus these should NOT be modified.} } } } \value{ \code{algo.hmm} gives a list of class \code{survRes} which includes the vector of alarm values for every timepoint in \code{range}. No \code{upperbound} can be specified and is put equal to zero. The resulting object contains a list \code{control$hmms}, which contains the \code{"msm"} objects with the fitted HMMs (if \code{saveHMMs=TRUE}). } \details{ For each time point t the reference values values are extracted. If the number of requested values is larger than the number of possible values the latter is used. Now the following happens on these reference values: A \code{noStates}-State Hidden Markov Model (HMM) is used based on the Poisson distribution with linear predictor on the log-link scale. I.e. \deqn{Y_t | X_t = j \sim Po(\mu_t^j),}{Y_t|X_t = j ~ Po(\mu_t^j),} where \deqn{\log(\mu_t^j) = \alpha_j + \beta_j\cdot t + \sum_{i=1}^{nH} \gamma_j^i \cos(2i\pi/freq\cdot (t-1)) + \delta_j^i \sin(2i\pi/freq\cdot (t-1))}{% log(mu_t^j) = alpha_j + beta_j t + \sum_{i=1}^{nH} gamma_j^i \cos(2*i*pi/freq * (t-1)) + delta_j^i sin(2*i*pi/freq * (t-1)) } and \eqn{nH=}\code{noHarmonics} and \eqn{freq=12,52} depending on the sampling frequency of the surveillance data. In the above \eqn{t-1} is used, because the first week is always saved as \code{t=1}, i.e. we want to ensure that the first observation corresponds to cos(0) and sin(0). If \code{covEffectEqual} then all covariate effects parameters are equal for the states, i.e. \eqn{\beta_j=\beta, \gamma_j^i=\gamma^i, \delta_j^i=\delta^i} for all \eqn{j=1,...,\code{noStates}}. In case more complicated HMM models are to be fitted it is possible to modify the \code{msm} code used in this function. Using e.g. \code{AIC} one can select between different models (see the \pkg{msm} package for further details). Using the Viterbi algorithms the most probable state configuration is obtained for the reference values and if the most probable configuration for the last reference value (i.e. time t) equals \code{control$noOfStates} then an alarm is given. Note: The HMM is re-fitted from scratch every time, sequential updating schemes of the HMM would increase speed considerably! A major advantage of the approach is that outbreaks in the reference values are handled automatically. } \seealso{\code{\link[msm:msm]{msm}}} \author{M. \enc{Hhle}{Hoehle}} \examples{ #Simulate outbreak data from HMM set.seed(123) counts <- sim.pointSource(p = 0.98, r = 0.8, length = 3*52, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.5) \dontrun{ #Do surveillance using a two state HMM without trend component and #the effect of the harmonics being the same in both states. A sliding #window of two years is used to fit the HMM surv <- algo.hmm(counts, control=list(range=(2*52):length(counts$observed), Mtilde=2*52,noStates=2,trend=FALSE, covEffectsEqual=TRUE,extraMSMargs=list())) plot(surv,legend.opts=list(x="topright")) } if (require("msm")) { #Retrospective use of the function, i.e. monitor only the last time point #but use option saveHMMs to store the output of the HMM fitting surv <- algo.hmm(counts,control=list(range=length(counts$observed),Mtilde=-1,noStates=2, trend=FALSE,covEffectsEqual=TRUE, saveHMMs=TRUE)) #Compute most probable state using the viterbi algorithm - 1 is "normal", 2 is "outbreak". viterbi.msm(surv$control$hmms[[1]])$fitted #How often correct? tab <- cbind(truth=counts$state + 1 , hmm=viterbi.msm(surv$control$hmm[[1]])$fitted) table(tab[,1],tab[,2]) } } \references{ Y. Le Strat and F. Carrat, Monitoring Epidemiologic Surveillance Data using Hidden Markov Models (1999), Statistics in Medicine, 18, 3463--3478 I.L. MacDonald and W. Zucchini, Hidden Markov and Other Models for Discrete-valued Time Series, (1997), Chapman & Hall, Monographs on Statistics and applied Probability 70 } \keyword{classif} surveillance/man/hhh4_simulate.Rd0000644000176200001440000001723214152422604016553 0ustar liggesusers\name{hhh4_simulate} \alias{simulate.hhh4} \title{Simulate \code{"hhh4"} Count Time Series} \description{ Simulates a multivariate time series of counts based on the Poisson/Negative Binomial model as described in Paul and Held (2011). } \usage{ \method{simulate}{hhh4}(object, nsim = 1, seed = NULL, y.start = NULL, subset = 1:nrow(object$stsObj), coefs = coef(object), components = c("ar","ne","end"), simplify = nsim>1, ...) } \arguments{ \item{object}{ an object of class \code{"\link{hhh4}"}. } \item{nsim}{ number of time series to simulate. Defaults to \code{1}. } \item{seed}{ an object specifying how the random number generator should be initialized for simulation (via \code{\link{set.seed}}). The initial state will also be stored as an attribute \code{"seed"} of the result. The original state of the \code{\link{.Random.seed}} will be restored at the end of the simulation. By default (\code{NULL}), neither initialization nor recovery will be done. This behaviour is copied from the \code{\link{simulate}.lm} method. } \item{y.start}{ vector or matrix (with \code{ncol(object$stsObj)} columns) with starting counts for the epidemic components. If \code{NULL}, the observed means in the respective units of the data in \code{object} during \code{subset} are used. } \item{subset}{ time period in which to simulate data. Defaults to (and cannot exceed) the whole period defined by the underlying \code{"sts"} object. } \item{coefs}{ coefficients used for simulation from the model in \code{object}. Default is to use the fitted parameters. Note that the \code{coefs}-vector must be in the same order and scaling as \code{coef(object)}, which especially means \code{reparamPsi = TRUE} (as per default when using the \code{coef}-method to extract the parameters). The overdispersion parameter in \code{coefs} is the inverse of the dispersion parameter \code{size} in \code{\link{rnbinom}}. } \item{components}{ character vector indicating which components of the fitted model \code{object} should be active during simulation. For instance, a simulation with \code{components="end"} is solely based on the fitted endemic mean. } \item{simplify}{ logical indicating if only the simulated counts (\code{TRUE}) or the full \code{"\linkS4class{sts}"} object (\code{FALSE}) should be returned for every replicate. By default a full \code{"sts"} object is returned iff \code{nsim=1}. } \item{\dots}{unused (argument of the generic).} } \details{ Simulates data from a Poisson or a Negative Binomial model with mean \deqn{\mu_{it} = \lambda_{it} y_{i,t-1} + \phi_{it} \sum_{j \neq i} w_{ji} y_{j,t-1} + \nu_{it}}{% \mu_it = \lambda_it y_i,t-1 + \phi_it \sum_j w_ji y_j,t-1 + \nu_it} where \eqn{\lambda_{it}>0}, \eqn{\phi_{it}>0}, and \eqn{\nu_{it}>0} are parameters which are modelled parametrically. The function uses the model and parameter estimates of the fitted \code{object} to simulate the time series. With the argument \code{coefs} it is possible to simulate from the model as specified in \code{object}, but with different parameter values. } \value{ If \code{simplify=FALSE}: an object of class \code{"\linkS4class{sts}"} (\code{nsim = 1}) or a list of those (\code{nsim > 1}). If \code{simplify=TRUE}: an object of class \code{"hhh4sims"}, which is an array of dimension \code{c(length(subset), ncol(object$stsObj), nsim)}. The originally observed counts during the simulation period, \code{object$stsObj[subset,]}, are attached for reference (used by the \code{plot}-methods) as an attribute \code{"stsObserved"}, and the initial condition \code{y.start} as attribute \code{"initial"}. The \code{[}-method for \code{"hhh4sims"} takes care of subsetting these attributes appropriately. } \references{ Paul, M. and Held, L. (2011) Predictive assessment of a non-linear random effects model for multivariate time series of infectious disease counts. Statistics in Medicine, \bold{30}, 1118--1136 } \author{ Michaela Paul and Sebastian Meyer } \seealso{ \code{\link{plot.hhh4sims}} and \code{\link{scores.hhh4sims}} and the examples therein for \code{nsim > 1}. } \examples{ data(influMen) # convert to sts class and extract meningococcal disease time series meningo <- disProg2sts(influMen)[,2] # fit model fit <- hhh4(meningo, control = list( ar = list(f = ~ 1), end = list(f = addSeason2formula(~1, period = 52)), family = "NegBin1")) plot(fit) # simulate from model (generates an "sts" object) simData <- simulate(fit, seed=1234) # plot simulated data plot(simData, main = "simulated data", xaxis.labelFormat=NULL) # use simplify=TRUE to return an array of simulated counts simCounts <- simulate(fit, seed=1234, simplify=TRUE) dim(simCounts) # nTime x nUnit x nsim \dontshow{stopifnot(observed(simData) == c(simCounts))} # plot the first year of simulated counts (+ initial + observed) plot(simCounts[1:52,,], type = "time", xaxis.labelFormat = NULL) # see help(plot.hhh4sims) for other plots, mainly useful for nsim > 1 # simulate from a Poisson instead of a NegBin model # keeping all other parameters fixed at their original estimates coefs <- replace(coef(fit), "overdisp", 0) simData2 <- simulate(fit, seed=123, coefs = coefs) plot(simData2, main = "simulated data: Poisson model", xaxis.labelFormat = NULL) # simulate from a model with higher autoregressive parameter coefs <- replace(coef(fit), "ar.1", log(0.9)) simData3 <- simulate(fit, seed=321, coefs = coefs) plot(simData3, main = "simulated data: lambda = 0.5", xaxis.labelFormat = NULL) ## more sophisticated: simulate beyond initially observed time range # extend data range by one year (non-observed domain), filling with NA values nextend <- 52 timeslots <- c("observed", "state", "alarm", "upperbound", "populationFrac") addrows <- function (mat, n) mat[c(seq_len(nrow(mat)), rep(NA, n)),,drop=FALSE] extended <- Map(function (x) addrows(slot(meningo, x), n = nextend), x = timeslots) # create new sts object with extended matrices meningo2 <- do.call("sts", c(list(start = meningo@start, frequency = meningo@freq, map = meningo@map), extended)) # fit to the observed time range only, via the 'subset' argument fit2 <- hhh4(meningo2, control = list( ar = list(f = ~ 1), end = list(f = addSeason2formula(~1, period = 52)), family = "NegBin1", subset = 2:(nrow(meningo2) - nextend))) # the result is the same as before stopifnot(all.equal(fit, fit2, ignore = c("stsObj", "control"))) \dontshow{ # one-week-ahead prediction only "works" for the first non-observed time point # because the autoregressive component relies on non-missing past counts oneStepAhead(fit2, tp = rep(nrow(meningo2)-nextend, 2), type = "final", verbose = FALSE) # however, methods won't work as observed is NA } # long-term probabilistic forecast via simulation for non-observed time points meningoSim <- simulate(fit2, nsim = 100, seed = 1, subset = seq(nrow(meningo)+1, nrow(meningo2)), y.start = tail(observed(meningo), 1)) apply(meningoSim, 1:2, function (ysim) quantile(ysim, c(0.1, 0.5, 0.9))) # three plot types are available for "hhh4sims", see also ?plot.hhh4sims plot(meningoSim, type = "time", average = median) plot(meningoSim, type = "size", observed = FALSE) if (requireNamespace("fanplot")) plot(meningoSim, type = "fan", means.args = list(), fan.args = list(ln = c(.1,.9), ln.col = 8)) } \keyword{datagen} surveillance/man/stsXtrct.Rd0000644000176200001440000000320213507411066015646 0ustar liggesusers\name{stsXtrct} \docType{methods} \title{Subsetting \code{"sts"} Objects} \alias{[,sts-method} % for convenience \alias{[,sts,ANY,ANY,ANY-method} \description{ The \code{[}-method extracts parts of an \code{"\linkS4class{sts}"} object using row (time) and column (unit) indices. } \usage{ \S4method{[}{sts}(x, i, j, ..., drop) } \arguments{ \item{x}{an object of class \code{"\linkS4class{sts}"}.} \item{i}{row index (integer or logical vector).} \item{j}{column index (character, integer, or logical vector).} \item{\dots,drop}{unused (arguments of the generic).\cr Dimensions are never dropped.} } \value{ an object of class \code{"sts"}. } \details{ Row indices are used to select a subset of the original time period. The \code{start} and \code{epoch} slots of the time series are adjusted accordingly. A warning is issued if an irregular integer sequence is used to extract rows, e.g., \code{x[c(1,2,4),]}, which could destroy the structure of the time series (\code{freq}). Column indices work as usual when indexing matrices, so may select units by name, position or a vector of booleans. When subsetting columns, population fractions are recomputed if and only if \code{x} is no \code{multinomialTS} and already contains population fractions. \code{NA} indices are not supported, negative indices are. Note that a \code{[<-} method (i.e., subassignment) is not implemented. } \examples{ data("ha.sts") haagg <- aggregate(ha.sts, nfreq=13) plot(haagg[, 3]) # Single series plot(haagg[1:30, 3]) # Somewhat shorter #Counts at time 20 plot(haagg[20, ], type = observed ~ unit) } \keyword{methods} surveillance/man/sim.seasonalNoise.Rd0000644000176200001440000000335113122471774017414 0ustar liggesusers\name{sim.seasonalNoise} \alias{sim.seasonalNoise} \encoding{latin1} \title{Generation of Background Noise for Simulated Timeseries} \description{Generation of a cyclic model of a Poisson distribution as background data for a simulated timevector. The mean of the Poisson distribution is modelled as: \deqn{\mu = \exp(A \sin( frequency \cdot \omega \cdot (t + \phi)) + \alpha + \beta * t + K * state)}{% mu = exp(A * sin( frequency * omega * (t + phi)) + alpha + beta * t + K * state)} } \usage{ sim.seasonalNoise(A = 1, alpha = 1, beta = 0, phi = 0, length, frequency = 1, state = NULL, K = 0) } \arguments{ \item{A}{amplitude (range of sinus), default = 1.} \item{alpha}{parameter to move along the y-axis (negative values not allowed) with alpha > = A, default = 1.} \item{beta}{regression coefficient, default = 0.} \item{phi}{factor to create seasonal moves (moves the curve along the x-axis), default = 0.} \item{length}{number of weeks to model.} \item{frequency}{factor to determine the oscillation-frequency, default = 1.} \item{state}{if a state chain is entered the outbreaks will be additional weighted by K.} \item{K}{additional weigth for an outbreak which influences the distribution parameter mu, default = 0.} } \value{ an object of class \code{seasonNoise} which includes the modelled timevector, the parameter \code{mu} and all input parameters. } \seealso{\code{\link{sim.pointSource}}} \author{M. \enc{Hhle}{Hoehle}, A. Riebler, C. Lang} \examples{ season <- sim.seasonalNoise(length = 300) plot(season$seasonalBackground,type = "l") # use a negative timetrend beta season <- sim.seasonalNoise(beta = -0.003, length = 300) plot(season$seasonalBackground,type = "l") } \keyword{datagen} surveillance/man/makeControl.Rd0000644000176200001440000000240614431621542016272 0ustar liggesusers\name{makeControl} \alias{makeControl} \title{Generate \code{control} Settings for an \code{hhh4} Model} \usage{ makeControl(f = list(~1), S = list(0, 0, 1), period = 52, offset = 1, ...) } \arguments{ \item{f, S, period}{ arguments for \code{\link{addSeason2formula}} defining each of the three model formulae in the order (\code{ar}, \code{ne}, \code{end}). Recycled if necessary within \code{\link{mapply}}. } \item{offset}{ multiplicative component offsets in the order (\code{ar}, \code{ne}, \code{end}). } \item{...}{ further elements for the \code{\link{hhh4}} control list. The \code{family} parameter is set to \code{"NegBin1"} by default. } } \value{ a list for use as the \code{control} argument in \code{\link{hhh4}}. } \description{ Generate \code{control} Settings for an \code{hhh4} Model } \examples{ makeControl() ## a simplistic model for the fluBYBW data ## (first-order transmission only, no district-specific intercepts) data("fluBYBW") mycontrol <- makeControl( f = list(~1, ~1, ~t), S = c(1, 1, 3), offset = list(population(fluBYBW)), # recycled -> in all components ne = list(normalize = TRUE), verbose = TRUE) str(mycontrol) \dontshow{if (surveillance.options("allExamples"))} ## fit this model fit <- hhh4(fluBYBW, mycontrol) } surveillance/man/plot.survRes.Rd0000644000176200001440000000264014200437000016426 0ustar liggesusers\name{plot.survRes} \alias{plot.survRes} \title{Plot a \code{survRes} object} \description{ Plotting a (multivariate) \code{survRes} object (soft-deprecated), including the number of infected, the threshold for recognizing an outbreak, the alarm status and the outbreak status. As of \pkg{surveillance} 1.20.0, legacy \code{survRes} objects are plotted via internal \code{\link{disProg2sts}} conversion and \code{\link{stsplot_time}}. } \usage{ \method{plot}{survRes}(x, method = x$control$name, disease = x$control$data, xaxis.years = TRUE, startyear = 2001, firstweek = 1, same.scale = TRUE, ..., main = paste0("Analysis of ", disease, " using ", method)) } \arguments{ \item{x}{object of class \code{survRes}} \item{method}{surveillance method to be used in title} \item{disease}{name of disease in title} \item{xaxis.years}{Boolean indicating whether to show a year-based x-axis} \item{startyear,firstweek}{(legacy arguments, ignored with a warning)} \item{same.scale}{if \code{TRUE} (default), all plots use the same \code{ylim}} \item{\dots}{further arguments passed to \code{\link{stsplot_time}}} \item{main}{the plot title is generated from the \code{method} and \code{disease} arguments if not specified otherwise} } \examples{ data(ha) ctrl <- list(range = 209:290, b = 2, w = 6, alpha = 0.005) plot(algo.bayes(aggregate(ha), control = ctrl)) } \keyword{hplot} \keyword{internal} surveillance/man/epidata_plot.Rd0000644000176200001440000001467513671635730016505 0ustar liggesusers\name{epidata_plot} \alias{plot.epidata} \alias{plot.summary.epidata} \alias{stateplot} \title{ Plotting the Evolution of an Epidemic } \description{ Functions for plotting the evolution of epidemics. The \code{\link{plot}} methods for \code{\link{class}}es \code{"\link{epidata}"} and \code{"summary.epidata"} plots the numbers of susceptible, infectious and recovered (= removed) individuals by step functions along the time axis. The function \code{stateplot} shows individual state changes along the time axis. } \usage{ \method{plot}{summary.epidata}(x, lty = c(2, 1, 3), lwd = 2, col = c("#1B9E77", "#D95F02", "#7570B3"), col.hor = col, col.vert = col, xlab = "Time", ylab = "Number of individuals", xlim = NULL, ylim = NULL, legend.opts = list(), do.axis4 = NULL, panel.first = grid(), rug.opts = list(), which.rug = c("infections", "removals", "susceptibility", "all"), ...) \method{plot}{epidata}(x, ...) stateplot(x, id, ...) } \arguments{ \item{x}{ an object inheriting from class \code{"epidata"} or \code{"summary.epidata"}. In the former case, its summary is calculated and the function continues as in the latter case. The \code{plot} method for class \code{"epidata"} is a simple wrapper for \code{plot.summary.epidata} implemented as \code{plot(summary(x, ...))}. } \item{lty, lwd}{ vectors of length 3 containing the line types and widths, respectively, for the numbers of susceptible, infectious and removed individuals (in this order). By default, all lines have width 1 and the line types are dashed (susceptible), solid (infectious) and dotted (removed), respectively. To omit the drawing of a specific line, just set the corresponding entry in \code{lty} to 0. The vectors are recycled if necessary. For information about the different \code{lty} and \code{lwd} codes, see the help pages of \code{\link{par}}. } \item{col, col.hor, col.vert}{ vectors of length 3 containing the line colors for the numbers of susceptible, infectious and removed individuals (in this order). \code{col.hor} defines the color for the horizontal parts of the step function, whilst \code{col.vert} defines the color for its vertical parts. The argument \code{col} is just short for \code{col.hor = col} and \code{col.vert = col}. The default \code{col} vector corresponds to \code{brewer.pal("Dark2",n=3)} from the \CRANpkg{RColorBrewer} package. The vectors are recycled if necessary. For information about the possible values of \code{col}, see the help pages of \code{\link{par}}. } \item{xlab, ylab}{ axis labels, default to "Time" and "Number of individuals", respectively. } \item{xlim, ylim}{ the x and y limits of the plot in the form \code{c(xmin, xmax)} and \code{c(ymin, ymax)}, respectively. By default, these are chosen adequately to fit the time range of the epidemic and the number of individuals. } \item{legend.opts}{ if this is a list (of arguments for the \code{\link{legend}} function), a legend will be plotted. The defaults are as follows: \describe{ \item{\code{x}:}{\code{"topright"}} \item{\code{inset}:}{\code{c(0,0.02)}} \item{\code{legend}:}{\code{c("susceptible", "infectious", "removed")}} \item{\code{lty},\code{lwd},\code{col}:}{same as the arguments \code{lty}, \code{lwd}, and \code{col.hor} of the main function} \item{\code{bty}:}{\code{"n"}} } } \item{do.axis4}{ logical indicating if the final numbers of susceptible and removed individuals should be indicated on the right axis. The default \code{NULL} means \code{TRUE}, if \code{x} represents a SIR epidemic and \code{FALSE} otherwise, i.e. if the epidemic is SI, SIS or SIRS. } \item{panel.first}{ an expression to be evaluated after the plot axes are set up but before any plotting takes place. By default, a standard grid is drawn. } \item{rug.opts}{ either a list of arguments passed to the function \code{\link{rug}} or \code{NULL} (or \code{NA}), in which case no \code{rug} will be plotted. By default, the argument \code{ticksize} is set to 0.02, \code{col} is set to the color according to \code{which.rug} (black if this is \code{"all"}), and \code{quiet} is set to \code{TRUE}. Note that the argument \code{x}, which contains the locations for the \code{rug} is fixed internally and can not be modified. The argument \code{which.rug} (see below) determines the locations to mark. } \item{which.rug}{ By default, tick marks are drawn at the time points of infections. Alternatively, one can choose to mark only \code{"removals"}, \code{"susceptibilities"} (i.e. state change from R to S) or \code{"all"} events. } \item{id}{ single character string or factor of length 1 specifying the individual for which the \code{stateplot} should be established. } \item{\dots}{ For \code{plot.summary.epidata}: further graphical parameters passed to \code{plot}, \code{lines} and \code{axis}, e.g. \code{main}, \code{las}, \code{cex.axis} (etc.) and \code{mgp}.\cr For \code{plot.epidata}: arguments passed to \code{plot.summary.epidata}.\cr For \code{stateplot}: arguments passed to \code{\link{plot.stepfun}} or \code{\link{plot.function}} (if \code{id} had no events during the observation period). By default, \code{xlab="time"}, \code{ylab="state"}, \code{xlim=attr(x,"timeRange")}, \code{xaxs="i"} and \code{do.points=FALSE}. } } \value{ \code{plot.summary.epidata} (and \code{plot.epidata}) invisibly returns the matrix used for plotting, which contains the evolution of the three counters.\cr \code{stateplot} invisibly returns the function, which was plotted, typically of class \code{"stepfun"}, but maybe of class \code{"function"}, if no events have been observed for the individual in question (then the function always returns the initial state). The vertical axis of \code{stateplot} can range from 1 to 3, where 1 corresponds to \emph{S}usceptible, 2 to \emph{I}nfectious and 3 to \emph{R}emoved. } \author{ Sebastian Meyer } \seealso{ \code{\link{summary.epidata}} for the data, on which the plots are based. \code{\link{animate.epidata}} for the animation of epidemics. } \examples{ data("hagelloch") (s <- summary(hagelloch)) # rudimentary stateplot stateplot(s, id = "187") # evolution of the epidemic plot(s) } \keyword{hplot} \keyword{methods} \keyword{spatial} surveillance/man/boda.Rd0000644000176200001440000001252314263515544014731 0ustar liggesusers\encoding{latin1} \name{boda} \alias{boda} \title{Bayesian Outbreak Detection Algorithm (BODA)} \description{ The function takes \code{range} values of a univariate surveillance time series \code{sts} and for each time point uses a negative binomial regression model to compute the predictive posterior distribution for the current observation. The \eqn{(1-\alpha)\cdot 100\%}{(1-alpha)*100\%} quantile of this predictive distribution is then used as bound: If the actual observation is above the bound an alarm is raised. The Bayesian Outbreak Detection Algorithm (\code{boda}) is due to Manitz and \enc{Hhle}{Hoehle} (2013) and its implementation is illustrated in Salmon et al. (2016). However, \code{boda} should be considered as an experiment, see the Warning section below! } \usage{ boda(sts, control = list( range=NULL, X=NULL, trend=FALSE, season=FALSE, prior=c('iid','rw1','rw2'), alpha=0.05, mc.munu=100, mc.y=10, verbose=FALSE, samplingMethod=c('joint','marginals'), quantileMethod=c("MC","MM") )) } \arguments{ \item{sts}{object of class sts (including the \code{observed} and the \code{state} time series)} \item{control}{Control object given as a \code{list} containing the following components: \describe{ \item{\code{range}}{Specifies the index of all timepoints which should be tested. If range is \code{NULL} all possible timepoints are used.} \item{\code{X}}{} \item{\code{trend}}{Boolean indicating whether a linear trend term should be included in the model for the expectation the log-scale} \item{\code{season}}{Boolean to indicate whether a cyclic spline should be included.} \item{\code{alpha}}{The threshold for declaring an observed count as an aberration is the \eqn{(1-\alpha)\cdot 100\%}{(1-alpha)*100\%} quantile of the predictive posterior.} \item{\code{mc.munu}}{} \item{\code{mc.y}}{Number of samples of \eqn{y}{y} to generate for each par of the mean and size parameter. A total of \eqn{mc.munu \times mc.y}{mc.munu*mc.y} samples are generated.} \item{\code{verbose}}{Argument sent to the inla call. When using ESS it might be necessary to force verbose mode for INLA to work.} \item{\code{samplingMethod}}{Should one sample from the parameters joint distribution (joint) or from their respective marginal posterior distribution (marginals)?} \item{quantileMethod}{Character, either \code{MC} or \code{MM}. Indicates how to compute the quantile based on the posterior distribution (no matter the inference method): either by sampling \code{mc.munu} values from the posterior distribution of the parameters and then for each sampled parameters vector sampling \code{mc.y} response values so that one gets a vector of response values based on which one computes an empirical quantile (MC method, as explained in Manitz and \enc{Hhle}{Hoehle} 2013); or by sampling \code{mc.munu} from the posterior distribution of the parameters and then compute the quantile of the mixture distribution using bisectioning, which is faster.} } } } \note{ This function requires the \R package \pkg{INLA}, which is currently \emph{not} available from CRAN. It can be obtained from INLA's own repository via \code{install.packages("INLA", repos="https://inla.r-inla-download.org/R/stable")}. } \section{Warning}{ This function is currently experimental!! It also heavily depends on the \pkg{INLA} package so changes there might affect the operational ability of this function. Since the computations for the Bayesian GAM are quite involved do not expect this function to be particularly fast. Results are not reproducible if \pkg{INLA} uses parallelization (as by default); set \code{INLA::inla.setOption(num.threads = "1:1")} to avoid that, then do \code{\link{set.seed}} as usual. } \keyword{classif} \examples{ \dontrun{ ## running this example takes a couple of minutes #Load the campylobacteriosis data for Germany data("campyDE") #Make an sts object from the data.frame cam.sts <- sts(epoch=campyDE$date, observed=campyDE$case, state=campyDE$state) #Define monitoring period # range <- which(epoch(cam.sts)>=as.Date("2007-01-01")) # range <- which(epoch(cam.sts)>=as.Date("2011-12-10")) range <- tail(1:nrow(cam.sts),n=2) control <- list(range=range, X=NULL, trend=TRUE, season=TRUE, prior='iid', alpha=0.025, mc.munu=100, mc.y=10, samplingMethod = "joint") #Apply the boda algorithm in its simples form, i.e. spline is #described by iid random effects and no extra covariates library("INLA") # needs to be attached cam.boda1 <- boda(cam.sts, control=control) plot(cam.boda1, xlab='time [weeks]', ylab='No. reported', dx.upperbound=0) } } \author{J. Manitz, M. \enc{Hhle}{Hoehle}, M. Salmon} \references{ Manitz, J. and \enc{Hhle}{Hoehle}, M. (2013): Bayesian outbreak detection algorithm for monitoring reported cases of campylobacteriosis in Germany. Biometrical Journal, 55(4), 509-526. Salmon, M., Schumacher, D. and \enc{Hhle}{Hoehle}, M. (2016): Monitoring count time series in \R: Aberration detection in public health surveillance. \emph{Journal of Statistical Software}, \bold{70} (10), 1-35. \doi{10.18637/jss.v070.i10} } surveillance/man/fanplot.Rd0000644000176200001440000000723313325600040015451 0ustar liggesusers\name{fanplot} \alias{fanplot} \title{Fan Plot of Forecast Distributions} \description{ The \code{fanplot()} function in \pkg{surveillance} wraps functionality of the dedicated \CRANpkg{fanplot} package, employing a different default style and optionally adding point predictions and observed values. } \usage{ fanplot(quantiles, probs, means = NULL, observed = NULL, start = 1, fan.args = list(), means.args = list(), observed.args = list(), key.args = NULL, xlim = NULL, ylim = NULL, log = "", xlab = "Time", ylab = "No. infected", add = FALSE, ...) } \arguments{ \item{quantiles}{ a time x \code{probs} matrix of forecast quantiles at each time point. } \item{probs}{ numeric vector of probabilities with values between 0 and 1. } \item{means}{ (optional) numeric vector of point forecasts. } \item{observed}{ (optional) numeric vector of observed values. } \item{start}{ time index (x-coordinate) of the first prediction. } \item{fan.args}{ a list of graphical parameters for the \code{\link[fanplot]{fan}}, e.g., to employ a different \code{\link{colorRampPalette}} as \code{fan.col}, or to enable contour lines via \code{ln}. } \item{means.args}{ a list of graphical parameters for \code{\link{lines}} to modify the plotting style of the \code{means}. The default is a white line within the fan. } \item{observed.args}{ a list of graphical parameters for \code{\link{lines}} to modify the plotting style of the \code{observed} values. } \item{key.args}{ if a list, a color key (in \code{\link[fanplot]{fan}()}'s \code{"boxfan"}-style) is added to the fan chart. The list may include positioning parameters \code{start} (the x-position) and \code{ylim} (the y-range of the color key), \code{space} to modify the width of the boxfan, and \code{rlab} to modify the labels. An alternative way of labeling the quantiles is via the argument \code{ln} in \code{fan.args}. } \item{xlim,ylim}{ axis ranges. } \item{log}{ a character string specifying which axes are to be logarithmic, e.g., \code{log="y"} (see \code{\link{plot.default}}). } \item{xlab,ylab}{ axis labels. } \item{add}{ logical indicating if the fan plot should be added to an existing plot. } \item{\dots}{ further arguments are passed to \code{\link{plot.default}}. For instance, \code{panel.first} could be used to initialize the plot with \code{\link{grid}(nx=NA, ny=NULL)} lines. } } \value{ \code{NULL} (invisibly), with the side effect of drawing a fan chart. } \author{ Sebastian Meyer } \seealso{ the underlying \code{\link[fanplot]{fan}} function in package \CRANpkg{fanplot}. The function is used in \code{\link{plot.oneStepAhead}} and \code{\link{plot.hhh4sims}}. } \examples{ ## artificial data example to illustrate the graphical options if (requireNamespace("fanplot")) { means <- c(18, 19, 20, 25, 26, 35, 34, 25, 19) y <- rlnorm(length(means), log(means), 0.5) quantiles <- sapply(1:99/100, qlnorm, log(means), seq(.5,.8,length.out=length(means))) ## default style with point predictions, color key and log-scale fanplot(quantiles = quantiles, probs = 1:99/100, means = means, observed = y, key.args = list(start = 1, space = .3), log = "y") ## with contour lines instead of a key, and different colors pal <- colorRampPalette(c("darkgreen", "gray93")) fanplot(quantiles = quantiles, probs = 1:99/100, observed = y, fan.args = list(fan.col = pal, ln = c(5,10,25,50,75,90,95)/100), observed.args = list(type = "b", pch = 19)) } } \keyword{hplot} \keyword{distribution} surveillance/man/rotaBB.Rd0000644000176200001440000000110613174706302015162 0ustar liggesusers\name{rotaBB} \alias{rotaBB} \docType{data} \title{Rotavirus cases in Brandenburg, Germany, during 2002-2013 stratified by 5 age categories} \description{ Monthly reported number of rotavirus infections in the federal state of Brandenburg stratified by five age categories (00-04, 05-09, 10-14, 15-69, 70+) during 2002-2013. } \usage{data(rotaBB)} \format{ A \code{sts} object. } \source{ The data were queried on 19 Feb 2014 from the Survstat@RKI database of the German Robert Koch Institute (\url{https://survstat.rki.de/}). } \keyword{datasets} surveillance/man/unionSpatialPolygons.Rd0000644000176200001440000000402214610747661020223 0ustar liggesusers\name{unionSpatialPolygons} \alias{unionSpatialPolygons} \title{ Compute the Unary Union of \code{"SpatialPolygons"} } \description{ Union all subpolygons of a \code{"\link[sp:SpatialPolygons-class]{SpatialPolygons}"} object. This is a legacy wrapper for the polygon clipping engines implemented by packages \pkg{sf} and \pkg{polyclip}. Internally, both \code{method}s need to convert the input polygons to a class appropriate for the \code{method}, so are rather inefficient. } \usage{ unionSpatialPolygons(SpP, method = c("sf", "polyclip"), ...) } \arguments{ \item{SpP}{ an object of class \code{"\link[sp:SpatialPolygons-class]{SpatialPolygons}"}. For the \pkg{polyclip} \code{method} only, all polygon classes for which an \code{\link[polyCub]{xylist}}-method exists should work as input. } \item{method}{ polygon clipping machinery to use. Default is to call \code{\link[sf]{st_union}} in package \pkg{sf}. For \code{method="polyclip"}, function \code{\link[polyclip]{polyclip}} from package \pkg{polyclip} is used. The old \code{method="gpclib"} is no longer available. } \item{\dots}{further arguments passed to the chosen \code{method}.} } \value{ an object of class \code{"\link[sp:SpatialPolygons-class]{SpatialPolygons}"} representing the union of all subpolygons. } \author{ Sebastian Meyer } \seealso{ \code{\link[sf]{st_union}} in package \pkg{sf}, \code{\link[polyclip]{polyclip}} in package \pkg{polyclip}. } \examples{ ## Load districts of Germany load(system.file("shapes", "districtsD.RData", package = "surveillance")) plot(districtsD, border = "gray", asp = 1) % to avoid sp -> sf ## Union these districts using either "sf" or "polyclip" if (requireNamespace("sf")) { stateD <- unionSpatialPolygons(districtsD, method = "sf") plot(stateD, add = TRUE, border = 2, lwd = 2) } if (requireNamespace("polyclip")) { stateD_pc <- unionSpatialPolygons(districtsD, method = "polyclip") plot(stateD_pc, add = TRUE, border = 1, lwd = 2, lty = 2) } } \keyword{spatial} surveillance/man/plot.disProg.Rd0000644000176200001440000000322414136730766016412 0ustar liggesusers\name{plot.disProg} \alias{plot.disProg} \title{Plot Observed Counts and Defined Outbreak States of a (Multivariate) Time Series} \description{ Plotting a (multivariate) \code{disProg} object (soft-deprecated). As of \pkg{surveillance} 1.20.0, legacy \code{disProg} objects are plotted via internal \code{\link{disProg2sts}} conversion and \code{\link{stsplot_time}}. } \usage{ \method{plot}{disProg}(x, title = "", xaxis.years=TRUE, startyear = x$start[1], firstweek = x$start[2], as.one=TRUE, same.scale=TRUE, ...) } \arguments{ \item{x}{object of class \code{disProg}} \item{title}{plot title} \item{xaxis.years}{if \code{TRUE}, the x axis is labeled using years} \item{startyear,firstweek}{(legacy arguments, ignored with a warning)} \item{as.one}{if \code{TRUE} all individual time series are shown in one plot} \item{same.scale}{if \code{TRUE} all plots have same scale} \item{\dots}{further arguments passed to \code{\link{stsplot_time}}} } \examples{ # Plotting of simulated data disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 208, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 5) plot(disProgObj) title <- "Infection Counts and Defined Outbreaks for Simulated Data" plot(disProgObj, title = title) plot(disProgObj, title = title, xaxis.years = FALSE) # Plotting of measles data data(measles.weser) # one plot plot(measles.weser, title = "measles cases in the district Weser-Ems") # plot cases for each "Kreis" plot(measles.weser, as.one = FALSE) plot(measles.weser, as.one = FALSE, same.scale = FALSE) } \keyword{hplot} \keyword{internal} surveillance/man/magic.dim.Rd0000644000176200001440000000137613276245673015666 0ustar liggesusers\name{magic.dim} \alias{magic.dim} \title{Compute Suitable k1 x k2 Layout for Plotting} \description{ For a given number \code{k}, \code{magic.dim} provides a vector containing two elements, the number of rows (k1) and columns (k2), respectively, which can be used to set the dimension of a single graphic device so that k1*k2 plots can be drawn by row (or by column) on the device. } \usage{ magic.dim(k) } \arguments{ \item{k}{an integer} } \value{numeric vector with two elements} \seealso{ \code{\link{primeFactors}} and \code{\link{bestCombination}} which are internally used to complete the task. \code{\link{n2mfrow}} is a similar function from package \pkg{grDevices}. } \keyword{dplot} \keyword{utilities} surveillance/man/twinstim_iaf.Rd0000644000176200001440000003442614610747661016532 0ustar liggesusers\encoding{latin1} \name{twinstim_iaf} \alias{siaf.constant} \alias{siaf.step} \alias{siaf.gaussian} \alias{siaf.exponential} \alias{siaf.powerlaw} \alias{siaf.powerlaw1} \alias{siaf.powerlawL} \alias{siaf.student} \alias{tiaf.constant} \alias{tiaf.step} \alias{tiaf.exponential} \title{ Temporal and Spatial Interaction Functions for \code{twinstim} } \description{ A \code{twinstim} model as described in Meyer et al. (2012) requires the specification of the spatial and temporal interaction functions (\eqn{f} and \eqn{g}, respectively), i.e. how infectivity decays with increasing spatial and temporal distance from the source of infection. Own such functions can be specified (see \code{\link{siaf}} and \code{\link{tiaf}}, respectively), but the package already predefines some common dispersal kernels returned by the constructor functions documented here. See Meyer and Held (2014) for various spatial interaction functions, and Meyer et al. (2017, Section 3, available as \code{vignette("twinstim")}) for an illustration of the implementation. } \usage{ # predefined spatial interaction functions siaf.constant() siaf.step(knots, maxRange = Inf, nTypes = 1, validpars = NULL) siaf.gaussian(nTypes = 1, logsd = TRUE, density = FALSE, F.adaptive = FALSE, F.method = "iso", effRangeMult = 6, validpars = NULL) siaf.exponential(nTypes = 1, validpars = NULL, engine = "C") siaf.powerlaw(nTypes = 1, validpars = NULL, engine = "C") siaf.powerlaw1(nTypes = 1, validpars = NULL, sigma = 1) siaf.powerlawL(nTypes = 1, validpars = NULL, engine = "C") siaf.student(nTypes = 1, validpars = NULL, engine = "C") # predefined temporal interaction functions tiaf.constant() tiaf.step(knots, maxRange = Inf, nTypes = 1, validpars = NULL) tiaf.exponential(nTypes = 1, validpars = NULL) } \arguments{ \item{knots}{numeric vector of distances at which the step function switches to a new height. The length of this vector determines the number of parameters to estimate. For identifiability, the step function has height 1 in the first interval \eqn{[0,knots_1)}. Note that the implementation is right-continuous, i.e., intervals are \eqn{[a,b)}.\cr An initial choice of knots could be based on quantiles of the observed distances between events and their potential source events. For instance, an identifiable spatial step function could be \code{siaf.step(quantile(\link{getSourceDists}(myepi, "space"), c(1,2,4)/10))}, where \code{myepi} is the \code{"epidataCS"} data to be modelled.} \item{maxRange}{a scalar larger than any of \code{knots}. Per default (\code{maxRange=Inf}), the step function never drops to 0 but keeps the last height for any distance larger than the last knot. However, this might not work in some cases, where the last parameter value would become very small and lead to numerical problems. It is then possible to truncate interaction at a distance \code{maxRange} (just like what the variables \code{eps.s} and \code{eps.t} do in the \code{"\link{epidataCS}"} object).} \item{nTypes}{ determines the number of parameters ((log-)scales or (log-)shapes) of the kernels. In a multitype epidemic, the different types may share the same spatial interaction function, in which case \code{nTypes=1}. Otherwise \code{nTypes} should equal the number of event types of the epidemic, in which case every type has its own (log-)scale or (log-)shape, respectively.\cr Currently, \code{nTypes > 1} is only implemented for \code{siaf.gaussian(F.adaptive = TRUE)}, \code{tiaf.step}, and \code{tiaf.exponential}. } \item{logsd,density}{ logicals affecting the parametrization of the Gaussian kernel. Settings different from the defaults are deprecated. The default is to use only the kernel of the bivariate, isotropic normal distribution (\code{density=FALSE}, see Details below), parametrized with the log-standard deviation (\code{logsd=TRUE}) to avoid constrained optimisation (L-BFGS-B) or \code{validpars}.\cr The power-law kernels always employ the log-scale for their scale and shape parameters. } \item{F.adaptive,F.method}{ If \code{F.adaptive = TRUE}, then an adaptive bandwidth of \code{adapt*sd} will be used in the midpoint-cubature (\code{\link[polyCub]{polyCub.midpoint}} in package \pkg{polyCub}) of the Gaussian interaction kernel, where \code{adapt} is an extra parameter of the returned \code{siaf$F} function and defaults to 0.1. It can be customized either by the \code{control.siaf$F} argument list of \code{twinstim}, or by a numeric specification of \code{F.adaptive} in the constructing call, e.g., \code{F.adaptive = 0.05} to achieve higher accuracy.\cr Otherwise, if \code{F.adaptive = FALSE}, the \code{F.method} argument determines which \code{\link[polyCub]{polyCub}} method to use in \code{siaf$F}. The accuracy (controlled via, e.g., \code{nGQ}, \code{rel.tol}, or \code{eps}, depending on the cubature method) can then be adjusted in \code{twinstim}'s \code{control.siaf$F} argument. } \item{effRangeMult}{ determines the effective range for numerical integration in terms of multiples of the standard deviation \eqn{\sigma} of the Gaussian kernel, i.e. with \code{effRangeMult=6} the \eqn{6 \sigma} region around the event is considered as the relevant integration domain instead of the whole observation region \code{W}. Setting \code{effRangeMult=NULL} will disable the integral approximation with an effective integration range. } \item{validpars}{ function taking one argument, the parameter vector, indicating if it is valid (see also \code{\link{siaf}}). If \code{logsd=FALSE} and one prefers not to use \code{method="L-BFGS-B"} for fitting the \code{twinstim}, then \code{validpars} could be set to \code{function (pars) pars > 0}. } \item{engine}{ character string specifying the implementation to use. Prior to \pkg{surveillance} 0.14.0, the \code{intrfr} functions for \code{\link[polyCub]{polyCub.iso}} were evaluated in \R (and this implementation is available via \code{engine = "R"}). The new C-implementation, \samp{LinkingTo} the newly exported \code{polyCub_iso} C-implementation in \pkg{polyCub} 0.6.0, is considerably faster. } \item{sigma}{ Fixed value of \eqn{\sigma} for the one-parameter power-law kernel. } } \details{ Evaluation of \code{twinstim}'s likelihood involves cubature of the spatial interaction function over polygonal domains. Various approaches have been compared by Meyer (2010, Section 3.2) and a new efficient method, which takes advantage of the assumed isotropy, has been proposed by Meyer and Held (2014, Supplement B, Section 2) for evaluation of the power-law kernels. These cubature methods are available in the dedicated \R package \pkg{polyCub} and used by the kernels implemented in \pkg{surveillance}. The readily available spatial interaction functions are defined as follows: \describe{ \item{\code{siaf.constant}:}{ \eqn{f(s) = 1} } \item{\code{siaf.step}:}{ \eqn{f(s) = \sum_{k=0}^K \exp(\alpha_k) I_k(||s||)},\cr where \eqn{\alpha_0 = 0}, and \eqn{\alpha_1, \dots, \alpha_K} are the parameters (heights) to estimate. \eqn{I_k(||s||)} indicates if distance \eqn{||s||} belongs to the \eqn{k}th interval according to \code{c(0,knots,maxRange)}, where \eqn{k=0} indicates the interval \code{c(0,knots[1])}.\cr Note that \code{siaf.step} makes use of the \pkg{memoise} package if it is available -- and that is highly recommended to speed up calculations. Specifically, the areas of the intersection of a polygonal domain (influence region) with the \dQuote{rings} of the two-dimensional step function will be cached such that they are only calculated once for every \code{polydomain} (in the first iteration of the \code{twinstim} optimization). They are used in the integration components \code{F} and \code{Deriv}. See Meyer and Held (2014) for a use case and further details. } \item{\code{siaf.gaussian}:}{ \eqn{f(s|\kappa) = \exp(-||s||/2/\sigma_\kappa^2)}\cr If \code{nTypes=1} (single-type epidemic or type-invariant \code{siaf} in multi-type epidemic), then \eqn{\sigma_\kappa = \sigma} for all types \eqn{\kappa}. If \code{density=TRUE} (deprecated), then the kernel formula above is additionally divided by \eqn{2 \pi \sigma_\kappa^2}, yielding the density of the bivariate, isotropic Gaussian distribution with zero mean and covariance matrix \eqn{\sigma_\kappa^2 I_2}. The standard deviation is optimized on the log-scale (\code{logsd = TRUE}, not doing so is deprecated). } \item{\code{siaf.exponential}:}{ \eqn{f(s) = exp(-||s||/sigma)}\cr The scale parameter \eqn{sigma} is estimated on the log-scale, i.e., \eqn{\sigma = \exp(\tilde{\sigma})}, and \eqn{\tilde{\sigma}} is the actual model parameter. } \item{\code{siaf.powerlaw}:}{ \eqn{f(s) = (||s|| + \sigma)^{-d}}\cr The parameters are optimized on the log-scale to ensure positivity, i.e., \eqn{\sigma = \exp(\tilde{\sigma})} and \eqn{d = \exp(\tilde{d})}, where \eqn{(\tilde{\sigma}, \tilde{d})} is the parameter vector. If a power-law kernel is not identifiable for the dataset at hand, the exponential kernel or a lagged power law are useful alternatives. } \item{\code{siaf.powerlaw1}:}{ \eqn{f(s) = (||s|| + 1)^{-d}},\cr i.e., \code{siaf.powerlaw} with fixed \eqn{\sigma = 1}. A different fixed value for \eqn{sigma} can be specified via the \code{sigma} argument of \code{siaf.powerlaw1}. The decay parameter \eqn{d} is estimated on the log-scale. } \item{\code{siaf.powerlawL}:}{ \eqn{f(s) = (||s||/\sigma)^{-d}}, for \eqn{||s|| \ge \sigma}, and \eqn{f(s) = 1} otherwise,\cr which is a \emph{L}agged power-law kernel featuring uniform short-range dispersal (up to distance \eqn{\sigma}) and a power-law decay (Pareto-style) from distance \eqn{\sigma} onwards. The parameters are optimized on the log-scale to ensure positivity, i.e. \eqn{\sigma = \exp(\tilde{\sigma})} and \eqn{d = \exp(\tilde{d})}, where \eqn{(\tilde{\sigma}, \tilde{d})} is the parameter vector. However, there is a caveat associated with this kernel: Its derivative wrt \eqn{\tilde{\sigma}} is mathematically undefined at the threshold \eqn{||s||=\sigma}. This local non-differentiability makes \code{twinstim}'s likelihood maximization sensitive wrt parameter start values, and is likely to cause false convergence warnings by \code{\link{nlminb}}. Possible workarounds are to use the slow and robust \code{method="Nelder-Mead"}, or to just ignore the warning and verify the result by sets of different start values. } \item{\code{siaf.student}:}{ \eqn{f(s) = (||s||^2 + \sigma^2)^{-d}},\cr which is a reparametrized \eqn{t}-kernel. For \eqn{d=1}, this is the kernel of the Cauchy density with scale \code{sigma}. In Geostatistics, a correlation function of this kind is known as the Cauchy model.\cr The parameters are optimized on the log-scale to ensure positivity, i.e. \eqn{\sigma = \exp(\tilde{\sigma})} and \eqn{d = \exp(\tilde{d})}, where \eqn{(\tilde{\sigma}, \tilde{d})} is the parameter vector. } } The predefined temporal interaction functions are defined as follows: \describe{ \item{\code{tiaf.constant}:}{ \eqn{g(t) = 1} } \item{\code{tiaf.step}:}{ \eqn{g(t) = \sum_{k=0}^K \exp(\alpha_k) I_k(t)},\cr where \eqn{\alpha_0 = 0}, and \eqn{\alpha_1, \dots, \alpha_K} are the parameters (heights) to estimate. \eqn{I_k(t)} indicates if \eqn{t} belongs to the \eqn{k}th interval according to \code{c(0,knots,maxRange)}, where \eqn{k=0} indicates the interval \code{c(0,knots[1])}. } \item{\code{tiaf.exponential}:}{ \eqn{g(t|\kappa) = \exp(-\alpha_\kappa t)},\cr which is the kernel of the exponential distribution. If \code{nTypes=1} (single-type epidemic or type-invariant \code{tiaf} in multi-type epidemic), then \eqn{\alpha_\kappa = \alpha} for all types \eqn{\kappa}. } } } \value{ The specification of an interaction function, which is a list. See \code{\link{siaf}} and \code{\link{tiaf}}, respectively, for a description of its components. } \references{ Meyer, S. (2010): Spatio-Temporal Infectious Disease Epidemiology based on Point Processes. Master's Thesis, Ludwig-Maximilians-Universit\enc{}{ae}t M\enc{}{ue}nchen.\cr Available as \url{https://epub.ub.uni-muenchen.de/11703/} Meyer, S., Elias, J. and H\enc{}{oe}hle, M. (2012): A space-time conditional intensity model for invasive meningococcal disease occurrence. \emph{Biometrics}, \bold{68}, 607-616. \doi{10.1111/j.1541-0420.2011.01684.x} Meyer, S. and Held, L. (2014): Power-law models for infectious disease spread. \emph{The Annals of Applied Statistics}, \bold{8} (3), 1612-1639. \doi{10.1214/14-AOAS743} Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \author{ Sebastian Meyer } \seealso{ \code{\link{twinstim}}, \code{\link{siaf}}, \code{\link{tiaf}}, and package \pkg{polyCub} for the involved cubature methods. } \examples{ # constant temporal dispersal tiaf.constant() # step function kernel tiaf.step(c(3,7), maxRange=14, nTypes=2) # exponential temporal decay tiaf.exponential() # Type-dependent Gaussian spatial interaction function using an adaptive # two-dimensional midpoint-rule to integrate it over polygonal domains siaf.gaussian(2, F.adaptive=TRUE) # Single-type Gaussian spatial interaction function (using polyCub.iso) siaf.gaussian() # Exponential kernel siaf.exponential() # Power-law kernel siaf.powerlaw() # Power-law kernel with fixed sigma = 1 siaf.powerlaw1() # "lagged" power-law siaf.powerlawL() # (reparametrized) t-kernel siaf.student() # step function kernel siaf.step(c(10,20,50), maxRange=100) } \keyword{models} \keyword{utilities} surveillance/man/salmNewport.Rd0000644000176200001440000000156313174706302016333 0ustar liggesusers\name{salmNewport} \alias{salmNewport} \docType{data} \title{Salmonella Newport cases in Germany 2004-2013} \description{ Reported number of cases of the Salmonella Newport serovar in the 16 German federal states 2004-2013. } \usage{data(salmNewport)} \format{ A \code{sts} object. } \source{ The data were queried from the SurvStat@RKI database of the German Robert Koch Institute (\url{https://survstat.rki.de/}). A detailed description of the 2011 outbreak can be found in the publication Bayer, C., Bernard, H., Prager, R., Rabsch, W., Hiller, P., Malorny, B., Pfefferkorn, B., Frank, C., de Jong, A., Friesema, I., Start, K., Rosner, B.M. (2014), An outbreak of Salmonella Newport associated with mung bean sprouts in Germany and the Netherlands, October to November 2011, Eurosurveillance 19(1):pii=20665. } \keyword{datasets} surveillance/man/hhh4_simulate_plot.Rd0000644000176200001440000002114713230375405017613 0ustar liggesusers\name{hhh4_simulate_plot} \alias{plot.hhh4sims} \alias{aggregate.hhh4sims} \alias{as.hhh4simslist} \alias{plot.hhh4simslist} \alias{aggregate.hhh4simslist} \alias{plotHHH4sims_size} \alias{plotHHH4sims_time} \alias{plotHHH4sims_fan} \title{ Plot Simulations from \code{"hhh4"} Models } \description{ Arrays of simulated counts from \code{\link{simulate.hhh4}} can be visualized as final size boxplots, individual or average time series, or fan charts (using the \CRANpkg{fanplot} package). An \code{aggregate}-method is also available. } \usage{ \method{plot}{hhh4sims}(x, ...) \method{aggregate}{hhh4sims}(x, units = TRUE, time = FALSE, ..., drop = FALSE) as.hhh4simslist(x, ...) \method{plot}{hhh4simslist}(x, type = c("size", "time", "fan"), ..., groups = NULL, par.settings = list()) \method{aggregate}{hhh4simslist}(x, units = TRUE, time = FALSE, ..., drop = FALSE) plotHHH4sims_size(x, horizontal = TRUE, trafo = NULL, observed = TRUE, names = base::names(x), ...) plotHHH4sims_time(x, average = mean, individual = length(x) == 1, conf.level = if (individual) 0.95 else NULL, matplot.args = list(), initial.args = list(), legend = length(x) > 1, xlim = NULL, ylim = NULL, add = FALSE, ...) plotHHH4sims_fan(x, which = 1, fan.args = list(), observed.args = list(), initial.args = list(), means.args = NULL, key.args = NULL, xlim = NULL, ylim = NULL, add = FALSE, xaxis = list(), ...) } \arguments{ \item{x}{ an object of class \code{"hhh4sims"} (as resulting from the \code{\link[=simulate.hhh4]{simulate}}-method for \code{"\link{hhh4}"} models if \code{simplify = TRUE} was set), or an \code{"hhh4simslist"}, i.e., a list of such simulations potentially obtained from different model fits (using the same simulation period). } \item{type}{ a character string indicating the summary plot to produce. } \item{\dots}{ further arguments passed to methods. } \item{groups}{ an optional factor to produce stratified plots by groups of units. The special setting \code{groups = TRUE} is a convenient shortcut for one plot by unit. } \item{par.settings}{ a list of graphical parameters for \code{\link{par}}. Sensible defaults for \code{mfrow}, \code{mar} and \code{las} will be applied unless overridden or \code{!is.list(par.settings)}. } \item{horizontal}{ a logical indicating if the boxplots of the final size distributions should be horizontal (the default). } \item{trafo}{ an optional transformation function from the \pkg{scales} package, e.g., \code{\link[scales]{sqrt_trans}}. } \item{observed}{ a logical indicating if a line and axis value for the observed size of the epidemic should be added to the plot. Alternatively, a list with graphical parameters can be specified to modify the default values. } \item{names}{ a character vector of names for \code{x}. } \item{average}{ scalar-valued function to apply to the simulated counts at each time point. } \item{individual}{ a logical indicating if the individual simulations should be shown as well. } \item{conf.level}{ a scalar in (0,1), which determines the level of the pointwise quantiles obtained from the simulated counts at each time point. A value of \code{NULL} disables the confidence interval. } \item{matplot.args}{ a list of graphical parameters for \code{\link{matlines}}. } \item{initial.args}{ if a list (of graphical parameters for \code{\link{lines}}), a bar for the initial number of cases is added to the plot. } \item{legend}{ a logical, a character vector (providing names for \code{x}), or a list of parameters for \code{\link{legend}}. } \item{xlim,ylim}{ vectors of length 2 determining the axis limits. } \item{add}{ a logical indicating if the (mean) simulated time series or the fan chart, respectively, should be added to an existing plot. } \item{which}{ a single integer or a character string selecting the model in \code{x} for which to produce the fan chart. This is only relevant if \code{x} is a \code{"hhh4simslist"} of simulations from multiple models. Defaults to the first model. } \item{fan.args}{ a list of graphical parameters for the \code{\link[fanplot]{fan}}, e.g., to employ a different \code{\link{colorRampPalette}} as \code{fan.col}, or to enable contour lines via \code{ln}. } \item{observed.args}{ if a list (of graphical parameters for \code{\link{lines}}), the originally observed counts are added to the plot. } \item{means.args}{ if a list (of graphical parameters for \code{\link{lines}}), the point forecasts are added to the plot (by default as a white line within the fan). } \item{key.args}{ if a list, a color key (in \code{\link[fanplot]{fan}}'s \code{"boxfan"}-style) is added to the fan chart. The list may include positioning parameters \code{start} (the x-position) and \code{ylim} (the y-range of the color key), \code{space} to modify the width of the boxfan, and \code{rlab} to modify the labels. The color key is disabled by default. An alternative way of labeling the quantiles is via the argument \code{ln} in \code{fan.args}, see the Examples. } \item{xaxis}{ if a list of arguments for \code{\link{addFormattedXAxis}}, that function is used to draw the time axis, otherwise a default x-axis is drawn. } \item{units}{ a logical indicating aggregation over units. Can also be a factor (or something convertible to a factor using \code{\link{as.factor}}) to aggregate groups of units. } \item{time}{ a logical indicating if the counts should be summed over the whole simulation period. } \item{drop}{ a logical indicating if the unit dimension and the \code{"hhh4sims"} (or \code{"hhh4simslist"}) class should be dropped after aggregating over (groups of) units. } } \author{ Sebastian Meyer } \examples{ ### univariate example data("salmAllOnset") ## fit a hhh4 model to the first 13 years salmModel <- list(end = list(f = addSeason2formula(~1 + t)), ar = list(f = ~1), family = "NegBin1", subset = 2:678) salmFit <- hhh4(salmAllOnset, salmModel) ## simulate the next 20 weeks ahead salmSims <- simulate(salmFit, nsim = 300, seed = 3, subset = 678 + seq_len(20), y.start = observed(salmAllOnset)[678,]) ## compare final size distribution to observed value summary(aggregate(salmSims, time = TRUE)) # summary of simulated values plot(salmSims, type = "size") ## individual and average simulated time series with a confidence interval plot(salmSims, type = "time", main = "20-weeks-ahead simulation") ## fan chart based on the quantiles of the simulated counts at each time point ## point forecasts are represented by a white line within the fan if (requireNamespace("fanplot")) { plot(salmSims, type = "fan", main = "20-weeks-ahead simulation", fan.args = list(ln = 1:9/10), means.args = list()) } ### multivariate example data("measlesWeserEms") ## fit a hhh4 model to the first year measlesModel <- list( end = list(f = addSeason2formula(~1), offset = population(measlesWeserEms)), ar = list(f = ~1), ne = list(f = ~1 + log(pop), weights = W_powerlaw(maxlag = 5, normalize = TRUE)), family = "NegBin1", subset = 2:52, data = list(pop = population(measlesWeserEms))) measlesFit1 <- hhh4(measlesWeserEms, control = measlesModel) ## use a Poisson distribution instead (just for comparison) measlesFit2 <- update(measlesFit1, family = "Poisson") ## simulate realizations from these models during the second year measlesSims <- lapply(X = list(NegBin = measlesFit1, Poisson = measlesFit2), FUN = simulate, nsim = 50, seed = 1, subset = 53:104, y.start = observed(measlesWeserEms)[52,]) ## final size of the first model plot(measlesSims[[1]]) ## stratified by groups of districts mygroups <- factor(substr(colnames(measlesWeserEms), 4, 4)) apply(aggregate(measlesSims[[1]], time = TRUE, units = mygroups), 1, summary) plot(measlesSims[[1]], groups = mygroups) ## a class and plot-method for a list of simulations from different models measlesSims <- as.hhh4simslist(measlesSims) plot(measlesSims) ## simulated time series plot(measlesSims, type = "time", individual = TRUE, ylim = c(0, 80)) ## fan charts if (requireNamespace("fanplot")) { opar <- par(mfrow = c(2,1)) plot(measlesSims, type = "fan", which = 1, ylim = c(0, 80), main = "NegBin", key.args = list()) plot(measlesSims, type = "fan", which = 2, ylim = c(0, 80), main = "Poisson") par(opar) } } \keyword{hplot} surveillance/man/algo.summary.Rd0000644000176200001440000000347013122471774016442 0ustar liggesusers\name{algo.summary} \alias{algo.summary} \title{Summary Table Generation for Several Disease Chains} \description{ Summary table generation for several disease chains. } \usage{ algo.summary(compMatrices) } \arguments{ \item{compMatrices}{list of matrices constructed by algo.compare.} } \value{ a matrix summing up the singular input matrices } \details{ As lag the mean of all single lags is returned. TP values, FN values, TN values and FP values are summed up. \code{dist}, \code{sens} and \code{spec} are new computed on the basis of the new TP value, FN value, TN value and FP value. } \seealso{\code{\link{algo.compare}}, \code{\link{algo.quality}}} \examples{ # Create a test object disProgObj1 <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) disProgObj2 <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 5) disProgObj3 <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 17) # Let this object be tested from any methods in range = 200:400 range <- 200:400 control <- list(list(funcName = "rki1", range = range), list(funcName = "rki2", range = range), list(funcName = "rki3", range = range)) compMatrix1 <- algo.compare(algo.call(disProgObj1, control=control)) compMatrix2 <- algo.compare(algo.call(disProgObj2, control=control)) compMatrix3 <- algo.compare(algo.call(disProgObj3, control=control)) algo.summary( list(a=compMatrix1, b=compMatrix2, c=compMatrix3) ) } \keyword{print} surveillance/man/pit.Rd0000644000176200001440000000547713446150274014627 0ustar liggesusers\name{pit} \alias{pit} \alias{pit.default} \title{ Non-Randomized Version of the PIT Histogram (for Count Data) } \description{ See Czado et al. (2009). } \usage{ pit(x, ...) \method{pit}{default}(x, pdistr, J = 10, relative = TRUE, ..., plot = list()) } \arguments{ \item{x}{ numeric vector representing the observed counts. } \item{pdistr}{ either a list of predictive cumulative distribution functions for the observations \code{x}, or (the name of) a single predictive CDF used for all \code{x} (with potentially varying arguments \code{...}). It is checked that the predictive CDF returns 0 at \code{x=-1}. The name of its first argument can be different from \code{x}, e.g., \code{pdistr="pnbinom"} is possible.\cr If \code{pdistr} is a single function and no additional \code{\dots} arguments are supplied, \code{pdistr} is assumed to be vectorized, i.e., it is simply called as \code{pdistr(x)} and \code{pdistr(x-1)}. Otherwise, the predictive CDF is called sequentially and does not need to be vectorized. } \item{J}{ the number of bins of the histogram. } \item{relative}{ logical indicating if relative frequency or the density should be plotted. Due to a historical bug, \code{relative=TRUE} (the default) actually plots a density histogram while \code{relative=FALSE} plots relative frequencies. } \item{\dots}{ ignored if \code{pdistr} is a list. Otherwise, such additional arguments are used in sequential calls of \code{pdistr} via \code{\link{mapply}(pdistr, x, ...)}. } \item{plot}{ a list of arguments for \code{\link{plot.histogram}}. Otherwise, no plot will be produced. } } \value{ an object of class \code{"pit"}, which inherits from class \code{"histogram"} (see \code{\link{hist}}). It is returned invisibly if a plot is produced. } \references{ Czado, C., Gneiting, T. and Held, L. (2009): Predictive model assessment for count data. \emph{Biometrics}, \bold{65} (4), 1254-1261. \doi{10.1111/j.1541-0420.2009.01191.x} } \author{ Michaela Paul and Sebastian Meyer } \examples{ ## Simulation example of Czado et al. (2009, Section 2.4) set.seed(100) x <- rnbinom(200, mu = 5, size = 2) pdistrs <- list("NB(5,0)" = function (x) ppois(x, lambda=5), "NB(5,1/2)" = function (x) pnbinom(x, mu=5, size=2), "NB(5,1)" = function (x) pnbinom(x, mu=5, size=1)) ## Reproduce Figure 1 op <- par(mfrow = c(1,3)) for (i in seq_along(pdistrs)) { pit(x, pdistr = pdistrs[[i]], J = 10, plot = list(ylim = c(0,2.75), main = names(pdistrs)[i])) box() } par(op) ## Alternative call using ... arguments for pdistr (less efficient) stopifnot(identical(pit(x, "pnbinom", mu = 5, size = 2, plot = FALSE), pit(x, pdistrs[[2]], plot = FALSE))) } \keyword{dplot} surveillance/man/toLatex.sts.Rd0000644000176200001440000000417714607740561016263 0ustar liggesusers\name{toLatex.sts} \docType{methods} \alias{toLatex.sts} \alias{toLatex,sts-method} \title{\code{toLatex}-Method for \code{"sts"} Objects} \description{ Convert \code{"\linkS4class{sts}"} objects to a character vector with LaTeX markup. } \usage{ \S4method{toLatex}{sts}(object, caption = "",label=" ", columnLabels = NULL, subset = NULL, alarmPrefix = "\\\\textbf{\\\\textcolor{red}{", alarmSuffix = "}}", ubColumnLabel = "UB", ...) } \arguments{ \item{object}{an \code{"\linkS4class{sts}"} object.} \item{caption}{A caption for the table. Default is the empty string.} \item{label}{A label for the table. Default is the empty string.} \item{columnLabels}{A list of labels for each column of the resulting table. Default is NULL} \item{subset}{A range of values which should be displayed. If Null, then all data in the sts objects will be displayed. Else only a subset of data. Therefore range needs to be a numerical vector of indexes from 1 to length(@observed).} \item{alarmPrefix}{A latex compatible prefix string wrapped around a table cell iff there is an alarm;i.e. alarm = TRUE} \item{alarmSuffix}{A latex compatible suffix string wrapped around a table cell iff there is an alarm;i.e. alarm[i,j] = TRUE} \item{ubColumnLabel}{The label of the upper bound column; default is \"UB\".} \item{\dots}{further arguments passed to \code{\link[xtable]{print.xtable}}.} } \value{ An object of class \code{\link[=toLatex]{"Latex"}}. } \examples{ # Create a test object data("salmonella.agona") # Create the corresponding sts object from the old disProg object salm <- disProg2sts(salmonella.agona) control <- list(range=(260:312), noPeriods=1,populationOffset=FALSE, fitFun="algo.farrington.fitGLM.flexible", b=4,w=3,weightsThreshold=1, pastWeeksNotIncluded=3, pThresholdTrend=0.05,trend=TRUE, thresholdMethod="delta",alpha=0.1) salm <- farringtonFlexible(salm,control=control) toLatex(salm, sanitize.text.function=identity, comment=FALSE) } \author{Dirk Schumacher} \keyword{print} surveillance/man/R0.Rd0000644000176200001440000002045313514363214014277 0ustar liggesusers\encoding{latin1} \name{R0} \alias{R0} \alias{R0.twinstim} \alias{R0.simEpidataCS} \alias{simpleR0} \title{Computes reproduction numbers from fitted models} \description{ The S3 generic function \code{R0} defined in package \pkg{surveillance} is intended to compute reproduction numbers from fitted epidemic models. The package currently defines a method for the \code{"\link{twinstim}"} class, which computes expected numbers of infections caused by infected individuals depending on the event type and marks attached to the individual, which contribute to the infection pressure in the epidemic predictor of that class. There is also a method for simulated \code{"epidataCS"} (just a wrapper for the \code{"twinstim"}-method). } \usage{ R0(object, ...) \method{R0}{twinstim}(object, newevents, trimmed = TRUE, newcoef = NULL, ...) \method{R0}{simEpidataCS}(object, trimmed = TRUE, ...) simpleR0(object, eta = coef(object)[["e.(Intercept)"]], eps.s = NULL, eps.t = NULL, newcoef = NULL) } \arguments{ \item{object}{A fitted epidemic model object for which an \code{R0} method exists.} \item{newevents}{ an optional \code{data.frame} of events for which the reproduction numbers should be calculated. If omitted, it is calculated for the original events from the fit. In this case, if \code{trimmed = TRUE} (the default), the result is just \code{object$R0}; however, if \code{trimmed = FALSE}, the model environment is required, i.e. \code{object} must have been fitted with \code{model = TRUE}. For the \code{twinstim} method, \code{newevents} must at least contain the following columns: the event \code{time} (only for \code{trimmed = TRUE}) and \code{type} (only for multi-type epidemics), the maximum interaction ranges \code{eps.t} and \code{eps.s}, as well as columns for the marks and \code{stgrid} variables used in the epidemic component of the fitted \code{"twinstim"} \code{object} as stored in \code{formula(object)$epidemic}. For \code{trimmed} R0 values, \code{newevents} must additionally contain the components \code{.influenceRegion} and, if using the \code{Fcircle} trick in the \code{siaf} specification, also \code{.bdist} (cf. the hidden columns in the \code{events} component of class \code{"epidataCS"}). } \item{trimmed}{ logical indicating if the individual reproduction numbers should be calculated by integrating the epidemic intensities over the observation period and region only (\code{trimmed = TRUE}) or over the whole time-space domain R+ x R^2 (\code{trimmed = FALSE}). By default, if \code{newevents} is missing, the trimmed \code{R0} values stored in \code{object} are returned. Trimming means that events near the (spatial or temporal) edges of the observation domain have lower reproduction numbers (ceteris paribus) because events outside the observation domain are not observed. } \item{newcoef}{ the model parameters to use when calculating reproduction numbers. The default (\code{NULL}) is to use the MLE \code{coef(object)}. This argument mainly serves the construction of Monte Carlo confidence intervals by evaluating \code{R0} for parameter vectors sampled from the asymptotic multivariate normal distribution of the MLE, see Examples. } \item{\dots}{additional arguments passed to methods. Currently unused for the \code{twinstim} method.} \item{eta}{a value for the epidemic linear predictor, see details.} \item{eps.s,eps.t}{the spatial/temporal radius of interaction. If \code{NULL} (the default), the original value from the data is used if this is unique and an error is thrown otherwise.} } \details{ For the \code{"\link{twinstim}"} class, the individual-specific expected number \eqn{\mu_j} of infections caused by individual (event) \eqn{j} inside its theoretical (untrimmed) spatio-temporal range of interaction given by its \code{eps.t} (\eqn{\epsilon}) and \code{eps.s} (\eqn{\delta}) values is defined as follows (cf. Meyer et al, 2012): \deqn{\mu_j = e^{\eta_j} \cdot \int_{b(\bold{0},\delta)} f(\bold{s}) d\bold{s} \cdot \int_0^\epsilon g(t) dt .} Here, \eqn{b(\bold{0},\delta)} denotes the disc centred at (0,0)' with radius \eqn{\delta}, \eqn{\eta_j} is the epidemic linear predictor, \eqn{g(t)} is the temporal interaction function, and \eqn{f(\bold{s})} is the spatial interaction function. For a type-specific \code{twinstim}, there is an additional factor for the number of event types which can be infected by the type of event \eqn{j} and the interaction functions may be type-specific as well. Alternatively to the equation above, the \code{trimmed} (observed) reproduction numbers are obtain by integrating over the observed infectious domains of the individuals, i.e. integrate \eqn{f} over the intersection of the influence region with the observation region \code{W} (i.e. over \eqn{\{ W \cap b(\bold{s}_j,\delta) \} - \bold{s}_j}) and \eqn{g} over the intersection of the observed infectious period with the observation period \eqn{(t_0;T]} (i.e. over \eqn{(0; \min(T-t_j,\epsilon)]}). The function \code{simpleR0} computes \deqn{\exp(\eta) \cdot \int_{b(\bold{0},\delta)} f(\bold{s}) d\bold{s} \cdot \int_0^{\epsilon} g(t) dt ,} where \eqn{\eta} defaults to \eqn{\gamma_0} disregarding any epidemic effects of types and marks. It is thus only suitable for simple epidemic \code{\link{twinstim}} models with \code{epidemic = ~1}, a diagonal (or secondary diagonal) \code{qmatrix}, and type-invariant interaction functions. \code{simpleR0} mainly exists for use by \code{\link{epitest}}. (Numerical) Integration is performed exactly as during the fitting of \code{object}, for instance \code{object$control.siaf} is queried if necessary. } \value{ For the \code{R0} methods, a numeric vector of estimated reproduction numbers from the fitted model \code{object} corresponding to the rows of \code{newevents} (if supplied) or the original fitted events including events of the prehistory. For \code{simpleR0}, a single number (see details). } \references{ Meyer, S., Elias, J. and H\enc{}{oe}hle, M. (2012): A space-time conditional intensity model for invasive meningococcal disease occurrence. \emph{Biometrics}, \bold{68}, 607-616. \doi{10.1111/j.1541-0420.2011.01684.x} } \author{Sebastian Meyer} \examples{ ## load the 'imdepi' data and a model fit data("imdepi", "imdepifit") ## calculate individual and type-specific reproduction numbers R0s <- R0(imdepifit) tapply(R0s, imdepi$events@data[names(R0s), "type"], summary) ## untrimmed R0 for specific event settings refevent <- data.frame(agegrp = "[0,3)", type = "B", eps.s = Inf, eps.t = 30) setting2 <- data.frame(agegrp = "[3,19)", type = "C", eps.s = Inf, eps.t = 14) newevents <- rbind("ref" = refevent, "event2" = setting2) (R0_examples <- R0(imdepifit, newevents = newevents, trimmed = FALSE)) stopifnot(all.equal(R0_examples[["ref"]], simpleR0(imdepifit))) ### compute a Monte Carlo confidence interval ## use a simpler model with constant 'siaf' for speed simplefit <- update(imdepifit, epidemic=~type, siaf=NULL, subset=NULL) ## we'd like to compute the mean R0's by event type meanR0ByType <- function (newcoef) { R0events <- R0(simplefit, newcoef=newcoef) tapply(R0events, imdepi$events@data[names(R0events),"type"], mean) } (meansMLE <- meanR0ByType(newcoef=NULL)) ## sample B times from asymptotic multivariate normal of the MLE B <- 5 # CAVE: toy example! In practice this has to be much larger set.seed(123) parsamples <- MASS::mvrnorm(B, mu=coef(simplefit), Sigma=vcov(simplefit)) ## for each sample compute the 'meanR0ByType' meansMC <- apply(parsamples, 1, meanR0ByType) ## get the quantiles and print the result cisMC <- apply(cbind(meansMLE, meansMC), 1, quantile, probs=c(0.025,0.975)) print(rbind(MLE=meansMLE, cisMC)) ### R0 for a simple epidemic model ### without epidemic covariates, i.e., all individuals are equally infectious mepi1 <- update(simplefit, epidemic = ~1, subset = type == "B", model = TRUE, verbose = FALSE) ## using the default spatial and temporal ranges of interaction (R0B <- simpleR0(mepi1)) # eps.s=200, eps.t=30 stopifnot(identical(R0B, R0(mepi1, trimmed = FALSE)[[1]])) ## assuming smaller interaction ranges (but same infection intensity) simpleR0(mepi1, eps.s = 50, eps.t = 15) } \keyword{methods} \keyword{univar} surveillance/man/hepatitisA.Rd0000644000176200001440000000101313174706302016101 0ustar liggesusers\name{hepatitisA} \docType{data} \alias{hepatitisA} \title{Hepatitis A in Germany} \description{ Weekly number of reported hepatitis A infections in Germany 2001-2004. } \usage{data(hepatitisA)} \format{ A \code{disProg} object containing \eqn{208\times 1}{208 x 1} observations starting from week 1 in 2001 to week 52 in 2004. } \source{ Robert Koch-Institut: SurvStat: \url{https://survstat.rki.de/}; Queried on 11-01-2005. } \examples{ data(hepatitisA) plot(hepatitisA) } \keyword{datasets} surveillance/man/pairedbinCUSUM.Rd0000644000176200001440000001457514431111475016577 0ustar liggesusers\name{pairedbinCUSUM} \alias{pairedbinCUSUM} \alias{pairedbinCUSUM.runlength} \alias{pairedbinCUSUM.LLRcompute} \encoding{latin1} \title{Paired binary CUSUM and its run-length computation} \description{ CUSUM for paired binary data as described in Steiner et al. (1999). } \usage{ pairedbinCUSUM(stsObj, control = list(range=NULL,theta0,theta1, h1,h2,h11,h22)) pairedbinCUSUM.runlength(p,w1,w2,h1,h2,h11,h22, sparse=FALSE) } \arguments{ \item{stsObj}{Object of class \code{sts} containing the paired responses for each of the, say n, patients. The observed slot of \code{stsObj} is thus a \eqn{n \times 2}{n x 2} matrix.} \item{control}{Control object as a list containing several parameters. \describe{ \item{\code{range}}{Vector of indices in the observed slot to monitor.} \item{\code{theta0}}{In-control parameters of the paired binary CUSUM.} \item{\code{theta1}}{Out-of-control parameters of the paired binary CUSUM.} \item{\code{h1}}{Primary control limit (=threshold) of 1st CUSUM.} \item{\code{h2}}{Primary control limit (=threshold) of 2nd CUSUM.} \item{\code{h11}}{Secondary limit for 1st CUSUM.} \item{\code{h22}}{Secondary limit for 2nd CUSUM.} } } \item{p}{Vector giving the probability of the four different possible states, i.e. c((death=0,near-miss=0),(death=1,near-miss=0), (death=0,near-miss=1),(death=1,near-miss=1)).} \item{w1}{The parameters \code{w1} and \code{w2} are the sample weights vectors for the two CUSUMs, see eqn. (2) in the paper. We have that \code{w1} is equal to deaths } \item{w2}{As for \code{w1}} \item{h1}{decision barrier for 1st individual cusums} \item{h2}{decision barrier for 2nd cusums} \item{h11}{together with \code{h22} this makes up the joing decision barriers} \item{h22}{together with \code{h11} this makes up the joing decision barriers} \item{sparse}{Boolean indicating whether to use sparse matrix computations from the \code{Matrix} library (usually much faster!). Default: \code{FALSE}.} } \details{ For details about the method see the Steiner et al. (1999) reference listed below. Basically, two individual CUSUMs are run each based on a logistic regression model. The combined CUSUM not only signals if one of its two individual CUSUMs signals, but also if the two CUSUMs simultaneously cross the secondary limits. } \seealso{\code{\link{categoricalCUSUM}}} \value{An \code{sts} object with \code{observed}, \code{alarm}, etc. slots trimmed to the \code{control$range} indices. } \references{ Steiner, S. H., Cook, R. J., and Farewell, V. T. (1999), Monitoring paired binary surgical outcomes using cumulative sum charts, Statistics in Medicine, 18, pp. 69--86. } \examples{ #Set in-control and out-of-control parameters as in paper theta0 <- c(-2.3,-4.5,2.5) theta1 <- c(-1.7,-2.9,2.5) #Small helper function to compute the paired-binary likelihood #of the length two vector yz when the true parameters are theta dPBin <- function(yz,theta) { exp(dbinom(yz[1],size=1,prob=plogis(theta[1]),log=TRUE) + dbinom(yz[2],size=1,prob=plogis(theta[2]+theta[3]*yz[1]),log=TRUE)) } #Likelihood ratio for all four possible configurations p <- c(dPBin(c(0,0), theta=theta0), dPBin(c(0,1), theta=theta0), dPBin(c(1,0), theta=theta0), dPBin(c(1,1), theta=theta0)) \dontshow{if (surveillance.options("allExamples"))} #Compute ARL using non-sparse matrix operations pairedbinCUSUM.runlength(p,w1=c(-1,37,-9,29),w2=c(-1,7),h1=70,h2=32, h11=38,h22=17) #Sparse computations can be considerably (!) faster pairedbinCUSUM.runlength(p,w1=c(-1,37,-9,29),w2=c(-1,7),h1=70,h2=32, h11=38,h22=17,sparse=TRUE) #Use paired binary CUSUM on the De Leval et al. (1994) arterial switch #operation data on 104 newborn babies data("deleval") #Switch between death and near misses observed(deleval) <- observed(deleval)[,c(2,1)] #Run paired-binary CUSUM without generating alarms. pb.surv <- pairedbinCUSUM(deleval,control=list(theta0=theta0, theta1=theta1,h1=Inf,h2=Inf,h11=Inf,h22=Inf)) plot(pb.surv, xaxis.labelFormat=NULL, ylab="CUSUM Statistic") ###################################################################### #Scale the plots so they become comparable to the plots in Steiner et #al. (1999). To this end a small helper function is defined. ###################################################################### ###################################################################### #Log LR for conditional specification of the paired model ###################################################################### LLR.pairedbin <- function(yz,theta0, theta1) { #In control alphay0 <- theta0[1] ; alphaz0 <- theta0[2] ; beta0 <- theta0[3] #Out of control alphay1 <- theta1[1] ; alphaz1 <- theta1[2] ; beta1 <- theta1[3] #Likelihood ratios llry <- (alphay1-alphay0)*yz[1]+log(1+exp(alphay0))-log(1+exp(alphay1)) llrz <- (alphaz1-alphaz0)*yz[2]+log(1+exp(alphaz0+beta0*yz[1]))- log(1+exp(alphaz1+beta1*yz[1])) return(c(llry=llry,llrz=llrz)) } val <- expand.grid(0:1,0:1) table <- t(apply(val,1, LLR.pairedbin, theta0=theta0, theta1=theta1)) w1 <- min(abs(table[,1])) w2 <- min(abs(table[,2])) S <- upperbound(pb.surv) / cbind(rep(w1,nrow(observed(pb.surv))),w2) #Show results opar <- par(mfcol=c(2,1)) plot(1:nrow(deleval),S[,1],type="l",main="Near Miss",xlab="Patient No.", ylab="CUSUM Statistic") lines(c(0,1e99), c(32,32),lty=2,col=2) lines(c(0,1e99), c(17,17),lty=2,col=3) plot(1:nrow(deleval),S[,2],type="l",main="Death",xlab="Patient No.", ylab="CUSUM Statistic") lines(c(0,1e99), c(70,70),lty=2,col=2) lines(c(0,1e99), c(38,38),lty=2,col=3) par(opar) ###################################################################### # Run the CUSUM with thresholds as in Steiner et al. (1999). # After each alarm the CUSUM statistic is set to zero and # monitoring continues from this point. Triangles indicate alarm # in the respective CUSUM (nearmiss or death). If in both # simultaneously then an alarm is caued by the secondary limits. ###################################################################### pb.surv2 <- pairedbinCUSUM(deleval,control=list(theta0=theta0, theta1=theta1,h1=70*w1,h2=32*w2,h11=38*w1,h22=17*w2)) plot(pb.surv2, xaxis.labelFormat=NULL) } \author{S. Steiner and M. \enc{Hhle}{Hoehle}} \keyword{regression} surveillance/man/hhh4_plot.Rd0000644000176200001440000004531714615113341015712 0ustar liggesusers\encoding{latin1} \name{hhh4_plot} \alias{plot.hhh4} \alias{plotHHH4_fitted} \alias{plotHHH4_fitted1} \alias{plotHHH4_season} \alias{getMaxEV_season} \alias{plotHHH4_maxEV} \alias{getMaxEV} \alias{plotHHH4_maps} \alias{plotHHH4_ri} \alias{plotHHH4_neweights} \title{Plots for Fitted \code{hhh4}-models} \description{ There are six \code{type}s of plots for fitted \code{\link{hhh4}} models: \itemize{ \item Plot the \code{"fitted"} component means (of selected units) along time along with the observed counts. \item Plot the estimated \code{"season"}ality of the three components. \item Plot the time-course of the dominant eigenvalue \code{"maxEV"}. \item If the units of the corresponding multivariate \code{"\linkS4class{sts}"} object represent different regions, maps of the fitted mean components averaged over time (\code{"maps"}), or a map of estimated region-specific intercepts (\code{"ri"}) of a selected model component can be produced. \item Plot the (estimated) neighbourhood weights (\code{"neweights"}) as a function of neighbourhood order (shortest-path distance between regions), i.e., \code{w_ji ~ o_ji}. } Spatio-temporal \code{"hhh4"} models and these plots are illustrated in Meyer et al. (2017, Section 5), see \code{vignette("hhh4_spacetime")}. } \usage{ \method{plot}{hhh4}(x, type=c("fitted", "season", "maxEV", "maps", "ri", "neweights"), ...) plotHHH4_fitted(x, units = 1, names = NULL, col = c("grey85", "blue", "orange"), pch = 19, pt.cex = 0.6, pt.col = 1, par.settings = list(), legend = TRUE, legend.args = list(), legend.observed = FALSE, decompose = NULL, total = FALSE, meanHHH = NULL, ...) plotHHH4_fitted1(x, unit = 1, main = NULL, col = c("grey85", "blue", "orange"), pch = 19, pt.cex = 0.6, pt.col = 1, border = col, start = x$stsObj@start, end = NULL, xaxis = NULL, xlim = NULL, ylim = NULL, xlab = "", ylab = "No. infected", hide0s = FALSE, decompose = NULL, total = FALSE, meanHHH = NULL) plotHHH4_season(..., components = NULL, intercept = FALSE, xlim = NULL, ylim = NULL, xlab = NULL, ylab = "", main = NULL, par.settings = list(), matplot.args = list(), legend = NULL, legend.args = list(), refline.args = list(), unit = 1, period = NULL) getMaxEV_season(x, period = x$stsObj@freq) plotHHH4_maxEV(..., matplot.args = list(), refline.args = list(), legend.args = list()) getMaxEV(x) plotHHH4_maps(x, which = c("mean", "endemic", "epi.own", "epi.neighbours"), prop = FALSE, main = which, zmax = NULL, col.regions = NULL, labels = FALSE, sp.layout = NULL, ..., map = x$stsObj@map, meanHHH = NULL) plotHHH4_ri(x, component, exp = FALSE, at = list(n = 10), col.regions = cm.colors(100), colorkey = TRUE, labels = FALSE, sp.layout = NULL, gpar.missing = list(col = "darkgrey", lty = 2, lwd = 2), ...) plotHHH4_neweights(x, plotter = boxplot, ..., exclude = 0, maxlag = Inf) } \arguments{ \item{x}{a fitted \code{\link{hhh4}} object.} \item{type}{type of plot: either \code{"fitted"} component means of selected \code{units} along time along with the observed counts, or \code{"season"}ality plots of the model components and the epidemic dominant eigenvalue (which may also be plotted along overall time by \code{type="maxEV"}, especially if the model contains time-varying neighbourhood weights or unit-specific epidemic effects), or \code{"maps"} of the fitted mean components averaged over time, or a map of estimated region-specific random intercepts (\code{"ri"}) of a specific model \code{component}. The latter two require \code{x$stsObj} to contain a map.} \item{\dots}{For \code{plotHHH4_season} and \code{plotHHH4_maxEV}, one or more \code{\link{hhh4}}-fits, or a single list of these. Otherwise further arguments passed on to other functions.\cr For the \code{plot}-method these go to the specific plot \code{type} function.\cr \code{plotHHH4_fitted} passes them to \code{plotHHH4_fitted1}, which is called sequentially for every unit in \code{units}.\cr \code{plotHHH4_maps} and \code{plotHHH4_ri} pass additional arguments to \code{\link[sp]{spplot}}, and \code{plotHHH4_neweights} to the \code{plotter}.} \item{units,unit}{integer or character vector specifying a single \code{unit} or possibly multiple \code{units} to plot. It indexes \code{colnames(x$stsObj)}.\cr In \code{plotHHH4_fitted}, \code{units=NULL} plots all units.\cr In the seasonality plot, selection of a unit is only relevant if the model contains unit-specific intercepts or seasonality terms.} \item{names,main}{main title(s) for the selected \code{unit}(\code{s}) / \code{components}. If \code{NULL} (default), \code{plotHHH4_fitted1} will use the appropriate element of \code{colnames(x$stsObj)}, whereas \code{plotHHH4_season} uses default titles.} \item{col,border}{length 3 vectors specifying the fill and border colors for the endemic, autoregressive, and spatio-temporal component polygons (in this order).} \item{pch,pt.cex,pt.col}{style specifications for the dots drawn to represent the observed counts. \code{pch=NA} can be used to disable these dots.} \item{par.settings}{list of graphical parameters for \code{\link{par}}. Sensible defaults for \code{mfrow}, \code{mar} and \code{las} will be applied unless overridden or \code{!is.list(par.settings)}.} \item{legend}{Integer vector specifying in which of the \code{length(units)} frames the legend should be drawn. If a logical vector is supplied, \code{which(legend)} determines the frame selection, i.e., the default is to drawn the legend in the first (upper left) frame only, and \code{legend=FALSE} results in no legend being drawn.} \item{legend.args}{list of arguments for \code{\link{legend}}, e.g., to modify the default positioning \code{list(x="topright", inset=0.02)}.} \item{legend.observed}{logical indicating if the legend should contain a line for the dots corresponding to observed counts.} \item{decompose}{if \code{TRUE} or (a permutation of) \code{colnames(x$stsObj)}, the fitted mean will be decomposed into the contributions from each single unit and the endemic part instead of the default endemic + AR + neighbours decomposition.} \item{total}{logical indicating if the fitted components should be summed over all units to be compared with the total observed counts at each time point. If \code{total=TRUE}, the \code{units}/\code{unit} argument is ignored.} \item{start,end}{time range to plot specified by vectors of length two in the form \code{c(year,number)}, see \code{"\linkS4class{sts}"}.} \item{xaxis}{if this is a list (of arguments for \code{\link{addFormattedXAxis}}), the time axis is nicely labelled similar to \code{\link{stsplot_time}}. Note that in this case or if \code{xaxis = NA}, the basic time indexes \code{1:nrow(x$stsObj)} will be used as x coordinates, which is different from the long-standing default (\code{xaxis = NULL}) with a real time scale.} \item{xlim}{numeric vector of length 2 specifying the x-axis range. The default (\code{NULL}) is to plot the complete time range (\code{type="fitted"}) or period (\code{type="season"}), respectively.} \item{ylim}{y-axis range. For \code{type="fitted"}, this defaults to \code{c(0,max(observed(x$stsObj)[,unit]))}. For \code{type="season"}, \code{ylim} must be a list of length \code{length(components)} specifying the range for every component plot, or a named list to customize only a subset of these. If only one \code{ylim} is specified, it will be recycled for all \code{components} plots.} \item{xlab,ylab}{axis labels. For \code{plotHHH4_season}, \code{ylab} specifies the y-axis labels for all \code{components} in a list (similar to \code{ylim}). If \code{NULL} or incomplete, default mathematical expressions are used. If a single name is supplied such as the default \code{ylab=""} (to omit y-axis labels), it is used for all \code{components}.} \item{hide0s}{logical indicating if dots for zero observed counts should be omitted. Especially useful if there are too many.} \item{meanHHH}{(internal) use different component means than those estimated and available from \code{x}.} \item{components}{character vector of component names, i.e., a subset of \code{c("ar", "ne", "end")}, for which to plot the estimated seasonality. If \code{NULL} (the default), only components which appear in any of the models in \code{\dots} are plotted.\cr A seasonality plot of the epidemic dominant eigenvalue is also available by including \code{"maxEV"} in \code{components}, but it only supports models without epidemic covariates/offsets.} \item{intercept}{logical indicating whether to include the global intercept. For \code{plotHHH4_season}, the default (\code{FALSE}) means to plot seasonality as a multiplicative effect on the respective component. Multiplication by the intercept only makes sense if there are no further (non-centered) covariates/offsets in the component.} \item{exp}{logical indicating whether to \code{exp}-transform the color-key axis labels to show the multiplicative effect of the region-specific random intercept on the respective component. Axis labels are then computed using \code{\link[scales]{log_breaks}} from package \pkg{scales} (if that is available) or \code{\link{axisTicks}} (as a fallback) respecting the \code{colorkey$tick.number} setting (default: 7). The default is \code{FALSE}.} \item{at}{a numeric vector of breaks for the color levels (see \code{\link[lattice]{levelplot}}), or a list specifying the number of breaks \code{n} (default: 10) and their \code{range} (default: range of the random effects, extended to be symmetric around 0). In the latter case, breaks are equally spaced (on the original, non-\code{exp} scale of the random intercepts). If \code{exp=TRUE}, custom breaks (or \code{range}) need to be given on the exp-scale.} \item{matplot.args}{list of line style specifications passed to \code{\link{matplot}}, e.g., \code{lty}, \code{lwd}, \code{col}.} \item{refline.args}{list of line style specifications (e.g., \code{lty} or \code{col}) passed to \code{\link{abline}} when drawing the reference line (\code{h=1}) in plots of seasonal effects (if \code{intercept=FALSE}) and of the dominant eigenvalue. The reference line is omitted if \code{refline.args} is not a list.} \item{period}{a numeric value giving the (longest) period of the harmonic terms in the model. This usually coincides with the \code{freq} of the data (the default), but needs to be adjusted if the model contains harmonics with a longer periodicity.} \item{which}{a character vector specifying the components of the mean for which to produce maps. By default, the overall mean and all three components are shown.} \item{prop}{a logical indicating whether the component maps should display proportions of the total mean instead of absolute numbers.} \item{zmax}{a numeric vector of length \code{length(which)} (recycled as necessary) specifying upper limits for the color keys of the maps, using a lower limit of 0. A missing element (\code{NA}) means to use a map-specific color key only covering the range of the values in that map (can be useful for \code{prop = TRUE}). The default \code{zmax = NULL} means to use the same scale for the component maps and a separate scale for the map showing the overall mean.} \item{col.regions}{a vector of colors used to encode the fitted component means (see \code{\link[lattice]{levelplot}}). For \code{plotHHH4_maps}, the length of this color vector also determines the number of levels, using 10 heat colors by default.} \item{colorkey}{a Boolean indicating whether to draw the color key. Alternatively, a list specifying how to draw it, see \code{\link[lattice]{levelplot}}.} \item{map}{an object inheriting from \code{"\linkSPclass{SpatialPolygons}"} with \code{row.names} covering \code{colnames(x)}.} \item{component}{component for which to plot the estimated region-specific random intercepts. Must partially match one of \code{colnames(ranef(x, tomatrix=TRUE))}.} \item{labels}{determines if and how regions are labeled, see \code{\link{layout.labels}}.} \item{sp.layout}{optional list of additional layout items, see \code{\link[sp]{spplot}}.} \item{gpar.missing}{list of graphical parameters for \code{\link[sp]{sp.polygons}}, applied to regions with missing random intercepts, i.e., not included in the model. Such extra regions won't be plotted if \code{!is.list(gpar.missing)}.} \item{plotter}{the (name of a) function used to produce the plot of weights (a numeric vector) as a function of neighbourhood order (a factor variable). It is called as \code{plotter(Weight ~ Distance, ...)} and defaults to \code{\link{boxplot}}. A useful alternative is, e.g., \code{\link[lattice]{stripplot}} from package \pkg{lattice}.} \item{exclude}{vector of neighbourhood orders to be excluded from plotting (passed to \code{\link{factor}}). By default, the neighbourhood weight for order 0 is not shown, which is usually zero anyway.} \item{maxlag}{maximum order of neighbourhood to be assumed when computing the \code{\link{nbOrder}} matrix. This additional step is necessary iff \code{neighbourhood(x$stsObj)} only specifies a binary adjacency matrix.} } \value{ \code{plotHHH4_fitted1} invisibly returns a matrix of the fitted component means for the selected \code{unit}, and \code{plotHHH4_fitted} returns these in a list for all \code{units}.\cr \code{plotHHH4_season} invisibly returns the plotted y-values, i.e. the multiplicative seasonality effect within each of \code{components}. Note that this will include the intercept, i.e. the point estimate of \eqn{exp(intercept + seasonality)} is plotted and returned.\cr \code{getMaxEV_season} returns a list with elements \code{"maxEV.season"} (as plotted by \code{plotHHH4_season(..., components="maxEV")}, \code{"maxEV.const"} and \code{"Lambda.const"} (the Lambda matrix and its dominant eigenvalue if time effects are ignored).\cr \code{plotHHH4_maxEV} (invisibly) and \code{getMaxEV} return the dominant eigenvalue of the \eqn{\Lambda_t} matrix for all time points \eqn{t} of \code{x$stsObj}.\cr \code{plotHHH4_maps} returns a \code{\link[lattice]{trellis.object}} if \code{length(which) == 1} (a single \code{\link[sp]{spplot}}), and otherwise uses \code{\link[gridExtra]{grid.arrange}} from the \pkg{gridExtra} package to arrange all \code{length(which)} \code{\link[sp]{spplot}}s on a single page. \code{plotHHH4_ri} returns the generated \code{\link[sp]{spplot}}, i.e., a \code{\link[lattice]{trellis.object}}.\cr \code{plotHHH4_neweights} eventually calls \code{plotter} and thus returns whatever is returned by that function. } \author{ Sebastian Meyer } \references{ Held, L. and Paul, M. (2012): Modeling seasonality in space-time infectious disease surveillance data. \emph{Biometrical Journal}, \bold{54}, 824-843. \doi{10.1002/bimj.201200037} Meyer, S., Held, L. and \enc{Hhle}{Hoehle}, M. (2017): Spatio-temporal analysis of epidemic phenomena using the \R package \pkg{surveillance}. \emph{Journal of Statistical Software}, \bold{77} (11), 1-55. \doi{10.18637/jss.v077.i11} } \seealso{ other methods for \code{hhh4} fits, e.g., \code{\link{summary.hhh4}}. } \examples{ data("measlesWeserEms") ## fit a simple hhh4 model measlesModel <- list( ar = list(f = ~ 1), end = list(f = addSeason2formula(~0 + ri(type="iid"), S=1, period=52), offset = population(measlesWeserEms)), family = "NegBin1" ) measlesFit <- hhh4(measlesWeserEms, measlesModel) ## fitted values for a single unit plot(measlesFit, units=2) ## sum fitted components over all units plot(measlesFit, total=TRUE) ## 'xaxis' option for a nicely formatted time axis ## default tick locations and labels: plot(measlesFit, total=TRUE, xaxis=list(epochsAsDate=TRUE, line=1)) ## an alternative with monthly ticks: oopts <- surveillance.options(stsTickFactors = c("\%m"=0.75, "\%Y" = 1.5)) plot(measlesFit, total=TRUE, xaxis=list(epochsAsDate=TRUE, xaxis.tickFreq=list("\%m"=atChange, "\%Y"=atChange), xaxis.labelFreq=list("\%Y"=atMedian), xaxis.labelFormat="\%Y")) surveillance.options(oopts) ## plot the multiplicative effect of seasonality plot(measlesFit, type="season") ## alternative fit with biennial pattern, plotted jointly with original fit measlesFit2 <- update(measlesFit, end = list(f = addSeason2formula(~0 + ri(type="iid"), S=2, period=104))) plotHHH4_season(measlesFit, measlesFit2, components="end", period=104) ## dominant eigenvalue of the Lambda matrix (cf. Held and Paul, 2012) getMaxEV(measlesFit) # here simply constant and equal to exp(ar.1) plot(measlesFit, type="maxEV") # not very exciting ## fitted mean components/proportions by district, averaged over time if (requireNamespace("gridExtra")) { plot(measlesFit, type="maps", labels=list(cex=0.6), which=c("endemic", "epi.own"), prop=TRUE, zmax=NA, main=c("endemic proportion", "autoregressive proportion")) } ## estimated random intercepts of the endemic component round(nu0 <- fixef(measlesFit)["end.ri(iid)"], 4) # global intercept round(ranefs <- ranef(measlesFit, tomatrix = TRUE), 4) # zero-mean deviations stopifnot(all.equal( nu0 + ranefs, ranef(measlesFit, intercept = TRUE) # local intercepts (log-scale) )) plot(measlesFit, type="ri", component="end", main="deviations around the endemic intercept (log-scale)") exp(ranef(measlesFit)) # multiplicative effects, plotted below plot(measlesFit, type="ri", component="end", exp=TRUE, main="multiplicative effects", labels=list(font=3, labels="GEN")) ## neighbourhood weights as a function of neighbourhood order plot(measlesFit, type="neweights") # boring, model has no "ne" component ## fitted values for the 6 regions with most cases and some customization bigunits <- tail(names(sort(colSums(observed(measlesWeserEms)))), 6) plot(measlesFit, units=bigunits, names=measlesWeserEms@map@data[bigunits,"GEN"], legend=5, legend.args=list(x="top"), xlab="Time (weekly)", hide0s=TRUE, ylim=c(0,max(observed(measlesWeserEms)[,bigunits])), start=c(2002,1), end=c(2002,26), par.settings=list(xaxs="i")) } \keyword{hplot} surveillance/man/stsplot_time.Rd0000644000176200001440000002037314200475573016552 0ustar liggesusers\encoding{latin1} \name{stsplot_time} \alias{stsplot_time} \alias{stsplot_time1} \alias{stsplot_alarm} \title{ Time-Series Plots for \code{"sts"} Objects } \description{ These are the \code{plot} variants of \code{type=observed~time|unit}, \code{type=observed~time}, and \code{type=alarm~time} for \code{"\linkS4class{sts}"} objects (see the central \code{"sts"} \code{\link[=plot,sts,missing-method]{plot}}-method for an overview of plot types). } \usage{ stsplot_time(x, units=NULL, as.one=FALSE, same.scale=TRUE, par.list=list(), ...) stsplot_time1(x, k=1, ylim=NULL, axes=TRUE, xaxis.tickFreq=list("\%Q"=atChange), xaxis.labelFreq=xaxis.tickFreq, xaxis.labelFormat="\%G\n\n\%OQ", epochsAsDate=x@epochAsDate, xlab="time", ylab="No. infected", main=NULL, type="s", lty=c(1,1,2), col=c(NA,1,4), lwd=c(1,1,1), outbreak.symbol=list(pch=3, col=3, cex=1, lwd=1), alarm.symbol=list(pch=24, col=2, cex=1, lwd=1), legend.opts=list(), dx.upperbound=0L, hookFunc=function(){}, .hookFuncInheritance=function() {}, ...) stsplot_alarm(x, lvl=rep(1,ncol(x)), xaxis.tickFreq=list("\%Q"=atChange), xaxis.labelFreq=xaxis.tickFreq, xaxis.labelFormat="\%G\n\n\%OQ", epochsAsDate=x@epochAsDate, xlab="time", ylab="", main=NULL, outbreak.symbol=list(pch=3, col=3, cex=1, lwd=1), alarm.symbol=list(pch=24, col=2, cex=1, lwd=1), cex.yaxis=1, ...) } \arguments{ \item{x}{an object of class \code{"\linkS4class{sts}"}.} \item{units}{optional integer or character vector to select the units (=columns of \code{observed(x)}) to plot. The default is to plot all time series. If \code{as.one=FALSE}, \code{stsplot_time1} is called \code{for (k in units)} with \code{mfrow} splitting (see \code{par.list}). Note that if there are too many \code{units}, the default \code{mfrow} setting might lead to the error \dQuote{figure margins too large} (meaning that the units do not fit onto a single page).} \item{as.one}{logical indicating if all time series should be plotted in a single frame (using \code{\link{matplot}}).} \item{same.scale}{logical indicating if all time series should be plotted with the same \code{ylim}. Default is to do so. Only relevant for multivariate plots (\code{ncol(x) > 1}).} \item{par.list}{a list of arguments delivered to a call of \code{\link{par}} to set graphical parameters before plotting. The \code{mfrow} splitting is handled per default. Afterwards, the \code{par}ameters are reverted to their original values. Use \code{par.list=NULL} to disable the internal \code{par} call.} \item{k}{the unit to plot, i.e., an element of \code{1:ncol(x)}.} \item{ylim}{the y limits of the plot(s). Ignored if \code{same.scale=FALSE}.} \item{axes}{a logical value indicating whether both axes should be drawn on the plot.} \item{xaxis.tickFreq,xaxis.labelFreq,xaxis.labelFormat}{ arguments for \code{\link{addFormattedXAxis}} if \code{epochsAsDate=TRUE}. Use \code{xaxis.labelFormat=NULL} to get a standard x-axis (without date labels).} \item{epochsAsDate}{Boolean indicating whether to treat the epochs as Date objects (or to transform them to dates such that the new x-axis formatting is applied). Default: Value of the \code{epochAsDate} slot of \code{x}.} \item{xlab}{a title for the x axis. See \code{plot.default}.} \item{ylab}{a title for the y axis. See \code{plot.default}.} \item{main}{an overall title for the plot: see 'title'.} \item{type}{type of plot to do.} \item{lty}{vector of length 3 specifying the line type for the three lines in the plot -- see \code{col} argument.} \item{col}{Vector of length 3 specifying the color to use in the plot. The first color is the fill color of the polygons for the counts bars (\code{NA} for unfilled), the 2nd element denotes their border color, the 3rd element is the color of the \code{upperbound} plotting.} \item{lwd}{Vector of length 3 specifying the line width of the three elements to plot. See also the \code{col} argument.} \item{alarm.symbol}{a list with entries \code{pch}, \code{col}, \code{cex} and \code{lwd} specifying the appearance of the outbreak symbol in the plot.} \item{outbreak.symbol}{a list with entries \code{pch}, \code{col}, \code{cex} and \code{lwd} specifying the appearance of the outbreak symbol in the plot.} \item{legend.opts}{a list of arguments for the \code{\link{legend}}. If \code{\link{missing}(legend.opts)} (i.e., not explicitly specified), the default legend will only be added if the \code{"sts"} object contains outbreaks, alarms, or upperbounds. The default legend options are \describe{ \item{\code{x}}{\code{"top"}} \item{\code{legend}}{\code{c("Infected","Threshold","Outbreak","Alarm")[included]}} \item{\code{lty,lwd,pch,col}}{the corresponding graphical settings of the included elements} } where individual elements are only \code{included} in the legend if they are plotted (except for alarms, which are also included if upperbounds exist). To disable the legend, use \code{legend.opts=NULL}. } \item{dx.upperbound}{horizontal change in the plotting of the upperbound line. Sometimes it can be convenient to offset this line a little for better visibility.} \item{lvl}{A vector of length \code{ncol(x)}, which is used to specify the hierarchy level for each time series in the sts object for alarm plots.} \item{cex.yaxis}{The magnification to be used for y-axis annotation.} \item{hookFunc}{a function that is called after all the basic plotting has be done, i.e., it is not possible to control formatting with this function. See Examples.} \item{.hookFuncInheritance}{a function which is altered by sub-classes plot method. Do not alter this function manually.} \item{...}{further arguments for the function \code{matplot}. If e.g. \code{xlab} or \code{main} are provided they overwrite the default values.} } \details{ The time series plot relies on the work-horse \code{stsplot_time1}. Its arguments are (almost) similar to \code{\link{plot.survRes}}. } \value{ \code{NULL} (invisibly). The functions are called for their side-effects. } \author{ Michael H\enc{}{oe}hle and Sebastian Meyer } \seealso{ There is an \code{\link[=autoplot.sts]{autoplot}}-method, which implements \CRANpkg{ggplot2}-based time-series plots of \code{"sts"} objects. The \code{\link{stsplot}} help page gives an overview of other types of plots for \code{"sts"} objects. } \examples{ data("ha.sts") print(ha.sts) plot(ha.sts, type=observed ~ time | unit) # default multivariate type plot(ha.sts, units=c("mitt", "pank")) # selected units plot(ha.sts, type=observed ~ time) # aggregated over all districts ## Hook function example hookFunc <- function() grid(NA,NULL,lwd=1) plot(ha.sts, hookFunc=hookFunc) ## another multivariate time series example plotted "as.one" data("measlesDE") plot(measlesDE, units=1:2, as.one=TRUE, legend.opts=list(cex=0.8)) ## more sophisticated plots are offered by package "xts" if (requireNamespace("xts")) plot(as.xts.sts(measlesDE)) ## Use ISO8601 date formatting (see ?strptime) and no legend data("salmNewport") plot(aggregate(salmNewport,by="unit"), xlab="Time (weeks)", xaxis.tickFreq=list("\%m"=atChange,"\%G"=atChange), xaxis.labelFreq=list("\%G"=atMedian),xaxis.labelFormat="\%G") ## Formatting now also works for daily data (illustrate by artifical ## outbreak converted to sts object by linelist2sts) set.seed(123) exposureTimes <- as.Date("2014-03-12") + sample(x=0:25,size=99,replace=TRUE) sts <- linelist2sts(data.frame(exposure=exposureTimes), dateCol="exposure",aggregate.by="1 day") ## Plot it with larger ticks for days than usual surveillance.options("stsTickFactors"=c("\%d"=1, "\%W"=0.33, "\%V"=0.33, "\%m"=1.75, "\%Q"=1.25, "\%Y"=1.5, "\%G"=1.5)) plot(sts,xaxis.tickFreq=list("\%d"=atChange,"\%m"=atChange), xaxis.labelFreq=list("\%d"=at2ndChange),xaxis.labelFormat="\%d-\%b", xlab="Time (days)") } \keyword{hplot} \keyword{ts} surveillance/man/epidataCS_permute.Rd0000644000176200001440000000270713263671176017430 0ustar liggesusers\name{epidataCS_permute} \alias{permute.epidataCS} \title{ Randomly Permute Time Points or Locations of \code{"epidataCS"} } \description{ Monte Carlo tests for space-time interaction (\code{\link{epitest}}) use the distribution of some test statistic under the null hypothesis of no space-time interaction. For this purpose, the function \code{permute.epidataCS} randomly permutes the time or space labels of the events. } \usage{ permute.epidataCS(x, what = c("time", "space"), keep) } \arguments{ \item{x}{an object of class \code{"\link{epidataCS}"}.} \item{what}{character string determining what to permute: time points (default) or locations.} \item{keep}{optional logical expression to be evaluated in the context of \code{x$events@data}, determining for which events the time and location should be kept as is. For instance, to keep some \dQuote{prehistory} before time point 30 unchanged, use \code{keep = time <= 30}.} } \value{ the permuted \code{"\link{epidataCS}"} object. } \author{ Sebastian Meyer } \seealso{ \code{\link{epitest}} } \examples{ data("imdepi") set.seed(3) permepi <- permute.epidataCS(imdepi, what = "time", keep = time <= 30) print(imdepi, n = 8) print(permepi, n = 8) ## the first 6 events are kept (as are all row.names), ## the time labels of the remaining events are shuffled ## (and events then again sorted by time), ## the marginal temporal distribution is unchanged } \keyword{manip} surveillance/man/twinstim_tiaf.Rd0000644000176200001440000000535312265262002016674 0ustar liggesusers\name{twinstim_tiaf} \alias{tiaf} \title{ Temporal Interaction Function Objects } \description{ A temporal interaction function for use in \code{\link{twinstim}} can be constructed via the \code{tiaf} function. It checks the supplied function elements, assigns defaults for missing arguments, and returns all checked arguments in a list. However, for standard applications it is much easier to use one of the pre-defined temporal interaction functions, e.g., \code{\link{tiaf.exponential}}. } \usage{ tiaf(g, G, deriv, Deriv, npars, validpars = NULL) } \arguments{ \item{g}{the temporal interaction function. It must accept two arguments, the first one being a vector of time points, the second one a parameter vector. For marked \code{twinstim}, it must accept the type of the event (integer code) as its third argument (either a single type for all locations or separate types for each location).} \item{G}{a primitive of \eqn{g(t)} (with respect to time). It must accept the same arguments as \code{g}, for instance a \emph{vector} of time points (not just a single one).} \item{deriv}{optional derivative of \eqn{g(t)} \emph{with respect to the parameters}. It takes the same arguments as \code{g} but returns a matrix with as many rows as there were time points in the input and \code{npars} columns. This derivative is necessary for the calculation of the score function in \code{twinstim()}, which is advantageous for the numerical log-likelihood maximization.} \item{Deriv}{optional primitive of \code{deriv} (with respect to time). It must accept the same arguments as \code{deriv}, \code{g} and \code{G} and returns a matrix with as many rows as there were time points in the input and \code{npars} columns. The integrated derivative is necessary for the score function in \code{twinstim}.} \item{npars}{the number of parameters of the temporal interaction function \code{g} (i.e. the length of its second argument).} \item{validpars}{ optional function taking one argument, the parameter vector, indicating if it is valid. This approach to specify parameter constraints is rarely needed, because usual box-constrained parameters can be taken into account by using L-BFGS-B as the optimization method in \code{twinstim} (with arguments \code{lower} and \code{upper}), and positivity constraints by using log-parametrizations. This component is not necessary (and ignored) if \code{npars == 0}. } } \value{ list of checked arguments. } \author{ Sebastian Meyer } \seealso{ \code{\link{tiaf.exponential}} for a pre-defined temporal interaction function, and \code{\link{siaf}} for the spatial interaction function. } \keyword{utilities} surveillance/man/twinSIR_exData.Rd0000644000176200001440000000051313562264564016651 0ustar liggesusers\name{twinSIR_exData} \alias{fooepidata} \docType{data} \title{ Toy Data for \code{twinSIR} } \description{ Toy \code{"\link{epidata}"} previously used to exemplify \code{\link{twinSIR}} models. We now use the well-known \code{\link{hagelloch}} dataset. } \usage{ data(fooepidata) } \keyword{datasets} \keyword{internal} surveillance/man/imdepifit.Rd0000644000176200001440000000171014431622644015767 0ustar liggesusers\name{imdepifit} \alias{imdepifit} \docType{data} \title{ Example \code{twinstim} Fit for the \code{imdepi} Data } \description{ \code{data("imdepifit")} is a \code{\link{twinstim}} model fitted to the \code{\link{imdepi}} data. } \usage{data("imdepifit")} \format{ an object of class \code{"\link{twinstim}"} obtained from the following call using \code{data(imdepi)}: \Sexpr[stage=build,results=verbatim]{ data(imdepifit, package="surveillance") writeLines(deparse(imdepifit$call, width.cutoff = 25)) } } \seealso{ common methods for \code{"twinstim"} fits, exemplified using \code{imdepifit}, e.g., \code{\link{summary.twinstim}}, \code{\link{plot.twinstim}}, and \code{\link{simulate.twinstim}} } \examples{ data("imdepi", "imdepifit") ## how this fit was obtained imdepifit$call \dontshow{if (surveillance.options("allExamples"))} ## reproduce "imdepifit" stopifnot(all.equal(imdepifit, eval(imdepifit$call))) } \keyword{datasets} surveillance/man/categoricalCUSUM.Rd0000644000176200001440000001546314614717045017124 0ustar liggesusers\name{categoricalCUSUM} \alias{categoricalCUSUM} \alias{catcusum.LLRcompute} \encoding{latin1} \title{CUSUM detector for time-varying categorical time series} \description{ Function to process \code{sts} object by binomial, beta-binomial or multinomial CUSUM as described by \enc{Hhle}{Hoehle} (2010). Logistic, multinomial logistic, proportional odds or Bradley-Terry regression models are used to specify in-control and out-of-control parameters. The implementation is illustrated in Salmon et al. (2016). } \usage{ categoricalCUSUM(stsObj,control = list(range=NULL,h=5,pi0=NULL, pi1=NULL, dfun=NULL, ret=c("cases","value")),...) } \arguments{ \item{stsObj}{Object of class \code{sts} containing the number of counts in each of the \eqn{k} categories of the response variable. Time varying number of counts \eqn{n_t} is found in slot \code{populationFrac}. } \item{control}{Control object containing several items \describe{ \item{\code{range}}{Vector of length \eqn{t_{max}} with indices of the \code{observed} slot to monitor.} \item{\code{h}}{Threshold to use for the monitoring. Once the CUSUM statistics is larger or equal to \code{h} we have an alarm.} \item{\code{pi0}}{\eqn{(k-1) \times t_{max}} in-control probability vector for all categories except the reference category.} \item{\code{mu1}}{\eqn{(k-1) \times t_{max}} out-of-control probability vector for all categories except the reference category.} \item{\code{dfun}}{The probability mass function (PMF) or density used to compute the likelihood ratios of the CUSUM. In a negative binomial CUSUM this is \code{dnbinom}, in a binomial CUSUM \code{dbinom} and in a multinomial CUSUM \code{dmultinom}. The function must be able to handle the arguments \code{y}, \code{size}, \code{mu} and \code{log}. As a consequence, one in the case of, e.g, the beta-binomial distribution has to write a small wrapper function.} \item{\code{ret}}{Return the necessary proportion to sound an alarm in the slot \code{upperbound} or just the value of the CUSUM statistic. Thus, \code{ret} is one of the values in \code{c("cases","value")}. Note: For the binomial PMF it is possible to compute this value explicitly, which is much faster than the numeric search otherwise conducted. In case \code{dfun} just corresponds to \code{dbinom} just set the attribute \code{isBinomialPMF} for the \code{dfun} object.} }} \item{\dots}{Additional arguments to send to \code{dfun}.} } \details{ The function allows the monitoring of categorical time series as described by regression models for binomial, beta-binomial or multinomial data. The later includes e.g. multinomial logistic regression models, proportional odds models or Bradley-Terry models for paired comparisons. See the \enc{Hhle}{Hoehle} (2010) reference for further details about the methodology. Once an alarm is found the CUSUM scheme is reset (to zero) and monitoring continues from there. } \seealso{\code{\link{LRCUSUM.runlength}}} \value{An \code{sts} object with \code{observed}, \code{alarm}, etc. slots trimmed to the \code{control$range} indices. } \references{ \enc{Hhle}{Hoehle}, M. (2010): Online Change-Point Detection in Categorical Time Series. In: T. Kneib and G. Tutz (Eds.), Statistical Modelling and Regression Structures, Physica-Verlag. Salmon, M., Schumacher, D. and \enc{Hhle}{Hoehle}, M. (2016): Monitoring count time series in \R: Aberration detection in public health surveillance. \emph{Journal of Statistical Software}, \bold{70} (10), 1-35. \doi{10.18637/jss.v070.i10} } \examples{ \dontshow{## IGNORE_RDIFF_BEGIN} have_GAMLSS <- require("gamlss") \dontshow{## IGNORE_RDIFF_END} if (have_GAMLSS) { ########################################################################### #Beta-binomial CUSUM for a small example containing the time-varying #number of positive test out of a time-varying number of total #test. ####################################### #Load meat inspection data data("abattoir") #Use GAMLSS to fit beta-bin regression model phase1 <- 1:(2*52) phase2 <- (max(phase1)+1) : nrow(abattoir) #Fit beta-binomial model using GAMLSS abattoir.df <- as.data.frame(abattoir) #Replace the observed and epoch column names to something more convenient dict <- c("observed"="y", "epoch"="t", "population"="n") replace <- dict[colnames(abattoir.df)] colnames(abattoir.df)[!is.na(replace)] <- replace[!is.na(replace)] m.bbin <- gamlss( cbind(y,n-y) ~ 1 + t + + sin(2*pi/52*t) + cos(2*pi/52*t) + + sin(4*pi/52*t) + cos(4*pi/52*t), sigma.formula=~1, family=BB(sigma.link="log"), data=abattoir.df[phase1,c("n","y","t")]) #CUSUM parameters R <- 2 #detect a doubling of the odds for a test being positive h <- 4 #threshold of the cusum #Compute in-control and out of control mean pi0 <- predict(m.bbin,newdata=abattoir.df[phase2,c("n","y","t")],type="response") pi1 <- plogis(qlogis(pi0)+log(R)) #Create matrix with in control and out of control proportions. #Categories are D=1 and D=0, where the latter is the reference category pi0m <- rbind(pi0, 1-pi0) pi1m <- rbind(pi1, 1-pi1) ###################################################################### # Use the multinomial surveillance function. To this end it is necessary # to create a new abattoir object containing counts and proportion for # each of the k=2 categories. For binomial data this appears a bit # redundant, but generalizes easier to k>2 categories. ###################################################################### abattoir2 <- sts(epoch=1:nrow(abattoir), start=c(2006,1), freq=52, observed=cbind(abattoir@observed, abattoir@populationFrac-abattoir@observed), populationFrac=cbind(abattoir@populationFrac,abattoir@populationFrac), state=matrix(0,nrow=nrow(abattoir),ncol=2), multinomialTS=TRUE) ###################################################################### #Function to use as dfun in the categoricalCUSUM #(just a wrapper to the dBB function). Note that from v 3.0-1 the #first argument of dBB changed its name from "y" to "x"! ###################################################################### mydBB.cusum <- function(y, mu, sigma, size, log = FALSE) { return(dBB(y[1,], mu = mu[1,], sigma = sigma, bd = size, log = log)) } #Create control object for multinom cusum and use the categoricalCUSUM #method control <- list(range=phase2,h=h,pi0=pi0m, pi1=pi1m, ret="cases", dfun=mydBB.cusum) surv <- categoricalCUSUM(abattoir2, control=control, sigma=exp(m.bbin$sigma.coef)) #Show results plot(surv[,1],dx.upperbound=0) lines(pi0,col="green") lines(pi1,col="red") #Index of the alarm which.max(alarms(surv[,1])) } } \author{M. \enc{Hhle}{Hoehle}} \keyword{regression} surveillance/man/layout.labels.Rd0000644000176200001440000001070414614160257016576 0ustar liggesusers\name{layout.labels} \alias{layout.labels} \alias{layout.scalebar} \title{ Layout Items for \code{spplot} } \description{ Generate \code{sp.layout} items for use by \code{\link[sp]{spplot}} or plot these items directly in the traditional graphics system. Function \code{layout.labels} draws labels at the coordinates of the spatial object, and \code{layout.scalebar} returns a labeled scale bar. } \usage{ layout.labels(obj, labels = TRUE, plot = FALSE) layout.scalebar(obj, corner = c(0.05, 0.95), scale = 1, labels = c(0, scale), height = 0.05, pos = 3, ..., plot = FALSE) } \arguments{ \item{obj}{ an object inheriting from a \code{"\linkSPclass{Spatial}"} class. } \item{labels}{ specification of the labels. For \code{layout.labels}: \itemize{ \item a \code{FALSE} or \code{NULL} value omits labels (\code{NULL} is returned), \item \code{labels = TRUE} uses \code{row.names(obj)}, \item a character or numeric index for a column of \code{obj@data} which contains suitable labels, \item a vector of length \code{length(obj)} with labels, \item or a list of arguments for \code{\link[lattice]{panel.text}}, where the optional \code{labels} component follows the same rules as above. } For \code{layout.scalebar}, a character vector of length two giving the labels to be put above the left and right ends of the scale bar. } \item{corner}{ the location of the scale bar in the unit square, where \code{c(0,0)} refers to the bottom left corner. By default, the scale bar is placed in the top left corner (with a small buffer). } \item{scale}{ the width of the scale bar in the units of \code{\link[sp]{proj4string}(obj)}. If \code{identical(FALSE, \link[sp]{is.projected}(obj))} (i.e., \code{obj} has longlat coordinates), \code{scale} is interpreted in kilometres. } \item{height}{ the height of the scale bar, see \code{\link[sp]{layout.scale.bar}}. } \item{pos}{ a position specifier for the labels (see \code{\link{text}}). By default, the labels are plotted above the scale bar. } \item{\dots}{ further arguments for \code{\link[lattice]{panel.text}} (if \code{plot = FALSE}) or \code{\link{text}} (if \code{plot = TRUE}) to change the style of the labels, e.g., \code{cex}, \code{col}, and \code{font}. } \item{plot}{ logical indicating if the layout item should be plotted using the traditional graphics system. By default (\code{FALSE}), a list for subsequent use by \code{\link[sp]{spplot}} is returned. } } \value{ For \code{layout.labels}, a single \code{sp.layout} item, which is a list with first element \code{"panel.text"} and subsequent elements being arguments to that function based on the \code{labels} specification. For \code{layout.scalebar}, a list of \code{sp.layout} items comprising the polygonal scale bar and the labels. If these layout functions are called with \code{plot = TRUE}, the item is plotted directly using traditional graphics functions and \code{NULL} is returned. } \author{ Sebastian Meyer } \examples{if (requireNamespace("sf")) { # required by recent 'sp' ## districts in the Regierungsbezirk Weser-Ems (longlat coordinates) data("measlesWeserEms") mapWE <- measlesWeserEms@map li1 <- layout.labels(mapWE, labels = list(font=2, labels="GEN")) li2 <- layout.scalebar(mapWE, corner = c(0.05, 0.05), scale = 20, labels = c("0", "20 km")) spplot(mapWE, zcol = "AREA", sp.layout = c(list(li1), li2), col.regions = rev(heat.colors(100)), scales = list(draw = TRUE)) ## districts in Bavaria (projected coordinates) load(system.file("shapes", "districtsD.RData", package = "surveillance")) bavaria <- districtsD[substr(row.names(districtsD), 1, 2) == "09", ] sb <- layout.scalebar(bavaria, corner = c(0.75,0.9), scale = 50, labels = c("0", "50 km"), cex = 0.8) spplot(bavaria, zcol = "POPULATION", sp.layout = sb, xlab = "x [km]", ylab = "y [km]", scales = list(draw = TRUE), col.regions = rev(heat.colors(100))) ## these layout functions also work in the traditional graphics system par(mar = c(0,0,0,0)) plot(bavaria, col = "lavender") layout.scalebar(bavaria, corner = c(0.75, 0.9), scale = 50, labels = c("0", "50 km"), plot = TRUE) layout.labels(bavaria, labels = list(cex = 0.8, labels = substr(bavaria$GEN, 1, 3)), plot = TRUE) } } \keyword{aplot} \keyword{dplot} surveillance/man/deleval.Rd0000644000176200001440000000274114100450412015417 0ustar liggesusers\name{deleval} \alias{deleval} \docType{data} \title{Surgical Failures Data} \description{ The dataset from Steiner et al. (1999) on A synthetic dataset from the Danish meat inspection -- useful for illustrating the beta-binomial CUSUM. } \usage{data(deleval)} \details{ Steiner et al. (1999) use data from de Leval et al. (1994) to illustrate monitoring of failure rates of a surgical procedure for a bivariate outcome. Over a period of six years an arterial switch operation was performed on 104 newborn babies. Since the death rate from this surgery was relatively low the idea of surgical "near miss" was introduced. It is defined as the need to reinstitute cardiopulmonary bypass after a trial period of weaning. The object of class \code{\linkS4class{sts}} contains the recordings of near misses and deaths from the surgery for the 104 newborn babies of the study. The data could also be handled by a multinomial CUSUM model. } \seealso{\code{\link{pairedbinCUSUM}}} \examples{ data("deleval") plot(deleval, xaxis.labelFormat=NULL,ylab="Response",xlab="Patient number") } \references{ Steiner, S. H., Cook, R. J., and Farewell, V. T. (1999), Monitoring paired binary surgical outcomes using cumulative sum charts, Statistics in Medicine, 18, pp. 69--86. De Leval, Marc R., Franiois, K., Bull, C., Brawn, W. B. and Spiegelhalter, D. (1994), Analysis of a cluster of surgical failures, Journal of Thoracic and Cardiovascular Surgery, March, pp. 914--924. } \keyword{datasets} surveillance/man/twinSIR_cox.Rd0000644000176200001440000000134312672347154016234 0ustar liggesusers\name{twinSIR_cox} \alias{cox} \title{ Identify Endemic Components in an Intensity Model } \description{ The special function \code{cox} marks terms in formulae of the functions \code{\link{twinSIR}} and \code{\link{simEpidata}} as endemic components, i.e. variables acting multiplicatively on the baseline infection intensity. An illustrative \code{twinSIR} call with two epidemic and two endemic covariates is: \code{twinSIR(~B1 + B2 + cox(vaccination) + cox(size), data=myEpidata)}. Technically, this function is implemented as \code{function(x) {x}} and defined as \dQuote{special} in \code{\link{terms.formula}}. } \seealso{ Usage in formulae of functions \code{\link{twinSIR}} and \code{\link{simEpidata}}. } \keyword{internal} surveillance/man/imdepi.Rd0000644000176200001440000001737714614160257015304 0ustar liggesusers\encoding{latin1} \docType{data} \name{imdepi} \alias{imdepi} \title{ Occurrence of Invasive Meningococcal Disease in Germany } \description{ \code{imdepi} contains data on the spatio-temporal location of 636 cases of invasive meningococcal disease (IMD) caused by the two most common meningococcal finetypes in Germany, \samp{B:P1.7-2,4:F1-5} (of serogroup B) and \samp{C:P1.5,2:F3-3} (of serogroup C). } \usage{ data("imdepi") } \format{ \code{imdepi} is an object of class \code{"\link{epidataCS}"} (a list with components \code{events}, \code{stgrid}, \code{W} and \code{qmatrix}). } \details{ The \code{imdepi} data is a simplified version of what has been analyzed by Meyer et al. (2012). Simplification is with respect to the temporal resolution of the \code{stgrid} (see below) to be used in \code{\link{twinstim}}'s endemic model component. In what follows, we describe the elements \code{events}, \code{stgrid}, \code{W}, and \code{qmatrix} of \code{imdepi} in greater detail. \code{imdepi$events} is a \code{"\linkSPclass{SpatialPointsDataFrame}"} object (ETRS89 projection, i.e. EPSG code 3035, with unit \sQuote{km}) containing 636 events, each with the following entries: \describe{ \item{time:}{Time of the case occurrence measured in number of days since origin. Note that a U(0,1)-distributed random number has been subtracted from each of the original event times (days) to break ties (using \code{\link{untie}(imdepi_tied, amount=list(t=1))}).} \item{tile:}{Tile ID in the spatio-temporal grid (\code{stgrid}) of endemic covariates, where the event is contained in. This corresponds to one of the 413 districts of Germany. } \item{type:}{Event type, a factor with levels \code{"B"} and \code{"C"}.} \item{eps.t:}{Maximum temporal interaction range for the event. Here set to 30 days.} \item{eps.s:}{Maximum spatial interaction range for the event. Here set to 200 km.} \item{sex:}{Sex of the case, i.e. a factor with levels \code{"female"} and \code{"male"}. Note: for some cases this information is not available (\code{NA}).} \item{agegrp:}{Factor giving the age group of the case, i.e. 0-2, 3-18 or >=19. Note: for one case this information is not available (\code{NA}).} \item{BLOCK, start:}{Block ID and start time (in days since origin) of the cell in the spatio-temporal endemic covariate grid, which the event belongs to.} \item{popdensity:}{Population density (per square km) at the location of the event (corresponds to population density of the district where the event is located).} } There are further auxiliary columns attached to the events' data the names of which begin with a . (dot): These are created during conversion to the \code{"epidataCS"} class and are necessary for fitting the data with \code{twinstim}, see the description of the \code{"\link{epidataCS}"}-class. With \code{coordinates(imdepi$events)} one obtains the (x,y) locations of the events. The district identifier in \code{tile} is indexed according to the German official municipality key ( \dQuote{Amtlicher Gemeindeschl\enc{}{ue}ssel}). See \url{https://de.wikipedia.org/wiki/Amtlicher_Gemeindeschl\%C3\%BCssel} for details. The data component \code{stgrid} contains the spatio-temporal grid of endemic covariate information. In addition to the usual bookkeeping variables this includes: \describe{ \item{area:}{Area of the district \code{tile} in square kilometers.} \item{popdensity:}{Population density (inhabitants per square kilometer) computed from DESTATIS (Federal Statistical Office) information (Date: 31.12.2008) on communities level (LAU2) aggregated to district level (NUTS3).} } We have actually not included any time-dependent covariates here, we just established this grid with a (reduced -> fast) temporal resolution of \emph{monthly} intervals so that we can model endemic time trends and seasonality (in this discretized time). The entry \code{W} contains the observation window as a \code{"\linkSPclass{SpatialPolygons}"} object, in this case the boundaries of Germany (\code{stateD}). It was obtained as the \dQuote{UnaryUnion} of Germany's districts (\code{districtsD}) as at 2009-01-01, simplified by the \dQuote{modified Visvalingam} algorithm (level 6.6\%) available at \url{https://MapShaper.org} (v. 0.1.17). The objects \code{districtsD} and \code{stateD} are contained in \code{system.file("shapes", "districtsD.RData", package="surveillance")}. The entry \code{qmatrix} is a \eqn{2\times 2}{2 x 2} identity matrix indicating that no transmission between the two finetypes can occur. } \source{ IMD case reports: German Reference Centre for Meningococci at the Department of Hygiene and Microbiology, Julius-Maximilians-Universit\enc{}{ae}t W\enc{}{ue}rzburg, Germany (\url{https://www.hygiene.uni-wuerzburg.de/meningococcus/}). Thanks to Dr. Johannes Elias and Prof. Dr. Ulrich Vogel for providing the data. Shapefile of Germany's districts as at 2009-01-01: German Federal Agency for Cartography and Geodesy, Frankfurt am Main, Germany, \url{https://gdz.bkg.bund.de/}. %% "Copy, distribution and making available to the public - also in %% parts - is allowed with reference." } \references{ Meyer, S., Elias, J. and H\enc{}{oe}hle, M. (2012): A space-time conditional intensity model for invasive meningococcal disease occurrence. \emph{Biometrics}, \bold{68}, 607-616. \doi{10.1111/j.1541-0420.2011.01684.x} } \seealso{ the data class \code{"\link{epidataCS}"}, and function \code{\link{twinstim}} for model fitting. } \examples{ data("imdepi") # Basic information print(imdepi, n=5, digits=2) # What is an epidataCS-object? str(imdepi, max.level=4) names(imdepi$events@data) # => events data.frame has hidden columns sapply(imdepi$events@data, class) # marks and print methods ignore these auxiliary columns # look at the B type only imdepiB <- subset(imdepi, type == "B") #<- subsetting applies to the 'events' component imdepiB # select only the last 10 events tail(imdepi, n=10) # there is also a corresponding 'head' method # Access event marks str(marks(imdepi)) # there is an update-method which assures that the object remains valid # when changing parameters like eps.s, eps.t or qmatrix update(imdepi, eps.t = 20) # Summary s <- summary(imdepi) s str(s) # Step function of number of infectives plot(s$counter, xlab = "Time [days]", ylab = "Number of infectious individuals", main = "Time series of IMD assuming 30 days infectious period") # distribution of number of potential sources of infection opar <- par(mfrow=c(1,2), las=1) for (type in c("B","C")) { plot(100*prop.table(table(s$nSources[s$eventTypes==type])), xlim=range(s$nSources), xlab = "Number of potential epidemic sources", ylab = "Proportion of events [\%]") } par(opar) # a histogram of the number of events along time (using the # plot-method for the epidataCS-class, see ?plot.epidataCS) opar <- par(mfrow = c(2,1)) plot(imdepi, "time", subset = type == "B", main = "Finetype B") plot(imdepi, "time", subset = type == "C", main = "Finetype C") par(opar) # Plot the spatial distribution of the events in W plot(imdepi, "space", points.args = list(col=c("indianred", "darkblue"))) # or manually (no legends, no account for tied locations) plot(imdepi$W, lwd=2, asp=1) % to avoid sp -> sf plot(imdepi$events, pch=c(3,4)[imdepi$events$type], cex=0.8, col=c("indianred", "darkblue")[imdepi$events$type], add=TRUE) \dontrun{ # Show a dynamic illustration of the spatio-temporal dynamics of the # spread during the first year of type B with a step size of 7 days animate(imdepiB, interval=c(0,365), time.spacing=7, sleep=0.1) } } \keyword{datasets} surveillance/man/nbOrder.Rd0000644000176200001440000000303214402466607015412 0ustar liggesusers\name{nbOrder} \alias{nbOrder} \title{ Determine Neighbourhood Order Matrix from Binary Adjacency Matrix } \description{ Given a square binary adjacency matrix, the function \code{nbOrder} determines the integer matrix of neighbourhood orders (shortest-path distance). } \usage{ nbOrder(neighbourhood, maxlag = Inf) } \arguments{ \item{neighbourhood}{ a square, numeric or logical, and usually symmetric matrix with finite entries (and usually zeros on the diagonal) which indicates vertex adjacencies, i.e., first-order neighbourhood (interpreted as \code{neighbourhood == 1}, \emph{not} \code{>0}). } \item{maxlag}{ positive scalar integer specifying an upper bound for the neighbourhood order. The default (\code{Inf}) means no truncation (but orders cannot be larger than the number of regions minus 1), whereas \code{maxlag = 1} just returns the input neighbourhood matrix (converted to binary integer mode). } } \value{ An integer matrix of neighbourhood orders, i.e., the shortest-path distance matrix of the vertices. The \code{dimnames} of the input \code{neighbourhood} matrix are preserved. } \author{ Sebastian Meyer } \seealso{ \code{\link[spdep]{nblag}} from the \pkg{spdep} package } \examples{ ## generate adjacency matrix set.seed(1) n <- 6 adjmat <- matrix(0, n, n) adjmat[lower.tri(adjmat)] <- sample(0:1, n*(n-1)/2, replace=TRUE) adjmat <- adjmat + t(adjmat) adjmat ## determine neighbourhood order matrix nblags <- nbOrder(adjmat) nblags } \keyword{spatial} \keyword{utilities} surveillance/man/twinstim_epitest.Rd0000644000176200001440000002124714614160257017437 0ustar liggesusers\encoding{latin1} \name{twinstim_epitest} \alias{epitest} \alias{coef.epitest} \alias{plot.epitest} \title{Permutation Test for Space-Time Interaction in \code{"twinstim"}} \description{ The function \code{epitest} takes a \code{"twinstim"} model and tests if the spatio-temporal interaction invoked by the epidemic model component is statistically significant. The test only works for simple epidemic models, where \code{epidemic = ~1} (no additional parameters for event-specific infectivity), and requires the non-canonical \code{epilink="identity"} (see \code{\link{twinstim}}). A permutation test is performed by default, which is only valid if the endemic intensity is space-time separable. The approach is described in detail in Meyer et al. (2016), where it is also compared to alternative global tests for clustering such as the \code{\link{knox}} test. } \usage{ epitest(model, data, tiles, method = "time", B = 199, eps.s = NULL, eps.t = NULL, fixed = NULL, verbose = TRUE, compress = FALSE, ...) \method{coef}{epitest}(object, which = c("m1", "m0"), ...) \method{plot}{epitest}(x, teststat = c("simpleR0", "D"), ...) } \arguments{ \item{model}{ a simple epidemic \code{"\link{twinstim}"} with \code{epidemic = ~1}, fitted using the non-canonical \code{epilink="identity"}. Note that the permutation test is only valid for models with a space-time separable endemic intensity, where covariates vary either in space or time but not both. } \item{data}{ an object of class \code{"\link{epidataCS}"}, the \code{data} to which the \code{model} was fitted. } \item{tiles}{ (only used by \code{method = "simulate"}) a \code{"\linkSPclass{SpatialPolygons}"} representation of the \code{tile}s in \code{data$stgrid}. } \item{method}{ one of the following character strings specifying the test method: \describe{ \item{\code{"LRT"}:}{ a simple likelihood ratio test of the epidemic \code{model} against the corresponding endemic-only model, } \item{\code{"time"}/\code{"space"}:}{ a Monte Carlo permutation test where the null distribution is obtained by relabeling time points or locations, respectively (using \code{\link{permute.epidataCS}}). } \item{\code{"simulate"}:}{ obtain the null distribution of the test statistic by simulations from the endemic-only model (using \code{\link{simEndemicEvents}}). } } } \item{B}{ the number of permutations for the Monte Carlo approach. The default number is rather low; if computationally feasible, \code{B = 999} is more appropriate. Note that this determines the \dQuote{resolution} of the p-value: the smallest attainable p-value is \code{1/(B+1)}. } \item{eps.s,eps.t}{arguments for \code{\link{simpleR0}}.} \item{fixed}{ optional character vector naming parameters to fix at their original value when re-fitting the \code{model} on permuted data. The special value \code{fixed = TRUE} means to fix all epidemic parameters but the intercept. } \item{verbose}{ the amount of tracing in the range \code{0:3}. Set to 0 (or \code{FALSE}) for no output, 1 (or \code{TRUE}, the default) for a progress bar, 2 for the test statistics resulting from each permutation, and to 3 for additional tracing of the log-likelihood maximization in each permutation (not useful if parallelized). Tracing does not work if permutations are parallelized using clusters. See \code{\link{plapply}} for other choices. } \item{compress}{ logical indicating if the \code{nobs}-dependent elements \code{"fitted"}, \code{"fittedComponents"}, and \code{"R0"} should be dropped from the permutation-based model fits. Not keeping these elements saves a lot of memory especially with a large number of events. Note, however, that the returned \code{permfits} then no longer are fully valid \code{"twinstim"} objects (but most methods will still work). } \item{\dots}{further arguments for \code{\link{plapply}} to configure parallel operation, i.e., \code{.parallel} as well as \code{.seed} to make the results reproducible.\cr For the \code{plot}-method, further arguments passed to \code{\link{truehist}}.\cr Ignored by the \code{coef}-method. } \item{object,x}{ an object of class \code{"epitest"} as returned by \code{epitest}. } \item{which}{ a character string indicating either the full (\code{"m1"}, default) or the endemic-only (\code{"m0"}) model. } \item{teststat}{ a character string determining the test statistic to plot, either \code{"\link{simpleR0}"} or \code{"D"} (twice the log-likelihood difference of the models). } } \value{ a list (inheriting from \code{"htest"}) with the following components: \item{method}{a character string indicating the type of test performed.} \item{data.name}{a character string giving the supplied \code{data} and \code{model} arguments.} \item{statistic}{the observed test statistic.} \item{parameter}{the (effective) number of permutations used to calculate the p-value (only those with convergent fits are used).} \item{p.value}{the p-value for the test. For the \code{method}s involving resampling under the null (\code{method != "LRT"}), it is based on the subset of convergent fits only and the p-value from the simple LRT is attached as an attribute \code{"LRT"}.} In addition, if \code{method != "LRT"}, the result will have the following elements: \item{permfits}{the list of model fits (endemic-only and epidemic) from the \code{B} permutations.} \item{permstats}{a data frame with \code{B} rows and the columns \code{"l0"} (log-likelihood of the endemic-only model \code{m0}), \code{"l1"} (log-likelihood of the epidemic model \code{m1}), \code{"D"} (twice their difference), \code{"simpleR0"} (the results of \code{\link{simpleR0}(m1, eps.s, eps.t)}), and \code{"converged"} (a boolean indicator if both models converged).} The \code{plot}-method invisibly returns \code{NULL}. The \code{coef}-method returns the \code{B} x \code{length(coef(model))} matrix of parameter estimates. } \details{ This space-time interaction test is limited to models with \code{epidemic = ~1}, since covariate effects are not identifiable under the null hypothesis of no space-time interaction. Estimating a rich epidemic \code{model} based on permuted data will most likely result in singular convergence. A similar issue might arise when the model employs parametric interaction functions, in which case \code{fixed=TRUE} can be used. For further details see Meyer et al. (2016). The test statistic is the reproduction number \code{\link{simpleR0}}. A likelihood ratio test of the supplied epidemic model against the corresponding endemic-only model is also available. By default, the null distribution of the test statistic under no space-time interaction is obtained by a Monte Carlo permutation approach (via \code{\link{permute.epidataCS}}) and therefore relies on a space-time separable endemic model component. The \code{plot}-method shows a \code{\link{truehist}} of the simulated null distribution together with the observed value. The \code{coef}-method extracts the parameter estimates from the \code{B} \code{permfits} (by default for the full model \code{which = "m1"}). } \references{ Meyer, S., Warnke, I., R\enc{}{oe}ssler, W. and Held, L. (2016): Model-based testing for space-time interaction using point processes: An application to psychiatric hospital admissions in an urban area. \emph{Spatial and Spatio-temporal Epidemiology}, \bold{17}, 15-25. \doi{10.1016/j.sste.2016.03.002}. Eprint: \url{https://arxiv.org/abs/1512.09052}. } \author{ Sebastian Meyer } \seealso{ \code{\link{permute.epidataCS}}, \code{\link{knox}} } \examples{ data("imdepi", "imdepifit") ## test for space-time interaction of the B-cases ## assuming spatial interaction to be constant within 50 km imdepiB50 <- update(subset(imdepi, type == "B"), eps.s = 50) imdfitB50 <- update(imdepifit, data = imdepiB50, subset = NULL, epidemic = ~1, epilink = "identity", siaf = NULL, start = c("e.(Intercept)" = 0)) ## simple likelihood ratio test epitest(imdfitB50, imdepiB50, method = "LRT") ## permutation test et <- epitest(imdfitB50, imdepiB50, B = 5, # CAVE: limited here for speed verbose = 2, # (tracing does not work on Windows .seed = 1, .parallel = 1) # if parallelized) et plot(et) ## summary of parameter estimates under permutation summary(coef(et, which = "m1")) } \keyword{htest} surveillance/man/disProg2sts.Rd0000644000176200001440000000161512672030523016236 0ustar liggesusers\name{disProg2sts} \alias{disProg2sts} \alias{sts2disProg} \title{Convert disProg object to sts and vice versa} \description{ A small helper function to convert a \code{disProg} object to become an object of the S4 class \code{sts} and vice versa. In the future the \code{sts} should replace the \code{disProg} class, but for now this function allows for conversion between the two formats. } \usage{ disProg2sts(disProgObj, map=NULL) sts2disProg(sts) } \arguments{ \item{disProgObj}{an object of class \code{"disProg"}} \item{map}{an optional \code{"SpatialPolygons"} object} \item{sts}{an object of class \code{"sts"} to convert} } \value{ an object of class \code{"sts"} or \code{"disProg"}, respectively. } \seealso{ \code{\link{sts-class}} } \examples{ data(ha) print(disProg2sts(ha)) class(sts2disProg(disProg2sts(ha))) } \keyword{utilities} surveillance/man/salmHospitalized.Rd0000644000176200001440000000116113174706302017326 0ustar liggesusers\name{salmHospitalized} \alias{salmHospitalized} \docType{data} \title{Hospitalized Salmonella cases in Germany 2004-2014} \description{ Reported number of cases of Salmonella in Germany 2004-2014 (early 2014) that were hospitalized. The corresponding total number of cases is indicated in the slot \code{populationFrac} and \code{multinomialTS} is \code{TRUE}. } \usage{data(salmHospitalized)} \format{ An \code{"\linkS4class{sts}"} object. } \source{ The data are queried from the Survstat@RKI database of the German Robert Koch Institute (\url{https://survstat.rki.de/}). } \keyword{datasets} surveillance/man/sim.pointSource.Rd0000644000176200001440000000514213431030260017103 0ustar liggesusers\name{sim.pointSource} \alias{sim.pointSource} \encoding{latin1} \title{Simulate Point-Source Epidemics} \description{ Simulation of epidemics which were introduced by point sources. The basis of this programme is a combination of a Hidden Markov Model (to get random timepoints for outbreaks) and a simple model (compare \code{\link{sim.seasonalNoise}}) to simulate the baseline. } \usage{ sim.pointSource(p = 0.99, r = 0.01, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K) } \arguments{ \item{p}{probability to get a new outbreak at time i if there was one at time i-1, default 0.99.} \item{r}{probability to get no new outbreak at time i if there was none at time i-1, default 0.01.} \item{length}{number of weeks to model, default 400. \code{length} is ignored if \code{state} is given. In this case the length of \code{state} is used.} \item{A}{amplitude (range of sinus), default = 1.} \item{alpha}{parameter to move along the y-axis (negative values not allowed) with alpha > = A, default = 1.} \item{beta}{regression coefficient, default = 0.} \item{phi}{factor to create seasonal moves (moves the curve along the x-axis), default = 0.} \item{frequency}{factor to determine the oscillation-frequency, default = 1.} \item{state}{use a state chain to define the status at this timepoint (outbreak or not). If not given a Markov chain is generated by the programme, default NULL.} \item{K}{additional weigth for an outbreak which influences the distribution parameter mu, default = 0.} } \value{ a \code{disProg} (disease progress) object including a list of the observed, the state chain and nearly all input parameters. } \seealso{\code{\link{sim.seasonalNoise}}} \author{M. \enc{Hhle}{Hoehle}, A. Riebler, C. Lang} \examples{ set.seed(123) disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 208, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 2) plot(disProgObj) ## with predefined state chain state <- rep(c(0,0,0,0,0,0,0,0,1,1), 20) disProgObj <- sim.pointSource(state = state, K = 1.2) plot(disProgObj) ## simulate epidemic, send to RKI 1 system, plot, and compute quality values testSim <- function (..., K = 0, range = 200:400) { disProgObj <- sim.pointSource(..., K = K) survResults <- algo.call(disProgObj, control = list(list(funcName = "rki1", range = range))) plot(survResults[[1]], "RKI 1", "Simulation") algo.compare(survResults) } testSim(K = 2) testSim(r = 0.5, K = 5) # larger and more frequent outbreaks } \keyword{datagen} surveillance/man/abattoir.Rd0000644000176200001440000000160013174712261015616 0ustar liggesusers\name{abattoir} \alias{abattoir} \docType{data} \encoding{latin1} \title{Abattoir Data} \description{ A synthetic dataset from the Danish meat inspection -- useful for illustrating the beta-binomial CUSUM. } \usage{ data(abattoir) } \details{ The object of class \code{"sts"} contains an artificial data set inspired by meat inspection data used by Danish Pig Production, Denmark. For each week the number of pigs with positive audit reports is recorded together with the total number of audits made that week. } \seealso{\code{\link{categoricalCUSUM}}} \examples{ data("abattoir") plot(abattoir) population(abattoir) } \references{ \enc{Hhle}{Hoehle}, M. (2010): Online change-point detection in categorical time series. In: T. Kneib and G. Tutz (Eds.), Statistical Modelling and Regression Structures, Physica-Verlag. } \keyword{datasets} surveillance/man/residualsCT.Rd0000644000176200001440000000444713433452051016243 0ustar liggesusers\name{residualsCT} \alias{residuals.twinSIR} \alias{residuals.twinstim} \alias{residuals.simEpidataCS} \title{ Extract Cox-Snell-like Residuals of a Fitted Point Process } \description{ Extract the \dQuote{residual process} (cf. Ogata, 1988) of a fitted point process model specified through the conditional intensity function, for instance a model of class \code{"\link{twinSIR}"} or \code{"\link{twinstim}"} (and also \code{"\link{simEpidataCS}"}). The residuals are defined as the fitted cumulative intensities at the event times, and are generalized residuals similar to those discussed in Cox and Snell (1968). } \usage{ \method{residuals}{twinSIR}(object, ...) \method{residuals}{twinstim}(object, ...) \method{residuals}{simEpidataCS}(object, ...) } \arguments{ \item{object}{ an object of one of the aforementioned model classes. } \item{\dots}{unused (argument of the generic).} } \details{ For objects of class \code{twinstim}, the residuals may already be stored in the object as component \code{object$tau} if the model was fitted with \code{cumCIF = TRUE} (and they always are for \code{"simEpidataCS"}). In this case, the \code{residuals} method just extracts these values. Otherwise, the residuals have to be calculated, which is only possible with access to the model environment, i.e. \code{object} must have been fitted with \code{model = TRUE}. The calculated residuals are then also appended to \code{object} for future use. However, if \code{cumCIF} and \code{model} were both set to true in the \code{object} fit, then it is not possible to calculate the residuals and the method returns an error. } \value{ Numeric vector of length the number of events of the corresponding point process fitted by \code{object}. This is the observed residual process. } \references{ Ogata, Y. (1988) Statistical models for earthquake occurrences and residual analysis for point processes. \emph{Journal of the American Statistical Association}, 83, 9-27 Cox, D. R. & Snell, E. J. (1968) A general definition of residuals. \emph{Journal of the Royal Statistical Society. Series B (Methodological)}, 30, 248-275 } \seealso{ \code{\link{checkResidualProcess}} to graphically check the goodness-of-fit of the underlying model. } \author{ Sebastian Meyer } \keyword{methods} surveillance/man/epidataCS_plot.Rd0000644000176200001440000002205314614160257016713 0ustar liggesusers\name{epidataCS_plot} \alias{plot.epidataCS} \alias{epidataCSplot_time} \alias{epidataCSplot_space} \title{ Plotting the Events of an Epidemic over Time and Space } \description{ The \code{plot} method for class \code{"epidataCS"} either plots the number of events along the time axis (\code{epidataCSplot_time}) as a \code{hist()}, or the locations of the events in the observation region \code{W} (\code{epidataCSplot_space}). The spatial plot can be enriched with tile-specific color levels to indicate attributes such as the population (using \code{\link[sp]{spplot}}). } \usage{ \method{plot}{epidataCS}(x, aggregate = c("time", "space"), subset, by = type, ...) epidataCSplot_time(x, subset, by = type, t0.Date = NULL, breaks = "stgrid", freq = TRUE, col = rainbow(nTypes), cumulative = list(), add = FALSE, mar = NULL, xlim = NULL, ylim = NULL, xlab = "Time", ylab = NULL, main = NULL, panel.first = abline(h=axTicks(2), lty=2, col="grey"), legend.types = list(), ...) epidataCSplot_space(x, subset, by = type, tiles = x$W, pop = NULL, cex.fun = sqrt, points.args = list(), add = FALSE, legend.types = list(), legend.counts = list(), sp.layout = NULL, ...) } \arguments{ \item{x}{ an object of class \code{"\link{epidataCS}"}. } \item{aggregate}{ character, one of \code{"time"} and \code{"space"}, referring to the specific plot functions \code{epidataCSplot_time} and \code{epidataCSplot_time}, respectively. For \code{"time"}, the number of events over time is plotted as \code{\link{hist}} (or \code{\link{hist.Date}}). For \code{"space"}, the observation region \code{x$W} (or the \code{tiles}) and the locations of the events therein are plotted. } \item{subset}{ logical expression indicating a subset of events to consider for plotting: missing values are taken as false. Note that the expression is evaluated in the data frame of event marks (\code{marks(x)}), which means that column names can be referred to by name (like in \code{\link{subset.data.frame}}). } \item{\dots}{ in the basic \code{plot}-method further arguments are passed to the \code{aggregate}-specific plot function. In \code{epidataCSplot_time}, further graphical parameters are passed to \code{\link{hist}} or \code{\link{hist.Date}}, respectively. In \code{epidataCSplot_space}, further arguments are passed to the \code{plot}-method for \code{"\linkSPclass{SpatialPolygons}"}, which draws \code{tiles}. } \item{by}{an expression evaluated in \code{marks(x)}, defining how events should be stratified in the plot (the result is converted to a factor), or \code{NULL} to disregard event types. By default (\code{by = type}) the plot distinguishes between event types, i.e., the bars of the temporal plot are stacked by type, and the point colors in the spatial plot differ by type, respectively.\cr Note: to select specific event types for plotting use the \code{subset} argument, e.g., \code{subset=(type=="B")}.} \item{t0.Date}{the beginning of the observation period \code{t0 = x$stgrid$start[1]} as a \code{"\link{Date}"} (or anything coercible by \code{as.Date} without further arguments), enabling a nice x-axis using \code{\link{hist.Date}} and sensible \code{breaks} of the histogram, e.g., \code{breaks="months"}. The event times then equal \code{t0.Date + as.integer(x$events$time - t0)}, i.e. possible fractional parts of the event times are removed (which ensures that using \code{breaks = "months"} or other automatic types always works).} \item{breaks}{ a specification of the histogram break points, see \code{\link{hist}} (or \code{\link{hist.Date}} if \code{t0.Date} is used). The default value \code{"stgrid"} is special and means to use the temporal grid points \code{with(x$stgrid, c(start[1L], unique.default(stop)))} as breaks (or their \code{"Date"} equivalents). } \item{freq}{see \code{\link{hist}}, defaults to \code{TRUE}.} \item{col}{fill colour for the bars of the histogram, defaults to the vector of \code{\link{rainbow}} colours.} \item{cumulative}{if a list (of style options), lines for the cumulative number of events (per type) will be added to the plot. Possible options are \code{axis} (logical), \code{lab} (axis label), \code{maxat} (single integer affecting the axis range), \code{lwd}, \code{col}, and \code{offset} (a numeric vector of length the number of types).} \item{add}{logical (default: \code{FALSE}) indicating if the plot should be added to an existing window. Ignored if an \code{\link[sp]{spplot}} is created (if \code{pop} is non-\code{NULL}).} \item{mar}{see \code{\link{par}}. The default (\code{NULL}) is \code{mar <- par("mar")}, with \code{mar[4] <- mar[2]} if an axis is requested for the \code{cumulative} numbers.} \item{xlim,ylim}{\code{NULL} provides automatic axis limits.} \item{xlab,ylab}{axis labels (with sensible defaults).} \item{main}{main title of the plot (defaults to no title).} \item{panel.first}{expression that should be evaluated after the plotting window has been set up but before the histogram is plotted. Defaults to adding horizontal grid lines.} \item{legend.types}{if a list (of arguments for \code{\link{legend}}), a legend for the event types is added to the plot in case there is more than one type.} \item{tiles}{the observation region \code{x$W} (default) or, alternatively, a \code{"\linkSPclass{SpatialPolygons}"} representation of the tiles of \code{x$stgrid}.} \item{pop}{if \code{tiles} is a \code{"\linkSPclass{SpatialPolygonsDataFrame}"}, \code{pop} can specify an attribute to be displayed in a \code{levelplot} behind the point pattern, see \code{\link[sp]{spplot}}. By default (\code{NULL}), the conventional graphics system is used to display the \code{tiles} and event locations, otherwise the result is a \code{\link[lattice]{trellis.object}}.} \item{cex.fun}{function which takes a vector of counts of events at each unique location and returns a (vector of) \code{cex} value(s) for the sizes of the corresponding \code{points}. Defaults to the \code{sqrt()} function, which for the default circular \code{pch=1} means that the area of each point is proportional to the number of events at its location.} \item{points.args}{a list of (type-specific) graphical parameters for \code{\link{points}}, specifically \code{pch}, \code{lwd}, and \code{col}, which are all recycled to give the length \code{nlevels(x$events$type)}. In contrast, a possible \code{cex} element should be scalar (default: 0.5) and multiplies the sizes obtained from \code{cex.fun}.} \item{legend.counts}{if a list (of arguments for \code{\link{legend}}), a legend illustrating the effect of \code{cex.fun} is added to the plot. This list may contain a special element \code{counts}, which is an integer vector specifying the counts to illustrate.} \item{sp.layout}{optional list of additional layout items in case \code{pop} is non-\code{NULL}, see \code{\link[sp]{spplot}}.} } \value{ For \code{aggregate="time"} (i.e., \code{epidataCSplot_time}) the data of the histogram (as returned by \code{\link{hist}}), and for \code{aggregate="space"} (i.e., \code{epidataCSplot_space}) \code{NULL}, invisibly, or the \code{\link[lattice]{trellis.object}} generated by \code{\link[sp]{spplot}} (if \code{pop} is non-\code{NULL}). } \author{ Sebastian Meyer } \seealso{ \code{\link{animate.epidataCS}} } \examples{ data("imdepi") ## show the occurrence of events along time plot(imdepi, "time", main = "Histogram of event time points") plot(imdepi, "time", by = NULL, main = "Aggregated over both event types") ## show the distribution in space plot(imdepi, "space", lwd = 2, col = "lavender") \dontshow{if (surveillance.options("allExamples")) \{} ## with the district-specific population density in the background, ## a scale bar, and customized point style load(system.file("shapes", "districtsD.RData", package = "surveillance")) districtsD$log10popdens <- log10(districtsD$POPULATION/districtsD$AREA) keylabels <- (c(1,2,5) * rep(10^(1:3), each=3))[-1] plot(imdepi, "space", tiles = districtsD, pop = "log10popdens", ## modify point style for better visibility on gray background points.args = list(pch=c(1,3), col=c("orangered","blue"), lwd=2), ## metric scale bar, see proj4string(imdepi$W) sp.layout = layout.scalebar(imdepi$W, scale=100, labels=c("0","100 km")), ## gray scale for the population density and white borders col.regions = gray.colors(100, start=0.9, end=0.1), col = "white", ## color key is equidistant on log10(popdens) scale at = seq(1.3, 3.7, by=0.05), colorkey = list(labels=list(at=log10(keylabels), labels=keylabels), title=expression("Population density per " * km^2))) \dontshow{\}} } \keyword{hplot} \keyword{methods} \keyword{spatial} surveillance/man/algo.quality.Rd0000644000176200001440000000450314531107643016427 0ustar liggesusers\name{algo.quality} \alias{algo.quality} \alias{xtable.algoQV} \title{Computation of Quality Values for a Surveillance System Result} \description{ Computation of the quality values for a surveillance system output. } \usage{ algo.quality(sts, penalty = 20) } \arguments{ \item{sts}{object of class \code{survRes} or \code{sts}, which includes the state chain and the computed alarm chain} \item{penalty}{the maximal penalty for the lag} } \value{ an object of class \code{"algoQV"}, which is a list of quality values: \item{TP}{Number of correct found outbreaks.} \item{FP}{Number of false found outbreaks.} \item{TN}{Number of correct found non outbreaks.} \item{FN}{Number of false found non outbreaks.} \item{sens}{True positive rate, meaning TP/(FN + TP).} \item{spec}{True negative rate, meaning TN/(TN + FP).} \item{dist}{Euclidean distance between (1-spec, sens) to (0,1).} \item{lag}{Lag of the outbreak recognizing by the system.} } \details{ The lag is defined as follows: In the state chain just the beginnings of an outbreak chain (outbreaks directly following each other) are considered. In the alarm chain, the range from the beginning of an outbreak until \code{min(\var{next outbreak beginning}, penalty)} timepoints is considered. The \code{penalty} timepoints were chosen, to provide an upper bound on the penalty for not discovering an outbreak. Now the difference between the first alarm by the system and the defined beginning is denoted \dQuote{the lag}. Additionally outbreaks found by the system are not punished. At the end, the mean of the lags for every outbreak chain is returned as summary lag. } \seealso{\code{\link{algo.compare}}} \examples{ # Create a test object disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 200, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) # Let this object be tested from rki1 survResObj <- algo.rki1(disProgObj, control = list(range = 50:200)) # Compute the list of quality values quality <- algo.quality(survResObj) quality # the list is printed in matrix form \dontshow{.opt <- options(xtable.comment = FALSE)} # Format as an "xtable", which is printed with LaTeX markup (by default) library("xtable") xtable(quality) \dontshow{options(.opt)} } \keyword{misc} surveillance/man/stsNClist_animate.Rd0000644000176200001440000000225214404370624017441 0ustar liggesusers\name{stsNClist_animate} \alias{stsNClist_animate} \alias{animate_nowcasts} \encoding{latin1} \title{Animate a Sequence of Nowcasts} \description{ Animate a sequence of nowcasts stored as a list. } \usage{ animate_nowcasts(nowcasts,linelist_truth, method="bayes.trunc.ddcp", control=list(dRange=NULL,anim.dRange=NULL, plot.dRange=NULL, consistent=FALSE, sys.sleep = 1, ylim=NULL,cex.names=0.7, col=c("violetred3","#2171B5","orange","blue","black", "greenyellow")), showLambda=TRUE) } \arguments{ \item{nowcasts}{A list of objects of class \code{\linkS4class{stsNC}}} \item{linelist_truth}{True linelist} \item{method}{Which method to show (has to be present in the nowcasts)} \item{control}{List with control options} \item{showLambda}{Boolean indicating whether to show the estimate for the epidemic curve (only applied to \code{bayes.trunc.ddcp})} } \value{ This function is experimental and not yet fully documented. } \author{M. \enc{Hhle}{Hoehle}} \seealso{ \url{https://staff.math.su.se/hoehle/blog/2016/07/19/nowCast.html} for a worked through example. } \keyword{hplot} surveillance/DESCRIPTION0000644000176200001440000001205514615346212014463 0ustar liggesusersPackage: surveillance Title: Temporal and Spatio-Temporal Modeling and Monitoring of Epidemic Phenomena Version: 1.23.0 Date: 2024-05-03 Authors@R: c( MH = person("Michael", "Hoehle", email = "hoehle@math.su.se", role = c("aut", "ths"), comment = c(ORCID = "0000-0002-0423-6702")), SM = person("Sebastian", "Meyer", email = "seb.meyer@fau.de", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-1791-9449")), MP = person("Michaela", "Paul", role = "aut"), LH = person("Leonhard", "Held", email = "Leonhard.Held@uzh.ch", role = c("ctb", "ths")), person("Howard", "Burkom", role = "ctb"), person("Thais", "Correa", role = "ctb"), person("Mathias", "Hofmann", role = "ctb"), person("Christian", "Lang", role = "ctb"), person("Juliane", "Manitz", role = "ctb"), person("Andrea", "Riebler", role = "ctb"), person("Daniel", "Sabanes Bove", role = "ctb"), MS = person("Maelle", "Salmon", role = "ctb"), DS = person("Dirk", "Schumacher", role = "ctb"), person("Stefan", "Steiner", role = "ctb"), person("Mikko", "Virtanen", role = "ctb"), person("Wei", "Wei", role = "ctb"), person("Valentin", "Wimmer", role = "ctb"), person("R Core Team", role = "ctb", comment = paste("A few code segments are modified", "versions of code from base R")) ) Depends: R (>= 3.6.0), methods, grDevices, graphics, stats, utils, sp (>= 1.0-15), xtable (>= 1.7-0) Imports: Rcpp (>= 0.11.1), polyCub (>= 0.8.0), MASS, Matrix, nlme, spatstat.geom LinkingTo: Rcpp, polyCub Suggests: parallel, grid, gridExtra (>= 2.0.0), lattice (>= 0.20-44), colorspace, scales, animation, msm, spc, coda, runjags, INLA, spdep, numDeriv, maxLik, gsl, fanplot, hhh4contacts, quadprog, memoise, polyclip, intervals, splancs, gamlss, MGLM (>= 0.1.0), sf, tinytest (>= 1.2.4), knitr Enhances: xts, ggplot2 Description: Statistical methods for the modeling and monitoring of time series of counts, proportions and categorical data, as well as for the modeling of continuous-time point processes of epidemic phenomena. The monitoring methods focus on aberration detection in count data time series from public health surveillance of communicable diseases, but applications could just as well originate from environmetrics, reliability engineering, econometrics, or social sciences. The package implements many typical outbreak detection procedures such as the (improved) Farrington algorithm, or the negative binomial GLR-CUSUM method of Hoehle and Paul (2008) . A novel CUSUM approach combining logistic and multinomial logistic modeling is also included. The package contains several real-world data sets, the ability to simulate outbreak data, and to visualize the results of the monitoring in a temporal, spatial or spatio-temporal fashion. A recent overview of the available monitoring procedures is given by Salmon et al. (2016) . For the retrospective analysis of epidemic spread, the package provides three endemic-epidemic modeling frameworks with tools for visualization, likelihood inference, and simulation. hhh4() estimates models for (multivariate) count time series following Paul and Held (2011) and Meyer and Held (2014) . twinSIR() models the susceptible-infectious-recovered (SIR) event history of a fixed population, e.g, epidemics across farms or networks, as a multivariate point process as proposed by Hoehle (2009) . twinstim() estimates self-exciting point process models for a spatio-temporal point pattern of infective events, e.g., time-stamped geo-referenced surveillance data, as proposed by Meyer et al. (2012) . A recent overview of the implemented space-time modeling frameworks for epidemic phenomena is given by Meyer et al. (2017) . License: GPL-2 URL: https://surveillance.R-Forge.R-project.org/ Additional_repositories: https://inla.r-inla-download.org/R/stable/ VignetteBuilder: utils, knitr NeedsCompilation: yes Packaged: 2024-05-03 14:07:02 UTC; smeyer Author: Michael Hoehle [aut, ths] (), Sebastian Meyer [aut, cre] (), Michaela Paul [aut], Leonhard Held [ctb, ths], Howard Burkom [ctb], Thais Correa [ctb], Mathias Hofmann [ctb], Christian Lang [ctb], Juliane Manitz [ctb], Andrea Riebler [ctb], Daniel Sabanes Bove [ctb], Maelle Salmon [ctb], Dirk Schumacher [ctb], Stefan Steiner [ctb], Mikko Virtanen [ctb], Wei Wei [ctb], Valentin Wimmer [ctb], R Core Team [ctb] (A few code segments are modified versions of code from base R) Maintainer: Sebastian Meyer Repository: CRAN Date/Publication: 2024-05-04 05:50:02 UTC surveillance/build/0000755000176200001440000000000014615167600014053 5ustar liggesuserssurveillance/build/vignette.rds0000644000176200001440000000127314615167600016415 0ustar liggesusersTKo0 N7Iu?mSn@ NbӶY$i{eHv^%ȏG;t:Nڣc>}G :QLh9ȹW <$J!S-/o^Jr4GUIk97KNeG[ELjcA,FcL[p`s %j&#& ϕJ@3K}+>H@`,y}B%(jV\J)2p u =X99N5$hқ_; IE1m5ˤ %7u]BrWe5,'{W1\ʄbD ؄ TRXDK2j.] :fSG8eMJZ/tVf]VrV DzG/\ƀw}I %h+)$Ƴ{7`‰Y^ wh ˌHb%iyrvo5 LDØAd) \1b%-m|ogzV,)ʼmms4+x/C~([ʰ!G]Z}I*pG\mާs dbIj6DWh5`/\hyzz(DAyzI5surveillance/build/partial.rdb0000644000176200001440000002273714615167534016221 0ustar liggesusers}YsI^q_Pv)A I"%vk!)EҀebJ,Tk!Ŗs{p8v̓&/Su HUUD;uNf7͍JnXj#5寭@LJ[Yq<|:le&_tCXZ\\|`;T7 ,љj'Zj-,fEYEy\#Ro}A=w  {iQ:@A6iuho־{#IJ A:YXn$0 N$j÷n Z_S]UP"ǐ>Z 4fQ#}M8+a ʊӏ"D$kex-s% ` $=awW7ll~ӵ"}65(0nY]RlV5yH_O3yn#"=۝湁8t ̪vc"ҋ)9Ww:Z5Q }]x%TYq \?!^K #zIpzh61%q:q]E/quID4j$o?瑞O ܎a)=uG/!. C6XD|CiaNzK5ZIH\>'e ':8dշבN5++o7o#};:8ZШS[fEU5 f(m(5<cDQ46 yy9+a(v񒬕3&?ВK2ahǰ }&qMԄ^. WKywx6҉Lm N=HOwߘ8KR)º&ʶU#eS-RR xrSk DZ~WxG~,- LfjJM1׷% 'r.M )Itz1 !^G:ST`7xD\LorWJ.8cŌ&@/*C1 ʍF*Nl񒬖KZDf"^ֺLwb希CLG.ONK܊xN}ZX+(וfy%e7u*J8Ge_ YB`FXgb*n*VlwR3V#2]} ĻH=%)6ٖ(o廆u-82-74(GT#S/w~7l(0 )EՏ1nR9To{9m :RAX64v*  Rޮek1{Ǒ~S╬G=w$H͋wjɶŸ8 ^j{E0&5gnPKZ:WXɖ ̊FrF4%H_+귟j'&݅6>2Tj-FJ] /L3?|mu Zc^܁țQ zmRn(э<ǵ&gԦ[FYVDÆِ5vWoh{<6@}/Զ#edSvTO Zuf}籂M:QKk7[.E#``h7H2'lcUFنd%"?kM9Zq=>[&둣blb=YPs kXhIW2uV\06ڷ yUI}d/heD8Pӵ=sَj+. OkCWu A>\@ܫ~ Emheas#ǹG JZ i~CTwT;>@p7GyAo[}w߿er.!Z E[i4g\D؀-f[[Lґ=XMA##EMB H::\Iuz  4eB z/D*[sffٹ4ZxC,g[32zEw闩K&M]C?CJowUf.i~hGQ?ro z8tXX?j5D|zҿK 67J.Ĝ )`DLa'ҨU%Ɨt!{_,=rO eK9%|6^yUuk_ՐR-cn]QS%q$69?oܴDXsHupooNkH^@t. ɽo8d]<8x|SK H/ih>ϥ޺,jͲUx"hkKE6Ǘ 2Y +PӪRSMм\ ,&}\S\0OjȿGiJo}A"H9īۆOY*oɊsd F<tL`Qb;2#y!1ݰt=IbRO͠w!N =q 842+M) 6OjO0Gꎫih$gK9!6um 6 مLj3II9ϥ˓%0S. \d;H;Yn<cL-Mj1A U>զH++T5 {P8 p 5颬R\? l?xKTRFƊZAF?c,5wt2^O^ƍR 2-P*g9ALΑeTUs_FgFb>1ܬ _2[] ! ^Z啕:F4H^ISdYW8.ECOZᘒ_]q@2aK ogܽs(T&uάyl̼C$!V0= f7Yj2?`HfSY)]&{ 염8:%=I$ܔbp1Op[v`h~VUM%;sLp{r-T!g 瑞OYuo}3O gH/%K[Ƞ0̬l}%ե[ #g_H9DA̮[O~y#.#-@X` >w8nCHoX, ;EgNIeEQ&QGGUj,/#hévWy/"}UZ5nN5/)MkSžd$kH/>iɇ)U7&@ Elӻmh$L,U8&VTg£#uXs&;/8nϋX ՅC0-3If7d]bm(N%rdd Ww+~.Z(M%͕/H8b?x35VXvǵ!IcA9/Z /B0$ٹ(s3b@gS:m"wT=Ai!0T!Yް&E5 iy O!$\c6_B!-?eV%f8'#6![5@5ܢ2 yă( 7tSxLIo28i{TS5iԘךvcELoF3wfSJq{f[ێE 6Gi:-y;.V" |3tsafA"Z}&v B]~SB͢ cH+|.!^E:(F̍Jctzb,x iy7l S_ŲA Ug7z q hJ_E 5H'گ'EpC A-3>CZ~нĆ`͢j43-Ġ&/2FNJ 1%'x5\aF>pcgNXGijH9v}NWO|7p":Ъtڀ<$\)9#ݜT 6Oo*iŚgyLsF @O?Gx : r`u=gڦ .SPEw\_qV_xer֬΄5 !I1FU꿾gEN$~Yna'@cWyk Df_88!. pcT'H H7x4Ä؍ C:͍1 #hFSϑL0oݙbдlq ^@@zCZG"tV83Cmӟ_@OCn-T'JփiU5晶).xiZJzajp-8!Vپ%S+( 8~ ZA"b1؅9QNXȔSoZ> AcڟSش!ZUԺT{+=n6_\~eC9|3IgǑ'`!^ӝkٍ$8, \"s{ZՌ=B߲ ٿ9u0)W$8!4nmMq}^^x%GdŁ"l{**5332ooP ,7 1}aK5-B }%@C*z9MtȭꧪG򽊸ZX"xuhQ13oyǼ'0G'mZQ碇sŽ^[ؿ|⁑qSMpG 7QB< )tC=mzs>}7,\xI1*!z̛g_} ZK`2 m%: P.T{UCt%'[%xR?0nɏIW5x { Je%QiC^=5/eVT;#e]V5KTT6>]ll]uMjYZ }B6>Pv?eɲ?$y qN 7-~統.$VSJVRnzjS?ZȠ%VT2S:u\xLM}ۣAT2瞹^`Ɇضf[Zb=5S prkO?c^/RݶrUS`ȞLwdV?G>o1 y3U7VUKC jIM^PHu!ٙ7SlSΌ}A-{o-R7Jȁq릣Ee[܈$Rt1t}.CmcBL ;%+"^]U"ksR]*?S''UJs˲D*%CBzJ.KdAw"UhUvY) hב_[2pվuپbqʏ݈DE44+4B^ﳆs3tG9h)M)mj:t]q#2)}`RVˏ_=DZ8%t.v}kyO6 etn=qˬ~#f$O^c&utѳqWF{ kM@MtfUc VTYQUGEк2~{F¯qm6 }Yzgfss.8Ŝ>7S}MPp۶j,0Qld)# &>TmڨgV /k~iѶ* ?A;Aڟ{ h߬O8\Ï3B8[aʼYn:9IFYAPHLM6OvKvqPފ:8tnzqF ekW8gv#@.hYR3euY!Х uj k5Y2P)BìG07;E©9)@^'X6ˊ^ "»~ƪYioW\,4M eȰf[?/> Z~%Fa;HIxzv+|.w~CR8c-T5C2*5Qi=#u*()AGz= 1.2.4)") q("no") } ## provide simple replacement for test_that() expectation bundles test_that <- function (desc, code) { eval(substitute(code), new.env(parent = parent.frame())) invisible() } ## show warnings as they appear options(warn = 1) ## we use verbose = 1 to print_status() only after each test file, ## not after each expression (verbose = 2) tinytest::test_package("surveillance", testdir = "testthat", verbose = 1) surveillance/tests/testthat/0000755000176200001440000000000014615164167015763 5ustar liggesuserssurveillance/tests/testthat/test-hhh4+derivatives.R0000644000176200001440000001570214406045141022230 0ustar liggesusers### Fixed effects hhh4() model fit and involved analytical derivatives data("measlesWeserEms") measlesModel <- list( end = list(f = addSeason2formula(~1 + t, S=1, period=52), offset = population(measlesWeserEms)), ar = list(f = ~1), ne = list(f = ~1 + log(pop), weights = W_powerlaw(maxlag = 5, normalize = TRUE)), family = "NegBin1", data = list(pop = population(measlesWeserEms)) ) measlesFit <- hhh4(stsObj = measlesWeserEms, control = measlesModel) test_that("estimates and standard errors are reproducible", { ## dput(coef(measlesFit, se = TRUE)) orig <- structure( c(-0.499636482022272, 0.551345030080107, 0.96093157194767, -0.153585641356373, 0.00333284018297979, 1.01500011496702, -0.588738943313705, 5.52782609236691, 1.81915612994789, 0.121781347106564, 1.27401298230559, 0.453889365025671, 0.281013375484401, 0.00459840327748742, 0.210642721317572, 0.191921649336323, 1.87984346848385, 0.265016986696184), .Dim = c(9L, 2L), .Dimnames = list(c("ar.1", "ne.1", "ne.log(pop)", "end.1", "end.t", "end.sin(2 * pi * t/52)", "end.cos(2 * pi * t/52)", "neweights.d", "overdisp"), c("Estimate", "Std. Error")) ) expect_equal(coef(measlesFit, se = TRUE), orig, tolerance = 1e-6) # increased for Solaris Sparc ## tolerance determined empirically by an R build with --disable-long-double }) test_that("neighbourhood weights array yields the same results", { What <- getNEweights(measlesFit) ## put that in an array for time-varying weights in hhh4 ## (they are not actually varying here) Warray <- array(What, dim = c(dim(What),nrow(measlesWeserEms)), dimnames = c(dimnames(What), list(NULL))) measlesFit_Warray <- update(measlesFit, ne = list(weights = Warray), use.estimates = FALSE) ## NOTE: variance estimates are different because of fixed powerlaw expect_equal(measlesFit_Warray, measlesFit, ignore = c("control", "coefficients", "se", "cov", "dim")) expect_equal(coef(measlesFit_Warray), coef(measlesFit)[names(coef(measlesFit_Warray))], tolerance = 1e-6) # triggered by 64-bit win-builder }) test_that("score vector and Fisher info agree with numerical approximations", if (requireNamespace("numDeriv")) { test <- function (neweights) { Wname <- deparse(substitute(neweights)) measlesModel$ne$weights <- neweights capture.output( # hide reports as we use a different tolerance pencomp <- hhh4(measlesWeserEms, measlesModel, check.analyticals = "numDeriv")$pen ) expect_equal(pencomp$score$analytic, pencomp$score$numeric, tolerance = .Machine$double.eps^0.5, info = Wname) expect_equal(pencomp$fisher$analytic, pencomp$fisher$numeric, tolerance = .Machine$double.eps^0.25, info = Wname) } test(W_powerlaw(maxlag = 5, normalize = FALSE, log = FALSE)) ## normalized PL with maxlag < max(nbmat) failed in surveillance < 1.9.0: test(W_powerlaw(maxlag = 3, normalize = TRUE, log = TRUE)) ## check unconstrained weights test(W_np(maxlag = 5, truncate = TRUE, normalize = FALSE)) test(W_np(maxlag = 3, truncate = FALSE, normalize = TRUE)) ## test two-component formulations (AR within NE) measlesModel$ar <- list(f = ~ -1) test(W_powerlaw(maxlag = 3, normalize = TRUE, log = TRUE, from0 = TRUE)) test(W_np(maxlag = 1, truncate = FALSE, normalize = FALSE, from0 = TRUE)) test(W_np(maxlag = 3, truncate = TRUE, normalize = TRUE, from0 = TRUE)) }) test_that("alternative optimizers give equivalent results", { ctrl_nlm <- list(method = "nlm", check.analyticals = TRUE) expect_equal( update(measlesFit, optimizer = list(regression = ctrl_nlm), use.estimates = FALSE), measlesFit, tolerance = 1e-5, ignore = "control" ) ctrl_BFGS <- list(method = "BFGS", reltol = 1e-12) expect_equal( update(measlesFit, optimizer = list(regression = ctrl_BFGS), use.estimates = FALSE), measlesFit, tolerance = 1e-5, ignore = "control" ) }) test_that("automatic and manual normalization are equivalent", { ## check for equivalent functions for (type in c("powerlaw", "np")) { W_type <- get(paste0("W_", type), mode = "function") w0 <- W_type(maxlag = 3, normalize = TRUE) w1 <- surveillance:::scaleNEweights.list( W_type(maxlag = 3, normalize = FALSE), normalize = TRUE) pars <- w0$initial nbmat <- neighbourhood(measlesWeserEms) expect_equal(w1$w(pars, nbmat), w0$w(pars, nbmat)) ## for the power law, dw and d2w are length 1 lists in w1 but not in w0 unlistIfPL <- if (type == "powerlaw") function (x) x[[1L]] else identity expect_equal(unlistIfPL(w1$dw(pars, nbmat)), w0$dw(pars, nbmat)) expect_equal(unlistIfPL(w1$d2w(pars, nbmat)), w0$d2w(pars, nbmat)) ## microbenchmark::microbenchmark(w1$d2w(pars, nbmat), w0$d2w(pars, nbmat)) ## -> type-specific implementations of normalized derivatives are faster } ## check for equivalent fits (rather redundant) measlesFit2 <- hhh4( stsObj = measlesWeserEms, control = modifyList(measlesModel, list( ne = list( weights = W_powerlaw(maxlag = 5, normalize = FALSE), normalize = TRUE # -> use scaleNEweights.list() ))) ) expect_equal(measlesFit, measlesFit2, ignore = "control", tolerance = 1e-6) # increased to pass on 32-bit Windows }) measlesWeserEms2 <- measlesWeserEms neighbourhood(measlesWeserEms2) <- neighbourhood(measlesWeserEms2) + 1L test_that("W_powerlaw(..., from0 = TRUE) equals manual approach", { measlesModel2 <- modifyList(measlesModel, list( ar = list(f = ~ -1), ne = list(weights = W_powerlaw(maxlag = 5, from0 = TRUE)) )) measlesFit2 <- hhh4(measlesWeserEms, measlesModel2) ## manual approach measlesModel2_manual <- modifyList(measlesModel2, list( ne = list(weights = W_powerlaw(maxlag = 5 + 1)) )) measlesFit2_manual <- hhh4(measlesWeserEms2, measlesModel2_manual) expect_equal(measlesFit2, measlesFit2_manual, ignore = c("control", "stsObj")) }) test_that("W_np(..., from0 = TRUE) equals manual approach", { measlesModel2 <- modifyList(measlesModel, list( ar = list(f = ~ -1), ne = list(weights = W_np(maxlag = 2, from0 = TRUE)) )) measlesFit2 <- hhh4(measlesWeserEms, measlesModel2) ## manual approach measlesModel2_manual <- modifyList(measlesModel2, list( ne = list(weights = W_np(maxlag = 2 + 1)) )) measlesFit2_manual <- hhh4(measlesWeserEms2, measlesModel2_manual) expect_equal(measlesFit2, measlesFit2_manual, ignore = c("control", "stsObj")) }) surveillance/tests/testthat/test-siafs.R0000644000176200001440000001363213777627613020205 0ustar liggesusers### Spatial interaction functions for twinstim() ## spatstat is no longer suggested, so is unavailable during R CMD check if (packageVersion("polyCub") <= "0.7.1") exit_file("need polyCub > 0.7.1 to run these tests") ### test bundle myexpectation <- function (siaf, intrfr, intrderivr, pargrid, type = 1, ...) { ## check analytical intrfr specification against numerical approximation if (!missing(intrfr)) apply(pargrid, 1, function (pars) expect_silent(capture.output( polyCub::checkintrfr(intrfr, siaf$f, pars, type, center=c(0,0), rs=c(1,2,5,10,20,50)) ))) ## also check intrfr for deriv if (!missing(intrderivr)) for (paridx in seq_along(intrderivr)) apply(pargrid, 1, function (pars) expect_silent(capture.output( polyCub::checkintrfr(intrderivr[[paridx]], function (...) siaf$deriv(...)[,paridx], pars, type, center=c(0,0), rs=c(1,2,5,10,20,50)) ))) ## check deriv, F, Deriv against numerical approximations checksiafres <- surveillance:::checksiaf(siaf, pargrid, type, ...) for (i in which(!sapply(checksiafres, is.null))) expect_true(unique(attr(checksiafres[[i]], "all.equal")), info = names(checksiafres)[i]) } ### test all pre-defined spatial interaction functions test_that("Gaussian 'F.adaptive' implementation agrees with numerical approximation", myexpectation(siaf.gaussian(F.adaptive=0.05), # Deriv uses polyCub.SV pargrid=as.matrix(log(c(0.5, 1, 3))), tolerance=0.01, method="midpoint", dimyx=150)) test_that("Gaussian iso-C-implementation agrees with numerical approximation", myexpectation(siaf.gaussian(F.adaptive=FALSE, F.method="iso"), pargrid=as.matrix(log(c(0.5, 1, 3))), tolerance=0.0005, method="SV", nGQ=25)) test_that("Exponential implementation agrees with numerical approximation", myexpectation(siaf.exponential(engine = "R"), surveillance:::intrfr.exponential, list(surveillance:::intrfr.exponential.dlogsigma), pargrid=as.matrix(log(c(0.1, 1, 2))), tolerance=0.0005, method="SV", nGQ=25)) test_that("Power-law implementation agrees with numerical approximation", myexpectation(siaf.powerlaw(engine = "R"), surveillance:::intrfr.powerlaw, list(surveillance:::intrfr.powerlaw.dlogsigma, surveillance:::intrfr.powerlaw.dlogd), pargrid=cbind(0.5,log(c(0.1,1,2))), tolerance=0.0005, method="SV", nGQ=13)) test_that("1-parameter power-law agrees with numerical approximations", myexpectation(siaf.powerlaw1(sigma = exp(0.5)), pargrid=as.matrix(log(c(0.1,1,2))), tolerance=0.0005, method="SV", nGQ=13)) test_that("Lagged power-law implementation agrees with numeric results", myexpectation(siaf.powerlawL(engine = "R"), surveillance:::intrfr.powerlawL, list(surveillance:::intrfr.powerlawL.dlogsigma, surveillance:::intrfr.powerlawL.dlogd), pargrid=cbind(-0.5,log(c(0.1,1,2))), tolerance=0.01, method="midpoint", dimyx=150)) test_that("Student implementation agrees with numerical approximation", myexpectation(siaf.student(engine = "R"), surveillance:::intrfr.student, list(surveillance:::intrfr.student.dlogsigma, surveillance:::intrfr.student.dlogd), pargrid=cbind(0.5,log(c(0.1,1,2))), tolerance=0.0005, method="SV", nGQ=5)) test_that("Step kernel implementation agrees with numerical approximation", myexpectation(siaf.step(c(0.1,0.5,1)), pargrid=-t(c(0.5,0.1,0.2)), tolerance=0.01, method="midpoint", dimyx=150)) ## ## plot the polygon on which F and Deriv are tested (to choose parameters) ## showsiaf <- function (siaf, pars) { ## plotpolyf(LETTERR, siaf$f, pars, print.args=list(split=c(1,1,2,1), more=TRUE)) ## plotpolyf(LETTERR, function (...) siaf$deriv(...)[,1], pars, print.args=list(split=c(2,1,2,1))) ## } ## showsiaf(siaf.student(), c(0.5,-0.5)) ### test new C-implementations of F and Deriv functions expect_equal_CnR <- function (siafgen, pargrid) { polydomain <- surveillance:::LETTERR siafR <- siafgen(engine = "R") siafC <- siafgen(engine = "C") ## check F resF <- apply(pargrid, 1, function (pars) c(C = siafC$F(polydomain, , pars), R = siafR$F(polydomain, , pars))) expect_equal(resF["C",], resF["R",], info = "C-version of F (current) vs. R-version of F (target)") ## check Deriv resDeriv <- apply(pargrid, 1, function (pars) c(siafC$Deriv(polydomain, , pars), siafR$Deriv(polydomain, , pars))) p <- siafR$npars expect_equal(resDeriv[seq_len(p),], resDeriv[p+seq_len(p),], info = "C-version of Deriv (current) vs. R-version of Deriv (target)") } test_that("siaf.exponential() engines agree", { expect_equal_CnR(siafgen = siaf.exponential, pargrid = matrix(log(c(0.1,1,2)))) }) test_that("siaf.powerlaw() engines agree", { expect_equal_CnR(siafgen = siaf.powerlaw, pargrid = cbind(0.5,log(c(0.1,1,2)))) }) test_that("siaf.student() engines agree", { expect_equal_CnR(siafgen = siaf.student, pargrid = cbind(0.5,log(c(0.1,1,2)))) }) test_that("siaf.powerlawL() engines agree", { expect_equal_CnR(siafgen = siaf.powerlawL, pargrid = cbind(-0.5,log(c(0.1,1,2)))) }) surveillance/tests/testthat/test-plapply.R0000644000176200001440000000036613746767713020563 0ustar liggesuserstest_that("plapply() results are reproducible", { res1 <- plapply(c(1, 1), rnorm, .parallel = 2, .seed = 1, .verbose = FALSE) res2 <- plapply(c(1, 1), rnorm, .parallel = 2, .seed = 1, .verbose = FALSE) expect_identical(res1, res2) }) surveillance/tests/testthat/test-earsC.R0000644000176200001440000000466414321225401020111 0ustar liggesuserstest_that("earsC returns a sts object", { #Sim data and convert to sts object disProgObj <- sim.pointSource(p = 0.99, r = 0.5, length = 208, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) stsObj = disProg2sts( disProgObj) res1 <- earsC(stsObj, control = list(range = 20:208, method = "C1")) res2 <- earsC(stsObj, control = list(range = 20:208, method = "C2", alpha = 0.05)) res3 <- earsC(stsObj, control = list(range = 20:208, method = "C3", sigma = 0.5)) expect_inherits(res1, "sts") expect_inherits(res2, "sts") expect_inherits(res3, "sts") data("salmNewport") in2011 <- which(isoWeekYear(epoch(salmNewport))$ISOYear == 2011) salmNewportGermany <- aggregate(salmNewport, by = "unit") control <- list(range = in2011, method = "C1", alpha = 0.05) surv <- earsC(salmNewportGermany, control = control) expect_inherits(surv, "sts") expect_true(max(surv@upperbound[1:4] - c(3.278854, 3.278854, 3.436517, 3.855617)) < 0.000001) }) test_that("earsC returns error messages",{ data("salmNewport") salmNewportGermany <- aggregate(salmNewport, by = "unit") control <- list(range = length(salmNewportGermany), method = "C1", alpha = 0.05, baseline = 2) expect_error(earsC(salmNewportGermany, control = control), "Minimum baseline to use is 3.") control <- list(range = length(salmNewportGermany), method = "C1", alpha = 0.05, minSigma = - 2) expect_error(earsC(salmNewportGermany, control = control), "The minimum sigma parameter") in2011 <- which(isoWeekYear(epoch(salmNewport))$ISOYear == 2011) control <- list(range = in2011, method = "C1", alpha = 0.05, baseline = 1500) expect_error(earsC(salmNewportGermany, control = control), "The vector of observed is too short!") }) test_that("The range is well defined",{ data("salmNewport") salmNewportGermany <- aggregate(salmNewport, by = "unit") control <- list(range = length(salmNewportGermany), method = "C1", alpha = 0.05, baseline = 2) surv <- earsC(salmNewportGermany, control = list(method = "C1", baseline = 10)) expect_equal(length(surv@upperbound), length(salmNewportGermany@observed) - 10) }) surveillance/tests/testthat/test-hhh4_weights.R0000644000176200001440000000225013746767713021461 0ustar liggesusers### Neighbourhood weights in hhh4() observed <- cbind(c(1,2,4), c(1,2,4)) test_that("AR-only and NE-only fit agree in toy scenario", { counts <- sts(observed) m1 <- hhh4(counts, control = list( end = list(f = ~ -1), family = "Poisson", ar = list(f = ~1))) expect_equivalent(coef(m1, idx2Exp=TRUE), 2) ## same fit via NE (because units have identical counts) m2 <- hhh4(counts, control = list( end = list(f = ~ -1), family = "Poisson", ne = list(f = ~1, weights = matrix(c(0,1,1,0), 2, 2)))) m1$control <- m2$control <- m1$lags <- m2$lags <- NULL expect_equivalent(m1, m2) }) test_that("time-varying NE weights align with time index of mu", { W <- matrix(c(0,1,1,0), 2, 2) Wt <- array(c(W, W, 0*W), c(dim(W), 3)) # w_jit = 0 for t=3 off <- surveillance:::weightedSumNE(observed, Wt, lag = 1) expect_true(all(is.na(off[1L,]))) expect_identical(off[3L,], c(0, 0)) # NE sum is zero at t=3 ## failed in surveillance <= 1.18.0, where w_ji(t-1) * y_j(t-1) ## was calculated, whereas w_jit * y_j(t-1) was used for simulation, ## the latter being the desired behaviour (same time index as covariates) }) surveillance/tests/testthat/test-createLambda.R0000644000176200001440000000554314615162374021434 0ustar liggesusersdata("measlesWeserEms") ## a simple endemic model measlesFit0 <- hhh4(measlesWeserEms, list( end = list(f = addSeason2formula(~1), offset = population(measlesWeserEms)), family = "NegBin1" )) test_that("endemic-only model has zero-valued Lambda matrix", { res <- getMaxEV_season(measlesFit0) expect_equal(res$maxEV.const, 0) zeromat <- matrix(0, measlesFit0$nUnit, measlesFit0$nUnit) expect_equal(res$Lambda.const, zeromat) expect_equal(surveillance:::createLambda(measlesFit0)(2), zeromat) }) ## + AR component measlesFit1 <- update(measlesFit0, ar = list(f = addSeason2formula(~1))) test_that("autoregressive model has a diagonal Lambda matrix", { res <- getMaxEV_season(measlesFit1) expect_equal(res$Lambda.const, diag(res$maxEV.const, measlesFit1$nUnit)) expect_equal(surveillance:::createLambda(measlesFit1)(2), diag(res$maxEV.season[2], measlesFit1$nUnit)) }) ## + NE component measlesFit2 <- update(measlesFit1, ne = list(f = ~1, weights = neighbourhood(measlesWeserEms) == 1)) # symmetric measlesFit3 <- update(measlesFit2, ne = list(normalize = TRUE)) # asymmetric test_that("getMaxEV() and getMaxEV_season() agree", { expect_equal(getMaxEV_season(measlesFit2)$maxEV.season, getMaxEV(measlesFit2)[seq_len(measlesWeserEms@freq)]) expect_equal(getMaxEV_season(measlesFit3)$maxEV.season, getMaxEV(measlesFit3)[seq_len(measlesWeserEms@freq)]) }) ## AR within NE + unit-specific epidemic covariate measlesFit4 <- update(measlesFit0, ne = list(f = ~pop, weights = (neighbourhood(measlesWeserEms)+1)^-2, normalize = TRUE), data = list(pop = population(measlesWeserEms))) ## calculate "nu + Lambda Y_{t-1}" and compare to fitted(object) check_createLambda <- function (object) { mname <- deparse(substitute(object)) model <- terms(object) means <- meanHHH(object$coefficients, model, subset = seq_len(model$nTime)) expect_equal(means$mean[model$subset,,drop=FALSE], fitted(object), expected.label = paste0("fitted(", mname, ")")) Lambda <- surveillance:::createLambda(object) if (any(object$lags != 1, na.rm = TRUE)) stop("check not implemented for lags != 1") meansByLambda <- t(vapply( X = object$control$subset, FUN = function(t) means$endemic[t,] + Lambda(t) %*% model$response[t-1,], FUN.VALUE = numeric(object$nUnit), USE.NAMES = FALSE)) expect_equal(meansByLambda, unname(fitted(object)), expected.label = paste0("fitted(", mname, ")")) } test_that("multivariate formulation using Lambda agrees with fitted values", { check_createLambda(measlesFit0) check_createLambda(measlesFit1) check_createLambda(measlesFit2) check_createLambda(measlesFit3) # failed in surveillance < 1.13.1 check_createLambda(measlesFit4) # failed in surveillance < 1.13.1 }) surveillance/tests/testthat/test-bodaDelay.R0000644000176200001440000001540314615162374020750 0ustar liggesusers### ## Checking the provided reporting triangle ### data('salmAllOnset') # Control slot for the proposed algorithm with D=10 correction rangeTest <- 410:412 alpha <- 0.05 controlDelay <- list(range = rangeTest, b = 4, w = 3, pastAberrations = TRUE, mc.munu=10, mc.y=10, verbose = FALSE,populationOffset=FALSE, alpha = alpha, trend = TRUE, limit54=c(0,50), noPeriods = 10, pastWeeksNotIncluded = 26, delay=TRUE) test_that("The absence of reporting triangle throws an error",{ data("salmNewport") expect_error(bodaDelay(salmNewport, controlDelay),"You have to") }) test_that("The function spots incorrect reporting triangles",{ stsFake <- salmAllOnset stsFake@control$reportingTriangle$n <- head(stsFake@control$reportingTriangle$n,n=10) expect_error(bodaDelay(stsFake, controlDelay),"The reporting triangle number") stsFake <- salmAllOnset stsFake@control$reportingTriangle$n[1,] <- stsFake@control$reportingTriangle$n[1,]/2 expect_error(bodaDelay(stsFake, controlDelay),"The reporting triangle is wrong") }) ### ## Data glm function ### epochAsDate <- TRUE epochStr <- "week" freq <- 52 b <- controlDelay$b w <- controlDelay$w populationOffset <- controlDelay$populationOffset noPeriods <- controlDelay$noPeriods verbose <- controlDelay$verbose reportingTriangle <- salmAllOnset@control$reportingTriangle timeTrend <- controlDelay$trend alpha <- controlDelay$alpha populationOffset <- controlDelay$populationOffset factorsBool <- controlDelay$factorsBool pastAberrations <- controlDelay$pastAberrations glmWarnings <- controlDelay$glmWarnings delay <- controlDelay$delay k <- controlDelay$k verbose <- controlDelay$verbose pastWeeksNotIncluded <- controlDelay$pastWeeksNotIncluded mc.munu <- controlDelay$mc.munu mc.y <- controlDelay$mc.y vectorOfDates <- as.Date(salmAllOnset@epoch, origin="1970-01-01") dayToConsider <- vectorOfDates[rangeTest[1]] observed <- salmAllOnset@observed population <- salmAllOnset@populationFrac dataGLM <- surveillance:::bodaDelay.data.glm(dayToConsider=dayToConsider, b=b, freq=freq, epochAsDate=epochAsDate, epochStr=epochStr, vectorOfDates=vectorOfDates,w=w, noPeriods=noPeriods, observed=observed,population=population, verbose=verbose, pastWeeksNotIncluded=pastWeeksNotIncluded, reportingTriangle=reportingTriangle, delay=delay) delay <- FALSE dataGLMNoDelay <- surveillance:::bodaDelay.data.glm(dayToConsider=dayToConsider, b=b, freq=freq, epochAsDate=epochAsDate, epochStr=epochStr, vectorOfDates=vectorOfDates,w=w, noPeriods=noPeriods, observed=observed,population=population, verbose=verbose, pastWeeksNotIncluded=pastWeeksNotIncluded, reportingTriangle=reportingTriangle, delay=delay) test_that("the output is a data.frame",{ expect_inherits(dataGLM, "data.frame") expect_inherits(dataGLMNoDelay, "data.frame") }) test_that("the data frame contains all variables",{ expect_identical(names(dataGLM), c("response", "wtime","population","seasgroups","vectorOfDates","delay")) expect_identical(names(dataGLMNoDelay), c("response", "wtime","population","seasgroups","vectorOfDates")) }) test_that("the variables have the right class",{ expect_inherits(dataGLM$response, "numeric") expect_inherits(dataGLM$wtime, "numeric") expect_inherits(dataGLM$population, "numeric") expect_inherits(dataGLM$seasgroups, "factor") expect_inherits(dataGLM$vectorOfDates, "Date") expect_inherits(dataGLM$delay, "numeric") expect_inherits(dataGLMNoDelay$response, "numeric") expect_inherits(dataGLMNoDelay$wtime, "numeric") expect_inherits(dataGLMNoDelay$population, "numeric") expect_inherits(dataGLMNoDelay$seasgroups, "factor") expect_inherits(dataGLMNoDelay$vectorOfDates, "Date") }) test_that("the time variable is ok with diff 1",{ delayWtime <- as.numeric(levels(as.factor(dataGLM$wtime))) expect_equal(diff(delayWtime), rep(1,length(delayWtime)-1)) expect_equal(diff(dataGLMNoDelay$wtime), rep(1,length(dataGLMNoDelay$wtime)-1)) }) test_that("the factor variable has the right number of levels",{ expect_equal(nlevels(dataGLM$seasgroups), noPeriods) expect_equal(nlevels(dataGLMNoDelay$seasgroups), noPeriods) }) ### ## Fit glm function ### argumentsGLM <- list(dataGLM=dataGLM,reportingTriangle=reportingTriangle, timeTrend=timeTrend,alpha=alpha, populationOffset=populationOffset, factorsBool=TRUE,pastAberrations=FALSE, glmWarnings=glmWarnings, verbose=verbose,delay=delay,k=k,control=controlDelay) if(surveillance.options("allExamples") && require("INLA")) { # needs to be attached argumentsGLM$inferenceMethod <- "INLA" model <- do.call(surveillance:::bodaDelay.fitGLM, args=argumentsGLM) test_that("the fitGLM function gives the right class of output",{ expect_inherits(model, "inla") }) } argumentsGLM$inferenceMethod <- "asym" model <- do.call(surveillance:::bodaDelay.fitGLM, args=argumentsGLM) test_that("the fitGLM function gives the right class of output",{ expect_inherits(model, "negbin") }) ### ## formula function ### test_that("We get the right formula",{ expect_identical(surveillance:::formulaGLMDelay(timeBool=TRUE,factorsBool=FALSE), "response ~ 1+wtime") expect_identical(surveillance:::formulaGLMDelay(timeBool=FALSE,factorsBool=FALSE), "response ~ 1") expect_identical(surveillance:::formulaGLMDelay(timeBool=TRUE,factorsBool=FALSE), "response ~ 1+wtime") expect_identical(surveillance:::formulaGLMDelay(timeBool=TRUE,factorsBool=TRUE), "response ~ 1+wtime+as.factor(seasgroups)") expect_identical(surveillance:::formulaGLMDelay(timeBool=TRUE,factorsBool=TRUE,delay=TRUE), "response ~ 1+wtime+as.factor(seasgroups)+as.factor(delay)") expect_identical(surveillance:::formulaGLMDelay(timeBool=TRUE,factorsBool=FALSE,outbreak=TRUE), "response ~ 1+wtime+f(outbreakOrNot,model='linear', prec.linear = 1)") }) surveillance/tests/testthat/test-twinstim_misc.R0000644000176200001440000000320314614534272021747 0ustar liggesusers## miscellaneous regression tests for twinstim() data("imdepi") load(system.file("shapes", "districtsD.RData", package = "surveillance"), verbose = TRUE) ## let some districts have no population imdepi0 <- update(imdepi, stgrid = within(imdepi$stgrid, popdensity[startsWith(as.character(tile), "01")] <- 0)) stopifnot(# verify update-method identical(names(imdepi0$stgrid), names(imdepi$stgrid)), identical(names(imdepi0$events), names(imdepi$events)), with(imdepi0$events@data, all.equal(startsWith(as.character(tile), "01"), popdensity == 0)), identical(marks(imdepi0), marks(imdepi)) ) ## automatic start value is robust against -Inf offset fit0 <- twinstim(endemic = ~offset(log(popdensity)) + I(start/365), data = imdepi0, model = TRUE, optim.args = list(fixed = TRUE)) ## beta0 was initialized at Inf in surveillance <= 1.22.1 stopifnot(is.finite(coef(fit0)), is.character(fit0$converged), is.infinite(logLik(fit0))) # because of events in 0-pop tiles ## endemic intensity is 0 in unpopulated districts hGrid <- intensity.twinstim(fit0, "space", tiles = districtsD)$hGrid districts_h0 <- names(which(hGrid == 0)) stopifnot(length(districts_h0) > 0, startsWith(districts_h0, "01")) ## intensityplot works for an endemic-only model fit_end <- twinstim(endemic = ~1, data = imdepi, model = TRUE, optim.args = list(fixed = TRUE)) intensityplot(fit_end, "total", "space", tiles = districtsD) -> .plotobj ## produced an error in surveillance <= 1.22.1: ## unable to find an inherited method for function 'coordinates' for signature '"NULL"' surveillance/tests/testthat/test-farringtonFlexible.R0000644000176200001440000003715114321225401022675 0ustar liggesusersdata("salmonella.agona") # sts object lala <- paste(salmonella.agona$start[1],salmonella.agona$start[2],"1",sep=" ") firstMonday <- as.POSIXlt(lala, format = "%Y %W %u") salm.ts <- salmonella.agona$observed dates <- as.Date(firstMonday) + 7 * 0:(length(salm.ts) - 1) start=c(salmonella.agona$start[1],salmonella.agona$start[2]) salm <- new("sts",epoch = as.numeric(dates), start = start, freq = 52, observed = salm.ts, epochAsDate = TRUE) ### ## WEIGHTS FUNCTION ### test_that("gamma = 1 if everything below the threshold",{ s <- rep(0,10) weightsThreshold <- 0 weights <- algo.farrington.assign.weights(s,weightsThreshold) expect_equal(weights,rep(1,10)) }) test_that(" A case that was checked by hand",{ s <- rep(2,10) s[1:5] <- 0 weightsThreshold <- 0 weights <- algo.farrington.assign.weights(s,weightsThreshold) expect_equal(weights[1:5],rep(1.6,5)) expect_equal(weights[6:10],rep(0.4,5)) }) ### ## RESIDUALS FUNCTION ### test_that(" residuals should be zero",{ x <- rpois(10,1) y <- exp(x) model <- glm(y~x,family = quasipoisson(link="log")) phi <- max(summary(model)$dispersion,1) s <- anscombe.residuals(model,phi) expect_equal(as.numeric(s),rep(0,10)) }) test_that(" residuals should not be zero",{ x <- rpois(1000,1) y <- exp(x)+runif(1) model <- glm(y~x,family = quasipoisson(link="log")) phi <- max(summary(model)$dispersion,1) s <- anscombe.residuals(model,phi) expect_true(mean(s)>0) }) ### ## FORMULA FUNCTION ### test_that("We get the right formula",{ expect_identical(surveillance:::formulaGLM(populationOffset=FALSE,timeBool=TRUE,factorsBool=FALSE), "response ~ 1+wtime") expect_identical(surveillance:::formulaGLM(populationOffset=FALSE,timeBool=FALSE,factorsBool=FALSE), "response ~ 1") expect_identical(surveillance:::formulaGLM(populationOffset=TRUE,timeBool=TRUE,factorsBool=FALSE), "response ~ 1+wtime+offset(log(population))") expect_identical(surveillance:::formulaGLM(populationOffset=TRUE,timeBool=TRUE,factorsBool=TRUE), "response ~ 1+wtime+offset(log(population))+seasgroups") }) ### ## REFERENCE TIME POINTS FUNCTION ### test_that("We get the expected timepoints with weekly data",{ # Case with weekly data with dates dayToConsider <- as.Date("2013-06-06") b <- 3 freq <- 52 epochAsDate <- TRUE epochStr <- "week" lala <- surveillance:::algo.farrington.referencetimepoints(dayToConsider,b=b,freq=freq,epochAsDate,epochStr) # Do we get the same day as dayToConsider? expect_equal(as.numeric(format(lala, "%w")),rep(4,4)) # Actually for this example I know the dates one should get expect_equal(sort(lala),sort(c(as.Date("2010-06-03"),as.Date("2013-06-06"),as.Date("2012-06-07"),as.Date("2011-06-09")))) }) test_that("We get the expected timepoints with monthly data",{ dayToConsider <- 48 b <- 3 freq <- 12 epochAsDate <- FALSE epochStr <- "month" lala <- surveillance:::algo.farrington.referencetimepoints(dayToConsider,b=b,freq=freq,epochAsDate,epochStr) expect_equal(lala,c(48,36,24,12)) }) test_that("We get an error when going too many years back",{ dayToConsider <- 48 b <- 3 freq <- 12 epochAsDate <- FALSE epochStr <- "month" expect_true(any(surveillance:::algo.farrington.referencetimepoints(dayToConsider,b=8,freq=freq,epochAsDate,epochStr) < 1)) # apply code control1 <- list(range=250,noPeriods=10,populationOffset=FALSE, fitFun="algo.farrington.fitGLM.flexible", b=10,w=3,weightsThreshold=2.58, pastWeeksNotIncluded=26, pThresholdTrend=1,trend=TRUE, thresholdMethod="muan",alpha=0.05,glmWarnings=FALSE) expect_error(farringtonFlexible(salm,control=control1),"Some reference") }) ### ## FIT GLM FUNCTION ### # Case with convergence control<- list(range=250,noPeriods=10,populationOffset=TRUE, fitFun="algo.farrington.fitGLM.flexible", b=40,w=3,weightsThreshold=2.58, pastWeeksNotIncluded=26, pThresholdTrend=1,trend=TRUE, thresholdMethod="muan",alpha=0.05,glmWarnings=FALSE) response=salm@observed[1:120] dataGLM <- data.frame(response=response,wtime=1:120, population=runif(120)*100, seasgroups=as.factor(rep(1:12,10))) arguments <- list(dataGLM=dataGLM, timeTrend=TRUE, populationOffset=TRUE, factorsBool=TRUE,reweight=TRUE, weightsThreshold=0.5,glmWarnings=control$glmWarnings, control=control) model <- do.call(surveillance:::algo.farrington.fitGLM.flexible, args=arguments) test_that("The fit glm function gives the right class of output",{ expect_inherits(model, "glm") }) test_that("The fit glm function gives as many coefficients as expected",{ expect_equal(dim(summary(model)$coefficients)[1], length(levels(dataGLM$seasgroups))-1+1+1) }) test_that("wtime, response, phi and weights were added to the model",{ expect_false(is.null(model$phi)) expect_false(is.null(model$wtime)) expect_false(is.null(model$response)) expect_false(is.null(model$population)) expect_false(is.null(model$weights)) }) test_that("reweighting was done",{ expect_true(all(model$weights!=1)) }) test_that("there are no weights if very high threshold",{ arguments$reweight <- TRUE arguments$weightsThreshold <- 100000 model <- do.call(surveillance:::algo.farrington.fitGLM.flexible, args=arguments) expect_true(all(model$weights==1)) }) test_that("there is not a too small overdispersion",{ expect_true(model$phi>=1) }) ### ## BLOCKS FUNCTION ### referenceTimePoints <- c(as.Date("2010-06-03"),as.Date("2013-06-06"),as.Date("2012-06-07"),as.Date("2011-06-09")) firstDay <- as.Date("1990-06-07") vectorOfDates <- dates <- as.Date(firstDay) + 7 * 0:1300 freq <- 52 dayToConsider <- as.Date("2013-06-06") b <- 3 w <- 3 epochAsDate <- TRUE # p=1 p <- 1 lala <- surveillance:::blocks(referenceTimePoints,vectorOfDates,freq,dayToConsider,b,w,p,epochAsDate) test_that("the reference window has the right length",{ expect_equal(length(vectorOfDates[is.na(lala)==FALSE&lala==p]),w+1+b*(2*w+1)) # p>1 p <- 8 lala <- surveillance:::blocks(referenceTimePoints,vectorOfDates,freq,dayToConsider,b,w,p,epochAsDate) # reference windows expect_equal(length(vectorOfDates[is.na(lala)==FALSE&lala==p]),w+1+b*(2*w+1)) }) lili <- as.factor(lala[is.na(lala)==FALSE]) test_that("there are as many levels as expected",{ expect_equal(length(levels(lili)),p) }) p <- 8 lala <- surveillance:::blocks(referenceTimePoints,vectorOfDates,freq,dayToConsider,b,w,p,epochAsDate) lili <- as.factor(lala[is.na(lala)==FALSE]) lolo <- lili[lili!=p] test_that("periods of roughly the same length each year",{ expect_equal(as.numeric(abs(diff(table(lolo))[1:(p-2)])<=b),rep(1,(p-2))) }) ### ## THRESHOLD FUNCTION FARRINGTON ### predFit <- 5 predSeFit <- 0.2 wtime <- 380 skewness.transform <- "2/88" alpha <- 0.05 y <- 8 method <- "delta" phi <- 1 test_that("the function recognizes wrong exponents",{ expect_error(surveillance:::algo.farrington.threshold.farrington( predFit, predSeFit, phi, skewness.transform, alpha, y, method ), "proper exponent") }) test_that("some results we know are found",{ skewness.transform <- "none" lala <- surveillance:::algo.farrington.threshold.farrington( predFit, predSeFit, phi, skewness.transform, alpha, y, method ) # Should always be ok lala <- as.numeric(lala) expect_true(lala[3]<=1&lala[1]>=0) expect_true(lala[2]>lala[1]) expect_true(lala[1]>=0) # Here we know the results expect_equal(as.numeric(lala), c(1.3073128, 8.6926872, 0.0907246, 0.8124165), tolerance = 1e-6, scale = 1) # Here we calculated some examples skewness.transform <- "1/2" lala <- surveillance:::algo.farrington.threshold.farrington( predFit, predSeFit, phi, skewness.transform, alpha, y, method ) expect_equal(as.numeric(lala), c(1.9891097, 9.3744842, 0.1189986, 0.6857951), tolerance = 1e-6, scale = 1) skewness.transform <- "2/3" lala <- surveillance:::algo.farrington.threshold.farrington( predFit, predSeFit, phi, skewness.transform, alpha, y, method ) expect_equal(as.numeric(lala), c(1.8084477, 9.1154825, 0.1094727, 0.7289546), tolerance = 1e-6, scale = 1) }) ### ## THRESHOLD FUNCTION NOUFAILY ### predFit <- log(5) predSeFit <- log(2) wtime <- 380 skewness.transform <- "none" alpha <- 0.05 y <- 11 phi <- 1.5 method <- "muan" lala <- surveillance:::algo.farrington.threshold.noufaily( predFit, predSeFit, phi, skewness.transform, alpha, y, method ) test_that("some results we know are found",{ # Should always be ok lala <- as.numeric(lala) expect_true(lala[3]<=1&lala[1]>=0) expect_true(lala[2]>lala[1]) expect_true(lala[1]>=0) # Here we calculated some examples expect_equal(as.numeric(lala), c(8.0000000, 24.0000000, 0.8597797, 0.4193982), tolerance = 1e-6, scale = 1) phi <- 1.0 method <- "muan" lala <- surveillance:::algo.farrington.threshold.noufaily( predFit, predSeFit, phi, skewness.transform, alpha, y, method ) expect_equal(as.numeric(lala), c(9.0000000, 22.0000000, 0.9093099, 0.4605347), tolerance = 1e-6, scale = 1) phi <- 1.5 method <- "nbPlugin" lala <- surveillance:::algo.farrington.threshold.noufaily( predFit, predSeFit, phi, skewness.transform, alpha, y, method ) expect_equal(as.numeric(lala), c(1.00000000, 10.00000000, 0.03763657, 1.11918153), tolerance = 1e-6, scale = 1) phi <- 1.0 method <- "nbPlugin" lala <- surveillance:::algo.farrington.threshold.noufaily( predFit, predSeFit, phi, skewness.transform, alpha, y, method ) expect_equal(as.numeric(lala), c(2.00000000, 9.00000000, 0.01369527, 1.27061541), tolerance = 1e-6, scale = 1) }) ### ## DATA GLM FUNCTION ### b <- 3 freq <- 52 dayToConsider <- as.Date("2013-05-30") epochAsDate <- TRUE epochStr <- "week" firstDay <- as.Date("1990-06-07") vectorOfDates <- dates <- as.Date(firstDay) + 7 * 0:1300 w <- 3 noPeriods <- 10 observed <- rnorm(1301)+runif(1301)+30 population <- rnorm(1301)+10 verbose <- FALSE pastWeeksNotIncluded <- w k <- 1200 lala <- surveillance:::algo.farrington.data.glm(dayToConsider, b, freq, epochAsDate,epochStr, vectorOfDates,w,noPeriods, observed,population, verbose,pastWeeksNotIncluded,k) test_that("the output is a data.frame",{ expect_inherits(lala, "data.frame") }) test_that("the data frame contains all variables",{ expect_identical(names(lala), c("response", "wtime","population","seasgroups","vectorOfDates")) }) test_that("the time variable is ok with diff 1",{ expect_equal(diff(lala$wtime), rep(1,length(lala$wtime)-1)) }) test_that("the factor variable has the right number of levels",{ expect_equal(nlevels(lala$seasgroups), noPeriods) }) observed[1150] <- NA lala <- surveillance:::algo.farrington.data.glm(dayToConsider, b, freq, epochAsDate,epochStr, vectorOfDates,w,noPeriods, observed,population, verbose,pastWeeksNotIncluded,k) test_that("the data frame has the right dimensions",{ expect_equal(dim(lala),c(156,5)) }) ### ## GLM FUNCTION ### dataGLM <- lala timeTrend <- TRUE populationOffset <- TRUE factorsBool <- TRUE reweight <- TRUE weightsThreshold <- 1 pThresholdTrend <- 1 b <- 3 noPeriods <- 10 typePred <- "link" fitFun <- "algo.farrington.fitGLM.flexible" glmWarnings <- FALSE epochAsDate <- TRUE dayToConsider <- as.Date("2013-05-30") diffDates <- 7 populationNow <- 10 test_that("the output has the needed variables",{ finalModel <- surveillance:::algo.farrington.glm(dataGLM,timeTrend,populationOffset,factorsBool, reweight,weightsThreshold,pThresholdTrend,b, noPeriods,typePred,fitFun,glmWarnings,epochAsDate, dayToConsider,diffDates,populationNow,verbose=FALSE) expect_identical(names(finalModel), c("pred","doTrend","coeffTime","phi")) }) test_that("no time trend in no time trend",{ pThresholdTrend <- 1 b <- 2 finalModel <- surveillance:::algo.farrington.glm(dataGLM,timeTrend,populationOffset,factorsBool, reweight,weightsThreshold,pThresholdTrend,b, noPeriods,typePred,fitFun,glmWarnings,epochAsDate, dayToConsider,diffDates,populationNow,verbose=FALSE) expect_false(finalModel$doTrend) }) ### ## ALARMS ### test <- farringtonFlexible(salm,control=list(thresholdMethod="nbPlugin",alpha=0.1)) test_that("there are only alarms when expected",{ # No alarm when observed is 0 expect_true(sum(test@alarm[test@observed==0])==0) # No alarm when the observed counts are UNDER the threshold expect_true(sum(observed(test)>upperbound(test),na.rm=TRUE)==sum(test@alarm==TRUE)) }) ### ## NO CONVERGENCE ### timeSeries <- rep(0,698) timeSeries[696] <- 1 algoControl <- list(noPeriods=10,alpha = 0.01,verbose = F, b=5,w=4,weightsThreshold=2.58,pastWeeksNotIncluded=26, pThresholdTrend=1,thresholdMethod='nbPlugin',limit54 = c(4,5), range = (length(timeSeries) - 1):length(timeSeries), glmWarnings = FALSE) seriesSTSObject <- new('sts', observed = timeSeries, epoch = as.numeric(seq(as.Date('2001-01-01'),length.out=length(timeSeries), by='1 week')), epochAsDate = TRUE) test_that("The code does not produce any error",{ # It is ok if the code does not produce any error expect_warning(farringtonFlexible(seriesSTSObject, control = algoControl)) }) ### ## NA ### timeSeries <- rnorm(698)*10+runif(698)*100+30 algoControl <- list(noPeriods=10,alpha = 0.01,verbose = F, b=5,w=4,weightsThreshold=2.58,pastWeeksNotIncluded=NULL, pThresholdTrend=1,thresholdMethod='nbPlugin',limit54 = c(4,5), range = (length(timeSeries) - 1):length(timeSeries), glmWarnings = FALSE) seriesSTSObject <- sts(timeSeries, epoch = seq(as.Date('2001-01-01'), length.out=length(timeSeries), by='1 week')) test_that("The code does not produce any error",{ farringtonFlexible(seriesSTSObject, control = algoControl) results1 <- farringtonFlexible(seriesSTSObject, control = algoControl) expect_inherits(results1, "sts") seriesSTSObject@observed[680:690] <- NA results2 <- farringtonFlexible(seriesSTSObject, control = algoControl) expect_inherits(results2, "sts") }) ### ## multivariate example with populationOffset ### msts <- sts(cbind(series1 = timeSeries, series2 = timeSeries), population = c(1,2)*10000) algoControl$populationOffset <- TRUE out <- farringtonFlexible(msts, control = algoControl) test_that("population offsets of multivariate sts are handled correctly", { ## resulting upperbounds must be the same as different offsets just rescale the intercept expect_equal(out@upperbound[,1], out@upperbound[,2]) }) ## failed in surveillance <= 1.19.1 (used series 1 offset for both fits) surveillance/tests/testthat/test-hhh4_offsets.R0000644000176200001440000000403013751215235021435 0ustar liggesusers### hhh4() with epidemic offsets ## select two adjacent regions data("measlesWeserEms") expect_message( measles2 <- measlesWeserEms[,c("03457","03454")], "could invalidate" ) expect_equivalent(neighbourhood(measles2), matrix(c(0,1,1,0), 2, 2)) ## AR model fit1 <- hhh4(measles2, list(ar = list(f = ~1))) ##plot(fit1, units=NULL) ## use estimated exp(lambda) as offset -> new lambda should be 0, equal fit o1 <- exp(fit1$coefficients[["ar.1"]]) fit1o <- hhh4(measles2, list( ar = list(f = ~1, offset = matrix(o1, nrow(measles2), ncol(measles2))) )) test_that("model with AR offset is fitted correctly", { expect_equal(fit1o$coefficients[["ar.1"]], 0) expect_equal(fitted(fit1o), fitted(fit1)) }) ## same test with an AR+NE model fit2 <- hhh4(measles2, list(ar = list(f = ~1), ne = list(f = ~1))) ##plot(fit2, units=NULL) o2_ar <- exp(fit2$coefficients[["ar.1"]]) o2_ne <- exp(fit2$coefficients[["ne.1"]]) fit2o <- hhh4(measles2, list( ar = list(f = ~1, offset = matrix(o2_ar, nrow(measles2), ncol(measles2))), ne = list(f = ~1, offset = matrix(o2_ne, nrow(measles2), ncol(measles2))) )) test_that("model with AR+NE offsets is fitted correctly", { expect_equal(fit2o$coefficients[["ar.1"]], 0, scale = 1) # use abs. diff expect_equal(fit2o$coefficients[["ne.1"]], 0, scale = 1, tolerance = 1e-6) # for ATLAS/MKL/OpenBLAS expect_equal(fitted(fit2o), fitted(fit2)) }) ## createLambda() and thus maxEV was wrong in surveillance <= 1.16.1 test_that("Lambda matrix incorporates epidemic offsets", { expect_equal(getMaxEV(fit1o)[1], getMaxEV(fit1)[1]) expect_equal(getMaxEV(fit2o)[1], getMaxEV(fit2)[1]) }) ## simulate.hhh4() was wrong in surveillance <= 1.16.1 test_that("simulation accounts for epidemic offsets", { ## check the relative difference in the total number of cases obs <- fitted(fit2o) sim <- simulate(fit2o, seed = 1, y.start = observed(measles2)[1,], subset = fit2o$control$subset, simplify = TRUE) expect_true(abs(sum(sim)/sum(obs)-1) < 0.5) }) surveillance/tests/testthat/test-toLatex.sts.R0000644000176200001440000000632713757503172021322 0ustar liggesusersdata("ha.sts") data("salmonella.agona") test_that("toLatex accepts basic input and returns Latex", { control <- list( noPeriods=10,populationBool=FALSE, fitFun="algo.farrington.fitGLM.flexible", b=4,w=3,weightsThreshold=2.58, pastWeeksNotIncluded=26, pThresholdTrend=1,trend=TRUE, thresholdMethod="new",alpha=0.01 ) result <- ha.sts result@alarm[,7] <- TRUE result@upperbound[,7] <- 1 laTex <- toLatex(result, subset=(280:290), table.placement="h", size = "scriptsize", sanitize.text.function = identity, NA.string = "-",include.rownames=FALSE) laTex3 <- toLatex(result, subset=(280:290), alarmPrefix = "aaaa", alarmSuffix = "bbbb", table.placement="h", size = "scriptsize", sanitize.text.function = identity, NA.string = "-",include.rownames=FALSE) expect_true(grepl("aaaa", paste(as.character(laTex3), collapse = ' '))) expect_true(grepl("bbbb", paste(as.character(laTex3), collapse = ' '))) expect_inherits(laTex, "Latex") expect_inherits(laTex3, "Latex") }) test_that("caption is incorporated", { testCaption <- "Please print my caption" latex <- toLatex(ha.sts, caption = testCaption) expect_true(grepl(testCaption, paste(as.character(latex), collapse = ' '))) }) test_that("label is incorporated", { testLabel <- "Please print my label" latex <- toLatex(ha.sts, label = testLabel) expect_true(grepl(testLabel, paste(as.character(latex), collapse = ' '))) }) test_that("ubColumnLabel is incorporated", { testUBLabel <- "Upperbound" latex <- toLatex(ha.sts, ubColumnLabel = testUBLabel) expect_true(grepl(testUBLabel, paste(as.character(latex), collapse = ' '))) }) test_that("one can override the default table column labels", { columnLabels <- c("Jahr", "Woche", "chwi1", "UB", "frkr2", "UB", "lich3", "UB", "mahe4", "UB", "mitt5", "UB", "neuk6", "UB", "pank7", "UB", "rein8", "UB", "span9", "UB", "zehl10", "UB", "scho11", "UB", "trko12", "UB") latex <- toLatex(ha.sts, columnLabels = columnLabels) expect_true(all( sapply(columnLabels, function(l) grepl(l, paste(as.character(latex), collapse = ' ')) , USE.NAMES = FALSE) )) }) test_that("toLatex works with output from farringtonFlexible()", { # Create the corresponding sts object from the old disProg object salm <- disProg2sts(salmonella.agona) # Farrington with old options control1 <- list(range=(260:312), noPeriods=1,populationOffset=FALSE, fitFun="algo.farrington.fitGLM.flexible", b=4,w=3,weightsThreshold=1, pastWeeksNotIncluded=3, pThresholdTrend=0.05,trend=TRUE, thresholdMethod="delta",alpha=0.1) salm1 <- farringtonFlexible(salm,control=control1) expect_inherits(toLatex(salm1), "Latex") }) test_that("toLatex stops if 'subset' is not applicable", { expect_error(toLatex(ha.sts, subset=(-5:290))) expect_error(toLatex(ha.sts, subset=(1:10000))) expect_error(toLatex(ha.sts, subset=(10000:100000))) }) surveillance/tests/testthat/test-algo.glrnb.R0000644000176200001440000000435414315341765021114 0ustar liggesusers## Simulation parameters S <- 1 ; t <- 1:120 ; m <- length(t) beta <- c(1.5,0.6,0.6) omega <- 2*pi/52 #log mu_{0,t} alpha <- 0.2 base <- beta[1] + beta[2] * cos(omega*t) + beta[3] * sin(omega*t) #Generate example data with changepoint and tau=tau tau <- 100 kappa <- 0.4 mu0 <- exp(base) mu1 <- exp(base + kappa) ## Generate counts set.seed(42) x <- rnbinom(length(t),mu=mu0*(exp(kappa)^(t>=tau)),size=1/alpha) suppressWarnings( s.ts <- create.disProg(week=t, observed=x, state=(t>=tau)) )#, "deprecatedWarning") # class needs R >= 4.0.0 ## Define control object cntrl1 <- list(range=t,c.ARL=5, mu0=mu0, alpha=alpha, change="intercept", ret="value", dir="inc") ## Run algorithm glr.ts1 <- algo.glrnb(s.ts, control=cntrl1) ## Correct upperbound (rounded) ## dput(signif(c(glr.ts1$upperbound), 7)) correctUpperbound <- c( 0.0933664, 0, 0.001387989, 0.4392282, 1.239898, 2.983766, 1.954988, 1.722341, 1.586777, 0.7331938, 0.9337575, 0.7903225, 1.104522, 1.425098, 1.24129, 1.633672, 2.033343, 1.788079, 1.397671, 0.9081794, 0.797097, 0.7270934, 0.5248943, 0.3093548, 0.2622768, 0.2301054, 0.1595651, 0.1484989, 0.06889605, 0.1504776, 0.04138495, 0.02219845, 0.0231524, 0.009575689, 0.1504776, 0.5827537, 0.0357062, 0.005011513, 0, 1.390972, 0.3167743, 0.5717088, 0.1053871, 0.003442552, 0.0005934715, 0, 0, 0.05509335, 0.1375619, 0.2449853, 0.6840703, 0.5427538, 0.05675776, 0.06656547, 0.09036596, 0.209314, 0.1392091, 0.03494786, 0.026216, 0.277202, 0.01762547, 0, 0, 0, 3.564077, 1.41019, 0.290548, 0.3740241, 0.4269062, 0.1296794, 0.1298662, 0.6322042, 0.2115204, 0.107457, 0.9366399, 0.1379007, 0.1509654, 0.03392803, 0.005775552, 0, 0, 0, 0, 0, 0.001143512, 0.001637927, 1.021689, 1.965804, 1.83044, 1.017412, 0.3033473, 0.1689957, 0.4051742, 0.1247774, 0.1460143, 0.03590031, 0.9459381, 0.4189531, 0.2637725, 0.03925406, 0.01374443, 0.2283519, 2.535301, 1.406133, 1.692899, 2.021258, 2.951635, 4.25683, 4.77543, 3.90064, 3.646361, 3.680106, 4.236502, 5.522696, 0.1221651, 0.4054735, 0.6761779, 0.8039129, 0.3913383, 0.1261521) test_that("upperbound equals pre-computed value", expect_equal(c(glr.ts1$upperbound), correctUpperbound, tolerance=1e-6)) surveillance/tests/testthat/test-sts.R0000644000176200001440000001034713746767713017713 0ustar liggesuserstest_that("\"sts\" prototype is a valid object", expect_true(validObject(new("sts")))) mysts <- sts(1:10, frequency = 4, start = c(1959, 2)) test_that("conversion from \"ts\" to \"sts\" works as expected", { myts <- ts(1:10, frequency = 4, start = c(1959, 2)) expect_identical(as(myts, "sts"), mysts) ## this failed in surveillance 1.11.0 due to a wrong "start" calculation }) test_that("if missing(observed), initialize-method copies slots", { mysts_updated <- initialize(mysts, epoch = 2:11) expect_identical(mysts_updated@epoch, 2:11) mysts_updated@epoch <- mysts@epoch expect_identical(mysts_updated, mysts) ## construct stsBP from existing "sts" object mystsBP <- new("stsBP", mysts, ci = array(NA_real_, c(10,1,2)), lambda = array(NA_real_, c(10,1,1))) expect_identical(as(mystsBP, "sts"), mysts) }) test_that("different initializations of \"stsBP\" work as expected", { mystsBP <- new("stsBP", observed = 1:10, freq = 4, start = c(1959, 2), ci = array(NA_real_, c(10,1,2)), lambda = array(NA_real_, c(10,1,0))) expect_identical(mystsBP, as(mysts, "stsBP")) }) test_that("different initializations of \"stsNC\" work as expected", { mystsNC <- new("stsNC", observed = 1:10, freq = 4, start = c(1959, 2), pi = array(NA_real_, c(10,1,2)), SR = array(NA_real_, c(10,0,0))) expect_identical(mystsNC, as(mysts, "stsNC")) }) test_that("sts(..., population) sets the populationFrac slot", { ## for sts() construction, "population" is an alias for "populationFrac" ## (the internal slot name), introduced in the space-time JSS paper sts1 <- sts(cbind(1:3, 11:13), population = c(10, 20)) sts2 <- sts(cbind(1:3, 11:13), populationFrac = c(10, 20)) expect_identical(sts1, sts2) }) test_that("\"sts\" conversion to a (tidy) data frame works consistently", { ## univariate sts mystsdata <- as.data.frame(mysts, as.Date = FALSE) expect_identical(tidy.sts(mysts)[names(mystsdata)], mystsdata) ## multivariate sts data("momo") momo3tidy_uv <- tidy.sts(momo[,3]) momo3tidy_mv <- subset(tidy.sts(momo), unit == levels(unit)[3]) momo3tidy_mv$unit <- momo3tidy_mv$unit[drop=TRUE] row.names(momo3tidy_mv) <- NULL expect_identical(momo3tidy_uv, momo3tidy_mv) }) test_that("we can subset epochs of an \"sts\" object", { expect_identical(mysts[TRUE,TRUE], mysts) expect_identical(mysts[2,]@start, c(1959, 3)) ## negative and 0 indices produced wrong "start" in surveillance <= 1.16.2 expect_identical(mysts[-1,], mysts[2:10,]) expect_identical(mysts[0,]@start, mysts@start) }) test_that("colnames need to be identical (only for multivariate data)", { slots_dn <- c("observed", "state", "alarm", "upperbound", "populationFrac") ## ignore colnames mismatch for univariate time series sts_args_1 <- lapply(setNames(nm = slots_dn), function (slot) matrix(0, 1, 1, dimnames = list(NULL, slot))) sts_args_1$neighbourhood <- matrix(0, 1, 1, dimnames = list("a", "a")) expect_silent(do.call(sts, sts_args_1)) ## multivariate time series with inconsistent column order are invalid sts_args_2 <- list( observed = matrix(0, 1, 2, dimnames = list(NULL, c("r1", "r2"))) ) sts_args_2[slots_dn[-1]] <- list(sts_args_2$observed[,2:1,drop=FALSE]) sts_args_2$neighbourhood <- matrix(0, 2, 2, dimnames = rep(list(c("r2", "r1")), 2)) expect_error(do.call(sts, sts_args_2), "colnames") # new in surveillance > 1.17.1 ## column names can be missing for other slots expect_silent(do.call(sts, c(sts_args_2[1], lapply(sts_args_2[-1], unname)))) }) test_that("epoch() finds Monday of 'start' week (ISO)", { mydate <- as.Date("2020-01-27") expect_identical(strftime(mydate, "%u"), "1") # Monday start <- unlist(isoWeekYear(mydate), use.names = FALSE) expect_equivalent(start, c(2020, 5)) # ISO week 5 expect_identical(strftime(mydate, "%W"), "04") # UK week 4 mysts <- sts(1:3, start = start) expect_equal(epoch(mysts, as.Date = TRUE)[1], mydate) ## failed in surveillance 1.18.0, where epoch(x, as.Date=TRUE) ## used %W to interpret the 'start' week, so here returned "2020-02-03" }) surveillance/tests/testthat/test-calibration.R0000644000176200001440000000320713746767713021366 0ustar liggesusers### Calibration tests for Poisson or NegBin predictions mu <- c(0.1, 1, 3, 6, pi, 100) size1 <- 0.5 size2 <- c(0.1, 0.1, 10, 10, 100, 100) ##set.seed(2); y <- rnbinom(length(mu), mu = mu, size = size1) y <- c(0, 0, 2, 14, 5, 63) zExpected <- rbind( dss = c(P = 6.07760977730636, NB1 = -0.468561113465647, NB2 = 2.81071829075294), logs = c(P = 5.95533908528874, NB1 = 0.403872251419915, NB2 = 2.77090543018323), rps = c(P = 4.45647234878906, NB1 = -0.437254253267393, NB2 = 2.57223607389215) ) delta <- 1e-4 #sqrt(.Machine$double.eps) for (score in rownames(zExpected)) { .zExpected <- zExpected[score, , drop = TRUE] ## if package "gsl" is not available, rps_EV is less accurate tol_equal <- if (score == "rps" && !requireNamespace("gsl", quietly = TRUE)) 1e-4 else .Machine$double.eps^0.5 test_that(paste0("still the same z-statistics with ", score), { ## Poisson predictions zP <- calibrationTest(y, mu, which = score, tolerance = delta)$statistic expect_equal(zP, .zExpected["P"], check.attributes = FALSE, tolerance = tol_equal) ## NegBin predictions with common size parameter zNB1 <- calibrationTest(y, mu, size1, which = score, tolerance = delta)$statistic expect_equal(zNB1, .zExpected["NB1"], check.attributes = FALSE, tolerance = tol_equal) ## NegBin predictions with varying size parameter zNB2 <- calibrationTest(y, mu, size2, which = score, tolerance = delta)$statistic expect_equal(zNB2, .zExpected["NB2"], check.attributes = FALSE, tolerance = tol_equal) }) } surveillance/tests/testthat/test-twinstim_score.R0000644000176200001440000000525713746767713022157 0ustar liggesusers### Likelihood and score function of twinstim() ## Note: derivatives of interaction functions are tested in separate files ## we thus use the relatively fast Gaussian kernel here data("imdepi") model <- twinstim( endemic = addSeason2formula(~offset(log(popdensity)), S = 1, period = 365, timevar = "start"), epidemic = ~type, siaf = siaf.gaussian(), tiaf = tiaf.step(2), data = imdepi, optim.args = NULL, verbose = FALSE ) theta <- c("h.(Intercept)" = -20, "h.sin(2 * pi * start/365)" = 0.2, "h.cos(2 * pi * start/365)" = 0.3, "e.(Intercept)" = -10, "e.typeC" = -0.9, "e.siaf.1" = 2, "e.tiaf.1" = -1) test_that("likelihood is still the same", { expect_equal(model$ll(theta), -9579.65468598488) }) test_that("score vector agrees with numerical approximation", { numsc <- if (surveillance.options("allExamples") && requireNamespace("numDeriv")) { numDeriv::grad(func = model$ll, x = theta) } else { # for faster --as-cran tests c(-321.766081898055, -17.0779781937451, -37.1712258869585, -21.4444934196989, -5.43080160401029, -15.085241575699, -20.1708323190602) } expect_equal(model$sc(theta), numsc) }) ## Note: twinstim() uses an estimate of the _expected_ Fisher information, ## which does not necessarily agree with the negative Hessian of the ll ## (it does asymptotically **at the MLE**) ## numfi <- -numDeriv::hessian(func = model$ll, x = theta) ## anafi <- model$fi(theta) test_that("one-parameter power law agrees with more general implementation", { m0 <- update.default(model, siaf = siaf.powerlaw(), tiaf = NULL, subset = time < 30) m1 <- update.default(m0, siaf = siaf.powerlaw1(sigma = exp(2))) expect_equal(m0$ll(theta), m1$ll(c(head(theta, -2), -1))) expect_equal(m0$sc(theta)[-6], m1$sc(c(head(theta, -2), -1))) }) ### now check with identity link for the epidemic predictor model2 <- update.default(model, siaf = NULL, tiaf = NULL, epidemic = ~1, epilink = "log") model2i <- update.default(model2, epilink = "identity") theta2 <- theta2i <- theta[1:4] theta2i["e.(Intercept)"] <- exp(theta2["e.(Intercept)"]) test_that("likelihoods with log-link and identity link are the same", { expect_equal(model2i$ll(theta2i), model2$ll(theta2)) }) test_that("identity link score vector agrees with numerical approximation", { numsc <- if (surveillance.options("allExamples") && requireNamespace("numDeriv")) { numDeriv::grad(func = model2i$ll, x = theta2i) } else { # for faster --as-cran tests c(-679.706275919901, -91.0659401491325, -114.082117122738, -1532144485.45524) } expect_equal(model2i$sc(theta2i), numsc) }) surveillance/tests/testthat/test-nbOrder.R0000644000176200001440000000213214615164167020454 0ustar liggesusers## generate random adjacency matrix ## radjmat <- function (n) { ## adjmat <- matrix(0L, n, n, dimnames=list(letters[1:n],letters[1:n])) ## adjmat[lower.tri(adjmat)] <- sample(0:1, n*(n-1)/2, replace=TRUE) ## adjmat + t(adjmat) ## } ## set.seed(3); adjmat <- radjmat(5) adjmat <- structure( c(0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 1L, 0L), .Dim = c(5L, 5L), .Dimnames = rep.int(list(c("a", "b", "c", "d", "e")), 2L) ) ## validated matrix of neighbourhood orders nbmat <- structure( c(0L, 2L, 1L, 3L, 2L, 2L, 0L, 1L, 1L, 2L, 1L, 1L, 0L, 2L, 1L, 3L, 1L, 2L, 0L, 1L, 2L, 2L, 1L, 1L, 0L), .Dim = c(5L, 5L), .Dimnames = rep.int(list(c("a", "b", "c", "d", "e")), 2L) ) test_that("nbOrder() returns the validated matrix", { expect_identical(nbOrder(adjmat), nbmat) }) test_that("zetaweights(.,maxlag=1,normalize=FALSE) is inverse of nbOrder", { expect_identical(zetaweights(nbmat, maxlag=1, normalize=FALSE), 1*adjmat) }) surveillance/tests/testthat/test-hhh4_ARasNE.R0000644000176200001440000000221313746767713021057 0ustar liggesusers### Validate AR hhh4 via NE with identity W data("measlesWeserEms") ## fit with AR component as usual vaccdata <- matrix(measlesWeserEms@map$vacc2.2004, byrow = TRUE, nrow = nrow(measlesWeserEms), ncol = ncol(measlesWeserEms)) measlesModel <- list( ar = list(f = addSeason2formula(~1 + vacc2, S=2, period=52)), end = list(f = addSeason2formula(~1, S=1, period=52), offset = population(measlesWeserEms)), family = "NegBin1", data = list(vacc2 = vaccdata)) measlesFit <- hhh4(measlesWeserEms, measlesModel) ## now use an identity matrix as W in the NE component instead of AR measlesFit2 <- suppressWarnings( update(measlesFit, ar = list(f = ~-1), ne = list(f = measlesModel$ar$f, weights = diag(ncol(measlesWeserEms))), use.estimates = FALSE) ) ## compare fits test_that("AR-hhh4 agrees with using identity W in NE", { expect_equivalent(coef(measlesFit2), coef(measlesFit)) expect_equivalent(measlesFit2$cov, measlesFit$cov) expect_equal(logLik(measlesFit2), logLik(measlesFit)) expect_equal(fitted(measlesFit2), fitted(measlesFit)) }) surveillance/tests/testthat/test-formatDate.R0000644000176200001440000000474613746767713021176 0ustar liggesusersd2 <- as.Date(c("2001-01-01","2002-05-01")) test_that("Formatting date vectors with ISO8601 and UK conventions", expect_identical(formatDate(d2, "W%V-%G / W%W-%Y / %d-%m-%Y"), c("W01-2001 / W01-2001 / 01-01-2001", "W18-2002 / W17-2002 / 01-05-2002"))) test_that("Formatting quarters", { expect_identical(formatDate(d2,"%Q"), c("1","2")) expect_identical(formatDate(d2,"%q"), c("1","31")) expect_identical(as.character(d2 - as.numeric(formatDate(d2,"%q")) + 1), c("2001-01-01","2002-04-01")) }) test_that("Formatting date vectors with roman letters for quarters", expect_identical(formatDate(d2,"%G\n%OQ"), c("2001\nI","2002\nII"))) #Some checks for the atChange dates <- seq(as.Date("2007-01-01"),as.Date("2013-01-01"),by="1 week") #Format with conversion string x <- as.numeric(formatDate(dates,"%m")) xm1 <- as.numeric(formatDate(dates[1]-7,"%m")) #At change test_that("atChange function works for %m", expect_identical( atChange(x,xm1), c(1L, 6L, 10L, 14L, 19L, 23L, 27L, 32L, 36L, 40L, 45L, 49L, 54L, 58L, 62L, 67L, 71L, 75L, 80L, 84L, 88L, 93L, 97L, 101L, 106L, 110L, 114L, 119L, 123L, 127L, 132L, 136L, 141L, 145L, 149L, 154L, 158L, 162L, 166L, 171L, 175L, 180L, 184L, 188L, 193L, 197L, 201L, 206L, 210L, 215L, 219L, 223L, 227L, 232L, 236L, 240L, 245L, 249L, 254L, 258L, 262L, 267L, 271L, 275L, 280L, 284L, 288L, 293L, 297L, 301L, 306L, 310L))) #Test every second change function test_that("at2ndChange function works for %m", expect_identical( at2ndChange(x,xm1), c(1L, 10L, 19L, 27L, 36L, 45L, 54L, 62L, 71L, 80L, 88L, 97L, 106L, 114L, 123L, 132L, 141L, 149L, 158L, 166L, 175L, 184L, 193L, 201L, 210L, 219L, 227L, 236L, 245L, 254L, 262L, 271L, 280L, 288L, 297L, 306L))) #### Year formatting x <- as.numeric(formatDate(dates,"%Y")) xm1 <- as.numeric(formatDate(dates[1]-7,"%Y")) test_that("atMedian function works for %Y", expect_identical( atMedian(x,xm1), c(26L, 79L, 131L, 183L, 235L, 287L))) test_that("at2ndChange function works for %Y", expect_identical( dates[at2ndChange(x,xm1)], as.Date(c("2007-01-01","2009-01-05","2011-01-03")))) #Does the following look as expected? (hard to check with testthat) #data("rotaBB") #plot(rotaBB, xaxis.tickFreq=list("%Y"=atChange), xaxis.labelFreq=list("%Y"=at2ndChange),xaxis.labelFormat="%Y",xlab="time (months)") surveillance/tests/testthat/test-determineSources.R0000644000176200001440000000116314013521730022365 0ustar liggesusersdata("imdepi") test_that("determineSources() yields same result as old implementation", { sources0 <- surveillance:::determineSources.epidataCS(imdepi, method = "R") expect_identical(sources0, imdepi$events$.sources) sources1 <- surveillance:::determineSources( imdepi$events$time, imdepi$events$eps.t, coordinates(imdepi$events), imdepi$events$eps.s, imdepi$events$type, imdepi$qmatrix ) expect_identical(sources1, imdepi$events$.sources) sources2 <- surveillance:::determineSources.epidataCS(imdepi, method = "C") expect_identical(sources2, imdepi$events$.sources) }) surveillance/tests/testthat/test-hhh4_NegBinGrouped.R0000644000176200001440000001374114402454111022455 0ustar liggesusers### hhh4() model with shared overdispersion parameters ## use a small subset of districts from the fluBYBW data data("fluBYBW") fluBWsub <- fluBYBW[, substr(colnames(fluBYBW), 1, 2) %in% "81"] ## stsplot_space(fluBWsub, labels = TRUE) ## set "neighbourhood" to order of adjacency + 1 neighbourhood(fluBWsub) <- nbOrder(neighbourhood(fluBWsub)) + 1L ## a crazy model base fluModel <- list( end = list(f = addSeason2formula(~0 + ri(type="iid"))), ne = list(f = ~0 + fe(1, unitSpecific = TRUE), weights = W_powerlaw(maxlag = 3)), start = list(random = rep.int(0, ncol(fluBWsub))) ) if (FALSE) { # check derivatives fluDeriv <- hhh4(stsObj = fluBWsub, control = c(fluModel, list(family = "NegBinM")), check.analyticals = TRUE) ana <- fluDeriv$pen$fisher$analytic num <- fluDeriv$pen$fisher$numeric equal <- mapply(function (...) isTRUE(all.equal.numeric(...)), ana, num, tolerance = 1e-4) dim(equal) <- dim(ana) Matrix::image(Matrix::Matrix(equal)) } ## fit a model with unit-specific overdispersion parameters using "NegBinM", ## equal to family = factor(colnames(fluBWsub), levels=colnames(fluBWsub)) fluFitM <- hhh4(stsObj = fluBWsub, control = c(fluModel, list( family = "NegBinM"))) test_that("\"NegBinM\" fit is invariant to the ordering of the overdispersion parameters", { fluFitM_reordered <- hhh4(stsObj = fluBWsub, control = c(fluModel, list( family = factor(colnames(fluBWsub), levels=rev(colnames(fluBWsub)))))) expect_equal(fluFitM_reordered$loglikelihood, fluFitM$loglikelihood) expect_equal(fluFitM_reordered$margll, fluFitM$margll) expect_equal(fluFitM_reordered$coefficients[names(fluFitM$coefficients)], fluFitM$coefficients) }) test_that("random intercepts can be extracted", { ris <- ranef(fluFitM, intercept = TRUE) expect_equal(dimnames(ris), list(colnames(fluBWsub), "end.ri(iid)")) ## compute endemic predictor at t = 0 (i.e., subset = 1) end.exppred.t0 <- meanHHH(theta = fluFitM$coefficients, model = terms(fluFitM), subset = 1)$end.exppred expect_equal(exp(ris + fluFitM$coefficients["end.cos(2 * pi * t/52)"]), t(end.exppred.t0), check.attributes = FALSE) }) ## fit a model with shared overdispersion parameters fluFitShared <- hhh4(stsObj = fluBWsub, control = c(fluModel, list( family = factor(substr(colnames(fluBWsub), 3, 3) == "1", levels = c(TRUE, FALSE), labels = c("region1", "elsewhere"))))) test_that("estimates with shared overdispersion are reproducible", { ## dput(coef(fluFitShared, se = TRUE)) orig <- structure( c(0.0172448275799737, -2.29936227176632, -0.311391919170833, 0.0173369590386396, 0.242634649538434, -0.73402605050834, -0.0411427686831543, -0.917845995715638, -0.324146451650439, -0.252506337389155, 0.153202205413176, -0.857813219848051, -1.00758863915022, 2.01735387997105, 2.38047570484809, -4.38317074697181, 2.46949727973784, 0.549903756338196, 1.12432744953686, 0.647372578569298, 0.21388842588635, -0.437822769909503, 0.255185408180267, 0.92949604237045, -1.09633602928844, 0.298117843865811, -0.68452091605681, 0.23456335139387, 0.162259631408099, 0.209619606465627, -0.10216429396362, -0.629658878921399, 0.114133112372732, 0.823887580788133, 0.12141926111051, 0.113879127629599, 0.109816278251024, 0.221038616887962, 0.115707006557826, 0.187260599970159, 0.121830940397345, 0.172070355414403, 0.157444513096506, 0.254811666726125, 0.268571254537371, 0.215202234247305, 0.212970632033808, 0.262762514629277, 0.205440489731246, 0.0567461846032841, 0.154168532075271, 0.320248263514015, 0.309517737483193, 0.366585194306804, 0.370748971125027, 0.304859567470968, 0.397763842736319, 0.357894067104384, 0.380956131344983, 0.344676554711052, 0.37300484854814, 0.378382126329053, 0.342270280546076, 0.359489843015429), .Dim = c(32L, 2L), .Dimnames = list( c("ne.1.8115", "ne.1.8135", "ne.1.8117", "ne.1.8116", "ne.1.8111", "ne.1.8121", "ne.1.8118", "ne.1.8136", "ne.1.8119", "ne.1.8125", "ne.1.8127", "ne.1.8126", "ne.1.8128", "end.sin(2 * pi * t/52)", "end.cos(2 * pi * t/52)", "end.ri(iid)", "neweights.d", "overdisp.region1", "overdisp.elsewhere", "end.ri(iid).8115", "end.ri(iid).8135", "end.ri(iid).8117", "end.ri(iid).8116", "end.ri(iid).8111", "end.ri(iid).8121", "end.ri(iid).8118", "end.ri(iid).8136", "end.ri(iid).8119", "end.ri(iid).8125", "end.ri(iid).8127", "end.ri(iid).8126", "end.ri(iid).8128"), c("Estimate", "Std. Error")) ) expect_equal(coef(fluFitShared, se = TRUE), orig) }) test_that("calibrationTest.oneStepAhead() works and \"final\" is equivalent to fit", { mysubset <- tail(fluFitShared$control$subset, 16) osa_final <- oneStepAhead(fluFitShared, tp = mysubset[1L]-1L, type = "final", verbose = FALSE) idx <- 3:5 # ignore "method" and "data.name" in calibrationTest() output expect_equal(calibrationTest(osa_final, which = "dss")[idx], calibrationTest(fluFitShared, which = "dss", subset = mysubset)[idx]) }) test_that("simulation correctly uses shared overdispersion parameters", { fluSimShared <- simulate(fluFitShared, seed = 1) ## simulate from the NegBinM model using the estimates from the shared fit psiShared <- coeflist(fluFitShared)$fixed$overdisp psiByUnit <- psiShared[fluFitShared$control$family] names(psiByUnit) <- paste0("overdisp.", names(fluFitShared$control$family)) coefsM <- c(coef(fluFitShared), psiByUnit)[names(coef(fluFitM))] fluSimSharedM <- simulate(fluFitM, seed = 1, coefs = coefsM) expect_identical(observed(fluSimShared), observed(fluSimSharedM)) ## fails for surveillance 1.12.2 }) surveillance/tests/testthat/test-hhh4_NA.R0000644000176200001440000000544114263475321020274 0ustar liggesusers### fitting hhh4() models to time series with missing values data("influMen") fluMen <- disProg2sts(influMen) ## set some observations to NA set.seed(3) is.na(fluMen@observed) <- sample(length(fluMen@observed), 100) ## compare endemic-only model against NegBin-GLM form <- addSeason2formula(f = ~ -1 + fe(1, which = c(TRUE, TRUE)), S = c(3, 1)) fitHHH <- hhh4(fluMen, list(end = list(f=form), family = "NegBin1", subset = 1:nrow(fluMen))) fitGLM <- MASS::glm.nb( formula = observed ~ -1 + unit + sin(2*pi*t/52):unit + cos(2*pi*t/52):unit + I(sin(4*pi*t/52)*unitI) + I(cos(4*pi*t/52)*unitI) + I(sin(6*pi*t/52)*unitI) + I(cos(6*pi*t/52)*unitI), data = transform(tidy.sts(fluMen), t = epoch - 1, unitI = unit == "influenza")) expect_equal(logLik(fitHHH), logLik(fitGLM)) expect_equal(fitted(fitHHH)[!terms(fitHHH)$isNA], unname(fitted(fitGLM))) expect_equivalent(coef(fitHHH)[["overdisp"]], 1/fitGLM$theta) idxhhh <- c(1:2, 7:10, 3:6) expect_equivalent(head(fitHHH$coefficients, -1), fitGLM$coefficients[idxhhh]) expect_equivalent(head(fitHHH$se, -1), summary(fitGLM)$coefficients[idxhhh, 2], tolerance = 0.01) ### compare AR-only model against NegBin-GLM ## meningococcal counts are strictly positive so plain AR works men <- fluMen[,"meningococcus"] fitHHH_AR <- hhh4(men, list(end = list(f = ~-1), family = "NegBin1", ar = list(f = addSeason2formula(~1)))) fitGLM_AR <- MASS::glm.nb( formula = addSeason2formula(observed ~ 1 + offset(log(Ylag))), data = transform(tidy.sts(men), t = epoch - 1, Ylag = c(NA, head(observed, -1)))) expect_equal(logLik(fitHHH_AR), logLik(fitGLM_AR)) expect_equal(fitted(fitHHH_AR)[!terms(fitHHH_AR)$isNA[fitHHH_AR$control$subset,,drop=FALSE]], unname(fitted(fitGLM_AR))) expect_equivalent(coef(fitHHH_AR)[["overdisp"]], 1/fitGLM_AR$theta) expect_equivalent(head(fitHHH_AR$coefficients, -1), fitGLM_AR$coefficients) expect_equivalent(head(fitHHH_AR$se, -1), summary(fitGLM_AR)$coefficients[, 2], tolerance = 0.05) ### compare NE-only model against NegBin-GLM (where NE is actually AR as above) expect_warning( fitHHH_NE <- hhh4(men, list(end = list(f = ~-1), family = "NegBin1", ne = list(f = addSeason2formula(~1), weights = diag(1)))) , "requires a multivariate") expect_equivalent(fitHHH_AR, fitHHH_NE, ignore = c("control", "lags")) expect_equal(meanHHH(fitHHH_AR$coefficients, terms(fitHHH_AR))$epi.own, meanHHH(fitHHH_NE$coefficients, terms(fitHHH_NE))$epi.neighbours) if (dev.capabilities("capture")[[1L]]) { # e.g. not in tinytest as that uses pdf plot(fitHHH_AR, legend = FALSE, col = c(8,8,8)); plotARfit <- dev.capture() plot(fitHHH_NE, legend = FALSE, col = c(8,8,8)); plotNEfit <- dev.capture() expect_identical(plotARfit, plotNEfit) } surveillance/tests/testthat/test-tiafs.R0000644000176200001440000000501313751221007020153 0ustar liggesusers### Temporal interaction functions for twinstim() test_that("Step kernel of a single type agrees with numerical approximations", { steptiaf <- tiaf.step(c(7,20), maxRange=25, nTypes=1) logvals <- log(c(1.2,0.2)) ##curve(steptiaf$g(x, logvals), 0, 30, n=301) ## check G Gana <- steptiaf$G(0:30, logvals) Gnum <- sapply(0:30, function (upper) { integrate(steptiaf$g, 0, upper, logvals, rel.tol=1e-8)$value }) expect_equal(Gana, Gnum, tolerance = 1e-8) ## check deriv if (requireNamespace("maxLik", quietly = TRUE)) { checkderiv <- maxLik::compareDerivatives( f = function(pars, x) steptiaf$g(x, pars), grad = function(pars, x) steptiaf$deriv(x, pars), t0 = logvals, x = c(0.5,2,5,7,10,15,20,25,30), print = FALSE) expect_true(checkderiv$maxRelDiffGrad < 1e-8) } ## check Deriv for (paridx in seq_along(logvals)) expect_equal( steptiaf$Deriv(0:30, logvals)[,paridx], sapply(0:30, function (upper) integrate(function(...) steptiaf$deriv(...)[,paridx], 0, upper, logvals, rel.tol=1e-6)$value), tolerance = 1e-6, label = paste0("steptiaf$Deriv()[,",paridx,"]"), expected.label = "integrate() approximation" ) }) test_that("Step kernel with maxRange>max(eps.t) is equivalent to maxRange=Inf", { data("imdepi", package="surveillance") imdfit_steptiafInf <- twinstim( endemic = ~offset(log(popdensity)) + I(start/365 - 3.5), epidemic = ~1, siaf = siaf.constant(), tiaf = tiaf.step(c(7,20), maxRange=Inf), data = imdepi, optim.args = NULL, verbose = FALSE) maxepst <- max(imdepi$events$eps.t) imdfit_steptiaf30 <- update.default( ## update() might call an update.list-method registered by another ## package, e.g., gdata (2.18.0) implicitly loaded in other tests imdfit_steptiafInf, tiaf = tiaf.step(c(7,20), maxRange=maxepst+0.1)) coefs <- c(-20, -0.05, -15, -0.5, 0.2, -1) expect_identical(imdfit_steptiafInf$ll(coefs), imdfit_steptiaf30$ll(coefs)) expect_identical(imdfit_steptiafInf$sc(coefs), imdfit_steptiaf30$sc(coefs)) }) surveillance/src/0000755000176200001440000000000014615167606013551 5ustar liggesuserssurveillance/src/determineSources.cc0000644000176200001440000000464114013521730017365 0ustar liggesusers/******************************************************************************* // Determine potential triggering events close in space and time // // Copyright (C) 2016,2021 Sebastian Meyer // // This file is part of the R package "surveillance", // free software under the terms of the GNU General Public License, version 2, // a copy of which is available at https://www.R-project.org/Licenses/. *******************************************************************************/ #include using namespace Rcpp; // Euclidean distance of a set of points to a single point (x0, y0) NumericVector distsN1(NumericVector x, NumericVector y, double x0, double y0) { // hypot(x, y) is not (yet) vectorized by Rcpp sugar return sqrt(pow(x - x0, 2.0) + pow(y - y0, 2.0)); } RcppExport SEXP determineSources( SEXP eventTimesSEXP, SEXP eps_tSEXP, SEXP eventCoordsSEXP, SEXP eps_sSEXP, SEXP eventTypesSEXP, SEXP qmatrixSEXP ){ BEGIN_RCPP NumericVector eventTimes(eventTimesSEXP); NumericVector eps_t(eps_tSEXP); NumericMatrix eventCoords(eventCoordsSEXP); NumericVector eps_s(eps_sSEXP); IntegerVector eventTypes(eventTypesSEXP); LogicalMatrix qmatrix(qmatrixSEXP); int N = eventTimes.size(); NumericVector removalTimes = eventTimes + eps_t; NumericMatrix::Column xcoords = eventCoords(_,0); NumericMatrix::Column ycoords = eventCoords(_,1); List sources(N); LogicalVector infectivity(N); LogicalVector proximity(N); LogicalVector matchType(N); LogicalVector typeInfective(qmatrix.nrow()); IntegerVector eventTypes0 = eventTypes - 1; // for correct indexing IntegerVector idx = seq_len(N); for (int i = 0; i < N; ++i) { infectivity = (eventTimes < eventTimes[i]) & (removalTimes >= eventTimes[i]); // "<" not "<=" because CIF is left-continuous. // Also guarantees no self-infection. proximity = distsN1(xcoords, ycoords, eventCoords(i,0), eventCoords(i,1)) <= eps_s; typeInfective = qmatrix(_,eventTypes0[i]); //<- logical vector indicating for each type if it could infect type of i matchType = typeInfective[eventTypes0]; sources[i] = idx[infectivity & proximity & matchType]; } return wrap(sources); END_RCPP } surveillance/src/twins.cc0000644000176200001440000020660314530153622015220 0ustar liggesusers/******************************************************************* * Authors: * Mathias Hofmann * Michael Hoehle * Volker Schmid * Contributors: * Michaela Paul * Daniel Sabanes Bove * Sebastian Meyer * History: * October 2022 (SM) -- dropped deprecated sprintf and a lot of unused code * and fixed a memory leak * July 2016 (SM) -- dropped deprecated "register" storage class specifier * April 2012 (SM) -- replaced exit() calls by Rf_error() * March 2012 (DSB) -- changed long types to int to be in accordance with R * (we observed bad allocations in 64 bit machines) * May 2010 (DSB) -- modified from Oct 2008 * * Markov Chain Monte Carlo (MCMC) estimation in the Branching Process * like Epidemic Model. Instead of a slow R solution this code * provides a faster C++ solution. Can be invoked through R or be * programmed as a librrary. * * For now this code is quick & dirty. A more OO framework would be nice * to enable better programming, but this will probably be speedwise slower. *******************************************************************/ #include #include /*New C++ uses header iostream (without the .h) followed by a namespace*/ using namespace std; #include /* Replaced calls to GSL with functions from the R API */ #include #include /*wrappers to what used to be GSL functions*/ #include "gsl_wrappers.h" // Dynamic_2d_array class by David Maisonave (609-345-1007) (www.axter.com) // Description: // The dynamic array class listed below is more efficient then other // similar classes that use temporary objects as return types, or use // an std::vector as a return type. // // It's also more compatible with a C style 2D array, in that the // array is in one continuous memory block. This makes it possible // to pass this array object to a C Function that has a C-Style // 2D array for a parameter. // Example usage: /* Dynamic_2d_array MyIntArray(12, 34); MyIntArray[0][1] = 123; cout << MyIntArray[0][1] << endl; */ template < class T > class Dynamic_2d_array { public: // constructor Dynamic_2d_array(size_t row, size_t col) : m_row(row), m_col(col), m_data((row!=0 && col!=0) ? new T[row*col] : NULL) {} // copy ctr Dynamic_2d_array(const Dynamic_2d_array& src) : m_row(src.m_row), m_col(src.m_col), m_data((src.m_row!=0 && src.m_col!=0) ? new T[src.m_row*src.m_col] : NULL) { for(size_t r=0; r LongMatrix; typedef Dynamic_2d_array DoubleMatrix; typedef Dynamic_2d_array IntMatrix; // Analogous class for vectors (== 1D arrays) template < class T > class Dynamic_1d_array { public: // constructor Dynamic_1d_array(size_t length) : m_length(length), m_data((length !=0) ? new T[length] : NULL) {} // copy ctr Dynamic_1d_array(const Dynamic_1d_array& src) : m_length(src.m_length), m_data((src.m_length!=0) ? new T[src.m_length] : NULL) { for(size_t i=0; i LongVector; typedef Dynamic_1d_array DoubleVector; typedef Dynamic_1d_array IntVector; /************************************ Globals *************************************/ /*Setup params*/ int overdispersion; int varnu; int la_rev; int K_geom; int la_estim; int nu_trend; int theta_pred_estim; int xi_estim; int delta_rev; int xi_estim_delta; int epsilon_rev; int xi_estim_epsilon; int xi_estim_psi; double psiRWSigma = 0.25; double xRWSigma = 0.25; double taubetaRWSigma = 0.25; /*Priors*/ double alpha_lambda = 1.0; double beta_lambda = 1.0; double alpha_xi = 1.0; double beta_xi = 1.0; double p_K = 1.0; double alpha_nu = 1.0; double beta_nu = 1.0; double alpha_psi = 1.0; double beta_psi = 10.0; double alpha_a=1; double alpha_b=0.001; double beta_a=1.0; double beta_b=.00001; double gamma_a=1; double gamma_b=0.001; double delta_a=1; double delta_b=0.001; double epsilon_a=1; double epsilon_b=0.001; /********************************************************************* * Compute sum from 1 to I and 2 to n of a vektor with indices 0,...,I * of a vektor with indices 0,...,n * Parameters: * * X a vector with indices 0,..,I of a vector with indices 0,...,n * I "length" of vector (true length due to zero indice is I+1) *********************************************************************/ double sumIn2(const LongMatrix& X, int I, int n) { double res = 0; for (int i=1; i<=I; i++){ for (int t=2; t<=n; t++) { res += X[i][t]; } } return(res); } /********************************************************************* * Compute sum from 1 to I and 2 to n of a vektor with indices 0,...,I * of a vektor with indices 0,...,n * This is the double version * Parameters: * * X a vector with indices 0,..,I of a vector with indices 0,...,n * I "length" of vector (true length due to zero indice is I+1) *********************************************************************/ double sumIn2(const DoubleMatrix& X, int I, int n) { double res = 0; for (int i=1; i<=I; i++){ for (int t=2; t<=n; t++) { res += X[i][t]; } } return(res); } /********************************************************************* * logit function *********************************************************************/ double logit(double y){ if(y <= 0 || y >= 1){ Rf_error("y <= 0 or y >= 1 in logit function.\n"); } double logit; logit = log(y/(1-y)); return(logit); } /********************************************************************* * inverse logit function *********************************************************************/ double invlogit(double y){ double invlogit; invlogit = 1/(1 + exp(-y)); return(invlogit); } /********************************************************************* * inverse logit function diff. *********************************************************************/ double invlogitd(double y){ double invlogitd; invlogitd = exp(-y)/pow((1.0 + exp(-y)),2); return(invlogitd); } /********************************************************************* * Tunes a parameter *********************************************************************/ double tune(double& parameter, double accepted, double samples, double& tunepar, double a=0.3, double b=0.4){ tunepar=1; if ((accepted/samples>a) && (accepted/samplesb) { parameter *= 1.5; } else if (accepted/samples= gsl_rng_uniform()) { alpha[i]=alphaneu; acc_alpha += 1; } } return; } void machnu(DoubleVector& mu, const DoubleVector& alpha, DoubleVector& beta, DoubleVector& delta, DoubleMatrix& nu, int I, int n, int ncov, const DoubleMatrix& xcov, int scov) { for (int i=1; i<=I; i++) { for (int t=2; t<=n; t++) { nu[i][t]=delta[t]*exp(sumg(ncov,xcov,mu,t,scov)+alpha[i]+beta[t]); } } return; } void update_gamma_j(int j, const DoubleVector& alpha, DoubleVector& beta, DoubleVector& gamma, DoubleVector& delta, int ncov, const DoubleMatrix& xcov, const LongMatrix& X, int n, int I, double taugamma, DoubleVector& gammaneu, long& acc_gamma, const DoubleMatrix& omega, int scov) { double g = 0; double gd = 0; double gdd = 0; double c = 0; for(int i=1;i<=I;i++){ for(int t=2;t<=n;t++){ g -= omega[i][t]*delta[t]*exp(alpha[i] + beta[t] + sumg(ncov,xcov,gamma,t,scov)); /* g ist g(gamma[j]^0)*/ gd -= omega[i][t]*delta[t]*exp(alpha[i] + beta[t] + sumg(ncov,xcov,gamma,t,scov))*xcov[j][t]; gdd -= omega[i][t]*delta[t]*exp(alpha[i] + beta[t] + sumg(ncov,xcov,gamma,t,scov))*xcov[j][t]*xcov[j][t]; c += xcov[j][t]*X[i][t]; } } double s = sqrt(1/(taugamma-gdd)); /* s ist s*/ double b = c + gd - gamma[j]*gdd; double m = b*s*s; double gammajStar = gsl_ran_gaussian(s) + m; /* Debug stuff deleted */ for(int k=0;kgsl_rng_uniform()){ gamma[j] = gammajStar; acc_gamma += 1; } return; } void update_lambda_br(DoubleMatrix& lambda, DoubleMatrix& lambda_br,DoubleVector& xi_lambda, IntMatrix& breakpoints, IntMatrix& breakpointsStar, IntVector& K, IntVector& KStar, IntVector& Km1, double alpha_lambda, double beta_lambda, const LongMatrix& Y, const LongMatrix& Z, int n, int I, double& acceptedbr, const DoubleMatrix& omega, int theta_pred_estim, int xi_estim, int K_geom, double p_K, double alpha_xi, double beta_xi) { /*update breakpoints of lambda using reversible jump MCMC*/ int newbreakpoint =0; int removebreakpoint=0; int newbreakpointnumber=0; int u; double v=1; double a; double alpha_la; double beta_la; for(int i=1;i<=I;i++){ if(!theta_pred_estim){ a=gsl_rng_uniform(); if(a<0.5){u=1;}else{u=2;} if(K[i]==1){u=2;v=.5;} /*K[i] is number of segments of lambda*/ if(K[i]==(n-1)){u=1;v=.5;} /*if(!theta_pred_estim) max of K[i] is n-1*/ /*decide if new brreakpoint or remove breakpoint*/ if(u==1){/*remove breakpoint*/ if(K[i]==2){v=2;} KStar[i]=K[i]-1; a=gsl_rng_uniform(); removebreakpoint=(int)floor(a*(double)(K[i]-1))+1; /*generate breakpointsStar*/ for(int k=1;kn){need=1;} for(int k=1;k<=K[i];k++){ if(newbreakpoint==breakpoints[i][k]){ need=1; } } }/*while(need==1)*/ /*generate breakpointsStar*/ for(int k=1;k<=K[i];k++){ if((newbreakpoint>breakpoints[i][k-1])&&(newbreakpoint(n+1)){need=1;} for(int k=1;k<=K[i];k++){ if(newbreakpoint==breakpoints[i][k]){ need=1; } } }/*while(need==1)*/ /*generate breakpointsStar*/ for(int k=1;k<=K[i];k++){ if((newbreakpoint>breakpoints[i][k-1])&&(newbreakpointn){need=1;} for(int k=1;k<=K_delta;k++){ if(newbreakpoint==breakpoints_delta[k]){ need=1; } } }//while(need==1) //generate breakpointsStar_delta for(int k=1;k<=K_delta;k++){ if((newbreakpoint>breakpoints_delta[k-1])&&(newbreakpointn){need=1;} for(int k=1;k<=K_epsilon;k++){ if(newbreakpoint==breakpoints_epsilon[k]){ need=1; } } }//while(need==1) //generate breakpointsStar_epsilon for(int k=1;k<=K_epsilon;k++){ if((newbreakpoint>breakpoints_epsilon[k-1])&&(newbreakpoint\t%f\n", alpha_lambda, beta_lambda, lambda_const); } if(!varnu){ Rprintf("nu: Ga(%f, %f)-->\t%f\n", alpha_nu, beta_nu, nu_const); } if(overdispersion){ Rprintf("psi: Ga(%f, %f)-->\t%f\n", alpha_psi, beta_psi, psi); } Rprintf("------------------------------------------------\n"); } //Allocate arrays for all latent variables and initialize them // first all 2D arrays (matrices) LongMatrix X(I+1, n+1); LongMatrix Y(I+1, n+1); LongMatrix S(I+1, n+1); DoubleMatrix omega(I+1, n+1); DoubleMatrix sumX(I+1, n+1); DoubleMatrix sumY(I+1, n+1); DoubleMatrix sumS(I+1, n+1); DoubleMatrix sumomega(I+1, n+1); DoubleMatrix nu(I+1, n+1); DoubleMatrix lambda(I+1, n+2); DoubleMatrix lambda_br(I+1, n+2); DoubleMatrix eta(I+1, n+1); DoubleMatrix eta2(I+1, n+1); DoubleMatrix varr(I+1, n+1); DoubleMatrix rpearson(I+1, n+1); DoubleMatrix Sumeta(I+1, n+1); DoubleMatrix Sumvarr(I+1, n+1); DoubleMatrix Sumrpearson(I+1, n+1); IntMatrix breakpoints(I+1, n+2); IntMatrix breakpointsStar(I+1, n+2); LongMatrix bp(I+1, n+2); // long** X = new long*[I+1]; // long** Y = new long*[I+1]; // long** S = new long*[I+1]; // double **omega= new double*[I+1]; // double** sumX = new double*[I+1]; // double** sumY = new double*[I+1]; // double** sumS = new double*[I+1]; // double **sumomega= new double*[I+1]; // double **nu= new double*[I+1]; // double *alpha=new double[I+1]; // double* beta= new double[n+1]; // double **lambda=new double*[I+1]; // double **lambda_br=new double*[I+1]; // double **eta=new double*[I+1]; // double **eta2=new double*[I+1]; // double **varr=new double*[I+1]; // double **rpearson=new double*[I+1]; // double **Sumeta=new double*[I+1]; // double **Sumvarr=new double*[I+1]; // double **Sumrpearson=new double*[I+1]; // int **breakpoints=new int*[I+1]; // int **breakpointsStar=new int*[I+1]; // long **bp=new long*[I+1]; // We would have to delete the pointers manually at the end of the routine // in order not to corrupt the memory!!! // for (long i=0; i<=I; i++){ // X[i]=new long[n+1]; // Y[i]=new long[n+1]; // S[i]=new long[n+1]; // omega[i]=new double[n+1]; // sumX[i]=new double[n+1]; // sumY[i]=new double[n+1]; // sumS[i]=new double[n+1]; // sumomega[i]=new double[n+1]; // nu[i]=new double[n+1]; // lambda[i]=new double[n+2]; // lambda_br[i]=new double[n+2]; // breakpoints[i]=new int[n+2]; // breakpointsStar[i]=new int[n+2]; // bp[i]=new long[n+2]; // eta[i]=new double[n+1]; // eta2[i]=new double[n+1]; // varr[i]=new double[n+1]; // rpearson[i]=new double[n+1]; // Sumeta[i]=new double[n+1]; // Sumvarr[i]=new double[n+1]; // Sumrpearson[i]=new double[n+1]; // } // then the rest (1D arrays and numbers) DoubleVector alpha(I + 1); DoubleVector beta(n + 1); DoubleVector delta(n + 2); DoubleVector delta_br(n + 2); double xi_delta = 1; DoubleVector epsilon(n + 2); DoubleVector epsilon_br(n + 2); double xi_epsilon = 1; double xi_psi = 1; IntVector K(I + 1); IntVector Km1(I + 1); IntVector KStar(I + 1); DoubleVector xi_lambda(I + 1); IntVector breakpoints_delta(n+2); IntVector breakpointsStar_delta(n+2); LongVector bp_delta(n+2); int K_delta = 0; int Km1_delta = 0; int KStar_delta = 0; IntVector breakpoints_epsilon(n+2); IntVector breakpointsStar_epsilon(n+2); LongVector bp_epsilon(n+2); int K_epsilon = 0; int Km1_epsilon = 0; int KStar_epsilon = 0; LongVector Xnp1(I + 1); LongVector Snp1(I + 1); LongVector Ynp1(I + 1); LongVector Znp1(I + 1); DoubleVector omeganp1(I + 1); DoubleVector nunp1(I + 1); if(!varnu){ for (int i=0; i<=I; i++) { for (int t=0; t<=n; t++) { nu[i][t] = alpha_nu/beta_nu; } } } for (int i=0; i<=I; i++) { for (int t=0; t<=n; t++) { lambda[i][t] = lambda_const; } } for (int i=0; i<=I; i++) { for (int t=0; t<=n; t++) { X[i][t] = 0; S[i][t] = 0; Y[i][t] = Z[i][t]; omega[i][t] = 1; eta[i][t] = 0; bp[i][t] = 0; bp_delta[t] = 0; bp_epsilon[t] = 0; sumX[i][t] = 0; sumY[i][t] = 0; sumS[i][t] = 0; sumomega[i][t] = 0; Sumeta[i][t] = 0; Sumrpearson[i][t] = 0; } bp[i][n+1] = 0; xi_lambda[i] = 1; bp_delta[n+1] = 0; bp_epsilon[n+1] = 0; } /* Fuer Saisonkomponenente */ int ncov; int scov = 0; if(delta_rev){ scov = 1; } // determine the number of covariates and allocate then // the vectors and design matrix. ncov = nu_trend ? (nfreq * 2 + 2) : (nfreq * 2 + 1); DoubleVector gamma(ncov); DoubleVector gammaneu(ncov); DoubleMatrix xcov(ncov, n+2); // bad, do not do that: // double* gamma; // double* gammaneu = NULL; // double** xcov; if(!nu_trend){ // ncov=nfreq*2+1; // gamma = new double[ncov]; // gammaneu = new double[ncov]; // xcov = new double*[ncov]; // for (int i=0; i tuneSampleSize && (!verbose) && (sampleCounter % (int)floor(sampleSize/100.0) == 0)) { Rprintf("%d%%", sampleCounter*100 / sampleSize); } if(0){ if(varnu){ if ((sampleCounter % 100 == 0)) { Rprintf("alpha\t%f beta\t%f %f gamma[0]\t%f gamma[1]\t%f gamma[2]\t%f %f lambda\t%f\n", (double)acc_alpha/I, beta[2], (double)acc_beta, gamma[0], gamma[1], gamma[2],(double)acc_gamma, lambda[1][2]); /* cout<< "alpha\t" << (double)acc_alpha/I<<" " << "beta\t" <<" "<< beta[2] <<" "<< (double)acc_beta<<" " << "gamma[0]\t" <<" "<< gamma[0] <<" "<< "gamma[1]\t" <<" " << gamma[1] <<" "<< "gamma[2]\t" <<" "<< gamma[2] <<" " << (double)acc_gamma<<" " << "lambda\t" << lambda[1][2] << endl;*/ } } if(la_rev){ if ((sampleCounter % 100 == 0)) { Rprintf("K\t%d\n", K[1]); } } if(delta_rev){ if ((sampleCounter % 100 == 0)) { Rprintf("K_delta\t%d delta[2]\t%f\n", K_delta, delta[2]); } } if(epsilon_rev){ if ((sampleCounter % 100 == 0)) { Rprintf("K_epsilon\t%d epsilon[2]\t%f\n", K_epsilon, epsilon[2]); } } } // cout << ":"<) superflous. double accpsi = exp(logFPsiStar-logFPsi); //Do we accept? if ((psi>0) && (gsl_rng_uniform() <= accpsi)) {psi = psiStar; acceptedPsi++;} } //update xi_psi if(xi_estim_psi){ double a = alpha_psi + 1; double b = beta_psi + psi; xi_psi = gsl_ran_gamma (a, 1/b); } ////////////////////////////////////////////////////////////////////////// //State information to file if we are on an filter'th sample if ((sampleCounter>burnin) && ((sampleCounter-burnin) % filter == 0)) { logfile << sampleCounter << "\t"; if (!la_rev){ logfile << lambda_const << "\t"; } logfile << psi << "\t"; logfile << xi_psi << "\t"; if(!varnu){ logfile << nu_const << "\t"; } } if(varnu){ // Unterprogramme fuer den Update von alpha und beta if (I>=2) { alphaupdate(gamma, alpha, beta, delta, lambda, 1, I, n, Y, X, acc_alpha, taualpha, ncov, xcov, xreg, omega, omega, scov,1); taualpha=update_tau_alpha(alpha, I, alpha_a, alpha_b, xreg); if (sampleCounter%3==0) { if(scov==0){ double asum=0; for (int i=1; i<=I; i++) { asum+=(alpha[i]-xreg[i]); } for (int i=1; i<=I; i++) { alpha[i]-=(asum/I); } gamma[0]=gamma[0]+(asum/I); } } } else { alpha[1]=0.0; } //Update fuer zeitlichen effekt mit RW if (rw>0) { if(scov==0){ // if (sampleCounter%1==0) // { double bsum=0; for (int t=2; t<=n; t++) { bsum+=(beta[t]); } for (int t=2; t<=n; t++) { beta[t]-=(bsum/(n-1)); } gamma[0]=gamma[0]+(bsum/(n-1)); // } } } //if (rw>0) //update saison //update_gamma( alpha, beta, gamma,ncov, xcov, X, Z, Y, n, I, taugamma, 1, lambda, acc_gamma, P, P2, gammaalt, z2, L, Q, omega, omega,1); taugamma=gamma_b; // cout << gamma[0]<<" " << gamma[1] << endl; for(int j=scov;jburnin) && ((sampleCounter-burnin) % filter == 0)) { // for (int i=1;i<=I; i++) { // for (int t=1; t<=n; t++) { // logfile << nu[i][t] << "\t"; // } // } // logfile << mu << "\t"; for (int j=0; jburnin) && ((sampleCounter-burnin) % filter == 0)) { logfile << Km1_delta<<"\t"<< xi_delta<<"\t"; for (int j=2; j<=n; j++) { logfile << delta[j] << "\t"; } } if (sampleCounter>burnin) { for (int k=1; k<=K_delta; k++) { for (int j=2; j<=n; j++) { if (breakpoints_delta[k]==j){ bp_delta[j]+=1; } } } } }//if(delta_rev) }//if }//if varnu if(epsilon_rev){ update_epsilon_br(epsilon, epsilon_br, xi_epsilon, breakpoints_epsilon, breakpointsStar_epsilon, K_epsilon, KStar_epsilon, Km1_epsilon, epsilon_a, epsilon_b, S, n, I, acceptedbr_epsilon, omega, xi_estim_epsilon, K_geom, p_K, alpha_xi, beta_xi); if ((sampleCounter>burnin) && ((sampleCounter-burnin) % filter == 0)) { logfile << Km1_epsilon<<"\t"<< xi_epsilon<<"\t"; for (int j=2; j<=n; j++) { logfile << epsilon[j] << "\t"; } } if (sampleCounter>burnin) { for (int k=1; k<=K_epsilon; k++) { for (int j=2; j<=n; j++) { if (breakpoints_epsilon[k]==j){ bp_epsilon[j]+=1; } } } } }//if(epsilon_rev) if(la_estim){ if (la_rev) { update_lambda_br(lambda, lambda_br, xi_lambda, breakpoints, breakpointsStar, K, KStar, Km1, alpha_lambda, beta_lambda, Y, Z, n, I, acceptedbr, omega, theta_pred_estim, xi_estim, K_geom, p_K, alpha_xi, beta_xi); if ((sampleCounter>burnin) && ((sampleCounter-burnin) % filter == 0)) { logfile << Km1[1]<<"\t"<< xi_lambda[1]<<"\t"; for (int j=2; j<=n; j++) { logfile << lambda[1][j] << "\t"; } } for (int i=1;i<=I; i++) { if (sampleCounter>burnin) { for (int k=1; k<=K[i]; k++) { for (int j=2; j<=n; j++) { if (breakpoints[i][k]==j){ bp[i][j]+=1; } } } } } }//if(la_rev) } // if(la_estim) // cout << S[1][106] << endl; // cout << "test" << endl; //Loop over the individual X[t], Y[t], S[t], and omega[t] for (int i=1;i<=I; i++) { for (int t=2; t<=n; t++) { //Update X double binp = nu[i][t]*xi[i] / (epsilon[t] + nu[i][t]*xi[i] + lambda[i][t] * Z[i][t-1]); X[i][t] = gsl_ran_binomial( binp, Z[i][t]); //Update S binp = epsilon[t] / (epsilon[t] + lambda[i][t] * Z[i][t-1]); //hoehle 9 Apr 2009 -- protection against Z[i][t-1]==0 case, leading to binp = nan if (Z[i][t-1] == 0) {binp = 1;} S[i][t] = gsl_ran_binomial( binp, (Z[i][t] - X[i][t])); //Update Y Y[i][t] = Z[i][t] - X[i][t] - S[i][t]; //Debug //cout << "i=" << i << "\tt=" << t << "\tX=" << X[i][t] << "\tY=" << Y[i][t] << "\tZ=" << Z[i][t] << "\tS=" << S[i][t] << "\tepsilon=" << epsilon[t] << "\tbinp=" << binp << endl; //Update omega[t] in case of overdispersion if(overdispersion){ double a = psi + Z[i][t]; double b = psi + epsilon[t] + nu[i][t] + lambda[i][t]*Z[i][t-1]; omega[i][t] = gsl_ran_gamma(a,1/b); } //Write state to log-file. if (sampleCounter>burnin) { sumX[i][t] += X[i][t]; sumY[i][t] += Y[i][t]; sumS[i][t] += S[i][t]; sumomega[i][t] += omega[i][t]; Sumeta[i][t] += eta[i][t]; Sumvarr[i][t] += varr[i][t]; Sumrpearson[i][t] += rpearson[i][t]; } }//for t }//for i // cout << "test2" << endl; // cout << Z[1][2] << endl; // cout << X[1][2] << endl; // cout << Y[1][2] << endl; // cout << S[1][2] << endl; //Praediktive Verteilung fuer variables nu for (int i=1;i<=I;i++) { if(!theta_pred_estim){ double p_thetanp1 = ((double(K[i]))/double(n)); //(1+double(K[i])) if(K_geom){ p_thetanp1 = (double(K[i])*(1.0-p_K)*(1.0-pow((double)1.0-p_K,double(n-1))))/((double(n)-1.0)*(1.0-pow((double)1.0-p_K,double(n)))); } if(gsl_rng_uniform()<=p_thetanp1){ if (sampleCounter>burnin) { bp[i][n+1] += 1; } double alpha_la = alpha_lambda; double beta_la = beta_lambda; if(xi_estim){ beta_la = xi_lambda[i]; } lambda[i][n+1]=gsl_ran_gamma(alpha_la,1/beta_la); } } if(overdispersion){ omeganp1[i] = gsl_ran_gamma(psi,1/psi); }else{ omeganp1[i] = 1; } if(varnu){ a = 0; for(int j=scov;j0){ a += gsl_ran_gaussian(sqrt(1/taubeta)) + (2*beta[n-1]-beta[n]); } if(delta_rev){ double p_thetanp1 = ((double(K[i]))/double(n)); //(1+double(K[i])) if(K_geom){ p_thetanp1 = ((double(K[i]))*(1.0-p_K)*(1.0-pow((double)1.0-p_K,double(n-1))))/((double(n)-1.0)*(1.0-pow((double)1.0-p_K,double(n)))); } if(gsl_rng_uniform()<=p_thetanp1){ if (sampleCounter>burnin) { bp_delta[n+1] += 1; } double alpha_de = delta_a; double beta_de = delta_b; if(xi_estim){ beta_de = xi_delta; } delta[n+1]=gsl_ran_gamma(alpha_de,1/beta_de); } a += log(delta[n+1]); } nunp1[i] = exp(a); }else{ nunp1[i]=nu[i][n]; } if(epsilon_rev){ double p_thetanp1 = ((double(K[i]))/double(n)); //(1+double(K[i])) if(K_geom){ p_thetanp1 = ((double(K[i]))*(1.0-p_K)*(1.0-pow((double)1.0-p_K,double(n-1))))/((double(n)-1.0)*(1.0-pow((double)1.0-p_K,double(n)))); } if(gsl_rng_uniform()<=p_thetanp1){ if (sampleCounter>burnin) { bp_epsilon[n+1] += 1; } double alpha_ep = epsilon_a; double beta_ep = epsilon_b; if(xi_estim){ beta_ep = xi_epsilon; } epsilon[n+1]=gsl_ran_gamma(alpha_ep,1/beta_ep); } } Xnp1[i] = gsl_ran_poisson(omeganp1[i]*nunp1[i]*xi[i]); Ynp1[i] = gsl_ran_poisson(lambda[i][n+1]*omeganp1[i]*(Z[i][n])); Snp1[i] = gsl_ran_poisson(omeganp1[i]*epsilon[n+1]); Znp1[i] = Xnp1[i] + Ynp1[i] + Snp1[i]; if ((sampleCounter>burnin) && ((sampleCounter-burnin) % filter == 0)) { logfile << Znp1[1] << "\t"; } } if ((sampleCounter>burnin) && ((sampleCounter-burnin) % filter == 0)) { logfile << satdev(n,I,Z,lambda,nu,xi,epsilon,eta,psi,overdispersion) << endl; } logfile.flush(); //Tuning if(sampleCounter == tuneSampleSize){ if (!la_rev) { Rprintf("Current xRWSigma= %f --> acc rate= %f\n", xRWSigma, acceptedlambda/tuneSampleSize); tune(xRWSigma, acceptedlambda, tuneSampleSize,tunex); Rprintf("Corrected xRWSigma= %f\n", xRWSigma); } if(overdispersion){ Rprintf("\nCurrent psiRWSigma= %f --> acc rate = %f\n", psiRWSigma, acceptedPsi/tuneSampleSize); tune(psiRWSigma, acceptedPsi, tuneSampleSize,tunepsi); Rprintf("Corrected psiRWSigma= %f\n", psiRWSigma); } if(varnu&&(rw>0)){ Rprintf("Current taubetaRWSigma= %f --> acc rate %f\n", taubetaRWSigma, acc_beta/tuneSampleSize); tune(taubetaRWSigma, acc_beta, tuneSampleSize,tunetaubeta,0.1,0.4); Rprintf("Corrected taubetaRWSigma= %f\n", taubetaRWSigma); } //tunetaubeta = 0; need=tunex + tunepsi + tunetaubeta; if(need > 0){ acceptedlambda = 0; acceptedbr = 0; acceptedbr_delta = 0; acceptedbr_epsilon = 0; acceptedPsi = 0; sampleCounter = 0; if(varnu){ acc_beta=0; acc_alpha=0; acc_gamma=0; } //Fix seed of generator to reproduce results. // gsl_rng_set(r,seed); }//if }//if sampleCounter++; }//while counter //Write means to logfile2 for (int t=1;t<=n;t++) { logfile2 << (double)sumX[1][t]/((double)samples*(double)filter) << "\t" << (double)sumY[1][t]/((double)samples*(double)filter)<< "\t" << (double)sumomega[1][t]/((double)samples*(double)filter) << "\t"<< (double)bp[1][t]/((double)samples*(double)filter) << "\t"; } logfile2 << (double)bp[1][n+1]/((double)samples*(double)filter) << "\t"; logfile2 << endl; //Write accepted status to file if(overdispersion){acclog << "psi\t" << psiRWSigma << "\t" << (double)acceptedPsi/(double)sampleSize << endl;} if (!la_rev){acclog << "lambda\t" << xRWSigma << "\t" << (double)acceptedlambda/(double)sampleSize << endl;} if (la_rev){acclog << "br\t" << 0 << "\t" << (double)acceptedbr/(double)sampleSize << endl;} if(I>1){acclog << "alpha\t" << 0 <<"\t" <<(double)acc_alpha/((double)sampleSize*I)<0)){acclog <<"beta\t"<<0 <<"\t"<< (double)acc_beta/((double)sampleSize*(double)(n-1.0))< #include #include /*** C-implementation of "intrfr" functions ***/ // power-law kernel static double intrfr_powerlaw(double R, double *logpars) { double sigma = exp(logpars[0]); double d = exp(logpars[1]); double onemd = 1.0 - d; double twomd = 2.0 - d; if (fabs(onemd) < 1e-7) { return R - sigma * log1p(R/sigma); } else if (fabs(twomd) < 1e-7) { return log1p(R/sigma) - R/(R+sigma); } else { return (R*pow(R+sigma,onemd) - (pow(R+sigma,twomd) - pow(sigma,twomd))/twomd) / onemd; } } static double intrfr_powerlaw_dlogsigma(double R, double *logpars) { double newlogpars[2] = {logpars[0], log1p(exp(logpars[1]))}; // sigma*d = exp(logsigma+logd) return -exp(logpars[0]+logpars[1]) * intrfr_powerlaw(R, newlogpars); } static double intrfr_powerlaw_dlogd(double R, double *logpars) { double sigma = exp(logpars[0]); double d = exp(logpars[1]); double onemd = 1.0 - d; double twomd = 2.0 - d; if (fabs(onemd) < 1e-7) { return sigma * logpars[0] * (1.0-logpars[0]/2.0) - log(R+sigma) * (R+sigma) + sigma/2.0 * pow(log(R+sigma),2.0) + R; } else if (fabs(twomd) < 1e-7) { return (-log(R+sigma) * ((R+sigma)*log(R+sigma) + 2.0*sigma) + (R+sigma)*logpars[0]*(logpars[0]+2.0) + 2.0*R) / (R+sigma); } else { return (pow(sigma,twomd) * (logpars[0]*(-d*d + 3.0*d - 2.0) - 2.0*d + 3.0) + pow(R+sigma,onemd) * (log(R+sigma)*onemd*twomd * (sigma - R*onemd) + R*(d*d+1.0) + 2.0*d*(sigma-R) - 3.0*sigma) ) * d/onemd/onemd/twomd/twomd; } } // student kernel static double intrfr_student(double R, double *logpars) { double sigma = exp(logpars[0]); double d = exp(logpars[1]); double onemd = 1.0 - d; if (fabs(onemd) < 1e-7) { return log(R*R+sigma*sigma) / 2.0 - logpars[0]; } else { return ( pow(R*R+sigma*sigma,onemd) - pow(sigma*sigma,onemd) )/2/onemd; } } static double intrfr_student_dlogsigma(double R, double *logpars) { double sigma = exp(logpars[0]); double d = exp(logpars[1]); return sigma*sigma * ( pow(R*R+sigma*sigma,-d) - pow(sigma,-2.0*d) ); } static double intrfr_student_dlogd_primitive(double x, double sigma, double d) { double x2ps2 = x*x + sigma*sigma; double dm1 = d - 1.0; return (d*dm1*log(x2ps2) + d) / (2.0*dm1*dm1 * pow(x2ps2,dm1)); } static double intrfr_student_dlogd(double R, double *logpars) { double sigma = exp(logpars[0]); double d = exp(logpars[1]); if (fabs(d-1.0) < 1e-7) { return pow(logpars[0], 2.0) - pow(log(R*R+sigma*sigma), 2.0) / 4.0; } else { return intrfr_student_dlogd_primitive(R, sigma, d) - intrfr_student_dlogd_primitive(0.0, sigma, d); } } // lagged power-law kernel static double intrfr_powerlawL_sigmadxplint(double R, double sigma, double d) { double twomd = 2.0 - d; double xplint = (fabs(twomd) < 1e-7) ? log(R/sigma) : (pow(R,twomd)-pow(sigma,twomd))/twomd; return pow(sigma,d) * xplint; } static double intrfr_powerlawL(double R, double *logpars) { double sigma = exp(logpars[0]); double upper = (R > sigma) ? sigma : R; double res = upper*upper / 2.0; // integral over x*constant part if (R <= sigma) { return res; } else { return res + intrfr_powerlawL_sigmadxplint(R, sigma, exp(logpars[1])); } } static double intrfr_powerlawL_dlogsigma(double R, double *logpars) { double sigma = exp(logpars[0]); if (R <= sigma) { return 0.0; } double d = exp(logpars[1]); return d * intrfr_powerlawL_sigmadxplint(R, sigma, d); } static double intrfr_powerlawL_dlogd(double R, double *logpars) { double sigma = exp(logpars[0]); if (R <= sigma) { return 0.0; } double d = exp(logpars[1]); double twomd = 2.0 - d; double sigmadRtwomdd = pow(sigma,d) * pow(R,twomd) * d; return (fabs(twomd) < 1e-7) ? -pow(sigma*log(R/sigma), 2.0) : (sigmadRtwomdd * (-twomd)*log(R/sigma) - d*sigma*sigma + sigmadRtwomdd)/(twomd*twomd); } // Gaussian kernel static double intrfr_gaussian(double R, double *logsigma) { double sigma2 = exp(2*logsigma[0]); return sigma2 * (1 - exp(-R*R/2/sigma2)); } static double intrfr_gaussian_dlogsigma(double R, double *logsigma) { double sigma2 = exp(2*logsigma[0]); double R2sigma2 = R*R/2/sigma2; return 2*sigma2 * (1 - (1+R2sigma2)/exp(R2sigma2)); } // Exponential kernel static double intrfr_exponential(double R, double *logsigma) { double sigma = exp(logsigma[0]); return sigma * (sigma - (R+sigma)*exp(-R/sigma)); } static double intrfr_exponential_dlogsigma(double R, double *logsigma) { double sigma = exp(logsigma[0]); return 2*sigma*sigma - ((R+sigma)*(R+sigma) + sigma*sigma)*exp(-R/sigma); } /*** function to be called from R ***/ void siaf_polyCub1_iso( double *x, double *y, // vertex coordinates (open) int *L, // number of vertices int *intrfr_code, // F(R) identifier double *pars, // parameters for F(R) int *subdivisions, double *epsabs, double *epsrel, // Rdqags options int *stop_on_error, double *value, double *abserr, int *neval) // results { intrfr_fn intrfr; switch(*intrfr_code) { // = INTRFR_CODE in ../R/twinstim_siaf_polyCub_iso.R case 10: intrfr = intrfr_powerlaw; break; case 11: intrfr = intrfr_powerlaw_dlogsigma; break; case 12: intrfr = intrfr_powerlaw_dlogd; break; case 20: intrfr = intrfr_student; break; case 21: intrfr = intrfr_student_dlogsigma; break; case 22: intrfr = intrfr_student_dlogd; break; case 30: intrfr = intrfr_powerlawL; break; case 31: intrfr = intrfr_powerlawL_dlogsigma; break; case 32: intrfr = intrfr_powerlawL_dlogd; break; case 40: intrfr = intrfr_gaussian; break; case 41: intrfr = intrfr_gaussian_dlogsigma; break; case 50: intrfr = intrfr_exponential; break; case 51: intrfr = intrfr_exponential_dlogsigma; break; default: error("unknown intrfr_code"); break; } double center_x = 0.0; double center_y = 0.0; polyCub_iso(x, y, L, intrfr, pars, ¢er_x, ¢er_y, subdivisions, epsabs, epsrel, stop_on_error, value, abserr, neval); return; } surveillance/src/stcd-assuncaocorrea.cc0000644000176200001440000002424114313613377020022 0ustar liggesusers/** * File based on algoritmos.cpp and sv.cpp from the TerraView plugin. * C++ source originally created by Marcos Oliveira Prates on 06 April 2006 * * R interface by Michael Hoehle initiated on 12 Jan 2009 */ #include "stcd-assuncaocorrea.h" #include #include using namespace std; // Calculate the number of events in the cylinder B( (xk,yk), rho) // (i.e. represented by the boolean matrix MSpace) between event times // (tj,ti] // // Params: // MSpace - contains for each pair of points is geographically // B( (xi,yi), rho) // EvtN - The last event, i.e. t_i // EvtJ - The first event, i.e. t_j int CalculaNCj(short **MSpace, const int EvtN, const int EvtJ) { int i; int Soma=0; for (i=EvtJ;i<=EvtN;i++) Soma += MSpace[EvtJ][i]; return(Soma); } // Calculate the number of events in the cylinder B( (xj,yj), rho) // (i.e. represented by the boolean matrix MSpace) between event times // (0,t_n] int ContaEvt(short **MSpace, const int EvtN, const int EvtJ) { int i; int Soma=0; for (i=0;i<=EvtN;i++) Soma += MSpace[EvtJ][i]; return(Soma); } ////////////////////////////////////////////////////////////////////// // Comment: Unfortunately, this function has not been commented in the // TerraView and hence it has been a bit difficult to document its exact // use. // // Params: // ev - a list of the events // RaioC - radius of the cylinder // epslon - relative change \lambda(s,t)(1+epsilon*I_{C_k}(s,t)) // areaA - area of the observation window A (also denoted W) // areaAcapBk - area of A \ B(s_k,\rho) for all k=1,\ldots,n // cusum - return Shiryaev-Roberts (FALSE) or CUSUM (TRUE) test // statistic // R - array of length ev where the computed values of R_n are // to be returned in. ////////////////////////////////////////////////////////////////////// int SistemadeVigilancia(SVEventLst &ev, const double RaioC, const double epslon, const double areaA, double *areaAcapBk, const int cusum, std::valarray &R) { size_t i, j, NCj, NumTotEvt, NumEvtCil; short **MSpace; double pontox, pontoy, DistEucl, Soma, UCj, fator; //order the event list ev.sort(); SVEventLst::size_type n_event = ev.size(); //create the spatio matrix MSpace = new short* [n_event]; if( MSpace == NULL ) return 1; for( i = 0; i < n_event; i++ ) { MSpace[i] = new short[n_event]; if( MSpace[i] == NULL ) { delete []MSpace; return 1; } } //create the output vector R.resize(n_event); if( R.size() != n_event ) { for( i = 0; i < n_event; i++ ) { delete []MSpace[i]; } delete []MSpace; return 1; } //Populate the spatio matrix with 1's if within radius rho in space //and 0 if not i = 0; for( SVEventLst::iterator it = ev.begin(); it != ev.end(); ++it, i++ ) { j = 0; for( SVEventLst::iterator jt = ev.begin(); jt != ev.end(); ++jt, j++ ) { pontox = (*it).x-(*jt).x; pontoy = (*it).y-(*jt).y; DistEucl = sqrt((pontox*pontox)+(pontoy*pontoy)); if((DistEucl < RaioC)) MSpace[i][j]=1; else MSpace[i][j]=0; } } ////////////////////////////////////////////////////////////////////// //Sequentually, for n=1,2,3,... compute the value of R_n by //by summing up all contributions of Lambda_{k,n} to form R_n, i.e. // \sum_{k=1}^n \Lambda_{k,n} ////////////////////////////////////////////////////////////////////// double LambdaMax = 0, Lambda; SVEventLst::iterator it2, jt2, ev0; //Loop over all n for( i = 0; i < n_event; i++ ) { Soma = 0.0; //Loop over 1<= k <= n (in code k is called j and n is i) for( j = 0; j <= i; j++ ) { //N(C_{k,n}) NCj = CalculaNCj(MSpace,i,j); //N(B(s_k, \rho) \times (0,t_n]) NumTotEvt = ContaEvt(MSpace,i,j); //N(A \times (t_k,t_n) ) = n-k+1 NumEvtCil = i-j+1; UCj = ((double)NumEvtCil*(double)NumTotEvt)/(double)(i+1); fator = 1.0+epslon; Lambda = pow(fator,(double)NCj) * exp((-epslon)*UCj); /* //Alternative estimation having the desired property for \rho->\infty // N( A \times (0,t_k] \cup (A\times (t_k,t_n) \backslash C_{k,n}) ) // \nu( A \times (0,t_k] \cup (A\times (t_k,t_n) \backslash C_{k,n}) ) double iCount=0; double jCount=0; ev0 = ev.begin(); for( it2 = ev.begin(); iCount < i ; ++it2, iCount++ ); for( jt2 = ev.begin(); jCount < j ; ++jt2, jCount++ ); double NNoCkn = ((j-1) + (NumEvtCil - NCj)); double volCkn = areaAcapBk[j] * ((*it2).t - (*jt2).t); double volNoCkn = areaA * ((*it2).t - (*ev0).t) - volCkn; UCj = (NNoCkn / volNoCkn) * volCkn; // Debug // cout << "----> k=" << j << " n= " << i << endl; // cout << "t_k=" << (*jt2).t << endl; // cout << "t_n=" << (*it2).t << endl; // cout << "N(C_{k,n}) = NCj; // cout << "N(W\\times(0,t_n) \\backslash C_{k,n}))=" << NNoCkn << endl; // cout << "vol(C_{k,n}))=" << volCkn << endl; // cout << "vol(W\\times(0,t_n) \backslash C_{k,n})=" << volNoCkn << endl; //// cout << "mu(C_{k,n})=" << UCj << endl; //Lambda = pow(fator,(double)NCj) * exp((-epslon)*UCj); */ //Summation for the Shiryaev-Roberts statistics Soma += Lambda; //Find maximum k of \Lambda_{k,n} for the CUSUM statistics if (Lambda> LambdaMax) { LambdaMax = Lambda; } } //Depending on the summation scheme compute the statistic. if (cusum) { R[i] = LambdaMax; } else { R[i] = Soma; } } //clean memory for( i = 0; i < n_event; i++ ) { delete [] MSpace[i]; } delete [] MSpace; return 0; } int CalculaLambda(SVEventLst &ev, const double RaioC, const double epslon, std::valarray &R, unsigned int &numObs) { size_t i, j, NCj, NumTotEvt, NumEvtCil; short **MSpace; double pontox, pontoy, DistEucl, UCj, fator, lambda, lambdaMax; ev.sort(); SVEventLst::size_type n_event = ev.size(); //create the spatio matrix MSpace = new short* [n_event]; if( MSpace == NULL ) return 1; for( i = 0; i < n_event; i++ ) { MSpace[i] = new short[n_event]; if( MSpace[i] == NULL ) { delete []MSpace; return 1; } } //create the output vector R.resize(n_event); if( R.size() != n_event ) { for( i = 0; i < n_event; i++ ) { delete []MSpace[i]; } delete []MSpace; return 1; } //populate the spatio matrix with 1 if is close in spatio and 0 if not i = 0; for( SVEventLst::iterator it = ev.begin(); it != ev.end(); ++it, i++ ) { j = 0; for( SVEventLst::iterator jt = ev.begin(); jt != ev.end(); ++jt, j++ ) { pontox = (*it).x-(*jt).x; pontoy = (*it).y-(*jt).y; DistEucl = sqrt((pontox*pontox)+(pontoy*pontoy)); if((DistEucl < RaioC)) MSpace[i][j]=1; else MSpace[i][j]=0; } } //do the calculus to find the output value of each event i = numObs; lambdaMax = 0; for( j = 0; j <= i; j++ ) { NCj = CalculaNCj(MSpace,i,j); NumTotEvt = ContaEvt(MSpace,i,j); NumEvtCil = i-j+1; UCj = ((double)NumEvtCil*(double)NumTotEvt)/(double)(i+1); fator = 1.0+epslon; lambda = (pow(fator,(double)NCj) * exp((-epslon)*UCj)); if (lambda > lambdaMax){ lambdaMax = lambda; numObs = j; } } //clean memory for( i = 0; i < n_event; i++ ) { delete [] MSpace[i]; } delete [] MSpace; return 0; } ////////////////////////////////////////////////////////////////////// // Shiryaev-Roberts space time detection as explained in the paper // by Correa and Assuncao (2009). // // Params: // x - array with x location of events // y - array with y location of events // t - array with time point of the events (on some arbitrary time scale) // n - number of elements in x, y and t (the same for the three vectors) // radius - cluster of the radius // epsilon - relative ratio of the intensity functions to detect for // areaA - area of the observation region (also denoted W) // areaAcapBk - area of A \ B(s_k,\rho) for all k=1,\ldots,n // threshold -- upper threshold when to sound the alarm // Rarray -- array of length n, this will contain the statistics calced // by the function // idxFirstAlarm -- index in the x,y,t vector resulting in the alarm // idxClusterCenter -- index in the x,y,t vector containing the cluster // center ////////////////////////////////////////////////////////////////////// extern "C" { void SRspacetime(double *x, double *y, double *t, int *n, double *radius, double *epsilon, double *areaA, double *areaAcapBk, int *cusum, double *threshold, double *Rarray, int *idxFirstAlarm, int *idxClusterCenter) { //Create SVEventLst SVEvent e; SVEventLst eList; unsigned int i; int j; //Fill coordinates of event list for(j=0;j<*n;j++){ e.x = x[j]; e.y = y[j]; e.t = t[j]; eList.push_back(e); } //Array of test statistic values std::valarray R; //Call SistemadeVigilancia, this calculates the SR statistics R_n SistemadeVigilancia(eList,*radius,*epsilon,*areaA,areaAcapBk,*cusum, R); //Debug purposes //cout << "Size of R = " << R.size() << endl; //Move values of test statistic for return for(i=0;i*threshold){ controle = true; break; } } //Advancing the iterator "it" to the point //where the alarm is generated. if (controle) { unsigned int cont = 0; SVEventLst::iterator it = eList.begin(); while((cont < i) && (it != eList.end())){ ++it; ++cont; } *idxFirstAlarm = cont; //Determine the cluster center of the alarm unsigned int num = cont; CalculaLambda(eList,*radius,*epsilon,R,num); //Index of the cluster center *idxClusterCenter = num; } else { //If no alarms, then return -1 for both alarm idx and cluster center idx *idxFirstAlarm = -2; *idxClusterCenter = -2; } //Clean up (nothing to clean) and done } } surveillance/src/surveillance.c0000644000176200001440000011055014615162374016410 0ustar liggesusers/** C routines for the surveillance package Author: (C) Michael Hoehle Date: 8 Jan 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, a copy is available at http://www.r-project.org/Licenses/ Atm the only C routines are concerned with the GLR computations in the algorithm algo.prc. //should check that these really work... void lr_cusum - intercept chart with known kappa void glr_cusum - intercept chart with estimated kappa void glr_cusum_window -- window limited intercept chart with estimated kappa //removedvoid glr_epi void glr_epi_window //History 17 Feb 2009 -- added LR scheme for negative binomial (still experimental) 08 Jan 2007 -- added the files for the negative binomial computations 21 Sep 2007 -- modified code to get around error of extreme strict (=pedantic) MacOS compiling on CRAN 28 Nov 2006 -- file created */ /*#define DEBUG*/ #include #include #include #include /* header */ /* void lr_cusum(int* ,double* , int *, double *, double *,int *, double *) ; void glr_cusum(int* ,double* , int *, int *, double *,int *, double *, int *, int *, int *) ; */ /* Helper function for x^2 */ static R_INLINE double sqr(double x) { return(x*x); } /*====================================================================== Poisson GLR detector ====================================================================== */ /********************************************************************** C implementation of the LR test for the seasonal Poisson chart with fixed change in the intercept Params: x - array of observed values (pos 0 is first interesting value) mu0 - array with the means once in-control (pos 0 is first interesting value) lx - length of the x and mu0 array kappa- the change in intercept to detect (here known in advance) c_ARL- when to sound alarm threshold ret_N- here the return value is stored ret_lr- GLR value for each n to be returned ret_cases - The number of cases to be returned ret - what should be returned (value of lr-statistic, cases)? **********************************************************************/ void lr_cusum(int* x,double* mu0, int *lx_R, double *kappa_R, double *c_ARL_R,int *ret_N, double *ret_lr, double *ret_cases, int *ret_R) { /* Pointers to something useful */ int lx = *lx_R; double c_ARL = *c_ARL_R; double kappa = *kappa_R; int ret = *ret_R; /* Loop variables */ register int n=0; int stop = 0; int N = lx; /* Loop over all 0 <= n <= length(x) */ while ((n < lx)) { /*Compute for one n*/ /*printf("n=%d\n",n);*/ double zn = kappa * x[n] + (1-exp(kappa))*mu0[n]; #ifdef DEBUG printf("For kappa=%f and mu[%d]=%f:\tx[%d]=%f, LR=%f\n",kappa,n,mu0[n],n,x[n],zn); #endif /* Add up */ if (n==0) { ret_lr[n] = fmax(0,zn); /*5.11.2009 -- Bug fix. There was a small programming error for the computing the cases for n==0. if (ret==2) ret_cases[n] = (c_ARL + mu0[n]*(kappa-1))/kappa ; */ if (ret==2) ret_cases[n] = (c_ARL + mu0[n]*(exp(kappa)-1))/kappa ; } else { ret_lr[n] = fmax(0,ret_lr[n-1] + zn); if (ret==2) ret_cases[n] = (c_ARL - ret_lr[n-1] + mu0[n]*(exp(kappa)-1))/kappa ; } /* Find the first time that the GLR increases c_ARL there we stop */ if ((ret_lr[n] > c_ARL) && !stop) { N = n; stop = 1; break; } /* Advance counter */ n++; } /* Return value (add 1 for R/SPlus array compatibility */ *ret_N = N+1; } /*********************************************************************** Function for the computation of the glr-statistic with time-varying in-control value Params n - timepoint n where the glr-statistic should be computed x - array with observations mu0 - array with estimated in-comtrol parameters dir - direction of testing (up (1) or down (-1) the function returns max_1<=k<=n sup_theta sum_t=k^n log f_theta(x_t)/f_theta0(x_t) ************************************************************************/ static double glr (int n, int x[], double mu0[], int dir){ /* For the recursive computation of kappa_ml */ double sumx = 0; double summu0 = 0; /* Define max of the GLR stats */ double maxGLR = -1e99; /* Loop variable */ register int k; /* For fitting and summation */ double kappa_ml = 0; double sum = 0; /* Loop over all k */ for (k=n; k>=0; k--) { /* Backwards loop makes calculations faster */ /* Recursive update of the kappa.ml quantitities */ sumx += x[k]; summu0 += mu0[k]; /* Calculate MLE of kappa */ kappa_ml = dir*fmax(0,dir*log(sumx/summu0)); /* Recursive updating of the likelihood ratios -- See notes on the 21 september printout. This is fast! */ sum = kappa_ml * sumx + (1-exp(kappa_ml))*summu0; /* save max value */ if (sum > maxGLR) { maxGLR = sum;} } return(maxGLR); } /*********************************************************************** Function for the computation of the window-limited glr-statistic with time-varying in-control value Params n - timepoint n where the glr-statistic should be computed x - array with observations mu0 - array with estimated in-comtrol parameters dir - direction of testing (up (1) or down (-1) M - max time to go back in time from N Mtilde - number of vals we will need to estimate a detection the function returns max(0,n-M) <= k <= n-Mtilde sup_theta sum_t=k^n log f_theta(x_t)/f_theta0(x_t) ************************************************************************/ static double glr_window (int n, int x[], double mu0[], int dir, int M, int Mtilde){ /* Define max of the GLR stats */ double maxGLR = -1e99; /* Loop variable */ register int k,l; /* For the recursive computation of kappa_ml compute for (n-Mtilde+1):n */ double sumx = 0; double summu0 = 0; /* For fitting and summation */ double sum = 0; double kappa_ml = 0; for (l=n-Mtilde+1; l<=n; l++) { sumx += x[l]; summu0 += mu0[l]; } /* Loop over all max(0,n-M) <= k <= n-Mtilde -- do this backwards */ /* for (k=max(0,n-M); k<= (n-Mtilde); k++) { */ for (k=n-Mtilde; k>=fmax(0,n-M); k--) { /* Recursive update of the kappa.ml quantitities */ sumx += x[k]; summu0 += mu0[k]; kappa_ml = dir*fmax(0,dir*log(sumx/summu0));; /*Calculate sum of likelihood ratios using recursive updating (fast!)*/ sum = kappa_ml * sumx + (1-exp(kappa_ml))*summu0; /* Save the max value */ if (sum > maxGLR) { maxGLR = sum;} } return(maxGLR); } /********************************************************************** Fast C implementation of the sequential GLR test without windowing for Poisson distributed variables, this function can test in both directions (up/down) and there is the possibility ( in opposite to old function glr_cusum) to return the number of cases at timepoint n to produce an alarm at any timepoint 1<=k<=n Params: x - array of observed values (pos 0 is first interesting value) mu0 - array with the means once in-control (pos 0 is first interesting value) lx - length of the x and mu0 array n0 - number of burn-in values (number of observations, not array index!) c_ARL- when to sound alarm threshold ret_N- here the return value is stored ret_glr- GLR value for each n to be returned dir - direction of testing ret - what should be returned (value of glr-statistic, cases)? **********************************************************************/ void glr_cusum(int* x,double* mu0, int *lx_R, int *n0_R, double *c_ARL_R,int *ret_N, double *ret_glr, double *ret_cases, int *dir_R, int *ret_R) { /* Pointers to something useful */ int lx = *lx_R; int n0 = *n0_R; int dir = *dir_R; int ret = *ret_R; double c_ARL = *c_ARL_R; /* Loop variables */ register int n; /*l,n0-1*/ for (n=0; n= c_ARL */ while ((dir*glrnew < c_ARL*dir)){ /* increase/decrease xnnew */ xnnew = xnnew + 1; /* put this value in vector x at timepoint n */ x[n] = xnnew; /* compute the glr-statistic */ glrnew = glr(n,x,mu0,dir); } /* save the value */ ret_cases[n] = xnnew; /* set x[n] back to original value so that we can go to next n*/ x[n] = xnold; } /* Find the first time that the GLR increases c_ARL there we stop */ if ((ret_glr[n] >= c_ARL) && !stop) { N = n; stop = 1; break; } /*Advance counter*/ n++; } /* Return value (add 1 for R/SPlus array compatibility */ *ret_N = N+1; } /********************************************************************** Fast C implementation of the sequential GLR test without windowing for Poisson distributed variables Params: x - array of observed values (pos 0 is first interesting value) mu0 - array with the means once in-control (pos 0 is first interesting value) lx - length of the x and mu0 array Mtilde - number of vals we will need to estimate a detection M - max time to go back in time from N c_ARL- when to sound alarm threshold **********************************************************************/ void glr_cusum_window(int* x,double* mu0, int *lx_R, int *M_R, int *Mtilde_R, double *c_ARL_R,int *ret_N, double *ret_glr, double *ret_cases, int *dir_R, int *ret_R) { /* Pointers to something useful */ int lx = *lx_R; int M = *M_R; int Mtilde = *Mtilde_R; int dir = *dir_R; int ret = *ret_R; double c_ARL = *c_ARL_R; /* Loop variables (n>Mtilde, so we start with n=Mtilde (due to -1 in index) */ register int n = Mtilde; /*l*/ int stop = 0; int N = lx; /* Precalculation of log(mu0) -- apparently not used anymore */ //double logmu0[lx]; //for (l=0;l= c_ARL */ while ((dir*glrnew < c_ARL*dir)){ /* increase/decrease xnnew */ xnnew = xnnew + 1; /* put this value in vector x at timepoint n */ x[n] = xnnew; /* compute the glr-statistic */ glrnew = glr_window(n,x,mu0,dir,M,Mtilde); } /* save the value */ ret_cases[n] = xnnew; /* set x[n] back to original value so that we can go to next n*/ x[n] = xnold; } /* Debug*/ /* printf("For n=%d the best GLR value is %f\n",n,maxGLR);*/ /* Find the first time that the GLR increases c_ARL there we stop */ if ((ret_glr[n] >= c_ARL) && !stop) { N = n; stop = 1; break; } /* Advance counter */ n++; } /* Return value (add 1 for R/SPlus array compatibility */ *ret_N = N+1; } /*====================================================================== GLR in the Epidemic Poisson model ====================================================================== */ /*Helper functions*/ /* Score function */ static R_INLINE double score(double phi, int *x, double *xm1, double *mu0, int k, int n) { register int i; double sum = 0; /*printf("[1] ");*/ for (i=k; i<=n; i++) { sum += (x[i]*xm1[i])/(exp(phi)*xm1[i]+mu0[i]) - xm1[i]; } /*printf("\n");*/ return(exp(phi)*sum); } /*fisher information*/ static R_INLINE double fisher(double phi,int *x,double *xm1, double *mu0, int k,int n,double scorephi) { register int i; double sum = 0; for (i=k; i<=n; i++) { sum += (x[i]*sqr(xm1[i]))/sqr(exp(phi)*xm1[i]+mu0[i]); } return(-scorephi + exp(2.0*phi)*sum); } /********************************************************************** GLR detector for the epidemic Poisson model described in Held et. al (2005). Parameters: x -- the data (as array) mu0 -- base means under H0 lx -- length of x Mtilde_R -- number of obs needed to get good estimate (typically 1) M -- Mtilde < M xm10 -- observed value of x_0 (0 for initialization, but known if >1st round) c_ARL_R -- constant determining when to signal alarm ret_N -- the return value ret_lr --- GLR value for each n to be returned **********************************************************************/ void glr_epi_window(int* x,double* mu0, int *lx_R, int *Mtilde_R, int *M_R, double *xm10, double *c_ARL_R,int *ret_N, double *ret_glr) { /* printf("====> begin glr_epi\n"); */ /* Pointers to something useful */ int lx = *lx_R; /* length of x */ int Mtilde = *Mtilde_R; int M = *M_R; double c_ARL = *c_ARL_R; /* Loop variables */ register int n, k,i; /* Init return values up to the first position */ int n0 = fmax(Mtilde-1,0); /*hoehle: 25.9: changepoint can happen at position one: fmax(Mtilde-1,1);*/ for (n=0; n-18) & (fabs(exp(phi_new) - exp(phi_old)) > 1e-6) & (iter maxGLR) { maxGLR = lnk;} } /*Debug */ /*printf("For n=%d the best GLR value is %f\n",n,maxGLR); */ /*Save the return value */ ret_glr[n] = maxGLR; /*Find the first time that the GLR increases c_ARL there we stop */ if ((maxGLR > c_ARL) && !stop) { N = n; stop = 1; break; } /*Advance counter */ n++; } /*Set the remaining values to zero */ for (i=n+1;i begin lr_cusum_nb\n"); #endif /* Pointers to something useful */ int lx = *lx_R; double c_ARL = *c_ARL_R; double kappa = *kappa_R; double alpha = *alpha_R; int ret = *ret_R; #ifdef DEBUG printf("lx = %d\n",lx); printf("alpha = %f\n",alpha); #endif /* Loop variables */ register int n=0; int stop = 0; int N = lx; /* Loop over all 0 <= n <= length(x) */ while ((n < lx)) { /*Compute for one n*/ #ifdef DEBUG printf("n=%d\n",n); #endif /* LR for one NB variable as given in the first equation of Sect 2.1 in the Hoehle and Paul (2008) paper */ double zn = kappa * x[n] + (x[n]+1/alpha)*log( (1+alpha*mu0[n])/(1+alpha*mu0[n]*exp(kappa)) ); /* Recursive CUSUM as given in (4) by Hoehle and Paul (2008) */ if (n==0) { /* Statistic */ ret_lr[n] = fmax(0,zn); /* Number of cases it takes to sound an alarm - backcalc'ed by backcalc.mws*/ if (ret==2) ret_cases[n] = -(log((1+alpha*mu0[n])/(1+alpha*mu0[n]*exp(kappa)))-c_ARL*alpha)/alpha/(kappa+log((1+alpha*mu0[n])/(1+alpha*mu0[n]*exp(kappa)))); } else { /* Statistic */ ret_lr[n] = fmax(0,ret_lr[n-1] + zn); /* Number of cases it takes to sound an alarm -- backcalc.mws*/ if (ret==2) ret_cases[n] = -(ret_lr[n-1]*alpha+log((1+alpha*mu0[n])/(1+alpha*mu0[n]*exp(kappa)))-c_ARL*alpha)/alpha/(kappa+log((1+alpha*mu0[n])/(1+alpha*mu0[n]*exp(kappa)))); } /* Find the first time that the GLR increases c_ARL there we stop */ if ((ret_lr[n] > c_ARL) && !stop) { N = n; stop = 1; break; } /* Advance counter */ n++; } /* Return value (add 1 for R/SPlus array compatibility */ *ret_N = N+1; } /* ====================================================================== Functions for the intercept chart ====================================================================== */ /* Score function for intercept chart*/ static R_INLINE double nbScore(double kappa, int *x, double *mu0, double alpha, int k, int n) { register int i; double sum = 0; /*printf("[1] ");*/ for (i=k; i<=n; i++) { sum += (x[i]-exp(kappa)*mu0[i])/(1+alpha*exp(kappa)*mu0[i]); } /*printf("\n");*/ return(sum); } /*fisher information for intercept chart -- its minus the hesse */ static R_INLINE double nbFisher(double kappa,int *x, double *mu0, double alpha, int k,int n) { register int i; double sum = 0; for (i=k; i<=n; i++) { sum += mu0[i]*(alpha*x[i]+1)/sqr(1+alpha*exp(kappa)*mu0[i]); } return( exp(kappa)*sum); } /* Formula to compute a single l_{n,k} for the intercept chart */ static R_INLINE double nblnk(double kappa,int *x, double *mu0, double alpha, int k,int n) { register int i; double lnk = 0; for (i=k;i<=n;i++) { lnk += kappa * x[i] + (x[i] + 1/alpha) * log( (1+alpha*mu0[i])/(1+alpha*mu0[i]*exp(kappa))); } return(lnk); } /********************************************************************** GLR detector for the negative binomial model described in Hoehle and Paul (2008). Parameters: x -- the data (as array) mu0 -- base means under H0 alpha -- fixed dispersion parameter of the NegBin distribution (see Lawless (1987)) lx -- length of x Mtilde_R -- number of obs needed to get good estimate (typically 1) M -- Mtilde < M c_ARL_R -- constant determining when to signal alarm ret_N -- the return value ret_lr --- GLR value for each n to be returned **********************************************************************/ void glr_nb_window(int* x,double* mu0, double* alpha_R, int *lx_R, int *Mtilde_R, int *M_R, double *c_ARL_R,int *ret_N, double *ret_glr, int *dir_R) { #ifdef DEBUG printf("====> begin glr_nb_window\n"); #endif /* Pointers to something useful */ int lx = *lx_R; /* length of x */ int Mtilde = *Mtilde_R; int M = *M_R; double c_ARL = *c_ARL_R; double alpha = *alpha_R; int dir = *dir_R; /* Loop variables */ register int n, k,i; /*changepoint can happen at position one (ie. index zero in C*/ int n0 = fmax(Mtilde-1,0); #ifdef DEBUG printf("Length of the data = %d\n",lx); printf("starting at n0= %d\n",n0); #endif /* Show the data */ /*for (n=0; n-18) & (fabs(kappa_new - kappa_old) > 1e-6) & (iter maxGLR) { maxGLR = lnk;} } /*Debug */ #ifdef DEBUG printf("For n=%d the highest GLR value is %f\n",n,maxGLR); #endif /*Save the return value */ ret_glr[n] = maxGLR; /*Find the first time that the GLR increases c_ARL there we stop */ /*hoehle: now >= */ if ((maxGLR >= c_ARL) && !stop) { N = n; stop = 1; break; } /*Advance counter */ n++; } /*Set the remaining values to zero */ for (i=n+1;i begin glr_nbgeneral_window \n"); #endif /* Pointers to something useful */ int lx = *lx_R; /* length of x */ int Mtilde = *Mtilde_R; int M = *M_R; double c_ARL = *c_ARL_R; double alpha = *alpha_R; /* int dir = *dir_R; -- currently direction is not supported?? */ /* Loop variables */ register int n, k,i; /*changepoint can happen at position one (ie. index zero in C*/ int n0 = fmax(Mtilde-1,0); /* Compute x_{t-1} */ double xm1[lx]; xm1[0] = *xm10; /* used to be 0 */ for (i=1; i-18) & (fabs(theta_new - theta_old) > 1e-6) & (iter maxGLR) { maxGLR = lnk;} } /*Debug */ #ifdef DEBUG printf("For n=%d the highest GLR value is %f\n",n,maxGLR); #endif /*Save the return value */ ret_glr[n] = maxGLR; /*Find the first time that the GLR increases c_ARL there we stop */ /*hoehle: now >= */ if ((maxGLR >= c_ARL) && !stop) { N = n; stop = 1; break; } /*Advance counter */ n++; } /*Set the remaining values to zero */ for (i=n+1;i tools::package_native_routine_registration_skeleton("..", character_only = FALSE) // for surveillance 1.19.1 // + adding R_forceSymbols(dll, TRUE); // + adding function declarations via cproto -I/usr/share/R/include -e *.c *******************************************************************************/ #include #include #include // for NULL #include /* .C calls */ extern void glr_cusum(int *x, double *mu0, int *lx_R, int *n0_R, double *c_ARL_R, int *ret_N, double *ret_glr, double *ret_cases, int *dir_R, int *ret_R); extern void glr_cusum_window(int *x, double *mu0, int *lx_R, int *M_R, int *Mtilde_R, double *c_ARL_R, int *ret_N, double *ret_glr, double *ret_cases, int *dir_R, int *ret_R); extern void glr_epi_window(int *x, double *mu0, int *lx_R, int *Mtilde_R, int *M_R, double *xm10, double *c_ARL_R, int *ret_N, double *ret_glr); extern void glr_nbgeneral_window(int *x, double *mu0, double *alpha_R, int *lx_R, int *Mtilde_R, int *M_R, double *xm10, double *c_ARL_R, int *ret_N, double *ret_glr, int *dir_R); extern void glr_nb_window(int *x, double *mu0, double *alpha_R, int *lx_R, int *Mtilde_R, int *M_R, double *c_ARL_R, int *ret_N, double *ret_glr, int *dir_R); extern void lr_cusum(int *x, double *mu0, int *lx_R, double *kappa_R, double *c_ARL_R, int *ret_N, double *ret_lr, double *ret_cases, int *ret_R); extern void lr_cusum_nb(int *x, double *mu0, double *alpha_R, int *lx_R, double *kappa_R, double *c_ARL_R, int *ret_N, double *ret_lr, double *ret_cases, int *ret_R); extern void siaf_polyCub1_iso(double *x, double *y, int *L, int *intrfr_code, double *pars, int *subdivisions, double *epsabs, double *epsrel, int *stop_on_error, double *value, double *abserr, int *neval); extern void SRspacetime(double *x, double *y, double *t, int *n, double *radius, double *epsilon, double *areaA, double *areaAcapBk, int *cusum, double *threshold, double *Rarray, int *idxFirstAlarm, int *idxClusterCenter); extern void twins(int *x_ptr, int *n_ptr, int *I_ptr, char **logFile_ptr, char **logFile2_ptr, int *burnin_ptr, int *filter_ptr, int *sampleSize_ptr, double *alpha_xi_ptr, double *beta_xi_ptr, int *T_ptr, int *nfreq_ptr, double *psiRWSigma_ptr, double *alpha_psi_ptr, double *beta_psi_ptr, int *nu_trend_ptr); /* .Call calls */ extern SEXP determineSources(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); extern SEXP eq3a(SEXP, SEXP, SEXP); extern SEXP pKS2(SEXP, SEXP); extern SEXP pKolmogorov2x(SEXP, SEXP); static const R_CMethodDef CEntries[] = { {"glr_cusum", (DL_FUNC) &glr_cusum, 10}, {"glr_cusum_window", (DL_FUNC) &glr_cusum_window, 11}, {"glr_epi_window", (DL_FUNC) &glr_epi_window, 9}, {"glr_nbgeneral_window", (DL_FUNC) &glr_nbgeneral_window, 11}, {"glr_nb_window", (DL_FUNC) &glr_nb_window, 10}, {"lr_cusum", (DL_FUNC) &lr_cusum, 9}, {"lr_cusum_nb", (DL_FUNC) &lr_cusum_nb, 10}, {"siaf_polyCub1_iso", (DL_FUNC) &siaf_polyCub1_iso, 12}, {"SRspacetime", (DL_FUNC) &SRspacetime, 13}, {"twins", (DL_FUNC) &twins, 16}, {NULL, NULL, 0} }; static const R_CallMethodDef CallEntries[] = { {"determineSources", (DL_FUNC) &determineSources, 6}, {"eq3a", (DL_FUNC) &eq3a, 3}, {"pKS2", (DL_FUNC) &pKS2, 2}, {"pKolmogorov2x", (DL_FUNC) &pKolmogorov2x, 2}, {NULL, NULL, 0} }; void R_init_surveillance(DllInfo *dll) { R_registerRoutines(dll, CEntries, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); R_forceSymbols(dll, TRUE); } surveillance/src/backproj.cc0000644000176200001440000000271312625315364015651 0ustar liggesusers#include using namespace Rcpp; RcppExport SEXP eq3a(SEXP rlambdaOld, SEXP ry, SEXP rincuPmf) { BEGIN_RCPP // get arguments NumericVector lambdaOld(rlambdaOld); int T = lambdaOld.length(); NumericVector y(ry); NumericVector incuPmf(rincuPmf); // Create long enough vectors for queries about dincu and pincu NumericVector dincu(T); NumericVector pincu(T); pincu[0] = dincu[0]; for (int i=1; i * Date: Aug 2008 * * * Header file containing wrappers for GSL related calls * to R calls using the R API. This code is used in twins.cc *******************************************************************/ /* new definitions to replace GSL code */ // Remove the dead RNG variable (DSB 04/05/2010): // int r; double gsl_rng_uniform () { // GetRNGstate(); double res = runif(0,1); //PutRNGstate(); return(res); } double gsl_ran_gaussian(double sigma) { //GetRNGstate(); double res = rnorm(0.0,sigma); //PutRNGstate(); return(res); } double gsl_ran_gamma(double a, double b) { //GetRNGstate(); double res = rgamma(a,b); //PutRNGstate(); return(res); } unsigned int gsl_ran_poisson(double lambda) { //GetRNGstate(); unsigned int res = rpois(lambda); //PutRNGstate(); return(res); } unsigned int gsl_ran_binomial(double p, unsigned int n) { //GetRNGstate(); unsigned int res = rbinom(n,p); //PutRNGstate(); return(res); } //hoehle: The original function assumes mu>0, which needs not be the case! //This version handles that part. This is the log version. double gsl_ran_poisson_log_pdf (const unsigned int k, const double mu) { double p; if (mu==0) { return(log((double)(k == 0))); } else { double lf = lgammafn(k+1); /*gsl2R: gsl_sf_lnfact(k) */ p = k*log(mu) - lf - mu; return p; } } double gsl_sf_lngamma(double x) { return(lgammafn(x)); } double gsl_ran_beta_pdf (double x, double a, double b) { return(dbeta(x,a,b,0)); } /********************************************************************** * Log version of the Gamma pdf with mean a*b and variance a*b^2. * **********************************************************************/ double gsl_ran_gamma_log_pdf (const double x, const double a, const double b) { if (x < 0) { //This is problematic! return log((double)0) ; } else if (x == 0) { if (a == 1) return log(1/b) ; else return log((double)0) ; } else if (a == 1) { return -x/b - log(b) ; } else { double p; /*gsl2R: double lngamma = gsl_sf_lngamma (a);*/ double lngamma = lgammafn(a); p = (a-1)*log(x) - x/b - lngamma - a*log(b); return p; } } /* Seed random number generator */ //void gsl_rng_set(int r, long seed) { // set.seed(seed); //} surveillance/src/stcd-assuncaocorrea.h0000644000176200001440000000261114615162374017662 0ustar liggesusers/** * File based on algoritmos.cpp and sv.cpp from the TerraView plugin. * C++ source originally created by Marcos Oliveira Prates from the * Department of Statistics, UFMG, Brazil on 06 April 2006 * * R interface by Michael Hoehle initiated on 12 Jan 2009 * Note: Some function names and documentation are in Portuguese */ #ifndef SRSPACETIME_H #define SRSPACETIME_H #include #include struct SVEvent { double x, y, t; friend bool operator<(const SVEvent &a, const SVEvent &b) { return (a.t < b.t); } }; //STL is used (check its use) typedef std::list SVEventLst; //Functions provided in sr-spacetime.cc int CalculaNCj(short **MSpace, const int EvtN, const int EvtJ); int ContaEvt(short **MSpace, const int EvtN, const int EvtJ); //int SistemadeVigilancia(SVEventLst &, const double RaioC, const double epslon, // std::valarray &R); //New version with different estimation approach int SistemadeVigilancia(SVEventLst &ev, const double RaioC, const double epslon, const double areaA, double *areaAcapBk, const int cusum, std::valarray &R); int CalculaLambda(SVEventLst &ev, const double RaioC, const double epslon, std::valarray &R, unsigned int &numObs); // Hoehle wrapper function to create SVEvent list //void SRspacetime(double *x, double *y, double *t, int *n, double *radius, double *epsilon, double *Rarray); #endif surveillance/src/ks.c0000644000176200001440000001341614244757706014343 0ustar liggesusers/* * This file contains a *subset* of the ks.c source file from R 4.2.0 * (https://svn.R-project.org/R/trunk/src/library/stats/src/ks.c, as at r81742) * with original Copyright (C) 1999-2022 The R Core Team * under GPL-2 (or later) as shown below. * The version included here just leaves out Smirnov-related functions and is * again available under GPL-2. * * License: * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * https://www.R-project.org/Licenses/ */ /* ks.c Compute the asymptotic distribution of the one- and two-sample two-sided Kolmogorov-Smirnov statistics, and the exact distributions in the two-sided one-sample and two-sample cases. */ #include #include #include #include /* constants */ static double K(int n, double d); static void m_multiply(double *A, double *B, double *C, int m); static void m_power(double *A, int eA, double *V, int *eV, int m, int n); /* Two-sample two-sided asymptotic distribution */ static void pkstwo(int n, double *x, double tol) { /* x[1:n] is input and output * * Compute * \sum_{k=-\infty}^\infty (-1)^k e^{-2 k^2 x^2} * = 1 + 2 \sum_{k=1}^\infty (-1)^k e^{-2 k^2 x^2} * = \frac{\sqrt{2\pi}}{x} \sum_{k=1}^\infty \exp(-(2k-1)^2\pi^2/(8x^2)) * * See e.g. J. Durbin (1973), Distribution Theory for Tests Based on the * Sample Distribution Function. SIAM. * * The 'standard' series expansion obviously cannot be used close to 0; * we use the alternative series for x < 1, and a rather crude estimate * of the series remainder term in this case, in particular using that * ue^(-lu^2) \le e^(-lu^2 + u) \le e^(-(l-1)u^2 - u^2+u) \le e^(-(l-1)) * provided that u and l are >= 1. * * (But note that for reasonable tolerances, one could simply take 0 as * the value for x < 0.2, and use the standard expansion otherwise.) * */ double new, old, s, w, z; int i, k, k_max; k_max = (int) sqrt(2 - log(tol)); for(i = 0; i < n; i++) { if(x[i] < 1) { z = - (M_PI_2 * M_PI_4) / (x[i] * x[i]); w = log(x[i]); s = 0; for(k = 1; k < k_max; k += 2) { s += exp(k * k * z - w); } x[i] = s / M_1_SQRT_2PI; } else { z = -2 * x[i] * x[i]; s = -1; k = 1; old = 0; new = 1; while(fabs(old - new) > tol) { old = new; new += 2 * s * exp(z * k * k); s *= -1; k++; } x[i] = new; } } } static double K(int n, double d) { /* Compute Kolmogorov's distribution. Code published in George Marsaglia and Wai Wan Tsang and Jingbo Wang (2003), "Evaluating Kolmogorov's distribution". Journal of Statistical Software, Volume 8, 2003, Issue 18. URL: http://www.jstatsoft.org/v08/i18/. */ int k, m, i, j, g, eH, eQ; double h, s, *H, *Q; /* The faster right-tail approximation is omitted here. s = d*d*n; if(s > 7.24 || (s > 3.76 && n > 99)) return 1-2*exp(-(2.000071+.331/sqrt(n)+1.409/n)*s); */ k = (int) (n * d) + 1; m = 2 * k - 1; h = k - n * d; H = (double*) R_Calloc(m * m, double); Q = (double*) R_Calloc(m * m, double); for(i = 0; i < m; i++) for(j = 0; j < m; j++) if(i - j + 1 < 0) H[i * m + j] = 0; else H[i * m + j] = 1; for(i = 0; i < m; i++) { H[i * m] -= R_pow_di(h, i + 1); H[(m - 1) * m + i] -= R_pow_di(h, (m - i)); } H[(m - 1) * m] += ((2 * h - 1 > 0) ? R_pow_di(2 * h - 1, m) : 0); for(i = 0; i < m; i++) for(j=0; j < m; j++) if(i - j + 1 > 0) for(g = 1; g <= i - j + 1; g++) H[i * m + j] /= g; eH = 0; m_power(H, eH, Q, &eQ, m, n); s = Q[(k - 1) * m + k - 1]; for(i = 1; i <= n; i++) { s = s * i / n; if(s < 1e-140) { s *= 1e140; eQ -= 140; } } s *= R_pow_di(10.0, eQ); R_Free(H); R_Free(Q); return(s); } static void m_multiply(double *A, double *B, double *C, int m) { /* Auxiliary routine used by K(). Matrix multiplication. */ int i, j, k; double s; for(i = 0; i < m; i++) for(j = 0; j < m; j++) { s = 0.; for(k = 0; k < m; k++) s+= A[i * m + k] * B[k * m + j]; C[i * m + j] = s; } } static void m_power(double *A, int eA, double *V, int *eV, int m, int n) { /* Auxiliary routine used by K(). Matrix power. */ double *B; int eB , i; if(n == 1) { for(i = 0; i < m * m; i++) V[i] = A[i]; *eV = eA; return; } m_power(A, eA, V, eV, m, n / 2); B = (double*) R_Calloc(m * m, double); m_multiply(V, V, B, m); eB = 2 * (*eV); if((n % 2) == 0) { for(i = 0; i < m * m; i++) V[i] = B[i]; *eV = eB; } else { m_multiply(A, B, V, m); *eV = eA + eB; } if(V[(m / 2) * m + (m / 2)] > 1e140) { for(i = 0; i < m * m; i++) V[i] = V[i] * 1e-140; *eV += 140; } R_Free(B); } /* Two-sample two-sided asymptotic distribution */ SEXP pKS2(SEXP statistic, SEXP stol) { int n = LENGTH(statistic); double tol = asReal(stol); SEXP ans = duplicate(statistic); pkstwo(n, REAL(ans), tol); return ans; } /* The two-sided one-sample 'exact' distribution */ SEXP pKolmogorov2x(SEXP statistic, SEXP sn) { int n = asInteger(sn); double st = asReal(statistic), p; p = K(n, st); return ScalarReal(p); } surveillance/vignettes/0000755000176200001440000000000014615167606014772 5ustar liggesuserssurveillance/vignettes/surveillance.Rnw0000644000176200001440000005523414615162374020164 0ustar liggesusers%\VignetteIndexEntry{Getting started with outbreak detection} \documentclass[a4paper,11pt]{article} \usepackage[T1]{fontenc} \usepackage{graphicx} \usepackage{natbib} \bibliographystyle{apalike} \usepackage{lmodern} \usepackage{amsmath} \usepackage{amsfonts,amssymb} \newcommand{\pkg}[1]{{\bfseries #1}} \newcommand{\surveillance}{\pkg{surveillance}} \usepackage{hyperref} \hypersetup{ pdfauthor = {Michael H\"ohle and Andrea Riebler and Michaela Paul}, pdftitle = {Getting started with outbreak detection}, pdfsubject = {R package 'surveillance'} } \title{Getting started with outbreak detection} \author{ Michael H{\"o}hle\thanks{Author of correspondence: Department of Statistics, University of Munich, Ludwigstr.\ 33, 80539 M{\"u}nchen, Germany, Email: \texttt{hoehle@stat.uni-muenchen.de}} , Andrea Riebler and Michaela Paul\\ Department of Statistics\\ University of Munich\\ Germany } \date{17 November 2007} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sweave %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \usepackage{Sweave} %Put all in another directory \SweaveOpts{prefix.string=plots/surveillance, width=9, height=4.5} \setkeys{Gin}{width=1\textwidth} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initial R code %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <>= library("surveillance") options(SweaveHooks=list(fig=function() par(mar=c(4,4,2,0)+.5))) options(width=70) ## create directory for plots dir.create("plots", showWarnings=FALSE) ###################################################################### #Do we need to compute or can we just fetch results ###################################################################### CACHEFILE <- "surveillance-cache.RData" compute <- !file.exists(CACHEFILE) message("Doing computations: ", compute) if(!compute) load(CACHEFILE) @ \begin{document} \fbox{\vbox{\small \noindent\textbf{Disclaimer}: This vignette reflects package state at version 0.9-7 and is hence somewhat outdated. New functionality has been added to the package: this includes various endemic-epidemic modelling frameworks for surveillance data (\texttt{hhh4}, \texttt{twinSIR}, and \texttt{twinstim}), as well as more outbreak detection methods (\texttt{glrnb}, \texttt{boda}, and \texttt{farringtonFlexible}). These new features are described in detail in \citet{meyer.etal2014} and \citet{salmon.etal2014}, respectively. %and corresponding vignettes are included in the package; %see \texttt{vignette(package = "surveillance")} for an overview. Note in particular that use of the new \texttt{S4} class \texttt{sts} instead of \texttt{disProg} is encouraged to encapsulate time series data. }} {\let\newpage\relax\maketitle} \begin{abstract} \noindent This document gives an introduction to the \textsf{R} package \surveillance\ containing tools for outbreak detection in routinely collected surveillance data. The package contains an implementation of the procedures described by~\citet{stroup89}, \citet{farrington96} and the system used at the Robert Koch Institute, Germany. For evaluation purposes, the package contains example data sets and functionality to generate surveillance data by simulation. To compare the algorithms, benchmark numbers like sensitivity, specificity, and detection delay can be computed for a set of time series. Being an open-source package it should be easy to integrate new algorithms; as an example of this process, a simple Bayesian surveillance algorithm is described, implemented and evaluated.\\ \noindent{\bf Keywords:} infectious disease, monitoring, aberrations, outbreak, time series of counts. \end{abstract} \newpage \section{Introduction}\label{sec:intro} Public health authorities have in an attempt to meet the threats of infectious diseases to society created comprehensive mechanisms for the collection of disease data. As a consequence, the abundance of data has demanded the development of automated algorithms for the detection of abnormalities. Typically, such an algorithm monitors a univariate time series of counts using a combination of heuristic methods and statistical modelling. Prominent examples of surveillance algorithms are the work by~\citet{stroup89} and~\citet{farrington96}. A comprehensive survey of outbreak detection methods can be found in~\citep{farrington2003}. The R-package \texttt{surveillance} was written with the aim of providing a test-bench for surveillance algorithms. From the Comprehensive R Archive Network (CRAN) the package can be downloaded together with its source code. It allows users to test new algorithms and compare their results with those of standard surveillance methods. A few real world outbreak datasets are included together with mechanisms for simulating surveillance data. With the package at hand, comparisons like the one described by~\citet{hutwagner2005} should be easy to conduct. The purpose of this document is to illustrate the basic functionality of the package with R-code examples. Section~\ref{sec:data} contains a description of the data format used to store surveillance data, mentions the built-in datasets and illustrates how to create new datasets by simulation. Section~\ref{sec:algo} contains a short description of how to use the surveillance algorithms and illustrate the results. Further information on the individual functions can be found on the corresponding help pages of the package. \section{Surveillance Data}\label{sec:data} Denote by $\{y_t\>;t=1,\ldots,n\}$ the time series of counts representing the surveillance data. Because such data typically are collected on a weekly basis, we shall also use the alternative notation $\{y_{i:j}\}$ with $j=\{1,\ldots,52\}$ being the week number in year $i=\{-b,\ldots,-1,0\}$. That way the years are indexed such that most current year has index zero. For evaluation of the outbreak detection algorithms it is also possible for each week to store -- if known -- whether there was an outbreak that week. The resulting multivariate series $\{(y_t,x_t)\>; t=1,\ldots,n\}$ is in \texttt{surveillance} given by an object of class \texttt{disProg} (disease progress), which is basically a \texttt{list} containing two vectors: the observed number of counts and a boolean vector \texttt{state} indicating whether there was an outbreak that week. A number of time series are contained in the package (see \texttt{data(package="surveillance")}), mainly originating from the SurvStat@RKI database at \url{https://survstat.rki.de/} maintained by the Robert Koch Institute, Germany~\citep{survstat}. For example the object \texttt{k1} describes cryptosporidiosis surveillance data for the German federal state Baden-W\"{u}rttemberg 2001-2005. The peak in 2001 is due to an outbreak of cryptosporidiosis among a group of army soldiers in a boot camp~\citep{bulletin3901}. <>= data(k1) plot(k1, main = "Cryptosporidiosis in BW 2001-2005") @ For evaluation purposes it is also of interest to generate surveillance data using simulation. The package contains functionality to generate surveillance data containing point-source like outbreaks, for example with a Salmonella serovar. The model is a Hidden Markov Model (HMM) where a binary state $X_t, t=1,\ldots,n$, denotes whether there was an outbreak and $Y_t$ is the number of observed counts, see Figure~\ref{fig:hmm}. \begin{figure}[htb] \centering \includegraphics[width=.75\textwidth]{surveillance-hmm} \caption{The Hidden Markov Model} \label{fig:hmm} \end{figure} The state $X_t$ is a homogeneous Markov chain with transition matrix \begin{center} \begin{tabular}{c|cc} $X_t\backslash X_{t+1}$ & 0 & 1\\ \hline $0$ & $p$ & $1 - p$ \\ $1$ & $1 - r$ & $r$ \end{tabular} \end{center} Hence $1-p$ is the probability to switch to an outbreak state and $1-r$ is the probability that $X_t=1$ is followed by $X_{t+1}=1$. Furthermore, the observation $Y_t$ is Poisson-distributed with log-link mean depending on a seasonal effect and time trend, i.e.\ \[ \log \mu_t = A \cdot \sin \, (\omega \cdot (t + \varphi)) + \alpha + \beta t. \] In case of an outbreak $(X_t=1)$ the mean increases with a value of $K$, altogether \begin{equation}\label{eq:hmm} Y_t \sim \operatorname{Po}(\mu_t + K \cdot X_t). \end{equation} The model in (\ref{eq:hmm}) corresponds to a single-source, common-vehicle outbreak, where the length of an outbreak is controlled by the transition probability $r$. The daily numbers of outbreak-cases are simply independently Poisson distributed with mean $K$. A physiologically better motivated alternative could be to operate with a stochastic incubation time (e.g.\ log-normal or gamma distributed) for each individual exposed to the source, which results in a temporal diffusion of the peak. The advantage of (\ref{eq:hmm}) is that estimation can be done by a generalized linear model (GLM) using $X_t$ as covariate and that it allows for an easy definition of a correctly identified outbreak: each $X_t=1$ has to be identified. More advanced setups would require more involved definitions of an outbreak, e.g.\ as a connected series of time instances, where the number of outbreak cases is greater than zero. Care is then required in defining what a correctly identified outbreak for time-wise overlapping outbreaks means. In \surveillance\ the function \verb+sim.pointSource+ is used to simulate such a point-source epidemic; the result is an object of class \verb+disProg+. \label{ex:sts} <<>>= set.seed(1234) sts <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) @ <>= plot(sts) @ \section{Surveillance Algorithms}\label{sec:algo} Surveillance data often exhibit strong seasonality, therefore most surveillance algorithms only use a set of so called \emph{reference values} as basis for drawing conclusions. Let $y_{0:t}$ be the number of cases of the current week (denoted week $t$ in year $0$), $b$ the number of years to go back in time and $w$ the number of weeks around $t$ to include from those previous years. For the year zero we use $w_0$ as the number of previous weeks to include -- typically $w_0=w$. Altogether the set of reference values is thus defined to be \[ R(w,w_0,b) = \left(\bigcup\limits_{i=1}^b\bigcup\limits_{j=\,-w}^w y_{-i:t+j}\right) \cup \left(\bigcup_{k=-w_0}^{-1} y_{0:t+k}\right) \] Note that the number of cases of the current week is not part of $R(w,w_0,b)$. A surveillance algorithm is a procedure using the reference values to create a prediction $\hat{y}_{0:t}$ for the current week. This prediction is then compared with the observed $y_{0:t}$: if the observed number of cases is much higher than the predicted number, the current week is flagged for further investigations. In order to do surveillance for time $0:t$ an important concern is the choice of $b$ and $w$. Values as far back as time $-b:t-w$ contribute to $R(w,w_0,b)$ and thus have to exist in the observed time series. Currently, we have implemented four different type of algorithms in \surveillance. The Centers for Disease Control and Prevention (CDC) method~\citep{stroup89}, the Communicable Disease Surveillance Centre (CDSC) method~\citep{farrington96}, the method used at the Robert Koch Institute (RKI), Germany~\citep{altmann2003}, and a Bayesian approach documented in~\citet{riebler2004}. A detailed description of each method is beyond the scope of this note, but to give an idea of the framework the Bayesian approach developed in~\citet{riebler2004} is presented: Within a Bayesian framework, quantiles of the predictive posterior distribution are used as a measure for defining alarm thresholds. The model assumes that the reference values are identically and independently Poisson distributed with parameter $\lambda$ and a Gamma-distribution is used as Prior distribution for $\lambda$. The reference values are defined to be $R_{\text{Bayes}}= R(w,w_0,b) = \{y_1, \ldots, y_{n}\}$ and $y_{0:t}$ is the value we are trying to predict. Thus, $\lambda \sim \text{Ga}(\alpha, \beta)$ and $y_i|\lambda \sim \text{Po}(\lambda)$, $i = 1,\ldots,{n}$. Standard derivations show that the posterior distribution is \begin{equation*} \lambda|y_1, \ldots, y_{n} \sim \text{Ga}(\alpha + \sum_{i=1}^{n} y_i, \beta + n). \end{equation*} Computing the predictive distribution \begin{equation*} f(y_{0:t}|y_1,\ldots,y_{n}) = \int\limits^\infty_0{f(y_{0:t}|\lambda)\, f(\lambda|y_1,\ldots,y_{n})}\, d\lambda \end{equation*} we get the Poisson-Gamma-distribution \begin{equation*} y_{0:t}|y_1,\ldots,y_{n} \sim \text{PoGa}(\alpha + \sum_{i=1}^{n} y_i, \beta + n), \end{equation*} which is a generalization of the negative Binomial distribution, i.e.\ \[ y_{0:t}|y_1,\ldots,y_{n} \sim \text{NegBin}(\alpha + \sum_{i=1}^{n} y_i, \tfrac{\beta + n}{\beta + n + 1}). \] Using the Jeffrey's Prior $\text{Ga}(\tfrac{1}{2}, 0)$ as non-informative Prior distribution for $\lambda$ the parameters of the negative Binomial distribution are \begin{align*} \alpha + \sum_{i=1}^{n} y_i &= \frac{1}{2} + \sum_{y_{i:j} \in R_{\text{Bayes}}}\!\! y_{i:j} \quad % \intertext{and} \quad\text{and}\quad \frac{\beta + n}{\beta + n + 1} = \frac{|R_{\text{Bayes}}|}{|R_{\text{Bayes}}| + 1}. \end{align*} Using a quantile-parameter $\alpha$, the smallest value $y_\alpha$ is computed, so that \begin{equation*} P(y \leq y_\alpha) \geq 1-\alpha. \end{equation*} Now \begin{equation*} A_{0:t} = I(y_{0:t} \geq y_\alpha), \end{equation*} i.e. if $y_{0:t}\geq y_\alpha$ the current week is flagged as an alarm. As an example, the \verb+Bayes1+ method uses the last six weeks as reference values, i.e.\ $R(w,w_0,b)=(6,6,0)$, and is applied to the \texttt{k1} dataset with $\alpha=0.01$ as follows. <>= k1.b660 <- algo.bayes(k1, control = list(range = 27:192, b = 0, w = 6, alpha = 0.01)) plot(k1.b660, disease = "k1") @ Several extensions of this simple Bayesian approach are imaginable, for example the inane over-dispersion of the data could be modeled by using a negative-binomial distribution, time trends and mechanisms to correct for past outbreaks could be integrated, but all at the cost of non-standard inference for the predictive distribution. Here simulation based methods like Markov Chain Monte Carlo or heuristic approximations have to be used to obtain the required alarm thresholds. In general, the \verb+surveillance+ package makes it easy to add additional algorithms -- also those not based on reference values -- by using the existing implementations as starting point. The following call uses the CDC and Farrington procedure on the simulated time series \verb+sts+ from page~\pageref{ex:sts}. Note that the CDC procedure operates with four-week aggregated data -- to better compare the upper bound value, the aggregated number of counts for each week are shown as circles in the plot. <>= cntrl <- list(range=300:400,m=1,w=3,b=5,alpha=0.01) sts.cdc <- algo.cdc(sts, control = cntrl) sts.farrington <- algo.farrington(sts, control = cntrl) @ <>= if (compute) { <> } @ <>= par(mfcol=c(1,2)) plot(sts.cdc, legend.opts=NULL) plot(sts.farrington, legend.opts=NULL) @ Typically, one is interested in evaluating the performance of the various surveillance algorithms. An easy way is to look at the sensitivity and specificity of the procedure -- a correct identification of an outbreak is defined as follows: if the algorithm raises an alarm for time $t$, i.e.\ $A_t=1$ and $X_t=1$ we have a correct classification, if $A_t=1$ and $X_t=0$ we have a false-positive, etc. In case of more involved outbreak models, where an outbreak lasts for more than one week, a correct identification could be if at least one of the outbreak weeks is correctly identified, see e.g.\ \citet{hutwagner2005}. To compute various performance scores the function \verb+algo.quality+ can be used on a \verb+survRes+ object. <<>>= print(algo.quality(k1.b660)) @ This computes the number of false positives, true negatives, false negatives, the sensitivity and the specificity. Furthermore, \texttt{dist} is defined as \[ \sqrt{(Spec-1)^2 + (Sens - 1)^2}, \] that is the distance to the optimal point $(1,1)$, which serves as a heuristic way of combining sensitivity and specificity into a single score. Of course, weighted versions are also imaginable. Finally, \texttt{lag} is the average number of weeks between the first of a consecutive number of $X_t=1$'s (i.e.\ an outbreak) and the first alarm raised by the algorithm. To compare the results of several algorithms on a single time series we declare a list of control objects -- each containing the name and settings of the algorithm we want to apply to the data. <>= control <- list( list(funcName = "rki1"), list(funcName = "rki2"), list(funcName = "rki3"), list(funcName = "bayes1"), list(funcName = "bayes2"), list(funcName = "bayes3"), list(funcName = "cdc", alpha=0.05), list(funcName = "farrington", alpha=0.05) ) control <- lapply(control, function(ctrl) { ctrl$range <- 300:400; return(ctrl) }) @ % In the above, \texttt{rki1}, \texttt{rki2} and \texttt{rki3} are three methods with reference values $R_\text{rki1}(6,6,0)$, $R_\text{rki2}(6,6,1)$ and $R_\text{rki3}(4,0,2)$, all called with $\alpha=0.05$. The \texttt{bayes*} methods use the Bayesian algorithm with the same setup of reference values. The CDC method is special since it operates on aggregated four-week blocks. To make everything comparable, a common $\alpha=0.05$ level is used for all algorithms. All algorithms in \texttt{control} are applied to \texttt{sts} using: <>= algo.compare(algo.call(sts, control = control)) @ <>= if (compute) { acall <- algo.call(sts, control = control) } print(algo.compare(acall), digits = 3) @ A test on a set of time series can be done as follows. Firstly, a list containing 10 simulated time series is created. Secondly, all the algorithms specified in the \texttt{control} object are applied to each series. Finally the results for the 10 series are combined in one result matrix. <>= #Create 10 series ten <- lapply(1:10,function(x) { sim.pointSource(p = 0.975, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7)}) @ <>= #Do surveillance on all 10, get results as list ten.surv <- lapply(ten,function(ts) { algo.compare(algo.call(ts,control=control)) }) @ <>= if (compute) { <> } @ <>= #Average results algo.summary(ten.surv) @ <>= print(algo.summary(ten.surv), digits = 3) @ A similar procedure can be applied when evaluating the 14 surveillance series drawn from SurvStat@RKI~\citep{survstat}. A problem is however, that the series after conversion to 52 weeks/year are of length 209 weeks. This is insufficient to apply e.g.\ the CDC algorithm. To conduct the comparison on as large a dataset as possible the following trick is used: The function \texttt{enlargeData} replicates the requested \texttt{range} and inserts it before the original data, after which the evaluation can be done on all 209 values. <>= #Update range in each - cyclic continuation range = (2*4*52) + 1:length(k1$observed) control <- lapply(control,function(cntrl) { cntrl$range=range;return(cntrl)}) #Auxiliary function to enlarge data enlargeData <- function(disProgObj, range = 1:156, times = 1){ disProgObj$observed <- c(rep(disProgObj$observed[range], times), disProgObj$observed) disProgObj$state <- c(rep(disProgObj$state[range], times), disProgObj$state) return(disProgObj) } #Outbreaks outbrks <- c("m1", "m2", "m3", "m4", "m5", "q1_nrwh", "q2", "s1", "s2", "s3", "k1", "n1", "n2", "h1_nrwrp") #Load and enlarge data. outbrks <- lapply(outbrks,function(name) { data(list=name) enlargeData(get(name),range=1:(4*52),times=2) }) #Apply function to one one.survstat.surv <- function(outbrk) { algo.compare(algo.call(outbrk,control=control)) } @ <>= algo.summary(lapply(outbrks,one.survstat.surv)) @ <>= if (compute) { res.survstat <- algo.summary(lapply(outbrks,one.survstat.surv)) } print(res.survstat, digits=3) @ In both this study and the earlier simulation study the Bayesian approach seems to do quite well. However, the extent of the comparisons do not make allowance for any more supported statements. Consult the work of~\citet{riebler2004} for a more thorough comparison using simulation studies. <>= if (compute) { # save computed results save(list=c("sts.cdc","sts.farrington","acall","res.survstat", "ten.surv"), file=CACHEFILE) tools::resaveRdaFiles(CACHEFILE) } @ \section{Discussion and Future Work} Many extensions and additions are imaginable to improve the package. For now, the package is intended as an academic tool providing a test-bench for integrating new surveillance algorithms. Because all algorithms are implemented in R, performance has not been an issue. Especially the current implementation of the Farrington Procedure is rather slow and would benefit from an optimization possible with fragments written in C. One important improvement would be to provide more involved mechanisms for the simulation of epidemics. In particular it would be interesting to include multi-day outbreaks originating from single-source exposure, but with delay due to varying incubation time~\citep{hutwagner2005} or SEIR-like epidemics~\citep{andersson2000}. However, defining what is meant by a correct outbreak identification, especially in the case of overlapping outbreaks, creates new challenges which have to be met. \section{Acknowledgements} We are grateful to K.\ Stark and D.\ Altmann, RKI, Germany, for discussions and information on the surveillance methods used by the RKI. Our thanks to C.\ Lang, University of Munich, for his work on the R--implementation and M. Kobl, T. Schuster and M. Rossman, University of Munich, for their initial work on gathering the outbreak data from SurvStat@RKI. The research was conducted with financial support from the Collaborative Research Centre SFB 386 funded by the German research foundation (DFG). \bibliography{references} \end{document} surveillance/vignettes/hhh4-cache.RData0000644000176200001440000000777014201024627017600 0ustar liggesusersZgXTɶmd+8: OGQ0&4 81zE0Ƅ:FQsR@$o_|{|_ugW׮ f `@$i4I)PZRK&M7h4)x%3֭[b2^6 Cd05]'f(!z =xnѺE/{/1=k4֦ot9J wV't8y)2T;;|x^Dɉ'soinrbw:SO(hؑb i fB̊MPV@ߵ> Ab#teVx3ƅ)&GN$FЇ=6v(:\'8-;>d'"5-p6։ l˸ zGxhfR iPv8JY6k.@{,WCPBԮ;Rv4 T;sP3,ުuYFxXE~ l_-e%J >{%S.*lA".t>Du[T=c`ho'2'64UiTKdy9e<9Ե,}2ovΛ`?_D~Mm.A >ȯl`տJ-12q/OS1NAuo|cm\ha:+|;1.gn\rR9>8w*MuAʳqY)ױl FuiYuGQ͡IkcBm-ѠlcZ|.*@xT4MW#SBE͞7@Qˌo!,hlI(c#_ڤj RjZQ}Q{hzFFP5Xv^I RX: <GnJ#NEMǻ[dQ=ֶvPv[s-TUze߲6 \M^ĀcZ, _ZMV,vyEGU !oIFx3ʤʼץ6~|(Lc(v {ht5:wJ~jBFrԮ]N ߨy`AvQ|Qe02T8!*ڲN\Eu(Az]"Eʉh0ȰG3nYS)(:3iP=V BAz=[TW:R]^w "/?y2xv'`1nQ&iuE{%*B!*?b#O|?|Ԧ2϶(Ʃwm@'Q3"U8,P)<KW"PP@:J1Nv9:RU(?]_Kܨ͎.=Ue]*#Ck m6F,,$K%K!Qե`.o"ྉadNJ@Ǯ6\65-YslJwBlzxj ɑe*GӋ!ay_ NZpCS# r72Q'7JJ*P;9E7N "S|dJN{gI" NwPs]4vJ <);*,q[>l?-Igx.ڬwNV=i;$8+J oڡJ[>h;Aվ3woer˙#>Z%+'z}ߠ]e:j!˟8/2x9ݚdD3gxw?z IkNzEwҟNz*T>)Oqoѣ~e齞{D#!Y[> 3,։<ظXe=H^|w4 h{|!>vuUW?ٳMTjF3dw)Ʀ5Moڮ5<,GAS_XsQܧ+arRKׇK;ԡ+wnpb,DZ?mt.jBv]|Fe.,HF-e/حVFqF-6p >`a0Ql 9xnF5/S()<'tL:AXՀ=<bT '|9l8kJ0>J:@|3;N)):Adુ§SE[ӹ)q oigRE3H O,[K) Xl,Soi[&8X[i,|+aau"%!;)Ei~(l8,'j`b <_$,|xk6!ixA%%b_$$)x 0bc0 ece/ =`rcJctB  ''( NU$Vyo7%88kLFC>8a u'qp/EN)a=XM8?x>q3O:a=C8q?q{.A'x|\zyg>ԶS^uA@e{_'臋ɰFiqf<⼒Pss{h@W'+|?C@$=NAܔA_XܒRIC.Iꂹbw-6Ĺ't 7,vpv[=<;H98{6G kkP `bbw3)CîkDO9O :9x@>= ## purl=FALSE => not included in the tangle'd R script knitr::opts_chunk$set(echo = TRUE, tidy = FALSE, results = 'markup', fig.path='plots/twinstim-', fig.width = 8, fig.height = 4, fig.align = "center", fig.scap = NA, out.width = NULL, cache = FALSE, error = FALSE, warning = FALSE, message = FALSE) knitr::render_sweave() # use Sweave environments knitr::set_header(highlight = '') # no \usepackage{Sweave} (part of jss class) ## add a chunk option "strip.white.output" to remove leading and trailing white ## space (empty lines) from output chunks ('strip.white' has no effect) local({ default_output_hook <- knitr::knit_hooks$get("output") knitr::knit_hooks$set(output = function (x, options) { if (isTRUE(options[["strip.white.output"]])) { x <- sub("[[:space:]]+$", "\n", # set a single trailing \n sub("^[[:space:]]+", "", x)) # remove leading space } default_output_hook(x, options) }) }) ## R settings options(prompt = "R> ", continue = "+ ", useFancyQuotes = FALSE) # JSS options(width = 85, digits = 4) options(scipen = 1) # so that 1e-4 gets printed as 0.0001 ## xtable settings options(xtable.booktabs = TRUE, xtable.size = "small", xtable.sanitize.text.function = identity, xtable.comment = FALSE) @ \documentclass[nojss,nofooter,article]{jss} \usepackage[utf8]{inputenc} % Rnw is ASCII, but auto-generated bib file isn't % (specification is redundant in LaTeX >= 2018-04-01) \title{% \vspace{-1.5cm} \fbox{\vbox{\normalfont\footnotesize This introduction to the \code{twinstim} modeling framework of the \proglang{R}~package \pkg{surveillance} is based on a publication in the \textit{Journal of Statistical Software} -- \citet[Section~3]{meyer.etal2014} -- which is the suggested reference if you use the \code{twinstim} implementation in your own work.}}\\[1cm] \code{twinstim}: An endemic-epidemic modeling framework for spatio-temporal point patterns} \Plaintitle{twinstim: An endemic-epidemic modeling framework for spatio-temporal point patterns} \Shorttitle{Endemic-epidemic modeling of spatio-temporal point patterns} \author{Sebastian Meyer\thanks{Author of correspondence: \email{seb.meyer@fau.de}}\\Friedrich-Alexander-Universit{\"a}t\\Erlangen-N{\"u}rnberg \And Leonhard Held\\University of Zurich \And Michael H\"ohle\\Stockholm University} \Plainauthor{Sebastian Meyer, Leonhard Held, Michael H\"ohle} %% Basic packages \usepackage{lmodern} % successor of CM -> searchable Umlauts (1 char) \usepackage[english]{babel} % language of the manuscript is American English %% Math packages \usepackage{amsmath,amsfonts} % amsfonts defines \mathbb \usepackage{bm} % \bm: alternative to \boldsymbol from amsfonts %% Packages for figures and tables \usepackage{booktabs} % make tables look nicer \usepackage{subcaption} % successor of subfig, which supersedes subfigure %% knitr uses \subfloat, which subcaption only provides since v1.3 (2019/08/31) \providecommand{\subfloat}[2][need a sub-caption]{\subcaptionbox{#1}{#2}} %% Handy math commands \newcommand{\abs}[1]{\lvert#1\rvert} \newcommand{\norm}[1]{\lVert#1\rVert} \newcommand{\given}{\,\vert\,} \newcommand{\dif}{\,\mathrm{d}} \newcommand{\IR}{\mathbb{R}} \newcommand{\IN}{\mathbb{N}} \newcommand{\ind}{\mathbb{I}} \DeclareMathOperator{\Po}{Po} \DeclareMathOperator{\NegBin}{NegBin} \DeclareMathOperator{\N}{N} %% Additional commands \newcommand{\class}[1]{\code{#1}} % could use quotes (JSS does not like them) \newcommand{\CRANpkg}[1]{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}} %% Reduce the font size of code input and output \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl, fontsize=\small} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\small} %% Abstract \Abstract{ The availability of geocoded health data and the inherent temporal structure of communicable diseases have led to an increased interest in statistical models and software for spatio-temporal data with epidemic features. The \proglang{R}~package \pkg{surveillance} can handle various levels of aggregation at which infective events have been recorded. This vignette illustrates the analysis of \emph{point-referenced} surveillance data using the endemic-epidemic point process model ``\code{twinstim}'' proposed by \citet{meyer.etal2011} and extended in \citet{meyer.held2013}. %% (For other types of surveillance data, see %% \code{vignette("twinSIR")} and \code{vignette("hhh4\_spacetime")}.) We first describe the general modeling approach and then exemplify data handling, model fitting, visualization, and simulation methods for time-stamped geo-referenced case reports of invasive meningococcal disease (IMD) caused by the two most common bacterial finetypes of meningococci in Germany, 2002--2008. } \Keywords{% spatio-temporal point pattern, endemic-epidemic modeling, infectious disease epidemiology, self-exciting point process, spatial interaction function, branching process with immigration} \begin{document} <>= ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("twinstim-cache.RData")) if (!COMPUTE) load("twinstim-cache.RData", verbose = TRUE) @ \section[Model class]{Model class: \code{twinstim}} \label{sec:twinstim:methods} Infective events occur at specific points in continuous space and time, which gives rise to a spatio-temporal point pattern $\{(\bm{s}_i,t_i): i = 1,\dotsc,n\}$ from a region~$\bm{W}$ observed during a period~$(0,T]$. The locations~$\bm{s}_i$ and time points~$t_i$ of the $n$~events can be regarded as a realization of a self-exciting spatio-temporal point process, which can be characterized by its conditional intensity function (CIF, also termed intensity process) $\lambda(\bm{s},t)$. It represents the instantaneous event rate at location~$\bm{s}$ at time point~$t$ given all past events, and is often more verbosely denoted by~$\lambda^*$ or by explicit conditioning on the ``history''~$\mathcal{H}_t$ of the process. \citet[Chapter~7]{Daley.Vere-Jones2003} provide a rigorous mathematical definition of this concept, which is key to likelihood analysis and simulation of ``evolutionary'' point processes. \citet{meyer.etal2011} formulated the model class ``\code{twinstim}'' -- a \emph{two}-component \emph{s}patio-\emph{t}emporal \emph{i}ntensity \emph{m}odel -- by a superposition of an endemic and an epidemic component: \begin{equation} \label{eqn:twinstim} \lambda(\bm{s},t) = \nu_{[\bm{s}][t]} + \sum_{j \in I(\bm{s},t)} \eta_j \, f(\norm{\bm{s}-\bm{s}_j}) \, g(t-t_j) \:. \end{equation} This model constitutes a branching process with immigration. Part of the event rate is due to the first, endemic component, which reflects sporadic events caused by unobserved sources of infection. This background rate of new events is modeled by a log-linear predictor $\nu_{[\bm{s}][t]}$ incorporating regional and/or time-varying characteristics. Here, the space-time index $[\bm{s}][t]$ refers to the region covering $\bm{s}$ during the period containing $t$ and thus spans a whole spatio-temporal grid on which the involved covariates are measured, e.g., district $\times$ month. We will later see that the endemic component therefore simply equals an inhomogeneous Poisson process for the event counts by cell of that grid. The second, observation-driven epidemic component adds ``infection pressure'' from the set \begin{equation*} I(\bm{s},t) = \big\{ j : t_j < t \:\wedge\: t-t_j \le \tau_j \:\wedge\: \norm{\bm{s}-\bm{s}_j} \le \delta_j \big\} \end{equation*} of past events and hence makes the process ``self-exciting''. During its infectious period of length~$\tau_j$ and within its spatial interaction radius~$\delta_j$, the model assumes each event~$j$ to trigger further events, which are called offspring, secondary cases, or aftershocks, depending on the application. The triggering rate (or force of infection) is proportional to a log-linear predictor~$\eta_j$ associated with event-specific characteristics (``marks'') $\bm{m}_j$, which are usually attached to the point pattern of events. The decay of infection pressure with increasing spatial and temporal distance from the infective event is modeled by parametric interaction functions~$f$ and~$g$, respectively. A simple assumption for the time course of infectivity is $g(t) = 1$. Alternatives include exponential decay, a step function, or empirically derived functions such as Omori's law for aftershock intervals. With regard to spatial interaction, a Gaussian kernel $f(x) = \exp\left\{-x^2/(2 \sigma^2)\right\}$ could be chosen. However, in modeling the spread of human infectious diseases on larger scales, a heavy-tailed power-law kernel $f(x) = (x+\sigma)^{-d}$ was found to perform better \citep{meyer.held2013}. The (possibly infinite) upper bounds~$\tau_j$ and~$\delta_j$ provide a way of modeling event-specific interaction ranges. However, since these need to be pre-specified, a common assumption is $\tau_j \equiv \tau$ and $\delta_j \equiv \delta$, where the infectious period~$\tau$ and the spatial interaction radius~$\delta$ are determined by subject-matter considerations. \subsection{Model-based effective reproduction numbers} Similar to the simple SIR model \citep[see, e.g.,][Section 2.1]{Keeling.Rohani2008}, the above point process model~\eqref{eqn:twinstim} features a reproduction number derived from its branching process interpretation. As soon as an event occurs (individual becomes infected), it triggers offspring (secondary cases) around its origin $(\bm{s}_j, t_j)$ according to an inhomogeneous Poisson process with rate $\eta_j \, f(\norm{\bm{s}-\bm{s}_j}) \, g(t-t_j)$. Since this triggering process is independent of the event's parentage and of other events, the expected number $\mu_j$ of events triggered by event $j$ can be obtained by integrating the triggering rate over the observed interaction domain: \begin{equation} \label{eqn:R0:twinstim} \mu_j = \eta_j \cdot \left[ \int_0^{\min(T-t_j,\tau_j)} g(t) \,dt \right] \cdot \left[ \int_{\bm{R}_j} f(\norm{\bm{s}}) \,d\bm{s} \right] \:, \end{equation} where \begin{equation} \label{eqn:twinstim:IR} \bm{R}_j = (b(\bm{s}_j,\delta_j) \cap \bm{W}) - \bm{s}_j \end{equation} is event $j$'s influence region centered at $\bm{s}_j$, and $b(\bm{s}_j, \delta_j)$ denotes the disc centered at $\bm{s}_j$ with radius $\delta_j$. Note that the above model-based reproduction number $\mu_j$ is event-specific since it depends on event marks through $\eta_j$, on the interaction ranges $\delta_j$ and $\tau_j$, as well as on the event location $\bm{s}_j$ and time point $t_j$. If the model assumes unique interaction ranges $\delta$ and $\tau$, a single reference number of secondary cases can be extrapolated from Equation~\ref{eqn:R0:twinstim} by imputing an unbounded domain $\bm{W} = \IR^2$ and $T = \infty$ \citep{meyer.etal2015}. Equation~\ref{eqn:R0:twinstim} can also be motivated by looking at a spatio-temporal version of the simple SIR model wrapped into the \class{twinstim} class~\eqref{eqn:twinstim}. This means: no endemic component, homogeneous force of infection ($\eta_j \equiv \beta$), homogeneous mixing in space ($f(x) = 1$, $\delta_j \equiv \infty$), and exponential decay of infectivity over time ($g(t) = e^{-\alpha t}$, $\tau_j \equiv \infty$). Then, for $T \rightarrow \infty$, \begin{equation*} \mu = \beta \cdot \left[ \int_0^\infty e^{-\alpha t} \,dt \right] \cdot \left[ \int_{\bm{W}-\bm{s}_j} 1 \,d\bm{s} \right] = \beta \cdot \abs{\bm{W}} / \alpha \:, \end{equation*} which corresponds to the basic reproduction number known from the simple SIR model by interpreting $\abs{\bm{W}}$ as the population size, $\beta$ as the transmission rate and $\alpha$ as the removal rate. If $\mu < 1$, the process is sub-critical, i.e., its eventual extinction is almost sure. However, it is crucial to understand that in a full model with an endemic component, new infections may always occur via ``immigration''. Hence, reproduction numbers in \class{twinstim} are adjusted for infections occurring independently of previous infections. This also means that a misspecified endemic component may distort model-based reproduction numbers \citep{meyer.etal2015}. Furthermore, under-reporting and implemented control measures imply that the estimates are to be thought of as \emph{effective} reproduction numbers. \subsection{Likelihood inference} The log-likelihood of the point process model~\eqref{eqn:twinstim} is a function of all parameters in the log-linear predictors $\nu_{[\bm{s}][t]}$ and $\eta_j$ and in the interaction functions $f$ and $g$. It has the form %% \begin{equation} \label{eqn:twinstim:marked:loglik} %% l(\bm{\theta}) = \left[ \sum_{i=1}^{n} \log\lambda(\bm{s}_i,t_i,k_i) \right] - %% \sum_{k\in\mathcal{K}} \int_0^T \int_{\bm{W}} \lambda(\bm{s},t,k) \dif\bm{s} %% \dif t \:, %% \end{equation} \begin{equation} \label{eqn:twinstim:loglik} \left[ \sum_{i=1}^{n} \log\lambda(\bm{s}_i,t_i) \right] - \int_0^T \int_{\bm{W}} \lambda(\bm{s},t) \dif\bm{s} \dif t \:. \end{equation} %\citep[Proposition~7.3.III]{Daley.Vere-Jones2003} To estimate the model parameters, we maximize the above log-likelihood numerically using the quasi-Newton algorithm available through the \proglang{R}~function \code{nlminb}. We thereby employ the analytical score function and an approximation of the expected Fisher information worked out by \citet[Web Appendices A and B]{meyer.etal2011}. The space-time integral in the log-likelihood \eqref{eqn:twinstim:loglik} poses no difficulties for the endemic component of $\lambda(\bm{s},t)$, since $\nu_{[\bm{s}][t]}$ is defined on a spatio-temporal grid. However, integration of the epidemic component involves two-dimensional integrals $\int_{\bm{R}_i} f(\norm{\bm{s}}) \dif\bm{s}$ over the influence regions~$\bm{R}_i$, which are represented by polygons (as is~$\bm{W}$). Similar integrals appear in the score function, where $f(\norm{\bm{s}})$ is replaced by partial derivatives with respect to kernel parameters. Calculation of these integrals is trivial for (piecewise) constant~$f$, but otherwise requires numerical integration. The \proglang{R}~package \CRANpkg{polyCub} \citep{meyer2019} offers various cubature methods for polygonal domains. % For Gaussian~$f$, we apply a midpoint rule with $\sigma$-adaptive bandwidth % %% combined with an analytical formula via the $\chi^2$ distribution % %% if the $6\sigma$-circle around $\bm{s}_i$ is contained in $\bm{R}_i$. % and use product Gauss cubature \citep{sommariva.vianello2007} % to approximate the integrals in the score function. % For the recently implemented power-law kernels, Of particular relevance for \code{twinstim} is the \code{polyCub.iso} method, which takes advantage of the assumed isotropy of spatial interaction such that numerical integration remains in only one dimension \citep[Supplement~B, Section~2]{meyer.held2013}. We \CRANpkg{memoise} \citep{R:memoise} the cubature function during log-likelihood maximization to avoid integration for unchanged parameters of~$f$. \subsection{Special cases: Single-component models} If the \emph{epidemic} component is omitted in Equation~\ref{eqn:twinstim}, the point process model becomes equivalent to a Poisson regression model for aggregated counts. This provides a link to ecological regression approaches in general and to the count data model \code{hhh4} illustrated in \code{vignette("hhh4")} and \code{vignette("hhh4\_spacetime")}. To see this, recall that the endemic component $\nu_{[\bm{s}][t]}$ is piecewise constant on the spatio-temporal grid with cells $([\bm{s}],[t])$. Hence the log-likelihood~\eqref{eqn:twinstim:loglik} of an endemic-only \code{twinstim} simplifies to a sum over all these cells, \begin{equation*} \sum_{[\bm{s}],[t]} \left\{ Y_{[\bm{s}][t]} \log\nu_{[\bm{s}][t]} - \abs{[\bm{s}]} \, \abs{[t]} \, \nu_{[\bm{s}][t]} \right\} \:, \end{equation*} where $Y_{[\bm{s}][t]}$ is the aggregated number of events observed in cell $([\bm{s}],[t])$, and $\abs{[\bm{s}]}$ and $\abs{[t]}$ denote cell area and length, respectively. Except for an additive constant, the above log-likelihood is equivalently obtained from the Poisson model $Y_{[\bm{s}][t]} \sim \Po( \abs{[\bm{s}]} \, \abs{[t]} \, \nu_{[\bm{s}][t]})$. This relation offers a means of code validation using the established \code{glm} function to fit an endemic-only \code{twinstim} model -- see the examples in \code{help("glm_epidataCS")}. %% The \code{help("glm_epidataCS")} also shows how to fit %% an equivalent endemic-only \code{hhh4} model. If, in contrast, the \emph{endemic} component is omitted, all events are necessarily triggered by other observed events. For such a model to be identifiable, a prehistory of events must exist to trigger the first event, and interaction typically needs to be unbounded such that each event can actually be linked to potential source events. \subsection[Extension: Event types]{Extension: \code{twinstim} with event types} To model the example data on invasive meningococcal disease in the remainder of this section, we actually need to use an extended version $\lambda(\bm{s},t,k)$ of Equation~\ref{eqn:twinstim}, which accounts for different event types~$k$ with own transmission dynamics. This introduces a further dimension in the point process, and the second log-likelihood component in Equation~\ref{eqn:twinstim:loglik} accordingly splits into a sum over all event types. We refer to \citet[Sections~2.4 and~3]{meyer.etal2011} for the technical details of this type-specific \code{twinstim} class. The basic idea is that the meningococcal finetypes share the same endemic pattern (e.g., seasonality), while infections of different finetypes are not associated via transmission. This means that the force of infection is restricted to previously infected individuals with the same bacterial finetype~$k$, i.e., the epidemic sum in Equation~\ref{eqn:twinstim} is over the set $I(\bm{s},t,k) = I(\bm{s},t) \cap \{j: k_j = k\}$. The implementation has limited support for type-dependent interaction functions $f_{k_j}$ and $g_{k_j}$ (not further considered here). \section[Data structure]{Data structure: \class{epidataCS}} \label{sec:twinstim:data} <>= ## extract components from imdepi to reconstruct data("imdepi") events <- SpatialPointsDataFrame( coords = coordinates(imdepi$events), data = marks(imdepi, coords=FALSE), proj4string = imdepi$events@proj4string # ETRS89 projection (+units=km) ) stgrid <- imdepi$stgrid[,-1] @ <>= load(system.file("shapes", "districtsD.RData", package = "surveillance")) @ The first step toward fitting a \code{twinstim} is to turn the relevant data into an object of the dedicated class \class{epidataCS}.\footnote{ The suffix ``CS'' indicates that the data-generating point process is indexed in continuous space. } The primary ingredients of this class are a spatio-temporal point pattern (\code{events}) and its underlying observation region (\code{W}). An additional spatio-temporal grid (\code{stgrid}) holds (time-varying) area-level covariates for the endemic regression part. We exemplify this data class by the \class{epidataCS} object for the \Sexpr{nobs(imdepi)} cases of invasive meningococcal disease in Germany originally analyzed by \citet{meyer.etal2011}. It is already contained in the \pkg{surveillance} package as \code{data("imdepi")} and has been constructed as follows: <>= imdepi <- as.epidataCS(events = events, W = stateD, stgrid = stgrid, qmatrix = diag(2), nCircle2Poly = 16) @ The function \code{as.epidataCS} checks the consistency of the three data ingredients described in detail below. It also pre-computes auxiliary variables for model fitting, e.g., the individual influence regions~\eqref{eqn:twinstim:IR}, which are intersections of the observation region with discs %of radius \code{eps.s} centered at the event location approximated by polygons with \code{nCircle2Poly = 16} edges. The intersections are computed using functionality of the package \CRANpkg{polyclip} \citep{R:polyclip}. For multitype epidemics as in our example, the additional indicator matrix \code{qmatrix} specifies transmissibility across event types. An identity matrix corresponds to an independent spread of the event types, i.e., cases of one type can not produce cases of another type. \subsection{Data ingredients} The core \code{events} data must be provided in the form of a \class{SpatialPointsDataFrame} as defined by the package \CRANpkg{sp} \citep{R:sp}: <>= summary(events) @ <>= oopt <- options(width=100) ## hack to reduce the 'print.gap' in the data summary but not for the bbox ## Note: sp >= 2.0-0 loads 'sf' for summary(events), but has a fallback, ## see https://github.com/r-spatial/evolution/issues/10 local({ print.summary.Spatial <- sp:::print.summary.Spatial environment(print.summary.Spatial) <- environment() print.table <- function (x, ..., print.gap = 0) { base::print.table(x, ..., print.gap = print.gap) } print.summary.Spatial(summary(events)) }) options(oopt) @ The associated event coordinates are residence postcode centroids, projected in the \emph{European Terrestrial Reference System 1989} (in kilometer units) to enable Euclidean geometry. See the \code{spTransform}-methods for how to project latitude and longitude coordinates into a planar coordinate reference system (CRS). The data frame associated with these spatial coordinates ($\bm{s}_i$) contains a number of required variables and additional event marks (in the notation of Section~\ref{sec:twinstim:methods}: $\{(t_i,[\bm{s}_i],k_i,\tau_i,\delta_i,\bm{m}_i): i = 1,\dotsc,n\}$). For the IMD data, the event \code{time} is measured in days since the beginning of the observation period 2002--2008 and is subject to a tie-breaking procedure (described later). The \code{tile} column refers to the region of the spatio-temporal grid where the event occurred and here contains the official key of the administrative district of the patient's residence. There are two \code{type}s of events labeled as \code{"B"} and \code{"C"}, which refer to the serogroups of the two meningococcal finetypes \emph{B:P1.7-2,4:F1-5} and \emph{C:P1.5,2:F3-3} contained in the data. The \code{eps.t} and \code{eps.s} columns specify upper limits for temporal and spatial interaction, respectively. Here, the infectious period is assumed to last a maximum of 30 days and spatial interaction is limited to a 200 km radius for all cases. The latter has numerical advantages for a Gaussian interaction function $f$ with a relatively small standard deviation. For a power-law kernel, however, this restriction will be dropped to enable occasional long-range transmission. The last two data attributes displayed in the above \code{event} summary are covariates from the case reports: the gender and age group of the patient. For the observation region \code{W}, we use a polygon representation of Germany's boundary. Since the observation region defines the integration domain in the point process log-likelihood~\eqref{eqn:twinstim:loglik}, the more detailed the polygons of \code{W} are the longer it will take to fit a \code{twinstim}. It is thus advisable to sacrifice some shape details for speed by reducing the polygon complexity. In \proglang{R} this can be achieved via, e.g., \code{ms_simplify} from the \CRANpkg{rmapshaper} package \citep{R:rmapshaper}, or \code{simplify.owin} from \CRANpkg{spatstat.geom} \citep{R:spatstat}. % \code{thinnedSpatialPoly} in package \CRANpkg{maptools}, % will retire % which implements the Douglas-Peucker reduction method. The \pkg{surveillance} package already contains a simplified representation of Germany's boundaries: <>= <> @ This file contains both the \class{SpatialPolygonsDataFrame} \code{districtsD} of Germany's \Sexpr{length(districtsD)} administrative districts as at January 1, 2009, as well as their union \code{stateD}. %obtained by the call \code{rgeos::gUnaryUnion(districtsD)} \citep{R:rgeos}. These boundaries are projected in the same CRS as the \code{events} data. The \code{stgrid} input for the endemic model component is a data frame with (time-varying) area-level covariates, e.g., socio-economic or ecological characteristics. In our example: <>= .stgrid.excerpt <- format(rbind(head(stgrid, 3), tail(stgrid, 3)), digits=3) rbind(.stgrid.excerpt[1:3,], "..."="...", .stgrid.excerpt[4:6,]) @ Numeric (\code{start},\code{stop}] columns index the time periods and the factor variable \code{tile} identifies the regions of the grid. Note that the given time intervals (here: months) also define the resolution of possible time trends and seasonality of the piecewise constant endemic intensity. We choose monthly intervals to reduce package size and computational cost compared to the weekly resolution originally used by \citet{meyer.etal2011} and \citet{meyer.held2013}. The above \code{stgrid} data frame thus consists of 7 (years) times 12 (months) blocks of \Sexpr{nlevels(stgrid[["tile"]])} (districts) rows each. The \code{area} column gives the area of the respective \code{tile} in square kilometers (compatible with the CRS used for \code{events} and \code{W}). A geographic representation of the regions in \code{stgrid} is not required for model estimation, and is thus not part of the \class{epidataCS} class. %It is, however, necessary for plots of the fitted intensity and for %simulation from the estimated model. In our example, the area-level data only consists of the population density \code{popdensity}, whereas \citet{meyer.etal2011} additionally incorporated (lagged) weekly influenza counts by district as a time-dependent covariate. %% In another application, \citet{meyer.etal2015} used a large number of socio-economic %% characteristics to model psychiatric hospital admissions. \pagebreak \subsection{Data handling and visualization} The generated \class{epidataCS} object \code{imdepi} is a simple list of the checked ingredients <>= cat(paste0('\\code{', names(imdepi), '}', collapse = ", "), ".", sep = "") @ Several methods for data handling and visualization are available for such objects as listed in Table~\ref{tab:methods:epidataCS} and briefly presented in the remainder of this section. <>= print(xtable( surveillance:::functionTable( class = "epidataCS", functions = list( Convert = c("epidataCS2sts"), Extract = c("getSourceDists"))), caption="Generic and \\textit{non-generic} functions applicable to \\class{epidataCS} objects.", label="tab:methods:epidataCS" ), include.rownames = FALSE) @ Printing an \class{epidataCS} object presents some metadata and the first \Sexpr{formals(surveillance:::print.epidataCS)[["n"]]} events by default: <>= imdepi @ During conversion to \class{epidataCS}, the last three columns \code{BLOCK} (time interval index), \code{start} and \code{popdensity} have been merged from the checked \code{stgrid} to the \code{events} data frame. The event marks including time and location can be extracted in a standard data frame by \code{marks(imdepi)} -- inspired by package \CRANpkg{spatstat} -- and this is summarized by \code{summary(imdepi)}. <>= (simdepi <- summary(imdepi)) @ The number of potential sources of infection per event (denoted \texttt{|.sources|} in the above output) is additionally summarized. It is determined by the events' maximum ranges of interaction \code{eps.t} and \code{eps.s}. The event-specific set of potential sources is stored in the (hidden) list \code{imdepi$events$.sources} (events are referenced by row index), and the event-specific numbers of potential sources are stored in the summarized object as \code{simdepi$nSources}. A simple plot of the number of infectives as a function of time (Figure~\ref{fig:imdepi_stepfun}) %determined by the event times and infectious periods can be obtained by the step function converter: <>= par(mar = c(5, 5, 1, 1), las = 1) plot(as.stepfun(imdepi), xlim = summary(imdepi)$timeRange, xaxs = "i", xlab = "Time [days]", ylab = "Current number of infectives", main = "") #axis(1, at = 2557, labels = "T", font = 2, tcl = -0.3, mgp = c(3, 0.3, 0)) @ \pagebreak[1] The \code{plot}-method for \class{epidataCS} offers aggregation of the events over time or space: <>= par(las = 1) plot(imdepi, "time", col = c("indianred", "darkblue"), ylim = c(0, 20)) par(mar = c(0, 0, 0, 0)) plot(imdepi, "space", lwd = 2, points.args = list(pch = c(1, 19), col = c("indianred", "darkblue"))) layout.scalebar(imdepi$W, scale = 100, labels = c("0", "100 km"), plot = TRUE) @ \pagebreak[1] The time-series plot (Figure~\ref{fig:imdepi_plot-1}) shows the monthly aggregated number of cases by finetype in a stacked histogram as well as each type's cumulative number over time. The spatial plot (Figure~\ref{fig:imdepi_plot-2}) shows the observation window \code{W} with the locations of all cases (by type), where the areas of the points are proportional to the number of cases at the respective location. Additional shading by the population is possible and exemplified in \code{help("plot.epidataCS")}. %The above static plots do not capture the space-time dynamics of epidemic spread. An animation may provide additional insight and can be produced by the corresponding \code{animate}-method. For instance, to look at the first year of the B-type in a weekly sequence of snapshots in a web browser (using facilities of the \CRANpkg{animation} package of \citealp{R:animation}): <>= animation::saveHTML( animate(subset(imdepi, type == "B"), interval = c(0, 365), time.spacing = 7), nmax = Inf, interval = 0.2, loop = FALSE, title = "First year of type B") @ Selecting events from \class{epidataCS} as for the animation above is enabled by the \code{[}- and \code{subset}-methods, which return a new \class{epidataCS} object containing only the selected \code{events}. A limited data sampling resolution may lead to tied event times or locations, which are in conflict with a continuous spatio-temporal point process model. For instance, a temporal residual analysis would suggest model deficiencies \citep[Figure 4]{meyer.etal2011}, and a power-law kernel for spatial interaction may diverge if there are events with zero distance to potential source events \citep{meyer.held2013}. The function \code{untie} breaks ties by random shifts. This has already been applied to the event \emph{times} in the provided \code{imdepi} data by subtracting a U$(0,1)$-distributed random number from the original dates. The event \emph{coordinates} in the IMD data are subject to interval censoring at the level of Germany's postcode regions. A possible replacement for the given centroids would thus be a random location within the corresponding postcode area. Lacking a suitable shapefile, \citet{meyer.held2013} shifted all locations by a random vector with length up to half the observed minimum spatial separation: <>= eventDists <- dist(coordinates(imdepi$events)) minsep <- min(eventDists[eventDists > 0]) set.seed(321) imdepi_untied <- untie(imdepi, amount = list(s = minsep / 2)) @ Note that random tie-breaking requires sensitivity analyses as discussed by \citet{meyer.held2013}, but these are skipped here for the sake of brevity. The \code{update}-method is useful to change the values of the maximum interaction ranges \code{eps.t} and \code{eps.s}, since it takes care of the necessary updates of the hidden auxiliary variables in an \class{epidataCS} object. For unbounded spatial interaction: <>= imdepi_untied_infeps <- update(imdepi_untied, eps.s = Inf) @ Last but not least, \class{epidataCS} can be aggregated to \class{epidata} (from \code{vignette("twinSIR")}) or \class{sts} (from \code{vignette("hhh4_spacetime")}). The method \code{as.epidata.epidataCS} aggregates events by region (\code{tile}), and the function \code{epidataCS2sts} yields counts by region and time interval. The latter could be analyzed by an areal time-series model such as \code{hhh4} (see \code{vignette("hhh4\_spacetime")}). We can also use \class{sts} visualizations, e.g.\ (Figure~\ref{fig:imdsts_plot}): <>= imdsts <- epidataCS2sts(imdepi, freq = 12, start = c(2002, 1), tiles = districtsD, neighbourhood = NULL) # skip adjacency matrix (needs spdep) par(las = 1, lab = c(7,7,7), mar = c(5,5,1,1)) plot(imdsts, type = observed ~ time) plot(imdsts, type = observed ~ unit, population = districtsD$POPULATION / 100000) @ \section{Modeling and inference} \label{sec:twinstim:fit} Having prepared the data as an object of class \class{epidataCS}, the function \code{twinstim} can be used to perform likelihood inference for conditional intensity models of the form~\eqref{eqn:twinstim}. The main arguments for \code{twinstim} are the formulae of the \code{endemic} and \code{epidemic} linear predictors ($\nu_{[\bm{s}][t]} = \exp$(\code{endemic}) and $\eta_j = \exp$(\code{epidemic})), and the spatial and temporal interaction functions \code{siaf} ($f$) and \code{tiaf} ($g$), respectively. Both formulae are parsed internally using the standard \code{model.frame} toolbox from package \pkg{stats} and thus can handle factor variables and interaction terms. While the \code{endemic} linear predictor incorporates %time-dependent and/or area-level covariates from \code{stgrid}, %% and in the disease mapping context usually contains at least the population density as a multiplicative offset, i.e., %% \code{endemic = ~offset(log(popdensity))}. There can be additional effects of time, %% which are functions of the variable \code{start} from \code{stgrid}, %% or effects of, e.g., socio-demographic and ecological variables. the \code{epidemic} formula may use both \code{stgrid} variables and event marks to be associated with the force of infection. %% For instance, \code{epidemic = ~log(popdensity) + type} corresponds to %% $\eta_j = \rho_{[\bm{s}_j]}^{\gamma_{\rho}} \exp(\gamma_0 + \gamma_C \ind(k_j=C))$, %% which models different infectivity of the event types, and scales %% with population density (a grid-based covariate) to reflect higher %% contact rates and thus infectivity in more densely populated regions. For the interaction functions, several alternatives are predefined as listed in Table~\ref{tab:iafs}. They are applicable out-of-the-box and illustrated as part of the following modeling exercise for the IMD data. Own interaction functions can also be implemented following the structure described in \code{help("siaf")} and \code{help("tiaf")}, respectively. <>= twinstim_iafs <- suppressWarnings( cbind("Spatial (\\code{siaf.*})" = ls(pattern="^siaf\\.", pos="package:surveillance"), "Temporal (\\code{tiaf.*})" = ls(pattern="^tiaf\\.", pos="package:surveillance")) ) twinstim_iafs <- apply(twinstim_iafs, 2, function (x) { is.na(x) <- duplicated(x) x }) print(xtable(substring(twinstim_iafs, 6), label="tab:iafs", caption="Predefined spatial and temporal interaction functions."), include.rownames=FALSE, sanitize.text.function=function(x) paste0("\\code{", x, "}"), sanitize.colnames.function=identity, sanitize.rownames.function=identity) @ \subsection{Basic example} To illustrate statistical inference with \code{twinstim}, we will estimate several models for the simplified and ``untied'' IMD data presented in Section~\ref{sec:twinstim:data}. In the endemic component, we include the district-specific population density as a multiplicative offset, a (centered) time trend, and a sinusoidal wave of frequency $2\pi/365$ to capture seasonality, where the \code{start} variable from \code{stgrid} measures time: <>= (endemic <- addSeason2formula(~offset(log(popdensity)) + I(start / 365 - 3.5), period = 365, timevar = "start")) @ See \citet[Section~2.2]{held.paul2012} for how such sine/cosine terms reflect seasonality. Because of the aforementioned integrations in the log-likelihood~\eqref{eqn:twinstim:loglik}, it is advisable to first fit an endemic-only model to obtain reasonable start values for more complex epidemic models: <>= imdfit_endemic <- twinstim(endemic = endemic, epidemic = ~0, data = imdepi_untied, subset = !is.na(agegrp)) @ We exclude the single case with unknown age group from this analysis since we will later estimate an effect of the age group on the force of infection. Many of the standard functions to access model fits in \proglang{R} are also implemented for \class{twinstim} fits (see Table~\ref{tab:methods:twinstim}). For example, we can produce the usual model summary: <>= summary(imdfit_endemic) @ Because of the aforementioned equivalence of the endemic component with a Poisson regression model, the coefficients can be interpreted as log rate ratios in the usual way. For instance, the endemic rate is estimated to decrease by \code{1 - exp(coef(imdfit_endemic)[2])} $=$ \Sexpr{round(100*(1-exp(coef(imdfit_endemic)[2])),1)}\% per year. Coefficient correlations can be retrieved via the argument \code{correlation = TRUE} in the \code{summary} call just like for \code{summary.glm}, or via \code{cov2cor(vcov(imdfit_endemic))}. <>= print(xtable( surveillance:::functionTable( class = "twinstim", functions = list( Display = c("iafplot", "checkResidualProcess"), Extract = c("intensity.twinstim", "simpleR0"), Modify = c("stepComponent"), Other = c("epitest"))), caption="Generic and \\textit{non-generic} functions applicable to \\class{twinstim} objects. Note that there is no need for specific \\code{coef}, \\code{confint}, \\code{AIC} or \\code{BIC} methods, since the respective default methods from package \\pkg{stats} apply outright.", label="tab:methods:twinstim" ), include.rownames = FALSE) @ We now update the endemic model to take additional spatio-temporal dependence between events into account. Infectivity shall depend on the meningococcal finetype and the age group of the patient, and is assumed to be constant over time (default), $g(t)=\ind_{(0,30]}(t)$, with a Gaussian distance-decay $f(x) = \exp\left\{-x^2/(2 \sigma^2)\right\}$. This model was originally selected by \citet{meyer.etal2011} and can be fitted as follows: <>= imdfit_Gaussian <- update(imdfit_endemic, epidemic = ~type + agegrp, siaf = siaf.gaussian(), cores = 2 * (.Platform$OS.type == "unix")) @ On Unix-alikes, the numerical integrations of $f(\norm{\bm{s}})$ in the log-likelihood and $\frac{\partial f(\norm{\bm{s}})}{\partial \log\sigma}$ in the score function (note that $\sigma$ is estimated on the log-scale) can be performed in parallel via %the ``multicore'' functions \code{mclapply} \textit{et al.}\ from the base package \pkg{parallel}, here with \code{cores = 2} processes. Table~\ref{tab:imdfit_Gaussian} shows the output of \code{twinstim}'s \code{xtable} method \citep{R:xtable} applied to the above model fit, providing a table of estimated rate ratios for the endemic and epidemic effects. The alternative \code{toLatex} method simply translates the \code{summary} table of coefficients to \LaTeX\ without \code{exp}-transformation. On the subject-matter level, we can conclude from Table~\ref{tab:imdfit_Gaussian} that the meningococcal finetype of serogroup~C is less than half as infectious as the B-type, and that patients in the age group 3 to 18 years are estimated to cause twice as many secondary infections as infants aged 0 to 2 years. <>= print(xtable(imdfit_Gaussian, caption="Estimated rate ratios (RR) and associated Wald confidence intervals (CI) for endemic (\\code{h.}) and epidemic (\\code{e.}) terms. This table was generated by \\code{xtable(imdfit\\_Gaussian)}.", label="tab:imdfit_Gaussian"), sanitize.text.function=NULL, sanitize.colnames.function=NULL, sanitize.rownames.function=function(x) paste0("\\code{", x, "}")) @ \subsection{Model-based effective reproduction numbers} The event-specific reproduction numbers~\eqref{eqn:R0:twinstim} can be extracted from fitted \class{twinstim} objects via the \code{R0} method. For the above IMD model, we obtain the following mean numbers of secondary infections by finetype: <<>>= R0_events <- R0(imdfit_Gaussian) tapply(R0_events, marks(imdepi_untied)[names(R0_events), "type"], mean) @ Confidence intervals %for the estimated reproduction numbers $\hat\mu_j$ can be obtained via Monte Carlo simulation, where Equation~\ref{eqn:R0:twinstim} is repeatedly evaluated with parameters sampled from the asymptotic multivariate normal distribution of the maximum likelihood estimate. For this purpose, the \code{R0}-method takes an argument \code{newcoef}, which is exemplified in \code{help("R0")}. %% Note that except for (piecewise) constant $f$, computing confidence intervals for %% $\hat\mu_j$ takes a considerable amount of time since the integrals over the %% polygons $\bm{R}_j$ have to be solved numerically for each new set of parameters. \subsection{Interaction functions} <>= imdfit_exponential <- update(imdfit_Gaussian, siaf = siaf.exponential()) @ <>= imdfit_powerlaw <- update(imdfit_Gaussian, siaf = siaf.powerlaw(), data = imdepi_untied_infeps, start = c("e.(Intercept)" = -6.2, "e.siaf.1" = 1.5, "e.siaf.2" = 0.9)) @ <>= imdfit_step4 <- update(imdfit_Gaussian, siaf = siaf.step(exp(1:4 * log(100) / 5), maxRange = 100)) @ <>= save(imdfit_Gaussian, imdfit_exponential, imdfit_powerlaw, imdfit_step4, file = "twinstim-cache.RData", compress = "xz") @ Figure~\ref{fig:imdfit_siafs} shows several estimated spatial interaction functions, which can be plotted by, e.g., \code{plot(imdfit_Gaussian, "siaf")}. <>= par(mar = c(5,5,1,1)) set.seed(2) # Monte-Carlo confidence intervals plot(imdfit_Gaussian, "siaf", xlim=c(0,42), ylim=c(0,5e-5), lty=c(1,3), xlab = expression("Distance " * x * " from host [km]")) plot(imdfit_exponential, "siaf", add=TRUE, col.estimate=5, lty = c(5,3)) plot(imdfit_powerlaw, "siaf", add=TRUE, col.estimate=4, lty=c(2,3)) plot(imdfit_step4, "siaf", add=TRUE, col.estimate=3, lty=c(4,3)) legend("topright", legend=c("Power law", "Exponential", "Gaussian", "Step (df=4)"), col=c(4,5,2,3), lty=c(2,5,1,4), lwd=3, bty="n") @ The estimated standard deviation $\hat\sigma$ of the Gaussian kernel is: <<>>= exp(cbind("Estimate" = coef(imdfit_Gaussian)["e.siaf.1"], confint(imdfit_Gaussian, parm = "e.siaf.1"))) @ \citet{meyer.held2013} found that a power-law decay of spatial interaction more appropriately describes the spread of human infectious diseases. A power-law kernel concentrates on short-range interaction, but also exhibits a heavier tail reflecting occasional transmission over large distances. %This result is supported by the power-law distribution of short-time human %travel \citep{brockmann.etal2006}, which is an important driver of epidemic spread. To estimate the power law $f(x) = (x+\sigma)^{-d}$, we use the prepared \code{eps.s = Inf} version of the \class{epidataCS} object, and update the model as follows: <>= <> @ To reduce the runtime of this example, we specified convenient \code{start} values for some parameters. The estimated parameters $(\hat\sigma, \hat d)$ are: <<>>= exp(cbind("Estimate" = coef(imdfit_powerlaw)[c("e.siaf.1", "e.siaf.2")], confint(imdfit_powerlaw, parm = c("e.siaf.1", "e.siaf.2")))) @ Sometimes $\sigma$ is difficult to estimate, and also in this example, its confidence interval is relatively large. The one-parameter version \code{siaf.powerlaw1} can be used to estimate a power-law decay with fixed $\sigma = 1$. A more common option is the exponential kernel $f(x) = \exp(-x/\sigma)$: <>= <> @ Table~\ref{tab:iafs} also lists the step function kernel as an alternative, which is particularly useful for two reasons. First, it is a more flexible approach since it estimates interaction between the given knots without assuming an overall functional form. Second, the spatial integrals in the log-likelihood can be computed analytically for the step function kernel, which therefore offers a quick estimate of spatial interaction. We update the Gaussian model to use four steps at log-equidistant knots up to an interaction range of 100 km: <>= <> @ Figure~\ref{fig:imdfit_siafs} suggests that the estimated step function is in line with the power law. Note that suitable knots for the step function could also be derived from quantiles of the observed distances between events and their potential source events, e.g.: <<>>= quantile(getSourceDists(imdepi_untied_infeps, "space"), c(1,2,4,8)/100) @ For the temporal interaction function $g(t)$, model updates and plots are similarly possible, e.g., using \code{update(imdfit_Gaussian, tiaf = tiaf.exponential())}. However, the events in the IMD data are too rare to infer the time-course of infectivity with confidence. <>= local({ nSources <- sapply(levels(imdepi$events$type), function (.type) { mean(summary(subset(imdepi_untied_infeps, type==.type))$nSources) }) structure( paste("Specifically, there are only", paste0(round(nSources,1), " (", names(nSources), ")", collapse=" and "), "cases on average within the preceding 30 days", "(potential sources of infection)."), class="Latex") }) @ \subsection{Model selection} <>= AIC(imdfit_endemic, imdfit_Gaussian, imdfit_exponential, imdfit_powerlaw, imdfit_step4) @ Akaike's Information Criterion (AIC) suggests superiority of the power-law vs.\ the exponential, Gaussian, and endemic-only models. The more flexible step function yields the best AIC value, but its shape strongly depends on the chosen knots and is not guaranteed to be monotonically decreasing. The function \code{stepComponent} -- a wrapper around the \code{step} function from \pkg{stats} -- can be used to perform AIC-based stepwise selection within a given model component. <>= ## Example of AIC-based stepwise selection of the endemic model imdfit_endemic_sel <- stepComponent(imdfit_endemic, component = "endemic") ## -> none of the endemic predictors is removed from the model @ \subsection{Model diagnostics} The element \code{"fittedComponents"} of a \class{twinstim} object contains the endemic and epidemic values of the estimated intensity at each event occurrence. However, plots of the conditional intensity (and its components) as a function of location or time provide more insight into the fitted process. Evaluation of \code{intensity.twinstim} requires the model environment to be stored with the fit. By default, \code{model = FALSE} in \code{twinstim}, but if the data are still available, the model environment can also be added afterwards using the convenient \code{update} method: <>= imdfit_powerlaw <- update(imdfit_powerlaw, model = TRUE) @ Figure~\ref{fig:imdfit_powerlaw_intensityplot_time} shows an \code{intensityplot} of the fitted ``ground'' intensity $\sum_{k=1}^2 \int_{\bm{W}} \hat\lambda(\bm{s},t,k) \dif \bm{s}$: %aggregated over both event types: <>= intensityplot(imdfit_powerlaw, which = "total", aggregate = "time", types = 1:2) @ <>= par(mar = c(5,5,1,1), las = 1) intensity_endprop <- intensityplot(imdfit_powerlaw, aggregate="time", which="endemic proportion", plot=FALSE) intensity_total <- intensityplot(imdfit_powerlaw, aggregate="time", which="total", tgrid=501, lwd=2, xlab="Time [days]", ylab="Intensity") curve(intensity_endprop(x) * intensity_total(x), add=TRUE, col=2, lwd=2, n=501) #curve(intensity_endprop(x), add=TRUE, col=2, lty=2, n=501) text(2500, 0.36, labels="total", col=1, pos=2, font=2) text(2500, 0.08, labels="endemic", col=2, pos=2, font=2) @ %% Note that this represents a realization of a stochastic process, since it %% depends on the occurred events. The estimated endemic intensity component has also been added to the plot. It exhibits strong seasonality and a slow negative trend. The proportion of the endemic intensity is rather constant along time since no major outbreaks occurred. This proportion can be visualized separately by specifying \code{which = "endemic proportion"} in the above call. <>= meanepiprop <- integrate(intensityplot(imdfit_powerlaw, which="epidemic proportion"), 50, 2450, subdivisions=2000, rel.tol=1e-3)$value / 2400 @ Spatial \code{intensityplot}s as in Figure~\ref{fig:imdfit_powerlaw_intensityplot_space} can be produced via \code{aggregate = "space"} and require a geographic representation of \code{stgrid}. The epidemic proportion is naturally high around clusters of cases and even more so if the population density is low. %% The function \code{epitest} offers a model-based global test for epidemicity, %% while \code{knox} and \code{stKtest} implement related classical approaches %% \citep{meyer.etal2015}. <>= for (.type in 1:2) { print(intensityplot(imdfit_powerlaw, aggregate="space", which="epidemic proportion", types=.type, tiles=districtsD, sgrid=1000, # scales=list(draw=TRUE), # default (sp>=2 uses 'sf', with a fallback) xlab="x [km]", ylab="y [km]", at=seq(0,1,by=0.1), col.regions=rev(hcl.colors(10,"Reds")), colorkey=list(title="Epidemic proportion"))) } @ Another diagnostic tool is the function \code{checkResidualProcess} (Figure~\ref{fig:imdfit_checkResidualProcess}), which transforms the temporal ``residual process'' in such a way that it exhibits a uniform distribution and lacks serial correlation if the fitted model describes the true CIF well \citep[see][Section~3.3]{ogata1988}. % more recent work: \citet{clements.etal2011} <>= par(mar = c(5, 5, 1, 1)) checkResidualProcess(imdfit_powerlaw) @ \section{Simulation} \label{sec:twinstim:simulation} %% Simulations from the fitted model are also useful to investigate the %% goodness of fit. To identify regions with unexpected IMD dynamics, \citet{meyer.etal2011} compared the observed numbers of cases by district to the respective 2.5\% and 97.5\% quantiles of 100 simulations from the selected model. Furthermore, simulations allow us to investigate the stochastic volatility of the endemic-epidemic process, to obtain probabilistic forecasts, and to perform parametric bootstrap of the spatio-temporal point pattern. The simulation algorithm we apply is described in \citet[Section 4]{meyer.etal2011}. It requires a geographic representation of the \code{stgrid}, as well as functionality for sampling locations from the spatial kernel $f_2(\bm{s}) := f(\norm{\bm{s}})$. This is implemented for all predefined spatial interaction functions listed in Table~\ref{tab:iafs}. %For instance for the %power-law kernel, we pass via polar coordinates (with density then proportional %to $rf(r)$) %, a function also involved in the efficient cubature of % %$f_2(\bm{s})$ via Green's theorem) %and the inverse transformation method with numerical root finding for the %quantiles. Event marks are by default sampled from their respective empirical distribution in the original data. %but a customized generator can be supplied as argument \code{rmarks}. The following code runs \emph{a single} simulation over the last year based on the estimated power-law model: <>= imdsim <- simulate(imdfit_powerlaw, nsim = 1, seed = 1, t0 = 2191, T = 2555, data = imdepi_untied_infeps, tiles = districtsD) @ This yields an object of the class \class{simEpidataCS}, which extends \class{epidataCS}. It carries additional components from the generating model to enable an \code{R0}-method and \code{intensityplot}s for simulated data. %All methods for \class{epidataCS} are applicable. %% The result is simplified in that only the \code{events} instead of a full %% \class{epidataCS} object are retained from every run to save memory and %% computation time. All other components, which do not vary between simulations, %% e.g., the \code{stgrid}, are only stored from the first run. %% There is a \code{[[}-method for such \class{simEpidataCSlist}s in order to %% extract single simulations as full \class{simEpidataCS} objects from the %% simplified structure. %Extracting a single simulation (e.g., \code{imdsims[[1]]}) Figure~\ref{fig:imdsim_plot} shows the cumulative number of cases from the simulation appended to the first six years of data. <>= .t0 <- imdsim$timeRange[1] .cumoffset <- c(table(subset(imdepi, time < .t0)$events$type)) par(mar = c(5,5,1,1), las = 1) plot(imdepi, ylim = c(0, 20), col = c("indianred", "darkblue"), subset = time < .t0, cumulative = list(maxat = 336), xlab = "Time [days]") plot(imdsim, add = TRUE, legend.types = FALSE, col = adjustcolor(c("indianred", "darkblue"), alpha.f = 0.5), subset = !is.na(source), # exclude events of the prehistory cumulative = list(offset = .cumoffset, maxat = 336, axis = FALSE), border = NA, density = 0) # no histogram for simulations plot(imdepi, add = TRUE, legend.types = FALSE, col = 1, subset = time >= .t0, cumulative = list(offset = .cumoffset, maxat = 336, axis = FALSE), border = NA, density = 0) # no histogram for the last year's data abline(v = .t0, lty = 2, lwd = 2) @ %% Because we have started simulation at time \code{t0 = 0}, %% no events from \code{data} have been used as the prehistory, i.e., %% the first simulated event is necessarily driven by the endemic model component. A special feature of such simulated epidemics is that the source of each event is known: <>= table(imdsim$events$source > 0, exclude = NULL) @ The stored \code{source} value is 0 for endemic events, \code{NA} for events of the prehistory but still infective at \code{t0}, and otherwise corresponds to the row index of the infective source. %% Averaged over all 30 simulations, the proportion of events triggered by %% previous events is %% Sexpr{mean(sapply(imdsims$eventsList, function(x) mean(x$source > 0, na.rm = TRUE)))}. %-------------- % BIBLIOGRAPHY %-------------- <>= ## create automatic references for R packages knitr::write_bib( # produces UTF-8 c("memoise", "sp", "polyclip", "xtable"), file = "twinstim-R.bib", tweak = FALSE, prefix = "R:") @ \bibliography{references,twinstim-R} \end{document} surveillance/vignettes/hhh4.Rnw0000644000176200001440000010307114516236515016313 0ustar liggesusers%\VignetteIndexEntry{hhh4: An endemic-epidemic modelling framework for infectious disease counts} %\VignetteDepends{surveillance, Matrix} \documentclass[a4paper,11pt]{article} \usepackage[T1]{fontenc} \usepackage[english]{babel} \usepackage{graphicx} \usepackage{color} \usepackage{natbib} \usepackage{lmodern} \usepackage{bm} \usepackage{amsmath} \usepackage{amsfonts,amssymb} \setlength{\parindent}{0pt} \setcounter{secnumdepth}{1} \newcommand{\Po}{\operatorname{Po}} \newcommand{\NegBin}{\operatorname{NegBin}} \newcommand{\N}{\mathcal{N}} \newcommand{\pkg}[1]{{\fontseries{b}\selectfont #1}} \newcommand{\surveillance}{\pkg{surveillance}} \newcommand{\code}[1]{\texttt{#1}} \newcommand{\hhh}{\texttt{hhh4}} \newcommand{\R}{\textsf{R}} \newcommand{\sts}{\texttt{sts}} \newcommand{\example}[1]{\subsubsection*{Example: #1}} %%% Meta data \usepackage{hyperref} \hypersetup{ pdfauthor = {Michaela Paul and Sebastian Meyer}, pdftitle = {'hhh4': An endemic-epidemic modelling framework for infectious disease counts}, pdfsubject = {R package 'surveillance'} } \newcommand{\email}[1]{\href{mailto:#1}{\normalfont\texttt{#1}}} \title{\code{hhh4}: An endemic-epidemic modelling framework for infectious disease counts} \author{ Michaela Paul and Sebastian Meyer\thanks{Author of correspondence: \email{seb.meyer@fau.de} (new affiliation)}\\ Epidemiology, Biostatistics and Prevention Institute\\ University of Zurich, Zurich, Switzerland } \date{8 February 2016} %%% Sweave \usepackage{Sweave} \SweaveOpts{prefix.string=plots/hhh4, keep.source=T, strip.white=true} \definecolor{Sinput}{rgb}{0,0,0.56} \DefineVerbatimEnvironment{Sinput}{Verbatim}{formatcom={\color{Sinput}},fontshape=sl,fontsize=\footnotesize} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontshape=sl,fontsize=\footnotesize} %%% Initial R code <>= library("surveillance") options(width=75) ## create directory for plots dir.create("plots", showWarnings=FALSE) ###################################################### ## Do we need to compute or can we just fetch results? ###################################################### compute <- !file.exists("hhh4-cache.RData") message("Doing computations: ", compute) if(!compute) load("hhh4-cache.RData") @ \begin{document} \maketitle \begin{abstract} \noindent The \R\ package \surveillance\ provides tools for the visualization, modelling and monitoring of epidemic phenomena. This vignette is concerned with the \hhh\ modelling framework for univariate and multivariate time series of infectious disease counts proposed by \citet{held-etal-2005}, and further extended by \citet{paul-etal-2008}, \citet{paul-held-2011}, \citet{held.paul2012}, and \citet{meyer.held2013}. The implementation is illustrated using several built-in surveillance data sets. The special case of \emph{spatio-temporal} \hhh\ models is also covered in \citet[Section~5]{meyer.etal2014}, which is available as the extra \verb+vignette("hhh4_spacetime")+. \end{abstract} \section{Introduction}\label{sec:intro} To meet the threats of infectious diseases, many countries have established surveillance systems for the reporting of various infectious diseases. The systematic and standardized reporting at a national and regional level aims to recognize all outbreaks quickly, even when aberrant cases are dispersed in space. Traditionally, notification data, i.e.\ counts of cases confirmed according to a specific definition and reported daily, weekly or monthly on a regional or national level, are used for surveillance purposes. The \R-package \surveillance\ provides functionality for the retrospective modelling and prospective aberration detection in the resulting surveillance time series. Overviews of the outbreak detection functionality of \surveillance\ are given by \citet{hoehle-mazick-2010} and \citet{salmon.etal2014}. This document illustrates the functionality of the function \hhh\ for the modelling of univariate and multivariate time series of infectious disease counts. It is part of the \surveillance\ package as of version 1.3. The remainder of this vignette unfolds as follows: Section~\ref{sec:data} introduces the S4 class data structure used to store surveillance time series data within the package. Access and visualization methods are outlined by means of built-in data sets. In Section~\ref{sec:model}, the statistical modelling approach by \citet{held-etal-2005} and further model extensions are described. After the general function call and arguments are shown, the detailed usage of \hhh\ is demonstrated in Section~\ref{sec:hhh} using data introduced in Section~\ref{sec:data}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Surveillance data}\label{sec:data} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Denote by $\{y_{it}; i=1,\ldots,I,t=1,\ldots,T\}$ the multivariate time series of disease counts for a specific partition of gender, age and location. Here, $T$ denotes the length of the time series and $I$ denotes the number of units (e.g\ geographical regions or age groups) being monitored. Such data are represented using objects of the S4 class \sts\ (surveillance time series). \subsection[The sts data class]{The \sts\ data class} The \sts\ class contains the $T\times I$ matrix of counts $y_{it}$ in a slot \code{observed}. An integer slot \code{epoch} denotes the time index $1\leq t \leq T$ of each row in \code{observed}. The number of observations per year, e.g.\ 52 for weekly or 12 for monthly data, is denoted by \code{freq}. Furthermore, \code{start} denotes a vector of length two containing the start of the time series as \code{c(year, epoch)}. For spatially stratified time series, the slot \code{neighbourhood} denotes an $I \times I$ adjacency matrix with elements 1 if two regions are neighbors and 0 otherwise. For map visualizations, the slot \code{map} links the multivariate time series to geographical regions stored in a \code{"SpatialPolygons"} object (package \pkg{sp}). Additionally, the slot \code{populationFrac} contains a $T\times I$ matrix representing population fractions in unit $i$ at time $t$. The \sts\ data class is also described in \citet[Section~2.1]{hoehle-mazick-2010}, \citet[Section~1.1]{salmon.etal2014}, \citet[Section~5.2]{meyer.etal2014}, and on the associated help page \code{help("sts")}. \subsection{Some example data sets} The package \surveillance\ contains a number of time series in the \code{data} directory. Most data sets originate from the SurvStat@RKI database\footnote{\url{https://survstat.rki.de}}, maintained by the Robert Koch Institute (RKI) in Germany. Selected data sets will be analyzed in Section~\ref{sec:hhh} and are introduced in the following. Note that many of the built-in datasets are stored in the S3 class data structure \mbox{\code{disProg}} used in ancient versions of the \surveillance\ package (until 2006). They can be easily converted into the new S4 \sts\ data structure using the function \code{disProg2sts}. The resulting \sts\ object can be accessed similar as standard \code{matrix} objects and allows easy temporal and spatial aggregation as will be shown in the remainder of this section. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \example{Influenza and meningococcal disease, Germany, 2001--2006} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% As a first example, the weekly number of influenza and meningococcal disease cases in Germany is considered. <>= # load data data("influMen") # convert to sts class and print basic information about the time series print(fluMen <- disProg2sts(influMen)) @ The univariate time series of meningococcal disease counts can be obtained with <>= meningo <- fluMen[, "meningococcus"] dim(meningo) @ The \code{plot} function provides ways to visualize the multivariate time series in time, space and space-time, as controlled by the \code{type} argument: \setkeys{Gin}{width=1\textwidth} <>= plot(fluMen, type = observed ~ time | unit, # type of plot (default) same.scale = FALSE, # unit-specific ylim? col = "grey") # color of bars @ See \code{help("stsplot")} for a detailed description of the plot routines. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \example{Influenza, Southern Germany, 2001--2008} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The spatio-temporal spread of influenza in the 140 Kreise (districts) of Bavaria and Baden-W\"urttemberg is analyzed using the weekly number of cases reported to the RKI~\citep{survstat-fluByBw} in the years 2001--2008. An \sts\ object containing the data is created as follows: <>= # read in observed number of cases flu.counts <- as.matrix(read.table(system.file("extdata/counts_flu_BYBW.txt", package = "surveillance"), check.names = FALSE)) @ \begin{center} \setkeys{Gin}{width=.5\textwidth} <>= # read in 0/1 adjacency matrix (1 if regions share a common border) nhood <- as.matrix(read.table(system.file("extdata/neighbourhood_BYBW.txt", package = "surveillance"), check.names = FALSE)) library("Matrix") print(image(Matrix(nhood))) @ \end{center} <>= # read in population fractions popfracs <- read.table(system.file("extdata/population_2001-12-31_BYBW.txt", package = "surveillance"), header = TRUE)$popFrac # create sts object flu <- sts(flu.counts, start = c(2001, 1), frequency = 52, population = popfracs, neighbourhood = nhood) @ These data are already included as \code{data("fluBYBW")} in \surveillance. In addition to the \sts\ object created above, \code{fluBYBW} contains a map of the administrative districts of Bavaria and Baden-W\"urttemberg. This works by specifying a \code{"SpatialPolygons"} representation of the districts as an extra argument \code{map} in the above \sts\ call. Such a \code{"SpatialPolygons"} object can be obtained from, e.g, an external shapefile using the \pkg{sf} functions \code{st\_read} followed by \code{as\_Spatial}. A map enables plots and animations of the cumulative number of cases by region. For instance, a disease incidence map of the year 2001 can be obtained as follows: \setkeys{Gin}{width=.5\textwidth} \begin{center} <>= data("fluBYBW") plot(fluBYBW[year(fluBYBW) == 2001, ], # select year 2001 type = observed ~ unit, # total counts by region population = fluBYBW@map$X31_12_01 / 100000, # per 100000 inhabitants colorkey = list(title = "Incidence [per 100'000 inhabitants]")) @ \end{center} <>= # consistency check local({ fluBYBW@map <- flu@map stopifnot(all.equal(fluBYBW, flu)) }) @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \example{Measles, Germany, 2005--2007} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The following data set contains the weekly number of measles cases in the 16 German federal states, in the years 2005--2007. These data have been analyzed by \citet{herzog-etal-2010} after aggregation into bi-weekly periods. <>= data("measlesDE") measles2w <- aggregate(measlesDE, nfreq = 26) @ \setkeys{Gin}{width=.75\textwidth} \begin{center} <>= plot(measles2w, type = observed ~ time, # aggregate counts over all units main = "Bi-weekly number of measles cases in Germany") @ \end{center} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Model formulation}\label{sec:model} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Retrospective surveillance aims to identify outbreaks and (spatio-)temporal patterns through statistical modelling. Motivated by a branching process with immigration, \citet{held-etal-2005} suggest the following model for the analysis of univariate time series of infectious disease counts $\{y_{t}; t=1,\ldots,T\}$. The counts are assumed to be Poisson distributed with conditional mean \begin{align*} \mu_{t} = \lambda y_{t-1}+ \nu_{t}, \quad(\lambda,\nu_{t}>0) \end{align*} where $\lambda$ and $\nu_t$ are unknown quantities. The mean incidence is decomposed additively into two components: an epidemic or \emph{autoregressive} component $\lambda y_{t-1}$, and an \emph{endemic} component $\nu_t$. The former should be able to capture occasional outbreaks whereas the latter explains a baseline rate of cases with stable temporal pattern. \citet{held-etal-2005} suggest the following parametric model for the endemic component: \begin{align}\label{eq:nu_t} \log(\nu_t) =\alpha + \beta t + \left\{\sum_{s=1}^S \gamma_s \sin(\omega_s t) + \delta_s \cos(\omega_s t)\right\}, \end{align} where $\alpha$ is an intercept, $\beta$ is a trend parameter, and the terms in curly brackets are used to model seasonal variation. Here, $\gamma_s$ and $\delta_s$ are unknown parameters, $S$ denotes the number of harmonics to include, and $\omega_s=2\pi s/$\code{freq} are Fourier frequencies (e.g.\ \code{freq = 52} for weekly data). For ease of interpretation, the seasonal terms in \eqref{eq:nu_t} can be written equivalently as \begin{align*} \gamma_s \sin(\omega_s t) + \delta_s \cos(\omega_s t)= A_s \sin(\omega_s t +\varphi_s) \end{align*} with amplitude $A_s=\sqrt{\gamma_s^2+\delta_s^2}$ describing the magnitude, and phase difference $\tan(\varphi_s)=\delta_s/\gamma_s$ describing the onset of the sine wave. To account for overdispersion, the Poisson model may be replaced by a negative binomial model. Then, the conditional mean $\mu_t$ remains the same but the conditional variance increases to $\mu_t (1+\mu_t \psi)$ with additional unknown overdispersion parameter $\psi>0$. The model is extended to multivariate time series $\{y_{it}\}$ in \citet{held-etal-2005} and \citet{paul-etal-2008} by including an additional \emph{neighbor-driven} component, where past cases in other (neighboring) units also enter as explanatory covariates. The conditional mean $\mu_{it}$ is then given by \begin{align} \label{eq:mu_it} \mu_{it} = \lambda y_{i,t-1} + \phi \sum_{j\neq i} w_{ji} y_{j,t-1} +e_{it} \nu_{t}, \end{align} where the unknown parameter $\phi$ quantifies the influence of other units $j$ on unit $i$, $w_{ji}$ are weights reflecting between-unit transmission and $e_{it}$ corresponds to an offset (such as population fractions at time $t$ in region $i$). A simple choice for the weights is $w_{ji}=1$ if units $j$ and $i$ are adjacent and 0 otherwise. See \citet{paul-etal-2008} for a discussion of alternative weights, and \citet{meyer.held2013} for how to estimate these weights in the spatial setting using a parametric power-law formulation based on the order of adjacency. When analyzing a specific disease observed in, say, multiple regions or several pathogens (such as influenza and meningococcal disease), the assumption of equal incidence levels or disease transmission across units is questionable. To address such heterogeneity, the unknown quantities $\lambda$, $\phi$, and $\nu_t$ in \eqref{eq:mu_it} may also depend on unit $i$. This can be done via \begin{itemize} \item unit-specific fixed parameters, e.g.\ $\log(\lambda_i)=\alpha_i$ \citep{paul-etal-2008}; \item unit-specific random effects, e.g\ $\log(\lambda_i)=\alpha_0 +a_i$, $a_i \stackrel{\text{iid}}{\sim} \N(0,\sigma^2_\lambda)$ \citep{paul-held-2011}; \item linking parameters with known (possibly time-varying) explanatory variables, e.g.\ $\log(\lambda_i)=\alpha_0 +x_i\alpha_1$ with region-specific vaccination coverage $x_i$ \citep{herzog-etal-2010}. \end{itemize} In general, the parameters of all three model components may depend on both time and unit. A call to \hhh\ fits a Poisson or negative binomial model with conditional mean \begin{align*} \mu_{it} = \lambda_{it} y_{i,t-1} + \phi_{it} \sum_{j\neq i} w_{ji} y_{j,t-1} +e_{it} \nu_{it} \end{align*} to a (multivariate) time series of counts. Here, the three unknown quantities are modelled as log-linear predictors \begin{align} \log(\lambda_{it}) &= \alpha_0 + a_i +\bm{u}_{it}^\top \bm{\alpha} \tag{\code{ar}}\\ \log(\phi_{it}) &= \beta_0 + b_i +\bm{x}_{it}^\top \bm{\beta} \tag{\code{ne}}\\ \log(\nu_{it}) &= \gamma_0 + c_i +\bm{z}_{it}^\top \bm{\gamma}\tag{\code{end}} \end{align} where $\alpha_0,\beta_0,\gamma_0$ are intercepts, $\bm{\alpha},\bm{\beta},\bm{\gamma}$ are vectors of unknown parameters corresponding to covariate vectors $\bm{u}_{it},\bm{x}_{it},\bm{z}_{it}$, and $a_i,b_i,c_i$ are random effects. For instance, model~\eqref{eq:nu_t} with $S=1$ seasonal terms may be represented as $\bm{z}_{it}=(t,\sin(2\pi/\code{freq}\;t),\cos(2\pi/\code{freq}\;t))^\top$. The stacked vector of all random effects is assumed to follow a normal distribution with mean $\bm{0}$ and covariance matrix $\bm{\Sigma}$. In applications, each of the components \code{ar}, \code{ne}, and \code{end} may be omitted in parts or as a whole. If the model does not contain random effects, standard likelihood inference can be performed. Otherwise, inference is based on penalized quasi-likelihood as described in detail in \citet{paul-held-2011}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Function call and control settings}\label{sec:hhh} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The estimation procedure is called with <>= hhh4(sts, control) @ where \code{sts} denotes a (multivariate) surveillance time series and the model is specified in the argument \code{control} in consistency with other algorithms in \surveillance. The \code{control} setting is a list of the following arguments (here with default values): <>= control = list( ar = list(f = ~ -1, # formula for log(lambda_it) offset = 1), # optional multiplicative offset ne = list(f = ~ -1, # formula for log(phi_it) offset = 1, # optional multiplicative offset weights = neighbourhood(stsObj) == 1), # (w_ji) matrix end = list(f = ~ 1, # formula for log(nu_it) offset = 1), # optional multiplicative offset e_it family = "Poisson", # Poisson or NegBin model subset = 2:nrow(stsObj), # subset of observations to be used optimizer = list(stop = list(tol = 1e-5, niter = 100), # stop rules regression = list(method = "nlminb"), # for penLogLik variance = list(method = "nlminb")), # for marLogLik verbose = FALSE, # level of progress reporting start = list(fixed = NULL, # list with initial values for fixed, random = NULL, # random, and sd.corr = NULL), # variance parameters data = list(t = epoch(stsObj)-1),# named list of covariates keep.terms = FALSE # whether to keep the model terms ) @ The first three arguments \code{ar}, \code{ne}, and \code{end} specify the model components using \code{formula} objects. By default, the counts $y_{it}$ are assumed to be Poisson distributed, but a negative binomial model can be chosen by setting \mbox{\code{family = "NegBin1"}}. By default, both the penalized and marginal log-likelihoods are maximized using the quasi-Newton algorithm available via the \R\ function \code{nlminb}. The methods from \code{optim} may also be used, e.g., \mbox{\code{optimizer = list(variance = list(method="Nelder-Mead")}} is a useful alternative for maximization of the marginal log-likelihood with respect to the variance parameters. Initial values for the fixed, random, and variance parameters can be specified in the \code{start} argument. If the model contains covariates, these have to be provided in the \code{data} argument. If a covariate does not vary across units, it may be given as a vector of length $T$. Otherwise, covariate values must be given in a matrix of size $T \times I$. In the following, the functionality of \hhh\ is demonstrated using the data sets introduced in Section~\ref{sec:data} and previously analyzed in \citet{paul-etal-2008}, \citet{paul-held-2011} and \citet{herzog-etal-2010}. Selected results are reproduced. For a thorough discussion we refer to these papers. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Univariate modelling} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% As a first example, consider the univariate time series of meningococcal infections in Germany, 01/2001--52/2006 \citep[cf.][Table~1]{paul-etal-2008}. A Poisson model without autoregression and $S=1$ seasonal term is specified as follows: <>= # specify a formula object for the endemic component ( f_S1 <- addSeason2formula(f = ~ 1, S = 1, period = 52) ) # fit the Poisson model result0 <- hhh4(meningo, control = list(end = list(f = f_S1), family = "Poisson")) summary(result0) @ To fit the corresponding negative binomial model, we can use the convenient \code{update} method: <>= result1 <- update(result0, family = "NegBin1") @ Note that the \code{update} method by default uses the parameter estimates from the original model as start values when fitting the updated model; see \code{help("update.hhh4")} for details. We can calculate Akaike's Information Criterion for the two models to check whether accounting for overdispersion is useful for these data: <<>>= AIC(result0, result1) @ Due to the default control settings with \verb|ar = list(f = ~ -1)|, the autoregressive component has been omitted in the above models. It can be included by the following model update: <>= # fit an autoregressive model result2 <- update(result1, ar = list(f = ~ 1)) @ To extract only the ML estimates and standard errors instead of a full model \code{summary}, the \code{coef} method can be used: <<>>= coef(result2, se = TRUE, # also return standard errors amplitudeShift = TRUE, # transform sine/cosine coefficients # to amplitude/shift parameters idx2Exp = TRUE) # exponentiate remaining parameters @ Here, \code{exp(ar.1)} is the autoregressive coefficient $\lambda$ and can be interpreted as the epidemic proportion of disease incidence \citep{held.paul2012}. Note that the above transformation arguments \code{amplitudeShift} and \code{idx2Exp} can also be used in the \code{summary} method. Many other standard methods are implemented for \code{"hhh4"} fits, see, e.g., \code{help("confint.hhh4")}. A plot of the fitted model components can be easily obtained: \begin{center} <>= plot(result2) @ \end{center} See the comprehensive \code{help("plot.hhh4")} for further options. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Bivariate modelling} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Now, the weekly numbers of both meningococcal disease (\textsc{MEN}) and influenza (\textsc{FLU}) cases are analyzed to investigate whether influenza infections predispose meningococcal disease \citep[cf.][Table~2]{paul-etal-2008}. This requires disease-specific parameters which are specified in the formula object with \code{fe(\ldots)}. In the following, a negative binomial model with mean \begin{align*} \binom{\mu_{\text{men},t}} {\mu_{\text{flu},t}}= \begin{pmatrix} \lambda_\text{men} & \phi \\ 0 & \lambda_\text{flu} \\ \end{pmatrix} \binom{\text{\sc men}_{t-1}}{\text{\sc flu}_{t-1}} + \binom{\nu_{\text{men},t}}{\nu_{\text{flu},t}}\,, \end{align*} where the endemic component includes $S=3$ seasonal terms for the \textsc{FLU} data and $S=1$ seasonal terms for the \textsc{MEN} data is considered. Here, $\phi$ quantifies the influence of past influenza cases on the meningococcal disease incidence. This model corresponds to the second model of Table~2 in \citet{paul-etal-2008} and is fitted as follows: <>= # no "transmission" from meningococcus to influenza neighbourhood(fluMen)["meningococcus","influenza"] <- 0 neighbourhood(fluMen) @ <>= # create formula for endemic component f.end <- addSeason2formula(f = ~ -1 + fe(1, unitSpecific = TRUE), # disease-specific intercepts S = c(3, 1), # S = 3 for flu, S = 1 for men period = 52) # specify model m <- list(ar = list(f = ~ -1 + fe(1, unitSpecific = TRUE)), ne = list(f = ~ 1, # phi, only relevant for meningococcus due to weights = neighbourhood(fluMen)), # the weight matrix end = list(f = f.end), family = "NegBinM") # disease-specific overdispersion # fit model result <- hhh4(fluMen, control = m) summary(result, idx2Exp=1:3) @ A plot of the estimated mean components can be obtained as follows: \setkeys{Gin}{width=1\textwidth} \begin{center} <>= plot(result, units = NULL, pch = 20, legend = 2, legend.args = list( legend = c("influenza-driven", "autoregressive", "endemic"))) @ \end{center} Alternatively, use the \code{decompose} argument to show the unit-specific contributions to the fitted mean: \begin{center} <>= plot(result, units = NULL, pch = 20, legend = 2, decompose = TRUE, col = c(7, 4)) @ \end{center} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Multivariate modelling} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% For disease counts observed in a large number of regions, say, (i.e.\ highly multivariate time series of counts) the use of region-specific parameters to account for regional heterogeneity is no longer feasible as estimation and identifiability problems may occur. Here we illustrate two approaches: region-specific random effects and region-specific covariates. For a more detailed illustration of areal \code{hhh4} models, see \verb+vignette("hhh4_spacetime")+, which uses \verb+data("measlesWeserEms")+ as an example. \subsubsection*{Influenza, Southern Germany, 2001--2008} \citet{paul-held-2011} propose a random effects formulation to analyze the weekly number of influenza cases in \Sexpr{ncol(fluBYBW)} districts of Southern Germany. For example, consider a model with random intercepts in the endemic component: $c_i \stackrel{iid}{\sim} \N(0,\sigma^2_\nu), i=1,\ldots,I$. Such effects are specified as: <>= f.end <- ~ -1 + ri(type = "iid", corr = "all") @ The alternative \code{type = "car"} would assume spatially correlated random effects; see \citet{paul-held-2011} for details. The argument \code{corr = "all"} allows for correlation between region-specific random effects in different components, e.g., random incidence levels $c_i$ in the endemic component and random effects $b_i$ in the neighbor-driven component. The following call to \hhh\ fits such a random effects model with linear trend and $S=3$ seasonal terms in the endemic component, a fixed autoregressive parameter $\lambda$, and first-order transmission weights $w_{ji}=\mathbb{I}(j\sim i)$ -- normalized such that $\sum_i w_{ji} = 1$ for all rows $j$ -- to the influenza data \citep[cf.][Table~3, model~B2]{paul-held-2011}. <>= # endemic component: iid random effects, linear trend, S=3 seasonal terms f.end <- addSeason2formula(f = ~ -1 + ri(type="iid", corr="all") + I((t-208)/100), S = 3, period = 52) # model specification model.B2 <- list(ar = list(f = ~ 1), ne = list(f = ~ -1 + ri(type="iid", corr="all"), weights = neighbourhood(fluBYBW), normalize = TRUE), # all(rowSums(weights) == 1) end = list(f = f.end, offset = population(fluBYBW)), family = "NegBin1", verbose = TRUE, optimizer = list(variance = list(method = "Nelder-Mead"))) # default start values for random effects are sampled from a normal set.seed(42) @ <>= if(compute){ result.B2 <- hhh4(fluBYBW, model.B2) s.B2 <- summary(result.B2, maxEV = TRUE, idx2Exp = 1:3) #pred.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52) predfinal.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52, type = "final") meanSc.B2 <- colMeans(scores(predfinal.B2)) save(s.B2, meanSc.B2, file="hhh4-cache.RData") } @ <>= # fit the model (takes about 35 seconds) result.B2 <- hhh4(fluBYBW, model.B2) summary(result.B2, maxEV = TRUE, idx2Exp = 1:3) @ <>= s.B2 @ Model choice based on information criteria such as AIC or BIC is well explored and understood for models that correspond to fixed-effects likelihoods. However, in the presence of random effects their use can be problematic. For model selection in time series models, the comparison of successive one-step-ahead forecasts with the actually observed data provides a natural alternative. In this context, \citet{gneiting-raftery-2007} recommend the use of strictly proper scoring rules, such as the logarithmic score (logs) or the ranked probability score (rps). See \citet{czado-etal-2009} and \citet{paul-held-2011} for further details. One-step-ahead predictions for the last 2 years for model B2 could be obtained as follows: <>= pred.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52) @ However, computing ``rolling'' one-step-ahead predictions from a random effects model is computationally expensive, since the model needs to be refitted at every time point. The above call would take approximately 45 minutes! So for the purpose of this vignette, we use the fitted model based on the whole time series to compute all (fake) predictions during the last two years: <>= predfinal.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52, type = "final") @ The mean scores (logs and rps) corresponding to this set of predictions can then be computed as follows: <>= colMeans(scores(predfinal.B2, which = c("logs", "rps"))) @ <>= meanSc.B2[c("logs", "rps")] @ Using predictive model assessments, \citet{meyer.held2013} found that power-law transmission weights more appropriately reflect the spread of influenza than the previously used first-order weights (which actually allow the epidemic to spread only to directly adjacent districts within one week). These power-law weights can be constructed by the function \code{W\_powerlaw} and require the \code{neighbourhood} of the \sts\ object to contain adjacency orders. The latter can be easily obtained from the binary adjacency matrix using the function \code{nbOrder}. See the corresponding help pages or \citet[Section~5]{meyer.etal2014} for illustrations. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection*{Measles, German federal states, 2005--2007} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <>= data(MMRcoverageDE) cardVac1 <- MMRcoverageDE[1:16,3:4] adjustVac <- function(cardVac, p=0.5,nrow=1){ card <- cardVac[,1] vac <- cardVac[,2] vacAdj <- vac*card + p*vac*(1-card) return(matrix(vacAdj,nrow=nrow, ncol=length(vacAdj), byrow=TRUE)) } vac0 <- 1-adjustVac(cardVac1,p=0.5,nrow=measles2w@freq*3) colnames(vac0) <- colnames(measles2w) @ As a last example, consider the number of measles cases in the 16 federal states of Germany, in the years 2005--2007. There is considerable regional variation in the incidence pattern which is most likely due to differences in vaccination coverage. In the following, information about vaccination coverage in each state, namely the log proportion of unvaccinated school starters, is included as explanatory variable in a model for the bi-weekly aggregated measles data. See \citet{herzog-etal-2010} for further details. Vaccination coverage levels for the year 2006 are available in the dataset \code{data(MMRcoverageDE)}. This dataset can be used to compute the $\Sexpr{nrow(vac0)}\times \Sexpr{ncol(vac0)}$ matrix \code{vac0} with adjusted proportions of unvaccinated school starters in each state $i$ used by \citet{herzog-etal-2010}. The first few entries of this matrix are shown below: <<>>= vac0[1:2, 1:6] @ We fit a Poisson model, which links the autoregressive parameter with this covariate and contains $S=1$ seasonal term in the endemic component \citep[cf.][Table~3, model~A0]{herzog-etal-2010}: <>= # endemic component: Intercept + sine/cosine terms f.end <- addSeason2formula(f = ~ 1, S = 1, period = 26) # autoregressive component: Intercept + vaccination coverage information model.A0 <- list(ar = list(f = ~ 1 + logVac0), end = list(f = f.end, offset = population(measles2w)), data = list(t = epoch(measles2w), logVac0 = log(vac0))) # fit the model result.A0 <- hhh4(measles2w, model.A0) summary(result.A0, amplitudeShift = TRUE) @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Conclusion} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% As part of the \R~package \surveillance, the function \hhh\ provides a flexible tool for the modelling of multivariate time series of infectious disease counts. The presented count data model is able to account for serial and spatio-temporal correlation, as well as heterogeneity in incidence levels and disease transmission. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \bibliographystyle{apalike} \renewcommand{\bibfont}{\small} \bibliography{references} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \end{document} surveillance/vignettes/hhh4_spacetime-cache.RData0000644000176200001440000001433012676602723021635 0ustar liggesusers[y8mYQd S)Q(4!DE@R)[B2C6O6m)/ss3]ֽ{zg=zz CBL!&YRI~0%28py 鏎 āCVk}=`Vx M6=[=}]ߎ sXY(|G7C=0|M(h^?-CpE8-3+֣-85H;JTBY&ջ mP-tJ g .;@6Ih9c0# EC$RP+׈[4?AjL~jUE /AEi/|g:\B*sn;( UvA 6n Cht0nY WUs?/5ZQj͗PdsUYd—kWAoPb (c]2~(ۛa 1CoRZ֭+~PqiAY 4S:; BӄV\zZQ 4T7*ͫɗ/~m!;$ozihOY#:ʀz]|?yD3j Oyd`26)5 m&n {R=._K]eF`ХF5 yw:`n3? `b>  =9c1Wa;!vګ 髹0PuF4t57v@OOjADԨ)@~C5lD=D3^o}G:/~ܶ}9[ٗ#;}fjm$%74/+aQG8>с ;,Eltsg)4ދ}Zxv9(\[5\Ŏȡs)Do`*uȚށE/B>.bx> T4# /C*.l7;K]7[EOqU9NAEQU*.pZ6q̅Vj0%{e7%ǔC/UBƗc9-/Q!N`}8JRs"aN"3ĨQX[yX 4ȹ)Ƥ &b{ޱ~3޹'`wOF>a*5!sQ&;"3n}w 9 PJCA+'n.JչoŽ[z>.êLJGHJ2 U=7f}+dD1{]D״ ۷'"a'& Dwj?,<9EZŦ `$B!fҷ9&Td(/~o TtZWC]kGf3 JU:\4 7<6)P)-4o]w>&[si@ *4N-k)sͷ,(Lu˅bbOku \;Bwy/Nr] U?<я$2z1[(^f3 e.Yyh>iE=" E.2(7nEwx ^u\=}غ#wdXׅrJݱRja\HKj2&Ɉj⫚ĪgU\դV9dV琑]^ Jq GRL|!س֐\kH1Z@jm~ ֐YkȮ5bk+J7 ZA2ncQ_sZ+W.r^|!e_Feu$._[9A|˸=˸r~p:\Yoy^p5/0j2b]qYYϒu{!wK7JR7RZ1@*Uztb+ܗ볚ۮIRLqon`r}Ƶђk2 w01)ח=O,|Ǥ"/w\?H RcI+;E悠Пgs+ C囙)v!\5Bl 1ᱪ\ѝ|nm Z}݁}N"=%%F!MNt;lPrDS@T#Q_q09}iZnohѭkaa4 0;%Yu4|u{p0pٰ<3x[焦]Z^:aÎ'CHxHo69@\ᦩot uAY& p(m 8X•A*( *,)Ύ` -)/@ w ^|a4NB~/ywݐni|$s+E Z"@mu2PB/vC ft%!fCT7Q\y w`Ƞ)XIk$yqE!w aQS':61K!#i"dш',o=V=ɲ xtL Jo7lD8;H<~'oD09vBy8"˃=2 CQUD Q9H~zr:ۿ5i*҇.bSOз&9&L8Fj:`haY pv(Z=04+zw:کY9?_E ,[ _'︿փƠ |DLbjru}o ug}jHrzfiv> }oGN@Jx]vsn$I+6AR7/+'=yTި*W: 1 qKAp o\_J:\9ؠ+CEUZM@eF? )[޸פPFb됈*kcwk}Hs8PI$M`זYk;{CAp 8vɴ{N[fq`DXLiCxCv6QxǞC)\x,:xKC /_晟Q":}p b:05a8؏\kaػO#nֵF-t–]&+AtHE8lkqU{퓪30Qij~2m08&5ƏȄ+C{;~L 4FkR>hV 7ҬFD͠EPW| hGXr!=IS@Vu,;LʓW糞]P :q% PVa$d-KEZqP|ǹo t4Assfsv{H^5N6w!ΖˎhZC]Ô 5E]A%|5D|Bέ,/!q? )-JouV WOCV41[.֐նs\ cCO9ջ%cS>3$DA-T~du,,&VBnl'$ JGDٱ\ÓYMy a~GԚ"0k[ xߤgi*ۯ^`@Z» `sf7F :+kxiFl4x,|yg3\Nhx)^.\ɁawʨQh|l1G[t ' <)dW]P$81:7s!YVg-^ [һP]hk935CqD6:ʌnbP-NjP'< Ղ[JwwgSf|Y펇OE@P*D=EJFR@>k'SҐKЫ<8/iml~ҜYng >Zs\r/i$B[Ŕ6^%q?QpV-u>JP]iRv@ħGZ=D5~ IpA[NWjPOxRx۲3eWɺ.s={%!OmSoI|m87".4!č~m'8'P:NA46ԕ@[6U>~ b4:AO|e|A㇓>34&p) hqo~)h=żOڜ uɪnPS;-'q^Wa0Q\0}F٧zVӄ+&oaҋK݆h3'osߜϱd"w-=wH:> endobj 2 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 5 0 obj << /Type /Page /Parent 3 0 R /Contents 6 0 R /Resources 4 0 R >> endobj 6 0 obj << /Length 571 /Filter /FlateDecode >> stream xVnA +XJE. wQa@>5={!]3]ryb83a$"bJ_XäՈ`fȘ2?θ(8;Lfa\H8b l`Î0  #lSB3` ;ۃq|?@w0wA' B. ma0[J (ҌIUIbcyB [1zBJ zj_&[P_em !ۂ^}cv*ɖD\QV#!߃EB$nmD\/{*Ayy̱$hѰZhx6/́Y"Ç5δ,I}FN4Kzܬi#exV,vrendstream endobj 3 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 /MediaBox [0 0 504 216] >> endobj 4 0 obj << /ProcSet [/PDF /Text] /Font <> /ExtGState << >> >> endobj 7 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 45/minus 96/quoteleft 144/dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron /space] >> endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F7 /BaseFont /Times-Roman /Encoding 7 0 R >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F11 /BaseFont /Symbol >> endobj xref 0 10 0000000000 65535 f 0000000021 00000 n 0000000163 00000 n 0000000934 00000 n 0000001017 00000 n 0000000212 00000 n 0000000292 00000 n 0000001109 00000 n 0000001366 00000 n 0000001464 00000 n trailer << /Size 10 /Info 1 0 R /Root 2 0 R >> startxref 1542 %%EOF surveillance/vignettes/monitoringCounts-cache/pMC.RData0000644000176200001440000000025414330454336023002 0ustar liggesusers r0b```f`abb`f2XCCt-"@# 'HA3baC&8vuᩃ[7$^r.ۂ׹߷Nqs76՗okfeR}H}=YuK (?jf QUxsurveillance/vignettes/monitoringCounts-cache/pMarkovChain.RData0000644000176200001440000000035714330454336024711 0ustar liggesusers r0b```f`abb`f2XCCt-"@# ')M,/sHXxc}{T-=گ?Ree?M_ RӼio_f,SxR}]|~cyrL߶Qsx'fPna+Twa}@uIo ;ho-el4?ސy[͍jsurveillance/vignettes/monitoringCounts-cache/boda.covars.RData0000644000176200001440000002104014615104657024524 0ustar liggesusersTTޙa( (HޥQ"^
(M]vEPE^H,c5boh}s&/{[k}3g==g;ݵue2\PJ)SֻLq 2=hИjQx me|:.VtN$#Vh>_1 ":!ͪG%F&DDDE#wSïϧ|>x Y8[> 2Y}|>>X[@]Zo@' Ƃd0Y`)ip;W d Հ )h AW CA4HT0 `X^p΂&LP3P8: 4 ہa`8$h8$T0d% .p A9x>d0=p>>hZLF]@o&q` @XV`Pn1xdYcdo\ ' qst@(`4R,+ZPv}(8 ΃ <OkQ& 8J` `+@h ڃΠ  0de`AP ~u xwR&  S`  A3| A}b(0LAXrAv"pA nLh|xܨpbQ^a9W&rsJRs[1r)(<1J8+J# vRaU7|A0OtJ|A#vJ7%O+16J8(p_J9sW ܛ/菈9"1r}1E_D K 61rO#甘JS~o >OWt: T5t9%sDX|RW{%bYX+v1OX rp%l/_"b "E9 %}h#6+.kVotT:G*u<'t0:y9^P٠Blց ^+aO%qQ1Q )grG8\_+|y5qN(9N7rW9bPS?:hP5|^RUﺈQ PaLT q@ATbL9ĜV9@SxA+;9'"{R֌g5sNyh#"6o4?41R;<' E3Mc.CMg..TqU%בb]X3H!.- m9b9bwQ*fGDi2Q2i&p DN0"3S=m׼O+-iI$+p… .\H]lju'QGj .vCG?166<.4&1zv3DK?_1@4茇Lә`W1ib734:sFgitBXibv].oFgL?cgXY?Z3]g-F/eF/9ˮ0ٸd>Jk;f76> YͬvYhi֟Of̐YicNkLO_Yi> "֏x9jr\6oޣ++u}'0ifQf-cZλx_#vb?Hv?leb㒩2ٸ,d3GY_gtfKyL3e˶`3vl.b/v2vVvylbﯩ/c3#'X;ϕ+`[Ǽbf:Gk'vv/e2ڧ'3Vt6>ileifl^e2e^_OB[R柹!L̻4*6.ktqFnƎ3}TsYY?K.=6i,cbcn&{ ;vl^.`󂍳Γ- v_ }eqfaρum4ϟϧQQ>uFgo#]5{fڠgX{M] fijnu/_U^Weg6α8i)=ﲙeͲy,n׼ZT: Ka115"W sſڿ ؘHuBDLt8uvu޹kkՑ ` 0MD0 $>A` _R@*ofG s<0tLA>T,؏ r䂕 ` (o z`?(H_R f`)l2͗쿅}K88 >aL(7 ?_ONpp\%2] Rpܔ}Pn;pC+xSPx ^ x ރ|BP ’( }/J_z \xMvʣGòSkm'˺_|e\ܐoe.[E&]zlqnQmI~Vwze yl~277]D^d7ٌuuRP_;D|?-9oW[wyznP񢰀<#KyѯX-(]J&sv+B/h׿`!H> ƇQb\M(7 2?Ϗ KzdAӌ_#Z;4.";6qT&ȿ[wTc{^Opz|eO9 & ʣ>jtx=y2V!Cn::,'T3H3n~^ul)q$E}K6-"{YKN}޳IrQ<1llQԠ̧>o}Y)n8V̂"^PgC ` Cfd1IwCW}ҲdaӐ -ّeHH9:酖R6:QSuL&6 vXpSd̄^\يl> /RכKΰ/td3MKx^u rie62/Uw=)KɱGd׬c}i/. A{doBcG͘rs6y,-6jT}ss7os;PLt#O(g&ʤ;a*3ma&C~Ok_"s{Fہct&7Ujc/G='"4!dp䚷޵QlrS>Pۋ=2&al=kJ6GwkN6߮P,jG9Q="}ʳҮj_enьl{*bMWגmRZ%djݸ͆dSqd^gF232YexC1kti; wٯ]=2fms<~yYwt!ύ ny/$SUBw]q*y\y\,j:֮&9o}W?c.5~J.7FS}"ǩ3w#^ί<^B2n{d;HPa]2~l4Y'EN=2s|tT㤟s=-T+pБ?n×b˩ar̎ `Y6Yzod:fԤ ͨ搷f=gN&?VWRM2kYm593xnde̋ORgΠxzx@rzzqCr2qZݗgE4;{ hMMK'NOGC4'#1Zu"S m&+M#t$X7kv%SSRS*'߂V]˧>ms|\y}PۺuxnJk|4|yA‰wƒϚ!?G_F;u!ʐz?}Wgǡd߯ {2itHYM r1?<;9Ş߿9:fxbo3]}CV~fY96%~j͛f6~m3x{0i$(@xd7Yǽdת|W軗dߩ< =Ykh: Ֆn DM&'[^[A+I=J..|M C'u&^w O nd7uǡǒaS¢'f?$_ǖ!Ɔ5F8E]'qfi9cܰ>̤S{'j<oz(*m 1ξ{xy44{/y^ B>^q#qƐ%ײ%jݲIFSNQŏvuw#? LUU,Uj9KXx>rWQ"7lk< >}W9\GP%N煼!Ǻ@οŎVx?I"^9: 3$i;" Lh;٘5X?,?orQv?w>hӃLs."%-$to{UQ?OϿA^ ESw~ ^^#{ƪ(39Fo\ {9Pz/btoE y9ϙM#l0ƣ rݶr2rBHrPE(zcltZ$;JߐO6sHΎػWū9VOɷi3gƐ`Ucʰ,ЯFs_pRɑӹљvIJc*0zrK$Ӌ<;LJaS Zؑ-'GL3{C}޹? 6i/(\MֱdoZd<=2;wu^ȰRe%Ǿ~$ w}VwWT3dqC{dc TV~ږdQtfbdrs\[9aid4VdA~/ o=hoI)9Y͚HwVvqm\S^ITwqη6#Y=,m" =ZIu:,s9U[}pTmn->U[}pTm \p… *)¿H, VSu"}%FqQ/H7:|pu\B`ذ(N~b""ښz_NP C.73GlS4 T1A@*AHɥ"T¾ J^RIR@* t]T J=A/ R@0 ߁A@ BAJKE@*@*A #TnQF@*U?T{"@2 @*MRt }u&JR `@: T> d <_%@* ,+@.X @>Jk@J l`3vn> 2?C@*QqP ?$JŸ?3,8΃ "2J_@)J7-Pn; !<Tj7g9x^W5x{TLSyEGʁBKMR$/5O&EkFҷ"_)W+E"_/E"_/E"_/E"_/E"_/E،@i]Zi߬R{V JNVkXa:*62"zha1LTG'DDjTx\hLOK-,OBFGDF)d~X(u\uGg>Xo?Z?Zyg+EW_)RJ"+EW_)RJ < < < < < < < U$wy________^řx~x~x~x~x~x~x~xg.pTmSۧj p;UmSۧ \On->U[}poSn->U[}*\p…T*T-N34:ͼ$/&ɋI:UN)jeV1surveillance/vignettes/monitoringCounts-cache/boda.RData0000644000176200001440000000617214615104657023241 0ustar liggesusersw|Nv{F D% bEvd u7AdSl˳aWXy{^ܙs~wNc'gR0,ö~ظ 6Qm`)ҐwRd?Y~w791>Eڪ{m7L356TfOTV+VDbH(zء+5̽wxKS~4a\< ua#]a pp2$a:̄0A+tUp=C<!,N5a=a8cGd(T™p\ihv 7p< OK&Wa#0ց asv@ X( q̀ R+a! wÃ8<[|φQH5(- [ Ip@…P 05p# G)xހwc7 \`t`6l3a#G8dc` D p>\ p\]W`17aD: aKB82qTRp:s 2p5"xux>/`,7Ek)l;D/:B@Nab&Z/""hI`SR0lfXlr¿9i1'OLYwbELYyX6gp#q'_%\'r!OB1ߴs7tuvC~䦍l6}WM+Wqfl6so1EX$ModC _XğX\ ]|  \r%'JHKEO]4scqZxrU;hM<;hm}<_)4B"OLD[MtDKMmboҶ{sWݻi#vF/,_K?Ysڶ:mxyq4}6--sZd~څb5bi_ߗK?ԶJS-ּmRyŖ8N LҶEmd\]3_Abn+e3ҿr>#~tH9*q"Bbe~e\LMZ/ Zo~|/+L'zs;FVϓd\xj.:ኻ\XoL C-VnсN|6Y=Wdm}hyi~׋nՊfTgܷk$nkiozQuXmqŴV=O[' ҮA(k|/y!~}EطŎ؁fy:r~WY,ϯ,Vxbm[DW}6&A U+Ymo^:?EjNO+קe>}WK|%r}gN z뜿..=ݻH~g投gvi@ƹ@P@].I] { ! 5P ԍjCP+f(S} C;t@'tA7d`\:Oy] Bn&n[NnJu "x~0\(p)P7iV_| ,~)P˵ JdZ@nz4QoHIJ[C"{ُG7ef9bzQFbh*9~[gxoHF6_50vr0!z|pTvp(9SC )U;*ODYPƇ+?2D=ӼH}^eJUJ*Yt#h(V^"O!JP_ +_ +J _ TdWVDi3/yU< > endobj 2 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 5 0 obj << /Type /Page /Parent 3 0 R /Contents 6 0 R /Resources 4 0 R >> endobj 6 0 obj << /Length 532 /Filter /FlateDecode >> stream xVnA +XJE.c w†|j~'{hW!* -gKrpgx1HD8?|5'I̐1 2?θ(8;Lz0.D$Q1w&[AvaGUlCl-FS#|~T6b`2ڠےZ8tTf\9_uϾՔ۪9)9cLUsQR|kyڲ6Y׀7I9`>ƭ„C5b}#M77r{NtM ]j;p?;]N,\R%%sl1+5JTM/CwlSp*U6!7_m )5ԧ/3~]OM-52[P_Sr !;ǂscv:ɖ }W\Fa_lh`-DB6I&M%׺aCZeI$t> endobj 4 0 obj << /ProcSet [/PDF /Text] /Font <> /ExtGState << >> >> endobj 7 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 45/minus 96/quoteleft 144/dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron /space] >> endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F7 /BaseFont /Times-Roman /Encoding 7 0 R >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F11 /BaseFont /Symbol >> endobj xref 0 10 0000000000 65535 f 0000000021 00000 n 0000000163 00000 n 0000000895 00000 n 0000000978 00000 n 0000000212 00000 n 0000000292 00000 n 0000001070 00000 n 0000001327 00000 n 0000001425 00000 n trailer << /Size 10 /Info 1 0 R /Root 2 0 R >> startxref 1503 %%EOF surveillance/vignettes/monitoringCounts.Rnw0000644000176200001440000031401014615162374021037 0ustar liggesusers%\VignetteIndexEntry{Monitoring count time series in R: Aberration detection in public health surveillance} %\VignetteEngine{knitr::knitr} %% additional dependencies beyond what is required for surveillance anyway: %\VignetteDepends{surveillance, gamlss, MGLM} <>= knitr::opts_chunk$set(fig.path="plots/monitoringCounts-", error = FALSE, warning = FALSE, message = FALSE) knitr::render_sweave() # use Sweave environments knitr::set_header(highlight = '') # no \usepackage{Sweave} (part of jss class) options(xtable.booktabs = TRUE, xtable.comment = FALSE) @ \documentclass[nojss]{jss} \usepackage{amsmath,bm} \usepackage{booktabs} \usepackage{subcaption} % successor of subfig, which supersedes subfigure \providecommand{\subfloat}[2][need a sub-caption]{\subcaptionbox{#1}{#2}} \newcommand{\BetaBin}{\operatorname{BetaBin}} \newcommand{\Var}{\operatorname{Var}} \newcommand{\logit}{\operatorname{logit}} \newcommand{\NB}{\operatorname{NB}} %% almost as usual \author{Ma\"elle Salmon\\Robert Koch Institute \And Dirk Schumacher\\Robert Koch Institute \And Michael H\"ohle\\ Stockholm University,\\Robert Koch Institute } \title{ \vspace{-2.2cm} \fbox{\vbox{\normalfont\footnotesize This vignette corresponds to an article published in the\\ \textit{Journal of Statistical Software} 2016;\textbf{70}(10):1--35. \doi{10.18637/jss.v070.i10}.}}\\[1cm] Monitoring Count Time Series in \proglang{R}: Aberration Detection in Public Health Surveillance} %% for pretty printing and a nice hypersummary also set: \Plainauthor{Ma\"elle Salmon, Dirk Schumacher, Michael H\"ohle} %% comma-separated \Plaintitle{Monitoring Count Time Series in R: Aberration Detection in Public Health Surveillance} % without formatting \Shorttitle{\pkg{surveillance}: Aberration detection in \proglang{R}} %% a short title (if necessary) %% an abstract and keywords \Abstract{ Public health surveillance aims at lessening disease burden by, e.g., timely recognizing emerging outbreaks in case of infectious diseases. Seen from a statistical perspective, this implies the use of appropriate methods for monitoring time series of aggregated case reports. This paper presents the tools for such automatic aberration detection offered by the \textsf{R} package \pkg{surveillance}. We introduce the functionalities for the visualization, modeling and monitoring of surveillance time series. With respect to modeling we focus on univariate time series modeling based on generalized linear models (GLMs), multivariate GLMs, generalized additive models and generalized additive models for location, shape and scale. Applications of such modeling include illustrating implementational improvements and extensions of the well-known Farrington algorithm, e.g., by spline-modeling or by treating it in a Bayesian context. Furthermore, we look at categorical time series and address overdispersion using beta-binomial or Dirichlet-multinomial modeling. With respect to monitoring we consider detectors based on either a Shewhart-like single timepoint comparison between the observed count and the predictive distribution or by likelihood-ratio based cumulative sum methods. Finally, we illustrate how \pkg{surveillance} can support aberration detection in practice by integrating it into the monitoring workflow of a public health institution. Altogether, the present article shows how well \pkg{surveillance} can support automatic aberration detection in a public health surveillance context. } \Keywords{\proglang{R}, \texttt{surveillance}, outbreak detection, statistical process control} \Plainkeywords{R, surveillance, outbreak detection, statistical process control} %% without formatting %% at least one keyword must be supplied \Address{ Ma\"{e}lle Salmon, Dirk Schumacher\\ Department for Infectious Diseases Epidemiology\\ Robert Koch Institut Berlin\\ Seestrasse 10\\ 13353 Berlin, Germany\\ E-mail: \email{maelle.salmon@yahoo.se}, \email{mail@dirk-schumacher.net}\\ URL: \url{https://masalmon.eu/}\\ \phantom{URL: }\url{https://dirk-schumacher.net/}\\ Michael H\"{o}hle\\ Department of Mathematics\\ Stockholm University\\ Kr\"{a}ftriket\\ 106 91 Stockholm, Sweden\\ E-mail: \email{hoehle@math.su.se}\\ URL: \url{https://staff.math.su.se/hoehle/} } \begin{document} \maketitle \section{Introduction} \label{sec:0} Nowadays, the fight against infectious diseases does not only require treating patients and setting up measures for prevention but also demands the timely recognition of emerging outbreaks in order to avoid their expansion. Along these lines, health institutions such as hospitals and public health authorities collect and store information about health events -- typically represented as individual case reports containing clinical information, and subject to specific case definitions. Analysing these data is crucial. It enables situational awareness in general and the timely detection of aberrant counts in particular, empowering the prevention of additional disease cases through early interventions. For any specific aggregation of characteristics of events, such as over-the-counter sales of pain medication, new cases of foot-and-mouth disease among cattle, or adults becoming sick with hepatitis C in Germany, data can be represented as time series of counts with days, weeks, months or years as time units of the aggregation. Abnormally high or low values at a given time point can reveal critical issues such as an outbreak of the disease or a malfunction of data transmission. Thus, identifying aberrations in the collected data is decisive, for human as well as for animal health. In this paper we present the \proglang{R} package \pkg{surveillance} which is available from the Comprehensive \proglang{R} Archive Network (CRAN) at \url{https://CRAN.R-project.org/package=surveillance}. It implements a range of methods for aberration detection in time series of counts and proportions. Statistical algorithms provide an objective and reproducible analysis of the data and allow the automation of time-consuming aspects of the monitoring process. In the recent years, a variety of such tools has flourished in the literature. Reviews of methods for aberration detection in time series of counts can be found in~\citet{Buckeridge2007}~and~\citet{Unkel2012}. However, the great variety of statistical algorithms for aberration detection can be a hurdle to practitioners wishing to find a suitable method for their data. It is our experience that ready-to-use and understandable implementation and the possibility to use the methods in a routine and automatic fashion are the criteria most important to the epidemiologists. The package offers an open-source implementation of state-of-the-art methods for the prospective detection of outbreaks in count data time series with established methods, as well as the visualization of the analysed time series. With the package, the practitioner can introduce statistical surveillance into routine practice without too much difficulty. As far as we know, the package is now used in several public health institutions in Europe: at the National Public Health Institute of Finland, at the Swedish Institute for Communicable Disease Control, at the French National Reference Centre for Salmonella, and at the Robert Koch Institute (RKI) in Berlin. The use of \pkg{surveillance} at the RKI shall be the focus of this paper. The package also provides many other functions serving epidemic modeling purposes. Such susceptible-infectious-recovered based models and their extensions towards regression based approaches are documented in other works~\citep{held-etal-2005,held_etal2006,meyer.etal2011,meyer.etal2014}. The present paper is designed as an extension of two previous articles about the \pkg{surveillance} package published as~\citet{hoehle-2007} and~\citet{hoehle-mazick-2010}. On the one hand, the paper aims at giving an overview of the new features added to the package since the publication of the two former papers. On the other hand it intends to illustrate how well the \pkg{surveillance} package can support routine practical disease surveillance by presenting the current surveillance system of infectious diseases at the RKI. This paper is structured as follows. Section~\ref{sec:1} gives an introduction to the data structure used in the package for representing and visualizing univariate or multivariate time series. Furthermore, the structure and use of aberration detection algorithms are explained. Section~\ref{sec:2} leads the reader through different surveillance methods available in the package. Section~\ref{sec:3} describes the integration of such methods in a complete surveillance system as currently in use at the RKI. Finally, a discussion rounds off the work. \section{Getting to know the basics of the package} <>= ## create directories for plots and cache dir.create("plots", showWarnings=FALSE) dir.create("monitoringCounts-cache", showWarnings=FALSE) ## load packages library('surveillance') library('gamlss') @ \label{sec:1} The package provides a central S4 data class \code{sts} to capture multivariate or univariate time series. All further methods use objects of this class as an input. Therefore we first describe the \code{sts} class and then show the typical usage of a function for aberration detection, including visualization. All monitoring methods of the package conform to the same syntax. \subsection{How to store time series and related information} In \pkg{surveillance}, time series of counts and related information are encoded in a specific S4-class called \code{sts} (\textit{surveillance time series}) that represents possibly multivariate time series of counts. Denote the counts as $\left( y_{it} ; i = 1, \ldots,m, t = 1, \ldots, n \right)$, where $n$ is the length of the time series and $m$ is the number of entities, e.g., geographical regions, hospitals or age groups, being monitored. An example which we shall look at in more details is a time series representing the weekly counts of cases of infection with \textit{Salmonella Newport} in all 16 federal states of Germany from 2004 to 2013 with $n=525$ weeks and $m=16$ geographical units. Infections with \textit{Salmonella Newport}, a subtype of \textit{Salmonella}, can trigger gastroenteritis, prompting the seek of medical care. Infections with \textit{Salmonella} are notifiable in Germany since 2001 with data being forwarded to the RKI by federal states health authorities on behalf of the local health authorities. \subsubsection[Slots of the class sts]{Slots of the class \texttt{sts}} The key slots of the \code{sts} class are those describing the observed counts and the corresponding time periods of the aggregation. The observed counts $\left(y_{it}\right)$ are stored in the $n \times m$ matrix \code{observed}. A number of other slots characterize time. First, \code{epoch} denotes the corresponding time period of the aggregation. If the Boolean \code{epochAsDate} is \code{TRUE}, \code{epoch} is the numeric representation of \code{Date} objects corresponding to each observation in \code{observed}. If the Boolean \code{epochAsDate} is \code{FALSE}, \code{epoch} is the time index $1 \leq t \leq n$ of each of these observations. Then, \code{freq} is the number of observations per year: 365 for daily data, 52 for weekly data and 12 for monthly data. Finally, \code{start} is a vector representing the origin of the time series with two values that are the year and the epoch within that year for the first observation of the time series -- \code{c(2014, 1)} for a weekly time series starting on the first week of 2014 for instance. Other slots enable the storage of additional information. Known aberrations are recorded in the Boolean slot \code{state} of the same dimensions as \code{observed} with \code{TRUE} indicating an outbreak and \code{FALSE} indicating the absence of any known aberration. The monitored population in each of the units is stored in slot \code{populationFrac}, which gives either proportions or numbers. The geography of the zone under surveillance is accessible through slot \code{map} which is an object of class \code{SpatialPolygonsDataFrame}~\citep{sp1,sp2} providing a shape of the $m$ areas which are monitored and slot \code{neighbourhood}, which is a symmetric matrix of Booleans size $m^2$ stating the neighborhood matrix. Slot \code{map} is pertinent when units are geographical units, whereas \code{neighbourhood} could be useful in any case, e.g., for storing a contact matrix between age groups for modeling purposes. Finally, if monitoring has been performed on the data, the information on its control arguments and its results are stored in \code{control}, \code{upperbound} and \code{alarm} presented in Section~\ref{sec:howto}. \subsubsection[Creation of an object of class sts]{Creation of an object of class \texttt{sts}} The creation of an \code{sts} object is straightforward, requiring a call of the constructor function \code{sts} together with the slots to be assigned as arguments. The input of data from external files is one possibility for getting the counts as it is described in \citet{hoehle-mazick-2010}. To exemplify the process we shall use weekly counts of \textit{Salmonella Newport} in Germany loaded using \code{data("salmNewport")}. Alternatively, one can use coercion methods to convert between the \texttt{ts} class and the \texttt{sts} class. Note that this only converts the content of the slot \texttt{observed}, that is, <>= data("salmNewport") @ <>= all.equal(observed(salmNewport), observed(as(as(salmNewport, "ts"), "sts"))) @ <>= stopifnot( <> ) @ Using the \texttt{ts} class as intermediate step also allows the conversion between other time series classes, e.g., from packages \pkg{zoo}~\citep{zoo} or \pkg{xts}~\citep{xts}. <>= # This code is the one used for the Salmon et al. (2016) JSS article. # Using this code all examples from the article can be reproduced. # computeALL is FALSE to avoid the computationally intensive parts # of the code (simulations to find a threshold value for categoricalCUSUM, # INLA-driven BODA) but one can set it to TRUE to have it run. computeALL <- FALSE @ <>= # Define plot parameters cex.text <- 1.7 line.lwd <- 2 plotOpts <- local({ #Add lines using grid by a hook function. Use NULL to align with tick marks hookFunc <- function() { grid(NA,NULL,lwd=1) } cex.axis <- cex.text cex.main <- cex.text cex.lab <- cex.text cex.leg <- cex.text stsPlotCol <- c("mediumblue","mediumblue","red2") alarm.symbol <- list(pch=17, col="red2", cex=2,lwd=3) #Define list with arguments to use with do.call("legend", legOpts) legOpts <- list(x="topleft",legend=c(expression(U[t])),bty="n",lty=1,lwd=line.lwd,col=alarm.symbol$col,horiz=TRUE,cex=cex.leg) #How should the par of each plot look? par.list <- list(mar=c(6,5,5,5),family="Times") #Do this once y.max <- 0 list(col=stsPlotCol,ylim=c(0,y.max), main='',lwd=c(1,line.lwd,line.lwd), dx.upperbound=0, #otherwise the upperbound line is put 0.5 off cex.lab=cex.lab, cex.axis=cex.axis, cex.main=cex.main, ylab="No. of reports", xlab="Time (weeks)",lty=c(1,1,1), legend.opts=legOpts,alarm.symbol=alarm.symbol, xaxis.tickFreq=list("%V"=atChange,"%m"=atChange,"%G"=atChange), xaxis.labelFreq=list("%Y"=atMedian), xaxis.labelFormat="%Y", par.list=par.list,hookFunc=hookFunc) }) @ \begin{figure} \centering <>= y.max <- max(aggregate(salmNewport,by="unit")@observed,na.rm=TRUE) plotOpts2 <- modifyList(plotOpts,list(x=salmNewport,legend.opts=NULL,ylim=c(0,y.max),type = observed ~ time),keep.null=TRUE) plotOpts2$par.list <- list(mar=c(6,5,0,5),family="Times") plotOpts2$xaxis.tickFreq <- list("%m"=atChange,"%G"=atChange) do.call("plot",plotOpts2) @ \caption{Weekly number of cases of S. Newport in Germany, 2004-2013.} \label{fig:Newport} \end{figure} \subsubsection[Basic manipulation of objects of the class sts]{Basic manipulation of objects of the class \texttt{sts}} This time series above is represented as a multivariate \code{sts} object whose dimensions correspond to the 16 German federal states. Values are weekly counts so \code{freq = 52}. Weeks are indexed by \code{Date} here (\code{epochAsDate = TRUE}). One can thus for instance get the weekday of the date by calling \code{weekdays(epoch(salmNewport))} (all Mondays here). Furthermore, one can use the function \code{format} (and the package specific platform independent version \code{dateFormat}) to obtain \code{strftime} compatible formatting of the epochs. Another advantage of using \code{Date} objects is that the plot functions have been re-written for better management of ticks and labelling of the x-axis based on \code{strftime} compatible conversion specifications. For example, to get ticks at all weeks corresponding to the first week in a month as well as all weeks corresponding to the first in a year while placing labels consisting of the year at the median index per year (Figure~\ref{fig:Newport}): <>= plot(salmNewport, type = observed ~ time, xaxis.tickFreq = list("%m" = atChange, "%G" = atChange), xaxis.labelFreq = list("%Y" = atMedian), xaxis.labelFormat = "%Y") @ The helper functions \code{atChange} and \code{atMedian} are documented in \code{help("addFormattedXAxis")}. % and the respective tick lengths are controlled by the \pkg{surveillance}-specific % option \code{surveillance.options("stsTickFactors")}. Actually \code{sts} objects can be plotted using different options: \code{type = observed ~ time} produces the time series for whole Germany as shown in Figure~\ref{fig:Newport}, whereas \code{type = observed ~ time | unit} (the default) is a panelled graph with each panel representing the time series of counts of a federal state as seen in Figure~\ref{fig:unit}. \begin{figure} \subfloat[]{ <>= y.max <- max(observed(salmNewport[,2]),observed(salmNewport[,3]),na.rm=TRUE) plotOpts2 <- modifyList(plotOpts,list(x=salmNewport[,2],legend.opts=NULL,ylim=c(0,y.max)),keep.null=TRUE) plotOpts2$xaxis.tickFreq <- list("%G"=atChange) do.call("plot",plotOpts2) @ } \subfloat[]{ <>= plotOpts2 <- modifyList(plotOpts,list(x=salmNewport[,3],legend.opts=NULL,ylim=c(0,y.max)),keep.null=TRUE) plotOpts2$xaxis.tickFreq <- list("%G"=atChange) do.call("plot",plotOpts2) @ } \caption{Weekly count of S. Newport in the German federal states (a) Bavaria and (b) Berlin.} \label{fig:unit} \end{figure} <>= plot(salmNewport, units = 2:3) @ Once created one can use typical subset operations on a \code{sts} object: for instance \code{salmNewport[} \code{1:10, "Berlin"]} is a new \code{sts} object with weekly counts for Berlin during the 10 first weeks of the initial dataset; \code{salmNewport[isoWeekYear(epoch(salmNewport))\$ISOYear<=2010,]} uses the \code{surveillance}'s \code{isoWeekYear()} function to get a \code{sts} object with weekly counts for all federal states up to 2010. Moreover, one can take advantage of the \proglang{R} function \code{aggregate()}. For instance, \code{aggregate(salmNewport,by="unit")} returns a \code{sts} object representing weekly counts of \textit{Salmonella Newport} in Germany as a whole, whereas \code{aggregate(salmNewport, by = "time")} corresponds to the total count of cases in each federal state over the whole period. \subsection{How to use aberration detection algorithms} \label{sec:howto} Monitoring algorithms of the package operate on objects of the class \code{sts} as described below. \subsubsection{Statistical framework for aberration detection} We introduce the framework for aberration detection on an univariate time series of counts $\left\{y_t,\> t=1,2,\ldots\right\}$. Surveillance aims at detecting an \textit{aberration}, that is to say, an important change in the process occurring at an unknown time $\tau$. This change can be a step increase of the counts of cases or a more gradual change~\citep{Sonesson2003}. Based on the possibility of such a change, for each time $t$ we want to differentiate between the two states \textit{in-control} and \textit{out-of-control}. At any timepoint $t_0\geq 1$, the available information -- i.e., past counts -- is defined as $\bm{y}_{t_0} = \left\{ y_t\>;\> t\leq t_0\right\}$. Detection is based on a statistic $r(\cdot)$ with resulting alarm time $T_A = \min\left\{ t_0\geq 1 : r(\bm{y}_{t_0}) > g\right\}$ where $g$ is a known threshold. Functions for aberration detection thus use past data to estimate $r(\bm{y}_{t_0})$, and compare it to the threshold $g$ above which the current count can be considered suspicious and thus \textit{out-of-control}. Threshold values and alarm Booleans for each timepoint of the monitored range are saved in the slots \code{upperbound} and \code{alarm} (of the same dimensions as \code{observed}), respectively, while the parameters of the algorithm %used for computing the threshold values and alarm Booleans are stored in the slot \code{control}. \subsubsection{Aberration detection in the package} To perform such a monitoring of the counts of cases, one has to choose one of the surveillance algorithms of the package -- this choice will be the topic of Section~\ref{sec:using}. Then, one must indicate which part of the time series or \code{range} has to be monitored -- for instance the current year. Lastly, one needs to specify the parameters specific to the algorithm. \subsubsection{Example with the EARS C1 method} We will illustrate the basic principle by using the \code{earsC}~function~that implements the EARS (Early Aberration Detection System) methods of the CDC as described in~\citet{SIM:SIM3197}. This algorithm is especially convenient in situations when little historic information is available. It offers three variants called C1, C2 and C3. Here we shall expand on C1 for which the baseline are the 7 timepoints before the assessed timepoint $t_0$, that is to say $\left(y_{t_0-7},\ldots,y_{t_0-1}\right)$. The expected value is the mean of the baseline. The method is based on a statistic called $C_{t_0}$ defined as $C_{t_0}= \frac{(y_{t_0}-\bar{y}_{t_0})}{s_{t_0}}$, where $$\bar{y}_{t_0}= \frac{1}{7} \cdot\sum_{i=t_0-7}^{t_0-1} y_i \textnormal{ and } s_{t_0}^2= \frac{1}{7-1} \cdot\sum_{i=t_0-7}^{t_0-1} \left(y_i - \bar{y}_{t_0}\right)^2 \,.$$ Under the null hypothesis of no outbreak, it is assumed that $C_{t_0} \stackrel{H_0}{\sim} {N}(0,1)$. The upperbound $U_{t_0}$ is found by assuming that $y_t$ is normal, estimating parameters by plug-in and then taking the $(1-\alpha)$-th quantile of this distribution, i.e. $U_{t_0}= \bar{y}_{t_0} + z_{1-\alpha}s_{t_0}$, where $z_{1-\alpha}$ is the $(1-\alpha)$-quantile of the standard normal distribution. An alarm is raised if $y_{t_0} > U_{t_0}$. The output of the algorithm is a \code{sts} object that contains subsets of slots \code{observed}, \code{population} and \code{state} defined by the range of timepoints specified in the input -- \textit{e.g} the last 20 timepoints of the time series, and with the slots \code{upperbound} and \code{alarm} filled by the output of the algorithm. Information relative to the \code{range} of data to be monitored and to the parameters of the algorithm, such as \code{alpha} for \code{earsC}, has to be formulated in the slot \code{control}. This information is also stored in the slot \code{control} of the returned \code{sts} object for later inspection. <>= in2011 <- which(isoWeekYear(epoch(salmNewport))$ISOYear == 2011) salmNewportGermany <- aggregate(salmNewport, by = "unit") control <- list(range = in2011, method = "C1", alpha = 0.05) surv <- earsC(salmNewportGermany, control = control) plot(surv) @ \begin{figure} \centering <>= y.max <- max(observed(surv),upperbound(surv),na.rm=TRUE) do.call("plot",modifyList(plotOpts,list(x=surv,ylim=c(0,y.max)),keep.null=TRUE)) @ \caption{Weekly reports of S. Newport in Germany in 2011 monitored by the EARS C1 method. The line represents the upperbound calculated by the algorithm. Triangles indicate alarms that are the timepoints where the observed number of counts is higher than the upperbound.} \label{fig:NewportEARS} \end{figure} The \code{sts} object is easily visualized using the function \code{plot} as depicted in Figure~\ref{fig:NewportEARS}, which shows the upperbound as a solid line and the alarms -- timepoints where the upperbound has been exceeded -- as triangles. The four last alarms correspond to a known outbreak in 2011 due to sprouts~\citep{Newport2011}. One sees that the upperbound right after the outbreak is affected by the outbreak: it is very high, so that a smaller outbreak would not be detected. The EARS methods C1, C2 and C3 are simple in that they only use information from the very recent past. This is appropriate when data has only been collected for a short time or when one expects the count to be fairly constant. However, data from the less recent past often encompass relevant information about e.g., seasonality and time trend, that one should take into account when estimating the expected count and the associated threshold. For instance, ignoring an increasing time trend could decrease sensitivity. Inversely, overlooking an annual surge in counts during the summer could decrease specificity. Therefore, it is advisable to use detection methods whose underlying models incorporate essential characteristics of time series of disease count data such as overdispersion, seasonality, time trend and presence of past outbreaks in the records~\citep{Unkel2012,Shmueli2010}. Moreover, the EARS methods do not compute a proper prediction interval for the current count. Sounder statistical methods will be reviewed in the next section. \section[Using surveillance in selected contexts]{Using \pkg{surveillance} in selected contexts} \label{sec:using} \label{sec:2} More than a dozen algorithms for aberration detection are implemented in the package. Among those, this section presents a set of representative algorithms, which are already in routine application at several public health institutions or which we think have the potential to become so. First we describe the Farrington method introduced by~\citet{farrington96} together with the improvements proposed by~\citet{Noufaily2012}. As a Bayesian counterpart to these methods we present the BODA method published by~\citet{Manitz2013} which allows the easy integration of covariates. All these methods perform one-timepoint detection in that they detect aberrations only when the count at the currently monitored timepoint is above the threshold. Hence, no accumulation of evidence takes place. As an extension, we introduce an implementation of the negative binomial cumulative sum (CUSUM) of~\citet{hoehle.paul2008} that allows the detection of sustained shifts by accumulating evidence over several timepoints. Finally, we present a method suitable for categorical data described in~\citet{hoehle2010} that is also based on cumulative sums. \subsection{One size fits them all for count data} Two implementations of the Farrington method, which is currently \textit{the} method of choice at European public health institutes \citep{hulth_etal2010}, exist in the package. First, the original method as described in \citet{farrington96} is implemented as the function \code{farrington}. Its use was already described in \citet{hoehle-mazick-2010}. Now, the newly implemented function \code{farringtonFlexible} supports the use of this \textit{original method} as well as of the \textit{improved method} built on suggestions made by~\citet{Noufaily2012} for improving the specificity without reducing the sensitivity. In the function \code{farringtonFlexible} one can choose to use the original method or the improved method by specification of appropriate \code{control} arguments. Which variant of the algorithm is to be used is determined by the contents of the \code{control} slot. In the example below, \code{con.farrington} corresponds to the use of the original method and \code{con.noufaily} indicates the options for the improved method. <>= con.farrington <- list( range = in2011, noPeriods = 1, b = 4, w = 3, weightsThreshold = 1, pastWeeksNotIncluded = 3, pThresholdTrend = 0.05, thresholdMethod = "delta" ) con.noufaily <- list( range = in2011, noPeriods = 10, b = 4, w = 3, weightsThreshold = 2.58, pastWeeksNotIncluded = 26, pThresholdTrend = 1, thresholdMethod = "nbPlugin" ) @ <>= con.farrington$limit54 <- con.noufaily$limit54 <- c(0,50) # for the figure @ In both cases the steps of the algorithm are the same. In a first step, an overdispersed Poisson generalized linear model with log link is fitted to the reference data $\bm{y}_{t_0} \subseteq \left\{ y_t\>;\> t\leq t_0\right\}$, where $\E(y_t)=\mu_t$ with $\log \mu_t = \alpha + \beta t$ and $\Var(y_t)=\phi\cdot\mu_t$ and where $\phi\geq1$ is ensured. The original method took seasonality into account by using a subset of the available data as reference data for fitting the GLM: \code{w} timepoints centred around the timepoint located $1,2,\ldots,b$ years before $t_0$, amounting to a total $b \cdot (2w+1)$ reference values. However, it was shown in~\citet{Noufaily2012} that the algorithm performs better when using more historical data. In order to do do so without disregarding seasonality, the authors introduced a zero order spline with 11 knots, which can be conveniently represented as a 10-level factor. We have extended this idea in our implementation so that one can choose an arbitrary number of periods in each year. Thus, $\log \mu_t = \alpha + \beta t +\gamma_{c(t)}$ where $\gamma_{c(t)}$ are the coefficients of a zero order spline with $\mathtt{noPeriods}+1$ knots, which can be conveniently represented as a $\mathtt{noPeriods}$-level factor that reflects seasonality. Here, $c(t)$ is a function indicating in which season or period of the year $t$ belongs to. The algorithm uses \code{w}, \code{b} and \texttt{noPeriods} to deduce the length of periods so they have the same length up to rounding. An exception is the reference window centred around $t_0$. Figure~\ref{fig:fPlot} shows a minimal example, where each character corresponds to a different period. Note that setting $\mathtt{noPeriods} = 1$ corresponds to using the original method with only a subset of the data: there is only one period defined per year, the reference window around $t_0$ and other timepoints are not included in the model. \begin{figure} \subfloat[$\texttt{noPeriods}=2$]{ \includegraphics[width=0.45\textwidth]{monitoringCounts-cache/fPlot1.pdf} } \qquad \subfloat[$\texttt{noPeriods}=3$]{ \includegraphics[width=0.45\textwidth]{monitoringCounts-cache/fPlot2.pdf} } \caption{Construction of the noPeriods-level factor to account for seasonality, depending on the value of the half-window size $w$ and of the freq of the data. Here the number of years to go back in the past $b$ is 2. Each level of the factor variable corresponds to a period delimited by ticks and is denoted by a character. The windows around $t_0$ are respectively of size $2w+1$,~$2w+1$ and $w+1$. The segments between them are divided into the other periods so that they have the same length up to rounding.} \label{fig:fPlot} \end{figure} Moreover, it was shown in \citet{Noufaily2012} that it is better to exclude the last 26 weeks before $t_0$ from the baseline in order to avoid reducing sensitivity when an outbreak has started recently before $t_0$. In the \code{farringtonFlexible} function, one controls this by specifying \code{pastWeeksNotIncluded}, which is the number of last timepoints before $t_0$ that are not to be used. The (historical) default is to use \code{pastWeeksNotIncluded = w}. Lastly, in the new implementation a population offset can be included in the GLM by setting \code{populationBool} to \code{TRUE} and supplying the possibly time-varying population size in the \code{population} slot of the \code{sts} object, but this will not be discussed further here. In a second step, the expected number of counts $\mu_{t_0}$ is predicted for the current timepoint $t_0$ using this GLM. An upperbound $U_{t_0}$ is calculated based on this predicted value and its variance. The two versions of the algorithm make different assumptions for this calculation. The original method assumes that a transformation of the prediction error $g\left(y_{t_0}-\hat{\mu}_{t_0}\right)$ is normally distributed, for instance when using the identity transformation $g(x)=x$ one obtains $$y_{t_0} - \hat{\mu}_0 \sim \mathcal{N}(0,\Var(y_{t_0}-\hat{\mu}_0)) \,.$$ The upperbound of the prediction interval is then calculated based on this distribution. First we have that $$ \Var(y_{t_0}-\hat{\mu}_{t_0}) = \Var(\hat{y}_{t_0}) + \Var(\hat{\mu}_{t_0})=\phi\mu_0+\Var(\hat{\mu}_{t_0}) $$ with $\Var(\hat{y}_{t_0})$ being the variance of an observation and $\Var(\hat{\mu}_{t_0})$ being the variance of the estimate. The threshold, defined as the upperbound of a one-sided $(1-\alpha)\cdot 100\%$ prediction interval, is then $$U_{t_0} = \hat{\mu}_0 + z_{1-\alpha}\sqrt{\widehat{\Var}(y_{t_0}-\hat{\mu}_{t_0})} \,.$$ This method can be used by setting the control option \code{thresholdMethod} equal to "\code{delta}". However, a weakness of this procedure is the normality assumption itself, so that an alternative was presented in \citet{Noufaily2012} and implemented as \code{thresholdMethod="Noufaily"}. The central assumption of this approach is that $y_{t_0} \sim \NB\left(\mu_{t_0},\nu\right)$, with $\mu_{t_0}$ the mean of the distribution and $\nu=\frac{\mu_{t_0}}{\phi-1}$ its overdispersion parameter. In this parameterization, we still have $\E(y_t)=\mu_t$ and $\Var(y_t)=\phi\cdot\mu_t$ with $\phi>1$ -- otherwise a Poisson distribution is assumed for the observed count. The threshold is defined as a quantile of the negative binomial distribution with plug-in estimates $\hat{\mu}_{t_0}$ and $\hat{\phi}$. Note that this disregards the estimation uncertainty in $\hat{\mu}_{t_0}$ and $\hat{\phi}$. As a consequence, the method "\code{muan}" (\textit{mu} for $\mu$ and \textit{an} for asymptotic normal) tries to solve the problem by using the asymptotic normal distribution of $(\hat{\alpha},\hat{\beta})$ to derive the upper $(1-\alpha)\cdot 100\%$ quantile of the asymptotic normal distribution of $\hat{\mu}_{t_0}=\hat{\alpha}+\hat{\beta}t_0$. Note that this does not reflect all estimation uncertainty because it disregards the estimation uncertainty of $\hat{\phi}$. Note also that for time series where the variance of the estimator is large, the upperbound also ends up being very large. Thus, the method "\code{nbPlugin}" seems to provide information that is easier to interpret by epidemiologists but with "\code{muan}" being more statistically correct. In a last step, the observed count $y_{t_0}$ is compared to the upperbound $U_{t_0}$ and an alarm is raised if $y_{t_0} > U_{t_0}$. In both cases the fitting of the GLM involves three important steps. First, the algorithm performs an optional power-transformation for skewness correction and variance stabilisation, depending on the value of the parameter \code{powertrans} in the \code{control} slot. Then, the significance of the time trend is checked. The time trend is included only when significant at a chosen level \code{pThresholdTrend}, when there are more than three years reference data and if no overextrapolation occurs because of the time trend. Lastly, past outbreaks are reweighted based on their Anscombe residuals. In \code{farringtonFlexible} the limit for reweighting past counts, \code{weightsThreshold}, can be specified by the user. If the Anscombe residual of a count is higher than \code{weightsThreshold} it is reweighted accordingly in a second fitting of the GLM. \citet{farrington96} used a value of $1$ whereas \citet{Noufaily2012} advise a value of $2.56$ so that the reweighting procedure is less drastic, because it also shrinks the variance of the observations. The original method is widely used in public health surveillance~\citep{hulth_etal2010}. The reason for its success is primarily that it does not need to be fine-tuned for each specific pathogen. It is hence easy to implement it for scanning data for many different pathogens. Furthermore, it does tackle classical issues of surveillance data: overdispersion, presence of past outbreaks that are reweighted, seasonality that is taken into account differently in the two methods. An example of use of the function is shown in Figure~\ref{fig:newportFar} with the code below. <<>>= salm.farrington <- farringtonFlexible(salmNewportGermany, con.farrington) salm.noufaily <- farringtonFlexible(salmNewportGermany, con.noufaily) @ <>= par(mfrow = c(1,2)) plot(salm.farrington) plot(salm.noufaily) @ \begin{figure} \subfloat[]{ <>= y.max <- max(observed(salm.farrington),upperbound(salm.farrington),observed(salm.noufaily),upperbound(salm.noufaily),na.rm=TRUE) do.call("plot",modifyList(plotOpts,list(x=salm.farrington,ylim=c(0,y.max)))) @ } \subfloat[]{ <>= do.call("plot",modifyList(plotOpts,list(x=salm.noufaily,ylim=c(0,y.max)))) @ } \caption{S. Newport in Germany in 2011 monitored by (a) the original method and (b) the improved method. For the figure we turned off the option that the threshold is only computed if there were more than 5 cases during the 4 last timepoints including $t_0$. One gets less alarms with the most recent method and still does not miss the outbreak in the summer. Simulations on more time series support the use of the improved method instead of the original method.} \label{fig:newportFar} \end{figure} % With our implementation of the improvements presented in \citet{Noufaily2012} we hope that the method with time can replace the original method in routine use. The RKI system described in Section~\ref{sec:RKI} already uses this improved method. \subsubsection{Similar methods in the package} The package also contains further methods based on a subset of the historical data: \code{bayes}, \code{rki} and \code{cdc}. See Table~\ref{table:ref} for the corresponding references. Here, \code{bayes} uses a simple conjugate prior-posterior approach and computes the parameters of a negative binomial distribution based on past values. The procedure \code{rki} makes either the assumption of a normal or a Poisson distribution based on the mean of past counts. Finally, \code{cdc} aggregates weekly data into 4-week-counts and computes a normal distribution based upper confidence interval. None of these methods offer the inclusion of a linear trend, down-weighting of past outbreaks or power transformation of the data. Although these methods are nice to have at hand, we recommend using the improved method implemented in the function \code{farringtonFlexible} because it is rather fast and makes use of more historical data than the other methods. \subsection{A Bayesian refinement} The \code{farringtonFlexible} function described previously was a first indication that the \textit{monitoring} of surveillance time series requires a good \textit{modeling} of the time series before assessing aberrations. Generalized linear models (GLMs) and generalized additive models (GAMs) are well-established and powerful modeling frameworks for handling the count data nature and trends of time series in a regression context. The \code{boda} procedure~\citep{Manitz2013} continues this line of thinking by extending the simple GLMs used in the \code{farrington} and \code{farringtonFlexible} procedures to a fully fledged Bayesian GAM allowing for penalized splines, e.g., to describe trends and seasonality, while simultaneously adjusting for previous outbreaks or concurrent processes influencing the case counts. A particular advantage of the Bayesian approach is that it constitutes a seamless framework for performing both estimation and subsequent prediction: the uncertainty in parameter estimation is directly carried forward to the predictive posterior distribution. No asymptotic normal approximations nor plug-in inference is needed. For fast approximate Bayesian inference we use the \pkg{INLA} \proglang{R} package~\citep{INLA} to fit the Bayesian GAM. Still, monitoring with \code{boda} is substantially slower than using the Farrington procedures. Furthermore, detailed regression modeling is only meaningful if the time series is known to be subject to external influences on which information is available. Hence, the typical use at a public health institution would be the detailed analysis of a few selected time series, e.g., critical ones or those with known trend character. As an example, \citet{Manitz2013} studied the influence of absolute humidity on the occurrence of weekly reported campylobacter cases in Germany. \begin{figure} \centering <>= # Load data and create \code{sts}-object data("campyDE") cam.sts <- sts(epoch=campyDE$date, observed=campyDE$case, state=campyDE$state) par(las=1) # Plot y.max <- max(observed(cam.sts),upperbound(cam.sts),na.rm=TRUE) plotOpts3 <- modifyList(plotOpts,list(x=cam.sts,ylab="",legend.opts=NULL,ylim=c(0,y.max),type = observed ~ time),keep.null=TRUE) plotOpts3$xaxis.tickFreq <- list("%m"=atChange,"%G"=atChange) do.call("plot",plotOpts3) par(las=0) #mtext(side=2,text="No. of reports", # las=0,line=3, cex=cex.text,family="Times") par(family="Times") text(-20, 2600, "No. of\n reports", pos = 3, xpd = T,cex=cex.text) text(510, 2900, "Absolute humidity", pos = 3, xpd = T,cex=cex.text) text(510, 2550, expression(paste("[",g/m^3,"]", sep='')), pos = 3, xpd = T,cex=cex.text) lines(campyDE$hum*50, col="white", lwd=2) axis(side=4, at=seq(0,2500,by=500),labels=seq(0,50,by=10),las=1,cex.lab=cex.text, cex=cex.text,cex.axis=cex.text,pos=length(epoch(cam.sts))+20) #mtext(side=4,text=expression(paste("Absolute humidity [ ",g/m^3,"]", sep='')), # las=0,line=1, cex=cex.text,family="Times") @ \caption{Weekly number of reported campylobacteriosis cases in Germany 2002-2011 as vertical bars. In addition, the corresponding mean absolute humidity time series is shown as a white curve.} \label{fig:campyDE} \end{figure} <>= data("campyDE") cam.sts <- sts(epoch = campyDE$date, observed = campyDE$case, state = campyDE$state) plot(cam.sts, col = "mediumblue") lines(campyDE$hum * 50, col = "white", lwd = 2) axis(4, at = seq(0, 2500, by = 500), labels = seq(0, 50, by = 10)) @ The corresponding plot of the weekly time series is shown in Figure~\ref{fig:campyDE}. We observe a strong association between humidity and case numbers - an association which is stronger than with, e.g., temperature or relative humidity. As noted in \citet{Manitz2013} the excess in cases in 2007 is thus partly explained by the high atmospheric humidity. Furthermore, an increase in case numbers during the 2011 STEC O104:H4 outbreak is observed, which is explained by increased awareness and testing of many gastroenteritits pathogens during that period. The hypothesis is thus that there is no actual increased disease activity~\citep{bernard_etal2014}. Unfortunately, the German reporting system only records positive test results without keeping track of the number of actual tests performed -- otherwise this would have been a natural adjustment variable. Altogether, the series contains several artefacts which appear prudent to address when monitoring the campylobacteriosis series. The GAM in \code{boda} is based on the negative binomial distribution with time-varying expectation and time constant overdispersion parameter, i.e., \begin{align*} y_t &\sim \operatorname{NB}(\mu_t,\nu) \end{align*} with $\mu_{t}$ the mean of the distribution and $\nu$ the dispersion parameter~\citep{lawless1987}. Hence, we have $\E(y_t)=\mu_t$ and $\Var(y_t)=\mu_t\cdot(1+\mu_t/\nu)$. The linear predictor is given by \begin{align*} \log(\mu_t) &= \alpha_{0t} + \beta t + \gamma_t + \bm{x}_t^\top \bm{\delta} + \xi z_t, \quad t=1,\ldots,t_0. \end{align*} Here, the time-varying intercept $\alpha_{0t}$ is described by a penalized spline (e.g., first or second order random walk) and $\gamma_t$ denotes a periodic penalized spline (as implemented in \code{INLA}) with period equal to the periodicity of the data. Furthermore, $\beta$ characterizes the effect of a possible linear trend (on the log-scale) and $\xi$ is the effect of previous outbreaks. Typically, $z_t$ is a zero-one process denoting if there was an outbreak in week $t$, but more involved adaptive and non-binary forms are imaginable. Finally, $\bm{x}_t$ denotes a vector of possibly time-varying covariates, which influence the expected number of cases. Data from timepoints $1,\ldots,t_0-1$ are now used to determine the posterior distribution of all model parameters and subsequently the posterior predictive distribution of $y_{t_0}$ is computed. If the actual observed value of $y_{t_0}$ is above the $(1-\alpha)\cdot 100\%$ quantile of the predictive posterior distribution an alarm is flagged for $t_0$. Below we illustrate the use of \code{boda} to monitor the campylobacteriosis time series from 2007. In the first case we include in the model for $\log\left(\mu_t\right)$ penalized splines for trend and seasonality and a simple linear trend. <>= library("INLA") rangeBoda <- which(epoch(cam.sts) >= as.Date("2007-01-01")) control.boda <- list(range = rangeBoda, X = NULL, trend = TRUE, season = TRUE, prior = "iid", alpha = 0.025, mc.munu = 10000, mc.y = 1000, samplingMethod = "marginals") boda <- boda(cam.sts, control = control.boda) @ <>= if (computeALL) { ##hoehle 2018-07-18: changed code to use NICELOOKINGboda, but that's iid. Reason: ##The option 'rw1' currently crashes INLA. <> save(list = c("boda", "control.boda", "rangeBoda"), file = "monitoringCounts-cache/boda.RData") } else { load("monitoringCounts-cache/boda.RData") } @ In the second case we instead use only penalized and linear trend components, and, furthermore, include as covariates lags 1--4 of the absolute humidity as well as zero-one indicators for $t_0$ belonging to the last two weeks (\code{christmas}) or first two weeks (\code{newyears}) of the year, respectively. These covariates shall account for systematically changed reporting behavior at the turn of the year (c.f.\ Figure~\ref{fig:campyDE}). Finally, \code{O104period} is an indicator variable on whether the reporting week belongs to the W21--W30 2011 period of increased awareness during the O104:H4 STEC outbreak. No additional correction for past outbreaks is made. <>= covarNames <- c("l1.hum", "l2.hum", "l3.hum", "l4.hum", "newyears", "christmas", "O104period") control.boda2 <- modifyList(control.boda, list(X = campyDE[, covarNames], season = FALSE)) boda.covars <- boda(cam.sts, control = control.boda2) @ <>= if (computeALL) { <> save(list = c("boda.covars", "covarNames", "control.boda2"), file = "monitoringCounts-cache/boda.covars.RData") } else { load("monitoringCounts-cache/boda.covars.RData") } @ We plot \code{boda.covars} in Figure~\ref{fig:b} and compare the alarms of the two \code{boda} calls with \code{farrington}, \code{farringtonFlexible} and \code{bayes} in Figure~\ref{fig:alarmplot} (plot \code{type = alarm ~ time}). \fbox{\vbox{ Note (2018-07-19): We currently have to use the argument \code{prior = "iid"} in both calls of the \code{boda} function, because the procedure crashes when using recent versions of \pkg{INLA} (\code{>= 17.06.20}) with argument \code{prior = "rw1"}. %(the original results were produced using version 0.0-1458166556, %and version 0.0-1485844051 from 2017-01-31 also works) This means results in this vignette deviate from the results reported in the JSS paper -- in particular we do not get any alarms when using the \code{boda} procedure with covariates. We are looking into the problem. }} Note here that the \code{bayes} procedure is not really useful as the adjustment for seasonality only works poorly. Moreover, we think that this method produces many false alarms for this time series because it disregards the increasing time trend in number of reported cases. Furthermore, it becomes clear that the improved Farrington procedure acts similar to the original procedure, but the improved reweighting and trend inclusion produces fewer alarms. The \code{boda} method is to be seen as a step towards more Bayesian thinking in aberration detection. However, besides its time demands for a detailed modeling, the speed of the procedure is also prohibitive as regards routine application. As a response~\citet{Maelle} introduce a method which has two advantages: it allows to adjust outbreak detection for reporting delays and includes an approximate inference method much faster than the INLA inference method. However, its linear predictor is more in the style of~\citet{Noufaily2012} not allowing for additional covariates or penalized options for the intercept. \begin{figure} \centering <>= y.max <- max(observed(boda.covars),upperbound(boda.covars),na.rm=TRUE) plotOpts2 <- modifyList(plotOpts,list(x=boda.covars,ylim=c(0,y.max)),keep.null=TRUE) plotOpts2$xaxis.tickFreq <- list("%m"=atChange,"%G"=atChange) do.call("plot",plotOpts2) @ <>= plot(boda.covars) @ \caption{Weekly reports of Campylobacter in Germany in 2007-2011 monitored by the boda method with covariates. The line represents the upperbound calculated by the algorithm. Triangles indicate alarms, \textit{i.e.}, timepoints where the observed number of counts is higher than the upperbound.} \label{fig:b} \end{figure} <>= control.far <- list(range=rangeBoda,b=4,w=5,alpha=0.025*2) far <- farrington(cam.sts,control=control.far) #Both farringtonFlexible and algo.bayes uses a one-sided interval just as boda. control.far2 <-modifyList(control.far,list(alpha=0.025)) farflex <- farringtonFlexible(cam.sts,control=control.far2) bayes <- suppressWarnings(bayes(cam.sts,control=control.far2)) @ <>= # Small helper function to combine several equally long univariate sts objects combineSTS <- function(stsList) { epoch <- as.numeric(epoch(stsList[[1]])) observed <- NULL alarm <- NULL for (i in 1:length(stsList)) { observed <- cbind(observed,observed(stsList[[i]])) alarm <- cbind(alarm,alarms(stsList[[i]])) } colnames(observed) <- colnames(alarm) <- names(stsList) res <- sts(epoch=as.numeric(epoch), epochAsDate=TRUE, observed=observed, alarm=alarm) return(res) } @ \begin{figure} \centering <>= # Make an artificial object containing two columns - one with the boda output # and one with the farrington output cam.surv <- combineSTS(list(boda.covars=boda.covars,boda=boda,bayes=bayes, farrington=far,farringtonFlexible=farflex)) par(mar=c(4,8,2.1,2),family="Times") plot(cam.surv,type = alarm ~ time,lvl=rep(1,ncol(cam.surv)), alarm.symbol=list(pch=17, col="red2", cex=1,lwd=3), cex.axis=1,xlab="Time (weeks)",cex.lab=1,xaxis.tickFreq=list("%m"=atChange,"%G"=atChange),xaxis.labelFreq=list("%G"=at2ndChange), xaxis.labelFormat="%G") @ \caption{Alarmplot showing the alarms for the campylobacteriosis time series for four different algorithms.} \label{fig:alarmplot} \end{figure} \subsection{Beyond one-timepoint detection} GLMs as used in the Farrington method are suitable for the purpose of aberration detection since they allow a regression approach for adjusting counts for known phenomena such as trend or seasonality in surveillance data. Nevertheless, the Farrington method only performs one-timepoint detection. In some contexts it can be more relevant to detect sustained shifts early, e.g., an outbreak could be characterized at first by counts slightly higher than usual in subsequent weeks without each weekly count being flagged by one-timepoint detection methods. Control charts inspired by statistical process control (SPC) e.g., cumulative sums would allow the detection of sustained shifts. Yet they were not tailored to the specific characteristics of surveillance data such as overdispersion or seasonality. The method presented in \citet{hoehle.paul2008} conducts a synthesis of both worlds, i.e., traditional surveillance methods and SPC. The method is implemented in the package as the function \code{glrnb}, whose use is explained here. \subsubsection{Definition of the control chart} For the control chart, two distributions are defined, one for each of the two states \textit{in-control} and \textit{out-of-control}, whose likelihoods are compared at each time step. The \textit{in-control} distribution $f_{\bm{\theta}_0}(y_t|\bm{z}_t)$ with the covariates $\bm{z}_t$ is estimated by a GLM of the Poisson or negative binomial family with a log link, depending on the overdispersion of the data. In this context, the standard model for the \textit{in-control} mean is $$\log \mu_{0,t}=\beta_0+\beta_1t+\sum_{s=1}^S\left[\beta_{2s}\cos \left(\frac{2\pi s t}{\mathtt{Period}}\right)+\beta_{2s+1}\sin \left(\frac{2\pi s t}{\mathtt{Period}}\right)\right] $$ where $S$ is the number of harmonic waves to use and \texttt{Period} is the period of the data as indicated in the \code{control} slot, for instance 52 for weekly data. However, more flexible linear predictors, e.g., containing splines, concurrent covariates or an offset could be used on the right hand-side of the equation. The GLM could therefore be made very similar to the one used by~\citet{Noufaily2012}, with reweighting of past outbreaks and various criteria for including the time trend. The parameters of the \textit{in-control} and \textit{out-of-control} models are respectively given by $\bm{\theta}_0$ and $\bm{\theta}_1$. The \textit{out-of-control} mean is defined as a function of the \textit{in-control} mean, either with a multiplicative shift (additive on the log-scale) whose size $\kappa$ can be given as an input or reestimated at each timepoint $t>1$, $\mu_{1,t}=\mu_{0,t}\cdot \exp(\kappa)$, or with an unknown autoregressive component as in \citet{held-etal-2005}, $\mu_{1,t}=\mu_{0,t}+\lambda y_{t-1}$ with unknown $\lambda>0$. In \code{glrnb}, timepoints are divided into two intervals: phase 1 and phase 2. The \textit{in-control} mean and overdispersion are estimated with a GLM fitted on phase 1 data, whereas surveillance operates on phase 2 data. When $\lambda$ is fixed, one uses a likelihood-ratio (LR) and defines the stopping time for alarm as $$N=\min \left\{ t_0 \geq 1 : \max_{1\leq t \leq t_0} \left[ \sum_{s=t}^{t_0} \log\left\{ \frac{f_{\bm{\theta}_1}(y_s|\bm{z}_s)}{f_{\bm{\theta}_0}(y_s|\bm{z}_s)} \right\} \right] \geq \mathtt{c.ARL} \right\},$$ where $\mathtt{c.ARL}$ is the threshold of the CUSUM. When $\lambda$ is unknown and with the autoregressive component one has to use a generalized likelihood ratio (GLR) with the following stopping rule to estimate them on the fly at each time point so that $$N_G=\min \left\{ t_0 \geq 1 : \max_{1\leq t \leq t_0} \sup_{\bm{\theta} \in \bm{\Theta}} \left[ \sum_{s=t}^{t_0} \log\left\{ \frac{f_{\bm{\theta}}(y_s|\bm{z}_s)}{f_{\bm{\theta}_0}(y_s|\bm{z}_s)} \right\} \right] \geq \mathtt{c.ARL} \right\} \,.$$ Thus, one does not make any hypothesis about the specific value of the change to detect, but this GLR is more computationally intensive than the LR. \subsubsection{Practical use} For using \code{glrnb} one has two choices to make. First, one has to choose an \textit{in-control} model that will be fitted on phase 1 data. One can either provide the predictions for the vector of \textit{in-control} means \code{mu0} and the overdispersion parameter \code{alpha} by relying on an external fit, or use the built-in GLM estimator, that will use all data before the beginning of the surveillance range to fit a GLM with the number of harmonics \code{S} and a time trend if \code{trend} is \code{TRUE}. The choice of the exact \textit{in-control} model depends on the data under surveillance. Performing model selection is a compulsory step in practical applications. Then, one needs to tune the surveillance function itself, for one of the two possible change forms, \code{intercept}~or~\code{epi}.~One~can choose either to set \code{theta} to a given value and thus perform LR instead of GLR. The value of \code{theta} has to be adapted to the specific context in which the algorithm is applied: how big are shifts one wants to detect optimally? Is it better not to specify any and use GLR instead? The threshold \texttt{c.ARL} also has to be specified by the user. As explained in \citet{hoehle-mazick-2010} one can compute the threshold for a desired run-length in control through direct Monte Carlo simulation or a Markov chain approximation. Lastly, as mentioned in \citet{hoehle.paul2008}, a window-limited approach of surveillance, instead of looking at all the timepoints until the first observation, can make computation faster. Here we apply \code{glrnb} to the time series of report counts of \textit{Salmonella Newport} in Germany by assuming a known multiplicative shift of factor $2$ and by using the built-in estimator to fit an \textit{in-control} model with one harmonic for seasonality and a trend. This model will be refitted after each alarm, but first we use data from the years before 2011 as reference or \code{phase1}, and the data from 2011 as data to be monitored or \code{phase2}. The threshold \texttt{c.ARL} was chosen to be 4 as we found with the same approach as \citet{hoehle-mazick-2010} that it made the probability of a false alarm within one year smaller than 0.1. Figure~\ref{fig:glrnb}~shows the results of this monitoring. <>= phase1 <- which(isoWeekYear(epoch(salmNewportGermany))$ISOYear < 2011) phase2 <- in2011 control <- list(range = phase2, c.ARL = 4, theta = log(2), ret = "cases", mu0 = list(S = 1, trend = TRUE, refit = FALSE)) salmGlrnb <- glrnb(salmNewportGermany, control = control) @ \begin{figure} \centering <>= y.max <- max(observed(salmGlrnb),upperbound(salmGlrnb),na.rm=TRUE) do.call("plot",modifyList(plotOpts,list(x=salmGlrnb,ylim=c(0,y.max)))) @ \caption{S. Newport in Germany in 2011 monitored by the \texttt{glrnb} function.} \label{fig:glrnb} \end{figure} The implementation of \code{glrnb} on individual time series was already thoroughly explained in \citet{hoehle-mazick-2010}. Our objective in the present document is rather to provide practical tips for the implementation of this function on huge amounts of data in public health surveillance applications. Issues of computational speed become very significant in such a context. Our proposal to reduce the computational burden incurred by this algorithm is to compute the \textit{in-control} model for each time series (pathogen, subtype, subtype in a given location, etc.) only once a year and to use this estimation for the computation of a threshold for each time series. An idea to avoid starting with an initial value of zero in the CUSUM is to use either $\left(\frac{1}{2}\right)\cdot\mathtt{c.ARL}$ as a starting value (fast initial response CUSUM as presented in~\citet{lucas1982fast}) or to let surveillance run with the new \textit{in-control} model during a buffer period and use the resulting CUSUM as an initial value. One could also choose the maximum of these two possible starting values as a starting value. During the buffer period alarms would be generated with the old model. Lastly, using GLR is much more computationally intensive than using LR, whereas LR performs reasonably well on shifts different from the one indicated by \code{theta} as seen in the simulation studies of~\citet{hoehle.paul2008}. Our advice would therefore be to use LR with a reasonable predefined \code{theta}. The amount of historical data used each year to update the model, the length of the buffer period and the value of \code{theta} have to be fixed for each specific application, e.g., using simulations and/or discussion with experts. \subsubsection{Similar methods in the package} The algorithm \code{glrPois} is the same function as \code{glrnb} but for Poisson distributed data. Other CUSUM methods for count data are found in the package: \code{cusum} and \code{rogerson}. Both methods are discussed and compared to \code{glrnb} in \citet{hoehle.paul2008}. The package also includes a semi-parametric method \code{outbreakP} that aims at detecting changes from a constant level to a monotonically increasing incidence, for instance the beginning of the influenza season. See Table~\ref{table:ref} for the corresponding references. \subsection{A method for monitoring categorical data} All monitoring methods presented up to now have been methods for analysing count data. Nevertheless, in public health surveillance one also encounters categorical time series which are time series where the response variable obtains one of $k\geq2$ different categories (nominal or ordinal). When $k=2$ the time series is binary, for instance representing a specific outcome in cases such as hospitalization, death or a positive result to some diagnostic test. One can also think of applications with $k>2$ if one studies, e.g., the age groups of the cases in the context of monitoring a vaccination program: vaccination targeted at children could induce a shift towards older cases which one wants to detect as quickly as possible -- this will be explained thoroughly with an example. The developments of prospective surveillance methods for such categorical time series were up to recently limited to CUSUM-based approaches for binary data such as those explained in~\citet{Chen1978},~\citet{Reynolds2000} and~\citet{rogerson_yamada2004}. Other than being only suitable for binary data these methods have the drawback of not handling overdispersion. A method improving on these two limitations while casting the problem into a more comprehending GLM regression framework for categorical data was presented in~\citet{hoehle2010}. It is implemented as the function \code{categoricalCUSUM}. The way \code{categoricalCUSUM} operates is very similar to what \code{glrnb} does with fixed \textit{out-of-control} parameter. First, the parameters in a multivariate GLM for the \textit{in-control} distribution are estimated from the historical data. Then the \textit{out-of-control} distribution is defined by a given change in the parameters of this GLM, e.g., an intercept change, as explained later. Lastly, prospective monitoring is performed on current data using a likelihood ratio detector which compares the likelihood of the response under the \textit{in-control} and \textit{out-of-control} distributions. \subsubsection{Categorical CUSUM for binomial models} The challenge when performing these steps with categorical data from surveillance systems is finding an appropriate model. Binary GLMs as presented in Chapter~6 of \citet{Fahrmeir.etal2013} could be a solution but they do not tackle well the inherent overdispersion in the binomial time series. Of course one could choose a quasi family but these are not proper statistical distributions making many issues such as prediction complicated. A better alternative is offered by the use of \textit{generalized additive models for location, scale and shape} \citep[GAMLSS,][]{Rigby2005}, that support distributions such as the beta-binomial distribution, suitable for overdispersed binary data. With GAMLSS one can model the dependency of the mean -- \textit{location} -- upon explanatory variables but the regression modeling is also extended to other parameters of the distribution, e.g., scale. Moreover any modelled parameter can be put under surveillance, be it the mean (as in the example later developed) or the time trend in the linear predictor of the mean. This very flexible modeling framework is implemented in \proglang{R} through the \pkg{gamlss} package~\citep{StasJSS}. As an example we consider the time series of the weekly number of hospitalized cases among all \textit{Salmonella} cases in Germany in Jan 2004--Jan 2014, depicted in Figure~\ref{fig:cat1}. We use 2004--2012 data to estimate the \textit{in-control} parameters and then perform surveillance on the data from 2013 and early 2014. We start by preprocessing the data. <>= data("salmHospitalized") isoWeekYearData <- isoWeekYear(epoch(salmHospitalized)) dataBefore2013 <- which(isoWeekYearData$ISOYear < 2013) data2013 <- which(isoWeekYearData$ISOYear == 2013) dataEarly2014 <- which(isoWeekYearData$ISOYear == 2014 & isoWeekYearData$ISOWeek <= 4) phase1 <- dataBefore2013 phase2 <- c(data2013, dataEarly2014) salmHospitalized.df <- cbind(as.data.frame(salmHospitalized), weekNumber = isoWeekYearData$ISOWeek) names(salmHospitalized.df) <- c("y", "t", "state", "alarm", "upperbound", "n", "freq", "epochInPeriod", "weekNumber") @ We assume that the number of hospitalized cases follows a beta-binomial distribution, i.e., $ y_t \sim \BetaBin(n_t,\pi_t,\sigma_t)$ with $n_t$ the total number of reported cases at time $t$, $\pi_t$ the proportion of these cases that were hospitalized and $\sigma$ the dispersion parameter. In this parametrization, $$E(y_t)=n_t \pi_t,\quad \text{and}$$ $$\Var(y_t)=n_t \pi_t(1-\pi_t)\left( 1 + \frac{\sigma(n_t-1)}{\sigma+1} \right) \,.$$ We choose to model the expectation $n_t \pi_t$ using a beta-binomial model with a logit-link which is a special case of a GAMLSS, i.e., $$\logit(\pi_t)=\bm{z}_t^\top\bm{\beta}$$ where $\bm{z}_t$ is a vector of possibly time-varying covariates and $\bm{\beta}$ a vector of covariate effects in our example. \begin{figure} \centering <>= y.max <- max(observed(salmHospitalized)/population(salmHospitalized),upperbound(salmHospitalized)/population(salmHospitalized),na.rm=TRUE) plotOpts2 <- modifyList(plotOpts,list(x=salmHospitalized,legend.opts=NULL,ylab="",ylim=c(0,y.max)),keep.null=TRUE) plotOpts2$xaxis.tickFreq <- list("%G"=atChange,"%m"=atChange) plotOpts2$par.list <- list(mar=c(6,5,5,5),family="Times",las=1) do.call("plot",plotOpts2) lines(salmHospitalized@populationFrac/4000,col="grey80",lwd=2) lines(campyDE$hum*50, col="white", lwd=2) axis(side=4, at=seq(0,2000,by=500)/4000,labels=as.character(seq(0,2000,by=500)),las=1, cex=2,cex.axis=1.5,pos=length(observed(salmHospitalized))+20) par(family="Times") text(-20, 0.6, "Proportion", pos = 3, xpd = T,cex=cex.text) text(520, 0.6, "Total number of \n reported cases", pos = 3, xpd = T,cex=cex.text) @ \caption{Weekly proportion of Salmonella cases that were hospitalized in Germany 2004-2014. In addition the corresponding number of reported cases is shown as a light curve.} \label{fig:cat1} \end{figure} The proportion of hospitalized cases varies throughout the year as seen in Figure~\ref{fig:cat1}. One observes that in the summer the proportion of hospitalized cases is smaller than in other seasons. However, over the holidays in December the proportion of hospitalized cases increases. Note that the number of non-hospitalized cases drops while the number of hospitalized cases remains constant (data not shown): this might be explained by the fact that cases that are not serious enough to go to the hospital are not seen by general practitioners because sick workers do not need a sick note during the holidays. Therefore, the \textit{in-control} model should contain these elements, as well as the fact that there is an increasing trend of the proportion because GPs prescribe less and less stool diagnoses so that more diagnoses are done on hospitalized cases. We choose a model with an intercept, a time trend, two harmonic terms and a factor variable for the first two weeks of each year. The variable \code{epochInPeriod} takes into account the fact that not all years have 52 weeks. <>= vars <- c( "y", "n", "t", "epochInPeriod", "weekNumber") m.bbin <- gamlss(cbind(y, n-y) ~ 1 + t + sin(2 * pi * epochInPeriod) + cos(2 * pi * epochInPeriod) + sin(4 * pi * epochInPeriod) + cos(4 * pi * epochInPeriod) + I(weekNumber == 1) + I(weekNumber == 2), sigma.formula =~ 1, family = BB(sigma.link = "log"), data = salmHospitalized.df[phase1, vars]) @ The change we aim to detect is defined by a multiplicative change of odds, from $\frac{\pi_t^0}{(1-\pi_t^0)}$ to $R\cdot\frac{\pi_t^0}{(1-\pi_t^0)}$ with $R>0$, similar to what was done in~\citet{Steiner1999} for the logistic regression model. This is equivalent to an additive change of the log-odds, $$\logit(\pi_t^1)=\logit(\pi_t^0)+\log R$$ with $\pi_t^0$ being the \textit{in-control} proportion and $\pi_t^1$ the \textit{out-of-control} distribution. The likelihood ratio based CUSUM statistic is now defined as $$C_{t_0}=\max_{1\leq t \leq {t_0}}\left( \sum_{s=t}^{t_0} \log \left( \frac{f(y_s;\bm{z}_s,\bm{\theta}_1)}{f(y_s;\bm{z}_s,\bm{\theta}_0)} \right) \right)$$ with $\bm{\theta}_0$ and $\bm{\theta}_1$ being the vector in- and \textit{out-of-control} parameters, respectively. Given a threshold \code{h}, an alarm is sounded at the first time when $C_{t_0}>\mathtt{h}$. We set the parameters of the \code{categoricalCUSUM} to optimally detect a doubling of the odds in 2013 and 2014, i.e., $R=2$. Furthermore, we for now set the threshold of the CUSUM at $h=2$. We use the GAMLSS to predict the mean of the \textit{in-control} and \textit{out-of-control} distributions and store them into matrices with two columns among which the second one represents the reference category. <>= R <- 2 h <- 2 pi0 <- predict(m.bbin, newdata = salmHospitalized.df[phase2, vars], type = "response") pi1 <- plogis(qlogis(pi0) + log(R)) pi0m <- rbind(pi0, 1 - pi0) pi1m <- rbind(pi1, 1 - pi1) @ Note that the \code{categoricalCUSUM} function is constructed to operate on the observed slot of \code{sts}-objects which have as columns the number of cases in each category at each timepoint, \textit{i.e.}, each row of the observed slot contains the elements $(y_{t1},...,y_{tk})$. <>= populationHosp <- unname(cbind( population(salmHospitalized), population(salmHospitalized))) observedHosp <- cbind( "Yes" = as.vector(observed(salmHospitalized)), "No" = as.vector(population(salmHospitalized) - observed(salmHospitalized))) salmHospitalized.multi <- sts( frequency = 52, start = c(2004, 1), epoch = epoch(salmHospitalized), observed = observedHosp, population = populationHosp, multinomialTS = TRUE) @ Furthermore, one needs to define a wrapper for the distribution function in order to have an argument named \code{"mu"} in the function. <>= dBB.cusum <- function(y, mu, sigma, size, log = FALSE) { dBB(if (is.matrix(y)) y[1,] else y, if (is.matrix(y)) mu[1,] else mu, sigma = sigma, bd = size, log = log) } @ After these preliminary steps, the monitoring can be performed. <>= controlCat <- list(range = phase2, h = 2, pi0 = pi0m, pi1 = pi1m, ret = "cases", dfun = dBB.cusum) salmHospitalizedCat <- categoricalCUSUM( salmHospitalized.multi, control = controlCat, sigma = exp(m.bbin$sigma.coefficients)) @ The results can be seen in Figure~\ref{fig:catDouble}(a). With the given settings, there are alarms at week 16 in 2004 and at week 3 in 2004. The one in 2014 corresponds to the usual peak of the beginning of the year, which was larger than expected this year, maybe because the weekdays of the holidays were particularly worker-friendly so that sick notes were even less needed. The value for the threshold \code{h} can be determined following the procedures presented in \citet{hoehle-mazick-2010} for count data, and as in the code exhibited below. Two methods can be used for determining the probability of a false alarm within a pre-specified number of steps for a given value of the threshold \code{h}: a Monte Carlo method relying on, e.g., 1000 simulations and a Markov Chain approximation of the CUSUM. The former is much more computationally intensive than the latter: with the code below, the Monte Carlo method needed approximately 300 times more time than the Markov Chain method. Since both results are close we recommend the Markov Chain approximation for practical use. The Monte Carlo method works by sampling observed values from the estimated distribution and performing monitoring with \code{categoricalCUSUM} on this \code{sts} object. As observed values are estimated from the \textit{in-control} distribution every alarm thus obtained is a false alarm so that the simulations allow to estimate the probability of a false alarm when monitoring \textit{in-control} data over the timepoints of \code{phase2}. The Markov Chain approximation introduced by \citet{brook_evans1972} is implemented as \code{LRCUSUM.runlength} which is already used for \code{glrnb}. Results from both methods can be seen in Figure~\ref{fig:catDouble}(b). We chose a value of 2 for \code{h} so that the probability of a false alarm within the 56 timepoints of \code{phase2} is less than $0.1$. One first has to set the values of the threshold to be investigated and to prepare the function used for simulation, that draws observed values from the \textit{in-control} distribution and performs monitoring on the corresponding time series, then indicating if there was at least one alarm. Then 1000 simulations were performed with a fixed seed value for the sake of reproducibility. Afterwards, we tested the Markov Chain approximation using the function \code{LRCUSUM.runlength} over the same grid of values for the threshold. <<>>= h.grid <- seq(1, 10, by = 0.5) @ <>= simone <- function(sts, h) { y <- rBB(length(phase2), mu = pi0m[1, , drop = FALSE], bd = population(sts)[phase2, ], sigma = exp(m.bbin$sigma.coefficients), fast = TRUE) observed(sts)[phase2, ] <- cbind(y, population(sts)[phase2, 1] - y) one.surv <- categoricalCUSUM( sts, control = modifyList(controlCat, list(h = h)), sigma = exp(m.bbin$sigma.coefficients)) return(any(alarms(one.surv)[, 1])) } set.seed(123) nSims <- 1000 pMC <- sapply(h.grid, function(h) { mean(replicate(nSims, simone(salmHospitalized.multi, h))) }) pMarkovChain <- sapply(h.grid, function(h) { TA <- LRCUSUM.runlength(mu = pi0m[1,,drop = FALSE], mu0 = pi0m[1,,drop = FALSE], mu1 = pi1m[1,,drop = FALSE], n = population(salmHospitalized.multi)[phase2, ], h = h, dfun = dBB.cusum, sigma = exp(m.bbin$sigma.coef)) return(tail(TA$cdf, n = 1)) }) @ <>= if (computeALL) { <> save(pMC, file = "monitoringCounts-cache/pMC.RData") save(pMarkovChain, file = "monitoringCounts-cache/pMarkovChain.RData") } else { load("monitoringCounts-cache/pMC.RData") load("monitoringCounts-cache/pMarkovChain.RData") } @ \begin{figure} \subfloat[]{ <>= y.max <- max(observed(salmHospitalizedCat[,1])/population(salmHospitalizedCat[,1]),upperbound(salmHospitalizedCat[,1])/population(salmHospitalizedCat[,1]),na.rm=TRUE) plotOpts3 <- modifyList(plotOpts,list(x=salmHospitalizedCat[,1],ylab="Proportion",ylim=c(0,y.max))) plotOpts3$legend.opts <- list(x="top",bty="n",legend=c(expression(U[t])),lty=1,lwd=line.lwd,col=plotOpts$alarm.symbol$col,horiz=TRUE,cex=cex.text) do.call("plot",plotOpts3) @ <>= plot(salmHospitalizedCat[,1]) @ } \subfloat[]{ <>= par(mar=c(6,5,5,5),family="Times") matplot(h.grid, cbind(pMC,pMarkovChain),type="l",ylab=expression(P(T[A] <= 56 * "|" * tau * "=" * infinity)),xlab="Threshold h",col=1,cex.axis=cex.text,cex.lab=cex.text) prob <- 0.1 lines(range(h.grid),rep(prob,2),lty=5,lwd=2) par(family="Times") legend(4,0.08,c("Monte Carlo","Markov chain"), lty=1:2,col=1,cex=cex.text,bty="n") @ <>= matplot(h.grid, cbind(pMC, pMarkovChain), type="l", lty=1:2, col=1) abline(h=0.1, lty=5) legend("center", c("Monte Carlo","Markov chain"), lty=1:2, bty="n") @ } \caption{(a) Results of the monitoring with categorical CUSUM of the proportion of Salmonella cases that were hospitalized in Germany in Jan 2013 - Jan 2014. (b) Probability of a false alarm within the 56 timepoints of the monitoring as a function of the threshold $h$.} \label{fig:catDouble} \end{figure} The procedure for using the function for multicategorical variables follows the same steps (as illustrated later). Moreover, one could expand the approach to utilize the multiple regression possibilities offered by GAMLSS. Here we chose to try to detect a change in the mean of the distribution of counts but as GAMLSS provides more general regression tools than GLM we could also aim at detecting a change in the time trend included in the model for the mean. \subsubsection{Categorical CUSUM for multinomial models} In order to illustrate the use of \code{categoricalCUSUM} for more than two classes we analyse the monthly number of rotavirus cases in the federal state Brandenburg during 2002-2013 and which are stratified into the five age-groups 00-04, 05-09, 10-14, 15-69, 70+ years. In 2006 two rotavirus vaccines were introduced, which are administered in children at the age of 4--6 months. Since then, coverage of these vaccination has steadily increased and interest is to detect possible age-shifts in the distribution of cases. <>= data("rotaBB") plot(rotaBB) @ \begin{figure} \centering <>= par(mar=c(5.1,20.1,4.1,0),family="Times") plot(rotaBB,xlab="Time (months)",ylab="", col="mediumblue",cex=cex.text,cex.lab=cex.text,cex.axis=cex.text,cex.main=cex.text, xaxis.tickFreq=list("%G"=atChange), xaxis.labelFreq=list("%G"=at2ndChange), xaxis.labelFormat="%G") par(las=0,family="Times") mtext("Proportion of reported cases", side=2, line=19, cex=1) @ \caption{Monthly proportions in five age-groups for the reported rotavirus cases in Brandenburg, Germany, \Sexpr{paste(format(range(epoch(rotaBB)),"%Y"),collapse="-")}.} \label{fig:vac} \end{figure} From Figure~\ref{fig:vac} we observe a shift in proportion away from the very young. However, interpreting the proportions only makes sense in combination with the absolute numbers. In these plots (not shown) it becomes clear that the absolute numbers in the 0--4 year old have decreased since 2009. However, in the 70+ group a small increase is observed with 2013 by far being the strongest season so far. Hence, our interest is in prospectively detecting a possible age-shift. Since the vaccine was recommended for routine vaccination in Brandenburg in 2009 we choose to start the monitoring at that time point. We do so by fitting a multinomial logit-model containing a trend as well as one harmonic wave and use the age group 0--4 years as reference category, to the data from the years 2002-2008. Different \proglang{R} packages implement such type of modeling, but we shall use the \pkg{MGLM} package~\citep{MGLM}, because it also offers the fitting of extended multinomial regression models allowing for extra dispersion. <<>>= rotaBB.df <- as.data.frame(rotaBB) X <- with(rotaBB.df, cbind(intercept = 1, epoch, sin1 = sin(2 * pi * epochInPeriod), cos1 = cos(2 * pi * epochInPeriod))) phase1 <- epoch(rotaBB) < as.Date("2009-01-01") phase2 <- !phase1 library("MGLM") ## MGLMreg automatically takes the last class as ref so we reorder order <- c(2:5, 1); reorder <- c(5, 1:4) m0 <- MGLMreg(as.matrix(rotaBB.df[phase1, order]) ~ -1 + X[phase1, ], dist = "MN") @ As described in \citet{hoehle2010} we can try to detect a specific shift in the intercept coefficients of the model. For example, a multiplicative shift of factor 2 in the example below, in the odds of each of the four age categories against the reference category is modelled by changing the intercept value of each category. Based on this, the \textit{in-control} and \textit{out-of-control} proportions are easily computed using the \code{predict} function for \code{MGLMreg} objects. <<>>= m1 <- m0 m1@coefficients[1, ] <- m0@coefficients[1, ] + log(2) pi0 <- t(predict(m0, newdata = X[phase2, ])[, reorder]) pi1 <- t(predict(m1, newdata = X[phase2, ])[, reorder]) @ For applying the \code{categoricalCUSUM} function one needs to define a compatible wrapper function for the multinomial as in the binomial example. With $\bm{\pi}^0$ and $\bm{\pi}^1$ in place one only needs to define a wrapper function, which defines the PMF of the sampling distribution -- in this case the multinomial -- in a \code{categoricalCUSUM} compatible way. <>= dfun <- function(y, size, mu, log = FALSE) { dmultinom(x = y, size = size, prob = mu, log = log) } h <- 2 # threshold for the CUSUM statistic control <- list(range = seq(nrow(rotaBB))[phase2], h = h, pi0 = pi0, pi1 = pi1, ret = "value", dfun = dfun) surv <- categoricalCUSUM(rotaBB,control=control) @ <>= alarmDates <- epoch(surv)[which(alarms(surv)[,1])] format(alarmDates,"%b %Y") @ <>= #Number of MC samples nSamples <- 1e4 #Do MC simone.stop <- function(sts, control) { phase2Times <- seq(nrow(sts))[phase2] #Generate new phase2 data from the fitted in control model y <- sapply(1:length(phase2Times), function(i) { rmultinom(n=1, prob=pi0[,i],size=population(sts)[phase2Times[i],1]) }) observed(sts)[phase2Times,] <- t(y) one.surv <- categoricalCUSUM(sts, control=control) #compute P(S<=length(phase2)) return(any(alarms(one.surv)[,1]>0)) } set.seed(1233) rlMN <- replicate(nSamples, simone.stop(rotaBB, control=control)) mean(rlMN) # 0.5002 @ The resulting CUSUM statistic $C_t$ as a function of time is shown in Figure~\ref{fig:ct}(a). The first time an aberration is detected is July 2009. Using 10000 Monte Carlo simulations we estimate that with the chosen threshold $h=2$ the probability for a false alarm within the 60 time points of \code{phase2} is 0.02. As the above example shows, the LR based categorical CUSUM is rather flexible in handling any type of multivariate GLM modeling to specify the \textit{in-control} and \textit{out-of-control} proportions. However, it requires a direction of the change to be specified -- for which detection is optimal. One sensitive part of such monitoring is the fit of the multinomial distribution to a multivariate time series of proportions, which usually exhibit extra dispersion when compared to the multinomial. For example comparing the AIC between the multinomial logit-model and a Dirichlet-multinomial model with $\alpha_{ti} = \exp(\bm{x}_t^\top\bm{\beta})$~\citep{MGLM} shows that overdispersion is present. The Dirichlet distribution is the multicategorical equivalent of the beta-binomial distribution. We exemplify its use in the code below. <<>>= m0.dm <- MGLMreg(as.matrix(rotaBB.df[phase1, 1:5]) ~ -1 + X[phase1, ], dist = "DM") c(m0@AIC, m0.dm@AIC) @ Hence, the above estimated false alarm probability might be too low for the actual monitoring problem, because the variation in the time series is larger than implied by the multinomial. Hence, it appears prudent to repeat the analysis using the more flexible Dirichlet-multinomial model. This is straightforward with \code{categoricalCUSUM} once the \textit{out-of-control} proportions are specified in terms of the model. Such a specification is, however, hampered by the fact that the two models use different parametrizations. For performing monitoring in this new setting we first need to calculate the $\alpha$'s of the multinomial-Dirichlet for the \textit{in-control} and \textit{out-of-control} distributions. <<>>= ## Change intercept in the first class (for DM all 5 classes are modeled) delta <- 2 m1.dm <- m0.dm m1.dm@coefficients[1, ] <- m0.dm@coefficients[1, ] + c(-delta, rep(delta/4, 4)) alpha0 <- exp(X[phase2,] %*% m0.dm@coefficients) alpha1 <- exp(X[phase2,] %*% m1.dm@coefficients) dfun <- function(y, size, mu, log = FALSE) { dLog <- ddirmn(t(y), t(mu)) if (log) dLog else exp(dLog) } h <- 2 control <- list(range = seq(nrow(rotaBB))[phase2], h = h, pi0 = t(alpha0), pi1 = t(alpha1), ret = "value", dfun = dfun) surv.dm <- categoricalCUSUM(rotaBB, control = control) @ <>= matplot(alpha0/rowSums(alpha0),type="l",lwd=3,lty=1,ylim=c(0,1)) matlines(alpha1/rowSums(alpha1),type="l",lwd=1,lty=2) @ \begin{figure} \subfloat[]{ <>= surv@observed[,1] <- 0 surv@multinomialTS <- FALSE surv.dm@observed[,1] <- 0 surv.dm@multinomialTS <- FALSE y.max <- max(observed(surv.dm[,1]),upperbound(surv.dm[,1]),observed(surv[,1]),upperbound(surv[,1]),na.rm=TRUE) plotOpts3 <- modifyList(plotOpts,list(x=surv[,1],ylim=c(0,y.max),ylab=expression(C[t]),xlab="")) plotOpts3$legend.opts <- list(x="topleft",bty="n",legend="R",lty=1,lwd=line.lwd,col=plotOpts$alarm.symbol$col,horiz=TRUE,cex=cex.text) do.call("plot",plotOpts3) abline(h=h, lwd=2, col="darkgrey") par(family="Times") mtext(side=1,text="Time (weeks)", las=0,line=3, cex=cex.text) @ } \subfloat[]{ <>= plotOpts3$x <- surv.dm[,1] do.call("plot",plotOpts3) abline(h=h, lwd=2, col="darkgrey") par(family="Times") mtext(side=1,text="Time (weeks)", las=0,line=3, cex=cex.text) @ } \caption{Categorical CUSUM statistic $C_t$. Once $C_t>\Sexpr{h}$ an alarm is sounded and the statistic is reset. In (a) surveillance uses the multinomial distribution and in (b) surveillance uses the Dirichlet-multinomial distribution.} \label{fig:ct} \end{figure} <>= par(mfrow = c(1,2)) surv@multinomialTS <- surv.dm@multinomialTS <- FALSE # trick plot method ... plot(surv[,1], col=c(NA,NA,4), ylab = expression(C[t]), ylim = c(0,33), xaxis.tickFreq=list("%Y"=atChange, "%m"=atChange), xaxis.labelFreq=list("%Y"=atMedian), xaxis.labelFormat="%Y") abline(h=h, lwd=2, col="darkgrey") plot(surv.dm[,1], col=c(NA,NA,4), ylab = expression(C[t]), ylim = c(0,33), xaxis.tickFreq=list("%Y"=atChange, "%m"=atChange), xaxis.labelFreq=list("%Y"=atMedian), xaxis.labelFormat="%Y") abline(h=h, lwd=2, col="darkgrey") @ The resulting CUSUM statistic $C_t$ using the Dirichlet multinomial distribution is shown in Figure~\ref{fig:ct}(b). We notice a rather similar behavior even though the shift-type specified by this model is slightly different than in the model of Figure~\ref{fig:ct}(a). \subsubsection{Categorical data in routine surveillance} The multidimensionality of data available in public health surveillance creates many opportunities for the analysis of categorical time series, for example: sex ratio of cases of a given disease, age group distribution, regions sending data, etc. If one is interested in monitoring with respect to a categorical variable, a choice has to be made between monitoring each time series individually, for instance a time series of \textit{Salmonella} cases for each age group, or monitoring the distribution of cases with respect to that factor jointly \textit{via} \code{categoricalCUSUM}. A downside of the latter solution is that one has to specify the change parameter \code{R} in advance, which can be quite a hurdle if one has no pre-conceived idea of what could happen for, say, the age shift after the introduction of a vaccine. Alternatively, one could employ an ensemble of monitors or monitor an aggregate. However, more straightforward applications could be found in the (binomial) surveillance of positive diagnostics given laboratory test data and not only data about confirmed cases. An alternative would be to apply \code{farringtonFlexible} while using the number of tests as \code{populationOffset}. \subsubsection{Similar methods in the package} The package also offers another CUSUM method suitable for binary data, \code{pairedbinCUSUM} that implements the method introduced by~\citet{Steiner1999}, which does not, however, take overdispersion into account as well as \code{glrnb}. The algorithm \code{rogerson} also supports the analysis of binomial data. See Table~\ref{table:ref} for the corresponding references. \subsection{Other algorithms implemented in the package} We conclude this description of surveillance methods by giving an overview of all algorithms implemented in the package in Table~\ref{table:ref}. Please see the cited articles or the package manual for more information about each method. Criteria for choosing a method in practice are numerous. First one needs to ponder on the amount of historical data at hand -- for instance the EARS methods only need data for the last timepoints whereas the Farrington methods use data up to $b$ years in the past. Then one should consider the amount of past data used by the algorithm -- historical reference methods use only a subset of the past data, namely the timepoints located around the same timepoint in the past years, whereas other methods use all past data included in the reference data. This can be a criterion of choice since one can prefer using all available data. It is also important to decide whether one wants to detect one-timepoint aberration or more prolonged shifts. And lastly, an important criterion is how much work needs to be done for finetuning the algorithm for each specific time series. The package on the one hand provides the means for analysing nearly all type of surveillance data and on the other hand makes the comparison of algorithms possible. This is useful in practical applications when those algorithms are implemented into routine use, which will be the topic of Section~\ref{sec:routine}. \begin{table}[t!] \centering \begin{tabular}{lp{11cm}} \toprule Function & References \\ \midrule \code{bayes} & \citet{riebler2004} \\ \code{boda} & \citet{Manitz2013} \\ \code{bodaDelay} & \citet{Maelle} \\ \code{categoricalCUSUM} & \citet{hoehle2010}\\ \code{cdc} & \citet{stroup89,farrington2003} \\ \code{cusum} & \citet{rossi_etal99,pierce_schafer86} \\ \code{earsC} & \citet{SIM:SIM3197} \\ \code{farrington} & \citet{farrington96} \\ \code{farringtonFlexible} & \citet{farrington96,Noufaily2012} \\ \code{glrnb} & \citet{hoehle.paul2008} \\ \code{glrpois} & \citet{hoehle.paul2008} \\ \code{outbreakP} & \citet{frisen_etal2009,fri2009} \\ \code{pairedbinCUSUM} & \citet{Steiner1999} \\ \code{rki} & Not available -- unpublished \\ \code{rogerson} & \citet{rogerson_yamada2004} \\ \bottomrule \end{tabular} \caption{Algorithms for aberration detection implemented in \pkg{surveillance}.} \label{table:ref} \end{table} \section[Implementing surveillance in routine monitoring]{Implementing \pkg{surveillance} in routine monitoring} \label{sec:routine} \label{sec:3} Combining \pkg{surveillance} with other \proglang{R} packages and programs is easy, allowing the integration of the aberration detection into a comprehensive surveillance system to be used in routine practice. In our opinion, such a surveillance system has to at least support the following process: loading data from local databases, analysing them within \pkg{surveillance} and sending the results of this analysis to the end-user who is typically an epidemiologist in charge of the specific pathogen. This section exemplifies the integration of the package into a whole analysis stack, first through the introduction of a simple workflow from data query to a \code{Sweave}~\citep{sweave} or \pkg{knitr}~\citep{knitr} report of signals, and secondly through the presentation of the more elaborate system in use at the German Robert Koch Institute. \subsection{A simple surveillance system} Suppose you have a database with surveillance time series but little resources to build a surveillance system encompassing all the above stages. Using \proglang{R} and \code{Sweave} or \code{knitr} for \LaTeX~you can still set up a simple surveillance analysis without having to do everything by hand. You only need to import the data into \proglang{R} and create \code{sts} objects for each time series of interest as explained thoroughly in~\citet{hoehle-mazick-2010}. Then, calling a surveillance algorithm, say \code{farringtonFlexible}, with an appropriate \code{control} argument gives an \code{sts} object with upperbounds and alarms over \code{control$range}. To define the range automatically one could use the \proglang{R} function \code{Sys.Date()} to get today's date. These steps can be introduced as a code chunk in a \code{Sweave} or \code{knitr} code that will translate it into a report that you can send to the epidemiologists in charge of the respective pathogen whose cases are monitored. Below is an example of a short code segment showing the analysis of the \textit{S. Newport} weekly counts in the German federal states Baden-W\"{u}rttemberg and North Rhine-Westphalia using the improved method implemented in \code{farringtonFlexible}. The package provides a \code{toLatex} method for \code{sts} objects that produces a table of the observed counts and upperbound values for each unit; alarms are highlighted by default. The result is shown in Table~\ref{tableResults}. <<>>= today <- which(epoch(salmNewport) == as.Date("2013-12-23")) rangeAnalysis <- (today - 4):today in2013 <- which(isoWeekYear(epoch(salmNewport))$ISOYear == 2013) algoParameters <- list(range = rangeAnalysis, noPeriods = 10, populationBool = FALSE, b = 4, w = 3, weightsThreshold = 2.58, pastWeeksNotIncluded = 26, pThresholdTrend = 1, thresholdMethod = "nbPlugin", alpha = 0.05, limit54 = c(0, 50)) results <- farringtonFlexible(salmNewport[, c("Baden.Wuerttemberg", "North.Rhine.Westphalia")], control = algoParameters) @ <>= start <- isoWeekYear(epoch(salmNewport)[min(rangeAnalysis)]) end <- isoWeekYear(epoch(salmNewport)[max(rangeAnalysis)]) caption <- paste0("Results of the analysis of reported S. Newport ", "counts in two German federal states for the weeks ", start$ISOYear, "-W", start$ISOWeek, " to ", end$ISOYear, "-W", end$ISOWeek, ". Bold red counts indicate weeks with alarms.") toLatex(results, caption = caption, label = "tableResults", ubColumnLabel = "Threshold", include.rownames = FALSE, sanitize.text.function = identity) @ The advantage of this approach is that it can be made automatic. The downside of such a system is that the report is not interactive, for instance one cannot click on the cases and get the linelist. Nevertheless, this is a workable solution in many cases -- especially when human and financial resources are narrow. In the next section, we present a more advanced surveillance system built on the package. \subsection{Automatic detection of outbreaks at the Robert Koch Institute} \label{sec:RKI} The package \pkg{surveillance} was used as a core building block for designing and implementing the automated outbreak detection system at the RKI in Germany~\citep{Dirk}. The text below describes the system as it was in early 2014. Due to the Infection Protection Act (IfSG) the RKI daily receives over 1,000 notifiable disease reports. The system analyses about half a million time series per day to identify possible aberrations in the reported number of cases. Structurally, it consists of two components: an analytical process written in \proglang{R} that daily monitors the data and a reporting component that compiles and communicates the results to the epidemiologists. The analysis task in the described version of the system relied on \pkg{surveillance} and three other \proglang{R} packages, namely \pkg{data.table}, \pkg{RODBC} and \pkg{testthat} as described in the following. The data-backend is an OLAP-system~\citep{SSAS} and relational databases, which are queried using \pkg{RODBC}~\citep{rodbc2013}. The case reports are then rapidly aggregated into univariate time series using \pkg{data.table}~\citep{datatable2013}. To each time series we apply the \code{farringtonFlexible} algorithm on univariate \code{sts} objects and store the analysis results in another SQL-database. We make intensive use of \pkg{testthat}~\citep{testthat2013} for automatic testing of the component. Although \proglang{R} is not the typical language to write bigger software components for production, choosing \proglang{R} in combination with \pkg{surveillance} enabled us to quickly develop the analysis workflow. We can hence report positive experience using \proglang{R} also for larger software components in production. The reporting component was realized using Microsoft Reporting Services~\citep{SSRS}, because this technology is widely used within the RKI. It allows quick development of reports and works well with existing Microsoft Office tools, which the end-user, the epidemiologist, is used to. For example, one major requirement by the epidemiologists was to have the results compiled as Excel documents. Moreover, pathogen-specific reports are automatically sent once a week by email to epidemiologists in charge of the respective pathogen. Having state-of-the-art detection methods already implemented in \pkg{surveillance} helped us to focus on other challenges during development, such as bringing the system in the organization's workflow and finding ways to efficiently and effectively analyse about half a million of time series per day. In addition, major developments in the \proglang{R} component can be shared with the community and are thus available to other public health institutes as well. \section{Discussion} \label{sec:4} The \proglang{R} package \pkg{surveillance} was initially created as an implementational framework for the development and the evaluation of outbreak detection algorithms in routine collected public health surveillance data. Throughout the years it has more and more also become a tool for the use of surveillance in routine practice. The presented description aimed at showing the potential of the package for aberration detection. Other functions offered by the package for modeling~\citep{meyer.etal2014}, nowcasting~\citep{hoehle-heiden} or back-projection of incidence cases~\citep{becker_marschner93} are documented elsewhere and contribute to widening the scope of possible analysis in infectious disease epidemiology when using \pkg{surveillance}. Future areas of interest for the package are, e.g., to better take into account the multivariate and hierarchical structure of the data streams analysed. Another important topic is the adjustment for reporting delays when performing the surveillance~\citep{Maelle}. The package can be obtained from CRAN and resources for learning its use are listed in the documentation section of the project (\url{https://surveillance.R-Forge.R-project.org/}). As all \proglang{R} packages, \pkg{surveillance} is distributed with a manual describing each function with corresponding examples. The manual, the present article and two previous ones~\citep{hoehle-2007, hoehle-mazick-2010} form a good basis for getting started with the package. The data and analysis of the present manuscript are accessible as the vignette \texttt{"monitoringCounts.Rnw"} in the package. Since all functionality is available just at the cost of learning \proglang{R} we hope that parts of the package can be useful in health facilities around the world. Even though the package is tailored for surveillance in public health contexts, properties such as overdispersion, low counts, presence of past outbreaks, apply to a wide range of count and categorical time series in other surveillance contexts such as financial surveillance~\citep{frisen2008financial}, occupational safety monitoring~\citep{accident} or environmental surveillance~\citep{Radio}. Other \proglang{R} packages can be worth of interest to \pkg{surveillance} users. Statistical process control is offered by two other packages, \pkg{spc}~\citep{spc} and \pkg{qcc}~\citep{qcc}. The package \pkg{strucchange} allows detecting structural changes in general parametric models including GLMs~\citep{strucchange}, while the package \pkg{tscount} provides methods for regression and (retrospective) intervention analysis for count time series based on GLMs~\citep{tscount, liboschik_tscount_2015} . For epidemic modelling and outbreaks, packages such as \pkg{EpiEstim}~\citep{EpiEstim}, \pkg{outbreaker}~\citep{outbreaker} and \pkg{OutbreakTools}~\citep{OutbreakTools} offer good functionalities for investigating outbreaks that may for instance have been detected through to the use of \pkg{surveillance}. They are listed on the website of the \textit{\proglang{R}-epi project} (\url{https://sites.google.com/site/therepiproject}) that was initiated for compiling information about \proglang{R} tools useful for infectious diseases epidemiology. Another software of interest for aberration detection is \pkg{SaTScan}~\citep{SaTScan} which allows the detection of spatial, temporal and space-time clusters of events -- note that it is not a \proglang{R} package. Code contributions to the package are very welcome as well as feedback and suggestions for improving the package. \section*{Acknowledgments} The authors would like to express their gratitude to all contributors to the package, in particular Juliane Manitz, University of G\"{o}ttingen, Germany, for her work on the \texttt{boda} code, and Angela Noufaily, The Open University, Milton Keynes, UK, for providing us with the code used in her article that we extended for \texttt{farringtonFlexible}. The work of M. Salmon was financed by a PhD grant of the RKI. \bibliography{monitoringCounts,references} \end{document} surveillance/vignettes/references.bib0000644000176200001440000003606414615162374017577 0ustar liggesusers@Unpublished{altmann2003, author = {D. Altmann}, title = {The surveillance system of the {Robert Koch Institute}, {Germany}}, note = {Personal communication}, year = {2003}, } @Book{andersson2000, title = {Stochastic Epidemic Models and their Statistical Analysis}, publisher = {Springer-Verlag}, year = {2000}, author = {H. Andersson and T. Britton}, volume = {151}, series = {Springer Lectures Notes in Statistics}, } @Article{czado-etal-2009, author = {Claudia Czado and Tilmann Gneiting and Leonhard Held}, title = {Predictive model assessment for count data}, journal = {Biometrics}, year = {2009}, volume = {65}, number = {4}, pages = {1254--1261}, doi = {10.1111/j.1541-0420.2009.01191.x}, } @Book{Daley.Vere-Jones2003, title = {An Introduction to the Theory of Point Processes}, publisher = {Springer-Verlag}, year = {2003}, author = {Daley, Daryl J. and Vere-Jones, David}, editor = {Gani, Joseph M. and Heyde, Christopher C. and Kurtz, Thomas G.}, volume = {I: Elementary Theory and Methods}, series = {Probability and its Applications}, address = {New York}, edition = {2nd}, isbn = {0-387-95541-0}, } @Book{Fahrmeir.etal2013, title = {Regression: Models, Methods and Applications}, publisher = {Springer-Verlag}, year = {2013}, author = {Ludwig Fahrmeir and Thomas Kneib and Stefan Lang and Brian Marx}, isbn = {978-3-642-34332-2}, doi = {10.1007/978-3-642-34333-9}, } @Article{farrington96, author = {C. P. Farrington and N. J. Andrews and A. D. Beale and M. A. Catchpole}, title = {A statistical algorithm for the early detection of outbreaks of infectious disease}, journal = {Journal of the Royal Statistical Society. Series A (Statistics in Society)}, year = {1996}, volume = {159}, pages = {547--563}, } @InCollection{farrington2003, author = {Paddy Farrington and Nick Andrews}, title = {Outbreak Detection: Application to Infectious Disease Surveillance}, booktitle = {Monitoring the Health of Populations}, publisher = {Oxford University Press}, year = {2003}, editor = {Ron Brookmeyer and Donna F. Stroup}, chapter = {8}, pages = {203--231}, } @Article{geilhufe.etal2012, author = {Marc Geilhufe and Leonhard Held and Stein Olav Skr{\o}vseth and Gunnar S. Simonsen and Fred Godtliebsen}, title = {Power law approximations of movement network data for modeling infectious disease spread}, journal = {Biometrical Journal}, year = {2014}, volume = {56}, number = {3}, pages = {363--382}, doi = {10.1002/bimj.201200262}, } @Article{gneiting-raftery-2007, author = {Tilmann Gneiting and Adrian E. Raftery}, title = {Strictly proper scoring rules, prediction, and estimation}, journal = {Journal of the American Statistical Association}, year = {2007}, volume = {102}, number = {477}, pages = {359--378}, doi = {10.1198/016214506000001437}, } @Article{held-etal-2005, author = {Leonhard Held and Michael H{\"o}hle and Mathias Hofmann}, title = {A statistical framework for the analysis of multivariate infectious disease surveillance counts}, journal = {Statistical Modelling}, year = {2005}, volume = {5}, number = {3}, pages = {187--199}, doi = {10.1191/1471082X05st098oa}, } @Article{held.paul2012, author = {Held, Leonhard and Paul, Michaela}, title = {Modeling seasonality in space-time infectious disease surveillance data}, journal = {Biometrical Journal}, year = {2012}, volume = {54}, number = {6}, pages = {824--843}, doi = {10.1002/bimj.201200037}, } @Article{herzog-etal-2010, author = {Herzog, S. A. and Paul, M. and Held, L.}, title = {Heterogeneity in vaccination coverage explains the size and occurrence of measles epidemics in {German} surveillance data}, journal = {Epidemiology and Infection}, year = {2011}, volume = {139}, number = {4}, pages = {505--515}, doi = {10.1017/S0950268810001664}, } @Article{hoehle-2007, author = {H{\"o}hle, M.}, title = {\texttt{surveillance}: {A}n \textsf{R} package for the monitoring of infectious diseases}, journal = {Computational Statistics}, year = {2007}, volume = {22}, number = {4}, pages = {571--582}, doi = {10.1007/s00180-007-0074-8}, } @Article{hoehle2009, author = {Michael H{\"o}hle}, title = {Additive-multiplicative regression models for spatio-temporal epidemics}, journal = {Biometrical Journal}, year = {2009}, volume = {51}, number = {6}, pages = {961--978}, doi = {10.1002/bimj.200900050}, } @Article{hoehle.anderheiden2014, author = {Michael H{\"o}hle and Matthias {an der Heiden}}, title = {{Bayesian} nowcasting during the {STEC} {O104:H4} outbreak in {Germany}, 2011}, journal = {Biometrics}, year = {2014}, volume = {70}, number = {4}, pages = {993--1002}, doi = {10.1111/biom.12194}, } @InCollection{hoehle-mazick-2010, author = {H{\"o}hle, M. and Mazick, A.}, title = {Aberration detection in \textsf{R} illustrated by {Danish} mortality monitoring}, booktitle = {Biosurveillance: Methods and Case Studies}, publisher = {Chapman \& Hall/CRC}, year = {2010}, editor = {Kass-Hout, T. and Zhang, X.}, chapter = {12}, pages = {215--238}, } @Article{hoehle.paul2008, author = {Michael H{\"o}hle and Michaela Paul}, title = {Count data regression charts for the monitoring of surveillance time series}, journal = {Computational Statistics and Data Analysis}, year = {2008}, volume = {52}, number = {9}, pages = {4357--4368}, doi = {10.1016/j.csda.2008.02.015}, } @Article{hughes.king2003, author = {Anthony W. Hughes and Maxwell L. King}, title = {Model selection using {AIC} in the presence of one-sided information}, journal = {Journal of Statistical Planning and Inference}, year = {2003}, volume = {115}, number = {2}, pages = {397--411}, doi = {10.1016/S0378-3758(02)00159-3}, } @Article{hutwagner2005, author = {L. Hutwagner and T. Browne and G.M Seeman and A.T. Fleischhauer}, title = {Comparing aberration detection methods with simulated data}, journal = {Emerging Infectious Diseases}, year = {2005}, volume = {11}, pages = {314--316}, doi = {10.3201/eid1102.040587}, } @Article{bulletin3901, author = {{Robert Koch-Institut}}, title = {{G}ruppenerkrankung in {B}aden-{W}{\"u}rttemberg: {V}erdacht auf {K}ryptosporidiose}, journal = {Epidemiologisches Bulletin}, volume = {39}, year = {2001}, pages = {298--299}, } @Book{Keeling.Rohani2008, title = {Modeling Infectious Diseases in Humans and Animals}, publisher = {Princeton University Press}, year = {2008}, author = {Matt J. Keeling and Pejman Rohani}, url = {http://www.modelinginfectiousdiseases.org/}, } @Misc{survstat, author = {{Robert Koch-Institut}}, title = {{SurvStat@RKI}}, howpublished = {\url{https://survstat.rki.de/}}, year = {2004}, note = {Date of query: September 2004}, } @Misc{survstat-fluByBw, author = {{Robert Koch-Institut}}, title = {{SurvStat@RKI}}, howpublished = {\url{https://survstat.rki.de/}}, year = {2009}, note = {Accessed March 2009}, } @Article{lai95, author = {T. L. Lai}, title = {Sequential changepoint detection in quality control and dynamical systems}, journal = {Journal of the Royal Statistical Society. Series B (Methodological)}, year = {1995}, volume = {57}, number = {4}, pages = {613--658}, } @Article{manitz.hoehle2013, author = {Juliane Manitz and Michael H{\"o}hle}, title = {Bayesian outbreak detection algorithm for monitoring reported cases of campylobacteriosis in {Germany}}, journal = {Biometrical Journal}, year = {2013}, volume = {55}, number = {4}, pages = {509--526}, doi = {10.1002/bimj.201200141}, } @Book{Martinussen.Scheike2006, title = {Dynamic Regression Models for Survival Data}, publisher = {Springer-Verlag}, year = {2006}, author = {Martinussen, Torben and Scheike, Thomas H.}, series = {Statistics for Biology and Health}, } @Article{meyer.etal2011, author = {Sebastian Meyer and Johannes Elias and Michael H{\"o}hle}, title = {A space-time conditional intensity model for invasive meningococcal disease occurrence}, journal = {Biometrics}, year = {2012}, volume = {68}, number = {2}, pages = {607--616}, doi = {10.1111/j.1541-0420.2011.01684.x}, } @Article{meyer.held2015, author = {Sebastian Meyer and Leonhard Held}, title = {Incorporating social contact data in spatio-temporal models for infectious disease spread}, journal = {Biostatistics}, year = {2017}, volume = {18}, number = {2}, pages = {338--351}, doi = {10.1093/biostatistics/kxw051}, } @Article{meyer.held2013, author = {Sebastian Meyer and Leonhard Held}, title = {Power-law models for infectious disease spread}, journal = {Annals of Applied Statistics}, year = {2014}, volume = {8}, number = {3}, pages = {1612--1639}, doi = {10.1214/14-AOAS743}, } @Article{meyer.etal2014, author = {Sebastian Meyer and Leonhard Held and Michael H{\"o}hle}, title = {Spatio-temporal analysis of epidemic phenomena using the \textsf{R} package \texttt{surveillance}}, journal = {Journal of Statistical Software}, year = {2017}, volume = {77}, number = {11}, pages = {1--55}, doi = {10.18637/jss.v077.i11}, } @Article{meyer.etal2015, author = {Sebastian Meyer and Ingeborg Warnke and Wulf R{\"o}ssler and Leonhard Held}, title = {Model-based testing for space-time interaction using point processes: {A}n application to psychiatric hospital admissions in an urban area}, journal = {Spatial and Spatio-temporal Epidemiology}, year = {2016}, volume = {17}, pages = {15--25}, doi = {10.1016/j.sste.2016.03.002}, } @Article{neal.roberts2004, author = {Neal, P. J. and Roberts, G. O.}, title = {Statistical inference and model selection for the 1861~{Hagelloch} measles epidemic}, journal = {Biostatistics}, year = {2004}, volume = {5}, number = {2}, pages = {249--261}, doi = {10.1093/biostatistics/5.2.249}, } @Article{ogata1988, author = {Yosihiko Ogata}, title = {Statistical models for earthquake occurrences and residual analysis for point processes}, journal = {Journal of the American Statistical Association}, year = {1988}, volume = {83}, number = {401}, pages = {9--27}, } @Article{paul-held-2011, author = {Michaela Paul and Leonhard Held}, title = {Predictive assessment of a non-linear random effects model for multivariate time series of infectious disease counts}, journal = {Statistics in Medicine}, year = {2011}, volume = {30}, number = {10}, pages = {1118--1136}, doi = {10.1002/sim.4177}, } @Article{paul-etal-2008, author = {Michaela Paul and Leonhard Held and Andr{\'e} Michael Toschke}, title = {Multivariate modelling of infectious disease surveillance data}, journal = {Statistics in Medicine}, year = {2008}, volume = {27}, number = {29}, pages = {6250--6267}, doi = {10.1002/sim.3440}, } @MastersThesis{riebler2004, author = {A. Riebler}, title = {{Empirischer Vergleich von statistischen Methoden zur Ausbruchserkennung bei Surveillance Daten}}, school = {Department of Statistics, University of Munich}, year = {2004}, type = {Bachelor's thesis}, } @Article{salmon.etal2014, author = {Ma{\"e}lle Salmon and Dirk Schumacher and Michael H{\"o}hle}, title = {Monitoring count time series in \textsf{R}: {A}berration detection in public health surveillance}, journal = {Journal of Statistical Software}, year = {2016}, volume = {70}, number = {10}, pages = {1--35}, doi = {10.18637/jss.v070.i10}, } @Book{Silvapulle.Sen2005, title = {Constrained Statistical Inference: Order, Inequality, and Shape Constraints}, publisher = {Wiley}, year = {2005}, author = {Silvapulle, Mervyn J. and Sen, Pranab Kumar}, series = {Wiley Series in Probability and Statistics}, isbn = {0-471-20827-2}, doi = {10.1002/9781118165614}, } @Article{stroup89, author = {D.F. Stroup and G.D. Williamson and J.L. Herndon and J.M. Karon}, title = {Detection of aberrations in the occurrence of notifiable diseases surveillance data}, journal = {Statistics in Medicine}, year = {1989}, volume = {8}, pages = {323--329}, doi = {10.1002/sim.4780080312}, } @Article{wei.held2013, author = {Wei, Wei and Held, Leonhard}, title = {Calibration tests for count data}, journal = {Test}, year = {2014}, volume = {23}, number = {4}, pages = {787--805}, doi = {10.1007/s11749-014-0380-8}, } @Article{ruckdeschel.kohl2014, author = {Peter Ruckdeschel and Matthias Kohl}, title = {General purpose convolution algorithm in {S4} classes by means of {FFT}}, journal = {Journal of Statistical Software}, year = {2014}, volume = {59}, number = {4}, pages = {1--25}, doi = {10.18637/jss.v059.i04}, } @Article{meyer2019, author = {Sebastian Meyer}, title = {\texttt{polyCub}: An \textsf{R} package for integration over polygons}, journal = {Journal of Open Source Software}, year = {2019}, volume = {4}, number = {34}, pages = {1056}, doi = {10.21105/joss.01056}, } @Manual{R:rmapshaper, title = {\texttt{rmapshaper}: Client for 'mapshaper' for 'Geospatial' Operations}, author = {Andy Teucher and Kenton Russell}, year = {2020}, url = {https://CRAN.R-project.org/package=rmapshaper}, } @Book{R:ggplot2, author = {Hadley Wickham}, title = {ggplot2: Elegant Graphics for Data Analysis}, publisher = {Springer-Verlag}, address = {New York}, year = {2016}, isbn = {978-3-319-24277-4}, url = {https://ggplot2.tidyverse.org}, } @Book{R:spatstat, title = {Spatial Point Patterns: Methodology and Applications with {R}}, author = {Adrian Baddeley and Ege Rubak and Rolf Turner}, year = {2015}, publisher = {Chapman and Hall/CRC}, address = {London}, isbn = {978-1-4822-1020-0}, } @Manual{R:quadprog, title = {\texttt{quadprog}: Functions to Solve Quadratic Programming Problems}, author = {Berwin A. Turlach and Andreas Weingessel}, year = {2019}, url = {https://CRAN.R-project.org/package=quadprog}, } @Article{R:animation, title = {\texttt{animation}: An R Package for Creating Animations and Demonstrating Statistical Methods}, author = {Yihui Xie}, journal = {Journal of Statistical Software}, year = {2013}, volume = {53}, number = {1}, pages = {1--27}, doi = {10.18637/jss.v053.i01}, } @Article{R:spdep, author = {Roger Bivand}, title = {R Packages for Analyzing Spatial Data: A Comparative Case Study with Areal Data}, journal = {Geographical Analysis}, year = {2022}, volume = {54}, number = {3}, pages = {488--518}, doi = {10.1111/gean.12319}, } surveillance/vignettes/.install_extras0000644000176200001440000000003014614655020020007 0ustar liggesusersmonitoringCounts-cache$ surveillance/vignettes/twinSIR.Rnw0000644000176200001440000006131514430704663017022 0ustar liggesusers%\VignetteIndexEntry{twinSIR: Individual-level epidemic modeling for a fixed population with known distances} %\VignetteEngine{knitr::knitr} %% additional dependencies beyond what is required for surveillance anyway: %\VignetteDepends{surveillance, quadprog} <>= ## purl=FALSE => not included in the tangle'd R script knitr::opts_chunk$set(echo = TRUE, tidy = FALSE, results = 'markup', fig.path='plots/twinSIR-', fig.width = 8, fig.height = 4.5, fig.align = "center", fig.scap = NA, out.width = NULL, cache = FALSE, error = FALSE, warning = FALSE, message = FALSE) knitr::render_sweave() # use Sweave environments knitr::set_header(highlight = '') # no \usepackage{Sweave} (part of jss class) ## R settings options(prompt = "R> ", continue = "+ ", useFancyQuotes = FALSE) # JSS options(width = 85, digits = 4) options(scipen = 1) # so that 1e-4 gets printed as 0.0001 ## xtable settings options(xtable.booktabs = TRUE, xtable.size = "small", xtable.sanitize.text.function = identity, xtable.comment = FALSE) @ \documentclass[nojss,nofooter,article]{jss} \title{% \vspace{-1.5cm} \fbox{\vbox{\normalfont\footnotesize This introduction to the \code{twinSIR} modeling framework of the \proglang{R}~package \pkg{surveillance} is based on a publication in the \textit{Journal of Statistical Software} -- \citet[Section~4]{meyer.etal2014} -- which is the suggested reference if you use the \code{twinSIR} implementation in your own work.}}\\[1cm] \code{twinSIR}: Individual-level epidemic modeling for a fixed population with known distances} \Plaintitle{twinSIR: Individual-level epidemic modeling for a fixed population with known distances} \Shorttitle{Modeling epidemics in a fixed population with known distances} \author{Sebastian Meyer\thanks{Author of correspondence: \email{seb.meyer@fau.de}}\\Friedrich-Alexander-Universit{\"a}t\\Erlangen-N{\"u}rnberg \And Leonhard Held\\University of Zurich \And Michael H\"ohle\\Stockholm University} \Plainauthor{Sebastian Meyer, Leonhard Held, Michael H\"ohle} %% Basic packages \usepackage{lmodern} % successor of CM -> searchable Umlauts (1 char) \usepackage[english]{babel} % language of the manuscript is American English %% Math packages \usepackage{amsmath,amsfonts} % amsfonts defines \mathbb \usepackage{bm} % \bm: alternative to \boldsymbol from amsfonts %% Packages for figures and tables \usepackage{booktabs} % make tables look nicer \usepackage{subcaption} % successor of subfig, which supersedes subfigure %% knitr uses \subfloat, which subcaption only provides since v1.3 (2019/08/31) \providecommand{\subfloat}[2][need a sub-caption]{\subcaptionbox{#1}{#2}} %% Handy math commands \newcommand{\abs}[1]{\lvert#1\rvert} \newcommand{\norm}[1]{\lVert#1\rVert} \newcommand{\given}{\,\vert\,} \newcommand{\dif}{\,\mathrm{d}} \newcommand{\IR}{\mathbb{R}} \newcommand{\IN}{\mathbb{N}} \newcommand{\ind}{\mathbb{I}} \DeclareMathOperator{\Po}{Po} \DeclareMathOperator{\NegBin}{NegBin} \DeclareMathOperator{\N}{N} %% Additional commands \newcommand{\class}[1]{\code{#1}} % could use quotes (JSS does not like them) \newcommand{\CRANpkg}[1]{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}} %% Reduce the font size of code input and output \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl, fontsize=\small} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\small} %% Abstract \Abstract{ The availability of geocoded health data and the inherent temporal structure of communicable diseases have led to an increased interest in statistical models and software for spatio-temporal data with epidemic features. The \proglang{R}~package \pkg{surveillance} can handle various levels of aggregation at which infective events have been recorded. This vignette illustrates the analysis of individual-level surveillance data for a fixed population, of which the complete SIR event history is assumed to be known. Typical applications for the multivariate, temporal point process model ``\code{twinSIR}'' of \citet{hoehle2009} include the spread of infectious livestock diseases across farms, household models for childhood diseases, and epidemics across networks. %% (For other types of surveillance data, see %% \code{vignette("twinstim")} and \code{vignette("hhh4\_spacetime")}.) We first describe the general modeling approach and then exemplify data handling, model fitting, and visualization for a particularly well-documented measles outbreak among children of the isolated German village Hagelloch in 1861. %% Due to the many similarities with the spatio-temporal point process model %% ``\code{twinstim}'' described and illustrated in \code{vignette("twinstim")}, %% we condense the \code{twinSIR} treatment accordingly. } \Keywords{% individual-level surveillance data, endemic-epidemic modeling, infectious disease epidemiology, self-exciting point process, branching process with immigration} \begin{document} <>= ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("twinSIR-cache.RData")) if (!COMPUTE) load("twinSIR-cache.RData", verbose = TRUE) @ \section[Model class]{Model class: \code{twinSIR}} \label{sec:twinSIR:methods} The spatio-temporal point process regression model ``\code{twinstim}'' (\citealp{meyer.etal2011}, illustrated in \code{vignette("twinstim")}) is indexed in a continuous spatial domain, i.e., the set of possible event locations %(the susceptible ``population'') consists of the whole observation region and is thus infinite. In contrast, if infections can only occur at a known discrete set of sites, such as for livestock diseases among farms, the conditional intensity function (CIF) of the underlying point process formally becomes $\lambda_i(t)$. It characterizes the instantaneous rate of infection of individual $i$ at time $t$, given the sets $S(t)$ and $I(t)$ of susceptible and infectious individuals, respectively (just before time $t$). %In a similar regression view as in \code{vignette("twinstim")}, \citet{hoehle2009} proposed the following endemic-epidemic multivariate temporal point process model (``\code{twinSIR}''): \begin{equation} \label{eqn:twinSIR} \lambda_i(t) = \lambda_0(t) \, \nu_i(t) + \sum_{j \in I(t)} \left\{ f(d_{ij}) + \bm{w}_{ij}^\top \bm{\alpha}^{(w)} \right\} \:, %\qquad \text{if } i \in S(t)\:, \end{equation} if $i \in S(t)$, i.e., if individual $i$ is currently susceptible, and $\lambda_i(t) = 0$ otherwise. The rate decomposes into two components. The first, endemic component consists of a Cox proportional hazards formulation containing a semi-parametric baseline hazard $\lambda_0(t)$ and a log-linear predictor $\nu_i(t)=\exp\left( \bm{z}_i(t)^\top \bm{\beta} \right)$ of covariates modeling infection from external sources. Furthermore, an additive epidemic component captures transmission from the set $I(t)$ of currently infectious individuals. The force of infection of individual $i$ depends on the distance $d_{ij}$ to each infective source $j \in I(t)$ through a distance kernel \begin{equation} \label{eqn:twinSIR:f} f(u) = \sum_{m=1}^M \alpha_m^{(f)} B_m(u) \: \geq 0 \:, \end{equation} which is represented by a linear combination of non-negative basis functions $B_m$ with the $\alpha_m^{(f)}$'s being the respective coefficients. For instance, $f$ could be modeled by a B-spline \citep[Section~8.1]{Fahrmeir.etal2013}, and $d_{ij}$ could refer to the Euclidean distance $\norm{\bm{s}_i - \bm{s}_j}$ between the individuals' locations $\bm{s}_i$ and $\bm{s}_j$, or to the geodesic distance between the nodes $i$ and $j$ in a network. The distance-based force of infection is modified additively by a linear predictor of covariates $\bm{w}_{ij}$ describing the interaction of individuals $i$ and~$j$ further. Hence, the whole epidemic component of Equation~\ref{eqn:twinSIR} can be written as a single linear predictor $\bm{x}_i(t)^\top \bm{\alpha}$ by interchanging the summation order to \begin{equation} \label{eqn:twinSIR:x} \sum_{m=1}^M \alpha^{(f)}_m \sum_{j \in I(t)} B_m(d_{ij}) + \sum_{k=1}^K \alpha^{(w)}_k \sum_{j \in I(t)} w_{ijk} = \bm{x}_i(t)^\top \bm{\alpha} \:, \end{equation} such that $\bm{x}_i(t)$ comprises all epidemic terms summed over $j\in I(t)$. Note that the use of additive covariates $\bm{w}_{ij}$ on top of the distance kernel in \eqref{eqn:twinSIR} is different from \code{twinstim}'s multiplicative approach. One advantage of the additive approach is that the subsequent linear decomposition of the distance kernel allows one to gather all parts of the epidemic component in a single linear predictor. Hence, the above model represents a CIF extension of what in the context of survival analysis is known as an additive-multiplicative hazard model~\citep{Martinussen.Scheike2006}. As a consequence, the \code{twinSIR} model could in principle be fitted with the \CRANpkg{timereg} package, which yields estimates for the cumulative hazards. However, \citet{hoehle2009} chooses a more direct inferential approach: To ensure that the CIF $\lambda_i(t)$ is non-negative, all covariates are encoded such that the components of $\bm{w}_{ij}$ are non-negative. Additionally, the parameter vector $\bm{\alpha}$ is constrained to be non-negative. Subsequent parameter inference is then based on the resulting constrained penalized likelihood which gives directly interpretable estimates of $\bm{\alpha}$. Future work could investigate the potential of a multiplicative approach for the epidemic component in \code{twinSIR}. \section[Data structure]{Data structure: \class{epidata}} \label{sec:twinSIR:data} New SIR-type event data typically arrive in the form of a simple data frame with one row per individual and sequential event time points as columns. For the 1861 Hagelloch measles epidemic, which has previously been analyzed by, e.g., \citet{neal.roberts2004}, such a data set of the 188 affected children is contained in the \pkg{surveillance} package: <>= data("hagelloch") head(hagelloch.df, n = 5) @ The \code{help("hagelloch")} contains a description of all columns. Here we concentrate on the event columns \code{PRO} (appearance of prodromes), \code{ERU} (eruption), and \code{DEAD} (day of death if during the outbreak). We take the day on which the index case developed first symptoms, 30 October 1861 (\code{min(hagelloch.df$PRO)}), as the start of the epidemic, i.e., we condition on this case being initially infectious. % t0 = 1861-10-31 00:00:00 As for \code{twinstim}, the property of point processes that concurrent events have zero probability requires special treatment. Ties are due to the interval censoring of the data to a daily basis -- we broke these ties by adding random jitter to the event times within the given days. The resulting columns \code{tPRO}, \code{tERU}, and \code{tDEAD} are relative to the defined start time. Following \citet{neal.roberts2004}, we assume that each child becomes infectious (S~$\rightarrow$~I event at time \code{tI}) one day before the appearance of prodromes, and is removed from the epidemic (I~$\rightarrow$~R event at time \code{tR}) three days after the appearance of rash or at the time of death, whichever comes first. For further processing of the data, we convert \code{hagelloch.df} to the standardized \class{epidata} structure for \code{twinSIR}. This is done by the converter function \code{as.epidata}, which also checks consistency and optionally pre-calculates the epidemic terms $\bm{x}_i(t)$ of Equation~\ref{eqn:twinSIR:x} to be incorporated in a \code{twinSIR} model. The following call generates the \class{epidata} object \code{hagelloch}: <>= hagelloch <- as.epidata(hagelloch.df, t0 = 0, tI.col = "tI", tR.col = "tR", id.col = "PN", coords.cols = c("x.loc", "y.loc"), f = list(household = function(u) u == 0, nothousehold = function(u) u > 0), w = list(c1 = function (CL.i, CL.j) CL.i == "1st class" & CL.j == CL.i, c2 = function (CL.i, CL.j) CL.i == "2nd class" & CL.j == CL.i), keep.cols = c("SEX", "AGE", "CL")) @ The coordinates (\code{x.loc}, \code{y.loc}) correspond to the location of the household the child lives in and are measured in meters. Note that \class{twinSIR} allows for tied locations of individuals, but assumes the relevant spatial location to be fixed during the entire observation period. By default, the Euclidean distance between the given coordinates will be used. Alternatively, \code{as.epidata} also accepts a pre-computed distance matrix via its argument \code{D} without requiring spatial coordinates. The argument \code{f} lists distance-dependent basis functions $B_m$ for which the epidemic terms $\sum_{j\in I(t)} B_m(d_{ij})$ shall be generated. Here, \code{household} ($x_{i,H}(t)$) and \code{nothousehold} ($x_{i,\bar{H}}(t)$) count for each child the number of currently infective children in its household and outside its household, respectively. Similar to \citet{neal.roberts2004}, we also calculate the covariate-based epidemic terms \code{c1} ($x_{i,c1}(t)$) and \code{c2} ($x_{i,c2}(t)$) % from $w_{ijk} = \ind(\code{CL}_i = k, \code{CL}_j = \code{CL}_i)$ counting the number of currently infective classmates. Note from the corresponding definitions of $w_{ij1}$ and $w_{ij2}$ in \code{w} that \code{c1} is always zero for children of the second class and \code{c2} is always zero for children of the first class. For pre-school children, both variables equal zero over the whole period. By the last argument \code{keep.cols}, we choose to only keep the covariates \code{SEX}, \code{AGE}, and school \code{CL}ass from \code{hagelloch.df}. The first few rows of the generated \class{epidata} object are shown below: <>= head(hagelloch, n = 5) @ The \class{epidata} structure inherits from counting processes as implemented by the \class{Surv} class of package \CRANpkg{survival} and also used in \CRANpkg{timereg}. Specifically, the observation period is split up into consecutive time intervals (\code{start}; \code{stop}] of constant conditional intensities. As the CIF $\lambda_i(t)$ of Equation~\eqref{eqn:twinSIR} only changes at time points, where the set of infectious individuals $I(t)$ or some endemic covariate in $\nu_i(t)$ change, those occurrences define the break points of the time intervals. Altogether, the \code{hagelloch} event history consists of \Sexpr{nrow(hagelloch)/nlevels(hagelloch$id)} time \code{BLOCK}s of \Sexpr{nlevels(hagelloch[["id"]])} rows, where each row describes the state of individual \code{id} during the corresponding time interval. The susceptibility status and the I- and R-events are captured by the columns \code{atRiskY}, \code{event} and \code{Revent}, respectively. The \code{atRiskY} column indicates if the individual is at risk of becoming infected in the current interval. The event columns indicate, which individual was infected or removed at the \code{stop} time. Note that at most one entry in the \code{event} and \code{Revent} columns is 1, all others are 0. Apart from being the input format for \code{twinSIR} models, the \class{epidata} class has several associated methods (Table~\ref{tab:methods:epidata}), which are similar in spirit to the methods described for \class{epidataCS}. <>= print(xtable( surveillance:::functionTable("epidata", list(Display = c("stateplot"))), caption="Generic and \\textit{non-generic} functions applicable to \\class{epidata} objects.", label="tab:methods:epidata"), include.rownames = FALSE) @ For example, Figure~\ref{fig:hagelloch_plot} illustrates the course of the Hagelloch measles epidemic by counting processes for the number of susceptible, infectious and removed children, respectively. Figure~\ref{fig:hagelloch_households} shows the locations of the households. An \code{animate}d map can also be produced to view the households' states over time and a simple \code{stateplot} shows the changes for a selected unit. <>= par(mar = c(5, 5, 1, 1)) plot(hagelloch, xlab = "Time [days]") @ <>= par(mar = c(5, 5, 1, 1)) hagelloch_coords <- summary(hagelloch)$coordinates plot(hagelloch_coords, xlab = "x [m]", ylab = "y [m]", pch = 15, asp = 1, cex = sqrt(multiplicity(hagelloch_coords))) legend(x = "topleft", pch = 15, legend = c(1, 4, 8), pt.cex = sqrt(c(1, 4, 8)), title = "Household size") @ \section{Modeling and inference} \label{sec:twinSIR:fit} \subsection{Basic example} To illustrate the flexibility of \code{twinSIR} we will analyze the Hagelloch data using class room and household indicators similar to \citet{neal.roberts2004}. We include an additional endemic background rate $\exp(\beta_0)$, which allows for multiple outbreaks triggered by external sources. Consequently, we do not need to ignore the child that got infected about one month after the end of the main epidemic (see the last event mark in Figure~\ref{fig:hagelloch_plot}). % ATM, there is no way to fit a twinSIR without an endemic component. Altogether, the CIF for a child $i$ is modeled as \begin{equation} \label{eqn:twinSIR:hagelloch} \lambda_i(t) = Y_i(t) \cdot \left[ \exp(\beta_0) + \alpha_H x_{i,H}(t) + \alpha_{c1} x_{i,c1}(t) + \alpha_{c2} x_{i,c2}(t) + \alpha_{\bar{H}} x_{i,\bar{H}}(t) \right] \:, \end{equation} where $Y_i(t) = \ind(i \in S(t))$ is the at-risk indicator. By counting the number of infectious classmates separately for both school classes as described in the previous section, we allow for class-specific effects $\alpha_{c1}$ and $\alpha_{c2}$ on the force of infection. The model is estimated by maximum likelihood \citep{hoehle2009} using the call <>= hagellochFit <- twinSIR(~household + c1 + c2 + nothousehold, data = hagelloch) @ and the fit is summarized below: <>= set.seed(1) summary(hagellochFit) @ <>= ## drop leading and trailing empty lines writeLines(tail(head(capture.output({ <> }), -1), -1)) @ The results show, e.g., a \Sexpr{sprintf("%.4f",coef(hagellochFit)["c1"])} / \Sexpr{sprintf("%.4f",coef(hagellochFit)["c2"])} $=$ \Sexpr{format(coef(hagellochFit)["c1"]/coef(hagellochFit)["c2"])} times higher transmission between individuals in the 1st class than in the 2nd class. Furthermore, an infectious housemate adds \Sexpr{sprintf("%.4f",coef(hagellochFit)["household"])} / \Sexpr{sprintf("%.4f",coef(hagellochFit)["nothousehold"])} $=$ \Sexpr{format(coef(hagellochFit)["household"]/coef(hagellochFit)["nothousehold"])} times as much infection pressure as infectious children outside the household. The endemic background rate of infection in a population with no current measles cases is estimated to be $\exp(\hat{\beta}_0) = \exp(\Sexpr{format(coef(hagellochFit)["cox(logbaseline)"])}) = \Sexpr{format(exp(coef(hagellochFit)["cox(logbaseline)"]))}$. An associated Wald confidence interval (CI) based on the asymptotic normality of the maximum likelihood estimator (MLE) can be obtained by \code{exp}-transforming the \code{confint} for $\beta_0$: <>= exp(confint(hagellochFit, parm = "cox(logbaseline)")) @ Note that Wald confidence intervals for the epidemic parameters $\bm{\alpha}$ are to be treated carefully, because their construction does not take the restricted parameter space into account. For more adequate statistical inference, the behavior of the log-likelihood near the MLE can be investigated using the \code{profile}-method for \class{twinSIR} objects. For instance, to evaluate the normalized profile log-likelihood of $\alpha_{c1}$ and $\alpha_{c2}$ on an equidistant grid of 25 points within the corresponding 95\% Wald CIs, we do: <>= prof <- profile(hagellochFit, list(c(match("c1", names(coef(hagellochFit))), NA, NA, 25), c(match("c2", names(coef(hagellochFit))), NA, NA, 25))) @ The profiling result contains 95\% highest likelihood based CIs for the parameters, as well as the Wald CIs for comparison: <<>>= prof$ci.hl @ The entire functional form of the normalized profile log-likelihood on the requested grid as stored in \code{prof$lp} can be visualized by: <>= plot(prof) @ The above model summary also reports the one-sided AIC~\citep{hughes.king2003}, which can be used for model selection under positivity constraints on $\bm{\alpha}$ as described in \citet{hoehle2009}. The involved parameter penalty is determined by Monte Carlo simulation, which is why we did \code{set.seed} before the \code{summary} call. The algorithm is described in \citet[p.~79, Simulation 3]{Silvapulle.Sen2005} and involves quadratic programming using package \CRANpkg{quadprog} \citep{R:quadprog}. If there are less than three constrained parameters in a \code{twinSIR} model, the penalty is computed analytically. \subsection{Model diagnostics} <>= print(xtable( surveillance:::functionTable("twinSIR", functions=list(Display = c("checkResidualProcess"))), caption="Generic and \\textit{non-generic} functions for \\class{twinSIR}. There are no specific \\code{coef} or \\code{confint} methods, since the respective default methods from package \\pkg{stats} apply outright.", label="tab:methods:twinSIR"), include.rownames = FALSE) @ Table~\ref{tab:methods:twinSIR} lists all methods for the \class{twinSIR} class. For example, to investigate how the conditional intensity function decomposes into endemic and epidemic components over time, we produce Figure~\ref{fig:hagellochFit_plot-1} by: <>= par(mar = c(5, 5, 1, 1)) plot(hagellochFit, which = "epidemic proportion", xlab = "time [days]") checkResidualProcess(hagellochFit, plot = 1) @ Note that the last infection was necessarily caused by the endemic component since there were no more infectious children in the observed population which could have triggered the new case. We can also inspect temporal Cox-Snell-like \code{residuals} of the fitted point process using the function \code{checkResidualProcess} as for the spatio-temporal point process models in \code{vignette("twinstim")}. The resulting Figure~\ref{fig:hagellochFit_plot-2} reveals some deficiencies of the model in describing the waiting times between events, which might be related to the assumption of fixed infection periods. <>= knots <- c(100, 200) fstep <- list( B1 = function(D) D > 0 & D < knots[1], B2 = function(D) D >= knots[1] & D < knots[2], B3 = function(D) D >= knots[2]) @ To illustrate AIC-based model selection, we may consider a more flexible model for local spread using a step function for the distance kernel $f(u)$ in Equation \ref{eqn:twinSIR:f}. An updated model with <>= .allknots <- c(0, knots, "\\infty") cat(paste0("$B_{", seq_along(fstep), "} = ", "I_{", ifelse(seq_along(fstep)==1,"(","["), .allknots[-length(.allknots)], ";", .allknots[-1], ")}(u)$", collapse = ", ")) @ can be fitted as follows: <>= <> hagellochFit_fstep <- twinSIR( ~household + c1 + c2 + B1 + B2 + B3, data = update(hagelloch, f = fstep)) @ <>= set.seed(1) AIC(hagellochFit, hagellochFit_fstep) @ Hence the simpler model with just a \code{nothousehold} component instead of the more flexible distance-based step function is preferred. \section{Simulation} \label{sec:twinSIR:simulation} Simulation from fitted \code{twinSIR} models is described in detail in~\citet[Section~4]{hoehle2009}. The implementation is made available by an appropriate \code{simulate}-method for class \class{twinSIR}. We skip the illustration here and refer to \code{help("simulate.twinSIR")}. %-------------- % BIBLIOGRAPHY %-------------- \bibliography{references} <>= save(prof, file = "twinSIR-cache.RData") @ \end{document} surveillance/vignettes/surveillance-cache.RData0000644000176200001440000002227514176017575021455 0ustar liggesusers] n@0걢4Snoֿ=^>] q"qt9fJ2PI_EVh:'yúTI*lfvmk}t~xl͕Ni]O.>/WI.W}-T)R2)r )婸T߀+C6y5c%<*/3]*C:CF^Y*,(`EQg-tn"޲:14^t{h-H"DB0v02X/OYy*_CFӐQc<'nďb }qǬ?}\Q9~u/he}J׍77L2*J%D?&oJ1|M'yJ+ 1N1{̰wfVŪ vak>vh~`KQyQ)6t`d<P&J#G 3'&DRS3_(eȄE&a^g:0٢"0JK`'<&4 ":kܠ~,(G҆bA%)x֤ؐbKJ;RړbGJRIq #),uaY# )Τ乒F;)BR3Z!n@V`nNOX1#!Gؾ4 ^hxB.t8"eCKXq7# ^p 7(<st47̷좣߄tҶg~?.q05eLcf1l淺L WCƏibzch%W8W)#[L-fj 2Zfj1S[πagX5?DQ_¿~9#%c-0[uӟ xX.%&ח⾨/`)S^LbVR>˿.?^[_,S~|,c 2Xc1[πagX5?DQ_c1KX`XPi> cKxS__; X*'ȋђVnCi+J[SڂkIiJsh>SZ]B,&w:?]o#1/>xN3PlmöfkqC󱘏%0/c1K|l=~_QcFc U>zDzG,uR,au}БAZkv_φt8dkG86-E'ijv@q8KWwt;*$M{>q>giq4l ӵ%0]/k1]Ktm=~QcFk t-k%XBcw;5?u@rѶlMgi}E˥фҴ\_iJuOrqjuKS]Bbӵkt-k ӵgx2C+)X~RZ{(Z=p9Xx3 l 0 =\1 4VD Su֙5/ X{F8,z\yyb N{6 pi`- O7׷#ynpr?ۭS88J-^018Y&'l8i߻E \#H]n! @UQ.|G_N,4OcwӃO]1JvFo;[ Bۅ ;~WE}3Y~!F tM}||xa6Cy2=yz`"`zI#k*GZps0-;2 NT1^`x[Jwd;4]=,͵?+^> cX?@X JK]KV~< mҖb左4_,_;ݯV,mvק4>fek^ѷo/\on m]AԮ_4 Nł̈́5ֹ`q:Z:.tF#YVEPL0M㽏 FnQ.ku?m|ԍݍL;ycU&1ߤ|UjD,ggz&Σ.x.ò7}Lv}$t+i 3DQodڄ'/>Ư=)go6U2+E2Jz2r ZQ1AoɨH$ţ¯ 3)ˇ\w!ߺuEa%]De<*p{ ~Ċ4yt-dV|'յ1 P n+ЫsSҷ),OJ Zƾ =WFA]ߡoZ6*'f;{zd* PgjG2]9Úm">m_>͗u9[z=A񩯊].¢kF΃IhUeg'. =-i6`{ͻ=]{vعP̜5cݯ A'ݾ|I݅*$N-rw]VhO 5Wʷau^nHjԄ>thw\z5hڷ(߭C/eXd]O6{۬ԥ-y-&B؏ɦYA&yQ0_Sl~fNz=FyQGܖ}-x18<ط x%EEyuACoyɼ٠>=DP=*35c2^do8KAˋ\ZXp'~{z jrkI{A{EIWI]QPn;vgn@33ϗcK[SAk޵n^~e! àƿi*[@eRAby b/:ogff !)7.a=ׁmT@^:Ot]_:??cG?-F;8jWT4jF8TIPAĝuP -TޢיǾn^ukOQfIM>ì- QͪWM*AŎ7;dϹla}0(~׺ *_,*{Ngw{P"o^ Ԧfm:iMntHjsΉ3_V_m "7@W_ُqh@`yz-.84L7*t&" bۃ֥J鎰K #Loe7/FG:mR¯j dN# ָ|:f:y+rx m }&?D<}:*n=m֞XrӐwMیN(0н+*E^/7Fݷ_}5t=_|1ٓMX &z`t5C8xȸT64cKyR#h E*XíD/O7 c,Db~DUYDYk77%T+(.2MiJ[Xʵ?eSwJh>ڇJ?Z{PATJGSSݨ7Sz")ݛk\!mePzI /ס"EitVL򧦩a}ƘQERA(z[9+#S[ ] Qv eYnڂ 2IŢKw@*;zM*K;Tk *4i9zZzl3z2*:G7Nqyw[vD;x6^tOn&ѓ1C]뜜վCӽ -*leۨT :@,٣EƎ|D˳JP)YK)tȭ"ߥ"GVY2#+fxzJ=xA|B|]NnՇ;|J?N߮.^E w{QI,Sۥnp6 ss߻A ZQB0onV#5zk w7:'݁;sO%^ omg&58!wg襤Q5`|6%:r]`sX\VW?Zۂy5kqdx+s-z AQkqSs$@X~&Ŗx%[2[Ŗ[Ŗ >Ǫ!  [Nnxe=_lŖUo6t&$M:>!c6ѵ%Z%M$[x6mUkqzqȲeEu;vn u y/G,hqK][hTh蛙ԗ40[#i?}~I^']??ޜ_^96;5Ӯ-|]6{Os⥡͂ ٬FڣTd@_8B0s۩siJ ̌ߕh\63(vvg\mhYsv-t# Az莏MC -=!/ׂ̜ΔSr*iz<^r4^704O=4ȒwG!&\<)ّhqgAl盦jh+>*t:k=RAc~qOC@]UƒR=LBxf1#&CW/Y_y"6|ښ<f\0'?\?2_夭ADޱ.yAzFЦ`  yb̾жEL; @c"ۥYۆ>4mk*K̆2жcx80Onu,X*{=>}s0_f8pO3tҒy>`} z=Nm :>*YuX4߈ Zt7ZN9fAs$N ˟3O5Rk o֭Wx^iTY4"4g:j`+5+Fx[7?ҨVu\}u?[)v3UOx7 wqû]Dwq\oHO- (J7{ҌG~\3áp#pqmɩ6A_qp Jszq/E~YOrRV {_-Ybmz!\i<ހO2g9²!D33܋'~RNf.3kaۯJ穎CΙeD3=gAp\l|S\D%3Wg.Z 8 0W~)#5s1̙'#ܛ#܃ ˰ff:WK. bvy6Aˊ :Wp[/o巫WV5W:j /yt3$qAB׺Hk ݮ<ߟ ?U1ҽ-=Z?=_Mm+$o@T}er8\O3g F'G8Hp #܃\d?_I 9i?fÈK>/ɮ¾3fTa-ڥ[~AggVœrVف s\Vpc7W\ C Wse?$s?1U&W?4mU㙋-8}3O ݘa)'`p=9s-<W=s-+'~J5AC JO;^~]v >^w~Vy>2e>a]\en *ǜ|j7WyD%~ӢW:j W=s&h[ŚIĕWxn|e $ =/3zHz|Mm|UGOW{Isq1G}33g.'YG6WM%N~د鬧<;{>\پEWaKʼޙqz!vY{UG8 xGm13WYEX'ALѐ#k 3|֓#0WurEb[ŶŮbd}Wz@stqض_W*'[ m\7s%3.0.co;2-q}, } @Article{inla, title = {Approximate Bayesian Inference for Latent Gaussian Models Using Integrated Nested Laplace Approximations}, author = {H. Rue and S. Martino and N. Chopin}, journal = {Journal of the Royal Statistical Society B}, year = {2009}, volume = {71}, number = {2}, pages = {319--392}, doi = {10.1111/j.1467-9868.2008.00700.x} } @Manual{xts, title = {\pkg{xts}: eXtensible Time Series}, author = {Jeffrey A. Ryan and Joshua M. Ulrich}, year = {2014}, note = {\proglang{R} package version 0.9-7}, url = {https://CRAN.R-project.org/package=xts}, } @Article{dirk, author = {M. Salmon and D. Schumacher and H. Burmann and C. Frank and H. Claus and M. H{\"o}hle}, title = {A {S}ystem for {A}utomated {O}utbreak {D}etection of {C}ommunicable {D}iseases in {G}ermany}, year = {2016}, volume = {21}, number = {13}, doi = {10.2807/1560-7917.ES.2016.21.13.30180}, } @Article{maelle, author = {M. Salmon and D. Schumacher and K. Stark and M. H{\"o}hle}, title = {{B}ayesian Outbreak Detection in the Presence of Reporting Delays}, journal = {Biometrical Journal}, year = {2015}, volume = {57}, number = {6}, pages = {1051--1067}, doi = {10.1002/bimj.201400159}, } @Article{accident, author = {Anna Schuh and Jaime A. Camelio and William H. Woodall}, title = {Control Charts for Accident Frequency: a Motivation for Real-Time Occupational Safety Monitoring}, journal = {International Journal of Injury Control and Safety Promotion}, year = {2014}, volume = {21}, number = {2}, pages = {154--162}, doi = {10.1080/17457300.2013.792285}, } @Article{qcc, author = {Luca Scrucca}, title = {\pkg{qcc}: An \proglang{R} Package for Quality Control Charting and Statistical Process Control}, journal = {\proglang{R} News}, year = {2004}, volume = {4}, number = {1}, pages = {11--17}, url = {https://CRAN.R-project.org/doc/Rnews/}, } @Article{shmueli2010, author = {Galit Shmueli and Howard Burkom}, title = {Statistical Challenges Facing Early Outbreak Detection in Biosurveillance}, journal = {Technometrics}, year = {2010}, volume = {52}, pages = {39-51}, number = {1}, doi = {10.1198/tech.2010.06134}, } @Article{sonesson2003, author = {Christian Sonesson and David Bock}, title = {A Review and Discussion of Prospective Statistical Surveillance in Public Health}, journal = {Journal of the Royal Statistical Society A}, year = {2003}, volume = {166}, pages = {5--21}, number = {1}, doi = {10.1111/1467-985x.00256}, } @Article{stasjss, author = {D. Mikis Stasinopoulos and Robert A. Rigby}, title = {Generalized Additive Models for Location Scale and Shape (GAMLSS) in \proglang{R}}, journal = {Journal of Statistical Software}, year = {2007}, volume = {23}, pages = {1--46}, number = {7}, doi = {10.18637/jss.v023.i07}, } @Article{steiner1999, author = {S. H. Steiner and R. J. Cook and V. T. Farewell}, title = {Monitoring Paired Binary Surgical Outcomes Using Cumulative Sum Charts}, journal = {Statistics in Medicine}, year = {1999}, volume = {18}, pages = {69--86}, doi = {10.1002/(sici)1097-0258(19990115)18:1<69::aid-sim966>3.0.co;2-l}, } @Manual{outbreaktools, title = {\pkg{OutbreakTools}: Basic Tools for the Analysis of Disease Outbreaks}, author = {{The Hackout Team}}, year = {2016}, note = {\proglang{R} package version 0.1-14}, url = {https://CRAN.R-project.org/package=OutbreakTools}, } @Article{unkel2012, author = {Steffen Unkel and C. Paddy Farrington and Paul H. Garthwaite and Chris Robertson and Nick Andrews}, title = {Statistical Methods for the Prospective Detection of Infectious Disease Outbreaks: A Review}, journal = {Journal of the Royal Statistical Society A}, year = {2012}, volume = {175}, pages = {49--82}, number = {1}, doi = {10.1111/j.1467-985x.2011.00714.x}, } @Manual{testthat2013, title = {\pkg{testthat}: Unit Testing for \proglang{R}}, author = {Hadley Wickham}, year = {2016}, note = {\proglang{R} package version 1.0.2}, url = {https://CRAN.R-project.org/package=testthat}, } @InCollection{knitr, booktitle = {Implementing Reproducible Computational Research}, editor = {Victoria Stodden and Friedrich Leisch and Roger D. Peng}, title = {\pkg{knitr}: A Comprehensive Tool for Reproducible Research in \proglang{R}}, author = {Yihui Xie}, publisher = {Chapman and Hall/CRC}, year = {2014}, } @Article{zoo, author = {Achim Zeileis and Gabor Grothendieck}, title = {\pkg{zoo}: S3 Infrastructure for Regular and Irregular Time Series}, journal = {Journal of Statistical Software}, year = {2005}, volume = {14}, pages = {1--27}, number = {6}, doi = {10.18637/jss.v014.i06}, } @Article{strucchange, author = {Achim Zeileis and Friedrich Leisch and Kurt Hornik and Christian Kleiber}, title = {\pkg{strucchange}: An \proglang{R} Package for Testing for Structural Change in Linear Regression Models}, journal = {Journal of Statistical Software}, year = {2002}, volume = {7}, pages = {1--38}, number = {2}, doi = {10.18637/jss.v007.i02}, } @Manual{mglm, title = {\pkg{MGLM}: Multivariate Response Generalized Linear Models}, author = {Yiwen Zhang and Hua Zhou}, year = {2016}, note = {\proglang{R} package version 0.0.7}, url = {https://CRAN.R-project.org/package=MGLM}, } surveillance/vignettes/twinSIR-cache.RData0000644000176200001440000000324512674766245020322 0ustar liggesusersyTSG$@Q,⊶ -E ւH @a1(T;ĭXѣ[\"*@ t_}$3w7oI]̂4@1 2  hָ4k],Y7Z'azʒ+.38Vз4:0y@Yyi6 sJV9 kk|?ij$fOmped4<@ Le18jxxilG#:׭zc8| [4"X̀CڇH uߠ6];_~wK :OS|d~}}4^cX󅱸aB8$$j`t$1b!jH$%EQ~' 4\V XAEm2q!P|+RUEEm0|6.H澀,ow蔖C`(`d.`ςBof \=VÑMx E'N^qwhq!OKaIsQgںbT4|勝* FVZd~=}P aҐ9- G6C1fWV9(䧐]I/c+9TgX@k}_eH^*oCdtJ*8R$DmFxۤNIa҅A%^o surveillance/vignettes/hhh4_spacetime.Rnw0000644000176200001440000015676114615162374020364 0ustar liggesusers%\VignetteIndexEntry{hhh4 (spatio-temporal): Endemic-epidemic modeling of areal count time series} %\VignetteEngine{knitr::knitr} %% additional dependencies beyond what is required for surveillance anyway: %\VignetteDepends{surveillance, lattice, gsl, colorspace, gridExtra, scales, fanplot, hhh4contacts} <>= ## purl=FALSE => not included in the tangle'd R script knitr::opts_chunk$set(echo = TRUE, tidy = FALSE, results = 'markup', fig.path='plots/hhh4_spacetime-', fig.width = 8, fig.height = 4.5, fig.align = "center", fig.scap = NA, out.width = NULL, cache = FALSE, error = FALSE, warning = FALSE, message = FALSE) knitr::render_sweave() # use Sweave environments knitr::set_header(highlight = '') # no \usepackage{Sweave} (part of jss class) ## R settings options(prompt = "R> ", continue = "+ ", useFancyQuotes = FALSE) # JSS options(width = 85, digits = 4) options(scipen = 1) # so that 1e-4 gets printed as 0.0001 ## xtable settings options(xtable.booktabs = TRUE, xtable.size = "small", xtable.sanitize.text.function = identity, xtable.comment = FALSE) @ \documentclass[nojss,nofooter,article]{jss} \usepackage[utf8]{inputenc} % Rnw is ASCII, but auto-generated bib file isn't % (specification is redundant in LaTeX >= 2018-04-01) \title{% \vspace{-1.5cm} \fbox{\vbox{\normalfont\footnotesize This introduction to spatio-temporal \code{hhh4} models implemented in the \proglang{R}~package \pkg{surveillance} is based on a publication in the \textit{Journal of Statistical Software} -- \citet[Section~5]{meyer.etal2014} -- which is the suggested reference if you use the \code{hhh4} implementation in your own work.}}\\[1cm] \code{hhh4}: Endemic-epidemic modeling\\of areal count time series} \Plaintitle{hhh4: Endemic-epidemic modeling of areal count time series} \Shorttitle{Endemic-epidemic modeling of areal count time series} \author{Sebastian Meyer\thanks{Author of correspondence: \email{seb.meyer@fau.de}}\\Friedrich-Alexander-Universit{\"a}t\\Erlangen-N{\"u}rnberg \And Leonhard Held\\University of Zurich \And Michael H\"ohle\\Stockholm University} \Plainauthor{Sebastian Meyer, Leonhard Held, Michael H\"ohle} %% Basic packages \usepackage{lmodern} % successor of CM -> searchable Umlauts (1 char) \usepackage[english]{babel} % language of the manuscript is American English %% Math packages \usepackage{amsmath,amsfonts} % amsfonts defines \mathbb \usepackage{bm} % \bm: alternative to \boldsymbol from amsfonts %% Packages for figures and tables \usepackage{booktabs} % make tables look nicer \usepackage{subcaption} % successor of subfig, which supersedes subfigure %% knitr uses \subfloat, which subcaption only provides since v1.3 (2019/08/31) \providecommand{\subfloat}[2][need a sub-caption]{\subcaptionbox{#1}{#2}} %% Handy math commands \newcommand{\abs}[1]{\lvert#1\rvert} \newcommand{\norm}[1]{\lVert#1\rVert} \newcommand{\given}{\,\vert\,} \newcommand{\dif}{\,\mathrm{d}} \newcommand{\IR}{\mathbb{R}} \newcommand{\IN}{\mathbb{N}} \newcommand{\ind}{\mathbb{I}} \DeclareMathOperator{\Po}{Po} \DeclareMathOperator{\NegBin}{NegBin} \DeclareMathOperator{\N}{N} %% Additional commands \newcommand{\class}[1]{\code{#1}} % could use quotes (JSS does not like them) \newcommand{\CRANpkg}[1]{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}} %% Reduce the font size of code input and output \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl, fontsize=\small} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\small} %% Abstract \Abstract{ The availability of geocoded health data and the inherent temporal structure of communicable diseases have led to an increased interest in statistical models and software for spatio-temporal data with epidemic features. The \proglang{R}~package \pkg{surveillance} can handle various levels of aggregation at which infective events have been recorded. This vignette illustrates the analysis of area-level time series of counts using the endemic-epidemic multivariate time-series model ``\code{hhh4}'' described in, e.g., \citet[Section~3]{meyer.held2013}. See \code{vignette("hhh4")} for a more general introduction to \code{hhh4} models, including the univariate and non-spatial bivariate case. %% (For other types of surveillance data, see %% \code{vignette("twinstim")} and \code{vignette("twinSIR")}.) We first describe the general modeling approach and then exemplify data handling, model fitting, visualization, and simulation methods for weekly counts of measles infections by district in the Weser-Ems region of Lower Saxony, Germany, 2001--2002. } \Keywords{% areal time series of counts, endemic-epidemic modeling, infectious disease epidemiology, branching process with immigration} \begin{document} <>= ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("hhh4_spacetime-cache.RData")) if (!COMPUTE) load("hhh4_spacetime-cache.RData", verbose = TRUE) @ \section[Model class]{Model class: \code{hhh4}} \label{sec:hhh4:methods} An endemic-epidemic multivariate time-series model for infectious disease counts $Y_{it}$ from units $i=1,\dotsc,I$ during periods $t=1,\dotsc,T$ was proposed by \citet{held-etal-2005} and was later extended in a series of papers \citep{paul-etal-2008,paul-held-2011,held.paul2012,meyer.held2013}. In its most general formulation, this so-called ``\code{hhh4}'' model assumes that, conditional on past observations, $Y_{it}$ has a negative binomial distribution with mean \begin{equation} \label{eqn:hhh4} \mu_{it} = e_{it} \, \nu_{it} + \lambda_{it} \, Y_{i,t-1} + \phi_{it} \sum_{j \ne i} w_{ji} \, Y_{j,t-1} \end{equation} and overdispersion parameter $\psi_i > 0$ such that the conditional variance of $Y_{it}$ is $\mu_{it} (1+\psi_i \mu_{it})$. Shared overdispersion parameters, e.g., $\psi_i\equiv\psi$, are supported as well as replacing the negative binomial by a Poisson distribution, which corresponds to the limit $\psi_i\equiv 0$. Similar to the point process models in \code{vignette("twinstim")} and \code{vignette("twinSIR")}, the mean~\eqref{eqn:hhh4} decomposes additively into endemic and epidemic components. The endemic mean is usually modeled proportional to an offset of expected counts~$e_{it}$. In spatial applications of the multivariate \code{hhh4} model as in this paper, the ``unit''~$i$ refers to a geographical region and we typically use (the fraction of) the population living in region~$i$ as the endemic offset. The observation-driven epidemic component splits up into autoregressive effects, i.e., reproduction of the disease within region~$i$, and neighborhood effects, i.e., transmission from other regions~$j$. Overall, Equation~\ref{eqn:hhh4} becomes a rich regression model by allowing for log-linear predictors in all three components: \begin{align} \label{eqn:hhh4:predictors} \log(\nu_{it}) &= \alpha_i^{(\nu)} + {\bm{\beta}^{(\nu)}}^\top \bm{z}^{(\nu)}_{it} \:, \\ \log(\lambda_{it}) &= \alpha_i^{(\lambda)} + {\bm{\beta}^{(\lambda)}}^\top \bm{z}^{(\lambda)}_{it} \:, \\ \log(\phi_{it}) &= \alpha_i^{(\phi)} + {\bm{\beta}^{(\phi)}}^\top \bm{z}^{(\phi)}_{it} \:. \end{align} %% The superscripts in brackets distinguish the component-specific parameters. The intercepts of these predictors can be assumed identical across units, unit-specific, or random (and possibly correlated). %\citep{paul-held-2011} The regression terms often involve sine-cosine effects of time to reflect seasonally varying incidence, %\citep{held.paul2012} but may, e.g., also capture heterogeneous vaccination coverage \citep{herzog-etal-2010}. Data on infections imported from outside the study region may enter the endemic component \citep{geilhufe.etal2012}, which generally accounts for cases not directly linked to other observed cases, e.g., due to edge effects. For a single time series of counts $Y_t$, \code{hhh4} can be regarded as an extension of \code{glm.nb} from package \CRANpkg{MASS} \citep{R:MASS} to account for autoregression. See the \code{vignette("hhh4")} for examples of modeling univariate and bivariate count time series using \code{hhh4}. With multiple regions, spatio-temporal dependence is adopted by the third component in Equation~\ref{eqn:hhh4} with weights $w_{ji}$ reflecting the flow of infections from region $j$ to region $i$. These transmission weights may be informed by movement network data \citep{paul-etal-2008,geilhufe.etal2012}, but may also be estimated parametrically. A suitable choice to reflect epidemiological coupling between regions \citep[Chapter~7]{Keeling.Rohani2008} is a power-law distance decay $w_{ji} = o_{ji}^{-d}$ defined in terms of the adjacency order~$o_{ji}$ in the neighborhood graph of the regions \citep{meyer.held2013}. %% For instance, a second-order neighbor~$j$ of a region~$i$ ($o_{ji} = 2$) is a %% region adjacent to a first-order neighbor of $i$, but not itself directly %% adjacent to $i$. Note that we usually normalize the transmission weights such that $\sum_i w_{ji} = 1$, i.e., the $Y_{j,t-1}$ cases are distributed among the regions proportionally to the $j$th row vector of the weight matrix $(w_{ji})$. Likelihood inference for the above multivariate time-series model has been established by \citet{paul-held-2011} with extensions for parametric neighborhood weights by \citet{meyer.held2013}. Supplied with the analytical score function and Fisher information, the function \code{hhh4} by default uses the quasi-Newton algorithm available through the \proglang{R} function \code{nlminb} to maximize the log-likelihood. Convergence is usually fast even for a large number of parameters. If the model contains random effects, the penalized and marginal log-likelihoods are maximized alternately until convergence. Computation of the marginal Fisher information is accelerated using the \CRANpkg{Matrix} package \citep{R:Matrix}. \section[Data structure]{Data structure: \class{sts}} \label{sec:hhh4:data} <>= ## extract components from measlesWeserEms to reconstruct data("measlesWeserEms") counts <- observed(measlesWeserEms) map <- measlesWeserEms@map populationFrac <- measlesWeserEms@populationFrac @ In public health surveillance, routine reports of infections to public health authorities give rise to spatio-temporal data, which are usually made available in the form of aggregated counts by region and period. The Robert Koch Institute (RKI) in Germany, for example, maintains a database of cases of notifiable diseases, which can be queried via the \emph{SurvStat@RKI} online service (\url{https://survstat.rki.de}). To exemplify area-level \code{hhh4} models in the remainder of this manuscript, we use weekly counts of measles infections by district in the Weser-Ems region of Lower Saxony, Germany, 2001--2002, downloaded from \emph{SurvStat@RKI} (as of Annual Report 2005). These data are contained in \pkg{surveillance} as \code{data("measlesWeserEms")} -- an object of the \proglang{S}4-class \class{sts} (``surveillance time series'') used for data input in \code{hhh4} models and briefly introduced below. See \citet{hoehle-mazick-2010} and \citet{salmon.etal2014} for more detailed descriptions of this class, which is also used for the prospective aberration detection facilities of the \pkg{surveillance} package. The epidemic modeling of multivariate count time series essentially involves three data matrices: a $T \times I$ matrix of the observed counts, a corresponding matrix with potentially time-varying population numbers (or fractions), and an $I \times I$ neighborhood matrix quantifying the coupling between the $I$ units. In our example, the latter consists of the adjacency orders~$o_{ji}$ between the districts. A map of the districts in the form of a \code{SpatialPolygons} object (defined by the \CRANpkg{sp} package of \citealp{R:sp}) can be used to derive the matrix of adjacency orders automatically using the functions \code{poly2adjmat} and \code{nbOrder}, where the former wraps functionality of package \CRANpkg{spdep} \citep{R:spdep}: <>= weserems_adjmat <- poly2adjmat(map) weserems_nbOrder <- nbOrder(weserems_adjmat) @ <>= weserems_nbOrder <- measlesWeserEms@neighbourhood @ Visual inspection of the adjacencies identified by \code{poly2adjmat} is recommended, e.g., via labelling each district with the number of its neighbors, i.e., \code{rowSums(weserems_adjmat)}. If adjacencies are not detected, this is probably due to sliver polygons. In that case either increase the \code{snap} tolerance in \code{poly2adjmat} or use \CRANpkg{rmapshaper} \citep{R:rmapshaper} to simplify and snap adjacent polygons in advance. Given the aforementioned ingredients, the \class{sts} object \code{measlesWeserEms} has been constructed as follows: <>= measlesWeserEms <- sts(counts, start = c(2001, 1), frequency = 52, population = populationFrac, neighbourhood = weserems_nbOrder, map = map) @ Here, \code{start} and \code{frequency} have the same meaning as for classical time-series objects of class \class{ts}, i.e., (year, sample number) of the first observation and the number of observations per year. Note that \code{data("measlesWeserEms")} constitutes a corrected version of \code{data("measles.weser")} originally analyzed by \citet[Section~3.2]{held-etal-2005}. Differences are documented on the associated help page. We can visualize such \class{sts} data in four ways: individual time series, overall time series, map of accumulated counts by district, or animated maps. For instance, the two plots in Figure~\ref{fig:measlesWeserEms} have been generated by the following code: <>= par(mar = c(5,5,1,1)) plot(measlesWeserEms, type = observed ~ time) plot(measlesWeserEms, type = observed ~ unit, population = measlesWeserEms@map$POPULATION / 100000, labels = list(font = 2), colorkey = list(space = "right"), sp.layout = layout.scalebar(measlesWeserEms@map, corner = c(0.05, 0.05), scale = 50, labels = c("0", "50 km"), height = 0.03)) @ The overall time-series plot in Figure~\ref{fig:measlesWeserEms-1} reveals strong seasonality in the data with slightly different patterns in the two years. The spatial plot in Figure~\ref{fig:measlesWeserEms-2} is a tweaked \code{spplot} (package \CRANpkg{sp}) with colors from \CRANpkg{colorspace} \citep{R:colorspace} using $\sqrt{}$-equidistant cut points. The default plot \code{type} is \code{observed ~ time | unit} and displays the district-specific time series. Here we show the output of the equivalent \code{autoplot}-method (Figure~\ref{fig:measlesWeserEms15}), which is based on and requires \CRANpkg{ggplot2} \citep{R:ggplot2}: <0), "affected districts."), out.width="\\linewidth", fig.width=10, fig.height=6, fig.pos="htb">>= if (require("ggplot2")) { autoplot(measlesWeserEms, units = which(colSums(observed(measlesWeserEms)) > 0)) } else plot(measlesWeserEms, units = which(colSums(observed(measlesWeserEms)) > 0)) @ The districts \Sexpr{paste0(paste0(row.names(measlesWeserEms@map), " (", measlesWeserEms@map[["GEN"]], ")")[colSums(observed(measlesWeserEms)) == 0], collapse = " and ")} without any reported cases are excluded in Figure~\ref{fig:measlesWeserEms15}. Obviously, the districts have been affected by measles to a very heterogeneous extent during these two years. An animation of the data can be easily produced as well. We recommend to use converters of the \CRANpkg{animation} package \citep{R:animation}, e.g., to watch the series of plots in a web browser. The following code will generate weekly disease maps during the year 2001 with the respective total number of cases shown in a legend and -- if package \CRANpkg{gridExtra} \citep{R:gridExtra} is available -- an evolving time-series plot at the bottom: <>= animation::saveHTML( animate(measlesWeserEms, tps = 1:52, total.args = list()), title = "Evolution of the measles epidemic in the Weser-Ems region, 2001", ani.width = 500, ani.height = 600) @ <>= ## to perform the following analysis using biweekly aggregated measles counts: measlesWeserEms <- aggregate(measlesWeserEms, by = "time", nfreq = 26) @ \pagebreak \section{Modeling and inference} \label{sec:hhh4:fit} For multivariate surveillance time series of counts such as the \code{measlesWeserEms} data, the function \code{hhh4} fits models of the form~\eqref{eqn:hhh4} via (penalized) maximum likelihood. We start by modeling the measles counts in the Weser-Ems region by a slightly simplified version of the original negative binomial model used by \citet{held-etal-2005}. Instead of district-specific intercepts $\alpha_i^{(\nu)}$ in the endemic component, we first assume a common intercept $\alpha^{(\nu)}$ in order to not be forced to exclude the two districts without any reported cases of measles. After the estimation and illustration of this basic model, we will discuss the following sequential extensions: covariates (district-specific vaccination coverage), estimated transmission weights, and random effects to eventually account for unobserved heterogeneity of the districts. %epidemic seasonality, biweekly aggregation \subsection{Basic model} Our initial model has the following mean structure: \begin{align} \mu_{it} &= e_i \, \nu_t + \lambda \, Y_{i,t-1} + \phi \sum_{j \ne i} w_{ji} Y_{j,t-1}\:,\label{eqn:hhh4:basic}\\ \log(\nu_t) &= \alpha^{(\nu)} + \beta_t t + \gamma \sin(\omega t) + \delta \cos(\omega t)\:. \label{eqn:hhh4:basic:end} \end{align} To account for temporal variation of disease incidence, the endemic log-linear predictor $\nu_t$ incorporates an overall trend and a sinusoidal wave of frequency $\omega=2\pi/52$. As a basic district-specific measure of disease incidence, the population fraction $e_i$ is included as a multiplicative offset. The epidemic parameters $\lambda = \exp(\alpha^{(\lambda)})$ and $\phi = \exp(\alpha^{(\phi)})$ are assumed homogeneous across districts and constant over time. Furthermore, we define $w_{ji} = \ind(j \sim i) = \ind(o_{ji} = 1)$ for the time being, which means that the epidemic can only arrive from directly adjacent districts. This \class{hhh4} model transforms into the following list of \code{control} arguments: <>= measlesModel_basic <- list( end = list(f = addSeason2formula(~1 + t, period = measlesWeserEms@freq), offset = population(measlesWeserEms)), ar = list(f = ~1), ne = list(f = ~1, weights = neighbourhood(measlesWeserEms) == 1), family = "NegBin1") @ The formulae of the three predictors $\log\nu_t$, $\log\lambda$ and $\log\phi$ are specified as element \code{f} of the \code{end}, \code{ar}, and \code{ne} lists, respectively. For the endemic formula we use the convenient function \code{addSeason2formula} to generate the sine-cosine terms, and we take the multiplicative \code{offset} of population fractions $e_i$ from the \code{measlesWeserEms} object. The autoregressive part only consists of the intercept $\alpha^{(\lambda)}$, whereas the neighborhood component specifies the intercept $\alpha^{(\phi)}$ and also the matrix of transmission \code{weights} $(w_{ji})$ to use -- here a simple indicator of first-order adjacency. The chosen \code{family} corresponds to a negative binomial model with a common overdispersion parameter $\psi$ for all districts. Alternatives are \code{"Poisson"}, \code{"NegBinM"} ($\psi_i$), or a factor determining which groups of districts share a common overdispersion parameter. Together with the data, the complete list of control arguments is then fed into the \code{hhh4} function to estimate the model: <>= measlesFit_basic <- hhh4(stsObj = measlesWeserEms, control = measlesModel_basic) @ The fitted model is summarized below: <>= summary(measlesFit_basic, idx2Exp = TRUE, amplitudeShift = TRUE, maxEV = TRUE) @ The \code{idx2Exp} argument of the \code{summary} method requests the estimates for $\lambda$, $\phi$, $\alpha^{(\nu)}$ and $\exp(\beta_t)$ instead of their respective internal log-values. For instance, \code{exp(end.t)} represents the seasonality-adjusted factor by which the basic endemic incidence increases per week. The \code{amplitudeShift} argument transforms the internal coefficients $\gamma$ and $\delta$ of the sine-cosine terms to the amplitude $A$ and phase shift $\varphi$ of the corresponding sinusoidal wave $A \sin(\omega t + \varphi)$ in $\log\nu_t$ \citep{paul-etal-2008}. The resulting multiplicative effect of seasonality on $\nu_t$ is shown in Figure~\ref{fig:measlesFit_basic_endseason} produced by: <>= plot(measlesFit_basic, type = "season", components = "end", main = "") @ The epidemic potential of the process as determined by the parameters $\lambda$ and $\phi$ is best investigated by a combined measure: the dominant eigenvalue (\code{maxEV}) of the matrix $\bm{\Lambda}$ %$\Lambda_t$, %such that $\bm{\mu}_t = \bm{\nu}_t + \bm{\Lambda} \bm{Y}_{t-1}$ which has the entries $(\Lambda)_{ii} = \lambda$ %$(\Lambda_t)_{ii} = \lambda_{it}$ on the diagonal and $(\Lambda)_{ij} = \phi w_{ji}$ %$(\Lambda_t)_{ij} = \phi_{it} w_{ji}$ for $j\ne i$ \citep{paul-etal-2008}. If the dominant eigenvalue is smaller than 1, it can be interpreted as the epidemic proportion of disease incidence. In the above model, the estimate is \Sexpr{round(100*getMaxEV(measlesFit_basic)[1])}\%. Another way to judge the relative importance of the three model components is via a plot of the fitted mean components along with the observed counts. Figure~\ref{fig:measlesFitted_basic} shows this for the five districts with more than 50 cases as well as for the sum over all districts: <>= districts2plot <- which(colSums(observed(measlesWeserEms)) > 50) par(mfrow = c(2,3), mar = c(3, 5, 2, 1), las = 1) plot(measlesFit_basic, type = "fitted", units = districts2plot, hide0s = TRUE, par.settings = NULL, legend = 1) plot(measlesFit_basic, type = "fitted", total = TRUE, hide0s = TRUE, par.settings = NULL, legend = FALSE) -> fitted_components @ We can see from the plots that the largest portion of the fitted mean indeed results from the within-district autoregressive component with very little contribution of cases from adjacent districts and a rather small endemic incidence. The \code{plot} method invisibly returns the component values in a list of matrices (one by unit). In the above code, we have assigned the result from plotting the overall fit (via \code{total = TRUE}) to the object \code{fitted_components}. Here we show the values for the weeks 20 to 22 (corresponding to the weeks 21 to 23 of the measles time series): <<>>= fitted_components$Overall[20:22,] @ The first column of this matrix refers to the fitted mean (epidemic + endemic). The four following columns refer to the epidemic (own + neighbours), endemic, autoregressive (``own''), and neighbourhood components of the mean. The last three columns refer to the point estimates of $\lambda$, $\phi$, and $\nu_t$, respectively. These values allow us to calculate the (time-averaged) proportions of the mean explained by the different components: <<>>= colSums(fitted_components$Overall)[3:5] / sum(fitted_components$Overall[,1]) @ Note that the ``epidemic proportion'' obtained here (\Sexpr{round(100*sum(fitted_components$Overall[,2]) / sum(fitted_components$Overall[,1]))}\%) is a function of the observed time series (so could be called ``empirical''), whereas the dominant eigenvalue calculated further above is a theoretical property derived from the autoregressive parameters alone. Finally, the \code{overdisp} parameter from the model summary and its 95\% confidence interval <<>>= confint(measlesFit_basic, parm = "overdisp") @ suggest that a negative binomial distribution with overdispersion is more adequate than a Poisson model corresponding to $\psi = 0$. We can underpin this finding by an AIC comparison, taking advantage of the convenient \code{update} method for \class{hhh4} fits: <>= AIC(measlesFit_basic, update(measlesFit_basic, family = "Poisson")) @ Other plot \code{type}s and methods for fitted \class{hhh4} models as listed in Table~\ref{tab:methods:hhh4} will be applied in the course of the following model extensions. <>= print(xtable( surveillance:::functionTable("hhh4", functions=list( Extract="getNEweights", Other="oneStepAhead" )), caption="Generic and \\textit{non-generic} functions applicable to \\class{hhh4} objects.", label="tab:methods:hhh4"), include.rownames = FALSE) @ \enlargethispage{\baselineskip} \subsection{Covariates} The \class{hhh4} model framework allows for covariate effects on the endemic or epidemic contributions to disease incidence. Covariates may vary over both regions and time and thus obey the same $T \times I$ matrix structure as the observed counts. For infectious disease models, the regional vaccination coverage is an important example of such a covariate, since it reflects the (remaining) susceptible population. In a thorough analysis of measles occurrence in the German federal states, \citet{herzog-etal-2010} found vaccination coverage to be associated with outbreak size. We follow their approach of using the district-specific proportion $1-v_i$ of unvaccinated children just starting school as a proxy for the susceptible population. As $v_i$ we use the proportion of children vaccinated with at least one dose among the ones presenting their vaccination card at school entry in district $i$ in the year 2004.\footnote{% First year with data for all districts; more recent data is available from the public health department of Lower Saxony (\url{https://www.nlga.niedersachsen.de/impfreport/}).} %% Note: districts are more heterogeneous in 2004 than in later years. %% Data is based on abecedarians in 2004, i.e.\ born in 1998, recommended to %% be twice vaccinated against Measles by the end of year 2000. This time-constant covariate needs to be transformed to the common matrix structure for incorporation in \code{hhh4}: <>= Sprop <- matrix(1 - measlesWeserEms@map@data$vacc1.2004, nrow = nrow(measlesWeserEms), ncol = ncol(measlesWeserEms), byrow = TRUE) summary(Sprop[1, ]) @ There are several ways to account for the susceptible proportion in our model, among which the simplest is to update the endemic population offset $e_i$ by multiplication with $(1-v_i)$. \citet{herzog-etal-2010} found that the susceptible proportion is best added as a covariate in the autoregressive component in the form \[ \lambda_i \, Y_{i,t-1} = \exp\big(\alpha^{(\lambda)} + \beta_s \log(1-v_i)\big) \, Y_{i,t-1} = \exp\big(\alpha^{(\lambda)}\big) \, (1-v_i)^{\beta_s} \, Y_{i,t-1} \] according to the mass action principle \citep{Keeling.Rohani2008}. A higher proportion of susceptibles in district $i$ is expected to boost the generation of new infections, i.e., $\beta_s > 0$. Alternatively, this effect could be assumed as an offset, i.e., $\beta_s \equiv 1$. To choose between endemic and/or autoregressive effects, and multiplicative offset vs.\ covariate modeling, we perform AIC-based model selection. First, we set up a grid of possible component updates: <>= Soptions <- c("unchanged", "Soffset", "Scovar") SmodelGrid <- expand.grid(end = Soptions, ar = Soptions) row.names(SmodelGrid) <- do.call("paste", c(SmodelGrid, list(sep = "|"))) @ Then we update the initial model \code{measlesFit_basic} according to each row of \code{SmodelGrid}: <>= measlesFits_vacc <- apply(X = SmodelGrid, MARGIN = 1, FUN = function (options) { updatecomp <- function (comp, option) switch(option, "unchanged" = list(), "Soffset" = list(offset = comp$offset * Sprop), "Scovar" = list(f = update(comp$f, ~. + log(Sprop)))) update(measlesFit_basic, end = updatecomp(measlesFit_basic$control$end, options[1]), ar = updatecomp(measlesFit_basic$control$ar, options[2]), data = list(Sprop = Sprop)) }) @ The resulting object \code{measlesFits_vacc} is a list of \Sexpr{nrow(SmodelGrid)} \class{hhh4} fits, which are named according to the corresponding \code{Soptions} used for the endemic and autoregressive components. We construct a call of the function \code{AIC} taking all list elements as arguments: <>= aics_vacc <- do.call(AIC, lapply(names(measlesFits_vacc), as.name), envir = as.environment(measlesFits_vacc)) @ <<>>= aics_vacc[order(aics_vacc[, "AIC"]), ] @ <>= if (AIC(measlesFits_vacc[["Scovar|unchanged"]]) > min(aics_vacc[,"AIC"])) stop("`Scovar|unchanged` is not the AIC-minimal vaccination model") @ Hence, AIC increases if the susceptible proportion is only added to the autoregressive component, but we see a remarkable improvement when adding it to the endemic component. The best model is obtained by leaving the autoregressive component unchanged ($\lambda$) and adding the term $\beta_s \log(1-v_i)$ to the endemic predictor in Equation~\ref{eqn:hhh4:basic:end}. <>= measlesFit_vacc <- update(measlesFit_basic, end = list(f = update(formula(measlesFit_basic)$end, ~. + log(Sprop))), data = list(Sprop = Sprop)) coef(measlesFit_vacc, se = TRUE)["end.log(Sprop)", ] @ The estimated exponent $\hat{\beta}_s$ is both clearly positive and different from the offset assumption. In other words, if a district's fraction of susceptibles is doubled, the endemic measles incidence is estimated to multiply by $2^{\hat{\beta}_s}$: <<>>= 2^cbind("Estimate" = coef(measlesFit_vacc), confint(measlesFit_vacc))["end.log(Sprop)",] @ \subsection{Spatial interaction} Up to now, the model assumed that the epidemic can only arrive from directly adjacent districts ($w_{ji} = \ind(j\sim i)$), and that all districts have the same ability $\phi$ to import cases from neighboring regions. Given that humans travel further and preferably to metropolitan areas, both assumptions seem overly simplistic and should be tuned toward a ``gravity'' model for human interaction. First, to reflect commuter-driven spread %\citep[Section~6.3.3.1]{Keeling.Rohani2008} in our model, we scale the district's susceptibility with respect to its population fraction by multiplying $\phi$ with $e_i^{\beta_{pop}}$: <>= measlesFit_nepop <- update(measlesFit_vacc, ne = list(f = ~log(pop)), data = list(pop = population(measlesWeserEms))) @ As in a similar analyses of influenza \citep{geilhufe.etal2012,meyer.held2013}, we find strong evidence for such an agglomeration effect: AIC decreases from \Sexpr{round(AIC(measlesFit_vacc))} to \Sexpr{round(AIC(measlesFit_nepop))} and the estimated exponent $\hat{\beta}_{pop}$ is <<>>= cbind("Estimate" = coef(measlesFit_nepop), confint(measlesFit_nepop))["ne.log(pop)",] @ Second, to account for long-range transmission of cases, \citet{meyer.held2013} proposed to estimate the weights $w_{ji}$ as a function of the adjacency order $o_{ji}$ between the districts. For instance, a power-law model assumes the form $w_{ji} = o_{ji}^{-d}$, for $j\ne i$ and $w_{jj}=0$, where the decay parameter $d$ is to be estimated. Normalization to $w_{ji} / \sum_k w_{jk}$ is recommended and applied by default when choosing \code{W_powerlaw} as weights in the neighborhood component: <>= measlesFit_powerlaw <- update(measlesFit_nepop, ne = list(weights = W_powerlaw(maxlag = 5))) @ The argument \code{maxlag} sets an upper bound for spatial interaction in terms of adjacency order. Here we set no limit since \code{max(neighbourhood(measlesWeserEms))} is \Sexpr{max(neighbourhood(measlesWeserEms))}. The decay parameter $d$ is estimated to be <<>>= cbind("Estimate" = coef(measlesFit_powerlaw), confint(measlesFit_powerlaw))["neweights.d",] @ which represents a strong decay of spatial interaction for higher-order neighbors. As an alternative to the parametric power law, unconstrained weights up to \code{maxlag} can be estimated by using \code{W_np} instead of \code{W_powerlaw}. For instance, \code{W_np(maxlag = 2)} corresponds to a second-order model, i.e., \mbox{$w_{ji} = 1 \cdot \ind(o_{ji} = 1) + e^{\omega_2} \cdot \ind(o_{ji} = 2)$}, which is also row-normalized by default: <>= measlesFit_np2 <- update(measlesFit_nepop, ne = list(weights = W_np(maxlag = 2))) @ Figure~\ref{fig:measlesFit_neweights-2} shows both the power-law model $o^{-\hat{d}}$ and the second-order model. %, where $e^{\hat{\omega}_2}$ is Alternatively, the plot \code{type = "neweights"} for \class{hhh4} fits can produce a \code{stripplot} \citep{R:lattice} of $w_{ji}$ against $o_{ji}$ as shown in Figure~\ref{fig:measlesFit_neweights-1} for the power-law model: <>= library("lattice") trellis.par.set("reference.line", list(lwd=3, col="gray")) trellis.par.set("fontsize", list(text=14)) set.seed(20200303) plot(measlesFit_powerlaw, type = "neweights", plotter = stripplot, panel = function (...) {panel.stripplot(...); panel.average(...)}, jitter.data = TRUE, xlab = expression(o[ji]), ylab = expression(w[ji])) ## non-normalized weights (power law and unconstrained second-order weight) local({ colPL <- "#0080ff" ogrid <- 1:5 par(mar=c(3.6,4,2.2,2), mgp=c(2.1,0.8,0)) plot(ogrid, ogrid^-coef(measlesFit_powerlaw)["neweights.d"], col=colPL, xlab="Adjacency order", ylab="Non-normalized weight", type="b", lwd=2) matlines(t(sapply(ogrid, function (x) x^-confint(measlesFit_powerlaw, parm="neweights.d"))), type="l", lty=2, col=colPL) w2 <- exp(c(coef(measlesFit_np2)["neweights.d"], confint(measlesFit_np2, parm="neweights.d"))) lines(ogrid, c(1,w2[1],0,0,0), type="b", pch=19, lwd=2) arrows(x0=2, y0=w2[2], y1=w2[3], length=0.1, angle=90, code=3, lty=2) legend("topright", col=c(colPL, 1), pch=c(1,19), lwd=2, bty="n", inset=0.1, y.intersp=1.5, legend=c("Power-law model", "Second-order model")) }) @ Note that only horizontal jitter is added in this case. Because of normalization, the weight $w_{ji}$ for transmission from district $j$ to district $i$ is determined not only by the districts' neighborhood $o_{ji}$ but also by the total amount of neighborhood of district $j$ in the form of $\sum_{k\ne j} o_{jk}^{-d}$, which causes some variation of the weights for a specific order of adjacency. The function \code{getNEweights} can be used to extract the estimated weight matrix $(w_{ji})$. An AIC comparison of the different models for the transmission weights yields: <<>>= AIC(measlesFit_nepop, measlesFit_powerlaw, measlesFit_np2) @ AIC improves when accounting for transmission from higher-order neighbors by a power law or a second-order model. In spite of the latter resulting in a slightly better fit, we will use the power-law model as a basis for further model extensions since the stand-alone second-order effect is not always identifiable in more complex models and is scientifically implausible. \subsection{Random effects} \citet{paul-held-2011} introduced random effects for \class{hhh4} models, which are useful if the districts exhibit heterogeneous incidence levels not explained by observed covariates, and especially if the number of districts is large. For infectious disease surveillance data, a typical example of unobserved heterogeneity is underreporting. Our measles data even contain two districts without any reported cases, while the district with the smallest population (03402, SK Emden) had the second-largest number of cases reported and the highest overall incidence (see Figures~\ref{fig:measlesWeserEms-2} and~\ref{fig:measlesWeserEms15}). Hence, allowing for district-specific intercepts in the endemic or epidemic components is expected to improve the model fit. For independent random effects $\alpha_i^{(\nu)} \stackrel{iid}{\sim} \N(\alpha^{(\nu)}, \sigma_\nu^2)$, $\alpha_i^{(\lambda)} \stackrel{iid}{\sim} \N(\alpha^{(\lambda)}, \sigma_\lambda^2)$, and $\alpha_i^{(\phi)} \stackrel{iid}{\sim} \N(\alpha^{(\phi)}, \sigma_\phi^2)$ in all three components, we update the corresponding formulae as follows: <>= measlesFit_ri <- update(measlesFit_powerlaw, end = list(f = update(formula(measlesFit_powerlaw)$end, ~. + ri() - 1)), ar = list(f = update(formula(measlesFit_powerlaw)$ar, ~. + ri() - 1)), ne = list(f = update(formula(measlesFit_powerlaw)$ne, ~. + ri() - 1))) @ <>= summary(measlesFit_ri, amplitudeShift = TRUE, maxEV = TRUE) @ <>= ## strip leading and trailing empty lines writeLines(tail(head(capture.output({ <> }), -1), -1)) @ The summary now contains an extra section with the estimated variance components $\sigma_\lambda^2$, $\sigma_\phi^2$, and $\sigma_\nu^2$. We did not assume correlation between the three random effects, but this is possible by specifying \code{ri(corr = "all")} in the component formulae. The implementation also supports a conditional autoregressive formulation for spatially correlated intercepts via \code{ri(type = "car")}. The estimated district-specific deviations $\alpha_i^{(\cdot)} - \alpha^{(\cdot)}$ can be extracted by the \code{ranef}-method: <<>>= head(ranef(measlesFit_ri, tomatrix = TRUE), n = 3) @ The \code{exp}-transformed deviations correspond to district-specific multiplicative effects on the model components, which can be visualized via the plot \code{type = "ri"} as follows (Figure~\ref{fig:measlesFit_ri_map}): % exp=TRUE plot has nicer (usually more) axis ticks if 'scales' is available <>= for (comp in c("ar", "ne", "end")) { print(plot(measlesFit_ri, type = "ri", component = comp, exp = TRUE, labels = list(cex = 0.6))) } @ For the autoregressive component in Figure~\ref{fig:measlesFit_ri_map-1}, we see a pronounced heterogeneity between the three western districts in pink and the remaining districts. These three districts have been affected by large local outbreaks and are also the ones with the highest overall numbers of cases. In contrast, the city of Oldenburg (03403) is estimated with a relatively low autoregressive coefficient: $\lambda_i = \exp(\alpha_i^{(\lambda)})$ can be extracted using the \code{intercept} argument as <<>>= exp(ranef(measlesFit_ri, intercept = TRUE)["03403", "ar.ri(iid)"]) @ However, this district seems to import more cases from other districts than explained by its population (Figure~\ref{fig:measlesFit_ri_map-2}). In Figure~\ref{fig:measlesFit_ri_map-3}, the two districts without any reported measles cases (03401 and 03405) appear in cyan, which means that they exhibit a relatively low endemic incidence after adjusting for the population and susceptible proportion. Such districts could be suspected of a larger amount of underreporting. We plot the new model fit (Figure~\ref{fig:measlesFitted_ri}) for comparison with the initial fit shown in Figure~\ref{fig:measlesFitted_basic}: <>= par(mfrow = c(2,3), mar = c(3, 5, 2, 1), las = 1) plot(measlesFit_ri, type = "fitted", units = districts2plot, hide0s = TRUE, par.settings = NULL, legend = 1) plot(measlesFit_ri, type = "fitted", total = TRUE, hide0s = TRUE, par.settings = NULL, legend = FALSE) @ For some of these districts, a great amount of cases is now explained via transmission from neighboring regions while others are mainly influenced by the local autoregression. The decomposition of the estimated mean by district can also be seen from the related plot \code{type = "maps"} (Figure~\ref{fig:measlesFitted_maps}): <>= plot(measlesFit_ri, type = "maps", which = c("epi.own", "epi.neighbours", "endemic"), prop = TRUE, labels = list(cex = 0.6)) @ The extra flexibility of the random effects model comes at a price. First, the runtime of the estimation increases considerably from \Sexpr{round(measlesFit_powerlaw[["runtime"]]["elapsed"], 1)} seconds for the previous power-law model \code{measlesFit_powerlaw} to \Sexpr{round(measlesFit_ri[["runtime"]]["elapsed"], 1)} seconds with random effects. Furthermore, we no longer obtain AIC values, since random effects invalidate simple AIC-based model comparisons. For quantitative comparisons of model performance we have to resort to more sophisticated techniques presented in the next section. \subsection{Predictive model assessment} \citet{paul-held-2011} suggest to evaluate one-step-ahead forecasts from competing models using proper scoring rules for count data \citep{czado-etal-2009}. These scores measure the discrepancy between the predictive distribution $P$ from a fitted model and the later observed value $y$. A well-known example is the squared error score (``ses'') $(y-\mu_P)^2$, which is usually averaged over a set of forecasts to obtain the mean squared error. The Dawid-Sebastiani score (``dss'') additionally evaluates sharpness. The logarithmic score (``logs'') and the ranked probability score (``rps'') assess the whole predictive distribution with respect to calibration and sharpness. Lower scores correspond to better predictions. In the \class{hhh4} framework, predictive model assessment is made available by the functions \code{oneStepAhead}, \code{scores}, \code{pit}, and \code{calibrationTest}. We will use the second quarter of 2002 as the test period, and compare the basic model, the power-law model, and the random effects model. First, we use the \code{"final"} fits on the complete time series to compute the predictions, which then simply correspond to the fitted values during the test period: <>= tp <- c(65, 77) models2compare <- paste0("measlesFit_", c("basic", "powerlaw", "ri")) measlesPreds1 <- lapply(mget(models2compare), oneStepAhead, tp = tp, type = "final") @ <>= stopifnot(all.equal(measlesPreds1$measlesFit_powerlaw$pred, fitted(measlesFit_powerlaw)[tp[1]:tp[2],], check.attributes = FALSE)) @ Note that in this case, the log-score for a model's prediction in district $i$ in week $t$ equals the associated negative log-likelihood contribution. Comparing the mean scores from different models is thus essentially a goodness-of-fit assessment: <>= stopifnot(all.equal( measlesFit_powerlaw$loglikelihood, -sum(scores(oneStepAhead(measlesFit_powerlaw, tp = 1, type = "final"), which = "logs", individual = TRUE)))) @ <>= SCORES <- c("logs", "rps", "dss", "ses") measlesScores1 <- lapply(measlesPreds1, scores, which = SCORES, individual = TRUE) t(sapply(measlesScores1, colMeans, dims = 2)) @ All scoring rules claim that the random effects model gives the best fit during the second quarter of 2002. Now we turn to true one-week-ahead predictions of \code{type = "rolling"}, which means that we always refit the model up to week $t$ to get predictions for week $t+1$: <>= measlesPreds2 <- lapply(mget(models2compare), oneStepAhead, tp = tp, type = "rolling", which.start = "final") @ Figure~\ref{fig:measlesPreds2_plot} shows \CRANpkg{fanplot}s \citep{R:fanplot} of the sequential one-week-ahead forecasts from the random effects models for the same districts as in Figure~\ref{fig:measlesFitted_ri}: <>= par(mfrow = sort(n2mfrow(length(districts2plot))), mar = c(4.5,4.5,2,1)) for (unit in names(districts2plot)) plot(measlesPreds2[["measlesFit_ri"]], unit = unit, main = unit, key.args = if (unit == tail(names(districts2plot),1)) list()) @ The \code{plot}-method for \class{oneStepAhead} predictions is based on the associated \code{quantile}-method (a \code{confint}-method is also available). Note that the sum of these negative binomial distributed forecasts over all districts is not negative binomial distributed. The package \CRANpkg{distr} \citep{ruckdeschel.kohl2014} could be used to approximate the distribution of the aggregated one-step-ahead forecasts (not shown here). Looking at the average scores of these forecasts over all weeks and districts, the most parsimonious initial model \code{measlesFit_basic} actually turns out best: <>= measlesScores2 <- lapply(measlesPreds2, scores, which = SCORES, individual = TRUE) t(sapply(measlesScores2, colMeans, dims = 2)) @ Statistical significance of the differences in mean scores can be investigated by a \code{permutationTest} for paired data or a paired $t$-test: <>= set.seed(321) sapply(SCORES, function (score) permutationTest( measlesScores2$measlesFit_ri[, , score], measlesScores2$measlesFit_basic[, , score], nPermutation = 999)) @ Hence, there is no clear evidence for a difference between the basic and the random effects model with regard to predictive performance during the test period. Whether predictions of a particular model are well calibrated can be formally investigated by \code{calibrationTest}s for count data as recently proposed by \citet{wei.held2013}. For example: <>= calibrationTest(measlesPreds2[["measlesFit_ri"]], which = "rps") @ <>= ## strip leading and trailing empty lines writeLines(tail(head(capture.output({ <> }), -1), -1)) @ Thus, there is no evidence of miscalibrated predictions from the random effects model. \citet{czado-etal-2009} describe an alternative informal approach to assess calibration: probability integral transform (PIT) histograms for count data (Figure~\ref{fig:measlesPreds2_pit}). <>= par(mfrow = sort(n2mfrow(length(measlesPreds2))), mar = c(4.5,4.5,2,1), las = 1) for (m in models2compare) pit(measlesPreds2[[m]], plot = list(ylim = c(0, 1.25), main = m)) @ Under the hypothesis of calibration, i.e., $y_{it} \sim P_{it}$ for all predictive distributions $P_{it}$ in the test period, the PIT histogram is uniform. Underdispersed predictions lead to U-shaped histograms, and bias causes skewness. In this aggregate view of the predictions over all districts and weeks of the test period, predictive performance is comparable between the models, and there is no evidence of badly dispersed predictions. However, the right-hand decay in all histograms suggests that all models tend to predict higher counts than observed. This is most likely related to the seasonal shift between the years 2001 and 2002. In 2001, the peak of the epidemic was in the second quarter, while it already occurred in the first quarter in 2002 (cp.\ Figure~\ref{fig:measlesWeserEms-1}). \subsection{Further modeling options} In the previous sections we extended our model for measles in the Weser-Ems region with respect to spatial variation of the counts and their interaction. Temporal variation was only accounted for in the endemic component, which included a long-term trend and a sinusoidal wave on the log-scale. \citet{held.paul2012} suggest to also allow seasonal variation of the epidemic force by adding a superposition of $S$ harmonic waves of fundamental frequency~$\omega$, $\sum_{s=1}^S \left\{ \gamma_s \sin(s\,\omega t) + \delta_s \cos(s\,\omega t) \right\}$, to the log-linear predictors of the autoregressive and/or neighborhood component -- just like for $\log\nu_t$ in Equation~\ref{eqn:hhh4:basic:end} with $S=1$. However, given only two years of measles surveillance and the apparent shift of seasonality with regard to the start of the outbreak in 2002 compared to 2001, more complex seasonal models are likely to overfit the data. Concerning the coding in \proglang{R}, sine-cosine terms can be added to the epidemic components without difficulties by again using the convenient function \code{addSeason2formula}. Updating a previous model for different numbers of harmonics is even simpler, since the \code{update}-method has a corresponding argument \code{S}. The plots of \code{type = "season"} and \code{type = "maxEV"} for \class{hhh4} fits can visualize the estimated component seasonality. Performing model selection and interpreting seasonality or other covariate effects across \emph{three} different model components may become quite complicated. Power-law weights actually enable a more parsimonious model formulation, where the autoregressive and neighbourhood components are merged into a single epidemic component: \begin{equation} \mu_{it} = e_{it} \, \nu_{it} + \phi_{it} \sum_{j} (o_{ji} + 1)^{-d} \, Y_{j,t-1} \:. \end{equation} With only two predictors left, model selection and interpretation is simpler, and model extensions are more straightforward, for example stratification by age group \citep{meyer.held2015} as mentioned further below. To fit such a two-component model, the autoregressive component has to be excluded (\code{ar = list(f = ~ -1)}) and power-law weights have to be modified to start from adjacency order~0 (via \code{W_powerlaw(..., from0 = TRUE)}). <>= ## a simplified model which includes the autoregression in the power law measlesFit_powerlaw2 <- update(measlesFit_powerlaw, ar = list(f = ~ -1), ne = list(weights = W_powerlaw(maxlag = 5, from0 = TRUE))) AIC(measlesFit_powerlaw, measlesFit_powerlaw2) ## simpler is really worse; probably needs random effects @ All of our models for the measles surveillance data incorporated an epidemic effect of the counts from the local district and its neighbors. Without further notice, we thereby assumed a lag equal to the observation interval of one week. However, the generation time of measles is around 10 days, which is why \citet{herzog-etal-2010} aggregated their weekly measles surveillance data into biweekly intervals. We can perform a sensitivity analysis by running the whole code of the current section based on \code{aggregate(measlesWeserEms, nfreq = 26)}. Doing so, the parameter estimates of the various models retain their order of magnitude and conclusions remain the same. However, with the number of time points halved, the complex random effects model would not always be identifiable when calculating one-week-ahead predictions during the test period. %% basic model: same epidemic parameters and dominant eigenvalue (0.78), same overdispersion (1.94) %% vaccination: the exponent $\beta_s$ for the susceptible proportion in the %% extended model \code{"Scovar|unchanged"} is closer to 1 (1.24), which is why %% \code{"Soffset|unchanged"} is selected by AIC. %% random effects: less variance, but similar pattern We have shown several options to account for the spatio-temporal dynamics of infectious disease spread. However, for directly transmitted human diseases, the social phenomenon of ``like seeks like'' results in contact patterns between subgroups of a population, which extend the pure distance decay of interaction. Especially for school children, social contacts are highly age-dependent. A useful epidemic model should therefore be additionally stratified by age group and take the inherent contact structure into account. How this extension can be incorporated in the spatio-temporal endemic-epidemic modeling framework \class{hhh4} has recently been investigated by \citet{meyer.held2015}. The associated \CRANpkg{hhh4contacts} package \citep{R:hhh4contacts} contains a demo script to exemplify this modeling approach with surveillance data on norovirus gastroenteritis and an age-structured contact matrix. \section{Simulation} \label{sec:hhh4:simulation} Simulation from fitted \class{hhh4} models is enabled by an associated \code{simulate}-method. Compared to the point process models described in \code{vignette("twinstim")} and \code{vignette("twinSIR")}, simulation is less complex since it essentially consists of sequential calls of \code{rnbinom} (or \code{rpois}). At each time point $t$, the mean $\mu_{it}$ is determined by plugging in the parameter estimates and the counts $Y_{i,t-1}$ simulated at the previous time point. In addition to a model fit, we thus need to specify an initial vector of counts \code{y.start}. As an example, we simulate 100 realizations of the evolution of measles during the year 2002 based on the fitted random effects model and the counts of the last week of the year 2001 in the 17 districts: <>= (y.start <- observed(measlesWeserEms)[52, ]) measlesSim <- simulate(measlesFit_ri, nsim = 100, seed = 1, subset = 53:104, y.start = y.start) @ The simulated counts are returned as a $52\times 17\times 100$ array instead of a list of 100 \class{sts} objects. We can, e.g., look at the final size distribution of the simulations: <<>>= summary(colSums(measlesSim, dims = 2)) @ A few large outbreaks have been simulated, but the mean size is below the observed number of \code{sum(observed(measlesWeserEms)[53:104, ])} $= \Sexpr{sum(observed(measlesWeserEms)[53:104,])}$ cases in the year 2002. Using the \code{plot}-method associated with such \code{hhh4} simulations, Figure~\ref{fig:measlesSim_plot_time} shows the weekly number of observed cases compared to the long-term forecast via a fan chart: <>= plot(measlesSim, "fan", means.args = list(), key.args = list()) @ We refer to \code{help("simulate.hhh4")} and \code{help("plot.hhh4sims")} for further examples. \pagebreak[2] %-------------- % BIBLIOGRAPHY %-------------- <>= ## create automatic references for R packages knitr::write_bib( # produces UTF-8 c("MASS", "Matrix", "colorspace", "gridExtra", "lattice", "sp", "fanplot", "hhh4contacts"), file = "hhh4_spacetime-R.bib", tweak = FALSE, prefix = "R:") @ \bibliography{references,hhh4_spacetime-R} <>= save(aics_vacc, measlesPreds2, file = "hhh4_spacetime-cache.RData") @ \end{document} surveillance/vignettes/surveillance-hmm.pdf0000644000176200001440000001434314070551443020734 0ustar liggesusers%PDF-1.4 % 4 0 obj << /Length 39 /Filter /FlateDecode >> stream x+2T0BC]Cs]3 K\.}\C|@.m/ endstream endobj 3 0 obj << /Type /Page /Contents 4 0 R /Resources 2 0 R /MediaBox [0 0 254 77] /Parent 5 0 R >> endobj 1 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./tmp-pdfcrop-21549-stdin.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 6 0 R /BBox [0 0 595 842] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 7 0 R >>/Font << /R12 8 0 R/R10 9 0 R/R8 10 0 R>> >> /Length 1058 /Filter /FlateDecode >> stream xW=$5Wt[I`6!E ҉ϳ.wF1 z]\;տ|nwnJrX%RSW DΒ\:ucVOj]ʔ===q>/?ce>?^/P JCEPAɁͯO(E0"L3גO'Kƹ(#2$ʊS0E6g&U0VX$T;s|}髚)'.Xʮ{z('>(y Et5x!F ԧ"E$"Ř݇&6o٭?F?VMG=|G>ݟ n,1i0 bc)Hc ,5@8Uqp؞ f>G@3aU#A%QPG{*pC oOvL2:a)PE0})^W~21 A}<@'0:"o^[}q{c0!hmurY%a"Dgwؖ?>#oPLyG{*L=D}/ yosG't#4V?<#oPLG{*2`CI'H}^)d  Uu֋ 3|,l"pΤ jb: ,tUi/:HD>R5{.wPz,L7˦~s_k=ey;9C|qRZ+zu;K@3kNf/b\UNC\I\c'W\e˸+JX&j,)/|$,|X7]aO|-wB<iSܩ`=t}, endstream endobj 6 0 obj << /Producer (GPL Ghostscript 9.26) /CreationDate (D:20210705111908+02'00') /ModDate (D:20210705111908+02'00') /Creator (dvips\(k\) 5.995 Copyright 2015 Radical Eye Software) /Title (surveillance-hmm.dvi) >> endobj 7 0 obj << /Type /ExtGState /OPM 1 >> endobj 8 0 obj << /BaseFont /ISYWPX+LMMathItalic7-Regular /FontDescriptor 11 0 R /Type /Font /FirstChar 110 /LastChar 110 /Widths [ 706] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 9 0 obj << /BaseFont /ZRBLWS+LMRoman7-Regular /FontDescriptor 12 0 R /Type /Font /FirstChar 49 /LastChar 51 /Widths [ 569 569 569] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 10 0 obj << /BaseFont /EENAQQ+LMMathItalic10-Regular /FontDescriptor 13 0 R /Type /Font /FirstChar 58 /LastChar 89 /Widths [ 278 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 828 581] /Encoding 14 0 R /Subtype /Type1 >> endobj 11 0 obj << /Type /FontDescriptor /FontName /ISYWPX+LMMathItalic7-Regular /FontBBox [ 0 -10 658 441] /Flags 131104 /Ascent 441 /CapHeight 441 /Descent -10 /ItalicAngle 0 /StemV 98 /MissingWidth 280 /XHeight 441 /CharSet (/n) /FontFile3 15 0 R >> endobj 12 0 obj << /Type /FontDescriptor /FontName /ZRBLWS+LMRoman7-Regular /FontBBox [ 0 -20 514 664] /Flags 65568 /Ascent 664 /CapHeight 664 /Descent -20 /ItalicAngle 0 /StemV 77 /MissingWidth 280 /CharSet (/one/three/two) /FontFile3 16 0 R >> endobj 13 0 obj << /Type /FontDescriptor /FontName /EENAQQ+LMMathItalic10-Regular /FontBBox [ 0 0 851 683] /Flags 65540 /Ascent 683 /CapHeight 683 /Descent 0 /ItalicAngle 0 /StemV 127 /MissingWidth 280 /CharSet (/X/Y/period) /FontFile3 17 0 R >> endobj 14 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 58/period] >> endobj 15 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 446 >> stream xcd`ab`ddM,,IL6 JM/I,ɨf!C_nn?4' ~-S_PYQ`d`` $-*ˋ3R|ˁ y I9i i ! A AzX]"rL _rUjߕEguwv6˕X'$%ws\hŒ;䧯09aɹr-&u'tԕuqӷlܬclX:)@0H{]kQwdsgϘ2An”ɫ',XTb‰ ',w-7hODoD*Yo.7K|S/϶2KH>g7򞾞=fL8gmo ;" endstream endobj 16 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 599 >> stream xcd`ab`dd M3 JM/I, f!CǴ:<<,~!=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k; g```642f`bf{ac5|, X{r +>]{ؗuyt%usHg_}r?سRپBMzO}}u߽D3:J[k9~}yn]W]8;"M#M]b-V]:pW7V&n[756uwvK0`Ww˿:g|c1hM}ٸZ [~3f6 \XrEW/[´ ;N$gwFvuvvuqt7v6N#Piӎ%ꝶ{E9UI~_γM2m=-n9.|n=}z'^ó|bI'20% endstream endobj 17 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 722 >> stream xmOqw[0jQbcu&A4*j(>Q@ڲn[) hix`<`"/sLH0]jk6p8d[vZǷ[G$[Gŋ C@ p?&;#m#OVUlw dg[zH=A6Ukf('٭7u.RF\nn!4lrU1 ݭǰ:؅JR|@ˊm'E|/Rieb Uvwj/T4ϭ |eqw/ & :y#n? ӓ&,NFnO8+4Ρ$DfoBcaV=a-o=` Y E5LX=d@P}6eoraE%_,LÂǚ8D'T~l(q1y"P%?9PO& QlK.ʩ`?H0@B7߷KƘd~bej'BFw[b`PIR爐YD K^@3A[/41t.]e>p0p.0 UtLNThMJ-,,<)qeM+EY\P e$ɖʉ|/˳,Qn&NrqlN~*UV endstream endobj 2 0 obj << /XObject << /Im1 1 0 R >> /ProcSet [ /PDF ] >> endobj 5 0 obj << /Type /Pages /Count 1 /Kids [3 0 R] >> endobj 18 0 obj << /Type /Catalog /Pages 5 0 R >> endobj 19 0 obj << /Producer (pdfTeX-1.40.16) /Creator (TeX) /CreationDate (D:20210705111908+02'00') /ModDate (D:20210705111908+02'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/Debian) kpathsea version 6.2.1) >> endobj xref 0 20 0000000000 65535 f 0000000236 00000 n 0000005376 00000 n 0000000133 00000 n 0000000015 00000 n 0000005441 00000 n 0000001625 00000 n 0000001848 00000 n 0000001893 00000 n 0000002076 00000 n 0000002260 00000 n 0000002499 00000 n 0000002752 00000 n 0000002998 00000 n 0000003244 00000 n 0000003339 00000 n 0000003875 00000 n 0000004564 00000 n 0000005498 00000 n 0000005548 00000 n trailer << /Size 20 /Root 18 0 R /Info 19 0 R /ID [ ] >> startxref 5815 %%EOF surveillance/vignettes/glrnb.Rnw0000644000176200001440000005454114405577243016576 0ustar liggesusers%\VignetteIndexEntry{algo.glrnb: Count data regression charts using the generalized likelihood ratio statistic} \documentclass[a4paper,11pt]{article} \usepackage[T1]{fontenc} \usepackage{graphicx} \usepackage{natbib} \bibliographystyle{apalike} \usepackage{lmodern} \usepackage{amsmath} \usepackage{amsfonts,amssymb} \setlength{\parindent}{0pt} %%% Meta data \usepackage{hyperref} \hypersetup{ pdfauthor = {Valentin Wimmer and Michael H\"ohle}, pdftitle = {'algo.glrnb': Count data regression charts using the generalized likelihood ratio statistic}, pdfsubject = {R package 'surveillance'} } \title{\texttt{algo.glrnb}: Count data regression charts using the generalized likelihood ratio statistic} \author{ Valentin Wimmer$^{(1,2)}$\thanks{Author of correspondence: \texttt{Valentin.Wimmer@gmx.de}}\; and Michael H\"{o}hle$^{(1,2)}$ \\ (1) Department of Statistics, University of Munich, Germany\\ (2) MC-Health -- Munich Center of Health Sciences } \date{6 June 2008} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sweave %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \usepackage{Sweave} \SweaveOpts{prefix.string=plots/glrnb} \setkeys{Gin}{width=1\textwidth} \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl,fontsize=\footnotesize} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\footnotesize} \DefineVerbatimEnvironment{Scode}{Verbatim}{fontshape=sl,fontsize=\footnotesize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initial R code %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <>= library("surveillance") options(SweaveHooks=list(fig=function() par(mar=c(4,4,2,0)+.5))) options(width=70) set.seed(247) ## create directory for plots dir.create("plots", showWarnings=FALSE) @ \begin{document} \maketitle \begin{abstract} \noindent The aim of this document is to show the use of the function \verb+algo.glrnb+ for a type of count data regression chart, the generalized likelihood ratio (GLR) statistic. The function is part of the \textsf{R} package \textbf{surveillance} \citep{hoehle-2007}, which provides outbreak detection algorithms for surveillance data. For an introduction to these monitoring features of the package, see \texttt{vignette("surveillance")}. There one can find information about the data structure of the \verb+disProg+ and \verb+survRes+ objects. Furthermore tools for outbreak detection, such as a Bayesian approach, procedures described by \citet{stroup89}, \citet{farrington96} and the methods used at the Robert Koch Institut, Germany, are explained. The function \verb+algo.glrnb+ is the implementation of the control charts for poisson and negative binomial distributions for monitoring time series of counts described in \citet{hoehle.paul2008}. This document gives an overview of the different features of the function and illustrations of its use are given for simulated and real surveillance data. \\ \noindent{\bf Keywords:} change-point detection, generalized regression charts, poisson and negative binomial distribution, increase and decrease \end{abstract} \section{Introduction}\label{sec:intro} For the monitoring of infectious diseases it is necessary to monitor time series of routinely collected surveillance data. Methods of the statistic process control (SPC) can be used for this purpose. Here it is important, that the methods can handle the special features of surveillance data, e.g.\ seasonality of the disease or the count data nature of the collected data. It is also important, that not only the number of counts of one time point (week, month) are regarded but instead the cases of previous time points are considered, because beside abrupt changes also small constant changes should be detected. CUSUM-methods (function \verb+algo.cusum+), LR-charts or GLR-methods as described by \citet{lai95} and \citet{hoehle.paul2008} can afford this. With the function \verb+algo.glrnb+ these methods can easily applied to surveillance data. A typical assumption for time series of counts is, that the observed counts at each time point follow a Poisson distribution. If overdispersion is likely, the negative binomial distribution provides a better alternative. Both distributions are provided by \verb+algo.glrnb+. In the GLR-scheme, an outbreak can be defined as a change in the intercept. The function \verb+algo.glrnb+ allows the user to specify whether increases or decreases in mean should be regarded. For each time point a GLR-statistic is computed, if this statistic exceeds a threshold value, an alarm is given. The function also provides the possibility to return the number of cases that would have been necessary to produce an alarm. This vignette is organized as follows: First, in Section \ref{sec:prel} the data structure is explained, in Section \ref{sec:glr} a short introduction in the theory of the GLR-charts is given and Section \ref{sec:control} shows the different \verb+control+-settings. % In Section \ref{sec:extensions} some possible extensions are presented. \section{Preliminaries}\label{sec:prel} Consider the situation, where a time series of counts is collected for surveillance purpose. In each interval, usually one week, the number of cases of the interesting disease in an area (country, district) is counted. The resulting time series is denoted by $\{y_t\>;t=1,\ldots,n\}$. Usually the data are collected on line, so that the time point $n$ is the actual time point. Our aim is to decide with the aid of a statistic for each time point $n$ if there is an outbreak at this or any former time point. If an outbreak is detected, the algorithm gives an alarm. Observed time series of counts are saved in a \verb+disProg+ object, a list containing the time series of counts, the number of weeks and a state chain. The state is 1, if e.g. the Robert Koch-Institut declares the week to be part of an outbreak and 0 otherwise. By using the state chain the quality of the surveillance algorithm can be tested. %The 'surveillance'-package provides standard plot routines for the surveillance objects. As an first example the number of cases of salmonella hadar in the years 2001-2006 is examined. \\ \textit{Example 1:} <>= data(shadar) plot(shadar,main="Number of salmonella hadar cases in Germany 2001-2006") @ The package provides the possibility to simulate surveillance data with the functions \verb+sim.pointSource+, \verb+sim.seasonalNoise+ and \verb+sim.HHH+. See \citet{hoehle-2007} and \texttt{vignette("surveillance")} for further information. \\ \textit{Example 2:} <>= # Simulate data simData <- sim.pointSource(length=300,K=0.5,r=0.6,p=0.95) @ <>= plot(simData) @ \section{LR and GLR-charts}\label{sec:glr} Our aim is to detect a significant change in the number of cases. This is done as follows. One assumes, that there is a number of cases that is usual, the in control mean $\mu_0$. The in-control mean is defined in \citet{hoehle.paul2008} to be \begin{equation} \label{mu0} \operatorname{log}(\mu_{0,t})=\beta_0 + \beta_1t + \sum_{s=1}^S(\beta_{2s} \cos(\omega s t) + \beta_{2s+1}\sin(\omega s t)). \end{equation} If an outbreak occurs, the number of cases increases and the situation is out-of control and the algorithm should produce an alarm. The change is assumed to be an additive increase on log scale, \begin{equation} \label{interceptchange} \operatorname{log}(\mu_1)= \operatorname{log}(\mu_0) + \kappa . \end{equation} If $\mu_0$ is unknown one could use a part of the data to estimate it with a generalized linear model (GLM). If $\kappa$ is known, LR-charts can be used, if not, $\kappa$ has to be estimated, which is the GLR-scheme setting. For each time point, the likelihood ratio statistic is computed as follows \begin{equation} \label{cusum} GLR(n)=\max_{1 \leq k \leq n} \sup_{\theta \in \Theta} \left[ \sum_{t=k}^n \log \left\{ \frac{f_{\theta}(y_t)}{f_{\theta_0}(y_t)} \right\} \right] . \end{equation} Now $N=\inf \{n \geq 1 : GLR(n) \geq c_{\gamma} \}$ is the first time point where the GLR-statistic is above a threshold $c_{\gamma}$. For this time point $N$ an alarm is given. If the parameter $\kappa$ and hence $\theta=\kappa$ is known, the maximisation over $\theta$ can be omitted. With the function \verb+algo.glrnb+ one can compute the the GLR-statistic for every time point. If the actual value extends the chosen threshold $c_{\gamma}$, an alarm is given. After every alarm, the algorithm gets reset and the surveillance starts again. The result of a call of \verb+algo.glrnb+ is an object of class \verb+survRes+. This is basically a list of several arguments. The most important one is the \verb+upperbound+ statistic, which is a vector of length $n$ containing the likelihood-ratio-statistic for every time point under surveillance. The \verb+alarm+-vector contains a boolean for every time point whether there was an alarm or not. \\ At this point in the vignette we move more into the applied direction and refer the user to \citet{hoehle.paul2008} for further theoretical details about the GLR procedure. The next example demonstrates the surveillance with the \verb+algo.glrnb+ in a learning by doing type of way. The example should demonstrate primarily the result of the surveillance. More details to the control-options follow in the next section. All control values are set here on default and the first two years are used to find a model for the in-control mean and so surveillance is starting in week 105. A plot of the results can be obtained as follows <>= survObj <- algo.glrnb(shadar,control=list(range=105:295,alpha=0)) plot(survObj, col=c(8,NA,4)) @ The default value for $c_{\gamma}$ is 5. The upperbound statistic is above this value several times in the third quarter of 2006 (time points marked by small triangles in the plot). In the next section follow a description of the control-setting for tuning the behavior of the algorithm, e.g.\ one can search not only for increases in mean as shown in the example but also for decreases. \section{Control-settings}\label{sec:control} In this section, the purpose and use of the control settings of the \verb+algo.glrnb+ function are shown and illustrated by the examples from Section \ref{sec:prel}. The control-setting is a list of the following arguments. <>= control=list(range=range,c.ARL=5, mu0=NULL, alpha=0, Mtilde=1, M=-1, change="intercept",theta=NULL, dir=c("inc","dec"),ret=c("cases","value")) @ \begin{itemize} \item \verb+range+ \\ The \verb+range+ is a vector of consecutive indices for the week numbers in the \verb+disProg+ object for which surveillance should be done. If a model for the in-control parameter $\mu_0$ is known (\verb+mu0+ is not \verb+NULL+), the surveillance can start at time point one. Otherwise it is necessary to estimate the values for \verb+mu0+ with a GLM. Thus, the range should not start at the first time point but instead use the first weeks/months as control-range. (Note: It is important to use enough data for estimating $\mu_0$, but one should be careful that these data are in control) With the following call one uses the first 2 years (104 weeks) for estimating $\mu_0$ and the the years 2003 to 2006 will be on line monitored. <>= control=list(range=105:length(shadar$observed)) algo.glrnb(disProgObj=shadar,control=control) @ \item \verb+alpha+ \\ This is the (known) dispersion parameter $\alpha$ of the negative binomial distribution. If \verb+alpha+=0, modeling corresponds to the Poisson distribution. In this case, the call of \verb+algo.glrnb+ is similar to a call of \verb+algo.glrpois+. If $\alpha$ is known, the value can be specified in the \verb+control+-settings. <>= control=list(range=105:295,alpha=3) algo.glrnb(disProgObj=shadar,control=control) @ If overdispersion is present in the data, but the dispersion parameter $\alpha$ is unknown, an estimation $\hat{\alpha}$ is calculated as part of the in-control model estimation. Use \verb+alpha=NULL+ to get this estimation. The estimated value $\hat{\alpha}$ is saved in the \verb+survRes+-Object in the \verb+control+-list. Use <>= control=list(range=105:295,alpha=NULL) surv <- algo.glrnb(shadar,control=control) surv$control$alpha @ to get the estimated dispersion parameter for the salmonella data. \item \verb+mu0+ \\ This vector contains the values for $\mu_0$ for each time point in the \verb+range+. If it has the value \verb+NULL+ the observed values with indices 1 to \verb+range+-1 are used to fit a GLM. If there is no knowledge about the in-control parameter, one can use the values before the range to find an seasonal model as in equation \ref{mu0}. \verb+mu0+ is at the moment a list of three argument: \verb+S+ is the number of harmonics to include in the model, \verb+trend+ is Boolean whether a linear trend $\beta_1t$ should be considered. The default is to use the same model of $\mu_0$ for the whole surveillance. An alternative is, to fit a new model after every detected outbreak. If refitting should be done, choose \verb+refit=TRUE+ in the \verb+mu0+ list. In this case, the observed value from time point 1 to the time point of the last alarm are used for estimating a GLM. Then we get a new model after every alarm. In the following example a model with \verb+S+=2 harmonics and no linear trend is fitted for the Salmonella data. The observed cases from the first two years are used for fitting the GLM. <>= control=list(range=105:295,mu0=list(S=2,trend=FALSE)) algo.glrnb(disProgObj=shadar,control=control) @ <>= control=list(range=105:295,mu0=list(S=2,trend=F,refit=T)) surv <- algo.glrnb(disProgObj=shadar,control=control) @ The predicted values for the in-control mean in the range are shown as a dashed line in the following plot. <>= plot(shadar) with(surv$control,lines(mu0~range,lty=2,lwd=4,col=4)) @ Information about the used model is saved in the \verb+survRes+-object, too. <>= surv$control$mu0Model @ The $\mu_0$ model is fitted by a call of the function \verb+estimateGLRNbHook+, %% Instead of using the standard seasonal negative binomial model from equation \ref{mu0}, one can change the \texttt{R}-code of the function \verb+estimateGLRNbHook+ to get any desired model. which is defined as follows: <>= estimateGLRNbHook @ \iffalse To include own models in the \verb+estimateGLRNbHook+ function, the code of the function has to be changed. In the following code chunk \verb+estimateGLRNbHook+ is modified so that weights are included in the model (here always Poisson, ignoring \verb+alpha+). \begin{small} \begin{verbatim} estimateGLRNbHook <- function() { control <- parent.frame()$control p <- parent.frame()$disProgObj$freq range <- parent.frame()$range train <- 1:(range[1]-1) test <- range #Weights of training data - sliding window also possible weights <- exp(-0.3 * ((max(train)-train)) %/% 12) data <- data.frame(y=parent.frame()$disProgObj$observed[train],t=train) formula <- "y ~ 1 " if (control$mu0Model$trend) { formula <- paste(formula," + t",sep="") } for (s in 1:control$mu0Model$S) { formula <- paste(formula,"+cos(2*",s,"*pi/p*t)+ sin(2*",s,"*pi/p*t)",sep="") } m <- eval(substitute(glm(form,family=poisson(),data=data,weights=weights), list(form=as.formula(formula)))) return(list(mod=m,pred=as.numeric(predict(m,newdata=data.frame(t=test), type="response")))) } \end{verbatim} \end{small} \fi The fitted model from the call of \verb+estimateGLRNbHook+ is saved. The result of a call of \verb+glm.nb+ is in the standard setting an object of class \verb+negbin+ inheriting from class \verb+glm+. So methods as \verb+summary+, \verb+plot+ of \verb+predict+ can be used on this object. If refitting is done, the list of the used models is saved. Use <>= coef(surv$control$mu0Model$fitted[[1]]) @ to get the estimated values of the first (and in case of \verb+refit=FALSE+ only) model for the parameter vector $\beta$ given in (\ref{mu0}). \item \verb+c.ARL+ \\ This is just the threshold $c_{\gamma}$ for the GLR-test (see equation \ref{cusum}). The smaller the value is chosen, the more likely it is to detect an outbreak but on the other hand false alarms can be produced. <>= control=list(range=105:295,alpha=0) surv <- algo.glrnb(disProgObj=shadar,control=control) table(surv$alarm) @ For a choice of $c_{\gamma}$ we get \Sexpr{table(surv$alarm)[2]} alarms. In the following table the results for different choices of the threshold are shown. <>= num <- rep(NA) for (i in 1:6){ num[i] <- table(algo.glrnb(disProgObj=shadar,control=c(control,c.ARL=i))$alarm)[2] } @ \begin{center} \begin{tabular}{l|cccccc} \verb+c.ARL+ & 1 & 2 & 3 & 4 & 5 & 6 \\ \hline no. of alarms & \Sexpr{num[1]} & \Sexpr{num[2]} & \Sexpr{num[3]} & \Sexpr{num[4]} & \Sexpr{num[5]} & \Sexpr{num[6]} \end{tabular} \end{center} \item \verb+change+ \\ There are two possibilitys to define an outbreak. The intercept-change is described in Section \ref{sec:glr} and equation \ref{interceptchange}. Use \verb+change="intercept"+ to choose this possibility. The other alternative is the epidemic chart, where an auto-regressive model is used. See \citet{hoehle.paul2008} for details. The plot below reproduces Figure 9 from that paper, using \verb+change="epi"+ in the control settings. Note that in the epidemic chart not every feature of \verb+algo.glrnb+ is available. <>= control=list(range=209:295,c.ARL=5.1,mu0=list(S=1,trend=TRUE), alpha=NULL,M=52,change="epi") surv <- algo.glrnb(shadar, control) plot(surv,col=c(NA,8,4),lty=c(1,0,1),lwd=c(1,1,3),legend.opts=NULL) lines(surv$control$mu0,lty=2,lwd=2,col=2) abline(h=surv$control$c.ARL,lty=2,col=3) legend(1,20,expression(GLR(n),mu[0],c[gamma]), col=c(4,2,3),lty=c(1,2,2),lwd=c(3,2,1)) @ \item \verb+theta+ \\ If the change in intercept in the intercept-charts is known in advance, this value can be passed to the function (see Section \ref{sec:glr}). These LR-charts are faster but can lead to inferior results if a wrong value of \verb+theta+ is used compared to the actual out-of-control value (\citet{hoehle.paul2008}). If an increase of 50 percent in cases is common when there is an outbreak which corresponds to a $\kappa$ of $\log(1.5)=0.405$ in equation \ref{interceptchange} use <>= control=list(range=105:295,theta=0.4) algo.glrnb(disProgObj=shadar,control=control) @ If there is no knowledge about this value (which is the usual situation), it is not necessary to specify \verb+theta+. In the GLR-charts, the value for $\kappa$ is calculated by a maximation of the likelihood. Use the call <>= control=list(range=105:295,theta=NULL) algo.glrnb(disProgObj=shadar,control=control) @ in this situation. \item \verb+ret+ \\ The \verb+upperbound+-statistic of a \verb+survRes+-object is usually filled with the LR- or GLR-statistic of equation \ref{cusum}. A small value means, that the in-control-situation is likely, a big value is a hint for an outbreak. If you choose \verb+ret="value"+, the upperbound slot is filled with the GLR-statistic. These values are plotted then, too. The alternative return value is \verb+"cases"+. In this case, the number of cases at time point $n$ that would have been necessary to produce an alarm are computed. The advantage of this option is the easy interpretation. If the actual number of cases is more extreme than the computed one, an alarm is given. With the following call, this is done for the salmonella data. <>= control=list(range=105:295,ret="cases",alpha=0) surv2 <- algo.glrnb(disProgObj=shadar,control=control) @ <>= plot(surv2, col=c(8,NA,4)) @ Of course, the alarm time points are the same as with \verb+ret="cases"+. \item \verb+dir+ \\ In the surveillance of infectious diseases it is regular to detect an increase in the number of infected persons. This is also the standard setting for \verb+algo.glrnb+. But in other applications it could be of interest to detect a decrease of counts. For this purpose, the \verb+dir+-option is available. If \verb+dir+ is set to \verb+"inc"+, only increases in regard to the in-control mean are taken into account in the likelihood-ratio-statistic. With \verb+dir="dec"+, only decreases are considered. As an example we take the salmonella data again, but know we look at the number of cases that would have been necessary if a decrease should be detected. <>= control=list(range=105:295,ret="cases",dir="dec",alpha=0) surv3 <- algo.glrnb(disProgObj=shadar,control=control) @ <>= plot(surv3, col=c(8,NA,4)) @ The observed number of cases is below the computed threshold several times in 2005 to 2006 and alarms are given. \item \verb+Mtilde+ and \verb+M+ \\ These parameters are necessary for the so called ''window-limited'' GLR scheme. Here the maximation is not performed for all $1 \leq k \leq n$ but instead only for a window $k \in \{n-M,...,n-\tilde{M}+1 \}$ of values. Note that $1 \leq \tilde{M} \leq M$, where the minimum delay $\tilde{M}$ is the minimal required sample size to obtain a sufficient estimate of $\theta_1=(\mu_0,\kappa)$ ~\citep{hoehle.paul2008}. The advantage of using a window of values instead of all values is the faster computation, but in the setup with intercept-charts and $\theta_1=\kappa$ this doesn't bother much and $\tilde{M}=1$ is sufficient. \end{itemize} \section{Discussion} As seen, the function \verb+algo.glrnb+ allows many possibilities for doing surveillance for a time series of counts. In order to achieve fast computations, the function is implemented in C. An important issue in surveillance is the quality of the used algorithms. This can be measured by the sensitivity and the specificity of the result. The aim of our future work is to provide the possibility for computing the quality and in the next step to include a ROC-approach in order to have a more formal framework for the choice of threshold $c_{\gamma}$. %\include{extensions} %\renewcommand{\bibsection}{\section{REFERENCES}} \bibliography{references} \end{document} surveillance/vignettes/twinstim-cache.RData0000644000176200001440000031605414176021011020614 0ustar liggesusers7zXZi"6!XV])TW"nRʟ$g;X(k/$3g=\`xEe"!_:($?+FH)P3\M57ءHu) lizTGCٶIZR#6s<ڌ~J9t{=9oG $ЉYR`q_',|[s2͸]T@ 4z)q*5 ق q|[ۀ-HJj"Ǵiy^2(?J)WYfy~pcVɣrx'gAűڔcv/Y1Aкր'}4Z- 6Vˆ9EBi/;e!p]ũz"X`(Y<4P VO4ŐH6q~ԸG(a%D<=@-dN}j2 ם_@i:aHZ%IP(k W֖Cfѫ @e~yU1L~|=uJ@$'uքpHzRV{ඈIK&'ᘡ9mz-ZkPЖ"A"%nx2:8KeLBI%\`0pJTxP߶̐SiTKAݳy}dZU9C2)X>A,R[ k~ Y(d"TD ;t,8"AoA0P߄EN>6^* yKQV+14OxC[pi4@R1FIb}++oі9ueQwZ;}4(&]S_okb7e/JFu%9‡kb 5cCBn WKF|Z 8k=T3o /4]ީKe,]*;w̌Hw8eڙحL?!dy%<}ӨC7z;fCjS)sMdv}F+ aӳoqasC3hY"$i秂PVyz}W݂@vK,[FGh8Ǿ؀ F0Mr= ⹐ހ[۲EmW+'Q]}&*eU`ب[򒥬|a0`Q]00\ _Mf ʏ0žgOnsb0hnv{o#~=b5;j3> KfkZOFHeac6B,J* J?!rxo2~Znxw}ZڃTrɸ> %M@B=ʔo e)*IbA{jZ)6Ιf̭%7_d^ZNI ( 'EFE ή8KA{xY};dƕZhkî,tQƆ7kj`P=U6XE)ZǶWg./cZFbFq~U??^= c~), 3;[u,5z9ZRo"ܼ{ _1>]M59! 6ص'_LYz5`F $lXG5\z+DP]k$kr?3t*m@FxQvx>Ӻj|O_&^NIzh!~%MChjm\/ޥa[z3 LQd.Fr(o9^ nt64ɕ/4٤Y;464ݩ˛%Tmv0n^w=?/3x$:mB:TS:<;gtEB v5mK{$۱t&T~:P,RSmUrҗe1:"~]Fw!#g\Fu0YLzt}sYDפc k"zC k&R]%K/50X?Ah0BC)]߄jwō(4RGP!,sih՛%.ph#a '_Ě.F.~\?=tI0=hHsAE> xo B|<7nQ͓ jHDk|-5*5+_+_"R2]"&T;: |[9+fer| M7 (1Nw R}IHے_ľNĨYwjx#nZ Af] i? viհ3U'. J6=i9}Ӌ˦hL zib$;B͏.wsD12* WxٽۏXq(Ⱦ)͚V?<8@ၡd-#˶)n}&E M!SNG[o?%,VRL # ϕ5lz߽%=?AWO5/S x2\̹@L'L"a+vevc,1ڊdsohypso:ĈϯA2OUu}, bfK̇vLඛ \րRJ~ tkMK65(8w3'T@X/nggiN ?>\BeE0@uO|^qE'&d8_=]L|SS?d_E\%[:Xd/̙tV%rZ,Is0sR{]vv;%$q|e8{ĬpY·^m-_ZǰL_rD VFgGPAx! |T ~#cבmPZ n91Cc9L !{ˉqk8z(3V!q"h|pp }^y"z;$d9Xdԑթ=%[=ިʘug@]̘~ cc~ls%?qɮ\d5F.'$Nuܸá&F{g>PJw&/nLm痗xߡJa<ê56sc*|`S.s݂ʳ7)xwB.A9 &*#^wL8'jee"US`~ $bBOsX)!gԨ=Y:3݋8:}TH_\ӶR$F:>|#~Y=0]Va?4W&untp-;1I$v1oQKvK@Fܹς׏ Hϼ95O=qml𗡩cۙo{Zd{oa"/ D޸am4쎪z _*<czUp9v{eϟ#w{HQ.֞orєU1]Y9UoEHHz>Ȥ$=A# /韼sf )T{ χMlpZx"E3% yyR!ӏ 4IuL.QedǷgTP{!:r%nt\ }q~|cr:(cBrc#!Yji;8K@.|KIle'oJy,Gr;I JGH30.$GJB]E0vr`R3e'E=Mu2psG2|A!)wAX*(Z҇$EC/I9T}x5XHQt>%@t§UסKR2Pf+\[Z"YZAP&$E:ߜF%~}yZ:bW̼aAMryH/'#s+SLzur/μk}(fE{)~Į,1ށH饅ҋŧ\}px3þZ'g#_a)x.RRPcۈhEQBR [mAwY!֒wĻ^=R^G\<0"t,+ui*C:P?S&&iJ>w])eO𽹭;BA: odR3`|^ `'Q6('J3?mȇi 1hf;t`Q%p򣗦O`M*!Y=W8v茺+*pGxy}3L/lj8/_ͅNdr|\$(A4c`q*% sA65뇖CS?|D>>VȤ,n)+!&xQyl͌sUtA~f}h R{k *ԦSbF N'_RI-502`sϒr9:mtz?][ \!.#9vެG/|YP$LUu@{βIUlZu-.ڷ΍IP{yP_p5 ')I(=pؚf.^בߖO"&ee JFf@؆@ʀQIK8I5$lj]HN}?V;֟8 \v!yE7`?Z|7L&<<;L )}WH*C̲@!K.؊8Q6_R*~4{;LpkoY`VZCRդ4pPYk8FJ}o_/n=%*ˑ&Cu ! %S%o)Ws2=+һYbPX(b6 C(ߧ5}\6֘}sJXYiGU  hKXī26\qt.^E0,RTGƳ*$}LZo`~~ybّAT%Xj]̎T[zM{Hd`' \:i{TZ7 =2#-d͔xY8#'!y֚rBkJk~9_r|Zi4=] *]Y(Կp{CG  ܤpP 97H)r^'I!o`? SmTp\G0x.dau,i+}"bkb[kic> e{Ȗ1_+GAS=|f{4C(Dhgtէƞ٨yJ U0v('?S:/.bO] zi3U[p`Pr VA1A8bSbw d (/.MV'ՆKHf#z]@ rЫ¥8IoߓSuYr@YmF=Y5I/LO0U X:~9 %\} U\CDmmk'@" JC3/sy6j,t.t[ۣ٤*V ?跴_tU/wr"[7GUe`L:3Qf[W&)z Cm ޫ~9jxZ9!9+lVI^Ndz[4tZz4i9a\O}S: 2|- Sq?x`!s_ F/Bno. 'C(Cݝh^%VC*"̷b8~i㟊AE<t-RUSZ x8y()`h wk2`QaܭSͬ xU'_{S YS0<~:”'S",-2:hKźqsz嬥vЀ_?qF.rco^4n Nme Dbx>>{!4u,{Xi_K<5&|G/o4n>_]M1A@~Q#lKR-ex9w: &ǩ )p0Pp!j9E B7zJW-(rlѕ]2(1S)߀V:`fM7U;rm]>) v~F{+\}v%bygcC-{F#{m/?n1`[҉%n3tMsNϱBOf/4ͩ%I-z?GU#Hc|.;,.W+ .0uH#ѮaШ5Ԑx4aW0RqjCո& M j2rX*;-MQz&{#a&\)zMiJ49^FFO~+ԦYH6=eo-=^E hxx0OTb :0`|dKjXlCJ< }L^ntrG sĥȨlO$I2D7qi `^KD3`_BzN%cV~`9y))5f`?/߅@V,5ǿ״髸rKujxmH(*zRx]%&m "%ymaµ b򵉘:b|9r<*=> fuHsÝM]~u_#n&CJRXJb^*a1{H`aJ_;Eqb(>[ lk!Mɭi!0 "[1W&N &򵙡['k.=X,"|x֨T6]UմuJ./ld8 dgc5WA_XOhg?ޕ}Sm٪ZAͳO{D𓛥)s2[s*kJ/j:tm#snIO(jmTնW{卶z=$\ص֨=<$% ,ӪMf,H]J`f8q 3xa&9yr8ĽJm\ Btȭ ~/G-b+140@vwu^V>kudĐN̸ښ!KQ 4ڱm!Vf6);̣9X2,!Ivu+^֜u^F9'?4 GO -zTP )d/SƐg8TQM$SA[آD(L$ %oYıhR| )B4qO({C6 Y&U>klp2 \O37&D\ajN֌ z53VLT- y(&-m5&%Ǡ:㿨#Y?xR?+ P@alH8k} Y :PP{fvoZ vw\QtF27uP8aX\ v?/{^xK`pWFKUF\wk%pA- <`qpwXlЩ F] p^,`m|T2^dMw՘c󼱋f̶M㋗KmNӖGAXڙ0!e97Btu+.Q~0\ *& V.6ph+l%OaP=>,LS84L{RGn HH;a^=sx:" oXS[C*kmB]1[_xHֵJuP{o%ƯWX`ލw^ kY~4`';#Y_yKpQTay!Z~JPWrywe8=2>Вvv]仒 êèU>B6V EY*EaJ,́'`yɉr+9iwB?;<a{@}43sQݴRPg@HQq)!RJuXd6ŗlfe#Dհ~^/Px-P)/S7bJi 퀵`m2l(DE =6(׷;-r`y$ P/ ow(MYzcq\[79bn1lڜVŬ{lνnAY{D Sw-~TX*`iW.S1΃(jhWl@?/YLX9 x?De3o fXmu Zޡ Hրp0%p.FX&je9B(0 ܴOiHef8X1GiF& E\58At."K [*ZelȆA ̌}iNw|-/z3#ym?hm. $a0D"W>w;6:eB2-at8WߔA3J4֫B0#fF3AG=eፓ[ʈKK6Hgv ȝ(9Ri3n~RD~]nu~sGGvwr'T(^ ߹t *Y/yFSELouܡe&i }O [HYQUl)*2Nl?ՊTS8ƺ*H<1 kVzߢC@tLO>KS?C}UqdMow뙜A!sa[Ɵ+hkLT ‚JQ ِԤDUbj}f{ޭ39smE.fʎbpQ8D"gg]PeGㅡS&|y ivBqZHcQw,i$}CIcW2sHAWʬHeyo@'Z@+6q8Ŭk'J=["F".77ҘD;nݮ sw]vzp5jIW+w!p2TǬ3޹KZ_cҐW +e 8=QPrC;|W,Cdbz( Oӏf :VVh&U?ۮ4}AqsAFrq/Iݷ#HxRpw; s ][31gX5hǑ,iyncݏ\>Eew~$bϵHb09X9E׾;xڮ_x ctO`齑֡5Flܒ ?A=/oG*ȻgDiuCIј D G O L7|K€ME=KJ~SkW2[`}HvِQV$J0֊6 ~ #(YO%œ61Dj*M|o 5oXgUE0_ms aV們wo^0):{Q4_,l84Y& Z_H+*;'^Tb[*"f_p`_!rnlq0!IVv!+&Y$+ڜ;NG֨MDB.(I*VHrmK^2 NvJÑdܱD3E*Y+{/8@ǎoP$SRU& h}A3/nMd;|e*ڳ@7k?x55mB;JDu_SWT2;5#b~ cQן@U`.ayCSI $pGc|vu 8=5^)vWj*g!\1ij;f(0,uU49ZSse>(kjU|7@?!VnV+Y(jo7 &{N%X<"a[~GW6e^O"ZV@u_><1#)ƛ╖>_E8y.b1}S:ોm؃wǢUq8FsvAnp?7mtk*j )/v3[a.p,[?_y136hr.2JV*M5b5j+V7@: UN(K w(@uJGuW~fN_o !g"ZŬ>{jfVSVz6+?s iUj,' v@{%9Sw\B^wv ,'9EBi~։j ! q*kؚX\?~qzX5A+%[><rx,X X-: ª5hȎ!\QE/:E.j=+%"&sZ7 kAJNf5Fb#]pt G=v,8tp2ABd{ܐ 5 V4Z(aԶiRO5= vY3Ce2PlE 4)ԽWd<*SVi.ɲdqS@p`[[\Sn?Jz^A'п.S[Mw+9ӳbwWܱkz?Hzk9N+ KOV;SA2mꙕY~eJњ~צi*͙F@z&9W_3 Qd[Kg4vo:!VF.8Ȑ5GSE,t%Q] 6Hb鈢b'P3p\BK V\.NP>*24~ 5 {C^>{K 0N0)P^#nH/Cݵ! MVS9,n `KuىS2SfĿ%#kyvFlnLGd¼`u`Hk1d#lNQ'C`' G 5վ C d\+lb|'V-CH"D7j+ q"dD14hr|٫Brc r#sj>E5Tķ6{5xr Geڑ54koc٩L4 9Y$o@/ƼҔL 7wzK&ZAJgfR⯺Ⱦ~-$>Ix!y${DZt'#ߥ3IJ`a~whz/>VZ[g))%/[[vf:TcŐl.麃p4즙pH~Y(sF|bQ{?,Ey{ԯYوYvOJ ]w+EɆӶ 4`n,74?~Π6qCe?qfF{ю)#åSG-,r.M|͗|HEMD  qEw2*f{tWเMl)ܑ)!-jg%qiNVIdb*P.,J"NHDTcv~`A1eCAVmgHÃ9ihMoYy?XF쟜͙I}3- : zS &VT¬ZsnNkp2VcbnsBރ' i3?3ipN0 (vWxm%ȴAJF{WG1=q(䋋5A{YF s-V5A1k5.ɗ4rG  ?m#&fP 19MoiJ.V+ *vA멄&zm$#౧%9o8 WydIeZspߌbΕ"RY>I,; mi{šm -,kUaA6|8D0Kd'޻@#R?KO"9Hf*6Жh2$TqJq mIv˨lKܴ͞[- *šy~έtO"C p>V]R]iU\nxH5;tLT/9DA3_J0O 9*'vu$gW`>'M*EkM<`*k$8 %cWU_;<-q>mk~(@؂[!*,g`L.4@˸yEGKN-4{>R.&2&gfrB8;s`4k'1&yEADW5-i40Q&/:2s!!6V_:bu/Z5e(,.<0R U]SHo˅=6(+RRrOKؿڒ9$@97ɀ~qx-R՝ HQ 3gBYt-B9.bnZdjŅZwa0k}LoChVMm0z]#cJV/|L=.JoniGcF698RKV[<#'3L+ܷyJ!ogCPoŦc}5*Xy,4'ce_~;9s?5$(lN]ʷ.pXc`7;:Fq*=q ${reFGPmIKqt|i=4LoBٲ_8K⟑oeT®Jv?-94Nj8ޞm lg0M cL0'1_RL+ך-iz;:Rlf]7Bب >1Ia!(\EBcAnAQ5&<ši'OP"} &}uB4kq!n Hf] D^`j VlzINP%{) y`R!35 u-7u5AѺ?!X;u21%AѲG -c{AcQ#&U6L@xOL؎np9qK7)V|D y1]H#kޱBڣUEr%*U"vT@dCwY}Te8{`3nă ~SIflJ1Z0p$~d8Gjy ^^xM:q* ot"_f fPn=2,jnrYw8ccq]Zx%^tZnZjUNȾ3$NJը5 #ch^׵_ސiXPTKcS,e7ԑeΩe 2vgu]Ұ1/|X X[u"*\{^>!.כ|^N_}<[Psj^ij]k(.ѳ z-f$>݄M-|Vp8wx+o`Β-v+- VIufwSE4kYEy2|E{Q~YUi+ﰢN`d,i@Zx T! zyHՍP3u[#791ӽ1J-RfIӼq" Q9QBs׿|V).n%b:7rKДIAZ5lr[,ayKD"2v;lfO)VN1.rz6e0ASfӾ6B?YPB-$],>ZY4[Tǹa|?Urޘr:L/aFMKx$n}hE#A[q3W[uU ^ZtΚAFRah]Z8fK"t1G,IA˃)2\JJ̃sh^ msɮKxREǓ a xbu[鏨R5I{R}td~·b3k"ss*>Z=l1HH qvzZ.)\Cvk1$"xlN(%oY'D\mt)9Xӿ‹hj#8VO6QiūNA3?ClBؖC%dttd5%Y]̠+JC`5 q F$QI-Is; .:d%#pLzZjk"Oml㷮> _Q>1!-02 y'TNhyWq~*NnvL7ل(l\HzIpߡʵp~:E9J Yw7J5)43r|.JLeA |IPm.>yHj6Gʉ]n'*+L'mleCV@a|<^N5VK2S !U0b#-)^?'jW8SAƭ&&)vT u,w,}8ew!9?K)s}}O/{^u}jE 3V>k)Y-F xTxW(i$] #U-O7Hs2ز.IRVe2 ^T7dU612TH{FUSWkɾPs&ͷ?{1XeG"րC}&gʦBiީq%yi_=Y5ˢͻ~[ ҪUmLuIwjY +fp;}WVJ )IfѴ68}~STk')i@êb)Ze,~fJRPzn1 iLL9j遻/xΝjTOC!}yL'=)#a UH>V=} YuI它' 9V iW(J)D+zjU V"ק$=椽x Nq@Ly^%7nJ] lu6K<?5gWe[1s G5nz].9gI$| iy̼Î|N7[GBa;vsA:WQ\?,^ Y\O: Յbl.'3LKNxN VoZB#%Z6UO^}ۚIt,T O"sP!5`)s i܃Io꾓3B  v{;{(}n5Kۜ.B~PEbŴ<9Dc!Q׫ ^BK=.AVnQ"Ch-d 1=Z!16A,=Ks9ĿMZL;2䛋m 3B}Đ6jʼ.ٶEqB92"Cz02lvFZ L԰yݐ#Z{h nK}eDKNB\MjΓMpk^ՙqQ׎zw}載T SaD 0Q8ZnhߤHX-rnw&S[Vc `/oVϢ٤*M=I"+^RcKy ґD(S) p gФe5Zp=f3l$d_c|q7F:ѧ5Akj1Fe'}C3]xspkOǐ֘5?LgJ0c^0dBR.27 Ώ2l& Z"NksM\y2;P-=d7na(JS(1Iv<-֞[)Mq& ~.ww!xjsEs'[}HFbBvb\ % bw3ok?PI+Tm+ L9_҉|v1:.u-O2FBB\,@<'K4ԡa3oEC] lH|V'F/h$ՑPnh.WzFo"xqQ*cĎV V5|| f 3dzl lDR<<[͑Io?k3A02VR,kI{7-xXaWvI&y5 ƒS]KGRPX) ' UE a<V>`|^ j@ Qޫ 1GU5h+9ou! d20b>"jg[*4@i=oYx\ظ6gN~[ =K="ailbGa7\ߟ01g"sÐ9o`ȿsxxx`Bmo]14췱"R2$]ѫvМtCF̳zfj$Jʀ-ɻ: Lb,e'z+ f`Aޛ&f{7'|XƘZVK@o{v~C7(l`\ȸLВo!'$JoH+O^ʩ){/u)! +[b B&T\@N1DVI%q#.7Ȉx2WeHL#Zjz>|ˁIL^ݏpKdWMXo8{TFxgkB M+K? wKkm'pϳ)'"_@v?^_peR ZMA۬O*nϫb6=t{b>h Y27$y!^<vgJ Bv!T"o6Hz 2f'N5·Ha+W+/ɛijBƙ2JəpwkЉ+#C>t) =N"Ig4siS)*2PLcݤ9)s93c/8YT{n,,Vi_$[%;QƐ@[N3X#iRo|zM f{˳F^K+Ec; ,ag+BŦOB[Wj ^Rgy ^ӝ (pU8 ;X [Ey;_O Ԍr>?]#rP|]P~-d5)OX0ۚ00UΈA$OfwwNQq89")=Ҋd)vY$nqMCvb,Mh eb {͉q7eH<٣RBa!!RfJ5TeM? Ȓc`ڭ!&*sƂ9i /+fd8mȐKK] @fvhAN8ಬe:zKEA "%yɸrFz2vԤ;Iwo'#6iZcTɲ2tl'g0y wo+>3$}ӯm=mu2W@렅mQXNM(;S7V2vqB g7 ς*콠<`Ff1_O [egLnq"dƆE%_%-I:&={^v0%ZM4xOޕֹݵ;6AKהP_ n:% KOnHiN9ۘ&K7>$DVPgO,֯7o5i.WB!D>z-W ~8Gwx~%zW58 \s4;h!f_>ig^d}FLkNduO{"ټZ^k=<sߊYGviEiH8BOqOI[5&{6)v75Cg$0G/}Sva&~HC39瘂tg?4,,20dWݖ~(Xi0#SRmcZfѤRw RaƽGhOF]fU钘߳i*RtЏXKH|Iz?SL,)IWGM.._aG2I"WJFj:K7\.V,Aho$\,J9pT@ЛT$݆.vb7>"ϥ@L6ND, S%ǺǷO/j\*D/ěYaqoCo)J! qh3 vG{&ouۊ͒c5BF[7;~(] _s; mdPl++cʯ y@" J'f"&9h'^yQIGէWdr%ITrOƖ`*db3zѓ"3qwn&g(es7u#i(gy<#6hO}ڵ:^X\bfJ2Sezvz=26N&cwzd"-{kŽQALH82 F :֎LTxƠQXCFȠZ4~_Wk7v]Ͷ#)CWxH@aHy;U,hyb[%O!dbT'l>A_MKf^}{J6ПطF#FcFhϚWfBQ =)hrVF/骗A|ä ȿ-V(H@*VO.Ct\}J=NTɰ=3qIiۮ@B~b~Sw S ؼDJWn6wϷjFaʙĀ!aI y1WW=rC =:-.oܓfY0W(1Y2uEH<}}얦*FztZ"Ulbm_]e?M/`Gs1a2E @CzONJdi*Ǐڪ,3]V&9 QF0b1s`ѹH{߮n_|xVa~S p{Y-Q*Mw |{\|;Y2S/PMoɍ˰aOPNᨂ>f^9+Χ0%wHXgQջ\1Fn§jir)amʨ kxbu ?~]1AX2=DT#?~ў D!LH0U[h^յh?F~0op| L5|dGsmn/6Wܛ~M`=5n쬎:+_铩ʒl(mz["!h,+7PnyI|$Ϯqp#&U"\2 nW68κSиN\bEAQ^"<mSVBHe.b~ˣǦ>icLo<|@ fa&?1L?s!FafiUGsFc3o3Qw2܎M*cTȃKStk GLkCCj Tz2-XN 5Kpao̵7}Ur5c>H$]FaFHXp |?^~nC:(V0Z VIE)snpZ9Ɵ@ⴙkj)~`W_OTqʦp.9~ū k< _1t؈;`ś2(R%Ghќl`DwsQn!"8`^1ܒ%є]t?SL?Gqo2<<ޣD]mR$(˹ *H LXzuMsŁ {̮܀Įvd8e:}7D],z⤨%ykZ;4r frl ߹KYO`w?"$࿁|,qv/uO;:-$׵)]"A ׌v>ASt&tbmv9p3fљ<uHH%U& >i"|Kt,Bw%[D;N#4yʆ߁v!jȞ~3%5=e.R%c3G=YaMG Y9J0{@ӕf.w3b^./eMCF9l{ql#AU+Z0owZ_91J Ʌ+~Y0Mq.?^4Џ=k9kG{jBk3VD ǶyZ\.2, g=UT0?,i z0[Nkϣ^lz[Lۉj8QElo WF@6vɁayeb0эZQhxXi|5oˣ[zG⒈cU=q7lFP:s b+Le^f2趌Dl@VZfG%fMZ$I^ʼ˯#:T}8f.xӨIF- w}z2lZdɸf#A}.ooA)4aJL9<[_6YuPO;`OU^i ƩkY{(5,I1_3Kdh%l(Zz,ǎU(t,0Nu Z!^<: uf3Db{- S={4|=j/ICZ]o'aU{dK">>~R;YCσRN[ |×fv.XQ `}E55[}'7@g" >VC#mSIo7*RuŸ8 ="' ({C*c kX՞ nT /)_KX: 6W?*c6 1lVYK-&,q{:cHtʐc ߨ|JT,S~DHT+w_|4TE%#z~ua[c@3W[waj-arQu=>yXe,X[{ߖ01G:(DcLS>CvN0OLvG _!Տ'Qb]P/i[q+[IgU)eb07oHurvSɊ]P? (.UI<_D$lmekZ803|~t1z>!V20O<6Ai3)c0!.}F%DW;TscBAvcClE䟿~`зM|<  4Axsn̘ %gyIKEldeQSXӾe:vvr-d+z፛6"U pCURm% #֚6LgPuBSdy8yW`_QZbW?LP߽VdHH_"7K:鲀Lq?Qҙ3Hnc1"JHc9v'5)Z/ UڰaE-.ps#HZp0E@YtN0Zr&3wKϴx8߁OLV1Nc8~3=8ݘ` )ڼb1*E{Yb5ҏY6A G:H3@J#̇QljX&4CwqBi82*@bE9ǝo*'[s/H?T}C7~hԘf?[(qŜ iTwY־8hn\l11EU>4}="/Er~e$Vo,^D$'O@h靓{FEF6oob-@.%})taj;N9/}0u) [ d5uC778trkhhWN_MJߒ(EGaMȾWpcKWuḗÁV'UIc]]˫#kNP~F^[85?5KirZ~Ӂ.:4dk+t^_q=ktz' Ae'e G0/gz@Pb[ Z=$x{ax{Lo*cS#eQ4D~qjXfNӎctulЅY'n+7cmiek A"oxk79\4vE.G)H6 j`MOr۽&, 4wR (?ABD$vG@B~;[LlBFR+TX'x$QJs ALr ]?#9s/Ň۟ {Fxӎ{b7)kLgM ۜ:9 zolHlϽmZh>BUϷJsk0^csETU )> > rܳ2靤yFs҂4?c!(HYqߤOI2ŠJD) !l,Aa[Kp˔HâV  jŶ W^G9NR/}i{) 3#>OBʸ@ւvc.b(d6j~U4g"b?$(x qJСwxbArOXנS1ʨb7mA׻!eyO5Yԍ h@OX2HHO0~'O;M26MTPpKčbf1Ӽ_JTΠM{4nrWrqFv,翩P~7D/Fq<0#]?CFhS?*fzk@rGT%Qb- EtWaR͏{z*- țato8jXV 3ɽxL %Xi~Gv0p}T `__S o[}WqjX>zV&I9CQ ;⢝oV>||LJ#4텁';{ܚ@ 9J90V~EvWQTȅ9)3d{-|#SCjv`OynUaeVEp&P'kbI GJI4mAӷjzW˧'9˫RC ԏ4f5Dz0&ƻhquUa$+CEYx*CDw6TRmkY,n ΰyZ/Noy -U!DƊ,|9Ac\yI׎nh @&N!\ICA_7JcO| 7'B9o9NcrY(db m,cfe|6{f9_[\ *G"xt~*9X|~h /Ck["g^Eَ#WV7[eQ=1q6`׵%а9u Hu65kAX%.|7}a+0rM 1_|FSіBV6y`r>]o%xU侁?Wz3tۈ8NkK?)yyB- hx\/:A^nmrauEfG$R:ɏ! CčrQP) w~t@hQ2{VtrC|cBB_1ֿe!/):-PrgsYR:hN9x|'۶TG{iO T؇F@XZz62,F:ՙ{!,f/W8+8iOy"1;>`M"6BD{>=r:TpkE.6+z?W`v/T6N4hC?IhĨ;ɱ \9/h W^iW~Z(E,X%^:ݷ>oɺ̥^[ O0jksr=ؽP j9d0ʼn:ahBn~qhET ߹u1 G5p8.|>f[6~#eKHrv oq-X40y`ԗtǏ:qtVv]o|,^]@w.r^T2[Bg([YmUkۉf&iN'[d6~56%ܷ~ Y!=Tp@F YgmkoD~ `*M̂A"E)܆$w("4gP}Zp6^<.0Vcm b$k28_Q,@^ s7OLmU3D !۾Ŋ&ѱ\ e~o ͲKH>Dl6:'[@0t_`GUo0v޿\/Z3!Ӱyy3l0N駾 '+T-y?l '4֧aexg`p;-﷦+оS 08c!m>upb-s= \>{YTp/>;|r @Hgfvb[3+2gT35xc=sw9Io9;IZ& 'lSΑ{r  [Ƥ_0!X$:_ӂ;Vw4wHyNcSUbnx7SMHn%D.wg!!&y}Zhʔq5ePrp ۶mY'T=0c9va؋B+1W7E͊٭&1@{ M}- &sAð.zF>4à441gu11BԃK,.W9ۺ>oyNͤ#7['S1u/Dabp⽖QE L5"yæ9R0p`-V),FAw_ͫEV$xrM {͑_/Jn4Wx#[32%1yp(3ԯ

ІpFxۦzp|[5Th9:mW=w6 ]kn0}0;i4 CV`v]fO+Eb2)hNz'hQӡ~6SQͼH(rÆcy0sJ }/21S$~Z5˜S*%GmYq&(ZrBrKZXΛ^ ZcpIdZ njBžmN<-RƢp|Z?@`6N tCM߈3"T 8ˆh"X:wШDjޒ/IU_5jxߴv{cV@)XeqL3M\+5ͺP؃7:pj+@pq_N:` (PrC`7S`{,L h\c⭑UHu+ vФv3sT@gBiUAUNjMAT®ʇ77j:j+YncWc?¶k^vj+}B; nm| [ xoWr pj@hEp>N{ @h׿;Zf/dlvŜӢ/m @>d𓻓ٽg?ou2Ai wJ'\ơhE7%`U>V NNf v=xBCLɌtHTvf7"sq` 7qЊw[I疧h_lۓV$,/xxkT@(+FbA*tѠPxڧH H]Q`ϗYG-"鎒τ$((|B R'wv3x zIl )QNep*4)#gLkrȚgo>z[Ub2Ok! Ws_J jn[Q !"WlvK18AƩ~1) ]t ȵ#ۑYk"!WKbgE*SJ]d#<6( ;~ 5ЬgA %Ǻ:! 8#=N1=iފoZ\ihGdiҰTqZN „r% o`[9Ğa翅XW1Valbx&8l1yx0 MZ|}\ pvۊ|`p]sA䰱/t?Z^0|^US6/IFdzb9Bi]05ؿ6 Ș)"r(|p 'Gk=8BHQnEMfp\9N80;sF터㵒XPh;xoVa(W"VEBeJ;vʡ益zDc@tav 4֕QZX-@f< 40:pu_V}M>QYXۂ;_;=v\31ag8F.JRv˝^gR3Y ;chW!'½D$s׍KۜM zt>Q}>5P-p^E]ľl 5,=SsSDKTRQóm z}gE&KǒM1rr^ϳu]rQѴiLLyUu1>X+s{%>Eg [n6KLw`<_2|Z0a˯=71k]0eBCieUtR'FA2#\cY_>lt$"h{@5peߡ'ׂa[omNA n0H1+Q̠?-UtЦ ٵNDݻy:J[<n4qp] _)uh=F0yaiqTdBu֡hݍM̟5ׯ$02hڀh1Xa$A&Sl8?vvZEGVz94OBLw~T\bPvT$7߇!-$ 4*wsdQXJ@;&%/{&q]8H )pl(I=XTV5# V̜dAG톙wC$KdWKRE.|3-La>N\a]ޏk/w\R7?w\f(gŸ<r̓Z=P7,^%FkB y1Bz5[\)}JVR FxA([&""h{7هq ^O.7]1-JhxWAߦ?BgCBi.>i=jI[;]mŨ\k8[ , sǒb(9]DPvIL- pQ Y0-¥ԶC-CTIܧN]ؿ]G!~?\=9Ơ$\B?j2M2;u* tAw;=DṪ /WcTBMIv]-E <-DQ*~>6BMtQ-:B">[`F`7*mmYo"gſ.N p@$ ݛֵܶ8Mƒ(fc*CљWx'3n`BnRkY:޶q}t[{my5x=bTpU W])o 4 bŽG J\>9bj' ظ\l(Tz$?XLRP|֏Jrϵ(0M*Nlߋsq} 3ٔDoo ^mQC^;gG'Fۥ:?6r xDɀ/ma/ PObU!1P q#6;J"t:-ᑙrvue/e⪎@E[lsFO%1*KT'. X+Pܯl֛Şa=L|̀)_Dm%C>4ur@~1q/w1t(F?Ԁ*dk#VJ} -RvI+.Rz bzJ>r+5<8MtU ~ 9@ iՁtr^)gr5i%\wk0Ճ8RK1W; ¤Z$qd4M"a5L93*z]Ԟ}2G:喯tKn09kh&kn} %b)3`]=zXKhK{#Wߐ4ti8./tx}WU&>fѿE=wb+uŽ"OBy9[VcڣI~ ͅSwV߰k5>J,g\ƢU{󪐼͚]T\8u SKObw B? g Q$׍ u fw-^4쫵atyg ߩ]˪RVKC>D#xhr⴦^T7rSu`~O~TNYe_QT|\^Ee_B=3@L펈NtDm`λ͒_Xd #Olc.yA;Ⱦ=_yzMJC<+|q)C9ބo+>עAop;fKewtfUUq@7Bj LUd|Q.b!A5 %qn\yrNæxȶ~DH.gAttTٽz|(&Hw%HKY7-ȯ9ub> ~b롖*h̄Ip}-Ӊ'/g 3mE7GBV ؟rF-'ZdSȓWA_@)1`Y#˜cO~5#qGٮ dRM){X{WI!!1i Xu׌H$?Kz %;Eb c+glY[ 6pp5K!~]NyYL _~aaKX~qxFeIӾ` ۠&ZnC[kڽ7&_f߆ ~O5KnVf9aħڲb"ѶX/RiiVƊ֕~u<7-BiV""͎ݟvz_tLp~蝦aˏzvZmJ)hV7@5^-Y^|nNdfvpW|J|#):TƄZW=5h9k-]e?!Gw/Icyb=p,䖕S&lY\H-!)s滯]&">-Xdzk)Cڂv!n)yu|T?GI̷Muy471,rWrF9 H+#Oz$L]-|Lz!ZǝaNf"8w|t^R)B&ȫOe4LrjAM~0Y3% '>Hcyc2ǧ'lǑl~ k' 2` &E)k{[ xah0%4 ':Fyovz$5Y-E'OU L+# :)kHqBG,,}J r*.sM/so,*cnBL35!#oH@ST3)1Ro!6&>Vi7Fz.$`qn: Ebi = }O@9CXx:QLۂ~[;g@ssxCD+\,: :;6 U\@cSu٠f=>5snewriR(JSZg@f+87֙Z$Ks_CZF.ьS˶=a{ Vn'O t |kQV0>Q:XKB%Ǘ "aјan`ZNɽ8n|RuH5e ^}\˲:z=nWϋ{`Hv&KAR!cin+iIbo^;pt-h}1w/CqO/ԀQ ?0W:>6l$JpEE?1;9  SFq.DJё3\Ә4<_r5wQAXsӝY}=5b?>uN~aT…UhA +4vi0r2os,Ş+ןIj/N}dZ2}x6:%0o-{%Kaݡ70aRGX2l_ZmtHXG5+H.*Z,ٻT[>IjsfPys-C+=rDKhan^?.J=-'P Ow!(@?T:ͷC;>e2.Omm&}J#8|imbI@^ylƼ9@R(~Wx b*}EwyfHĦ  "oc5ډsr.}Y<< =_}уF^svɟZ,^|0,jJq`m$㋜"ܻoǐхۊ\P#[Wx:̱V9(kJz%f&B%x=$I"1n)3`!U."}*mw ssg?i_-cZq.{HeC+W>@'0Lhen>ds<q tWR|Mٔ&^@˂7ڮT€|AR3ܦF3՚\ E3RM1ݳ|)qOZG4e50dGq](d3QzjpX@E6?gE\:p5]{Qw܃pcMJLO 2$HlbWymnpp@ d *TJ3rv{T1.ԏdEfǓZrxJa PRwA|x@ ,L{|l] !O!?'pph3 ϑQ%ZWF,LT=֖췖HiHbŽ%J/ߘ](mщ4oO+r^ _I6jt {09/EPX p1qzݙΌII (X;A]ۼa[gIR5U|qQ1 H!O.^"h^4 U[b:CsV~yɪ"1CۃV0{fAQ;J7I@-uB %(V(MR7jkjM|")d:]Q] /<32\w-CQ~%$#(+c8eo.+%.FPQSF}F9xw0ORiOr9у\~J>O}'mB'w uN$@ai'Oz}޵E_t=\Q qJ&/PL:fUk Zz Eˊ@{ô^ވLb!id yl_arK Ԉ胯$N =?M kvyMgtkquey$oPIۤҌf+0}adU? A)m'Z7$kc өb>+@HxLG3rukw%U~+) N/z Ms1ҿAA SA3 Zׇ]ИRvFERQ7f|qS(eqYg9͒]m6t0nPܸz).pO.qn?oCTV$q0'(=Mq|*`qEOuf{VܿR p؉&;`JWJ`zrXЏ-zVE"Pyib,M?hxSH i -gŘ譫2-XxGtB [?e|I~LAYiǎgG߉Yse#w~YS) d0<3 :p̽bߙ},^ctMjiV;88/TzXwH w.SD3Zsc:Efu9TE;5J'n}7EKZ{5lS [ $B6S,a斫q\GbX e6u3!XJݔA`ӟ*@;c1>VBf0w<^dm_6A(c᭼yRg ڹߪ5=;l%(C5#ŸT)!_$Eg[h\p!jc4/U-hqvR~2 /QŽ$=ihgUKfalxvlNJQ6uƶh^;FqFJbv!|[EZQjFU#1+-UvGW -cѫ@]gpZWF&[vyaG)]d!'ϿMov괒'+1@4."},\g&$[qS"Wrs*A^L)<h[6&Yk3Y5#FK+,m@PdȄ>&aؒх ,r^qTʍL #$D.Fr6c yAeڔptwuT/4Z@64YxM[4؜A}y![;>jCy}9AF >ɴv#۶iEBB`qڑnS=.*K8|1t%guk)UUGB9k&y]b ۝ i*6_pq6dq$o6ͮ3kyF D.(93d,טf|@!|cӢ \3=q RKXWrp֟F $>K- uQ^pG4_Gxp+st[ >A_):љǃ#J^ٿ^g0A-.AUq_2a61WTg'/A(v=GHDXYvIc>!0qQ5J6tƱ ,/?hOנ "%LyG"c㼴_Y'YF~pˍ1A!'}:{夞a=7o"w"bg qqHSNt(hA^=_y\' Q眾ExGՏ.b,%F_Ѹn?x:GW9easտ2> 3#'1y8Ű 5I@w\#4#Iv$5ˑ? .0Qm KW#< aPډ`'V Hcj尊RCjB3&U|E2Am8,}~Kw7nf4Po'VeW{ٹdilzV|"VbA3aPgW;GfvJ-R Ħzϻ6`L1oyh4Lv˨KIv|mNr|Qn xQ=al NzaR>Av /-TBOt",IJxZְyquPac|Jnw0I@6o#MjP.:uA p>1u><8 jD.*ۯ4}z^:g}白B*:clF|E\$9F3%&%\Di[[ +%Cb(NbHEuQh~_{C:6PSi?\*C%={wDKfOg G{ݝynޫIqRsہؘ/3xK7Buq@c1mCUkG◃hHd@1tV} Z{=Xa/n,t791m-*PH࿴0D2o}oU=H%U n nyꐽ e;$Sw[ 6օ& n_D\X i-).4RݔzY]dc iv]7~)AۧEmOӁBErӌk[B"ݷfLM!.w @"ׂ/cȍ&(:'3QrTfrTe=Jy!/ slRHrMD>,9I|0+|Vуl:nIUWV8ɭonQ Ө|wYpyo$gQg$â#$O&BƅZ,ہD kP;׎"1 dr NC5Rk;!VcuPNXuO-t@1Qg?ar.֭ƈeFڰ8x״A1'7} 5( 9 B.t:9‰),\cpR_nCe܆PU+\> ՛>k20ov0}x_ UbHK,D1X-nf)>ƵB%nIEܸ(OǍ0a"zI'+cvWEӻ=:5 دs%!`V\ۄ bZuyj+VqC}J${nχL.SX.ڄ5TQk^_fX}mIn f}'k *}3)TB*˟ȡ*?\K|C~jm`Nf&R \VocҺKItlir 69L*`&c# I5E:3ꆢD*# X_?V)PW\rOU0bxjt7az&5cghU˖kL~w+6n0M!VbNˑ`i.Dj98 -6 3R+V-KvS旲 9{;`員_@VKɂx-Sdz* ~6p -|2h!oPwAe|qNM>{g2C$Dljp|⟵Shc =Z={ R^=Vg-ԂWӨ&D? >TX<\ZIJ︗\]>7QbUI=ڦFqTYA}gVWܿK&oޔƼJ6c3CftSSQůIgA!UJ M`8:ˆ4vtώRCP;:|uܣ7ʋ?p2X7kJCJAanav3e ze*-XMoES4 M "]] p"$6d8\.Y֓*Շr6y`AX8\sEvyOqE 6Zy s<2ᆻ('8j{=@ӝ #x0e)٪6 Y>vBWx~M -[E|EDw 4PfɻcJRc0CEY٭H[zT%EƝHZN{_ͽoh9y++ ⨶* @dݰL.vB}oVL燡im!`q WrۆG:=!sM[/ kjp\fF=$TVFMNlYR}Pj3onQ{lG֥4ZTOx+qy 3&_9[Vv\Q3L' }Vҷl*Јfi H#+GeSySHߐu+h(~z(IYuah<8ELsZsie{jE#'S/A+̷KP6L[*`ʇ߯w~ӊbP e{RZ94Dǒ-qbJ["Hv=8]DC|ʆtNq+5HN z Ӯ֦@_Ww/ \"NrUp8ohR9 H_=p(˫l6o5v[9rPj1K8裡54UW>Յ&zƓNg;ꕃ|wt1{X ` $,gjI/IqG0`9.jP#B>  9}W3|O ĈJo`MwH܍Vr;ĉ 2(8޿*G˺Ԅ,#2<1pMeq+/\rn`9eΈjk0ĮA)!Bpu]LmZA"`ɜbJr*}miMn Y&}*3K&Yc'$+9JZ%q/G։$>Cr`25v(b?Q1UHk,W?GYQ<IŎr5nn5̝Gm~}Rsڛn0R](QM6~rH$bTccUg~MQP#8ģԁ?F0Fu5gpQFm3+bسў˓ss涹u"TkA2r˭H-U.åtC˳Y Ӻ[W*+[<"f,f8Kht8 LUJ .HH`=~A>)W!38-V{ ݮ4+Ko3>*\;i,]I(sHxpHIг+>V}2vJu:+G>"SNa)X8 Qc5"b8f2/7}v֍ݺZ =nD]]4NbA\eft7e^Rƽ"IaV+² d/d %)*!%P RޱiUC"݇f\CmM ?<-m{~& F|m[s}kyN |HB㏃r3,@f^\ b(" Z?cKnp* ^ymf$ɲ*u;J^(H; ՃFuX1m:7 EdQ ǕĂd;/n|3]Wh-GÓc] 5f< 4ާ\W<@x_>1|~o-M4A`1&`Kg460պCa%oo+I?&zKM^ ة$-:8mŐ3C ^[8;@fU lNHzw~}_E1υB몿ye)c*#F1P}&ZرD 1bjn 8獏sM ;5TBwYAݶ /)A/%,Wa+bdh%-J3n[,6•9m ~ ~0_oXd*oJ/vPt(NKP\ĐԘ#g[o=! =uD$ٽ=!T'9ѰdKm28\ %K{u+۵p yX=]:<9T q|$uV,+[$A*v"eq9#k 5?Ej?RK=~ O_rtC vï#G4 =܈ oa֮Ks}`^E1񡥭f>OS@V>C*KlFCk4ceyx  3t٭\&JڗDsIH6w{pFޏ'vRRos/9qD;Zx G^b zaӭ0/پX)V_mM^9 q]~y79F2ɬKf68HHCHN1…moXWQ_y} D [1b啢϶ (4I\ֿ&Rpw&itfUGn e|XC)r0+qu Z )r$vJ]w=3QoTt~ZHb@x453M:K'Vt'p^6(0-; _|RpY19l&4$289'3XV*LA [H  t1+X~.ztk&iAa_͍e7׺j! wBf͙8 -w/07R)|Q/@IyG[% h7@f;x~z p{Bu7-7/&41=¤)tS\ `gY贀_w&Ha _ av~,D-~#kC_߆-UVH=~Q$]xSqFyxѽޜ<@/ይBN0vB5ZvK,Z߸&Tw,?bos}}UDҋhuQGEqˆ4iHsߐʞBS>g?TB^R\$IiD r03݈eHfhvQW=E2#k%#u楋rXd&:q\렭f~l#9>AZ8wc: JvMcЏ.p)kѐ5/X\f1z0*Ns^p0Jo2O2ZP;Vg3tgtP^8x  `qF愴"~5ʸ:OY3/Q5OHM<ͻ-,1!<|D˙q>_5ZjwpI*O?e:`qܺcnگ}7atq q,yahjBٜ|W=,f<*/O3k?ʠ +ut*L[uZNv$Za>]ʘF .cيqU|a;%[0#,fJ\j[0/DuL sЂt /cfQkcI!.jͺ^Ͼ57zqkfeHdIzdZ*QqŲN]xKne)9}! )9ע}7*34=9&(;) ST`d]+qaV2hTT}'J/kj_6U1mIt:E5i3EGrj4>T EHK|Uq.CkI*EZ Exh~AZ3Ik{ v9ݖAYujTk6!OML`ekM\\TN"h)+HFKkEsnzi{7>UΤf+95Z|3MޒƊbxz/W9oJ/qX@+Doh:|[b_XӕH5di_(Ϟ|R&O5PbE$AFwlۚt;l YCepIҟgw4mqѦwR{Tӷ?;Hz#d|Lzkfdp}W~N`z Ɛ[L@R/2>:[tPAŅI -k8'`L/b6\'W~ ୯g{QMwĀ2I"ƦAܡ)-%'dz6Ess=W 32p߉5B.}}]+ -wRuD<(| MSZ/΢[LAGRdVϬK!Cz+{]n8ɗq|dy@xN/l"0=f~\U$ČQM2;I,{X#Xv$ݍQ6*> -h>jH]~dr{;|#DcƒlK~@Qb=2vy_0PsFD.[{$v>Ҫ6fJE 9O WZ4l*},sUf(JKԘy!6+gP{ 늆ׁ7]2I,I5yuV66Puj*+uFu>J^bԪ'mp">ݮen,]ڏk;Zl^XYP@F?AMoo1hSgAE;sc|M Kmk 6\(CrN-iF/!"k3F)j,:CqN!c-mǣ`L%9’a[t'f_!W~7CXp%qa"2s.@~y\r3,yN^of?m%; 6W8}٠99$ sSS] ك8/g`ͨPU}xU3DX 7*V$M.sB MV?tayEV-ԭ;:BSBRSt3"GШgU/']J*$\+ҐW>-ԑd)].3 O9*CWu)63޵݄'E ~ȝ4?'ucJ~'2l&,I"]aM[ Od+'pDnhFar|}Ϥ9~Fo k)3Sn+dr=vX{?A76 Yg4/"*M"A5;yYcX{"AR =Ha"L4oi9">u- .l w) kBFZ~01%|SH1LL]aG;֖QaG T$?=CXSy`$\Ő\C&^s: ;CǩTH{Kuk97KKqOQW$_6CMy y("o=xt{Tr-Y8?&DQL޵+Ҽ 0D8 `-?SWDΤA"~=vY`@"_>=tM׻Xu (?9)Q S飫6RTYJlOf6Nc?tG3'hSL$׹Z*'vz#LhXC[XĜc5wF6-@<<Д%:p2A6.DI”O{g-71@-f`8^"f H_\H8$ PPӳFo 3!5[Kީٴ 4?oAFw&Nd@(,p#9 ȃAgwӂ'oGS8/l0_7qUФ(➕5_ :+"cPpEޭYjX`\OHS.;#5Pln#t1l6g9Z'P#6ҭa(df 9ưA9[ t=&Bᢘjpj;Z\4Fg+E_z«/^?:ǩoZV 8½X4M9o+}=˧ɼNSd`dր^ߡiҢ=Z! s$!XГC[;GEtvRhh}Tg1V/t9#WJ.Ra< b#J{Rd"I#o6} ѿf+įWL:6 ʽB>~88>|rHzy*Ti~Qo&}a1l?r39xݠU7M3 zAK\p*F3]=U5G^ikTbtVFPp^?8cdVzAhD@A Z8.BY_+RA~q+޹h8<jKOw2P?v(wBs$Vm< *3D87[I8o?9ź FWYBFۄ/0?3QT5X&޷VsI2*3<| 9qh5>X +x%ݥ:j xpT.+ ɸb(K~R`FT PŠ 9"=TRv{lB=+OqśЉyYS'K.h XDVI~<Ͳ5ϥnI1dӈò^p>nh~]VNɑh.k*{vlL"xypc:WEEWy+\b8^̼UFJa?=Ho*=c=tDɐ0rq'g=vo򷍘up6ܢ\cX?$XjAf)u`rVHŊ {t!11e6`g HwdkB:lnat8_IgK>Nj_D62<;ɣ}a;8 T qάcCZ4D:Q/W\޴'ɳJG/l V<9P旮,?d]T? H}?SXvH7CQ'fJVXҩvWW7cEךItX(q ?, 0q_\Ģ}z39[@ٌ2V#NtJF[`4S\ _ (jMt_בC`( xk2CYf[p203pрX_L^L$['XBBby?KH,A8W}DTjmI:y_%5)EFt緝Cs,3ߋD[vt8@y*rwȀ c:wB)xP?+ޛg3TRQwRMߦ+lP6NjDTie!QrS6E43 Fs#hYLKSAl1㉀V`[+|B~sXmI쉘R g.@Ew+(H@938xU : XCI{AN(JAilOg}(t r9Z)CNQJbm*@Gl M,D~rG3A٧[âpI0IABmwt{<3ˁmv4kT|ѵ$ %|LmlP} fv=pyKwH^vPTGY6')|oXJ ·qUDc-mmv"6oz} GL %U9_<9Yh7ů3ˎcȳ|.U_N_Z'mUPKdL1Lj*5[PW3L3K0Dy .c~jlDN$kS8⫲ٍ{K[r~ ypڮ-3=Try7WZ HӉ=+X\5u֟ilЃ磤W܃e>9YZQi{NqLX 9sz:&T{lX KjZ?c17\Yy=T|T &0c6;RW-12Ob4egiF9~CmVK`i1 ˼`+PvwPJ~ gJ`Pעh^)ik]g;3F;HOD"i"Q;|Z^wʘ7:D=Іq"g̽vFNԿc){,@UF+=+gJgĚgXeſTN|k 0b"ҷQ`RgLajƉ'֦*>m\&[o_.]Ae eZR?#>N>pτ&!%.]'YI/e?xBjQ9W4"].̒څx +#ފ^Uj.I%N6]2 ko{_ܙ}Q,PlG[( 1j{ >8cPq 7*C#f69{/d{Pb8a/6 CӸ7-0HmPKCl{~VrYk*yF > .R3":MC'2:d]pH8߫bEv1QTQ"BR{ abI4Ń+&Xi L26fϏ>\hg`l!m}%2%6+luc\Ѷ7G畗 \cETPbֵȢ7&>};3r!dCVSohKT҆d[ q\M 0,;+! ohc3'@@@w* , \Q0 %pu&r#k֣QU@i\HU"m-RNwS)ԩ!k0gEQ>i:̴E |"0Lx8`h9ygR_uӧ #OLgrte{`l2jF]Ah*e|-s'Yt'LpJz ?])}'}($D[Zv6g7/L 9VsS0`&Ǫ7ַwa߿ۥ,2&Y<~ŧmO6 籼6q7Eߌ:oV"8I[6;Q5PO9$4Q$}x6F{H}{ X>3eF&.wsf~v5g<4*a))v<>*(ZSepx|QFr]$6M]>d7K9CN6 ?޲^r#fDp<.PF2U,e`c&:f"3|ْB8TCBƄK|kp#7gwi(@87/@Nռ@^j5ű XW屙wsӁ|#orM]Ю $gU~loMPmn6Ox@bnDU“`V(P6`]ajUI.gToXqT{FJAJerS;e5Gx"\,&eEIo뢛մl|ңDAR*_f>9 ! Xo ?)m*1_2(v،=w@[ёk%U옠h. 4Z kvAqg}߯|GX4.%b+$H+RZsoцќ*$6y*ĸ+ϰIXJP]:{lQ@;\ܢ&UY~?E1+SJC$p9qYp֧c4dk;*08L̠la2ȅv2(E3*(=M smbQE'NS6ņ4^@!բUKYEL3/eHU 7WCPU#I-%)riRU+pzp\;dڶy*#9az(qB*u۷@0y5 }|O0m8QU%uV=oƋsj'7mJngm(ấ{S,LekIH ̑$v?z _뾿Д)"B%("v-b+}Zf)8+K84~wn|gRrй>ۿIZ?)vSJ Gk Sߓ%?exPEt!2gmof2Տ0s"qu8Fޮs~4_bj:+GejE=EF-lz;N@5(ZtIZXsbHk:$bO`*Bޣ3xut{WTc61p+t^,ʞ9m~u4Z~0y;/-KMf P_ 8Y+Mo1;ΒS#e60/fd^mN=̓jݦ#|",\εڴGjP;kQQ>xcXJjw>)\` $UxN;uKSO}Y:4P騈OH8 sZw-E *U۹~Ӣ,hGi hmD42( *k(f}t l V1@+Ul&gM<1\T4K!&J~[ NuIG?ȩ@ߜ7ZZD3 3!~hNq\~D)yrHn%4zzJR>p Hrn: ϺRvύ,*E蠰5WI;&Za[<^So ;ty |`0aP4 $]zO/6ɣ_r{ҲT7*"E.<:ƍ*9`%Sg +Nc&Gv v`Yx Z6?@!Ph\UQ$7lh=E[;i*ÇҘ- &^ 0:+/ɏ4QhwYSi\*Y#Y`^t>uTjHK"0~Ş XtfW)vw:9 NT0&^2Q٧A"R#ʐ6Q'cV<8uceA~tl94 \qQlUɡa ?}1[['ydTk8f+HPrGjn*I<$ GMc4S7l(P"κ)TYL|ĥ.e)X&ip 'Vr Q!ŀ*G0X ѴtݧY*J:-X6ô#zudB%oDZD!'7wP m;#nT^%+}ȵ4Z7[ åQJ;A60!?勢[~p2M<(F1=F:g]KnAuBMX 0.<8z^ID%Xr[Ax_t"⨅}ȃd[B-^T bBVdF9Z[nͭ6|w&N+G'ҝ4;S==a m/#6Aލ pxn"4H_$J@ $UBK6* ˜^h4CJS\sRuᵛ2 KR.Z`v? /\! Y%wDoiѶ/pOk|ʐSڜѼ՘}E Zt޽>=,S_2?>/[q6kSN#\nVEٻfI"D Ynnͳp<{{5K!SӱV~䈩fU1;kmF] GY@wDvNw1Rڱ udɯl?= /p7ŇE Y8t6Y SGғ b۪G4ZNw {JzfS}`h|} hL9@-ZW ޚ#Oux*P[8QOZkm )gU18M1 +au5:3m6+6TeUE(HH1[q0\Ve[M{}YvyШA>3LȄ{kSWdfGE6:o"mfgyas9Ƃb$K_{V\WWMKf}BH0iQ[ Cɋ`9\Iz4{$w'[ bV /@ :Tfښwde ۋh/IxQ\`c0 ? -!m,|mbt7U|G  Ds01@|(_iZ0IN.|P+=_bVJ*W;P/7a;N+tkyG5JVv2`&m3 ^#T^L^q o3oZ8K-!غi7@u}ULd([5aeE>1_b:拿j0 ]>6Uf4oY'?*+aWC(2BC%>Q_r)h[^|awDwG.Pc͕Gz'$DJYS|lA3 D ':B ̮zƠ1s63|Q0W携< *9DP@6ON!9 }!\Mek(YYa ҥJk&WPg?^zu<]rXML\Qç]ZT̰z-t ϸbØ TP'DOS;؊45u*B~)-#ShJ6rT"ˢ<ue 47{b\m-|眽ɾ/>,VQmӈYd'Su <4`zBj]ɿ7Qy^&]H^ x!9='M B7ߗs<'TCes _ +HԪ7@C|lFэzד6C&Z2̈́@ڳƟnU#=Z2"3T &]=ʨ_l(<ͻ{"L|[ t2eW$czp[]4rW8fK\A(%UyDK$]g(*pQk{Gzu$c୮R!Ο!B=`TwZȶ@"bLQ F1`R /k,F׻Z 1" Hi&k=YJ7߻q@7lR⊣=ǯ+Lח1H" iB>tn$akh$i%iHI;*I?s7}_g[/}}e2=f`"JH*XN!DžqoЦ lo`S>].A{tU46X)PN/(S3-Z0^HSVAψ#N[]˩}{e[Ȅ(nʔ~&L~%lS+Q Ue{` =,ROI 8mzwJ9?Z nΎ[VͦEB_G$hI C+թk êՂ<+?k/~)RWQ|( W\(gE|Z=K "+4$L-kwA1cҖI{f^&vjw5֢>[-Oih ȞWzđ@=Nъh3g]x*g#sc-5g@j(Z(M&.Ig1{ RH>RhTR`4ρ3Ĕ3YӪ[S] ~to0\/6)+KbzLm%QAE)ՍSa-%'8g fbn96e_x?e_vn= ?oZ,ns2uˎYT, T#Hd5ZkPZٷW>K}M0ECЎhYjٸ+s_v(5\,AiET"߷E$",X5ej$G{3J 7ExP%b7sҠ K0Y*F)ӝaz{cV*8ҙ9,{bܫFlG11N=?_ZH8XJZ"m0b쉺aT ?;Tɭ/f~x yɵ|gyjLfR=|`V`WN+lTk%*3!ŴbWֶ`{Ljf_hk# BCV

y%AqE<i;vC@l  $;~./,f.)'".@-Qu"&p.IVBMjJ}J |o~P\h\C ( 'x$Prѣe,ndo}d[mXi7K+$ IadTӌ0Ds?ߞ fTuL҄䪦gРSEmbbi^8ч;>aY=sRL?zgІGieP& ;`XFw%uI^Z[?+~Lk FWj҉dK}p^*aؗ"hr41=Ovx!5W… $(-_mEצ oa%hAhWkE2tAR(1ȕmerܻx(0 ￸bDJnGULwyha\^p ͋?nDshn\EOT*@ST @0//$糁uL|3ߜ .Q}P 4m󉈣e{GJ}6ό@X#2L;q ="P>^zZzꬍYXFArCWYvr_&q1@[2Bn)O,:PHx;Y{_˅ZM,7otz}OI@κ?LEX,$Kz1Ya➆b봵N'0s `9eP]+"mGc,͓&žG# )ܢ k8'%RA_D c ][gEHzZFҼpf*UVڱ卙\Rl*+ !o79KO `v\qŬQto²œf :}j %m+y~]xatcYng};>GErBBI,[!9-J!Lݍ !VOAL]fpݾZZQ1ߞT И?:@Y+mgEpj[ԛf^gs'׎4 Csv{ BFOgHp\"r+aߏ]fo?a(7(Fb߬0#c q{.j ` k0L\a9;޹k,+rީ![۴zh`wE\zȆeflOa_nyew?7GUCXQ;d'|bu wLLh>S@~n_|ȠeC 5vk3HްlF ud:Ebj1.o] O<%]\)YKoY h^[BQKQV{zW,Qu`o߁ίy~w}}|UI!d%}6&lNu`㘛*f"yVncR$B&-}E.. O\.%s7p敃rFzu rEv>Ձ8B.\1o@!+HO5'O-# cyմ2\ڟ{IsBR⾰kDh2JRfq1\@$.:q ;H qqEiޛ^  \3IxJhySau<2E% ͉ dl&BgLIii5۽ٺ& `*h$rMyܟ7 _-s~ CO2_uԅШwoa+!7*NLjtZSNO؎| ϵ4\bf,U:( !ᅨ?WL~BzR47Mh{]xo5xY@,~u[A{]b鍫*˿+ yz dpLaׅ3Ș *D?Zњ =w ooPQ`U7r/Ⱥ.pM?ۡt۰BqSH;*kY"3(PP]z#Pa(Arl9VjSoCX% >3[u<ˢTlC+=91g>^"mL/Vi]*:*;"M߱O#AO}]"!kkܠz%B|H+_>T;&ןq7-(Ph[\TX,޹@cq?cf2I!v"T?r?7 Xuvߗ,% 0u CJ@#<8 - M'%롮2|fdg_hwC5r!EẌ.bb9 ;\`]~=)s Da@T |D?P.(nl8CaǐL$T3gt*,o:W~ }g1f?Y5E  \DYC$፯prES־]Ы\P[RuY|G:ֹ WkO-/"}e+h~ћ:eh9M59 sV%}1ϰ!P(#|s`{7ˈ7ߏq*Q-ѥУ?l$t* a@'6jRp7+ ^Nk6{<YF-` hzOnɶ+~]Ղe3AI-y vdSҋM5!BI>Z+ΨlHSx qRsɫYl O0Ñ'%< 5C^ ہz`~4W;NA:q6+ze<ēsOV;OUyݿRpZ<5Eמ!@B1YȤ$5C- 7?VW)`TUl{TJ5:qߍ+ujx<Lj8ޞ;I{L5}@[q/)f J[Z[(䲰B#C ɰԌ68O[ "5AYk,A<_dJU K1W!l{4jai(`/Hk7`VC$# qf!)_?) RarGrYCC}ri۽ ZWeId>c G U'6^̡+5rKga14 T9PjcZ5~:8lIw+y9 5:Z½:fM>g rg&[$]\'{* ]?.Egf9WS ;ڝb{U}eE !zG%?A9$H{,֢\O ST p^de &{[o*mXo?n?:˵U} |`rq((#n&zB]>PvB&MSh?gw=/yzz$,n[. 6Q ޢE@gu &Kmɓ#Ѹy^kFz33m6<{3G:*ȉN5SOnKq FZ<*!c r$X+J=CgЮx\QNZBwyI#͉ARap w86ÐD>){ ;l)Pm\89oI 7vʟ8L0#>5H<{(1ShW]s/IfN{Udm=|m䰇Σ!2Be;;-FY*[$A5'/JQvPbFpWSVM0PDuä>~ i7 M am>E$%u~(LOVhF][k }*3} 7nTŧYIZFӼ׼@g߰ԹZY3#V1\iQL)`<7[|t5?,@,]=?I ;@ɬ0G-1+w!6CIiڈ4ų`$AV3vŢ_WZ׶=:4wCnps`g4~ы1{%Cd2oAgUe{ uK&X4ZZ> QAu_b:L&ٸYXXAڵ Qf0gi UZ_] r~/$CgPDRy1FBTz&_K_^0}sC[&gTk6r0l2\>:Qߋc+;pˌnd'lj)̢S5*=RR28OK[g r$ɩ͍Mӳ"}R]Y$b*c$S qV#&#X`Fb5#ڼӋ*"0kpw}hz$ 5D{,̏O#Pg @΢]#ǰNo$FfQ|uix љk^jzRQߟM+x2NAj010%!3.Fvf2,ϸxN[os VTJ k$2)B;^#d'gi'!s<eM.z֯}i~i$igٚ sw_Fs()#+2MiX1­!0wgD }DEVȁڵB Z^ю&zqO:{xY|Lfܕx;j?YVc)_j9(Mq,+7WXF' <{Ծ0rK:EerדG5rLGj:/w"v.)}g;5)Vm6{M%wWlSv8vKA@!VW92N`Hrc!*ʺ65b_g~ W![9P:ИE;6xl[Fj8@%Zӎ{28Rqn;ݵ3. $SoW؀Ǘ6NA]ЧydC;W(C3|A1Pt40Y`91CH;DocRoW_v47fv\Dm9A5m[~2GN i %P_J!Zͬ2Ƨg1[*IEgZS(ӅD6S9h:U_G:+&j$(ϐGI*-ryYKd3X)xAAPa| ; 'u["o11ɝh f1dA 8d9OuɛRi5Kx1g>K*N9 8 < A"(d/U/OQ0(sfC2a}Mpw :LRQvsW3cVVr+F,k13s"`K 12W5uF@ !֡!&t-_C5E(/jи y݋k; }z4;I=BB'1rJm]Hƨ WPl=ēf/xmxNXO'-V(p Lg"pG<(udܫc\ڋʅQU/~KGC ̳r[FJ~}.h@wvu$DԺ\PqD)?tZI\pU rͪB7qJ<4ϏaX]jEhX:ioDVT'+6;cQiizLcQm8OkE D4Lr|S/6N+G4@C `ann>u7-K=Ҿ;+G^>F΋|o`,R|4ɝtƪI*@n6 G'+#c$80Z Qa)ؿr=qD=X.^d{,ٲ ljm 6ɁHY2Xx"Wnj` lЦͦh5丫zJn) N%CaU1`ne^ݺK |JhNܳzY pO;\RdZs%ViGKLt@^@*w쀃r9q46 KE=t^%\|Vc|M͊ 7Z{=BN羱/Dqf=sLQH~X~H(]`]&$57'w߀bʚ2O<}mdXȶx _(>u>0d x0 i^9u^.!LE6N?bHX}h*Y|NH[DzA>DJp* i\]r 9@n?xYT<ߔgc\^h/*U)9Phc'{*vĄfqr3ϚQ~nL(r}wPG\zFąM8 bu7i|qqo"xP@gIwCc1c&hK|!g}RAAD|$xՄRK+:8qL +p}: .لGGV;cR;Of6ax?G}$'݉wER$Rlmˡ F LdJC9Yc4B131CVSY3|-FNv=!rhHß()Cnd=l 俑zh,IF|1ߣDZ\_+<7%-Iy}d~4gĵ@sQeT^ @|H?v_{d! 4 8.MВ`B G>ƒb|΀[\Ѯ|'<=R¾ԳĿ[}P#~6j(MN:7p2 VΤ+78u=˗sM/>6ݧsYe}' {gySzu[|@C&^Ҫaq:gjfr%_R|ݙG~CܼϏ3:QuVa7+]E{I/@utcLdbVw F9gEU G$v=k@߀ujzk<ӵmSіo?fnZrGRw*ޥZ{K|#G>we{o˷Y]|xW?le ܓJ+߸B 8AWe{+*Ed{e}90[j4-o;nl3 DL7fUED9VeD ]$#ԑt3 ꯸/o'Iq!ڴ&۩>"l K6qtRqdC10MJ/'v:5qAstu]yoH,8[xIRb3Q$3k6EH%f;cXǹi-$_'w1&*+O1 RIjE_rpa JƦ='ց5pgǧ!GnXGP5 7o%v~Lh̑0TF0<J&5u.ÊphL@~Pɢq,%uә`EEL?^# ;;+EŎ1ET8c@R+酼MdD_M*wokmZUf1y%(+^F/R"VG~=t f&p"̨I/γs'Tn TzfwUEUI8?Wccu{cGø0(U[tg*}{6qsE"'י6_vmHHC;Z?wwq3[vM}Bc J A+CƖcy"WL6SLe{H"B, eXw}ReK{p~QNqm{_ Id{a77jZ1a|6Ɇte1B0NJ~-MBe5u"Aa %x9)d +8{^cK1X_/})q;hiæVh%JlW` HL9P7qgŭV@7=P0蒶WaԀ$*#U2;ґFZa'8t"BgY}t[KY@G.{Z_:0fZ'v=mFQ Ă*1Uamc" zG܇,JЙ GyQSJuFt; Ά;fK@3p e #`<瑘>;^; P衒%ߣ/IS ^{ɸ\|C7@<y)rWCBSk4Q-x=׀p8\PÝaĤ*pКa7u^uۮ fs@'lvoUO`Ktc,OW!wgeUDzJ[aTh NEcO<9?)Okϻ3e_jS2^v愈E]É9dzcTk , LE@Xک Um['?<, '\Stw?7)k8BSA_*9t|~;;1;XX 6^Q ]H&!1} # ]rs/S]@mYrރv8 MrDƓnZW pQl1آSW4>La,/j} Os]KN]a!8mާ$fm\|>E'~,v.@"_͜ *rLA=Gn!:6h6KKvj{ >0c!Uo=:GmƢ'p*%~,83Q8~e$CB&);@m" \uz5 %\'_qflv]OG09lXW"㎲}{h!*|H'd7U&oRd`8y2uh;I^GKpF>O6ECHa6RY@nJwS(x֐&hd:W ^"7@?Z2~RuVD.}:U`J~̤5!z@NAXFT''s߆ 2ᴋ$$m08nZ׉,TX./T W5pE~M?AFC:\Lhr#<`Ȱ ! SqTdJS&ǽ45;^OWm88 R&A+3ƽRjPO BzJNISeDm,@OfWe=Aũ_f1 6 ye94%HO`"hլ_Шp#ذ^`Qhyc+N*lYxg h׳AƋgCZ"KJ!Y{cFyH@b@YG߶X^IŽW:,{{#USa{EA X1\mJ#PF!O.uL,aplVg~!y2N4M\fm'Sڱ3.tK%S,Oms]b/3Oqz!߽sR5 UY*maOȑ`v)fsg`LGwpѽ71UCa: ǛΝ;?9FIɮBX 1E1O׶b 8;%AU.}լ)]ڑbdnc;Ʃ>W5+,_}1UM-h3]k_3%D9qiKPNu|x!Q9[GGgv(JYs۬%G ~܆ܜAQAi&Pu 7t58QhcXХrywA}2?uꎹ C^4s]۟ H> Dۓ,Er Ld1t1+2Wv{u\/\'Cˎ ;3Gjx$~ʿ)nд2h=B%.MXRQՍ6v>cl 7YpFު `_ʨ+c|~ĝCgRM.21Q05A>&4,7jyBeb'b{i\h> fY]e. 1hƩb:^<ĮKQp!E,J>%-t4bԎօ3& EL%}Mc9iJnz̯ئ_.RP7råDA馭>_U)хx,u~e2_'DZ\.^'8zyL:{enh2ǥm\M ZLۜ8MUlMը=bm`k d_l+"ܰՈBj.GkJU-Ȋ!|P. 1#ÀW\m;dsj=R&% dЃN_9>A%\ ~:vh0Px}7 9 7<]U^$ttVZ5: HU_b[>%>mW%λ2_?O=]?qȧ` +mUBlDflk0(3 )Ikjps, \ϮT9K]#妞"Bi>+哸SynR=#G1CꍇyqՓ_ak ִ7+iIUwYb!m#1;w#yWUǦt$`ZQʸR ?FLSt ( v!2bJ9 3Gabv`ѧ.W-3(}^jLPʡLPlN}!hcMu~R@ ӉapzFrB.NS9U7$N4{w$&g;e8,Z{@hb?s?Ȃ]%" ΪTQ{\ ifHMOR[`,nfGT]H .!J7Y ._Ȝƅy'HF kR1NE J/K|BG6ɵIRp9GJex;bS0u!EJWZNVmt6v J Z=d||F>jc*RP/$ow3#0WIf9ZFEN?cФnjB*O O. W ?k4͙_` ۯ$DGo_Qng U>'*N 6ښ=PVZUlfWYѦ/6F8q%*ɘ[f1cA-Kw:R8Kq1U FPº ]LYN1{Պ%GtzZ>,oZRY8LF\Ía:P "ϴ5QAfw {kɅ"m )?oW;~Ë.֔Z e"@jD퟽rl× f b!pjQ^3"S<{tth d5%V~{SvLN_9C%gBY).|oqV>*ndi^hCJ WG&ֱBʋ"7 "9zD`S}}ň8α$UmA*kY` W@0p;x/m6hsZ{h~AJBE){vȎKͰSzF̖ -㽛#d 0G} i<=yuqgB:5߽#-V3³TL؆ Qy/Rlx)^TTjv]}I*[fc9iڎ H|W:p^ptg<zv22h{yL 7ϔ1(s~~#Fpm;aNKZ8})D ]0S$013\qȼB^Y̬ہ7kѪ MvQh@7vNq [*I\ktg~D)|U"s 1/o(k)/S{Ł1$1xJapo󮀓ЁԨכ%'?UaJUv˖(\!K%/gEQexOcm3>+wxMX4`9e$FU<ޜ>suyYb˅C|nAKν;ӑzU$Fmq ?>HD@ Xm/0,u~\(0+i½oA")F7))#8&_C^Ysu2 E|-Ya-8j6l4st9˘ GP{XzzP@0Q_r7A[؋)40OX:"? (&C+`(don:Q A(r; Q.ȮPm?`.{u"鮆 Y$?GU!r,!'l5/Z ^ř0I9Xq/ГLҜ?}{AfV鞋 w`$Bl7( w(ń(Dax>cqJo4H%;Ds='>FnSO |,N}k$/u';M^̘ߐ<|zU}A5 /.#PowyA-:ߓCf/)(v3wȓRCŒ5 EJjh>#EOsp6-E:12q_Q.NUZ`5,SCe/1 ERD&+Ji"u8>΋EƬw;?:SR ٸa|%piGҫ8(|R&i<4WֺR߁.Ԑrq]%!4GuTUgHa yΦ4;h_?, ܆|?X\= ;yEB#S=RD*TF^EO /!?p!GxjV׍F{ymK<ã2 [`8n<0R7 |*)L KDAk; (5f| -h 4ؘ_yO;s7 reVR}88+w*}-Ql.8b8snHC&` T !K Aq?(t w; ,Fc& GOT1cC6bIi{I3d~`֐_b*m4ciQ/Nyk&p(ɼș4cP9XcB܌Qw67mO9dIdt]h]Xݩ#Q,wmFP2RH,[{qhXJ-ndhHJYuI:-{m?[QC9ŐLPR(WPC,9,L,i9Ξ..lQ!IcK ϷF]SvTVa޳R؛%hNW0&V(n\z *]ҭm6EsbY2`d'2e"/4*Qw0~ \Etǵt|CagΗF#d8<^?pQ KB4n94y R(:oΗnR8r`*Esّ%m@(ܟp5Z? e#YYgRws;Xqsc{FYo0S Hhf(1l*R¹qAْfֈhY,Ž& LSuU%M`>gdU> 9ܑKyz"EoNm&)F}hKnŻuVhHT.`ut^4/c+(͉c@qSR |l?gT[ 4hC؍r [\]d߸eXE 2ȧW!FJ2wWVal'#Yt%v916jU_챩lk aQ?LS k< EvJ7Ed('M* +#j'@GfQ2S)@s uXgЁ9[2][{ iW^zG{9}s rXSjU7^@}-D2 c~J{Zt/(9 T痐c&}i߽,"]V'+ }+6&Ñmeõ䊈۽wxyt.8bZUP΄`>>m29mHCL6r^_U܂x"<,JK6U%/lװ7\~Cg#{_K F@B|0Uq >x&J w,P)~v9 czV6hiMӥq@2v:ir5̈́N *] JXW$]:x}j;1{He`cB^kW^ rY/v)cX}*i(%N+Gq,mn\M16x@(sBJSQ(p4Ws!DUCBf{&f2Bwwr\qW/_q Qm&]h0^@f58Qu3I}.<|٪ [|:~W땙Zmh 9)YA2u2F@!g |Zi)TUy1)DŽ9/ϥz>Q.EΫ0k뻔{nCH\,dX0)sFj9_rly/.wr%/|߰|];&λ| >?Ci6)SkբCEYy4VHesf`KקU씆4Epkȕ?S%Dt t-鳃Bfj98oV-VS'2ܿ'_"n c{$c3Qzx]MRsw k"ݗ $i m}O!vZR.ݏEHC{LCRP<H%^<S;K{ědCfUkeQhسד)TtH>vx@[wouM?5>#snAN@(.bKSojmF7 vXx4cF A9uLXHUQrJ#l5\#v8ʩh [%pNQI\{@^e<#,1|u`niN9|}C0ZAtfc{gŨwF#YrӇOc$_YVeժ=7 ]vh=;Z"Gr/@;AG Xjhmi%dr+}+iWj rifi| Ak5".<*cDs!>":NjH֩&BYWw"J1όH%1(Cr94c$; +H;%EQkv?"͍|-[hw@2 ƩwSyq,{5[/0h2b^I 3gШx yQg w dx 7Fo^SȄ|P(dl?2ʑg[UZi?']\9. 5 i fOf9Mb4CTq7&7-zQXK/{l^ڝ't0 9r&E\Q[5Wҧ;|[YvUAAmYw'l5ڸQ1tss- 99Z[2<6h! }9f3"k|:~-@,+bq_}X݈\ *I>Oݛΰ^kV=}O' H9vofge;)uLYqړd>׸P,kg{JnQO}xYf]Nwy2δq^q̏o![ʞ $ Ngj)Tx/jwx cjQw 2"yJ @mf(B+x)Xߡؠ- Q~ xoswO}/UEh eI0c+Rq^2+-I(LhrFM{oϑ{UME58& MsBd5\KoC," Rxյ iv#U~` 6E5؝ۻc-;i1(>8P`ՈƂq.K㯟34Px3= 13}AY^Ҩ͙p'Q zbڡnLUe&U,wFO5ea+@'u8dcmHuqwi9CY0gȳAؔXeYx, _b614I^b()6MOvTYu0>nr)⟫0[;:"mh\Ei2ӑ,ڕ>xlUQ0,j0lY2I }!2^z e|؛K֮yr@7io*]U]*$st..78NEuݿ|Жڋ5?mL-g'KLVH1:^e1ZSVo`wH߬UhXlJs!Xo%V.Uenoϭ\'HlGD8I#(1x^Υ\gi*)섌ʐ0C0㱜y|ghw_<-WF!!G `B7c+&?VaHO, V3C'X,zI4t`. cĢ/Х6 ! .-dT&D},!!y` `1u](Ɠ5*nTo^S d6}*}^T{\9<jMճza͎C[ I3' mO`i ܊_͕yHU?`1~_&jcx7Fc.)lo/ H'LrRfz F4F{j|I)axg`_gOn.fOjkd[ɽ^/ڱ>^K MmH| TY7{>:ߏaq('ֹJD4lQx~X[0ؽ I"ݝaDyU4f_Mb)W0ά*ӾD'CCtKZӊDWKVkFq 3-c7_D+Wɤ+X Va%^fBOϞ`{rForS./2~iVC`p})~TKIH<>2+7ݾKAĘG Vky(ċi\տ``\g9KGwEv8*Wʴ?zH%Fd*~)0REr=j|], 0 >_N|  ~Mw Jmakt888zjVv"ICv׉'*a|ʾZ:!]5mG k"ۑjh*>VT[!C2AZ@UZ i:(a-SÕ#*'EEomJߓ2-IV!X+a1`hW t23f,3'c*Ԟ܎k@z7sz̒UpdcsTr4b7V ëE*Gr^(_`i^qZ"?X܄y͍@`աCsD`bK3ܮit:lV<3zB|Bu=1`\ ej2@ _ongĀWQ~OrQ@(;mLH+qڸi1*51O lw8zŅ)e {WYTR.6zuwdoPD?k|ؓ` ZP]% ,1d|L zu>z"> y LZȴHzK>$чj1C)KEwHZ ^a(§_C۴:nNU oS:_sBwH̭2^KL9ve , Lk> .|* Ӿ  *D6cgR?JzEBRA7JVԜ]~=z6ͫƳi-WrfEBԄ0—UY E843U@†f1v O< jb\Wg% W`iУTcs–Q^cWY 7oqC?|mk eQ4 QcRu؟qX,)Rap=)81 wh:4~&ܖ&JVòN?2 3 ?Ix4=@RR.Vmif]C ʢEJ[_h+=R}LǴ §t`S#"/!%§O0GD遲Ży kL}+o:&&iz;t%]#v, N_pv <"<>71$ײezQaڑ2l?lѕm{Co[B)8kv"ǨR7tmNagKPrMW"rI%϶\$\GʅD(jjGߞF:DN~R<-Gh@07Jf6ִxɏN,Z7-i?v)/|?oj.)|UA|̡4}pjO_l~M<6/ á&-~>0 YZsurveillance/R/0000755000176200001440000000000014615164167013162 5ustar liggesuserssurveillance/R/stK.R0000644000176200001440000001515114426171115014040 0ustar liggesusers################################################################################ ### Space-time K-function analysis of "epidataCS" objects ### along the lines of Diggle et al (1995): ### "Second-order analysis of space-time clustering" (Stat Methods Med Res) ### ### Copyright (C) 2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## call K-function methods in package "splancs" stKcall <- function (which = c("stkhat", "stsecal", "stmctest"), object, eps.s, eps.t, ...) { stopifnot(inherits(object, "epidataCS")) ## get the function which <- match.arg(which) FUN <- get(which, mode = "function", envir = getNamespace("splancs")) ## default arguments commonArgs <- list( pts = coordinates(object$events), times = object$events$time, poly = NULL, tlimits = summary(object)$timeRange, s = eps.s, tm = eps.t ) args <- modifyList(commonArgs, list(...)) if (is.null(args$poly)) { # use coordinates of first polygon if (length(object$W) > 1L || length(object$W@polygons[[1]]@Polygons) > 1L) stop("package \"splancs\" does not support multi-'poly'gons") args$poly <- coordinates(object$W@polygons[[1L]]@Polygons[[1L]]) } if (which == "stmctest" && is.null(args[["nsim"]])) { args$nsim <- 199L } ## unfortunately, argument names are not consistent across functions if (which == "stsecal") names(args)[names(args) == "tlimits"] <- "tlim" if (which == "stmctest") names(args)[names(args) == "tm"] <- "tt" ## call the selected splancs function do.call(FUN, args) } ## Monte-Carlo test for space-time interaction stKtest <- function (object, eps.s = NULL, eps.t = NULL, B = 199, cores = 1, seed = NULL, poly = object$W) { stopifnot(inherits(object, "epidataCS"), isScalar(cores), cores > 0, isScalar(B), B > 0) cores <- as.integer(cores) B <- as.integer(B) ## naive default grids if (is.null(eps.s)) eps.s <- seq(0, min(object$events$eps.s, apply(bbox(object$W), 1, diff)/2), length.out = 10) if (is.null(eps.t)) eps.t <- seq(0, min(object$events$eps.t, tail(object$stgrid$stop,1L)/2), length.out = 10) ## extract coordinates of the polygon polycoordslist <- xylist(poly) if (length(polycoordslist) > 1L) { stop("package \"splancs\" does not support multi-'poly'gons") } Wcoords <- as.matrix(as.data.frame(polycoordslist[[1L]])) ## calculate K-function stK <- stKcall("stkhat", object = object, eps.s = eps.s, eps.t = eps.t, poly = Wcoords) ## calculate standard error seD <- stKcall("stsecal", object = object, eps.s = eps.s, eps.t = eps.t, poly = Wcoords) ## perform Monte Carlo permutation test (parallelized) permt <- plapply( X = diff(round(seq(from = 0, to = B, length.out = cores + 1L))), FUN = function (nsim) { stKcall("stmctest", object = object, eps.s = eps.s, eps.t = eps.t, poly = Wcoords, nsim = nsim, quiet = TRUE)[["t"]] }, .parallel = cores, .seed = seed, .verbose = FALSE ) mctest <- list( "t0" = sum(stK$kst - outer(stK$ks, stK$kt)), "t" = unlist(permt, recursive = FALSE, use.names = FALSE) ) PVAL <- mean(c(mctest[["t0"]], mctest[["t"]]) >= mctest[["t0"]]) ## return test results structure( list(method = "Diggle et al (1995) K-function test for space-time clustering", data.name = deparse(substitute(object)), statistic = setNames(mctest$t0, "U"), # sum of residuals parameter = setNames(B, "B"), p.value = PVAL, pts = coordinates(object$events), stK = stK, seD = seD, mctest = mctest), class = c("stKtest", "htest") ) } ## diagnostic plots related to space-time K-function analysis ## inspired by splancs::stdiagn authored by Barry Rowlingson and Peter Diggle plot.stKtest <- function (x, which = c("D", "R", "MC"), args.D = list(), args.D0 = args.D, args.R = list(), args.MC = list(), mfrow = sort(n2mfrow(length(which))), ...) { stkh <- x$stK stse <- x$seD stmc <- x$mctest if (identical(which, "stdiagn")) { splancs::stdiagn(pts = x$pts, stkh = stkh, stse = stse, stmc = stmc) return(invisible()) } which <- match.arg(which, several.ok = TRUE) stopifnot(is.list(args.D), is.list(args.D0), is.list(args.R), is.list(args.MC)) ## K_0(s,t) = K(s) * K(t) K0 <- outer(stkh$ks, stkh$kt) ## D(s,t) = K(s,t) - K_0(s,t) st.D <- stkh$kst - K0 if (!is.null(mfrow)) { omfrow <- par(mfrow = mfrow) on.exit(par(omfrow)) } ## D plots Dzero <- which[which %in% c("D", "D0")] == "D0" whichDzero <- match(Dzero, c(FALSE, TRUE)) omar <- par(mar = if (is.null(args.D[["mar"]])) c(2,2,par("mar")[3L],1) else args.D[["mar"]]) mapply( FUN = function (z, Dzero, args) { defaultArgs <- list( x = stkh$s, y = stkh$t, z = z, main = if (Dzero) "Excess risk" else "D plot", xlab = "Distance", ylab = "Time lag", zlab = "", ticktype = "detailed", shade = 0.5, col = "lavender", theta = -30, phi = 15, expand = 0.5 ) do.call("persp", modifyList(defaultArgs, args)) }, z = list(st.D, st.D/K0)[whichDzero], Dzero = Dzero, args = list(args.D, args.D0)[whichDzero], SIMPLIFY = FALSE, USE.NAMES = FALSE ) par(omar) ## Residual plot if ("R" %in% which) { st.R <- st.D/stse defaultArgs.R <- list( x = K0, y = st.R, panel.first = quote(abline(h = c(-2,0,2), lty = c(2,1,2))), xlab = "K(s)K(t)", ylab = "R", main = "Standardized residuals", ylim = range(0, st.R, finite = TRUE) ) do.call("plot.default", modifyList(defaultArgs.R, args.R)) } ## MC permutation test plot if ("MC" %in% which) { defaultArgs.MC <- list( permstats = stmc$t, xmarks = setNames(stmc$t0, "observed"), main = "MC permutation test" ) do.call("permtestplot", modifyList(defaultArgs.MC, args.MC)) } invisible() } surveillance/R/AllClass.R0000644000176200001440000001124613554101316014773 0ustar liggesusers# ------------- class sts ---------------------------------------- .sts <- setClass( "sts", slots = c( epoch = "numeric", # this slot was called "week" in surveillance < 1.3 freq = "numeric", start = "numeric", observed = "matrix", state = "matrix", alarm = "matrix", upperbound = "matrix", neighbourhood = "matrix", populationFrac = "matrix", map = "SpatialPolygons", control = "list", ## New slots added in version 1.1-2 to handle proportion time series: epochAsDate = "logical", multinomialTS = "logical" ), prototype = list( start = c(2000, 1), freq = 52, # historical defaults epochAsDate = FALSE, multinomialTS = FALSE ), validity = function (object) { dimObserved <- dim(object@observed) namesObserved <- colnames(object@observed) errors <- c( if (!isScalar(object@freq) || object@freq <= 0) "'freq' must be a single positive number", if (length(object@start) != 2) "'start' must be of length two: (year, week/month/idx)", if (!is.numeric(object@observed)) "'observed' must be a numeric matrix", ## check consistency of slot dimensions wrt dim(observed): if (length(object@epoch) != dimObserved[1L]) "'epoch' must be of length 'nrow(observed)'", if (!identical(dim(object@state), dimObserved)) "'state' must have the same dimensions as 'observed'", if (!identical(dim(object@alarm), dimObserved)) "'alarm' must have the same dimensions as 'observed'", if (!identical(dim(object@upperbound), dimObserved)) "'upperbound' must have the same dimensions as 'observed'", if (!identical(dim(object@neighbourhood), dimObserved[c(2L,2L)])) "'neighbourhood' must be a square matrix of size 'ncol(observed)'", if (!identical(dim(object@populationFrac), dimObserved)) "'populationFrac' must have the same dimensions as 'observed'", ## disallow NULL colnames in *multivariate* "sts" objects if (dimObserved[2L] > 1 && is.null(namesObserved)) "units must be named (set 'colnames(observed)')", ## FIXME: should we generally disallow NULL colnames? ## NOTE: aggregate(by="unit") previously (<= 1.15.0) had no colnames ## if a map is provided, it must cover all colnames(observed): if (length(object@map) > 0 && # i.e., not the empty prototype !all(namesObserved %in% row.names(object@map))) "'map' is incomplete; ensure that all(colnames(observed) %in% row.names(map))", ## check booleans if (length(object@epochAsDate) != 1 || is.na(object@epochAsDate)) "'epochAsDate' must be either TRUE or FALSE", ## FIXME: we should enforce epoch[1L] to correspond to start ## if (!object@epochAsDate && object@epoch[1L] != 1) ## "'epoch' must be an integer sequence starting at 1", if (length(object@multinomialTS) != 1 || is.na(object@multinomialTS)) "'multinomialTS' must be either TRUE or FALSE" ) ## detect mismatch in column names between different slots if (dimObserved[2L] > 1 && !is.null(namesObserved)) { slots_dn <- c("state", "alarm", "upperbound", "populationFrac", "neighbourhood") errors_dn <- lapply(slots_dn, function (name) { cn <- colnames(slot(object, name)) if (!is.null(cn) && !identical(cn, namesObserved)) paste0("'colnames(", name, ")' differ from 'colnames(observed)'") }) errors <- c(errors, unlist(errors_dn)) } if (length(errors) > 0) errors else TRUE } ) ###################################################################### # Definition of the stsBP class for backprojections. ###################################################################### setClass("stsBP", slots = list( ci = "array", lambda = "array" ), contains = "sts") ###################################################################### # Definition of the stsNC class for nowcasts. ###################################################################### setClass("stsNC", slots = list( reportingTriangle = "matrix", predPMF = "list", pi = "array", truth = "sts", delayCDF = "list", SR = "array" ), contains = "sts") surveillance/R/bodaDelay.R0000644000176200001440000006313414304100624015157 0ustar liggesusers# ____________________________ # |\_________________________/|\ # || || \ # || bodaDelay || \ # || || | # || || | # || || | # || || | # || || | # || || / # ||_________________________|| / # |/_________________________\|/ # __\_________________/__/|_ # |_______________________|/ ) # ________________________ (__ # /oooo oooo oooo oooo /| _ )_ # /ooooooooooooooooooooooo/ / (_)_(_) # /ooooooooooooooooooooooo/ / (o o) #/C=_____________________/_/ ==\o/== # Author: M.Salmon ################################################################################ # CONTENTS ################################################################################ # # MAIN FUNCTION # Function that manages input and output. # # FIT GLM FUNCTION # Function that fits a GLM. # # THRESHOLD FUNCTION # Function that calculates the threshold. # # DATA GLM FUNCTION # Function that prepares data for the GLM. # # FORMULA FUNCTION # Function that writes the formula for the GLM. ################################################################################ # END OF CONTENTS ################################################################################ ################################################################################ # MAIN FUNCTION ################################################################################ bodaDelay <- function(sts, control = list(range = NULL, b = 5, w = 3, mc.munu=100, mc.y=10, pastAberrations = TRUE, verbose = FALSE, alpha = 0.05, trend = TRUE, limit54=c(5,4), inferenceMethod=c("asym","INLA"), quantileMethod=c("MC","MM"), noPeriods = 1, pastWeeksNotIncluded = NULL, delay = FALSE)) { ###################################################################### # Use special Date class mechanism to find reference months/weeks/days ###################################################################### if (is.null( sts@epochAsDate)) { epochAsDate <- FALSE } else { epochAsDate <- sts@epochAsDate } ###################################################################### # Fetch observed and population ###################################################################### # Fetch observed observed <- observed(sts) freq <- sts@freq if (epochAsDate) { epochStr <- switch( as.character(freq), "12" = "month","52" = "week", "365" = "day") } else { epochStr <- "none" } # Fetch population (if it exists) if (!is.null(population(sts))) { population <- population(sts) } else { population <- rep(1,length(observed)) } ###################################################################### # Fix missing control options ###################################################################### if (is.null(control[["b",exact=TRUE]])) { control$b = 5 } if (is.null(control[["w", exact = TRUE]])) { control$w = 3 } if (is.null(control[["range", exact=TRUE]])) { control$range <- (freq*(control$b)+control$w +1):dim(observed)[1] } if (is.null(control[["pastAberrations",exact=TRUE]])) {control$pastAberrations=TRUE} if (is.null(control[["verbose",exact=TRUE]])) {control$verbose=FALSE} if (is.null(control[["alpha",exact=TRUE]])) {control$alpha=0.05} if (is.null(control[["trend",exact=TRUE]])) {control$trend=TRUE} # No alarm is sounded # if fewer than cases = 5 reports were received in the past period = 4 # weeks. limit54=c(cases,period) is a vector allowing the user to change # these numbers if (is.null(control[["limit54",exact=TRUE]])) {control$limit54=c(5,4)} if (is.null(control[["noPeriods",exact=TRUE]])){control$noPeriods=1} # Use factors in the model? Depends on noPeriods, no input from the user. if (control$noPeriods!=1) { control$factorsBool=TRUE } else { control$factorsBool=FALSE } # How many past weeks not to take into account? if (is.null(control[["pastWeeksNotIncluded",exact=TRUE]])){ control$pastWeeksNotIncluded=control$w } # Correct for delays? if (is.null(control[["delay",exact=TRUE]])) { control$delay = FALSE } # Reporting triangle here? if (control$delay) { if (is.null( sts@control$reportingTriangle$n)) {stop("You have to provide a reporting triangle in control of the sts-object")} if (!(length(apply(sts@control$reportingTriangle$n,1,sum,na.rm=TRUE))==length(sts@observed))) {stop("The reporting triangle number of lines is not the length of the observed slot.")} if (!(sum(apply(sts@control$reportingTriangle$n,1,sum,na.rm=TRUE)==sts@observed)==length(sts@observed))) {stop("The reporting triangle is wrong: not all cases are in the reporting triangle.")} } # setting for monte carlo integration if(is.null(control[["mc.munu",exact=TRUE]])){ control$mc.munu <- 100 } if(is.null(control[["mc.y",exact=TRUE]])){ control$mc.y <- 10 } ###################################################################### # Check options ###################################################################### if (!((control$limit54[1] >= 0) && (control$limit54[2] > 0))) { stop("The limit54 arguments are out of bounds: cases >= 0 and period > 0.") } # inference method if(is.null(control[["inferenceMethod",exact=TRUE]])){ control$inferenceMethod <- "asym" } else { control$inferenceMethod <- match.arg(control$inferenceMethod, c("asym","INLA")) } if(is.null(control[["quantileMethod",exact=TRUE]])){ control$quantileMethod <- "MC" } else { control$quantileMethod <- match.arg(control$quantileMethod, c("MC","MM")) } #Check if the INLA package is available. if (control$inferenceMethod=="INLA"){ if (!requireNamespace("INLA", quietly = TRUE)) { stop("The bodaDelay function requires the INLA package to be installed.\n", " The package is not available on CRAN, but can be easily obtained\n", " from .\n", " Alternatively, set inferenceMethod to \"asym\".") } } # Define objects n <- control$b*(2*control$w+1) # loop over columns of sts #Vector of dates if (epochAsDate){ vectorOfDates <- as.Date(sts@epoch, origin="1970-01-01") } else { vectorOfDates <- seq_len(length(observed)) } # Parameters b <- control$b w <- control$w noPeriods <- control$noPeriods verbose <- control$verbose reportingTriangle <- sts@control$reportingTriangle timeTrend <- control$trend alpha <- control$alpha factorsBool <- control$factorsBool pastAberrations <- control$pastAberrations glmWarnings <- control$glmWarnings delay <- control$delay k <- control$k verbose <- control$verbose pastWeeksNotIncluded <- control$pastWeeksNotIncluded mc.munu <- control$mc.munu mc.y <- control$mc.y # Loop over control$range for (k in control$range) { ###################################################################### # Prepare data for the glm ###################################################################### dayToConsider <- vectorOfDates[k] diffDates <- diff(vectorOfDates) delay <- control$delay dataGLM <- bodaDelay.data.glm(dayToConsider=dayToConsider, b=b, freq=freq, epochAsDate=epochAsDate, epochStr=epochStr, vectorOfDates=vectorOfDates,w=w, noPeriods=noPeriods, observed=observed,population=population, verbose=verbose, pastWeeksNotIncluded=pastWeeksNotIncluded, reportingTriangle=reportingTriangle, delay=delay) ###################################################################### # Fit the model ###################################################################### argumentsGLM <- list(dataGLM=dataGLM,reportingTriangle=reportingTriangle, timeTrend=timeTrend,alpha=alpha, factorsBool=factorsBool,pastAberrations=pastAberrations, glmWarnings=glmWarnings, verbose=verbose,delay=delay, inferenceMethod=control$inferenceMethod) model <- do.call(bodaDelay.fitGLM, args=argumentsGLM) if(is.null(model)){ sts@upperbound[k] <- NA sts@alarm[k] <- NA } else{ ###################################################################### # Calculate the threshold ###################################################################### quantileMethod <- control$quantileMethod argumentsThreshold <- list(model,alpha=alpha,dataGLM=dataGLM,reportingTriangle, delay=delay,k=k,control=control,mc.munu=mc.munu,mc.y=mc.y, inferenceMethod=control$inferenceMethod, quantileMethod=quantileMethod) threshold <- do.call(bodaDelay.threshold,argumentsThreshold) ###################################################################### # Output results if enough cases ###################################################################### sts@upperbound[k] <- threshold enoughCases <- (sum(observed[(k-control$limit54[2]+1):k]) >=control$limit54[1]) sts@alarm[k] <- FALSE if (is.na(threshold)){sts@alarm[k] <- NA} else { if (sts@observed[k]>sts@upperbound[k]) {sts@alarm[k] <- TRUE} } if(!enoughCases){ sts@upperbound[k] <- NA sts@alarm[k] <- NA } } } #done looping over all time points return(sts[control$range,]) } ################################################################################ # END OF MAIN FUNCTION ################################################################################ ################################################################################ # FIT GLM FUNCTION ################################################################################ bodaDelay.fitGLM <- function(dataGLM,reportingTriangle,alpha, timeTrend,factorsBool,delay,pastAberrations, glmWarnings,verbose,inferenceMethod,...) { # Model formula depends on whether to include a time trend or not. theModel <- formulaGLMDelay(timeBool=timeTrend,factorsBool,delay,outbreak=FALSE) if(inferenceMethod=="INLA"){ E <- max(0,mean(dataGLM$response, na.rm=TRUE)) link=1 model <- INLA::inla(as.formula(theModel),data=dataGLM, family='nbinomial',E=E, control.predictor=list(compute=TRUE,link=link), control.compute=list(cpo=TRUE,config=TRUE), control.inla = list(int.strategy = "grid",dz=1,diff.logdens = 10), control.family = list(hyper = list(theta = list(prior = "normal", param = c(0, 0.001))))) if (pastAberrations){ # if we have failures => recompute those manually #if (sum(model$cpo$failure,na.rm=TRUE)!=0){ # model <- inla.cpo(model) #} # Calculate the mid p-value vpit <- model$cpo$pit vcpo <- model$cpo$cpo midpvalue <- vpit - 0.5*vcpo # Detect the point with a high mid p-value # outbreakOrNot <- midpvalue #outbreakOrNot[midpvalue <= (1-alpha)] <- 0 outbreakOrNot <- ifelse(midpvalue > (1-alpha), 1, 0) outbreakOrNot[is.na(outbreakOrNot)] <- 0# FALSE outbreakOrNot[is.na(dataGLM$response)] <- 0#FALSE # Only recompute the model if it will bring something! if (sum(outbreakOrNot)>0){ dataGLM <- cbind(dataGLM,outbreakOrNot) theModel <- formulaGLMDelay(timeBool=timeTrend,factorsBool,delay,outbreak=TRUE) model <- INLA::inla(as.formula(theModel),data=dataGLM, family='nbinomial',E=E, control.predictor=list(compute=TRUE,link=link), control.compute=list(cpo=FALSE,config=TRUE), control.inla = list(int.strategy = "grid",dz=1,diff.logdens = 10), control.family = list(hyper = list(theta = list(prior = "normal", param = c(0, 0.001))))) # if we have failures => recompute those manually # if (sum(model$cpo$failure,na.rm=TRUE)!=0){model <- inla.cpo(model)} vpit <- model$cpo$pit vcpo <- model$cpo$cpo midpvalue <- vpit - 0.5*vcpo } } } if (inferenceMethod=="asym"){ model <- MASS::glm.nb(as.formula(theModel),data=dataGLM) if(!model$converged){ return(NULL) } } return(model) } ################################################################################ # END OF FIT GLM FUNCTION ################################################################################ ################################################################################ # THRESHOLD FUNCTION ################################################################################ bodaDelay.threshold <- function(model, mc.munu,mc.y,alpha, delay,k,control,dataGLM,reportingTriangle, inferenceMethod,quantileMethod...) { quantileMethod <- control$quantileMethod if (inferenceMethod=="INLA"){ E <- max(0,mean(dataGLM$response, na.rm=TRUE)) # Sample from the posterior jointSample <- INLA::inla.posterior.sample(mc.munu,model, intern = TRUE) # take variation in size hyperprior into account by also sampling from it theta <- t(sapply(jointSample, function(x) x$hyperpar)) if (delay){ mu_Tt <- numeric(mc.munu) N_Tt <- numeric(mc.munu*mc.y) # Maximal delay + 1 Dmax0 <- ncol(as.matrix(reportingTriangle$n)) # The sum has to be up to min(D,T-t). This is how we find the right indices. loopLimit <- min(Dmax0,which(is.na(as.matrix(reportingTriangle$n)[k,]))-1,na.rm=TRUE) # Find the mu_td and sum for (d in 1:loopLimit) { if(sum(dataGLM$response[dataGLM$delay==d],na.rm=TRUE)!=0){ mu_Tt <- mu_Tt + exp(t(sapply(jointSample, function(x) x$latent[[nrow(dataGLM)-Dmax0+d]]))) } } # with no delay this is similar to boda. } else { mu_Tt <- exp(t(sapply(jointSample, function(x) x$latent[[nrow(dataGLM)]]))) } } if (inferenceMethod=="asym"){ E <- 1 # Sample from the posterior set.seed(1) # take variation in size hyperprior into account by also sampling from it theta <- rnorm(n=mc.munu,mean=summary(model)$theta,sd=summary(model)$SE.theta) if (delay){ # Maximal delay + 1 Dmax0 <- ncol(as.matrix(reportingTriangle$n)) mu_Tt <- numeric(mc.munu) newData <- tail(dataGLM,n=Dmax0) P=predict(model,type="link",se.fit=TRUE, newdata=newData) # The sum has to be up to min(D,T-t). This is how we find the right indices. loopLimit <- min(Dmax0,which(is.na(as.matrix(reportingTriangle$n)[k,]))-1,na.rm=TRUE) # Find the mu_td and sum for (d in 1:loopLimit) { if(sum(dataGLM$response[dataGLM$delay==d],na.rm=TRUE)!=0){ mu_Tt <- mu_Tt + exp(rnorm(n=mc.munu,mean=P$fit[d],sd=P$se.fit[d])) } } # with no delay this is similar to boda. } else { newData <- tail(dataGLM,n=1) P=try(predict(model,type="link",se.fit=TRUE, newdata=newData),silent=TRUE) if (inherits(P, "try-error")){P<- NA return(NA)} set.seed(1) mu_Tt <- exp(rnorm(n=mc.munu,mean=P$fit,sd=P$se.fit)) } } # can only use positive theta (mu_Tt is positive anyway) mu_Tt <- mu_Tt[theta>0] theta <- theta[theta>0] if(quantileMethod=="MC"){ N_Tt <- rnbinom(n=mc.y*mc.munu,size=theta,mu=E*mu_Tt) qi <- quantile(N_Tt, probs=(1-alpha), type=3, na.rm=TRUE) } if(quantileMethod=="MM"){ minBracket <- qnbinom(p=(1-alpha), mu=E*min(mu_Tt), size=max(theta)) maxBracket <- qnbinom(p=(1-alpha), mu=E*max(mu_Tt), size=min(theta)) qi <- qmix(p=(1-alpha), mu=E*mu_Tt, size=theta, bracket=c(minBracket, maxBracket)) } return(as.numeric(qi)) } ################################################################################ # END OF THRESHOLD GLM FUNCTION ################################################################################ ################################################################################ # DATA GLM FUNCTION ################################################################################ bodaDelay.data.glm <- function(dayToConsider, b, freq, epochAsDate,epochStr, vectorOfDates,w,noPeriods, observed,population, verbose,pastWeeksNotIncluded,reportingTriangle,delay){ # Identify reference time points # Same date but with one year, two year, etc, lag # b+1 because we need to have the current week in the vector referenceTimePoints <- algo.farrington.referencetimepoints(dayToConsider,b=b, freq=freq, epochAsDate=epochAsDate, epochStr=epochStr ) if (!all(referenceTimePoints %in% vectorOfDates)) { ## previously only checked min(referenceTimePoints) warning("Some reference time points did not exist; ", "decrease 'b' or postpone 'range'.") } # Create the blocks for the noPeriods between windows (including windows) # If noPeriods=1 this is a way of identifying windows, actually. blocks <- blocks(referenceTimePoints,vectorOfDates,epochStr,dayToConsider, b,w,noPeriods,epochAsDate) # Here add option for not taking the X past weeks into account # to avoid adaptation of the model to emerging outbreaks blocksID <- blocks # Extract values for the timepoints of interest only blockIndexes <- which(is.na(blocksID)==FALSE) # Time # if epochAsDate make sure wtime has a 1 increment if (epochAsDate){ wtime <- (as.numeric(vectorOfDates[blockIndexes])- as.numeric(vectorOfDates[blockIndexes][1]))/as.numeric(diff(vectorOfDates))[1] } else { wtime <- as.numeric(vectorOfDates[blockIndexes]) } # Factors seasgroups <- as.factor(blocks[blockIndexes]) # Observed response <- as.numeric(observed[blockIndexes]) response[length(response)] <- NA # Population pop <- population[blockIndexes] if (verbose) { print(response)} # If the delays are not to be taken into account it is like farringtonFlexible if (!delay) { dataGLM <- data.frame(response=response,wtime=wtime,population=pop, seasgroups=seasgroups,vectorOfDates=vectorOfDates[blockIndexes]) dataGLM$response[(nrow(dataGLM)-pastWeeksNotIncluded):nrow(dataGLM)] <- NA } # If the delays are to be taken into account we need a bigger dataframe else { # Delays delays <- as.factor(0:(dim(reportingTriangle$n)[2]-1)) # Take the subset of the reporting triangle corresponding to the timepoints used for fitting the model reportingTriangleGLM <- reportingTriangle$n[rownames(reportingTriangle$n) %in% as.character(vectorOfDates[blockIndexes]),] # All vectors of data will be this long: each entry will correspond to one t and one d lengthGLM <- dim(reportingTriangleGLM)[2]*dim(reportingTriangleGLM)[1] # Create the vectors for storing data responseGLM <- numeric(lengthGLM) wtimeGLM <- numeric(lengthGLM) seasgroupsGLM <- numeric(lengthGLM) popGLM <- numeric(lengthGLM) vectorOfDatesGLM <- numeric(lengthGLM) delaysGLM <- numeric(lengthGLM) # Fill them D by D D <- dim(reportingTriangleGLM)[2] for (i in (1:dim(reportingTriangleGLM)[1])){ vectorOfDatesGLM[((i-1)*D+1):(i*D)] <- rep(vectorOfDates[blockIndexes][i],D) wtimeGLM[((i-1)*D+1):(i*D)] <- rep(wtime[i],D) popGLM[((i-1)*D+1):(i*D)] <- rep(pop[i],D) seasgroupsGLM[((i-1)*D+1):(i*D)] <- rep(seasgroups[i],D) responseGLM[((i-1)*D+1):(i*D)] <- reportingTriangleGLM[i,] delaysGLM[((i-1)*D+1):(i*D)] <- 0:(D-1) } responseGLM[((i-1)*D+1):(i*D)] <- rep (NA, D) responseGLM[(length(responseGLM)-pastWeeksNotIncluded*D):length(responseGLM)] <- NA dataGLM <- data.frame(response=responseGLM,wtime=wtimeGLM,population=popGLM, seasgroups=as.factor(seasgroupsGLM),vectorOfDates=as.Date(vectorOfDatesGLM,origin="1970-01-01"),delay=delaysGLM) } return(as.data.frame(dataGLM)) } ################################################################################ # END OF DATA GLM FUNCTION ################################################################################ ################################################################################ # FORMULA FUNCTION ################################################################################ # Function for writing the good formula depending on timeTrend, # and factorsBool formulaGLMDelay <- function(timeBool=TRUE,factorsBool=FALSE,delay=FALSE,outbreak=FALSE){ # Description # Args: # populationOffset: --- # Returns: # Vector of X # Smallest formula formulaString <- "response ~ 1" # With time trend? if (timeBool){ formulaString <- paste(formulaString,"+wtime",sep ="")} # With factors? if(factorsBool){ formulaString <- paste(formulaString,"+as.factor(seasgroups)",sep ="")} # # With delays? if(delay){ formulaString <- paste(formulaString,"+as.factor(delay)",sep ="")} if(outbreak){ formulaString <- paste(formulaString,"+f(outbreakOrNot,model='linear', prec.linear = 1)",sep ="")} # Return formula as a string return(formulaString) } ################################################################################ # END OF FORMULA FUNCTION ################################################################################ ###################################################################### # CDF of the negbin mixture with different means and sizes ###################################################################### pmix <- function(y, mu, size) { PN <- pnbinom(y, mu=mu, size=size) lala <- 1/sum(!is.na(PN))*sum(PN, na.rm=TRUE) return(lala) } ###################################################################### # END OF CDF of the negbin mixture with different means and sizes ###################################################################### ###################################################################### # Find the root(s) of a 1D function using the bisection method # # Params: # f - the function to minimize or the first derivate of the function to optim # reltol - relative tolerance epsilon ###################################################################### bisection <- function(f, bracket) { ##Boolean for convergence convergence <- FALSE ##Loop until converged while (!convergence) { #Half the interval (problem with ints: what uneven number?) x <- ceiling(mean(bracket)) ##Direct hit? -> stop if (isTRUE(all.equal(f(x),0))) break ##Choose the interval, containing the root bracket <- if (f(bracket[1])*f(x) <= 0) c(bracket[1],x) else c(x,bracket[2]) ##Have we obtained convergence? convergence <- (bracket[1]+1) == bracket[2] } #Return the value of x^{n+1} return(ceiling(mean(bracket))) } ###################################################################### # END OF BISECTION FUNCTION ###################################################################### ###################################################################### ##Find the p-quantile of the mixture distribution using bisectioning ## ## Parameters: ## p - the q_p quantile is found ## mu - mean vector ## size - size param ## bracket - vector length two, s.t. qmix(bracket[1] < 1-alpha and ## qmix(bracket[2]) > 1-alpha. Exception: if bracket[1]=0 ## then qmix(bracket[1] > 1-alpha is ok. ###################################################################### qmix <- function(p, mu, size, bracket=c(0,mu*100)) { target <- function(y) { pmix(y=y,mu=mu,size=size) - p } if (target(bracket[1]) * target(bracket[2]) > 0) { if ((bracket[1] == 0) & (target(bracket[1]) > 0)) return(0) stop("Not a good bracket.") } bisection(target, bracket=bracket) } surveillance/R/algo_farrington.R0000644000176200001440000005046214615162374016465 0ustar liggesusers### R code from vignette source 'Rnw/algo_farrington.Rnw' ### Encoding: ISO8859-1 ################################################### ### code chunk number 1: algo_farrington.Rnw:25-35 ################################################### anscombe.residuals <- function(m,phi) { y <- m$y mu <- fitted.values(m) #Compute raw Anscombe residuals a <- 3/2*(y^(2/3) * mu^(-1/6) - mu^(1/2)) #Compute standardized residuals a <- a/sqrt(phi * (1-hatvalues(m))) return(a) } ################################################################################ # WEIGHTS FUNCTION ################################################################################ algo.farrington.assign.weights <- function(s,weightsThreshold=1) { #s_i^(-2) for s_iweightsThreshold) )) omega <- numeric(length(s)) omega[s>weightsThreshold] <- gamma*(s[s>weightsThreshold]^(-2)) omega[s<=weightsThreshold] <- gamma return(omega) } ################################################### ### code chunk number 3: algo_farrington.Rnw:136-305 ################################################### algo.farrington.fitGLM <- function(response,wtime,timeTrend=TRUE,reweight=TRUE,...) { #Model formula depends on whether to include a time trend or not. theModel <- as.formula(ifelse(timeTrend, "response~1+wtime","response~1")) #Fit it -- this is slow. An improvement would be to use glm.fit here. model <- glm(theModel, family = quasipoisson(link="log")) #Check convergence - if no convergence we return empty handed. if (!model$converged) { #Try without time dependence if (timeTrend) { cat("Warning: No convergence with timeTrend -- trying without.\n") #Set model to one without time trend theModel <- as.formula("response~1") model <- glm(response ~ 1, family = quasipoisson(link="log")) } if (!model$converged) { cat("Warning: No convergence in this case.\n") print(cbind(response,wtime)) return(NULL) } } #Overdispersion parameter phi phi <- max(summary(model)$dispersion,1) #In case reweighting using Anscome residuals is requested if (reweight) { s <- anscombe.residuals(model,phi) omega <- algo.farrington.assign.weights(s) model <- glm(theModel,family=quasipoisson(link="log"),weights=omega) #Here, the overdispersion often becomes small, so we use the max #to ensure we don't operate with quantities less than 1. phi <- max(summary(model)$dispersion,1) } # end of refit. #Add wtime, response and phi to the model model$phi <- phi model$wtime <- wtime model$response <- response #Done return(model) } ###################################################################### # The algo.farrington.fitGLM function in a version using glm.fit # which is faster than the call using "glm. # This saves lots of overhead and increases speed. # # Author: Mikko Virtanen (@thl.fi) with minor modifications by Michael Hoehle # Date: 9 June 2010 # # Note: Not all glm results may work on the output. But for the # necessary ones for the algo.farrington procedure work. ###################################################################### algo.farrington.fitGLM.fast <- function(response,wtime,timeTrend=TRUE,reweight=TRUE, ...) { #Create design matrix and formula needed for the terms object #Results depends on whether to include a time trend or not. if (timeTrend) { design<-cbind(intercept=1,wtime=wtime) Formula<-response~wtime } else { design<-matrix(1,nrow=length(wtime),dimnames=list(NULL,c("intercept"))) Formula<-response~1 } #Fit it using glm.fit which is faster than calling "glm" model <- glm.fit(design,response, family = quasipoisson(link = "log")) #Check convergence - if no convergence we return empty handed. if (!model$converged) { #Try without time dependence if (timeTrend) { cat("Warning: No convergence with timeTrend -- trying without.\n") #Drop time from design matrix design <- design[,1,drop=FALSE] #Refit model <- glm.fit(design,response, family = quasipoisson(link = "log")) Formula<-response~1 } #No convergence and no time trend. That's not good. } #Fix class of output to glm/lm object in order for anscombe.residuals to work #Note though: not all glm methods may work for the result class(model) <- c("glm","lm") #Overdispersion parameter phi phi <- max(summary.glm(model)$dispersion,1) #In case reweighting using Anscome residuals is requested if (reweight) { s <- anscombe.residuals(model,phi) omega <- algo.farrington.assign.weights(s) model <- glm.fit(design,response, family = quasipoisson(link = "log"), weights = omega) #Here, the overdispersion often becomes small, so we use the max #to ensure we don't operate with quantities less than 1. phi <- max(summary.glm(model)$dispersion,1) } # end of refit. model$phi <- phi model$wtime <- wtime model$response <- response model$terms <- terms(Formula) # cheating a bit, all methods for glm may not work class(model)<-c("algo.farrington.glm","glm","lm") # 23/10/2012 (SM): # added "lm" class to avoid warnings # from predict.lm about fake object #Done return(model) } ###################################################################### # Experimental function to include a population offset in the # farrington procedure based on algo.farrington.fitGLM # Alternative: include populationOffset argument in the two other # fit functions, but I suspect use of this is not so common # # Parameters: # takes an additional "population" parameter ###################################################################### algo.farrington.fitGLM.populationOffset <- function(response,wtime,population,timeTrend=TRUE,reweight=TRUE,...) { #Model formula depends on whether to include a time trend or not. theModel <- as.formula(ifelse(timeTrend, "response~offset(log(population)) + 1 + wtime","response~offset(log(population)) + 1")) #Fit it -- this is slow. An improvement would be to use glm.fit here. model <- glm(theModel, family = quasipoisson(link="log")) #Check convergence - if no convergence we return empty handed. if (!model$converged) { #Try without time dependence if (timeTrend) { model <- glm(response ~ 1, family = quasipoisson(link="log")) cat("Warning: No convergence with timeTrend -- trying without.\n") } if (!model$converged) { cat("Warning: No convergence in this case.\n") print(cbind(response,wtime)) return(NULL) } } #Overdispersion parameter phi phi <- max(summary(model)$dispersion,1) #In case reweighting using Anscome residuals is requested if (reweight) { s <- anscombe.residuals(model,phi) omega <- algo.farrington.assign.weights(s) model <- glm(theModel,family=quasipoisson(link="log"),weights=omega) #Here, the overdispersion often becomes small, so we use the max #to ensure we don't operate with quantities less than 1. phi <- max(summary(model)$dispersion,1) } # end of refit. #Add wtime, response and phi to the model model$phi <- phi model$wtime <- wtime model$response <- response model$population <- population #Done return(model) } ################################################### ### code chunk number 4: algo_farrington.Rnw:344-370 ################################################### algo.farrington.threshold <- function(pred,phi,alpha=0.01,skewness.transform="none",y) { #Fetch mu0 and var(mu0) from the prediction object mu0 <- pred$fit tau <- phi + (pred$se.fit^2)/mu0 #Standard deviation of prediction, i.e. sqrt(var(h(Y_0)-h(\mu_0))) switch(skewness.transform, "none" = { se <- sqrt(mu0*tau); exponent <- 1}, "1/2" = { se <- sqrt(1/4*tau); exponent <- 1/2}, "2/3" = { se <- sqrt(4/9*mu0^(1/3)*tau); exponent <- 2/3}, { stop("No proper exponent in algo.farrington.threshold.")}) #Note that lu can contain NA's if e.g. (-1.47)^(3/2) lu <- sort((mu0^exponent + c(-1,1)*qnorm(1-alpha/2)*se)^(1/exponent),na.last=FALSE) #Ensure that lower bound is non-negative lu[1] <- max(0,lu[1],na.rm=TRUE) #Compute quantiles of the predictive distribution based on the #normal approximation on the transformed scale q <- pnorm( y^(exponent) , mean=mu0^exponent, sd=se) m <- qnorm(0.5, mean=mu0^exponent, sd=se)^(1/exponent) #Return lower and upper bounds return(c(lu,q=q,m=m)) } ################################################### ### code chunk number 5: algo_farrington.Rnw:412-451 ################################################### ###################################################################### # Compute indices of reference value using Date class # # Params: # t0 - Date object describing the time point # b - Number of years to go back in time # w - Half width of window to include reference values for # epochStr - "1 month", "1 week" or "1 day" # epochs - Vector containing the epoch value of the sts/disProg object # # Details: # Using the Date class the reference values are formed as follows: # Starting from d0 go i, i in 1,...,b years back in time. # # Returns: # a vector of indices in epochs which match ###################################################################### refvalIdxByDate <- function(t0, b, w, epochStr, epochs) { refDays <- NULL refPoints <- seq( t0, length.out=b+1, by="-1 year")[-1] #Loop over all b-lagged points and append appropriate w-lagged points for (j in 1:length(refPoints)) { refPointWindow <- c(rev(seq(refPoints[j], length.out=w+1, by=paste("-",epochStr,sep=""))), seq(refPoints[j], length.out=w+1, by=epochStr)[-1]) refDays <- append(refDays,refPointWindow) } if (epochStr == "1 week") { #What weekday is t0 (0=Sunday, 1=Monday, ...) epochWeekDay <- as.numeric(format(t0,"%w")) #How many days to go forward to obtain the next "epochWeekDay", i.e. (d0 - d) mod 7 dx.forward <- (epochWeekDay - as.numeric(format(refDays,"%w"))) %% 7 #How many days to go backward to obtain the next "epochWeekDay", i.e. (d - d0) mod 7 dx.backward <- (as.numeric(format(refDays,"%w")) - epochWeekDay) %% 7 #What is shorter - go forward or go backward? #By convention: always go to the closest weekday as t0 refDays <- refDays + ifelse(dx.forward < dx.backward, dx.forward, -dx.backward) } if (epochStr == "1 month") { #What day of the month is t0 (it is assumed that all epochs have the same value here) epochDay <- as.numeric(format(t0,"%d")) #By convention: go back in time to closest 1st of month refDays <- refDays - (as.numeric(format(refDays, "%d")) - epochDay) } #Find the index of these reference values wtime <- match(as.numeric(refDays), epochs) return(wtime) } ################################################### ### code chunk number 6: algo_farrington.Rnw:571-769 ################################################### algo.farrington <- function(disProgObj, control=list( range=NULL, b=5, w=3, reweight=TRUE, verbose=FALSE, plot=FALSE, alpha=0.05, trend=TRUE, limit54=c(5,4), powertrans="2/3", fitFun="algo.farrington.fitGLM.fast") ) { #Fetch observed observed <- disProgObj$observed freq <- disProgObj$freq epochStr <- switch( as.character(freq), "12" = "1 month","52" = "1 week","365" = "1 day") #Fetch population (if it exists) if (!is.null(disProgObj$populationFrac)) { population <- disProgObj$populationFrac } else { population <- rep(1,length(observed)) } ###################################################################### # Initialize and check control options ###################################################################### defaultControl <- eval(formals()$control) control <- modifyList(defaultControl, control, keep.null = TRUE) if (is.null(control$range)) { control$range <- (freq*control$b - control$w):length(observed) } control$fitFun <- match.arg(control$fitFun, c("algo.farrington.fitGLM.fast", "algo.farrington.fitGLM", "algo.farrington.fitGLM.populationOffset")) #Use special Date class mechanism to find reference months/weeks/days if (is.null(disProgObj[["epochAsDate",exact=TRUE]])) { epochAsDate <- FALSE } else { epochAsDate <- disProgObj[["epochAsDate",exact=TRUE]] } #check options if (!((control$limit54[1] >= 0) & (control$limit54[2] > 0))) { stop("The limit54 arguments are out of bounds: cases >= 0 and period > 0.") } #Check control$range is within bounds. if (any((control$range < 1) | (control$range > length(disProgObj$observed)))) { stop("Range values are out of bounds (has to be within 1..",length(disProgObj$observed)," for the present data).") } # initialize the necessary vectors alarm <- matrix(data = 0, nrow = length(control$range), ncol = 1) trend <- matrix(data = 0, nrow = length(control$range), ncol = 1) upperbound <- matrix(data = 0, nrow = length(control$range), ncol = 1) # predictive distribution pd <- matrix(data = 0, nrow = length(control$range), ncol = 2) # Define objects n <- control$b*(2*control$w+1) # 2: Fit of the initial model and first estimation of mean and dispersion # parameter for (k in control$range) { # transform the observed vector in the way # that the timepoint to be evaluated is at last position #shortObserved <- observed[1:(maxRange - k + 1)] if (control$verbose) { cat("k=",k,"\n")} #Find index of all epochs, which are to be used as reference values #i.e. with index k-w,..,k+w #in the years (current year)-1,...,(current year)-b if (!epochAsDate) { wtimeAll <- NULL for (i in control$b:1){ wtimeAll <- append(wtimeAll,seq(k-freq*i-control$w,k-freq*i+control$w,by=1)) } #Select them as reference values - but only those who exist wtime <- wtimeAll[wtimeAll>0] if (length(wtimeAll) != length(wtime)) { warning("@ range= ",k,": With current b and w then ",length(wtimeAll) - length(wtime),"/",length(wtimeAll), " reference values did not exist (index<1).") } } else { #Alternative approach using Dates t0 <- as.Date(disProgObj$week[k], origin="1970-01-01") wtimeAll <- refvalIdxByDate( t0=t0, b=control$b, w=control$w, epochStr=epochStr, epochs=disProgObj$week) #Select them as reference values (but only those not being NA!) wtime <- wtimeAll[!is.na(wtimeAll)] #Throw warning if necessary if (length(wtimeAll) != length(wtime)) { warning("@ range= ",k,": With current b and w then ",length(wtimeAll) - length(wtime),"/",length(wtimeAll), " reference values did not exist (index<1).") } } #Extract values from indices response <- observed[wtime] pop <- population[wtime] if (control$verbose) { print(response)} ###################################################################### #Fit the model with overdispersion -- the initial fit ###################################################################### #New feature: fitFun can now be the fast function for fitting the GLM model <- do.call(control$fitFun, args=list(response=response,wtime=wtime,population=pop,timeTrend=control$trend,reweight=control$reweight)) #Stupid check to pass on NULL values from the algo.farrington.fitGLM proc. if (is.null(model)) return(model) ###################################################################### #Time trend # #Check whether to include time trend, to do this we need to check whether #1) wtime is significant at the 95lvl #2) the predicted value is not larger than any observed value #3) the historical data span at least 3 years. doTrend <- control$trend #Bug discovered by Julia Kammerer and Sabrina Heckl: Only investigate trend if it actually was part of the GLM #if (control$trend) { if ("wtime" %in% names(coef(model))){ #is the p-value for the trend significant (0.05) level p <- summary.glm(model)$coefficients["wtime",4] significant <- (p < 0.05) #prediction for time k mu0Hat <- predict.glm(model,data.frame(wtime=c(k),population=population[k]),type="response") #have to use at least three years of data to allow for a trend atLeastThreeYears <- (control$b>=3) #no horrible predictions noExtrapolation <- mu0Hat <= max(response) #All 3 criteria have to be met in order to include the trend. Otherwise #it is removed. Only necessary to check this if a trend is requested. if (!(atLeastThreeYears && significant && noExtrapolation)) { doTrend <- FALSE model <- do.call(control$fitFun, args=list(response=response,wtime=wtime,population=pop,timeTrend=FALSE,reweight=control$reweight)) } } else { doTrend <- FALSE } #done with time trend ###################################################################### ###################################################################### # Calculate prediction & confidence interval # ###################################################################### #Predict value - note that the se is the mean CI #and not the prediction error of a single observation pred <- predict.glm(model,data.frame(wtime=c(k),population=population[k]),dispersion=model$phi, type="response",se.fit=TRUE) #Calculate lower and upper threshold lu <- algo.farrington.threshold(pred,model$phi,skewness.transform=control$powertrans,alpha=control$alpha, observed[k]) ###################################################################### # If requested show a plot of the fit. ###################################################################### if (control$plot) { #Compute all predictions data <- data.frame(wtime=seq(min(wtime),k,length.out=1000)) preds <- predict(model,data,type="response",dispersion=model$phi) #Show a plot of the model fit. plot(c(wtime, k), c(response,observed[k]),ylim=range(c(observed[data$wtime],lu)),,xlab="time",ylab="No. infected",main=paste("Prediction at time t=",k," with b=",control$b,",w=",control$w,sep=""),pch=c(rep(1,length(wtime)),16)) #Add the prediction lines(data$wtime,preds,col=1,pch=2) #Add the thresholds to the plot lines(rep(k,2),lu[1:2],col=3,lty=2) } ###################################################################### #Postprocessing steps ###################################################################### #Compute exceedance score unless less than 5 reports during last 4 weeks. #Changed in version 0.9-7 - current week is included now enoughCases <- (sum(observed[(k-control$limit54[2]+1):k])>=control$limit54[1]) #18 May 2006: Bug/unexpected feature found by Y. Le Strat. #the okHistory variable meant to protect against zero count problems, #but instead it resulted in exceedance score == 0 for low counts. #Now removed to be concordant with the Farrington 1996 paper. X <- ifelse(enoughCases,(observed[k] - pred$fit) / (lu[2] - pred$fit),0) #Do we have an alarm -- i.e. is observation beyond CI?? #upperbound only relevant if we can have an alarm (enoughCases) trend[k-min(control$range)+1] <- doTrend alarm[k-min(control$range)+1] <- (X>1) upperbound[k-min(control$range)+1] <- ifelse(enoughCases,lu[2],0) #Compute bounds of the predictive pd[k-min(control$range)+1,] <- lu[c(3,4)] }#done looping over all time points #Add name and data name to control object. control$name <- paste("farrington(",control$w,",",0,",",control$b,")",sep="") control$data <- paste(deparse(substitute(disProgObj))) #Add information about predictive distribution control$pd <- pd # return alarm and upperbound vectors result <- list(alarm = alarm, upperbound = upperbound, trend=trend, disProgObj=disProgObj, control=control) class(result) <- "survRes" #Done return(result) } surveillance/R/earsC.R0000644000176200001440000001616014263461255014343 0ustar liggesusers# \|||/ # (o o) # ,~~~ooO~~(_)~~~~~~~~~, # | EARS | # | surveillance | # | methods | # | C1, C2 and C3 | # '~~~~~~~~~~~~~~ooO~~~' # |__|__| # || || # ooO Ooo ###################################################################### # Implementation of the EARS surveillance methods. ###################################################################### # DESCRIPTION ###################################################################### # Given a time series of disease counts per month/week/day # this function determines whether there was an outbreak at given time points: # it deduces for each time point an expected value from past values, # it defines an upperbound based on this value and on the variability # of past values # and then it compares the observed value with the upperbound. # If the observed value is greater than the upperbound # then an alert is flagged. # Three methods are implemented. # They do not use the same amount of past data # and are expected to have different specificity and sensibility # from C1 to C3 # the amount of past data used increases, # so does the sensibility # but the specificity decreases. ###################################################################### # PARAMETERS ###################################################################### # range : range of timepoints over which the function will look for # outbreaks. # method : which of the three EARS methods C1, C2 and C3 should be used. # ###################################################################### # INPUT ###################################################################### # A R object of class sts ###################################################################### # OUTPUT ###################################################################### # The same R object of class sts with slot alarm and upperbound filled # by the function ###################################################################### earsC <- function(sts, control = list(range = NULL, method = "C1", baseline = 7, minSigma = 0, alpha = 0.001)) { ###################################################################### #Handle I/O ###################################################################### #If list elements are empty fill them! if (is.null(control[["baseline", exact = TRUE]])) { control$baseline <- 7 } if (is.null(control[["minSigma", exact = TRUE]])) { control$minSigma <- 0 } baseline <- control$baseline minSigma <- control$minSigma if(minSigma < 0) { stop("The minimum sigma parameter (minSigma) needs to be positive") } if (baseline < 3) { stop("Minimum baseline to use is 3.") } # Method if (is.null(control[["method", exact = TRUE]])) { control$method <- "C1" } # Extracting the method method <- match.arg( control$method, c("C1","C2","C3"),several.ok=FALSE) # Range # By default it will take all possible weeks # which is not the same depending on the method if (is.null(control[["range",exact=TRUE]])) { if (method == "C1"){ control$range <- seq(from=baseline+1, to=dim(sts@observed)[1],by=1) } if (method == "C2"){ control$range <- seq(from=baseline+3, to=dim(sts@observed)[1],by=1) } if (method == "C3"){ control$range <- seq(from=baseline+5, to=dim(sts@observed)[1],by=1) } } # zAlpha if (is.null(control[["alpha",exact=TRUE]])) { # C1 and C2: Risk of 1st type error of 10-3 # This corresponds to an Z(1-zAlpha) of about 3 if (method %in% c("C1","C2")) { control$alpha = 0.001 } # C3: Risk of 1st type error of 0.025 # This corresponds to an Z(1-zAlpha) of about 2 if (method=="C3") { control$alpha = 0.025 } } # Calculating the threshold zAlpha zAlpha <- qnorm((1-control$alpha)) #Deduce necessary amount of data from method maxLag <- switch(method, C1 = baseline, C2 = baseline+2, C3 = baseline+4) # Order range in case it was not given in the right order control$range = sort(control$range) ###################################################################### #Loop over all columns in the sts object #Call the right EARS function depending on the method chosen (1, 2 or 3) ##################################################################### for (j in 1:ncol(sts)) { # check if the vector observed includes all necessary data: maxLag values. if((control$range[1] - maxLag) < 1) { stop("The vector of observed is too short!") } ###################################################################### # Method C1 or C2 ###################################################################### if(method == "C1"){ # construct the matrix for calculations ndx <- as.vector(outer(control$range, baseline:1, FUN = "-")) refVals <- matrix(observed(sts)[,j][ndx], ncol = baseline) sts@upperbound[control$range, j] <- apply(refVals,1, mean) + zAlpha * pmax(apply(refVals, 1, sd), minSigma) } if (method == "C2") { # construct the matrix for calculations ndx <- as.vector(outer(control$range, (baseline + 2):3, FUN = "-")) refVals <- matrix(observed(sts)[,j][ndx], ncol = baseline) sts@upperbound[control$range, j] <- apply(refVals,1, mean) + zAlpha * pmax(apply(refVals, 1, sd), minSigma) } if (method == "C3") { # refVals <- NULL rangeC2 = ((min(control$range) - 2):max(control$range)) ##HB replacing loop: ndx <- as.vector(outer(rangeC2, (baseline + 2):3, FUN = "-")) refVals <- matrix(observed(sts)[,j][ndx], ncol = baseline) ##HB using argument 'minSigma' to avoid dividing by zero, huge zscores: C2 <- (observed(sts)[rangeC2, j] - apply(refVals, 1, mean))/ pmax(apply(refVals, 1, sd), minSigma) partUpperboundLag2 <- pmax(rep(0, length.out = length(C2) - 2), C2[1:(length(C2) - 2)] - 1) partUpperboundLag1 <- pmax(rep(0, length.out = length(C2) - 2), C2[2:(length(C2) - 1)] - 1) ##HB using argument 'minSigma' to avoid alerting threshold that is zero or too small sts@upperbound[control$range, j] <- observed(sts)[control$range, j] + pmax(apply(as.matrix(refVals[3:length(C2), ]),1, sd),minSigma) * (zAlpha - (partUpperboundLag2 + partUpperboundLag1)) sts@upperbound[control$range, j] = pmax(rep(0, length(control$range)), sts@upperbound[control$range, j]) } } #Copy administrative information control$name <- paste("EARS_", method, sep = "") control$data <- paste(deparse(substitute(sts))) sts@control <- control sts@alarm[control$range, ] <- matrix(observed(sts)[control$range, ] > upperbound(sts)[control$range, ]) return(sts[control$range, ]) } surveillance/R/intersectPolyCircle.R0000644000176200001440000000265314517030246017270 0ustar liggesusers################################################################################ ### Compute the intersection of a circular domain with a polygonal domain of ### various classes (currently: "owin" or "SpatialPolygons") ### ### Copyright (C) 2009-2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ intersectPolyCircle.owin <- function (object, center, radius, npoly = 32, ...) { circle <- disc(radius = radius, centre = center, npoly = npoly) res <- intersect.owin(circle, object) # order does not affect runtime ## ensure "polygonal" type (because of rescue.rectangle in intersect.owin) as.polygonal(res) } intersectPolyCircle.SpatialPolygons <- function (object, center, radius, npoly = 32, ...) { .Defunct() ## FIXME: could implement and wrap a method for sf polygons ##intersectPolyCircle.sfc(sf::st_as_sfc(object), center, radius, npoly, ...) } ## intersectPolyCircle.sfc <- function (object, center, radius, npoly = 32, ...) ## { ## ## FIXME: assert polygonal object ## circle <- discpoly(center, radius, npoly = npoly, class = "sfg") # or sfc? ## sf::st_intersection(object, circle) ## } surveillance/R/magic.dim.R0000644000176200001440000000705114615162374015136 0ustar liggesusers###################################################################### # Compute a suitable layout for plotting ###################################################################### magic.dim <- function(k){ if(k==1) return(c(1,1)) #factorize k factors <- primeFactors(k) #find the best factorization of k into two factors res <- bestCombination(factors) #if k is a prime or the difference between the two factors of k is too large #rather use the roots of the next square number greater than k if(diff(res) >5){ #up is root of the smallest square number >= k up <- ceiling(sqrt(k)) #low is root of the biggest square number < k low <- up -1 # e.g. k=11 is a prime, the next square number is 16 so up=4 and low=3 # low^2 = 9 < 11 is naturally too small, up^2=16 > 11 so c(4,4) is a solution # but low*up = 3*4 = 12 > 11 is also adequate and a better solution if((k - low^2) < up) res <- c(low,up) else res <- c(up,up) } return(sort(res)) } ###################################################################### # Compute the prime number factorization of an integer ###################################################################### primeFactors <- function(x){ if(x %in% 1:3) return(x) factors<- numeric(0) i<-1 #start with i=2 and divide x by i (as often as possible) then try division by i+1 #until all factors are found, i.e. x=1 while(i < x){ i <- i+1 while((x %% i)==0){ # each time a new factor i is found, save it and proceed with x = x/i # e.g. k=20: 2 is a factor of x=20, continue with x = 10 = 20/2 # 2 is a factor of x=10, continue with x = 5 = 10/2 # 3 and 4 are no factors of x = 5 # 5 is a factor of x = 5, continue with x = 1 # result: 20 = c(2, 2, 5) factors <- c(factors, i) x <- x/i } } return(factors) } ###################################################################### # Given a prime number factorization of a number, e.g. 36 # yields x=c(2,2,3,3) # and partition x into two groups, such that the product of the numbers # in group one is as similar as possible to the product # of the numbers of group two. This is useful in magic.dim # # Params: # x - the prime number factorization # # Returns: # c(prod(set1),prod(set2)) ###################################################################### bestCombination <- function(x) { #Compute the power set of 0:1^length(x), i.e. a binary indicator for #variable stating whether to include it in set 1 or not. combos <- as.matrix(expand.grid(rep(list(c(FALSE,TRUE)), length(x)), KEEP.OUT.ATTRS = FALSE)) ## more efficient version, if ever needed: ## ncomb <- 2^length(x) ## combos <- vapply( ## X = seq_along(x), ## FUN = function(i) rep_len(rep(c(FALSE,TRUE), each = 2^(i-1)), ncomb), ## FUN.VALUE = logical(ncomb), ## USE.NAMES = FALSE) #Small helper function, given a vector of length(x) stating whether #to include an element in set1 or not, compute the product #of set1 and set2=x\backslash set1 #set1: all those for which include is TRUE, set2: all those for which #include is FALSE setsize <- function(include) c(prod(x[include]), prod(x[!include])) #Compute the product of set1 and set2 for each possible combination sizes <- apply(combos,MARGIN=1,FUN=setsize) #Calculate the combination, where x is as close to y as possible bestConfig <- combos[which.min(abs(diff(sizes))),] #Return this setsize of this configuration return(setsize(bestConfig)) } surveillance/R/stsNClist_animate.R0000644000176200001440000002276514615162374016743 0ustar liggesusers###################################################################### # Function to plot a sequence of nowcasts. Can be wrapped with the # animation package to produce PDF or Web animations # # Parameters: # linelist_truth - data.frame containing the linelist of cases/reports # dEventCol - name of the column containing the time of event (as Date) # dReportCol - name of the column containing the time of report receipt (as Date) # aggregate.by - aggregation level (see function linelist2sts) # nowcasts - a list of nowcasts (if NULL then they are generated on the fly - Note: This is currently not implemented!) # method - which method to animate. Has to be part of the individual nowcast objects in 'nowcasts' # control - control object for controlling how the plotting is done ###################################################################### animate_nowcasts <- function(nowcasts,linelist_truth, method="bayes.trunc.ddcp", control=list(dRange=NULL,anim.dRange=NULL, plot.dRange=NULL,consistent=FALSE,sys.sleep=1,ylim=NULL,cex.names=0.7,col=c("violetred3","#2171B5","orange","blue","black","greenyellow")),showLambda=TRUE) { ##Extract the dEventCol and dReportCol from the nowcasts dEventCol <- nowcasts[[1]]@control$call$dEventCol dReportCol <- nowcasts[[1]]@control$call$dReportCol aggregate.by <- nowcasts[[1]]@control$call$aggregate.by ##Boolean indicator for those having information on dEventCol validVarInfo <- !is.na(linelist_truth[,dEventCol]) ##Show info about what is being illustrated message(paste("Total of ",nrow(linelist_truth)," cases in linelist_truth.\nIllustring reporting for ",sum(!is.na(linelist_truth[,dEventCol]))," cases with information on \"",dEventCol,"\"\n",sep="")) ##Reduce linelist_truth to those who have the appropriate information linelist_truth <- linelist_truth[validVarInfo,] ######################################### ## Check and set default control options ######################################### if (is.null(control[["dRange",exact=TRUE]])) { range <- range(c(linelist_truth[,dEventCol],linelist_truth[,dReportCol]),na.rm=TRUE) } else { range <- control$dRange } range.dates <- seq(range[1],range[2],by=aggregate.by) #plot.dRange if (is.null(control[["plot.dRange",exact=TRUE]])) { control$plot.dRange <- range(range) } #anim.dRange if (is.null(control[["anim.dRange",exact=TRUE]])) { control$anim.dRange <- control$dRange } #sys.sleep if (is.null(control[["sys.sleep",exact=TRUE]])) control$sys.sleep <- 1 if (is.null(control[["cex.names",exact=TRUE]])) control$cex.names <- 1 if (is.null(control[["col",exact=TRUE]])) control$col <- c("violetred3","#2171B5","orange","blue","black","springgreen4") if (is.null(control[["showLambda",exact=TRUE]])) control$showLambda <- TRUE ##Check that a list of nowcasts is available if (is.null(nowcasts)) { stop("not implemented!") } ##################### # Preprocessing block ##################### #Create an sts object with the true number of cases.. sts <- linelist2sts(linelist_truth,dEventCol,aggregate.by=aggregate.by,dRange=range) #Index of the time points in the plot.dRange plot.dates.idx <- as.numeric(control$plot.dRange - range[1] + 1) #Index of the animate dates anim.dates <- seq(control$anim.dRange[1],control$anim.dRange[2],by="1 day") idxSet <- pmatch(anim.dates,range.dates) ##Find ylim if (is.null(control[["ylim",exact=TRUE]])) { ymax <- max(observed(sts),upperbound(sts),na.rm=TRUE) ymax <- max(ymax,unlist(lapply(nowcasts, function(nc) max(c(observed(nc),upperbound(nc),predint(nc)),na.rm=TRUE)))) control$ylim <- c(0,ymax) } ##====================== ## Loop over all dates ##====================== ##Loop over all days. always show what we know for (i in idxSet) { ##fix this #Set "today" curDate <- as.Date(range.dates[i]) message("Animating ",as.character(curDate),"...") #Choose all reports available until this "today" linelist_truth.avail <- linelist_truth[ linelist_truth[,dReportCol] <= curDate,] #If consistency checking is requested remove all entries which #are "beyond" today if (!is.null(control$consistent)) { linelist_truth.avail <- linelist_truth.avail[ linelist_truth.avail[,dEventCol] <= curDate,] } ##Check that date exists in nowcast list. sts.nowcast <- nowcasts[[as.character(curDate)]] if (is.null(sts.nowcast)) { stop("Date: ",as.character(curDate)," not available in nowcasts.") } ##Check that method exists in nowcast object if (!(method %in% nowcasts[[as.character(curDate)]]@control$method)) { stop("Method ",method," not in nowcasts!") } ##Extract the used safePredictLag control$safePredictLag <- sts.nowcast@control$now - max(sts.nowcast@control$when) ##Fill upperbound and CI slots with output of that method (not pretty code: ToDo Improve!!) N.tInf.support <- sts.nowcast@control$N.tInf.support Ps <- sts.nowcast@predPMF when <- sts.nowcast@control$when dateRange <- epoch(sts.nowcast) idxt <- which(dateRange %in% when) alpha <- sts.nowcast@control$alpha ##Loop over all time points for (i in idxt) { predPMF <- Ps[[as.character(dateRange[i])]][[method]] sts.nowcast@upperbound[i,] <- median(N.tInf.support[which.max( cumsum(predPMF)>0.5)]) sts.nowcast@pi[i,,] <- N.tInf.support[c(which.max(cumsum(predPMF) >= alpha/2),which.max(cumsum(predPMF) >= 1-alpha/2))] } dimnames(sts.nowcast@pi) <- list(as.character(dateRange),NULL,paste( c(alpha/2*100,(1-alpha/2)*100),"%",sep="")) #Done upperbound(sts.nowcast)[-idxt] <- NA #All events which (in an ideal world) would be available now linelist_truth.now <- linelist_truth[ linelist_truth[,dEventCol] <= curDate,] sts.now <- linelist2sts(linelist_truth.now,dEventCol,aggregate.by=aggregate.by,dRange=c(range[1],curDate))#range) ##Percentage of possible observations which are available sum(observed(sts.nowcast)) sum(upperbound(sts.nowcast)) message(sprintf("(%.0f%% of total cases in linelist_truth reported)\n",sum(observed(sts.nowcast))/sum(observed(sts.now))*100)) ##Show the true number of counts observed(sts) <- matrix(0,nrow=nrow(sts),ncol=1) upperbound(sts) <- matrix(0,nrow=nrow(sts),ncol=1) observed(sts)[1:nrow(sts.now),] <- observed(sts.now) upperbound(sts)[1:nrow(sts.now),] <- upperbound(sts.now) ##Plot the true number of counts as sts object plot(sts,legend=NULL,dx.upperbound=0,main="",lwd=c(1,1,3),ylab="No. Cases",ylim=control$ylim,lty=c(1,1,1),axes=FALSE,xlab="",col=c(control$col[c(1,1)],NULL), xlim=plot.dates.idx,xaxs="i") ####################start to change. Use proper customizable arguments ### plot the nowcast using the S4 method and then add the other ### stuff on top of it... ##Add the nowcast plot(sts.nowcast,dx.upperbound=0,axes=FALSE,col=control$col[c(2,2,3)],lty=c(1,1,1),legend=NULL,add=TRUE,lwd=c(3,3,3),xlim=plot.dates.idx,xaxs="i") ##Last proper index idx <- nrow(sts.nowcast) - which.max(!is.na(rev(upperbound(sts.nowcast)))) + 1 ##Continue line from plot lines( idx+c(-0.5,0.5), rep(upperbound(sts.nowcast)[idx,],2),lty=1,col=control$col[3],lwd=3) ##Add CIs from the nowcast for (i in 1:nrow(sts.nowcast)) { lines( i+c(-0.3,0.3), rep(sts.nowcast@pi[i,,1],2),lty=1,col=control$col[3]) lines( i+c(-0.3,0.3), rep(sts.nowcast@pi[i,,2],2),lty=1,col=control$col[3]) lines( rep(i,each=2), sts.nowcast@pi[i,,],lty=2,col=control$col[3]) } ##Add lambda_t if it exists. if (method == "bayes.trunc.ddcp" && control$showLambda) { lambda <- attr(delayCDF(sts.nowcast)[["bayes.trunc.ddcp"]],"model")$lambda showIdx <- seq(ncol(lambda) - control$safePredictLag) ##matlines( showIdx,t(lambda)[showIdx,],col="gray",lwd=c(1,2,1),lty=c(2,1,2)) ##If m parameter is used then also only show the polynomial up to m times back. if (!is.null(sts.nowcast@control$call$m)) { showIdx <- seq(ncol(lambda) - sts.nowcast@control$call$m, ncol(lambda) - control$safePredictLag, by=1) } matlines( showIdx, t(lambda)[showIdx,],col="gray",lwd=c(1,2,1),lty=c(2,1,2)) } ##Add axis information axis(2) ##Add extra line parts on x-axis axis(1,at=0:1e3,tick=TRUE,lwd.ticks=0,labels=rep("",1e3+1)) axis(1,at=0:1e3,tick=TRUE,lwd.ticks=1,tcl=-0.2,labels=rep("",1e3+1)) ##Highlight the mondays is.monday <- format(range.dates,"%w") == 1 axis(1,at=(1:length(range.dates))[is.monday],labels=format(range.dates[is.monday],"%a %d %b"),las=2,cex.axis=control$cex.names) ##Show month breaks dom <- as.numeric(format(range.dates,"%d")) axis(1,at=which(dom==1),labels=rep("",sum(dom==1)),tcl=-0.8,lwd=0,lwd.ticks=1) ####################stop to change ##Extra text <- c("Events up to \"now\"","Reports received by \"now\"",paste("Nowcasts by ",method,sep=""), if (method=="bayes.trunc.ddcp") expression(lambda[t]*" of bayes.trunc.ddcp") else NULL) col <- c(control$col[1:3], if (method=="bayes.trunc.ddcp") "gray" else NULL) legend(x="topright",text,col=col, lwd=3,lty=1) ##Add now symbol points(curDate-range[1]+1,0,pch=10,col=control$col[6],cex=1.5) ##Add nowcast symbol points(curDate-range[1]+1-control$safePredictLag,0,pch=9,col=control$col[3],cex=1.5) ##Add this to the legend legend(x="right",c("Now","Nowcast horizon"),pch=c(10,9),col=control$col[c(6,3)],pt.cex=1.5) ##Pause Sys.sleep(control$sys.sleep) } invisible() } surveillance/R/sysdata.rda0000644000176200001440000002375014026445515015324 0ustar liggesusers7zXZi"6!X'])TW"nRʟF X#Qd[ZfFdO~ڒ.e$/|<07qKܜn,,m?TKDU0NOp1HɝsQY]\fՅ k?m; M4H'hNag!7}[ݼݫ!h(`'>:uGxЯ9##q2shIʡqcU `#Ьnt !iYOS7?b-IWP: 1I!i}b TR|eXn #@DKP wkNÔ'>MAfS6]BۮZoh%UBr֢-Ojg{d3u1R˰OVG6ǧ S\CindI%ڝ?We uP?۸e7*z8]/y҃Qmf]>;bg89 9fJe\u'Ki\L$QUd.D- 7lkuijʼ܎ d1#k^u#1k{ ?&Us!/sq1e< $ U亱"}S %_b& !}ݰIF@(#jR ,0yV ?ϑ[ 5{Q@.d{5@QW9Ӵ-ed҉W: ǻ6^QxU6<6=L>-޿ , kGYbltRmvg Է9og3+4%8è׻8e]B' }D=?7H$d]txVĪXޒr OВmy竷c@i,$Jn::exaf} ԓ QkYu9O텡n\m̶@gP_ S&r QB벪B- T7^J?:0#B)uW{M:1R/7ܐSDԧ#Gn~GL_E*#iBv=Ar]F~j#`"!aEx Jj(^7rWVCa&"U'[CWԷWzJ,E2n.תMX_GUmya ۣ <8>!aHt̒>LY@Z1<: 5= w1I_Qִ-]\%?K!_{Ybڹ]7Y<7Ìgx,*Voܰ(/2G eJ"0q&KJl$ aǴ.Vs+!坩%'p 9,X}5&88 c&", b2 hӝdS>Qk;dssYNa3;|41w8C_LF2dݚ^e`L޳$^J%14?ɀ-!i>;mT\*]djP߸h#c1"wqu[g,E1Dg(VѰj)ӠW&:l"F-Hn o?UÊc8+RM>4Skl`W.jїnAi9)Cukݼk_Y8OeeK hZ/uy2< x zMll4<+ݥ]' "rj$hn^f&]d5nXVmo'چrKCFgu)w垵40yUzހC* N ҾoMQ*}sMW^TD L-,غLA8NaWWDp<,1e p$D O=]滲b<2B\g;)rU 3!+@&MV" Mmn؊ OThޮ9h8>`u}9ID_\N`].$R4T%,>2n% m>DŽaa`\X==\މ0D,`]X 5[ *6 D|/>\ M\iÇ]ڹHTܚm|4lAGU? /RF$6eҧ^~=<V$G=PL_s r\G몑Zo =Ѳ- _\D뾤0ITFpSC݌A$yF-a8 h[H}trҼ_ێP5&Rd }݋6 p.Oug8qlj6hDE1 ՅE )CȾ`pQiu/8@gVG$HS ~ 6Zb]q.8,Q:d ~(/E%¸q)S58J!-<'GAv@Vk9n~?ޝƭd*BmT"=HrYWn;{LE @@аUV}S|+6\XE:,"!RЇf_}ٿm01N7 //Xû:J]ͱ̇*,VZI 1$iFjz+Ӳ,cL7iٻg+|F)S A%ov<=EQ GGH%_bӪbh}Z WUɯ_}!ζFp q!<5t y>=';G/ɯ.n9GL74-1z/54ؗ_u6| mOF}Hq>A Sq/jHH?|=x:E%pr e׋7$$0vC'PirAn"(ա Qvu _1 85\3B{ $n5Lf*f0iD?e289r :4j64L'p;eO]#qb%K"v5dt:tt(<3Z9y\ǜT{ߦUh;|c$-8vdtieo! EJ byZ4px3ej ݐ7߫y!=~sRG6kdƵ3}d{뭳 n棼ܢ e7K%\4ab?3ؘ0OR--3Ns+ӓR6 f<NwN# !^)hFwxALV8΅wCX}$"GFaIsdչTw?$L'CpsG1I{i/@{|Uug d_z+gy?ejTYs^H]뺕r} G$9|%(p:(dŦc)_(&%xuc崂lh7H!00DykŸӞDmU+@5{ ,c: k-PVޙrB橉F{Nrzu=M.Ԫ=A@fJE),Mn֏=SPGmtHh= { Ps t.4Pw~sz)'dr$AJwuQ;ܩU)Z>'*`?):Omyn׿mزLV7ӹLISO H1[7&%fMVYX~t'U*'"_mM;+V8-52p]Ӟv '0ڿ&l-Nbkfv`ҧ NM*3Vo(-TyM6 l%Ǩnz(ep!s0/YEw/NLnW+*ۖV hשU4I|[PKZ;IT8K,4!س+ۢy ΜKZNٓNw N [Cދ -aP6Zƻ19>K +YR N b?H;Nf( R_~9DkDtC P/]ckDJh:ڣdR+2za,g#6O`k ,5Cea:Y +mNQjc@NCs:]d&ݐO;~۴F mgBj?".ޮ$hSSΉyXʬ22,(35tʂ>lC,}C܄Ғn1 ?&B"},óbeԆNϸֆ7M@b|n N;f^> E7Ǩ%虲BnUZ6,#Y6GѰED=JST豄"\`aip˓Q0'C]@ر~4ާPŠ2q uio1c]x^_pgYe"6S]E0j f7e!J;UYN i&"x:nK>lo/B)T 0/reSvNhA5c@ԑ^QQYw9bHV[n,fsIeZvs?V9GG}wJ|fhPeh#[VE d1Z8WFgU2?isƶJwWNmcВ*W>jzC/iaajT ? MEa$5L6z'DZ|w 9In}!FS\B1n%$dmPbJ[~pQ֖VGeUL{ZU'9inW؛!'زJJ4Yn7З.Bj;紽8JީcM*4} aM$$2EumQhBg hbӂ {\@|RD AI6O2|9j"|**[)PgnIQE: m-(~lvP :oq`%EϬR` ݋n'NƏyQ~>LŵX0A"bt#wD(m`tOe? =ъh~ J3e_< 1 QM|SF5mӒBWA{8@=q]L~<ڔNk}Q%epҿ9'l/{yͥ4[Y+NH@ܽSYLޛeS?2%x32Δǚ ~sAˀGE&"5ͩ%To+*srkOb6xOOfks jFz7JpLK*d<;!NTNOA@ENcNIFXխgc\Ԫkݨ㼾uD).KU^@RJ)̪?cX\M<҈V⢭{DQDƏn7 `<`WAi+zab^`!|96v4[vN 0U;,aXl NgZWT_~⒜;lc<l<# U/ {(:QCP2)/n^ Ü9~Fr1c0֌Q1bhVMXwh|өE(ZN^ M& l-)l=>+z{[In #k'Laݥ)%[! j?l6!'l|/JCN{?N*^M>F_F7a -FVmG$|#qG;S.Ǿdw?8iǡ@əF\2gfg.le8)m]*ujѝ^j{AEmL.iqH>3I5dp;(2 TG#zSB u9rA&Z#A h0?ŗMdtT͇"^;?!"yˁ"ZI MӐ/-RyB{t)ڱl38УSXװT,11ξbIϊ׈q,̼?O.mG2ȸ=`ܧ%%k}dγ=ꓼ$n*3!Y)fTUƞ{.F.zjwN3_57jwX V+WEEՄ)ͪ_Sm7n^NvϊZˉ8dmReS%BNîq||[Qos\ܨNzz*w^1bנiU[#]^eޞҝK,O} Ͽqe‹G*Zc4meXjwBI'=ׇ]JE8}=8m]܀X'22g {3GSE{. tWUG 6/m#1:l2 t0$/a r}1RM'V3ڒ3u Bzpa2yi4D^SLeXTajߛ2߅2OTCD6d癰y|_z"yiXY0prM;A88dFr9kM5?.s 3lA^F}>Y`#tv>H>uвp:*p)s9wۧbHDl~Z»_ˣ g/!ifm6ldlheX|'V֋]]0y/NI~P -Ogm>0 YZsurveillance/R/isScalar.R0000644000176200001440000000110013117531333015023 0ustar liggesusers################################################################################ ### Check if an R object is scalar, i.e., a numeric vector of length 1 ### ### Copyright (C) 2009,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ isScalar <- function (x) { length(x) == 1L && is.vector(x, mode = "numeric") } surveillance/R/knox.R0000644000176200001440000001243314426171115014256 0ustar liggesusers################################################################################ ### Knox test for space-time interaction ### ### Copyright (C) 2015-2016 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ knox <- function (dt, ds, eps.t, eps.s, simulate.p.value = TRUE, B = 999, ...) { stopifnot(length(dt) == length(ds)) if (isSymmetric.matrix(dt) || isSymmetric.matrix(ds)) warning("symmetric input matrix detected; use 'lower.tri'?") ## logical vectors indicating which pairs are close in time and space closeInTime <- if (is.logical(dt)) { dt } else { stopifnot(is.numeric(dt), isScalar(eps.t)) dt <= eps.t } closeInSpace <- if (is.logical(ds)) { ds } else { stopifnot(is.numeric(ds), isScalar(eps.s)) ds <= eps.s } ## manually build the contingency table (table() with factor() is too slow) .lab <- c("close", "not close") knoxtab <- array( tabulate(4L - closeInTime - 2L*closeInSpace, nbins = 4L), dim = c(2L, 2L), dimnames = list( dt = if (is.logical(dt)) .lab else paste(c("<=", " >"), eps.t), ds = if (is.logical(ds)) .lab else paste(c("<=", " >"), eps.s) )) class(knoxtab) <- "table" ## expected number of close pairs in the absence of spatio-temporal interaction npairs <- sum(knoxtab) expected <- sum(knoxtab[1L,]) / npairs * sum(knoxtab[,1L]) ##<- this order of terms avoids integer overflow ## test statistic is the number of spatio-temporally close pairs METHOD <- "Knox test" STATISTIC <- knoxtab[1L] ## determine statistical significance pval_Poisson <- ppois(STATISTIC, expected, lower.tail = FALSE) PVAL <- if (simulate.p.value) { # Monte Carlo permutation approach stopifnot(isScalar(B)) B <- as.integer(B) METHOD <- paste(METHOD, "with simulated p-value") PARAMETER <- setNames(B, "B") permstats <- plapply(X = integer(B), FUN = function (...) sum(closeInSpace & closeInTime[sample.int(npairs)]), ...) structure(mean(c(STATISTIC, permstats, recursive = TRUE) >= STATISTIC), Poisson = pval_Poisson) } else { METHOD <- paste(METHOD, "with Poisson approximation") PARAMETER <- setNames(expected, "lambda") pval_Poisson } ## return test results structure( list(method = METHOD, data.name = paste("dt =", deparse(substitute(dt)), "and ds =", deparse(substitute(ds))), statistic = setNames(STATISTIC, "number of close pairs"), parameter = PARAMETER, p.value = PVAL, alternative = "greater", null.value = setNames(expected, "number"), permstats = if (simulate.p.value) { unlist(permstats, recursive = FALSE, use.names = FALSE) }, table = knoxtab), class = c("knox", "htest") ) } print.knox <- function (x, ...) { ## first print by the default method for class "htest" NextMethod("print") ## then also output the contingency table cat("contingency table:\n") print(x$table) cat("\n") invisible(x) } plot.knox <- function (x, ...) { if (is.null(permstats <- x[["permstats"]])) { stop("this plot-method is for a permutation-based Knox test") } defaultArgs <- list( permstats = permstats, xmarks = setNames(c(x[["null.value"]], x[["statistic"]]), c("expected", "observed")), xlab = "number of close pairs" ) do.call("permtestplot", modifyList(defaultArgs, list(...))) } xtable.knox <- function (x, caption = NULL, label = NULL, align = paste0("r|rr", if (!is.null(sumlabel)) "|r"), digits = 0, display = NULL, ..., sumlabel = "$\\sum$") { tab <- x$table if (!is.null(sumlabel)) { FUN <- setNames(list(sum), sumlabel) tab <- addmargins(tab, FUN = FUN, quiet = TRUE) } xtable(tab, caption = caption, label = label, align = align, digits = digits, display = display, ...) } toLatex.knox <- function (object, dnn = names(dimnames(object$table)), hline.after = NULL, sanitize.text.function = NULL, ...) { xtab <- xtable(object, ...) if (is.null(hline.after)) hline.after <- unique(c(-1,0,2,nrow(xtab))) if (is.null(sanitize.text.function)) sanitize.text.function <- function (x) gsub("<=", "$\\le$", gsub(">", "$>$", x, fixed = TRUE), fixed = TRUE) res <- toLatex.xtable(xtab, hline.after = hline.after, sanitize.text.function = sanitize.text.function, ...) if (is.null(dnn)) { res } else { stopifnot(length(dnn) == 2) headeridx <- grep("&", res, fixed = TRUE)[1L] res[headeridx] <- paste0(dnn[1L], res[headeridx]) res <- append(res, paste0(" & \\multicolumn{2}{|c|}{", dnn[2L], "} & \\\\"), after = headeridx - 1L) class(res) <- "Latex" res } } surveillance/R/isoWeekYear.R0000644000176200001440000000544113430566615015536 0ustar liggesusers###################################################################### # Extract numerical ISO week and year from a Date object # # Details: # This now simply wraps strftime(x, "%V") and strftime(x, "%G"), # supported on Windows since R 3.1.0. Thus, a handmade implementation # of isoWeekYear as in surveillance <= 1.16.2 is no longer necessary. # # Parameters: # Y -- year or a Date/POSIXt object # M -- month (only used if Y is the year) # D -- day (only used if Y is the year) # # Returns: # numeric ISO year and week of the date ###################################################################### isoWeekYear <- function(Y, M, D) { if (!inherits(Y, c("Date", "POSIXt"))) Y <- strptime(paste(Y,M,D,sep="-"),"%Y-%m-%d") Wn <- as.numeric(strftime(Y, "%V")) Yn <- as.numeric(strftime(Y, "%G")) return(list(ISOYear = Yn, ISOWeek = Wn)) } ###################################################################### # An extension of format.Date with additional formatting strings # - "%Q" / "%OQ" for the quarter (1-4 / I-IV) the month belongs to # - "%q" days within quarter # If these formats are not used, base format() is called. # # Params: # x - An object of type Date to be converted. # format - A character string. ###################################################################### #Small helper function - vectorized gsub, but disregarding names of x gsub2 <- function(pattern, replacement, x) { len <- length(x) mapply(FUN = gsub, pattern = rep_len(as.character(pattern), len), replacement = rep_len(as.character(replacement), len), x = x, MoreArgs = list(fixed = TRUE), SIMPLIFY = TRUE, USE.NAMES = FALSE) } formatDate <- function(x, format) { ##Anything to do? if (!grepl("%Q|%OQ|%q", format)) { #nope return(format(x,format)) } ##Replicate string formatStr <- rep_len(format,length(x)) ##If days within quarter requested (this is kind of slow) if (grepl("%q",format)) { ##Loop over vectors of dates dateOfQuarter <- sapply(x, function(date) { ##Month number in quarter modQ <- (as.numeric(format(date,"%m"))-1) %% 3 dateInMonth <- seq(date,length.out=2,by=paste0("-",modQ," month"))[2] ##Move to first of month return(dateInMonth - as.numeric(format(dateInMonth,"%d")) + 1) }) dayInQuarter <- as.numeric(x - dateOfQuarter) + 1 formatStr <- gsub2("%q",as.character(dayInQuarter),formatStr) } if (grepl("%Q|%OQ",format)) { Q <- (as.numeric(format(x,"%m"))-1) %/% 3 + 1 #quarter formatStr <- gsub2("%Q",as.character(Q),formatStr) formatStr <- gsub2("%OQ",as.roman(Q),formatStr) } ##The rest of the formatting - works normally as defined by strptime res <- character(length(x)) for (i in 1:length(x)) res[i] <- format(x[i],formatStr[i]) return(res) } surveillance/R/zzz.R0000644000176200001440000000216314516240231014127 0ustar liggesusers####################################### ### Hook functions for package start-up ####################################### .onLoad <- function (libname, pkgname) { ## initialize options reset.surveillance.options() } .onAttach <- function (libname, pkgname) { VERSION <- packageVersion(pkgname, lib.loc=libname) packageStartupMessage("This is ", pkgname, " ", VERSION, "; ", "see ", sQuote(paste0("package?", pkgname)), " or\n", "https://surveillance.R-Forge.R-project.org/", " for an overview.") if (!interactive()) { # particularly for R CMD check ## skip long examples, unless: allExamples <- nzchar(Sys.getenv("_R_SURVEILLANCE_ALL_EXAMPLES_")) .Options$allExamples$value <- allExamples } } ########################### ### Little helper functions ########################### ### determines multiplicities in a matrix (or data frame) ### and returns unique rows with appended column of counts ### using spatstat's multiplicity methods countunique <- function (x) unique(cbind(x, COUNT = multiplicity(x))) surveillance/R/twinstim_siaf_powerlawL.R0000644000176200001440000001705714615162374020231 0ustar liggesusers################################################################################ ### _L_agged power-law kernel f(s) = (||s||/sigma)^-d for ||s|| >= sigma, else 1 ### Similar to the density of the Pareto distribution (but value 1 for < sigma) ### ### Copyright (C) 2013-2014,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ siaf.powerlawL <- function (nTypes = 1, validpars = NULL, engine = "C") { nTypes <- as.integer(nTypes) stopifnot(length(nTypes) == 1L, nTypes > 0L) engine <- match.arg(engine, c("C", "R")) ## for the moment we don't make this type-specific if (nTypes != 1) stop("type-specific shapes are not yet implemented") ## helper expression, note: logpars=c(logscale=logsigma, logd=logd) tmp <- expression( logsigma <- logpars[[1L]], # used "[[" to drop names logd <- logpars[[2L]], sigma <- exp(logsigma), d <- exp(logd) ) ## spatial kernel f <- function (s, logpars, types = NULL) {} body(f) <- as.call(c(as.name("{"), tmp, expression( sLength <- sqrt(.rowSums(s^2, L <- length(s)/2, 2L)), fvals <- rep.int(1, L), inPLrange <- which(sLength > sigma), fvals[inPLrange] <- (sLength[inPLrange]/sigma)^-d, fvals ))) environment(f) <- baseenv() ## numerically integrate f over a polygonal domain F <- siaf_F_polyCub_iso(intrfr_name = "intrfr.powerlawL", engine = engine) ## fast integration of f over a circular domain Fcircle <- function (r, logpars, type = NULL) {} body(Fcircle) <- as.call(c(as.name("{"), tmp, expression( ## trivial case: radius of integration domain < sigma (=> constant f) if (r <= sigma) return(pi * r^2), ## otherwise, if r > sigma, integration via f^-1 fofr <- (r/sigma)^-d, basevolume <- pi * r^2 * fofr, # cylinder volume up to height f(r) intfinvsq <- sigma^2 * if (d == 2) -d*log(sigma/r) else { d/(d-2) * (1 - (sigma/r)^(d-2)) }, basevolume + pi * intfinvsq ) )) environment(Fcircle) <- baseenv() ## derivative of f wrt logpars ## CAVE: the derivative of f wrt logsigma is mathematically NaN at x=sigma ## this non-differentiability at the threshold causes false convergence ## warnings by nlminb but is otherwise not relevant (could use slow and ## robust Nelder-Mead instead) deriv <- function (s, logpars, types = NULL) {} body(deriv) <- as.call(c(as.name("{"), tmp, expression( sLength <- sqrt(.rowSums(s^2, L <- length(s)/2, 2L)), derivlogsigma <- derivlogd <- numeric(L), inPLrange <- which(sLength > sigma), fPL <- (sLength[inPLrange]/sigma)^-d, derivlogsigma[inPLrange] <- d * fPL, derivlogd[inPLrange] <- fPL * log(fPL), cbind(derivlogsigma, derivlogd) ))) environment(deriv) <- baseenv() ## Numerical integration of 'deriv' over a polygonal domain Deriv <- siaf_Deriv_polyCub_iso( intrfr_names = c("intrfr.powerlawL.dlogsigma", "intrfr.powerlawL.dlogd"), engine = engine) ## simulate from the lagged power law (within a maximum distance 'ub') ##simulate <- siaf.simulatePC(intrfr.powerlawL) # <- generic simulator ##environment(simulate) <- getNamespace("surveillance") ## faster implementation taking advantage of the constant component: simulate <- function (n, logpars, type, ub) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) ## Sampling via polar coordinates and inversion method ## random angle theta <- runif(n, 0, 2*pi) ## sampling radius r ## trivial case u < sigma: p(r) \propto r on [0;u] if (ub < sigma) { r <- ub * sqrt(runif(n)) # inversion sampling ## now rotate each point by a random angle to cover all directions return(r * cbind(cos(theta), sin(theta))) } ## case u >= sigma: p(r) \propto r if r sample component unir <- runif(n) <= mass1 / (mass1 + mass2) ## samples from the uniform short-range component: n1 <- sum(unir) r1 <- sigma * sqrt(runif(n1)) # similar to the case u < sigma ## samples from power-law component: p2(r) \propto r^(-d+1) on [sigma;u] ## For d>2 only, we could use VGAM::rpareto(n,sigma,d-2), d=1 is trivial n2 <- n - n1 r2 <- if (d==1) runif(n2, sigma, ub) else { # inversion sampling P2inv <- if (d == 2) { function (z) ub^z * sigma^(1-z) } else { function (z) (z*ub^(2-d) + (1-z)*sigma^(2-d))^(1/(2-d)) } P2inv(runif(n2)) } ## put samples from both components together r <- c(r1, r2) ## now rotate each point by a random angle to cover all directions r * cbind(cos(theta), sin(theta)) } environment(simulate) <- getNamespace("stats") ## return the kernel specification list(f=f, F=F, Fcircle=Fcircle, deriv=deriv, Deriv=Deriv, simulate=simulate, npars=2L, validpars=validpars) } ## integrate x*f(x) from 0 to R (vectorized) intrfr.powerlawL <- function (R, logpars, types = NULL) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) pl <- which(R > sigma) upper <- R upper[pl] <- sigma res <- upper^2 / 2 # integral over x*constant part xplint <- if (d == 2) log(R[pl]/sigma) else (R[pl]^(2-d)-sigma^(2-d))/(2-d) res[pl] <- res[pl] + sigma^d * xplint res } ## integrate x * (df(x)/dlogsigma) from 0 to R (vectorized) intrfr.powerlawL.dlogsigma <- function (R, logpars, types = NULL) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) pl <- which(R > sigma) res <- numeric(length(R)) xplint <- if (d == 2) log(R[pl]/sigma) else (R[pl]^(2-d)-sigma^(2-d))/(2-d) res[pl] <- d * sigma^d * xplint res } ## local({ # validation via numerical integration -> tests/testthat/test-siafs.R ## p <- function (r, sigma, d) ## r * siaf.powerlawL()$deriv(cbind(r,0), log(c(sigma,d)))[,1L] ## Pnum <- function (r, sigma, d) sapply(r, function (.r) { ## integrate(p, 0, .r, sigma=sigma, d=d, rel.tol=1e-8)$value ## }) ## r <- c(1,2,5,10,20,50,100) ## dev.null <- sapply(c(1,2,1.6), function(d) stopifnot(isTRUE( ## all.equal(intrfr.powerlawL.dlogsigma(r, log(c(3, d))), Pnum(r, 3, d))))) ## }) ## integrate x * (df(x)/dlogd) from 0 to R (vectorized) intrfr.powerlawL.dlogd <- function (R, logpars, types = NULL) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) pl <- which(R > sigma) res <- numeric(length(R)) res[pl] <- if (d == 2) -(sigma*log(R[pl]/sigma))^2 else (sigma^d * R[pl]^(2-d) * (d-2)*d*log(R[pl]/sigma) - d*(sigma^2 - R[pl]^(2-d)*sigma^d)) / (d-2)^2 res } surveillance/R/twinstim_siaf_powerlaw1.R0000644000176200001440000000574614426171115020171 0ustar liggesusers################################################################################ ### 1-parameter power-law kernel f(s) = (1 + ||s||)^-d, i.e., sigma = 1 ### ### Copyright (C) 2019 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ siaf.powerlaw1 <- function (nTypes = 1, validpars = NULL, sigma = 1) { nTypes <- as.integer(nTypes) stopifnot(length(nTypes) == 1L, nTypes > 0L) stopifnot(isScalar(sigma), sigma > 0) SIAF <- siaf.powerlaw(nTypes) # we can reuse some functions from there ## for the moment we don't make this type-specific if (nTypes != 1) stop("type-specific shapes are not yet implemented") ## spatial kernel f <- function (s, logd, types = NULL, sigma = 1) { d <- exp(logd) sLength <- sqrt(.rowSums(s^2, nrow(s), 2L)) (sLength + sigma)^-d } ## set desired sigma as default value formals(f)$sigma <- sigma environment(f) <- baseenv() ## numerically integrate f over a polygonal domain F <- function (polydomain, f, logd, type = NULL, logsigma = 0, ...) { logpars <- c(logsigma, logd) siaf_polyCub_iso(polydomain$bdry, "intrfr.powerlaw", logpars, list(...)) } formals(F)$logsigma <- log(sigma) environment(F) <- getNamespace("surveillance") ## fast integration of f over a circular domain Fcircle <- SIAF$Fcircle # hack original two-parameter version ... body(Fcircle)[2:4] <- NULL names(formals(Fcircle))[2] <- "logd" formals(Fcircle)$sigma <- sigma ## derivative of f wrt logpars deriv <- function (s, logd, types = NULL, sigma = 1) { d <- exp(logd) sLength <- sqrt(.rowSums(s^2, nrow(s), 2L)) tmp <- -d*log(sLength + sigma) matrix(tmp * exp(tmp)) } formals(deriv)$sigma <- sigma environment(deriv) <- baseenv() ## Numerical integration of 'deriv' over a polygonal domain Deriv <- function (polydomain, deriv, logd, type = NULL, logsigma = 0, ...) { logpars <- c(logsigma, logd) siaf_polyCub_iso(polydomain$bdry, "intrfr.powerlaw.dlogd", logpars, list(...)) } formals(Deriv)$logsigma <- log(sigma) environment(Deriv) <- getNamespace("surveillance") ## Simulation function (via polar coordinates) simulate <- SIAF$simulate # hack original two-parameter version ... names(formals(simulate))[2] <- "logd" formals(simulate)$logsigma <- log(sigma) body(simulate) <- as.call( append(as.list(body(simulate)), quote(siafpars <- c(logsigma, logd)), after = 1) ) ## return the kernel specification list(f = f, F = F, Fcircle = Fcircle, deriv = deriv, Deriv = Deriv, simulate = simulate, npars = 1L, validpars = validpars) } surveillance/R/algo_glrnb.R0000644000176200001440000003144114615162374015414 0ustar liggesusers###################################################################### # # Implementation of GLR and ordinary Poisson/NegBin CUSUM # -- documentation converted to Rd format. # # Author: Michael Hoehle (with contributions by Valentin Wimmer) # Date: 8 Jan 2008 # History # - 2016-01-17 added ret="cases" for glr using the NegBin distribution ###################################################################### algo.glrnb <- function(disProgObj, control = list(range=range,c.ARL=5, mu0=NULL, alpha=0, Mtilde=1, M=-1, change="intercept", theta=NULL,dir=c("inc","dec"), ret=c("cases","value"),xMax=1e4)) { #Small helper function either <- function(cond, whenTrue, whenFalse) { if (cond) return(whenTrue) else return(whenFalse) } # Set the default values if not yet set if(is.null(control[["c.ARL",exact=TRUE]])) control$c.ARL <- 5 if(is.null(control[["change",exact=TRUE]])) control$change <- "intercept" if(is.null(control[["Mtilde",exact=TRUE]])) control$Mtilde <- 1 if(is.null(control[["M",exact=TRUE]])) control$M <- -1 if(is.null(control[["dir",exact=TRUE]])) control$dir <- "inc" if(is.null(control[["ret",exact=TRUE]])) control$ret <- "value" if(is.null(control[["xMax",exact=TRUE]])) control$xMax <- 1e4 if(!is.null(control[["theta",exact=TRUE]])) { if(control[["theta",exact=TRUE]] == 1) { stop("Error: theta has to be larger than 1!") } } ##Set alpha to null as default. Not necessary, coz it would be taken from ##glrnb output. ##if(is.null(control[["alpha",exact=TRUE]])) control$alpha <- 0 #GLM (only filled if estimated) m <- NULL ################################################ #Extract the important parts from the arguments ################################################ observed <- disProgObj$observed #range is fixed, but t is modified as we iterate the cusum t <- control$range ; range <- control$range control$mu0Model <- NULL control$dir <- match.arg(control$dir, c("inc","dec")) dir <- ifelse(control$dir=="inc",1,-1) control$ret <- match.arg(control$ret, c("value","cases")) ret <- pmatch(control$ret,c("value","cases")) mod <- list() # Estimate m (the expected number of cases), i.e. parameter lambda of a # poisson distribution based on time points 1:t-1 if (is.null(control[["mu0",exact=TRUE]]) | is.list(control[["mu0",exact=TRUE]])) { #Initialize if (is.null(control[["mu0",exact=TRUE]])) control$mu0 <- list() if (is.null(control[["mu0",exact=TRUE]][["S"]])) control$mu0$S <- 1 if (is.null(control[["mu0",exact=TRUE]][["trend"]])) control$mu0$trend <- FALSE if (is.null(control[["mu0",exact=TRUE]][["refit"]])) control$mu0$refit <- FALSE control$mu0Model <- control$mu0 #Estimate using a hook function (lazy evaluation) control$mu0 <- estimateGLRNbHook()$pred mod[[1]] <- estimateGLRNbHook()$mod # if it is necessary to estimate alpha. Note: glm.nb uses a different # parametrization of the negative binomial distribution, i.e. the # variance is 'mu + mu^2/size' (?dnbinom). # Hence the correct alpha is 1/theta. But now it's the same every time. if(is.null(control[["alpha",exact=TRUE]])) control$alpha <- 1/mod[[1]]$theta } #The counts x <- observed[control$range] mu0 <- control$mu0 #Reserve space for the results # start with cusum[timePoint -1] = 0, i.e. set cusum[1] = 0 alarm <- matrix(data = 0, nrow = length(t), ncol = 1) upperbound <- matrix(data = 0, nrow = length(t), ncol = 1) #Setup counters for the progress doneidx <- 0 N <- 1 xm10 <- 0 noofalarms <- 0 noOfTimePoints <- length(t) #Loop as long as we are not through the sequence while (doneidx < noOfTimePoints) { # cat("Doneidx === ",doneidx,"\n") # Call the C-interface -- this should depend on the type if (control$change == "intercept") { #Generalized likehood ratio vs. ordinary CUSUM if (is.null(control[["theta",exact=TRUE]])) { if (control$alpha == 0) { #poisson if (control$M > 0 ){ # window limited res <- .C(C_glr_cusum_window,as.integer(x),as.double(mu0),length(x),as.integer(control$M),as.integer(control$Mtilde),as.double(control$c.ARL),N=as.integer(0),val=as.double(numeric(length(x))),cases=as.double(numeric(length(x))),as.integer(dir),as.integer(ret)) } else { # standard, not window limited res <- .C(C_glr_cusum,as.integer(x),as.double(mu0),length(x),as.integer(control$Mtilde),as.double(control$c.ARL),N=as.integer(0),val=as.double(numeric(length(x))),cases=as.double(numeric(length(x))),as.integer(dir),as.integer(ret)) } } else { #negbin. This is directly the window limited version, does M=-1 work here? res <- .C(C_glr_nb_window,x=as.integer(x),mu0=as.double(mu0),alpha=as.double(control$alpha),lx=length(x),Mtilde=as.integer(control$Mtilde),M=as.integer(control$M),c.ARL=as.double(control$c.ARL),N=as.integer(0),val=as.double(numeric(length(x))),dir=as.integer(dir)) ##hoehle - 2016-01-17. Try out calculating upper bound in terms of cases if (control$ret == "cases") { ##Warn that this might be slow. message("Return of cases is for the GLR detector based on the negative binomial distribution is currently\n only implemented brute force and hence might be very slow!") ### browser() myx <- x res$cases <- rep(0,length(res$val)) for (pos in seq_len(min(length(x),res$N))) { myx <- x gotAlarm <- (res$N <= pos) #already got an alarm at the position? direction <- ifelse(gotAlarm, -1, 1) #go up or down? alarmChange <- FALSE #have we succeeded in changing x such that the alarm status changed? #Loop over values until one is such that an alarm at (or before!) the time point is given while (!alarmChange & (myx[pos] <= control$xMax) & (myx[pos] >=1)) { myx[pos] <- myx[pos] + direction ##cat("pos=",pos,"x=",myx[pos],"\n") tmpRes <- .C(C_glr_nb_window,x=as.integer(myx),mu0=as.double(mu0),alpha=as.double(control$alpha),lx=length(myx),Mtilde=as.integer(control$Mtilde),M=as.integer(control$M),c.ARL=as.double(control$c.ARL),N=as.integer(0),val=as.double(numeric(length(myx))),dir=as.integer(dir)) if (!gotAlarm & (tmpRes$N <= pos)) { alarmChange <- TRUE ; res$cases[pos] <- myx[pos]} if (gotAlarm & (tmpRes$N > pos)) { alarmChange <- TRUE ; res$cases[pos] <- myx[pos] + 1} } if (!alarmChange) { res$cases[pos] <- ifelse(gotAlarm,NA,1e99) } #didn't find alarm before control$xMax } } ##end new 2016 addition to calculate 'cases' for negbin glrnb } } else { ###################### !is.null(control$theta), i.e. ordinary CUSUM if (control$alpha == 0) { #poisson res <- .C(C_lr_cusum,x=as.integer(x),mu0=as.double(mu0),lx=length(x),as.double(control$theta),c.ARL=as.double(control$c.ARL),N=as.integer(0),val=as.double(numeric(length(x))),cases=as.double(numeric(length(x))),as.integer(ret)) } else { #negbin res <- .C(C_lr_cusum_nb,x=as.integer(x),mu0=as.double(mu0),alpha=as.double(control$alpha),lx=length(x),as.double(control$theta),c.ARL=as.double(control$c.ARL),N=as.integer(0),val=as.double(numeric(length(x))),cases=as.double(numeric(length(x))),as.integer(ret)) } } } else { ################### Epidemic chart ####################### if (control$change == "epi") { if (control$alpha == 0) { #pois res <- .C(C_glr_epi_window,as.integer(x),as.double(mu0),length(x),as.integer(control$Mtilde),as.integer(control$M),as.double(xm10),as.double(control$c.ARL),N=as.integer(0),val=as.double(numeric(length(x)))) } else { res <- .C(C_glr_nbgeneral_window,as.integer(x),as.double(mu0),alpha=as.double(control$alpha),lx=length(x),Mtilde=as.integer(control$Mtilde),M=as.integer(control$M),xm10=as.double(xm10),c.ARL=as.double(control$c.ARL),N=as.integer(0),val=as.double(numeric(length(x))),dir=as.integer(dir)) } } } ##In case an alarm found log this and reset the chart at res$N+1 if (res$N <= length(x)) { #Put appropriate value in upperbound upperbound[1:res$N + doneidx] <- either(ret == 1, res$val[1:res$N] ,res$cases[1:res$N]) alarm[res$N + doneidx] <- TRUE #Chop & get ready for next round xm10 <- x[res$N] #put start value x_0 to last value x <- x[-(1:res$N)] ; t <- t[-(1:res$N)] #If no refitting is to be done things are easy if (!is.list(control$mu0Model) || (control$mu0Model$refit == FALSE)) { mu0 <- mu0[-(1:res$N)] } else { #Update the range (how to change back??) range <- range[-(1:res$N)] mu0 <- estimateGLRNbHook()$pred mod[[noofalarms+2]] <- estimateGLRNbHook()$mod control$mu0[(doneidx + res$N + 1):length(control$mu0)] <- mu0 #Note: No updating of alpha is currently done. } noofalarms <- noofalarms + 1 } doneidx <- doneidx + res$N } #fix of the problem that no upperbound-statistic is returned after #last alarm upperbound[(doneidx-res$N+1):nrow(upperbound)] <- either(ret == 1, res$val, res$cases) #fix of the problem that no upperbound-statistic is returned #in case of no alarm if (noofalarms == 0) { upperbound <- either(ret==1, res$val, res$cases) } # ensure upper bound is positive and not NaN upperbound[is.na(upperbound)] <- 0 upperbound[upperbound < 0] <- 0 # Add name and data name to control object algoName <- either(control$alpha == 0, "glrpois:", "glrnb:") control$name <- paste(algoName, control$change) control$data <- paste(deparse(substitute(disProgObj))) control$m <- m control$mu0Model$fitted <- mod # return alarm and upperbound vectors result <- list(alarm = alarm, upperbound = upperbound, disProgObj=disProgObj,control=control) class(result) = "survRes" # for surveillance system result return(result) } ##################################################################### ### Function to estimate a Poisson or glm.nb model on the fly - to be ### called within the algo.glrnb function. Experts can customize this ### function. ##################################################################### estimateGLRNbHook <- function() { #Fetch control object from parent control <- parent.frame()$control #The period p <- parent.frame()$disProgObj$freq #Current range to perform surveillance on range <- parent.frame()$range #Define phase1 & phase2 data set (phase2= the rest) train <- 1:(range[1]-1) test <- range #Perform an estimation based on all observations before timePoint #Event better - don't do this at all in the algorithm - force #user to do it himself - coz its a model selection problem data <- data.frame(y=parent.frame()$disProgObj$observed[train],t=train) #Build the model equation formula <- "y ~ 1 " if (control$mu0Model$trend) { formula <- paste(formula," + t",sep="") } for (s in seq_len(control$mu0Model$S)) { formula <- paste(formula,"+cos(2*",s,"*pi/p*t)+ sin(2*",s,"*pi/p*t)",sep="") } ##hoehle - 2016-01-16 -- problematic: a full model was fitted, but ##this implied a different alpha. Changed now such that a glm ##is fitted having the specified alpha (i.e. theta) fixed. ##Determine appropriate fitter function if (is.null(control[["alpha",exact=TRUE]])) { ##Fit while also estimating alpha (if possible!) m <- eval(substitute(glm.nb(form,data=data),list(form=as.formula(formula)))) } else { ##Fit the Poisson GLM if (control$alpha == 0) { message(paste0("glrnb: Fitting Poisson model because alpha == 0")) m <- eval(substitute(glm(form,family=poisson(),data=data),list(form=as.formula(formula)))) } else { message(paste0("glrnb: Fitting glm.nb model with alpha=",control$alpha)) m <- eval(substitute(glm(form,family=negative.binomial(theta=1/control$alpha),data=data),list(form=as.formula(formula)))) } } #Predict mu_{0,t} pred <- as.numeric(predict(m,newdata=data.frame(t=range),type="response")) return(list(mod=m,pred=pred)) } ###################################################################### # simple wrapper for the Poisson case ###################################################################### algo.glrpois <- function(disProgObj, control = list(range=range,c.ARL=5, mu0=NULL, Mtilde=1, M=-1, change="intercept", theta=NULL,dir=c("inc","dec"), ret=c("cases","value"),xMax=1e4)) { if (is.null(control$alpha)) { control$alpha <- 0 } else if (control$alpha != 0) { stop("algo.glrpois has to operate with control$alpha = 0") } algo.glrnb(disProgObj, control) } surveillance/R/stsplot_space.R0000644000176200001440000002003014430705133016150 0ustar liggesusers################################################################################ ### Snapshot map (spplot) of an sts-object or matrix of counts ### ### Copyright (C) 2013-2014,2016,2017,2020,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## x: "sts" or (simulated) matrix of counts ## tps: one or more time points. The unit-specific _sum_ of time points "tps" is ## plotted. tps=NULL means cumulation over all time points in x. ## at: number of levels for the grouped counts or specific break points to ## use, or list(n, data, trafo) passed to getPrettyIntervals(), ## where data and trafo are optional. ## CAVE: intervals are closed on the left and open to the right. ## From panel.levelplot: zcol[z >= at[i] & z < at[i + 1]] <- i ## i.e. at=0:1 will have NA (=also white) for counts=1, thus we have to ## ensure max(at) > max(counts) stsplot_space <- function (x, tps = NULL, map = x@map, population = NULL, main = NULL, labels = FALSE, ..., # placed here to support passing 'col' at = 10, col.regions = NULL, colorkey = list(space="bottom", labels=list(at=at)), total.args = NULL, gpar.missing = list(col="darkgrey", lty=2, lwd=2), sp.layout = NULL, ## aspect = mapasp(map), # currently hard-coded xlim = bbox(map)[1, ], ylim = bbox(map)[2, ]) { counts <- if (inherits(x, "sts")) observed(x) else x if (is.null(tps)) tps <- seq_len(nrow(counts)) if (length(map) == 0L) stop("no map") if (is.null(colnames(counts))) stop("need 'colnames(x)' (to be matched against 'row.names(map)')") if (!all(colnames(counts) %in% row.names(map))) stop("incomplete 'map'; ensure that 'all(colnames(x) %in% row.names(map))'") ## compute data to plot ncases <- getCumCounts(counts, tps) total <- sum(ncases) if (!is.null(population)) { # divide counts by region-specific population population <- parse_population_argument(population, x) # pop matrix populationByRegion <- population[tps[1L],] # pop at first time point ncases <- ncases / populationByRegion # (cumulative) incidence by region total <- total / sum(populationByRegion) } ## add ncases to map@data map <- as(map, "SpatialPolygonsDataFrame") map$ncases <- NA_real_ map$ncases[match(colnames(counts),row.names(map))] <- ncases ## default main title if (is.null(main) && inherits(x, "sts")) main <- stsTimeRange2text(x, tps) ## check/determine color break points 'at' at <- checkat(at, ncases, counts = is.null(population)) ## default color palette if (is.null(col.regions)) { separate0 <- is.null(population) && at[1] == 0 && at[2] <= 1 col.regions <- c(if (separate0) "white", .hcl.colors(length(at)-1-separate0)) } ## colorkey settings if (!missing(colorkey) && is.list(colorkey)) colorkey <- modifyList(eval(formals()$colorkey), colorkey) ## automatic additions to sp.layout (region labels and total) if (is.list(gpar.missing) && anyNA(map$ncases)) { layout.missing <- c(list("sp.polygons", obj=map[is.na(map$ncases),]), gpar.missing) sp.layout <- c(sp.layout, list(layout.missing)) } if (!is.null(layout.labels <- layout.labels(map, labels))) { sp.layout <- c(sp.layout, list(layout.labels)) } if (is.list(total.args)) { total.args <- modifyList(list(label="Overall: ", x=1, y=0), total.args) if (is.null(total.args$just)) total.args$just <- with (total.args, if (all(c(x,y) %in% 0:1)) { c(c("left", "right")[1+x], c("bottom","top")[1+y]) } else "center") total.args$label <- paste0(total.args$label, round(total,1)) layout.total <- c(grid::grid.text, total.args) ## "grid.text" wouldn't work since package "sp" doesn't import it sp.layout <- c(sp.layout, list(layout.total)) } ## generate the spplot() args <- list(quote(map[!is.na(map$ncases),]), "ncases", main=main, col.regions=col.regions, at=at, colorkey=colorkey, sp.layout=sp.layout, aspect=mapasp(map), xlim=xlim, ylim=ylim, quote(...)) do.call("spplot", args) } ####################################################### ### Auxiliary functions for the "sts" snapshot function ####################################################### ## sum of counts by unit over time points "tps" ## the resulting vector has no names getCumCounts <- function (counts, tps) { ntps <- length(tps) if (ntps == 1) { counts[tps,] } else { .colSums(counts[tps,,drop=FALSE], ntps, ncol(counts)) } } parse_population_argument <- function (population, x) { if (is.matrix(population)) { if (!identical(dim(population), dim(x))) stop("'dim(population)' does not match the data dimensions") } else if (isScalar(population)) { # a unit, e.g., per 1000 inhabitants if (!inherits(x, "sts")) stop("'", deparse(substitute(x)), "' is no \"sts\" object; ", "population numbers must be supplied") population <- population(x) / population } else { # region-specific population numbers (as in surveillance <= 1.12.2) stopifnot(is.vector(population, mode = "numeric")) if (length(population) != ncol(x)) stop("'length(population)' does not match the number of data columns") population <- rep(population, each = nrow(x)) dim(population) <- dim(x) } population } checkat <- function (at, data, counts = TRUE) { # for non-transformed "data" if (isScalar(at)) at <- list(n=at) if (is.list(at)) { at <- modifyList(list(n=10, data=data, counts=counts), at) do.call("getPrettyIntervals", at) } else { # manual breaks stopifnot(is.vector(at, mode = "numeric"), !anyNA(at)) at <- sort(at) r <- range(data, na.rm = TRUE) c(if (r[1L] < at[1L]) 0, at, if (r[2L] >= at[length(at)]) { ## round up max to 1 significant digit (including 0.1 to 0.2) .decs <- 10^floor(log10(r[2L])) ceiling(r[2L]/.decs + sqrt(.Machine$double.eps))*.decs }) } } getPrettyIntervals <- function (n, data, trafo=NULL, counts=TRUE, ...) { maxcount <- max(data, na.rm=TRUE) if (counts && maxcount < n) { # no aggregation of counts necessary at <- 0:ceiling(maxcount+sqrt(.Machine$double.eps)) # max(at) > maxcount } else { at <- if (is.null(trafo)) { # equivalent to trafo=scales::sqrt_trans() pretty(sqrt(data), n=n+1, ...)^2 } else { scales::trans_breaks(trafo$trans, trafo$inv, n=n+1, ...)(data) } ## { # alternative: quantile-based scale (esp. for incidence plots) ## quantile(data, probs=seq(0,1,length.out=n+1), na.rm=TRUE) ## } if (counts && at[1] == 0 && at[2] > 1) # we want 0 counts separately ("white") at <- sort(c(1, at)) if (at[length(at)] == maxcount) # ensure max(at) > max(data) at[length(at)] <- at[length(at)] + if (counts) 1 else 0.001*diff(range(at)) } at } stsTime2text <- function (stsObj, tps=TRUE, fmt=NULL) { if (is.null(fmt)) fmt <- switch(as.character(stsObj@freq), "1" = "%i", "52" = "%i-W%02i", "%i/%i") sprintf(fmt, year(stsObj)[tps], epochInYear(stsObj)[tps]) } stsTimeRange2text <- function (stsObj, tps, fmt=NULL, sep=" to ") { tpsRangeYW <- stsTime2text(stsObj, tps=range(tps), fmt=fmt) paste0(unique(tpsRangeYW), collapse=sep) } surveillance/R/twinstim_siaf_student.R0000644000176200001440000000745114426171115017731 0ustar liggesusers################################################################################ ### Student (t) kernel f(s) = (||s||^2+sigma^2)^-d ### This is a reparametrization of the t-kernel; For d=1, this is the kernel of ### the Cauchy density with scale sigma; in Geostatistics, a correlation ### function of this kind is known as the Cauchy model. ### ### Copyright (C) 2013-2014,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ siaf.student <- function (nTypes = 1, validpars = NULL, engine = "C") { nTypes <- as.integer(nTypes) stopifnot(length(nTypes) == 1L, nTypes > 0L) engine <- match.arg(engine, c("C", "R")) ## for the moment we don't make this type-specific if (nTypes != 1) stop("type-specific shapes are not yet implemented") ## helper expression, note: logpars=c(logscale=logsigma, logd=logd) tmp <- expression( logsigma <- logpars[[1L]], # used "[[" to drop names logd <- logpars[[2L]], sigma <- exp(logsigma), d <- exp(logd) ) ## spatial kernel f <- function (s, logpars, types = NULL) {} body(f) <- as.call(c(as.name("{"), tmp, expression(s2 <- .rowSums(s^2, nrow(s), 2L)), expression((s2+sigma^2)^-d) )) environment(f) <- baseenv() ## numerically integrate f over a polygonal domain F <- siaf_F_polyCub_iso(intrfr_name = "intrfr.student", engine = engine) ## fast integration of f over a circular domain ## is not relevant for this heavy-tail kernel since we don't use ## 'effRange', and usually eps.s=Inf ##Fcircle <- function (r, logpars, type = NULL) {} ## derivative of f wrt logpars deriv <- f body(deriv)[[length(body(deriv))]] <- # assignment for return value of f substitute(fvals <- x, list(x=body(deriv)[[length(body(deriv))]])) body(deriv) <- as.call(c(as.list(body(deriv)), expression( derivlogsigma <- -2*d*sigma^2 * fvals / (s2+sigma^2), derivlogd <- log(fvals) * fvals, cbind(derivlogsigma, derivlogd, deparse.level = 0) ))) environment(deriv) <- baseenv() ## Numerical integration of 'deriv' over a polygonal domain Deriv <- siaf_Deriv_polyCub_iso( intrfr_names = c("intrfr.student.dlogsigma", "intrfr.student.dlogd"), engine = engine) ## simulation from the kernel (via polar coordinates) simulate <- siaf.simulatePC(intrfr.student) environment(simulate) <- getNamespace("surveillance") ## return the kernel specification list(f=f, F=F, deriv=deriv, Deriv=Deriv, simulate=simulate, npars=2L, validpars=validpars) } ## integrate x*f(x) from 0 to R (vectorized) intrfr.student <- function (R, logpars, types = NULL) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) if (d == 1) { log(R^2+sigma^2) / 2 - log(sigma) } else { ( (R^2+sigma^2)^(-d+1) - (sigma^2)^(-d+1) ) / (2-2*d) } } ## integrate x * (df(x)/dlogsigma) from 0 to R (vectorized) intrfr.student.dlogsigma <- function (R, logpars, types = NULL) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) sigma^2 * ( (R^2+sigma^2)^-d - sigma^(-2*d) ) } ## integrate x * (df(x)/dlogd) from 0 to R (vectorized) intrfr.student.dlogd <- function (R, logpars, types = NULL) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) if (d == 1) { log(sigma)^2 - log(R^2+sigma^2)^2 / 4 } else { # thanks to Maple 17 primitive <- function (x) { x2ps2 <- x^2 + sigma^2 (d*(d-1)*log(x2ps2) + d) / (2*(d-1)^2 * (x2ps2)^(d-1)) } primitive(R) - primitive(0) } } surveillance/R/algo_twins.R0000644000176200001440000002123614326704036015451 0ustar liggesusers###################################################################### # Experimental version -- integrating the twins program into # the surveillance package ###################################################################### algo.twins <- function(disProgObj, control= list(burnin=1000, filter=10, sampleSize=2500, noOfHarmonics=1, alpha_xi=10, beta_xi=10, psiRWSigma=0.25, alpha_psi=1, beta_psi=0.1, nu_trend=FALSE, logFile="twins.log")) { if (inherits(disProgObj, "sts")) disProgObj <- sts2disProg(disProgObj) if (ncol(disProgObj$observed)>1) { stop("algo.twins() only handles univariate time series of counts") } ## Determine period from data T <- as.integer(disProgObj$freq) ## set default values (if not provided in control) if(is.null(control[["burnin",exact=TRUE]])) control$burnin <- 1000 if(is.null(control[["filter",exact=TRUE]])) control$filter <- 10 if(is.null(control[["sampleSize",exact=TRUE]])) control$sampleSize <- 2500 if(is.null(control[["alpha_xi",exact=TRUE]])) control$alpha_xi <- 10 if(is.null(control[["beta_xi",exact=TRUE]])) control$beta_xi <- 10 if(is.null(control[["psiRWSigma",exact=TRUE]])) control$psiRWSigma <- 0.25 if(is.null(control[["alpha_psi",exact=TRUE]])) control$alpha_psi <- 1 if(is.null(control[["beta_psi",exact=TRUE]])) control$beta_psi <- 0.1 if(is.null(control[["nu_trend",exact=TRUE]])) control$nu_trend <- FALSE if(is.null(control[["logFile",exact=TRUE]])) control$logFile <- "twins.log" if(is.null(control[["noOfHarmonics",exact=TRUE]])) control$noOfHarmonics <- 1 nfreq <- control$noOfHarmonics control$logFile2 <- paste(control$logFile,"2",sep="") ## Call the C code x <- disProgObj$observed n <- as.integer(dim(x)[1]) I <- as.integer(dim(x)[2]) with(control, .C(C_twins, x=as.integer(x), n=n, I=I, logFile=logFile, logFile2=logFile2, burnin=as.integer(burnin), filter=as.integer(filter), sampleSize=as.integer(sampleSize), alpha_xi=as.double(alpha_xi), beta_xi=as.double(beta_xi), T=as.integer(T), nfreq=as.integer(nfreq), psiRWSigma=as.double(0.25), alpha_psi=as.double(alpha_psi), beta_psi=as.double(beta_psi), nu_trend=as.integer(nu_trend))) ## Log files results <- read.table(control$logFile,header=T,na.strings=c("NaN","-NaN")) results2 <- read.table(control$logFile2,header=T,na.strings=c("NaN","-NaN")) ## and currently not returned: ## acc <- read.table(paste(control$logFile,".acc",sep=""),col.names=c("name","RWSigma","acc")) ## rownames(acc) <- acc[,1] ## acc <- acc[,-1] ## result is not a standard survObj result <- structure(list(control=control, disProgObj=disProgObj, logFile=results, logFile2=results2), class="atwins") return(result) } ###################################################################### # Adapted the functions form figures.R ###################################################################### ## Helper functions to make list of Z and the means of X,Y and omega make.pois <- function(obj) { n <- nrow(obj$disProgObj$observed) m<-list() m$n <- n m$Z <- obj$disProgObj$observed m$X <- numeric(n) m$Y <- numeric(n) m$omega <- numeric(n) ## Read means at each time instance Vars <- c("X","Y","omega") for (t in 1:n) { for (v in Vars) { m[[v]][t] <- obj$logFile2[,paste(v,".",t,".",sep="")] } } return(m) } pois.plot <- function(m.results,...) { plotorder <- c(expression(Z),expression(Y),expression(X)) plotcols <- c(1,"red","blue") lwd <- c(1,3,3) sts <- disProg2sts(m.results$disProgObj) ## Make default legend if nothing else is specified. if (!"legend.opts" %in% names(list(...))) { plot(sts,legend.opts=list(x="topleft",legend=paste(plotorder),lwd=lwd,col=plotcols,horiz=TRUE,y.intersp=0,lty=1,pch=NA),...) } else { plot(sts,...) } ## Add Y and X lines for (i in 2:length(plotorder)) { lines(1:(m.results$n)+0.5,m.results[[paste(plotorder[i])]][c(2:m.results$n,m.results$n)],type="s",col=plotcols[i],lwd=lwd[i]) } } ## makes list of gamma, zeta and nu make.nu <- function(obj) { n <- nrow(obj$disProgObj$observed) samplesize <- obj$control$sampleSize frequencies <- obj$control$noOfHarmonics # instead of just always "1" ! season <- obj$disProgObj$freq basefrequency <- 2 * pi / season ## optionally also get the linear time trend coefficient withTrend <- obj$control$nu_trend ## this list will be returned at the end m<-list() ## first get all the gamma's from the logFile matrix into nicer elements of ## the list m for (j in 0:(2*frequencies + withTrend)) { m$gamma[[j+1]] <- numeric(samplesize) m[["gamma"]][[j+1]] <- obj$logFile[,paste("gamma",".",j,".",sep="")] } ## zeta is a list which has one element for each time point (vector of samples) m$zeta<-list() ## for all time points: for (t in 1:n) { ## start with the intercept m$zeta[[t]]<-m$gamma[[1]] ## add all harmonic terms for(j in 1:frequencies){ m$zeta[[t]] <- m$zeta[[t]] + m$gamma[[2*j]]*sin(basefrequency*j*(t-1)) + m$gamma[[2*j+1]]*cos(basefrequency*j*(t-1)) } ## and (optionally) finally add the linear trend if(withTrend) { m$zeta[[t]] <- m$zeta[[t]] + m$gamma[[2*frequencies + 2]] * (t - n/2) } } ## nu is the analogous list with the exponentiated zeta's m$nu<-list() for (t in 1:n) { m$nu[[t]]<-exp(m$zeta[[t]]) } ## also copy the number of harmonics m$frequencies <- frequencies ## and return return(m) } ## Function to plot median, and quantiles over time for m.par (m.par is list of n vectors, x is time) tms.plot <-function(x,m.par,xlab="",ylab="",ylim=NULL,...){ m<-list() n<-length(m.par) m$median<-numeric(n) for (t in 1:n) { m$median[t]<- median(m.par[[t]]) m$q025[t]<- quantile(m.par[[t]],0.025) m$q975[t]<- quantile(m.par[[t]],0.975) } if(is.null(ylim)){ ymin<-min(m$q025) ymax<-max(m$q975) ylim=c(ymin,ymax) } plot(x-1,m$q975[x],type="l",col="red",main="",xlab=xlab,ylab=ylab,ylim=ylim,...) lines(x-1,m$median[x],type="l") lines(x-1,m$q025[x],type="l",col="red") } ###################################################################### # Function to plot an atwins object -- currently not # properly documented ###################################################################### plot.atwins <- function(x, which=c(1,4,6,7), ask=TRUE,...) { ## Make list of X,Y,Z,omega means of results2 m.results <-make.pois(x) m.results$disProgObj <- x$disProgObj ## Make list of results of gamma, zeta and nu nu<-make.nu(x) ## Plots show <- rep(FALSE,7) show[which] <- TRUE opar <- par(ask=ask && sum(show) > 1, "mfcol") on.exit(par(opar)) if (show[1]) { par(mfcol=c(1,1)) pois.plot(m.results,...) } if (show[2]) { ## make room for 2 * (frequencies + 1) panels par(mfcol=c(2,nu$frequencies+1)) ## and plot all gamma coefficients (possibly including the linear time ## trend coef) for(j in seq_along(nu$gamma)) { plot(nu$gamma[[j]],type="l",ylab=paste("gamma",j - 1,sep="")) } } if (show[3]) { par(mfcol=c(1,1)) plot(x$logFile$K,type="l",ylab=expression(K)) plot(x$logFile$xilambda,type="l",ylab=expression(xi)) plot(x$logFile$psi,type="l",ylab=expression(psi)) } if (show[4]) { par(mfcol=c(1,2)) acf(x$logFile$K,lag.max = 500,main="",xlab=expression(K)) acf(x$logFile$psi,lag.max = 500,main="",xlab=expression(psi)) } if (show[5]) { par(mfcol=c(1,1)) tms.plot(2:m.results$n,nu$nu,xlab="time") } if (show[6]) { par(mfcol=c(1,2)) hist(x$logFile$K,main="",xlab=expression(K),probability=TRUE,breaks=seq(-0.5,max(x$logFile$K)+0.5,1)) hist(x$logFile$psi,main="",xlab=expression(psi),probability=TRUE,nclass=50) } if (show[7]) { par(mfcol=c(1,1)) hist(x$logFile$Znp1,main="",xlab=expression(Z[n+1]),probability=TRUE,breaks=seq(-0.5,max(x$logFile$Znp1)+0.5,1)) } invisible() } surveillance/R/hhh4_W_powerlaw.R0000644000176200001440000001272714426171115016346 0ustar liggesusers################################################################################ ### Parametric power-law specification for neighbourhood weights in hhh4() ### ### Copyright (C) 2012-2016,2018 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### Construct weight matrix wji according to the Zeta-distribution with respect ### to the orders of neighbourhood (in nbmat, as e.g. obtained from nbOrder()), ### optionally fulfilling rowSums(wji) = 1 ## As a formula (for j != i, otherwise wji = 0): ## wji = pzeta(oji; d, maxlag) / sum_k pzeta(ojk; d, maxlag) ## Here, oji = oij is the order of nb of i and j, ## and pzeta(o; d, m) = o^-d / sum_{r=1}^m r^-d is the Zeta-distribution ## on 1:m (also called Zipf's law). ## Special cases: maxlag >= max(nbmat) yields the weights ## wji = oji^-d / sum_k ojk^-d ## and maxlag=1 yields the classical weights wji=1/nj. zetaweights <- function (nbmat, d = 1, maxlag = max(nbmat), normalize = FALSE) { ## raw (non-normalized) zeta-distribution on 1:maxlag zeta <- c(0, seq_len(maxlag)^-d) # first 0 is for lag 0 (i.e., diag(nbmat)) ## replace order by zetaweight of that order wji <- zeta[nbmat + 1L] # results in vector wji[is.na(wji)] <- 0 # for lags > maxlag ## set dim and names dim(wji) <- dim(nbmat) dimnames(wji) <- dimnames(nbmat) if (normalize) normalizeW(wji) else wji } ### powerlaw weights ## in the non-truncated case, i.e. maxlag = max(nbmat), ## the raw powerlaw weights are defined as w_ji = o_ji^-d, o_ji >= 1 ## and with (row-)normalization we have w_ji = o_ji^-d / sum_k o_jk^-d ## from0 = TRUE results in a power-law for o_ji >= 0: w(o) = (o + 1)^-d W_powerlaw <- function (maxlag, normalize = TRUE, log = FALSE, initial = if (log) 0 else 1, from0 = FALSE) { if (missing(maxlag)) { stop("'maxlag' must be specified (e.g. maximum neighbourhood order)") ## specifying 'maxlag' in zetaweights is actually optional since it has ## the default value max(nbmat). however, repeatedly asking for this ## maximum would be really inefficient. } else { stopifnot(isScalar(maxlag), maxlag >= 2 - from0) if (from0) maxlag <- maxlag + 1L } stopifnot(isScalar(initial)) ## main function which returns the weight matrix weights.call <- call("zetaweights", if (from0) quote(nbmat + 1L) else quote(nbmat), quote(d), maxlag, normalize) weights <- as.function(c(alist(d=, nbmat=, ...=), call("{", weights.call)), envir=getNamespace("surveillance")) if (log) { # the parameter d is interpreted on log-scale ## we prepend the necessary conversion d <- exp(d) body(weights) <- as.call(append(as.list(body(weights)), quote(d <- exp(d)), after=1)) } ## construct derivatives with respect to "d" (or log(d), respectively) dweights <- d2weights <- as.function(c(alist(d=, nbmat=, ...=), quote({})), envir=getNamespace("surveillance")) weights.call[[5L]] <- FALSE # normalize separately header <- c( if (log) quote(d <- exp(d)), # such that d is again on original scale substitute(Wraw <- weights.call, list(weights.call=weights.call)), if (normalize) expression( nUnits <- nrow(Wraw), norm <- .rowSums(Wraw, nUnits, nUnits) ), expression( # Wraw == 0 means o = 0 (diagonal) or o > maxlag => deriv = 0 is.na(Wraw) <- Wraw == 0, # set to NA since we will take the log logo <- -log(Wraw)/d # = log(nbmat) with NA's at Wraw == 0 ), if (normalize) quote(W <- Wraw / norm) else quote(W <- Wraw) ) footer <- expression(deriv[is.na(deriv)] <- 0, deriv) ## first derivative tmp1 <- expression( ## in surveillance < 1.9-0, 'norm' and 'tmpnorm' were based on 'nbmat', ## which is incorrect for the truncated case maxlag < max(nbmat) tmpnorm <- .rowSums(Wraw * -logo, nUnits, nUnits, na.rm=TRUE) / norm, tmp1 <- logo + tmpnorm ) deriv1 <- if (normalize) { expression(deriv <- W * -tmp1) } else expression(deriv <- W * -logo) body(dweights) <- as.call(c(as.name("{"), header, if (normalize) tmp1, deriv1, if (log) expression(deriv <- deriv * d), # this is the non-log d footer )) ## second derivative body(d2weights) <- as.call(c(as.name("{"), header, if (normalize) { c(tmp1, expression( tmp2 <- .rowSums(Wraw * logo^2, nUnits, nUnits, na.rm=TRUE) / norm - tmpnorm^2, deriv <- W * (tmp1^2 - tmp2) )) } else expression(deriv <- W * logo^2), if (log) c( do.call("substitute", list(deriv1[[1L]], list(deriv=as.name("deriv1")))), expression(deriv <- deriv * d^2 + deriv1 * d) # this is the non-log d ), footer )) ## return list of functions list(w=weights, dw=dweights, d2w=d2weights, initial=initial) } surveillance/R/stsNC.R0000644000176200001440000002456014615162374014344 0ustar liggesusers###################################################################### # initialize-method for "stsNC" objects ###################################################################### init.stsNC <- function(.Object, ..., reportingTriangle, predPMF, pi, truth, delayCDF, SR) { .Object <- callNextMethod() # use initialize,sts-method ## initialize defaults for extra stsNC-slots or check supplied values dimObserved <- dim(.Object@observed) if (missing(pi)) { .Object@pi <- array(NA_integer_, dim = c(dimObserved, 2L)) } else { dimPI <- dim(.Object@pi) if (length(dimPI) != 3 || any(dimPI != c(dimObserved, 2L))) stop("dim(pi) = (", paste0(dimPI, collapse=","), ")") } if (missing(SR)) { .Object@SR <- array(NA_real_, dim = c(nrow(.Object@observed),0L,0L)) } else { stopifnot(length(dim(.Object@SR)) == 3) } if (missing(truth)) .Object@truth <- as(.Object, "sts") return(.Object) } setMethod("initialize", "stsNC", init.stsNC) ###################################################################### # Special coerce method to account for consistent dimensions ###################################################################### setAs(from = "sts", to = "stsNC", function (from) { new("stsNC", from, pi = array(NA_real_, dim = c(dim(from@observed), 2L)), truth = from, SR = array(NA_real_, dim = c(nrow(from@observed), 0L, 0L))) }) ###################################################################### # plot-method for the "stsNC" class, which starts by # using the inherited method, but with some additional plotting # put into the .hookFunSpecial function. # # Parameters: # same as the for the plot method of sts objects. ###################################################################### setMethod(f="plot", signature=signature(x="stsNC", y="missing"), function (x, type = observed ~ time | unit, ...) { ## if special type "delay" (only applies for stsNC objects) if (type == "delay") { stsNC_plotDelay(x, ...) return(invisible()) } ## environment of hook function will be set to evaluation ## environment of stsplot_time1() and only then be called legend.opts <- lty <- lwd <- "accommodate tools:::.check_code_usage_in_package()" #Hook function specifically for nowcasting objects. nowcastPlotHook <- function() { #Define some colors for the plotting as well as some plot symbols color <- surveillance.options("colors") pchList <- c(nowSymbol=10) #Prolong line of last observation (this should go into the plot function idx <- nrow(x) - which.max(!is.na(rev(upperbound(x)))) + 1 #Continue line from plot - use same style as stsplot_time1 lines( idx+c(-0.5,0.5), rep(upperbound(x)[idx,],2),col=col[3],lwd=lwd[3],lty=lty[3]) #Add the prediction intervals as bars (where not NA). Conf level #is found in x@control$alpha idxt <- which(apply(x@pi[1:nrow(x),1,],1,function(x) all(!is.na(x)))) for (i in idxt) { lines( i+c(-0.3,0.3), rep(x@pi[i,,1],2),lty=1,col=color["piBars"]) lines( i+c(-0.3,0.3), rep(x@pi[i,,2],2),lty=1,col=color["piBars"]) lines( rep(i,each=2), x@pi[i,,],lty=2,col=color["piBars"]) } #Extract now date and date range of the plotting startDate <- epoch(x)[1] #Add "now" symbol on x-axis. Plotting now takes possible temporal aggregation into account. #points(x@control$now-startDate+1,0,pch=pchList["nowSymbol"],col=color["nowSymbol"],cex=1.5) points(x@control$timeDelay(startDate,x@control$now)+1,0,pch=pchList["nowSymbol"],col=color["nowSymbol"],cex=1.5) #Add this to the legend if (!is.null(legend.opts)) { legend(x="topright",c("Now"),pch=pchList["nowSymbol"],col=color["nowSymbol"],bg="white") } return(invisible()) } callNextMethod(x=x, type=type, ..., .hookFuncInheritance=nowcastPlotHook) }) ###################################### ## For plotting the delay distribution ###################################### ###################################################################### # Find a quantile of a discrete random variable with support on # 0,...,D and which has a PMF given by the vector prob. We # define the q quantile as \min_{x} F(x) \geq q. # # Parameters: # prob - vector on 0,..,D containing the PMF # q - quantile to compute ###################################################################### pmfQuantile <- function(prob,q=0.5) { which.max(cumsum(prob) >= q)-1 } ###################################################################### ## Show empirical and, if available, model based median of delay ## distribution as a function of occurrence time t. ## ## Parameters: ## nc - nowcast object ## rT.truth - reporting triangle as it would be at the end. Typically ## this is taken directly from the nc object. ## dates - vector of dates where to show the result ## w - half-width of moving window ## modelQuantiles - which model quantiles to show ###################################################################### stsNC_plotDelay <- function(nc, rT.truth=NULL, dates=NULL, w=1, modelQuantiles=0.5, epochUnit=NULL) { ##Extract reporting triangle from the nc object if (is.null(rT.truth)) { rT.truth <- reportingTriangle(nc) } ##Which dates to plot if (is.null(dates)) { dates <- epoch(nc) } ##Determine the appropriate unit of the delay if (is.null(epochUnit)) { epochUnit <- switch( as.character(nc@freq), "12" = "months", "%m" = "months", "52" = "weeks", "%V"="weeks", "%j"="days", "365" = "days") } ##Determine max delay from reporting triangle. D <- nc@control$D res <- matrix(NA, nrow=length(dates), ncol=D+1) ##which data variables are actually in rT.truth isThere <- !is.na(sapply(dates, function(date) pmatch(as.character(date),rownames(rT.truth)))) idx <- which(isThere) ##Loop over all time points. for (i in (w+min(idx)):(max(idx)-w)) { now <- dates[i] the_idx <- pmatch(as.character(now),rownames(rT.truth)) subset <- rT.truth[the_idx + c(-w:w),,drop=FALSE] res[i,] <- colSums(subset,na.rm=TRUE) / sum(subset,na.rm=TRUE) } ##A slightly modified function to determine quantiles, which can ##handle NAs (if there is no case at all) quantile <- function(q) { apply(res, 1, function(x) { if (all(is.na(x))) return(NA) else return(which.max(cumsum(x) >= q) - 1) }) } ##Find 10%, 50% and 90% quantiles quants <- sapply(c(0.1,0.5,0.9), quantile) ##Make a plot (use plot.Dates instead of matplot) plot(dates, quants[,2],xlab="Time of occurrence",ylab=paste0("Delay (",epochUnit,")"),ylim=c(0,15),col=1,lty=c(1),lwd=4,type="n") idxFirstTruncObs <- which(dates == (nc@control$now - D)) idxNow <- which(dates == nc@control$now) polygon( dates[c(idxFirstTruncObs,idxFirstTruncObs,idxNow,idxNow)], c(-1e99,1e99,1e99,-1e99), col=rgb(0.95,0.95,0.95),lwd=0.001) text( dates[round(mean(c(idxNow,idxFirstTruncObs)))], D, "right truncated\n observations",adj=c(0.5,0.5)) lines(dates, quants[,2],col=1,lty=c(1),lwd=4) matlines(dates, quants[,c(1,3)],type="l",col=1,lty=c(2,3),lwd=c(1,1)) legend_str <- c(expression(q[0.1](T)),expression(q[0.5](T)),expression(q[0.9](T))) legend_lty <- c(2,1,3) legend_col <- c(1,1,1) legend_lwd <- c(1,4,1) ##Which dates have been analysed in the nowcasts dates2show <- attr(reportingTriangle(nc),"t02s") ##Loop over all model based estimates model_CDF <- delayCDF(nc) if (length(model_CDF) > 0) { for (methodIdx in seq_len(length(model_CDF))) { ##browser() ##Fetch CDF from model (can be a vector or a matrix) theCDF <- delayCDF(nc)[[names(model_CDF)[methodIdx]]] if (!is.matrix(theCDF)) { theCDF <- matrix(theCDF, ncol=length(theCDF),nrow=length(dates2show),byrow=TRUE) } cdf <- cbind(0,theCDF) pmf <- t(apply(cdf,1,diff)) ##Determine model quantiles quants.model <- matrix(NA, nrow=length(dates2show),ncol=length(modelQuantiles),dimnames=list(as.character(dates2show),modelQuantiles)) for (t in 1:length(dates2show)) { quants.model[t,] <- sapply(modelQuantiles, function(q) pmfQuantile( pmf[t,],q=q)) } ##Make sure the NAs in the beginning agree i <- 1 while (all(is.na(quants[i,]))) {quants.model[i,] <- NA ; i <- i + 1} legend_str <- c(legend_str,substitute(q[0.5]^methodName(T),list(methodName=names(model_CDF)[methodIdx]))) legend_lty <- c(legend_lty,3+methodIdx) legend_col <- c(legend_col,"gray") legend_lwd <- c(legend_lwd,2) ##only estimates up to 'now' are to be shown and which are within ##the moving window of m time points show <- (nc@control$now - dates2show <= nc@control$m) matlines(dates2show[show], quants.model[show,], col=tail(legend_col,n=1),lwd=ifelse(modelQuantiles==0.5,tail(legend_lwd,n=1),1),lty=ifelse(modelQuantiles==0.5,tail(legend_lty,n=1),2)) } ##Show lines for breakpoints (if available from the model) if ("bayes.trunc.ddcp" %in% names(model_CDF)) { ddcp.model <- attr(model_CDF[["bayes.trunc.ddcp"]], "model") changePoints <- as.Date(colnames(ddcp.model$W)) ## hoehle: changed, if ddcp.model contains weekend effects, these give NA dates. changePoints <- changePoints[!is.na(changePoints)] for (i in 1:length(changePoints)) { axis(1,at=changePoints[i], changePoints[i], las=1, cex.axis=0.7,line=-2.5) lines( rep(changePoints[i],2),c(0,1e99),lty=2) } } } ##Make a legend ##c(expression(q[0.1](T)),expression(q[0.5](T)),expression(q[0.9](T)),expression(q[0.5]^"ddcp"(T))) legend(x="bottomleft",legend_str,lty=legend_lty,col=legend_col,lwd=legend_lwd) ##Add title if (!is.null(nc)) { title(nc@control$now) } ##Done invisible() } surveillance/R/twinSIR_profile.R0000644000176200001440000002367514615162374016377 0ustar liggesusers################################################################################ ### profile-method for class "twinSIR" to calculate the profile log-likelihood ### (normalized) as well as profile likelihood based confidence intervals ### ### Copyright (C) 2009 Michael Hoehle, 2014 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ###################################################################### # Function to compute likelihood based confidence interval, basically # the two solutions to # f(\theta) = l(\theta)-l(\hat{theta)) + 1/2 dchisq(1-alpha,df=1)=0 # are found. # # # Parameters: # logliktilde - normalized likelihood function(theta, ...) # theta.hat - the MLE # lower - search interval [lower,theta.hat] for f=0 # upper - search interval [theta.hat,upper] for f=0 # alpha - confidence level (see Equation 2.6 in Pawitan (2003) # ... - additional arguments passed to function logliktilde ###################################################################### likelihood.ci <- function (logliktilde, theta.hat, lower, upper, alpha = 0.05, ...) { # Highest Likelihood interval -- target function f <- function(theta, ...) { logliktilde(theta, ...) + 1/2*qchisq(1-alpha, df=1) } # Compute upper and lower boundary numerically hl.lower <- uniroot(f, interval = c(lower, theta.hat), ...)$root hl.upper <- uniroot(f, interval = c(theta.hat, upper), ...)$root return(c(hl.lower,hl.upper)) } ###################################################################### # Function to compute estimated and profile likelihood based # confidence intervals. Heavy computations might be necessary! # #Params: # fitted - output from a fit with twinSIR # profile - list with 4D vector as entries - format: # c(index, lower, upper, grid size) # where index is the index in the coef vector # lower and upper are the parameter limits (can be NA) # grid size is the grid size of the equally spaced grid # between lower and upper (can be 0) # alpha - (1-alpha)% profile likelihood CIs are computed. # If alpha <= 0 then no CIs are computed # control - control object to use for optim in the profile loglik computations # # Returns: # list with profile loglikelihood evaluations on the grid # and highest likelihood and wald confidence intervals ###################################################################### profile.twinSIR <- function (fitted, profile, alpha = 0.05, control = list(fnscale = -1, factr = 1e1, maxit = 100), ...) { ## Check that input is ok profile <- as.list(profile) if (length(profile) == 0L) { stop("nothing to do") } lapply(profile, function(one) { if (length(one) != 4L) { stop("each profile entry has to be of form ", "'c(index, lower, upper, grid size)'") }}) if (is.null(fitted[["model"]])) { stop("'fitted' must contain the model component") } px <- ncol(fitted$model$X) pz <- ncol(fitted$model$Z) ## Control of the optim procedure if (is.null(control[["fnscale",exact=TRUE]])) { control$fnscale <- -1 } if (is.null(control[["factr",exact=TRUE]])) { control$factr <- 1e1 } if (is.null(control[["maxit",exact=TRUE]])) { control$maxit <- 100 } ## Estimated normalized likelihood function ltildeestim <- function(thetai,i) { theta <- theta.ml theta[i] <- thetai with(fitted$model, .loglik(theta, X=X, Z=Z, survs=survs, weights=weights)) - loglik.theta.ml } ## Profile normalized likelihood function ltildeprofile <- function(thetai,i) { emptyTheta <- rep(0, length(theta.ml)) # Likelihood l(theta_{-i}) = l(theta_i, theta_i) ltildethetaminusi <- function(thetaminusi) { theta <- emptyTheta theta[-i] <- thetaminusi theta[i] <- thetai with(fitted$model, .loglik(theta, X=X, Z=Z, survs=survs, weights=weights)) - loglik.theta.ml } # Score function of all params except thetaminusi stildethetaminusi <- function(thetaminusi) { theta <- emptyTheta theta[-i] <- thetaminusi theta[i] <- thetai with(fitted$model, .score(theta, X=X, Z=Z, survs=survs, weights=weights))[-i] } # Call optim using L-BFGS-B. For harder constrains we need constr.Optim lower <- if (fitted$method == "L-BFGS-B") { c(rep(0,px),rep(-Inf,pz))[-i] } else { -Inf } upper <- if (fitted$method == "L-BFGS-B") { c(rep(Inf,px),rep(Inf,pz))[-i] } else { Inf } resOthers <- tryCatch(with(fitted$model, optim(theta.ml[-i], fn = ltildethetaminusi, gr = stildethetaminusi, method = fitted$method, control = control, lower = lower, upper = upper)), warning = function(w) print(w), error = function(e) list(value=NA)) resOthers$value } ## Initialize theta.ml <- coef(fitted) loglik.theta.ml <- c(logLik(fitted)) se <- sqrt(diag(vcov(fitted))) resProfile <- list() ## Perform profile computations for all requested parameters cat("Evaluating the profile log-likelihood on a grid ...\n") for (i in 1:length(profile)) { cat("i= ",i,"/",length(profile),"\n") #Index of the parameter in the theta vector idx <- profile[[i]][1] #If no borders are given use those from wald intervals (unconstrained) if (is.na(profile[[i]][2])) profile[[i]][2] <- theta.ml[idx] - 3*se[idx] if (is.na(profile[[i]][3])) profile[[i]][3] <- theta.ml[idx] + 3*se[idx] #Evaluate profile loglik on a grid (if requested) if (profile[[i]][4] > 0) { thetai.grid <- seq(profile[[i]][2],profile[[i]][3],length.out=profile[[i]][4]) resProfile[[i]] <- matrix(NA, nrow = length(thetai.grid), ncol = 4L, dimnames = list(NULL, c("grid","profile","estimated","wald"))) for (j in 1:length(thetai.grid)) { cat("\tj= ",j,"/",length(thetai.grid),"\n") resProfile[[i]][j,] <- c(thetai.grid[j], ltildeprofile(thetai.grid[j],idx), ltildeestim(thetai.grid[j],idx), #9 June 2009: Bug discovered by L. Held. as part of paper revision. C.f. Pawitan p.63 - 1/2*(1/se[idx]^2)*(thetai.grid[j] - theta.ml[idx])^2) } } } #9 June 2009. This did not work. # names(resProfile) <- names(theta.ml)[sapply(profile, function(x) x[4L]) > 0] names(resProfile) <- names(theta.ml)[sapply(profile, function(x) x[1L])] ## Profile likelihood intervals ciProfile <- matrix(NA, nrow = length(profile), ncol = 6L, dimnames = list(NULL, c("idx","hl.low","hl.up","wald.low","wald.up","mle"))) ciProfile[,"idx"] <- sapply(profile, "[", 1L) ciProfile[,"mle"] <- theta.ml[ciProfile[,"idx"]] rownames(ciProfile) <- names(theta.ml)[ciProfile[,"idx"]] if (alpha > 0) { cat("Computing profile likelihood-based confidence intervals ...\n") lower <- if (fitted$method == "L-BFGS-B") { c(rep(0,px),rep(-Inf,pz)) } else { -Inf } for (i in seq_along(profile)) { cat(i,"/", length(profile),"\n") #Index of the parameter in the theta vector idx <- profile[[i]][1] #Compute highest likelihood intervals ci.hl <- tryCatch( likelihood.ci(ltildeprofile, theta.hat = theta.ml[idx], lower = max(lower[idx], theta.ml[idx]-5*se[idx]), upper = theta.ml[idx]+5*se[idx], alpha = alpha, i = idx), warning = function(w) print(w), error = function(e) rep(NA,2)) #Wald intervals based on expected fisher information ci.wald <- theta.ml[idx] + c(-1,1) * qnorm(1-alpha/2) * se[idx] ciProfile[i,2:5] <- c(ci.hl, ci.wald) } } res <- list(lp=resProfile, ci.hl=ciProfile, profileObj=profile) class(res) <- "profile.twinSIR" return(res) } ###################################################################### ## Plot the result of the profiler ## Parameters: ## x - the result of calling profile() on a "twinSIR" object ## which - names of selected parameters, NULL meaning all available ## conf.level - level for the horizontal line for -qchisq(,df=1)/2 ## legend - logical indicating whether to add a legend to the plot, ## or numeric vector of indexes of plots where to add the legend ###################################################################### plot.profile.twinSIR <- function(x, which = NULL, conf.level = 0.95, xlab = which, ylab = "normalized log-likelihood", legend = TRUE, par.settings = list(), ...) { ## extract relevant components of 'x' lp <- x$lp[!vapply(X=x$lp, FUN=is.null, FUN.VALUE=FALSE, USE.NAMES=FALSE)] mle <- x$ci.hl[,"mle"] ## check arguments which <- if (is.null(which)) { names(lp) } else { match.arg(which, names(lp), several.ok = TRUE) } xlab <- rep_len(xlab, length(which)) if (is.logical(legend)) legend <- which(legend) if (is.list(par.settings)) { par.defaults <- list(mfrow = sort(n2mfrow(length(which))), mar = c(5,5,1,1)+.1, las = 1) par.settings <- modifyList(par.defaults, par.settings) opar <- do.call("par", par.settings) on.exit(par(opar)) } ## loop over parameters for (i in seq_along(which)) { coefname <- which[i] matplot(lp[[coefname]][,1L], lp[[coefname]][,-1L], type = "l", col = 1:3, lty = 1:3, xlab = xlab[i], ylab = ylab) if (i %in% legend) { legend(x = "bottomright", legend = c("profile","estimated","Wald"), col = 1:3, lty = 1:3) } ## some lines which help interpretation segments(x0=mle[coefname], y0=par("usr")[3L], y1=0, lty=2, col="darkgray") abline(h=-1/2*qchisq(conf.level, df=1), lty=2, col="darkgray") } } surveillance/R/epidata_plot.R0000644000176200001440000001552014426171115015744 0ustar liggesusers################################################################################ ### The plot-method for "epidata" (via plot.summary.epidata) shows the evolution ### of the numbers of susceptible, infectious and recovered individuals. ### The extra function "stateplot" shows the event history of one individual. ### ### Copyright (C) 2008-2009, 2013-2014 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ plot.epidata <- function(x, ...) { sx <- summary(x) plot.summary.epidata(sx, ...) } plot.summary.epidata <- function (x, lty = c(2,1,3), lwd = 2, col = c("#1B9E77", "#D95F02", "#7570B3"), col.hor = col, col.vert = col, xlab = "Time", ylab = "Number of individuals", xlim = NULL, ylim = NULL, legend.opts = list(), do.axis4 = NULL, panel.first = grid(), rug.opts = list(), which.rug = c("infections", "removals", "susceptibility", "all"), ...) { counters <- x[["counters"]] type <- x[["type"]] n <- counters[1L,"nSusceptible"] m <- counters[1L,"nInfectious"] N <- n + m times <- counters[-1L,"time"] if (missing(lty)) { lty <- c(2, 1, 3 * (type %in% c("SIR","SIRS"))) } recycle3 <- function (xnam) assign(xnam, rep(get(xnam), length.out = 3), inherits = TRUE) for(varname in c("lty", "lwd", "col", "col.hor", "col.vert")) recycle3(varname) if (is.null(xlim)) { xlim <- attr(x, "timeRange") if (xlim[2] == Inf) xlim[2] <- times[length(times)] } if (is.null(ylim)) ylim <- c(0, max( (lty[1] > 0) * {if (type %in% c("SIRS", "SIS")) N else n}, (lty[2] > 0) * max(counters$nInfectious), (lty[3] > 0) * max(counters$nRemoved) )) # basic plotting frame plot(xlim, ylim, type = "n", xlab = xlab, ylab = ylab, panel.first = panel.first, ...) abline(h = c(0, N), col = "grey") # for real xlim in lines.stepfun (see 'dr' adjustment in plot.stepfun code) fakexlim <- c(1,2) * (xlim[2] + 2*xlim[1])/3 - c(0,xlim[1]) # this isn't nice, a user argument 'dr' in plot.stepfun would be appreciated # add #Susceptibles if (all(counters$nSusceptible == n)) { lines(x = xlim, y = c(n,n), lty = lty[1], lwd = lwd[1], col = col.hor[1], ...) } else { lines(stepfun(times, counters$nSusceptible), xlim = fakexlim, lty = lty[1], lwd = lwd[1], col.hor = col.hor[1], col.vert = col.vert[1], do.points = FALSE, ...) } # add #Infected if (all(counters$nInfectious == m)) { lines(x = xlim, y = c(m,m), lty = lty[2], lwd = lwd[2], col = col.hor[2], ...) } else { lines(stepfun(times, counters$nInfectious), xlim = fakexlim, lty = lty[2], lwd = lwd[2], col.hor = col.hor[2], col.vert = col.vert[2], do.points = FALSE, ...) } # add #Removed if (all(counters$nRemoved == 0)) { lines(x = xlim, y = c(0,0), lty = lty[3], lwd = lwd[3], col = col.hor[3], ...) } else { lines(stepfun(times, counters$nRemoved), xlim = fakexlim, lty = lty[3], lwd = lwd[3], col.hor = col.hor[3], col.vert = col.vert[3], do.points = FALSE, ...) } # add special annotations if (is.null(do.axis4)) do.axis4 <- type == "SIR" if (do.axis4) { finalvalues <- counters[nrow(counters), c("nSusceptible", "nRemoved")] axis(4, at = finalvalues[lty[c(1,3)] > 0], font = 2, ...) } if (is.list(rug.opts)) { if (is.null(rug.opts$ticksize)) rug.opts$ticksize <- 0.02 if (is.null(rug.opts$quiet)) rug.opts$quiet <- TRUE which.rug <- match.arg(which.rug) if (is.null(rug.opts$col)) rug.opts$col <- switch(which.rug, all = 1, infections = col.hor[2], removals = col.hor[3], susceptibility = col.hor[1]) rugLocations <- switch(which.rug, all = times, infections = attr(x, "eventTimes"), removals = counters$time[counters$type == "R"], susceptibility = counters$time[counters$type == "S"] ) if (length(rugLocations) > 0) { do.call(rug, c(list(x = rugLocations), rug.opts)) } } if (is.list(legend.opts)) { legend.opts <- modifyList( list(x = "topright", bty = "n", inset = c(0,0.02), legend = c("susceptible", "infectious", "removed")[lty>0], lty = lty[lty>0], lwd = lwd[lty>0], col = col.hor[lty>0]), legend.opts) do.call(legend, legend.opts) } invisible(as.matrix( counters[c("time", "nSusceptible", "nInfectious", "nRemoved")] )) } ################################################################################ # PLOT THE STATE CHANGES OF ONE INDIVIDUAL OF "epidata" # ... will be passed to the plot function (stepfun or curve), # e.g. add, xlim, ylim, main, xlab, ylab, ... ################################################################################ stateplot <- function(x, id, ...) { sx <- getSummary(x, class = "epidata") .id <- as.character(id) if (length(.id) != 1) { stop ("'id' must have length 1") } initiallyInfected <- sx[["initiallyInfected"]] if (! .id %in% levels(initiallyInfected)) { stop ("invalid 'id', does not exist in 'x'") } isInitiallyInfected <- .id %in% initiallyInfected counters <- sx[["counters"]] states <- levels(counters[["type"]]) path <- counters[which(counters$id == .id), c("time", "type")] # remove pseudo-R-events, which come before S-event directSevents <- which(duplicated(path[["time"]])) path_noPseudoR <- if (length(directSevents)) { path[-(directSevents-1), ] } else { path } pathfunc <- if (nrow(path_noPseudoR) > 0) { stepfun( x = path_noPseudoR[["time"]], y = c(1+isInitiallyInfected, unclass(path_noPseudoR[["type"]])), right = FALSE ) } else { function(t) rep(1+isInitiallyInfected, length(t)) } # plot it dotargs <- list(...) nms <- names(dotargs) if(! "xlab" %in% nms) dotargs$xlab <- "time" if(! "ylab" %in% nms) dotargs$ylab <- "state" if(! "main" %in% nms) dotargs$main <- "" if(! "xlim" %in% nms) dotargs$xlim <- attr(sx, "timeRange") if(! "xaxs" %in% nms) dotargs$xaxs <- "i" if(! "do.points" %in% nms && inherits(pathfunc, "stepfun")) { dotargs$do.points <- FALSE } do.call("plot", args = c(list(x = pathfunc, yaxt = "n"), dotargs)) axis(2, at = seq_along(states), labels = states) invisible(pathfunc) } surveillance/R/twinstim_tiaf_exponential.R0000644000176200001440000000506014426171115020564 0ustar liggesusers################################################################################ ### Exponential temporal interaction function g(t) = exp(-alpha*t) ### ### Copyright (C) 2009-2014,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## nTypes: determines the number of parameters of the Exponential kernel. ## In a multitype epidemic, the different types may share ## the same temporal interaction function (type-invariant), in which case ## nTypes=1. Otherwise nTypes should equal the number of event types of the ## epidemic, in which case every type has its own alpha. tiaf.exponential <- function (nTypes = 1, validpars = NULL) { nTypes <- as.integer(nTypes) stopifnot(length(nTypes) == 1L, nTypes > 0L) ## function definitions for nTypes = 1 (length(alpha) == 1) g <- function (t, alpha, types) { exp(-alpha*t) } G <- function (t, alpha, types) { if (alpha==0) t else -exp(-alpha*t)/alpha } deriv <- function (t, alpha, types) { as.matrix( -t*exp(-alpha*t) ) } Deriv <- function (t, alpha, types) { as.matrix( if (alpha==0) -t^2/2 else (t+1/alpha)*exp(-alpha*t)/alpha ) } ## adaptions for nTypes > 1 if (nTypes > 1) { ## time points vector t, length(types) = length(t) body(g) <- as.call(append(as.list(body(g)), quote(alpha <- alpha[types]), after=1)) body(G) <- quote({ alpha <- alpha[types] ifelse (alpha==0, t, -exp(-alpha*t)/alpha) }) body(deriv) <- quote({ L <- length(t) deriv <- matrix(0, L, length(alpha)) alpha <- alpha[types] deriv[cbind(1:L,types)] <- -t*exp(-alpha*t) deriv }) body(Deriv) <- quote({ L <- length(t) Deriv <- matrix(0, L, length(alpha)) alpha <- alpha[types] Deriv[cbind(1:L,types)] <- ifelse(alpha==0, -t^2/2, (t+1/alpha)*exp(-alpha*t)/alpha) Deriv }) } ## functions only need the base environment environment(g) <- environment(G) <- environment(deriv) <- environment(Deriv) <- baseenv() ## return the kernel specification list(g=g, G=G, deriv=deriv, Deriv=Deriv, npars=nTypes, validpars=validpars) } surveillance/R/hcl.colors.R0000644000176200001440000000205314024100031015321 0ustar liggesusers################################################################################ ### Generate a color palette via the colorspace package ### ### Copyright (C) 2007 Michael Hoehle, 2012-2014,2017,2019,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ .hcl.colors <- function (ncolors=100, use.color=TRUE) { GYR <- if (requireNamespace("colorspace", quietly=TRUE)) { ## the Zeil-ice colors colorspace::heat_hcl(ncolors, h=c(0,120), c.=if (use.color) c(90,30) else c(0,0), l=c(50,90), power=c(0.75, 1.2)) } else if (use.color) { grDevices::hcl.colors(n = ncolors, palette = "Heat 2") ## this is the same as colorspace::heat_hcl(ncolors) } else { grey.colors(ncolors) } return(rev(GYR)) } surveillance/R/twinstim_siaf_polyCub_iso.R0000644000176200001440000001022414013521730020514 0ustar liggesusers################################################################################ ### C-Level Cubature of "siaf" over Polygonal Domains using 'polyCub_iso' ### ### Copyright (C) 2017,2020,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### construct a call using either .polyCub.iso or its C-version .call.polyCub.iso <- function (intrfr_name, engine = "C") { if (engine == "C") { call("siaf_polyCub_iso", quote(polydomain$bdry), intrfr_name, quote(siafpars), quote(list(...))) } else { call(".polyCub.iso", quote(polydomain$bdry), as.name(intrfr_name), quote(siafpars), center = c(0,0), control = quote(list(...))) } } ## construct siaf$F function siaf_F_polyCub_iso <- function (intrfr_name, engine = "C") { F <- function (polydomain, f, siafpars, type, ...) {} body(F) <- .call.polyCub.iso(intrfr_name, engine) environment(F) <- getNamespace("surveillance") return(F) } ## construct siaf$Deriv function siaf_Deriv_polyCub_iso <- function (intrfr_names, engine = "C") { Deriv <- function (polydomain, deriv, siafpars, type, ...) {} res_names <- paste0("res", seq_along(intrfr_names)) calls <- mapply( FUN = function (intrfr_name, res_name) call("<-", as.name(res_name), .call.polyCub.iso(intrfr_name, engine)), intrfr_name = intrfr_names, res_name = res_names, SIMPLIFY = FALSE, USE.NAMES = FALSE ) result <- as.call(c(as.name("c"), lapply(res_names, as.name))) body(Deriv) <- as.call(c(as.name("{"), calls, result)) environment(Deriv) <- getNamespace("surveillance") return(Deriv) } ## 'polys' is a list of polygons in the form of owin$bdry ## 'intrfr_name' identifies the function used in the integrand ## 'pars' is a vector of parameters for "intrfr" siaf_polyCub_iso <- function (polys, intrfr_name, pars, control = list()) { ## default control arguments for polyCub_iso / Rdqags ## similar to args(stats::integrate) control <- modifyList( list(subdivisions = 100L, rel.tol = .Machine$double.eps^0.25, stop.on.error = TRUE), control) if (is.null(control[["abs.tol"]])) control$abs.tol <- control$rel.tol ## integrate over each polygon ints <- lapply(X = polys, FUN = siaf_polyCub1_iso, intrfr_code = INTRFR_CODE[intrfr_name], pars = pars, subdivisions = control$subdivisions, rel.tol = control$rel.tol, abs.tol = control$abs.tol, stop.on.error = control$stop.on.error) sum(unlist(ints, recursive = FALSE, use.names = FALSE)) } ## 'xypoly' is a list(x, y) of vertex coordinates (open) siaf_polyCub1_iso <- function (xypoly, intrfr_code, pars, subdivisions = 100L, rel.tol = .Machine$double.eps^0.25, abs.tol = rel.tol, stop.on.error = TRUE) { if (length(xypoly[["y"]]) != (L <- length(xypoly[["x"]]))) stop("xypoly$x and xypoly$y must have equal length") .C(C_siaf_polyCub1_iso, as.double(xypoly$x), as.double(xypoly$y), as.integer(L), as.integer(intrfr_code), as.double(pars), as.integer(subdivisions), as.double(abs.tol), as.double(rel.tol), as.integer(stop.on.error), value = double(1L), abserr = double(1L), neval = integer(1L) )$value } ## integer codes are used to select the corresponding C-routine, ## see ../src/twinstim_siaf_polyCub_iso.c INTRFR_CODE <- c( "intrfr.powerlaw" = 10L, "intrfr.powerlaw.dlogsigma" = 11L, "intrfr.powerlaw.dlogd" = 12L, "intrfr.student" = 20L, "intrfr.student.dlogsigma" = 21L, "intrfr.student.dlogd" = 22L, "intrfr.powerlawL" = 30L, "intrfr.powerlawL.dlogsigma" = 31L, "intrfr.powerlawL.dlogd" = 32L, "intrfr.gaussian" = 40L, "intrfr.gaussian.dlogsigma" = 41L, "intrfr.exponential" = 50L, "intrfr.exponential.dlogsigma" = 51L ) surveillance/R/hhh4_W_np.R0000644000176200001440000001562314426171115015121 0ustar liggesusers################################################################################ ### Non-parametric specification of neighbourhood weights in hhh4() ### ### Copyright (C) 2014,2018 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### non-parametric estimation of weight function, i.e., provide each ### neighbourhood order (including 0 if from0=TRUE) up to 'maxlag' with its ### own (unconstrained) weight. For identifiability: ### - lowest order is fixed to weight=1 ### - usually maxlag < max(nborder) (since only few pairs with highest orders), ### and 'truncate' indicates if there should be zero weight for orders above ### 'maxlag' (default), or the same as for order 'maxlag' ### Thus, if from0, the parameters refer to lags 1:maxlag, otherwise 2:maxlag W_np <- function (maxlag, truncate = TRUE, normalize = TRUE, initial = log(zetaweights(2:(maxlag+from0))), from0 = FALSE, to0 = truncate) # 'to0' has been renamed to 'truncate' { if (missing(maxlag)) { stop("'maxlag' must be specified (usually < max. neighbourhood order)") } else { stopifnot(isScalar(maxlag), maxlag >= 2 - from0) # at least one parameter } stopifnot(is.vector(initial, mode = "numeric"), length(initial) == maxlag + from0 - 1) if (!missing(to0)) { .Deprecated(msg = "argument 'to0' has been renamed; use 'truncate'") truncate <- to0 } ## auxiliary expression used in 'dw' and 'd2w' below indicatormatrixExpr <- if (truncate) { quote(nbmat==nbOrder) } else { if (from0) { # maxlag = npars quote(if(nbOrder==npars) nbmat>=nbOrder else nbmat==nbOrder) } else { # maxlag = 1 + npars quote(if(nbOrder==1L+npars) nbmat>=nbOrder else nbmat==nbOrder) } } ## weights as a function of parameters and a matrix of neighbourhood orders w <- function (logweights, nbmat, ...) {} body(w) <- substitute( { weights <- exp(logweights) # values for orders (2-from0):maxlag npars <- length(weights) W <- .WEIGHTS[1L+nbmat] # substituted depending on 'from0' ## repeat last coefficient for higher orders without separate estimate W[is.na(W)] <- .HOWEIGHT # substituted depending on 'truncate' dim(W) <- dimW <- dim(nbmat) # nUnits x nUnits dimnames(W) <- dimnames(nbmat) .RETVAL # substituted depending on 'normalize' }, list( .WEIGHTS = if (from0) quote(c(1, weights)) else quote(c(0, 1, weights)), .HOWEIGHT = if (truncate) 0 else quote(weights[npars]), .RETVAL = if (normalize) quote(W / (norm <- .rowSums(W, dimW[1L], dimW[2L]))) else quote(W) )) ## version of w with assignment of its return value (for use in normalized ## versions of dw and d2w) .w <- w body(.w)[[length(body(.w))]] <- substitute(Wnorm <- x, list(x=body(.w)[[length(body(.w))]])) ## derivative of w(logweights) -> a list of matrices (one for each param.) if (normalize) { dw <- .w ## append code to calculate first derivatives body(dw) <- as.call(c(as.list(body(dw)), eval(substitute( expression( FUN <- function (nbOrder, weight) { ind <- .INDICATORMATRIX (ind - Wnorm*.rowSums(ind,dimW[1L],dimW[2L])) * weight/norm }, mapply(FUN, .LAGS, weights, SIMPLIFY=FALSE, USE.NAMES=FALSE) ), list(.INDICATORMATRIX = indicatormatrixExpr, .LAGS = if (from0) quote(seq_len(npars)) else quote(1L + seq_len(npars))) )))) } else { dw <- function (logweights, nbmat, ...) {} body(dw) <- substitute( { weights <- exp(logweights) npars <- length(weights) FUN <- function (nbOrder, weight) weight * (.INDICATORMATRIX) mapply(FUN, .LAGS, weights, SIMPLIFY=FALSE, USE.NAMES=FALSE) }, list(.INDICATORMATRIX = indicatormatrixExpr, .LAGS = if (from0) quote(seq_len(npars)) else quote(1L + seq_len(npars)))) } ## result of d2w must be a list of matrices of length npars*(npars+1L)/2L if (normalize) { d2w <- .w body(d2w) <- as.call(c(as.list(body(d2w)), eval(substitute( expression( seqnpars <- seq_len(npars), inds <- lapply(.LAGS, function (nbOrder) { ind <- .INDICATORMATRIX indrs <- .rowSums(ind, dimW[1L], dimW[2L]) list(indterm = ind - Wnorm * indrs, indrs = indrs) }), k <- rep.int(seqnpars, npars), # row index l <- rep.int(seqnpars, rep.int(npars,npars)), # column index ##<- 12x faster than expand.grid(seqnpars,seqnpars) lowertri <- k >= l, ##<- and 2.5x faster than ##kl <- which(lower.tri(matrix(,npars,npars), diag=TRUE), arr.ind=TRUE) norm2 <- norm^2, mapply(function (k, l) weights[k] / norm2 * if (k==l) { inds[[k]][[1L]] * (norm - 2*weights[k]*inds[[k]][[2L]]) } else { -weights[l] * (inds[[k]][[1L]] * inds[[l]][[2L]] + inds[[l]][[1L]] * inds[[k]][[2L]]) }, k[lowertri], l[lowertri], # inds[k[lowertri]], inds[l[lowertri]], SIMPLIFY=FALSE, USE.NAMES=FALSE) ), list(.INDICATORMATRIX = indicatormatrixExpr, .LAGS = if (from0) quote(seqnpars) else quote(1L + seqnpars)) )))) } else { # for k=k', second derivative = first derivative, otherwise 0 d2w <- dw if (length(initial) > 1) { ## add assignment for the return value of dw body(d2w)[[length(body(d2w))]] <- substitute(dW <- x, list(x=body(d2w)[[length(body(d2w))]])) ## append code to generate the list of second derivatives body(d2w) <- as.call(c(as.list(body(d2w)), expression( d2wlength <- (npars^2+npars)/2, ## indices of diagonal elements in x[lower.tri(x,diag=TRUE)] d2wdiag <- c(1L,1L+cumsum(seq.int(npars,2L))), d2wlist <- rep.int(list(0*nbmat), d2wlength), d2wlist[d2wdiag] <- dW, d2wlist ))) } } ## Done environment(w) <- environment(dw) <- environment(d2w) <- .GlobalEnv list(w = w, dw = dw, d2w = d2w, initial = initial) } surveillance/R/twinstim.R0000644000176200001440000016715114615162374015174 0ustar liggesusers################################################################################ ### Maximum Likelihood inference for the two-component spatio-temporal intensity ### model described in Meyer et al (2012), DOI: 10.1111/j.1541-0420.2011.01684.x ### ### Copyright (C) 2009-2019,2024 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## model.frame() evaluates 'subset' and '...' with 'data' utils::globalVariables(c("tile", "type", "BLOCK", ".obsInfLength", ".bdist", "area")) twinstim <- function ( endemic, epidemic, siaf, tiaf, qmatrix = data$qmatrix, data, subset, t0 = data$stgrid$start[1], T = tail(data$stgrid$stop,1), na.action = na.fail, start = NULL, partial = FALSE, epilink = "log", control.siaf = list(F=list(), Deriv=list()), optim.args = list(), finetune = FALSE, model = FALSE, cumCIF = FALSE, cumCIF.pb = interactive(), cores = 1, verbose = TRUE ) { #################### ### Preparations ### #################### ptm <- proc.time() cl <- match.call() partial <- as.logical(partial) finetune <- if (partial) FALSE else as.logical(finetune) ## (inverse) link function for the epidemic linear predictor of event marks epilink <- match.arg(epilink, choices = c("log", "identity")) epilinkinv <- switch(epilink, "log" = exp, "identity" = identity) ## Clean the model environment when exiting the function if (model) on.exit(suppressWarnings(rm(cl, cumCIF, cumCIF.pb, data, doHessian, eventsData, finetune, neghess, fisherinfo, fit, fixed, functions, globalEndemicIntercept, inmfe, initpars, ll, negll, loglik, msgConvergence, msgNotConverged, mfe, mfhEvents, mfhGrid, model, my.na.action, na.action, namesOptimUser, namesOptimArgs, nlminbControl, nlminbRes, nlmObjective, nlmControl, nlmRes, nmRes, optim.args, optimArgs, control.siaf, optimMethod, optimRes, optimRes1, optimValid, origenv.endemic, origenv.epidemic, partial, partialloglik, ptm, qmatrix, res, negsc, score, start, subset, tmpexpr, typeSpecificEndemicIntercept, useScore, verbose, whichfixed, inherits = FALSE))) ## also set fixed[st]iafpars to FALSE (for free posteriori evaluations, and ## to be defined for score function evaluation with optim.args=NULL) on.exit(fixedsiafpars <- fixedtiafpars <- FALSE, add = TRUE) ### Verify that 'data' inherits from "epidataCS" if (!inherits(data, "epidataCS")) { stop("'data' must inherit from class \"epidataCS\"") } ### Check time range if (!isScalar(t0) || !isScalar(T)) { stop("endpoints 't0' and 'T' must be single numbers") } if (T <= t0) { stop("'T' must be greater than 't0'") } if (!t0 %in% data$stgrid$start) { justBeforet0 <- match(TRUE, data$stgrid$start > t0) - 1L # if 't0' is beyond the time range covered by 'data$stgrid' if (is.na(justBeforet0)) justBeforet0 <- length(data$stgrid$start) # t0 was too big if (justBeforet0 == 0L) justBeforet0 <- 1L # t0 was too small t0 <- data$stgrid$start[justBeforet0] warning("replaced 't0' by the value ", t0, " (must be a 'start' time of 'data$stgrid')") } if (!T %in% data$stgrid$stop) { justAfterT <- match(TRUE, data$stgrid$stop > T) # if 'T' is beyond the time range covered by 'data$stgrid' if (is.na(justAfterT)) justAfterT <- length(data$stgrid$stop) # T was too big T <- data$stgrid$stop[justAfterT] warning("replaced 'T' by the value ", T, " (must be a 'stop' time of 'data$stgrid')") } ### Subset events eventsData <- if (missing(subset)) data$events@data else { do.call("subset.data.frame", args = list( x = quote(data$events@data), subset = cl$subset, drop = FALSE )) } ############################################################# ### Build up a model.frame for both components separately ### ############################################################# ########################## ### epidemic component ### ########################## ### Parse epidemic formula if (missing(epidemic)) { origenv.epidemic <- parent.frame() epidemic <- ~ 0 } else { origenv.epidemic <- environment(epidemic) environment(epidemic) <- environment() ## such that t0 and T are found in the subset expression below } epidemic <- terms(epidemic, data = eventsData, keep.order = TRUE) if (!is.null(attr(epidemic, "offset"))) { warning("offsets are not implemented for the 'epidemic' component") } ### Generate model frame # na.action mod such that for simulated epidataCS, where events of the # prehistory have missing 'BLOCK' indexes, those NA's do not matter. # ok because actually, 'eventBlocks' are only used in the partial likelihood # and there only eventBlocks[includes] is used (i.e. no prehistory events) my.na.action <- function (object, ...) { prehistevents <- row.names(object)[object[["(time)"]] <= t0] if (length(prehistevents) == 0L) return(na.action(object, ...)) origprehistblocks <- object[prehistevents, "(BLOCK)"] # all NA object[prehistevents, "(BLOCK)"] <- 0L # temporary set non-NA xx <- na.action(object, ...) xx[match(prehistevents,row.names(xx),nomatch=0L), "(BLOCK)"] <- origprehistblocks[prehistevents %in% row.names(xx)] xx } mfe <- model.frame(epidemic, data = eventsData, subset = time + eps.t > t0 & time <= T, # here we can have some additional rows (individuals) compared to mfhEvents, which is established below! # Namely those with time in (t0-eps.t; t0], i.e. still infective individuals, which are part of the prehistory of the process na.action = my.na.action, # since R 2.10.0 patched also works with epidemic = ~1 and na.action=na.fail (see PR#14066) drop.unused.levels = FALSE, time = time, tile = tile, type = type, eps.t = eps.t, eps.s = eps.s, BLOCK = BLOCK, obsInfLength = .obsInfLength, bdist = .bdist) ### Extract essential information from model frame # 'inmfe' indexes rows of data$events@data and is necessary for subsetting # influenceRegion (list incompatible with model.frame) and coordinates. # Note: model.frame() takes row.names from data inmfe <- which(row.names(data$events@data) %in% row.names(mfe)) N <- length(inmfe) # mfe also contains events of the prehistory eventTimes <- mfe[["(time)"]] # I don't use model.extract since it returns named vectors # Indicate events after t0, which are actually part of the process # (events in (-Inf;t0] only contribute in sum over infected individuals) includes <- which(eventTimes > t0) # this indexes mfe! Nin <- length(includes) if (Nin == 0L) { stop("none of the ", nrow(data$events@data), " supplied ", "events is in the model (check 'subset', 't0' and 'T')") } eventBlocks <- mfe[["(BLOCK)"]] # only necessary for partial log-likelihood eventTypes <- factor(mfe[["(type)"]]) # drop unused levels typeNames <- levels(eventTypes) nTypes <- length(typeNames) if (verbose && nTypes > 1L) cat("marked point pattern of", nTypes, "types\n") qmatrix <- checkQ(qmatrix, typeNames) # we only need the integer codes for the calculations eventTypes <- as.integer(eventTypes) # coords are needed for intensityplot(), so even for endemic-only models eventCoords <- coordinates(data$events)[inmfe,,drop=FALSE] ### Generate model matrix mme <- model.matrix(epidemic, mfe) xlevels_epidemic <- .getXlevels(epidemic, mfe) q <- ncol(mme) hase <- q > 0L ### Extract further model components (only if q > 0) if (hase) { eps.t <- mfe[["(eps.t)"]] removalTimes <- eventTimes + eps.t eps.s <- mfe[["(eps.s)"]] bdist <- mfe[["(bdist)"]] gIntUpper <- mfe[["(obsInfLength)"]] gIntLower <- pmax(0, t0-eventTimes) influenceRegion <- data$events@data$.influenceRegion[inmfe] iRareas <- vapply(X = influenceRegion, FUN = attr, which = "area", FUN.VALUE = 0, USE.NAMES = FALSE) eventSources <- if (N == nobs(data) && identical(qmatrix, data$qmatrix)) { data$events@data$.sources } else { # re-determine because subsetting has invalidated row indexes if (verbose) cat("updating list of potential sources ...\n") determineSources(eventTimes = eventTimes, eps.t = eps.t, eventCoords = eventCoords, eps.s = eps.s, eventTypes = eventTypes, qmatrix = qmatrix) } ## calculate sum_{k=1}^K q_{kappa_j,k} for all j = 1:N qSum <- unname(rowSums(qmatrix)[eventTypes]) # N-vector } else if (verbose) { message("no epidemic component in model") } ### Drop "terms" and restore original formula environment epidemic <- formula(epidemic) if (epilink != "log") # set as attribute only if non-standard link function attr(epidemic, "link") <- epilink environment(epidemic) <- origenv.epidemic ## We keep the original formula environment since it will be used to ## evaluate the modified twinstim-call in drop1/add1 (with default ## enclos=baseenv()), and cl$data should be visible from there. ## Alternatively, we could set it to parent.frame(). ######################### ### endemic component ### ######################### ### Parse endemic formula if (missing(endemic)) { origenv.endemic <- parent.frame() endemic <- ~ 0 } else { origenv.endemic <- environment(endemic) environment(endemic) <- environment() ## such that t0 and T are found in the subset expressions below } endemic <- terms(endemic, data = data$stgrid, keep.order = TRUE) ## check for type-specific endemic intercept and remove it from the formula ## (will be handled separately) typeSpecificEndemicIntercept <- "1 | type" %in% attr(endemic, "term.labels") if (typeSpecificEndemicIntercept) { endemic <- update.formula(endemic, ~ . - (1|type)) # this drops the terms attributes endemic <- terms(endemic, data = data$stgrid, keep.order = TRUE) } globalEndemicIntercept <- if (typeSpecificEndemicIntercept) { attr(endemic, "intercept") <- 1L # we need this to ensure that we have correct contrasts FALSE } else attr(endemic, "intercept") == 1L nbeta0 <- globalEndemicIntercept + typeSpecificEndemicIntercept * nTypes ### Generate endemic model frame and model matrix on event data mfhEvents <- model.frame(endemic, data = eventsData[row.names(mfe),], subset = time>t0 & time<=T, na.action = na.fail, # since R 2.10.0 patched also works with # endemic = ~1 (see PR#14066) drop.unused.levels = FALSE) mmhEvents <- model.matrix(endemic, mfhEvents) xlevels_endemic <- .getXlevels(endemic, mfhEvents) # exclude intercept from endemic model matrix below, will be treated separately if (nbeta0 > 0) mmhEvents <- mmhEvents[,-1,drop=FALSE] #stopifnot(nrow(mmhEvents) == Nin) p <- ncol(mmhEvents) hash <- (nbeta0+p) > 0L ### Generate model frame and model matrix on grid data (only if p > 0) if (hash) { offsetEvents <- model.offset(mfhEvents) mfhGrid <- model.frame(endemic, data = data$stgrid, subset = start >= t0 & stop <= T, na.action = na.fail, # since R 2.10.0 patched also works with # endemic = ~1 (see PR#14066) drop.unused.levels = FALSE, BLOCK=BLOCK, tile=tile, dt=stop-start, ds=area) # 'tile' is redundant here for fitting but useful # for debugging & necessary for intensityplots gridBlocks <- mfhGrid[["(BLOCK)"]] histIntervals <- data$stgrid[!duplicated.default( data$stgrid$BLOCK, nmax = data$stgrid$BLOCK[length(data$stgrid$BLOCK)] ), c("BLOCK", "start", "stop")] # sorted row.names(histIntervals) <- NULL histIntervals <- histIntervals[histIntervals$start >= t0 & histIntervals$stop <= T,] gridTiles <- mfhGrid[["(tile)"]] # only needed for intensityplot mmhGrid <- model.matrix(endemic, mfhGrid) nGrid <- nrow(mmhGrid) # exclude intercept from endemic model matrix below, will be treated separately if (nbeta0 > 0) mmhGrid <- mmhGrid[,-1,drop=FALSE] # Extract endemic model components offsetGrid <- model.offset(mfhGrid) dt <- mfhGrid[["(dt)"]] ds <- mfhGrid[["(ds)"]] ## expression to calculate the endemic part on the grid -> .hIntTW() if (p > 0L) { hGridExpr <- quote(drop(mmhGrid %*% beta)) if (!is.null(offsetGrid)) hGridExpr <- call("+", quote(offsetGrid), hGridExpr) } else { hGridExpr <- if (is.null(offsetGrid)) quote(numeric(nGrid)) else quote(offsetGrid) } hGridExpr <- call("exp", hGridExpr) ## expression to calculate the endemic part for the events -> .hEvents() hEventsExpr <- if (p > 0L) { quote(drop(mmhEvents %*% beta)) } else { quote(numeric(Nin)) } if (nbeta0 == 1L) { # global intercept hEventsExpr <- call("+", quote(beta0), hEventsExpr) } else if (nbeta0 > 1L) { # type-specific intercept hEventsExpr <- call("+", quote(beta0[eventTypes[includes]]), hEventsExpr) } if (!is.null(offsetEvents)) hEventsExpr <- call("+", quote(offsetEvents), hEventsExpr) hEventsExpr <- call("exp", hEventsExpr) } else if (verbose) message("no endemic component in model") ### Drop "terms" and restore original formula environment endemic <- if (typeSpecificEndemicIntercept) { ## re-add it to the endemic formula update.formula(formula(endemic), ~ (1|type) + .) } else formula(endemic) environment(endemic) <- origenv.endemic ## We keep the original formula environment since it will be used to ## evaluate the modified twinstim-call in drop1/add1 (with default ## enclos=baseenv()), and cl$data should be visible from there. ## Alternatively, we could set it to parent.frame(). ### Stop if model is degenerate if (!hash) { if (hase) { if (nEventsWithoutSources <- sum(lengths(eventSources[includes]) == 0)) stop("found ", nEventsWithoutSources, " events without .sources ", "(impossible in a purely epidemic model)") } else { stop("nothing to do: neither endemic nor epidemic parts were specified") } } ############################# ### Interaction functions ### ############################# if (hase) { ## Check interaction functions siaf <- do.call(".parseiaf", args = alist(siaf, "siaf", eps.s, verbose)) constantsiaf <- attr(siaf, "constant") nsiafpars <- siaf$npars tiaf <- do.call(".parseiaf", args = alist(tiaf, "tiaf", eps.t, verbose)) constanttiaf <- attr(tiaf, "constant") ntiafpars <- tiaf$npars ## Check control.siaf if (constantsiaf) { control.siaf <- NULL } else if (is.list(control.siaf)) { if (!is.null(control.siaf$F)) stopifnot(is.list(control.siaf$F)) if (!is.null(control.siaf$Deriv)) stopifnot(is.list(control.siaf$Deriv)) } else if (!is.null(control.siaf)) { stop("'control.siaf' must be a list or NULL") } ## should we compute siafInt in parallel? useParallel <- cores > 1L && requireNamespace("parallel") ## but do not parallelize for a memoised siaf.step (becomes slower) if (useParallel && !is.null(attr(siaf, "knots")) && !is.null(attr(siaf, "maxRange")) && requireNamespace("memoise", quietly = TRUE) && memoise::is.memoised(environment(siaf$f)$ringAreas)) { cores <- 1L useParallel <- FALSE } ## Define function that integrates the 'tiaf' function .tiafInt <- .tiafIntFUN() ## Define function that integrates the two-dimensional 'siaf' function ## over the influence regions of the events ..siafInt <- if (is.null(control.siaf[["siafInt"]])) { .siafInt <- .siafIntFUN(siaf = siaf, noCircularIR = all(eps.s > bdist), parallel = useParallel) ## Memoisation of .siafInt if (!constantsiaf && requireNamespace("memoise")) { memoise::memoise(.siafInt) ## => speed-up optimization since 'nlminb' evaluates the loglik and ## score for the same set of parameters at the end of each iteration } else { if (!constantsiaf && verbose) message("Continuing without memoisation of 'siaf$f' cubature ...") .siafInt } } else { ## predefined cubature results in epitest(..., fixed = TRUE), ## where siafInt is identical during all permutations (only permuted) stopifnot(is.vector(control.siaf[["siafInt"]], mode = "numeric"), length(control.siaf[["siafInt"]]) == N) local({ env <- new.env(hash = FALSE, parent = .GlobalEnv) env$siafInt <- control.siaf[["siafInt"]] as.function(alist(siafpars=, ...=, siafInt), envir = env) }) } .siafInt.args <- c(alist(siafpars), control.siaf$F) } else { if (!missing(siaf) && !is.null(siaf)) warning("'siaf' can only be modelled in conjunction with an 'epidemic' process") if (!missing(tiaf) && !is.null(tiaf)) warning("'tiaf' can only be modelled in conjunction with an 'epidemic' process") siaf <- tiaf <- NULL nsiafpars <- ntiafpars <- 0L control.siaf <- NULL } hassiafpars <- nsiafpars > 0L hastiafpars <- ntiafpars > 0L ## Can we calculate the score function? useScore <- if (partial) FALSE else if (hase) { (!hassiafpars | !is.null(siaf$deriv)) & (!hastiafpars | (!is.null(tiaf$deriv)) & !is.null(tiaf$Deriv)) } else TRUE ## Define function that applies siaf$Deriv on all events (integrate the ## two-dimensional siaf$deriv function) if (useScore && hassiafpars) { .siafDeriv <- mapplyFUN( c(alist(siaf$Deriv, influenceRegion, type=eventTypes), list(MoreArgs=quote(list(siaf$deriv, siafpars, ...)), SIMPLIFY=TRUE, USE.NAMES=FALSE)), ##<- we explicitly quote() the ...-part instead of simply including ## it in the above alist() - only to make checkUsage() happy ## depending on nsiafpars, mapply() will return an N-vector ## or a nsiafpars x N matrix => transform to N x nsiafpars: after = quote(if (is.matrix(res)) t(res) else as.matrix(res)), parallel = useParallel) .siafDeriv.args <- c(alist(siafpars), control.siaf$Deriv) } ############################################################################ ### Log-likelihood function, score function, expected Fisher information ### ############################################################################ ### Total number of parameters (= length of 'theta') npars <- nbeta0 + p + q + nsiafpars + ntiafpars # REMINDER: # theta - parameter vector c(beta0, beta, gamma, siafpars, tiafpars), where # beta0 - endemic intercept (maybe type-specific) # beta - other parameters of the endemic component exp(offset + eta_h(t,s)) # gamma - coefficients of the epidemic predictor # siafpars- parameters of the epidemic spatial interaction function # tiafpars- parameters of the epidemic temporal interaction function # mmh[Events/Grid] - model matrix related to beta, i.e the endemic component, # either for events only or for the whole spatio-temporal grid # offset[Events/Grid] - offset vector related to the endemic component (can be NULL), # either for events only or for the whole spatio-temporal grid # dt, ds - columns of the spatio-temporal grid (dt = stop-start, ds = area) # mme - model matrix related to gamma in the epidemic component # siaf, tiaf - spatial/temporal interaction function (NULL, list or numeric) # eventTimes, eventCoords, eventSources, gIntLower, gIntUpper, influenceRegion - # columns of the events data frame if (hash) { ### Calculates the endemic component (for i in includes -> Nin-vector) ### h(t_i,s_i,kappa_i) = exp(offset_i + beta_{0,kappa_i} + eta_h(t_i,s_i)) .hEvents <- function (beta0, beta) {} body(.hEvents) <- hEventsExpr ### Integral of the endemic component over [0;uppert] x W .hIntTW <- function (beta, score = NULL, #matrix(1,nrow(mmhGrid),1L) uppert = NULL) {} body(.hIntTW) <- as.call(c(as.name("{"), expression( subtimeidx <- if (!is.null(uppert)) { # && isScalar(uppert) && t0 <= uppert && uppert < T if (uppert == t0) return(0) # actually never happens # since uppert %in% eventTimes[includes] > t0 idx <- match(TRUE, histIntervals$stop >= uppert) firstBlockBeyondUpper <- histIntervals$BLOCK[idx] newdt <- uppert - histIntervals$start[idx] dt[gridBlocks == firstBlockBeyondUpper] <- newdt which(gridBlocks <= firstBlockBeyondUpper) } else NULL ), substitute(hGrid <- hGridExpr, list(hGridExpr=hGridExpr)), expression(sumterms <- hGrid * ds * dt), expression(if (is.null(score)) { if (is.null(subtimeidx)) sum(sumterms) else sum(sumterms[subtimeidx]) } else { if (is.null(subtimeidx)) .colSums(score * sumterms, nGrid, ncol(score)) else .colSums((score * sumterms)[subtimeidx,,drop=FALSE], length(subtimeidx), ncol(score)) }) )) } if (hase) { ### Calculates the epidemic component for all events .eEvents <- function (gammapred, siafpars, tiafpars, ncolsRes = 1L, score = matrix(1,N,ncolsRes), f = siaf$f, g = tiaf$g) # second line arguments are for score functions with defaults for loglik { e <- vapply(X = includes, FUN = function (i) { sources <- eventSources[[i]] nsources <- length(sources) if (nsources == 0L) numeric(ncolsRes) else { scoresources <- score[sources,,drop=FALSE] predsources <- gammapred[sources] repi <- rep.int(i, nsources) sdiff <- eventCoords[repi,,drop=FALSE] - eventCoords[sources,,drop=FALSE] fsources <- f(sdiff, siafpars, eventTypes[sources]) tdiff <- eventTimes[repi] - eventTimes[sources] gsources <- g(tdiff, tiafpars, eventTypes[sources]) # if(length(predsources) != NROW(fsources) || NROW(fsources) != NROW(gsources)) browser() .colSums(scoresources * predsources * fsources * gsources, nsources, ncolsRes) } }, FUN.VALUE = numeric(ncolsRes), USE.NAMES = FALSE) ## return a vector if ncolsRes=1, otherwise a matrix (Nin x ncolsRes) if (ncolsRes == 1L) e else t(e) } } ### Calculates the two components of the integrated intensity function ### over [0;uppert] x W x K heIntTWK <- function (beta0, beta, gammapred, siafpars, tiafpars, uppert = NULL) {} body(heIntTWK) <- as.call(c(as.name("{"), if (hash) { # endemic component expression( hIntTW <- .hIntTW(beta, uppert = uppert), .beta0 <- rep_len(if (nbeta0==0L) 0 else beta0, nTypes), fact <- sum(exp(.beta0)), hInt <- fact * hIntTW ) } else { expression(hInt <- 0) }, if (hase) { # epidemic component c(expression(siafInt <- do.call("..siafInt", .siafInt.args)),#N-vector if (useParallel) expression( # print "try-catch"ed errors if (any(.nonfinitesiafint <- !is.finite(siafInt))) stop("invalid result of 'siaf$F' for 'siafpars=c(", paste(signif(siafpars, getOption("digits")), collapse=", "), ")':\n", paste(unique(siafInt[.nonfinitesiafint]), sep="\n"), call.=FALSE) ), expression( if (!is.null(uppert)) { # && isScalar(uppert) && t0 <= uppert && uppert < T gIntUpper <- pmin(uppert-eventTimes, eps.t) subtimeidx <- eventTimes < uppert tiafIntSub <- .tiafInt(tiafpars, from = gIntLower[subtimeidx], to = gIntUpper[subtimeidx], type = eventTypes[subtimeidx]) eInt <- sum(qSum[subtimeidx] * gammapred[subtimeidx] * siafInt[subtimeidx] * tiafIntSub) } else { tiafInt <- .tiafInt(tiafpars) eInt <- sum(qSum * gammapred * siafInt * tiafInt) } ) ) } else expression(eInt <- 0), expression(c(hInt, eInt)) )) ### Calculates the log-likelihood loglik <- function (theta) { # Extract parameters from theta beta0 <- theta[seq_len(nbeta0)] beta <- theta[nbeta0+seq_len(p)] gamma <- theta[nbeta0+p+seq_len(q)] siafpars <- theta[nbeta0+p+q+seq_len(nsiafpars)] tiafpars <- theta[nbeta0+p+q+nsiafpars+seq_len(ntiafpars)] # dN part of the log-likelihood hEvents <- if (hash) .hEvents(beta0, beta) else 0 eEvents <- if (hase) { gammapred <- drop(epilinkinv(mme %*% gamma)) # N-vector .eEvents(gammapred, siafpars, tiafpars) # Nin-vector! (only 'includes' here) } else 0 lambdaEvents <- hEvents + eEvents # Nin-vector llEvents <- sum(log(lambdaEvents)) # * llEvents is -Inf in case of 0-intensity at any event time # * If epilinkinv is 'identity', lambdaEvents < 0 if eEvents < -hEvents, # and llEvents is NaN with a warning (intensity must be positive) if (is.nan(llEvents)) # nlminb() does not like NA function values llEvents <- -Inf # lambda integral of the log-likelihood heInt <- heIntTWK(beta0, beta, gammapred, siafpars, tiafpars) # !hase => missing(gammapred), but lazy evaluation omits an error in this case because heIntTWK doesn't ask for gammapred llInt <- sum(heInt) # Return the log-likelihood ll <- llEvents - llInt ll } ### Calculates the score vector score <- function (theta) { # Extract parameters from theta beta0 <- theta[seq_len(nbeta0)] beta <- theta[nbeta0+seq_len(p)] gamma <- theta[nbeta0+p+seq_len(q)] siafpars <- theta[nbeta0+p+q+seq_len(nsiafpars)] tiafpars <- theta[nbeta0+p+q+nsiafpars+seq_len(ntiafpars)] if (hase) { gammapred <- drop(epilinkinv(mme %*% gamma)) # N-vector hEvents <- if (hash) .hEvents(beta0, beta) else 0 eEvents <- .eEvents(gammapred, siafpars, tiafpars) # Nin-vector! (only 'includes' here) lambdaEvents <- hEvents + eEvents # Nin-vector siafInt <- do.call("..siafInt", .siafInt.args) # N-vector tiafInt <- .tiafInt(tiafpars) # N-vector } # score vector for beta hScore <- if (hash) { score_beta0 <- if (nbeta0 == 1L) local({ # global intercept sEvents <- if (hase) { hEvents / lambdaEvents } else rep.int(1, Nin) sEventsSum <- sum(sEvents) sInt <- nTypes*exp(beta0) * .hIntTW(beta) sEventsSum - unname(sInt) }) else if (nbeta0 > 1L) local({ # type-specific intercepts ind <- sapply(seq_len(nTypes), function (type) eventTypes[includes] == type, simplify=TRUE, USE.NAMES=FALSE) # logical Nin x nTypes matrix sEvents <- if (hase) { ind * hEvents / lambdaEvents } else ind sEventsSum <- .colSums(sEvents, Nin, nTypes) sInt <- exp(beta0) * .hIntTW(beta) sEventsSum - unname(sInt) }) else numeric(0L) # i.e. nbeta0 == 0L score_beta <- if (p > 0L) local({ sEvents <- if (hase) { mmhEvents * hEvents / lambdaEvents } else mmhEvents sEventsSum <- .colSums(sEvents, Nin, p) fact <- if (nbeta0 > 1L) sum(exp(beta0)) else if (nbeta0 == 1L) nTypes*exp(beta0) else nTypes sInt <- fact * .hIntTW(beta, mmhGrid) sEventsSum - sInt }) else numeric(0L) c(score_beta0, score_beta) } else numeric(0L) # score vector for gamma, siafpars and tiafpars eScore <- if (hase) { score_gamma <- local({ nom <- .eEvents(switch(epilink, "log" = gammapred, "identity" = rep.int(1, N)), siafpars, tiafpars, ncolsRes=q, score=mme) # Nin-vector if q=1 sEventsSum <- .colSums(nom / lambdaEvents, Nin, q) # |-> dotted version also works for vector-arguments dgammapred <- switch(epilink, "log" = mme * gammapred, "identity" = mme) sInt <- .colSums(dgammapred * (qSum * siafInt * tiafInt), N, q) sEventsSum - sInt }) score_siafpars <- if (hassiafpars && !fixedsiafpars) local({ nom <- .eEvents(gammapred, siafpars, tiafpars, ncolsRes=nsiafpars, f=siaf$deriv) sEventsSum <- .colSums(nom / lambdaEvents, Nin, nsiafpars) derivInt <- do.call(".siafDeriv", .siafDeriv.args) # N x nsiafpars matrix ## if useParallel, derivInt may contain "try-catch"ed errors ## in which case we receive a one-column character or list matrix if (!is.numeric(derivInt)) # we can throw a helpful error message stop("invalid result of 'siaf$Deriv' for 'siafpars=c(", paste(signif(siafpars, getOption("digits")), collapse=", "), ")':\n", paste(unique(derivInt[sapply(derivInt, is.character)]), sep="\n"), call.=FALSE) sInt <- .colSums(derivInt * (qSum * gammapred * tiafInt), N, nsiafpars) sEventsSum - sInt }) else numeric(nsiafpars) # if 'fixedsiafpars', this part is unused score_tiafpars <- if (hastiafpars && !fixedtiafpars) local({ nom <- .eEvents(gammapred, siafpars, tiafpars, ncolsRes=ntiafpars, g=tiaf$deriv) sEventsSum <- .colSums(nom / lambdaEvents, Nin, ntiafpars) derivIntUpper <- tiaf$Deriv(gIntUpper, tiafpars, eventTypes) derivIntLower <- tiaf$Deriv(gIntLower, tiafpars, eventTypes) derivInt <- derivIntUpper - derivIntLower # N x ntiafpars matrix sInt <- .colSums(derivInt * (qSum * gammapred * siafInt), N, ntiafpars) sEventsSum - sInt }) else numeric(ntiafpars) # if 'fixedtiafpars', this part is unused c(score_gamma, score_siafpars, score_tiafpars) } else numeric(0L) # return the score vector scorevec <- c(hScore, eScore) scorevec } ### Estimates the expected Fisher information matrix ### by the "optional variation process" (Martinussen & Scheike, p. 64), ### or see Rathbun (1996, equation (4.7)) fisherinfo <- function (theta) { # Extract parameters from theta beta0 <- theta[seq_len(nbeta0)] beta <- theta[nbeta0+seq_len(p)] gamma <- theta[nbeta0+p+seq_len(q)] siafpars <- theta[nbeta0+p+q+seq_len(nsiafpars)] tiafpars <- theta[nbeta0+p+q+nsiafpars+seq_len(ntiafpars)] # only events (intdN) part of the score function needed zeromatrix <- matrix(0, Nin, 0) if (hase) { gammapred <- drop(epilinkinv(mme %*% gamma)) # N-vector hEvents <- if (hash) .hEvents(beta0, beta) else 0 eEvents <- .eEvents(gammapred, siafpars, tiafpars) # Nin-vector! (only 'includes' here) lambdaEvents <- hEvents + eEvents # Nin-vector } # for beta hScoreEvents <- if (hash) { scoreEvents_beta0 <- if (nbeta0 > 1L) local({ # type-specific intercepts ind <- sapply(seq_len(nTypes), function (type) eventTypes[includes] == type, simplify=TRUE, USE.NAMES=FALSE) # logical Nin x nTypes matrix if (hase) { ind * hEvents / lambdaEvents } else ind }) else if (nbeta0 == 1L) { # global intercept if (hase) { hEvents / lambdaEvents } else matrix(1, Nin, 1L) } else zeromatrix scoreEvents_beta <- if (p > 0L) { if (hase) { mmhEvents * hEvents / lambdaEvents } else mmhEvents # Nin x p matrix } else zeromatrix unname(cbind(scoreEvents_beta0, scoreEvents_beta, deparse.level=0)) } else zeromatrix # for gamma, siafpars and tiafpars eScoreEvents <- if (hase) { scoreEvents_gamma_nom <- .eEvents(switch(epilink, "log" = gammapred, "identity" = rep.int(1, N)), siafpars, tiafpars, ncolsRes = q, score = mme) # Ninxq matrix scoreEvents_siafpars_nom <- if (hassiafpars) { .eEvents(gammapred, siafpars, tiafpars, ncolsRes = nsiafpars, f = siaf$deriv) # Ninxnsiafpars matrix } else zeromatrix scoreEvents_tiafpars_nom <- if (hastiafpars) { .eEvents(gammapred, siafpars, tiafpars, ncolsRes = ntiafpars, g = tiaf$deriv) # Ninxntiafpars matrix } else zeromatrix eScoreEvents_nom <- cbind(scoreEvents_gamma_nom, scoreEvents_siafpars_nom, scoreEvents_tiafpars_nom, deparse.level=0) eScoreEvents_nom / lambdaEvents } else zeromatrix scoreEvents <- cbind(hScoreEvents, eScoreEvents, deparse.level=0) ## Build the optional variation process (Martinussen & Scheike, p64) ## info <- matrix(0, nrow = npars, ncol = npars, ## dimnames = list(names(theta), names(theta))) ## for (i in 1:Nin) info <- info + crossprod(scoreEvents[i,,drop=FALSE]) ## oh dear, this is nothing else but t(scoreEvents) %*% scoreEvents crossprod(scoreEvents) } ### Calculates the partial log-likelihood for continuous space ### (Diggle et al., 2009) partialloglik <- function (theta) { # Extract parameters from theta beta0 <- theta[seq_len(nbeta0)] beta <- theta[nbeta0+seq_len(p)] gamma <- theta[nbeta0+p+seq_len(q)] siafpars <- theta[nbeta0+p+q+seq_len(nsiafpars)] tiafpars <- theta[nbeta0+p+q+nsiafpars+seq_len(ntiafpars)] # calculate the observed intensities hEvents <- if (hash) .hEvents(beta0, beta) else 0 eEvents <- if (hase) { gammapred <- drop(epilinkinv(mme %*% gamma)) # N-vector .eEvents(gammapred, siafpars, tiafpars) # Nin-vector! (only 'includes' here) } else 0 lambdaEvents <- hEvents + eEvents # Nin-vector # calculate integral of lambda(t_i, s, kappa) over at-risk set = (observation region x types) hInts <- if (hash) { # endemic component hGrid <- eval(hGridExpr) # integral over W and types for each time block in mfhGrid fact <- if (nbeta0 > 1L) sum(exp(beta0)) else if (nbeta0 == 1L) nTypes*exp(beta0) else nTypes hInt_blocks <- fact * tapply(hGrid*ds, gridBlocks, sum, simplify=TRUE) .idx <- match(eventBlocks[includes], names(hInt_blocks)) unname(hInt_blocks[.idx]) # Nin-vector } else 0 eInts <- if (hase) { # epidemic component siafInt <- do.call("..siafInt", .siafInt.args) # N-vector gs <- gammapred * siafInt # N-vector sapply(includes, function (i) { timeSources <- determineSources1(i, eventTimes, removalTimes, 0, Inf, NULL) nSources <- length(timeSources) if (nSources == 0L) 0 else { repi <- rep.int(i, nSources) tdiff <- eventTimes[repi] - eventTimes[timeSources] gsources <- tiaf$g(tdiff, tiafpars, eventTypes[timeSources]) sum(qSum[timeSources] * gs[timeSources] * gsources) } }, simplify=TRUE, USE.NAMES=FALSE) # Nin-vector } else 0 lambdaEventsIntW <- hInts + eInts # Nin-vector # Calculate and return the partial log-likelihood p <- lambdaEvents / lambdaEventsIntW # Nin-vector pll <- sum(log(p)) pll } ################################ ### Prepare for optimization ### ################################ ll <- if (partial) partialloglik else loglik functions <- list(ll = ll, sc = if (useScore) score else NULL, fi = if (useScore) fisherinfo else NULL) ### Include check for validity of siafpars and tiafpars ('validpars') in ll if (!is.null(siaf$validpars)) { body(ll) <- as.call(append(as.list(body(ll)), as.list(expression( if (hassiafpars && !siaf$validpars(siafpars)) { if (!isTRUE(optimArgs$control$trace == 0)) # default: NULL cat("(invalid 'siafpars' in loglik)\n") return(-Inf) } )), after = grep("^siafpars <-", body(ll)))) } if (!is.null(tiaf$validpars)) { body(ll) <- as.call(append(as.list(body(ll)), as.list(expression( if (hastiafpars && !tiaf$validpars(tiafpars)) { if (!isTRUE(optimArgs$control$trace == 0)) # default: NULL cat("(invalid 'tiafpars' in loglik)\n") return(-Inf) } )), after = grep("^tiafpars <-", body(ll)))) } ### Check that optim.args is a list or NULL if (is.null(optim.args)) { # no optimisation requested setting <- functions on.exit(rm(setting), add = TRUE) # Append model information setting$npars <- c(nbeta0 = nbeta0, p = p, q = q, nsiafpars = nsiafpars, ntiafpars = ntiafpars) setting$qmatrix <- qmatrix # -> information about nTypes and typeNames setting$formula <- list(endemic = endemic, epidemic = epidemic, siaf = siaf, tiaf = tiaf) # Return settings setting$call <- cl environment(setting) <- environment() if (verbose) message("optimization skipped", " (returning functions in data environment)") return(setting) } else if (!is.list(optim.args)) stop("'optim.args' must be a list or NULL") ### Check initial value for theta initpars <- rep(0, npars) names(initpars) <- c( if (nbeta0 > 1L) { paste0("h.type",typeNames) } else if (nbeta0 == 1L) "h.(Intercept)", if (p > 0L) paste("h", colnames(mmhEvents), sep = "."), if (hase) paste("e", colnames(mme), sep = "."), if (hassiafpars) paste("e.siaf", seq_len(nsiafpars), sep="."), if (hastiafpars) paste("e.tiaf", seq_len(ntiafpars), sep=".") ) ## some naive defaults if (nbeta0 > 0) initpars[seq_len(nbeta0)] <- crudebeta0( nEvents = Nin, offset.mean = if (is.null(offsetGrid)) 0 else weighted.mean(offsetGrid, replace(ds, !is.finite(offsetGrid), 0)), W.area = sum(ds[gridBlocks==histIntervals[1,"BLOCK"]]), period = T-t0, nTypes = nTypes ) if (hase && "e.(Intercept)" %in% names(initpars) && epilink == "log") initpars["e.(Intercept)"] <- -9 # suitable value depends on [st]iafInt if (hassiafpars && identical(body(siaf$f)[[2L]], quote(sds <- exp(pars)))) { ## "detect" siaf.gaussian => use 10% of bbox diameter as initial sd initpars[paste0("e.siaf.", seq_len(nsiafpars))] <- round(log(0.1*sqrt(sum(apply(bbox(data$W), 1L, diff.default)^2)))) } ## manual par-specification overrides these defaults if (!is.null(optim.args[["par"]])) { if (!is.vector(optim.args$par, mode="numeric")) { stop("'optim.args$par' must be a numeric vector") } if (length(optim.args$par) != npars) { stop(gettextf(paste("'optim.args$par' (%d) does not have the same", "length as the number of unknown parameters (%d)"), length(optim.args$par), npars)) } initpars[] <- optim.args$par } ## values in "start" overwrite defaults and optim.args$par if (!is.null(start)) { start <- check_twinstim_start(start) start <- start[names(start) %in% names(initpars)] initpars[names(start)] <- start } ## warn if initial intercept is negative when the identity link is used if (epilink == "identity" && "e.(Intercept)" %in% names(initpars) && initpars["e.(Intercept)"] < 0) warning("identity link and negative start value for \"e.(Intercept)\"") ## check that start values are finite if (any(!is.finite(initpars))) { print(initpars[!is.finite(initpars)]) stop("initial parameter values must be finite; set 'start'", call. = FALSE) } ## update optim.args$par optim.args$par <- initpars ### Fixed parameters during optimization fixed <- optim.args[["fixed"]] optim.args[["fixed"]] <- NULL whichfixed <- if (is.null(fixed)) { integer(0L) } else if (isTRUE(fixed)) { seq_len(npars) } else { stopifnot(is.vector(fixed)) if (is.numeric(fixed)) { stopifnot(fixed %in% seq_len(npars)) fixed } else if (is.character(fixed)) { ## we silently ignore names of non-existent parameters intersect(fixed, names(initpars)) } else if (is.logical(fixed)) { stopifnot(length(fixed) == npars) which(fixed) } else { stop("'optim.args$fixed' must be a numeric, character or logical vector") } } fixed <- setNames(logical(npars), names(initpars)) # FALSE fixed[whichfixed] <- TRUE fixedsiafpars <- hassiafpars && all(fixed[paste("e.siaf", 1:nsiafpars, sep=".")]) fixedtiafpars <- hastiafpars && all(fixed[paste("e.tiaf", 1:ntiafpars, sep=".")]) ### Define negative log-likelihood (score, hessian) for minimization ### as a function of the non-fixed parameters negll <- ll body(negll)[[length(body(negll))]] <- call("-", body(negll)[[length(body(negll))]]) negsc <- if (useScore) { negsc <- score body(negsc)[[length(body(negsc))]] <- call("-", body(negsc)[[length(body(negsc))]]) negsc } else NULL neghess <- if (useScore) fisherinfo else NULL if (any(fixed)) { ## modify negll, negsc and neghess for subvector optimization optim.args$par <- initpars[!fixed] if (verbose) { if (all(fixed)) { cat("\nno numerical likelihood optimization, all parameters fixed:\n") } else cat("\nfixed parameters during optimization:\n") print(initpars[fixed]) } tmpexpr <- expression( initpars[!fixed] <- theta, theta <- initpars ) body(negll) <- as.call(append(as.list(body(negll)), as.list(tmpexpr), 1)) if (useScore) { body(negsc) <- as.call(append(as.list(body(negsc)), as.list(tmpexpr), 1)) body(neghess) <- as.call(append(as.list(body(neghess)), as.list(tmpexpr), 1)) # return non-fixed sub-vector / sub-matrix only body(negsc)[[length(body(negsc))]] <- call("[", body(negsc)[[length(body(negsc))]], quote(!fixed)) body(neghess)[[length(body(neghess))]] <- call("[", body(neghess)[[length(body(neghess))]], quote(!fixed), quote(!fixed), drop=FALSE) } ## if siafpars or tiafpars are fixed, pre-evaluate integrals if (fixedsiafpars) { if (verbose) cat("pre-evaluating 'siaf' integrals with fixed parameters ...\n") if (!"memoise" %in% loadedNamespaces()) cat("WARNING: Memoization of siaf integration not available!\n", " Repeated integrations with same parameters ", "are redundant and slow!\n", " Really consider installing package \"memoise\"!\n", sep="") siafInt <- local({ siafpars <- initpars[paste("e.siaf", 1:nsiafpars, sep=".")] do.call("..siafInt", .siafInt.args) # memoise()d }) } if (fixedtiafpars) { if (verbose) cat("pre-evaluating 'tiaf' integrals with fixed parameters ...\n") tiafInt <- .tiafInt(initpars[paste("e.tiaf", 1:ntiafpars, sep=".")]) ## re-define .tiafInt such that it just returns the pre-evaluated ## integrals if called with the default arguments .tiafInt.orig <- .tiafInt body(.tiafInt) <- expression( if (nargs() == 1L) tiafInt else .tiafInt.orig(tiafpars, from, to, type, G) ) ## restore the original function at the end on.exit({ .tiafInt <- .tiafInt.orig rm(.tiafInt.orig) }, add=TRUE) } } if (any(!fixed)) { #################### ### Optimization ### #################### ## Configure the optim procedure (check optim.args) # default arguments optimArgs <- list(par = NULL, # replaced by optim.args$par below fn = quote(negll), gr = quote(negsc), method = if (partial) "Nelder-Mead" else "nlminb", lower = -Inf, upper = Inf, control = list(), hessian = TRUE) # user arguments namesOptimArgs <- names(optimArgs) namesOptimUser <- names(optim.args) optimValid <- namesOptimUser %in% namesOptimArgs optimArgs[namesOptimUser[optimValid]] <- optim.args[optimValid] if (any(!optimValid)) { warning("unknown names in optim.args: ", paste(namesOptimUser[!optimValid], collapse = ", "), immediate. = TRUE) } doHessian <- optimArgs$hessian optimMethod <- optimArgs$method ## Call 'optim', 'nlminb', or 'nlm' with the above arguments if (verbose) { cat("\nminimizing the negative", if (partial) "partial", "log-likelihood", "using", if (optimMethod %in% c("nlm", "nlminb")) paste0("'",optimMethod,"()'") else { paste0("'optim()'s \"", optimMethod, "\"") }, "...\n") cat("initial parameters:\n") print(optimArgs$par) } optimRes1 <- if (optimMethod == "nlminb") { nlminbControl <- control2nlminb(optimArgs$control, defaults = list(trace=1L, rel.tol=1e-6)) ## sqrt(.Machine$double.eps) is the default reltol used in optim, ## which usually equals about 1.49e-08. ## The default rel.tol of nlminb (1e-10) seems too small ## (nlminb often does not finish despite no "relevant" change in loglik). ## I therefore use 1e-6, which is also the default in package nlme ## (see 'lmeControl'). if (nlminbControl$trace > 0L) { cat("negative log-likelihood and parameters ") if (nlminbControl$trace == 1L) cat("in each iteration") else { cat("every", nlminbControl$trace, "iterations") } cat(":\n") } nlminbRes <- nlminb(start = optimArgs$par, objective = negll, gradient = negsc, hessian = if (doHessian) neghess else NULL, control = nlminbControl, lower = optimArgs$lower, upper = optimArgs$upper) nlminbRes$value <- -nlminbRes$objective nlminbRes$counts <- nlminbRes$evaluations nlminbRes } else if (optimMethod == "nlm") { nlmObjective <- function (theta) { value <- negll(theta) grad <- negsc(theta) #hess <- neghess(theta) structure(value, gradient = grad)#, hessian = hess) } nlmControl <- optimArgs$control if (is.null(nlmControl[["print.level"]])) { nlmControl$print.level <- min(nlmControl$trace, 2L) } nlmControl$trace <- nlmControl$REPORT <- NULL if (is.null(nlmControl[["iterlim"]])) { nlmControl$iterlim <- nlmControl$maxit } nlmControl$maxit <- NULL nlmControl$check.analyticals <- FALSE ##<- we use the negative _expected_ Fisher information as the Hessian, ## which is of course different from the true Hessian (=neg. obs. Fisher info) nlmRes <- do.call("nlm", c(alist(f = nlmObjective, p = optimArgs$par, hessian = doHessian), nlmControl)) names(nlmRes)[names(nlmRes) == "estimate"] <- "par" nlmRes$value <- -nlmRes$minimum nlmRes$counts <- rep.int(nlmRes$iterations, 2L) nlmRes$convergence <- if (nlmRes$code %in% 1:2) 0L else nlmRes$code nlmRes } else { # use optim() optimArgs$control <- modifyList(list(trace=1L, REPORT=1L), optimArgs$control) if (finetune) optimArgs$hessian <- FALSE res <- do.call("optim", optimArgs) res$value <- -res$value res } ## Optional fine-tuning of ML estimates by robust Nelder-Mead optimRes <- if (finetune) { if (verbose) { cat("\nMLE from first optimization:\n") print(optimRes1$par) cat("loglik(MLE) =", optimRes1$value, "\n") cat("\nfine-tuning MLE using Nelder-Mead optimization ...\n") } optimArgs$par <- optimRes1$par optimArgs$method <- "Nelder-Mead" optimArgs$hessian <- doHessian optimArgs$control <- modifyList(list(trace=1L), optimArgs$control) nmRes <- do.call("optim", optimArgs) nmRes$value <- -nmRes$value nmRes$counts[2L] <- 0L # 0 gradient evaluations (replace NA for addition below) nmRes } else optimRes1 ## Convergence message msgConvergence <- if (finetune || optimMethod != "nlminb") { paste("code", optimRes$convergence) } else optimRes$message if (optimRes$convergence != 0) { msgNotConverged <- paste0("optimization routine did not converge (", msgConvergence, ")") warning(msgNotConverged) if (verbose) { cat("\nWARNING: ", msgNotConverged, "!\n", sep="") if ((finetune || optimMethod != "nlminb") && !is.null(optimRes$message) && nzchar(optimRes$message)) { cat("MESSAGE: \"", optimRes$message, "\"\n", sep="") } if (hase && useScore && !constantsiaf && grepl("false", msgNotConverged)) { cat("SOLUTION: increase the precision of 'siaf$Deriv' (and 'siaf$F')\n") if (optimMethod == "nlminb") { cat(" or nlminb's false convergence tolerance 'xf.tol'\n") } } } } if (verbose) { cat("\n", if (finetune) "final ", "MLE:\n", sep = "") print(optimRes$par) cat("loglik(MLE) =", optimRes$value, "\n") } } ############## ### Return ### ############## ### Set up list object to be returned fit <- list( coefficients = if (any(fixed)) { if (all(fixed)) initpars else unlist(modifyList(as.list(initpars), as.list(optimRes$par))) } else optimRes$par, loglik = structure(if (all(fixed)) ll(initpars) else optimRes$value, partial = partial), counts = if (all(fixed)) c("function"=1L, "gradient"=0L) else { optimRes1$counts + if (finetune) optimRes$counts else c(0L, 0L) }, converged = if (all(fixed) || (optimRes$convergence == 0)) TRUE else msgConvergence ) ## fix convergence status if (isTRUE(fit$converged) && !is.finite(fit$loglik)) fit$converged <- warning("non-finite log-likelihood") ### Add Fisher information matrices # estimation of the expected Fisher information matrix fit["fisherinfo"] <- list( if (useScore) structure( fisherinfo(fit$coefficients), dimnames = list(names(initpars), names(initpars)) ) ) # If requested, add observed fisher info (= negative hessian at maximum) fit["fisherinfo.observed"] <- list( if (any(!fixed) && !is.null(optimRes$hessian)) optimRes$hessian ## no "-" here because we optimized the negative log-likelihood ) ### Add fitted intensity values and integrated intensities at events # final coefficients theta <- fit$coefficients beta0 <- theta[seq_len(nbeta0)] beta <- theta[nbeta0+seq_len(p)] gamma <- theta[nbeta0+p+seq_len(q)] siafpars <- theta[nbeta0+p+q+seq_len(nsiafpars)] tiafpars <- theta[nbeta0+p+q+nsiafpars+seq_len(ntiafpars)] # final siaf and tiaf integrals over influence regions / periods # and final gammapred (also used by intensity.twinstim) if (hase) { gammapred <- drop(epilinkinv(mme %*% gamma)) # N-vector if (!fixedsiafpars) siafInt <- do.call("..siafInt", .siafInt.args) if (!fixedtiafpars) tiafInt <- .tiafInt(tiafpars) } # fitted intensities hEvents <- if (hash) .hEvents(unname(beta0), beta) else rep.int(0, Nin) eEvents <- if (hase) { .eEvents(gammapred, siafpars, tiafpars) # Nin-vector! (only 'includes' here) } else rep.int(0, Nin) fit$fitted <- hEvents + eEvents # = lambdaEvents # Nin-vector fit$fittedComponents <- cbind(h = hEvents, e = eEvents) rm(hEvents, eEvents) # calculate cumulative ground intensities at event times # Note: this function is also used by residuals.twinstim LambdagEvents <- function (cores = 1L, cumCIF.pb = interactive()) { if (cores != 1L) cumCIF.pb <- FALSE if (cumCIF.pb) pb <- txtProgressBar(min=0, max=Nin, initial=0, style=3) heIntEvents <- if (cores == 1L) { sapply(seq_len(Nin), function (i) { if (cumCIF.pb) setTxtProgressBar(pb, i) heIntTWK(beta0, beta, gammapred, siafpars, tiafpars, eventTimes[includes[i]]) }, simplify=TRUE, USE.NAMES=FALSE) } else { # cannot use progress bar simplify2array(parallel::mclapply( X=eventTimes[includes], FUN=heIntTWK, beta0=beta0, beta=beta, gammapred=gammapred, siafpars=siafpars,tiafpars=tiafpars, mc.preschedule=TRUE, mc.cores=cores ), higher=FALSE) } if (cumCIF.pb) close(pb) setNames(.colSums(heIntEvents, 2L, Nin), rownames(mmhEvents)) } fit["tau"] <- list( if (cumCIF) { if (verbose) cat("\nCalculating fitted cumulative intensities at events ...\n") LambdagEvents(cores, cumCIF.pb) }) # calculate observed R0's: mu_j = spatio-temporal integral of e_j(t,s) over # the observation domain (t0;T] x W (not whole R+ x R^2) fit$R0 <- if (hase) qSum * gammapred * siafInt * tiafInt else rep.int(0, N) names(fit$R0) <- row.names(mfe) ### Append model information fit$npars <- c(nbeta0 = nbeta0, p = p, q = q, nsiafpars = nsiafpars, ntiafpars = ntiafpars) fit$qmatrix <- qmatrix # -> information about nTypes and typeNames fit$bbox <- bbox(data$W) # for completeness and for iafplot fit$timeRange <- c(t0, T) # for simulate.twinstim's defaults fit$formula <- list(endemic = endemic, epidemic = epidemic, siaf = siaf, tiaf = tiaf) fit["xlevels"] <- list( if (length(xlevels_endemic) + length(xlevels_epidemic) > 0) { list(endemic = xlevels_endemic, epidemic = xlevels_epidemic) } else NULL) fit["control.siaf"] <- list(control.siaf) # might be NULL ### Append optimizer configuration optim.args$par <- initpars # reset to also include fixed coefficients if (any(fixed)) optim.args$fixed <- names(initpars)[fixed] # restore fit$optim.args <- optim.args fit["functions"] <- list( if (model) { environment(fit) <- environment() functions }) ### Return object of class "twinstim" if (verbose) cat("\nDone.\n") fit$call <- cl fit$runtime <- structure(proc.time() - ptm, cores=cores) class(fit) <- "twinstim" return(fit) } surveillance/R/algo_cdc.R0000644000176200001440000000677214615162374015052 0ustar liggesusers################################################### ### chunk number 1: ################################################### # Implementation of the CDC surveillance system. # The system evaluates specified timepoints and gives alarm if it recognizes # an outbreak for this timepoint. # algo.cdcLatestTimepoint <- function(disProgObj, timePoint = NULL, control = list(b = 5, m = 1, alpha=0.025)){ observed <- disProgObj$observed freq <- disProgObj$freq # If there is no value in timePoint, then take the last value in observed if(is.null(timePoint)){ timePoint = length(observed) } # check if the vector observed includes all necessary data. if((timePoint-(control$b*freq)-control$m*4) < 1){ stop("The vector of observed is too short!") } ###################################################################### #Find which weeks to take -- hoehle 27.3.2007 - fixed bug taking #things in the wrong time order (more recent values) ###################################################################### midx <- seq(-control$m*4-3,control$m*4) yidx <- ((-control$b):(-1))*freq baseidx <- sort(rep(yidx,each=length(midx)) + midx) months <- rep(1:((2*control$m+1)*control$b),each=4) basevec <- as.integer(by(observed[timePoint + baseidx ],months,sum)) # Create a normal distribution based upper confidence interval # (we will use the prediction interval described in # Farrington & Andrew (2003)) upCi <- mean(basevec)+qnorm(1-control$alpha/2)*sd(basevec)*sqrt(1+1/length(basevec)) #Counts for the current month yt0 <- sum(observed[timePoint:(timePoint-3)]) # Alarm if the actual value is larger than the upper limit. alarm <- yt0 > upCi # Save aggregated score for later visualisation. aggr <- yt0 result <- list(alarm=alarm, upperbound=upCi,aggr=aggr) class(result) = "survRes" # for surveillance system result return(result) } # 'algo.cdc' calls 'algo.bayesLatestTimepoint' for data points given by range. algo.cdc <- function(disProgObj, control = list(range = range, b=5, m=1, alpha=0.025)){ if(disProgObj$freq != 52) { stop("algo.cdc only works for weekly data.") } # initialize the necessary vectors alarm <- matrix(data = 0, nrow = length(control$range), ncol = 1) aggr <- matrix(data = 0, nrow = length(control$range), ncol = 1) upperbound <- matrix(data = 0, nrow = length(control$range), ncol = 1) #Set control options (standard CDC options) if (is.null(control$range)) { control$range <- (disProgObj$freq*control$b - control$m):length(disProgObj$observed) } if (is.null(control$b)) {control$b=5} if (is.null(control$m)) {control$m=1} #bug fixed if (is.null(control$alpha)) {control$alpha=0.025} count <- 1 for(i in control$range){ # call algo.cdcLatestTimepoint result <- algo.cdcLatestTimepoint(disProgObj, i,control=control) # store the results in the right order alarm[count] <- result$alarm aggr[count] <- result$aggr upperbound[count] <- result$upperbound count <- count + 1 } #Add name and data name to control object. control$name <- paste("cdc(",control$m*4,"*,",0,",",control$b,")",sep="") control$data <- paste(deparse(substitute(disProgObj))) # Return the vectors- # as a special feature CDC objects contain an "aggr" identifier # containing the aggregated counts for each week. result <- list(alarm = alarm, upperbound = upperbound, disProgObj=disProgObj, control=control, aggr=aggr) class(result) = "survRes" # for surveillance system result return(result) } surveillance/R/functionTable.R0000644000176200001440000000711513122025572016072 0ustar liggesusers################################################################################ ### Categorize functions and methods for a specific class ### (this is an internal utility function used in some of the package vignettes) ### ### Copyright (C) 2014-2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ functionTable <- function (class, functions = list(), format = "\\texttt", format.nongenerics = "\\textit", horizontal = FALSE) { ## categorization of known generic functions KNOWNGENERICS <- list( Display = c("print", "summary", "xtable", "plot", "animate", "as.stepfun", "intensityplot"), Subset = c("[", "head", "tail", "subset"), Extract = c("nobs", "marks", "coef", "fixef", "ranef", "vcov", "confint", "coeflist", "logLik", "AIC", "extractAIC", "profile", "residuals", "terms", "formula", "R0"), Modify = c("update", "untie", "add1", "drop1"), Convert = c("as.epidata"), Other = c("predict", "simulate", "pit", "scores", "calibrationTest") ) if (is.null(names(functions))) # put all functions in category "Other" functions <- list(Other = unlist(functions, use.names=FALSE)) ## union known generics with specified functions categoryNames <- union(names(KNOWNGENERICS), names(functions)) knowngenerics <- mapply( FUN = union, setNames(KNOWNGENERICS[categoryNames], categoryNames), functions[categoryNames], SIMPLIFY = FALSE, USE.NAMES = TRUE) ## get registered methods and associated generics allmethods <- methods(class = class) allgenerics <- attr(allmethods, "info")$generic genericsList <- lapply(X = knowngenerics, FUN = intersect, allgenerics) genericsList$Other <- c(genericsList$Other, setdiff(allgenerics, unlist(genericsList, use.names=FALSE))) ## all extra 'functions' are not generic or without a method for 'class' nongenericsList <- lapply(X = functions, FUN = function (fnames) { res <- setdiff(fnames, allgenerics) ## note: we do not check if these functions actually exist() if (length(res)) paste0(format.nongenerics, "{", res, "}") else res }) ## merge generics and non-generics functionList <- mapply(FUN = c, genericsList, nongenericsList[names(genericsList)], SIMPLIFY = FALSE, USE.NAMES = TRUE) ## transform list into a matrix by filling with empty cells categoryLengths <- lengths(functionList, use.names = FALSE) nrows <- max(categoryLengths) functionTable <- if (horizontal) { as.matrix(vapply(X = functionList[categoryLengths > 0L], FUN = function (x) paste0(format, "{", x, "}", collapse = ", "), FUN.VALUE = character(1L), USE.NAMES = TRUE)) } else { vapply(X = functionList[categoryLengths > 0L], FUN = function (x) c(paste0(format, "{", x, "}"), rep.int(NA_character_, nrows-length(x))), FUN.VALUE = character(nrows), USE.NAMES = TRUE) } ## done functionTable #xtable::xtable(functionTable, ...) } surveillance/R/boda.R0000644000176200001440000002603014615164167014213 0ustar liggesusers###################################################################### # An implementation of the Bayesian Outbreak Detection Algorithm (BODA) # described in Manitz and H{\"o}hle (2013), Biometrical Journal. # # Note: The algorithm requires the non-CRAN package INLA to run. # You can easily install this package as described at # https://www.r-inla.org/download-install # # # Author: # The initial code was written by J. Manitz, which was then later # adapted and modified for integration into the package by M. Hoehle. # Contributions by M. Salmon and S. Meyer. # # Date: # Code continuously developed during 2010-2014 # # Changes: # MS@2015-02-18 # fixed problem that the posterior was drawn from the respective marginals # instead of the joint distribution. # MH@2014-02-05 # changed tcltk progress bar to text based one and modified code, # use S4 sts object (no wrapping wanted) and changed to new INLA # function name for calculating the transformed marginal. ###################################################################### boda <- function(sts, control=list(range=NULL, X=NULL, trend=FALSE, season=FALSE, prior=c('iid','rw1','rw2'), alpha=0.05, mc.munu=100, mc.y=10, verbose=FALSE, samplingMethod=c('joint','marginals'), quantileMethod=c("MC","MM"))) { #Check if the INLA package is available. if (!requireNamespace("INLA", quietly = TRUE)) { stop("The boda function requires the INLA package to be installed.\n", " The package is not available on CRAN, but can be easily obtained\n", " from .") } #Stop if the sts object is multivariate if (ncol(sts)>1) { stop("boda currently only handles univariate sts objects.") } # quantileMethod parameter if(is.null(control[["quantileMethod",exact=TRUE]])){ control$quantileMethod <- "MC" } else { control$quantileMethod <- match.arg(control$quantileMethod, c("MC","MM")) } # extract data observed <- as.vector(observed(sts)) state <- as.vector(sts@state) time <- 1:length(observed) # clean model data from given outbreaks -- this is now part of the modelling # observed[which(state==1)] <- NA ### define range # missing range if(is.null(control[["range",exact=TRUE]])){ warning('No range given. Range is defined as time from second period until end of time series.') control$range <- (sts@freq+1):length(observed) } # check that range is subset of time series indices if(!all(control$range %in% time)){ stop("Evaluation period 'range' has to be vector of time series indices.") } #set order of range control$range <- sort(control$range) ### show extra output from INLA if(is.null(control[["verbose",exact=TRUE]])) { control$verbose <- FALSE } ### setting for different models if(is.null(control[["trend",exact=TRUE]])){ control$trend <- FALSE } if(is.null(control[["season",exact=TRUE]])){ control$season <- FALSE } if(!is.logical(control$trend)||!is.logical(control$season)){ stop('trend and season are logical parameters.') } ### Prior prior <- match.arg(control$prior, c('iid','rw1','rw2')) if(is.vector(control$X)){ control$X <- as.matrix(control$X,ncol=1) } # sampling method for the parameters samplingMethod <- match.arg(control$samplingMethod, c('joint','marginals')) # setting for threshold calculation if(is.null(control[["alpha",exact=TRUE]])){ control$alpha <- 0.05 } if(control$alpha <= 0 | control$alpha >= 1){ stop("The significance level 'alpha' has to be a probability, and thus has to be between 0 and 1.") } # setting for monte carlo integration if(is.null(control[["mc.munu",exact=TRUE]])){ control$mc.munu <- 100 } if(is.null(control[["mc.y",exact=TRUE]])){ control$mc.y <- 10 } if(!control$mc.munu>0 || control$mc.munu!=round(control$mc.munu,0) || !control$mc.y>0 || control$mc.y!=round(control$mc.y,0)){ stop('Number of Monte Carlo trials has to be an integer larger than zero') } ### set model formula and data modelformula <- paste("observed ~ f(time, model='",prior,"', cyclic=FALSE)", sep="") dat <- data.frame(observed=observed, time=time) # outbreak id if(sum(state)>0){ modelformula <- paste(modelformula, "+ f(state, model='linear')", sep="") dat <- data.frame(dat, state=state) } # trend if(control$trend){ modelformula <- paste(modelformula, "+ f(timeT, model='linear')", sep="") dat <- data.frame(dat, timeT=time) } # season if(control$season){ modelformula <- paste(modelformula, "+ f(timeS, model='seasonal', season.length=",sts@freq,")", sep="") dat <- data.frame(dat, timeS=time) } # covariables X.formula <- NULL if(!is.null(control$X)){ if(nrow(control$X)!=length(observed)){ stop("Argument for covariates 'X' has to have the same length like the time series") } for(i in 1:ncol(control$X)){ X.formula <- (paste(X.formula ,'+', colnames(control$X)[i])) } modelformula <- paste(modelformula, X.formula, sep="") dat <- data.frame(dat, control$X) } modelformula <- as.formula(modelformula) ##### sequential steps ##### #If there is more than one time point in range, then setup a progress bar #(now text based. Alternative: tcltk based) useProgressBar <- length(control$range)>1 if (useProgressBar) { pb <- txtProgressBar(min=min(control$range), max=max(control$range), initial=0, style=if (interactive()) 3 else 1) } #Allocate vector of thresholds xi <- rep(NA,length(observed)) #Loop over all time points in 'range' for(i in control$range){ # prepare data frame dati <- dat[1:i,] dati$observed[i] <- NA #current value to be predicted dati$state[i] <- 0 #current state to be predicted # fit model and calculate quantile using INLA & MC sampling # browser() xi[i] <- bodaFit(dat=dati, samplingMethod=samplingMethod, modelformula=modelformula, alpha=control$alpha, mc.munu=control$mc.munu, mc.y=control$mc.y, quantileMethod=control$quantileMethod, verbose=control$verbose) # update progress bar if (useProgressBar) setTxtProgressBar(pb, i) } # close progress bar if (useProgressBar) close(pb) # compare observed with threshold an trigger alarm: FALSE=no alarm sts@alarm[,1] <- observed > xi sts@upperbound[,1] <- xi control$name <- paste('boda(prior=',prior,')',sep='') sts@control <- control # return result as an sts object return(sts[control$range,]) } ####################################################################### # Helper function for fitting the Bayesian GAM using INLA and computing # the (1-alpha)*100% quantile for the posterior predictive of y[T1] # # Parameters: # dat - data.frame containing the data # modelformula - formula to use for fitting the model with inla # prior - what type of prior for the spline c('iid','rw1','rw2') # alpha - quantile to compute in the predictive posterior # mc.munu - no. of Monte Carlo samples for the mu/size param in the NegBin # mc.y - no. of samples for y. # # Returns: # (1-alpha)*100% quantile for the posterior predictive of y[T1] ###################################################################### bodaFit <- function(dat, modelformula, alpha, mc.munu, mc.y, samplingMethod, quantileMethod, verbose = FALSE) { # set time point T1 <- nrow(dat) # workaround scoping issue with 'E' in recent versions of INLA environment(modelformula) <- environment() ### fit model link <- 1 E <- mean(dat$observed, na.rm=TRUE) # FIXME: is this really needed? model <- INLA::inla(modelformula, data=dat, family='nbinomial', E=E, verbose=verbose, control.predictor=list(compute=TRUE,link=link), control.compute=c(list(cpo=FALSE,config=TRUE), if (packageVersion("INLA") >= "21.07.10") list(return.marginals.predictor=TRUE)), control.inla = list(int.strategy = "grid",dz=1,diff.logdens = 10)) if(is.null(model)){ # probably no longer happens in recent versions of INLA warning("NULL result from INLA at t = ", T1) return(NA_real_) } if(samplingMethod=='marginals'){ # draw sample from marginal posteriori of muT1 & etaT1 to determine predictive # quantile by sampling. marg <- model$marginals.fitted.values[[T1]] mT1 <- try(INLA::inla.rmarginal(n=mc.munu,marg), silent=TRUE) if(inherits(mT1,'try-error')){ warning("degenerate marginal posterior at t = ", T1) return(NA_real_) } # take variation in size hyperprior into account by also sampling from it mtheta <- model$internal.marginals.hyperpar[[1]] theta <- exp(INLA::inla.rmarginal(n=mc.munu,mtheta)) } if (samplingMethod=='joint'){ # Sample from the posterior ## CAVE: 'model' is not reproducible if num.threads != "1:1" (INLA 22.05.07), ## so there is no point in making the sampling step reproducible ##inla.seed <- as.integer(runif(1) * .Machine$integer.max) jointSample <- INLA::inla.posterior.sample( n = mc.munu, result = model, intern = TRUE, # seed = inla.seed skew.corr = FALSE) # added with default TRUE in INLA 19.10.30, needs sn # take variation in size hyperprior into account by also sampling from it theta <- exp(t(sapply(jointSample, function(x) x$hyperpar[[1]]))) mT1 <- exp(t(sapply(jointSample, function(x) x$latent[[T1]]))) } valid <- mT1 >= 0 & theta > 0 if (any(!valid)) { ## a range of (-4.7e-55, 5.8e-52) was seen for mT1 from inla.rmarginal() ## which produced an error (-> NA) in previous versions of INLA warning("degenerate posterior sampling at t = ", T1) return(NA_real_) ## mT1 <- mT1[valid] ## theta <- theta[valid] } if(quantileMethod=="MC"){ #Draw (mc.munu \times mc.y) responses. Would be nice, if we could #determine the quantile of the predictive posterior in more direct form yT1 <- unlist(mapply(rnbinom, size = theta, mu = E*mT1, MoreArgs = list(n = mc.y), SIMPLIFY = FALSE)) qi <- quantile(yT1, probs=(1-alpha), type=3, na.rm=TRUE) } if(quantileMethod=="MM"){ minBracket <- qnbinom(p=(1-alpha), mu=E*min(mT1), size=max(theta)) maxBracket <- qnbinom(p=(1-alpha), mu=E*max(mT1), size=min(theta)) qi <- qmix(p=(1-alpha), mu=E*mT1, size=theta, bracket=c(minBracket, maxBracket)) } return(qi) } #done bodaFit surveillance/R/hhh4_simulate_plot.R0000644000176200001440000003310314426171115017070 0ustar liggesusers################################################################################ ### Plots for an array "hhh4sims" of simulated counts from an "hhh4" model, ### or a list thereof as produced by different "hhh4" models (same period!) ### ### Copyright (C) 2013-2018,2020-2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ plot.hhh4sims <- function (x, ...) { ## use the object name of x x <- eval(substitute(as.hhh4simslist(x)), envir = parent.frame()) plot.hhh4simslist(x, ...) } ## class for a list of "hhh4sims" arrays from different models ## (over the same period with same initial values) hhh4simslist <- function (x, initial, stsObserved) { ## drop attributes from every single hhh4sims object for (i in seq_along(x)) attr(x[[i]], "class") <- attr(x[[i]], "initial") <- attr(x[[i]], "stsObserved") <- NULL ## set as list attributes attr(x, "initial") <- initial attr(x, "stsObserved") <- stsObserved class(x) <- "hhh4simslist" x } ## converter functions as.hhh4simslist <- function (x, ...) UseMethod("as.hhh4simslist") as.hhh4simslist.hhh4sims <- function (x, ...) { ## we do not use x here, but construct a list() from the sys.call() ## such that as.hhh4simslist(name1 = model1, name2 = model2) works cl <- sys.call() cl[[1L]] <- as.name("list") xx <- eval(cl, envir = parent.frame()) objnames <- as.character(cl)[-1L] if (is.null(names(xx))) { names(xx) <- objnames } else { names(xx)[names(xx) == ""] <- objnames[names(xx) == ""] } as.hhh4simslist.list(xx) } as.hhh4simslist.list <- function (x, ...) { ## verify class lapply(X = x, FUN = function (Xi) if (!inherits(Xi, "hhh4sims")) stop(sQuote("x"), " is not a list of ", dQuote("hhh4sims"))) hhh4simslist(x, initial = attr(x[[1L]], "initial"), stsObserved = attr(x[[1L]], "stsObserved")) } as.hhh4simslist.hhh4simslist <- function (x, ...) x ## 'x[i]': select models (elements of the list) ## 'x[i,j,]': subset simulations while keeping attributes in sync "[.hhh4simslist" <- function (x, i, j, ..., drop = FALSE) { ## case 1: select models if (nargs() == 2L) { ## select elements of the list xx <- NextMethod("[") ## restore class attributes xx <- hhh4simslist(xx, initial = attr(x, "initial"), stsObserved = attr(x, "stsObserved")) return(xx) } ## case 2: subset simulations, i.e., index individual arrays cl <- sys.call() cl[[1L]] <- as.name("[") cl[[2L]] <- quote(x) cl$drop <- drop subseti <- as.function(c(alist(x=), cl), envir = parent.frame()) x[] <- lapply(X = unclass(x), subseti) # unclass to use default [[ subset_hhh4sims_attributes(x, i, j) } ## select a specific "hhh4sims" from the list of simulations ## (the inverse of as.hhh4simslist.hhh4sims(xx)) "[[.hhh4simslist" <- function (x, i) { xx <- NextMethod("[[") a <- attributes(xx) attributes(xx) <- c(a[c("dim", "dimnames")], attributes(x)[c("initial", "stsObserved")], list(class = "hhh4sims"), a[c("call", "seed")]) xx } ## aggregate predictions over time and/or (groups of) units aggregate.hhh4simslist <- function (x, units = TRUE, time = FALSE, ..., drop = FALSE) { if (drop || time) { # unclass(x) to use default "[["-method in lapply lapply(X = unclass(x), FUN = aggregate.hhh4sims, units = units, time = time, ..., drop = TRUE) } else { as.hhh4simslist.list( lapply(X = x, FUN = aggregate.hhh4sims, units = units, time = time, ..., drop = FALSE) ) } } #################### ### plot methods ### #################### check_groups <- function (groups, units) { if (is.null(groups)) { factor(rep.int("overall", length(units))) } else if (isTRUE(groups)) { factor(units, levels = units) } else { stopifnot(length(groups) == length(units)) as.factor(groups) } } plot.hhh4simslist <- function (x, type = c("size", "time", "fan"), ..., groups = NULL, par.settings = list()) { FUN <- paste("plotHHH4sims", match.arg(type), sep = "_") groups <- check_groups(groups, colnames(attr(x, "stsObserved"), do.NULL=FALSE)) ngroups <- nlevels(groups) if (is.list(par.settings)) { par.defaults <- list(mar = c(4,4,2,0.5)+.1, las = 1) if (ngroups > 1) par.defaults$mfrow <- sort(n2mfrow(ngroups)) par.settings <- modifyList(par.defaults, par.settings) opar <- do.call("par", par.settings) on.exit(par(opar)) } if (ngroups == 1) { do.call(FUN, list(quote(x), ...)) } else { # stratified plots by groups of units invisible(lapply( X = setNames(nm = levels(groups)), FUN = function (group) { x_group <- x[, which(group == groups) , ] # [-method has drop=F do.call(FUN, list(quote(x_group), ..., main = group)) })) } } ### simulated final size distribution as boxplots aggregated over all units plotHHH4sims_size <- function (x, horizontal = TRUE, trafo = NULL, observed = TRUE, names = base::names(x), ...) { x <- as.hhh4simslist(x) if (horizontal) { names <- rev(names) x <- rev(x) } if (is.null(trafo)) #trafo <- scales::identity_trans() trafo <- list(name = "identity", transform = identity) if (isTRUE(observed)) observed <- list() nsims <- do.call("cbind", # no simplify2array() as we need a matrix even for nsim=1 lapply(X = unclass(x), # simply use the default "[["-method FUN = colSums, dims = 2L) # sum over 1:2 (time x unit) ) nsimstrafo <- trafo$transform(nsims) ## default boxplot arguments fslab <- "size" if (trafo$name != "identity") fslab <- paste0(fslab, " (", trafo$name, "-scale)") defaultArgs <- list(ylab=fslab, yaxt="n", las=1, cex.axis=1, border=1) if (horizontal) names(defaultArgs) <- sub("^y", "x", names(defaultArgs)) ## defaultArgs$mai <- par("mai") ## defaultArgs$mai[2] <- max(strwidth(boxplot.args$names, units="inches", ## cex=boxplot.args$cex.axis)) ## if (trafo$name != "identity") { ## ## ?bxp: 'yaxs' and 'ylim' are used 'along the boxplot' ## defaultArgs <- c(defaultArgs, ## list(ylim=c(0,max(nsimstrafo)*1.05), yaxs="i")) ## } ## generate boxplots boxplot.args <- modifyList(defaultArgs, list(...)) boxplot.args$horizontal <- horizontal boxplot.args$names <- names do.call("boxplot", c(list(x=nsimstrafo), boxplot.args)) ## add means if (horizontal) { points(x=colMeans(nsimstrafo), y=1:ncol(nsimstrafo), pch=8, col=boxplot.args$border) } else points(colMeans(nsimstrafo), pch=8, col=boxplot.args$border) ## add axis aty <- pretty(nsims, n=par("lab")[2-horizontal]) ##aty <- checkat(list(n=par("lab")[2], trafo=trafo), nsims) # linear on sqrt-scale axis(2-horizontal, at=trafo$transform(aty), labels=aty, las=boxplot.args$las) ## add line showing observed size if (is.list(observed)) { nObs <- sum(observed(attr(x, "stsObserved"))) observed <- modifyList( list(col = 1, lty = 2, lwd = 2, labels = nObs, font = 2, las = boxplot.args$las, mgp = if (horizontal) c(3, 0.4, 0)), observed) observed_line <- c( setNames(list(trafo$transform(nObs)), if (horizontal) "v" else "h"), observed[c("col", "lty", "lwd")]) do.call("abline", observed_line) if (!is.null(observed[["labels"]])) do.call("axis", c( list(side = 2-horizontal, at = trafo$transform(nObs)), observed)) } ## numeric summary mysummary <- function(x) c(mean=mean(x), quantile(x, probs=c(0.025, 0.5, 0.975))) nsum <- t(apply(nsims, 2, mysummary)) invisible(nsum) } ### Plot mean time series of the simulated counts plotHHH4sims_time <- function ( x, average = mean, individual = length(x) == 1, conf.level = if (individual) 0.95 else NULL, #score = "rps", matplot.args = list(), initial.args = list(), legend = length(x) > 1, xlim = NULL, ylim = NULL, add = FALSE, ...) { x <- as.hhh4simslist(x) nModels <- length(x) ytInit <- rowSums(attr(x, "initial")) stsObserved <- attr(x, "stsObserved") ytObs <- rowSums(observed(stsObserved)) ytSim <- aggregate.hhh4simslist(x, units = TRUE, time = FALSE, drop = TRUE) average <- match.fun(average) ytMeans <- vapply( X = ytSim, FUN = function (x) apply(x, 1, average), FUN.VALUE = numeric(length(ytObs)), USE.NAMES = TRUE) ## axis range if (is.null(xlim) && is.list(initial.args)) xlim <- c(1 - length(ytInit) - 0.5, length(ytObs) + 0.5) if (is.null(ylim)) ylim <- c(0, max(ytObs, if (individual) unlist(ytSim, recursive = FALSE, use.names = FALSE) else ytMeans, na.rm = TRUE)) ## graphical parameters stopifnot(is.list(matplot.args)) matplot.args <- modifyList( list(y = ytMeans, type = "b", lty = 1, lwd = 3, pch = 20, col = rainbow(nModels)), matplot.args) col <- rep_len(matplot.args$col, nModels) ## observed time series data during simulation period if (!add) plot(stsObserved, type = observed ~ time, xlim = xlim, ylim = ylim, ...) ## add initial counts if (is.list(initial.args)) { initial.args <- modifyList( list(x = seq(to = 0, by = 1, length.out = length(ytInit)), y = ytInit, type = "h", lwd = 5), initial.args) do.call("lines", initial.args) } ## add counts of individual simulation runs if (individual) { for (i in seq_len(nModels)) matlines(ytSim[[i]], lty=1, col=adjustcolor(col[i], alpha.f=0.1)) col <- ifelse(colSums(col2rgb(col)) == 0, "grey", adjustcolor(col, transform=diag(c(.5, .5, .5, 1)))) } ## add means (or medians) matplot.args[["col"]] <- col do.call("matlines", matplot.args) ## add CIs if (isScalar(conf.level)) { alpha2 <- (1-conf.level)/2 ytQuant <- lapply(ytSim, function (sims) t(apply(sims, 1, quantile, probs=c(alpha2, 1-alpha2)))) matlines(sapply(ytQuant, "[", TRUE, 1L), col=col, lwd=matplot.args$lwd, lty=2) matlines(sapply(ytQuant, "[", TRUE, 2L), col=col, lwd=matplot.args$lwd, lty=2) } ## add scores ## if (length(score)==1) { ## scorestime <- simplify2array( ## simscores(x, by="time", scores=score, plot=FALSE), ## higher=FALSE) ## matlines(scales::rescale(scorestime, to=ylim), ## lty=2, lwd=1, col=col) ## } ## add legend if (!identical(FALSE, legend)) { xnames <- if (is.vector(legend, mode = "character")) { if (length(legend) != length(x)) warning("'length(legend)' should be ", length(x)) legend } else { names(x) } legendArgs <- list(x="topright", legend=xnames, bty="n", col=col, lwd=matplot.args$lwd, lty=matplot.args$lty) if (is.list(legend)) legendArgs <- modifyList(legendArgs, legend) do.call("legend", legendArgs) } ## Done ret <- cbind(observed = ytObs, ytMeans) ## if (length(score) == 1) ## attr(ret, score) <- scorestime invisible(ret) } ### Better for a single model: "fanplot" plotHHH4sims_fan <- function (x, which = 1, fan.args = list(), observed.args = list(), initial.args = list(), means.args = NULL, key.args = NULL, xlim = NULL, ylim = NULL, add = FALSE, xaxis = list(), ...) { x <- as.hhh4simslist(x)[[which]] ytInit <- rowSums(attr(x, "initial")) stsObserved <- attr(x, "stsObserved") ytObs <- rowSums(observed(stsObserved)) ytSim <- aggregate.hhh4sims(x, units = TRUE, time = FALSE, drop = TRUE) ## graphical parameters if (is.null(xlim) && is.list(initial.args)) xlim <- c(1 - length(ytInit) - 0.5, length(ytObs) + 0.5) stopifnot(is.list(fan.args)) fan.args <- modifyList( list(probs = seq.int(0.01, 0.99, 0.01)), fan.args, keep.null = TRUE) ## compute the quantiles quantiles <- t(apply(ytSim, 1, quantile, probs = fan.args$probs)) ## create (or add) the fanplot fanplot(quantiles = quantiles, probs = fan.args$probs, means = rowMeans(ytSim), observed = ytObs, fan.args = fan.args, means.args = means.args, observed.args = observed.args, key.args = key.args, xlim = xlim, ylim = ylim, add = add, xaxt = if (is.list(xaxis)) "n" else "s", ...) ## add initial counts if (is.list(initial.args)) { initial.args <- modifyList( list(x = seq(to = 0, by = 1, length.out = length(ytInit)), y = ytInit, type = "p", pch = 19), initial.args) do.call("lines", initial.args) } ## add time axis if (is.list(xaxis)) { xaxis <- modifyList(list(epochsAsDate = TRUE), xaxis) do.call("addFormattedXAxis", c(list(x = stsObserved), xaxis)) } invisible(NULL) } surveillance/R/sts_creation.R0000644000176200001440000000641513430613231015771 0ustar liggesusers################################################################################ ### Simulate count time series with outbreaks (following Noufaily et al, 2012) ### ### Copyright (C) 2014-2015 Maelle Salmon ################################################################################ sts_creation <- function(theta,beta,gamma1,gamma2,m,overdispersion,dates, sizesOutbreak,datesOutbreak,delayMax,alpha, densityDelay) { lengthT <- length(dates) # Baseline observed <- rep(NA,lengthT) upperbound <- rep(NA,lengthT) state <- logical(length=lengthT) for (t in 1:lengthT) { if (m==0){season=0} if (m==1){season=gamma1*cos(2*pi*t/52)+ gamma2*sin(2*pi*t/52)} if (m==2){season=gamma1*cos(2*pi*t/52)+ gamma2*sin(2*pi*t/52)+gamma1*cos(4*pi*t/52)+ gamma2*sin(4*pi*t/52)} mu <- exp(theta + beta*t + season) observed[t] <- rnbinom(mu=mu,size=overdispersion,n=1) upperbound[t] <- qnbinom(mu=mu,size=overdispersion,p=(1-alpha)) } # Outbreaks nOutbreaks <- length(sizesOutbreak) if (nOutbreaks>1){ dens <- lognormDiscrete(Dmax=20,logmu=0,sigma=0.5) for (i in 1:nOutbreaks){ tOutbreak <- which(dates==datesOutbreak[i]) numberOfCases <- rpois(n=1,lambda=sizesOutbreak[i]*(mu*(1+mu/overdispersion))) cases <- rep(0,length(dens)) if (numberOfCases!=0){ for (case in 1:numberOfCases){ t <- sample(x=1:length(dens),size=1,prob=dens) cases[t] <- cases[t] + 1 } } cases <- cases[cases>0] if(sum(cases)>0){ observed[tOutbreak:(tOutbreak+length(cases)-1)] <- observed[tOutbreak:(tOutbreak+length(cases)-1)] + cases state[tOutbreak:(tOutbreak+length(cases)-1)] <- TRUE } } } observed <- observed[1:lengthT] # Reporting triangle if (!is.null(densityDelay)){ # use density delay n <- matrix(0, lengthT, delayMax + 1,dimnames=list(as.character(dates),NULL)) for (t in 1:lengthT){ if(observed[t]!=0){ for (case in 1:observed[t]){ delay <- sample(x=0:delayMax,size=1,prob=densityDelay) if (delay > delayMax) {delay <- delayMax} n[t, delay + 1] <- n[t, delay + 1] + 1 } } } } else{ # Using a poisson as for the outbreaks because it looks good n <- matrix(0, lengthT, D + 1,dimnames=list(as.character(dates),NULL)) for (t in 1:lengthT){ if(observed[t]!=0){ for (case in 1:observed[t]){ delay <- rpois(n=1, lambda=1.5) if (delay > D) {delay <- D} n[t, delay + 1] <- n[t, delay + 1] + 1 } } } } # Create the sts start <- unlist(isoWeekYear(dates[1]), use.names = FALSE) newSts <- new("sts", epoch = as.numeric(dates), start = start, upperbound = as.matrix(upperbound), freq = 52, observed = observed, state = as.matrix(state), epochAsDate = TRUE) newSts@control$reportingTriangle$n <- n return(newSts) } ## FUNCTION FOR DISCRETIZING THE LOG NORM DISTRIBUTION lognormDiscrete <- function(Dmax=20,logmu=0,sigma=0.5){ Fd <- plnorm(0:Dmax, meanlog = logmu, sdlog = sigma) FdDmax <- plnorm(Dmax, meanlog = logmu, sdlog = sigma) #Normalize prob <- diff(Fd)/FdDmax return(prob) } surveillance/R/algo_call.R0000644000176200001440000001511014615164167015220 0ustar liggesusers################################################### ### chunk number 1: ################################################### # 'algo.quality' calculates quality values # like specificity, sensitivity for a surveillance method # # Parameters: # survResObj: object of class survRes, which includes the state chain and # the computed alarm chain ###################################################################### ## Hot fix function fixing two issues in the algo.quality function. ## ## Author: Michael Hoehle ## Date: 2015-11-24 ## ## 1) The function does not work if state or alarms are coded as TRUE/FALSE ## instead of 0/1. ## 2) algo.quality doesn't work for sts objects. ## ## The function now branches on the appropriate thing to do depending on ## what class the argument is. This is not necessarily very good object ## oriented programming, but it works for now. ###################################################################### algo.quality <- function (sts, penalty = 20) { if (inherits(sts, "survRes")) { state <- sts$disProgObj$state[sts$control$range] * 1 alarm <- sts$alarm * 1 } else { if (inherits(sts, "sts")) { if (ncol(sts) > 1) { stop("Function only works for univariate objects.") } state <- sts@state*1 alarm <- alarms(sts)*1 } else { stop(paste0("Class ",class(sts)," not supported!")) } } state <- factor(state, levels = c(0, 1)) alarm <- factor(alarm, levels = c(0, 1)) confusionTable <- table(state, alarm) sens = confusionTable[2, 2]/(confusionTable[2, 2] + confusionTable[2, 1]) spec = confusionTable[1, 1]/(confusionTable[1, 2] + confusionTable[1, 1]) TP = confusionTable[2, 2] FN = confusionTable[2, 1] TN = confusionTable[1, 1] FP = confusionTable[1, 2] dist = sqrt(((1 - spec) - 0)^2 + (sens - 1)^2) if (!(is.element(1, state))) { lag = 0 } else { lag <- c() outbegins <- c() varA <- which(state == 1) outbegins <- c(outbegins, varA[1]) if (length(varA) > 1) { varB <- diff(varA) outbegins <- c(outbegins, varA[which(varB != 1) + 1]) } count <- 1 for (i in outbegins) { if (count < length(outbegins)) { pos <- match(1, alarm[i:min(i + penalty, (outbegins[count + 1] - 1))]) if (is.na(pos)) { lag <- c(lag, penalty) } else { lag <- c(lag, pos - 1) } } else { pos <- match(1, alarm[i:min(i + penalty, length(alarm))]) if (is.na(pos)) { lag <- c(lag, penalty) } else { lag <- c(lag, pos - 1) } } count <- count + 1 } lag <- mean(lag) } result <- list(TP = TP, FP = FP, TN = TN, FN = FN, sens = sens, spec = spec, dist = dist, mlag = lag) class(result) <- "algoQV" return(result) } ################################################### ### chunk number 2: ################################################### print.algoQV <- function(x,...) { qualityValues <- c("TP", "FP", "TN", "FN", "Sens", "Spec", "dist", "mlag" ) class(x) <- "list" result <- t(as.matrix(x)) #Give the result matrix names dimnames(result)[[2]] <- qualityValues #Print to screen print(result) invisible() } ################################################### ### chunk number 3: ################################################### xtable.algoQV <- function(x, caption = NULL, label = NULL, align = NULL, digits = NULL, display = NULL, ...) { n <- names(x) x <- matrix(x,nrow=1) dimnames(x)[[2]] <- n xtable(x,caption, label, align, digits, display, ...) } ################################################### ### chunk number 4: ################################################### # 'algo.call' calls the defined surveillance algorithms for # a specified observed vector. # # Parameter # disProgObj: object of class survRes, which includes the state chain, the observed # control: specifies which surveillance systems should be used with their parameters. # The parameter funcName and range must be specified where funcName must be # the appropriate function (without 'algo.') # range (in control): positions in observed which should be computed algo.call <- function(disProgObj, control = list( list(funcName = "rki1", range = range), list(funcName = "rki", range = range, b = 2, w = 4, actY = TRUE), list(funcName = "rki", range = range, b = 2, w = 5, actY = TRUE) ) ) { #Function to apply one algorithm to the disProgObj onecall <- function(i) { do.call(paste0("algo.", control[[i]]$funcName), alist(disProgObj = disProgObj, control = control[[i]])) } #Apply each algorithm in the control list to the disProgObj survResults <- lapply(seq_along(control), onecall) #Create some fancy naming.. names(survResults) <- lapply(survResults,function(survObj) {survObj$control$name}) #Done return(survResults) } ################################################### ### chunk number 5: ################################################### algo.compare <- function(survResList){ return(t(sapply(survResList,algo.quality))) } ################################################### ### chunk number 6: ################################################### algo.summary <- function(compMatrices){ # check if the input is large enough for summing if(length(compMatrices) < 1){ stop("It's an empty list !") } if(length(compMatrices) == 1){ return(compMatrices[[1]]) } #Stupid conversion... compMatrices <- lapply(compMatrices,function(one) { n <- dimnames(one) one <- matrix(as.numeric(one),nrow=dim(one)[[1]]) dimnames(one) <- n return(one) }) # Compute the whole result wholeResult = compMatrices[[1]] lag = matrix(0,length(compMatrices),length(wholeResult[,1])) lag[1,] = wholeResult[,8] for(i in 2:length(compMatrices)){ wholeResult = wholeResult + compMatrices[[i]] lag[i,] = compMatrices[[i]][,8] } # Sens (TP) wholeResult[,5] = wholeResult[,1]/(wholeResult[,1]+wholeResult[,4]) # Spec (TN/(TN+FP)) wholeResult[,6] = wholeResult[,3]/(wholeResult[,2]+wholeResult[,3]) # dist wholeResult[,7] = sqrt((wholeResult[,6]-1)^2 + (wholeResult[,5]-1)^2) # median(lag) for(i in 1:length(wholeResult[,1])){ wholeResult[i,8] = mean(lag[,i]) } #class(wholeResult) <- "compMatrix" # comparison matrix return(wholeResult) } surveillance/R/hhh4_amplitudeShift.R0000644000176200001440000000452313627533641017205 0ustar liggesusers## convert between sin/cos and amplitude/shift formulation ################################################### # y = gamma*sin(omega*t)+delta*cos(omega*t) # = A*sin(omega*t + phi) # with Amplitude A= sqrt(gamma^2+delta^2) # and shift phi= arctan(delta/gamma) ################################################# sinCos2amplitudeShift <- function(params){ # number of sin+cos terms lengthParams <- length(params) if(lengthParams %% 2 != 0) stop("wrong number of params") index.sin <- seq(1,lengthParams,by=2) one <- function(i=1){ coef.sin <- params[i] coef.cos <- params[i+1] amplitude <- sqrt(coef.cos^2+coef.sin^2) shift <- atan2(coef.cos, coef.sin) return(c(amplitude,shift)) } return(c(sapply(index.sin,one))) } amplitudeShift2sinCos <- function(params){ lengthParams <- length(params) if (lengthParams %% 2 != 0) stop("wrong number of params") index.A <- seq(1, lengthParams, by = 2) one <- function(i = 1) { coef.A <- params[i] coef.shift <- params[i + 1] coef.cos <- -coef.A*tan(coef.shift)/sqrt(1+tan(coef.shift)^2) coef.sin <- -coef.A/sqrt(1+tan(coef.shift)^2) return(c(coef.sin,coef.cos)) } return(c(sapply(index.A, one))) } ############################################## # y = gamma*sin(omega*t)+delta*cos(omega*t) # g(gamma,delta) = [sqrt(gamma^2+delta^2), arctan(delta/gamma) ]' # compute jacobian (dg_i(x)/dx_j)_ij ############################################# jacobianAmplitudeShift <- function(params){ # number of sin+cos terms lengthParams <- length(params) if(lengthParams %% 2 != 0) stop("wrong number of params") index.sin <- seq(1,lengthParams,by=2) # function to compute jacobian of the transformation sinCos2AmplitudeShift() one <- function(i=1){ coef.sin <- params[i] coef.cos <- params[i+1] dAmplitude.dcoef.sin <- coef.sin/sqrt(coef.cos^2+coef.sin^2) dAmplitude.dcoef.cos <- coef.cos/sqrt(coef.cos^2+coef.sin^2) dShift.dcoef.sin <- - coef.cos/(coef.cos^2+coef.sin^2) dShift.dcoef.cos <- coef.sin/(coef.cos^2+coef.sin^2) return(c(dAmplitude.dcoef.sin,dShift.dcoef.sin,dAmplitude.dcoef.cos,dShift.dcoef.cos)) } jacobi<-sapply(index.sin,one) res <- matrix(0,nrow=lengthParams,ncol=lengthParams) j<-0 for (i in index.sin){ j<-j+1 res[i:(i+1),i:(i+1)] <- jacobi[,j] } return(res) } surveillance/R/hhh4_methods.R0000644000176200001440000005451514426171115015664 0ustar liggesusers################################################################################ ### Standard methods for "hhh4" fits ### ### Copyright (C) 2010-2012 Michaela Paul, 2012-2023 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## NOTE: we also apply print.hhh4 in print.summary.hhh4() print.hhh4 <- function (x, digits = max(3, getOption("digits")-3), ...) { if (!x$convergence) { cat('Results are not reliable! Try different starting values.\n') return(invisible(x)) } if (!is.null(x$call)) { cat("\nCall: \n", paste(deparse(x$call), sep = "\n", collapse = "\n"), "\n\n", sep = "") } if (x$dim["random"] > 0) { cat('Random effects:\n') .printREmat(if (is.null(x$REmat)) .getREmat(x) else x$REmat, digits = digits) cat("\nFixed effects:\n") } else if (x$dim["fixed"] > 0) { cat("Coefficients:\n") } if (x$dim["fixed"] > 0) { print.default( format(if (is.null(x$fixef)) fixef.hhh4(x, ...) else x$fixef, digits=digits), quote = FALSE, print.gap = 2) } else cat("No coefficients\n") cat("\n") invisible(x) } ## get estimated covariance matrix of random effects .getREmat <- function (object) { ## return NULL if model has no random effects if (is.null(REmat <- object$Sigma)) return(NULL) ## hhh4()$Sigma is named since r791 only -> derive names from Sigma.orig if (is.null(dimnames(REmat))) dimnames(REmat) <- rep.int( list(sub("^sd\\.", "", names(object$Sigma.orig)[seq_len(nrow(REmat))])), 2L) attr(REmat, "correlation") <- cov2cor(REmat) attr(REmat, "sd") <- sqrt(diag(REmat)) REmat } .printREmat <- function (REmat, digits = 4) { V <- format(diag(REmat), digits=digits) corr <- format(attr(REmat, "correlation"), digits=digits) corr[upper.tri(corr,diag=TRUE)] <- "" V.corr <- cbind(V, corr, deparse.level=0) colnames(V.corr) <- c("Var", "Corr", rep.int("", ncol(corr)-1L)) print.default(V.corr, quote=FALSE) } summary.hhh4 <- function (object, maxEV = FALSE, ...) { ## do not summarize results in case of non-convergence if (!object$convergence) { cat('Results are not reliable! Try different starting values.\n') return(invisible(object)) } ret <- c(object[c("call", "convergence", "dim", "loglikelihood", "margll", "lags", "nObs", "nTime", "nUnit")], list(fixef = fixef.hhh4(object, se=TRUE, ...), ranef = ranef.hhh4(object, ...), REmat = .getREmat(object), AIC = AIC(object), BIC = BIC(object), maxEV_range = if (maxEV) unique(range(getMaxEV(object))))) class(ret) <- "summary.hhh4" return(ret) } print.summary.hhh4 <- function (x, digits = max(3, getOption("digits")-3), ...) { ## x$convergence is always TRUE if we have a summary print.hhh4(x, digits = digits) # also works for summary.hhh4-objects if (!is.null(x$maxEV_range)) cat("Epidemic dominant eigenvalue: ", paste(sprintf("%.2f", x$maxEV_range), collapse = " -- "), "\n\n") if(x$dim["random"]==0){ ## format(x$AIC,digits=4) would often yield no decimal digits (big AIC) cat('Log-likelihood: ',round(x$loglikelihood,digits=digits-2),'\n') cat('AIC: ',round(x$AIC,digits=digits-2),'\n') cat('BIC: ',round(x$BIC,digits=digits-2),'\n\n') } else { cat('Penalized log-likelihood: ',round(x$loglikelihood,digits=digits-2),'\n') cat('Marginal log-likelihood: ',round(x$margll,digits=digits-2),'\n\n') } cat('Number of units: ', x$nUnit, '\n') cat('Number of time points: ', x$nTime, '\n') if ((nOmit <- x$nTime * x$nUnit - x$nObs) > 0) cat(" (", nOmit, " observations excluded due to missingness)\n", sep = "") if (!is.null(x$lags)) { # only available since surveillance 1.8-0 if (!is.na(x$lags["ar"]) && x$lags["ar"] != 1) cat("Non-default autoregressive lag: ", x$lags[["ar"]], "\n") if (!is.na(x$lags["ne"]) && x$lags["ne"] != 1) cat("Non-default neighbor-driven lag: ", x$lags[["ne"]], "\n") } cat("\n") invisible(x) } terms.hhh4 <- function (x, ...) { if (is.null(x$terms)) interpretControl(x$control,x$stsObj) else x$terms } nobs.hhh4 <- function (object, ...) { if (object$convergence) object$nObs else NA_real_ } logLik.hhh4 <- function(object, ...) { val <- if (object$convergence) object$loglikelihood else { warning("algorithm did not converge") NA_real_ } attr(val, "df") <- if (object$dim["random"]) NA_integer_ else object$dim[["fixed"]] # use "[[" to drop the name attr(val, "nobs") <- nobs(object) class(val) <- "logLik" val } coef.hhh4 <- function(object, se=FALSE, reparamPsi=TRUE, idx2Exp=NULL, amplitudeShift=FALSE, ...) { if (identical(object$control$family, "Poisson")) reparamPsi <- FALSE coefs <- object$coefficients coefnames <- names(coefs) idx <- getCoefIdxRenamed(coefnames, reparamPsi, idx2Exp, amplitudeShift, warn=!se) ## transform and rename if (length(idx$Psi)) { coefs[idx$Psi] <- exp(-coefs[idx$Psi]) # -log(overdisp) -> overdisp coefnames[idx$Psi] <- names(idx$Psi) } if (length(idx$toExp)) { coefs[idx$toExp] <- exp(coefs[idx$toExp]) coefnames[idx$toExp] <- names(idx$toExp) } if (length(idx$AS)) { coefs[idx$AS] <- sinCos2amplitudeShift(coefs[idx$AS]) coefnames[idx$AS] <- names(idx$AS) } ## set new names names(coefs) <- coefnames if (se) { cov <- vcov.hhh4(object, reparamPsi=reparamPsi, idx2Exp=idx2Exp, amplitudeShift=amplitudeShift) cbind("Estimate"=coefs, "Std. Error"=sqrt(diag(cov))) } else coefs } vcov.hhh4 <- function (object, reparamPsi=TRUE, idx2Exp=NULL, amplitudeShift=FALSE, ...) { if (identical(object$control$family, "Poisson")) reparamPsi <- FALSE idx <- getCoefIdxRenamed(names(object$coefficients), reparamPsi, idx2Exp, amplitudeShift, warn=FALSE) newcoefs <- coef.hhh4(object, se=FALSE, reparamPsi=reparamPsi, idx2Exp=idx2Exp, amplitudeShift=amplitudeShift) ## Use multivariate Delta rule => D %*% vcov %*% t(D), D: Jacobian. ## For idx2Exp and reparamPsi, we only transform coefficients independently, ## i.e. D is diagonal (with elements 'd') d <- rep.int(1, length(newcoefs)) if (length(idx$Psi)) # h = exp(-psi), h' = -exp(-psi) d[idx$Psi] <- -newcoefs[idx$Psi] if (length(idx$toExp)) # h = exp(coef), h' = exp(coef) d[idx$toExp] <- newcoefs[idx$toExp] ## For the amplitude/shift-transformation, D is non-diagonal vcov <- if (length(idx$AS)) { D <- diag(d, length(d)) D[idx$AS,idx$AS] <- jacobianAmplitudeShift(newcoefs[idx$AS]) D %*% object$cov %*% t(D) } else t(t(object$cov*d)*d) # 30 times faster than via matrix products dimnames(vcov) <- list(names(newcoefs), names(newcoefs)) vcov } getCoefIdxRenamed <- function (coefnames, reparamPsi=TRUE, idx2Exp=NULL, amplitudeShift=FALSE, warn=TRUE) { ## indexes of overdispersion parameters idxPsi <- if (reparamPsi) { idxPsi <- grep("-log(overdisp", coefnames, fixed=TRUE) ## change labels from "-log(overdisp.xxx)" to "overdisp.xxx" names(idxPsi) <- substr(coefnames[idxPsi], start=6, stop=nchar(coefnames[idxPsi])-1L) if (length(idxPsi) == 0L) { # backward compatibility (internal psi coef # was named "overdisp" prior to r406) idxPsi <- grep("^overdisp", coefnames) names(idxPsi) <- coefnames[idxPsi] } idxPsi } else NULL ## indexes of *pairs* of sine-cosine coefficients idxAS <- if (amplitudeShift) { idx_sin <- grep(".sin(", coefnames, fixed=TRUE) idx_cos <- match(sub(".sin(", ".cos(", coefnames[idx_sin], fixed=TRUE), coefnames) if (anyNA(idx_cos)) stop("failed to detect sine-cosine pairs") idxAS <- c(rbind(idx_sin, idx_cos)) # pairwise coefficients names(idxAS) <- sub(".sin", ".A", coefnames[idxAS], fixed=TRUE) names(idxAS) <- sub(".cos", ".s", names(idxAS), fixed=TRUE) idxAS } else NULL ## indexes of coefficients to exp()-transform if (isTRUE(idx2Exp)) { idxLogCovar <- grep(".log(", coefnames, fixed = TRUE) idx2Exp <- setdiff(seq_along(coefnames), c(idxLogCovar, idxPsi, idxAS)) } else if (length(idx2Exp)) { stopifnot(is.vector(idx2Exp, mode = "numeric")) ## index sets must be disjoint if (length(idxOverlap <- intersect(c(idxPsi, idxAS), idx2Exp))) { if (warn) warning("following 'idx2Exp' were ignored due to overlap: ", paste(idxOverlap, collapse=", ")) idx2Exp <- setdiff(idx2Exp, idxOverlap) } } if (length(idx2Exp)) names(idx2Exp) <- paste0("exp(", coefnames[idx2Exp], ")") ## done list(Psi=idxPsi, AS=idxAS, toExp=idx2Exp) } fixef.hhh4 <- function (object,...) { if (object$dim[1L] > 0) { head(coef.hhh4(object, ...), object$dim[1L]) } else NULL } ranef.hhh4 <- function (object, tomatrix = FALSE, intercept = FALSE, ...) { if (object$dim[2L] > 0){ ranefvec <- tail(coef.hhh4(object, ...), object$dim[2L]) } else return(NULL) if (intercept) tomatrix <- TRUE if (!tomatrix) return(ranefvec) ## transform to a nUnits x c matrix (c %in% 1:3) model <- terms(object) idxRE <- model$indexRE idxs <- unique(idxRE) mat <- vapply(X = idxs, FUN = function (idx) { RE <- ranefvec[idxRE==idx] Z <- model$terms["Z.intercept",][[idx]] "%m%" <- get(model$terms["mult",][[idx]]) c(Z %m% RE) }, FUN.VALUE = numeric(model$nUnits), USE.NAMES = FALSE) dimnames(mat) <- list( colnames(model$response), model$namesFE[match(idxs, model$indexFE)] ) if (intercept) { FE <- object$coefficients[colnames(mat)] mat <- t(t(mat) + FE) } return(mat) } ## adaption of stats::confint.default authored by the R Core Team confint.hhh4 <- function (object, parm, level = 0.95, reparamPsi=TRUE, idx2Exp=NULL, amplitudeShift=FALSE, ...) { cf <- coef.hhh4(object, se=TRUE, reparamPsi=reparamPsi, idx2Exp=idx2Exp, amplitudeShift=amplitudeShift, ...) ## CAVE: random intercepts have no names (all "") if (missing(parm)) parm <- seq_len(nrow(cf)) pnames <- if (is.numeric(parm)) rownames(cf)[parm] else parm a <- (1 - level)/2 a <- c(a, 1 - a) pct <- paste(format(100*a, trim=TRUE, scientific=FALSE, digits=3), "%") fac <- qnorm(a) ci <- array(NA, dim = c(length(parm), 2L), dimnames = list(pnames, pct)) ses <- cf[parm,2] ci[] <- cf[parm,1] + ses %o% fac ci } ## mean predictions for a subset of 1:nrow(object$stsObj) predict.hhh4 <- function(object, newSubset = object$control$subset, type = "response", ...) { if (type == "response" && all((m <- match(newSubset, object$control$subset, nomatch=0L)) > 0)) { ## we can extract fitted means from object object$fitted.values[m,,drop=FALSE] } else { ## means for time points not fitted (not part of object$control$subset) predicted <- meanHHH(object$coefficients, terms(object), subset=newSubset) if (type=="response") predicted$mean else { type <- match.arg(type, names(predicted)) predicted[[type]] } } } ### refit hhh4-model ## ...: arguments modifying the original control list ## S: a named list to adjust the number of harmonics of the three components ## subset.upper: refit on a subset of the data up to that time point ## use.estimates: use fitted parameters as new start values update.hhh4 <- function (object, ..., S = NULL, subset.upper = NULL, use.estimates = object$convergence, evaluate = TRUE) { control <- object$control ## first modify the control list according to the components in ... extras <- list(...) control <- modifyList(control, extras) ## adjust start values control$start <- if (use.estimates) { # use parameter estimates hhh4coef2start(object) } else local({ # re-use previous 'start' specification ## for pre-1.8-2 "hhh4" objects, ## object$control$start is not necessarily a complete list: template <- eval(formals(hhh4)$control$start) template[] <- object$control$start[names(template)] template }) ## and update according to an extra 'start' argument if (!is.null(extras[["start"]])) { if (!is.list(extras$start) || is.null(names(extras$start))) { stop("'start' must be a named list, see 'help(\"hhh4\")'") } control$start[] <- mapply( FUN = function (now, extra) { if (is.null(names(extra))) { extra } else { # can retain non-extra values now[names(extra)] <- extra now } }, control$start, extras$start[names(control$start)], SIMPLIFY = FALSE, USE.NAMES = FALSE ) } ## update initial values of parametric weight function if (use.estimates && length(coefW <- coefW(object)) && ! "weights" %in% names(extras$ne)) { # only if function is unchanged control$ne$weights$initial <- coefW } ## adjust seasonality if (!is.null(S)) { stopifnot(is.list(S), !is.null(names(S)), names(S) %in% c("ar", "ne", "end")) control[names(S)] <- mapply(function (comp, S) { comp$f <- addSeason2formula(removeSeasonFromFormula(comp$f), period = object$stsObj@freq, S = S) comp }, control[names(S)], S, SIMPLIFY=FALSE, USE.NAMES=FALSE) } ## use a different time range of the data (only changing the end) ## Note: surveillance < 1.15.0 disallowed subset.upper > max(control$subset) if (isScalar(subset.upper)) { if (subset.upper < control$subset[1L]) stop("'subset.upper' is smaller than the lower bound of 'subset'") control$subset <- control$subset[1L]:subset.upper } ## fit the updated model or just return the modified control list if (evaluate) { hhh4(stsObj = object$stsObj, control = control) } else { control } } ## remove sine-cosine terms from a formula ## f: usually a model "formula", but can generally be of any class for which ## terms() and formula() apply removeSeasonFromFormula <- function (f) { fterms <- terms(f, keep.order = TRUE) ## search sine-cosine terms of the forms "sin(..." and "fe(sin(..." idxSinCos <- grep("^(fe\\()?(sin|cos)\\(", attr(fterms, "term.labels")) formula(if (length(idxSinCos)) fterms[-idxSinCos] else f) } ## remove all temporal terms from a formula removeTimeFromFormula <- function (f, timevar = "t") { fterms <- terms(f, keep.order = TRUE) containsTime <- vapply(attr(fterms, "variables")[-1L], FUN = function (x) timevar %in% all.vars(x), FUN.VALUE = TRUE, USE.NAMES = FALSE) formula(if (any(containsTime)) fterms[!containsTime] else f) } ## convert fitted parameters to a list suitable for control$start hhh4coef2start <- function (fit) { res <- list(fixed = fit$coefficients[seq_len(fit$dim[1L])], random = fit$coefficients[fit$dim[1L]+seq_len(fit$dim[2L])], sd.corr = fit$Sigma.orig) if (any(!nzchar(names(res$random)))) { # no names pre 1.8-2 names(res$random) <- NULL } res } ## extract coefficients in a list coeflist.hhh4 <- function (x, ...) { ## determine number of parameters by parameter group model <- terms(x) dim.fe.group <- unlist(model$terms["dim.fe",], recursive = FALSE, use.names = FALSE) dim.re.group <- unlist(model$terms["dim.re",], recursive = FALSE, use.names = FALSE) nFERE <- lapply(X = list(fe = dim.fe.group, re = dim.re.group), FUN = function (dims) { nParByComp <- tapply( X = dims, INDEX = factor( unlist(model$terms["offsetComp",], recursive = FALSE, use.names = FALSE), levels = 1:3, labels = c("ar", "ne", "end")), FUN = sum, simplify = TRUE) nParByComp[is.na(nParByComp)] <- 0 # component not in model nParByComp }) ## extract coefficients in a list (by parameter group) coefs <- coef.hhh4(x, se = FALSE, ...) list(fixed = coeflist.default(coefs[seq_len(x$dim[1L])], c(nFERE$fe, "neweights" = model$nd, "overdisp" = model$nOverdisp)), random = coeflist.default(coefs[x$dim[1L] + seq_len(x$dim[2L])], nFERE$re), sd.corr = x$Sigma.orig) } ## extract estimated overdispersion in dnbinom() parametrization (and as matrix) psi2size.hhh4 <- function (object, subset = object$control$subset, units = NULL) { size <- sizeHHH(object$coefficients, terms(object), subset = subset) if (!is.null(size) && !is.null(units)) { if (is.null(subset)) { warning("ignoring 'units' (not compatible with 'subset = NULL')") size } else { size[, units, drop = FALSE] } } else { size } } ## character vector of model components that are "inModel" componentsHHH4 <- function (object) names(which(sapply(object$control[c("ar", "ne", "end")], "[[", "inModel"))) ## deviance residuals residuals.hhh4 <- function (object, type = c("deviance", "response"), ...) { type <- match.arg(type) obs <- observed(object$stsObj)[object$control$subset,] fit <- fitted(object) if (type == "response") return(obs - fit) ## deviance residuals ## Cf. residuals.ah, it calculates: ## deviance = sign(y - mean) * sqrt(2 * (distr(y) - distr(mean))) ## pearson = (y - mean)/sqrt(variance) dev.resids <- if (identical(object$control$family, "Poisson")) { poisson()$dev.resids } else { size <- if (identical(object$control$family, "NegBin1")) { psi2size.hhh4(object, subset = NULL) } else { psi2size.hhh4(object) # CAVE: a matrix -> non-standard "size" } negative.binomial(size)$dev.resids } di2 <- dev.resids(y=obs, mu=fit, wt=1) sign(obs-fit) * sqrt(pmax.int(di2, 0)) } ## extract the formulae of the three log-linear predictors formula.hhh4 <- function (x, ...) { lapply(x$control[c("ar", "ne", "end")], "[[", "f") } ## decompose the fitted mean of a "hhh4" model returning an array ## with dimensions (t, i, j), where the first j index is "endemic" decompose.hhh4 <- function (x, coefs = x$coefficients, ...) { ## get three major components from meanHHH() function meancomps <- meanHHH(coefs, terms(x)) ## this contains c("endemic", "epi.own", "epi.neighbours") ## but we really want the mean by neighbour neArray <- c(meancomps$ne.exppred) * neOffsetArray(x, coefW(coefs)) ##<- ne.exppred is (t, i) and recycled for (t, i, j) stopifnot(all.equal(rowSums(neArray, dims = 2), meancomps$epi.neighbours, check.attributes = FALSE)) ## add autoregressive part to neArray diagidx <- cbind(c(row(meancomps$epi.own)), c(col(meancomps$epi.own)), c(col(meancomps$epi.own))) ## usually: neArray[diagidx] == 0 neArray[diagidx] <- neArray[diagidx] + meancomps$epi.own ## add endemic component to the array res <- array(c(meancomps$endemic, neArray), dim = dim(neArray) + c(0, 0, 1), dimnames = with(dimnames(neArray), list(t=t, i=i, j=c("endemic",j)))) stopifnot(all.equal(rowSums(res, dims = 2), meancomps$mean, check.attributes = FALSE)) res } ## get the w_{ji} Y_{j,t-1} values from a hhh4() fit ## (i.e., before summing the neighbourhood component over j) ## in an array with dimensions (t, i, j) neOffsetArray <- function (object, pars = coefW(object), subset = object$control$subset) { ## initialize array ordered as (j, t, i) for apply() below res <- array(data = 0, dim = c(object$nUnit, length(subset), object$nUnit), dimnames = list( "j" = colnames(object$stsObj), "t" = rownames(object$stsObj)[subset], "i" = colnames(object$stsObj))) ## calculate array values if the fit has an NE component if ("ne" %in% componentsHHH4(object)) { W <- getNEweights(object, pars = pars) Y <- observed(object$stsObj) tm1 <- subset - object$control$ne$lag is.na(tm1) <- tm1 <= 0 tYtm1 <- t(Y[tm1,,drop=FALSE]) res[] <- apply(W, 2L, function (wi) tYtm1 * wi) offset <- object$control$ne$offset res <- if (length(offset) > 1L) { offset <- offset[subset,,drop=FALSE] res * rep(offset, each = object$nUnit) } else { res * offset } ## stopifnot(all.equal( ## colSums(res), # sum over j ## terms(object)$offset$ne(pars)[subset,,drop=FALSE], ## check.attributes = FALSE)) } ## permute dimensions as (t, i, j) aperm(res, perm = c(2L, 3L, 1L), resize = TRUE) } ## compare two hhh4 fits ignoring at least the "runtime" and "call" elements all.equal.hhh4 <- function (target, current, ..., ignore = NULL) { if (!inherits(target, "hhh4")) return("'target' is not a \"hhh4\" object") if (!inherits(current, "hhh4")) return("'current' is not a \"hhh4\" object") ignore <- unique.default(c(ignore, "runtime", "call")) target[ignore] <- current[ignore] <- list(NULL) NextMethod("all.equal") } surveillance/R/epidata_animate.R0000644000176200001440000001361714426171115016411 0ustar liggesusers################################################################################ ### Two types of spatio-temporal animations of "epidata" are supported: ### - sequential plots regardless of time between events (i.e. only ordering) ### - chronological animation with timer ### ### Copyright (C) 2008-2009, 2012, 2014, 2019 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ animate.epidata <- function (object, ...) { s <- summary(object) animate.summary.epidata(s, ...) } animate.summary.epidata <- function (object, main = "An animation of the epidemic", pch = 19, col = c(3, 2, gray(0.6)), time.spacing = NULL, sleep = quote(5/.nTimes), legend.opts = list(), timer.opts = list(), end = NULL, generate.snapshots = NULL, ...) { counters <- object[["counters"]] # remove pseudo-R-events, which come before S-event directSevents <- which(duplicated(counters[["time"]])) counters_noPseudoR <- if (length(directSevents)) { counters[-(directSevents-1), ] } else { counters } # remove initial row and keep essential columns eventTable <- counters_noPseudoR[-1, c("time", "type", "id")] eventTable[["type"]] <- unclass(eventTable[["type"]]) # get integer codes .nTimes <- nrow(eventTable) # extract initial individual information (id, at-risk, coordinates) coords <- object[["coordinates"]] d <- ncol(coords) if (d > 2L) { stop("spatial plotting in more than two dimensions is not implemented") } else if (d == 1L) { coords <- cbind(coords, 0) } else if (d == 0L) { stop ("'object' does not contain any defined coordinates") } # plot the initial state pch <- rep(pch, length.out = 3) col <- rep(col, length.out = 3) isInitiallyInfected <- rownames(coords) %in% object[["initiallyInfected"]] plot(coords, pch = ifelse(isInitiallyInfected, pch[2L], pch[1L]), col = ifelse(isInitiallyInfected, col[2L], col[1L]), main = main, ...) if (is.list(legend.opts)) { if (is.null(legend.opts[["x",exact=TRUE]])) legend.opts$x <- "topright" if (is.null(legend.opts$legend)) legend.opts$legend <- c("susceptible", "infectious", "removed") if (is.null(legend.opts$col)) legend.opts$col <- col if (is.null(legend.opts$pch)) legend.opts$pch <- pch do.call(legend, legend.opts) } # animate the epidemic by iteratively re-drawing points at the coordinates sleep <- eval(sleep) if (is.null(time.spacing)) { # plot events sequentially for(i in seq_len(.nTimes)) { if (dev.interactive()) Sys.sleep(sleep) tmp <- eventTable[i,] # c(time, type, id) points(coords[as.character(tmp[["id"]]),,drop=FALSE], pch = pch[tmp[["type"]]], col = col[tmp[["type"]]]) } } else { # plot events chronologically if (is.null(end)) end <- eventTable[.nTimes, "time"] + time.spacing timeGrid <- seq(from = time.spacing, to = end, by = time.spacing) timeWidth <- nchar(timeGrid[length(timeGrid)]) timeDigits <- if (grepl(".", as.character(time.spacing), fixed = TRUE)) { nchar(strsplit(as.character(time.spacing), split = ".", fixed = TRUE)[[1L]][2L]) } else 0 form <- paste("%", timeWidth, ".", timeDigits, "f", sep = "") if (is.list(timer.opts)) { if (is.null(timer.opts[["x",exact=TRUE]])) timer.opts$x <- "bottomright" if (is.null(timer.opts$title)) timer.opts$title <- "time" if (is.null(timer.opts$box.lty)) timer.opts$box.lty <- 0 if (is.null(timer.opts$adj)) timer.opts$adj <- c(0.5,0.5) if (is.null(timer.opts$inset)) timer.opts$inset <- 0.01 if (is.null(timer.opts$bg)) timer.opts$bg <- "white" do.call(legend, c(list(legend = sprintf(form, 0)), timer.opts)) } oldtp <- tp <- attr(object, "timeRange")[1L] i <- 1L # to be used in the file argument in dev.print if (is.vector(generate.snapshots, mode="character") && length(generate.snapshots) == 1L && requireNamespace("animation")) { img.name <- generate.snapshots ani.dev <- animation::ani.options("ani.dev") if (is.character(ani.dev)) ani.dev <- get(ani.dev) imgdir <- animation::ani.options("imgdir") imgtype <- animation::ani.options("ani.type") generate.snapshots <- list( device = ani.dev, file = quote(file.path(imgdir, paste0(img.name,i,".",imgtype))), width = animation::ani.options("ani.width"), height = animation::ani.options("ani.height") ) } if (is.list(generate.snapshots)) { do.call(dev.print, generate.snapshots) } for(i in 1L+seq_along(timeGrid)) { tp <- timeGrid[i-1L] if (dev.interactive()) Sys.sleep(sleep) timeIndex <- which(eventTable[["time"]] > oldtp & eventTable[["time"]] <= tp) if (length(timeIndex) > 0L) { tmp <- eventTable[timeIndex,] # c(time, type, id) points(coords[as.character(tmp[["id"]]),,drop=FALSE], pch = pch[tmp[["type"]]], col = col[tmp[["type"]]]) } if (is.list(timer.opts)) { do.call(legend, c(list(legend = sprintf(form,tp)), timer.opts)) } oldtp <- tp if (is.list(generate.snapshots)) { do.call(dev.print, generate.snapshots) } } } invisible(NULL) } surveillance/R/plapply.R0000644000176200001440000001070313621207062014753 0ustar liggesusers################################################################################ ### Parallelized lapply (wrapping around mclapply and parLapply) ### taking care of the random seed and printing progress information ### ### Copyright (C) 2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ plapply <- function (X, FUN, ..., .parallel = 1, .seed = NULL, .verbose = TRUE) { if (!(useCluster <- inherits(.parallel, "cluster"))) { stopifnot(length(.parallel) == 1L, is.vector(.parallel, "numeric"), .parallel >= 1) .parallel <- as.vector(.parallel, mode = "integer") if (.Platform$OS.type == "windows" && .parallel > 1L) { useCluster <- TRUE .parallel <- parallel::makeCluster(.parallel) on.exit(parallel::stopCluster(.parallel)) } } FUN <- match.fun(FUN) .FUN <- if (useCluster || is.primitive(FUN)) { FUN # no support for reporting to the master || add.on.exit } else { # be verbose on.exit of FUN verboseExpr <- if (isTRUE(.verbose)) { ## progress bar or dots if (.parallel == 1L && interactive()) { env <- new.env(hash = FALSE, parent = environment(FUN)) environment(FUN) <- env # where the progress bar lives env$pb <- txtProgressBar(min = 0, max = length(X), initial = 0, style = 3) on.exit(close(env$pb), add = TRUE) quote(setTxtProgressBar(pb, pb$getVal() + 1L)) } else { on.exit(cat("\n"), add = TRUE) quote(cat(".")) } } else if (is.call(.verbose) || is.expression(.verbose)) { ## custom call or expression .verbose } else if (is.character(.verbose)) { ## custom progress symbol on.exit(cat("\n"), add = TRUE) substitute(cat(.verbose)) } # else NULL (no output) ## add on.exit(verboseExpr) to body(FUN) do.call(add.on.exit, list(FUN, verboseExpr)) } ## set random seed for reproducibility if (!is.null(.seed)) { if (useCluster) { parallel::clusterSetRNGStream(cl = .parallel, iseed = .seed) } else { if (!exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE)) { set.seed(NULL) # initialize } .orig.seed <- get(".Random.seed", envir = .GlobalEnv) on.exit(assign(".Random.seed", .orig.seed, envir = .GlobalEnv), add = TRUE) if (.parallel == 1L) { set.seed(seed = .seed) } else { stopifnot(requireNamespace("parallel", quietly = TRUE)) ## Note @ R 3.1.3: this loading of package "parallel" ## before set.seed() is crucial; otherwise, the first run of ## plapply() would not be reproducible !!! set.seed(seed = .seed, kind = "L'Ecuyer-CMRG") parallel::mc.reset.stream() } } } ## rock'n'roll if (useCluster) { parallel::parLapply(cl = .parallel, X = X, fun = .FUN, ...) } else if (.parallel == 1L) { lapply(X = X, FUN = .FUN, ...) } else { # use forking parallel::mclapply(X = X, FUN = .FUN, ..., mc.preschedule = TRUE, mc.set.seed = TRUE, mc.silent = FALSE, mc.cores = .parallel) } } ## add an on.exit() statement at the beginning of a function add.on.exit <- function (FUN, expr) { FUN <- match.fun(FUN) if (is.null(expr <- substitute(expr))) { return(FUN) } if (is.primitive(FUN)) { # body(FUN) is NULL stop("not implemented for primitive functions") } onexitexpr <- substitute(on.exit(expr)) obody <- body(FUN) body(FUN) <- if (is.call(obody) && identical(as.name("{"), obody[[1L]])) { ## body(FUN) is a braced expression (usual case) ## and we insert on.exit(expr) directly after "{" as.call(append(x = as.list(obody), values = onexitexpr, after = 1L)) } else { ## body(FUN) is a symbol or a single call like UseMethod("print") as.call(c(as.name("{"), onexitexpr, obody)) } FUN } surveillance/R/sim_pointSource.R0000644000176200001440000000423214615162374016466 0ustar liggesusers################################################### ### chunk number 1: ################################################### # Programme to simulate epidemies which were # introduced by point sources. # The basis of this proagramme is a combination of # a Hidden Markov Model (to get random dates # for outbreaks) and a simple Model to simulate # the epidemy. # # Parameters: # r - probability to get a new epidemy at time i if there was one # at time i-1 # p - probability to get no new epidemy at time i if there was none # at time i-1 # length - number of timesteps to visit # # Parameters for the background: # A - Amplitude, default = 1. # alpha - Incidence, default = 1. # beta - time dependent regression coefficient, default = 0. # phi - weeks of seaonal move, default = 0. # frequency - frequency of the sinus, default = 1. # state - a eventually given markov chain, # which defines the status at this time (outbreak or not) # K - additional weight for an outbreak sim.pointSource <- function(p = 0.99, r = 0.01, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K){ if(is.null(state)){ # create a markov-chain state <- matrix(data = 0, ncol = 1, nrow = length) state[1] <- 0 #hoehle - fix: rbinom(1,1,0.5) # always begin with a zero # create the transition matrix transitionMatrix <- matrix(data = c(p, (1-r),(1-p), r), nrow = 2, ncol = 2) if(length(state) > 1){ # just do it if there is a preceding value for (i in 2:length){ # check the matrix for the correct line and take the right # probability. The last value of state is the newest. state[i] <- rbinom(1,1,transitionMatrix[state[i-1] + 1, 2]) } } } # go sure to have the right length as parameter length <- length(state) observed <-sim.seasonalNoise(A, alpha, beta, phi, length, frequency, state, K)$seasonalBackground result <- list(observed = observed, state = state, A = A, alpha = alpha, beta = beta, K = K, p = p, r = r, freq=52, start=c(2001,1)) class(result) = "disProg" # for disease progress return(result) } surveillance/R/hhh4_plot.R0000644000176200001440000010572214430705133015172 0ustar liggesusers################################################################################ ### Plot method(s) for fitted "hhh4" models ### ### Copyright (C) 2010-2012 Michaela Paul, 2012-2023 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ plot.hhh4 <- function (x, type = c("fitted", "season", "maxEV", "maps", "ri", "neweights"), ...) { stopifnot(x$convergence) cl <- sys.call() # not match.call() because plotHHH4_season() has no 'x' ## remove the type argument from the call if (is.null(names(cl)) && nargs() > 1L) { # unnamed call plot(x, type) cl[[3L]] <- NULL # remove the second argument } else { cl$type <- NULL } cl[[1L]] <- as.name(paste("plotHHH4", match.arg(type), sep="_")) eval(cl, envir = parent.frame()) } ### ### Time series of fitted component means and observed counts for selected units ### plotHHH4_fitted <- function (x, units = 1, names = NULL, col = c("grey85", "blue", "orange"), pch = 19, pt.cex = 0.6, pt.col = 1, par.settings = list(), legend = TRUE, legend.args = list(), legend.observed = FALSE, decompose = NULL, total = FALSE, meanHHH = NULL, ...) { stopifnot(inherits(x, "hhh4")) if (total) { units <- "Overall" # only used as a label } else if (is.null(units)) { units <- seq_len(x$nUnit) } if (!is.null(names)) stopifnot(length(units) == length(names)) if (isTRUE(decompose)) decompose <- colnames(x$stsObj) ## get decomposed mean => no need to compute it in each plotHHH4_fitted1() if (is.null(meanHHH)) { meanHHH <- if (is.null(decompose)) { meanHHH(x$coefficients, terms(x)) } else { decompose.hhh4(x) } } ## check color vector col <- if (is.null(decompose) && length(col) == 4) { ## compatibility with surveillance < 1.10-0 pt.col <- col[4L] rev(col[-4L]) } else { plotHHH4_fitted_check_col_decompose(col, decompose) } ## setup graphical parameters if (is.list(par.settings)) { par.defaults <- list(mfrow = sort(n2mfrow(length(units))), mar = c(4,4,2,0.5)+.1, las = 1) par.settings <- modifyList(par.defaults, par.settings) opar <- do.call("par", par.settings) on.exit(par(opar)) } ## legend options if (is.logical(legend)) legend <- which(legend) if (!is.list(legend.args)) { if (length(legend) > 0) warning("ignored 'legend' since 'legend.args' is not a list") legend <- integer(0L) } if (length(legend) > 0) { legendidx <- 1L + c( if (legend.observed && !is.na(pch)) 0L, if (is.null(decompose)) { which(c("ne","ar","end") %in% componentsHHH4(x)) } else seq_along(col)) default.args <- list( x="topright", col=c(pt.col,rev(col))[legendidx], lwd=6, lty=c(NA,rep.int(1,length(col)))[legendidx], pch=c(pch,rep.int(NA,length(col)))[legendidx], pt.cex=pt.cex, pt.lwd=1, bty="n", inset=0.02, legend=if (is.null(decompose)) { c("observed","spatiotemporal","autoregressive","endemic")[legendidx] } else c("observed", rev(decompose), "endemic")[legendidx] ) legend.args <- modifyList(default.args, legend.args) } ## plot fitted values region by region meanHHHunits <- vector(mode="list", length=length(units)) names(meanHHHunits) <- if (is.character(units)) units else colnames(x$stsObj)[units] for(i in seq_along(units)) { meanHHHunits[[i]] <- plotHHH4_fitted1(x, unit=units[i], main=names[i], col=col, pch=pch, pt.cex=pt.cex, pt.col=pt.col, decompose=decompose, total=total, meanHHH=meanHHH, ...) if (i %in% legend) do.call("legend", args=legend.args) } invisible(meanHHHunits) } plotHHH4_fitted_check_col_decompose <- function (col, decompose) { if (is.null(decompose)) { stopifnot(length(col) == 3L) } else { nUnit <- length(decompose) if (length(col) == nUnit) { col <- c("grey85", col) # first color is for "endemic" } else if (length(col) != 1L + nUnit) { warning("'col' should be of length ", 1L + nUnit) col <- c(col[1L], rep_len(col[-1L], nUnit)) } } col } ### plot estimated component means for a single region plotHHH4_fitted1 <- function(x, unit=1, main=NULL, col=c("grey85", "blue", "orange"), pch=19, pt.cex=0.6, pt.col=1, border=col, start=x$stsObj@start, end=NULL, xaxis=NULL, xlim=NULL, ylim=NULL, xlab="", ylab="No. infected", hide0s=FALSE, decompose=NULL, total=FALSE, meanHHH=NULL) { stopifnot(inherits(x, "hhh4")) stsObj <- x$stsObj if (!total && is.character(unit) && is.na(unit <- match(.unit <- unit, colnames(stsObj)))) stop("region '", .unit, "' does not exist") if (is.null(main)) main <- if (total) "Overall" else colnames(stsObj)[unit] if (isTRUE(decompose)) decompose <- colnames(stsObj) ## get observed counts obs <- if (total) rowSums(observed(stsObj)) else observed(stsObj)[,unit] ## time range for plotting start0 <- yearepoch2point(stsObj@start, stsObj@freq, toleft=TRUE) start <- yearepoch2point(start, stsObj@freq) tp <- start0 + seq_along(obs)/stsObj@freq # all observation time points if (start < start0 || start > tp[length(tp)]) stop("'start' is not within the time range of 'x$stsObj'") end <- if(is.null(end)) tp[length(tp)] else yearepoch2point(end,stsObj@freq) stopifnot(start < end) tpInRange <- which(tp >= start & tp <= end) # plot only those tpInSubset <- intersect(x$control$subset, tpInRange) # fitted time points ## use time indexes as x-values for use of addFormattedXAxis() if (is.list(xaxis) || identical(xaxis, NA)) { tp <- seq_along(obs) start <- tpInRange[1L] end <- tpInRange[length(tpInRange)] } ## get fitted component means if (is.null(meanHHH)) { meanHHH <- if (is.null(decompose)) { meanHHH(x$coefficients, terms(x)) } else { decompose.hhh4(x) } } meanHHHunit <- if (is.null(decompose)) { if (total) { sapply(meanHHH, rowSums) } else { sapply(meanHHH, "[", i=TRUE, j=unit) } } else { if (!setequal(decompose, dimnames(meanHHH)[[3L]][-1L])) stop("'decompose' must be (a permutation of) the fitted units") if (total) { apply(meanHHH[,,c("endemic",decompose)], c(1L, 3L), sum) } else { meanHHH[,unit,c("endemic",decompose)] } } stopifnot(is.matrix(meanHHHunit), !is.null(colnames(meanHHHunit)), nrow(meanHHHunit) == length(x$control$subset)) meanHHHunit <- meanHHHunit[x$control$subset %in% tpInRange,,drop=FALSE] ## check color vector col <- if (is.null(decompose) && length(col) == 4L) { ## compatibility with surveillance < 1.10-0 pt.col <- col[4L] rev(col[-4L]) } else { plotHHH4_fitted_check_col_decompose(col, decompose) } ## establish basic plot window if (is.null(ylim)) ylim <- c(0, max(obs[tpInRange],na.rm=TRUE)) plot(c(start,end), ylim, xlim=xlim, xlab=xlab, ylab=ylab, type="n", xaxt = if (is.list(xaxis)) "n" else par("xaxt")) if (is.list(xaxis)) do.call(addFormattedXAxis, c(list(x = stsObj), xaxis)) title(main=main, line=0.5) ## draw polygons if (is.null(decompose)) { non0 <- which(c("end", "ar", "ne") %in% componentsHHH4(x)) plotComponentPolygons( x = tp[tpInSubset], y = meanHHHunit[,c("endemic", "epi.own", "epi.neighbours")[non0],drop=FALSE], col = col[non0], border = border[non0], add = TRUE) } else { non0 <- apply(X = meanHHHunit > 0, MARGIN = 2L, FUN = any) plotComponentPolygons(x = tp[tpInSubset], y = meanHHHunit[, non0, drop = FALSE], col = col[non0], border = border[non0], add = TRUE) } ## add observed counts within [start;end] ptidx <- if (hide0s) intersect(tpInRange, which(obs > 0)) else tpInRange points(tp[ptidx], obs[ptidx], col=pt.col, pch=pch, cex=pt.cex) ## invisibly return the fitted component means for the selected region invisible(meanHHHunit) } ### function which does the actual plotting of the polygons plotComponentPolygons <- function (x, y, col = 1:6, border = col, add = FALSE) { if (!is.vector(x, mode = "numeric") || length(x) == 0 || is.unsorted(x, strictly = TRUE)) stop("'x' must be a strictly increasing sequence of time points") stopifnot(is.numeric(y), # y >= 0 nrow(y <- as.matrix(y)) == (nTime <- length(x))) yc <- if ((nPoly <- ncol(y)) > 1L) { apply(X = y, MARGIN = 1L, FUN = function(comps) if (anyNA(comps)) `is.na<-`(comps) else cumsum(comps)) # nPoly x nTime } else t(y) if (!add) { ## establish basic plot window plot(range(x), c(0, max(yc[nPoly,], na.rm = TRUE)), type = "n") } ## recycle graphical parameters col <- rep_len(col, nPoly) border <- rep_len(border, nPoly) ## draw 0-anchored polygons (piecewise if y contains missing values) draw1 <- function (x, y, col, border) { if (!is.na(nextNA <- match(NA_real_, y))) { if (nextNA < length(y)) { remainder <- (nextNA+1L):length(y) draw1(x[remainder], y[remainder], col, border) } if (nextNA == 1L) return(invisible()) x <- x[seq_len(nextNA-1L)] y <- y[seq_len(nextNA-1L)] } ## cat("drawing from x =", paste0(range(x), collapse=" to "), "\n") polygon(c(x[1L], x, x[length(x)]), y = c(0, y, 0), col = col, border = border) } for (poly in nPoly:1) { draw1(x, yc[poly, ], col[poly], border[poly]) } } ### ### Maps of the fitted mean components averaged over time ### plotHHH4_maps <- function (x, which = c("mean", "endemic", "epi.own", "epi.neighbours"), prop = FALSE, main = which, zmax = NULL, col.regions = NULL, labels = FALSE, sp.layout = NULL, ..., map = x$stsObj@map, ## aspect = mapasp(map), # currently hard-coded meanHHH = NULL) { stopifnot(inherits(x, "hhh4")) which <- match.arg(which, several.ok = TRUE) if (is.null(col.regions)) col.regions <- .hcl.colors(10) ## extract district-specific mean components if (is.null(meanHHH)) { meanHHH <- meanHHH(x$coefficients, terms(x)) } ## select relevant components and convert to an array meanHHH <- simplify2array( meanHHH[c("mean", "endemic", "epi.own", "epi.neighbours")], higher = TRUE) ## convert to proportions if (prop) { meanHHH[,,-1L] <- meanHHH[,,-1L,drop=FALSE] / c(meanHHH[,,1L]) } ## select only 'which' components meanHHH <- meanHHH[,,which,drop=FALSE] ## check map map <- as(map, "SpatialPolygonsDataFrame") if (!all(dimnames(meanHHH)[[2L]] %in% row.names(map))) { stop("'row.names(map)' do not cover all fitted districts") } ## average over time comps <- as.data.frame(colMeans(meanHHH, dims = 1)) ## attach to map data map@data <- cbind(map@data, comps[row.names(map),,drop=FALSE]) ## color key range if (is.null(zmax)) { zmax <- if (prop) { ceiling(10*sapply(comps, max))/10 } else ceiling(sapply(comps, max)) ## sub-components should have the same color range .idxsub <- setdiff(seq_along(zmax), match("mean", names(zmax))) zmax[.idxsub] <- suppressWarnings(max(zmax[.idxsub])) } ## add sp.layout item for district labels if (!is.null(layout.labels <- layout.labels(map, labels))) { sp.layout <- c(sp.layout, list(layout.labels)) } ## produce maps grobs <- mapply( FUN = function (zcol, main, zmax) if (is.na(zmax)) { # automatic color breaks over range of values spplot(map, zcol = zcol, main = main, cuts = length(col.regions) - 1L, col.regions = col.regions, sp.layout = sp.layout, aspect = mapasp(map), ...) } else { # breakpoints from 0 to zmax spplot(map, zcol = zcol, main = main, at = seq(0, zmax, length.out = length(col.regions) + 1L), col.regions = col.regions, sp.layout = sp.layout, aspect = mapasp(map), ...) }, zcol = names(comps), main = main, zmax = zmax, SIMPLIFY = FALSE, USE.NAMES = FALSE) if (length(grobs) == 1L) { grobs[[1L]] } else { mfrow <- sort(n2mfrow(length(grobs))) gridExtra::grid.arrange(grobs = grobs, nrow = mfrow[1L], ncol = mfrow[2L]) } } ### ### Map of estimated random intercepts of a specific component ### plotHHH4_ri <- function (x, component, exp = FALSE, at = list(n = 10), col.regions = cm.colors(100), colorkey = TRUE, labels = FALSE, sp.layout = NULL, ## aspect = mapasp(map), # currently hard-coded gpar.missing = list(col="darkgrey", lty=2, lwd=2), ...) { stopifnot(inherits(x, "hhh4")) ranefmatrix <- ranef.hhh4(x, tomatrix=TRUE) if (is.null(ranefmatrix)) stop("model has no random effects") stopifnot(length(component) == 1L) if (is.na(comp <- pmatch(component, colnames(ranefmatrix)))) stop("'component' must (partially) match one of ", paste(dQuote(colnames(ranefmatrix)), collapse=", ")) map <- as(x$stsObj@map, "SpatialPolygonsDataFrame") if (length(map) == 0L) stop("'x$stsObj' has no map") map$ranef <- ranefmatrix[,comp][row.names(map)] if (is.list(at)) { if (is.null(at[["n"]])) at$n <- 10 if (is.null(at[["range"]])) { at$range <- c(-1, 1) * max(abs(map$ranef), na.rm = TRUE) # 0-centered } else if (exp) { # custom range given on exp-scale stopifnot(at$range > 0) at$range <- log(at$range) } at <- seq(at$range[1L], at$range[2L], length.out = at$n) ## include max value (levelplot uses right-open intervals) at[length(at)] <- at[length(at)] + sqrt(.Machine$double.eps) } else { stopifnot(is.numeric(at), length(at) > 2) if (exp) { # custom breaks given on exp-scale stopifnot(at > 0) at <- log(at) } } rng <- range(map$ranef, na.rm = TRUE) if (rng[1] < at[1] | rng[2] >= at[length(at)]) { if (exp) rng <- exp(rng) warning(paste0( sprintf("color breaks ('at') do not span range of data (%.3g,%.3g)", rng[1], rng[2]), if (exp) " (exp-scale)")) } if (isTRUE(colorkey)) colorkey <- list() if (exp && is.list(colorkey) && is.null(colorkey[["labels"]])) { ## use exp-scale axis labels if (is.null(nint <- colorkey[["tick.number"]])) nint <- 7 lab <- if (requireNamespace("scales", quietly = TRUE)) { scales::log_breaks(n = nint)(exp(at)) } else { axisTicks(log10(exp(range(at))), log = TRUE, nint = nint) } ## workaround colorkey labeling bug in lattice (see https://github.com/deepayan/lattice/pull/22) lab <- lab[log(lab) > at[1]] colorkey$labels <- list(at = log(lab), labels = lab) } if (is.list(gpar.missing) && anyNA(map$ranef)) { sp.layout <- c(sp.layout, c(list("sp.polygons", map[is.na(map$ranef),]), gpar.missing)) } if (!is.null(layout.labels <- layout.labels(map, labels))) { sp.layout <- c(sp.layout, list(layout.labels)) } spplot(map[!is.na(map$ranef),], zcol = "ranef", sp.layout = sp.layout, col.regions = col.regions, at = at, colorkey = colorkey, aspect = mapasp(map), ...) } ### ### Plot the course of the dominant eigenvalue of one or several hhh4-fits ### plotHHH4_maxEV <- function (..., matplot.args = list(), refline.args = list(), legend.args = list()) { objnams <- unlist(lapply(match.call(expand.dots=FALSE)$..., deparse)) objects <- getHHH4list(..., .names = objnams) ## get time points epoch <- attr(objects, "epoch") start <- attr(objects, "start") freq <- attr(objects, "freq") start0 <- yearepoch2point(start, freq, toleft=TRUE) tp <- start0 + seq_along(epoch) / freq ## compute course of dominant eigenvalue for all models maxEV <- sapply(objects, getMaxEV, simplify=TRUE, USE.NAMES=TRUE) ## line style matplot.args <- modifyList( list(type="l", col=c(1,2,6,3), lty=c(1,3,2,4), lwd=1.7, cex=1, pch=NULL, xlab="", ylab="dominant eigenvalue", ylim=c(0,max(2,maxEV))), matplot.args) ## main plot do.call("matplot", c(list(x=tp, y=maxEV), matplot.args)) ## add reference line if (is.list(refline.args)) do.call("abline", modifyList(list(h=1, lty=3, col="grey"), refline.args)) ## add legend if (missing(legend.args) && length(objects) == 1) legend.args <- NULL # omit legend if (is.list(legend.args)) { legend.args <- modifyList( c(list(x="topright", inset=0.02, legend=names(objects), bty="n"), matplot.args[c("col", "lwd", "lty", "pch")], with(matplot.args, list(pt.cex=cex, text.col=col))), legend.args) do.call("legend", legend.args) } ## done invisible(maxEV) } getMaxEV <- function (x) { stopifnot(inherits(x, "hhh4")) Lambda <- createLambda(x) if (identical(type <- attr(Lambda, "type"), "zero")) { rep.int(0, nrow(x$stsObj)) } else { diagonal <- identical(type, "diagonal") vapply(X = seq_len(nrow(x$stsObj)), FUN = function (t) maxEV(Lambda(t), symmetric = FALSE, diagonal = diagonal), FUN.VALUE = 0, USE.NAMES = FALSE) } } ## generate a function that computes the Lambda_t matrix createLambda <- function (object) { nTime <- nrow(object$stsObj) nUnit <- object$nUnit if (identical(componentsHHH4(object), "end")) { # no epidemic components zeromat <- matrix(0, nUnit, nUnit) Lambda <- function (t) zeromat attr(Lambda, "type") <- "zero" return(Lambda) } exppreds <- get_exppreds_with_offsets(object) W <- getNEweights(object) Wt <- if (is.null(W)) { NULL } else if (is.matrix(W)) { function (t) W } else { function (t) W[,,t] } type <- NULL Lambda <- if (is.null(Wt)) { # no neighbourhood component type <- "diagonal" function (t) { stopifnot(isScalar(t) && t > 0 && t <= nTime) diag(exppreds$ar[t,], nUnit, nUnit) } } else { function (t) { stopifnot(isScalar(t) && t > 0 && t <= nTime) Lambda <- exppreds$ne[t,] * t(Wt(t)) diag(Lambda) <- diag(Lambda) + exppreds$ar[t,] Lambda } } attr(Lambda, "type") <- type Lambda } ## extract exppreds multiplied with offsets ## note: theta = coef(object) would also work since psi is not involved here get_exppreds_with_offsets <- function (object, subset = seq_len(nrow(object$stsObj)), theta = object$coefficients) { means <- meanHHH(theta, terms(object), subset = subset) res <- sapply(X = c("ar", "ne", "end"), FUN = function (comp) { exppred <- means[[paste0(comp, ".exppred")]] offset <- object$control[[comp]]$offset if (length(offset) > 1) offset <- offset[subset,,drop=FALSE] exppred * offset }, simplify = FALSE, USE.NAMES = TRUE) res } ## determine the dominant eigenvalue of the Lambda matrix maxEV <- function (Lambda, symmetric = isSymmetric.matrix(Lambda), diagonal = FALSE) { maxEV <- if (diagonal) { max(Lambda) # faster than max(diag(Lambda)) } else { eigen(Lambda, symmetric = symmetric, only.values = TRUE)$values[1L] } ## dominant eigenvalue may be complex if (is.complex(maxEV)) { if (Im(maxEV) == 0) { # if other eigenvalues are complex Re(maxEV) } else { warning("dominant eigenvalue is complex, using its absolute value") abs(maxEV) } } else { maxEV } } ### ### Plot estimated seasonality (sine-cosine terms) of one or several hhh4-fits ### either as multiplicative effect on the 'components' (intercept=FALSE) ### or with intercept=TRUE, which only makes sense if there are no further ### non-centered covariates and offsets. ### plotHHH4_season <- function (..., components = NULL, intercept = FALSE, xlim = NULL, ylim = NULL, xlab = NULL, ylab = "", main = NULL, par.settings = list(), matplot.args = list(), legend = NULL, legend.args = list(), refline.args = list(), unit = 1, period = NULL) # for harmonics with period > freq { objnams <- unlist(lapply(match.call(expand.dots=FALSE)$..., deparse)) objects <- getHHH4list(..., .names = objnams) freq <- attr(objects, "freq") if (is.null(period)) period <- freq components <- if (is.null(components)) { intersect(c("end", "ar", "ne"), unique(unlist( lapply(objects, componentsHHH4), use.names = FALSE))) } else { match.arg(components, choices = c("ar", "ne", "end", "maxEV"), several.ok = TRUE) } ## x-axis if (is.null(xlab)) xlab <- if (freq==52) "week" else if (freq==12) "month" else "time" ## auxiliary function for an argument list "x" with named "defaults" list withDefaults <- function(x, defaults) { if (is.null(x)) defaults else if (is.list(x)) { if (is.null(names(x))) { # x must be complete stopifnot(length(x) == length(defaults)) setNames(x, names(defaults)) } else modifyList(defaults, x) # x might be a subset of parameters } else if (is.atomic(x)) { setNames(rep(list(x), length(defaults)), names(defaults)) } else stop("'", deparse(substitute(x)), "' is not suitably specified") } ## component-specific arguments ylim <- withDefaults(ylim, list(ar=NULL, ne=NULL, end=NULL, maxEV=NULL)) ylab <- withDefaults(ylab, list(ar=expression(hat(lambda)), ne=expression(hat(phi)), end=expression(hat(nu)), maxEV="dominant eigenvalue")) main <- withDefaults(main, list(ar="autoregressive component", ne="spatiotemporal component", end="endemic component", maxEV="dominant eigenvalue")) anyMain <- any(unlist(lapply(main, nchar), recursive=FALSE, use.names=FALSE) > 0) ## basic graphical settings if (is.list(par.settings)) { par.defaults <- list(mfrow=sort(n2mfrow(length(components))), mar=c(4,5,if(anyMain) 2 else 1,1)+.1, las=1) par.settings <- modifyList(par.defaults, par.settings) opar <- do.call("par", par.settings) on.exit(par(opar)) } ## line style matplot.args <- modifyList(list(type="l", col=c(1,2,6,3), lty=c(1,3,2,4), lwd=1.7, cex=1, pch=NULL), matplot.args) ## legend options if (is.null(legend)) legend <- length(objects) > 1 if (is.logical(legend)) legend <- which(legend) if (!is.list(legend.args)) { if (length(legend) > 0) warning("ignored 'legend' since 'legend.args' is not a list") legend <- integer(0L) } if (length(legend) > 0) { default.args <- c( list(x="topright", inset=0.02, legend=names(objects), bty="n"), matplot.args[c("col", "lwd", "lty", "pch")], with(matplot.args, list(pt.cex=cex, text.col=col)) ) legend.args <- modifyList(default.args, legend.args) } ## plot seasonality in individual model components seasons <- list() for(comp in setdiff(components, "maxEV")){ s2 <- lapply(objects, getSeason, component = comp, unit = unit, period = period) seasons[[comp]] <- exp(vapply(s2, FUN = if (intercept) { function (intseas) do.call("+", intseas) } else { function (intseas) intseas$season # disregard intercept }, FUN.VALUE = numeric(period), USE.NAMES = TRUE)) do.call("matplot", # x defaults to 1:period c(list(seasons[[comp]], xlim=xlim, ylim=ylim[[comp]], xlab=xlab, ylab=ylab[[comp]], main=main[[comp]]), matplot.args)) if (is.list(refline.args) && !intercept && any(seasons[[comp]] != 1)) do.call("abline", modifyList(list(h=1, lty=3, col="grey"), refline.args)) if (match(comp, components) %in% legend) do.call("legend", legend.args) } ## plot seasonality of dominant eigenvalue if ("maxEV" %in% components) { seasons[["maxEV"]] <- vapply(objects, FUN = function (obj) { getMaxEV_season(obj, period = period)$maxEV.season }, FUN.VALUE = numeric(period), USE.NAMES = TRUE) do.call("matplot", c(list(seasons[["maxEV"]], xlim=xlim, ylim=if (is.null(ylim[["maxEV"]])) c(0,max(2,seasons[["maxEV"]])) else ylim[["maxEV"]], xlab=xlab, ylab=ylab[["maxEV"]], main=main[["maxEV"]]), matplot.args)) if (is.list(refline.args)) do.call("abline", modifyList(list(h=1, lty=3, col="grey"), refline.args)) if (4 %in% legend) do.call("legend", legend.args) } ## invisibly return the data that has been plotted invisible(seasons) } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # get estimated intercept and seasonal pattern in the different components # CAVE: other covariates and offsets are ignored #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ getSeason <- function(x, component = c("end", "ar", "ne"), unit = 1, period = x$stsObj@freq) { component <- match.arg(component) startseason <- getSeasonStart(x) if (is.character(unit)) unit <- match(unit, colnames(x$stsObj)) ## return -Inf is component is not in the model (-> exp(-Inf) = 0) if (!component %in% componentsHHH4(x)) return(list(intercept=-Inf, season=rep.int(-Inf, period))) ## get the intercept est <- fixef.hhh4(x, reparamPsi=FALSE) intercept <- unname(est[grep(paste0("^", component, "\\.(1|ri)"), names(est))]) if (length(intercept) == 0) { intercept <- 0 # no intercept (not standard) } else if (length(intercept) > 1) { # unit-specific intercepts if (length(intercept) != ncol(x$stsObj)) stop(component,"-component has incomplete unit-specific intercepts") intercept <- intercept[unit] if (is.na(intercept)) stop("the specified 'unit' does not exist") } ## get seasonality terms (relying on sin(2*pi*t/52)-kind coefficient names) coefSinCos <- est[grep(paste0("^",component, "\\.(sin|cos)\\("), names(est))] if (unitspecific <- length(grep(").", names(coefSinCos), fixed=TRUE))) { if (unitspecific < length(coefSinCos)) stop("cannot handle partially unit-specific seasonality") coefSinCos <- coefSinCos[grep(paste0(").",colnames(x$stsObj)[unit]), names(coefSinCos), fixed=TRUE)] ## drop .unitname-suffix since non-syntactic (cannot reformulate()) names(coefSinCos) <- sub("\\)\\..+$", ")", names(coefSinCos)) } if (length(coefSinCos)==0) return(list(intercept=intercept, season=rep.int(0,period))) fSinCos <- reformulate( sub(paste0("^",component,"\\."), "", names(coefSinCos)), intercept=FALSE) mmSinCos <- model.matrix(fSinCos, data=data.frame(t=startseason-1 + seq_len(period))) ## Done list(intercept=intercept, season=as.vector(mmSinCos %*% coefSinCos)) } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # compute dominant eigenvalue of Lambda_t # CAVE: no support for Lambda_it #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ getMaxEV_season <- function (x, period = x$stsObj@freq) { stopifnot(inherits(x, "hhh4")) nUnits <- x$nUnit components <- componentsHHH4(x) ## CAVE: this function ignores epidemic covariates/offsets ## and unit-specific seasonality if (nUnits > 1L && any(c("ar", "ne") %in% components)) { compOK <- vapply(x$control[c("ar","ne")], FUN = function (comp) { terms <- terms(x)$terms epiterms <- terms[,terms["offsetComp",] %in% seq_len(2L),drop=FALSE] identical(as.numeric(comp$offset), 1) && length(all.vars(removeTimeFromFormula(comp$f))) == 0L && all(!unlist(epiterms["unitSpecific",])) }, FUN.VALUE = TRUE, USE.NAMES = FALSE) if (any(!compOK)) warning("epidemic components have (unit-specific) ", "covariates/offsets not accounted for;\n", " use getMaxEV() or plotHHH4_maxEV()") } ## global intercepts and seasonality s2.lambda <- getSeason(x, "ar") s2.phi <- getSeason(x, "ne") ## unit-specific intercepts ris <- ranef.hhh4(x, tomatrix=TRUE) ri.lambda <- ris[,pmatch("ar.ri", colnames(ris), nomatch=0L),drop=TRUE] if (length(ri.lambda) == 0L) ri.lambda <- rep.int(0, nUnits) ri.phi <- ris[,pmatch("ne.ri", colnames(ris), nomatch=0L),drop=TRUE] if (length(ri.phi) == 0L) ri.phi <- rep.int(0, nUnits) ## get neighbourhood weights as a function of time W <- getNEweights(x) # NULL, matrix or 3-dim array if (!is.null(W) && !is.matrix(W)) stop("neighbourhood weights are time-varying; ", # and thus probably changing within or across seasons "use getMaxEV() or plotHHH4_maxEV()") ## create the Lambda_t matrix createLambda <- function (t) { Lambda <- if ("ne" %in% components) { exp(s2.phi$intercept + ri.phi + if(t==0) 0 else s2.phi$season[t]) * t(W) } else matrix(0, nUnits, nUnits) if ("ar" %in% components) { diag(Lambda) <- diag(Lambda) + exp(s2.lambda$intercept + ri.lambda + if(t==0) 0 else s2.lambda$season[t]) } Lambda } ## do this for t in 0:period diagonal <- !("ne" %in% components) .maxEV <- function (t) { maxEV(createLambda(t), symmetric = FALSE, diagonal = diagonal) } maxEV.const <- .maxEV(0) maxEV.season <- if (all(c(s2.phi$season, s2.lambda$season) %in% c(-Inf, 0))) { rep.int(maxEV.const, period) } else { vapply(X = seq_len(period), FUN = .maxEV, FUN.VALUE = 0, USE.NAMES = FALSE) } ## Done list(maxEV.season = maxEV.season, maxEV.const = maxEV.const, Lambda.const = createLambda(0)) } ## Determine the time point t of the start of a season in a hhh4() fit. ## If \code{object$stsObj@start[2] == 1}, it simply equals ## \code{object$control$data$t[1]}. Otherwise, the \code{stsObj} time series ## starts within a year (at sample \code{s}, say) and the beginning of ## the next season is ## \code{object$control$data$t[1] + object$stsObj@freq - s + 1}. getSeasonStart <- function (object) { if ((startsample <- object$stsObj@start[2]) == 1) { object$control$data$t[1L] } else { object$control$data$t[1L] + object$stsObj@freq-startsample + 1 } } ### ### plot neighbourhood weight as a function of distance (neighbourhood order) ### plotHHH4_neweights <- function (x, plotter = boxplot, ..., exclude = 0, maxlag = Inf) { plotter <- match.fun(plotter) ## orders of neighbourhood (o_ji) nbmat <- neighbourhood(x$stsObj) if (all(nbmat %in% 0:1)) { message("'neighbourhood(x$stsObj)' is binary; ", "computing neighbourhood orders ...") nbmat <- nbOrder(nbmat, maxlag=maxlag) } ## extract (estimated) weight matrix (w_ji) W <- getNEweights(x) if (is.null(W)) { # if no spatio-temporal component in the model W <- nbmat W[] <- 0 } ## draw the boxplot Distance <- factor(nbmat, exclude = exclude) notexcluded <- which(!is.na(Distance)) Distance <- Distance[notexcluded] Weight <- W[notexcluded] plotter(Weight ~ Distance, ...) } ### ### auxiliary functions ### yearepoch2point <- function (yearepoch, frequency, toleft=FALSE) yearepoch[1L] + (yearepoch[2L] - toleft) / frequency getHHH4list <- function (..., .names = NA_character_) { objects <- list(...) if (length(objects) == 1L && is.list(objects[[1L]]) && inherits(objects[[1L]][[1L]], "hhh4")) { ## ... is a single list of fits objects <- objects[[1L]] if (is.null(names(objects))) names(objects) <- seq_along(objects) } else { names(objects) <- if (is.null(names(objects))) .names else { ifelse(nzchar(names(objects)), names(objects), .names) } } if (!all(sapply(objects, inherits, what="hhh4"))) stop("'...' must consist of hhh4()-fits only") ## check common epoch, start and frequency and append them as attributes epoch <- unique(t(sapply(objects, function(x) x$stsObj@epoch))) if (nrow(epoch) > 1) stop("supplied hhh4-models obey different 'epoch's") attr(objects, "epoch") <- drop(epoch) start <- unique(t(sapply(objects, function(x) x$stsObj@start))) if (nrow(start) > 1) stop("supplied hhh4-models obey different start times") attr(objects, "start") <- drop(start) freq <- unique(sapply(objects, function(x) x$stsObj@freq)) if (length(freq)>1) stop("supplied hhh4-models obey different frequencies") attr(objects, "freq") <- freq ## done return(objects) } surveillance/R/epidataCS_plot.R0000644000176200001440000003476514615162374016215 0ustar liggesusers################################################################################ ### plot-method for "epidataCS" objects ### ### Copyright (C) 2009-2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ plot.epidataCS <- function (x, aggregate = c("time", "space"), subset, by = type, ...) { aggregate <- match.arg(aggregate) FUN <- paste("epidataCSplot", aggregate, sep = "_") do.call(FUN, args = list(x = quote(x), subset = substitute(subset), by = substitute(by), ...)) } ### plot.epidataCS(x, aggregate = "time") -> number of cases over time ## in case t0.Date is specified, hist.Date() is used and breaks must set in ... (e.g. "months") epidataCSplot_time <- function (x, subset, by = type, t0.Date = NULL, breaks = "stgrid", freq = TRUE, col = rainbow(nTypes), cumulative = list(), add = FALSE, mar = NULL, xlim = NULL, ylim = NULL, xlab = "Time", ylab = NULL, main = NULL, panel.first = abline(h=axTicks(2), lty=2, col="grey"), legend.types = list(), ...) { timeRange <- with(x$stgrid, c(start[1L], stop[length(stop)])) ## subset event marks eventMarks <- if (missing(subset)) { marks.epidataCS(x, coords = FALSE) } else { do.call(base::subset, list( x = quote(marks.epidataCS(x, coords = FALSE)), subset = substitute(subset) )) } if (nrow(eventMarks) == 0L) stop("no events left after 'subset'") ## extract the data to plot by <- substitute(by) eventTimesTypes <- eventMarks[c("time", "type")] eventTimesTypes$type <- if (is.null(by)) { # disregard event types factor("all") } else { # stratification of counts (default is to stack bars by event type) as.factor(eval(by, envir = eventMarks)) } typeNames <- levels(eventTimesTypes$type) nTypes <- length(typeNames) if (!freq && nTypes > 1L) warning("a stacked barplot of multiple event types only makes sense for 'freq=TRUE'") ## default breaks at stop times of stgrid if (identical(breaks, "stgrid")) { breaks <- c(timeRange[1L], unique.default(x$stgrid$stop)) if (any(eventTimesTypes$time < timeRange[1L])) { message("Note: ignoring events of the prehistory (before \"stgrid\")") eventTimesTypes <- base::subset(eventTimesTypes, time >= timeRange[1L]) if (nrow(eventTimesTypes) == 0L) stop("no events left to plot") } } ## calculate cumulative numbers if requested if (is.list(cumulative)) { csums <- tapply(eventTimesTypes$time, eventTimesTypes["type"], function (t) cumsum(table(t)), simplify=FALSE) if (!is.null(cumulative[["offset"]])) { stopifnot(is.vector(cumulative$offset, mode="numeric"), length(cumulative$offset) == nTypes) csums <- mapply(FUN="+", csums, cumulative$offset, SIMPLIFY=FALSE, USE.NAMES=TRUE) } if (is.null(cumulative[["axis"]])) cumulative[["axis"]] <- TRUE } eventTimesTypes$type <- as.integer(eventTimesTypes$type) typesEffective <- sort(unique(eventTimesTypes$type)) col <- rep_len(col, nTypes) if (!is.null(t0.Date)) { stopifnot(length(t0.Date) == 1L) t0.Date <- as.Date(t0.Date) t0 <- timeRange[1L] if (is.numeric(breaks) && length(breaks) > 1L) # transform to Date breaks <- t0.Date + (breaks - t0) if (is.null(xlim)) xlim <- t0.Date + (timeRange - t0) if (missing(xlab) && is.character(breaks)) xlab <- paste0("Time (", breaks, ")") eventTimesTypes$time <- t0.Date + as.integer(eventTimesTypes$time - t0) ## we need integer dates here because otherwise, if the last event ## occurs on the last day of a month, year, etc. (depending on ## 'breaks') with a fractional date (e.g. as.Date("2009-12-31") + 0.5), ## then the automatic 'breaks' (e.g., breaks = "months") will not cover ## the data (in the example, it will only reach until ## as.Date("2009-12-31")). The following would fail: ## data("imdepi"); plot(imdepi, t0.Date = "2002-01-15", breaks = "months") } gethistdata <- function (breaks, types = seq_len(nTypes)) { times <- eventTimesTypes$time[eventTimesTypes$type %in% types] if (is.null(t0.Date)) { hist(times, breaks=breaks, plot=FALSE, warn.unused=FALSE, ...) } else { hist(times, breaks=breaks, plot=FALSE, ...) ## warn.unused=FALSE is hard-coded in hist.Date } } histdata <- gethistdata(breaks=breaks) if (!is.null(t0.Date)) { ## hist.Date() drops the Date class, but we need it for later re-use class(histdata$breaks) <- "Date" } ## establish the basic plot window if (!add) { if (is.null(xlim)) xlim <- timeRange if (is.null(ylim)) { ylim <- range(0, histdata[[if (freq) "counts" else "density"]]) } if (is.null(ylab)) { ylab <- if (freq) "Number of cases" else "Density of cases" } if (is.null(mar)) { mar <- par("mar") if (is.list(cumulative) && cumulative$axis) mar[4L] <- mar[2L] } opar <- par(mar = mar); on.exit(par(opar)) plot(x=xlim, y=ylim, xlab=xlab, ylab=ylab, main=main, type="n", bty="n") force(panel.first) } ## plot histogram (over all types) suppressWarnings( # about wrong AREAS if breaks are non-equidistant plot(histdata, freq = freq, add = TRUE, col = col[typesEffective[1L]], ...) ) if (!add) # doesn't work as expected when adding to plot with cumulative axis box() # because white filling of bars might overdraw the initial box ## add type-specific sub-histograms for (typeIdx in seq_along(typesEffective)[-1L]) { .histdata <- gethistdata( breaks = histdata$breaks, # have to use same breaks types = typesEffective[typeIdx:length(typesEffective)] ) suppressWarnings( # about wrong AREAS if breaks are non-equidistant plot(.histdata, freq = freq, add = TRUE, col = col[typesEffective[typeIdx]], ...) ) } ## optionally add cumulative number of cases if (is.list(cumulative)) { aT2 <- axTicks(2) div <- length(aT2) - 1L darken <- function (col, f = 0.6) apply(X = col2rgb(col, alpha = TRUE), MARGIN = 2L, FUN = function (x) rgb(f*x[1L], f*x[2L], f*x[3L], x[4L], maxColorValue = 255)) cumulative <- modifyList( list(maxat = ceiling(max(unlist(csums))/div)*div, col = darken(col), lwd = 3, axis = TRUE, lab = "Cumulative number of cases"), cumulative) csum2y <- function (x) x / cumulative$maxat * aT2[length(aT2)] for (typeIdx in typesEffective) { .times <- as.numeric(names(csums[[typeIdx]])) lines(if (is.null(t0.Date)) .times else t0.Date + .times - t0, csum2y(csums[[typeIdx]]), lwd=cumulative$lwd, col=cumulative$col[typeIdx]) } if (cumulative$axis) { axis(4, at=aT2, labels=aT2/aT2[length(aT2)]*cumulative$maxat) mtext(cumulative$lab, side=4, line=3, las=0) } } ## optionally add legend if (is.list(legend.types) && length(typesEffective) > 1) { legend.types <- modifyList( list(x="topleft", legend=typeNames[typesEffective], title=deparse(by, nlines = 1), fill=col[typesEffective]), legend.types) do.call("legend", legend.types) } invisible(histdata) } ### plot.epidataCS(x, aggregate = "space") -> spatial point pattern epidataCSplot_space <- function (x, subset, by = type, tiles = x$W, pop = NULL, cex.fun = sqrt, points.args = list(), add = FALSE, legend.types = list(), legend.counts = list(), sp.layout = NULL, ...) { ## extract the points to plot events <- if (missing(subset)) { x$events } else { # calls sp:::subset.Spatial eval(substitute(base::subset(x$events, subset=.subset), list(.subset=substitute(subset)))) } ## should the plot distinguish between different event types? by <- substitute(by) events@data$type <- if (is.null(by)) { # disregard event types factor("all") } else { # default is to distinguish points by event type as.factor(eval(by, envir = events@data)) } typeNames <- levels(events$type) nTypes <- length(typeNames) eventCoordsTypes <- data.frame( coordinates(events), type = as.integer(events$type), row.names = NULL, check.rows = FALSE, check.names = FALSE) ## count events by location and type eventCoordsTypesCounts <- if (is.null(pop)) { countunique(eventCoordsTypes) } else { ## work with "SpatialPolygons" -> spplot() events$COUNT <- multiplicity(eventCoordsTypes) events[!duplicated(eventCoordsTypes), c("type", "COUNT")] } pointCounts <- eventCoordsTypesCounts$COUNT countsLegend <- unique(round(10^(do.call("seq", c( as.list(log10(range(pointCounts))), list(length.out=5) ))))) typesEffective <- sort(unique(eventCoordsTypesCounts$type)) ## point style colTypes <- list(...)[["colTypes"]] # backwards compatibility for < 1.8 if (is.null(colTypes)) { colTypes <- rainbow(nTypes) } else warning("argument 'colTypes' is deprecated; ", "use 'points.args$col' instead") points.args <- modifyList(list(pch=1, col=colTypes, lwd=1, cex=0.5), points.args) styleArgs <- c("pch", "col", "lwd") points.args[styleArgs] <- lapply(points.args[styleArgs], rep_len, length.out=nTypes) ## select style parameters according to the events' types points.args_pointwise <- points.args points.args_pointwise[styleArgs] <- lapply( points.args_pointwise[styleArgs], "[", eventCoordsTypesCounts$type) points.args_pointwise$cex <- points.args_pointwise$cex * cex.fun(pointCounts) ## plot ## Note: "epidataCS" always works with projected coords, ## so we can set asp/aspect and thus avoid sp::is.projected() if (is.null(pop)) { ## classical plotting system if (!add) plot(tiles, asp = 1, ...) do.call("points", c(alist(x=eventCoordsTypesCounts[,1:2,drop=FALSE]), points.args_pointwise)) ## optionally add legends if (is.list(legend.types) && length(typesEffective) > 1) { legend.types <- modifyList( list(x="topright", legend=typeNames[typesEffective], title=deparse(by, nlines = 1), #pt.cex=points.args$cex, # better use par("cex") pch=points.args$pch[typesEffective], col=points.args$col[typesEffective], pt.lwd=points.args$lwd[typesEffective]), legend.types) do.call("legend", legend.types) } if (is.list(legend.counts) && any(pointCounts > 1)) { if (!is.null(legend.counts[["counts"]])) { countsLegend <- as.vector(legend.counts[["counts"]], mode="integer") legend.counts[["counts"]] <- NULL } legend.counts <- modifyList( list(x="bottomright", bty="n", legend=countsLegend, pt.cex=points.args$cex * cex.fun(countsLegend), pch=points.args$pch[1L], col=if(length(unique(points.args$col)) == 1L) points.args$col[1L] else 1, pt.lwd=points.args$lwd[1L]), legend.counts) do.call("legend", legend.counts) } invisible() } else { if (!is(tiles, "SpatialPolygonsDataFrame")) { stop("'pop' requires 'tiles' to be a \"SpatialPolygonsDataFrame\"") } ## grid plotting system -> spplot() layout.points <- c(list("sp.points", eventCoordsTypesCounts), points.args_pointwise) ## optional legend definitions legend.types <- if (is.list(legend.types) && length(typesEffective) > 1) { legend.types <- modifyList( list(corner = c(1, 1), # "topright" title = deparse(by, nlines = 1), cex.title = 1, border = TRUE, points = list( pch = points.args$pch[typesEffective], col = points.args$col[typesEffective], lwd = points.args$lwd[typesEffective] ), text = list(typeNames[typesEffective])), legend.types ) corner.types <- legend.types$corner legend.types$corner <- NULL list(inside = list(fun = lattice::draw.key(legend.types), corner = corner.types)) } legend.counts <- if (is.list(legend.counts) && any(pointCounts > 1)) { if (!is.null(legend.counts[["counts"]])) { countsLegend <- as.vector(legend.counts[["counts"]], mode="integer") legend.counts[["counts"]] <- NULL } legend.counts <- modifyList( list(corner = c(1,0), # "bottomright" points = list( cex = points.args$cex * cex.fun(countsLegend), pch = points.args$pch[1L], col = if(length(unique(points.args$col)) == 1L) points.args$col[1L] else 1, lwd = points.args$lwd[1L] ), text = list(as.character(countsLegend)), padding.text=2, between=0), legend.counts ) corner.counts <- legend.counts$corner legend.counts$corner <- NULL list(inside = list(fun = lattice::draw.key(legend.counts), corner = corner.counts)) } ## create the plot spplot(obj = tiles, zcol = pop, aspect = "iso", sp.layout = c(list(layout.points), sp.layout), legend = c(legend.types, legend.counts), ...) } } surveillance/R/twinSIR.R0000644000176200001440000005243314615115350014641 0ustar liggesusers################################################################################ ### Function 'twinSIR' performs (penalized) maximum likelihood inference ### for the Hoehle (2009) model. Now with REML estimation of smoothing ### parameter lambda. ### ### Copyright (C) 2008-2009 Michael Hoehle ### Copyright (C) 2008-2009,2014,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## ATTENTION: the .loglik and .score functions assume atRiskY == 1 data ###################################################################### # Log-Likelihood function # # PARAMS: # theta - parameter vector c(alpha,beta), where # beta also contains the baseline coefficients in the first place # X - covariate matrix related to alpha, i.e. the epidemic component # Z - covariate matrix related to beta, i.e. the Cox-like endemic component # survs - data.frame with columns id, start, stop and event # weights - vector of length nrow(X) indicating the number of individuals # with the same covariates. weights are allowed to change over time. # Note: it is assumed that none of the individuals covered by # "weights" can have an actual event, if so they need to have their # own row ###################################################################### .loglik <- function(theta, X, Z, survs, weights) { # Calculate epidemic (e) and endemic (h) component of the infection intensity eh <- .eh(theta, X, Z) # Calculate infection intensity assuming atRiskY == 1 for all rows lambdaNoY <- rowSums(eh) # dN Part of the loglik isEvent <- survs$event == 1 events <- which(isEvent) intdN <- numeric(length(isEvent)) # zeros intdN[events] <- weights[events] * log(lambdaNoY[events]) # here one might have got -Inf values in case of 0-intensity at an event time # lambda integral of the log-likelihood dt <- survs$stop - survs$start intlambda <- weights * lambdaNoY * dt # Return the log-likelihood loglik <- sum( intdN - intlambda ) return(loglik) } ###################################################################### # Penalized log-likelihood function # Additional Params: # lambda.smooth - smoothing parameter # K - penalty matrix on the beta component ###################################################################### .ploglik <- function(theta, X, Z, survs, weights, lambda.smooth, K) { loglik <- .loglik(theta, X, Z, survs, weights) if (lambda.smooth == 0) { return(loglik) } # Add penalty term and return the penalized log-likelihood beta <- theta[ncol(X) + seq_len(ncol(Z))] penalty <- lambda.smooth/2 * drop(t(beta) %*% K %*% beta) return(loglik - penalty) } ###################################################################### # Score function # Params: see .loglik ###################################################################### .score <- function(theta, X, Z, survs, weights) { dimX <- dim(X) nRows <- dimX[1] px <- dimX[2] pz <- ncol(Z) isEvent <- survs$event == 1 # event indicator for the dN integral events <- which(isEvent) dt <- survs$stop - survs$start # for the dt integral # Calculate epidemic (e) and endemic (h) component of the infection intensity eh <- .eh(theta, X, Z) h <- eh[,2,drop=TRUE] # Calculate infection intensity at event times lambdaEvents <- rowSums(eh[events,,drop=FALSE]) score <- if (px > 0L) { wX <- X * weights part1intdN <- matrix(0, nrow = nRows, ncol = px, dimnames = dimnames(X)) part1intdN[events,] <- wX[events,] / lambdaEvents part1intlambda <- wX * dt colSums(part1intdN - part1intlambda) } else NULL if (pz > 0L) { wZh <- Z * (h * weights) part2intdN <- matrix(0, nrow = nRows, ncol = pz, dimnames = dimnames(Z)) part2intdN[events,] <- wZh[events,] / lambdaEvents part2intlambda <- wZh * dt part2 <- colSums(part2intdN - part2intlambda) score <- c(score, part2) } return(score) } ###################################################################### # Penalized Score function # Additional Params: see .ploglik ###################################################################### .pscore <- function(theta, X, Z, survs, weights, lambda.smooth, K, ...) { score <- .score(theta, X, Z, survs, weights) if (lambda.smooth == 0) { return(score) } # Add penalty term and return the penalized Score function beta <- theta[ncol(X) + seq_len(ncol(Z))] penalty <- c(rep.int(0, ncol(X)), lambda.smooth * K %*% beta) return(score - penalty) } ###################################################################### # Fisher information matrix function # Params: see .loglik ###################################################################### .fisherinfo <- function(theta, X, Z, survs, weights) { px <- ncol(X) pz <- ncol(Z) isEvent <- survs$event == 1 # event indicator events <- which(isEvent) # Fisher matrix calculation only incorporates data at event times! Xevents <- X[events,,drop = FALSE] Zevents <- Z[events,,drop = FALSE] # Calculate epidemic (e) and endemic (h) component of the infection intensity eh <- .eh(theta, Xevents, Zevents) h <- eh[,2,drop=TRUE] # Calculate infection intensity lambda <- rowSums(eh) # calculate intdN of d/dtheta log(lambda_i(t)) for all individuals with events wpl <- weights[events] / lambda dloglambda <- if (px > 0L) Xevents * wpl else NULL if (pz > 0L) { dloglambda <- cbind(dloglambda, Zevents * (h * wpl)) } # Build the optional variation process (Martinussen & Scheike, p64) fisherinfo <- matrix(0, nrow=px+pz, ncol=px+pz) for (i in seq_len(nrow(dloglambda))) { x <- dloglambda[i,,drop=FALSE] # single-ROW matrix fisherinfo <- fisherinfo + crossprod(x) # t(x) %*% x } return(fisherinfo) } ###################################################################### # Fisher information matrix function # Additional Params: see .ploglik ###################################################################### .pfisherinfo <- function(theta, X, Z, survs, weights, lambda.smooth, K) { fisherinfo <- .fisherinfo(theta, X, Z, survs, weights) if (lambda.smooth == 0) { return(fisherinfo) } # Add penalty term and return the penalized Fisher information matrix penalty <- matrix(0, ncol=ncol(fisherinfo), nrow=nrow(fisherinfo)) zIndex <- ncol(X) + seq_len(ncol(Z)) penalty[zIndex,zIndex] <- lambda.smooth * K return(fisherinfo + penalty) } ###################################################################### # Marginal likelihood of the log(smoothing) parameter as given # by a Laplace approximation c.f. Kneib & Fahrmeir (2006), p.9. # or Cai et al (2002) # # Params: # log.lambda.smooth - log parametrization to ensure positive value of # lambda.smooth # theta - fixed regression parameters # X - design matrix of additive part # Z - design matrix of multiplicative part # survs - the data.frame containing the data in survs format # weights - for weighting individual entries # K - smoother matrix # # Returns: # value of lmarg ###################################################################### .lmarg.lambda <- function(log.lambda.smooth, theta, X, Z, survs, weights, K) { #Contribution of the penalized likelihood loglik <- .ploglik(theta, X, Z, survs, weights, exp(log.lambda.smooth), K) #Laplace approximation using TP representation H <- .pfisherinfo(theta, X, Z, survs, weights, exp(log.lambda.smooth), K) beta <- theta[ncol(X) + seq_len(ncol(Z))] #[Q]: Extract baseline terms from model and translate into #TP-spline setting, i.e. a B-spline of 0th order is assumed baselineIdx <- grep("cox\\(logbaseline.*\\)",dimnames(Z)[[2]]) b <- diff(beta[baselineIdx]) laplace <- 1/2*(length(b)-1)*log.lambda.smooth - 1/2*log(det(H)) return(loglik + laplace) } ###################################################################### # Model fitter. Prepares everything and uses optim's (L-)BFGS(-B) to # maximize the (penalized) log-likelihood. ###################################################################### twinSIR <- function (formula, data, weights, subset, knots = NULL, nIntervals = 1, lambda.smooth = 0, penalty = 1, optim.args = list(), model = TRUE, keep.data = FALSE) { cl <- match.call() ## Verify that 'data' inherits from "epidata" data <- eval(cl$data, parent.frame()) if (!inherits(data, "epidata")) { stop("'data' must inherit from class \"epidata\"") } ## Extract the time range of the epidemic timeRange <- attr(data, "timeRange") minTime <- timeRange[1L] maxTime <- timeRange[2L] # ## NOTE: modification of 'data' has no effect with the current evaluation # ## of model.frame in the parent.frame() as the original 'data' will # ## be used. # ## Impute blocks for 'knots', which are not existing stop times # if (is.vector(knots, mode = "numeric")) { # insideKnot <- (knots > minTime) & (knots < maxTime) # if (any(!insideKnot)) { # warning("only 'knots' inside the observation period are considered") # } # knots <- sort(knots[insideKnot]) # data <- intersperse(data, knots) # } ############################ ### Build up model.frame ### (this is derived from the coxph function) ############################ mfnames <- c("", "formula", "data", "weights", "subset") mf <- cl[match(mfnames, names(cl), nomatch = 0L)] mf$id <- as.name("id") mf$atRiskY <- as.name("atRiskY") mf$subset <- if (is.null(mf$subset)) { call("==", mf$atRiskY, 1) } else { call("&", mf$subset, call("==", mf$atRiskY, 1)) } if(length(formula) == 2L) { # i.e. no response specified formula[3L] <- formula[2L] formula[[2L]] <- quote(cbind(start, stop, event)) } mf$na.action <- as.name("na.fail") special <- c("cox") Terms <- terms(formula, specials = special, data = data, keep.order = FALSE) mf$formula <- Terms mf[[1]] <- as.name("model.frame") mf <- eval(mf, parent.frame()) ########################################################### ### Check arguments and extract components of the model ### ########################################################### ## Extract and check 'weights' weights <- model.extract(mf, "weights") if (is.null(weights)) { weights <- rep(1, nrow(mf)) names(weights) <- attr(mf, "row.names") } else { if (!is.vector(weights, mode="numeric")) { stop("'weights' must be a numeric vector") } if (any(weights < 0)) { stop("negative 'weights' not allowed") } } ## Extract the response response <- model.response(mf) survs <- data.frame(id = model.extract(mf, "id"), start = response[,1L], stop = response[,2L], event = response[,3L], check.names = FALSE, stringsAsFactors = FALSE) attr(survs, "eventTimes") <- survs$stop[survs$event == 1] ##<- equals attr(data, "eventTimes") if missing(subset) attr(survs, "timeRange") <- timeRange ## Check that we have events if (length(attr(survs, "eventTimes")) == 0) warning("no events in data", if (!missing(subset)) " (subject to 'subset')") ## Check specified baseline intervals if (is.null(knots) && isScalar(nIntervals)) { knots <- if (nIntervals == 1) { numeric(0) } else if (nIntervals > 1) { quantile(attr(survs, "eventTimes"), probs = seq(from=0, to=1, length.out=nIntervals+1)[-c(1,nIntervals+1)], type = 1, names = FALSE) } else { stop("'nIntervals' must be a single number >= 1") } } else if (is.vector(knots, mode = "numeric")) { isInsideKnot <- (knots > minTime) & (knots < maxTime) if (any(!isInsideKnot)) { warning("only 'knots' inside the observation period are considered") knots <- knots[isInsideKnot] } isStopKnot <- knots %in% unique(survs$stop) if (any(!isStopKnot)) { stop("'knots' must be a subset of 'unique(data$stop[data$atRiskY==1])'", if (!missing(subset)) ",\n where 'data' is subject to 'subset'") } knots <- sort(knots) } else { stop("'knots' (a numeric vector) or 'nIntervals' (a single number) ", "must be specified") } intervals <- c(minTime, knots, maxTime) nIntervals <- length(intervals) - 1L message( sprintf(ngettext(nIntervals, "Initialized %d log-baseline interval: ", "Initialized %d log-baseline intervals: "), nIntervals), paste(format(intervals, trim = TRUE), collapse=" ") ) ## Extract the two parts of the design matrix: ## Z contains the Cox part, X contains the epidemic part, there's no intercept des <- read.design(mf, Terms) X <- des$X; px <- ncol(X) Z <- des$Z ## Add variables for the piecewise constant baseline to Z (if requested) if (nIntervals == 1L) { nEvents <- length(attr(survs, "eventTimes")) if (attr(Terms, "intercept") == 1) Z <- cbind("cox(logbaseline)" = 1, Z) } else { # we have more than one baseline interval/parameter intervalIndices <- findInterval(survs$start, intervals, rightmost.closed = FALSE) intervalNumbers <- seq_len(nIntervals) baselineVars <- sapply(intervalNumbers, function(i) intervalIndices == i) dimnames(baselineVars) <- list(NULL, paste("cox(logbaseline.", intervalNumbers, ")", sep="")) Z <- cbind(baselineVars, Z) nEvents <- as.vector(table(factor(intervalIndices[survs$event == 1], levels = seq_len(nIntervals)))) } pz <- ncol(Z) ## Check that we have at least one parameter if (pz == 0L && px == 0L) { stop("nothing to do: neither a baseline nor covariates have been specified") } ## Check lambda.smooth if (!isScalar(lambda.smooth)) { stop("'lambda.smooth' must be scalar") } if (lambda.smooth != 0 && pz == 0L) { lambda.smooth <- 0 message("Note: 'lambda.smooth' was set to 0, because there was no endemic ", "component in the formula.") } ## Setup penalty matrix if (isScalar(penalty)) { K <- matrix(0, ncol = pz, nrow = pz) if (lambda.smooth != 0 && nIntervals > 1L) { # do we have equidistant knots? knotSpacings <- diff(intervals) #equidistant <- all(sapply(knotSpacings[-1], function(x) isTRUE(all.equal(x,knotSpacings[1])))) equidistant <- isTRUE(all.equal(diff(knotSpacings), rep.int(0,nIntervals-1))) if (equidistant) { # K = D'D only works for equidistant knots # difference matrix of order 'penalty' D <- diff(diag(nIntervals), differences=penalty) K[intervalNumbers,intervalNumbers] <- crossprod(D) # t(D) %*% D } else { # special weighting scheme for the non-equidistant case if (penalty != 1) { stop("ATM, non-equidistant knots only work for 1st order penalty") } #Use Fahrmeir & Lang (2001), p.206 invdelta <- 1/diff(intervals) * mean(diff(intervals)) #Use Fahrmeir & Lang (2001), p.206 for (i in seq_len(nIntervals)) { idx2 <- cbind(j=c(-1,1) + i, deltaidx=i+c(-1,0),fac=c(-1,-1)) idx2 <- idx2[idx2[,"j"] > 0 & idx2[,"j"] <= nIntervals,,drop=FALSE] #Off diagonal elements K[i, idx2[,"j"]] <- invdelta[idx2[,"deltaidx"]] * idx2[,"fac"] #Diagonal element K[i, i] <- sum(invdelta[idx2[,"deltaidx"]]) } message("Note: non-equidistant knots. Using penalization matrix ", "correcting for distance between knots.\n") # print(K) # browser() } } } else if (is.matrix(penalty) && ncol(penalty) == pz && nrow(penalty) == pz) { K <- penalty } else { stop("'penalty' must either be a single number or a square matrix of ", "dimension ", pz, "x", pz, ", fitting the number of unknown ", "parameters in the endemic component (baseline and covariates)") } ## Check that optim.args is a list if (!is.list(optim.args)) { stop("'optim.args' must be a list") } ## Check start value for theta if (!is.null(optim.args[["par"]])) { if (!is.vector(optim.args$par, mode="numeric")) { stop("'optim.args$par' must be a numeric vector or NULL") } if (length(optim.args$par) != px + pz) { stop(gettextf(paste("'optim.args$par' (%d) does not have the same length", "as the number of unknown parameters (%d + %d = %d)"), length(optim.args$par), px, pz, px + pz)) } } else { optim.args$par <- c(rep.int(1, px), rep.int(0, pz)) } message("Initial parameter vector: ", paste(format(optim.args$par, trim=TRUE), collapse=" ")) ## Set names for theta names(optim.args$par) <- c(colnames(X), colnames(Z)) #################### ### Optimization ### #################### ## Configuring the optim procedure (check optim.args) optimControl <- list(trace = 1, fnscale = -1, maxit = 300, factr = 1e7) optimControl[names(optim.args[["control"]])] <- optim.args[["control"]] optim.args$control <- optimControl optimArgs <- list(par = optim.args$par, fn = .ploglik, gr = .pscore, X = X, Z = Z, survs = survs, weights = weights, lambda.smooth = lambda.smooth, K = K, method = "L-BFGS-B", lower = c(rep(0,px), rep(-Inf,pz)), upper = rep(Inf,px+pz), control = list(), hessian = FALSE) namesOptimArgs <- names(optimArgs) namesOptimUser <- names(optim.args) optimValid <- namesOptimUser %in% namesOptimArgs optimArgs[namesOptimUser[optimValid]] <- optim.args[optimValid] if (any(!optimValid)) warning("unknown names in optim.args: ", paste(namesOptimUser[!optimValid], collapse = ", ")) if (! "method" %in% namesOptimUser && px == 0L) { optimArgs$method <- "BFGS" } if (optimArgs$method != "L-BFGS-B") { optimArgs$lower <- -Inf optimArgs$upper <- Inf } #Fit model using fixed smoothing parameter or use mixed model #representation to estimate lambda.smooth using marginal likelihood if (lambda.smooth == -1) { if (isScalar(penalty) && penalty == 1) { ################################################################### ##TODO: Need to check for B-spline (?). Move options into ctrl obj ################################################################### #Iterative procedure where we change between optimizing regression #parameters given fixed smoothing parameter and optimizing the #smoothing parameter given fixed regression parameters (Gauss-Seidel) #procedure. The tuning parameters (5) could go into the control object. lambda.smooth <- 5 reltol <- 1e-2 maxit <- 25 #Parameters for keeping track of the iterations lambda.smoothOld <- 1e99 iter <- 0 #Loop until relative convergence or max-iteration reached while ((abs(lambda.smooth-lambda.smoothOld)/lambda.smoothOld > reltol) & (iter < maxit)) { #Iteration begins iter <- iter + 1 if (optimControl$trace > 0) { cat("==> Iteration ",iter," of Gauss-Seidel maximization. lambda.smooth = ",lambda.smooth,"\n") } #Step 1 - maximize (alpha,beta) with fixed lambda optimArgs$lambda.smooth <- lambda.smooth optimRes <- do.call("optim", optimArgs) theta <- optimRes$par optimArgs$par <- theta #better start value the next time #Step 2 - maximize log(lambda) with fixed (alpha,beta) optimLambda <- optim(log(lambda.smooth), .lmarg.lambda, control=list(fnscale=-1,trace=1),method="BFGS", theta=theta, X=X, Z=Z, survs=survs, weights=weights, K=K) lambda.smoothOld <- lambda.smooth lambda.smooth <- exp(optimLambda$par) } #Done, update optimArgs with new smoothing parameter optimArgs$lambda.smooth <- lambda.smooth } else { stop("REML estimation using TP-splines only works for 1st order differences.") } } ## Call optim with the arguments above (including the news smoothing param) optimRes <- do.call("optim", optimArgs) ############## ### Return ### ############## ## Set up list object to be returned fit <- list(coefficients = optimRes$par, lambda.smooth = lambda.smooth, loglik = optimRes$value, counts = optimRes$counts, converged = (optimRes$convergence == 0)) ## If requested, add observed fisher info (= negative hessian at maximum) if (!is.null(optimRes$hessian)) { fit$fisherinfo.observed <- -optimRes$hessian } ## Add own (exact) fisher info computation fit$fisherinfo <- .pfisherinfo(theta = fit$coefficients, X = X, Z = Z, survs = survs, weights = weights, lambda.smooth = lambda.smooth, K = K) ## Add 'method' fit$method <- optimArgs$method ## Append further information fit$intervals <- intervals fit$nEvents <- nEvents if (model) { fit$model <- list( survs = survs, X = X, Z = Z, weights = weights, lambda.smooth = lambda.smooth, K = K, f = attr(data, "f")[match(colnames(X), names(attr(data, "f")), nomatch=0)], w = attr(data, "w")[match(colnames(X), names(attr(data, "w")), nomatch=0)] ) } if (keep.data) { fit$data <- data } fit$call <- cl fit$formula <- formula(Terms) fit$terms <- Terms ## Return object of class "twinSIR" class(fit) <- "twinSIR" return(fit) } surveillance/R/fanplot.R0000644000176200001440000000717714145043265014755 0ustar liggesusers################################################################################ ### Wrapper function for fanplot::fan() ### ### Copyright (C) 2017-2018,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ fanplot <- function (quantiles, probs, means = NULL, observed = NULL, start = 1, fan.args = list(), means.args = list(), observed.args = list(), key.args = NULL, xlim = NULL, ylim = NULL, log = "", xlab = "Time", ylab = "No. infected", add = FALSE, ...) { if (!requireNamespace("fanplot", quietly = TRUE)) stop("package ", sQuote("fanplot"), " is missing; ", "do 'install.packages(\"fanplot\")'") stopifnot(is.matrix(quantiles), length(probs) == ncol(quantiles), is.null(means) || length(means) == nrow(quantiles), is.null(observed) || length(observed) == nrow(quantiles), isScalar(start)) ## axis range ylog <- grepl("y", log) if (is.null(xlim)) xlim <- c(1 - 0.5, nrow(quantiles) + 0.5) + (start-1) if (is.null(ylim)) { ylim <- range(quantiles, observed, na.rm = TRUE) if (!ylog && ylim[1L] > 0) { ylim[1L] <- 0 } } ## graphical parameters stopifnot(is.list(fan.args)) fan.args <- modifyList( list(data = t(quantiles), data.type = "values", probs = probs, start = start, fan.col = heat.colors, ln = NULL), fan.args, keep.null = TRUE) ## initialize empty plot if (!add) plot.default(xlim, ylim, type = "n", log = log, xlab = xlab, ylab = ylab, ...) ## add fan do.call(fanplot::fan, fan.args) ## add point predictions if (!is.null(means) && is.list(means.args)) { means.args <- modifyList( list(x = seq_along(means) + (start-1), y = means, type = "l", lwd = 2, col = "white"), means.args) do.call("lines", means.args) } ## add observed time series if (!is.null(observed) && is.list(observed.args)) { observed.args <- modifyList( list(x = seq_along(observed) + (start-1), y = observed, type = "b", lwd = 2), observed.args) do.call("lines", observed.args) } ## add color key if (is.list(key.args)) { defaultyrange <- local({ if (ylog) ylim <- log(ylim) {if (ylog) exp else identity}(c(ylim[1L] + mean(ylim), ylim[2L])) }) key.args <- modifyList( list(start = xlim[2L] - 1, ylim = defaultyrange, data.type = "values", style = "boxfan", probs = fan.args$probs, fan.col = fan.args$fan.col, ln = NULL, space = 0.9, rlab = quantile(fan.args$probs, names = FALSE, type = 1)), key.args) ## convert ylim to data yvals <- if (ylog) { exp(seq.int(from = log(key.args$ylim[1L]), to = log(key.args$ylim[2L]), length.out = length(fan.args$probs))) } else { seq.int(from = key.args$ylim[1L], to = key.args$ylim[2L], length.out = length(fan.args$probs)) } key.args$data <- matrix(yvals) key.args$ylim <- NULL tryCatch(do.call(fanplot::fan, key.args), error = function (e) warning("color key could not be drawn, probably due to non-standard 'probs'", call. = FALSE)) } invisible(NULL) } surveillance/R/calibration.R0000644000176200001440000000473714426171115015576 0ustar liggesusers################################################################################ ### Calibration tests for count data based on proper scoring rules ### Reference: Wei and Held (2014), Test, 23, 787-805 ### ### Copyright (C) 2015,2018 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## perform a calibration test given observations x ## with Poisson (size = NULL) or NegBin predictions calibrationTest.default <- function (x, mu, size = NULL, which = c("dss", "logs", "rps"), tolerance = 1e-4, method = 2, ...) { stopifnot(x >= 0, mu > 0, is.null(size) || all(size > 0)) ## calculate scores which <- match.arg(which) score <- do.call(which, args = alist(x = x, mu = mu, size = size)) ## calculate z-statistic z <- calibrationZ(score, mu, size, which, tolerance, method) ## calculate two-sided p-value p <- 2 * pnorm(-abs(z)) ## construct an object of class "htest" res <- list( method = paste0("Calibration Test for Count Data (based on ", toupper(which), ")"), data.name = deparse(substitute(x)), statistic = c("z" = z), parameter = c("n" = length(x)), p.value = p ) class(res) <- "htest" res } ## compute the calibration z-statistic given the computed scores calibrationZ <- function (score, mu, size = NULL, which = c("dss", "logs", "rps"), tolerance = 1e-4, method = 2) { stopifnot(method %in% 1:2) ## expectation and variance of score for given predictive distribution EV <- score_EV(mu, size, tolerance, which) ## calculate the z-statistic z <- do.call(paste0("zScore", method), args = alist(score, EV[[1L]], EV[[2L]])) z } ## compute the calibration z-statistic and p-value ## from a set of scores and their null expectations and variances zScore1 <- function (score, E0, V0) { n <- length(score) ## emean <- mean(E0) ## varmean <- sum(V0) / n^2 ## (mean(score) - emean) / sqrt(varmean) sum(score - E0) / sqrt(sum(V0)) } ## alternative z-statistic Z* zScore2 <- function (score, E0, V0) { n <- length(score) sum((score - E0) / sqrt(V0)) / sqrt(n) } surveillance/R/sts_observation.R0000644000176200001440000000233113346465003016521 0ustar liggesusers################################################################################ ### Function for creating an "sts" object with a given observation date ### ### Copyright (C) 2014-2015 Maelle Salmon ################################################################################ sts_observation <- function(sts,dateObservation,cut=TRUE) { # The sts object we shall return stsSub <- sts # Index of the observation date line1 <- which(epoch(sts)==dateObservation) # Maximal delay D <- dim(stsSub@control$reportingTriangle$n)[2]-1 # Number of dates theEnd <- dim(stsSub@control$reportingTriangle$n)[1] # Nothing observed after the observation date (I am a genius) stsSub@control$reportingTriangle$n[(line1+1):theEnd,] <- NA stsSub@observed[(line1+1):theEnd] <- 0 # Not everything observed before the observation date for (i in 1:D){ stsSub@control$reportingTriangle$n[line1+1-i,(i+1):(D+1)] <- NA stsSub@observed[line1+1-i] <- sum(stsSub@control$reportingTriangle$n[line1+1-i,],na.rm=T) } stsSub@control$reportingTriangle$n <- stsSub@control$reportingTriangle$n[1:line1,] # Return the new sts object if (cut){return(stsSub[1:line1])} else{return(stsSub)} } surveillance/R/options.R0000644000176200001440000001065314516240231014770 0ustar liggesusers################################################################################ ### Set up .Options for "surveillance". ### Inspired by the options management in the R package "spatstat" (1.29-0) ### by Adrian Baddeley and Rolf Turner (2012). ### ### Copyright (C) 2012,2023 Sebastian Meyer, 2014 Michael Hoehle ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ .Options <- new.env() ## the "gpclib" option is obsolete and no longer documented .Options$gpclib <- list( default = FALSE, # no gpclib due to license restrictions check = function(x) { if (!is.logical(x) || length(x) != 1L) return(FALSE) if (x) { .Deprecated(msg = paste("Option", dQuote("gpclib"), "is obsolete.")) if (!requireNamespace("gpclib")) { warning("cannot use ", sQuote("gpclib"), call. = FALSE) return(FALSE) } } TRUE }, valid = "a single logical value" ) ## mainly a maintainer-level switch driven by _R_SURVEILLANCE_ALL_EXAMPLES_ .Options$allExamples <- list( default = TRUE, # maybe disabled by .onAttach() check = function(x) is.logical(x) && length(x) == 1L, valid = "a single logical value" ) #Tick sizes of sts xaxis relative to par()$tcl .Options$stsTickFactors <- list( default = c("%d"=0.33,"%W"=0.33,"%V"=0.33,"%m"=1,"%Q"=1.25,"%Y"=1.5,"%G"=1.5), check = function(x) is.vector(x, mode="numeric") && !is.null(names(x)), valid = "a named vector of relative tick sizes" ) #Colors for the prediction intervals in nowcast plots .Options$colors <- list( default = c(nowSymbol="springgreen4",piBars="orange"), check = function(x) is.character(x), valid = "a vector of color names" ) ## Function to activate the defaults reset.surveillance.options <- function () { opts <- sapply(ls(.Options, all.names=TRUE), function (option) { .Options[[option]]$value <- .Options[[option]]$default }, simplify=FALSE, USE.NAMES=TRUE) invisible(opts) } ## Internal function to query options get.surveillance.options <- function (x, drop = TRUE) { opts <- lapply(.Options, "[[", "value") if (drop && !missing(x) && length(x) == 1L) opts[[x]] else opts[x] } ## Exported function to modify and query options surveillance.options <- function (...) { knownOptions <- ls(.Options, all.names=TRUE) called <- list(...) if (length(called) == 0) return(get.surveillance.options()) if (is.null(names(called)) && length(called)==1) { x <- called[[1]] if (is.null(x)) return(get.surveillance.options()) if (is.list(x)) called <- x } if (is.null(names(called))) # case: surveillance.options("par1","par2",...) { ischar <- unlist(lapply(called, is.character)) if(all(ischar)) { choices <- unlist(called) ok <- choices %in% knownOptions if(!all(ok)) stop("unrecognised option(s): ", called[!ok]) return(get.surveillance.options(choices)) } else { wrong <- called[!ischar] offending <- unlist(lapply(wrong, deparse, nlines=1, control="delayPromises")) offending <- paste(offending, collapse=",") stop("unrecognised mode of argument(s) [", offending, "]:", "\n should be character string or name=value pair") } } else { # case: surveillance.options(name=value, name2=value2, ...) assignto <- names(called) if (!all(nzchar(assignto))) stop("options must all be identified by name=value") recog <- assignto %in% knownOptions if(!all(recog)) stop("unrecognised option(s): ", assignto[!recog]) ## validate and assign new values oldopts <- get.surveillance.options(assignto, drop=FALSE) for(i in seq_along(assignto)) { nama <- assignto[i] valo <- called[[i]] entry <- .Options[[nama]] if (!entry$check(valo)) stop("option ", dQuote(nama), " should be ", entry$valid) .Options[[nama]]$value <- valo } ## done invisible(oldopts) } } surveillance/R/algo_cusum.R0000644000176200001440000002060314402172334015431 0ustar liggesusers################################################### ### chunk number 1: ################################################### algo.cusum <- function(disProgObj, control = list(range=range, k=1.04, h=2.26, m=NULL, trans="standard",alpha=NULL)){ # Set the default values if not yet set if(is.null(control$k)) control$k <- 1.04 if(is.null(control$h)) control$h <- 2.26 if(is.null(control$trans)) control$trans <- "standard" if(is.null(control$alpha)) control$alpha <- 0.1 alpha <- control$alpha observed <- disProgObj$observed timePoint <- control$range[1] # Estimate m (the expected number of cases), i.e. parameter lambda of a # poisson distribution based on time points 1:t-1 if(is.null(control$m)) { m <- mean(observed[1:(timePoint-1)]) } else if (is.numeric(control$m)) { m <- control$m } else if (control$m == "glm") { #Fit a glm to the first observations training <- 1:(timePoint-1) #Set the time index t <- disProgObj$start[2] + training - 1 #Set the observations x <- observed[training] #Set period p <- disProgObj$freq df <- data.frame(x=x,t=t) control$m.glm<- glm(x ~ 1 + cos(2*pi/p*t) + sin(2*pi/p*t) ,family=poisson(),data=df) #predict the values in range t.new <- disProgObj$start[2] + control$range - 1 m <- predict(control$m.glm,newdata=data.frame(t=t.new),type="response") } #No transformation #standObs <- observed[control$range] x <- observed[control$range] standObs <- switch(control$trans, # compute standardized variables z3 (proposed by Rossi) "rossi" = (x - 3*m + 2*sqrt(x*m))/(2*sqrt(m)), # compute standardized variables z1 (based on asympotic normality) "standard" = (x - m)/sqrt(m), # anscombe residuals "anscombe" = 3/2*(x^(2/3)-m^(2/3))/m^(1/6), # anscombe residuals as in pierce schafer based on 2nd order approx of E(X) "anscombe2nd" = (x^(2/3)-(m^(2/3)-m^(-1/3)/9))/(2/3*m^(1/6)), # compute Pearson residuals for NegBin "pearsonNegBin" = (x - m)/sqrt(m+alpha*m^2), # anscombe residuals for NegBin "anscombeNegBin" = anscombeNB(x,mu=m,alpha=alpha), # don't do anything "none" = x, stop("invalid 'trans'formation") ) # initialize the necessary vectors # start with cusum[timePoint -1] = 0, i.e. set cusum[1] = 0 cusum <- matrix(0,nrow=(length(control$range)+1), ncol=1) alarm <- matrix(data = 0, nrow = (length(control$range)+1), ncol = 1) for (t in 1:length(control$range)){ # compute cumulated sums of standardized observations corrected with the # reference value k for all time points in range cusum[t+1]<- max(0, cusum[t]+(standObs[t]-control$k)) # give alarm if the cusum is larger than the decision boundary h alarm[t+1] <- cusum[t+1] >= control$h } #Backtransform h <- control$h k <- control$k Ctm1 <- cusum[1:length(control$range)] upperbound <- switch(control$trans, # standardized variables z3 (proposed by Rossi) "rossi" = 2*h*m^(1/2)+2*k*m^(1/2)-2*Ctm1*m^(1/2)+5*m-2*(4*m^2+2*m^(3/2)*h+2*m^(3/2)*k-2*m^(3/2)*Ctm1)^(1/2), # standardized variables z1 (based on asympotic normality) "standard" = ceiling(sqrt(m)*(h+k-Ctm1)+ m), # anscombe residuals "anscombe" = ifelse( ((2/3)*m^(1/6)*(h+k-Ctm1)+m^(2/3))<0, 0, (2/3*m^(1/6)*(h+k-Ctm1)+m^(2/3))^(3/2) ), # anscombe residuals ? "anscombe2nd" = ifelse( ((2/3)*m^(1/6)*(h+k-Ctm1)+(m^(2/3)-m^(1/3)/9))<0, 0, (2/3*m^(1/6)*(h+k-Ctm1)+(m^(2/3)-m^(1/3)/9))^(3/2) ), # Pearson residuals for NegBin "pearsonNegBin" = sqrt(m+alpha*m^2)*(h+k-Ctm1)+ m, # anscombe residuals for NegBin ? "anscombeNegBin" = h-cusum[-1], # don't do anything "none" = h-cusum[-1] ) # ensure upper bound is positive and not NaN upperbound[is.na(upperbound)] <- 0 upperbound[upperbound < 0] <- 0 # discard cusum[1] and alarm[1] cusum <- cusum[-1] alarm <- alarm[-1] #Add name and data name to control object. control$name <- paste("cusum:", control$trans) control$data <- paste(deparse(substitute(disProgObj))) control$m <- m # return alarm and upperbound vectors result <- list(alarm = alarm, upperbound = upperbound, disProgObj=disProgObj,control=control, cusum=cusum) class(result) = "survRes" # for surveillance system result return(result) } ################################################### ### chunk number 2: ################################################### ###################################################################### # Program to test the transformation of NegBin variables # using the transformation similar to Anscombe residuals ###################################################################### ##################################################################### # function to evaluate hypgeom_2F1(1/3,2/3, 5/3, x) # "exact" values for x = -(0:10) and linear interpolation for x = -(10:100) #################################################################### hypgeom2F1special <- function(x) { #Return the z (the approximation grid), which is closest to x idx <- which.min(abs(surveillance.gvar.z-x)) if(x >= -10) return(surveillance.gvar.hyp[idx]) else{ # find out interval that contains x if((x-surveillance.gvar.z[idx]) < 0){ idxLow <- idx +1 idxUp <- idx } else { idxLow <- idx idxUp <- idx -1 } #linear interpolation: f(x)=f(x0)+(f(x1)-f(x0))/1*(x-x0) return(surveillance.gvar.hyp[idxLow]+(surveillance.gvar.hyp[idxUp]-surveillance.gvar.hyp[idxLow])*(x-surveillance.gvar.z[idxLow])) } } ##################################################################### # compute anscombe residuals for Y ~ NegBin(mu, alpha) using hypgeom2F1 function # E(Y)= \mu, Var(Y) = \mu + \alpha*\mu^2 ################################################################# anscombeNB <- function(y,mu,alpha=0.1) { hypgeom.mu <- 3/2*mu^(2/3)*hypgeom2F1special(-alpha*mu) one <- function(y){ up <- 3/2*y^(2/3) * hypgeom2F1special(-alpha*y) - hypgeom.mu down <- (mu+alpha*mu^2)^(1/6) return(up/down) } return(sapply(y,one)) } ################################################### ### chunk number 3: ################################################### ###################################################################### # Given a specification of the average run length in the (a)cceptance # and (r)ejected setting determine the k and h values in a standard # normal setting. # # Description: # Functions from the spc package are used in a simple univariate # root finding problem. # # Params: # ARLa - average run length in acceptance setting (i.e. number before # false alarm # ARLw - average run length in rejection state (i.e. number before # an increase is detected (i.e. detection delay) # method - optim method to use, see ?optim # # Returns: # list( k - reference value, h - decision interval) ###################################################################### find.kh <- function(ARLa=500,ARLr=7,sided="one",method="BFGS",verbose=FALSE) { if (!requireNamespace("spc")) stop("find.kh() requires package ", sQuote("spc")) #Small helper function which is to be minimized fun <- function(k) { if (k>0) { #Compute decision interval h <- spc::xcusum.crit(L0=ARLa,k=k,r=50,sided=sided) #Check if xcusum.crit managed to find a solution if (is.nan(h)) stop("spc::xcusum.crit was not able to find a h corresponding to ", "ARLa=",ARLa," and k=",k) if (h > 0) { #Compute ARLr given the above computed h arlr <- spc::xcusum.arl(k,h,mu=2*k,r=50,sided=sided) #Deviation from the requested ARLr if (verbose) { cat("k=",k," score = ",(arlr-ARLr)^2,"\n") } return( (arlr-ARLr)^2 ) } else { return(1e99) } } else { return( 1e99) } } k <- optim(1,fun,method=method)$par return(list(k=k,h=spc::xcusum.crit(L0=ARLa,k=k,r=50,sided=sided))) } surveillance/R/catCUSUM.R0000644000176200001440000002135514615162374014675 0ustar liggesusers######################################################################### # Categorical CUSUM for y_t \sim M_k(n_t, \pi_t) for t=1,...,tmax # Workhorse function doing the actual computations - no semantic checks # are performed here, we expect "proper" input. # # Params: # y - (k) \times tmax observation matrix for all categories # pi0 - (k) \times tmax in-control prob vector for all categories # pi1 - (k) \times tmax out-of-control prob vector for all categories # dfun - PMF function of the categorical response, i.e. multinomial, binomial, # beta-binom, etc. # n - vector of dim tmax containing the varying sizes # h - decision threshold of the Categorical CUSUM # calc.at - ######################################################################### catcusum.LLRcompute <- function(y, pi0, pi1, h, dfun, n, calc.at=TRUE,...) { #Initialize variables t <- 0 stopped <- FALSE S <- numeric(ncol(y)+1) U <- numeric(ncol(y)+1) ##Check if dfun is the binomial isBinomialPMF <- isTRUE(attr(dfun,which="isBinomialPMF")) #Run the Categorical LR CUSUM while (!stopped) { #Increase time t <- t+1 #Compute log likelihood ratio llr <- dfun(y=y[,t,drop=FALSE], size=n[t], mu=pi1[,t,drop=FALSE], log=TRUE,...) - dfun(y=y[,t,drop=FALSE], size=n[t], mu=pi0[,t,drop=FALSE], log=TRUE, ...) #Add to CUSUM S[t+1] <- max(0,S[t] + llr) #For binomial data it is also possible to compute how many cases it would take #to sound an alarm given the past. if ((nrow(y) == 2) & calc.at) { ##For the binomial PMF it is possible to compute the number needed for an ##alarm exactly if (isBinomialPMF) { ##Calculations in ../maple/numberneededbeforealarm.mw. at <- (h - S[t] - n[t] * ( log(1 - pi1[1,t]) - log(1-pi0[1,t]))) / (log(pi1[1,t]) - log(pi0[1,t]) - log(1-pi1[1,t]) + log(1-pi0[1,t])) U[t+1] = ceiling(max(0,at)) ##Note: U[t+1] Can be higher than corresponding n_t. if (U[t+1]>n[t]) U[t+1] <- NA } else { #Compute the value at by trying all values between 0 and n_t. If #no alarm, then we know the value for an alarm must be larger than y_t if (S[t+1]>h) { ay <- rbind(seq(0,y[1,t],by=1),n[t]-seq(0,y[1,t],by=1)) } else { ay <- rbind(seq(y[1,t],n[t],by=1),n[t]-seq(y[1,t],n[t],by=1)) } llr <- dfun(ay, size=n[t], mu=pi1[,t,drop=FALSE], log=TRUE,...) - dfun(ay, size=n[t], mu=pi0[,t,drop=FALSE], log=TRUE, ...) alarm <- llr > h-S[t] ##Is any a_t==TRUE?, i.e. does a y_t exist or is the set over which to ##take the minimum empty? if (any(alarm)) { U[t+1] <- ay[1,which.max(alarm)] } else { U[t+1] <- NA } } } ##Only run to the first alarm. Then reset. if ((S[t+1] > h) | (t==ncol(y))) { stopped <- TRUE} } ##If no alarm at the end put rl to end (its censored! hoehle: Actually it should be length+1! ##but the chopping is written such that copying occurs until the final index (hence we can't ##just do ncol(pi0)+1 ##Hence, N is more like the last index investigated. if (any(S[-1]>h)) { t <- which.max(S[-1] > h) } else { t <- ncol(pi0) ##Last one } ##Missing: cases needs to be returned! return(list(N=t,val=S[-1],cases=U[-1])) } ###################################################################### ## Wrap function to process sts object by categoricalCUSUM (new S4 ## style). Time varying number of counts is found in slot populationFrac. ## ## Params: ## control - list with the following components ## * range - vector of indices in disProgObj to monitor ## * h - threshold, once CUSUM > h we have an alarm ## * pi0 - (k-1) \times tmax in-control prob vector for all but ref cat ## * pi1 - (k-1) \times tmax out-of-control prob vector for all but ref cat ## * dfun - PMF to use for the computations, dmultinom, dbinom, dBB, etc. ## ... - further parameters to be sent to dfun ###################################################################### categoricalCUSUM <- function(stsObj, control = list(range=NULL,h=5, pi0=NULL, pi1=NULL, dfun=NULL, ret=c("cases","value")),...) { ##Set the default values if not yet set if(is.null(control[["pi0"]])) { stop("no specification of in-control proportion vector pi0") } if(is.null(control[["pi1"]])) { stop("no specification of out-of-control proportion vector pi1") } if(is.null(control[["dfun"]])) { stop("no specification of the distribution to use, e.g. dbinom, dmultinom or similar") } if(is.null(control[["h"]])) control$h <- 5 if(is.null(control[["ret"]])) control$ret <- "value" ##Extract the important parts from the arguments if (is.numeric(control[["range"]])) { range <- control$range } else { stop("the range needs to be an index vector") } stsObj <- stsObj[range,] y <- t(stsObj@observed) pi0 <- control[["pi0"]] pi1 <- control[["pi1"]] dfun <- control[["dfun"]] control$ret <- match.arg(control$ret, c("value","cases")) ##Total number of objects that are investigated. Note this ##can't be deduced from the observed y, because only (c-1) columns ##are reported so using: n <- apply(y, 2, sum) is wrong! ##Assumption: all populationFrac's contain n_t and we can take just one n <- stsObj@populationFrac[,1] ##Semantic checks if ( ((ncol(y) != ncol(pi0)) | (ncol(pi0) != ncol(pi1))) | ((nrow(y) != nrow(pi0)) | (nrow(pi0) != nrow(pi1)))) { stop("dimensions of y, pi0 and pi1 have to match") } if ((control$ret == "cases") & nrow(pi0) != 2) { stop("cases can only be returned in case k=2") } if (length(n) != ncol(y)) { stop("length of n has to be equal to number of columns in y") } ##Check if all n entries are the same if (!all(apply(stsObj@populationFrac,1,function(x) all.equal(as.numeric(x),rev(as.numeric(x)))))) { stop("all entries for n have to be the same in populationFrac") } ##Reserve space for the results ##start with cusum[timePoint -1] = 0, i.e. set cusum[1] = 0 alarm <- matrix(data = FALSE, nrow = length(range), ncol = nrow(y)) upperbound <- matrix(data = 0, nrow = length(range), ncol = nrow(y)) ##Small helper function to be used along the way --> move to other file! either <- function(cond, whenTrue, whenFalse) { if (cond) return(whenTrue) else return(whenFalse) } ##Setup counters for the progress doneidx <- 0 N <- 1 noofalarms <- 0 noOfTimePoints <- length(range) ####################################################### ##Loop as long as we are not through the entire sequence ####################################################### while (doneidx < noOfTimePoints) { ##Run Categorical CUSUM until the next alarm res <- catcusum.LLRcompute(y=y, pi0=pi0, pi1=pi1, n=n, h=control$h, dfun=dfun,calc.at=(control$ret=="cases"),...) ##Note: res$N is the last index investigated in the updated y vector. ##If res$N == ncol(y) no alarm was found in the last segment. ##In case an alarm found put in into the log and reset the chart at res$N+1. if (res$N < ncol(y)) { ##Put appropriate value in upperbound upperbound[1:res$N + doneidx,] <- matrix(rep(either(control$ret == "value", res$val[1:res$N] ,res$cases[1:res$N]),each=ncol(upperbound)),ncol=ncol(upperbound),byrow=TRUE) alarm[res$N + doneidx,] <- TRUE ##Chop & get ready for next round y <- y[,-(1:res$N),drop=FALSE] pi0 <- pi0[,-(1:res$N),drop=FALSE] pi1 <- pi1[,-(1:res$N),drop=FALSE] n <- n[-(1:res$N)] ##Add to the number of alarms noofalarms <- noofalarms + 1 } ##cat("doneidx = ",doneidx, "\t res$N =", res$N,"\n") ##Update index of how far we are in the time series doneidx <- doneidx + res$N } ##Add upperbound-statistic of last segment (note: an alarm might or might be reached here) upperbound[(doneidx-res$N+1):nrow(upperbound),] <- matrix( rep(either(control$ret == "value", res$val, res$cases),each=ncol(upperbound)),ncol=ncol(upperbound),byrow=TRUE) ##Inherit alarms as well (last time point might contain an alarm!) alarm[(doneidx-res$N+1):nrow(upperbound),] <- matrix( rep(res$val > control$h,each=ncol(alarm)), ncol=ncol(alarm),byrow=TRUE) # Add name and data name to control object control$name <- "categoricalCUSUM" control$data <- NULL #not supported anymore #store results in the sts object stsObj@alarm <- alarm stsObj@upperbound <- upperbound stsObj@control <- control #Ensure dimnames in the new object stsObj <- fix.dimnames(stsObj) #Done return(stsObj) } surveillance/R/plot.survRes.R0000644000176200001440000000247214200437000015713 0ustar liggesusers## legacy code removed in surveillance 1.20.0 ## now plotting via stsplot_time() plot.survRes <- function(x, method = x$control$name, disease = x$control$data, xaxis.years = TRUE, startyear = 2001, firstweek = 1, same.scale = TRUE, ..., main = paste0("Analysis of ", disease, " using ", method)) { stopifnot(is.vector(x$control$range, mode = "numeric")) stsObjRange <- disProg2sts(x[["disProgObj"]])[x$control$range,] stsObjRange@alarm[] <- x[["alarm"]] stsObjRange@upperbound[] <- x[["upperbound"]] if (length(ignored <- c("startyear", "firstweek")[c(!missing(startyear), !missing(firstweek))])) warning("ignored legacy argument(s): ", paste0(ignored, collapse = ", ")) ## see plot(sts.cdc) in vignette("surveillance") or demo("cost") hookFunc <- if (is.null(x$aggr)) function() NULL else { stsObjRange@control$aggr <- x$aggr upperboundx <- NULL # make codetools::checkUsage() happy function() points(upperboundx, x@control$aggr) } if (xaxis.years) { stsplot_time(stsObjRange, same.scale = same.scale, ..., main = main, hookFunc = hookFunc) } else { stsplot_time(stsObjRange, same.scale = same.scale, ..., main = main, hookFunc = hookFunc, xaxis.labelFormat = NULL) } } surveillance/R/twinstim_siaf_powerlaw.R0000644000176200001440000001312614426171115020077 0ustar liggesusers################################################################################ ### Power-law kernel f(s) = (||s||+sigma)^-d ### This is the pure kernel of the Lomax density (the density requires d>1, but ### for the siaf specification we only want d to be positive) ### ### Copyright (C) 2013-2014,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ siaf.powerlaw <- function (nTypes = 1, validpars = NULL, engine = "C") { nTypes <- as.integer(nTypes) stopifnot(length(nTypes) == 1L, nTypes > 0L) engine <- match.arg(engine, c("C", "R")) ## for the moment we don't make this type-specific if (nTypes != 1) stop("type-specific shapes are not yet implemented") ## helper expression, note: logpars=c(logscale=logsigma, logd=logd) tmp <- expression( logsigma <- logpars[[1L]], # used "[[" to drop names logd <- logpars[[2L]], sigma <- exp(logsigma), d <- exp(logd) ) ## spatial kernel f <- function (s, logpars, types = NULL) {} body(f) <- as.call(c(as.name("{"), tmp, expression(sLength <- sqrt(.rowSums(s^2, nrow(s), 2L))), expression((sLength+sigma)^-d) )) environment(f) <- baseenv() ## numerically integrate f over a polygonal domain F <- siaf_F_polyCub_iso(intrfr_name = "intrfr.powerlaw", engine = engine) ## fast integration of f over a circular domain Fcircle <- function (r, logpars, type = NULL) {} body(Fcircle) <- as.call(c(as.name("{"), tmp, expression( fofr <- (r+sigma)^-d, fof0 <- sigma^-d, ## calculate cylinder volume up to height f(r) basevolume <- if (is.infinite(r)) 0 else pi * r^2 * fofr, ## r=Inf is used in R0(,trimmed=F), Fcircle(Inf) is finite if d>2 Ifinvsq <- function (z) { if (d == 1) { -1/z - 2*sigma*log(z) + sigma^2*z } else if (d == 2) { log(z) - 4*sigma*sqrt(z) + sigma^2*z } else { z^(1-2/d) * d / (d-2) - z^(1-1/d) * 2*sigma*d/(d-1) + sigma^2*z } }, intfinvsq <- Ifinvsq(fof0) - Ifinvsq(fofr), basevolume + pi * intfinvsq ) )) environment(Fcircle) <- baseenv() ## derivative of f wrt logpars deriv <- function (s, logpars, types = NULL) {} body(deriv) <- as.call(c(as.name("{"), tmp, expression( sLength <- sqrt(.rowSums(s^2, nrow(s), 2L)), rsigma <- sLength + sigma, rsigmad <- rsigma^d, derivlogsigma <- -d*sigma / rsigmad / rsigma, derivlogd <- -d*log(rsigma) / rsigmad, cbind(derivlogsigma, derivlogd) ) )) environment(deriv) <- baseenv() ## Numerical integration of 'deriv' over a polygonal domain Deriv <- siaf_Deriv_polyCub_iso( intrfr_names = c("intrfr.powerlaw.dlogsigma", "intrfr.powerlaw.dlogd"), engine = engine) ## Simulation function (via polar coordinates) simulate <- siaf.simulatePC(intrfr.powerlaw) ## if (!is.finite(ub)) normconst <- { ## ## for sampling on [0;Inf] the density is only proper if d > 2 ## if (d <= 2) stop("improper density for d<=2, 'ub' must be finite") ## 1/(sigma^(d-2) * (d-2)*(d-1)) # = intrfr.powerlaw(Inf) ## } environment(simulate) <- getNamespace("surveillance") ## return the kernel specification list(f=f, F=F, Fcircle=Fcircle, deriv=deriv, Deriv=Deriv, simulate=simulate, npars=2L, validpars=validpars) } ## integrate x*f(x) from 0 to R (vectorized) intrfr.powerlaw <- function (R, logpars, types = NULL) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) if (d == 1) { R - sigma * log(R/sigma + 1) } else if (d == 2) { log(R/sigma + 1) - R/(R+sigma) } else { (R*(R+sigma)^(1-d) - ((R+sigma)^(2-d) - sigma^(2-d))/(2-d)) / (1-d) } } ## local({ # validation via numerical integration -> tests/testthat/test-siafs.R ## p <- function (r, sigma, d) r * (r+sigma)^-d ## Pnum <- function (r, sigma, d) sapply(r, function (.r) { ## integrate(p, 0, .r, sigma=sigma, d=d)$value ## }) ## r <- c(1,2,5,10,20,50,100) ## dev.null <- sapply(c(1,2,1.6), function(d) stopifnot(isTRUE( ## all.equal(intrfr.powerlaw(r, log(c(3, d))), Pnum(r, 3, d))))) ## }) ## integrate x * (df(x)/dlogsigma) from 0 to R (vectorized) intrfr.powerlaw.dlogsigma <- function (R, logpars, types = NULL) { pars <- exp(logpars) -prod(pars) * intrfr.powerlaw(R, log(pars+c(0,1)), types) } ## integrate x * (df(x)/dlogd) from 0 to R (vectorized) ## (thanks to Maple 17) -> validated in tests/testthat/test-siafs.R intrfr.powerlaw.dlogd <- function (R, logpars, types = NULL) { sigma <- exp(logpars[[1L]]) d <- exp(logpars[[2L]]) if (d == 1) { sigma * logpars[[1L]] * (1-logpars[[1L]]/2) - log(R+sigma) * (R+sigma) + sigma/2 * log(R+sigma)^2 + R } else if (d == 2) { (-log(R+sigma) * ((R+sigma)*log(R+sigma) + 2*sigma) + (R+sigma)*logpars[[1L]]*(logpars[[1L]]+2) + 2*R) / (R+sigma) } else { (sigma^(2-d) * (logpars[[1L]]*(-d^2 + 3*d - 2) - 2*d + 3) + (R+sigma)^(1-d) * (log(R+sigma)*(d-1)*(d-2) * (R*(d-1) + sigma) + R*(d^2+1) + 2*d*(sigma-R) - 3*sigma) ) * d / (d-1)^2 / (d-2)^2 } } surveillance/R/sts_ggplot.R0000644000176200001440000000366214026737231015473 0ustar liggesusers################################################################################ ### Plot a surveillance time series ("sts") object using ggplot2 ### ### Copyright (C) 2018,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ autoplot.sts <- function (object, population = FALSE, units = NULL, as.one = FALSE, scales = "fixed", width = NULL, ...) { stopifnot(is(object, "sts")) data <- tidy.sts(object) if (all(is.na(data$date))) stop("could not derive date index via 'epoch(object, as.Date=TRUE)';", "\n attach dates using 'epoch(object) <- DATE_OBJECT' first") ## sensible default width for weekly/daily data if (is.null(width)) { if (object@freq == 52) width <- 7 if (object@freq == 365) width <- 1 } ## select subset of units to plot if (!is.null(units)) { ## ensure that 'units' are labels, not indices units <- unname(setNames(nm = levels(data$unit))[units]) data <- data[data$unit %in% units, , drop=FALSE] } ## scale counts by population if (doInc <- isScalar(population) || isTRUE(population)) data$observed <- data$observed / (data$population / population) p <- ggplot2::ggplot( data = data, mapping = ggplot2::aes_(x = ~date, y = ~observed, group = ~unit), environment = parent.frame() ) if (as.one) { p <- p + ggplot2::geom_line(ggplot2::aes_(colour = ~unit)) } else { p <- p + ggplot2::geom_col(width = width) + ggplot2::facet_wrap(~unit, scales = scales, drop = TRUE) } p + ggplot2::labs(x = "Time", y = if(doInc) "Incidence" else "No. infected") } surveillance/R/twinSIR_simulation.R0000644000176200001440000006426314430705133017110 0ustar liggesusers################################################################################ ### Simulate from a "twinSIR" model as described in Hoehle (2009) ### ### Copyright (C) 2009 Michael Hoehle, 2009,2012,2014,2019,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## Apart from simulation of SIR data, it is possible to simulate ## - SI: infPeriod = function(ids) rep(Inf, length(ids) ## - SIS: remPeriod = function(ids) rep(0, length(ids) ## - SIRS: remPeriod in (0;Inf) ## ## One can even simulate from a Cox model with the following settings: ## + no removal (i.e. infPeriod = function(ids) rep(Inf, length(ids)) ## + no epidemic component (i.e. no alpha, no f, no w). simEpidata <- function (formula, data, id.col, I0.col, coords.cols, subset, beta, h0, f = list(), w = list(), alpha, infPeriod, remPeriod = function(ids) rep(Inf, length(ids)), end = Inf, trace = FALSE, .allocate = NULL) { stopifnot(inherits(formula, "formula"), is.data.frame(data)) cl <- match.call() ####################### ### Check arguments ### ####################### ### Build up model.frame mfnames <- c("", "formula", "data", "subset") mf <- cl[match(mfnames, names(cl), nomatch = 0L)] if (!"subset" %in% names(mf)) { # subset can be missing ## need explicit argument to avoid partial matching with coords.cols mf["subset"] <- list(NULL) } mf$na.action <- as.name("na.fail") mf$drop.unused.levels <- FALSE mf$xlev <- list() ## additional columns for the model frame if (inherits(data, "epidata")) { id.col <- "id" I0.col <- "atRiskY" # but we need !atRiskY (will be considered below) coords.cols <- names(data)[attr(data, "coords.cols")] if(length(formula) == 2L) { # i.e. no response specified formula[3L] <- formula[2L] formula[[2L]] <- quote(cbind(start, stop)) } } else { for(colarg in c("id.col", "I0.col", "coords.cols")) { colidx <- get(colarg, inherits = FALSE) if (is.numeric(colidx)) { tmp <- names(data)[colidx] if (anyNA(tmp)) { stop("'", colarg, " = ", deparse(cl[[colarg]]), "': ", "column index must be in [1; ", ncol(data), "=ncol(data)]") } assign(colarg, tmp, inherits = FALSE) } } } mf$I0 <- if (is.null(I0.col)) { substitute(rep(0, N), list(N=nrow(data))) } else as.name(I0.col) mf$id <- as.name(id.col) for(coords.col in coords.cols) { mf[[coords.col]] <- as.name(coords.col) } special <- c("cox") Terms <- terms(formula, specials = special, data = data, keep.order = TRUE, simplify = FALSE) mf$formula <- Terms mf[[1]] <- as.name("model.frame") mf <- eval(mf, parent.frame()) ### Convert id to a factor (also removing unused levels if it was a factor) mf[["(id)"]] <- factor(mf[["(id)"]]) ids <- levels(mf[["(id)"]]) nObs <- length(ids) if (nObs == 0L) { stop("nothing to do: no individuals in 'data'") } idsInteger <- seq_len(nObs) ### Check start/stop consistency (response) .startstop <- model.response(mf) if (NCOL(.startstop) != 2L || !is.numeric(.startstop)) { stop("the lhs of 'formula' must be a numeric matrix with two columns ", "like 'cbind(start, stop)'") } timeIntervals <- unique(.startstop) timeIntervals <- timeIntervals[order(timeIntervals[,1L]), , drop = FALSE] nBlocks <- nrow(timeIntervals) if (any(timeIntervals[,2L] <= timeIntervals[,1L])) { stop("stop times must be greater than start times") } if (any(timeIntervals[-1L,1L] != timeIntervals[-nBlocks,2L])) { stop("inconsistent start/stop times: time intervals not consecutive") } ### Check .allocate if (is.null(.allocate)) { .allocate <- max(500, ceiling(nBlocks/100)*100) } else { if (!isScalar(.allocate) || .allocate < nBlocks) { stop("'.allocate' must be >= ", nBlocks) } } ### Check that all blocks are complete (all id's present) .blockidx <- match(.startstop[,1L], timeIntervals[,1L]) if (any(table(.blockidx) != nObs)) { stop("all time intervals must be present for all id's") } ### Define a vector containing the time points where covariates change # unique 'start' time points (=> includes beginning of observation period) externalChangePoints <- as.vector(timeIntervals[,1L]) ### SORT THE MODEL.FRAME BY BLOCK AND ID !!! mf <- mf[order(.blockidx, mf[["(id)"]]),] ### Extract the coordinates coords <- as.matrix(mf[idsInteger, tail(1:ncol(mf),length(coords.cols))]) colnames(coords) <- coords.cols rownames(coords) <- ids ### Extract the endemic part Z of the design matrix (no intercept) des <- read.design(mf, Terms) Z <- des$Z nPredCox <- ncol(Z) # number of endemic (cox) predictor terms ### Only include basic endemic variables in the event history output basicCoxNames <- rownames(attr(Terms,"factors"))[attr(Terms,"specials")$cox] basicVarNames <- sub("cox\\(([^)]+)\\)", "\\1", basicCoxNames) nBasicVars <- length(basicCoxNames) # this is necessary if some variables in 'formula' do not have main effects extraBasicVars <- as.matrix(mf[setdiff(basicCoxNames, colnames(Z))]) ### Build up 3-dim array [id x time x var] of endemic terms coxArray <- array(cbind(Z, extraBasicVars), dim = c(nObs, nBlocks, ncol(Z) + ncol(extraBasicVars)), dimnames = list(ids, NULL, c(colnames(Z), colnames(extraBasicVars)))) idxPredVars <- seq_len(nPredCox) idxBasicVars <- match(basicCoxNames, dimnames(coxArray)[[3]]) ### Check simulation parameters ## endemic (cox) part if (nPredCox > 0L) { if(missing(beta) || length(beta) != nPredCox || !is.numeric(beta)) { stop(gettextf(paste("'beta', a numeric vector of length %d", "(number of endemic terms), must be specified"), nPredCox)) } } else { beta <- numeric(0L) } ## epidemic part nPredEpi <- length(f) + length(w) if (nPredEpi > 0L) { ## check f if (length(f) > 0L) { if (ncol(coords) == 0L) { stop("need coordinates for distance-based epidemic covariates 'f'") } if (!is.list(f) || is.null(names(f)) || any(!sapply(f, is.function))) { stop("'f' must be a named list of functions") } distmat <- as.matrix(dist(coords, method = "euclidean")) } ## check w if (length(w) > 0L) { if (!is.list(w) || is.null(names(w)) || any(!sapply(w, is.function))) { stop("'w' must be a named list of functions") } wijlist <- compute_wijlist(w = w, data = mf[idsInteger, ]) } ## check alpha (coefficients for all of f and w) if (missing(alpha) || !is.numeric(alpha) || is.null(names(alpha))) { stop(gettextf(paste("'alpha', a named numeric vector of length %d", "(number of epidemic terms), must be specified"), nPredEpi)) } alpha <- alpha[c(names(f), names(w))] if (anyNA(alpha)) { stop("'alpha' is incomplete for 'f' or 'w'") } stopifnot(alpha >= 0) } else { alpha <- numeric(0L) } ### Parse the generator function for the infectious periods if (missing(infPeriod)) { stop("argument 'infPeriod' is missing (with no default)") } infPeriod <- match.fun(infPeriod) ### Parse the generator function for the removal periods remPeriod <- match.fun(remPeriod) ### Parse the log baseline function h0spec <- paste("'h0' must be a single number or a list of functions", "\"exact\" and \"upper\"") if (missing(h0)) { stop(h0spec) } if (is.list(h0)) { if (!all(is.function(h0[["exact"]]), is.function(h0[["upper"]]))) { stop(h0spec) } if (!inherits(h0$upper, "stepfun")) { stop("function 'h0$upper' must be a 'stepfun'") } h0ChangePoints <- knots(h0$upper) } else if (isScalar(h0)) { h0func <- as.function(c(alist(t=), list(h0)), envir = .GlobalEnv) h0 <- list(exact = h0func, upper = h0func) h0ChangePoints <- numeric(0L) } else { stop(h0spec) } if (!isScalar(h0$exact(0))) { stop("'h0$exact' must return a scalar") } ### Define function which decides if to reject a proposal during simulation exactEqualsUpper <- identical(h0$exact, h0$upper) mustReject <- if (exactEqualsUpper) { function () FALSE } else { function () lambdaStar/lambdaStarMax < runif(1) } ### Check simulation ending time if (!isScalar(end) || end <= 0) { stop("'end' must be a single positive numeric value") } ################### ### Preparation ### ################### ### Initialize set of infected and susceptible individuals infected <- which( mf[idsInteger,"(I0)"] == as.numeric(!inherits(data, "epidata")) ) # in case of "epidata", mf$(I0) equals data$atRiskY => infected = I0==0 susceptibles <- which(! idsInteger %in% infected) ### Initialize tables of planned R-events and S-events Revents <- if (length(infected) > 0) { cbind(infected, infPeriod(ids[infected])) } else { matrix(numeric(0), ncol = 2) } Sevents <- matrix(numeric(0), ncol = 2) ### Small hook to subsequently update the (time depending) Cox predictor ### based on the current time (ct) during the simulation loop if (nPredCox > 0L) { coxUpdate <- expression( predCox <- as.matrix( coxArray[,which(externalChangePoints == ct),idxPredVars] ) %*% beta ) } else { predCox <- numeric(nObs) # zeros } ### 'lambdaCalc' is the main expression for the calculation of the intensity ### values IMMEDIATELY AFTER the current time 'ct'. ### It will be evaluated during the while-loop below. lambdaCalc <- expression( # Endemic Cox predictor (no h0 here!) of susceptibles predCoxS <- predCox[susceptibles], # Epidemic component of susceptibles lambdaEpidemic <- numeric(length(susceptibles)), # zeros if (nPredEpi > 0L && length(infected) > 0L) { fCovars <- if (length(f) > 0L) { u <- distmat[,infected, drop = FALSE] vapply(X = f, FUN = function (B) rowSums(B(u)), FUN.VALUE = numeric(nObs), USE.NAMES = FALSE) } else NULL wCovars <- if (length(w) > 0L) { vapply(X = wijlist, FUN = function (wij) { rowSums(wij[, infected, drop = FALSE]) }, FUN.VALUE = numeric(nobs), USE.NAMES = FALSE) } else NULL epiCovars <- cbind(fCovars, wCovars, deparse.level=0) # epiCovars is a matrix [nObs x nPredEpi] also used by updateNextEvent if (length(susceptibles) > 0L) { lambdaEpidemic <- epiCovars[susceptibles,,drop=FALSE] %*% alpha } }, # Combined intensity lambdaS <- lambdaEpidemic + exp(h0$exact(ct) + predCoxS), # Ground intensity (sum of all lambdaS's) lambdaStar <- sum(lambdaS), # Upper bound on ground intensity lambdaStarMax <- if (exactEqualsUpper) { lambdaStar } else { sum(lambdaEpidemic) + sum(exp(h0$upper(ct) + predCoxS)) } ) # the following initializations are for R CMD check only ("visible binding") lambdaS <- numeric(length(susceptibles)) lambdaStarMax <- lambdaStar <- numeric(1L) # At current time (ct) we have: # lambdaS is a _vector of length the current number of susceptibles_ # containing the intensity of infection for each susceptible individual. # lambdaStar is the overall infection rate. # lambdaStarMax is the upper bound for lambdaStar regarding baseline. # 'susceptible' and 'infected' are the corresponding sets of individuals # immediately AFTER the last event # in theory, if a covariate changes in point t, then the intensity changes # at t+0 only. intensities are left-continuous functions. time interval of # constant intensity is (start;stop]. but in the implementation we need at # time ct the value of the log-baseline at ct+0, especially for # ct %in% h0ChangePoints, thus h0$upper should be a stepfun with right=FALSE ### Create a history object alongside the simulation epiCovars0 <- matrix(0, nrow = nObs, ncol = nPredEpi, dimnames = list(NULL, c(names(f), names(w)))) basicVars0 <- matrix(0, nrow = nObs, ncol = nBasicVars, dimnames = list(NULL, basicVarNames)) emptyEvent <- cbind(BLOCK = 0, id = idsInteger, start = 0, stop = 0, atRiskY = 0, event = 0, Revent = 0, coords, basicVars0, epiCovars0) # WARNING: if you change the column order, you have to adjust the # hard coded column indexes everywhere below, also in getModel.simEpidata ! .epiIdx <- tail(seq_len(ncol(emptyEvent)), nPredEpi) .basicIdx <- 7L + ncol(coords) + seq_len(nBasicVars) .nrowsEvHist <- .allocate * nObs # initial size of the event history evHist <- matrix(NA_real_, nrow = .nrowsEvHist, ncol = ncol(emptyEvent), dimnames = list(NULL, colnames(emptyEvent))) ## Hook - create new event and populate it with appropriate covariates updateNextEvent <- expression( nextEvent <- emptyEvent, # populate epidemic covariates if (nPredEpi > 0L && length(infected) > 0L) { nextEvent[,.epiIdx] <- epiCovars # was calculated in lambdaCalc }, # Which time is currently appropriate in (time varying) covariates tIdx <- match(TRUE, c(externalChangePoints,Inf) > ct) - 1L, if (nBasicVars > 0L) { nextEvent[,.basicIdx] <- coxArray[,tIdx,idxBasicVars] }, # At-risk indicator if (length(susceptibles) > 0) { nextEvent[susceptibles,5L] <- 1 }, # Block index nextEvent[,1L] <- rep.int(block, nObs), # Start time nextEvent[,3L] <- rep.int(ct, nObs) ) ## Hook function to add the event to the history addNextEvent <- expression( nextEvent[,4L] <- rep.int(ct, nObs), # stop time if (block*nObs > .nrowsEvHist) { # enlarge evHist if not big enough if (trace > 0L) { cat("Enlarging the event history @ block", block, "...\n") } evHist <- rbind(evHist, matrix(NA_real_, nrow = .allocate * nObs, ncol = ncol(emptyEvent)) ) .nrowsEvHist <- .nrowsEvHist + .allocate * nObs }, evHistIdx <- idsInteger + nObs * (block-1), # = seq.int(from = 1 + nObs*(block-1), to = nObs*block) evHist[evHistIdx,] <- nextEvent, block <- block + 1 ) ####################################################################### ### MAIN PART: sequential simulation of infection and removal times ### ####################################################################### ### Some indicators ct <- timeIntervals[1L,1L] # = externalChangePoints[1] # current time block <- 1 pointRejected <- FALSE loopCounter <- 0L trace <- as.integer(trace) hadNumericalProblemsInf <- hadNumericalProblems0 <- FALSE eventTimes <- numeric(0) ### Update (time depending) endemic covariates (if there are any) if (nPredCox > 0L) { eval(coxUpdate) } ### Let's rock 'n roll repeat { loopCounter <- loopCounter + 1L if (trace > 0L && loopCounter %% trace == 0L) { cat(loopCounter, "@t =", ct, ":\t|S| =", length(susceptibles), " |I| =", length(infected), "\trejected?", pointRejected, "\n") } if (!pointRejected) { ## Compute current conditional intensity eval(lambdaCalc) ## Update event history (uses epiCovars from lambdaCalc) eval(updateNextEvent) } pointRejected <- FALSE ## Determine time of next external change point changePoints <- c(externalChangePoints, h0ChangePoints, Revents[,2], Sevents[,2]) .isPendingChangePoint <- changePoints > ct nextChangePoint <- if (any(.isPendingChangePoint)) { min(changePoints[.isPendingChangePoint]) } else Inf ## Simulate waiting time for the subsequent infection T <- tryCatch(rexp(1, rate = lambdaStarMax), warning = function(w) { if (!is.na(lambdaStarMax) && lambdaStarMax < 1) { # rate was to small for rexp if (length(susceptibles) > 0L) { assign("hadNumericalProblems0", TRUE, inherits = TRUE) } if (nextChangePoint == Inf) NULL else Inf } else { # rate was to big for rexp 0 # since R-2.7.0 rexp(1, Inf) returns 0 with no warning! } }) ## Stop if lambdaStarMax too small AND no more changes in rate if (is.null(T)) { ct <- end eval(addNextEvent) break } ## Stop if lambdaStarMax too big meaning T == 0 (=> concurrent events) if (T == 0) { hadNumericalProblemsInf <- TRUE break } ## Stop at all costs if end of simulation time [0; end) has been reached if (isTRUE(min(ct+T, nextChangePoint) >= end)) { # ">=" because we don't want an event at "end" ct <- end eval(addNextEvent) break } if (ct + T > nextChangePoint) { ## Simulated time point is beyond the next time of intensity change ## (removal or covariate or upper baseline change point) ct <- nextChangePoint if (nPredCox > 0L && ct %in% externalChangePoints) { # update endemic covariates eval(coxUpdate) } if (.Reventidx <- match(ct, Revents[,2L], nomatch = 0L)) { # removal (I->R), thus update set of infected remover <- Revents[.Reventidx,1L] .remPeriod <- remPeriod(ids[remover]) Sevents <- rbind(Sevents, c(remover, ct + .remPeriod)) infected <- infected[-match(remover, infected)] nextEvent[remover,7L] <- 1 } if (.Seventidx <- match(ct, Sevents[,2L], nomatch = 0L)) { # this will also be TRUE if above .remPeriod == 0 (SIS-like with pseudo-R-event) # re-susceptibility (R->S), thus update set of susceptibles resusceptible <- Sevents[.Seventidx,1L] susceptibles <- c(susceptibles, resusceptible) } # update event history eval(addNextEvent) } else { ## Simulated time point lies within the thinning period ## => rejection sampling step ct <- ct + T if (length(h0ChangePoints) > 0L) {# i.e. if non-constant baseline # Update intensities for rejection probability at new ct eval(lambdaCalc) } if (mustReject()) { pointRejected <- TRUE next } # At this point, we have an actual event! => # Sample the individual who becomes infected with probabilities # according to the intensity proportions victimSindex <- sample(length(susceptibles), 1L, prob = lambdaS/lambdaStar) victim <- susceptibles[victimSindex] eventTimes <- c(eventTimes, ct) Revents <- rbind(Revents, c(victim, ct + infPeriod(ids[victim]))) susceptibles <- susceptibles[-victimSindex] infected <- c(infected, victim) # Add to history nextEvent[victim,6L] <- 1 eval(addNextEvent) } } ############## ### Return ### ############## if (hadNumericalProblemsInf) { warning("simulation ended due to an infinite overall infection rate") } if (hadNumericalProblems0) { warning("occasionally, the overall infection rate was numerically ", "equal to 0 although there were individuals at risk") } if (trace > 0L) { cat("Converting the event history into a data.frame (\"epidata\") ...\n") } epi <- as.data.frame(evHist[seq_len(nObs*(block-1)),,drop=FALSE]) epi$id <- factor(ids[epi$id], levels = ids) rownames(epi) <- NULL attr(epi, "eventTimes") <- eventTimes attr(epi, "timeRange") <- c(timeIntervals[1L,1L], ct) attr(epi, "coords.cols") <- 7L + seq_len(ncol(coords)) attr(epi, "f") <- f attr(epi, "w") <- w attr(epi, "config") <- list(h0 = h0$exact, beta = beta, alpha = alpha) attr(epi, "call") <- cl attr(epi, "terms") <- Terms class(epi) <- c("simEpidata", "epidata", "data.frame") if (trace > 0L) { cat("Done.\n") } return(epi) } ### We define no plot-method for simEpidata (as a wrapper for intensityPlot), ### because we want plot(simEpidataObject) to use the inherited method plot.epidata ### which shows the evolution of the numbers of individuals in states S, I, and R ################################################################################ # A 'simulate' method for objects of class "twinSIR". ################################################################################ simulate.twinSIR <- function (object, nsim = 1, seed = 1, infPeriod = NULL, remPeriod = NULL, end = diff(range(object$intervals)), trace = FALSE, .allocate = NULL, data = object$data, ...) { theta <- coef(object) px <- ncol(object$model$X) pz <- ncol(object$model$Z) nh0 <- attr(object$terms, "intercept") * length(object$nEvents) f <- object$model$f # contains only the f's used in the model formula w <- object$model$w # contains only the w's used in the model formula if (any(missingf <- !names(f) %in% colnames(object$model$X))) { stop("simulation requires distance functions 'f', missing for: ", paste(colnames(object$model$X)[missingf], collapse=", ")) } if (any(missingw <- !names(w) %in% colnames(object$model$X))) { stop("simulation requires functions 'w', missing for: ", paste(colnames(object$model$X)[missingw], collapse=", ")) } formulaLHS <- "cbind(start, stop)" formulaRHS <- paste(c(as.integer(nh0 > 0), # endemic intercept? names(theta)[px+nh0+seq_len(pz-nh0)]), collapse = " + ") formula <- formula(paste(formulaLHS, formulaRHS, sep="~"), env = environment(formula(object))) h0 <- if (nh0 == 0L) { if (pz == 0L) { -Inf # no endemic component at all (exp(-Inf) == 0) } else { 0 # endemic covariates act on 0-log-baseline hazard } } else { .h0 <- stepfun(x = object$intervals[1:nh0], y = c(0,theta[px+seq_len(nh0)]), right = FALSE) list(exact = .h0, upper = .h0) } if (!inherits(data, "epidata")) { stop("invalid 'data' argument: use function 'twinSIR' with ", "'keep.data = TRUE'") } if (is.null(infPeriod) || is.null(remPeriod)) { s <- summary(data) eventsByID <- s$byID if (is.null(infPeriod)) { infPeriod <- if (s$type == "SI") { function (ids) rep.int(Inf, length(ids)) } else { # SIR, SIRS or SIS eventsByID$infPeriod <- eventsByID$time.R - eventsByID$time.I meanInfPeriodByID <- if (s$type %in% c("SIRS", "SIS")) { c(tapply(eventsByID$infPeriod, list(eventsByID$id), mean, na.rm = TRUE, simplify = TRUE)) } else { structure(eventsByID$infPeriod, names = eventsByID$id) } meanInfPeriod <- mean(meanInfPeriodByID, na.rm = TRUE) if (is.na(meanInfPeriod)) { stop("'infPeriod = NULL' invalid: ", "no infection periods observed") } function (ids) { infPeriods <- meanInfPeriodByID # named vector infPeriods[is.na(infPeriods)] <- meanInfPeriod infPeriods[ids] } } } if (is.null(remPeriod)) { remPeriod <- if (s$type == "SIRS") { eventsByID$remPeriod <- eventsByID$time.S - eventsByID$time.R meanRemPeriodByID <- c(tapply(eventsByID$remPeriod, list(eventsByID$id), mean, na.rm = TRUE, simplify = TRUE)) meanRemPeriod <- mean(meanRemPeriodByID, na.rm = TRUE) function (ids) { remPeriods <- meanRemPeriodByID # named vector remPeriods[is.na(remPeriods)] <- meanRemPeriod remPeriods[ids] } } else if (s$type == "SIS") { function (ids) rep.int(0, length(ids)) } else { # SIR or SI function (ids) rep.int(Inf, length(ids)) } } } set.seed(seed) res <- replicate(nsim, simEpidata(formula, data = data, beta = theta[px + nh0 + seq_len(pz-nh0)], h0 = h0, f = f, w = w, alpha = theta[seq_len(px)], infPeriod = infPeriod, remPeriod = remPeriod, end = end, trace = trace, .allocate = .allocate), simplify = FALSE ) if (nsim == 1L) res[[1L]] else res } surveillance/R/twinstim_siaf_exponential.R0000644000176200001440000000603013612577730020572 0ustar liggesusers################################################################################ ### Exponential kernel f(s) = exp(-||s||/sigma) ### ### Copyright (C) 2020 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ siaf.exponential <- function (nTypes = 1, validpars = NULL, engine = "C") { nTypes <- as.integer(nTypes) stopifnot(length(nTypes) == 1L, nTypes > 0L) engine <- match.arg(engine, c("C", "R")) ## for the moment we don't make this type-specific if (nTypes != 1) stop("type-specific shapes are not yet implemented") ## spatial kernel f <- function (s, logsigma, types = NULL) { sigma <- exp(logsigma) sLength <- sqrt(.rowSums(s^2, nrow(s), 2L)) exp(-sLength/sigma) } environment(f) <- baseenv() ## numerically integrate f over a polygonal domain F <- siaf_F_polyCub_iso(intrfr_name = "intrfr.exponential", engine = engine) ## fast integration of f over a circular domain Fcircle <- function (r, logsigma, type = NULL) { sigma <- exp(logsigma) fofr <- exp(-r/sigma) ## f(r) approaches 0, r=Inf is used in R0(,trimmed=F) if (fofr == 0) return(2*pi*sigma^2) ## calculate cylinder volume up to height f(r) basevolume <- pi * r^2 * fofr ## integration via f^-1 Ifinvsq <- function (z) sigma^2 * z * ((log(z)-1)^2 + 1) ##intfinvsq <- Ifinvsq(fof0) - Ifinvsq(fofr) # fof0 = 1 intfinvsq <- 2*sigma^2 - Ifinvsq(fofr) basevolume + pi * intfinvsq } environment(Fcircle) <- baseenv() ## derivative of f wrt logsigma deriv <- function (s, logsigma, types = NULL) { sigma <- exp(logsigma) sLength <- sqrt(.rowSums(s^2, nrow(s), 2L)) z <- sLength/sigma matrix(z * exp(-z)) } environment(deriv) <- baseenv() ## Numerical integration of 'deriv' over a polygonal domain Deriv <- siaf_Deriv_polyCub_iso(intrfr_names = "intrfr.exponential.dlogsigma", engine = engine) ## simulation from the kernel (via polar coordinates) simulate <- siaf.simulatePC(intrfr.exponential) environment(simulate) <- getNamespace("surveillance") ## return the kernel specification list(f = f, F = F, Fcircle = Fcircle, deriv = deriv, Deriv = Deriv, simulate = simulate, npars = 1L, validpars = validpars) } ## integrate x*f(x) from 0 to R (vectorized) intrfr.exponential <- function (R, logsigma, types = NULL) { sigma <- exp(logsigma) sigma * (sigma - (R+sigma)*exp(-R/sigma)) } ## integrate x * (df(x)/dlogsigma) from 0 to R (vectorized) ## Note: df(x)/dlogsigma = x * exp(-(x/sigma)-logsigma) intrfr.exponential.dlogsigma <- function (R, logsigma, types = NULL) { sigma <- exp(logsigma) 2*sigma^2 - ((R+sigma)^2 + sigma^2)*exp(-R/sigma) } surveillance/R/twinstim_tiaf_step.R0000644000176200001440000001252714426171115017217 0ustar liggesusers################################################################################ ### Step function implementation for temporal interaction ### ### Copyright (C) 2014 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ tiaf.step <- function (knots, maxRange = Inf, nTypes = 1, validpars = NULL) { knots <- sort(unique(as.vector(knots,mode="numeric"))) stopifnot(knots > 0, is.finite(knots), isScalar(maxRange), maxRange > knots) nknots <- length(knots) # = number of parameters (per type) knotsmax <- c(knots, maxRange) nknotsmax <- nknots + 1L allknots <- c(0, knots, maxRange) nallknots <- length(allknots) allknotsInf <- unique(c(allknots, Inf)) # ensure Inf as last element stopifnot(isScalar(nTypes <- as.integer(nTypes)), nTypes > 0L) npars <- nknots * nTypes .parintwidths <- rep.int(c(diff.default(knotsmax)), nTypes) .parintwidths[is.infinite(.parintwidths)] <- -1 ##<- in case maxRange=Inf, last interval width will always be multiplied by ## 0 and should give 0, but Inf would produce NaN, so we just set it to -1 ## the step function is right-continuous, intervals are [a,b) g <- if (nTypes > 1) { heights <- function (logvals) { # get matrix of type-specific heights dim(logvals) <- c(nknots, nTypes) rbind(1, exp(logvals), 0, deparse.level=0) } function (t, logvals, types) heights(logvals)[(types-1)*nallknots + .bincode(t, allknotsInf, right=FALSE)] } else { function (t, logvals, types = NULL) c(1,exp(logvals),0)[.bincode(t, allknotsInf, right=FALSE)] } G <- if (nTypes > 1) { typeheights <- function (logvals, type) # vector of type-specific heights c(1, exp(logvals[(type-1)*nknots+seq_len(nknots)])) as.function(c(alist(t=, logvals=, types=), substitute({ mapply(function (t, type) { knots2t <- c(0, pmin.int(knots, t), TMAX) sum(typeheights(logvals, type) * diff.default(knots2t)) }, t, types, SIMPLIFY=TRUE, USE.NAMES=FALSE) }, list(TMAX = if (is.finite(maxRange)) quote(min(t,maxRange)) else quote(t))))) } else { ## function (t, logvals, types = NULL) { ## vapply(t, function (t) { ## knots2t <- c(0, pmin.int(knots, t), min(t, maxRange)) ## sum(c(1,exp(logvals)) * diff.default(knots2t)) ## }, 0, USE.NAMES=FALSE) # vapply is faster than sapply ## } as.function(c(alist(t=, logvals=, types = NULL), substitute({ ##omtk <- outer(t, knots, pmin.int), bare-bone implementation: omtk <- pmin.int(rep.int(knots, rep.int(L <- length(t), nknots)), t) dim(omtk) <- c(L, nknots) .colSums(apply(cbind(0, omtk, TMAX, deparse.level=0), 1L, diff.default) * c(1,exp(logvals)), nknotsmax, L) }, list(TMAX = if (is.finite(maxRange)) quote(pmin.int(t,maxRange)) else quote(t))))) } ## the derivative is simply the height corresponding to (t, type) and is 0 ## outside this interval/type deriv <- function (t, logvals, types) { whichvals <- .bincode(t, knotsmax, right=FALSE) fixedheight <- is.na(whichvals) ##<- intervals number 1 and 'nallknots' don't correspond to parameters whichvals <- whichvals + (types-1)*nknots # select type parameter whichvals[fixedheight] <- 0 ## we do a bare-bone implementation of relevant parts of ## deriv <- outer(whichvals, seq_len(npars), "==") * rep(exp(logvals), each=L) repL <- rep.int(L <- length(t), npars) Y <- rep.int(seq_len(npars), repL) # column index Z <- rep.int(exp(logvals), repL) # value ##<- 6x faster than rep(..., each=L) res <- (Y == whichvals) * Z dim(res) <- c(L, npars) res } ## only tiny modification necessary for nTypes == 1 if (nTypes == 1) { body(deriv)[[grep("types", body(deriv))]] <- NULL formals(deriv)["types"] <- list(NULL) } Deriv <- deriv body(Deriv) <- as.call(append(as.list(body(Deriv)), expression( partwidth <- t - knots[whichvals] ), after=2L)) body(Deriv)[[grep("whichvals[fixedheight]", body(Deriv), fixed=TRUE)]] <- quote(whichvals[fixedheight] <- partwidth[fixedheight] <- 0) body(Deriv) <- as.call(append(as.list(body(Deriv)), expression( W <- rep.int(.parintwidths, repL) ), after=grep("Z <-", body(Deriv)))) body(Deriv)[[grep("res <-", body(Deriv))]] <- if (nTypes == 1) { quote(res <- ((Y < whichvals | t >= maxRange) * W + (Y == whichvals) * partwidth) * Z) } else { quote(res <- ((Y > (types-1)*nknots & (Y < whichvals | t >= maxRange)) * W + (Y == whichvals) * partwidth) * Z) } ## Done res <- list(g = g, G = G, deriv = deriv, Deriv = Deriv, ## FIXME: simulate = simulate, npars = npars, validpars = validpars) attr(res, "knots") <- knots attr(res, "maxRange") <- maxRange res } surveillance/R/epidataCS_methods.R0000644000176200001440000003577014614531277016700 0ustar liggesusers################################################################################ ### Standard S3-methods for "epidataCS" objects, which represent ### CONTINUOUS SPATIO-temporal infectious disease case data ### ### Copyright (C) 2009-2015,2017-2019,2024 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### Number of events (including prehistory) nobs.epidataCS <- function (object, ...) length(object$events) ### UPDATE # all arguments but 'object' are optional, the ... argument is unused update.epidataCS <- function (object, eps.t, eps.s, qmatrix, nCircle2Poly, stgrid, ...) { nEvents <- nobs(object) # Update spatio-temporal grid data if (!missing(stgrid)) { oldT <- tail(object$stgrid$stop, 1L) if (inherits(stgrid, "SpatialPolygons")) stgrid <- tiles2stgrid(stgrid, start = 0, T = oldT) stgrid <- check_stgrid(stgrid, T = oldT, verbose = FALSE, warn = FALSE) ## cannot update tiles because events are linked to these stopifnot(identical(levels(stgrid$tile), levels(object$stgrid$tile))) nTiles <- nlevels(object$stgrid$tile) if ((oldA <- sum(head(object$stgrid$area, nTiles))) != (newA <- sum(head( stgrid$area, nTiles)))) warning("total tile area has changed: ", paste(oldA, "->", newA)) ## merge new spatio-temporal grid data into events@data object$events@data <- cbind( merge_stgrid(marks(object, coords = FALSE), stgrid, # possibly with dropped/added endemic vars verbose = FALSE), object$events@data[dotNames_events] ) object$stgrid <- stgrid } # Check and update eps.t if (!missing(eps.t)) { stopifnot(is.numeric(eps.t), eps.t > 0) object$events$eps.t <- eps.t } # Initialise indicator of which influenceRegions to update ir2update <- logical(nEvents) # all FALSE # Check and update eps.s if (!missing(eps.s)) { stopifnot(is.numeric(eps.s), eps.s > 0) oldeps.s <- object$events$eps.s object$events$eps.s <- eps.s ir2update <- oldeps.s != object$events$eps.s } # Check nCircle2Poly nCircle2Poly <- if (missing(nCircle2Poly)) { attr(object$events$.influenceRegion, "nCircle2Poly") } else { stopifnot(isScalar(nCircle2Poly)) ir2update <- rep.int(TRUE, nEvents) as.integer(nCircle2Poly) } # Update influenceRegions of events if (any(ir2update)) { clipper <- attr(object$events$.influenceRegion, "clipper") if (is.null(clipper)) # epidataCS < 1.8-1 clipper <- "polyclip" object$events$.influenceRegion[ir2update] <- .influenceRegions(object$events[ir2update,], object$W, nCircle2Poly, clipper = clipper) attr(object$events$.influenceRegion, "nCircle2Poly") <- nCircle2Poly } # Check qmatrix if (!missing(qmatrix)) object$qmatrix <- checkQ(qmatrix, levels(object$events$type)) # Update length of infection time, i.e. length = min(T-time, eps.t) if (!missing(eps.t) || !missing(stgrid)) { ..T <- tail(object$stgrid$stop, 1L) object$events$.obsInfLength <- with(object$events@data, pmin(..T - time, eps.t)) } # Update .sources if (!missing(eps.t) || !missing(eps.s) || !missing(qmatrix)) { object$events$.sources <- determineSources.epidataCS(object) } # Done update. return(object) } ### subsetting epidataCS, i.e. select only part of the events, ### but retain stgrid and W. If any event types disappear due to subsetting, ### these types will be dropped from the factor levels and from qmatrix "[.epidataCS" <- function (x, i, j, ..., drop = TRUE) { ## rescue attributes of .influenceRegion (dropped when indexing) iRattr <- attributes(x$events$.influenceRegion) ## apply [,SpatialPointsDataFrame-method (where "drop" is ignored) cl <- sys.call() cl[[1]] <- as.name("[") cl[[2]] <- substitute(x$events) x$events <- eval(cl, envir=parent.frame()) ## assure valid epidataCS after subsetting if (!missing(j)) { # only epidemic covariates may be selected endemicVars <- setdiff(names(x$stgrid), c( reservedColsNames_stgrid, obligColsNames_stgrid)) if (!all(c(reservedColsNames_events, obligColsNames_events, endemicVars) %in% names(x$events))) { stop("only epidemic covariates may be removed from 'events'") } } if (!missing(i)) { ## update .sources x$events$.sources <- determineSources.epidataCS(x) if (drop) { ## update type levels and qmatrix (a type could have disappeared) x$events$type <- x$events$type[drop=TRUE] typeNames <- levels(x$events$type) if (!identical(rownames(x$qmatrix), typeNames)) { message("Note: dropped type(s) ", paste0("\"", setdiff(rownames(x$qmatrix), typeNames), "\"", collapse = ", ")) x$qmatrix <- checkQ(x$qmatrix, typeNames) } } } ## restore attributes of .influenceRegion attributes(x$events$.influenceRegion) <- iRattr ## done return(x) } ## The subset method for epidataCS-objects is adapted from ## base::subset.data.frame (authored by Peter ## Dalgaard and Brian Ripley, Copyright (C) 1995-2012 ## The R Core Team) with slight modifications only ## (we just replace 'x' by 'x$events@data' for evaluation of subset and select) subset.epidataCS <- function (x, subset, select, drop = TRUE, ...) { if (missing(subset)) r <- TRUE else { e <- substitute(subset) r <- eval(e, x$events@data, parent.frame()) # HERE IS A MOD if (!is.logical(r)) stop("'subset' must evaluate to logical") r <- r & !is.na(r) } if (missing(select)) vars <- TRUE else { nl <- as.list(seq_along(x$events@data)) # HERE IS A MOD names(nl) <- names(x$events@data) # HERE IS A MOD vars <- eval(substitute(select), nl, parent.frame()) } x[r, vars, drop = drop] # this calls the [.epidataCS-method from above } ## Subset epidataCS object using head and tail methods (which use [.epidataCS) ## adapted from the corresponding matrix-methods, which have ## Copyright (C) 1995-2012 The R Core Team head.epidataCS <- function (x, n = 6L, ...) { stopifnot(isScalar(n)) n <- if (n < 0L) max(nobs(x) + n, 0L) else min(n, nobs(x)) x[seq_len(n), , drop = FALSE] } tail.epidataCS <- function (x, n = 6L, ...) { stopifnot(isScalar(n)) nrx <- nobs(x) n <- if (n < 0L) max(nrx + n, 0L) else min(n, nrx) x[seq.int(to = nrx, length.out = n), , drop = FALSE] } ### extract marks of the events (actually also including time and tile) idxNonMarks <- function (x) { endemicCovars <- setdiff(names(x$stgrid), c( reservedColsNames_stgrid, obligColsNames_stgrid)) match(c(reservedColsNames_events, endemicCovars), names(x$events@data)) } marks.epidataCS <- function (x, coords = TRUE, ...) { if (coords) { # append coords (cp. as.data.frame.SpatialPointsDataFrame) data.frame(x$events@data[-idxNonMarks(x)], x$events@coords) } else { # return marks without coordinates x$events@data[-idxNonMarks(x)] } } ## extract the events point pattern as.SpatialPointsDataFrame.epidataCS <- function (from) { stopifnot(inherits(from, "epidataCS")) events <- from$events events@data <- marks.epidataCS(from, coords = FALSE) events } setOldClass("epidataCS") setAs(from = "epidataCS", to = "SpatialPointsDataFrame", def = as.SpatialPointsDataFrame.epidataCS) ### permute event times and/or locations holding remaining columns fixed permute.epidataCS <- function (x, what = c("time", "space"), keep) { stopifnot(inherits(x, "epidataCS")) what <- match.arg(what) ## permutation index perm <- if (missing(keep)) { sample.int(nobs.epidataCS(x)) } else { # some events should not be relabeled keep <- eval(substitute(keep), envir = x$events@data, enclos = parent.frame()) stopifnot(is.logical(keep), !is.na(keep)) which2permute <- which(!keep) howmany2permute <- length(which2permute) if (howmany2permute < 2L) { message("Note: data unchanged ('keep' all)") return(x) } perm <- seq_len(nobs.epidataCS(x)) perm[which2permute] <- which2permute[sample.int(howmany2permute)] perm } ## rescue attributes of .influenceRegion (dropped when indexing) iRattr <- attributes(x$events@data$.influenceRegion) ## permute time points and/or locations PERMVARS <- if (what == "time") { c("time", "BLOCK", "start", ".obsInfLength") } else { x$events@coords <- x$events@coords[perm,,drop=FALSE] c("tile", ".bdist", ".influenceRegion") } x$events@data[PERMVARS] <- x$events@data[perm, PERMVARS] ## re-sort on time if necessary if (what == "time") { x$events <- x$events[order(x$events@data$time), ] } ## .sources and endemic variables need an update x$events@data$.sources <- determineSources.epidataCS(x) ENDVARS <- setdiff(names(x$stgrid), c(reservedColsNames_stgrid, obligColsNames_stgrid)) gridcellsOfEvents <- match( do.call("paste", c(x$events@data[c("BLOCK", "tile")], sep = "\r")), do.call("paste", c(x$stgrid[c("BLOCK", "tile")], sep = "\r")) ) x$events@data[ENDVARS] <- x$stgrid[gridcellsOfEvents, ENDVARS] ## restore attributes of .influenceRegion attributes(x$events@data$.influenceRegion) <- iRattr ## done x } ### printing methods print.epidataCS <- function (x, n = 6L, digits = getOption("digits"), ...) { print_epidataCS_header( timeRange = c(x$stgrid$start[1L], x$stgrid$stop[nrow(x$stgrid)]), bbox = bbox(x$W), nBlocks = length(unique(x$stgrid$BLOCK)), nTiles = nlevels(x$stgrid$tile), digits = digits ) cat("Types of events: ") str(levels(x$events$type), give.attr = FALSE, give.head = FALSE, width = getOption("width") - 17L) cat("Overall number of events:", nEvents <- nobs(x)) if (npre <- sum(x$events$time <= x$stgrid$start[1L])) cat(" (prehistory: ", npre, ")", sep = "") cat("\n\n") visibleCols <- grep("^\\..+", names(x$events@data), invert = TRUE) if (nEvents == 0L) { # not handled by [,SpatialPointsDataFrame-method # and thus actually not supported by "epidataCS" ## display header only print(data.frame(coordinates = character(0L), x$events@data[visibleCols])) } else { ## 2014-03-24: since sp 1.0-15, print.SpatialPointsDataFrame() ## appropriately passes its "digits" argument to print.data.frame() print(head.matrix(x$events[visibleCols], n = n), digits = digits, ...) if (n < nEvents) cat("[....]\n") } invisible(x) } print_epidataCS_header <- function (timeRange, bbox, nBlocks, nTiles, digits = getOption("digits")) { bboxtxt <- paste( apply(bbox, 1, function (int) paste0( "[", paste(format(int, trim=TRUE, digits=digits), collapse=", "), "]" )), collapse = " x ") cat("Observation period:", paste(format(timeRange, trim=TRUE, digits=digits), collapse = " - "), "\n") cat("Observation window (bounding box):", bboxtxt, "\n") cat("Spatio-temporal grid (not shown):", nBlocks, ngettext(nBlocks, "time block,", "time blocks"), "x", nTiles, ngettext(nTiles, "tile", "tiles"), "\n") } ### SUMMARY # the epidemic is summarized by the following returned components: # timeRange, nEvents, eventTimes, eventCoords, nSources, as well as # - tile/typetable: number of events per tile/type # - counter: number of infective individuals as stepfun summary.epidataCS <- function (object, ...) { res <- list( timeRange = with(object$stgrid, c(start[1], stop[length(stop)])), bbox = bbox(object$W), nBlocks = length(unique(object$stgrid$BLOCK)), nEvents = nobs(object), nTypes = nlevels(object$events$type), eventTimes = object$events$time, eventCoords = coordinates(object$events), eventTypes = object$events$type, eventRanges = object$events@data[c("eps.t", "eps.s")], eventMarks = marks.epidataCS(object), tileTable = c(table(object$events$tile)), typeTable = c(table(object$events$type)), counter = as.stepfun.epidataCS(object), nSources = lengths(object$events$.sources, use.names = FALSE) ) class(res) <- "summary.epidataCS" res } print.summary.epidataCS <- function (x, ...) { print_epidataCS_header(timeRange = x$timeRange, bbox = x$bbox, nBlocks = x$nBlocks, nTiles = length(x$tileTable)) cat("Overall number of events: ", x$nEvents, " (", if (x$nTypes==1) "single type" else paste(x$nTypes, "types"), if (npre <- sum(x$eventTimes <= x$timeRange[1L])) paste(", prehistory:", npre), ")\n", sep = "") cat("\nSummary of event marks and number of potential sources:\n") print(summary(cbind(x$eventMarks, "|.sources|"=x$nSources)), ...) invisible(x) } as.stepfun.epidataCS <- function (x, ...) { eventTimes <- x$events$time removalTimes <- eventTimes + x$events$eps.t tps <- sort(unique(c(eventTimes, removalTimes[is.finite(removalTimes)]))) nInfectious <- sapply(tps, function(t) sum(eventTimes <= t & removalTimes > t)) stepfun(tps, c(0,nInfectious), right = TRUE) # no ties, 'tps' is unique } ################################################### ### Distances from potential (eps.s, eps.t) sources ################################################### getSourceDists <- function (object, dimension = c("space", "time")) { dimension <- match.arg(dimension) ## extract required info from "epidataCS"-object distmat <- as.matrix(dist( if (dimension == "space") { coordinates(object$events) } else object$events$time )) .sources <- object$events$.sources ## number of sources nsources <- lengths(.sources, use.names = FALSE) hasSources <- nsources > 0 cnsources <- c(0, cumsum(nsources)) ## generate vector of distances of events to their potential sources sourcedists <- numeric(sum(nsources)) for (i in which(hasSources)) { .sourcesi <- .sources[[i]] .sourcedists <- distmat[i, .sourcesi] .idx <- cnsources[i] + seq_len(nsources[i]) sourcedists[.idx] <- .sourcedists names(sourcedists)[.idx] <- paste(i, .sourcesi, sep="<-") } ## Done sourcedists } surveillance/R/hhh4_simulate.R0000644000176200001440000002670014426171115016037 0ustar liggesusers################################################################################ ### Simulate from a HHH4 model ### ### Copyright (C) 2012 Michaela Paul, 2013-2016,2018,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### Simulate-method for hhh4-objects simulate.hhh4 <- function (object, # result from a call to hhh4 nsim=1, # number of replicates to simulate seed=NULL, y.start=NULL, # initial counts for epidemic components subset=1:nrow(object$stsObj), coefs=coef(object), # coefficients used for simulation components=c("ar","ne","end"), # which comp to include simplify=nsim>1, # counts array only (no full sts) ...) { ## Determine seed (this part is copied from stats:::simulate.lm with ## Copyright (C) 1995-2012 The R Core Team) if(!exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE)) runif(1) # initialize the RNG if necessary if(is.null(seed)) RNGstate <- get(".Random.seed", envir = .GlobalEnv) else { R.seed <- get(".Random.seed", envir = .GlobalEnv) set.seed(seed) RNGstate <- structure(seed, kind = as.list(RNGkind())) on.exit(assign(".Random.seed", R.seed, envir = .GlobalEnv)) } ## END seed cl <- match.call() theta <- if (missing(coefs)) coefs else checkCoefs(object, coefs) stopifnot(subset >= 1, subset <= nrow(object$stsObj)) ## lags lag.ar <- object$control$ar$lag lag.ne <- object$control$ne$lag maxlag <- max(lag.ar, lag.ne) ## initial counts nUnits <- object$nUnit if (is.null(y.start)) { # set starting value to mean observed (in subset!) y.means <- ceiling(colMeans(observed(object$stsObj)[subset,,drop=FALSE])) y.start <- matrix(y.means, maxlag, nUnits, byrow=TRUE) } else { if (is.vector(y.start)) y.start <- t(y.start) if (ncol(y.start) != nUnits) stop(sQuote("y.start"), " must have nUnits=", nUnits, " columns") if (nrow(y.start) < maxlag) stop("need 'y.start' values for lag=", maxlag, " initial time points") } ## store model terms in the hhh4 object because we request them repeatedly ## (within get_exppreds_with_offsets() and directly afterwards) ## CAVE: for an ri()-model, building the terms affects the .Random.seed, ## so doing that twice would yield different simulations than pre-1.16.2 if (is.null(object$terms)) object$terms <- terms(object) ## get fitted exppreds nu_it, phi_it, lambda_it (incl. offsets, t in subset) exppreds <- get_exppreds_with_offsets(object, subset = subset, theta = theta) ## extract overdispersion parameters (simHHH4 assumes psi->0 means Poisson) model <- terms(object) psi <- splitParams(theta,model)$overdisp if (length(psi) > 1) # "NegBinM" or shared overdispersion parameters psi <- psi[model$indexPsi] ## weight matrix/array of the ne component neweights <- getNEweights(object, coefW(theta)) ## set predictor to zero if not included ('components' argument) stopifnot(length(components) > 0, components %in% c("ar", "ne", "end")) getComp <- function (comp) { exppred <- exppreds[[comp]] if (comp %in% components) exppred else "[<-"(exppred, value = 0) } ar <- getComp("ar") ne <- getComp("ne") end <- getComp("end") ## simulate simcall <- quote( simHHH4(ar, ne, end, psi, neweights, y.start, lag.ar, lag.ne) ) if (!simplify) { ## result template res0 <- object$stsObj[subset,] setObserved <- function (observed) { res0@observed[] <- observed res0 } simcall <- call("setObserved", simcall) } res <- if (nsim==1 && !simplify) eval(simcall) else replicate(nsim, eval(simcall), simplify=if (simplify) "array" else FALSE) if (simplify) { dimnames(res)[1:2] <- list(subset, colnames(model$response)) attr(res, "initial") <- y.start attr(res, "stsObserved") <- object$stsObj[subset,] class(res) <- "hhh4sims" } ## Done attr(res, "call") <- cl attr(res, "seed") <- RNGstate res } ### Internal auxiliary function, which performs the actual simulation simHHH4 <- function(ar, # lambda_it (nTime x nUnits matrix) ne, # phi_it (nTime x nUnits matrix) end, # nu_it (nTime x nUnits matrix, offset included) psi, # overdisp param(s) or numeric(0) (psi->0 = Poisson) neW, # weight matrix/array for neighbourhood component start, # starting counts (vector of length nUnits, or # matrix with nUnits columns if lag > 1) lag.ar = 1, lag.ne = lag.ar ) { nTime <- nrow(end) nUnits <- ncol(end) ## check and invert psi since rnbinom() uses different parametrization size <- if (length(psi) == 0 || isTRUE(all.equal(psi, 0, check.attributes=FALSE))) { NULL # Poisson } else { if (!length(psi) %in% c(1, nUnits)) stop("'length(psi)' must be ", paste(unique(c(1, nUnits)), collapse = " or "), " (number of units)") 1/psi } ## simulate from Poisson or NegBin model rdistr <- if (is.null(size)) { rpois } else { ## unit-specific 'mean's and variance = mean + psi*mean^2 ## where 'size'=1/psi and length(psi) == 1 or length(mean) function(n, mean) rnbinom(n, mu = mean, size = size) } ## if only endemic component -> simulate independently if (all(ar + ne == 0)) { if (!is.null(size)) size <- matrix(size, nTime, nUnits, byrow = TRUE) return(matrix(rdistr(length(end), end), nTime, nUnits)) } ## weighted sum of counts of other (neighbouring) regions ## params: y - vector with (lagged) counts of regions ## W - nUnits x nUnits adjacency/weight matrix (0=no neighbour) wSumNE <- if (is.null(neW) || all(neW == 0)) { # includes the case nUnits==1 function (y, W) numeric(nUnits) } else function (y, W) .colSums(W * y, nUnits, nUnits) ## initialize matrices for means mu_i,t and simulated data y_i,t mu <- y <- matrix(0, nTime, nUnits) y <- rbind(start, y) nStart <- nrow(y) - nrow(mu) # usually just 1 for lag=1 ## simulate timeDependentWeights <- length(dim(neW)) == 3 if (!timeDependentWeights) neWt <- neW for(t in seq_len(nTime)){ if (timeDependentWeights) neWt <- neW[,,t] ## mean mu_i,t = lambda*y_i,t-1 + phi*sum_j wji*y_j,t-1 + nu_i,t mu[t,] <- ar[t,] * y[nStart+t-lag.ar,] + ne[t,] * wSumNE(y[nStart+t-lag.ne,], neWt) + end[t,] ## Sample from Poisson/NegBin with that mean y[nStart+t,] <- rdistr(nUnits, mu[t,]) } ## return simulated data without initial counts y[-seq_len(nStart),,drop=FALSE] } ### check compatibility of a user-specified coefficient vector with model checkCoefs <- function (object, coefs, reparamPsi=TRUE) { theta <- coef(object, reparamPsi=reparamPsi) if (length(coefs) != length(theta)) stop(sQuote("coefs"), " must be of length ", length(theta)) names(coefs) <- names(theta) coefs } ### subset simulations and keep attributes in sync "[.hhh4sims" <- function (x, i, j, ..., drop = FALSE) { xx <- NextMethod("[", drop = drop) if (nargs() == 2L) # x[i] call -> hhh4sims class is lost return(xx) ## otherwise we were subsetting the array and attributes are lost attributes(xx) <- c(attributes(xx), attributes(x)[c("initial", "stsObserved", "class")]) subset_hhh4sims_attributes(xx, i, j) } subset_hhh4sims_attributes <- function (x, i, j) { if (!missing(i)) attr(x, "stsObserved") <- attr(x, "stsObserved")[i,] if (!missing(j)) { attr(x, "stsObserved") <- suppressMessages(attr(x, "stsObserved")[, j]) is.na(attr(x, "stsObserved")@neighbourhood) <- TRUE attr(x, "initial") <- attr(x, "initial")[, j, drop = FALSE] } x } ### aggregate predictions over time and/or (groups of) units aggregate.hhh4sims <- function (x, units = TRUE, time = FALSE, ..., drop = FALSE) { ax <- attributes(x) if (time) { ## sum counts over the whole simulation period res <- colSums(x) ## -> a nUnits x nsim matrix -> will no longer be "hhh4sims" if (isTRUE(units)) { # sum over all units res <- colSums(res) # now a vector of length nsim } else if (!identical(FALSE, units)) { # sum over groups of units stopifnot(length(units) == dim(x)[2]) res <- t(rowSumsBy.matrix(t(res), units)) } } else { if (isTRUE(units)) { # sum over all units res <- apply(X = x, MARGIN = c(1L, 3L), FUN = sum) if (!drop) { ## restore unit dimension conforming to "hhh4sims" class dim(res) <- replace(ax$dim, 2L, 1L) dimnames(res) <- replace(ax$dimnames, 2L, list(NULL)) ## restore attributes attr(res, "initial") <- as.matrix(rowSums(ax$initial)) attr(res, "stsObserved") <- aggregate(ax$stsObserved, by = "unit") class(res) <- "hhh4sims" } } else if (!identical(FALSE, units)) { # sum over groups of units stopifnot(length(units) == dim(x)[2]) groupnames <- names(split.default(seq_along(units), units)) res <- apply(X = x, MARGIN = 3L, FUN = rowSumsBy.matrix, by = units) dim(res) <- replace(ax$dim, 2L, length(groupnames)) dimnames(res) <- replace(ax$dimnames, 2L, list(groupnames)) if (!drop) { ## restore attributes attr(res, "initial") <- rowSumsBy.matrix(ax$initial, units) attr(res, "stsObserved") <- rowSumsBy.sts(ax$stsObserved, units) class(res) <- "hhh4sims" } } else { return(x) } } ## done res } rowSumsBy.matrix <- function (x, by, na.rm = FALSE) { dn <- dim(x) res <- vapply(X = split.default(x = seq_len(dn[2L]), f = by), FUN = function (idxg) .rowSums(x[, idxg, drop = FALSE], dn[1L], length(idxg), na.rm = na.rm), FUN.VALUE = numeric(dn[1L]), USE.NAMES = TRUE) if (dn[1L] == 1L) t(res) else res } rowSumsBy.sts <- function (x, by, na.rm = FALSE) { ## map, neighbourhood, upperbound, control get lost by aggregation of units .sts(epoch = x@epoch, freq = x@freq, start = x@start, observed = rowSumsBy.matrix(x@observed, by, na.rm), state = rowSumsBy.matrix(x@state, by, na.rm) > 0, alarm = rowSumsBy.matrix(x@alarm, by, na.rm) > 0, populationFrac = rowSumsBy.matrix(x@populationFrac, by, na.rm), epochAsDate = x@epochAsDate, multinomialTS = x@multinomialTS) } surveillance/R/twinstim_siaf_step.R0000644000176200001440000001167014615162374017223 0ustar liggesusers################################################################################ ### twinstim's spatial interaction function as a step function ### ### Copyright (C) 2014,2018,2022 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ siaf.step <- function (knots, maxRange = Inf, nTypes = 1, validpars = NULL) { knots <- sort(unique(as.vector(knots,mode="numeric"))) stopifnot(knots > 0, is.finite(knots), isScalar(maxRange), maxRange > knots) nknots <- length(knots) # = number of parameters (per type) allknots <- c(0, knots, unique(c(maxRange,Inf))) allknotsPos <- c(0,knots,maxRange) # pos. domain, =allknots if maxRange=Inf nTypes <- as.integer(nTypes) stopifnot(length(nTypes) == 1L, nTypes > 0L) ## for the moment we don't make this type-specific if (nTypes != 1) stop("type-specific shapes are not yet implemented") npars <- nknots * nTypes ## ## auxiliary function to get the type-specific values (heights) from logvals ## logvals4type <- function (logvals, type) ## logvals[(type-1)*nknots + seq_len(nknots)] ## auxiliary function calculating the areas of the "rings" of the ## two-dimensional step function intersected with a polydomain. ## Returns a numeric vector of length ## length(allknotsPos)-1 == nknots+1 (i.e. not appending the area of the ## 0-height ring from maxRange to Inf in case maxRange < Inf) .ringAreas <- function (polydomain, npoly = 256) { polyvertices <- vertices(polydomain) polyarea <- area.owin(polydomain) bdist <- bdist(cbind(0,0), polydomain) ## distance to farthest vertex (-> later steps not relevant) R <- sqrt(max(polyvertices[["x"]]^2 + polyvertices[["y"]]^2)) sliceAreas <- vapply(X = allknotsPos[-1L], FUN = function (r) { if (r <= bdist) pi * r^2 else if (r >= R) polyarea else area.owin(intersectPolyCircle.owin(polydomain,c(0,0),r,npoly=npoly)) }, FUN.VALUE = 0, USE.NAMES = FALSE) diff.default(c(0,sliceAreas)) } ## since this is the most cumbersome task, use memoization (result does not ## depend on the parameters being optimized, but on influenceRegions only) ringAreas <- if (requireNamespace("memoise")) { memoise::memoise(.ringAreas) } else { warning("siaf.step() is much slower without memoisation", immediate.=TRUE) .ringAreas } f <- function (s, logvals, types = NULL) { sLength <- sqrt(.rowSums(s^2, length(s)/2, 2L)) ## step function is right-continuous, intervals are [a,b) c(1, exp(logvals), 0)[.bincode(sLength, allknots, right=FALSE)] } F <- function (polydomain, f, logvals, type = NULL, npoly = 256) { ## sum of the volumes of the intersections of "rings" with 'polydomain' sum(c(1, exp(logvals)) * ringAreas(polydomain, npoly=npoly)) } Fcircle <- function (r, logvals, type = NULL) { # exact integration on disc ## this is just the sum of the "ring" volumes sum(c(1, exp(logvals)) * pi * diff(pmin.int(allknotsPos, r)^2)) } deriv <- function (s, logvals, types = NULL) { sLength <- sqrt(.rowSums(s^2, L <- length(s)/2, 2L)) whichvals <- .bincode(sLength, allknots, right=FALSE) - 1L ## NOTE: sLength >= maxRange => whichvals > nknots (=> f=0) ## we do a bare-bone implementation of relevant parts of ## deriv <- outer(whichvals, seq_len(nknots), "==") Y <- rep.int(seq_len(nknots), rep.int(L,nknots)) # column index Z <- rep.int(exp(logvals), rep.int(L,nknots)) # value ##<- 6x faster than rep(..., each=L) #X <- rep.int(whichvals, nknots) deriv <- (Y == whichvals) * Z dim(deriv) <- c(L, nknots) deriv } Deriv <- function (polydomain, deriv, logvals, type = NULL, npoly = 256) { ringAreas <- ringAreas(polydomain, npoly=npoly) exp(logvals) * ringAreas[-1L] } simulate <- function (n, logvals, type = NULL, ub) { upper <- min(maxRange, ub) knots2upper <- c(knots[knots < upper], upper) heights <- c(1,exp(logvals))[seq_along(knots2upper)] ## first, sample the "rings" of the points rings <- sample.int(length(heights), size=n, replace=TRUE, prob=heights*diff.default(c(0,knots2upper^2))) ## sample points from these rings runifdisc(n, knots2upper[rings], c(0,knots2upper)[rings]) } ## Done structure(list(f = f, F = F, Fcircle = Fcircle, deriv = deriv, Deriv = Deriv, simulate = simulate, npars = npars, validpars = validpars), "knots" = knots, "maxRange" = maxRange) } surveillance/R/twinstim_step.R0000644000176200001440000001412114426171115016204 0ustar liggesusers################################################################################ ### Functions and methods to make step() work for twinstim objects ### (restricted to one component at a time) ### ### Copyright (C) 2013 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### To make step() work, we are dealing with modified twinstim objects: ### object$formula is replaced by the result of terms(object), which selects only ### one of the two components! The original full formula specification is ### retained in the new "formulae" component. ### We let this special class inherit from "twinstim" such that, e.g., ### extractAIC.twinstim is used for its objects. However, this is tricky since ### the classes are actually incompatible in the formula specification. Only ### methods which don't use the $formula part work, but this constraint holds ### for what is needed to run step(), if we define some additional specific ### methods for this class. twinstim_stependemic <- twinstim_stepepidemic <- function (object) { stepClass <- grep("twinstim_step", sys.call()[[1L]], value=TRUE) ##<- since sys.call()[[1L]] may also be surveillance:::... if (identical(class(object), "twinstim")) { component <- sub("twinstim_step", "", stepClass) object$formulae <- object$formula object$formula <- object$formulae[[component]] class(object) <- c(stepClass, "twinstim") } else if (!inherits(object, stepClass)) stop("unintended use") object } ## In the first step() loop, object$call$formula is set to terms(object). Since ## there is no "formula" argument to twinstim(), we must remove it from the call ## before update()ing. We also have to convert object$formula to the complete ## formula specification (a named list) and remove the original one ($formulae). .step2twinstim <- function (object) { ##if (identical(class(object), "twinstim")) return(object) component <- sub("^twinstim_step", "", class(object)[1]) stopifnot(component %in% c("endemic", "epidemic")) object$call$formula <- NULL object$formula <- modifyList( object$formulae, setNames(list(formula(object$formula)), component) ) object$formulae <- NULL class(object) <- "twinstim" object } ### special update- and terms-methods for use through stepComponent() below update.twinstim_stependemic <- function (object, endemic, ..., evaluate = TRUE) { object <- .step2twinstim(object) res <- NextMethod("update") # use update.twinstim() ## we need to keep the special class such that step() will keep invoking ## the special update- and terms-methods on the result stepClass <- sub("update.", "", .Method, fixed=TRUE) ##<- or: .Class[1L], or: grep("step", class(object), value=TRUE) if (evaluate) { do.call(stepClass, alist(res)) } else { as.call(list(call(":::", as.name("surveillance"), as.name(stepClass)), res)) ## the call will only be evaluated within stats:::drop1.default() or ## stats:::add1.default, where the "stepClass" constructor function ## (twinstim_stependemic or twinstim_stepepidemic) is not visible; ## we thus have to use ":::". } } update.twinstim_stepepidemic <- function (object, epidemic, ..., evaluate = TRUE) {} body(update.twinstim_stepepidemic) <- body(update.twinstim_stependemic) terms.twinstim_stependemic <- terms.twinstim_stepepidemic <- function (x, ...) terms(x$formula) ### Function to perform AIC-based model selection (component-specific) ### This is essentially a wrapper around stats::step() stepComponent <- function (object, component = c("endemic", "epidemic"), scope = list(upper=object$formula[[component]]), direction = "both", trace = 2, verbose = FALSE, ...) { component <- match.arg(component) ## Convert to special twinstim class where $formula is the component formula object_step <- do.call(paste0("twinstim_step", component), alist(object)) ## silent optimizations if (trace <= 2) object_step$call$optim.args$control$trace <- object_step$optim.args$control$trace <- 0 object_step$call$verbose <- verbose ## Run the selection procedure res <- step(object_step, scope = scope, direction = direction, trace = trace, ...) ## Restore original trace and verbose arguments if (trace <= 2) { res$call$optim.args$control <- object$call$optim.args$control res$optim.args$control <- object$optim.args$control } res$call$verbose <- object$call$verbose ## Convert back to original class .step2twinstim(res) } ### add1.default and drop1.default work without problems through the above ### implementation of stepComponent() using the tricky twinstim classes, ### where object$formula is replaced by the requested component's formula. ### However, for stand-alone use of add1 and drop1, we need specialised methods. add1.twinstim <- drop1.twinstim <- function (object, scope, component = c("endemic", "epidemic"), trace = 2, ...) { component <- match.arg(component) ## Convert to special twinstim class where $formula is the component formula object <- do.call(paste0("twinstim_step", component), alist(object)) ## Call the default method (unfortunately not exported from stats) ## Note that the next method chosen is "unchanged if the class of the ## dispatching argument is changed" (see ?NextMethod) ## (the "component" argument will be part of "..." and passed further on to ## extractAIC.twinstim() where it is unused) NextMethod(trace=trace) } add1.twinstim_stependemic <- drop1.twinstim_stependemic <- function (object, scope, ...) NextMethod(component="endemic") add1.twinstim_stepepidemic <- drop1.twinstim_stepepidemic <- function (object, scope, ...) NextMethod(component="epidemic") surveillance/R/sts.R0000644000176200001440000004417214403721212014107 0ustar liggesusers################################################################################ ### Initialization and other basic methods for the S4 class "sts" ### ### Copyright (C) 2007-2014 Michael Hoehle, 2012-2019,2021,2023 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ ###################################################################### # initialize-method -- see ../man/sts-class.Rd for class information ###################################################################### #Ensure that all matrix slots have the same dimnames, which are #always taken from the observed matrix fix.dimnames <- function(x) { dn <- dimnames(x@observed) #Make sure all arrays have the same dimnames dimnames(x@alarm) <- dimnames(x@state) <- dimnames(x@upperbound) <- dimnames(x@populationFrac) <- dn #Special for neighbourhood dimnames(x@neighbourhood) <- dn[c(2L,2L)] return(x) } ## a user-level constructor function, ## which calls the standard generator function .sts(), ## which calls initialize() on the "sts" prototype - see init.sts() below ## NOTE: using sts() is the preferred approach since surveillance 1.10-0 ## NOTE: NULL arguments are ignored => default slot values sts <- function (observed, start = c(2000, 1), frequency = 52, # prototype values epoch = NULL, # defaults to 1:nrow(observed), can be Date population = NULL, # an alias for "populationFrac" ...) # further named arguments representing "sts" slots { slots <- list(observed = observed, start = start, freq = frequency, epoch = epoch, ...) if (!is.null(population)) { if ("populationFrac" %in% names(slots)) warning("'population' takes precedence over 'populationFrac'") slots$populationFrac <- population } # else "populationFrac" is a possible element of ... if (inherits(epoch, "Date")) { ## FIXME: guess missing start value similar to linelist2sts ## if (missing(start) && frequency == 52) ## slots$start <- unlist(isoWeekYear(epoch[1L]), use.names = FALSE) slots$epoch <- as.integer(epoch) slots$epochAsDate <- TRUE } ## call the standard generator function with explicitly set slots isNULL <- vapply(X = slots, FUN = is.null, FUN.VALUE = FALSE, USE.NAMES = FALSE) do.call(.sts, slots[!isNULL]) } ## initialize-method called by new("sts", ...), ## the long-standing default way of creating "sts" objects. ## For backward-compatibility, we keep this customized initialize-method, ## although it would be cleaner to put things into the generator function ## and use the default initialize-method. init.sts <- function(.Object, ..., # also for slots of classes extending "sts" observed, # use copy constructor if missing(observed) ## the following default arguments depend on dim(observed) epoch = seq_len(nTime), state = matrix(FALSE, nTime, nUnit), alarm = matrix(NA, nTime, nUnit), upperbound = matrix(NA_real_, nTime, nUnit), neighbourhood = matrix(NA, nUnit, nUnit), populationFrac = matrix(1/nUnit, nTime, nUnit), ## FIXME: change default to a matrix of NA_real_ ? ## the map slot needs special treatment (see below) map = .Object@map # old/prototype value ## the remaining slots have useful prototype values ## and are handled as part of ... ##start = c(2000, 1), freq = 52, ##epochAsDate = FALSE, multinomialTS = FALSE, ##control = .Object@control ) { if (nargs() < 2) # nothing to do return(.Object) if (missing(observed)) { # use default initialize-method ## such that, e.g., initialize(stsObj, map=newMap) will set a new map ## and copy other slots from stsObj instead of (re-)setting to defaults, ## as well as to support new("stsBP", stsObj, ci=ci, lambda=lambda). ## CAVE: automatic dimension correction of matrix slots is not done. .Object <- callNextMethod() ## Drawback: .Object@map has been forced to "SpatialPolygons" if (!missing(map)) # restore the supplied map .Object@map <- map ## If missing(map), .Object@map = as(stsObj@map, "SpatialPolygons"), ## i.e., data will be lost => map=stsObj@map must be passed explicitly .Object <- fix.dimnames(.Object) return(.Object) } ## Ensure matrix form (auto-conversion is useful for single time series) observed <- as.matrix(observed) nUnit <- ncol(observed) nTime <- nrow(observed) state <- as.matrix(state) alarm <- as.matrix(alarm) upperbound <- as.matrix(upperbound) ## clear rownames and set colnames for the matrix of observed counts if (is.null(namesObs <- colnames(observed))){ namesObs <- paste0("observed", seq_len(nUnit)) } dimnames(observed) <- list(NULL, namesObs) ## if there is only one state-vector for more than one area, repeat it if (nUnit > 1 && ncol(state) == 1 && length(state) == nTime) { state <- rep.int(state, nUnit) dim(state) <- c(nTime, nUnit) } ## time-constant population fractions can be provided as a single vector if (is.vector(populationFrac, mode="numeric") && length(populationFrac) == nUnit) { populationFrac <- matrix(populationFrac, nTime, nUnit, byrow=TRUE) } ## we need to set the map manually since the initialize,ANY-method called ## next would coerce a "SpatialPolygonsDataFrame" to "SpatialPolygons" if (!missing(map)) .Object@map <- map ## set all other slots (including for classes extending this class) ## using the default initialize-method .Object <- callNextMethod(.Object, ..., observed=observed, epoch=epoch, state=state, alarm=alarm, upperbound=upperbound, neighbourhood=neighbourhood, populationFrac=populationFrac) ## this also checks validObject(.Object) ## for nUnit > 1, it will catch if any column names differ from namesObs ## use dimnames(observed) for all matrix slots (could be unnamed) .Object <- fix.dimnames(.Object) return(.Object) } setMethod("initialize", "sts", init.sts) ########################################################################### # Conversion between old "disProg" and new "sts" classes ########################################################################### ## transform a "disProg" object to the new "sts" class disProg2sts <- function(disProgObj, map=NULL) { disProgObj$map <- map ## NOTE: we cannot trust disProgObj$week to be a valid "epoch" specification, ## e.g., the week in data("ha") refers to the week number _within_ a year. ## CAVE: in "disProg" objects, several elements may be missing or NULL, ## and there could be further elements not matching any "sts" slot, ## e.g., in "disProg" objects generated by sim.pointSource() validElements <- names(disProgObj) %in% slotNames("sts") & !vapply(X=disProgObj, FUN=is.null, FUN.VALUE=FALSE, USE.NAMES=FALSE) ## initialize an "sts" object using the valid "disProg" elements stsObj <- do.call(.sts, disProgObj[validElements]) return(stsObj) } ## The reverse action sts2disProg <- function(sts) { disProgObj <- list( # no need for create.disProg() checks, sts is formal week=sts@epoch, observed=sts@observed, state=sts@state, start=sts@start, freq=sts@freq, neighbourhood=sts@neighbourhood, populationFrac=sts@populationFrac, epochAsDate=sts@epochAsDate ) class(disProgObj) <- "disProg" #For survRes: alarm=sts@alarm, upperbound=sts@upperbound) return(disProgObj) } ########################################################################### #Method to aggregate over all units, either the time series is aggregated #so a new sampling frequency of nfreq units per time slot is obtained. #The other alternative is to aggregate all units. # # Note: The function is not 100% consistent with what the generic # aggregate does. # # Warning: In case the aggregation is by unit the upperbound slot is set # to NA. Furthermore the MAP object is left as.is, but # the object cannot be plotted anymore. # # Params: # by - a string being either "time" or "unit" # nfreq - new sampling frequency if by=="time". If "all" then all # time instances are summed. ########################################################################### aggregate.sts <- function(x, by="time", nfreq="all", ...) { by <- match.arg(by, choices = c("time", "unit")) #Aggregate time if (by == "time") { if (nfreq == "all") { howmany <- dim(x@observed)[1] } else if (nfreq == x@freq) { # nothing to do return(x) } else { # nfreq != x@freq howmany <- x@freq / nfreq if (howmany - ceiling(howmany) != 0) stop("nfreq has to be a multiple of x@freq.") } n <- dim(x@observed)[1] m <- ceiling(n/howmany) new <- rep(1:m,each=howmany)[1:n] x@freq <- ifelse(nfreq == "all", howmany, nfreq) x@epoch <- 1:m x@observed <- as.matrix(aggregate(x@observed,by=list(new),sum)[,-1]) x@state <- as.matrix(aggregate(x@state,by=list(new),sum)[,-1])>0 x@alarm <- as.matrix(aggregate(x@alarm,by=list(new),sum)[,-1]) # number of alarms x@upperbound <- as.matrix(aggregate(x@upperbound,by=list(new),sum)[,-1]) ## summing population (fractions) over time had_fractions <- !x@multinomialTS && all(rowSums(x@populationFrac) == 1) x@populationFrac <- as.matrix(aggregate(x@populationFrac,by=list(new),sum)[,-1]) if (isTRUE(had_fractions)) { # population fractions need to be recomputed x@populationFrac <- x@populationFrac / rowSums(x@populationFrac) } } #Aggregate units if (by == "unit") { #Aggregate units x@observed <- as.matrix(rowSums(x@observed)) x@state <- as.matrix(rowSums(x@state))>0 x@alarm <- as.matrix(rowSums(x@alarm))>0 # contrary to counting for by="time"! #There is no clever way to aggregate the upperbounds x@upperbound <- matrix(NA_real_,ncol=ncol(x@alarm),nrow=nrow(x@alarm)) x@populationFrac <- as.matrix(rowSums(x@populationFrac)) x@neighbourhood <- matrix(NA, 1, 1) # consistent with default for new("sts") ## we have lost colnames colnames(x@observed) <- "overall" x <- fix.dimnames(x) ## drop the map (set to empty prototype) x@map <- new(getSlots("sts")[["map"]]) } #validObject(x) #just a check return(x) } setMethod("aggregate", signature(x="sts"), aggregate.sts) ##################################################################### # Miscellaneous access methods #################################################################### setMethod("dim", "sts", function (x) dim(x@observed)) setMethod("dimnames", "sts", function (x) dimnames(x@observed)) #Extract which observation within year we have setMethod("epochInYear", "sts", function(x,...) { if (x@epochAsDate && x@freq %in% c(12, 52, 365)) { epochStr <- switch(as.character(x@freq), "12" = "%m", "52" = "%V", "365" = "%j") as.numeric(strftime(epoch(x), epochStr)) } else { index <- if (x@epochAsDate) { # non-standard frequency seq_along(x@epoch) } else x@epoch # should always be 1:nrow(x) actually (index-1 + x@start[2]-1) %% x@freq + 1 } }) #Extract the corresponding year for each observation setMethod("year", "sts", function(x,...) { if (x@epochAsDate) { as.numeric(strftime(epoch(x), if (x@freq == 52) "%G" else "%Y")) } else { ((x@epoch-1 + x@start[2]-1) + (x@freq*x@start[1])) %/% x@freq } }) ##################################################################### #[-method for truncating the time series and/or selecting units ##################################################################### setMethod("[", "sts", function(x, i, j, ..., drop) { nTimeOriginal <- nrow(x@observed) if (missing(i)) { # set default value i <- seq_len(nTimeOriginal) } else if (anyNA(i)) { stop("missing row index values are not supported") } else if (is.logical(i)) { # convert to integer index i <- which(rep_len(i, nTimeOriginal)) } else if (is.character(i)) { stop("character row indices are not supported") } else if (any(i < 0)) { # convert to (positive) indices if (any(i > 0)) stop("only 0's may be mixed with negative subscripts") i <- setdiff(seq_len(nTimeOriginal), -i) } else if (any(i0 <- i == 0)) { # drop 0's (for the diff check below) i <- i[!i0] } ## if(missing(j)) j <- seq_len(ncol(x@observed)) # redundant if (!missing(j) && anyNA(j)) stop("missing column index values are not supported") ## check if i is a regular integer sequence (not invalidating freq) if (any(diff(i) != 1)) warning("irregular row index could invalidate \"freq\"") x@epoch <- x@epoch[i] x@observed <- x@observed[i,j,drop=FALSE] x@state <- x@state[i,j,drop=FALSE] x@alarm <- x@alarm[i,j,drop=FALSE] recompute_fractions <- !missing(j) && !x@multinomialTS && all(rowSums(x@populationFrac) == 1) x@populationFrac <- x@populationFrac[i,j,drop=FALSE] if (isTRUE(recompute_fractions)) { x@populationFrac <- x@populationFrac / rowSums(x@populationFrac) } x@upperbound <- x@upperbound[i,j,drop=FALSE] #Neighbourhood matrix if (ncol(x@observed) != ncol(x@neighbourhood) && # selected units !all(x@neighbourhood %in% c(NA,0,1))) { # no adjacency matrix message("Note: selection of units could invalidate the 'neighbourhood'") ## e.g., if 'neighbourhood' specifies neighbourhood orders } x@neighbourhood <- x@neighbourhood[j,j,drop=FALSE] #Fix the "start" and "epoch" entries (if necessary) if (any(i != 0) && i[1] != 1) { #Note: This code does not work if we have week 53s! i.min <- min(i) # in regular use, this should actually be i[1] new.sampleNo <- x@start[2] + i.min - 1 start.year <- x@start[1] + (new.sampleNo - 1) %/% x@freq start.sampleNo <- (new.sampleNo - 1) %% x@freq + 1 x@start <- c(start.year, start.sampleNo) if (!x@epochAsDate) { ## we also have to update epoch since it is relative to start ## and actually it should always equal 1:nrow(observed) x@epoch <- x@epoch - i.min + 1L } ## if (x@epochAsDate && x@freq == 52) { ## ## FIXME: should we derive start from the first date? ## ISO <- isoWeekYear(as.Date(x@epoch[1], origin = "1970-01-01")) ## x@start <- c(ISO$ISOYear, ISO$ISOWeek) ## } } ## Note: We do not automatically subset the map according to j, since ## identical(row.names(map), colnames(observed)) ## is not a property of the sts-class; Unmonitored regions are allowed. #Done return(x) }) ######################################################################### ## Plot method ... the type argument specifies what type of plot to make ## ## plot as multivariate time series: type = observed ~ time | unit ## plot as map object aggregated over time: type = observed ~ 1 | unit ## new map implementation via: type = observed ~ unit ## the specific plot functions are in separate files (stsplot_*.R) ######################################################################## plot.sts <- function (x, type = observed ~ time | unit, ...) { # catch new implementation of time-aggregate map plot if (isTRUE(all.equal(observed ~ unit, type))) return(stsplot_space(x, ...)) #Valid formula? valid <- lapply(as.list(type[[3]]), function(i) is.na(pmatch(i,c("1","unit","|","time","*","+")))) valid <- all(!unlist(valid)) obsOk <- (type[[2]] == "observed") alarmOk <- (type[[2]] == "alarm") if (!valid || !(obsOk | alarmOk)) stop("Not a valid plot type") #Parse the formula, i.e. extract components map <- (length(type[[3]])==3) && (type[[3]][[1]] == "|") && (type[[3]][[2]] == "1") time <- pmatch("time",type[[3]]) > 0 #All-in-one if type=time+unit -> no, use argument "as.one" for stsplot_time #as.one <- all(!is.na(pmatch(c("time","unit"),type[[3]] ))) && is.na(pmatch("|",type[[3]])) #No unit dimension? justTime <- type[[3]] == "time" #space-time plots if (map) { stsplot_spacetime(x, type, ...) return(invisible()) } #time plots if (time) { if (obsOk) { #In case observed ~ time, the units are aggregated stsplot_time(if(justTime) aggregate(x,by="unit") else x, ...) return(invisible()) } if (alarmOk) { stsplot_alarm(x, ...) return(invisible()) } } } setMethod("plot", signature(x="sts", y="missing"), plot.sts) ## define how "sts" objects get printed setMethod( "show", "sts", function( object ){ cat( "-- An object of class ", class(object), " -- \n", sep = "" ) if (!object@epochAsDate) { cat( "freq:\t\t", object@freq,"\n" ) } else { epochStr <- switch( as.character(object@freq), "12" = "%m","52" = "%V","365" = "%j") cat( "freq:\t\t", paste(object@freq," with strptime format string ",epochStr,"\n",sep="")) } if (!object@epochAsDate) { cat( "start:\t\t",object@start,"\n" ) } else { cat( "start:\t\t",paste(epoch(object)[1]),"\n" ) } cat( "dim(observed):\t", dim(object@observed), "\n\n") n <- 1 cat("Head of observed:\n") print(head(object@observed,n)) if (npoly <- length(object@map)) { cat("\nmap:", npoly, "Polygons, ") ## no longer print SpatialPolygons as this may load heavy sf (for is.projected) ## print(modifyList(summary(object@map), list(data=NULL))) # no data summary if (inherits(object@map, "SpatialPolygonsDataFrame")) { cat(ncol(object@map), "variables") cat("\nHead of map@data:\n") print(head(object@map@data, n)) } else cat("without data\n") } if (ncol(object@observed) > 1 && !all(is.na(object@neighbourhood))) { cat("\nHead of neighbourhood:\n") print( head(object@neighbourhood,n)) } } ) surveillance/R/LRCUSUM.runlength.R0000644000176200001440000001253314615162374016446 0ustar liggesusers###################################################################### # Compute log likelihood ratio for a univariate or multivariate # categorical distribution # # Params: # outcomes - a data frame with all possible configuration for the (c-1) # variables not being the reference category. # mu - expectation under which LLR under pi is computed # mu0 - null model. A vector of length (k-1) # mu1 - alternative model. A vector of length (k-1) ###################################################################### LLR.fun <- function(outcomes, mu, mu0, mu1, dfun, ...) { #Compute likelihood ratios. Both univariate and the multivariate #values are computed llr.res <- t(apply(outcomes,1, function(y) { llr <- dfun(y, mu=mu1, log=TRUE,...) - dfun(y, mu=mu0, log=TRUE, ...) p <- dfun(y, mu=mu, ...) return(c(llr=llr,p=p)) })) res <- cbind(outcomes,llr.res) colnames(res) <- c(paste("y",1:ncol(outcomes),sep=""),"llr","p") return(res) } ###################################################################### # Function to compute all possible outcomes for the categorical time # series. This is needed for the LLR computations # # Parameters: # km1 - Dimension of the problem (k-1) # n - number of items arranged (i.e. number of experiments). Integer # # Returns: # matrix of size (number of configs) \times km1 # containing all possible states ###################################################################### outcomeFunStandard <- function(k,n) { #Compute all possible likelihood ratios and their probability under mu #Note: Currently all states are investigated. This might be way too #much work as defacto many states have an occurrence prob near 0!! outcomes <- as.matrix(expand.grid(rep(list(0:n), k), KEEP.OUT.ATTRS=FALSE)) #Take only valid outcomes (might reduce drastically the number of cells) outcomes <- outcomes[rowSums(outcomes) <= n,,drop=FALSE] return(outcomes) } ###################################################################### # Compute run length for CUSUM based on Markov representation of the # Likelihood ratio based CUSUM # # Parameters: # mu - (k-1 \times T) matrix with true proportions, i.e. equal to mu0 or mu1 if one wants to compute e.g. ARL_0 or ARL_1 # mu0 - (k-1 \times T) matrix with in-control proportions # mu1 - (k-1 \times T) matrix with out-of-control proportion # n - vector of length T containing the total number of experiments for each time point # h- The threshold h which is used for the CUSUM # g - The number of levels to cut the state space into, i.e. M on foil 12 ###################################################################### LRCUSUM.runlength <- function(mu,mu0,mu1,h,dfun, n, g=5,outcomeFun=NULL,...) { #Semantic checks if ( ((ncol(mu) != ncol(mu0)) | (ncol(mu0) != ncol(mu1))) | ((nrow(mu) != nrow(mu0)) | (nrow(mu0) != nrow(mu1)))) { stop("Error: dimensions of mu, mu0 and mu1 have to match") } if (missing(h)) { stop("No threshold specified!") } #If no specific way for computing the outcomes is given #use the standard way. if (is.null(outcomeFun)) { outcomeFun <- outcomeFunStandard } #Discretize number of possible states of the CUSUM S <- c(-Inf,seq(0,h,length.out=g)) names <- c(levels(cut(1,S,right=TRUE)),">=h") #Time variable t <- 1:ncol(mu) #Dimension of the problem (k-1) km1 <- nrow(mu) #Create transition matrix for CUSUM control chart P <- array(0, dim=c(length(t),g+1,g+1),dimnames=list(t,names,names)) #Once in the absorbing state stay there! P[,g+1,g+1] <- 1 #Loop over all P[t,,] and compute probabilities for (i in seq_along(t)) { if (length(t) > 1) cat("Looking at t =", i, "/", length(t), "\n") #Determine all possible outcomes outcomes <- outcomeFun(km1,n[i]) #Compute all possible likelihood ratios and their probability under mu llr <- LLR.fun(outcomes,mu=mu[,i],mu0=mu0[,i],mu1=mu1[,i],dfun=dfun,size=n[i],...) #Exact CDF of the LLR for this time F <- stepfun(sort(llr[,"llr"]),c(0,cumsum(llr[order(llr[,"llr"]),"p"]))) #Compute probability going from c <= S_{t-1} < d to a <= S_{t} < b for (j in 1:g) { #from index for (k in 1:g) { #to index a <- S[k] ; b <- S[k+1] ; c <- S[j] ; d <- S[j+1] ; m <- (c+d)/2 #From zero to new state if (j == 1) { P[i,j,k] <- F(b) - F(a) } else { #Rieman integral assuming as in Brook & Evans (1972) that S at midpoint #P[i,j,k] <- F(b-m) - F(a-m) #Slightly better approximation by Hawkins (1992), which uses Simpson's rule P[i,j,k] <- (F(b-c) + 4*F(b-m) + F(b-d) - F(a-c) - 4*F(a-m) - F(a-d))/6 } } } #Whatever is missing goes to >h category (take care of rounding errors) P[i,-(g+1),(g+1)] <- pmax(0,1-apply(P[i,-(g+1),-(g+1)],1,sum)) } #Use matrix to compute RL distribution Ppower <- P[1,,] alarmUntilTime <- numeric(ncol(mu0)) alarmUntilTime[1] <- Ppower[1,ncol(P)] for (time in t[-1]) { #from 2 to length of t Ppower <- Ppower %*% P[time,,] alarmUntilTime[time] <- Ppower[1,ncol(P)] } pRL <- c(alarmUntilTime[1],diff(alarmUntilTime)) mom <- NA #If the Markov chain is homogeneous then compute ARL by inverting if (length(t) == 1) { R <- P[,1:g,1:g] I <- diag(nrow=g) mom <- rowSums(solve(I-R)) } return(list(P=P,pmf=pRL,cdf=alarmUntilTime,arl=mom[1])) } surveillance/R/graphs.R0000644000176200001440000000514414426171115014564 0ustar liggesusers################################################################################ ### Functions concerning graphs: neighbourhood order, adjacency matrix ### ### Copyright (C) 2009-2013,2017,2023 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### Determine the matrix of neighbourhood orders ### given the binary matrix of first-order neighbours. nbOrder <- function (neighbourhood, maxlag = Inf) { stopifnot(isScalar(maxlag), maxlag > 0) checkNeighbourhood(neighbourhood) neighbourhood <- neighbourhood == 1 # convert to binary matrix nregions <- nrow(neighbourhood) maxlag <- as.integer(min(maxlag, nregions-1)) # upper bound of nb order if (maxlag == 1L) { storage.mode(neighbourhood) <- "integer" return(neighbourhood) } ## list of indexes of first-order neighbours by region ##first <- apply(neighbourhood, 1L, which, simplify = FALSE) # R >= 4.1.0 first <- lapply(seq_len(nregions), function (i) which(neighbourhood[i,])) ## Side note: fast method to determine neighbours _up to_ specific order: ## crossprod(neighbourhood) > 0 # up to second order neighbours (+set diag to 0) ## (neighbourhood %*% neighbourhood %*% neighbourhood) > 0 # up to order 3 ## and so on... ## now find recursive neighbours for each region nbmat <- `diag<-`(neighbourhood, NA) # skip self in which() below for (i in seq_len(nregions)) { # slightly faster than [l]apply() variants nblags <- as.integer(nbmat[i,]) lag <- 1L while (lag < maxlag) { nbs <- which(nblags == lag) nbs2 <- unlist(first[nbs]) new <- intersect(nbs2, which(nblags == 0)) if (length(new)) { lag <- lag + 1L nblags[new] <- lag } else break } nbmat[i,] <- nblags } diag(nbmat) <- 0L ## Done nbmat } ### Derive adjacency structure from a SpatialPolygons object ### Working horse: spdep::poly2nb poly2adjmat <- function (SpP, ..., zero.policy = TRUE) { if (!requireNamespace("spdep")) stop("package ", sQuote("spdep"), " is required to derive adjacencies from SpatialPolygons") nb <- spdep::poly2nb(SpP, ...) adjmat <- spdep::nb2mat(nb, style="B", zero.policy=zero.policy) attr(adjmat, "call") <- NULL colnames(adjmat) <- rownames(adjmat) adjmat } surveillance/R/hhh4.R0000644000176200001440000023502114615162374014141 0ustar liggesusers################################################################################ ### Endemic-epidemic modelling for univariate or multivariate ### time series of infectious disease counts (data class "sts") ### ### Copyright (C) 2010-2012 Michaela Paul, 2012-2016,2019-2023 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## Error message issued in loglik, score and fisher functions upon NA parameters ADVICEONERROR <- "\n Try different starting values, more iterations, or another optimizer.\n" ### Main function to be called by the user hhh4 <- function (stsObj, control = list( ar = list(f = ~ -1, # a formula "exp(x'lamba)*y_t-lag" (ToDo: matrix) offset = 1, # multiplicative offset lag = 1), # autoregression on y_i,t-lag ne = list(f = ~ -1, # a formula "exp(x'phi) * sum_j w_ji * y_j,t-lag" offset = 1, # multiplicative offset lag = 1, # regression on y_j,t-lag weights = neighbourhood(stsObj) == 1, # weights w_ji scale = NULL, # such that w_ji = scale * weights normalize = FALSE), # w_ji -> w_ji / rowSums(w_ji), after scaling end = list(f = ~ 1, # a formula "exp(x'nu) * n_it" offset = 1), # optional multiplicative offset e_it family = c("Poisson", "NegBin1", "NegBinM"), # or a factor of length nUnit subset = 2:nrow(stsObj), # epidemic components require Y_{t-lag} optimizer = list(stop = list(tol = 1e-5, niter = 100), # control arguments regression = list(method = "nlminb"), # for optimization variance = list(method = "nlminb")), # <- or "Nelder-Mead" verbose = FALSE, # level of reporting during optimization start = list(fixed = NULL, # list of start values, replacing initial random = NULL, # values from fe() and ri() in 'f'ormulae sd.corr = NULL), data = list(t = stsObj@epoch - min(stsObj@epoch)), # named list of covariates keep.terms = FALSE # whether to keep interpretControl(control, stsObj) ), check.analyticals = FALSE) { ptm <- proc.time() ## Convert old disProg class to new sts class if (inherits(stsObj, "disProg")) { stsObj <- disProg2sts(stsObj) } else { stopifnot(inherits(stsObj, "sts")) } ## check control and set default values (for missing arguments) control <- setControl(control, stsObj) ## get model terms model <- interpretControl(control, stsObj) dimFixedEffects <- model$nFE + model$nd + model$nOverdisp dimRandomEffects <- model$nRE ## starting values #* -> better default values possible theta.start <- model$initialTheta Sigma.start <- model$initialSigma ## check if initial values are valid ## CAVE: there might be NA's in mu if there are missing values in Y mu <- meanHHH(theta.start, model, total.only=TRUE) if(any(mu==0, na.rm=TRUE) || any(is.infinite(mu))) stop("some mean is degenerate (0 or Inf) at initial values") ## check score vector and fisher information at starting values check.analyticals <- if (isTRUE(check.analyticals)) { if (length(theta.start) > 50) "maxLik" else "numDeriv" } else if (is.character(check.analyticals)) { match.arg(check.analyticals, c("numDeriv", "maxLik"), several.ok=TRUE) } else NULL if (length(check.analyticals) > 0L) { resCheck <- checkAnalyticals(model, theta.start, Sigma.start, methods=check.analyticals) return(resCheck) } ## maximize loglikelihood (penalized and marginal) myoptim <- fitHHH(theta=theta.start,sd.corr=Sigma.start, model=model, cntrl.stop = control$optimizer$stop, cntrl.regression = control$optimizer$regression, cntrl.variance = control$optimizer$variance, verbose=control$verbose) ## extract parameter estimates convergence <- myoptim$convergence == 0 thetahat <- myoptim$theta if (dimRandomEffects>0) { Sigma.orig <- myoptim$sd.corr Sigma.trans <- getSigmai(head(Sigma.orig,model$nVar), tail(Sigma.orig,model$nCorr), model$nVar) dimnames(Sigma.trans) <- rep.int(list(sub("^sd\\.", "", names(Sigma.orig)[seq_len(model$nVar)])), 2L) } else { Sigma.orig <- Sigma.trans <- NULL } ## compute covariance matrices of regression and variance parameters cov <- try(solve(myoptim$fisher), silent=TRUE) Sigma.cov <- if(dimRandomEffects>0) try(solve(myoptim$fisherVar), silent=TRUE) ## check for degenerate fisher info if(inherits(cov, "try-error")){ # fisher info is singular if (control$verbose) cat("WARNING: Final Fisher information matrix is singular!\n") convergence <- FALSE } else if(any(!is.finite(diag(cov))) || any(diag(cov)<0)){ if (control$verbose) cat("WARNING: non-finite or negative covariance of regression parameters!\n") convergence <- FALSE } if (!convergence) { if (control$verbose) { cat("Penalized loglikelihood =", myoptim$loglik, "\n") thetastring <- paste(round(thetahat,2), collapse=", ") thetastring <- strwrap(thetastring, exdent=10, prefix="\n", initial="") cat("theta = (", thetastring, ")\n") } warning("Results are not reliable!", if (any(splitParams(thetahat, model)$overdisp > 10)) { # FALSE for Poisson "\n Overdispersion parameter close to zero; maybe try a Poisson model.\n" } else ADVICEONERROR) } ## gather results in a list -> "hhh4" object result <- list(coefficients=thetahat, se=if (convergence) sqrt(diag(cov)), cov=cov, Sigma=Sigma.trans, # estimated covariance matrix of ri's Sigma.orig=Sigma.orig, # variance parameters on original scale Sigma.cov=Sigma.cov, # covariance matrix of Sigma.orig call=match.call(), dim=c(fixed=dimFixedEffects,random=dimRandomEffects), loglikelihood=myoptim$loglik, margll=myoptim$margll, convergence=convergence, fitted.values=meanHHH(thetahat, model, total.only=TRUE), control=control, terms=if(control$keep.terms) model else NULL, stsObj=stsObj, lags=sapply(control[c("ar","ne")], function (comp) if (comp$inModel) comp$lag else NA_integer_), nObs=sum(!model$isNA[control$subset,]), nTime=length(model$subset), nUnit=ncol(stsObj), ## CAVE: nTime is not nrow(stsObj) as usual! runtime=proc.time()-ptm) if (!convergence) { ## add (singular) Fisher information for further investigation result[c("fisher","fisherVar")] <- myoptim[c("fisher","fisherVar")] } class(result) <- "hhh4" return(result) } ## set default values for model specifications in control setControl <- function (control, stsObj) { stopifnot(is.list(control)) nTime <- nrow(stsObj) nUnit <- ncol(stsObj) if(nTime <= 2) stop("too few observations") ## arguments in 'control' override any corresponding default arguments defaultControl <- eval(formals(hhh4)$control) environment(defaultControl$ar$f) <- environment(defaultControl$ne$f) <- environment(defaultControl$end$f) <- .GlobalEnv control <- modifyList(defaultControl, control, keep.null = TRUE) ## check that component specifications are list objects for (comp in c("ar", "ne", "end")) { if(!is.list(control[[comp]])) stop("'control$", comp, "' must be a list") } ## check lags in "ar" and "ne" components for (comp in c("ar", "ne")) { if (!isScalar(control[[comp]]$lag) || control[[comp]]$lag < (comp=="ar")) stop("'control$", comp, "$lag' must be a ", if (comp=="ar") "positive" else "non-negative", " integer") control[[comp]]$lag <- as.integer(control[[comp]]$lag) } ### check AutoRegressive component if (control$ar$isMatrix <- is.matrix(control$ar$f)) { ## this form is not implemented -> will stop() in interpretControl() if (any(dim(control$ar$f) != nUnit)) stop("'control$ar$f' must be a square matrix of size ", nUnit) if (is.null(control$ar$weights)) { # use identity matrix control$ar$weights <- diag(nrow=nUnit) } else if (!is.matrix(control$ar$weights) || any(dim(control$ar$weights) != nUnit)) { stop("'control$ar$weights' must be a square matrix of size ", nUnit) } control$ar$inModel <- TRUE } else if (inherits(control$ar$f, "formula")) { if (!is.null(control$ar$weights)) { warning("argument 'control$ar$weights' is not used") control$ar$weights <- NULL } # check if formula is valid control$ar$inModel <- isInModel(control$ar$f) } else { stop("'control$ar$f' must be either a formula or a matrix") } ### check NEighbourhood component if (!inherits(control$ne$f, "formula")) stop("'control$ne$f' must be a formula") control$ne$inModel <- isInModel(control$ne$f) if (control$ne$inModel) { if (nUnit == 1) warning("\"ne\" component requires a multivariate 'stsObj'") ## if ar$f is a matrix it includes neighbouring units => no "ne" component if (control$ar$isMatrix) stop("there must not be an extra \"ne\" component ", "if 'control$ar$f' is a matrix") ## check ne$weights specification checkWeights(control$ne$weights, nUnit, nTime, neighbourhood(stsObj), control$data, check0diag = control$ar$inModel) ## check optional scaling of weights if (!is.null(control$ne$scale)) { stopifnot(is.numeric(control$ne$scale)) if (is.vector(control$ne$scale)) { stopifnot(length(control$ne$scale) == 1L || length(control$ne$scale) %% nUnit == 0, !is.na(control$ne$scale)) } else { checkWeightsArray(control$ne$scale, nUnit, nTime) } } } else { control$ne[c("weights", "scale", "normalize")] <- list(NULL, NULL, FALSE) } ### check ENDemic component if (!inherits(control$end$f, "formula")) stop("'control$end$f' must be a formula") control$end$inModel <- isInModel(control$end$f) ### check offsets for (comp in c("ar", "ne", "end")) { if (is.matrix(control[[comp]]$offset) && is.numeric(control[[comp]]$offset)){ if (!identical(dim(control[[comp]]$offset), dim(stsObj))) stop("'control$",comp,"$offset' must be a numeric matrix of size ", nTime, "x", nUnit) if (anyNA(control[[comp]]$offset)) stop("'control$",comp,"$offset' must not contain NA values") } else if (!identical(as.numeric(control[[comp]]$offset), 1)) { stop("'control$",comp,"$offset' must either be 1 or a numeric ", nTime, "x", nUnit, " matrix") } } ### stop if no component is included in the model if (length(comps <- componentsHHH4(list(control=control))) == 0L) stop("none of the components 'ar', 'ne', 'end' is included in the model") ### check remaining components of the control list if (is.factor(control$family)) { stopifnot(length(control$family) == nUnit) ## guard against misuse as family = factor("Poisson"), e.g., if taken ## from a data.frame of control options with "stringsAsFactors" if (nUnit == 1 && as.character(control$family) %in% defaultControl$family) { control$family <- as.character(control$family) warning("'family = factor(\"", control$family, "\")' is interpreted ", "as 'family = \"", control$family, "\"'") } else { control$family <- droplevels(control$family) names(control$family) <- colnames(stsObj) } } else { control$family <- match.arg(control$family, defaultControl$family) } if (!is.vector(control$subset, mode="numeric") || !all(control$subset %in% seq_len(nTime))) stop("'control$subset' must be %in% 1:", nTime) lags <- c(ar = control$ar$lag, ne = control$ne$lag) maxlag <- suppressWarnings(max(lags[names(lags) %in% comps])) # could be -Inf if (control$subset[1L] <= maxlag) { warning("'control$subset' should be > ", maxlag, " due to epidemic lags") } if (!is.list(control$optimizer) || any(! sapply(c("stop", "regression", "variance"), function(x) is.list(control$optimizer[[x]])))) stop("'control$optimizer' must be a list of lists") control$verbose <- as.integer(control$verbose) if (length(control$verbose) != 1L || control$verbose < 0) stop("'control$verbose' must be a logical or non-negative numeric value") stopifnot(is.list(control$start)) control$start <- local({ defaultControl$start[] <- control$start[names(defaultControl$start)] defaultControl$start }) if (!all(vapply(X = control$start, FUN = function(x) is.null(x) || is.vector(x, mode="numeric"), FUN.VALUE = TRUE, USE.NAMES = FALSE))) stop("'control$start' must be a list of numeric start values") stopifnot(length(control$keep.terms) == 1L, is.logical(control$keep.terms)) ## Done return(control) } # check whether or not one of the three components is included in the model isInModel <- function(formula, name=deparse(substitute(formula))) { term <- terms.formula(formula) if(attr(term,"response") > 0) stop(name, " cannot contain a response") attr(term, "intercept") + length(attr(term, "term.labels")) > 0 } # used to incorporate covariates and unit-specific effects fe <- function(x, # covariate unitSpecific = FALSE, # TRUE means which = rep.int(TRUE, nUnits) which=NULL, # NULL = overall, vector with booleans = unit-specific initial=NULL) # vector of initial values for parameters { stsObj <- get("stsObj", envir=parent.frame(1), inherits=TRUE) #checkFormula() nTime <- nrow(stsObj) nUnits <- ncol(stsObj) if(!is.numeric(x)){ stop("Covariate \'",deparse(substitute(x)),"\' is not numeric\n") } lengthX <- length(x) if(lengthX == 1){ terms <- matrix(x, nTime, nUnits, byrow=FALSE) mult <- "*" } else if(lengthX == nTime){ terms <- matrix(x, nTime, nUnits, byrow=FALSE) mult <- "*" } else if(lengthX == nTime*nUnits){ if(!is.matrix(x)){ stop("Covariate \'",deparse(substitute(x)),"\' is not a matrix\n") } # check dimensions of covariate if((ncol(x) != nUnits) | (nrow(x) != nTime)){ stop("Dimension of covariate \'",deparse(substitute(x)),"\' is not suitably specified\n") } terms <- x mult <- "*" } else { stop("Covariate \'",deparse(substitute(x)),"\' is not suitably specified\n") } intercept <- all(terms==1) # overall or unit-specific effect? unitSpecific <- unitSpecific || !is.null(which) if (unitSpecific) { if (is.null(which)) { which <- rep.int(TRUE, nUnits) } else { stopifnot(is.vector(which, mode="logical"), length(which) == nUnits) } terms[,!which] <- 0 } # get dimension of parameter dim.fe <- if (unitSpecific) sum(which) else 1 # check length of initial values + set default values if (is.null(initial)) { initial <- rep.int(0,dim.fe) } else if (length(initial) != dim.fe) { stop("initial values for '",deparse(substitute(x)),"' must be of length ",dim.fe) } name <- deparse(substitute(x)) if (unitSpecific) name <- paste(name, colnames(stsObj)[which], sep=".") result <- list(terms=terms, name=name, Z.intercept=NULL, which=which, dim.fe=dim.fe, initial.fe=initial, dim.re=0, dim.var=0, initial.var=NULL, initial.re=NULL, intercept=intercept, unitSpecific=unitSpecific, random=FALSE, corr=FALSE, mult=mult ) return(result) } # random intercepts ri <- function(type=c("iid","car"), corr=c("none","all"), initial.fe=0, initial.var=-.5, initial.re=NULL) { stsObj <- get("stsObj", envir=parent.frame(1), inherits=TRUE) #checkFormula() if (ncol(stsObj) == 1) stop("random intercepts require a multivariate 'stsObj'") type <- match.arg(type) corr <- match.arg(corr) corr <- switch(corr, "none"=FALSE, "all"=TRUE) if(type=="iid"){ Z <- 1 dim.re <- ncol(stsObj) mult <- "*" } else if(type=="car"){ # construct penalty matrix K K <- neighbourhood(stsObj) checkNeighbourhood(K) K <- K == 1 # indicate first-order neighbours ne <- colSums(K) # number of first-order neighbours K <- -1*K diag(K) <- ne dimK <- nrow(K) # check rank of the nhood, only connected neighbourhoods are allowed if(qr(K)$rank != dimK-1) stop("neighbourhood matrix contains islands") # singular-value decomposition of K svdK <- svd(K) # just use the positive eigenvalues of K in descending order # for a the factorisation of the penalty matrix K = LL' L <- svdK$u[,-dimK] %*% diag(sqrt(svdK$d[-dimK])) #* only use non-zero eigenvalues # Z = L(L'L)^-1, which can't be simplified to Z=(L')^-1 as L is not square Z <- L %*% solve(t(L)%*%L) dim.re <- dimK - 1L mult <- "%*%" } # check length of initial values + set default values stopifnot(length(initial.fe) == 1, length(initial.var) == 1) if (is.null(initial.re)) { initial.re <- rnorm(dim.re,0,sd=sqrt(0.001)) } else if (length(initial.re) != dim.re) { stop("'initial.re' must be of length ", dim.re) } result <- list(terms=1, name=paste("ri(",type,")",sep=""), Z.intercept=Z, which=NULL, dim.fe=1, initial.fe=initial.fe, dim.re=dim.re, dim.var=1, initial.var=initial.var, initial.re=initial.re, intercept=TRUE, unitSpecific=FALSE, random=TRUE, corr=corr, mult=mult ) return(result) } ### check specification of formula ## f: one of the component formulae (ar$f, ne$f, or end$f) ## component: 1, 2, or 3, corresponding to the ar/ne/end component, respectively ## data: the data-argument of hhh4() ## stsObj: the stsObj is not used directly in checkFormula, but in fe() and ri() checkFormula <- function(f, component, data, stsObj) { term <- terms.formula(f, specials=c("fe","ri")) # check if there is an overall intercept intercept.all <- attr(term, "intercept") == 1 # list of variables in the component vars <- as.list(attr(term,"variables"))[-1] # first element is "list" nVars <- length(vars) if (nVars > 0 && any(attr(term, "order") > 1)) warning("interaction terms are not implemented") # begin with intercept res <- if (intercept.all) { c(fe(1), list(offsetComp=component)) } else { if (nVars==0) stop("formula ", deparse(substitute(f)), " contains no variables") NULL } # find out fixed effects without "fe()" specification # (only if there are variables in addition to an intercept "1") fe.raw <- setdiff(seq_len(nVars), unlist(attr(term, "specials"))) # evaluate covariates for(i in fe.raw) res <- cbind(res, c( eval(substitute(fe(x), list(x=vars[[i]])), envir=data), list(offsetComp=component) )) # fixed effects for(i in attr(term, "specials")$fe) res <- cbind(res, c( eval(vars[[i]], envir=data), list(offsetComp=component) )) res <- cbind(res, deparse.level=0) # ensure res has matrix dimensions # random intercepts RI <- attr(term, "specials")$ri if (sum(unlist(res["intercept",])) + length(RI) > 1) stop("There can only be one intercept in the formula ", deparse(substitute(f))) for(i in RI) res <- cbind(res, c( eval(vars[[i]], envir=data), list(offsetComp=component) )) return(res) } ## Create function (pars, type = "response") which ## returns the weighted sum of time-lagged counts of neighbours ## (or its derivates, if type = "gradient" or type = "hessian"). ## For type="response", this is a nTime x nUnits matrix (like Y), ## otherwise a list of such matrices, ## which for the gradient has length length(pars) and ## length(pars)*(length(pars)+1)/2 for the hessian. ## If neweights=NULL (i.e. no NE component in model), the result is always 0. ## offset is a multiplicative offset for \phi_{it}, e.g., the population. ## scale is a nUnit-vector or a nUnit x nUnit matrix scaling neweights. neOffsetFUN <- function (Y, neweights, scale, normalize, nbmat, data, lag = 1, offset = 1) { if (is.null(neweights)) { # no neighbourhood component as.function(alist(...=, 0), envir=.GlobalEnv) ## dimY <- dim(Y) ## as.function(c(alist(...=), ## substitute(matrix(0, r, c), list(r=dimY[1], c=dimY[2]))), ## envir=.GlobalEnv) } else if (is.list(neweights)) { # parametric weights wFUN <- scaleNEweights.list(neweights, scale, normalize) function (pars, type = "response") { name <- switch(type, response="w", gradient="dw", hessian="d2w") weights <- wFUN[[name]](pars, nbmat, data) ## gradient and hessian are lists if length(pars$d) > 1L ## but can be single matrices/arrays if == 1 => _c_onditional lapply res <- clapply(weights, function (W) offset * weightedSumNE(Y, W, lag)) ##<- clapply always returns a list (possibly of length 1) if (type=="response") res[[1L]] else res } } else { # fixed (known) weight structure (0-length pars) weights <- scaleNEweights.default(neweights, scale, normalize) env <- new.env(hash = FALSE, parent = emptyenv()) # small -> no hash env$initoffset <- offset * weightedSumNE(Y, weights, lag) as.function(c(alist(...=), quote(initoffset)), envir=env) } } # interpret and check the specifications of each component # control must contain all arguments, i.e. setControl was used interpretControl <- function (control, stsObj) { nTime <- nrow(stsObj) nUnits <- ncol(stsObj) Y <- observed(stsObj) ########################################################################## ## get the model specifications for each of the three components ########################################################################## ar <- control$ar ne <- control$ne end <- control$end ## for backwards compatibility with surveillance < 1.8-0, where the ar and ne ## components of the control object did not have an offset if (is.null(ar$offset)) ar$offset <- 1 if (is.null(ne$offset)) ne$offset <- 1 ## for backward compatibility with surveillance < 1.9-0 if (is.null(ne$normalize)) ne$normalize <- FALSE ## create list of offsets of the three components Ym1 <- rbind(matrix(NA_integer_, ar$lag, nUnits), head(Y, nTime-ar$lag)) Ym1.ne <- neOffsetFUN(Y, ne$weights, ne$scale, ne$normalize, neighbourhood(stsObj), control$data, ne$lag, ne$offset) offsets <- list(ar=ar$offset*Ym1, ne=Ym1.ne, end=end$offset) ## -> offset$ne is a function of the parameter vector 'd', which returns a ## nTime x nUnits matrix -- or 0 (scalar) if there is no NE component ## -> offset$end might just be 1 (scalar) ## Initial parameter vector 'd' of the neighbourhood weight function initial.d <- if (is.list(ne$weights)) ne$weights$initial else numeric(0L) dim.d <- length(initial.d) names.d <- if (dim.d == 0L) character(0L) else { paste0("neweights.", if (is.null(names(initial.d))) { if (dim.d==1L) "d" else paste0("d", seq_len(dim.d)) } else names(initial.d)) } ## determine all NA's isNA <- is.na(Y) if (ar$inModel) isNA <- isNA | is.na(offsets[[1L]]) if (ne$inModel) isNA <- isNA | is.na(offsets[[2L]](initial.d)) ## get terms for all components all.term <- NULL if(ar$isMatrix) stop("matrix-form of 'control$ar$f' is not implemented") if(ar$inModel) # ar$f is a formula all.term <- cbind(all.term, checkFormula(ar$f, 1, control$data, stsObj)) if(ne$inModel) all.term <- cbind(all.term, checkFormula(ne$f, 2, control$data, stsObj)) if(end$inModel) all.term <- cbind(all.term, checkFormula(end$f,3, control$data, stsObj)) dim.fe <- sum(unlist(all.term["dim.fe",])) dim.re.group <- unlist(all.term["dim.re",], use.names=FALSE) dim.re <- sum(dim.re.group) dim.var <- sum(unlist(all.term["dim.var",])) dim.corr <- sum(unlist(all.term["corr",])) if(dim.corr>0){ if(dim.var!=dim.corr) stop("Use corr=\'all\' or corr=\'none\' ") dim.corr <- switch(dim.corr,0,1,3) } # the vector with dims of the random effects must be equal if they are correlated if(length(unique(dim.re.group[dim.re.group>0]))!=1 & dim.corr>0){ stop("Correlated effects must have same penalty") } n <- c("ar","ne","end")[unlist(all.term["offsetComp",])] names.fe <- names.var <- names.re <- character(0L) for(i in seq_along(n)){ .name <- all.term["name",i][[1]] names.fe <- c(names.fe, paste(n[i], .name, sep=".")) if(all.term["random",i][[1]]) { names.var <- c(names.var, paste("sd", n[i], .name, sep=".")) names.re <- c(names.re, paste(n[i], .name, if (.name == "ri(iid)") { colnames(stsObj) } else { seq_len(all.term["dim.re",i][[1]]) }, sep = ".")) } } index.fe <- rep(1:ncol(all.term), times=unlist(all.term["dim.fe",])) index.re <- rep(1:ncol(all.term), times=unlist(all.term["dim.re",])) # poisson or negbin model if(identical(control$family, "Poisson")){ ddistr <- function(y,mu,size){ dpois(y, lambda=mu, log=TRUE) } dim.overdisp <- 0L index.overdisp <- names.overdisp <- NULL } else { # NegBin ddistr <- function(y,mu,size){ dnbinom(y, mu=mu, size=size, log=TRUE) } ## version that can handle size = Inf (i.e. the Poisson special case): ## ddistr <- function (y,mu,size) { ## poisidx <- is.infinite(size) ## res <- y ## res[poisidx] <- dpois(y[poisidx], lambda=mu[poisidx], log=TRUE) ## res[!poisidx] <- dnbinom(y[!poisidx], mu=mu[!poisidx], ## size=size[!poisidx], log=TRUE) ## res ## } index.overdisp <- if (is.factor(control$family)) { control$family } else if (control$family == "NegBinM") { factor(colnames(stsObj), levels = colnames(stsObj)) ## do not sort levels (for consistency with unitSpecific effects) } else { # "NegBin1" factor(character(nUnits)) } names(index.overdisp) <- colnames(stsObj) dim.overdisp <- nlevels(index.overdisp) names.overdisp <- if (dim.overdisp == 1L) { "-log(overdisp)" } else { paste0("-log(", paste("overdisp", levels(index.overdisp), sep = "."), ")") } } environment(ddistr) <- getNamespace("stats") # function is self-contained # parameter start values from fe() and ri() calls via checkFormula() initial <- list( fixed = c(unlist(all.term["initial.fe",]), initial.d, rep.int(2, dim.overdisp)), random = as.numeric(unlist(all.term["initial.re",])), # NULL -> numeric(0) sd.corr = c(unlist(all.term["initial.var",]), rep.int(0, dim.corr)) ) # set names of parameter vectors names(initial$fixed) <- c(names.fe, names.d, names.overdisp) names(initial$random) <- names.re names(initial$sd.corr) <- c(names.var, head(paste("corr",1:3,sep="."), dim.corr)) # modify initial values according to the supplied 'start' values initial[] <- mapply( FUN = function (initial, start, name) { if (is.null(start)) return(initial) if (is.null(names(initial)) || is.null(names(start))) { if (length(start) == length(initial)) { initial[] <- start } else { stop("initial values in 'control$start$", name, "' must be of length ", length(initial)) } } else { ## we match by name and silently ignore additional start values start <- start[names(start) %in% names(initial)] initial[names(start)] <- start } return(initial) }, initial, control$start[names(initial)], names(initial), SIMPLIFY = FALSE, USE.NAMES = FALSE ) # Done result <- list(response = Y, terms = all.term, nTime = nTime, nUnits = nUnits, nFE = dim.fe, nd = dim.d, nOverdisp = dim.overdisp, nRE = dim.re, rankRE = dim.re.group, nVar = dim.var, nCorr = dim.corr, nSigma = dim.var+dim.corr, nGroups = ncol(all.term), namesFE = names.fe, indexFE = index.fe, indexRE = index.re, initialTheta = c(initial$fixed, initial$random), initialSigma = initial$sd.corr, offset = offsets, family = ddistr, indexPsi = index.overdisp, subset = control$subset, isNA = isNA ) return(result) } splitParams <- function(theta, model){ fixed <- theta[seq_len(model$nFE)] d <- theta[model$nFE + seq_len(model$nd)] overdisp <- theta[model$nFE + model$nd + seq_len(model$nOverdisp)] random <- theta[seq.int(to=length(theta), length.out=model$nRE)] list(fixed=fixed, random=random, overdisp=overdisp, d=d) } ### compute predictor meanHHH <- function(theta, model, subset=model$subset, total.only=FALSE) { ## unpack theta pars <- splitParams(theta, model) fixed <- pars$fixed random <- pars$random ## unpack model term <- model$terms offsets <- model$offset offsets[[2L]] <- offsets[[2L]](pars$d) # evaluate at current parameter value nGroups <- model$nGroups comp <- unlist(term["offsetComp",]) idxFE <- model$indexFE idxRE <- model$indexRE toMatrix <- function (x, r=model$nTime, c=model$nUnits) matrix(x, r, c, byrow=TRUE) unitNames <- dimnames(model$response)[[2L]] setColnames <- if (is.null(unitNames)) identity else function(x) "dimnames<-"(x, list(NULL, unitNames)) ## go through groups of parameters and compute predictor of each component, ## i.e. lambda_it, phi_it, nu_it, EXCLUDING the multiplicative offset terms, ## as well as the resulting component mean (=exppred * offset) computePartMean <- function (component) { pred <- nullMatrix <- toMatrix(0) if(!any(comp==component)) { # component not in model -> return 0-matrix zeroes <- setColnames(pred[subset,,drop=FALSE]) return(list(exppred = zeroes, mean = zeroes)) } for(i in seq_len(nGroups)[comp==component]){ fe <- fixed[idxFE==i] if(term["unitSpecific",i][[1]]){ fe <- nullMatrix which <- term["which",i][[1]] fe[,which] <- toMatrix(fixed[idxFE==i],c=sum(which)) } if(term["random",i][[1]]){ re <- random[idxRE==i] "%m%" <- get(term["mult",i][[1]]) Z.re <- toMatrix(term["Z.intercept",i][[1]] %m% re) } else { Z.re <- 0 } X <- term["terms",i][[1]] pred <- pred + X*fe + Z.re } exppred <- setColnames(exp(pred[subset,,drop=FALSE])) offset <- offsets[[component]] if (length(offset) > 1) offset <- offset[subset,,drop=FALSE] ##<- no subsetting if offset is scalar (time- and unit-independent) list(exppred = exppred, mean = exppred * offset) } ## compute component means ar <- computePartMean(1) ne <- computePartMean(2) end <- computePartMean(3) ## Done epidemic <- ar$mean + ne$mean endemic <- end$mean if (total.only) epidemic + endemic else list(mean=epidemic+endemic, epidemic=epidemic, endemic=endemic, epi.own=ar$mean, epi.neighbours=ne$mean, ar.exppred=ar$exppred, ne.exppred=ne$exppred, end.exppred=end$exppred) } ### compute dispersion in dnbinom (mu, size) parametrization sizeHHH <- function (theta, model, subset = model$subset) { if (model$nOverdisp == 0L) # Poisson case return(NULL) ## extract dispersion in dnbinom() parametrization pars <- splitParams(theta, model) size <- exp(pars$overdisp) # = 1/psi, pars$overdisp = -log(psi) ## return either a vector or a time x unit matrix of dispersion parameters if (is.null(subset)) { unname(size) # no longer is "-log(overdisp)" } else { matrix(data = size[model$indexPsi], nrow = length(subset), ncol = model$nUnits, byrow = TRUE, dimnames = list(NULL, names(model$indexPsi))) } } ## auxiliary function used in penScore and penFisher ## it sums colSums(x) within the groups defined by f (of length ncol(x)) ## and returns these sums in the order of levels(f) .colSumsGrouped <- function (x, f, na.rm = TRUE) { nlev <- nlevels(f) if (nlev == 1L) { # all columns belong to the same group ("NegBin1") sum(x, na.rm = na.rm) } else { dimx <- dim(x) colsums <- .colSums(x, dimx[1L], dimx[2L], na.rm = na.rm) if (nlev == dimx[2L]) { # each column separately ("NegBinM" or factor) colsums[order(f)] # for NegBinM, order(f)==1:nlev, not in general } else { # sum colsums within groups unlist(lapply( X = split.default(colsums, f, drop = FALSE), FUN = sum ), recursive = FALSE, use.names = FALSE) } } } ############################################ penLogLik <- function(theta, sd.corr, model, attributes=FALSE) { if(anyNA(theta)) stop("NAs in regression parameters.", ADVICEONERROR) ## unpack model subset <- model$subset Y <- model$response[subset,,drop=FALSE] dimPsi <- model$nOverdisp dimRE <- model$nRE ## unpack random effects if (dimRE > 0) { pars <- splitParams(theta, model) randomEffects <- pars$random sd <- head(sd.corr, model$nVar) corr <- tail(sd.corr, model$nCorr) dimBlock <- model$rankRE[model$rankRE>0] Sigma.inv <- getSigmaInv(sd, corr, model$nVar, dimBlock) } ############################################################ ## evaluate dispersion psi <- sizeHHH(theta, model, subset = if (dimPsi > 1L) subset) # else scalar or NULL #psi might be numerically equal to 0 or Inf in which cases dnbinom (in meanHHH) #would return NaN (with a warning). The case size=Inf rarely happens and #corresponds to a Poisson distribution. Currently this case is not handled #in order to have the usual non-degenerate case operate faster. #For size=0, log(dnbinom) equals -Inf for positive x or if (x=0 and mu=0), and #zero if x=0 and mu>0 and mu0, which is always true), we have that sum(ll.units) = -Inf, hence: if (any(psi == 0)) return(-Inf) ## evaluate mean mu <- meanHHH(theta, model, total.only=TRUE) # if, numerically, mu=Inf, log(dnbinom) or log(dpois) both equal -Inf, hence: #if (any(is.infinite(mu))) return(-Inf) # however, since mu=Inf does not produce warnings below and this is a rare # case, it is faster to not include this conditional expression ## penalization term for random effects lpen <- if (dimRE==0) 0 else { # there are random effects ##-.5*(t(randomEffects)%*%Sigma.inv%*%randomEffects) ## the following implementation takes ~85% less computing time ! -0.5 * c(crossprod(randomEffects, Sigma.inv) %*% randomEffects) } ## log-likelihood ll.units <- .colSums(model$family(Y,mu,psi), length(subset), model$nUnits, na.rm=TRUE) ## penalized log-likelihood ll <- sum(ll.units) + lpen ## Done if (attributes) { attr(ll, "loglik") <- ll.units attr(ll, "logpen") <- lpen } ll } penScore <- function(theta, sd.corr, model) { if(anyNA(theta)) stop("NAs in regression parameters.", ADVICEONERROR) ## unpack model subset <- model$subset Y <- model$response[subset,,drop=FALSE] isNA <- model$isNA[subset,,drop=FALSE] dimPsi <- model$nOverdisp dimRE <- model$nRE term <- model$terms nGroups <- model$nGroups dimd <- model$nd ## unpack parameters pars <- splitParams(theta, model) if (dimRE > 0) { randomEffects <- pars$random sd <- head(sd.corr, model$nVar) corr <- tail(sd.corr, model$nCorr) dimBlock <- model$rankRE[model$rankRE>0] Sigma.inv <- getSigmaInv(sd, corr, model$nVar, dimBlock) } ## evaluate dispersion psi <- sizeHHH(theta, model, subset = if (dimPsi > 1L) subset) # else scalar or NULL ## evaluate mean mu <- meanHHH(theta, model) meanTotal <- mu$mean ############################################################ ## helper function for derivatives derivHHH.factor <- if(dimPsi > 0L){ # NegBin psiPlusMu <- psi + meanTotal # also used below for calculation of grPsi psiYpsiMu <- (psi+Y) / psiPlusMu Y/meanTotal - psiYpsiMu } else { # Poisson Y/meanTotal - 1 } derivHHH <- function (dmu) derivHHH.factor * dmu ## go through groups of parameters and compute the gradient of each component computeGrad <- function(mean.comp){ grad.fe <- numeric(0L) grad.re <- numeric(0L) for(i in seq_len(nGroups)){ comp <- term["offsetComp",i][[1]] Xit<- term["terms",i][[1]] # either 1 or a matrix with values if(is.matrix(Xit)){ Xit <- Xit[subset,,drop=FALSE] } dTheta <- derivHHH(mean.comp[[comp]]*Xit) dTheta[isNA] <- 0 # dTheta must not contain NA's (set NA's to 0) if(term["unitSpecific",i][[1]]){ which <- term["which",i][[1]] dimi <- sum(which) if(dimi < model$nUnits) dTheta <- dTheta[,which,drop=FALSE] dTheta <- .colSums(dTheta, length(subset), dimi) grad.fe <- c(grad.fe,dTheta) } else if(term["random",i][[1]]){ Z <- term["Z.intercept",i][[1]] "%m%" <- get(term["mult",i][[1]]) dRTheta <- .colSums(dTheta %m% Z, length(subset), term["dim.re",i][[1]]) grad.re <- c(grad.re, dRTheta) grad.fe <- c(grad.fe, sum(dTheta)) } else{ grad.fe <- c(grad.fe, sum(dTheta)) } } list(fe=grad.fe, re=grad.re) } gradients <- computeGrad(mu[c("epi.own","epi.neighbours","endemic")]) ## gradient for parameter vector of the neighbourhood weights grd <- if (dimd > 0L) { dneOffset <- model$offset[[2L]](pars$d, type="gradient") ##<- this is always a list (of length dimd) of matrices onescore.d <- function (dneoff) { dmudd <- mu$ne.exppred * dneoff[subset,,drop=FALSE] grd.terms <- derivHHH(dmudd) sum(grd.terms, na.rm=TRUE) } unlist(clapply(dneOffset, onescore.d), recursive=FALSE, use.names=FALSE) } else numeric(0L) ## gradient for overdispersion parameter psi grPsi <- if(dimPsi > 0L){ dPsiMat <- psi * (digamma(Y+psi) - digamma(psi) + log(psi) + 1 - log(psiPlusMu) - psiYpsiMu) .colSumsGrouped(dPsiMat, model$indexPsi) } else numeric(0L) ## add penalty to random effects gradient s.pen <- if(dimRE > 0) c(Sigma.inv %*% randomEffects) else numeric(0L) if(length(gradients$re) != length(s.pen)) stop("oops... lengths of s(b) and Sigma.inv %*% b do not match") grRandom <- c(gradients$re - s.pen) ## Done res <- c(gradients$fe, grd, grPsi, grRandom) res } penFisher <- function(theta, sd.corr, model, attributes=FALSE) { if(anyNA(theta)) stop("NAs in regression parameters.", ADVICEONERROR) ## unpack model subset <- model$subset Y <- model$response[subset,,drop=FALSE] isNA <- model$isNA[subset,,drop=FALSE] dimPsi <- model$nOverdisp dimRE <- model$nRE term <- model$terms nGroups <- model$nGroups dimd <- model$nd dimFE <- model$nFE idxFE <- model$indexFE idxRE <- model$indexRE indexPsi <- model$indexPsi ## unpack parameters pars <- splitParams(theta, model) if (dimRE > 0) { randomEffects <- pars$random sd <- head(sd.corr, model$nVar) corr <- tail(sd.corr, model$nCorr) dimBlock <- model$rankRE[model$rankRE>0] Sigma.inv <- getSigmaInv(sd, corr, model$nVar, dimBlock) } ## evaluate dispersion psi <- sizeHHH(theta, model, subset = if (dimPsi > 1L) subset) # else scalar or NULL ## evaluate mean mu <- meanHHH(theta, model) meanTotal <- mu$mean ############################################################ ## helper functions for derivatives: if (dimPsi > 0L) { # negbin psiPlusY <- psi + Y psiPlusMu <- psi + meanTotal psiPlusMu2 <- psiPlusMu^2 psiYpsiMu <- psiPlusY / psiPlusMu psiYpsiMu2 <- psiPlusY / psiPlusMu2 deriv2HHH.fac1 <- psiYpsiMu2 - Y / (meanTotal^2) deriv2HHH.fac2 <- Y / meanTotal - psiYpsiMu ## psi-related derivatives dThetadPsi.fac <- psi * (psiYpsiMu2 - 1/psiPlusMu) dThetadPsi <- function(dTheta){ dThetadPsi.fac * dTheta } dPsiMat <- psi * (digamma(psiPlusY) - digamma(psi) + log(psi) + 1 - log(psiPlusMu) - psiYpsiMu) # as in penScore() dPsidPsiMat <- psi^2 * ( trigamma(psiPlusY) - trigamma(psi) + 1/psi - 1/psiPlusMu - (meanTotal-Y)/psiPlusMu2) + dPsiMat } else { # poisson deriv2HHH.fac1 <- -Y / (meanTotal^2) deriv2HHH.fac2 <- Y / meanTotal - 1 } deriv2HHH <- function(dTheta_l, dTheta_k, dTheta_lk){ dTheta_l * dTheta_k * deriv2HHH.fac1 + dTheta_lk * deriv2HHH.fac2 } ## go through groups of parameters and compute the hessian of each component computeFisher <- function(mean.comp){ # initialize hessian hessian.FE.FE <- matrix(0,dimFE,dimFE) hessian.FE.RE <- matrix(0,dimFE,dimRE) hessian.RE.RE <- matrix(0,dimRE,dimRE) hessian.FE.Psi <- matrix(0,dimFE,dimPsi) hessian.Psi.RE <- matrix(0,dimPsi,dimPsi+dimRE) # CAVE: contains PsiPsi and PsiRE hessian.FE.d <- matrix(0,dimFE,dimd) hessian.d.d <- matrix(0,dimd,dimd) hessian.d.Psi <- matrix(0,dimd,dimPsi) hessian.d.RE <- matrix(0,dimd,dimRE) ## derivatives wrt neighbourhood weight parameters d if (dimd > 0L) { phi.doff <- function (dneoff) { mu$ne.exppred * dneoff[subset,,drop=FALSE] } ## for type %in% c("gradient", "hessian"), model$offset[[2L]] always ## returns a list of matrices. It has length(pars$d) elements for the ## gradient and length(pars$d)*(length(pars$d)+1)/2 for the hessian. dneOffset <- model$offset[[2L]](pars$d, type="gradient") dmudd <- lapply(dneOffset, phi.doff) d2neOffset <- model$offset[[2L]](pars$d, type="hessian") d2mudddd <- lapply(d2neOffset, phi.doff) ## d l(theta,x) /dd dd (fill only upper triangle, BY ROW) ij <- 0L for (i in seq_len(dimd)) { for (j in i:dimd) { ij <- ij + 1L #= dimd*(i-1) + j - (i-1)*i/2 # for j >= i ## d2mudddd contains upper triangle by row (=lowertri by column) d2ij <- deriv2HHH(dmudd[[i]], dmudd[[j]], d2mudddd[[ij]]) hessian.d.d[i,j] <- sum(d2ij, na.rm=TRUE) } } } if (dimPsi > 0L) { ## d l(theta,x) /dpsi dpsi dPsidPsi <- .colSumsGrouped(dPsidPsiMat, indexPsi) hessian.Psi.RE[,seq_len(dimPsi)] <- if (dimPsi == 1L) { dPsidPsi } else { diag(dPsidPsi) } ## d l(theta) / dd dpsi for (i in seq_len(dimd)) { # will not be run if dimd==0 ## dPsi.i <- colSums(dThetadPsi(dmudd[[i]]),na.rm=TRUE) ## hessian.d.Psi[i,] <- if(dimPsi==1L) sum(dPsi.i) else dPsi.i[order(indexPsi)] hessian.d.Psi[i,] <- .colSumsGrouped(dThetadPsi(dmudd[[i]]), indexPsi) } } ## i.fixed <- function(){ if(random.j){ Z.j <- term["Z.intercept",j][[1]] "%mj%" <- get(term["mult",j][[1]]) hessian.FE.RE[idxFE==i,idxRE==j] <<- colSums(didj %mj% Z.j) ##<- didj must not contain NA's (all NA's set to 0) dIJ <- sum(didj,na.rm=TRUE) # fixed on 24/09/2012 } else if(unitSpecific.j){ dIJ <- colSums(didj,na.rm=TRUE)[ which.j ] } else { dIJ <- sum(didj,na.rm=TRUE) } hessian.FE.FE[idxFE==i,idxFE==j] <<- dIJ } ## i.unit <- function(){ if(random.j){ Z.j <- term["Z.intercept",j][[1]] "%mj%" <- get(term["mult",j][[1]]) dIJ <- colSums(didj %mj% Z.j) # didj must not contain NA's (all NA's set to 0) hessian.FE.RE[idxFE==i,idxRE==j] <<- diag(dIJ)[ which.i, ] # FIXME: does not work if type="car" dIJ <- dIJ[ which.i ] # added which.i subsetting in r432 } else if(unitSpecific.j){ dIJ <- diag(colSums(didj))[ which.i, which.j ] } else { dIJ <- colSums(didj)[ which.i ] } hessian.FE.FE[idxFE==i,idxFE==j] <<- dIJ } ## i.random <- function(){ if(random.j){ Z.j <- term["Z.intercept",j][[1]] "%mj%" <- get(term["mult",j][[1]]) hessian.FE.RE[idxFE==i,idxRE==j] <<- colSums(didj %mj% Z.j) if (j != i) # otherwise redundant (duplicate) hessian.FE.RE[idxFE==j,idxRE==i] <<- colSums(didj %m% Z.i) if(length(Z.j)==1 & length(Z.i)==1){ # both iid Z <- Z.i*Z.j hessian.RE.RE[which(idxRE==i),idxRE==j] <<- diag(colSums( didj %m% Z)) } else if(length(Z.j)==1 & length(Z.i)>1){ #* Z.j <- diag(nrow=model$nUnits) for(k in seq_len(ncol(Z.j))){ Z <- Z.i*Z.j[,k] hessian.RE.RE[idxRE==i,which(idxRE==j)[k]] <<- colSums( didj %m% Z) } } else if(length(Z.j)>1 & length(Z.i)==1){ #* Z.i <- diag(nrow=model$nUnits) for(k in seq_len(ncol(Z.i))){ Z <- Z.i[,k]*Z.j hessian.RE.RE[which(idxRE==i)[k],idxRE==j] <<- colSums( didj %mj% Z) } } else { # both CAR for(k in seq_len(ncol(Z.j))){ Z <- Z.i*Z.j[,k] hessian.RE.RE[which(idxRE==i)[k],idxRE==j] <<- colSums( didj %m% Z) } } dIJ <- sum(didj) } else if(unitSpecific.j){ dIJ <- colSums(didj %m% Z.i) hessian.FE.RE[idxFE==j,idxRE==i] <<- diag(dIJ)[ which.j, ] dIJ <- dIJ[ which.j ] } else { hessian.FE.RE[idxFE==j,idxRE==i] <<- colSums(didj %m% Z.i) dIJ <- sum(didj) } hessian.FE.FE[idxFE==i,idxFE==j] <<- dIJ } ##---------------------------------------------- for(i in seq_len(nGroups)){ #go through rows of hessian # parameter group belongs to which components comp.i <- term["offsetComp",i][[1]] # get covariate value Xit <- term["terms",i][[1]] # either 1 or a matrix with values if(is.matrix(Xit)){ Xit <- Xit[subset,,drop=FALSE] } m.Xit <- mean.comp[[comp.i]] * Xit random.i <- term["random",i][[1]] unitSpecific.i <- term["unitSpecific",i][[1]] ## fill psi-related entries and select fillHess function if (random.i) { Z.i <- term["Z.intercept",i][[1]] # Z.i and %m% (of i) determined here "%m%" <- get(term["mult",i][[1]]) # will also be used in j's for loop fillHess <- i.random if (dimPsi > 0L) { dThetadPsiMat <- dThetadPsi(m.Xit) hessian.FE.Psi[idxFE==i,] <- .colSumsGrouped(dThetadPsiMat, indexPsi) dThetadPsi.i <- .colSums(dThetadPsiMat %m% Z.i, length(subset), term["dim.re",i][[1]], na.rm=TRUE) if (dimPsi==1L) { hessian.Psi.RE[,dimPsi + which(idxRE==i)] <- dThetadPsi.i } else { hessian.Psi.RE[cbind(indexPsi,dimPsi + which(idxRE==i))] <- dThetadPsi.i ## FIXME: does not work with type="car" } } } else if (unitSpecific.i) { which.i <- term["which",i][[1]] fillHess <- i.unit if (dimPsi > 0L) { dThetadPsi.i <- .colSums(dThetadPsi(m.Xit), length(subset), model$nUnits, na.rm=TRUE) if (dimPsi==1L) { hessian.FE.Psi[idxFE==i,] <- dThetadPsi.i[which.i] } else { hessian.FE.Psi[cbind(which(idxFE==i),indexPsi[which.i])] <- dThetadPsi.i[which.i] } } } else { fillHess <- i.fixed if (dimPsi > 0L) { ## dPsi <- colSums(dThetadPsi(m.Xit),na.rm=TRUE) ## hessian.FE.Psi[idxFE==i,] <- if (dimPsi==1L) sum(dPsi) else dPsi[order(indexPsi)] hessian.FE.Psi[idxFE==i,] <- .colSumsGrouped(dThetadPsi(m.Xit), indexPsi) } } ## fill pars$d-related entries for (j in seq_len(dimd)) { # will not be run if dimd==0 didd <- deriv2HHH(dTheta_l = m.Xit, dTheta_k = dmudd[[j]], dTheta_lk = if (comp.i == 2) dmudd[[j]] * Xit else 0) didd[isNA] <- 0 hessian.FE.d[idxFE==i,j] <- if (unitSpecific.i) { colSums(didd,na.rm=TRUE)[which.i] } else sum(didd) if (random.i) hessian.d.RE[j,idxRE==i] <- colSums(didd %m% Z.i) } ## fill other (non-psi, non-d) entries (only upper triangle, j >= i!) for(j in i:nGroups){ comp.j <- term["offsetComp",j][[1]] Xjt <- term["terms",j][[1]] # either 1 or a matrix with values if(is.matrix(Xjt)){ Xjt <- Xjt[subset,,drop=FALSE] } # if param i and j do not belong to the same component, d(i)d(j)=0 m.Xit.Xjt <- if (comp.i != comp.j) 0 else m.Xit * Xjt didj <- deriv2HHH(dTheta_l = m.Xit, dTheta_k = mean.comp[[comp.j]]*Xjt, dTheta_lk = m.Xit.Xjt) didj[isNA]<-0 random.j <- term["random",j][[1]] unitSpecific.j <- term["unitSpecific",j][[1]] which.j <- term["which",j][[1]] fillHess() } } ######################################################### ## fill lower triangle of hessians and combine them ######################################################## hessian <- rbind(cbind(hessian.FE.FE,hessian.FE.d,hessian.FE.Psi,hessian.FE.RE), cbind(matrix(0,dimd,dimFE),hessian.d.d,hessian.d.Psi,hessian.d.RE), cbind(matrix(0,dimPsi,dimFE+dimd),hessian.Psi.RE), cbind(matrix(0,dimRE,dimFE+dimd+dimPsi),hessian.RE.RE)) hessian[lower.tri(hessian)] <- 0 # CAR blocks in hessian.RE.RE were fully filled diagHessian <- diag(hessian) fisher <- -(hessian + t(hessian)) diag(fisher) <- -diagHessian return(fisher) } fisher <- computeFisher(mu[c("epi.own","epi.neighbours","endemic")]) ## add penalty for random effects pen <- matrix(0, length(theta), length(theta)) Fpen <- if(dimRE > 0){ thetaIdxRE <- seq.int(to=length(theta), length.out=dimRE) pen[thetaIdxRE,thetaIdxRE] <- Sigma.inv fisher + pen } else fisher ## Done if(attributes){ attr(Fpen, "fisher") <- fisher attr(Fpen, "pen") <- pen } Fpen } ################################################# sqrtOf1pr2 <- function(r){ sqrt(1+r^2) } getSigmai <- function(sd, # vector of length dim with log-stdev's correlation, # vector of length dim with correlation # parameters, 0-length if uncorrelated dim ){ if(dim==0) return(NULL) Sigma.i <- if (length(correlation) == 0L) diag(exp(2*sd), dim) else { D <- diag(exp(sd), dim) L <- diag(nrow=dim) L[2,1:2] <- c(correlation[1],1)/sqrtOf1pr2(correlation[1]) if (dim==3) { L[3,] <- c(correlation[2:3],1)/sqrtOf1pr2(correlation[2]) L[3,2:3] <- L[3,2:3]/sqrtOf1pr2(correlation[3]) } D %*% tcrossprod(L) %*% D # ~75% quicker than D %*% L %*% t(L) %*% D } return(Sigma.i) } getSigmaiInv <- function(sd, # vector of length dim with log-stdev's correlation, # vector of length dim with correlation # parameters, 0-length if uncorrelated dim ){ if(dim==0) return(NULL) Sigma.i.inv <- if (length(correlation) == 0L) diag(exp(-2*sd), dim) else { r <- correlation Dinv <- diag(exp(-sd), dim) L <- diag(nrow=dim) L[2,1:2] <- c(-r[1],sqrtOf1pr2(r[1])) if(dim==3){ L[3,1] <- r[1]*r[3]-r[2]*sqrtOf1pr2(r[3]) L[3,2] <- -L[2,2]*r[3] L[3,3] <- sqrtOf1pr2(r[2])*sqrtOf1pr2(r[3]) } Dinv %*% crossprod(L) %*% Dinv # ~75% quicker than Dinv %*% t(L) %*% L %*% Dinv } return(Sigma.i.inv) } #* allow blockdiagonal matrix blockdiag(A,B), with A=kronecker product, B=diagonal matrix? getSigmaInv <- function(sd, correlation, dimSigma, dimBlocks, SigmaInvi=NULL){ if(is.null(SigmaInvi)){ SigmaInvi <- getSigmaiInv(sd,correlation,dimSigma) } if(length(unique(dimBlocks))==1){ # kronecker product formulation possible kronecker(SigmaInvi,diag(nrow=dimBlocks[1])) # the result is a symmetric matrix if SigmaInvi is symmetric } else { # kronecker product not possible -> correlation=0 diag(rep.int(diag(SigmaInvi),dimBlocks)) } } getSigma <- function(sd, correlation, dimSigma, dimBlocks, Sigmai=NULL){ if(is.null(Sigmai)){ Sigmai <- getSigmai(sd,correlation,dimSigma) } if(length(unique(dimBlocks))==1){ # kronecker product formulation possible kronecker(Sigmai,diag(nrow=dimBlocks[1])) # the result is a symmetric matrix if Sigmai is symmetric } else { # kronecker product not possible -> correlation=0 diag(rep.int(diag(Sigmai),dimBlocks)) } } ## Approximate marginal likelihood for variance components ## Parameter and model unpacking at the beginning (up to the ###...-line) is ## identical in marScore() and marFisher() marLogLik <- function(sd.corr, theta, model, fisher.unpen=NULL, verbose=FALSE){ dimSigma <- model$nSigma if(dimSigma == 0){ return(-Inf) } if(anyNA(sd.corr)) stop("NAs in variance parameters.", ADVICEONERROR) dimVar <- model$nVar dimCorr <- model$nCorr sd <- head(sd.corr,dimVar) corr <- tail(sd.corr,dimCorr) pars <- splitParams(theta,model) randomEffects <- pars$random dimRE <- model$nRE dimBlocks <- model$rankRE[model$rankRE>0] Sigma.inv <- getSigmaInv(sd, corr, dimVar, dimBlocks) # if not given, calculate unpenalized part of fisher info if(is.null(fisher.unpen)){ fisher.unpen <- attr(penFisher(theta, sd.corr, model,attributes=TRUE), "fisher") } # add penalty to fisher fisher <- fisher.unpen thetaIdxRE <- seq.int(to=length(theta), length.out=dimRE) fisher[thetaIdxRE,thetaIdxRE] <- fisher[thetaIdxRE,thetaIdxRE] + Sigma.inv ############################################################ # penalized part of likelihood # compute -0.5*log(|Sigma|) - 0.5*RE' %*% Sigma.inv %*% RE # where -0.5*log(|Sigma|) = -dim(RE_i)*[Sum(sd_i) -0.5*log(1+corr_i^2)] ##lpen <- -0.5*(t(randomEffects)%*%Sigma.inv%*%randomEffects) ## the following implementation takes ~85% less computing time ! lpen <- -0.5 * c(crossprod(randomEffects, Sigma.inv) %*% randomEffects) loglik.pen <- sum(-dimBlocks*sd) + lpen if(dimCorr >0){ loglik.pen <- loglik.pen + 0.5*dimBlocks[1]*sum(log(1+corr^2)) } ## approximate marginal likelihood logdetfisher <- determinant(fisher,logarithm=TRUE)$modulus lmarg <- loglik.pen -0.5*c(logdetfisher) return(lmarg) } marScore <- function(sd.corr, theta, model, fisher.unpen=NULL, verbose=FALSE){ dimSigma <- model$nSigma if(dimSigma == 0){ return(numeric(0L)) } if(anyNA(sd.corr)) stop("NAs in variance parameters.", ADVICEONERROR) dimVar <- model$nVar dimCorr <- model$nCorr sd <- head(sd.corr,dimVar) corr <- tail(sd.corr,dimCorr) pars <- splitParams(theta,model) randomEffects <- pars$random dimRE <- model$nRE dimBlocks <- model$rankRE[model$rankRE>0] Sigma.inv <- getSigmaInv(sd, corr, dimVar, dimBlocks) # if not given, calculate unpenalized part of fisher info if(is.null(fisher.unpen)){ fisher.unpen <- attr(penFisher(theta, sd.corr, model,attributes=TRUE), "fisher") } # add penalty to fisher fisher <- fisher.unpen thetaIdxRE <- seq.int(to=length(theta), length.out=dimRE) fisher[thetaIdxRE,thetaIdxRE] <- fisher[thetaIdxRE,thetaIdxRE] + Sigma.inv # inverse of penalized fisher info F.inv <- try(solve(fisher),silent=TRUE) if(inherits(F.inv,"try-error")){ if(verbose) cat(" WARNING (in marScore): penalized Fisher is singular!\n") #return(rep.int(0,dimSigma)) ## continuing with the generalized inverse often works, otherwise we would ## have to stop() here, because nlminb() cannot deal with NA's F.inv <- ginv(fisher) } F.inv.RE <- F.inv[thetaIdxRE,thetaIdxRE] ############################################################ ## compute marginal score and fisher for each variance component # initialize score and fisher info marg.score <- rep.int(NA_real_,dimSigma) ## specify functions for derivatives deriv1 <- switch(dimVar, dSigma1, dSigma2, dSigma3) d1Sigma <- deriv1(sd, corr) Sigmai.inv <- getSigmaiInv(sd, corr, dimVar) # derivation of log determinant # -.5*tr(Sigma^-1 %*% dSigma/ds) = -R (for sd.i) # = R*corr.i/(corr.i^2+1) (for corr.i) d1logDet <- c(-dimBlocks,dimBlocks[1]*corr/(corr^2+1)) # go through all variance parameters for(i in seq_len(dimSigma)){ dSi <- -Sigmai.inv %*% d1Sigma[,,i] %*% Sigmai.inv # CAVE: sign dS.i <- getSigma(dimSigma=dimVar,dimBlocks=dimBlocks,Sigmai=dSi) #dlpen.i <- -0.5* t(randomEffects) %*% dS.i %*% randomEffects # ~85% faster implementation using crossprod() avoiding "slow" t(): dlpen.i <- -0.5 * c(crossprod(randomEffects, dS.i) %*% randomEffects) #tr.d1logDetF <- sum(diag(F.inv.RE %*% dS.i)) tr.d1logDetF <- sum(F.inv.RE * dS.i) # since dS.i is symmetric #<- needs 1/100 (!) of the computation time of sum(diag(F.inv.RE %*% dS.i)) marg.score[i] <- d1logDet[i] + dlpen.i - 0.5 * tr.d1logDetF } return(marg.score) } marFisher <- function(sd.corr, theta, model, fisher.unpen=NULL, verbose=FALSE){ dimSigma <- model$nSigma if(dimSigma == 0){ return(matrix(numeric(0L),0L,0L)) } if(anyNA(sd.corr)) stop("NAs in variance parameters.", ADVICEONERROR) dimVar <- model$nVar dimCorr <- model$nCorr sd <- head(sd.corr,dimVar) corr <- tail(sd.corr,dimCorr) pars <- splitParams(theta,model) randomEffects <- pars$random dimRE <- model$nRE dimBlocks <- model$rankRE[model$rankRE>0] Sigma.inv <- getSigmaInv(sd, corr, dimVar, dimBlocks) # if not given, calculate unpenalized part of fisher info if(is.null(fisher.unpen)){ fisher.unpen <- attr(penFisher(theta, sd.corr, model,attributes=TRUE), "fisher") } # add penalty to fisher fisher <- fisher.unpen thetaIdxRE <- seq.int(to=length(theta), length.out=dimRE) fisher[thetaIdxRE,thetaIdxRE] <- fisher[thetaIdxRE,thetaIdxRE] + Sigma.inv # inverse of penalized fisher info F.inv <- try(solve(fisher),silent=TRUE) if(inherits(F.inv,"try-error")){ if(verbose) cat(" WARNING (in marFisher): penalized Fisher is singular!\n") #return(matrix(Inf,dimSigma,dimSigma)) ## continuing with the generalized inverse often works, otherwise we would ## have to stop() here, because nlminb() cannot deal with NA's F.inv <- ginv(fisher) } F.inv.RE <- F.inv[thetaIdxRE,thetaIdxRE] ## declare F.inv.RE as a symmetric matrix? ##F.inv.RE <- new("dsyMatrix", Dim = dim(F.inv.RE), x = c(F.inv.RE)) ## -> no, F.inv.RE %*% dS.i becomes actually slower (dS.i is a "sparseMatrix") ############################################################ marg.hesse <- matrix(NA_real_,dimSigma,dimSigma) ## specify functions for derivatives deriv1 <- switch(dimVar,dSigma1, dSigma2, dSigma3) deriv2 <- switch(dimVar,d2Sigma1, d2Sigma2, d2Sigma3) d1Sigma <- deriv1(sd, corr) d2Sigma <- deriv2(sd, corr, d1Sigma) Sigmai.inv <- getSigmaiInv(sd, corr, dimVar) # 2nd derivatives of log determinant d2logDet <- diag(c(rep.int(0,dimVar),-dimBlocks[1]*(corr^2-1)/(corr^2+1)^2),dimSigma) # function to convert dS.i and dS.j matrices to sparse matrix objects dS2sparse <- if (dimCorr > 0) function (x) { forceSymmetric(as(x, "sparseMatrix")) # dS.i & dS.j are symmetric } else function (x) { #as(x, "diagonalMatrix") new("ddiMatrix", Dim = dim(x), diag = "N", x = diag(x)) } # go through all variance parameters for(i in seq_len(dimSigma)){ # compute first derivative of the penalized Fisher info (-> of Sigma^-1) # with respect to the i-th element of Sigma (= kronecker prod. of Sigmai and identity matrix) # Harville Ch15, Eq. 8.15: (d/d i)S^-1 = - S^-1 * (d/d i) S * S^-1 SigmaiInv.d1i <- Sigmai.inv %*% d1Sigma[,,i] dSi <- -SigmaiInv.d1i %*% Sigmai.inv dS.i <- getSigma(dimSigma=dimVar,dimBlocks=dimBlocks,Sigmai=dSi) dS.i <- dS2sparse(dS.i) # compute second derivatives for(j in i:dimSigma){ # compute (d/d j) S^-1 SigmaiInv.d1j <- Sigmai.inv %*% d1Sigma[,,j] dSj <- -SigmaiInv.d1j %*% Sigmai.inv dS.j <- getSigma(dimSigma=dimVar,dimBlocks=dimBlocks,Sigmai=dSj) dS.j <- dS2sparse(dS.j) # compute (d/di dj) S^-1 #dS.ij <- getSigma(dimSigma=dimVar,dimBlocks=dimBlocks, # Sigmai=d2Sigma[[i]][,,j]) # compute second derivatives of Sigma^-1 (Harville Ch15, Eq 9.2) d2S <- (- Sigmai.inv %*% d2Sigma[[i]][,,j] + SigmaiInv.d1i %*% SigmaiInv.d1j + SigmaiInv.d1j %*% SigmaiInv.d1i) %*% Sigmai.inv dSij <- getSigma(dimSigma=dimVar,dimBlocks=dimBlocks,Sigmai=d2S) #d2lpen.i <- -0.5* t(randomEffects) %*% dSij %*% randomEffects # ~85% faster implementation using crossprod() avoiding "slow" t(): d2lpen.i <- -0.5 * c(crossprod(randomEffects, dSij) %*% randomEffects) # compute second derivative of log-determinant of penFisher mpart1 <- dS.j %*% F.inv.RE # 3 times as fast as the other way round mpart2 <- dS.i %*% F.inv.RE mpart <- mpart1 %*% mpart2 ## speed-ups: - tr(F.inv.RE %*% dSij) simply equals sum(F.inv.RE * dSij) ## - accelerate matrix product by sparse matrices dS.i and dS.j ## - use cyclic permutation of trace: ## tr(F.inv.RE %*% dS.j %*% F.inv.RE %*% dS.i) = ## tr(dS.j %*% F.inv.RE %*% dS.i %*% F.inv.RE) tr.d2logDetF <- -sum(Matrix::diag(mpart)) + sum(F.inv.RE * dSij) marg.hesse[i,j] <- marg.hesse[j,i] <- d2logDet[i,j] + d2lpen.i - 0.5 * tr.d2logDetF } } marg.Fisher <- as.matrix(-marg.hesse) return(marg.Fisher) } ## first and second derivatives of the covariance matrix dSigma1 <- function(sd,corr){ derivs <- array(2*exp(2*sd), c(1,1,1)) return(derivs) } #d1: result of dSigma1 d2Sigma1 <- function(sd,corr,d1){ return(list(dsd1=2*d1)) } dSigma2 <- function(sd,corr){ derivs <- array(0,c(2,2,3)) dSigma <- diag(2*exp(2*sd)) if(length(corr)>0){ dSigma[1,2] <- dSigma[2,1] <- exp(sum(sd[1:2]))*corr[1]/sqrtOf1pr2(corr[1]) # derivative of corr_1 derivs[2,1,3] <- derivs[1,2,3] <- exp(sum(sd[1:2]))/(sqrtOf1pr2(corr[1])^3) } derivs[,,1:2] <- dSigma # derivative of sd_1 derivs[2,2,1] <- 0 # derivative of sd_2 derivs[1,1,2] <- 0 return(derivs) } d2Sigma2 <- function(sd,corr, d1){ derivs <- array(0,c(2,2,3)) result <- list(dsd1=d1, dsd2=derivs, dcorr1=derivs) result$dsd1[1,1,1] <- 2*d1[1,1,1] result$dsd1[2,2,2] <- 0 result$dsd2[,,2:3]<- d1[,,2:3] result$dsd2[2,2,2] <- 2*d1[2,2,2] if(length(corr)>0){ result$dcorr1[2,1,3] <- result$dcorr1[1,2,3] <- -(3*corr[1]*exp(sum(sd[1:2])))/(sqrtOf1pr2(corr[1])^5) } return(result) } dSigma3 <- function(sd,corr){ derivs <- array(0,c(3,3,6)) dSigma <- diag(2*exp(2*sd)) # if(length(corr)>0){ dSigma[1,2] <- dSigma[2,1] <- exp(sum(sd[1:2]))*corr[1]/sqrtOf1pr2(corr[1]) # dSigma[1,3] <- dSigma[3,1] <- exp(sum(sd[c(1,3)]))*corr[2]/sqrtOf1pr2(corr[2]) # dSigma[2,3] <- dSigma[3,2] <- exp(sum(sd[c(2,3)]))*(corr[1]*corr[2]*sqrtOf1pr2(corr[3])+corr[3])/prod(sqrtOf1pr2(corr[1:3]))# # derivative of corr_1 derivs[2,1,4] <- derivs[1,2,4] <- exp(sum(sd[1:2]))/(sqrtOf1pr2(corr[1])^3) derivs[3,2,4] <- derivs[2,3,4] <-(exp(sum(sd[2:3]))*(corr[2]*sqrtOf1pr2(corr[3])-prod(corr[c(1,3)])))/ (prod(sqrtOf1pr2(corr[2:3]))*(sqrtOf1pr2(corr[1])^3))# # derivative of corr_2 derivs[3,1,5] <- derivs[1,3,5] <- exp(sum(sd[c(3,1)]))/(sqrtOf1pr2(corr[2])^3)# derivs[3,2,5] <- derivs[2,3,5] <- (exp(sum(sd[2:3]))*(corr[1]*sqrtOf1pr2(corr[3])-prod(corr[c(2,3)])))/ (prod(sqrtOf1pr2(corr[c(1,3)]))*(sqrtOf1pr2(corr[2])^3)) # # derivative of corr_3 derivs[3,2,6] <- derivs[2,3,6] <- exp(sum(sd[2:3]))/ (prod(sqrtOf1pr2(corr[c(1,2)]))*(sqrtOf1pr2(corr[3])^3)) } derivs[,,1:3] <- dSigma # derivative of sd_1 derivs[2:3,2:3,1] <- 0 # derivative of sd_2 derivs[1,c(1,3),2] <- derivs[3,c(1,3),2] <- 0 # derivative of sd_3 derivs[1:2,1:2,3] <- 0 return(derivs) } d2Sigma3 <- function(sd,corr, d1) { derivs <- array(0,c(3,3,6)) result <- list(dsd1=d1, dsd2=derivs, dsd3=derivs, dcorr1=derivs, dcorr2=derivs, dcorr3=derivs) result$dsd1[1,1,1] <- 2*d1[1,1,1] result$dsd1[2,2:3,2] <- result$dsd1[3,2,2] <- 0 result$dsd1[2:3,2:3,3] <- 0 # result$dsd2[,,2]<- d1[,,2] result$dsd2[2,2,2] <- 2*d1[2,2,2] result$dsd2[3,2,3] <- result$dsd2[2,3,3] <- d1[3,2,3]# result$dsd3[,,3]<- d1[,,3] result$dsd3[3,3,3] <- 2*d1[3,3,3]# if (length(corr)>0) { result$dsd1[2:3,2:3,4] <- 0 result$dsd1[2:3,2:3,5] <- 0 result$dsd1[,,6] <- 0 result$dsd2[,,c(4,6)] <- d1[,,c(4,6)] result$dsd2[3,2,5] <- result$dsd2[2,3,5] <- d1[3,2,5] result$dsd3[3,2,4] <- result$dsd3[2,3,4] <- d1[3,2,4] result$dsd3[,,c(5,6)] <- d1[,,c(5,6)] # derivative of corr_1 result$dcorr1[2,1,4] <- result$dcorr1[1,2,4] <- -(exp(sum(sd[1:2]))*3*corr[1])/(sqrtOf1pr2(corr[1])^5) # result$dcorr1[3,2,4] <- result$dcorr1[2,3,4] <- -(exp(sum(sd[2:3]))*(corr[1]*(3*corr[2]*sqrtOf1pr2(corr[3])-2*prod(corr[c(1,3)])) + corr[3]) )/ (prod(sqrtOf1pr2(corr[2:3]))*(sqrtOf1pr2(corr[1])^5)) # result$dcorr1[3,2,5] <- result$dcorr1[2,3,5] <- (exp(sum(sd[2:3]))*(sqrtOf1pr2(corr[3])+prod(corr[1:3])))/ (prod(sqrtOf1pr2(corr[c(1,2)])^3)*sqrtOf1pr2(corr[3])) result$dcorr1[3,2,6] <- result$dcorr1[2,3,6] <- -(exp(sum(sd[2:3]))*corr[1])/ (prod(sqrtOf1pr2(corr[c(1,3)])^3)*sqrtOf1pr2(corr[2])) # derivative of corr_2 result$dcorr2[3,1,5] <- result$dcorr2[1,3,5] <- -(exp(sum(sd[c(3,1)]))*3*corr[2])/(sqrtOf1pr2(corr[2])^5) result$dcorr2[3,2,5] <- result$dcorr2[2,3,5] <- -(exp(sum(sd[2:3]))*(corr[2]*(3*corr[1]*sqrtOf1pr2(corr[3])-2*prod(corr[c(2,3)])) + corr[3]) )/ (prod(sqrtOf1pr2(corr[c(1,3)]))*(sqrtOf1pr2(corr[2])^5)) result$dcorr2[3,2,6] <- result$dcorr2[2,3,6] <- -exp(sum(sd[2:3]))*corr[2] / # SM @ 14/05/13: formula fixed, marFisher() # and hhh4()$Sigma.cov[5,6] are now correct (prod(sqrtOf1pr2(corr[c(2,3)])^3)*sqrtOf1pr2(corr[1])) # derivative of corr_3 result$dcorr3[3,2,6] <- result$dcorr3[2,3,6] <- -(exp(sum(sd[2:3]))*3*corr[3])/ (prod(sqrtOf1pr2(corr[c(1,2)]))*sqrtOf1pr2(corr[3])^5) } return(result) } ### Various optimizers updateParams_nlminb <- function (start, ll, sc, fi, ..., control) { lower <- control[["lower"]]; control$lower <- NULL upper <- control[["upper"]]; control$upper <- NULL scale <- control[["scale"]]; control$scale <- NULL negll <- function (x, ...) -ll(x, ...) negsc <- function (x, ...) -sc(x, ...) ## run the optimization res <- nlminb(start, negll, gradient=negsc, hessian=fi, ..., scale=scale, control=control, lower=lower, upper=upper) if (any(is.finite(c(lower, upper)))) checkParBounds(res$par, lower, upper) ## Done list(par=res$par, ll=-res$objective, rel.tol=getRelDiff(res$par, start), convergence=res$convergence, message=res$message) } updateParams_nlm <- function (start, ll, sc, fi, ..., control) { ## objective function negllscfi <- function (x, ...) { negloglik <- -ll(x, ...) attr(negloglik, "gradient") <- -sc(x, ...) attr(negloglik, "hessian") <- fi(x, ...) negloglik } ## run the optimization res <- do.call("nlm", args=c(alist(p=start, f=negllscfi, ...), control)) ## Done list(par=setNames(res$estimate, names(start)), ll=-res$minimum, rel.tol=getRelDiff(res$estimate, start), convergence=as.numeric(res$code>2), message=res$message) ## nlm returns convergence status in $code, 1-2 indicate convergence, ## 3-5 indicate non-convergence } updateParams_optim <- function (start, ll, sc, fi, ..., control) { ## Note: "fi" is not used in optim method <- control[["method"]]; control$method <- NULL lower <- control[["lower"]]; control$lower <- NULL upper <- control[["upper"]]; control$upper <- NULL res <- optim(start, ll, sc, ..., # Note: control$fnscale is negative method=method, lower=lower, upper=upper, control=control) if (any(is.finite(c(lower, upper)))) checkParBounds(res$par, lower, upper) ## Done list(par=res$par, ll=res$value, rel.tol=getRelDiff(res$par, start), convergence=res$convergence, message=res$message) } ## Calculate relative parameter change criterion. ## We use a weaker criterion than the maximum relative parameter change ## max(abs(sd.corr.new/sd.corr - 1)) getRelDiff <- function (final, start) max(abs(final - start)) / max(abs(start)) checkParBounds <- function (par, lower, upper) { if (is.null(names(par))) names(par) <- seq_along(par) if (any(atl <- par <= lower)) cat(" WARNING: parameters reached lower bounds:", paste(names(par)[atl], par[atl], sep="=", collapse=", "), "\n") if (any(atu <- par >= upper)) cat(" WARNING: parameters reached upper bounds:", paste(names(par)[atu], par[atu], sep="=", collapse=", "), "\n") } ## default control arguments for updates defaultOptimControl <- function (method = "nlminb", lower = -Inf, upper = Inf, iter.max = NULL, verbose = 0) { if (is.null(iter.max)) iter.max <- 20 + 480*(method=="Nelder-Mead") lowVerbose <- verbose %in% 0:2 luOptimMethod <- method %in% c("Brent", "L-BFGS-B") defaults.nlminb <- list(iter.max=iter.max, scale=1, lower=lower, upper=upper, trace=if(lowVerbose) c(0,0,5)[verbose+1] else 1) defaults.nlm <- list(iterlim=iter.max, check.analyticals=FALSE, print.level=if(lowVerbose) c(0,0,1)[verbose+1] else 2) defaults.optim <- list(maxit=iter.max, fnscale=-1, trace=max(0,verbose-1), lower=if (luOptimMethod) lower else -Inf, upper=if (luOptimMethod) upper else Inf) switch(method, "nlm" = defaults.nlm, "nlminb" = defaults.nlminb, defaults.optim) } setOptimControl <- function (method, control, ...) { defaults <- defaultOptimControl(method, ...) cntrl <- modifyList(defaults, control) ## ensure fnscale < 0 (optim performs minimization) if (!is.null(cntrl$fnscale)) { # i.e., using optim() cntrl$method <- method # append method to control list if (cntrl$fnscale > 0) cntrl$fnscale <- -cntrl$fnscale } cntrl } ## fitHHH is the main workhorse where the iterative optimization is performed fitHHH <- function(theta, sd.corr, model, cntrl.stop=list(tol=1e-5, niter=100), cntrl.regression=list(method="nlminb"), cntrl.variance=list(method="nlminb"), verbose=0, shrinkage=FALSE) { dimFE.d.O <- model$nFE + model$nd + model$nOverdisp dimRE <- model$nRE getUpdater <- function (cntrl, start, ...) { method <- cntrl$method; cntrl$method <- NULL if (length(start) == 1 && method == "Nelder-Mead") { method <- "Brent" message("Switched optimizer from \"Nelder-Mead\" to \"Brent\"", " (dim(", deparse(substitute(start)), ")=1)") } list(paste("updateParams", if (method %in% c("nlminb", "nlm")) method else "optim", sep="_"), control = setOptimControl(method, cntrl, ...)) } ## ## artificial lower bound on intercepts of epidemic components ## reg.lower <- rep.int(-Inf, length(theta)) ## reg.lower[grep("^(ar|ne)\\.(1|ri)", model$namesFE)] <- -20 ## set optimizer for regression parameters updateRegressionControl <- getUpdater(cntrl.regression, theta, ## lower=reg.lower, iter.max=if(dimRE==0) 100, verbose=verbose+(dimRE==0)) updateRegression <- function (theta, sd.corr) do.call(updateRegressionControl[[1]], alist(theta, penLogLik, penScore, penFisher, sd.corr=sd.corr, model=model, control=updateRegressionControl[[2]])) ## set optimizer for variance parameters updateVarianceControl <- getUpdater(cntrl.variance, sd.corr, lower=-5, upper=5, verbose=verbose) updateVariance <- function (sd.corr, theta, fisher.unpen) do.call(updateVarianceControl[[1]], alist(sd.corr, marLogLik, marScore, marFisher, theta=theta, model=model, fisher.unpen=fisher.unpen, verbose=verbose>1, control=updateVarianceControl[[2]])) ## Let's go if (verbose>0) { if (verbose > 1) utils::timestamp() cat(if (dimRE == 0) "Optimization of regression parameters" else "Iterative optimization of regression & variance parameters", "\n", sep = "") } if (dimRE == 0) { # optimization of regression coefficients only parReg <- updateRegression(theta, sd.corr) theta <- parReg$par if ((convergence <- parReg$convergence) != 0 && !is.null(parReg$message)) cat("! Non-convergence message from optimizer:", parReg$message, "\n") } else { # swing between updateRegression & updateVariance convergence <- 99 i <- 0 while(convergence != 0 && (i < cntrl.stop$niter)){ i <- i+1 if (verbose>0) cat("\n") ## update regression coefficients parReg <- updateRegression(theta, sd.corr) theta <- parReg$par fisher.unpen <- attr(penFisher(theta, sd.corr, model, attributes=TRUE), "fisher") if(verbose>0) cat("Update of regression parameters: ", "max|x_0 - x_1| / max|x_0| =", parReg$rel.tol, "\n") if(parReg$convergence != 0) { if (!is.null(parReg$message)) cat("! Non-convergence message from optimizer:", parReg$message, "\n") cat("Update of regression coefficients in iteration ", i, " unreliable\n") } if(parReg$convergence > 20 && shrinkage){ cat("\n\n***************************************\nshrinkage", 0.1*theta[abs(theta)>10],"\n") theta[abs(theta)>10] <- 0.1*theta[abs(theta)>10] diag(fisher.unpen) <- diag(fisher.unpen)+1e-2 } ## update variance parameters parVar <- updateVariance(sd.corr, theta, fisher.unpen) if(verbose>0) cat("Update of variance parameters: max|x_0 - x_1| / max|x_0| =", parVar$rel.tol, "\n") if(parVar$convergence!=0) { if (!is.null(parVar$message)) cat("! Non-convergence message from optimizer:", parVar$message, "\n") cat("Update of variance parameters in iteration ", i, " unreliable\n") } sd.corr <- parVar$par ## overall convergence ? if( (parReg$rel.tol < cntrl.stop$tol) && (parVar$rel.tol < cntrl.stop$tol) && (parReg$convergence==0) && (parVar$convergence==0) ) convergence <- 0 ## exit loop if no more change in parameters (maybe false convergence) if (parReg$rel.tol == 0 && parVar$rel.tol == 0) break } } if(verbose > 0) { cat("\n", if (convergence==0) "Optimization converged" else "Optimization DID NOT CONVERGE", "\n", sep = "") if (verbose > 1) utils::timestamp() } ll <- penLogLik(theta, sd.corr, model) fisher <- penFisher(theta, sd.corr, model, attributes = TRUE) dimnames(fisher) <- list(names(theta), names(theta)) margll <- marLogLik(sd.corr, theta, model, attr(fisher, "fisher")) fisher.var <- marFisher(sd.corr, theta, model, attr(fisher, "fisher")) dimnames(fisher.var) <- list(names(sd.corr), names(sd.corr)) list(theta=theta, sd.corr=sd.corr, loglik=ll, margll=margll, fisher=fisher, fisherVar=fisher.var, convergence=convergence, dim=c(fixed=dimFE.d.O,random=dimRE)) } ## check analytical score functions and Fisher information for ## a given model (the result of interpretControl(control, stsObj)) ## and given parameters theta (regression par.) and sd.corr (variance par.). ## This is a wrapper around functionality of the numDeriv and maxLik packages. checkAnalyticals <- function (model, theta = model$initialTheta, sd.corr = model$initialSigma, methods = c("numDeriv","maxLik")) { cat("\nPenalized log-likelihood:\n") resCheckPen <- sapply(methods, function(derivMethod) { if (requireNamespace(derivMethod)) { do.call(paste("checkDerivatives", derivMethod, sep="."), args=alist(penLogLik, penScore, penFisher, theta, sd.corr=sd.corr, model=model)) } }, simplify=FALSE, USE.NAMES=TRUE) if (length(resCheckPen) == 1L) resCheckPen <- resCheckPen[[1L]] resCheckMar <- if (length(sd.corr) == 0L) list() else { cat("\nMarginal log-likelihood:\n") fisher.unpen <- attr(penFisher(theta, sd.corr, model, attributes=TRUE), "fisher") resCheckMar <- sapply(methods, function(derivMethod) { if (requireNamespace(derivMethod)) { do.call(paste("checkDerivatives", derivMethod, sep="."), args=alist(marLogLik, marScore, marFisher, sd.corr, theta=theta, model=model, fisher.unpen=fisher.unpen)) } }, simplify=FALSE, USE.NAMES=TRUE) if (length(resCheckMar) == 1L) resCheckMar[[1L]] else resCheckMar } list(pen = resCheckPen, mar = resCheckMar) } surveillance/R/epidataCS_animate.R0000644000176200001440000001516614426171115016640 0ustar liggesusers################################################################################ ### animate-method for "epidataCS" objects ### It respects the ani.options() "interval" and "nmax" of the animation ### package, and it is advisable to use it within saveHTML() or similar ### ### Copyright (C) 2009-2014 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## three types: ## time.spacing=NULL: sequential snapshots at all event times ## time.spacing=scalar: snapshots with given time step (and timer) ## time.spacing=NA: time step is determined such that "nmax" snapshots result animate.epidataCS <- function (object, interval = c(0,Inf), time.spacing = NULL, nmax = NULL, sleep = NULL, legend.opts = list(), timer.opts = list(), pch = 15:18, col.current = "red", col.I = "#C16E41", col.R = "#B3B3B3", col.influence = NULL, main = NULL, verbose = interactive(), ...) { stopifnot(is.numeric(interval), length(interval) == 2L) with.animation <- requireNamespace("animation", quietly = TRUE) if (is.null(sleep)) { sleep <- if (with.animation) animation::ani.options("interval") else 0.1 ## we cannot set this as default function argument, because we don't ## want to depend on package "animation" (surveillance only suggests it) } if (is.null(nmax)) { nmax <- if (with.animation) animation::ani.options("nmax") else Inf } s <- summary(object) removalTimes <- s$eventTimes + object$events$eps.t eventCoordsTypes <- cbind(s$eventCoords, type = s$eventTypes) pch <- rep_len(pch, s$nTypes) typeNames <- names(s$typeTable) multitype <- length(typeNames) > 1L # set default legend options doLegend <- if (is.list(legend.opts)) { if (is.null(legend.opts[["x"]])) legend.opts$x <- "topright" if (is.null(legend.opts$title)) legend.opts$title <- if (multitype) "type" else "state" if (is.null(legend.opts$legend)) { legend.opts$legend <- if (multitype) typeNames else c("infectious", if (!is.na(col.R)) "removed") } if (is.null(legend.opts$col)) { legend.opts$col <- if (multitype) col.current else c(col.I, if (!is.na(col.R)) col.R) } if (is.null(legend.opts$pch)) legend.opts$pch <- pch TRUE } else FALSE # set default timer options doTimer <- if (is.list(timer.opts)) { if (is.null(timer.opts[["x"]])) timer.opts$x <- "bottomright" if (is.null(timer.opts$title)) timer.opts$title <- "time" if (is.null(timer.opts$box.lty)) timer.opts$box.lty <- 0 if (is.null(timer.opts$adj)) timer.opts$adj <- c(0.5,0.5) if (is.null(timer.opts$inset)) timer.opts$inset <- 0.01 if (is.null(timer.opts$bg)) timer.opts$bg <- "white" TRUE } else FALSE # wrapper for 'points' with specific 'cex' for multiplicity multpoints <- function (tableCoordsTypes, col) { tableMult <- countunique(tableCoordsTypes) points(tableMult[,1:2,drop=FALSE], pch = pch[tableMult[,"type"]], col = col, cex = sqrt(1.5*tableMult[,"COUNT"]/pi) * par("cex")) } # functions returning if events are in status I or R at time t I <- function (t) s$eventTimes <= t & removalTimes >= t R <- function (t) removalTimes < t sequential <- is.null(time.spacing) # plot observed infections sequentially if (!sequential) stopifnot(length(time.spacing) == 1L) timeGrid <- if (sequential) unique(s$eventTimes) else { start <- max(s$timeRange[1], interval[1]) end <- min(interval[2], s$timeRange[2], max(removalTimes) + if (is.na(time.spacing)) 0 else time.spacing) if (is.na(time.spacing)) { if (!is.finite(nmax)) { stop("with 'time.spacing=NA', 'nmax' must be finite") } seq(from = start, to = end, length.out = nmax) } else { tps <- seq(from = start, to = end, by = time.spacing) if (length(tps) > nmax) { message("Generating only the first ", sQuote(if (with.animation) "ani.options(\"nmax\")" else "nmax"), " (=", nmax, ") snapshots") head(tps, nmax) } else tps } } .info <- format.info(timeGrid) timerformat <- paste0("%", .info[1], ".", .info[2], "f") # animate loopIndex <- if (!sequential) timeGrid else { idxs <- which(s$eventTimes >= interval[1] & s$eventTimes <= interval[2]) if (length(idxs) > nmax) { message("Generating only the first ", sQuote(if (with.animation) "ani.options(\"nmax\")" else "nmax"), " (=", nmax, ") events") head(idxs, nmax) } else idxs } told <- -Inf if (verbose) pb <- txtProgressBar(min=0, max=max(loopIndex), initial=0, style=3) for(it in loopIndex) { t <- if (sequential) s$eventTimes[it] else it infectious <- I(t) removed <- R(t) plot(object$W, asp = 1, ...) # hard-coded 'asp' avoids sp -> sf title(main = main) if (doLegend) do.call(legend, legend.opts) if (doTimer) { ttxt <- sprintf(timerformat, t) do.call(legend, c(list(legend = ttxt), timer.opts)) } if (!is.null(col.influence)) { iRids <- which(infectious) if (sequential) setdiff(iRids, it) for(j in iRids) { iR <- shift.owin(object$events@data$.influenceRegion[[j]], s$eventCoords[j,]) plot(iR, add = TRUE, col = col.influence, border = NA) } } rTable <- eventCoordsTypes[removed,,drop=FALSE] if (nrow(rTable) > 0L) multpoints(rTable, col = col.R) iTable <- eventCoordsTypes[infectious,,drop=FALSE] if (nrow(iTable) > 0L) multpoints(iTable, col = col.I) infectiousNew <- if (sequential) it else infectious & !I(told) iTableNew <- eventCoordsTypes[infectiousNew,,drop=FALSE] if (nrow(iTableNew) > 0L) multpoints(iTableNew, col = col.current) told <- t if (verbose) setTxtProgressBar(pb, it) if (dev.interactive()) Sys.sleep(sleep) } if (verbose) close(pb) ## if (dev.interactive()) ## message("Note: use facilities of the \"animation\" package, e.g.,\n", ## " saveHTML() to view the animation in a web browser.") invisible(NULL) } surveillance/R/stsplot_spacetime.R0000644000176200001440000001311214426171115017034 0ustar liggesusers################################################################################ ### Old implementation of (animated) maps of an sts-object ### ### Copyright (C) 2007-2013 Michael Hoehle, 2016 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ stsplot_spacetime <- function( x, type, legend=NULL, opts.col=NULL, labels=TRUE, wait.ms=250, cex.lab=0.7, verbose=FALSE, dev.printer=NULL, ...) { #Extract the mappoly if (length(x@map) == 0) stop("The sts object has an empty map.") map <- x@map maplim <- list(x=bbox(map)[1,],y=bbox(map)[2,]) #Check colnames, otherwise no need to continue if (is.null(colnames(x@observed))) stop("The sts observed slot does not have any colnames to match with the shapefile.") #Check for legend options if (is.null(legend)) { legend <- list(dx=0.4,dy=0.04,x=maplim$x[1],y=maplim$y[1],once=TRUE) } #Extract the data o <- x@observed alarm <- x@alarm #Formula is of type "observed ~ 1|unit" (i.e. no time) aggregate <- type[[3]][[3]] == "unit" if (aggregate) { .Deprecated("stsplot_space") o <- t(as.matrix(apply(o,MARGIN=2,sum))) alarm <- t(as.matrix(apply(alarm,MARGIN=2,sum)))>0 } else { .Deprecated("animate") } #Number of time points maxt <- dim(o)[1] #Process dev.printer options if (is.list(dev.printer)) { dev.printer <- modifyList( list(device = png, extension = ".png", width = 640, height = 480, name = "Rplot"), dev.printer) #filename format (padding with zeroes) fnfmt <- paste0("%s-%0", nchar(maxt), "i%s") } #Get color vector opts.col_default <- list(ncolors=length(o), use.color=TRUE) gyr <- do.call(".hcl.colors", if (is.list(opts.col)) modifyList(opts.col_default, opts.col) else opts.col_default) theCut <- cut(o, length(gyr)) #Cut into specified number of colors o.cut <- matrix(as.numeric(theCut),nrow=nrow(o),ncol=ncol(o)) o.col <- matrix(gyr[o.cut],ncol=ncol(o.cut)) o.col[is.na(o.col)] <- gray(1) dimnames(o.col) <- dimnames(o) #Sort the o according to the names in the map region.id <- row.names(map) o.col.id <- dimnames(o.col)[[2]] #Make the columns of o as in the map object o.col <- o.col[,pmatch(region.id,o.col.id),drop=FALSE] alarm.col <- alarm[,pmatch(region.id,o.col.id),drop=FALSE] #Screen processing screen.matrix <- matrix(c(0,1,0,1,0,1,0.8,1),2,4,byrow=TRUE) split.screen(screen.matrix) #Loop over all time slices for (t in 1:maxt) { #Status information if (verbose) { cat(paste("Processing slice",t,"of",maxt,"\n")) } #Clean screen (title area) screen(n=2) par(bg=gray(1)) erase.screen() par(bg="transparent") #Plot the map on screen 1 screen(n=1) plot(map,col=o.col[t,],xlab="",ylab="",...) #Indicate alarms as shaded overlays if (length(alarmIdx <- which(alarm.col[t,] > 0))) { plot(map[alarmIdx,], density=15, add=TRUE) } if (labels) #getSpPPolygonsLabptSlots is deprecated. Use coordinates method insteas text(coordinates(map), labels=as.character(region.id), cex.lab=cex.lab) if (!aggregate) { title(paste(t,"/",maxt,sep="")) } #In case a legend is requested if (is.list(legend) && !(legend$once & t>1) | (t==1)) { add.legend(legend, maplim, list(col=gyr, min=min(o), max=max(o), trans=identity)) } #Is writing to files requested? if (is.list(dev.printer)) { #Create filename fileName <- sprintf(fnfmt, dev.printer$name, t, dev.printer$extension) cat("Creating ",fileName,"\n") #Save the current device using dev.print if (inherits(try( dev.print(dev.printer$device, file=fileName, width=dev.printer$width, height=dev.printer$height) ), "try-error")) { warning("disabling dev.print()", immediate. = TRUE) dev.printer <- NULL } } wait(wait.ms) } close.screen(all.screens = TRUE) } ####################### ### auxiliary functions ####################### ### wait a specific amount of milliseconds (via "while" and "proc.time") wait <- function (wait.ms) # number of milliseconds to wait { #Initialize start.time <- proc.time()[3]*1000 ellapsed <- proc.time()[3]*1000 - start.time #Loop as long as required. while (ellapsed < wait.ms) { ellapsed <- proc.time()[3]*1000 - start.time } } ### add the color key add.legend <- function(legend, maplim, theColors) { #Preproc dy <- diff(maplim$y) * legend$dy dx <- diff(maplim$x) * legend$dx #Add legend -- i.e. a slider xlu <- xlo <- legend$x xru <- xro <- xlu + dx yru <- ylu <- legend$y yro <- ylo <- yru + dy step <- (xru - xlu)/length(theColors$col) for (i in 0:(length(theColors$col) - 1)) { polygon(c(xlo + step * i, xlo + step * (i + 1), xlu + step * (i + 1), xlu + step * i), c(ylo, yro, yru, ylu), col = theColors$col[i + 1], border = theColors$col[i + 1]) } #Write info about min and max on the slider. black <- grey(0) lines(c(xlo, xro, xru, xlu, xlo), c(ylo, yro, yru, ylu, ylo), col = black) #Transformation function for data values, e.g., exp or identity trans <- theColors$trans text(xlu, ylu - 0.5*dy, formatC(trans(theColors$min)), cex = 1, col = black,adj=c(0,1)) text(xru, yru - 0.5*dy, formatC(trans(theColors$max)), cex = 1, col = black,adj=c(1,1)) } surveillance/R/linelist2sts.R0000644000176200001440000000546314615162374015752 0ustar liggesusers###################################################################### # Takes a data frame with dates of individual # cases and create an aggregated sts time series object for these # data with aggregation occurring at the desired scale. # # Parameters: # linelist - a data frame containing individual case information, one per line # dateCol - a character string denoting the column name in case containing # the relevant date variable to aggregate # aggregate.by - aggregation block length given as a string compatible with # seq.Date -- see \link{seq.Date} for further details. # # Author: Michael Hoehle # Date LaMo: 04 Jan 2014 ###################################################################### linelist2sts <- function(linelist,dateCol,aggregate.by=c("1 day", "1 week", "7 day", "1 week", "1 month", "3 month", "1 year"),dRange=NULL, epochInPeriodStr=switch(aggregate.by, "1 day"="1","1 week"="%u", "1 month"="%d","3 month"="%q","1 year"="%j"), startYearFormat=switch(aggregate.by,"1 day"="%Y","7 day"="%G","1 week"="%G","1 month"="%Y","3 month"="%Y","1 year"="%Y"), startEpochFormat=switch(aggregate.by,"1 day"="%j","7 day"="%V","1 week"="%V","1 month"="%m","3 month"="%Q","1 year"="1") ) { ##Check aggregate.by argument aggregate.by <- match.arg(aggregate.by, c("1 day", "1 week", "7 day", "1 week", "1 month", "3 month", "1 year")) #If no dRange let it be the range of the dateCol if (is.null(dRange)) { dRange <- range(linelist[,dateCol],na.rm=TRUE) } if (aggregate.by != "1 day") { ##Move dates back to first of each epoch unit dRange <- dRange - as.numeric(formatDate(dRange,epochInPeriodStr)) + 1 } #Add exactly one time step to dRange to ensure that cut #contains the last level as well. We use 'seq' to ensure #that even weeks/days with no data are present in the factor. maxDate <- seq(max(dRange),length.out=2,by=aggregate.by)[-1] dates <- seq(min(dRange), maxDate, by=aggregate.by) #Make a table containing the specific number of cases. Note that this #needs to occur using a cut statement lvl <- cut(linelist[,dateCol], breaks=dates,right=FALSE) observed <- table(lvl) epoch <- as.Date(names(observed)) #Translate "by" to freq string freq <- switch(aggregate.by,"1 day"=365,"7 day"=52,"1 week"=52,"1 month"=12,"3 month"=4,"1 year"=1) startYear <- as.numeric(formatDate(min(dates),startYearFormat)) startEpoch <- as.numeric(formatDate(min(dates),startEpochFormat)) observed <- matrix(observed,ncol=1) #Create S4 object sts <- new("sts",epoch=as.numeric(epoch),observed=observed, alarm=0*observed, epochAsDate=TRUE,freq=freq,start=c(startYear,startEpoch)) #Return return(sts) } surveillance/R/hhh4_oneStepAhead.R0000644000176200001440000002527214201042047016547 0ustar liggesusers################################################################################ ### Compute one-step-ahead predictions at a series of time points ### ### Copyright (C) 2011-2012 Michaela Paul, 2012-2018,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ oneStepAhead <- function(result, # hhh4-object (i.e. a hhh4 model fit) tp, # scalar: one-step-ahead predictions for time # points (tp+1):nrow(stsObj), or tp=c(from, to) type = c("rolling", "first", "final"), which.start = c("current", "final"), #if type="rolling" keep.estimates = FALSE, verbose = type != "final", # verbose-1 is used # for sequentially refitted hhh4 models cores = 1) # if which.start="final", the predictions # can be computed in parallel { stopifnot(inherits(result, "hhh4")) type <- match.arg(type) if (type == "rolling" && !is.list(which.start)) { ## new in surveillance 1.10-0: if 'which.start' is a list, it is ## directly used as the 'start' argument for hhh4() in all time steps which.start <- match.arg(which.start) if (cores > 1 && which.start == "current") stop("no parallelization for 'type=\"rolling\"' ", "if 'which.start=\"current\"'") } ## get model terms model <- result[["terms"]] if (is.null(model)) model <- result$terms <- terms(result) nTime <- model$nTime # = nrow(result$stsObj) nUnits <- model$nUnits # = ncol(result$stsObj) dimPsi <- model$nOverdisp withPsi <- dimPsi > 0L psiIdx <- model$nFE + model$nd + seq_len(dimPsi) ## check that tp is within the time period of the data stopifnot(length(tp) %in% 1:2, tp >= 0) tpRange <- c(model$subset[1L], nTime-1L) # supported range if (any(tp > tpRange[2L]) || (type != "final" && any(tp < tpRange[1L]))) { stop("the time range defined by 'tp' must be a subset of ", tpRange[1L], ":", tpRange[2L]) } if (length(tp) == 1) { tp <- c(tp, max(model$subset)-1L) # historical default if (tp[1L] > tp[2L]) # probably unintended stop("'tp' larger than the default upper limit (", tp[2L], ")") } tps <- tp[1L]:tp[2L] # this function actually works if tp[1] > tp[2] ntps <- length(tps) observed <- model$response[tps+1,,drop=FALSE] rownames(observed) <- tps+1 ## adjust verbosity for model refitting verbose <- as.integer(verbose) result$control$verbose <- max(0, verbose - (ntps>1)) if (type != "rolling" && verbose > 1L) verbose <- 1L do_pb <- verbose == 1L && interactive() ## initial fit fit <- if (type == "first") { if (verbose) cat("\nRefitting model at first time point t =", tps[1L], "...\n") update.hhh4(result, subset.upper = tps[1L], use.estimates = TRUE, keep.terms = TRUE) # need "model" -> $terms } else result if (!fit$convergence) stop("initial fit did not converge") ## result templates (named and filled with NA's) pred <- matrix(NA_real_, nrow=ntps, ncol=nUnits, dimnames=list(tps+1, colnames(observed))) if (withPsi) psi <- matrix(NA_real_, nrow=ntps, ncol=dimPsi, dimnames=list(tps, names(model$initialTheta)[psiIdx])) if (keep.estimates) { coefficients <- matrix(NA_real_, nrow=ntps, ncol=length(model$initialTheta), dimnames=list(tps, names(model$initialTheta))) Sigma.orig <- matrix(NA_real_, nrow=ntps, ncol=model$nSigma, dimnames=list(tps, names(result$Sigma.orig))) logliks <- matrix(NA_real_, nrow=ntps, ncol=2L, dimnames=list(tps, c("loglikelihood", "margll"))) } ## extract predictions and stuff for specific tp from fit getPreds <- function (fit, tp) { coefs <- unname(fit$coefficients) c(list(pred = as.vector( meanHHH(coefs, fit$terms, subset=tp+1L, total.only=TRUE))), if (withPsi) list(psi = coefs[psiIdx]), if (keep.estimates) list( coefficients=coefs, Sigma.orig=unname(fit$Sigma.orig), logliks=c(fit$loglikelihood, fit$margll)) ) } ## compute the predictions and save ## pred, psi, coefficients, Sigma.orig, and logliks if (cores > 1L) { ## return value template (unnamed NA vectors) resTemplate <- lapply(getPreds(fit, tps[1L]), "is.na<-", TRUE) ## run parallel res <- parallel::mclapply(tps, function (tp) { if (verbose) cat("One-step-ahead prediction @ t =", tp, "...\n") if (type == "rolling") { # update fit fit <- update.hhh4(result, subset.upper=tp, use.estimates=TRUE, start=if (is.list(which.start)) which.start, verbose=FALSE, # chaotic in parallel keep.terms=TRUE) # need "model" -> $terms if (!fit$convergence) { cat("WARNING: No convergence @ t =", tp, "!\n") return(resTemplate) } } getPreds(fit, tp) }, mc.preschedule=TRUE, mc.cores=cores) ## gather results .extractFromList <- function (what) t(vapply(res, "[[", resTemplate[[what]], what, USE.NAMES=FALSE)) pred[] <- .extractFromList("pred") if (withPsi) psi[] <- .extractFromList("psi") if (keep.estimates) { coefficients[] <- .extractFromList("coefficients") Sigma.orig[] <- .extractFromList("Sigma.orig") logliks[] <- .extractFromList("logliks") } } else { ## sequential one-step ahead predictions if (do_pb) pb <- txtProgressBar(min=0, max=ntps, initial=0, style=3) for(i in seq_along(tps)) { if (do_pb) setTxtProgressBar(pb, i) else if (verbose) { cat("One-step-ahead prediction @ t =", tps[i], "...\n") } if (type == "rolling") { # update fit fit.old <- fit # backup start <- if (is.list(which.start)) { which.start } else if (which.start == "current") hhh4coef2start(fit) ## else NULL fit <- update.hhh4(result, subset.upper=tps[i], start=start, # takes precedence use.estimates=TRUE, keep.terms=TRUE) # need "model" -> $terms if (!fit$convergence) { if (do_pb) cat("\n") cat("WARNING: No convergence @ t =", tps[i], "!\n") ## FIXME: do a grid search ? fit <- fit.old next } } res <- getPreds(fit, tps[i]) ## gather results pred[i,] <- res$pred if (withPsi) psi[i,] <- res$psi if (keep.estimates) { coefficients[i,] <- res$coefficients Sigma.orig[i,] <- res$Sigma.orig logliks[i,] <- res$logliks } } if (do_pb) close(pb) } ## with shared overdispersion parameters we need to expand psi to ncol(pred) if (dimPsi > 1L && dimPsi != nUnits) { psi <- psi[,model$indexPsi,drop=FALSE] } ## done res <- c(list(pred = pred, observed = observed, psi = if (withPsi) psi else NULL, allConverged = all(!is.na(pred))), if (keep.estimates) list(coefficients = coefficients, Sigma.orig = Sigma.orig, logliks = logliks) ) class(res) <- "oneStepAhead" res } ## extract estimated overdispersion in dnbinom() parametrization, as full matrix psi2size.oneStepAhead <- function (object) { if (is.null(object$psi)) # Poisson model return(NULL) size <- exp(object$psi) # a matrix with 1 or nUnit columns ## ensure that we always have a full 'size' matrix with nUnit columns dimpred <- dim(object$pred) if (ncol(size) != dimpred[2L]) { # => ncol(size)=1, unit-independent psi size <- rep.int(size, dimpred[2L]) dim(size) <- dimpred } dimnames(size) <- list(rownames(object$psi), colnames(object$pred)) size } ## quantiles of the one-step-ahead forecasts quantile.oneStepAhead <- function (x, probs = c(2.5, 10, 50, 90, 97.5)/100, ...) { stopifnot(is.vector(probs, mode = "numeric"), probs >= 0, probs <= 1, (np <- length(probs)) > 0) names(probs) <- paste(format(100*probs, trim=TRUE, scientific=FALSE, digits=3), "%") size <- psi2size.oneStepAhead(x) qs <- if (is.null(size)) { vapply(X = probs, FUN = qpois, FUN.VALUE = x$pred, lambda = x$pred) } else { vapply(X = probs, FUN = qnbinom, FUN.VALUE = x$pred, mu = x$pred, size = size) } ## one tp, one unit -> qs is a vector of length np ## otherwise, 'qs' has dimensions ntps x nUnit x np ## if nUnit==1, we return an ntps x np matrix, otherwise an array if (is.vector(qs)) { qs <- t(qs) rownames(qs) <- rownames(x$pred) qs } else if (dim(qs)[2L] == 1L) { matrix(qs, dim(qs)[1L], dim(qs)[3L], dimnames = dimnames(qs)[c(1L,3L)]) } else qs } ## confidence intervals for one-step-ahead predictions confint.oneStepAhead <- function (object, parm, level = 0.95, ...) { quantile.oneStepAhead(object, (1+c(-1,1)*level)/2, ...) } ## simple plot of one-step-ahead forecasts plot.oneStepAhead <- function (x, unit = 1, probs = 1:99/100, start = NULL, means.args = NULL, ...) { stopifnot(length(unit) == 1, length(probs) > 1) ## select unit obs <- x$observed[,unit] ms <- x$pred[,unit] qs <- quantile.oneStepAhead(x, probs = probs) if (!is.matrix(qs)) # multi-unit predictions qs <- matrix(qs[,unit,], dim(qs)[1L], dim(qs)[3L], dimnames = dimnames(qs)[c(1L,3L)]) ## produce fanplot if (is.null(start)) start <- as.integer(rownames(qs)[1L]) fanplot(quantiles = qs, probs = probs, means = ms, observed = obs, start = start, means.args = means.args, ...) } surveillance/R/twinstim_siaf.R0000644000176200001440000003177414615162374016177 0ustar liggesusers################################################################################ ### Spatial interaction functions for twinstim's epidemic component. ### Specific implementations are in separate files (e.g.: Gaussian, power law). ### ### Copyright (C) 2009-2015,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ##################### ### "Constructor" ### ##################### siaf <- function (f, F, Fcircle, effRange, deriv, Deriv, simulate, npars, validpars = NULL) { npars <- as.integer(npars) if (length(npars) != 1 || npars < 0L) { stop("'siaf$npars' must be a single nonnegative number") } f <- .checknargs3(f, "siaf$f") F <- if (missing(F) || is.null(F)) siaf.fallback.F else { F <- match.fun(F) if (length(formals(F)) < 4L) stop("siaf$F() must accept >=4 arguments ", "(polydomain, f, pars, type)") F } haspars <- npars > 0L if (!haspars || missing(deriv)) deriv <- NULL if (!is.null(deriv)) deriv <- .checknargs3(deriv, "siaf$deriv") if (missing(effRange)) effRange <- NULL if (missing(Fcircle) || is.null(Fcircle)) { Fcircle <- NULL if (!is.null(effRange)) { message("'siaf$effRange' only works in conjunction with 'siaf$Fcircle'") effRange <- NULL } } if (!is.null(Fcircle)) Fcircle <- .checknargs3(Fcircle, "siaf$Fcircle") if (!is.null(effRange)) { effRange <- match.fun(effRange) if (length(formals(effRange)) < 1L) { stop("the 'siaf$effRange' function must accept a parameter vector") } } Deriv <- if (is.null(deriv)) NULL else if (missing(Deriv) || is.null(Deriv)) siaf.fallback.Deriv else { Deriv <- match.fun(Deriv) if (length(formals(Deriv)) < 4L) stop("siaf$Deriv() must accept >=4 arguments ", "(polydomain, deriv, pars, type)") Deriv } ## Check if simulation function has proper format if (missing(simulate)) simulate <- NULL if (!is.null(simulate)) { simulate <- .checknargs3(simulate, "siaf$simulate") if (length(formals(simulate)) == 3L) formals(simulate) <- c(formals(simulate), alist(ub=)) } ## Check if the validpars are of correct form validpars <- if (!haspars || is.null(validpars)) NULL else match.fun(validpars) ## Done, return result. list(f = f, F = F, Fcircle = Fcircle, effRange = effRange, deriv = deriv, Deriv = Deriv, simulate = simulate, npars = npars, validpars = validpars) } ########################################## ### Constant spatial interaction/dispersal ########################################## siaf.constant <- function () { res <- list( ## use explicit quote()ing to prevent notes from codetools::checkUsage f = as.function(c(alist(s=, pars=NULL, types=NULL), quote(rep.int(1, length(s)/2))), ##<- nrow() would take extra time in standardGeneric() envir = .GlobalEnv), ## integration over polydomains (F) is handled specially in twinstim Fcircle = as.function(c(alist(r=, pars=NULL, type=NULL), quote(pi*r^2)), envir = .GlobalEnv), simulate = as.function(c(alist(n=, pars=NULL, type=NULL, ub=), quote(runifdisc(n, ub))), envir = getNamespace("surveillance")), npars = 0L ) attr(res, "constant") <- TRUE res } ########################################## ### Naive defaults for the siaf primitives ########################################## ## numerical integration of f over a polygonal domain (single "owin" and type) siaf.fallback.F <- function (polydomain, f, pars, type, method = "SV", ...) { if (identical(method,"SV")) { polyCub.SV(polyregion = polydomain, f = f, pars, type, alpha = 0, ...) # since max at origin } else { polyCub(polyregion = polydomain, f = f, method = method, pars, type, ...) } } ## numerical integration of f over a circular domain getFcircle <- function (siaf, control.F = list()) { if (is.null(siaf$Fcircle)) { function (r, pars, type) { disc <- discpoly(c(0,0), r, npoly = 64, class = "owin") do.call(siaf$F, c(alist(disc, siaf$f, pars, type), control.F)) } } else { siaf$Fcircle } } ## numerical integration of deriv over a polygonal domain siaf.fallback.Deriv <- function (polydomain, deriv, pars, type, method = "SV", ...) { deriv1 <- function (s, paridx) deriv(s, pars, type)[,paridx,drop=TRUE] intderiv1 <- function (paridx) polyCub(polyregion = polydomain, f = deriv1, method = method, paridx = paridx, ...) vapply(X = seq_along(pars), FUN = intderiv1, FUN.VALUE = 0, USE.NAMES = FALSE) } #################################### ### Simulation via polar coordinates (used, e.g., for siaf.powerlaw) #################################### ## Simulate from an isotropic spatial interaction function ## f_{2D}(s) \propto f(||s||), ||s|| <= ub. ## within a maximum distance 'ub' via polar coordinates and the inverse ## transformation method: ## p_{2D}(r,theta) = r * f_{2D}(x,y) \propto r*f(r) ## => angle theta ~ U(0,2*pi) and sample r according to r*f(r) siaf.simulatePC <- function (intrfr) # e.g., intrfr.powerlaw { as.function(c(alist(n=, siafpars=, type=, ub=), substitute({ ## Note: in simEpidataCS, simulation is always bounded to eps.s and to ## the largest extend of W, thus, 'ub' is finite stopifnot(is.finite(ub)) ## Normalizing constant of r*f(r) on [0;ub] normconst <- intrfr(ub, siafpars, type) ## => cumulative distribution function CDF <- function (q) intrfr(q, siafpars, type) / normconst ## For inversion sampling, we need the quantile function CDF^-1 ## However, this is not available in closed form, so we use uniroot ## (which requires a finite upper bound) QF <- function (p) uniroot(function(q) CDF(q)-p, lower=0, upper=ub)$root ## Now sample r as QF(U), where U ~ U(0,1) r <- vapply(X=runif(n), FUN=QF, FUN.VALUE=0, USE.NAMES=FALSE) ## Check simulation of r via kernel estimate: ## plot(density(r, from=0, to=ub)); curve(p(x)/normconst,add=TRUE,col=2) ## now rotate each point by a random angle to cover all directions theta <- runif(n, 0, 2*pi) r * cbind(cos(theta), sin(theta)) })), envir=parent.frame()) } ################################################ ### Check F, Fcircle, deriv, Deriv, and simulate ################################################ checksiaf <- function (siaf, pargrid, type = 1, tolerance = 1e-5, method = "SV", ...) { stopifnot(is.list(siaf), is.numeric(pargrid), !is.na(pargrid), length(pargrid) > 0) pargrid <- as.matrix(pargrid) stopifnot(siaf$npars == ncol(pargrid)) ## Check 'F' if (!is.null(siaf$F)) { cat("'F' vs. cubature using method = \"", method ,"\" ... ", sep="") comp.F <- checksiaf.F(siaf$F, siaf$f, pargrid, type=type, method=method, ...) cat(attr(comp.F, "all.equal") <- all.equal(comp.F[,1], comp.F[,2], check.attributes=FALSE, tolerance=tolerance), "\n") } ## Check 'Fcircle' if (!is.null(siaf$Fcircle)) { cat("'Fcircle' vs. cubature using method = \"",method,"\" ... ", sep="") comp.Fcircle <- checksiaf.Fcircle(siaf$Fcircle, siaf$f, pargrid, type=type, method=method, ...) cat(attr(comp.Fcircle, "all.equal") <- all.equal(comp.Fcircle[,1], comp.Fcircle[,2], check.attributes=FALSE, tolerance=tolerance), "\n") } ## Check 'deriv' if (!is.null(siaf$deriv)) { cat("'deriv' vs. numerical derivative ... ") if (requireNamespace("maxLik", quietly=TRUE)) { maxRelDiffs.deriv <- checksiaf.deriv(siaf$deriv, siaf$f, pargrid, type=type) cat(attr(maxRelDiffs.deriv, "all.equal") <- if (any(maxRelDiffs.deriv > tolerance)) paste("maxRelDiff =", max(maxRelDiffs.deriv)) else TRUE, "\n") } else cat("Failed: need package", sQuote("maxLik"), "\n") } ## Check 'Deriv' if (!is.null(siaf$Deriv)) { cat("'Deriv' vs. cubature using method = \"", method ,"\" ... ", sep="") comp.Deriv <- checksiaf.Deriv(siaf$Deriv, siaf$deriv, pargrid, type=type, method=method, ...) if (siaf$npars > 1) cat("\n") attr(comp.Deriv, "all.equal") <- sapply(seq_len(siaf$npars), function (j) { if (siaf$npars > 1) cat("\tsiaf parameter ", j, ": ", sep="") ae <- all.equal(comp.Deriv[,j], comp.Deriv[,siaf$npars+j], check.attributes=FALSE, tolerance=tolerance) cat(ae, "\n") ae }) } ## Check 'simulate' if (interactive() && !is.null(siaf$simulate)) { cat("Simulating ... ") checksiaf.simulate(siaf$simulate, siaf$f, pargrid[1,], type=type) cat("(-> check the plot)\n") } ## invisibly return check results invisible(mget(c("comp.F", "comp.Fcircle", "maxRelDiffs.deriv", "comp.Deriv"), ifnotfound=list(NULL), inherits=FALSE)) } checksiaf.F <- function (F, f, pargrid, type=1, method="SV", ...) { res <- t(apply(pargrid, 1, function (pars) { given <- F(LETTERR, f, pars, type) num <- siaf.fallback.F(polydomain = LETTERR, f = f, pars = pars, type = type, method = method, ...) c(given, num) })) colnames(res) <- c("F", method) res } checksiaf.Fcircle <- function (Fcircle, f, pargrid, type=1, rs=c(1,5,10,50,100), method="SV", ...) { pargrid <- pargrid[rep(1:nrow(pargrid), each=length(rs)),,drop=FALSE] rpargrid <- cbind(rs, pargrid, deparse.level=0) res <- t(apply(rpargrid, 1, function (x) { disc <- discpoly(c(0,0), x[1L], npoly = 128, class = "owin") c(ana = Fcircle(x[1L], x[-1L], type), num = siaf.fallback.F(polydomain = disc, f = f, pars = x[-1L], type = type, method = method, ...)) })) res } checksiaf.deriv <- function (deriv, f, pargrid, type=1, rmax=100) { rgrid <- seq(-rmax,rmax,length.out=21) / sqrt(2) rgrid <- rgrid[rgrid != 0] # some siafs are always 1 at (0,0) (deriv=0) sgrid <- cbind(rgrid, rgrid) apply(pargrid, 1, function (pars) { maxLik::compareDerivatives(f, deriv, t0=pars, s=sgrid, print=FALSE)$maxRelDiffGrad ## Note: numDeriv::grad() would only allow one location s at a time }) } checksiaf.Deriv <- function (Deriv, deriv, pargrid, type=1, method="SV", ...) { res <- t(apply(pargrid, 1, function (pars) { given <- Deriv(LETTERR, deriv, pars, type) num <- siaf.fallback.Deriv(polydomain = LETTERR, deriv = deriv, pars = pars, type = type, method = method, ...) c(given, num) })) paridxs <- seq_len(ncol(pargrid)) colnames(res) <- c(paste("Deriv",paridxs,sep="."), paste(method,paridxs,sep=".")) res } checksiaf.simulate <- function (simulate, f, pars, type=1, B=3000, ub=10, plot=interactive()) { ## Simulate B points on the disc with radius 'ub' simpoints <- simulate(B, pars, type=type, ub=ub) if (plot) { ## Graphical check in 2D opar <- par(mfrow=c(2,1), mar=c(4,3,2,1)); on.exit(par(opar)) plot(as.im.function(function(x,y,...) f(cbind(x,y), pars, type), W=discpoly(c(0,0), ub, class="owin")), axes=TRUE, main="Simulation from the spatial kernel") points(simpoints, cex=0.2) kdens <- kde2d(simpoints[,1], simpoints[,2], n=100) contour(kdens, add=TRUE, col=2, lwd=2, labcex=1.5, vfont=c("sans serif", "bold")) ##x11(); image(kdens, add=TRUE) ## Graphical check of distance distribution truehist(sqrt(rowSums(simpoints^2)), xlab="Distance") rfr <- function (r) r*f(cbind(r,0), pars, type) rfrnorm <- integrate(rfr, 0, ub)$value do.call("curve", list(quote(rfr(x)/rfrnorm), add=TRUE, col=2, lwd=2)) ##<- use do.call-construct to prevent codetools::checkUsage from noting "x" } ## invisibly return simulated points invisible(simpoints) } surveillance/R/twinstim_intensity.R0000644000176200001440000003051514426171115017264 0ustar liggesusers################################################################################ ### Plot the temporal or spatial evolution of the estimated intensity ### ### Copyright (C) 2012-2015, 2022 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ intensity.twinstim <- function (x, aggregate = c("time", "space"), types = 1:nrow(x$qmatrix), tiles, tiles.idcol = NULL) { modelenv <- environment(x) ## check arguments if (is.null(modelenv)) stop("'x' is missing the model environment\n", " -- re-fit or update() with 'model=TRUE'") aggregate <- match.arg(aggregate) stopifnot(is.vector(types, mode="numeric"), types %in% seq_len(modelenv$nTypes), !anyDuplicated(types)) ## remove (big) x object from current evaluation environment qmatrix <- x$qmatrix # not part of modelenv force(types) # evaluate types before rm(x) rm(x) # don't need this anymore ##thisenv <- environment() ##parent.env(thisenv) <- modelenv # objects of modelenv become visible ## Instead of the above, we do cheap and nasty model unpacking! ## safer than the parent.env<- hack (R manual: "extremely dangerous"), and ## cleaner than running code inside with(modelenv,...) since assignments ## then would take place in modelenv, which would produce garbage t0 <- modelenv$t0 T <- modelenv$T histIntervals <- modelenv$histIntervals eventTimes <- modelenv$eventTimes eventCoords <- modelenv$eventCoords eventTypes <- modelenv$eventTypes removalTimes <- modelenv$removalTimes gridTiles <- modelenv$gridTiles gridBlocks <- modelenv$gridBlocks ds <- modelenv$ds tiaf <- modelenv$tiaf tiafpars <- modelenv$tiafpars eps.s <- modelenv$eps.s siaf <- modelenv$siaf siafpars <- modelenv$siafpars ## endemic component on the spatial or temporal grid hInt <- if (modelenv$hash) { eta <- drop(modelenv$mmhGrid %*% modelenv$beta) if (!is.null(modelenv$offsetGrid)) eta <- modelenv$offsetGrid + eta expeta <- exp(unname(eta)) .beta0 <- rep_len(if (modelenv$nbeta0==0L) 0 else modelenv$beta0, modelenv$nTypes) fact <- sum(exp(.beta0[types])) if (aggregate == "time") { # int over W and types by BLOCK fact * c(tapply(expeta * modelenv$ds, gridBlocks, sum, simplify = TRUE)) } else { # int over T and types by tile fact * c(tapply(expeta * modelenv$dt, gridTiles, sum, simplify = TRUE)) } } else { ## the endemic intensity is 0 ## but a non-endemic "twinstim" holds no information on 'stgrid': ## 'gridBlocks' and 'gridTiles', respectively, are undefined NULL } ## endemic component as a function of time or location hIntFUN <- if (modelenv$hash) { if (aggregate == "time") { function (tp) { stopifnot(isScalar(tp)) if (tp == t0) { hInt[1L] } else { starts <- histIntervals$start idx <- match(TRUE, c(starts,T) >= tp) - 1L if (identical(idx, 0L)) { # tp <= t0 NA_real_ } else { # idx is NA if tp > T block <- histIntervals$BLOCK[idx] hInt[as.character(block)] } } } } else { if (!is.null(tiles.idcol)) { stopifnot(is(tiles, "SpatialPolygonsDataFrame")) row.names(tiles) <- tiles@data[[tiles.idcol]] } tileLevels <- levels(gridTiles) tiles <- check_tiles(tiles, tileLevels, areas.stgrid = ds[seq_along(tileLevels)], keep.data = FALSE) # drop data for over-method tilesIDs <- row.names(tiles) # = sapply(tiles@polygons, slot, "ID") function (xy) { # works with a whole coordinate matrix points <- SpatialPoints(xy, proj4string=tiles@proj4string) polygonidxOfPoints <- over(points, tiles) tilesOfPoints <- tilesIDs[polygonidxOfPoints] hInt[tilesOfPoints] # index by name } } } else function (...) 0 ## epidemic component eInt <- if (modelenv$hase) { qSum_types <- rowSums(qmatrix[,types,drop=FALSE])[eventTypes] fact <- qSum_types * modelenv$gammapred if (aggregate == "time") { # as a function of time (int over W & types) factS <- fact * modelenv$siafInt function (tp) { stopifnot(isScalar(tp)) tdiff <- tp - eventTimes infectivity <- qSum_types > 0 & (tdiff > 0) & (removalTimes >= tp) if (any(infectivity)) { gsources <- tiaf$g(tdiff[infectivity], tiafpars, eventTypes[infectivity]) intWj <- factS[infectivity] * gsources sum(intWj) } else 0 } } else { # as a function of location (int over time and types) factT <- fact * modelenv$tiafInt nEvents <- nrow(eventCoords) function (xy) { stopifnot(is.vector(xy, mode="numeric"), length(xy) == 2L) point <- matrix(xy, nrow=nEvents, ncol=2L, byrow=TRUE) sdiff <- point - eventCoords proximity <- qSum_types > 0 & .rowSums(sdiff^2, nEvents, 2L) <= eps.s^2 if (any(proximity)) { fsources <- siaf$f(sdiff[proximity,,drop=FALSE], siafpars, eventTypes[proximity]) intTj <- factT[proximity] * fsources sum(intTj) } else 0 } } } else function (...) 0 ## return component functions list(hGrid = hInt, hFUN = hIntFUN, eFUN = eInt, aggregate = aggregate, types = types) } intensityplot.twinstim <- function (x, which = c("epidemic proportion", "endemic proportion", "total intensity"), aggregate, types, tiles, tiles.idcol, # arguments of intensity.twinstim; # defaults are set below plot = TRUE, add = FALSE, tgrid = 101, rug.opts = list(), sgrid = 128, polygons.args = list(), points.args = list(), cex.fun = sqrt, ...) { which <- match.arg(which) ## set up desired intensities cl <- match.call() cl <- cl[c(1L, match(names(formals(intensity.twinstim)), names(cl), 0L))] cl[[1]] <- as.name("intensity.twinstim") components <- eval(cl, envir = parent.frame()) aggregate <- components$aggregate types <- components$types ## define function to plot FUN <- function (tmp) {} names(formals(FUN)) <- if (aggregate == "time") "times" else "coords" body1 <- if (aggregate == "time") expression( hGrid <- vapply(times, components$hFUN, 0, USE.NAMES=FALSE), eGrid <- vapply(times, components$eFUN, 0, USE.NAMES=FALSE) ) else expression( hGrid <- unname(components$hFUN(coords)), # takes whole coord matrix eGrid <- apply(coords, 1, components$eFUN) ) body2 <- switch(which, "epidemic proportion" = expression(eGrid / (hGrid + eGrid)), "endemic proportion" = expression(hGrid / (hGrid + eGrid)), "total intensity" = expression(hGrid + eGrid)) body(FUN) <- as.call(c(as.name("{"), c(body1, body2))) if (!plot) return(FUN) ## plot the FUN modelenv <- environment(x) dotargs <- list(...) nms <- names(dotargs) if (aggregate == "time") { ## set up grid of x-values (time points where 'which' will be evaluated) tgrid <- if (isScalar(tgrid)) { seq(modelenv$t0, modelenv$T, length.out=tgrid) } else { stopifnot(is.vector(tgrid, mode="numeric")) sort(tgrid) } ## calculate 'which' on tgrid yvals <- FUN(tgrid) ## plot it if(! "xlab" %in% nms) dotargs$xlab <- "time" if(! "ylab" %in% nms) dotargs$ylab <- which if(! "type" %in% nms) dotargs$type <- "l" if(! "ylim" %in% nms) dotargs$ylim <- { if (which == "total intensity") c(0,max(yvals)) else c(0,1) } do.call(if (add) "lines" else "plot", args=c(alist(x=tgrid, y=yvals), dotargs)) if (is.list(rug.opts)) { if (is.null(rug.opts$ticksize)) rug.opts$ticksize <- 0.02 if (is.null(rug.opts$quiet)) rug.opts$quiet <- TRUE eventTimes.types <- modelenv$eventTimes[modelenv$eventTypes %in% types] do.call("rug", args = c(alist(x=eventTimes.types), rug.opts)) } invisible(FUN) } else { tiles <- as(tiles, "SpatialPolygons") # remove potential data for over() ## set up grid of coordinates where 'which' will be evaluated if (isScalar(sgrid)) { sgrid <- makeGrid(tiles, n = sgrid) } sgrid <- as(sgrid, "SpatialPixels") ## only select grid points inside W (tiles) sgridTileIdx <- over(sgrid, tiles) sgrid <- sgrid[!is.na(sgridTileIdx),] ## calculate 'which' on sgrid yvals <- FUN(coordinates(sgrid)) sgridy <- SpatialPixelsDataFrame(sgrid, data=data.frame(yvals=yvals), proj4string=tiles@proj4string) ## define sp.layout lobjs <- list() if (is.list(polygons.args)) { nms.polygons <- names(polygons.args) if(! "col" %in% nms.polygons) polygons.args$col <- "darkgrey" lobjs <- c(lobjs, list(c(list("sp.polygons", tiles, first=FALSE), polygons.args))) } if (is.list(points.args)) { eventCoords.types <- modelenv$eventCoords[modelenv$eventTypes %in% types,,drop=FALSE] ## eventCoords as Spatial object with duplicates counted and removed eventCoords.types <- SpatialPoints(eventCoords.types, proj4string = tiles@proj4string, bbox = tiles@bbox) eventCoords.types <- SpatialPointsDataFrame(eventCoords.types, data.frame(mult = multiplicity.Spatial(eventCoords.types))) eventCoords.types <- eventCoords.types[!duplicated(coordinates(eventCoords.types)),] points.args <- modifyList(list(pch=1, cex=0.5), points.args) pointcex <- cex.fun(eventCoords.types$mult) pointcex <- pointcex * points.args$cex points.args$cex <- NULL lobjs <- c(lobjs, list(c(list("sp.points", eventCoords.types, first=FALSE, cex=pointcex), points.args))) } if ("sp.layout" %in% nms) { if (!is.list(dotargs$sp.layout[[1]])) { # let sp.layout be a list of lists dotargs$sp.layout <- list(dotargs$sp.layout) } lobjs <- c(lobjs, dotargs$sp.layout) dotargs$sp.layout <- NULL } ## plotit if (add) message("'add'ing is not possible with 'aggregate=\"space\"'") if (! "xlim" %in% nms) dotargs$xlim <- bbox(tiles)[1,] if (! "ylim" %in% nms) dotargs$ylim <- bbox(tiles)[2,] if (! "aspect" %in% nms) dotargs$aspect <- "iso" # always projected if (! "scales" %in% nms) dotargs$scales <- list(draw = TRUE) do.call("spplot", args=c(alist(sgridy, zcol="yvals", sp.layout=lobjs, checkEmptyRC=FALSE), dotargs)) } } ## set default arguments for intensityplot.twinstim from intensity.twinstim formals(intensityplot.twinstim)[names(formals(intensity.twinstim))] <- formals(intensity.twinstim) surveillance/R/hhh4_W.R0000644000176200001440000002477114430705133014426 0ustar liggesusers################################################################################ ### Helper functions for neighbourhood weight matrices in hhh4() ### ### Copyright (C) 2012-2016,2020,2022 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ checkNeighbourhood <- function (neighbourhood) { ## setValidity() in sts.R only guarantees correct 'dim' and 'dimnames' ## we also assert numeric or logical matrix with non-NA entries stopifnot(is.matrix(neighbourhood), nrow(neighbourhood) == ncol(neighbourhood), is.numeric(neighbourhood) | is.logical(neighbourhood), is.finite(neighbourhood)) invisible(TRUE) } ### calculate the weighted sum of counts of adjacent (or all other) regions ### i.e. the nTime x nUnit matrix with elements (ti): sum_j w_jit * y_j(t-lag) ## W is either a nUnits x nUnits matrix of time-constant weights w_ji ## or a nUnits x nUnits x nTime array of time-varying weights w_jit ## Note that a missing value in any unit at t-lag gives NA at t, ## even if w_jit = 0 for that unit (e.g., if own past is missing) weightedSumNE <- function (observed, weights, lag) { dimY <- dim(observed) nTime <- dimY[1L] nUnits <- dimY[2L] if (length(dim(weights)) == 2L) { # fast track for time-constant weights rbind(matrix(NA_real_, lag, nUnits), observed[seq_len(nTime-lag),,drop=FALSE] %*% weights) } else { tYlagged <- t(observed[seq_len(nTime-lag),,drop=FALSE]) apply(weights[,,(lag+1L):nTime,drop=FALSE], 2L, function (wi) ## wi and tYlagged are matrices of size nUnits x (nTime-lag) c(rep(NA_real_, lag), .colSums(tYlagged * wi, nUnits, nTime-lag))) } } ### normalize weight matrix such that each row sums to 1 (at each time point) normalizeW <- function (W) { dimW <- dim(W) if (length(dimW) == 2L) { W / .rowSums(W, dimW[1L], dimW[2L]) } else { # time-varying weights res <- apply(W, 3L, normalizeW) dim(res) <- dimW res } } ### scale and/or normalize a weight matrix/array scaleNEweights.default <- function (weights, scale = NULL, normalize = FALSE) { if (!is.null(scale)) weights <- scale * weights if (normalize) weights <- normalizeW(weights) weights } ## update parametric weights functions w, dw, d2w scaleNEweights.list <- function (weights, scale = NULL, normalize = FALSE) { if (is.null(scale) && !normalize) return(weights) if (normalize) { dprod <- function (u, v, du, dv) du * v + u * dv dfrac <- function (u, v, du, dv) (du * v - u * dv) / v^2 w <- function (...) scaleNEweights.default(weights$w(...), scale, TRUE) dw <- function (...) { W <- scaleNEweights.default(weights$w(...), scale) dW <- clapply(X = weights$dw(...), # matrix or list thereof FUN = scaleNEweights.default, scale = scale) # always returns a list dimW <- dim(W) normW <- .rowSums(W, dimW[1L], dimW[2L]) normdW <- lapply(X = dW, FUN = .rowSums, m = dimW[1L], n = dimW[2L]) mapply(FUN = dfrac, du = dW, dv = normdW, MoreArgs = list(u = W, v = normW), SIMPLIFY = FALSE, USE.NAMES = FALSE) } ## for d2w() we need all the stuff from dw() -> substitute d2w <- as.function(c(alist(...=), substitute({ dWnorm <- DWBODY d2W <- clapply(X = weights$d2w(...), # matrix or list thereof FUN = scaleNEweights.default, scale = scale) # always returns a list normd2W <- lapply(X = d2W, FUN = .rowSums, m = dimW[1L], n = dimW[2L]) ## order of d2w is upper triangle BY ROW dimd <- length(dW) ri <- rep.int(seq_len(dimd), rep.int(dimd, dimd)) # row index ci <- rep.int(seq_len(dimd), dimd) # column index uppertri <- ci >= ri mapply(FUN = function (k, l, d2W, normd2W) { dfrac(dW[[k]], normW, d2W, normdW[[l]]) - dprod(W/normW, normdW[[k]]/normW, dWnorm[[l]], dfrac(normdW[[k]], normW, normd2W, normdW[[l]])) }, k = ri[uppertri], l = ci[uppertri], d2W = d2W, normd2W = normd2W, SIMPLIFY = FALSE, USE.NAMES = FALSE) }, list(DWBODY = body(dw))))) } else { w <- function (...) scaleNEweights.default(weights$w(...), scale) dw <- function (...) clapply(X = weights$dw(...), FUN = scaleNEweights.default, scale = scale) d2w <- function (...) clapply(X = weights$d2w(...), FUN = scaleNEweights.default, scale = scale) } ## return list with updated functions list(w = w, dw = dw, d2w = d2w, initial = weights$initial) } ################################## ### check ne$weights specification ################################## ### checks for a fixed matrix/array checkWeightsArray <- function (W, nUnits, nTime, name = deparse(substitute(W)), check0diag = FALSE, islands = FALSE) { if (!is.array(W) || !(length(dim(W)) %in% 2:3)) stop("'", name, "' must return a matrix or 3-dim array") if (any(dim(W)[1:2] != nUnits) || isTRUE(dim(W)[3] != nTime)) stop("'", name, "' must conform to dimensions ", nUnits, " x ", nUnits, " (x ", nTime, ")") if (anyNA(W)) { if (islands) # normalization of parametric weights yields division by 0 warning("neighbourhood structure contains islands") stop("missing values in '", name, "' are not allowed") } if (check0diag) { diags <- if (is.matrix(W)) diag(W) else apply(W, 3, diag) if (any(diags != 0)) warning("'", name, "' has nonzeros on the diagonal", if (!is.matrix(W)) "s") } } ### check parametric weights specification consisting of a list of: ## - three functions: w, dw, and d2w ## - a vector of initial parameter values checkWeightsFUN <- function (object) { fnames <- paste0(c("","d","d2"), "w") if (any(!sapply(object[fnames], is.function))) stop("parametric weights require functions ", paste0("'", fnames, "'", collapse=", ")) if (any(!sapply(object[fnames], function(FUN) length(formals(FUN)) >= 3L))) stop("parametric weights functions must accept (not necessarily use)", "\n at least 3 arguments (parameter vector, ", "neighbourhood order matrix, data)") if (!is.vector(object$initial, mode="numeric") || length(object$initial) == 0L) stop("parametric weights require initial parameter values") TRUE } ### entry function for checks in hhh4() checkWeights <- function (weights, nUnits, nTime, nbmat, data, # only used for parametric weights check0diag = FALSE) { name <- deparse(substitute(weights)) # "control$ne$weights" ## check specification testweights <- if (is.array(weights)) weights else { if (is.list(weights) && checkWeightsFUN(weights) && checkNeighbourhood(nbmat)) { if (all(nbmat %in% 0:1)) warning("'", deparse(substitute(nbmat)), "' is binary (should contain", " general neighbourhood orders)") weights$w(weights$initial, nbmat, data) } else { stop("'", name, "' must be a matrix/array or a list of functions") } } ## apply matrix/array checks if (is.list(weights)) { # parametric weights if (length(dim(testweights)) > 2L) warning("time-varying parametric weights are not fully supported") checkWeightsArray(testweights, nUnits, nTime, name = paste0(name, "$w"), check0diag = check0diag, islands = any(.rowSums(nbmat, nUnits, nUnits) == 0)) dim.d <- length(weights$initial) dw <- weights$dw(weights$initial, nbmat, data) d2w <- weights$d2w(weights$initial, nbmat, data) if (dim.d == 1L && !is.list(dw) && !is.list(d2w)) { checkWeightsArray(dw, nUnits, nTime, name=paste0(name, "$dw")) checkWeightsArray(d2w, nUnits, nTime, name=paste0(name, "$d2w")) } else { if (!is.list(dw) || length(dw) != dim.d) stop("'", name, "$dw' must return a list (of matrices/arrays)", " of length ", dim.d) if (!is.list(d2w) || length(d2w) != dim.d*(dim.d+1)/2) stop("'", name, "$d2w' must return a list (of matrices/arrays)", " of length ", dim.d*(dim.d+1)/2) lapply(dw, checkWeightsArray, nUnits, nTime, name=paste0(name, "$dw[[i]]")) lapply(d2w, checkWeightsArray, nUnits, nTime, name=paste0(name, "$d2w[[i]]")) } } else checkWeightsArray(testweights, nUnits, nTime, name = name, check0diag = check0diag) ## Done invisible(TRUE) } ############################################# ### Utility functions for fitted hhh4-objects ############################################# ### extract the (final) weight matrix/array from a fitted hhh4 object getNEweights <- function (object, pars = coefW(object), scale = ne$scale, normalize = ne$normalize) { ne <- object$control$ne weights <- if (is.list(ne$weights)) { # parametric weights nd <- length(ne$weights$initial) if (length(pars) != nd) stop("'pars' must be of length ", nd) ne$weights$w(pars, neighbourhood(object$stsObj), object$control$data) } else { # NULL or fixed weight structure ne$weights } if (is.null(normalize)) normalize <- FALSE # backward compatibility < 1.9-0 scaleNEweights.default(weights, scale, normalize) } ### extract parameters of neighbourhood weights from hhh4-object or coef vector coefW <- function (object) { coefs <- if (inherits(object, "hhh4")) object$coefficients else object coefW <- coefs[grep("^neweights", names(coefs))] names(coefW) <- sub("^neweights\\.", "", names(coefW)) coefW } surveillance/R/twinstim_epitest.R0000644000176200001440000002627214426171115016720 0ustar liggesusers################################################################################ ### Monte Carlo Permutation Test for Space-Time Interaction in "twinstim" ### ### Copyright (C) 2015-2016,2018,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ epitest <- function (model, data, tiles, method = "time", B = 199, eps.s = NULL, eps.t = NULL, fixed = NULL, verbose = TRUE, compress = FALSE, ...) { ## check input stopifnot(inherits(model, "twinstim"), inherits(data, "epidataCS"), model$converged, isScalar(B), B >= 1) B <- as.integer(B) method <- match.arg(method, choices = c("LRT", "simulate", "time", "space")) # eval(formals(permute.epidataCS)$what) if (model$npars["q"] == 0L) { stop("no epidemic component in 'model'") } if (.epilink(model) == "log") { warning("boundary issues with epidemic log-link; ", "refit with epilink=\"identity\"", immediate. = TRUE) } if (isTRUE(fixed)) { fixed <- setdiff(grep("^e\\.", names(coef(model)), value = TRUE), "e.(Intercept)") } else { stopifnot(is.null(fixed) || is.character(fixed)) } t0 <- model$timeRange[1L] # will not permute events before t0 T <- model$timeRange[2L] ## auxiliary function to compute the LRT statistic lrt <- function (m0, m1) { l0 <- m0$loglik l1 <- m1$loglik c(l0 = l0, l1 = l1, D = 2 * (l1 - l0), converged = isTRUE(m1$converged) && isTRUE(m0$converged)) } ## observed test statistic m0 <- update.twinstim(model, data = data, epidemic = ~0, siaf = NULL, tiaf = NULL, control.siaf = NULL, model = method == "simulate", cumCIF = FALSE, cores = 1, verbose = FALSE, optim.args = list(fixed = fixed, control = list(trace = 0))) if (!isTRUE(m0$converged)) { stop("endemic-only model did not converge") } LRT <- lrt(m0 = m0, m1 = model) STATISTIC_D <- structure(LRT["D"], l0 = LRT[["l0"]], l1 = LRT[["l1"]]) STATISTIC_R0 <- c("simpleR0" = simpleR0(model, eps.s = eps.s, eps.t = eps.t)) ## LRT p-value (CAVE: invalid for the default log-link models) DF <- length(coef(model)) - length(coef(m0)) # number of epidemic parameters PVAL_LRT <- pchisq(as.vector(STATISTIC_D), # drop attributes df = DF, lower.tail = FALSE) ## result template res <- list( method = "Likelihood Ratio Test for Space-Time Interaction", data.name = paste0(deparse(substitute(data)), "\ntwinstim: ", deparse(substitute(model))), statistic = STATISTIC_D, parameter = c("df" = DF), p.value = PVAL_LRT ) class(res) <- c("epitest", "htest") if (method == "LRT") { ## we are done return(res) } ## otherwise: determine the null distribution via permutation or simulation res$method <- if (method == "simulate") { paste("Test for Space-Time Interaction (based on", B, "endemic simulations)") } else { "Monte Carlo Permutation Test for Space-Time Interaction" } if (model$npars["q"] > 1L) { warning("epidemic covariate effects might not be identifiable for null data", immediate. = TRUE) } if (!is.finite(STATISTIC_R0)) { warning("observed 'simpleR0' test statistic is infinite; ", "maybe specify 'eps.*'", # or use D-based p.value ... immediate. = TRUE) } ## define a function which generates data under the null generateNullData <- if (method == "simulate") { if (missing(tiles)) stop("'tiles' is required for 'method = \"simulate\"'") rmarks <- .rmarks(data, t0 = t0, T = T) function() { events <- simEndemicEvents(m0, tiles = tiles) events@data <- cbind(events@data, rmarks(n = length(events))) as.epidataCS(events = events, stgrid = data$stgrid[,-1L], W = data$W, qmatrix = data$qmatrix, nCircle2Poly = attr(data$events$.influenceRegion, "nCircle2Poly"), clipper = "polyclip", verbose = FALSE) } } else { function() permute.epidataCS(data, what = method, keep = time <= t0) } ## interpret 'verbose' level .verbose <- if (is.numeric(verbose)) { if (verbose >= 2) { ## create '.verbose' expression to print test statistics on the fly ## (will be ignored by plapply() if parallelized using clusters) stats2string <- function (lrt, simpleR0) paste0(c(names(lrt)[1:3], "simpleR0"), " = ", sprintf(paste0("%4.", c(0,0,1,2), "f"), c(lrt[1:3], simpleR0)), collapse = " | ") cat("Endemic/Epidemic log-likelihoods, LRT statistic, and simple R0:\n", stats2string(LRT, STATISTIC_R0), "\n", "\nRunning B = ", B, if (method == "simulate") " endemic simulations" else paste0(" permutations of ", method), " ...\n", sep = "") substitute({ cat(STATS2STRING) if (!lrt["converged"]) { msg <- c(m0 = m0$converged, m1 = m1$converged) msg <- msg[msg != "TRUE"] cat(" | WARNING (", paste0(names(msg), collapse = " and "), "): ", paste0(unique(msg), collapse = " and "), sep = "") } cat("\n") }, list(STATS2STRING = body(stats2string))) } else { verbose <- verbose == 1 } } else verbose siafInt <- NULL if (method != "simulate") { ## if siafpars are fixed, determine siafInt for use in all permutations siafpars <- coeflist(model)$siaf if (length(siafpars) > 0L && all(names(siafpars) %in% fixed) && is.null(siafInt <- environment(model)$siafInt)) { if (!identical(FALSE, verbose)) cat("pre-evaluating 'siaf' integrals with fixed parameters ...\n") setup <- update.twinstim(model, data = data, optim.args = NULL, verbose = FALSE) assign("siafpars", siafpars, envir = environment(setup)) siafInt <- with(environment(setup), do.call("..siafInt", .siafInt.args)) } } ## define the function to be replicated B times: ## permute/simulate data, update epidemic model, compute endemic-only model, ## and compute test statistics permfits1 <- function (...) { ## depends on 'data', 'model', 'lrt', 'eps.s', 'eps.t', and 'fixed' .permdata <- generateNullData() .siafInt <- if (!is.null(siafInt)) { siafInt[match(row.names(.permdata$events), row.names(data$events))] } # else NULL ## sink(paste0("/tmp/trace_", Sys.getpid()), append = TRUE) m1 <- update.twinstim(model, data = .permdata, control.siaf = list(siafInt = .siafInt), model = FALSE, cumCIF = FALSE, cores = 1, verbose = FALSE, optim.args = list(fixed = fixed, control = list(trace = is.numeric(verbose) && verbose >= 3))) ## sink() m0 <- update.twinstim(m1, epidemic = ~0, siaf = NULL, tiaf = NULL, control.siaf = NULL, optim.args = list(control = list(trace = 0))) lrt <- lrt(m0, m1) simpleR0 <- simpleR0(m1, eps.s = eps.s, eps.t = eps.t) if (isTRUE(compress)) { # save memory m0[c("fitted", "fittedComponents", "R0")] <- m1[c("fitted", "fittedComponents", "R0")] <- list(NULL) } list(m0 = m0, m1 = m1, stats = c(lrt[1:3], simpleR0 = simpleR0, lrt["converged"])) } ## rock'n'roll (the computationally intensive part) permfits <- plapply(X = integer(B), FUN = permfits1, .verbose = .verbose, ...) ## if parallelized using forking with insufficient memory available, ## part of the replications in 'permfits' may be left unassigned (NULL) permIsNull <- vapply(X = permfits, FUN = is.null, FUN.VALUE = logical(1L), USE.NAMES = FALSE) if (npermIsNull <- sum(permIsNull)) { warning(npermIsNull, "/", B, " replications did not return (insufficient memory?)") permfits <- permfits[!permIsNull] } ## extract the statistics permstats <- as.data.frame(t(vapply( X = permfits, FUN = "[[", "stats", FUN.VALUE = numeric(5L), USE.NAMES = TRUE ))) permstats$converged <- as.logical(permstats$converged) ## compute permutation-based p-value PVAL_D <- mean(c(STATISTIC_D, permstats[permstats$converged, "D"]) >= STATISTIC_D) PVAL_R0 <- mean(c(STATISTIC_R0, permstats[permstats$converged, "simpleR0"]) >= STATISTIC_R0) ## set results res$statistic <- structure(STATISTIC_R0, "D" = unname(STATISTIC_D)) res$parameter <- c("B" = sum(permstats$converged)) res$p.value <- structure(PVAL_R0, "D-based" = PVAL_D, "LRT" = PVAL_LRT) res$permfits <- permfits res$permstats <- permstats res } coef.epitest <- function (object, which = c("m1", "m0"), ...) { which <- match.arg(which) permcoefs <- vapply(X = object$permfits, FUN = function (x) coef(x[[which]]), FUN.VALUE = coef(object$permfits[[1L]][[which]]), USE.NAMES = TRUE) t(permcoefs) } plot.epitest <- function (x, teststat = c("simpleR0", "D"), ...) { teststat <- match.arg(teststat) defaultArgs <- switch(teststat, "simpleR0" = list( permstats = x$permstats$simpleR0, xmarks = setNames(x$statistic, "observed"), xlab = expression("Simple " * R[0]) ), "D" = list( permstats = x$permstats$D, xmarks = setNames(attr(x$statistic, "D"), "observed"), xlab = expression(D == 2 %.% log(L[full]/L[endemic])) ) ) args <- modifyList(defaultArgs, list(...)) if (is.null(args[["permstats"]])) stop("nothing to plot (no 'permstats' available)") do.call("permtestplot", args) } ## auxiliary function also used by plot.knox(), permutationTest(), ... permtestplot <- function (permstats, xmarks = NULL, xlab = "test statistic", ...) { defaultArgs <- list( data = permstats, xlab = xlab, col = "lavender", main = "Monte Carlo permutation test for space-time interaction", xlim = extendrange(c(permstats, xmarks)) ) do.call("truehist", modifyList(defaultArgs, list(...), keep.null = TRUE)) if (!is.null(xmarks)) { abline(v = xmarks, lwd = 2) axis(3, at = xmarks, labels = names(xmarks), # if NULL the value is used tick = FALSE, line = -1, font = 2) } invisible(NULL) } surveillance/R/farringtonFlexible.R0000644000176200001440000007620214615162374017136 0ustar liggesusers# ____________________________ # |\_________________________/|\ # || || \ # || algo.farrington || \ # || new version || | # || || | # || || | # || || | # || || | # || || / # ||_________________________|| / # |/_________________________\|/ # __\_________________/__/|_ # |_______________________|/ ) # ________________________ (__ # /oooo oooo oooo oooo /| _ )_ # /ooooooooooooooooooooooo/ / (_)_(_) # /ooooooooooooooooooooooo/ / (o o) #/C=_____________________/_/ ==\o/== # Contributed to "surveillance" on 2013-06-26 by M. Salmon # Later (>= 2016) bug fixes and maintenance by M. Hoehle and S. Meyer ################################################################################ # CONTENTS ################################################################################ # # MAIN FUNCTION # Function that manages input and output. # # RESIDUALS FUNCTION # Function that calculates Anscombe residuals. # # WEIGHTS FUNCTION # Function that calculates weights based on these residuals. # # FORMULA FUNCTION # Function that writes a formula for the glm using Booleans from control. # # FIT GLM FUNCTION # Function that fits a GLM. If it does not converge this function tries to fit it without time trend. # # THRESHOLD FUNCTION # Function that calculates the lower and upper threshold, the probability of observing a count that is >= observed, and the score. # There are two versions of this function depending on the method chosen. # # BLOCKS FUNCTION # Function that creates the factor variable for the glm. # # DATA GLM FUNCTION # Function that prepares data for the glm # # GLM FUNCTION # Function that calls fit glm, checkst he time trend and calculate the prediction fort he current timepoint. ################################################################################ # END OF CONTENTS ################################################################################ ################################################################################ # MAIN FUNCTION ################################################################################ farringtonFlexible <- function(sts, control = list( range = NULL, # range of time points to be monitored b = 5, # how many years to go back in time? w = 3, # half-window length reweight = TRUE, # reweighting past outbreaks? weightsThreshold = 2.58, # with which threshold? verbose = FALSE, # printing information? glmWarnings = TRUE, # printing warning from glm.fit? alpha = 0.05, # (one-sided) (1-alpha)% prediction interval trend = TRUE, # include a time trend when possible? pThresholdTrend = 0.05, # which pvalue for the time trend is significant? limit54 = c(5,4), # ignore if <5 reports during the past 4 weeks powertrans = "2/3", # power transformation for the data fitFun = "algo.farrington.fitGLM.flexible", # which function to use? populationOffset = FALSE, # use a population offset in the model? noPeriods = 1, # how many periods between windows around reference weeks? pastWeeksNotIncluded = NULL, # how many past weeks not to take into account? thresholdMethod = "delta" # which method for calculating the threshold? )) { ###################################################################### # Use special Date class mechanism to find reference months/weeks/days ###################################################################### epochAsDate <- sts@epochAsDate ###################################################################### # Fetch observed and population ###################################################################### # Fetch observed observed <- observed(sts) freq <- sts@freq if (epochAsDate) { epochStr <- switch( as.character(freq), "12" = "month","52" = "week", "365" = "day") } else { epochStr <- "none" } # Fetch population population <- population(sts) ###################################################################### # Fix missing control options ###################################################################### defaultControl <- eval(formals()$control) control <- modifyList(defaultControl, control, keep.null = TRUE) if (is.null(control$range)) { control$range <- (freq*control$b + control$w + 1):nrow(observed) ## NOTE: this default is different from algo.farrington() } # Use factors in the model? Depends on noPeriods, no input from the user. control$factorsBool <- control$noPeriods != 1 # How many past weeks not to take into account? if (is.null(control$pastWeeksNotIncluded)) { control$pastWeeksNotIncluded <- control$w } # there is only one fitFun at the moment control$fitFun <- match.arg(control$fitFun, c("algo.farrington.fitGLM.flexible")) # extract the threshold method thresholdMethod <- match.arg(control$thresholdMethod, c("delta", "nbPlugin", "muan")) # Adapt the argument for the glm function control$typePred <- switch(thresholdMethod, "delta" = "response", "nbPlugin" = "link", "muan" = "link") # Which threshold function? control$thresholdFunction <- switch(thresholdMethod, "delta" = "algo.farrington.threshold.farrington", "nbPlugin" = "algo.farrington.threshold.noufaily", "muan" = "algo.farrington.threshold.noufaily") # check options if (!((control$limit54[1] >= 0) && (control$limit54[2] > 0))) { stop("The limit54 arguments are out of bounds: cases >= 0 and period > 0.") } ###################################################################### # Initialize the necessary vectors ###################################################################### score <- trend <- pvalue <- expected <- mu0Vector <- phiVector <- trendVector <- matrix(data = 0, nrow = length(control$range), ncol = ncol(sts)) # Define objects n <- control$b*(2*control$w+1) # loop over columns of sts for (j in 1:ncol(sts)) { #Vector of dates if (epochAsDate) { vectorOfDates <- as.Date(sts@epoch, origin="1970-01-01") } else { vectorOfDates <- seq_len(length(observed[,j])) } # Loop over control$range for (k in control$range) { ###################################################################### # Prepare data for the glm ###################################################################### dayToConsider <- vectorOfDates[k] diffDates <- diff(vectorOfDates) dataGLM <- algo.farrington.data.glm(dayToConsider=dayToConsider, b=control$b, freq=freq, epochAsDate=epochAsDate, epochStr=epochStr, vectorOfDates=vectorOfDates,w=control$w, noPeriods=control$noPeriods, observed=observed[,j],population=population[,j], verbose=control$verbose, pastWeeksNotIncluded=control$pastWeeksNotIncluded,k) ###################################################################### # Fit the model ###################################################################### finalModel <- algo.farrington.glm(dataGLM,timeTrend=control$trend,populationOffset=control$populationOffset, factorsBool=control$factorsBool,reweight=control$reweight, weightsThreshold=control$weightsThreshold, pThresholdTrend=control$pThresholdTrend,b=control$b, noPeriods=control$noPeriods,typePred=control$typePred, fitFun=control$fitFun,glmWarnings=control$glmWarnings, epochAsDate=epochAsDate,dayToConsider=dayToConsider, diffDates=diffDates,populationNow=population[k,j],k, verbose=control$verbose) if (is.null(finalModel)) { #Do we have an alarm -- i.e. is observation beyond CI?? #upperbound only relevant if we can have an alarm (enoughCases) sts@alarm[k,j] <- NA sts@upperbound[k,j] <- NA mu0Vector[(k-min(control$range)+1),j] <- NA # Get overdispersion phiVector[(k-min(control$range)+1),j] <- NA # Get score score[(k-min(control$range)+1),j] <- NA #Compute bounds of the predictive pvalue[(k-min(control$range)+1),j] <- NA # Time trend trendVector[(k-min(control$range)+1),j] <- NA trend[(k-min(control$range)+1),j] <- NA warning(paste("The model could not converge with nor without time trend at timepoint ", k," so no result can be given for timepoint ", k,".\n")) } else { pred <- finalModel$pred doTrend <- finalModel$doTrend coeffTime <- finalModel$coeffTime ###################################################################### # Calculate lower and upper threshold ###################################################################### argumentsThreshold <- list(predFit=pred$fit,predSeFit=pred$se.fit, phi=finalModel$phi, skewness.transform=control$powertrans, alpha=control$alpha, y=observed[k,j], method=control$thresholdMethod ) lu <- do.call(control$thresholdFunction, args=argumentsThreshold) ###################################################################### # Postprocessing steps & output ###################################################################### #Compute exceedance score unless less than 5 reports during last 4 weeks. #Changed in version 0.9-7 - current week is included now enoughCases <- (sum(observed[(k-control$limit54[2]+1):k,j]) >=control$limit54[1]) #18 May 2006: Bug/unexpected feature found by Y. Le Strat. #the okHistory variable meant to protect against zero count problems, #but instead it resulted in exceedance score == 0 for low counts. #Now removed to be concordant with the Farrington 1996 paper. X <- ifelse(enoughCases,lu$score,NA) #Do we have an alarm -- i.e. is observation beyond CI?? #upperbound only relevant if we can have an alarm (enoughCases) sts@alarm[k,j] <- !is.na(X) && (X>1) && observed[k,j]!=0 sts@upperbound[k,j] <- ifelse(enoughCases,lu$upper,NA) # Possible bug alarm although upperbound <- 0? # Calculate expected value from glm if (is.na(lu$upper)==FALSE) { if ( control$typePred=="response"){ expected[(k-min(control$range)+1),j] <- ifelse(enoughCases,pred$fit,NA) } else{ expected[(k-min(control$range)+1),j] <- ifelse(enoughCases,exp(pred$fit),NA) } } else { expected[(k-min(control$range)+1),j] <- NA } # Calculate mean of the negbin distribution of the observation # Use linear predictor mean and sd eta0 <- pred$fit seEta0 <- pred$se.fit # deduce the quantile for mu0 from eta0 which is normally distributed if (control$thresholdMethod=='nbPlugin'){ mu0Vector[(k-min(control$range)+1),j] <- exp(eta0) } else { mu0Vector[(k-min(control$range)+1),j] <- exp(qnorm(1-control$alpha, mean=eta0, sd=seEta0)) } # Get overdispersion phiVector[(k-min(control$range)+1),j] <- finalModel$phi # Get score score[(k-min(control$range)+1),j] <- lu$score #Compute bounds of the predictive pvalue[(k-min(control$range)+1),j] <- lu$prob # Time trend if(doTrend) { trendVector[(k-min(control$range)+1),j] <- coeffTime trend[(k-min(control$range)+1),j] <- 1 } else { trendVector[(k-min(control$range)+1),j] <- NA } } }#done looping over all time points } #end of loop over cols in sts sts@control$score <- score sts@control$pvalue <- pvalue sts@control$expected <- expected sts@control$mu0Vector <- mu0Vector sts@control$phiVector <- phiVector sts@control$trendVector <- trendVector sts@control$trend <- trend #Done return(sts[control$range,]) } ################################################################################ # END OF MAIN FUNCTION ################################################################################ ################################################################################ # REFERENCE TIME POINTS FUNCTION ################################################################################ algo.farrington.referencetimepoints <- function(dayToConsider,b=control$b,freq=freq,epochAsDate,epochStr){ if (epochAsDate) { referenceTimePoints <- as.Date(seq(as.Date(dayToConsider, origin="1970-01-01"), length.out=(b+1), by="-1 year")) } else { referenceTimePoints <- seq(dayToConsider, length.out=(b+1), by=-freq) } if (epochStr == "week") { # get the date of the Mondays/Tuesdays/etc so that it compares to # the reference data # (Mondays for Mondays for instance) # Vectors of same days near the date (usually the same week) # dayToGet dayToGet <- as.numeric(format(dayToConsider, "%w")) actualDay <- as.numeric(format(referenceTimePoints, "%w")) referenceTimePointsA <- referenceTimePoints - (actualDay - dayToGet) # Find the other "same day", which is either before or after referenceTimePoints referenceTimePointsB <- referenceTimePointsA + ifelse(referenceTimePointsA>referenceTimePoints,-7,7) # For each year choose the closest Monday/Tuesday/etc # The order of referenceTimePoints is NOT important AB <- cbind(referenceTimePointsA,referenceTimePointsB) ABnumeric <- cbind(as.numeric(referenceTimePointsA),as.numeric(referenceTimePointsB)) distMatrix <- abs(ABnumeric-as.numeric(referenceTimePoints)) idx <- (distMatrix[,1]>distMatrix[,2])+1 referenceTimePoints <- as.Date(AB[cbind(1:dim(AB)[1],idx)],origin="1970-01-01") } return(referenceTimePoints) } ################################################################################ # END OF REFERENCE TIME POINTS FUNCTION ################################################################################ ################################################################################ # RESIDUALS FUNCTION # anscombe.residuals(m,phi) # is defined in algo_farrington.R ################################################################################ ################################################################################ # WEIGHTS FUNCTION # algo.farrington.assign.weights(s,weightsThreshold) # is defined in algo_farrington.R ################################################################################ ################################################################################ # FORMULA FUNCTION ################################################################################ # Function for writing the good formula depending on timeTrend, # populationOffset and factorsBool formulaGLM <- function(populationOffset=FALSE,timeBool=TRUE,factorsBool=FALSE){ # Description # Args: # populationOffset: --- # Returns: # Vector of X # Smallest formula formulaString <- "response ~ 1" # With time trend? if (timeBool){ formulaString <- paste(formulaString,"+wtime",sep ="")} # With population offset? if(populationOffset){ formulaString <- paste(formulaString,"+offset(log(population))",sep ="")} # With factors? if(factorsBool){ formulaString <- paste(formulaString,"+seasgroups",sep ="")} # Return formula as a string return(formulaString) } ################################################################################ # END OF FORMULA FUNCTION ################################################################################ ################################################################################ # FIT GLM FUNCTION ################################################################################ algo.farrington.fitGLM.flexible <- function(dataGLM, timeTrend,populationOffset,factorsBool,reweight,weightsThreshold,glmWarnings,verbose,control,...) { # Model formula depends on whether to include a time trend or not. theModel <- formulaGLM(populationOffset,timeBool=timeTrend,factorsBool) # Fit it -- this is slow. An improvement would be to use glm.fit here. # This would change the syntax, however. if (glmWarnings) { model <- glm(formula(theModel),data=dataGLM,family = quasipoisson(link="log")) } else { model <- suppressWarnings(glm(formula(theModel),data=dataGLM,family = quasipoisson(link="log"))) } #Check convergence - if no convergence we return empty handed. if (!model$converged) { #Try without time dependence if (timeTrend) { theModel <- formulaGLM(populationOffset,timeBool=F,factorsBool) if (glmWarnings) { model <- glm(as.formula(theModel), data=dataGLM, family = quasipoisson(link="log")) } else { model <- suppressWarnings(glm(as.formula(theModel), data=dataGLM, family = quasipoisson(link="log"))) } if (verbose) {cat("Warning: No convergence with timeTrend -- trying without.\n")} } if (!model$converged) { if (verbose) {cat("Warning: No convergence in this case.\n")} if (verbose) {print(dataGLM[,c("response","wtime"),exact=TRUE])} return(NULL) } } #Overdispersion parameter phi phi <- max(summary(model)$dispersion,1) #In case reweighting using Anscome residuals is requested if (reweight) { s <- anscombe.residuals(model,phi) omega <- algo.farrington.assign.weights(s,weightsThreshold) if (glmWarnings) { model <- glm(as.formula(theModel),data=dataGLM, family=quasipoisson(link="log"), weights=omega) } else { model <- suppressWarnings(glm(as.formula(theModel),data=dataGLM, family=quasipoisson(link="log"), weights=omega)) } #Here, the overdispersion often becomes small, so we use the max #to ensure we don't operate with quantities less than 1. phi <- max(summary(model)$dispersion,1) } # end of refit. #Add wtime, response and phi to the model model$phi <- phi model$wtime <- dataGLM$wtime model$response <- dataGLM$response model$population <- dataGLM$population if (reweight) { model$weights <- omega } else{ model$weights <- model$weights } #Done return(model) } ################################################################################ # END OF FIT GLM FUNCTION ################################################################################ ################################################################################ # THRESHOLD FUNCTION FARRINGTON ################################################################################ algo.farrington.threshold.farrington <- function(predFit,predSeFit,phi, skewness.transform, alpha,y,method){ #Fetch mu0 and var(mu0) from the prediction object mu0 <- predFit tau <- phi + (predSeFit^2)/mu0 #Standard deviation of prediction, i.e. sqrt(var(h(Y_0)-h(\mu_0))) switch(skewness.transform, "none" = { se <- sqrt(mu0*tau); exponent <- 1}, "1/2" = { se <- sqrt(1/4*tau); exponent <- 1/2}, "2/3" = { se <- sqrt(4/9*mu0^(1/3)*tau); exponent <- 2/3}, { stop("No proper exponent in algo.farrington.threshold.")}) #Note that lu can contain NA's if e.g. (-1.47)^(3/2) lu <- sort((mu0^exponent + c(-1,1)*qnorm(1-alpha)*se)^(1/exponent), na.last=FALSE) #Ensure that lower bound is non-negative lu[1] <- max(0,lu[1],na.rm=TRUE) # probability associated to the observed value as quantile # hoehle 2018-09-12: fixed p-value bug detected by Lore Merdrignac q <- pnorm( y^(exponent), mean=mu0^exponent, sd=se,lower.tail=FALSE) # calculate score x <- ifelse(is.na(lu[2])==FALSE,(y - predFit) / (lu[2] - predFit),NA) return(list(lower=lu[1],upper=lu[2],prob=q,score=x)) } ################################################################################ # END OF THRESHOLD FUNCTION FARRINGTON ################################################################################ ################################################################################ # THRESHOLD FUNCTION NOUFAILY ################################################################################ algo.farrington.threshold.noufaily <- function(predFit,predSeFit,phi, skewness.transform, alpha,y,method){ # method of Angela Noufaily with modifications # Use linear predictor mean and sd eta0 <- predFit seEta0 <- predSeFit # deduce the quantile for mu0 from eta0 which is normally distributed if (method=='nbPlugin'){ mu0Quantile <- exp(eta0) } else { mu0Quantile <- exp(qnorm(1-alpha, mean=eta0, sd=seEta0)) } if (mu0Quantile==Inf){ lu <- c(NA,NA) q <- NA # else is when the method is "muan" } else{ # Two cases depending on phi value if (phi>1){ lu<-c(qnbinom(alpha,mu0Quantile/(phi-1),1/phi), qnbinom(1-alpha,mu0Quantile/(phi-1),1/phi)) } else { lu<-c(qpois(alpha,mu0Quantile),qpois(1-alpha,mu0Quantile)) } # cannot be negative lu[1]=max(0,lu[1]) # probability associated to the observed value as quantile if (phi!=1){ q <- pnbinom(q= y-1 ,size=mu0Quantile/(phi-1),prob=1/phi,lower.tail=FALSE) } else{ q <- ppois(y-1,mu0Quantile,lower.tail=FALSE) } } # calculate score x <- ifelse(is.na(lu[2])==FALSE,(y - predFit) / (lu[2] - predFit),NA) return(list(lower=lu[1],upper=lu[2],prob=q,score=x)) } ################################################################################ # END OF THRESHOLD FUNCTION NOUFAILY ################################################################################ ################################################################################ # BLOCKS FUNCTION ################################################################################ blocks <- function(referenceTimePoints,vectorOfDates,freq,dayToConsider,b,w,p, epochAsDate) { ## INPUT # freq: are we dealing with daily/weekly/monthly data? # b: how many years to go back in time # w: half window length around the reference timepoints # p: number of noPeriods one wants the year to be split into ## VECTOR OF ABSOLUTE NUMBERS # Very useful to write the code! vectorOfAbsoluteNumbers <- seq_len(length(vectorOfDates)) # logical vector indicating where the referenceTimePoints # are in the vectorOfDates referenceTimePointsOrNot <- vectorOfDates %in% referenceTimePoints ## VECTOR OF FACTORS vectorOfFactors <- rep(NA_real_,length(vectorOfDates)) ## SETTING THE FACTORS # Current week if (epochAsDate==FALSE){ now <- which(vectorOfDates==dayToConsider) } else { now <- which(vectorOfDates==as.Date(dayToConsider)) } vectorOfFactors[(now-w):now] <- p # Reference weeks referenceWeeks <- rev(as.numeric( vectorOfAbsoluteNumbers[referenceTimePointsOrNot])) for (i in 1:b) { # reference week refWeek <- referenceWeeks[i+1] vectorOfFactors[(refWeek-w):(refWeek+w)] <- p # The rest is only useful if ones want factors, otherwise only have # reference timepoints like in the old algo.farrington if (p!=1){ # Number of time points to be shared between vectors period <- referenceWeeks[i] - 2 * w - 1 - refWeek # Check that p is not too big if (period < (p-(2*w+1))){stop('Number of factors too big!')} # Look for the length of blocks lengthOfBlocks <- period %/% (p-1) rest <- period %% (p-1) vectorLengthOfBlocks <- rep(lengthOfBlocks,p-1) # share the rest of the Euclidean division among the first blocks add <- seq_len(rest) vectorLengthOfBlocks[add] <- vectorLengthOfBlocks[add]+1 # slight transformation necessary for the upcoming code with cumsum vectorLengthOfBlocks <- c(0,vectorLengthOfBlocks) # fill the vector for (j in 1:(p-1)) { vectorOfFactors[(refWeek+w+1+cumsum(vectorLengthOfBlocks)[j]): (refWeek+w+1+cumsum(vectorLengthOfBlocks)[j+1]-1)]<-j } } } ## DONE! return(vectorOfFactors) #indent } ################################################################################ # END OF BLOCKS FUNCTION ################################################################################ ################################################################################ # DATA GLM FUNCTION ################################################################################ algo.farrington.data.glm <- function(dayToConsider, b, freq, epochAsDate,epochStr, vectorOfDates,w,noPeriods, observed,population, verbose,pastWeeksNotIncluded,k){ # Identify reference time points # Same date but with one year, two year, etc, lag # b+1 because we need to have the current week in the vector referenceTimePoints <- algo.farrington.referencetimepoints(dayToConsider,b=b, freq=freq, epochAsDate=epochAsDate, epochStr=epochStr ) if (!all(referenceTimePoints %in% vectorOfDates)) { ## previously only checked min(referenceTimePoints) stop("Some reference time points did not exist; ", "decrease 'b' or postpone 'range'.") } if (verbose) { cat("k=", k,"\n")} # Create the blocks for the noPeriods between windows (including windows) # If noPeriods=1 this is a way of identifying windows, actually. blocks <- blocks(referenceTimePoints,vectorOfDates,epochStr,dayToConsider, b,w,noPeriods,epochAsDate) # Here add option for not taking the X past weeks into account # to avoid adaptation of the model to emerging outbreaks blocksID <- blocks blocksID[(k-pastWeeksNotIncluded):k] <- NA # Extract values for the timepoints of interest only blockIndexes <- which(is.na(blocksID)==FALSE) # Time # if epochAsDate make sure wtime has a 1 increment if (epochAsDate){ wtime <- (as.numeric(vectorOfDates[blockIndexes])- as.numeric(vectorOfDates[blockIndexes][1]))/as.numeric(diff(vectorOfDates))[1] } else { wtime <- as.numeric(vectorOfDates[blockIndexes]) } # Factors seasgroups <- as.factor(blocks[blockIndexes]) # Observed response <- observed[blockIndexes] # Population pop <- population[blockIndexes] if (verbose) { print(response)} dataGLM <- data.frame(response=response,wtime=wtime,population=pop, seasgroups=seasgroups,vectorOfDates=vectorOfDates[blockIndexes]) dataGLM <- dataGLM[is.na(dataGLM$response)==FALSE,] return(dataGLM) } ################################################################################ # END OF DATA GLM FUNCTION ################################################################################ ################################################################################ # GLM FUNCTION ################################################################################ algo.farrington.glm <- function(dataGLM,timeTrend,populationOffset,factorsBool, reweight,weightsThreshold,pThresholdTrend,b, noPeriods,typePred,fitFun,glmWarnings,epochAsDate, dayToConsider,diffDates,populationNow,k,verbose) { arguments <- list(dataGLM=dataGLM, timeTrend=timeTrend, populationOffset=populationOffset, factorsBool=factorsBool,reweight=reweight, weightsThreshold=weightsThreshold,glmWarnings=glmWarnings, verbose=verbose,control=control) model <- do.call(fitFun, args=arguments) #Stupid check to pass on NULL values from the algo.farrington.fitGLM proc. if (is.null(model)) return(model) ###################################################################### #Time trend ###################################################################### #Check whether to include time trend, to do this we need to check whether #1) wtime is significant at the 95lvl #2) the predicted value is not larger than any observed value #3) the historical data span at least 3 years. doTrend <- NULL # if model converged with time trend if ("wtime" %in% names(coef(model))){ # get the prediction for k if(epochAsDate){ wtime=(as.numeric(dayToConsider)-as.numeric(dataGLM$vectorOfDates[1]))/as.numeric(diffDates)[1] } else { wtime <- c(k) } pred <- predict.glm(model,newdata=data.frame(wtime=wtime, population=populationNow, seasgroups=factor(noPeriods), dispersion=model$phi),se.fit=TRUE,type="response") # check if three criterion ok #is the p-value for the trend significant (0.05) level significant <- (summary.glm(model)$coefficients["wtime",4] < pThresholdTrend) #have to use at least three years of data to allow for a trend atLeastThreeYears <- (b>=3) #no horrible predictions noExtrapolation <- (pred$fit <= max(dataGLM$response,na.rm=T)) #All 3 criteria have to be met in order to include the trend. Otherwise #it is removed. Only necessary to check this if a trend is requested. doTrend <- (atLeastThreeYears && significant && noExtrapolation) # if not then refit if (doTrend==FALSE) { arguments$timeTrend=FALSE model <- do.call(fitFun, args=arguments) } } else { doTrend <- FALSE } #done with time trend ###################################################################### ###################################################################### # Calculate prediction # ###################################################################### #Predict value if(epochAsDate){ wtime=(as.numeric(dayToConsider)-as.numeric(dataGLM$vectorOfDates[1]))/as.numeric(diffDates)[1] } else { wtime <- c(k) } pred <- predict.glm(model,newdata=data.frame(wtime=wtime, population=populationNow, seasgroups=factor(noPeriods), dispersion=model$phi),se.fit=TRUE,type=typePred) coeffTime=ifelse(doTrend,summary.glm(model)$coefficients["wtime",1],NA) finalModel <- list (pred,doTrend,coeffTime,model$phi) names(finalModel) <- c("pred","doTrend","coeffTime","phi") return(finalModel) } ################################################################################ # END OF GLM FUNCTION ################################################################################ surveillance/R/algo_outbreakP.R0000644000176200001440000001274313607336043016244 0ustar liggesusers###################################################################### # Workhorse computing the OutbreakP statistic. # Alarm statistic at end time n is returned. # # Author: # Michael Hoehle # # R port of the Java code by Marianne Frisen & Linus Schioler from # the CASE project. See https://smisvn.smi.se/case/ # # For a manual on how to use the method see also # http://www.hgu.gu.se/item.aspx?id=16857 # # Date: # 25 May 2010 # # Parameters: # x -- the series with the counts # # Returns: # value of the alarm statistic at the end of the series x. ###################################################################### calc.outbreakP.statistic <- function(x) { #Length of the monitored series n <- length(x) #Index problem when converting java arrays to R arrays x <- c(0,x) #Initialization (not all parts might be needed) leftl <- numeric(n+1) y <- numeric(n+1) yhat <- numeric(n+1) sumwy <- numeric(n+1) sumwys <- numeric(n+1) sumw <- numeric(n+1) w <- numeric(n+1) meanl <- numeric(n+1) xbar <- 0 meanl[1] = -Inf leftl[1] = 0 for (i in 1:n) { #Initialize yhat[i+1] <- x[i+1] sumwy[i+1] <- x[i+1] sumw[i+1] <- 1 meanl[i+1] <- x[i+1] leftl[i+1] <- i #Calculate mean (this is a sequential formula to calculate mean(x[1:i])) xbar=xbar+(x[i+1]-xbar)/i #Create plateaus while (meanl[i+1] <= meanl[ (leftl[i+1] - 1) + 1]) { #merge sets sumwy[i+1] = sumwy[i+1] + sumwy[(leftl[i+1] - 1)+1] sumw[i+1] = sumw[i+1] + sumw[(leftl[i+1] - 1)+1] meanl[i+1] = sumwy[i+1] / sumw[i+1] leftl[i+1] = leftl[(leftl[i+1] - 1)+1] } #calculate yhat for (j in leftl[i+1]:i) { yhat[j+1] = meanl[i+1] } } #Compute the statistic in case of a Poisson distribution alarm.stat <- 1 for (j in seq_len(n)) { #Ensure 0/0 = 1 so we don't get NaNs div <- ifelse(yhat[j+1]==0 & xbar==0, 1, yhat[j+1]/xbar) alarm.stat <- alarm.stat * (div)^x[j+1] } return(alarm.stat) ## The above might cause NaN's in case of large numbers. ## logalarm <- 0 ## for (j in 1:n) { ## #Eqn (5) in Frisen et al paper in log form. However: it is undefined ## #if \hat{\mu}^D(t) == 0 (it is a division by zero). ## #We fix 0/0 = 1 ## if (xbar != 0) { ## if (yhat[j+1] != 0) { #if \hat{\mu}^{C1} == 0 then ## logalarm = logalarm + x[j+1] * (log(yhat[j+1]) - log(xbar)) ## } ## } else { ## if (yhat[j+1] != 0) { ## stop("Division by zero in Eqn (5) of Frisen paper!") ## } ## } ## } ## #Done, return the value ## return(exp(logalarm)) } ###################################################################### # The detection function in S3 style ###################################################################### algo.outbreakP <- function(disProgObj, control = list(range = range, k=100, ret=c("cases","value"),maxUpperboundCases=1e5)) { #Set threshold to some fixed value, i.e. 100 if(is.null(control[["k",exact=TRUE]])) control$k <- 100 #Set largest observed value to try as upperbound when numerically searching #for NNBA in case ret = "cases" if(is.null(control[["maxUpperboundCases",exact=TRUE]])) control$maxUpperboundCases <- 1e5 #Which value to return in upperbound? control$ret <- match.arg(control$ret, c("value","cases")) #Initialize the necessary vectors alarm <- matrix(data = 0, nrow = length(control$range), ncol = 1) upperbound <- matrix(data = 0, nrow = length(control$range), ncol = 1) observed <- disProgObj$observed #Store results count <- 1 for(i in control$range) { statistic <- calc.outbreakP.statistic( observed[seq_len(i)] ) # store the results in the right order alarm[count] <- statistic > control$k #Find NNBA or just return value of the test statistic (faster) if (control$ret == "cases") { #If length is 1 no alarm can be given unless k<1 if (i<=1) { upperbound[count] <- ifelse(control$k>=1, NA, 0) } else { if (is.nan(statistic)) { #if no decent statistic was computed. upperbound[count] <- NA } else { #Go up or down delta <- ifelse(alarm[count], -1, 1) #Initialize observedi <- observed[i] foundNNBA <- FALSE #Loop with modified last observation until alarm is caused (dx=1) #or until NO alarm is caused anymore (dx=-1) while ( ((delta == -1 & observedi > 0) | (delta == 1 & observedi < control$maxUpperboundCases)) & (!foundNNBA)) { observedi <- observedi + delta newObserved <- c(observed[seq_len(i-1)],observedi) statistic <- calc.outbreakP.statistic( newObserved ) if (is.nan(statistic)) { #statistic produced a numeric overflow. observedi <- control$maxUpperboundCases } else { foundNNBA <- (statistic > control$k) == ifelse(alarm[count],FALSE,TRUE) } } upperbound[count] <- ifelse( foundNNBA, observedi + ifelse(alarm[count],1,0), NA) } } } else { upperbound[count] <- statistic } #Advance time index count <- count + 1 } #Add name and data name to control object. control$name <- paste("outbreakP(",control$k,")",sep="") control$data <- paste(deparse(substitute(disProgObj))) # return alarm and upperbound vectors result <- list(alarm = alarm, upperbound = upperbound, disProgObj=disProgObj, control=control) class(result) = "survRes" # for surveillance system result return(result) } surveillance/R/ks.plot.unif.R0000644000176200001440000001063614244757706015652 0ustar liggesusers################# # Plot the empirical distribution function of a sample from U(0,1) # together with a confidence band of the corresponding K-S-test. # # Copyright (C) 2012 Michael Hoehle and Sebastian Meyer # # This file is part of the R package "surveillance", # free software under the terms of the GNU General Public License, version 2, # a copy of which is available at https://www.R-project.org/Licenses/. # # Parts of the 'ks.plot.unif' code are taken from R's ks.test.R source file # with Copyright (C) 1995-2022 The R Core Team # under GPL-2 (or later). # # # Parameters: # U - numeric vector containing the sample (NA's are silently removed) # conf.level - confindence level for the K-S-test, # can also be a vector of multiple levels # exact - see ks.test # col.conf - colour of the confidence band # col.ref - colour of the reference line ################# ks.plot.unif <- function (U, conf.level = 0.95, exact = NULL, col.conf = "gray", col.ref = "gray", xlab = expression(u[(i)]), ylab = "Cumulative distribution") { stopifnot(is.vector(U, mode="numeric")) U <- U[!is.na(U)] n <- length(U) if(n < 1L) stop("empty sample") TIES <- FALSE if (anyDuplicated(U)) { warning("ties should not be present for the Kolmogorov-Smirnov test") TIES <- TRUE } if (is.null(exact)) exact <- (n < 100) && !TIES ## Helper function to invert the K-S test. The function ## pKolmogorov2x is the CDF of the Kolmogorov test statistic (x). f <- if (exact) { function (x, p) { PVAL <- 1 - .Call(C_pKolmogorov2x, x, n) PVAL - p } } else { function (x, p) { PVAL <- if (x == 0) 1 else 1 - .Call(C_pKS2, sqrt(n) * x, tol = 1e-6) PVAL - p } } ## Test inversion Dconf <- sapply(conf.level, function (level) { uniroot(f, lower=0, upper=1, p=1-level)$root }) ## Small helper function to draw a line myabline <- function (a, b, x.grid = seq(0,1,length.out=101), ...) { lines(x.grid, a + b * x.grid, ...) } ## Figure 10 in Ogata (1988) plot(c(0,1), c(0,1), type="n", xlab=xlab, ylab=ylab) myabline(a=0, b=1, col=col.ref, lwd=2) rug(U) lines(ecdf(U), verticals=TRUE, do.points=FALSE) sapply(Dconf, function (D) { myabline(a=D, b=1, col=col.conf, lty=2) myabline(a=-D, b=1, col=col.conf, lty=2) }) #legend(x="topleft", col=col.conf, lty=2, # legend=paste(100*conf.level,"% KS error bounds", sep="")) invisible() } ###################################################################### # Check the residual process of fitted twinstim or twinSIR # using ks.plot.unif on 1-exp(-diff(tau)) # and a scatterplot of u_i vs. u_{i+1} to inspect serial correlation # # Parameters: # object - a fitted twinSIR or twinstim model # # Draws the ECDF of the transformed residuals together with backtransformed # 95% Kolmogorov-Smirnov error bounds. ###################################################################### checkResidualProcess <- function (object, plot = 1:2, mfrow = c(1,length(plot)), ...) { stopifnot(inherits(object, c("twinSIR", "twinstim", "simEpidataCS"))) ## check plot argument if (is.logical(plot)) plot <- which(rep(plot, length.out = 2)) else { stopifnot(is.vector(plot, mode="numeric"), plot %in% 1:2) } ## extract residual process tau <- do.call("residuals", args = list(substitute(object)), envir = parent.frame()) ## Transform to uniform variable Y <- diff(c(0,tau)) U <- 1 - exp(-Y) ## Calculate KS test ks <- ks.test(U, "punif", alternative = "two.sided", exact = match.call()[["exact"]]) ## return value ret <- list(tau=tau, U=U, ks=ks) ## 2 types of plots plotcalls <- alist( ## Investigate uniform distribution of U ks.plot.unif(U, ...), ## Investigate serial correlation between U_t and U_{t+1} which ## corresponds to Figure 11 in Ogata (1988) plot(tail(U,n=-1), head(U,n=-1), xlab=expression(u[i]), ylab=expression(u[i+1])) ) ## eval selected plot calls if (length(plot) > 0L) { opar <- par(mfrow = mfrow); on.exit(par(opar)) for (i in plot) eval(plotcalls[[i]]) invisible(ret) } else { ret } } surveillance/R/disProg.R0000644000176200001440000001061014200426174014677 0ustar liggesusers################################################### ### chunk number 1: ################################################### create.disProg <- function(week, observed, state, start=c(2001,1), freq=52, neighbourhood=NULL, populationFrac=NULL,epochAsDate=FALSE){ ## issue a deprecation warning if not internally called if (!isTRUE(packageName(parent.frame()) == .packageName)) .Deprecated("sts") namesObs <-colnames(observed) # check whether observed contains only numbers stopifnot(is.numeric(observed)) #univariate timeseries ? if(is.vector(observed)){ observed <- matrix(observed,ncol=1) namesObs <- "observed" } else { # ensure we have a matrix observed <- as.matrix(observed) } if(missing(state)){ state <- 0*observed } else if(is.vector(state)){ state <- matrix(state,ncol=1) } else { state <- as.matrix(state) } #check number of columns of observed and state nAreas <- ncol(observed) nObs <- nrow(observed) if(ncol(state) != nAreas){ #if there is only one state-vector for more than one area, repeat it if(ncol(state)==1) { state <- matrix(rep(state,nAreas),ncol=nAreas,byrow=FALSE) } else { stop("wrong dimensions of 'observed' and 'state'") } } #check neighbourhood matrix # neighbourhood can be a matrix or an array of dimension c(nAreas,nAreas, nrow(observed)) if(!is.null(neighbourhood) ) { dimNhood <- dim(neighbourhood) if(!(length(dimNhood) %in% 2:3) || any(dimNhood[1:2] != nAreas) || (length(dimNhood)==3 && dimNhood[3] != nrow(observed))) { stop('wrong dimensions of neighbourhood matrix') } } else { # no neighbourhood specified neighbourhood <- matrix(NA,nrow=nAreas,ncol=nAreas) } if(is.null(populationFrac)) { populationFrac <- matrix(1/nAreas,nrow=nObs,ncol=nAreas) } else { # make sure populationFrac is a matrix populationFrac <- as.matrix(populationFrac) # check dimensions if(nrow(populationFrac)!= nObs | ncol(populationFrac)!= nAreas) stop("dimensions of 'populationFrac' and 'observed' do not match") # check whether populationFrac contains only numbers if(!is.numeric(populationFrac)) stop("'populationFrac' must be a numeric matrix") } #labels for observed and state if(is.null(namesObs)){ namesObs <- paste0("observed",1:nAreas) } colnames(observed) <- namesObs colnames(state) <- namesObs res <- list("week"=week, "observed"=observed, "state"=state, "start"=start, "freq"=freq, "neighbourhood"=neighbourhood, "populationFrac"=populationFrac,"epochAsDate"=epochAsDate) class(res) <- "disProg" return(res) } print.disProg <- function(x, ...) { cat( "-- An object of class disProg -- \n" ) cat( "freq:\t\t", x$freq,"\n" ) cat( "start:\t\t", x$start,"\n" ) cat( "dim(observed):\t", dim(x$observed), "\n\n") n <- 1 cat("Head of observed:\n") print(head(x$observed,n)) #cat("\nhead of neighbourhood:\n") #print( head(x$neighbourhood,n)) } ################################################### ### chunk number 3: ################################################### aggregate.disProg <- function(x,...){ #aggregate observed counts observed <- apply(x$observed,MARGIN=1,sum) #aggregate states state <- apply(x$state,MARGIN=1,sum) state[state > 1] <- 1 #create univariate disProg object x <- create.disProg(week=x$week, observed=observed, state=state, freq=x$freq,start=x$start) return(x) } ################################################### ### chunk number 4: ################################################### ## legacy code removed in surveillance 1.20.0 ## now plotting via syntax transformation to stsplot_time(disProg2sts(x)) plot.disProg <- function(x, title = "", xaxis.years = TRUE, startyear = x$start[1], firstweek = x$start[2], as.one = TRUE, same.scale = TRUE, ...) { cl <- match.call() cl[[1]] <- quote(surveillance::stsplot_time) stopifnot(!missing(x)) cl$x <- substitute(surveillance::disProg2sts(x)) names(cl)[names(cl) == "title"] <- "main" if (!xaxis.years) cl["xaxis.labelFormat"] <- list(NULL) cl$xaxis.years <- NULL if (length(ignored <- intersect(c("startyear", "firstweek", "quarters"), names(cl)))) { warning("ignored legacy argument(s): ", paste0(ignored, collapse = ", ")) cl[ignored] <- NULL } if (missing(as.one)) cl$as.one <- TRUE # stsplot_time has different default eval.parent(cl) } surveillance/R/algo_rogerson.R0000644000176200001440000004030314615162374016143 0ustar liggesusers################################################### ### chunk number 1: ################################################### ################################################################### # Average Run Lengths for CUSUMs using Markov Chain approach # # based on the program of Hawkins, D. M. (1992) # "Evaluation of Average Run Lengths of Cumulative Sum Charts # for an Arbitrary Data Distribution" # Communications in Statistics--Simulation. 21(4) 1001-1020. #--------------------------------------------------------------- # # for discrete distributions (i.e. Pois, Bin) # and upward CUSUMS (increasing rate,probability) # # Parameters: # h - decision interval h # k - reference value k # distr - "poisson" or "binomial" # theta - distribution parameter for cdf distr, e.g. lambda for ppois, p for pbinomial # W - winsorizing value W (for robust CUSUM) # to get a nonrobust CUSUM set W > k+h # digits - k and h are rounded to digits decimal places # ... - further arguments for distribution # i.e. number of trials n for binomial (defaults to n=1) # # Returns: # ARL - one-sided ARL of the regular (no-head-start) CUSUM ################################################################### arlCusum <- function(h=10, k=3, theta=2.4, distr=c("poisson","binomial"), W=NULL,digits=1,...){ h <- round(h,digits) k <- round(k,digits) #cat("h",h,"k",k,"\n") distr <- match.arg(distr,c("poisson","binomial")) ############## # cdf of a binomial variate with fixed sample size pbinomial <- function(x,p,n=1){ pbinom(x,size=n,prob=p) } ######## distribution <- switch(distr, "poisson" = ppois, "binomial" = pbinomial ) #no winsorization if(is.null(W)) W <- ceiling(h+k+1) # common denominator of h and k denrat <- commonDenom(h,k,digits=digits) #cat("h =",h,"k =",k,"denrat",denrat,"\n") # check parameters for feasibility if(h <=0) stop("Nonpositive decision interval\n") if(W <= k) stop("Winsorization value less than reference value\n") K <- as.integer(k*denrat+0.5) N <- as.integer(denrat) M <- as.integer(h*denrat -0.5) w <- as.integer(W*denrat+0.5) deviat <- abs(K-k*denrat)+abs(M-h*denrat+1)+abs(w-W*denrat) if(deviat > .01) stop("h, k or W not a multiple of 1/denrat\n") # determine probabilities x <- seq(((-M-1)+K)/N,(M+K)/N,by=(1/denrat)) probs <- distribution(x, theta,...) # Winsorization (any observation exceeding some threshold value W is replaced by W # CUSUM is then: S_n = max{0, S_n-1 + min(X_n,W) - k} probs[x>=W] <- 1 #construct transition matrix transition <- matrix(NA,M+1,M+1) transition[1,1] <- probs[(M+2)] #Pr(X <= k) transition[-1,1] <- probs[(M+2)-(1:M)] #Pr(X <= -j+ k) ,j=1,2,...,h-1 transition[1,-1] <- probs[(M+2)+(1:M)]- probs[(M+2)+(1:M)-1] #Pr(X = j+ k) , j=1,2,...,h-1 idx <-rep((M+2):((M+2)+M-1),M)-rep(0:(M-1),each=M) transition[-1,-1] <- matrix(probs[idx]-probs[idx-1],nrow=M,ncol=M,byrow=TRUE) #print(transition) # I - transition matrix R IminusR <- diag(1,M+1) - transition #Solve might work poorly in some cases res <- try(solve(IminusR)%*%rep(1,M+1),silent=TRUE) # res <- try(qr.solve(IminusR)%*%rep(1,M+1),silent=TRUE) if(inherits(res, "try-error")){ warning("I-R singular\n") return(NA) } ARL <- res[1] #FIRARL - one-sided ARL of the FIR CUSUM with head start 0.5h FIRARL <- res[(M+1)/2+1] return(list(ARL=ARL,FIR.ARL=FIRARL)) } ################################################################# # find smallest common denominator of x and y, # i.e find an integer N so that x=X/N and y=Y/N (with X,Y integer) ################################################################# commonDenom <- function(x,y,digits=1){ x <- round(x,digits) y <- round(y,digits) which.max( ( round((x+y)*1:(10^digits),digits)%%1 == 0 ) # (x+y)*N is integer & ( round(x*1:(10^digits),digits)%%1 == 0 ) # x*N is integer & ( round(y*1:(10^digits),digits)%%1 == 0 ) ) # y*N is integer } ################################################### ### chunk number 2: ################################################### ################################################################# # find reference value k for a Poisson /Binomial CUSUM # designed to detect a change from theta0 to theta1 # # digits - k is rounded to digits decimal places if roundK=TRUE # ... - extra arguments for distribution, # i.e number of trials n for binomial, set to 1 if not specified ################################################################## findK <- function(theta0,theta1,distr=c("poisson","binomial"),roundK=FALSE,digits=1,...){ n <- list(...)$n if(is.null(n)) n <- 1 distr <- match.arg(distr,c("poisson","binomial")) k <- switch(distr, "poisson" = (theta1 - theta0)/(log(theta1)-log(theta0)), "binomial" = -n*(log(1-theta1)-log(1-theta0))/(log(theta1*(1-theta0))-log(theta0*(1-theta1))) ) # for discrete data the # Cusum values are of form integer - integer multiple of k # so there is a limited set of possible values of h (and ARL) if(roundK){ # add/subtract 0.05 to k so that k isn't an integer or a multiple of 0.5 # when rounded (then the Markov Chain has more states) if(round(k,digits=digits)%%1 == 0.5 | round(k,digits=digits)%%1 == 0){ round.k <- ((k-floor(k))*10^digits)%%1 #print(roundK) if(round.k < .5 ) k <- k+0.5*10^(-digits) else k <- k-0.5*10^(-digits) } k <- round(k,digits=digits) } return(k) } ################################################### ### chunk number 3: ################################################### ################################################################## # function to find the decision limit h so that the # average run length for a Poisson/Binomial CUSUM with in-control # parameter theta0 is (approx.) ARL0 # # Params: # ARL0 - desired in-control ARL # theta0 - in-control parameter # s - change to detect (in stdev) # rel.tol - (relative) tolerance (if attainable) # roundK - should k be rounded up to digits decimal place (avoiding integers, multiples of 0.5) # digits - h is rounded to digits decimal places # distr - "poisson" or "binomial" # ... - further arguments for distribution (i.e number of trials n for "binomial") # # Returns: # vector c(theta0, h, k, ARL, rel.tol) ################################################################# findH <- function(ARL0,theta0,s=1, rel.tol=0.03,roundK=TRUE,distr=c("poisson","binomial"),digits=1,FIR=FALSE,...){ distr <- match.arg(distr,c("poisson","binomial")) #FIR-ARL or zero-start ARL? fir.arl <- ifelse(FIR,2,1) theta1 <- getTheta1(theta0,s=s,distr=distr) k <- findK(theta0,theta1,roundK=roundK,distr=distr,digits=digits,...) # compute ARL for two (arbitrary) points (h1, h2) h1 <- min(12,4*k) arl1 <- arlCusum(h=h1,k=k,theta=theta0,distr=distr,digits=digits,...)[[fir.arl]] nEval <- 1 #ensure h1 and arl1 are not too small (-> log. interpolation is better) while(arl1 < 100){ h1 <- 2*h1 arl1 <- arlCusum(h=h1,k=k,theta=theta0,distr=distr,digits=digits,...)[[fir.arl]] nEval <- nEval + 1 } h2 <- h1*2^(sign(ARL0-arl1)) arl2 <- arlCusum(h=h2,k=k,theta=theta0,distr=distr,digits=digits,...)[[fir.arl]] nEval <- nEval + 1 # determine h (that leads to an ARL of ARL0) using logarithmic interpolation h.hat <- round(logInterpolation(ARL0,h1,h2,arl1,arl2),digits) # what's the actual ARL for h arl <- arlCusum(h=h.hat,k=k,theta=theta0,distr=distr,digits=digits,...)[[fir.arl]] nEval <- nEval + 1 relTol <- abs((arl-ARL0)/ARL0) #cat("theta0:", theta0,"k:", k,"h:", h.hat,"ARL:",arl,"relTol:", relTol,"\n") i<-0 signs <- sign(ARL0-arl) convergence <- relTol < rel.tol if(convergence){ # print(nEval) return(c("theta0"=theta0,"h"=h.hat,"k"=k,"ARL"=arl,"rel.tol"=relTol)) } # find hLow so that the target ARL0 is in interval c(ARL(hLow), ARL(h.hat)) denrat <- 1/commonDenom(1,k,digits=digits) steps <- denrat #max(0.1,denrat) # cat("denrat",denrat,"steps",steps,"\n") hLow <- round(h.hat+signs*steps,digits) arlLow <- arlCusum(h=hLow,k=k,theta=theta0,distr=distr,digits=digits,...)[[fir.arl]] nEval <- nEval + 1 relTol.Low <- abs((arlLow-ARL0)/ARL0) if(relTol.Low < rel.tol){ # print(nEval) return(c("theta0"=theta0,"h"=hLow,"k"=k,"ARL"=arlLow,"rel.tol"=relTol.Low)) } while(sign(ARL0-arl)*sign(ARL0-arlLow)>0){ # cat("steps:",nEval,"\n") h.hat <- hLow arl <-arlLow relTol <- relTol.Low signs <- sign(ARL0-arl) hLow <- round(h.hat+signs*steps,digits) arlLow <- arlCusum(h=hLow,k=k,theta=theta0,distr=distr,digits=digits,...)[[fir.arl]] nEval <- nEval + 1 relTol.Low <- abs((arlLow-ARL0)/ARL0) if(relTol.Low < rel.tol){ # print(nEval) return(c("theta0"=theta0,"h"=hLow,"k"=k,"ARL"=arlLow,"rel.tol"=relTol.Low)) } # cat("hLow:", hLow,"ARL:",arlLow,"relTol:",relTol.Low,"\n") } # cat("hLow:", hLow,"ARL:",arlLow,"relTol:",relTol.Low,"\n") # return the ARL which is at least the target ARL0 if(sign(ARL0-arlLow)<0){ h.hat <- hLow arl <- arlLow relTol <- relTol.Low } #print(nEval) return(c("theta0"=theta0,"h"=h.hat,"k"=k,"ARL"=arl,"rel.tol"=relTol)) } ################################################################## # find h for various values theta0 # # Params: # theta0 - vector of in control parameter # ARL0 - desired in-control ARL # # Returns: # matrix with columns c(theta0, h, k, ARL, rel.Tol) ################################################################## hValues <- function(theta0,ARL0,rel.tol=0.02,s=1,roundK=TRUE,digits=1,distr=c("poisson","binomial"),FIR=FALSE,...){ distr <- match.arg(distr,c("poisson","binomial")) n <- list(...)$n hVals <- t(sapply(theta0,findH,ARL0=ARL0,rel.tol=rel.tol,s=s,roundK=roundK,digits=digits,distr=distr,FIR=FIR,...)) res <- list(hValues=hVals,ARL0=ARL0,s=s,rel.tol=rel.tol,distribution=distr,firARL=FIR) res$n <- n return(res) } ################################################################## # get decision interval h and reference value k for CUSUM with # in-control parameter theta using a "table" of h values # # theta - in-control parameter # hValues - matrix with columns c(theta, h) ################################################################## getHK <- function(theta,hValues){ one<- function(theta){ theta.diff <- abs(hValues[,1]-theta) idx <- which.min(theta.diff) hk <- hValues[idx,2:3] if(theta.diff[idx] > 0.05) warning("table doesn't contain h value for theta = ",theta,"\n") return(hk) } t(sapply(theta,one)) } ################################################################# # get out-of-control parameter theta1 # # X ~ Po(lambda0): theta1 = lambda0 + s*sqrt(lambda0) # theta1 corresponds to a s*stdev increase in mean # # X ~Bin(n,pi) # H0: Odds of failure =pi/(1-pi) vs H1: Odds = s*pi/(1-pi) # prob of failure under H1 is then pi1 = s*pi0/(1+(s-1)*pi0) ################################################################# getTheta1 <- function(theta0,s=1,distr=c("poisson","binomial")){ distr <- match.arg(distr,c("poisson","binomial")) theta1 <- switch(distr, "poisson" = theta0 + s*sqrt(theta0), "binomial" = s*theta0/(1-theta0+s*theta0) ) return(theta1) } ################################################################# # logarithmic interpolation, i.e. linear interpolation of ln(f(x)) # in points (x0,ln(f0)), (x1,ln(f1)) # # (ln(f)-ln(f0))/(ln(f1)-ln(f0)) = (x-x0)/(x1-x0) # # returns: x # # to find decision limit h for given ARL0 set x = h, f(h) = ARL0(h,k) # and solve equation for x ################################################################# logInterpolation <- function(f,x0,x1,f0,f1){ x0 + ((x1-x0)*(log(f)-log(f0)))/(log(f1)-log(f0)) } ################################################### ### chunk number 4: ################################################### # control - list with # range - vector of indices in the observed matrix to monitor # theta0t - matrix with in-control parameter, needs to be specified # ARL0 - desired average run length for each one of the univariate CUSUMs # s - change to detect # hValues - matrix with decision intervals for theta0_t # reset - if TRUE, the CUSUM is reset to zero after an alarm # nt - time varying sample sizes (for Binomial), # matrix of same dimension as theta0t algo.rogerson <- function(disProgObj, control=list(range=range, theta0t=NULL, ARL0=NULL, s=NULL, hValues=NULL, distribution=c("poisson","binomial"), nt=NULL, FIR=FALSE,limit=NULL, digits=1)){ if (is.null(control$s)) { stop("Error: the s value is not specified") } if (is.null(control$hValues)) { stop("Error: the hValues are not specified") } # if (is.null(control$ARL0)) { stop("Error: no ARL0 value specified") } #Default value is poisson control$distribution <- match.arg(control$distribution,c("poisson","binomial")) if(is.null(control$FIR)){ control$FIR <- FALSE } if(is.null(control$limit)) control$limit <- -1 if(is.null(control$digits)) control$digits <- 1 x <- as.matrix(disProgObj$observed[control$range,]) if (is.null(control$theta0t)) { stop("Error: no theta0t vector specified") } else { theta0t <- as.matrix(control$theta0t) } #theta0 <- colMeans(theta0t) #size = length of process size <- nrow(x) nAreas <- ncol(theta0t) theta0 <- rep(mean(theta0t),nAreas) #check dimensions of x, theta0t if(size !=nrow(theta0t) | (ncol(x)%%nAreas)!=0) stop("wrong dimensions\n") reps <- ncol(x)/nAreas #time-varying size n for Binomial nt<-control$nt if(control$distribution=="binomial"){ if(is.null(nt)) nt <- matrix(rep(control$n,size),ncol=1) else nt<-as.matrix(nt) } theta1 <- getTheta1(theta0,s=control$s,distr=control$distribution) theta1t <- getTheta1(theta0t,s=control$s,distr=control$distribution) hk <- getHK(theta0,hValues=control$hValues) k <- hk[,"k"] h <- hk[,"h"] #cat("k =",k,"h =",h,"\n") if(control$FIR){ control$limit <- 0.5 fir <- h/2 } else { fir <- 0 } #cat("fir",fir,"\n") # initialize the necessary vectors # start with cusum[1] = 0 cusum <- matrix(0,nrow=(size+1), ncol=nAreas*reps) cusum[1,] <- fir alarm <- matrix(data = 0, nrow = (size+1), ncol = nAreas*reps) upperbound <- matrix(0,nrow=(size+1),ncol=reps) #CUSUM as in Rogerson (2004) for(t in 1:size){ #choose k_t based upon theta_0t and theta_1t hkt <- getHK(theta0t[t,],hValues=control$hValues) #kt <- hkt[,"k"] kt <- findK(theta0t[t,],theta1t[t,],distr=control$distribution,roundK=TRUE, digits=control$digits, n=if(control$distribution=="binomial") nt[t,]) #for given k_t (theta0t) and ARL_0 choose h_t ht <- hkt[,"h"] ct <- h/ht # compute cumulative sums of observations x corrected with the # reference value kt, scaled by factor ct # cusum[t+1,]<- pmax(0, cusum[t,] + ct*(x[t,]-kt)) # reset CUSUM to zero if an alarm is given at time t if((control$limit >= 0) & any(alarm[t,]==1)){ cusum.t <- cusum[t,] cusum.t[alarm[t,]==1] <- pmin(cusum[t,], control$limit*h)[alarm[t,]==1] cusum[t+1,]<- pmax(0, cusum.t + ct*(x[t,]-kt)) } else { cusum[t+1,]<- pmax(0, cusum[t,] + ct*(x[t,]-kt)) } # give alarm if the cusum is larger than h alarm[t+1,] <- cusum[t+1,] >= h # in case speed is premium then one might want to comment this line if((control$limit >= 0) & any(alarm[t,]==1)) { upperbound[t+1,] <- ceiling( (h-cusum.t)/ct + kt) } else { upperbound[t+1,] <- ceiling( (h-cusum[t,])/ct + kt) } #Ensure upperbound is positive (this should always be the case) if (upperbound[t+1,] < 0) { upperbound[t+1,] <- 0} } # discard cusum[1] and alarm[1] cusum <- as.matrix(cusum[-1,]) alarm <- as.matrix(alarm[-1,]) upperbound <- as.matrix(upperbound[-1,]) #Add name and data name to control object. control$name <- paste("CUSUM Rogerson:",control$distribution) control$data <- paste(deparse(substitute(disProgObj))) # return alarm and upperbound vectors result <- list(alarm = alarm, upperbound = upperbound, disProgObj=disProgObj,control=c(control,list(h=h))) class(result) = "survRes" # for surveillance system result return(result) } surveillance/R/sts_animate.R0000644000176200001440000001420014426171115015600 0ustar liggesusers################################################################################ ### Animated map (and time series chart) of an sts-object (or matrix of counts) ### ### Copyright (C) 2013-2016,2018,2020 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### Corresponding to the S3-generic function animate(), ### we define a method for the S4-class "sts" and omit the recommended ### setGeneric("animate"); setMethod("animate", "sts", animate.sts) ### [see Section "Methods for S3 Generic Functions" in help("Methods")] animate.sts <- function (object, tps = NULL, cumulative = FALSE, population = NULL, at = 10, ..., timeplot = list(pos = 1, size = 0.3, fill = TRUE), sleep = 0.5, verbose = interactive(), draw = TRUE) { if (draw && dev.interactive()) message("Advice: use facilities of the \"animation\" package, e.g.,\n", " saveHTML() to view the animation in a web browser.") if (is.null(tps)) tps <- seq_len(nrow(object)) if (!is.null(population)) { # get population matrix population <- parse_population_argument(population, object) } ## determine color breaks (checkat() is defined in stsplot_space.R) at <- checkat(at, data=.rangeOfDataToPlot(object, tps, cumulative, population), counts=is.null(population)) ## style of the additional temporal plot if (is.list(timeplot)) { timeplot <- modifyList(eval(formals()$timeplot), timeplot) if (!is.null(timeplot[["height"]])) { # surveillance <= 1.18.0 timeplot$pos <- 1 timeplot$size <- timeplot$height timeplot$height <- NULL } stopifnot(timeplot$pos %in% 1:4, timeplot$size > 0, timeplot$size < 1) ## disentangle arguments not for stsplot_timeSimple() timeplot_pos <- timeplot$pos timeplot_size <- timeplot$size timeplot_fill <- timeplot$fill timeplot$pos <- timeplot$size <- timeplot$fill <- NULL } if (verbose) pb <- txtProgressBar(min=0, max=length(tps), initial=0, style=3) grobs <- vector(mode = "list", length = length(tps)) for(i in seq_along(tps)) { cti <- if (cumulative) seq_len(i) else i ls <- stsplot_space(object, tps=tps[cti], population=population, at=at, ...) if (is.list(timeplot) && requireNamespace("gridExtra")) { stopifnot(packageVersion("gridExtra") >= "2.0.0") lt <- do.call("stsplot_timeSimple", c( list(x=object, tps=tps, highlight=cti), timeplot)) if (!isTRUE(timeplot_fill)) { # see ?trellis.object lt$aspect.fill <- FALSE lt$aspect.ratio <- ls$aspect.ratio * if (timeplot_pos %in% c(1,3)) timeplot_size / (1-timeplot_size) else (1-timeplot_size) / timeplot_size } grobs[[i]] <- switch(timeplot_pos, gridExtra::arrangeGrob(ls, lt, heights=c(1-timeplot_size, timeplot_size)), gridExtra::arrangeGrob(lt, ls, widths=c(timeplot_size, 1-timeplot_size)), gridExtra::arrangeGrob(lt, ls, heights=c(timeplot_size, 1-timeplot_size)), gridExtra::arrangeGrob(ls, lt, widths=c(1-timeplot_size, timeplot_size))) if (draw) { grid::grid.newpage() grid::grid.draw(grobs[[i]]) } } else { grobs[[i]] <- ls if (draw) print(ls) } if (verbose) setTxtProgressBar(pb, i) if (dev.interactive()) Sys.sleep(sleep) } if (verbose) close(pb) invisible(grobs) } ### additional time plot below the map stsplot_timeSimple <- function (x, tps = NULL, highlight = integer(0), inactive = list(col="gray", lwd=2), active = list(col=1, lwd=4), as.Date = x@epochAsDate, ...) { observed <- if (inherits(x, "sts")) observed(x) else x if (is.null(tps)) { tps <- seq_len(nrow(observed)) } else { observed <- observed[tps,,drop=FALSE] } epoch <- if (inherits(x, "sts")) epoch(x, as.Date = as.Date)[tps] else tps if (anyNA(observed)) warning("ignoring NA counts in time series plot") ## build highlight-specific style vectors (col, lwd, ...) stopifnot(is.list(inactive), is.list(active)) stylepars <- intersect(names(inactive), names(active)) styleargs <- sapply(stylepars, function (argname) { res <- rep.int(inactive[[argname]], length(tps)) res[highlight] <- active[[argname]] res }, simplify=FALSE, USE.NAMES=TRUE) par_no_top_padding <- list( layout.heights = list(top.padding = 0, main.key.padding = 0, key.axis.padding = 0) ) xyplot.args <- modifyList( c(list(x = rowSums(observed, na.rm = TRUE) ~ epoch, type = "h", grid = "h", ylab = "", xlab = "", ylim = c(0, NA), scales = list(x = list(tck = c(1, 0))), par.settings = par_no_top_padding), styleargs), list(...)) do.call(lattice::xyplot, xyplot.args) } ### determine data range for automatic color breaks 'at' .rangeOfDataToPlot <- function (object, tps, cumulative = FALSE, population = NULL) { observed <- if (inherits(object, "sts")) observed(object) else object observed <- observed[tps,,drop=FALSE] if (!is.null(population)) { # compute (cumulative) incidence observed <- if (cumulative) { observed / rep(population[tps[1L],], each = nrow(observed)) } else { observed / population[tps,,drop=FALSE] } } range(if (cumulative) c(observed[1L,], colSums(observed)) else observed, na.rm = TRUE) } surveillance/R/scores.R0000644000176200001440000001517614175102531014601 0ustar liggesusers################################################################################ ### Part of the surveillance package, http://surveillance.r-forge.r-project.org ### Free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ### ### Scoring rules as discussed in: ### Predictive model assessment for count data ### Czado, C., Gneiting, T. & Held, L. (2009) ### Biometrics 65:1254-1261 ### ### Copyright (C) 2010-2012 Michaela Paul ### Copyright (C) 2014-2015, 2017-2019, 2022 Sebastian Meyer ################################################################################ ## logarithmic score ## logs(P,x) = -log(P(X=x)) .logs <- function (px) -log(px) logs <- function (x, mu, size=NULL) { if (is.null(size)) { - dpois(x, lambda=mu, log=TRUE) } else { - dnbinom(x, mu=mu, size=size, log=TRUE) } } ## squared error score ## ses(P,x) = (x-mu_p)^2 ses <- function (x, mu, size=NULL) { (x-mu)^2 } ## normalized squared error score (IMPROPER) ## nses(P,x) = ((x-mu_p)/sigma_p)^2 nses <- function (x, mu, size=NULL) { sigma2 <- if (is.null(size)) mu else mu * (1 + mu/size) ((x-mu)^2) / sigma2 } ## Dawid-Sebastiani score ## dss(P,x) = ((x-mu_p)/sigma_p)^2 + 2*log(sigma_p) .dss <- function (meanP, varP, x) (x-meanP)^2 / varP + log(varP) dss <- function (x, mu, size=NULL) .dss(meanP = mu, varP = if (is.null(size)) mu else mu * (1 + mu/size), x = x) ## ranked probability score ## rps(P,x) = sum_0^Kmax {P(X<=k) - 1(x<=k)}^2 ## for a single prediction (general formulation) .rps <- function (P, ..., x, kmax, kmin = 0, tolerance = sqrt(.Machine$double.eps)) { ## compute P(X<=k) k <- kmin:kmax Pk <- P(k, ...) ## check precision if ((1 - Pk[length(Pk)])^2 > tolerance) warning("finite sum approximation error larger than tolerance=", format(tolerance)) ## compute the RPS sum((Pk - (x <= k))^2) } ## for a single Poisson prediction rps_1P <- function (x, mu, k=40, tolerance=sqrt(.Machine$double.eps)) { ## return NA for non-convergent fits (where mu=NA) if (is.na(x) || is.na(mu)) return(NA_real_) ## finite sum truncation at mean + k*sd, but not before x kmax <- max(x, ceiling(mu + k*sqrt(mu))) ## skip low k for large mu kmin <- if (mu > k^2) floor(mu - k*sqrt(mu)) else 0 ## compute the RPS .rps(P = ppois, lambda = mu, x = x, kmax = kmax, kmin = kmin, tolerance = tolerance) } ## for a single NegBin prediction rps_1NB <- function (x, mu, size, k=40, tolerance=sqrt(.Machine$double.eps)) { ## return NA for non-convergent fits (where mu=NA) if (anyNA(c(x, mu, size))) return(NA_real_) ## finite sum truncation at mean + k*sd, but not before x sigma2 <- mu * (1 + mu/size) kmax <- max(x, ceiling(mu + k*sqrt(sigma2))) ## skip low k for large mu kmin <- max(0, floor(mu - k*sqrt(sigma2))) ## protect against wide NegBin (excessive memory consumption) if (kmax - kmin > 1e8) { warning("quasi-continuous NegBin distribution (too wide); returning NA") return(NA_real_) } ## compute the RPS .rps(P = pnbinom, mu = mu, size = size, x = x, kmax = kmax, kmin = kmin, tolerance = tolerance) } ## vectorized version rps <- function (x, mu, size=NULL, k=40, tolerance=sqrt(.Machine$double.eps)) { res <- if (is.null(size)) { mapply(rps_1P, x=x, mu=mu, MoreArgs=list(k=k, tolerance=tolerance), SIMPLIFY=TRUE, USE.NAMES=FALSE) } else { mapply(rps_1NB, x=x, mu=mu, size=size, MoreArgs=list(k=k, tolerance=tolerance), SIMPLIFY=TRUE, USE.NAMES=FALSE) } attributes(res) <- attributes(x) # set dim and dimnames res } ### apply a set of scoring rules at once scores.default <- function(x, mu, size = NULL, which = c("logs", "rps", "dss", "ses"), sign = FALSE, ...) { stopifnot(is.na(mu) | mu >= 0) if (!is.null(size)) stopifnot(is.na(size) | size > 0) ## compute individual scores (these have the same dimensions as x) scorelist <- lapply(X = setNames(nm = which), FUN = do.call, args = alist(x = x, mu = mu, size = size), envir = environment()) ## append sign of x-mu if (sign) scorelist <- c(scorelist, list("sign" = sign(x-mu))) ## gather scores in an array simplify2array(scorelist, higher = TRUE) } ### apply scoring rules to a set of oneStepAhead() forecasts scores.oneStepAhead <- function (x, which = c("logs","rps","dss","ses"), units = NULL, sign = FALSE, individual = FALSE, reverse = FALSE, ...) { y <- x$observed # observed counts during the prediction window mu <- x$pred # predicted counts (same dim as y) ## transform overdispersion to dnbinom() parameterization size <- psi2size.oneStepAhead(x) # -> NULL or full dim(y) matrix ## select units if (!is.null(units)) { y <- y[,units,drop=FALSE] mu <- mu[,units,drop=FALSE] size <- size[,units,drop=FALSE] # works with size = NULL } nUnits <- ncol(y) if (nUnits == 1L) individual <- TRUE # no need to apply rowMeans() below result <- scores.default(x = y, mu = mu, size = size, which = which, sign = sign) ## reverse order of the time points (historically) if (reverse) { result <- result[nrow(result):1L,,,drop=FALSE] } ## average over units if requested if (individual) { drop(result) } else { apply(X=result, MARGIN=3L, FUN=rowMeans) ## this gives a nrow(y) x (5L+sign) matrix (or a vector in case nrow(y)=1) } } ## calculate scores with respect to fitted values scores.hhh4 <- function (x, which = c("logs","rps","dss","ses"), subset = x$control$subset, units = seq_len(x$nUnit), sign = FALSE, ...) { ## slow implementation via "fake" oneStepAhead(): ##fitted <- oneStepAhead(x, tp = subset[1L] - 1L, type = "final", ## keep.estimates = FALSE, verbose = FALSE) ##scores.oneStepAhead(fitted, which = which, units = units, sign = sign, ## individual = TRUE, reverse = FALSE) result <- scores.default( x = x$stsObj@observed[subset, units, drop = FALSE], mu = x$fitted.values[match(subset, x$control$subset), units, drop = FALSE], size = psi2size.hhh4(x, subset, units), which = which, sign = sign) rownames(result) <- subset drop(result) } surveillance/R/twinstim_siaf_gaussian.R0000644000176200001440000002045114426171115020050 0ustar liggesusers################################################################################ ### Gaussian spatial interaction function for twinstim's epidemic component ### ### Copyright (C) 2009-2014,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## nTypes: determines the number of parameters=(log-)standard deviations of the ## Gaussian kernel. In a multitype epidemic, the different types may share the ## same spatial interaction function (type-invariant), in which case nTypes=1. ## Otherwise nTypes should equal the number of event types of the epidemic, in ## which case every type has its own variance parameter. ## logsd: logical indicating if the gaussian kernel should be reparametrized ## such that the log-standard deviation is the parameter in question. This ## avoids constrained optimisation (L-BFGS-B) or the use of 'validpars'. ## density: logical. If TRUE, the isotropic Gaussian density (on R^2) will not ## be scaled to have maximum value of 1 at the mean c(0,0). ## effRangeMult: determines the effective range for numerical integration in ## terms of multiples of the parameter, i.e. with effRangeMult=6 numerical ## integration only considers the 6-sigma area around the event instead of the ## whole observation region W. ## validpars: If logsd = FALSE, you should either use ## constrained optimisation (L-BFGS-B) or set 'validpars' to function (pars) ## pars > 0. siaf.gaussian <- function (nTypes = 1, logsd = TRUE, density = FALSE, F.adaptive = FALSE, F.method = "iso", effRangeMult = 6, validpars = NULL) { if (!logsd || density) .Deprecated(msg = "non-default parametrizations of siaf.gaussian() are deprecated") nTypes <- as.integer(nTypes) stopifnot(length(nTypes) == 1L, nTypes > 0L) if (isScalar(F.adaptive)) { adapt <- F.adaptive F.adaptive <- TRUE } else adapt <- 0.1 if (F.adaptive && !missing(F.method)) warning("ignoring 'F.method' since 'F.adaptive=TRUE' (adaptive midpoint cubature)") f <- function (s, pars, types) {} # coordinate matrix s, length(types) = 1 or nrow(s) F <- if (F.adaptive) { as.function(c(alist(polydomain=, f=, pars=, type=), list(adapt=adapt), quote({}))) } else if (F.method == "iso") { if (!logsd || density) stop("only the default parametrization is implemented for 'F.method=\"iso\"'") if (nTypes > 1L) stop("only the single-type kernel is implemented for 'F.method=\"iso\"'") siaf_F_polyCub_iso(intrfr_name = "intrfr.gaussian", engine = "C") } else { formals(siaf.fallback.F)$method <- F.method siaf.fallback.F } Fcircle <- function (r, pars, type) {} # single radius and type effRange <- function (pars) {} deriv <- function (s, pars, types) {} # coordinate matrix s, length(types) = 1 or nrow(s) Deriv <- if (F.adaptive || F.method != "iso") { function (polydomain, deriv, pars, type, nGQ = 20L) {} # single "owin" and type } else { siaf_Deriv_polyCub_iso(intrfr_names = "intrfr.gaussian.dlogsigma", engine = "C") } simulate <- function (n, pars, type, ub) {} # n=size of the sample, # type=single type, # ub=upperbound (unused here) ## if there is only one type, we set the default type(s) argument to 1 ## (it is actually unused inside the functions) if (nTypes == 1L) { formals(f)$types <- formals(F)$type <- formals(Fcircle)$type <- formals(deriv)$types <- formals(Deriv)$type <- formals(simulate)$type <- 1L } # helper expressions tmp1 <- if (logsd) expression(sds <- exp(pars)) else expression(sds <- pars) tmp1.1 <- if (nTypes==1L) expression(sd <- sds) else expression(sd <- sds[type]) tmp2 <- c( expression(sLengthSquared <- .rowSums(s^2, L <- nrow(s), 2L)), if (nTypes == 1L) expression(sdss <- sds) else expression( types <- rep_len(types, L), sdss <- sds[types] ) ) # spatial interaction function body(f) <- as.call(c(as.name("{"), tmp1, tmp2, expression(fvals <- exp(-sLengthSquared/2/sdss^2)), if (density) expression(fvals / (2*pi*sdss^2)) else expression(fvals) )) environment(f) <- baseenv() # numerically integrate f over a polygonal domain if (F.adaptive) { body(F) <- as.call(c(as.name("{"), tmp1, tmp1.1, expression( eps <- adapt * sd, intf <- polyCub.midpoint(polydomain, f, pars, type, eps=eps), intf ) )) environment(F) <- getNamespace("surveillance") } # calculate the integral of f over a circular domain around 0 body(Fcircle) <- as.call(c(as.name("{"), tmp1, tmp1.1, expression(val <- pchisq((r/sd)^2, 2)), # cf. Abramowitz&Stegun formula 26.3.24 if (!density) expression(val <- val * 2*pi*sd^2), expression(val) )) environment(Fcircle) <- getNamespace("stats") # effective integration range of f as a function of sd if (isScalar(effRangeMult)) { body(effRange) <- as.call(c(as.name("{"), tmp1, substitute(effRangeMult*sds) )) environment(effRange) <- baseenv() } else effRange <- NULL # derivative of f wrt pars derivexpr <- if (logsd) { # derive f wrt psi=log(sd) !! if (density) { quote(deriv[cbind(seq_len(L),colidx)] <- exp(-frac) / pi/sdss^2 * (frac-1)) } else { quote(deriv[cbind(seq_len(L),colidx)] <- exp(-frac) * 2*frac) } } else { # derive f wrt sd !! if (density) { quote(deriv[cbind(seq_len(L),colidx)] <- exp(-frac) / pi/sdss^3 * (frac-1)) } else { quote(deriv[cbind(seq_len(L),colidx)] <- exp(-frac) * 2*frac/sdss) } } derivexpr <- do.call("substitute", args=list(expr=derivexpr, env=list(colidx=if (nTypes==1L) 1L else quote(types)))) body(deriv) <- as.call(c(as.name("{"), tmp1, tmp2, expression( deriv <- matrix(0, L, length(pars)), frac <- sLengthSquared/2/sdss^2 ), derivexpr, expression(deriv) )) environment(deriv) <- baseenv() # integrate 'deriv' over a polygonal domain if (F.adaptive || F.method != "iso") { body(Deriv) <- as.call(c(as.name("{"), ## Determine a = argmax(abs(deriv(c(x,0)))) if (density) { # maximum absolute value is at 0 expression(a <- 0) } else { c(tmp1, tmp1.1, expression( xrange <- polydomain$xrange, # polydomain is a "owin" a <- min(max(abs(xrange)), sqrt(2)*sd), # maximum absolute value if (sum(xrange) < 0) a <- -a # is more of the domain left of 0? )) }, if (nTypes == 1L) { expression(deriv.type <- function (s) deriv(s, pars, 1L)[,1L,drop=TRUE]) } else { # d f(s|type_i) / d sigma_{type_j} is 0 for i != j expression(deriv.type <- function (s) deriv(s, pars, type)[,type,drop=TRUE]) }, expression(int <- polyCub.SV(polydomain, deriv.type, nGQ=nGQ, alpha=a)), if (nTypes == 1L) expression(int) else expression( res <- numeric(length(pars)), # zeros res[type] <- int, res ) )) environment(Deriv) <- getNamespace("surveillance") } ## sampler (does not obey the 'ub' argument!!) body(simulate) <- as.call(c(as.name("{"), tmp1, tmp1.1, expression(matrix(rnorm(2*n, mean=0, sd=sd), nrow=n, ncol=2L)) )) environment(simulate) <- getNamespace("stats") ## return the kernel specification list(f=f, F=F, Fcircle=Fcircle, effRange=effRange, deriv=deriv, Deriv=Deriv, simulate=simulate, npars=nTypes, validpars=validpars) } surveillance/R/gd.R0000644000176200001440000000474114425015376013701 0ustar liggesusers###################################################################### # This file contains utility functions for the generalized Dirichlet # distribution described in the article by T.-T. Wong et al. (1998), # Generalized Dirichlet distribution in Bayesian analysis. Applied # Mathematics and Computation, volume 97, pp 165-181. # # This includes: # rgd - sample from the generalized Dirichlet distribution # Egd - expectation of the generalized Dirichlet distribution # # Author: Michael Hoehle # Date: LaMo Apr 2014. ###################################################################### ###################################################################### # Sample from the generalized dirichlet distribution, i.e. # (X_1,...,X_{k+1})' ~ GD(alpha,beta) # This is the algorithm described by Wong (1998), p. 174. # # Parameters: # alpha - vector of length k # beta - vector of length k # # Note: The alpha and beta vectors are for the first k categories. # The element in k+1 is automatically given as 1-sum_{i=1}^k X_i. ###################################################################### rgd <- function(n,alpha,beta) { #Check that alpha and beta are of the same length. if (length(alpha) != length(beta)) { stop("alpha and beta not of same length") } if (!all(alpha>0) | !all(beta>0)) { stop("Assumptiom alpha>0 and beta>0 is violated.") } #Prepare result and sample the first step as in Wong (1998), p.174 res <- matrix(NA,nrow=n,ncol=length(alpha)+1) res[,1] <- rbeta(n,alpha[1],beta[1]) sum <- res[,1] for (j in 2:(length(alpha))) { xj <- rbeta(n, alpha[j], beta[j]) #Adjust for previous samples res[,j] <- xj * (1-sum) sum <- sum + res[,j] } #Last cell is fixed. res[,length(alpha)+1] <- 1-sum return(res) } ###################################################################### #Compute analytically the expectation of a GD(alpha,beta) distributed #variable using the expression of Wong (1998). # # Parameters: # alpha - vector of alpha parameters of the distribution # beta - vector of beta parameters of the distribution # # Returns: # Expectation vector of the GD(alpha,betra) distribution ###################################################################### Egd <- function(alpha, beta) { mu <- alpha/(alpha+beta) mean <- NULL for (j in 1:length(mu)) { mean[j] <- mu[j] * prod(1-mu[seq_len(j-1)]) } return(c(mean,prod(1-mu))) } surveillance/R/sts_toLatex.R0000644000176200001440000001142112672242502015604 0ustar liggesusers################################################################################ ### toLatex-method for "sts" objects ### ### Copyright (C) 2014 Dirk Schumacher, 2014 Maelle Salmon ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ toLatex.sts <- function(object, caption = "",label=" ", columnLabels = NULL, subset = NULL, alarmPrefix = "\\textbf{\\textcolor{red}{", alarmSuffix = "}}", ubColumnLabel = "UB", ...) { # Args: # object: A single sts object; must not be NULL or empty. # caption: A caption for the table. Default is the empty string. # label: A label for the table. Default is the empty string. # columnLabels: A list of labels for each column of the resulting table. # subset: A range of values which should be displayed. If Null, then all # data in the sts objects will be displayed. Else only a subset of # data. Therefore range needs to be a numerical vector of indexes # from 1 to length(@observed). # alarmPrefix: A latex compatible prefix string wrapped around a table cell # iff there is an alarm;i.e. alarm = TRUE # alarmSuffix: A latex compatible suffix string wrapped around a table cell # iff there is an alarm;i.e. alarm[i,j] = TRUE # ubColumnLabel: The label of the upper bound column; default is "UB". # ...: Variable arguments passed to toLatex.xtable # Returns: # An object of class Latex # Error Handling isEmpty <- function(o) is.null(o) if (isEmpty(object)) stop("object must not be null or NA.") if (is.list(object)) stop("supplying a list of sts has been removed from the api. Sorry.") if (!isS4(object) || !is(object, "sts")) stop("object must be of type sts from the surveillance package.") if (!is.character(caption)) stop("caption must be a character.") if (!isEmpty(labels) && length(labels) != length(object)) stop("number of labels differ from the number of sts objects.") # derive default values tableLabels <- colnames(object@observed) if (!is.null(columnLabels) && length(columnLabels) != ncol(object@observed) * 2 + 2) { stop("the number of labels must match the number of columns in the resulting table; i.e. 2 * columns of sts + 2.") } tableCaption <- caption tableLabel <- label vectorOfDates <- epoch(object, as.Date = TRUE) yearColumn <- Map(function(d)isoWeekYear(d)$ISOYear, vectorOfDates) if (object@freq == 12 ) monthColumn <- Map(function(d) as.POSIXlt(d)$mon, vectorOfDates) if (object@freq == 52 ) weekColumn <- Map(function(d)isoWeekYear(d)$ISOWeek, vectorOfDates) dataTable <- data.frame(unlist(yearColumn)) colnames(dataTable) <- "year" if (object@freq == 12 ) { dataTable$month <- unlist(monthColumn) } if (object@freq == 52 ) { dataTable$week <- unlist(weekColumn) } if (object@freq == 365 ) { dataTable$day <- unlist(vectorOfDates) dataTable <- dataTable[c(2)] } noCols <- ncol(dataTable) j <- 1 + noCols tableLabelsWithUB <- c() # I know it is imperative - shame on me for (k in 1:(ncol(object@observed))) { upperbounds <- round(object@upperbound[,k], 2) observedValues <- object@observed[,k] alarms <- object@alarm[,k] ubCol <- c() for (l in 1:length(upperbounds)) { if (is.na(upperbounds[l])) { ubCol <- c(ubCol, NA) } else { ubCol <- c(ubCol, upperbounds[l]) if (!is.na(alarms[l]) && alarms[l]) { observedValues[l] <- paste0(alarmPrefix, observedValues[l], alarmSuffix) } } } dataTable[,(j)] <- observedValues dataTable[,(j + 1)] <- ubCol tableLabelsWithUB <- c(tableLabelsWithUB, tableLabels[k]) tableLabelsWithUB <- c(tableLabelsWithUB, ubColumnLabel) j <- j + 2 } # remove rows which should not be displayed if (is.null(subset)) subset <- 1:nrow(dataTable) else if (min(subset) < 1 || max(subset) > nrow(dataTable)) stop("'subset' must be a subset of 1:nrow(observed), i.e., 1:", nrow(dataTable)) dataTable <- dataTable[subset,] # prepare everything for xtable newColNames <- c(colnames(dataTable)[1:noCols], tableLabelsWithUB) if (!is.null(columnLabels)) { colnames(dataTable) <- columnLabels } else { colnames(dataTable) <- newColNames } xDataTable <- xtable(dataTable, label = tableLabel, caption = tableCaption, digits = c(0)) toLatex(xDataTable, ...) } setMethod("toLatex", "sts", toLatex.sts) surveillance/R/calibration_null.R0000644000176200001440000001555314426171115016626 0ustar liggesusers################################################################################ ### Expectation and variance of proper scoring rules for Poisson and NegBin ### Reference: Wei and Held (2014), Test, 23, 787-805 ### ### Copyright (C) 2013-2014 Wei Wei, 2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## wrapper function calling the necessary "EV" function for the selected score score_EV <- function (mu, size = NULL, tolerance = 1e-4, which = c("dss", "logs", "rps")) { which <- match.arg(which) if (which == "dss") return(dss_EV(mu, size)) ## for "logs" and "rps", the EV function only works with a single prediction ## -> apply to each mu (size) res <- if (is.null(size)) { # Poisson vapply(X = mu, FUN = paste0(which, "_EV_1P"), FUN.VALUE = c(E = 0, V = 0), tolerance = tolerance, USE.NAMES = FALSE) } else { # NegBin mapply(FUN = paste0(which, "_EV_1NB"), mu = mu, size = size, MoreArgs = list(tolerance = tolerance), SIMPLIFY = TRUE, USE.NAMES = FALSE) } ## 'res' has dimension 2 x length(mu) list(E = res[1L,], V = res[2L,]) } ########################## ### Dawid-Sebastiani Score ########################## dss_EV <- function (mu, size = NULL) { sigma2 <- if (is.null(size)) mu else mu * (1 + mu/size) E <- 1 + log(sigma2) V <- if (is.null(size)) { 2 + 1/sigma2 } else { 2 + 6/size + 1/sigma2 } list(E = E, V = V) } ##################### ### Logarithmic Score ##################### ## for a single Poisson prediction logs_EV_1P <- function (mu, tolerance = 1e-4) # tolerance is in absolute value { ## use the same kmax for expectation and variance -> shared computations ## K2 is always a bit larger than K1, so we use K2 kmax <- if (mu^3 < tolerance/.Machine$double.eps/2) { ## we can calculate K2 from Theorem 1 (b) qpois(1 - tolerance/(mu^3 + 6*mu^2 + 7*mu + 1), lambda = mu) + 3 } else { # very high quantile (e.g., 1 - 1e-16) would yield Inf mu + 10 * sqrt(mu) } kseq <- seq_len(kmax) ## compute values required by both E and V fseq <- dpois(kseq, lambda = mu) logfactseq <- lfactorial(kseq) ## expectation E <- if (mu > tolerance^(-1/4)) { # fast version for "large" mu ## approximation error is of order 1/mu^4 0.5 + 0.5*log(2*pi*mu) - 1/12/mu - 1/24/mu^2 - 19/360/mu^3 } else { ##kmax1 <- qpois(1 - tolerance/(mu^2 + 3*mu + 1), lambda = mu) + 2 seqq1 <- fseq * logfactseq mu * (1-log(mu)) + sum(seqq1) } ## variance (does it converge to 0.5 as mu -> Inf ?) seqq2 <- (logfactseq - kseq * log(mu))^2 * fseq V <- sum(seqq2) - (E - mu)^2 c(E = E, V = V) } ## for a single NegBin prediction logs_EV_1NB <- function (mu, size, tolerance = 1e-4) { ## TODO: replace simple kmax by formulae from the paper kmax <- qnbinom(1-tolerance/10, mu = mu, size = size) + 5 kseq <- 0:kmax ## compute values required by both E and V fseq <- dnbinom(kseq, mu = mu, size = size) lgammaseq <- lbeta(kseq + 1L, size) + log(kseq + size) ## expectation seqq1 <- lgammaseq * fseq E <- sum(seqq1) - size*log(size) - mu*log(mu) + (mu+size)*log(mu+size) ## variance con2 <- E - size * log(1 + mu/size) seqq2 <- (lgammaseq + kseq * log(1 + size/mu))^2 * fseq V <- sum(seqq2) - con2^2 ## check against formulation in the paper (Equation 11): ## con2paper <- E + size*log(size) - size*log(size+mu) - lgamma(size) ## seqq2paper <- (-lgamma(kseq+size) + lgamma(kseq+1L) + kseq*log(1+size/mu))^2 * fseq ## Vpaper <- sum(seqq2paper) - con2paper^2 ## => V and Vpaper are only identical for kmax -> Inf c(E = E, V = V) } ############################ ### Ranked Probability Score ############################ ## for a single Poisson prediction rps_EV_1P <- function (mu, tolerance = 1e-4) # tolerance is in absolute value { ## expectation if (requireNamespace("gsl", quietly = TRUE)) { ## faster and more accurate implementation (works for larger mu) E <- mu * gsl::bessel_I0_scaled(2*mu, give=FALSE, strict=TRUE) + mu * gsl::bessel_I1_scaled(2*mu, give=FALSE, strict=TRUE) } else { E <- mu * besselI(2*mu, 0, expon.scaled = TRUE) + mu * besselI(2*mu, 1, expon.scaled = TRUE) if (identical(E, 0)) { ## R's besselI() works fine for mu <= 50000 (on my .Machine) ## but returns 0 (buffer overflow) for larger arguments warning("'mu' is too large for besselI(), install package \"gsl\"") return(c(E = NA_real_, V = NA_real_)) } } ## variance kmax <- max(qpois(1 - tolerance/(10*mu^2 + mu), lambda = mu) + 2, 8) # cf. Theorem 2 (a) kseq <- 0:kmax fseq <- dpois(kseq, lambda = mu) Fseq <- cumsum(fseq) # = ppois(kseq, lambda = mu) psiseq <- (kseq - mu) * (2*Fseq - 1) + 2*mu * fseq seqq <- psiseq^2 * fseq V <- sum(seqq) - 4 * E^2 c(E = E, V = V) } ## for a single NegBin prediction rps_EV_1NB <- function (mu, size, tolerance = 1e-4) { ## determine kmax for Var0(RPS), which is always > kmax for E0(RPS), ## cf. Theorem 2 (c), here corrected (1-) and simplified l5 <- (mu + 1)^2 + 1 kmax2 <- max(qnbinom(1-tolerance/l5, mu = mu*(1+2/size), size = size+2) + 2, 8) ## the other listed terms seem to be always smaller than the first one: ## qnbinom(1-tolerance/l5, mu = mu, size = size) ## qnbinom(1-tolerance/l5, mu = mu*(1+1/size), size = size+1) + 1 kseq2 <- 0:kmax2 fseq2 <- dnbinom(kseq2, mu = mu, size = size) Fseq2 <- cumsum(fseq2) # = pnbinom(kseq2, mu = mu, size = size) ## expectation ghgz_part <- mu * (1 + mu/size) ghgz <- 4 * ghgz_part / size E <- if (ghgz < 1 && requireNamespace("gsl", quietly = TRUE)) { ghgz_part * gsl::hyperg_2F1(1+size, 0.5, 2, -ghgz, give = FALSE, strict = TRUE) } else { kmax1 <- max(qnbinom(1-tolerance/mu, mu = mu*(1+1/size), size = size+1) + 1, 8) # cf. Theorem 2 (b) kseq1 <- seq_len(kmax1) seqq1 <- vapply( X = kseq1, # we could use kmax2 (> kmax1) also here FUN = function (i) fseq2[i+1L] * sum((i:1) * fseq2[seq_len(i)]), FUN.VALUE = 0, USE.NAMES = FALSE) sum(seqq1) } ## variance psiseq <- kseq2 * (2 * Fseq2 - 1) + mu * (1 - 2 * pnbinom(kseq2 - 1, mu = mu + mu/size, size = size + 1)) seqq <- psiseq^2 * fseq2 V <- sum(seqq) - 4 * E^2 c(E = E, V = V) } surveillance/R/algo_bayes.R0000644000176200001440000000755112600466365015417 0ustar liggesusers################################################### ### chunk number 1: ################################################### # Implementation of the Bayes system. # The system evaluates specified timepoints and gives alarm if it recognizes # an outbreak for this timepoint. # # Features: # Choice between different Bayes sub-systems (difference in reference values). algo.bayesLatestTimepoint <- function(disProgObj, timePoint = NULL, control = list(b = 0, w = 6, actY = TRUE, alpha=0.05)){ observed <- disProgObj$observed freq <- disProgObj$freq # If there is no value in timePoint, then take the last value in observed if(is.null(timePoint)){ timePoint = length(observed) } #If no level specified. # check if the vector observed includes all necessary data. if((timePoint-(control$b*freq)-control$w) < 1){ stop("The vector of observed is too short!") } # construct the reference values basevec <- c() # if actY == TRUE use also the values of the year of timepoint if(control$actY){ basevec <- observed[(timePoint - control$w):(timePoint - 1)] } # check if you need more referencevalues of the past if(control$b >= 1){ for(i in 1:control$b){ basevec <- c(basevec, observed[(timePoint-(i*freq)-control$w):(timePoint-(i*freq)+control$w)]) } } # get the parameter for the negative binomial distribution # Modification on 13 July 2009 after comment by C. W. Ryan on NAs in the # time series sumBasevec <- sum(basevec, na.rm=TRUE) lengthBasevec <- sum(!is.na(basevec)) # compute the upper limit of a one sided (1-alpha)*100% prediction interval. upPI <- qnbinom(1-control$alpha, sumBasevec + 1/2, (lengthBasevec)/(lengthBasevec + 1)) # give alarm if the actual value is larger than the upper limit. alarm <- observed[timePoint] > upPI result <- list(alarm=alarm, upperbound=upPI, disProgObj=disProgObj) class(result) = "survRes" # for surveillance system result return(result) } # 'algo.bayes' calls 'algo.bayesLatestTimepoint' for data points given by range. algo.bayes <- function(disProgObj, control = list(range = range, b = 0, w = 6, actY = TRUE,alpha=0.05)){ # Set the default values if not yet set if(is.null(control$b)){ # value from bayes 1 control$b <- 0 } if(is.null(control$w)){ # value from bayes 1 control$w <- 6 } if(is.null(control$alpha)){ # value from bayes 1 control$alpha <- 0.05 } if(is.null(control$actY)){ # value from bayes 1 control$actY <- TRUE } # initialize the necessary vectors alarm <- matrix(data = 0, nrow = length(control$range), ncol = 1) upperbound <- matrix(data = 0, nrow = length(control$range), ncol = 1) count <- 1 for(i in control$range){ # call algo.bayesLatestTimepoint result <- algo.bayesLatestTimepoint(disProgObj, i, control = control) # store the results in the right order alarm[count] <- result$alarm upperbound[count] <- result$upperbound count <- count + 1 } #Add name and data name to control object. control$name <- paste("bayes(",control$w,",",control$w*control$actY,",",control$b,")",sep="") control$data <- paste(deparse(substitute(disProgObj))) # return alarm and upperbound vectors result <- list(alarm = alarm, upperbound = upperbound, disProgObj=disProgObj,control=control) class(result) = "survRes" # for surveillance system result return(result) } algo.bayes1 <- function(disProgObj, control = list(range = range)){ algo.bayes(disProgObj, control = list(range = control$range, b = 0, w = 6, actY = TRUE,alpha=0.05)) } algo.bayes2 <- function(disProgObj, control = list(range = range)){ algo.bayes(disProgObj, control = list(range = control$range, b = 1, w = 6, actY = TRUE,alpha=0.05)) } algo.bayes3 <- function(disProgObj, control = list(range = range)){ algo.bayes(disProgObj, control = list(range = control$range, b = 2, w = 4, actY = FALSE,alpha=0.05)) } surveillance/R/twinstim_tiaf.R0000644000176200001440000000336414615162374016172 0ustar liggesusers################################################################################ ### Temporal interaction functions for twinstim's epidemic component. ### Specific implementations are in separate files (e.g.: exponential, step). ### ### Copyright (C) 2009-2014 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ##################### ### "Constructor" ### ##################### tiaf <- function (g, G, deriv, Deriv, npars, validpars = NULL) { npars <- as.integer(npars) if (length(npars) != 1 || npars < 0L) { stop("'tiaf'/'npars' must be a single nonnegative number") } haspars <- npars > 0L g <- .checknargs3(g, "tiaf$g") G <- .checknargs3(G, "tiaf$G") if (!haspars || missing(deriv)) deriv <- NULL if (!haspars || missing(Deriv)) Deriv <- NULL if (!is.null(deriv)) deriv <- .checknargs3(deriv, "tiaf$deriv") if (!is.null(Deriv)) Deriv <- .checknargs3(Deriv, "tiaf$Deriv") validpars <- if (!haspars || is.null(validpars)) NULL else match.fun(validpars) list(g = g, G = G, deriv = deriv, Deriv = Deriv, npars = npars, validpars = validpars) } ################################# ### Constant temporal interaction ################################# tiaf.constant <- function () { res <- list( g = as.function(alist(t=, pars=, types=, rep.int(1, length(t))), envir = .GlobalEnv), G = as.function(alist(t=, pars=, types=, t), envir = .GlobalEnv), npars = 0L ) attr(res, "constant") <- TRUE res } surveillance/R/permutationTest.R0000644000176200001440000000331514426171115016505 0ustar liggesusers################################################################################ ### Permutation test to compare the means of paired samples ### ### Copyright (C) 2011-2012 Michaela Paul, 2013-2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ permutationTest <- function(score1, score2, nPermutation = 9999, plot = FALSE, verbose = FALSE) { stopifnot((nTime <- length(score1)) == length(score2), !is.na(score1), !is.na(score2)) meanScore1 <- mean(score1) meanScore2 <- mean(score2) diffObserved <- meanScore1 - meanScore2 diffMean <- replicate(nPermutation, { sel <- rbinom(nTime, size=1, prob=0.5) g1 <- (sum(score1[sel==0]) + sum(score2[sel==1]))/nTime g2 <- (sum(score1[sel==1]) + sum(score2[sel==0]))/nTime g1 - g2 }) if (isTRUE(plot)) plot <- list() if (is.list(plot)) { do.call("permtestplot", args = modifyList( list(permstats = diffMean, xmarks = c("observed" = diffObserved), xlab = "Difference between means", ylab = "Density", main = ""), plot)) } pVal <- (1+sum(abs(diffMean)>=abs(diffObserved))) / (nPermutation+1) pTtest <- t.test(score1, score2, paired=TRUE)$p.value if (verbose) cat("mean difference =", diffObserved, "\tp(permutation) =", pVal, "\tp(paired t-test) =", pTtest, "\n") list(diffObs=diffObserved, pVal.permut=pVal, pVal.t=pTtest) } surveillance/R/algo_rki.R0000644000176200001440000001056511770114750015073 0ustar liggesusers### R code from vignette source 'Rnw/algo_rki.Rnw' ### Encoding: ISO8859-1 ################################################### ### code chunk number 1: algo_rki.Rnw:96-214 ################################################### # Implementation of the Robert-Koch Institute (RKI) surveillance system. # The system evaluates specified timepoints and gives alarm if it recognizes # an outbreak for this timepoint. # # Features: # Choice between the different RKI sub-systems (difference in reference values). algo.rkiLatestTimepoint <- function(disProgObj, timePoint = NULL, control = list(b = 2, w = 4, actY = FALSE)){ observed <- disProgObj$observed freq <- disProgObj$freq # If there is no value in timePoint, then take the last value in observed if(is.null(timePoint)){ timePoint = length(observed) } # check if the vector observed includes all necessary data. if((timePoint-(control$b*freq)-control$w) < 1){ stop("The vector of observed is too short!") } # Extract the reference values from the historic time series basevec <- c() # if actY == TRUE use also the values of the year of timepoint if(control$actY){ basevec <- observed[(timePoint - control$w):(timePoint - 1)] } # check if you need more referencevalues of the past if(control$b >= 1){ for(i in 1:control$b){ basevec <- c(basevec, observed[(timePoint-(i*freq)-control$w):(timePoint-(i*freq)+control$w)]) } } # compute the mean. mu <- mean(basevec) if(mu > 20){ # use the normal distribution. # comupte the standard deviation. sigma <- sqrt(var(basevec)) # compute the upper limit of the 95% CI. upCi <- mu + 2 * sigma } else{ # use the poisson distribution. # take the upper limit of the 95% CI from the table CIdata.txt. #data("CIdata", envir=environment()) # only local assignment -> SM: however, should not use data() here #CIdata <- read.table(system.file("data", "CIdata.txt", package="surveillance"), header=TRUE) #SM: still better: use R/sysdata.rda (internal datasets being lazy-loaded into the namespace environment) # for the table-lookup mu must be rounded down. mu <- floor(mu) # we need the third column in the row mu + 1 upCi <- CIdata[mu + 1, 3] } # give alarm if the actual value is larger than the upper limit. alarm <- observed[timePoint] > upCi result <- list(alarm=alarm, upperbound=upCi) class(result) = "survRes" # for surveillance system result return(result) } # 'algo.rki' calls 'algo.bayesLatestTimepoint' for data points given by range. algo.rki <- function(disProgObj, control = list(range = range, b = 2, w = 4, actY = FALSE)){ # Set the default values if not yet set if(is.null(control$b)){ # value from rki 3 control$b <- 2 } if(is.null(control$w)){ # value from rki 3 control$w <- 4 } if(is.null(control$actY)){ # value from rki 3 control$actY <- FALSE } # initialize the necessary vectors alarm <- matrix(data = 0, nrow = length(control$range), ncol = 1) upperbound <- matrix(data = 0, nrow = length(control$range), ncol = 1) count <- 1 for(i in control$range){ #hoehle Debug: #print(i) # call algo.rki1LatestTimepoint result <- algo.rkiLatestTimepoint(disProgObj, i, control = control) # store the results in the right order alarm[count] <- result$alarm upperbound[count] <- result$upperbound count <- count + 1 } #Add name and data name to control object. control$name <- paste("rki(",control$w,",",control$w*control$actY,",",control$b,")",sep="") control$data <- paste(deparse(substitute(disProgObj))) # return alarm and upperbound vectors result <- list(alarm = alarm, upperbound = upperbound, disProgObj=disProgObj, control=control) class(result) = "survRes" # for surveillance system result return(result) } algo.rki1 <- function(disProgObj, control = list(range = range)) { algo.rki(disProgObj, control = list(range = control$range, b = 0, w = 6, actY = TRUE)) } algo.rki2 <- function(disProgObj, control = list(range = range)){ algo.rki(disProgObj, control = list(range = control$range, b = 1, w = 6, actY = TRUE)) } algo.rki3 <- function(disProgObj, control = list(range = range)){ algo.rki(disProgObj, control = list(range = control$range, b = 2, w = 4, actY = FALSE)) } surveillance/R/twinstim_methods.R0000644000176200001440000010065114531107643016702 0ustar liggesusers################################################################################ ### Methods for objects of class "twinstim", specifically: ### vcov, logLik, print, summary, plot, R0, residuals, update, terms, all.equal ### ### Copyright (C) 2009-2019,2022 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## extract the link function used for the epidemic predictor (default: log-link) .epilink <- function (x) { link <- attr(x$formula$epidemic, "link") if (is.null(link)) "log" else link } ### don't need a specific coef-method (identical to stats:::coef.default) ## coef.twinstim <- function (object, ...) ## { ## object$coefficients ## } ## list coefficients by component coeflist.twinstim <- coeflist.simEpidataCS <- function (x, ...) { coeflist <- coeflist.default(x$coefficients, x$npars) ## rename elements and union "nbeta0" and "p" as "endemic" coeflist <- c(list(c(coeflist[[1L]], coeflist[[2L]])), coeflist[-(1:2)]) names(coeflist) <- c("endemic", "epidemic", "siaf", "tiaf") coeflist } ## asymptotic variance-covariance matrix (inverse of expected fisher information) vcov.twinstim <- function (object, ...) { if (!is.null(object[["fisherinfo"]])) { solve(object$fisherinfo) } else if (!is.null(object[["fisherinfo.observed"]])) { solve(object$fisherinfo.observed) } else { stop("Fisher information not available; use, e.g., -optimHess()") } } ## Extract log-likelihood of the model (which also enables the use of AIC()) logLik.twinstim <- function (object, ...) { r <- object$loglik attr(r, "df") <- length(coef(object)) attr(r, "nobs") <- nobs(object) class(r) <- "logLik" r } ## Also define an extractAIC-method to make step() work extractAIC.twinstim <- function (fit, scale, k = 2, ...) { loglik <- logLik(fit) edf <- attr(loglik, "df") penalty <- k * edf c(edf = edf, AIC = -2 * c(loglik) + penalty) } ## Number of events (excluding the prehistory) nobs.twinstim <- function (object, ...) length(object$fitted) ## print-method print.twinstim <- function (x, digits = max(3, getOption("digits") - 3), ...) { cat("\nCall:\n") print.default(x$call) cat("\nCoefficients:\n") print.default(format(coef(x), digits=digits), print.gap = 2, quote = FALSE) cat("\nLog-likelihood: ", format(logLik(x), digits=digits), "\n", sep = "") if (!isTRUE(x$converged)) { cat("\nWARNING: OPTIMIZATION ROUTINE DID NOT CONVERGE!", paste0("(",x$converged,")"), "\n") } cat("\n") invisible(x) } summary.twinstim <- function (object, test.iaf = FALSE, correlation = FALSE, symbolic.cor = FALSE, runtime = FALSE, ...) { ans <- unclass(object)[c("call", "converged", if (runtime) "counts")] npars <- object$npars nbeta0 <- npars[1]; p <- npars[2]; nbeta <- nbeta0 + p q <- npars[3] nNotIaf <- nbeta + q niafpars <- npars[4] + npars[5] est <- coef(object) ans$cov <- tryCatch(vcov(object), error = function (e) { warning(e) matrix(NA_real_, length(est), length(est)) }) se <- sqrt(diag(ans$cov)) zval <- est/se pval <- 2 * pnorm(abs(zval), lower.tail = FALSE) coefficients <- cbind(est, se, zval, pval) dimnames(coefficients) <- list(names(est), c("Estimate", "Std. Error", "z value", "Pr(>|z|)")) ans$coefficients.beta <- coefficients[seq_len(nbeta),,drop=FALSE] ans$coefficients.gamma <- structure( coefficients[nbeta+seq_len(q),,drop=FALSE], link = .epilink(object) ) ans$coefficients.iaf <- coefficients[nNotIaf+seq_len(niafpars),,drop=FALSE] if (!test.iaf) { ## usually, siaf and tiaf parameters are strictly positive, ## or parametrized on the logscale. In this case the usual wald test ## with H0: para=0 is invalid or meaningless. is.na(ans$coefficients.iaf[,3:4]) <- TRUE } # estimated parameter correlation if (correlation) { ans$correlation <- cov2cor(ans$cov) ans$symbolic.cor <- symbolic.cor } ans$loglik <- logLik(object) ans$aic <- AIC(object) if (runtime) { ans$runtime <- object$runtime } class(ans) <- "summary.twinstim" ans } ## additional methods to make confint.default work for summary.twinstim vcov.summary.twinstim <- function (object, ...) object$cov coef.summary.twinstim <- function (object, ...) with(object, { coeftab <- rbind(coefficients.beta, coefficients.gamma, coefficients.iaf) structure(coeftab[,1], names=rownames(coeftab)) }) ## print-method for summary.twinstim print.summary.twinstim <- function (x, digits = max(3, getOption("digits") - 3), symbolic.cor = x$symbolic.cor, signif.stars = getOption("show.signif.stars"), ...) { nbeta <- nrow(x$coefficients.beta) # = nbeta0 + p q <- nrow(x$coefficients.gamma) niafpars <- nrow(x$coefficients.iaf) cat("\nCall:\n") print.default(x$call) if (nbeta > 0L) { cat("\nCoefficients of the endemic component:\n") printCoefmat(x$coefficients.beta, digits = digits, signif.stars = signif.stars, signif.legend = (q==0L) && signif.stars, ...) } else cat("\nNo coefficients in the endemic component.\n") if (q + niafpars > 0L) { cat("\nCoefficients of the epidemic component", if (attr(x$coefficients.gamma, "link") != "log") paste0(" (LINK FUNCTION: ", attr(x$coefficients.gamma, "link"), ")"), ":\n", sep = "") printCoefmat(rbind(x$coefficients.gamma, x$coefficients.iaf), digits = digits, signif.stars = signif.stars, ...) } else cat("\nNo epidemic component.\n") cat("\nAIC: ", format(x$aic, digits=max(4, digits+1))) cat("\nLog-likelihood:", format(x$loglik, digits = digits)) runtime <- x$runtime if (!is.null(runtime)) { cat("\nNumber of log-likelihood evaluations:", x$counts[1L]) cat("\nNumber of score function evaluations:", x$counts[2L]) cores <- attr(runtime, "cores") elapsed <- if (length(runtime) == 1L) { # surveillance < 1.6-0 runtime } else { runtime[["elapsed"]] } cat("\nRuntime", if (!is.null(cores) && cores > 1) paste0(" (", cores, " cores)"), ": ", format(elapsed, digits = max(4, digits+1)), " seconds", sep = "") } cat("\n") correl <- x$correlation if (!is.null(correl)) { p <- NCOL(correl) if (p > 1L) { cat("\nCorrelation of Coefficients:\n") if (is.logical(symbolic.cor) && symbolic.cor) { correl <- symnum(correl, abbr.colnames = NULL) correlcodes <- attr(correl, "legend") attr(correl, "legend") <- NULL print(correl) cat("---\nCorr. codes: ", correlcodes, "\n", sep="") } else { correl <- format(round(correl, 2), nsmall = 2) correl[!lower.tri(correl)] <- "" colnames(correl) <- substr(colnames(correl), 1, 5) print(correl[-1, -p, drop = FALSE], quote = FALSE) } } } if (!isTRUE(x$converged)) { cat("\nWARNING: OPTIMIZATION ROUTINE DID NOT CONVERGE!", paste0("(",x$converged,")"), "\n") } cat("\n") invisible(x) } ### 'cat's the summary in LaTeX code toLatex.summary.twinstim <- function ( object, digits = max(3, getOption("digits") - 3), eps.Pvalue = 1e-4, align = "lrrrr", booktabs = getOption("xtable.booktabs", FALSE), withAIC = FALSE, ...) { ret <- capture.output({ cat("\\begin{tabular}{", align, "}\n", if (booktabs) "\\toprule" else "\\hline", "\n", sep="") cat(" & Estimate & Std. Error & $z$ value & $P(|Z|>|z|)$ \\\\\n", if (!booktabs) "\\hline\n", sep="") tabh <- object$coefficients.beta tabe <- rbind(object$coefficients.gamma, object$coefficients.iaf) for (tabname in c("tabh", "tabe")) { tab <- get(tabname) if (nrow(tab) > 0L) { rownames(tab) <- gsub(" ", "", rownames(tab)) tab_char <- capture.output( printCoefmat(tab, digits=digits, signif.stars=FALSE, eps.Pvalue = eps.Pvalue, na.print="NA") )[-1] ## remove extra space (since used as column sep in read.table) tab_char <- sub("< ", "<", tab_char, fixed=TRUE) # small p-values ## replace scientific notation by corresponding LaTeX code tab_char <- sub("( xtable.summary.twinstim must be exported } formals(xtable.twinstim) <- formals(xtable.summary.twinstim) ### Plot method for twinstim (wrapper for iafplot and intensityplot) plot.twinstim <- function (x, which, ...) { cl <- match.call() which <- match.arg(which, choices = c(eval(formals(intensityplot.twinstim)$which), eval(formals(iafplot)$which))) FUN <- if (which %in% eval(formals(intensityplot.twinstim)$which)) "intensityplot" else "iafplot" cl[[1]] <- as.name(FUN) if (FUN == "iafplot") names(cl)[names(cl) == "x"] <- "object" eval(cl, envir = parent.frame()) } ### Calculates the basic reproduction number R0 for individuals ### with marks given in 'newevents' R0.twinstim <- function (object, newevents, trimmed = TRUE, newcoef = NULL, ...) { ## check for epidemic component npars <- object$npars if (npars["q"] == 0L) { message("no epidemic component in model, returning 0-vector") if (missing(newevents)) return(object$R0) else { return(structure(rep.int(0, nrow(newevents)), names = rownames(newevents))) } } ## update object for use of new parameters if (!is.null(newcoef)) { object <- update.twinstim(object, optim.args = list(par=newcoef, fixed=TRUE), cumCIF = FALSE, cores = 1L, verbose = FALSE) } ## extract model information t0 <- object$timeRange[1L] T <- object$timeRange[2L] typeNames <- rownames(object$qmatrix) nTypes <- length(typeNames) types <- seq_len(nTypes) form <- formula(object) siaf <- form$siaf tiaf <- form$tiaf coefs <- coef(object) tiafpars <- coefs[sum(npars[1:4]) + seq_len(npars["ntiafpars"])] siafpars <- coefs[sum(npars[1:3]) + seq_len(npars["nsiafpars"])] if (missing(newevents)) { ## if no newevents are supplied, use original events if (trimmed) { # already calculated by 'twinstim' return(object$R0) } else { # untrimmed version (spatio-temporal integral over R+ x R^2) ## extract relevant data from model environment if (is.null(modelenv <- environment(object))) { stop("need model environment for untrimmed R0 of fitted events\n", " -- re-fit or update() with 'model=TRUE'") } eventTypes <- modelenv$eventTypes eps.t <- modelenv$eps.t eps.s <- modelenv$eps.s gammapred <- modelenv$gammapred names(gammapred) <- names(object$R0) # for names of the result } } else { # use newevents stopifnot(is.data.frame(newevents)) eps.t <- newevents[["eps.t"]] eps.s <- newevents[["eps.s"]] if (is.null(eps.s) || is.null(eps.t)) { stop("missing \"eps.s\" or \"eps.t\" columns in 'newevents'") } if (is.null(newevents[["type"]])) { if (nTypes == 1) { newevents$type <- factor(rep.int(typeNames, nrow(newevents)), levels = typeNames) } else { stop("missing event \"type\" column in 'newevents'") } } else { newevents$type <- factor(newevents$type, levels = typeNames) if (anyNA(newevents$type)) { stop("unknown event type in 'newevents'; must be one of: ", paste0("\"", typeNames, "\"", collapse = ", ")) } } ## subset newevents to timeRange if (trimmed) { eventTimes <- newevents[["time"]] if (is.null(eventTimes)) { stop("missing event \"time\" column in 'newevents'") } .N <- nrow(newevents) newevents <- subset(newevents, time + eps.t > t0 & time <= T) if (nrow(newevents) < .N) { message("subsetted 'newevents' to only include events infectious ", "during 'object$timeRange'") } } ## calculate gammapred for newevents epidemic <- terms(form$epidemic, data = newevents, keep.order = TRUE) mfe <- model.frame(epidemic, data = newevents, na.action = na.pass, drop.unused.levels = FALSE, xlev = object$xlevels$epidemic) # sync factor levels mme <- model.matrix(epidemic, mfe) gamma <- coefs[sum(npars[1:2]) + seq_len(npars["q"])] if (ncol(mme) != length(gamma)) { stop("epidemic model matrix has the wrong number of columns ", "(check the variable types in 'newevents' (factors, etc))") } gammapred <- drop(mme %*% gamma) # identity link if (.epilink(object) == "log") gammapred <- exp(gammapred) names(gammapred) <- rownames(newevents) ## now, convert types of newevents to integer codes eventTypes <- as.integer(newevents$type) } ## qSum qSumTypes <- rowSums(object$qmatrix) qSum <- unname(qSumTypes[eventTypes]) ## calculate remaining factors of the R0 formula, i.e. siafInt and tiafInt if (trimmed) { # trimmed R0 for newevents ## integral of g over the observed infectious periods .tiafInt <- .tiafIntFUN() gIntUpper <- pmin(T - eventTimes, eps.t) gIntLower <- pmax(0, t0 - eventTimes) tiafInt <- .tiafInt(tiafpars, from=gIntLower, to=gIntUpper, type=eventTypes, G=tiaf$G) ## integral of f over the influenceRegion bdist <- newevents[[".bdist"]] influenceRegion <- newevents[[".influenceRegion"]] if (is.null(influenceRegion)) { stop("missing \".influenceRegion\" component in 'newevents'") } noCircularIR <- if (is.null(bdist)) FALSE else all(eps.s > bdist) if (attr(siaf, "constant")) { iRareas <- sapply(influenceRegion, area.owin) ## will be used by .siafInt() } else if (! (is.null(siaf$Fcircle) || (is.null(siaf$effRange) && noCircularIR))) { if (is.null(bdist)) { stop("missing \".bdist\" component in 'newevents'") } } .siafInt <- .siafIntFUN(siaf, noCircularIR=noCircularIR) .siafInt.args <- c(alist(siafpars), object$control.siaf$F) siafInt <- do.call(".siafInt", .siafInt.args) } else { # untrimmed R0 for original events or newevents ## integrals of interaction functions for all combinations of type and ## eps.s/eps.t in newevents typeTcombis <- expand.grid(type=types, eps.t=unique(eps.t), KEEP.OUT.ATTRS=FALSE) typeTcombis$gInt <- with(typeTcombis, tiaf$G(eps.t, tiafpars, type)) - tiaf$G(rep.int(0,nTypes), tiafpars, types)[typeTcombis$type] Fcircle <- getFcircle(siaf, object$control.siaf$F) typeScombis <- expand.grid(type=types, eps.s=unique(eps.s), KEEP.OUT.ATTRS=FALSE) typeScombis$fInt <- apply(typeScombis, MARGIN=1, FUN=function (type_eps.s) { type <- type_eps.s[1L] eps.s <- type_eps.s[2L] Fcircle(eps.s, siafpars, type) }) ## match combinations to rows of original events or 'newevents' eventscombiidxS <- match(paste(eventTypes,eps.s,sep="."), with(typeScombis,paste(type,eps.s,sep="."))) eventscombiidxT <- match(paste(eventTypes,eps.t,sep="."), with(typeTcombis,paste(type,eps.t,sep="."))) siafInt <- typeScombis$fInt[eventscombiidxS] tiafInt <- typeTcombis$gInt[eventscombiidxT] if (any(is.infinite(eps.t) & !is.finite(tiafInt), is.infinite(eps.s) & !is.finite(siafInt))) { message("infinite interaction ranges yield non-finite R0 values ", "because 'trimmed = FALSE'") } } ## return R0 values R0s <- qSum * gammapred * siafInt * tiafInt R0s } ## calculate simple R0 (over circular domain, without epidemic covariates, ## for type-invariant siaf/tiaf) simpleR0 <- function (object, eta = coef(object)[["e.(Intercept)"]], eps.s = NULL, eps.t = NULL, newcoef = NULL) { stopifnot(inherits(object, c("twinstim", "simEpidataCS"))) if (object$npars[["q"]] == 0L) return(0) if (any(rowSums(object$qmatrix) != 1)) warning("'simpleR0' is not correct for type-specific epidemic models") if (!is.null(newcoef)) { # use alternative coefficients object$coefficients <- newcoef } coeflist <- coeflist(object) siaf <- object$formula$siaf tiaf <- object$formula$tiaf ## default radii of interaction if (is.null(eps.s)) { eps.s <- attr(siaf, "eps") if (length(eps.s) > 1L) stop("found non-unique 'eps.s'; please set one") } else stopifnot(isScalar(eps.s)) if (is.null(eps.t)) { eps.t <- attr(tiaf, "eps") if (length(eps.t) > 1L) stop("found non-unique 'eps.t'; please set one") } else stopifnot(isScalar(eps.t)) ## integral of siaf over a disc of radius eps.s Fcircle <- getFcircle(siaf, object$control.siaf$F) siafInt <- unname(Fcircle(eps.s, coeflist$siaf)) ## integral of tiaf over a period of length eps.t tiafInt <- unname(tiaf$G(eps.t, coeflist$tiaf) - tiaf$G(0, coeflist$tiaf)) ## calculate basic R0 (if (.epilink(object) == "log") exp(eta) else eta) * siafInt * tiafInt } ### Extract the "residual process" (cf. Ogata, 1988) of a twinstim, i.e. the ### fitted cumulative intensity of the ground process at the event times. ### "generalized residuals similar to those discussed in Cox and Snell (1968)" residuals.twinstim <- function (object, ...) { res <- object$tau if (is.null(res)) { if (is.null(modelenv <- environment(object))) { stop("residuals not available; re-fit the model with 'cumCIF = TRUE'") } else { message("'", substitute(object), "' was fit with disabled 'cumCIF'", " -> calculate it now ...") res <- with(modelenv, LambdagEvents(cumCIF.pb = interactive())) try({ objname <- deparse(substitute(object)) object$tau <- res assign(objname, object, envir = parent.frame()) message("Note: added the 'tau' component to object '", objname, "' for future use.") }, silent = TRUE) } } return(res) } ###################################################################### # Function to compute estimated and profile likelihood based # confidence intervals. Heavy computations might be necessary! # #Params: # fitted - output from a fit with twinstim # profile - list with 4D vector as entries - format: # c(index, lower, upper, grid size) # where index is the index in the coef vector # lower and upper are the parameter limits (can be NA) # grid size is the grid size of the equally spaced grid # between lower and upper (can be 0) # alpha - (1-alpha)% profile likelihood CIs are computed. # If alpha <= 0 then no CIs are computed # control - control object to use for optim in the profile loglik computations # # Returns: # list with profile loglikelihood evaluations on the grid # and highest likelihood and wald confidence intervals ###################################################################### profile.twinstim <- function (fitted, profile, alpha = 0.05, control = list(fnscale = -1, maxit = 100, trace = 1), do.ltildeprofile=FALSE, ...) { warning("the profile likelihood implementation is experimental") ## the implementation below is not well tested, simply uses optim (ignoring ## optimizer settings from the original fit), and does not store the complete ## set of coefficients ## Check that input is ok profile <- as.list(profile) if (length(profile) == 0L) { stop("nothing to do") } lapply(profile, function(one) { if (length(one) != 4L) { stop("each profile entry has to be of form ", "'c(index, lower, upper, grid size)'") }}) if (is.null(fitted[["functions"]])) { stop("'fitted' must contain the component 'functions' -- fit using the option model=TRUE") } ## Control of the optim procedure if (is.null(control[["fnscale",exact=TRUE]])) { control$fnscale <- -1 } if (is.null(control[["maxit",exact=TRUE]])) { control$maxit <- 100 } if (is.null(control[["trace",exact=TRUE]])) { control$trace <- 1 } ## Estimated normalized likelihood function ltildeestim <- function(thetai,i) { theta <- theta.ml theta[i] <- thetai fitted$functions$ll(theta) - loglik.theta.ml } ## Profile normalized likelihood function ltildeprofile <- function(thetai,i) { #cat("Investigating theta[",i,"] = ",thetai,"\n") emptyTheta <- rep(0, length(theta.ml)) # Likelihood l(theta_{-i}) = l(theta_i, theta_i) ltildethetaminusi <- function(thetaminusi) { theta <- emptyTheta theta[-i] <- thetaminusi theta[i] <- thetai #cat("Investigating theta = ",theta,"\n") res <- fitted$functions$ll(theta) - loglik.theta.ml #cat("Current ltildethetaminusi value: ",res,"\n") return(res) } # Score function of all params except thetaminusi stildethetaminusi <- function(thetaminusi) { theta <- emptyTheta theta[-i] <- thetaminusi theta[i] <- thetai res <- fitted$functions$sc(theta)[-i] #cat("Current stildethetaminusi value: ",res,"\n") return(res) } # Call optim -- currently not adapted to arguments of control arguments # used in the fit resOthers <- tryCatch( optim(par=theta.ml[-i], fn = ltildethetaminusi, gr = stildethetaminusi, method = "BFGS", control = control), error = function(e) list(value=NA)) resOthers$value } ## Initialize theta.ml <- coef(fitted) loglik.theta.ml <- c(logLik(fitted)) se <- sqrt(diag(vcov(fitted))) resProfile <- list() ## Perform profile computations for all requested parameters cat("Evaluating the profile logliks on a grid...\n") for (i in 1:length(profile)) { cat("i= ",i,"/",length(profile),"\n") #Index of the parameter in the theta vector idx <- profile[[i]][1] #If no borders are given use those from wald intervals (unconstrained) if (is.na(profile[[i]][2])) profile[[i]][2] <- theta.ml[idx] - 3*se[idx] if (is.na(profile[[i]][3])) profile[[i]][3] <- theta.ml[idx] + 3*se[idx] #Evaluate profile loglik on a grid (if requested) if (profile[[i]][4] > 0) { thetai.grid <- seq(profile[[i]][2],profile[[i]][3],length.out=profile[[i]][4]) resProfile[[i]] <- matrix(NA, nrow = length(thetai.grid), ncol = 4L, dimnames = list(NULL, c("grid","profile","estimated","wald"))) #Loop over all gridpoints for (j in 1:length(thetai.grid)) { cat("\tj= ",j,"/",length(thetai.grid),"\n") resProfile[[i]][j,] <- c(thetai.grid[j], #Do we need to compute ltildeprofile (can be quite time consuming) if (do.ltildeprofile) ltildeprofile(thetai.grid[j],idx) else NA_real_, ltildeestim(thetai.grid[j],idx), - 1/2*(1/se[idx]^2)*(thetai.grid[j] - theta.ml[idx])^2) } } } names(resProfile) <- names(theta.ml)[sapply(profile, function(x) x[1L])] ############################### ## Profile likelihood intervals ############################### # Not done, yet ciProfile <- NULL ####Done, return return(list(lp=resProfile, ci.hl=ciProfile, profileObj=profile)) } ### update-method for the twinstim-class ## stats::update.default would also work but is not adapted to the specific ## structure of twinstim: optim.args (use modifyList), two formulae, model, ... ## However, this specific method is inspired by and copies small parts of the ## update.default method from the stats package developed by The R Core Team update.twinstim <- function (object, endemic, epidemic, control.siaf, optim.args, model, ..., use.estimates = TRUE, evaluate = TRUE) { call <- object$call thiscall <- match.call(expand.dots=FALSE) extras <- thiscall$... if (!missing(model)) { call$model <- model ## Special case: update model component ONLY if (evaluate && all(names(thiscall)[-1] %in% c("object", "model", "evaluate"))) { return(.update.twinstim.model(object, model)) } } ## Why we no longer use call$endemic but update object$formula$endemic: ## call$endemic would be an unevaluated expression eventually receiving the ## parent.frame() as environment, cp.: ##(function(e) {ecall <- match.call()$e; eval(call("environment", ecall))})(~1+start) ## This could cause large files if the fitted model is saved. ## Furthermore, call$endemic could refer to some object containing ## the formula, which is no longer visible. call$endemic <- if (missing(endemic)) object$formula$endemic else update.formula(object$formula$endemic, endemic) call$epidemic <- if (missing(epidemic)) object$formula$epidemic else update.formula(object$formula$epidemic, epidemic) ## Note: update.formula uses terms.formula(...,simplify=TRUE), but ## the principle order of terms is retained. Offsets will be moved to ## the end and a missing intercept will be denoted by a final -1. if (!missing(control.siaf)) { if (is.null(control.siaf)) { call$control.siaf <- NULL # remove from call, i.e., use defaults } else { call$control.siaf <- object$control.siaf # =NULL if constantsiaf call$control.siaf[names(control.siaf)] <- control.siaf } } call["optim.args"] <- if (missing(optim.args)) object["optim.args"] else { list( # use list() to enable optim.args=NULL if (is.list(optim.args)) { modifyList(object$optim.args, optim.args) } else optim.args # = NULL ) } ## Set initial values (will be appropriately subsetted and/or extended with ## zeroes inside twinstim()) call$start <- if (missing(optim.args) || (!is.null(optim.args) && !"par" %in% names(optim.args))) { ## old optim.args$par probably doesn't match updated model, ## thus we set it as "start"-argument call$optim.args$par <- NULL if (use.estimates) coef(object) else object$optim.args$par } else NULL if ("start" %in% names(extras)) { newstart <- check_twinstim_start(eval.parent(extras$start)) call$start[names(newstart)] <- newstart extras$start <- NULL } ## CAVE: the remainder is copied from stats::update.default (as at R-2.15.0) if(length(extras)) { existing <- !is.na(match(names(extras), names(call))) ## do these individually to allow NULL to remove entries. for (a in names(extras)[existing]) call[[a]] <- extras[[a]] if(any(!existing)) { call <- c(as.list(call), extras[!existing]) call <- as.call(call) } } if(evaluate) eval(call, parent.frame()) else call } .update.twinstim.model <- function (object, model) { call <- object$call call$model <- model if (model) { # add model environment call$start <- coef(object) call$optim.args$fixed <- TRUE call$cumCIF <- FALSE call$verbose <- FALSE ## evaluate in the environment calling update.twinstim() message("Setting up the model environment ...") objectWithModel <- eval(call, parent.frame(2L)) ## add the model "functions" and environment object$functions <- objectWithModel$functions environment(object) <- environment(objectWithModel) } else { # remove model environment object["functions"] <- list(NULL) environment(object) <- NULL } object$call$model <- model object } ## a terms-method is required for stepComponent() terms.twinstim <- function (x, component=c("endemic", "epidemic"), ...) { component <- match.arg(component) terms.formula(x$formula[[component]], keep.order=TRUE) } ## compare two twinstim fits ignoring at least the "runtime" and the "call" ## just like all.equal.hhh4() all.equal.twinstim <- function (target, current, ..., ignore = NULL) { if (!inherits(target, "twinstim")) return("'target' is not a \"twinstim\" object") if (!inherits(current, "twinstim")) return("'current' is not a \"twinstim\" object") ignore <- unique.default(c(ignore, "runtime", "call")) target[ignore] <- current[ignore] <- list(NULL) ## also ignore siaf.step() cache ("cachem" is time-dependent) drop_cache <- function (siaf) { isStepFun <- !is.null(knots <- attr(siaf, "knots")) && !is.null(maxRange <- attr(siaf, "maxRange")) if (isStepFun) { structure(list(), knots = knots, maxRange = maxRange) } else siaf } target$formula$siaf <- drop_cache(target$formula$siaf) current$formula$siaf <- drop_cache(current$formula$siaf) NextMethod("all.equal") } surveillance/R/stsplot_time.R0000644000176200001440000003736414615162374016046 0ustar liggesusers################################################################################ ### Time series plot for sts-objects ### ### Copyright (C) 2007-2014 Michael Hoehle, 2013-2016,2021-2022 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ###################################################################### # stsplot_time() sets the scene and calls either stsplot_time_as1() # or stsplot_time1() for each unit ###################################################################### stsplot_time <- function(x, units = NULL, as.one = FALSE, same.scale = TRUE, par.list = list(), ...) { observed <- x@observed if (is.null(units)) # plot all units units <- seq_len(ncol(observed)) nUnits <- length(units) #graphical parameters if (is.list(par.list)) { if (nUnits > 1 && !as.one) { par.list <- modifyList( #default: reduced margins and mfrow panels list(mar = c(5,4,1,1), mfrow = magic.dim(nUnits)), par.list) } else { par.list$mfrow <- NULL #no mf formatting.. } if (length(par.list) > 0) { oldpar <- par(par.list) on.exit(par(oldpar)) } } if (nUnits == 1L) { # a single time-series plot stsplot_time1(x = x, k = units, ...) } else { # multiple time series if (as.one) { # all time series in one plot stsplot_time_as1(x, units = units, ...) } else { # each time series in a separate plot args <- list(...) if(same.scale) { # compute suitable ylim if not specified if (is.null(args[["ylim"]])) { ymax <- if (x@multinomialTS) { max(0, pmax(observed,x@upperbound,na.rm=TRUE)/x@populationFrac, na.rm=TRUE) } else { max(observed,x@upperbound,na.rm=TRUE) } args$ylim <- c(-1/20*ymax, ymax) } } else { args$ylim <- NULL } #plot areas for (k in units) { argsK <- modifyList(args, list(x=x, k=k, main="", legend.opts=NULL), keep.null = TRUE) do.call("stsplot_time1",args=argsK) title(main=if (is.character(k)) k else colnames(observed)[k], line=-1) } } } invisible() } ## a simple matplot of observed counts from all/selected units, with a legend stsplot_time_as1 <- function (x, units = NULL, type = "l", lty = 1:5, lwd = 1, col = 1:6, epochsAsDate = x@epochAsDate, xaxis.tickFreq = list("%Q"=atChange), xaxis.labelFreq = xaxis.tickFreq, xaxis.labelFormat = "%G\n\n%OQ", xlab = "time", ylab = "No. infected", legend.opts = list(), ...) { observed <- x@observed if (x@multinomialTS) { observed <- ifelse(x@populationFrac != 0, observed/x@populationFrac, 0) } if (!is.null(units)) observed <- observed[, units, drop = FALSE] ## basic plot opar <- par(bty = "n", xaxt = "n") # a formatted time axis is added below matplot(observed, type = type, lty = lty, lwd = lwd, col = col, xlab = xlab, ylab = ylab, ...) par(opar) ## add time axis xaxis.line <- !epochsAsDate || grepl("\n", xaxis.labelFormat) addFormattedXAxis(x = x, epochsAsDate = epochsAsDate, xaxis.tickFreq = xaxis.tickFreq, xaxis.labelFreq = xaxis.labelFreq, xaxis.labelFormat = xaxis.labelFormat) # line = 1 ## add legend if (is.list(legend.opts)) { legend.opts <- modifyList( list(x = "top", legend = colnames(observed), lty = lty, lwd = lwd, col = col, ncol = magic.dim(ncol(observed))[2L], bty = "n"), legend.opts) do.call("legend", legend.opts) } invisible() } ### work-horse which produces a single time series plot with formatted x-axis stsplot_time1 <- function( x, k=1, ylim=NULL, axes=TRUE, xaxis.tickFreq=list("%Q"=atChange), xaxis.labelFreq=xaxis.tickFreq, xaxis.labelFormat="%G\n\n%OQ", epochsAsDate=x@epochAsDate, xlab="time", ylab="No. infected", main=NULL, type="s", lty=c(1,1,2), col=c(NA,1,4), lwd=c(1,1,1), outbreak.symbol=list(pch=3, col=3, cex=1, lwd=1), alarm.symbol=list(pch=24, col=2, cex=1, lwd=1), legend.opts=list(), dx.upperbound=0L, hookFunc=function(){}, .hookFuncInheritance=function() {}, ...) { stopifnot(length(k) == 1, is.character(k) || k != 0) #Extract slots -- depending on the algorithms: x@control$range observed <- x@observed[,k] state <- x@state[,k] alarm <- x@alarm[,k] upperbound <- x@upperbound[,k] population <- x@populationFrac[,k] binaryTS <- x@multinomialTS #Control what axis style is used xaxis.dates <- !is.null(xaxis.labelFormat) if (binaryTS) { observed <- ifelse(population!=0,observed/population,0) upperbound <- ifelse(population!=0,upperbound/population,0) if (ylab == "No. infected") { ylab <- "Proportion infected" } } ##### Handle the NULL arguments ###################################### if (is.null(main) && length(method <- x@control$name)) { #a surveillance algorithm has been run action <- switch(class(x), "sts" = "surveillance", "stsNC" = "nowcasting","stsBP" = "backprojection") main <- paste0(action, " using ", method) } #if ylim is not specified, give it a default value if(is.null(ylim)){ ymax <- max(c(observed,upperbound),na.rm=TRUE) ylim <- c(-1/20*ymax, ymax) } # left/right help for constructing the columns dx.observed <- 0.5 upperboundx <- (1:length(upperbound)) - (dx.observed - dx.upperbound) #Generate the matrices to plot (values,last value) xstuff <- cbind(c(upperboundx,length(observed) + min(1-(dx.observed - dx.upperbound),0.5))) ystuff <-cbind(c(upperbound,upperbound[length(observed) ])) #Plot the results if (length(lty) < 3) lty[3] <- 0 # blank upperbound matplot(x=xstuff,y=ystuff,xlab=xlab,ylab=ylab,main=main,ylim=ylim,axes = !(xaxis.dates),type=type,lty=lty[-c(1:2)],col=col[-c(1:2)],lwd=lwd[-c(1:2)],...) #This draws the polygons containing the number of counts (sep. by NA) i <- rep(1:length(observed),each=5) dx <- rep(dx.observed * c(-1,-1,1,1,NA), times=length(observed)) x.points <- i + dx y.points <- as.vector(t(cbind(0, observed, observed, 0, NA))) polygon(x.points,y.points,col=col[1],border=col[2],lwd=lwd[1],lty=lty[1]) #Draw upper bound once more in case the polygons are filled if (!is.na(col[1])) { lines(x=xstuff,y=ystuff,type=type,lty=lty[-c(1:2)],col=col[-c(1:2)],lwd=lwd[-c(1:2)],...) } #Draw alarm symbols alarmIdx <- which(alarm == 1) if (length(alarmIdx)>0) { matpoints( alarmIdx, rep(-1/40*ylim[2],length(alarmIdx)), pch=alarm.symbol$pch, col=alarm.symbol$col, cex= alarm.symbol$cex, lwd=alarm.symbol$lwd) } #Draw outbreak symbols stateIdx <- which(state == 1) if (length(stateIdx)>0) { matpoints( stateIdx, rep(-1/20*ylim[2],length(stateIdx)), pch=outbreak.symbol$pch, col=outbreak.symbol$col,cex = outbreak.symbol$cex,lwd=outbreak.symbol$lwd) } #Label x-axis if(xaxis.dates & axes) { addFormattedXAxis(x = x, epochsAsDate = epochsAsDate, xaxis.tickFreq = xaxis.tickFreq, xaxis.labelFreq = xaxis.labelFreq, xaxis.labelFormat = xaxis.labelFormat, ...) } #Label y-axis if (axes) { axis( side=2 ,...) } hasupper <- any(upperbound > 0, na.rm = TRUE) included <- c(observed = TRUE, upperbound = hasupper, outbreaks = length(stateIdx) > 0, alarms = hasupper || length(alarmIdx) > 0) doLegend <- if (missing(legend.opts)) { sum(included) > 1 } else { is.list(legend.opts) } if(doLegend) { ## FIXME: use method-specific default upperbound label? ## ublegend <- if (identical(x@control[["ret"]], "value") && ## startsWith(x@control$name, "glr")) ## "GLR statistic" else "Threshold" if (!is.na(col[1])) { # filled polygons ltyObs <- NA pchObs <- 22 fillObs <- col[1] } else { ltyObs <- lty[1] pchObs <- NA fillObs <- NA } legend.opts <- modifyList( list(x = "top", lty = c(ltyObs,lty[3],NA,NA)[included], lwd = c(lwd[1],lwd[3],outbreak.symbol$lwd,alarm.symbol$lwd)[included], col = c(col[2],col[3],outbreak.symbol$col,alarm.symbol$col)[included], pch = c(pchObs,NA, outbreak.symbol$pch,alarm.symbol$pch)[included], pt.bg = c(fillObs,NA,NA,NA)[included], legend = c("Infected", "Threshold", "Outbreak", "Alarm")[included]), legend.opts) #Make the legend do.call("legend",legend.opts) } #Call hook function for user customized action using the current environment environment(hookFunc) <- environment() hookFunc() #Extra hook functions for inheritance plotting (see e.g. plot function of stsNC objects) environment(.hookFuncInheritance) <- environment() .hookFuncInheritance() invisible() } ############## ### alarm plot ############## stsplot_alarm <- function( x, lvl=rep(1,ncol(x)), xaxis.tickFreq=list("%Q"=atChange), xaxis.labelFreq=xaxis.tickFreq, xaxis.labelFormat="%G\n\n%OQ", epochsAsDate=x@epochAsDate, xlab="time", ylab="", main=NULL, outbreak.symbol=list(pch=3, col=3, cex=1, lwd=1), # unused alarm.symbol=list(pch=24, col=2, cex=1, lwd=1), cex.yaxis=1, ...) { if (is.null(main) && length(method <- x@control$name)) { #a surveillance algorithm has been run action <- switch(class(x), "sts" = "surveillance", "stsNC" = "nowcasting","stsBP" = "backprojection") main <- paste0(action, " using ", method) } #Control what axis style is used xaxis.dates <- !is.null(xaxis.labelFormat) #Initialize plot plot(x=c(0.5,nrow(x)+0.5),y=c(0.5,ncol(x)),xlab=xlab,ylab=ylab,main=main,axes=FALSE,type="n",...) #Label of x-axis if(xaxis.dates){ addFormattedXAxis(x = x, epochsAsDate = epochsAsDate, xaxis.tickFreq = xaxis.tickFreq, xaxis.labelFreq = xaxis.labelFreq, xaxis.labelFormat = xaxis.labelFormat, ...) } axis( side=2, at=1:ncol(x),cex.axis=cex.yaxis, labels=colnames(x),las=2) #Draw all alarms for (i in 1:nrow(x)) { idx <- (1:ncol(x))[x@alarm[i,] > 0] for (j in idx) { points(i,j,pch=alarm.symbol$pch,col=alarm.symbol$col[lvl[j]],cex=alarm.symbol$cex,lwd=alarm.symbol$lwd) } } #Draw lines separating the levels m <- c(-0.5,cumsum(as.numeric(table(lvl)))) sapply(m, function(i) lines(c(0.5,nrow(x@alarm)+0.5),c(i+0.5,i+0.5),lwd=2)) invisible() } ##################################### ### Utilities to set up the time axis ##################################### #Every unit change atChange <- function(x,xm1) { which(diff(c(xm1,x)) != 0) } #Median index of factor atMedian <- function(x,xm1) { as.integer(tapply(seq_along(x), INDEX=x, quantile, probs=0.5, type=3)) } #Only every second unit change at2ndChange <- function(x,xm1) { idxAtChange <- atChange(x,xm1) idxAtChange[seq(idxAtChange) %% 2 == 1] } #Helper function to format the x-axis of the time series addFormattedXAxis <- function(x, epochsAsDate = FALSE, xaxis.tickFreq = list("%Q"=atChange), xaxis.labelFreq = xaxis.tickFreq, xaxis.labelFormat = "%G\n\n%OQ", ...) { #Old style if there are no Date objects if (!epochsAsDate) { #Declare commonly used variables. nTime <- nrow(x) startyear <- x@start[1] firstweek <- x@start[2] if (x@freq ==52) { #Weekly epochs are the most supported # At which indices to put the "at" tick label. This will # be exactly those week numbers where the new quarter begins: 1, 14, 27 and 40 + i*52. # Note that week number and index is not the same due to the "firstweek" argument weeks <- seq_len(nTime) + (firstweek-1) noYears <- ceiling(max(weeks)/52) quarterStarts <- rep( (0:(noYears))*52, each=4) + rep( c(1,14,27,40), noYears+1) weeks <- subset(weeks, !is.na(match(weeks,quarterStarts))) weekIdx <- weeks - (firstweek-1) # get the right year for each week year <- weeks %/% 52 + startyear # function to define the quarter order quarterFunc <- function(i) { switch(i+1,"I","II","III","IV") } #nicer:as.roman, but changes class. # get the right number and order of quarter labels quarter <- sapply( (weeks-1) %/% 13 %% 4, quarterFunc) #Computed axis labels -- add quarters (this is the old style) labels.week <- paste(year,"\n\n",quarter,sep="") #Make the line. Use lwd.ticks to get full line but no marks. axis( side=1,labels=FALSE,at=c(1,nTime),lwd.ticks=0,line=1,...) axis( at=weekIdx[which(quarter != "I")] , labels=labels.week[which(quarter != "I")] , side=1, line = 1 ,...) #Bigger tick marks at the first quarter (i.e. change of the year) at <- weekIdx[which(quarter == "I")] axis( at=at, labels=rep(NA,length(at)), side=1, line = 1 ,tcl=2*par("tcl")) } else { ##other frequency (not really supported) #A label at each unit myat.unit <- seq(firstweek,length.out=nTime) # get the right year order month <- (myat.unit-1) %% x@freq + 1 year <- (myat.unit - 1) %/% x@freq + startyear #construct the computed axis labels -- add quarters if xaxis.units is requested mylabels.unit <- paste(year,"\n\n", (myat.unit-1) %% x@freq + 1,sep="") #Add axis axis( at=seq_len(nTime), labels=NA, side=1, line = 1, ...) axis( at=seq_len(nTime)[month==1], labels=mylabels.unit[month==1] , side=1, line = 1 ,...) #Bigger tick marks at the first unit at <- seq_len(nTime)[(myat.unit - 1) %% x@freq == 0] axis( at=at, labels=rep(NA,length(at)), side=1, line = 1 ,tcl=2*par("tcl")) } } else { ################################################################ #epochAsDate -- experimental functionality to handle ISO 8601 ################################################################ dates <- epoch(x, as.Date = TRUE) #make one which has one extra element at beginning with same spacing datesOneBefore <- c(dates[1]-(dates[2]-dates[1]),dates) #Make the line. Use lwd.ticks to get full line but no marks. axis( side=1,labels=FALSE,at=c(1,length(dates)),lwd.ticks=0,...) ###Make the ticks (depending on the selected level).### tcl <- par("tcl") tickFactors <- surveillance.options("stsTickFactors") #Loop over all pairs in the xaxis.tickFreq list for (i in seq_along(xaxis.tickFreq)) { format <- names(xaxis.tickFreq)[i] xm1x <- as.numeric(formatDate(datesOneBefore,format)) idx <- xaxis.tickFreq[[i]](x=xm1x[-1],xm1=xm1x[1]) #Find tick size by table lookup tclFactor <- tickFactors[pmatch(format, names(tickFactors))] if (is.na(tclFactor)) { warning("no \"tcl\" factor found for \"", format ,"\" -> setting it to 1") tclFactor <- 1 } axis(1,at=idx, labels=NA,tcl=tclFactor*tcl,...) } ###Make the labels (depending on the selected level)### if (!is.null(xaxis.labelFormat)) { labelIdx <- NULL for (i in seq_along(xaxis.labelFreq)) { format <- names(xaxis.labelFreq)[i] xm1x <- as.numeric(formatDate(datesOneBefore,format)) labelIdx <- c(labelIdx,xaxis.labelFreq[[i]](x=xm1x[-1],xm1=xm1x[1])) } #Format labels (if any) for the requested subset if (length(labelIdx)>0) { labels <- rep(NA,nrow(x)) labels[labelIdx] <- formatDate(dates[labelIdx],xaxis.labelFormat) axis(1,at=1:nrow(x), labels=labels,tick=FALSE,...) } } }#end epochAsDate #Done invisible() } surveillance/R/twinstim_simulation.R0000644000176200001440000015257614426171115017436 0ustar liggesusers################################################################################ ### Simulate a point pattern according to a spatio-temporal intensity model of ### class "twinstim". The function basically uses Ogata's modified thinning ### algorithm (cf. Daley & Vere-Jones, 2003, Algorithm 7.5.V.). ### ### Copyright (C) 2010-2018,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### CAVE: ### - the type of contrasts for factor variables has to be set through options("contrasts") ### - if epidemic-only process (!hash), we actually don't need stgrid, but we ### want to have valid epidataCS at the end, which requires stgrid ## model.frame() evaluates '...' with 'data' utils::globalVariables(c("BLOCK", "tile", "area")) simEpidataCS <- function (endemic, epidemic, siaf, tiaf, qmatrix, rmarks, events, stgrid, tiles, beta0, beta, gamma, siafpars, tiafpars, epilink = "log", t0 = stgrid$start[1], T = tail(stgrid$stop,1), nEvents = 1e5, control.siaf = list(F=list(), Deriv=list()), W = NULL, trace = 5, nCircle2Poly = 32, gmax = NULL, .allocate = 500, .skipChecks = FALSE, .onlyEvents = FALSE) { ptm <- proc.time()[[3]] cl <- match.call() ####################### ### Check arguments ### (this takes many lines of code ...) ####################### cat("\nChecking the supplied arguments ...\n") ### Some simple input checks if (missing(endemic)) endemic <- ~ 0 else stopifnot(inherits(endemic, "formula")) if (missing(epidemic)) epidemic <- ~ 0 else stopifnot(inherits(epidemic, "formula")) if (length(trace) != 1L) stop("'trace' must be a single integer or logical value") trace <- as.integer(trace) if (!isScalar(nCircle2Poly)) stop("'nCircle2Poly' must be scalar") nCircle2Poly <- as.integer(nCircle2Poly) if (!isScalar(.allocate)) stop("'.allocate' must be scalar") .allocate <- as.integer(.allocate) .skipChecks <- as.logical(.skipChecks) .onlyEvents <- as.logical(.onlyEvents) ### Check qmatrix if (missing(qmatrix)) qmatrix <- diag(1) nTypes <- nrow(qmatrix) if (is.null(typeNames <- rownames(qmatrix))) { if (nTypes > length(LETTERS)) stop("'qmatrix' needs dimnames") typeNames <- LETTERS[seq_len(nTypes)] } qmatrix <- checkQ(qmatrix, typeNames) qSumTypes <- rowSums(qmatrix) # how many types can be triggered by each type ### Check other "epidataCS" components (events, stgrid, tiles, and W) if (!missing(events) && !is.null(events)) { events <- events[!names(events) %in% reservedColsNames_events] if (!.skipChecks) { cat("Checking 'events':\n") events <- check_events(events, dropTypes = FALSE) # epscols are obligatory in 'check_events', which is also appropriate here } ## check event types events@data$type <- factor(events@data$type, levels=typeNames) if (any(.typeIsNA <- is.na(events@data$type))) { warning("ignored some 'events' of unknown type") events <- events[!.typeIsNA,] } } if (!.skipChecks) { cat("Checking 'stgrid':\n") stgrid <- check_stgrid(stgrid[grep("^BLOCK$", names(stgrid), invert=TRUE)]) } if (!is.null(W)) { W <- check_W(W) # does as(W, "SpatialPolygons") } if (!.skipChecks) { cat("Checking 'tiles' ...\n") ## we always check 'tiles', but quietly in the simulate-method } tileLevels <- levels(stgrid$tile) tiles <- check_tiles(tiles, tileLevels, areas.stgrid = stgrid[["area"]][seq_along(tileLevels)], W = W, keep.data = FALSE) if (is.null(W)) { cat("Building 'W' as the union of 'tiles' ...\n") W <- unionSpatialPolygons(tiles) } ## empty CRS to avoid costly intermediate CRS checks (and rgdal warnings) if (!missing(events) && !is.null(events)) stopifnot(identicalCRS(tiles, events)) tiles@proj4string <- events@proj4string <- new("CRS") ## Transform W to class "owin" Wowin <- SpP2owin(W) maxExtentOfW <- diameter.owin(Wowin) ### Check parameters beta0 <- if (missing(beta0)) numeric(0L) else as.vector(beta0, mode="numeric") beta <- if (missing(beta)) numeric(0L) else as.vector(beta, mode="numeric") gamma <- if (missing(gamma)) numeric(0L) else as.vector(gamma, mode="numeric") siafpars <- if (missing(siafpars)) numeric(0L) else as.vector(siafpars, mode="numeric") tiafpars <- if (missing(tiafpars)) numeric(0L) else as.vector(tiafpars, mode="numeric") nbeta0 <- length(beta0) if (nbeta0 > 1L && nbeta0 != nTypes) { stop("'beta0' must have length 0, 1, or 'nrow(qmatrix)'") } p <- length(beta) q <- length(gamma) nsiafpars <- length(siafpars) ntiafpars <- length(tiafpars) hase <- q > 0L hassiafpars <- nsiafpars > 0L hastiafpars <- ntiafpars > 0L if (!hase && (hassiafpars | hastiafpars)) { stop("'siafpars' and 'tiafpars' require 'gamma'") } ### Check time range if (is.null(t0)) t0 <- eval(formals()$t0) if (is.null(T)) T <- eval(formals()$T) if (!isScalar(t0) || !isScalar(T)) { stop("endpoints 't0' and 'T' must be single numbers") } if (T <= t0) { stop("'T' must be greater than 't0'") } stopifnot(t0 >= stgrid$start[1], T <= tail(stgrid$stop,1)) ### Subset stgrid to include actual time range only # BLOCK in stgrid such that start time is equal to or just before t0 block_t0 <- stgrid$BLOCK[match(TRUE, c(stgrid$start,Inf) > t0) - 1L] # BLOCK in stgrid such that stop time is equal to or just after T block_T <- stgrid$BLOCK[match(TRUE, stgrid$stop >= T)] stgrid <- stgrid[stgrid$BLOCK>=block_t0 & stgrid$BLOCK<=block_T,,drop=FALSE] stgrid$start[stgrid$BLOCK == block_t0] <- t0 stgrid$stop[stgrid$BLOCK == block_T] <- T # matrix of BLOCKS and start times (used later) blockstarts <- with(stgrid, cbind(block_t0:block_T, start[match(block_t0:block_T, BLOCK)], deparse.level = 0L) ) ### Check mark-generating function # eps.t and eps.s are also unpredictable marks (generated by rmarks) unpredMarks <- unique(c("eps.t", "eps.s", if (hase) { setdiff(all.vars(epidemic), c("type", names(stgrid))) })) rmarks <- match.fun(rmarks) sampleCoordinate <- coordinates(spsample(tiles, n=1L, type="random")) sampleMarks <- rmarks(t0, sampleCoordinate) # should be a one-row data.frame if (!is.data.frame(sampleMarks) || nrow(sampleMarks) != 1L) { stop("'rmarks' must return a one-row data.frame of marks") } markNames <- names(sampleMarks) if (.idx <- match(FALSE, unpredMarks %in% markNames, nomatch=0L)) { stop("the unpredictable mark '", unpredMarks[.idx], "' is not returned by 'rmarks'") } if (!all(sapply(sampleMarks[unpredMarks], function(x) inherits(x, c("integer","numeric","logical","factor"), which=FALSE)))) warning("'rmarks' should return \"numeric\", \"logical\", or", " \"factor\" ('epidemic') variables only") ### Check prehistory of the process Nout <- 0L if (!missing(events) && !is.null(events)) { .stillInfective <- with(events@data, time <= t0 & time + eps.t > t0) Nout <- sum(.stillInfective) events <- if (Nout > 0L) { events[.stillInfective,] } else { .eventstxt <- if (.skipChecks) "data$events" else "events" # for simulate.twinstim cat("(no events from '", .eventstxt, "' were considered as prehistory)\n", sep="") NULL } } ## separate coordinates and data if (Nout > 0L) { check_tiles_events(tiles, events) eventCoords <- coordinates(events) rownames(eventCoords) <- NULL # to avoid duplicates ("" for new events) # which disturb the final SpatialPointsDataFrame() eventData <- events@data ## check presence of unpredictable marks if (length(.idx <- which(!unpredMarks %in% names(eventData)))) { stop("missing unpredictable marks in 'events': ", paste0("\"", unpredMarks[.idx], "\"", collapse=", ")) } ## check type of unpredictable marks for (um in unpredMarks) { if (!identical(class(sampleMarks[[um]]), class(eventData[[um]]))) stop("the class of the unpredictable mark '", um, "' in the 'events' prehistory ", "is not identical to the class returned by 'rmarks'") } ## add marks which are not in the prehistory but simulated by 'rmarks' if (length(.add2events <- setdiff(markNames, names(eventData)))) { eventData <- cbind(eventData, sampleMarks[.add2events]) is.na(eventData[.add2events]) <- TRUE } eventData <- eventData[c("time", "tile", "type", markNames)] } else { ## empty prehistory eventCoords <- matrix(0, nrow=0L, ncol=2L) eventData <- data.frame( time = numeric(0L), tile = factor(character(0L), levels=tileLevels), type = factor(character(0L), levels=typeNames), check.rows = FALSE, check.names = FALSE ) eventData <- cbind(eventData, sampleMarks[0L,]) } ## helper function to attach covariates from 'stgrid' to events attachstgridvars <- function (eventData, stgridvars) { if (length(stgridvars) == 0L) return(eventData) gridcellsOfEvents <- integer(nrow(eventData)) for (i in seq_along(gridcellsOfEvents)) { gridcellsOfEvents[i] <- gridcellOfEvent(eventData[i,"time"], eventData[i,"tile"], stgrid) } cbind(eventData, stgrid[gridcellsOfEvents, stgridvars, drop=FALSE]) } ### Build epidemic model matrix epidemic <- terms(epidemic, data = eventData, keep.order = TRUE) if (!is.null(attr(epidemic, "offset"))) { warning("offsets are not implemented for the 'epidemic' component") } # helper function taking eventData and returning the epidemic model.matrix buildmme <- function (eventData) { # which variables do we have to copy from stgrid? stgridCopyCols <- match(all.vars(epidemic), names(stgrid), nomatch = 0L) eventData <- attachstgridvars(eventData, stgridCopyCols) mfe <- model.frame(epidemic, data = eventData, na.action = na.fail, drop.unused.levels = FALSE) model.matrix(epidemic, mfe) } mme <- buildmme(eventData) if (ncol(mme) != q) { cat(ncol(mme), "epidemic model terms:\t", paste(colnames(mme), collapse=" "), "\n") stop("length of 'gamma' (", q, ") does not match the 'epidemic' specification (", ncol(mme), ")") } ## (inverse) link function for the epidemic linear predictor of event marks epilink <- match.arg(epilink, choices = c("log", "identity")) epilinkinv <- switch(epilink, "log" = exp, "identity" = identity) ### Build endemic model matrix endemic <- terms(endemic, data = stgrid, keep.order = TRUE) # check if we have an endemic component at all hasOffset <- !is.null(attr(endemic, "offset")) hash <- (nbeta0 + p + hasOffset) > 0L if (!hash) { if (!hase) { stop("nothing to do: neither endemic nor epidemic parameters were specified") # actually, the process might be endemic offset-only, which I don't care about ATM } if (Nout == 0L) { stop("missing 'events' prehistory (no endemic component)") } } # remove (1|type) specification typeSpecificEndemicIntercept <- "1 | type" %in% attr(endemic, "term.labels") || nbeta0 > 1 if (typeSpecificEndemicIntercept) { endemic <- update.formula(endemic, ~ . - (1|type)) # this drops the terms attributes endemic <- terms(endemic, data = stgrid, keep.order = TRUE) if (nbeta0 <= 1L) { stop("for type-specific endemic intercepts, 'beta0' must be longer than 1") } } # ensure that we have correct contrasts in the endemic component attr(endemic, "intercept") <- as.integer(nbeta0 > 0L) # helper function taking eventData (with time and tile columns) # and returning the endemic model.matrix buildmmh <- function (eventData) { # if 'pi' appears in 'endemic' we don't care, and if a true covariate is # missing, model.frame will throw an error # which variables do we have to copy from stgrid? stgridCopyCols <- match(all.vars(endemic), names(stgrid), nomatch = 0L) # attaching covariates from 'stgrid' to events eventData <- attachstgridvars(eventData, stgridCopyCols) # construct model matrix mfhEvents <- model.frame(endemic, data = eventData, na.action = na.fail, drop.unused.levels = FALSE) mmhEvents <- model.matrix(endemic, mfhEvents) # exclude intercept from endemic model matrix below, will be treated separately if (nbeta0 > 0) mmhEvents <- mmhEvents[,-1,drop=FALSE] structure(mmhEvents, offset = model.offset(mfhEvents)) } # actually, we don't need the endemic model matrix for the prehistory events at all # this is just to test consistence with 'beta' and for the names of 'beta' mmh <- buildmmh(eventData[0L,]) if (ncol(mmh) != p) { stop("length of 'beta' (", p, ") does not match the 'endemic' specification (", ncol(mmh), ")") } ### Build endemic model matrix on stgrid mfhGrid <- model.frame(endemic, data = stgrid, na.action = na.fail, drop.unused.levels = FALSE, BLOCK = BLOCK, tile = tile, ds = area) # we don't actually need 'tile' in mfhGrid; this is only for easier identification when debugging mmhGrid <- model.matrix(endemic, mfhGrid) # exclude intercept from endemic model matrix below, will be treated separately if (nbeta0 > 0) mmhGrid <- mmhGrid[,-1,drop=FALSE] # Extract endemic model components offsetGrid <- model.offset(mfhGrid) gridBlocks <- mfhGrid[["(BLOCK)"]] ds <- mfhGrid[["(ds)"]] ### Parse interaction functions if (hase) { ## Check interaction functions siaf <- do.call(".parseiaf", args = alist(siaf, "siaf", verbose=trace>0)) constantsiaf <- attr(siaf, "constant") if (siaf$npars != nsiafpars) { stop("length of 'siafpars' (", nsiafpars, ") does not match the 'siaf' specification (", siaf$npars, ")") } tiaf <- do.call(".parseiaf", args = alist(tiaf, "tiaf", verbose=trace>0)) constanttiaf <- attr(tiaf, "constant") if (constanttiaf) gmax <- 1L if (tiaf$npars != ntiafpars) { stop("length of 'tiafpars' (", ntiafpars, ") does not match the 'tiaf' specification (", tiaf$npars, ")") } ## Check control.siaf if (constantsiaf) control.siaf <- NULL else { stopifnot(is.null(control.siaf) || is.list(control.siaf)) } ## Define function that integrates the two-dimensional 'siaf' function ## over the influence regions of the events if (!constantsiaf && !is.null(siaf$Fcircle) && !is.null(siaf$effRange)) { ## pre-compute effective range of the 'siaf' (USED BY .siafInt) effRangeTypes <- rep_len(siaf$effRange(siafpars), nTypes) } .siafInt <- .siafIntFUN(siaf = siaf, noCircularIR = FALSE) # not certain beforehand .siafInt.args <- c(list(siafpars), control.siaf$F) ## Check gmax if (is.null(gmax)) { gmax <- max(tiaf$g(rep.int(0,nTypes), tiafpars, 1:nTypes)) cat("assuming gmax =", gmax, "\n") } else if (!isScalar(gmax)) { stop("'gmax' must be scalar") } } else { if (!missing(siaf) && !is.null(siaf)) warning("'siaf' can only be modelled in conjunction with an 'epidemic' process") if (!missing(tiaf) && !is.null(tiaf)) warning("'tiaf' can only be modelled in conjunction with an 'epidemic' process") siaf <- tiaf <- NULL control.siaf <- NULL } ### print some information on the upcoming simulation txtPrehistory <- if (Nout == 0L) "no prehistory" else paste(Nout, ngettext(Nout, "event", "events"), "in the prehistory") cat("\nSimulating a", if (length(unpredMarks) > 2L) "marked", "spatio-temporal point pattern with", "\n\t-", nTypes, ngettext(nTypes, "event type", "event types"), "\n\t-", txtPrehistory) coefs <- c( if (nbeta0 > 1L) { setNames(beta0, paste0("h.type",typeNames)) } else if (nbeta0 == 1L) setNames(beta0, "h.(Intercept)"), if (p > 0L) setNames(beta, paste("h",colnames(mmh),sep=".")), if (hase) setNames(gamma, paste("e",colnames(mme),sep=".")), if (hassiafpars) setNames(siafpars, paste("e.siaf",1:nsiafpars,sep=".")), if (hastiafpars) setNames(tiafpars, paste("e.tiaf",1:ntiafpars,sep=".")) ) cat("\n\t-", length(coefs), "coefficients:\n\n") print(coefs) ########################################## ### CIF of the temporal ground process ### ########################################## ### calculate integral of endemic component over W (= union of tiles) ### and over types for all time blocks in stgrid hIntWK <- if (hash) { dsexpeta <- local({ eta <- drop(mmhGrid %*% beta) # =0 if p = 0 if (!is.null(offsetGrid)) eta <- offsetGrid + eta ds * exp(unname(eta)) }) fact <- if (nbeta0 > 1L) sum(exp(beta0)) else if (nbeta0 == 1L) nTypes*exp(unname(beta0)) else nTypes fact * c(tapply(dsexpeta, gridBlocks, sum)) } else setNames(numeric(nrow(blockstarts)), blockstarts[,1]) # zeroes #<- is a named vector with names referencing BLOCK in stgrid ### helper function evaluating the epidemic terms of the ground intensity ### for a specific set of events (the lambdag function uses eTerms) eTermsCalc <- function (eventData, eventCoords) { # extract some marks from the eventData (USED INSIDE .siafInt() BELOW!) eventTypes <- as.integer(eventData$type) eps.s <- eventData$eps.s # distance to the border (required for siafInt below, and for epidataCS) bdist <- bdist(eventCoords, Wowin) # spatial influence regions of the events influenceRegion <- if (nrow(eventCoords) > 0L) .influenceRegions( events = SpatialPointsDataFrame( coords = eventCoords, data = data.frame(eps.s = eps.s, .bdist = bdist), match.ID = FALSE ), W = Wowin, npoly = nCircle2Poly, maxExtent = maxExtentOfW, clipper = "polyclip" ) else list() # epidemic terms if (!hase) { return(list(matrix(NA_real_, length(influenceRegion), 3L), bdist, influenceRegion)) } # epidemic model matrix (will be multiplied with gamma) mme <- buildmme(eventData) # integrate the two-dimensional 'siaf' function over the influence region siafInts <- if (length(influenceRegion) == 0L) numeric(0L) else { environment(.siafInt) <- environment() do.call(".siafInt", .siafInt.args) } # Matrix of terms in the epidemic component eTerms <- cbind( qSum = qSumTypes[eventTypes], expeta = epilinkinv(drop(mme %*% gamma)), siafInt = siafInts ) # Return list(eTerms, bdist, influenceRegion) } ### function calculating the (upper bound) intensity of the ground process ### it relies on several objects for the epidemic component which are updated alongside simulation # t will be one of the break points in stgrid or an event time lambdagVec <- function (t, upper=FALSE) { ## endemic part hIntWKt <- hIntWK[[as.character(tBLOCK)]] ## epidemic part ejIntWt <- if (!hase || length(infectives) == 0L) numeric(0L) else { eTerms <- eTerms[infectives,,drop=FALSE] gTerm <- if (upper) { rep.int(gmax, length(infectives)) } else { times <- eventMatrix[infectives,"time"] types <- eventMatrix[infectives,"type"] tiaf$g(t-times, tiafpars, types) } # ejIntWt only for infectives, others have 0 setNames(apply(cbind(eTerms,gTerm), 1, prod), infectives) } c("0"=hIntWKt, ejIntWt) # endemic component has index "0" ! } ### helper function calculating the integral of lambdag from oldct to ct ### during simulation; it depends on the current values of the simulation add2Lambdag <- if (!hase || constanttiaf) { function () lambdagUpper * (ct-oldct) } else function () { # old endemic ground intensity * passed time hIntWKInt_oldct_ct <- lambdaghe[1L] * (ct-oldct) # integrated epidemic ground intensities of infectives (from oldct) ejIntWInt_oldct_ct <- if (length(infectives) == 0L) numeric(0L) else { eTermsProd <- apply(eTerms[infectives,,drop=FALSE], 1, prod) # integral of \id_{(0;eps.t]}(t-t_j) g(t-t_j \vert \kappa_j) from oldct to ct, for j in infectives # we can ignore the indicator because t-t_j is not >eps.t if t in [oldct;ct], because recoveries are change points times <- eventMatrix[infectives,"time"] types <- eventMatrix[infectives,"type"] gInt_0_ct <- tiaf$G(ct -times, tiafpars, types) gInt_0_oldct <- tiaf$G(oldct-times, tiafpars, types) gInt_oldct_ct <- gInt_0_ct - gInt_0_oldct eTermsProd * gInt_oldct_ct } sum(hIntWKInt_oldct_ct, ejIntWInt_oldct_ct) } ################## ### Simulation ### ################## ### Initialise values for simulation loop # all necessary components for an epidataCS object will be build along the simulation # let's start with the events of the prehistory tmp <- eTermsCalc(eventData, eventCoords) eTerms <- tmp[[1]]; rownames(eTerms) <- NULL bdists <- tmp[[2]] influenceRegions <- tmp[[3]] sources <- rep.int(list(integer(0L)), Nout) # Transform eventData into a matrix, which is faster with rbind # (factors will be recreated at the end of simulation) # simulated events will be subsequently appended to this matrix eventMatrix <- if (Nout == 0L) { matrix(numeric(0L), nrow=0L, ncol=ncol(eventData), dimnames=list(NULL, names(eventData))) } else { sapply(eventData, as.numeric, simplify = TRUE) # prehistory } if (Nout == 1L) eventMatrix <- t(eventMatrix) # we will also know about the source of infection and corresponding BLOCK in stgrid navec <- rep.int(NA_real_, Nout) eventMatrix <- cbind(eventMatrix, source = navec, lambda.h = navec, lambda.e = navec, Lambdag = navec, BLOCK = navec) # row indices of currently infective individuals infectives <- seq_len(Nout) # maximum total number of events (including prehistory) maxEvents <- Nout + nEvents # change points of lambdag stgridbreaks <- blockstarts[-1,2] Rtimes <- setNames(eventMatrix[,"time"]+eventMatrix[,"eps.t"], infectives) # name indexes row of eventMatrix # index of next event (row in eventMatrix) j <- Nout + 1L # allocation of large objects for faster filling-in of new events allocated <- Nout ncolEventMatrix <- ncol(eventMatrix) newAllocation <- expression({ eventMatrix <- rbind(eventMatrix, matrix(NA_real_, nrow = .allocate, ncol = ncolEventMatrix)) eventCoords <- rbind(eventCoords, matrix(NA_real_, nrow = .allocate, ncol = 2L)) eTerms <- rbind(eTerms, matrix(NA_real_, nrow = .allocate, ncol = 3L)) bdists <- c(bdists, rep.int(NA_real_,.allocate)) influenceRegions <- c(influenceRegions, vector(.allocate, mode="list")) sources <- c(sources, vector(.allocate, mode="list")) allocated <- allocated + .allocate }) # current time point ct <- t0 # current value of the cumulative intensity function of the ground process Lambdag <- 0 # last point rejected? pointRejected <- FALSE # did we have numerical problems simulating from Exp(lambdagUpper) in the current loop? hadNumericalProblems0 <- FALSE # index of the current loop loopCounter <- 0L ### Let's Rock 'n' Roll if (trace > 0L) { cat("\nSimulation path (starting from t=", t0, "):\n---\n", sep="") } else { cat("\nSimulating (starting from t=", t0, ") ...\n", sep="") } while(j <= maxEvents && ct < T && (hash || length(infectives) > 0L)) { loopCounter <- loopCounter + 1L if (trace > 0L && loopCounter %% trace == 0L) { cat(loopCounter, "@t =", ct, ":\t#simulated events =", j-1L-Nout, "\t#currently infective =", length(infectives), if (hase && !constanttiaf) paste("\tlast rejected?", pointRejected), "\n") flush.console() # affects Windows only } # check if we need to allocate larger matrices if (j > allocated) { eval(newAllocation) } if (!pointRejected) # what we have to do in the usual case { # we need the time block of stgrid corresponding to the new covariates, # i.e. search BLOCK such that t in [start; stop) tBLOCK <- blockstarts[findInterval(ct, blockstarts[,2]), 1] # Compute new infection intensity (upper bound) lambdaghe <- lambdagVec(ct, upper=TRUE) lambdagUpper <- sum(lambdaghe) # Determine time of next external change point changePoints <- c(nextblock = if (length(stgridbreaks) > 0L) stgridbreaks[1L], Rtimes) nextChangePoint <- if (length(changePoints) > 0L) { changePoints[which.min(changePoints)] # don't use min() because need names } else Inf } pointRejected <- FALSE ## Simulate waiting time for the subsequent infection if (is.na(lambdagUpper)) { warning("simulation stopped due to undefined intensity") break } if (lambdagUpper < 0) { warning("simulation stopped due to negative overall intensity") break } Delta <- if (lambdagUpper == 0) Inf else tryCatch( rexp(1, rate = lambdagUpper), warning = function (w) { # rate was too small (for R >= 2.7.0, # rexp(1, Inf) returns 0 without warning) assign("hadNumericalProblems0", TRUE, inherits = TRUE) Inf }) # Stop if lambdaStarMax too big meaning Delta == 0 (=> concurrent events) if (Delta == 0) { warning("simulation stopped due to infinite overall intensity") break } # Stop at all costs if end of simulation time [t0; T) has been reached if (isTRUE(min(ct+Delta, nextChangePoint) >= T)) { # ">=" because we don't want an event at "end" break } oldct <- ct if (ct + Delta > nextChangePoint) { ## Simulated time point is beyond the next time of intensity change (removal or endemic covariates) ct <- unname(nextChangePoint) # update cumulative intensity of the ground processes up to time ct, # i.e. add integral of lambdag from oldct to ct Lambdag <- Lambdag + add2Lambdag() # is this change point due to next time block in stgrid? if (names(nextChangePoint) == "nextblock") { stgridbreaks <- stgridbreaks[-1] } else { # i.e. change point due to recovery recoverer <- names(nextChangePoint) # update set of infectives infectives <- setdiff(infectives, recoverer) # remove recovery time from Rtimes .Rtimesidx <- match(recoverer, names(Rtimes)) Rtimes <- Rtimes[-.Rtimesidx] } } else { ## Simulated time point lies within the thinning period ct <- ct + Delta # rejection sampling if non-constant temporal interaction kernel g if (hase && !constanttiaf) { # Calculate actual ground intensity for rejection probability at new ct lambdaghe <- lambdagVec(ct, upper=FALSE) lambdag <- sum(lambdaghe) # rejection sampling step if (lambdag/lambdagUpper < runif(1)) { pointRejected <- TRUE next } } # At this point, we have an actual event! # update cumulative intensity of the ground processes up to time ct, # i.e. add integral of lambdag from oldct to ct Lambdag <- Lambdag + add2Lambdag() # note that lambdaghe[1L] did not change by the above update in case of !constanttiaf, # which is expected by add2Lambdag (which requires the value of lambdag.h(oldct)) # Where did the event come from: imported case or infection? .eventSource <- as.integer(sample(names(lambdaghe), 1L, prob=lambdaghe)) # We now sample type and location if (.eventSource == 0L) { # i.e. endemic source of infection .eventType <- sample(typeNames, 1L, prob=if (nbeta0 > 1L) exp(beta0)) stgrididx <- which(gridBlocks == tBLOCK) .eventTile <- sample(stgrid$tile[stgrididx], 1L, prob=dsexpeta[stgrididx]) # this is a factor ## spsample doesn't guarantee that the sample will consist of ## exactly n points. if no point is sampled (very unlikely ## though), there would be an error ntries <- 1L .nsample <- 1L while( inherits(eventLocationSP <- try( spsample(tiles[as.character(.eventTile),], n=.nsample, type="random"), silent = TRUE), "try-error")) { .nsample <- 10L # this also circumvents a bug in sp 1.0-0 # (missing drop=FALSE in sample.Spatial()) if (ntries >= 1000) { stop("'sp::spsample()' didn't succeed in sampling a ", "point from tile \"", as.character(.eventTile), "\"") } ntries <- ntries + 1L } .eventLocation <- coordinates(eventLocationSP)[1L,,drop=FALSE] } else { # i.e. source is one of the currently infective individuals sourceType <- eventMatrix[.eventSource,"type"] sourceCoords <- eventCoords[.eventSource,,drop=FALSE] sourceIR <- influenceRegions[[.eventSource]] sourceEpss <- eventMatrix[.eventSource,"eps.s"] .upperRange <- min(sourceEpss, maxExtentOfW) .eventType <- sample(typeNames[qmatrix[sourceType,]], 1L) .eventTypeCode <- match(.eventType, typeNames) eventInsideIR <- FALSE ntries <- 0L while(!eventInsideIR) { if (ntries >= 1000) { stop("event location sampled by siaf$simulate() was", " rejected 1000 times (not in influence region)") } ntries <- ntries + 1L eventLocationIR <- siaf$simulate(1L, siafpars, .eventTypeCode, .upperRange) eventInsideIR <- inside.owin(eventLocationIR[,1], eventLocationIR[,2], sourceIR) } .eventLocation <- sourceCoords + eventLocationIR whichTile <- over(SpatialPoints(.eventLocation), tiles) if (is.na(whichTile)) { warning("event generated at (", paste(.eventLocation, collapse=","), ") not in 'tiles'") stop("'tiles' must cover all of 'W'") } .eventTile <- factor(row.names(tiles)[whichTile], levels = tileLevels) } .eventType <- factor(.eventType, levels=typeNames) # sample marks at this time and location .eventMarks <- rmarks(ct, .eventLocation) # gather event information .eventData <- data.frame(time=ct, tile=.eventTile, type=.eventType, .eventMarks, check.rows = FALSE, check.names = FALSE) # determine potential sources of infection (for epidataCS and lambda) .sources <- infectives[eventMatrix[infectives,"type"] %in% which(qmatrix[,.eventType])] if (length(.sources) > 0L) { .sdiffs <- .eventLocation[rep.int(1L,length(.sources)),,drop=FALSE] - eventCoords[.sources,,drop=FALSE] .sources <- .sources[sqrt(.rowSums(.sdiffs^2, length(.sources), 2L)) <= eventMatrix[.sources,"eps.s"]] } # calculate actual intensity at this time, location and type .mmhEvent <- buildmmh(.eventData) .etaEvent <- .mmhEvent %*% beta if (!is.null(.offsetEvent <- attr(.mmhEvent, "offset"))) .etaEvent <- .etaEvent + .offsetEvent if (nbeta0 == 1L) { .etaEvent <- .etaEvent + beta0 } else if (nbeta0 > 1L) { .etaEvent <- .etaEvent + beta0[.eventType] } .lambdah <- exp(.etaEvent) .lambdae <- if (hase && length(.sources) > 0L) { .sdiffs <- .eventLocation[rep.int(1L,length(.sources)),,drop=FALSE] - eventCoords[.sources,,drop=FALSE] .fSources <- siaf$f(.sdiffs, siafpars, eventMatrix[.sources,"type"]) .gSources <- tiaf$g(ct - eventMatrix[.sources,"time"], tiafpars, eventMatrix[.sources,"type"]) sum(eTerms[.sources,"expeta"] * .fSources * .gSources) } else 0 # calculate terms of the epidemic component e_j(t,s) of the new infective tmp <- eTermsCalc(.eventData, .eventLocation) # Update objects eventMatrix[j,] <- c(ct, as.numeric(.eventTile), as.numeric(.eventType), sapply(.eventMarks, as.numeric), .eventSource, .lambdah, .lambdae, Lambdag, tBLOCK) eventCoords[j,] <- .eventLocation eTerms[j,] <- tmp[[1]] bdists[j] <- tmp[[2]] influenceRegions[[j]] <- tmp[[3]][[1]] sources[[j]] <- .sources # Update set of infectives and recovery times infectives <- c(infectives, j) Rtimes <- c(Rtimes, setNames(ct + .eventMarks[["eps.t"]], j)) # Increment next event iterator j <- j + 1L } } if (trace > 0L) cat("---\n") ### update T if simulation ended preterm if (j > maxEvents || (!hash && length(infectives) == 0L)) { T <- ct # clip stgrid to effective time range of simulation stgrid <- subset(stgrid, start <= T) if (j > maxEvents) { cat("Maximum number of events (nEvents=", nEvents, ") reached @t = ", T, "\n", sep="") } else { # epidemic-only model cat("Simulation has ended preterm (no more infectives)", "@t =", T, "with", j-1L-Nout, "simulated events.\n") } } else { # ct >= T or ct+Delta >= T cat("Simulation has ended @t =", T, "with", j-1L-Nout, "simulated events.\n") } ############## ### Return ### ############## ### Throw warning in case of numerical difficulties if (hadNumericalProblems0) { warning("occasionally, the overall infection rate was numerically equal to 0") } ### throw an error if no events have been simulated ## because SpatialPoints[DataFrame]() does not allow the empty set, try: ## SpatialPoints(coords = matrix(numeric(0), 0, 2), bbox=bbox(W)) if (j-1L == Nout) { stop("no events have been simulated") } ### transform eventMatrix back into a data.frame with original factor variables cat("\nPreparing simulated events for \"epidataCS\" ...\n") preEventData <- eventData # drop unused entries (due to large pre-allocation) from objects seqAlongEvents <- seq_len(j-1L) eventData <- as.data.frame(eventMatrix[seqAlongEvents,,drop=FALSE]) # rebuild factor variables for (idx in which(sapply(preEventData, is.factor))) { origlevels <- levels(preEventData[[idx]]) eventData[[idx]] <- factor(eventData[[idx]], levels=seq_along(origlevels), labels=origlevels) } # transform integer columns to integer eventData[c("source","BLOCK")] <- lapply(eventData[c("source","BLOCK")], as.integer) ### Append additional columns for an epidataCS object # add endemic covariates at events stgrididx <- apply(eventData[c("BLOCK","tile")], 1, function (x) { ret <- with(stgrid, which(BLOCK==as.integer(x[1L]) & tile==x[2L])) if (length(ret) == 0L) NA_integer_ else ret #<- events of the prehistory have missing BLOCKs, thus return NA }) stgridIgnoreCols <- match(c("BLOCK", setdiff(obligColsNames_stgrid, "start")), names(stgrid)) eventData <- cbind(eventData, stgrid[stgrididx, -stgridIgnoreCols, drop = FALSE]) rownames(eventData) <- seqAlongEvents # add hidden columns eventData$.obsInfLength <- with(eventData, pmin(T-time, eps.t)) eventData$.sources <- sources[seqAlongEvents] eventData$.bdist <- bdists[seqAlongEvents] eventData$.influenceRegion <- influenceRegions[seqAlongEvents] attr(eventData$.influenceRegion, "nCircle2Poly") <- nCircle2Poly attr(eventData$.influenceRegion, "clipper") <- "polyclip" ### Construct "epidataCS" object events <- SpatialPointsDataFrame( coords = eventCoords[seqAlongEvents,,drop=FALSE], data = eventData, proj4string = W@proj4string, match.ID = FALSE #, bbox = bbox(W)) # the bbox of SpatialPoints is defined as the actual # bbox of the points and is also updated every time # when subsetting the SpatialPoints object # -> useless to specify it as the bbox of W ) if (.onlyEvents) { cat("Done.\n") attr(events, "timeRange") <- c(t0, T) attr(events, "runtime") <- proc.time()[[3]] - ptm return(events) } epi <- list(events=events, stgrid=stgrid, W=W, qmatrix=qmatrix) ### Return object of class "simEpidataCS" cat("Done.\n") # append configuration of the model epi$bbox <- bbox(W) epi$timeRange <- c(t0, T) epi$formula <- list( endemic = if (typeSpecificEndemicIntercept) { update.formula(formula(endemic), ~ (1|type) + .) # re-add to the formula } else formula(endemic), epidemic = formula(epidemic), siaf = siaf, tiaf = tiaf ) if (epilink != "log") # set as attribute only if non-standard link function attr(epi$formula$epidemic, "link") <- epilink # coefficients as a numeric vector to be compatible with twinstim-methods epi$coefficients <- coefs #list(beta0=beta0, beta=beta, gamma=gamma, # siafpars=siafpars, tiafpars=tiafpars) epi$npars <- c(nbeta0=nbeta0, p=p, q=q, nsiafpars=nsiafpars, ntiafpars=ntiafpars) epi$control.siaf <- control.siaf # for R0.simEpidataCS epi$call <- cl epi$runtime <- proc.time()[[3]] - ptm class(epi) <- c("simEpidataCS", "epidataCS") return(epi) } ############################################################################# ### much more efficient simulation for endemic-only models ### where intensities are piecewise constant and independent from the history ############################################################################# ## auxiliary function to calculate the endemic intensity by spatio-temporal cell ## from the model environment of a "twinstim" fit .hGrid <- function (modelenv) { .beta0 <- rep_len(if (modelenv$nbeta0==0L) 0 else modelenv$beta0, modelenv$nTypes) hGrid <- sum(exp(.beta0)) * eval(modelenv$hGridExpr, envir = modelenv) blockstartstop <- modelenv$histIntervals[ match(modelenv$gridBlocks, modelenv$histIntervals$BLOCK), ] data.frame(blockstartstop, tile = modelenv$gridTiles, hGrid = hGrid, hInt = hGrid * modelenv$ds * modelenv$dt, row.names = NULL, check.rows = FALSE, check.names = FALSE) } ## simulate events from the endemic component of a "twinstim" fit ## this simulates pure (s,t,k) data with the only extra column being "tile" simEndemicEvents <- function (object, tiles) { ## check arguments stopifnot(inherits(object, "twinstim")) if (is.null(modelenv <- environment(object))) stop("no model environment -- re-fit or update() with 'model=TRUE'") tileLevels <- levels(modelenv$gridTiles) tiles <- check_tiles(tiles, levels = tileLevels, areas.stgrid = modelenv$ds[seq_along(tileLevels)], keep.data = FALSE) ## calculate endemic intensity by spatio-temporal cell lambdaGrid <- .hGrid(modelenv) ## simulate number of events by cell nGrid <- rpois(n = nrow(lambdaGrid), lambda = lambdaGrid[["hInt"]]) nTotal <- sum(nGrid) ## sample time points tps <- mapply( FUN = runif, n = nGrid, min = lambdaGrid[["start"]], max = lambdaGrid[["stop"]], SIMPLIFY = FALSE, USE.NAMES = FALSE ) ## sample types beta0 <- coeflist.default(coef(object), object$npars)[["nbeta0"]] nTypes <- nrow(object$qmatrix) types <- if (nTypes == 1L) { rep.int(1L, nTotal) } else { sample.int(n = nTypes, size = nTotal, replace = TRUE, prob = if (length(beta0) > 1L) exp(beta0)) } ## put event times, tiles, and types in a data frame events <- data.frame( ##lambdaGrid[rep.int(seq_len(nrow(lambdaGrid)), nGrid), c("tile", "BLOCK")], time = unlist(tps, recursive = FALSE, use.names = FALSE), tile = rep.int(lambdaGrid[["tile"]], nGrid), type = factor(types, levels = seq_len(nTypes), labels = rownames(object$qmatrix)), row.names = NULL, check.rows = FALSE, check.names = FALSE ) ## empty CRS to avoid spending 3/4 of this function's runtime in rebuild_CRS() proj4string <- tiles@proj4string tiles@proj4string <- new("CRS") ## sample coordinates from tiles nByTile <- tapply(X = nGrid, INDEX = lambdaGrid["tile"], FUN = sum) xyByTile <- sapply( X = names(nByTile), FUN = function (tile) { n <- nByTile[tile] if (n > 0L) coordinates(spsample(x = tiles[tile,], n = n, type = "random", iter = 10)) ## else NULL }, simplify = FALSE, USE.NAMES = TRUE ) ## set coordinates of events events <- SpatialPointsDataFrame( coords = do.call("rbind", xyByTile), data = events[order(events$tile),], proj4string = proj4string, match.ID = FALSE) ## order by time events <- events[order(events$time),] row.names(events) <- seq_along(events) events } #################################################### ### some twinstim-methods for "simEpidataCS" objects #################################################### ### wrapper for R0.twinstim R0.simEpidataCS <- function (object, trimmed = TRUE, ...) { R0.twinstim(object, newevents=object$events@data, trimmed = trimmed, ...) } ### wrapper for intensityplot.twinstim as.twinstim.simEpidataCS <- function (x) { m <- do.call("twinstim", c( formula(x), list(data = quote(x), control.siaf = x$control.siaf, optim.args = list(par=coef(x), fixed=TRUE), model = TRUE, cumCIF = FALSE, verbose = FALSE) )) components2copy <- setdiff(names(m), names(x)) for (comp in components2copy) x[[comp]] <- m[[comp]] environment(x) <- environment(m) class(x) <- c("simEpidataCS", "epidataCS", "twinstim") x } intensityplot.simEpidataCS <- function (x, ...) { if (is.null(environment(x))) { objname <- deparse(substitute(x)) message("Setting up the model environment ...") x <- as.twinstim.simEpidataCS(x) try({ assign(objname, x, envir=parent.frame()) message("Note: added model environment to '", objname, "' for future use.") }, silent=TRUE) } intensityplot.twinstim(x, ...) } ### the residual process Lambda_g(t) is stored with the simulated events residuals.simEpidataCS <- function (object, ...) { setNames(object$events$Lambdag, row.names(object$events))[!is.na(object$events$Lambdag)] } ################################################################################ # A 'simulate' method for objects of class "twinstim". ################################################################################ ### FIXME: actually stgrid's of simulations might have different time ranges ### when nEvents is active -> atm, simplify ignores this .rmarks <- function (data, t0, T) { observedMarks <- subset(marks.epidataCS(data, coords = FALSE), subset = time > t0 & time <= T) if (nrow(observedMarks) == 0L) { message("Note: 'data' does not contain any events during ('t0';'T'],\n", " 'rmarks' thus samples marks from all of 'data$events'") observedMarks <- marks.epidataCS(data, coords = FALSE) } observedMarks <- observedMarks[match("eps.t", names(observedMarks)):ncol(observedMarks)] rm(list = "data", inherits = FALSE) # to save memory (environment is kept) function (t, s, n = 1L) { as.data.frame(lapply(observedMarks, function (x) sample(na.omit(x), size = n, replace = TRUE)), optional = TRUE) } } simulate.twinstim <- function (object, nsim = 1, seed = NULL, data, tiles, newcoef = NULL, rmarks = NULL, t0 = NULL, T = NULL, nEvents = 1e5, control.siaf = object$control.siaf, W = data$W, trace = FALSE, nCircle2Poly = NULL, gmax = NULL, .allocate = 500, simplify = TRUE, ...) { ptm <- proc.time()[[3]] cl <- match.call() ### Determine seed (this part is copied from stats:::simulate.lm with ### Copyright (C) 1995-2012 The R Core Team) if (!exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE)) runif(1) if (is.null(seed)) RNGstate <- get(".Random.seed", envir = .GlobalEnv) else { R.seed <- get(".Random.seed", envir = .GlobalEnv) set.seed(seed) RNGstate <- structure(seed, kind = as.list(RNGkind())) on.exit(assign(".Random.seed", R.seed, envir = .GlobalEnv)) } ### Few checks stopifnot(inherits(object, "twinstim"), inherits(data, "epidataCS")) stopifnot(isScalar(nsim), nsim > 0) nsim <- as.integer(nsim) if (is.null(t0)) t0 <- object$timeRange[1] if (is.null(T)) T <- object$timeRange[2] if (is.null(nCircle2Poly)) nCircle2Poly <- attr(data$events$.influenceRegion, "nCircle2Poly") ### Retrieve arguments for simulation endemic <- formula(object)$endemic epidemic <- formula(object)$epidemic # we don't need any reference to the original formula environment environment(endemic) <- environment(epidemic) <- .GlobalEnv if (is.null(rmarks)) rmarks <- .rmarks(data, t0 = t0, T = T) theta <- coef(object) if (!is.null(newcoef)) { newcoef <- check_twinstim_start(newcoef) newcoef <- newcoef[names(newcoef) %in% names(theta)] theta[names(newcoef)] <- newcoef } thetalist <- coeflist.default(theta, object$npars) ### Run the simulation(s) # establish call simcall <- call("simEpidataCS", endemic=endemic, epidemic=epidemic, siaf=quote(formula(object)$siaf), tiaf=quote(formula(object)$tiaf), qmatrix=quote(object$qmatrix), rmarks=quote(rmarks), events=quote(data$events), stgrid=quote(data$stgrid), tiles=quote(tiles), beta0=thetalist[[1L]], beta=thetalist[[2L]], gamma=thetalist[[3L]], siafpars=thetalist[[4L]], tiafpars=thetalist[[5L]], epilink = .epilink(object), t0=t0, T=T, nEvents=nEvents, control.siaf=control.siaf, W=quote(W), trace=trace, nCircle2Poly=nCircle2Poly, gmax=gmax, .allocate=.allocate, .skipChecks=TRUE, .onlyEvents=FALSE) # First simulation if (nsim > 1L) { cat("\nTime at beginning of simulation:", as.character(Sys.time()), "\n") cat("Simulation 1 /", nsim, "...\n") cat("-------------------------------------------------------------------------------\n") } res <- eval(simcall) if (nsim > 1L) { cat("\n-------------------------------------------------------------------------------\n") cat("Runtime of first simulation:", res$runtime, "seconds\n") cat("Estimated finishing time:", as.character(Sys.time() + (nsim-1) * res$runtime), "\n\n") # set up list of simulations res <- if (simplify) { with(res, list( eventsList=c(structure(events, timeRange = timeRange, runtime = runtime), vector(nsim-1L, mode="list")), stgrid=stgrid, W=W, qmatrix=qmatrix, bbox=bbox, formula=formula, coefficients=coefficients, npars=npars, control.siaf=control.siaf, call=call )) } else { c(list(res), vector(nsim-1L, mode="list")) } # force garbage collection gc() # run the remaining simulations simcall$.onlyEvents <- simplify for (i in 2:nsim) { cat("Simulation", sprintf(paste0("%",nchar(nsim),"i"), i), "/", nsim, "...") capture.output(resi <- eval(simcall)) .nEvents <- if (simplify) sum(!is.na(resi$source)) else { sum(!is.na(resi$events$source)) } .T <- if (simplify) attr(resi,"timeRange")[2] else resi$timeRange[2] cat("\tsimulated", .nEvents, "events", if (nEvents == .nEvents) "(reached maximum)", "up to time", .T, "\n") if (simplify) res$eventsList[[i]] <- resi else res[[i]] <- resi } cat("\nDone (", as.character(Sys.time()), ").\n", sep="") } attr(res, "call") <- cl attr(res, "seed") <- RNGstate attr(res, "runtime") <- proc.time()[[3]] - ptm class(res) <- if (nsim == 1L) { c("simEpidataCS", "epidataCS") } else { attr(res, "simplified") <- simplify c("simEpidataCSlist") } res } ### print method for lists of simulated epidemics print.simEpidataCSlist <- function (x, ...) { cat("\nCall:\n") print.default(attr(x, "call")) simplified <- attr(x, "simplified") nsim <- if (simplified) length(x$eventsList) else length(x) cat("\n") cat(if (simplified) "Simplified list" else "List", "of", nsim, "simulated epidemics of class \"simEpidataCS\" (not printed)\n\n") invisible(x) } "[[.simEpidataCSlist" <- function (x, i) { simplified <- attr(x, "simplified") if (simplified) { x <- unclass(x) x$eventsList <- x$eventsList[[i]] names(x)[names(x) == "eventsList"] <- "events" x <- append(x, list(timeRange = attr(x$events, "timeRange")), after=5L) x$runtime <- attr(x$events, "runtime") attr(x$events, "timeRange") <- attr(x$events, "runtime") <- NULL class(x) <- c("simEpidataCS", "epidataCS") x } else NextMethod("[[") } plot.simEpidataCSlist <- function (x, which = NULL, mfrow = n2mfrow(length(which)), main = paste("Simulated epidemic", which), aggregate = c("time", "space"), subset, ...) { simplified <- attr(x, "simplified") nsim <- if (simplified) length(x$eventsList) else length(x) if (is.null(which)) { which <- seq_len(nsim) if (nsim > 4) which <- sample(which, 4L) } opar <- par(mfrow = mfrow); on.exit(par(opar)) main <- rep_len(main, length(which)) for (i in seq_along(which)) { do.call("plot", args=list(x=quote(x[[which[i]]]), aggregate=aggregate, subset=substitute(subset), main = main[i], ...)) } } surveillance/R/wrap_univariate.R0000644000176200001440000001334214615164167016510 0ustar liggesusers############################################################################## # This function is a wrapper for univariate surveillance algorithms # using the old disProg and survRes object # # An sts object is given and a pre specified algorithms is ran # by successively creating a disProg object for each region, # running the algo and then assign the slots of the resulting survRes # object to an sts object. ################################################################################### ###Apply other algorithms by wrapping up a suitable package. #Wrapper function to call algo.farrington for each time series in an sts object wrap.algo <- function(sts, algo, control, control.hook=function(k, control) return(control), verbose=TRUE,...) { chkDots(...) stopifnot(is.vector(control[["range"]], mode = "numeric")) #Number of time series nAreas <- ncol(sts@observed) #Set old alarms and upperbounds to NA sts@alarm[] <- NA sts@upperbound[] <- NA_real_ #Loop over all regions for (k in 1:nAreas) { if (verbose && nAreas > 1) { cat("Running ",algo," on area ",k," out of ",nAreas,"\n") } ##Create an old S3 disProg object disProg.k <- sts2disProg(sts[,k]) #Use the univariate algorithm (possibly preprocess control object) kcontrol <- control.hook(k, control) survRes.k <- do.call(algo,args = list(disProg.k, control=kcontrol)) #Transfer results to the S4 object if (!is.null(survRes.k)) { sts@alarm[control$range,k] <- survRes.k$alarm sts@upperbound[control$range,k] <- survRes.k$upperbound } } #Control object needs only to be set once sts@control <- survRes.k$control #Fix invalid data name (= deparse(disProg.k) from last iteration) sts@control$data <- "sts" #Set correct theta0t matrix for all sts@control$theta0t <- control$theta0t #Reduce sts object to only those observations in range sts <- sts[control$range, ] return(sts) } #Farrington wrapper farrington <- function(sts, control=list(range=NULL, b=5, w=3, reweight=TRUE, verbose=FALSE, alpha=0.05),...) { wrap.algo(sts,algo="algo.farrington",control=control,...) } #Bayes wrapper (this can be implemented more efficiently) bayes <- function(sts, control = list(range = range, b = 0, w = 6, actY = TRUE,alpha=0.05),...) { if (sts@epochAsDate) { warning("algo.bayes currently can't handle Date entries. Computing reference values based on freq") } wrap.algo(sts,algo="algo.bayes",control=control) } #RKI wrapper rki <- function(sts, control = list(range = range, b = 2, w = 4, actY = FALSE),...) { if (sts@epochAsDate) { warning("algo.rki currently can't handle Date entries. Computing reference values based on freq") } wrap.algo(sts,algo="algo.rki",control=control,...) } #outbreakP wrapper outbreakP <- function(sts, control=list(range = range, k=100, ret=c("cases","value"),maxUpperboundCases=1e5),...) { wrap.algo(sts,algo="algo.outbreakP",control=control,...) } #HMM wrapper hmm <- function(sts, control=list(range=NULL, noStates=2, trend=TRUE, noHarmonics=1,covEffectEqual=FALSE),...) { if (sts@epochAsDate) { warning("algo.hmm currently can't handle Date entries. Computing reference values based on freq") } wrap.algo(sts,algo="algo.hmm",control=control,...) } #Cusum wrapper cusum <- function(sts, control = list(range=range, k=1.04, h=2.26, m=NULL, trans="standard",alpha=NULL),...) { wrap.algo(sts,algo="algo.cusum",control=control,...) } #GLRpois wrapper glrpois <- function(sts, control = list(range=range,c.ARL=5, S=1, beta=NULL, Mtilde=1, M=-1, change="intercept",theta=NULL),...) { wrap.algo(sts,algo="algo.glrpois",control=control,...) } #GLRnb wrapper glrnb <- function(sts, control = list(range=range,c.ARL=5, mu0=NULL, alpha=0, Mtilde=1, M=-1, change="intercept",theta=NULL,dir=c("inc","dec"), ret=c("cases","value")), ...) { wrap.algo(sts,algo="algo.glrnb",control=control,...) } #### this code definitely needs some more documentation -- wrap.algo atm is # 100% without docu #Rogerson wrapper # theta0t now has to be a matrix #library(surveillance) #data("ha") #rogerson(disProg2sts(ha),control=list(range=200:290,ARL0=100,s=1,theta0t=matrix(1,nrow=91,ncol=12))) rogerson <- function(sts, control = list(range=range, theta0t=NULL, ARL0=NULL, s=NULL, hValues=NULL, distribution=c("poisson","binomial"), nt=NULL, FIR=FALSE,limit=NULL, digits=1),...) { if (sts@epochAsDate) { warning("algo.rogerson currently can't handle Date entries. Computing reference values based on freq") } #Hook function to find right theta0t vector control.hook = function(k,control) { #Extract values relevant for the k'th component control$theta0t <- control$theta0t[,k] if (is.null(control[["nt",exact=TRUE]])) { control$nt <- sts@populationFrac[control$range,k] } else { if (!all.equal(sts@populationFrac[control$range,k],control$nt[,k])) { warning("Warning: nt slot of control specified, but specified population differs.") } else { control$nt <- control$nt[,k] } } #If no hValues given then compute them if (is.null(control[["hValues",exact=TRUE]])) { #This code does not appear to work once n is big. # control$hValues <- hValues(theta0 = unique(control$theta0t), ARL0=control$ARL0, s=control$s , distr = control$distribution, n=mean(control$nt))$hValues control$hValues <- hValues(theta0 = unique(control$theta0t), ARL0=control$ARL0, s=control$s , distr = control$distribution)$hValues } return(control) } #WrapIt wrap.algo(sts,algo="algo.rogerson",control=control,control.hook=control.hook,...) } surveillance/R/checkDerivatives.R0000644000176200001440000000446514426171115016570 0ustar liggesusers################################################################################ ### Simple wrapper around functionality of the numDeriv and maxLik packages ### to check the score vector and the Fisher information matrix ### CAVE: the return values of both wrappers are not unified ### ### Copyright (C) 2012, 2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ checkDerivatives.numDeriv <- function(ll, score, fisher, par, method="Richardson", method.args=list(), ...) { cat("Checking analytical score vector using numDeriv::grad() ...\n") nsc <- numDeriv::grad(ll, par, method = method, method.args = method.args, ...) asc <- score(par, ...) print(all.equal(asc, nsc, check.attributes=FALSE)) cat("Checking analytical Fisher information matrix using numDeriv::hessian() ...\n") if (length(par) > 50) cat("NOTE: this might take several minutes considering length(par) =", length(par), "\n") nfi <- -numDeriv::hessian(ll, par, method = "Richardson", method.args = method.args, ...) afi <- fisher(par, ...) print(all.equal(afi, nfi, check.attributes=FALSE)) invisible(list(score = list(analytic=asc, numeric=nsc), fisher = list(analytic=afi, numeric=nfi))) } checkDerivatives.maxLik <- function(ll, score, fisher, par, eps=1e-6, print=FALSE, ...) { cat("Checking analytical score and Fisher using maxLik::compareDerivatives() ...\n") res <- maxLik::compareDerivatives( f=ll, grad=score, hess=function (par, ...) -fisher(par, ...), t0=par, eps=eps, print=print, ...) cat("Comparison of score vectors:\n") print(all.equal(res$compareGrad$analytic, drop(res$compareGrad$numeric), check.attributes=FALSE)) cat("Comparison of Fisher information matrices:\n") print(all.equal(res$compareHessian$analytic, drop(res$compareHessian$numeric), check.attributes=FALSE)) invisible(res) } surveillance/R/twinstim_helper.R0000644000176200001440000003706714615162374016535 0ustar liggesusers################################################################################ ### Internal helper functions for "twinstim" ### ### Copyright (C) 2009-2016,2018,2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### Determines indexes of potential sources of infection ## determine potential sources of the i'th event ## all arguments but i and qmatrix are nEvents-vectors ## -> determine potential sources for eventTimes[i], eventsTypes[i] with ## distances distvec_j = ||s_i - s_j|| determineSources1 <- function (i, eventTimes, removalTimes, distvec, eps.s, eventTypes = NULL, qmatrix) { tp <- eventTimes[i] infectivity <- (eventTimes < tp) & (removalTimes >= tp) #<- eventTimes= t)) ## lidx <- length(idx) ## if (lidx == 0L) NA_integer_ else if (lidx == 1L) idx else { ## stop("'stgrid' has overlapping spatio-temporal grid cells") ## } ## ~5x faster alternative assuming a full BLOCK x tile grid, which is ## sorted by BLOCK and tile (tile varying first), specifically there must be ## all levels(stgrid$tile) in every BLOCK in that order; ## this structure is guaranteed by check_stgrid() if (t <= stgrid$start[1L]) return(NA_integer_) # prehistory event blockstart <- match(TRUE, stgrid$stop >= t) # NA if t is beyond idx <- blockstart + match(tilename, levels(stgrid$tile)) - 1L return(idx) } ## Crude estimate for a start value of the endemic intercept ## assuming the model only had a single-cell endemic component ## (rate of homogeneous Poisson process scaled for the offset) crudebeta0 <- function (nEvents, offset.mean, W.area, period, nTypes) { ## nEvents = exp(offset + beta0) * W.area * period * nTypes log(nEvents/W.area/period/nTypes) - offset.mean } ### Really internal helper function, which constructs the function that ### integrates the two-dimensional 'siaf' function over the influence regions of ### the events. The only argument of the returned function is 'siafpars'. ### The returned function is defined in the callers environment, where the ### variables used in the function are available (inside twinstim() or ### simEpidataCS()). .siafIntFUN <- function (siaf, noCircularIR, #= all(eps.s>bdist) = all(sapply(influenceRegion, function(x) # is.null(attr(x,"radius")))) parallel = FALSE ){ ## the following variables are unused here, because the environment of ## FUN will be set to the parent.frame(), where the variables exist ## they are only included to avoid the notes in R CMD check iRareas <- influenceRegion <- eventTypes <- eps.s <- bdist <- effRanges <- NULL ## define the siaf integration function depending on the siaf specification FUN <- if (attr(siaf, "constant")) { if (exists("iRareas", where=parent.frame(), mode="numeric")) { ## in twinstim(), 'iRareas' are pre-defined to save ## computation time (data are fixed during fitting) function (siafpars) iRareas } else { function (siafpars) vapply(X = influenceRegion, FUN = attr, which = "area", FUN.VALUE = 0, USE.NAMES = FALSE) } } else if (is.null(siaf$Fcircle) || # if siaf$Fcircle not available (is.null(siaf$effRange) && noCircularIR)) { ## Numerically integrate 'siaf' over each influence region mapplyFUN( c(alist(siaf$F, influenceRegion, type=eventTypes), list(MoreArgs=quote(list(siaf$f, siafpars, ...)), SIMPLIFY=TRUE, USE.NAMES=FALSE)), ##<- we explicitly quote() the ...-part instead of simply including ## it in the above alist() - only to make checkUsage() happy parallel = parallel) } else if (is.null(siaf$effRange)) # use Fcircle but only delta-trick { mapplyFUN( c(alist(function (iR, type, eps, bdisti, siafpars, ...) if (eps <= bdisti) # influence region completely inside W siaf$Fcircle(eps, siafpars, type) else # numerically integrate over influence region siaf$F(iR, siaf$f, siafpars, type, ...) , influenceRegion, eventTypes, eps.s, bdist), list(MoreArgs=quote(list(siafpars, ...)), SIMPLIFY=TRUE, USE.NAMES=FALSE)), parallel = parallel) } else { # fast Fcircle integration considering the delta-trick AND effRange .ret <- mapplyFUN( c(alist(function (iR, type, eps, bdisti, effRange, siafpars, ...) if (eps <= bdisti) # influence region completely inside W siaf$Fcircle(eps, siafpars, type) else if (effRange <= bdisti) # effective region inside W siaf$Fcircle(bdisti, siafpars, type) else # numerically integrate over influence region siaf$F(iR, siaf$f, siafpars, type, ...) , influenceRegion, eventTypes, eps.s, bdist, effRanges), list(MoreArgs=quote(list(siafpars, ...)), SIMPLIFY=TRUE, USE.NAMES=FALSE)), ## before: compute computationally effective range of the 'siaf' ## for the current 'siafpars' for each event (type): before = expression( effRangeTypes <- rep_len(siaf$effRange(siafpars), nTypes), effRanges <- effRangeTypes[eventTypes] # N-vector ), parallel = parallel) if (exists("effRangeTypes", where=parent.frame(), mode="numeric")) { ## in simEpidataCS effRangeTypes is pre-calculated outside siafInt to ## save computation time ('siafpars' is constant during simulation) body(.ret)[[grep("^effRangeTypes <-", body(.ret))]] <- NULL } .ret } ## set the environment of the siafInt function to the callers environment ## (i.e. inside twinstim() or simEpidataCS()) ## where the variables used in the function are defined environment(FUN) <- parent.frame() FUN } ### Helper function, which constructs the function that integrates the 'tiaf'. ### The returned function is defined in the callers environment, where the ### variables used in the function are available (inside twinstim() or ### simEpidataCS()). .tiafIntFUN <- function () { ## the following variables are unused here, because the environment of ## FUN will be set to the parent.frame(), where the variables exist ## they are only included to avoid the notes in R CMD check gIntLower <- gIntUpper <- eventTypes <- tiaf <- NULL ## from, to and type may be vectors of compatible lengths FUN <- function(tiafpars, from = gIntLower, to = gIntUpper, type = eventTypes, G = tiaf$G) { tiafIntUpper <- G(to, tiafpars, type) tiafIntLower <- G(from, tiafpars, type) tiafIntUpper - tiafIntLower } ## set the environment of the tiafInt function to the callers environment ## (i.e. inside twinstim() or simEpidataCS()) ## where the default argument values are defined environment(FUN) <- parent.frame() FUN } ### rename control arguments with optim names to have names compatible with nlminb control2nlminb <- function (control, defaults) { renamelist <- cbind(optim = c("maxit", "REPORT", "abstol", "reltol"), nlminb = c("iter.max", "trace", "abs.tol", "rel.tol")) for (i in which(renamelist[,"optim"] %in% names(control))) { fromname <- renamelist[i, "optim"] toname <- renamelist[i, "nlminb"] if (is.null(control[[toname]])) { control[[toname]] <- control[[fromname]] } control[[fromname]] <- NULL } defaults[names(control)] <- control defaults } ### Helper for iaf-checks: ### Checks if FUN has three arguments (s/t, pars, type) and ### eventually adds the last two .checknargs3 <- function (FUN, name) { FUN <- match.fun(FUN) NARGS <- length(formals(FUN)) if (NARGS == 0L) { stop("the function '", name, "' must accept at least one argument") } else if (NARGS == 1L) { formals(FUN) <- c(formals(FUN), alist(pars=, types=)) } else if (NARGS == 2L) { formals(FUN) <- c(formals(FUN), alist(types=)) } FUN } ### Internal wrapper used in twinstim() and simEpidataCS() to evaluate the siaf ### and tiaf arguments. If successful, returns checked interaction function. .parseiaf <- function (iaf, type, eps = NULL, verbose = TRUE) { type <- match.arg(type, choices=c("siaf", "tiaf"), several.ok=FALSE) res <- if (missing(iaf) || is.null(iaf)) { if (verbose) { message("assuming constant ", switch(type, siaf="spatial", tiaf="temporal"), " interaction '", type, ".constant()'") } do.call(paste(type, "constant", sep="."), args=alist()) } else if (is.list(iaf)) { ret <- do.call(type, args = iaf) ## keep special attributes attr(ret, "knots") <- attr(iaf, "knots") attr(ret, "maxRange") <- attr(iaf, "maxRange") attr(ret, "Boundary.knots") <- attr(iaf, "Boundary.knots") attr(ret, "constant") <- attr(iaf, "constant") ret } else if (is.vector(iaf, mode = "numeric")) { do.call(paste(type,"step",sep="."), args = list(knots = iaf)) } else { stop("'", as.character(substitute(iaf)), "' must be NULL (or missing), a list (-> continuous ", "function), or numeric (-> knots of step function)") } ## indicate if this is a constant iaf attr(res, "constant") <- isTRUE(attr(res, "constant")) ## attach unique interaction ranges if (!is.null(eps)) { # in simEpidataCS() eps is not known beforehand attr(res, "eps") <- sort(unique(eps)) } return(res) } ### Construct a call/function for mapply or parallel::mcmapply, respectively ## args: alist() of arguments for mapply() ## before,after: expressions to be prepended/appended to the function body, ## where "res" will be the result of mapply() mapplyCall <- function (args, cores = 1L) { parallel <- is.name(cores) || cores > 1L mapplyFUN <- if (parallel) quote(parallel::mcmapply) else quote(mapply) parallelArgs <- list(mc.preschedule=TRUE, mc.cores=cores) as.call(c(mapplyFUN, args, if (parallel) parallelArgs)) } mapplyFUN <- function (args, before = list(), after = list(), parallel = TRUE) { FUN <- as.function(alist(siafpars=, ...=, NULL), envir=parent.frame()) body(FUN) <- mapplyCall(args, if (parallel) quote(cores) else 1L) if (length(after) + length(before) > 0) { body(FUN) <- as.call(c( list(as.name("{")), before, if (length(after)) call("<-", as.name("res"), body(FUN)) else body(FUN), after)) } FUN } ### parse the list or vector of start values check_twinstim_start <- function (start) { if (is.null(start)) { return(start) } else if (is.list(start)) { # convert allowed list specification to vector stopifnot(names(start) %in% c("endemic", "epidemic", "h", "e", "siaf", "tiaf", "e.siaf", "e.tiaf")) names(start)[names(start) == "endemic"] <- "h" names(start)[names(start) == "epidemic"] <- "e" names(start)[names(start) == "siaf"] <- "e.siaf" names(start)[names(start) == "tiaf"] <- "e.tiaf" start <- unlist(start, recursive=FALSE, use.names=TRUE) } if (!is.vector(start, mode="numeric") || is.null(names(start))) stop("parameter values must be named and numeric") return(start) } surveillance/R/stsBP.R0000644000176200001440000000367712672237564014360 0ustar liggesusers###################################################################### # initialize-method for "stsBP" objects ###################################################################### fix.dimnamesBP <- function (x) { dimnames(x@ci) <- dimnames(x@lambda) <- c(dimnames(x@observed), list(NULL)) x } init.stsBP <- function(.Object, ..., ci, lambda) { .Object <- callNextMethod() # use initialize,sts-method ## NOTE: we cannot have a validity check for the dimensions of ci and lambda ## in the class definition of "stsBP" since we could not easily get ## new("stsBP") to be a valid object. Thus, we will directly check here. ## check/set extra stsBP-slots dimObserved <- dim(.Object@observed) if (missing(ci)) { .Object@ci <- array(NA_real_, dim = c(dimObserved, 2L)) } else { dimCI <- dim(.Object@ci) if (length(dimCI) != 3 || any(dimCI != c(dimObserved, 2L))) stop("dim(ci) = (", paste0(dimCI, collapse=","), ")") } if (missing(lambda)) { .Object@lambda <- array(NA_real_, dim = c(dimObserved, 0L)) } else { dimLambda <- dim(.Object@lambda) if (length(dimLambda) != 3 || !identical(dimLambda[1:2], dimObserved)) stop("dim(lambda) = (", paste0(dimLambda, collapse=","), ")") } ## fix dimnames of extra stsBP-slots .Object <- fix.dimnamesBP(.Object) return(.Object) } setMethod("initialize", "stsBP", init.stsBP) ###################################################################### # Special coerce method to account for consistent dimensions ###################################################################### setAs(from = "sts", to = "stsBP", function (from) { res <- new("stsBP", from, ci = array(NA_real_, dim = c(dim(from@observed), 2L)), lambda = array(NA_real_, dim = c(dim(from@observed), 0L))) fix.dimnamesBP(res) }) surveillance/R/nowcast.R0000644000176200001440000014050214615164167014765 0ustar liggesusers###################################################################### # Function to perform nowcast at a specific day "now" using a procedure # which takes truncation of the available observations into # account. The full documentation is available in the nowcast.Rd file. # # Author: Michael Hoehle # # Parameters: # now - a Date object representing today # when - a vector of Date objects representing the days to do the forecast for. # A requirement is that for all elements in when are smaller or equal # than "now". # data - the Database containing columns dEventCol and dReportCol, which # contain the date of the event and of when the report arrives in # the database. # dEventCol - name of column in data containing time of event occurrence # dReportCol - name of column in data containing time of reprt arrival # method - which method to use # D - maximum delay to consider # m - moving window for delay estimation # control - a list containing the following arguments # * gd.prior.kappa - prior for delay is symmetric Dirichlet # with concentration parameter gd.prior.kappa # # Note: As predictions are done simultaneously the entire vector of observations # is casted. Then the subset specified in "when" is returned. # # Returns: # stsNC object with reporting triangle, delay estimate and prediction interval in the appropriate slots. # # Todo: # * yt.support to N.tInf support in nowcast?? # * bayes.notrunc and bayes.notrunc.bnb could become one code segment # * Enable user to provide reporting triangle directly. # * Function should work for weekly and monthly data as well ###################################################################### nowcast <- function(now, when, data, dEventCol="dHospital", dReportCol="dReport", method=c("bayes.notrunc","bayes.notrunc.bnb","lawless","bayes.trunc","unif","bayes.trunc.ddcp"), aggregate.by="1 day", D=15, m=NULL, m.interpretation=c("hoehle_anderheiden2014", "lawless1994"), control=list( dRange=NULL,alpha=0.05,nSamples=1e3, N.tInf.prior=c("poisgamma","pois","unif"), N.tInf.max=300, gd.prior.kappa=0.1, ddcp=list(ddChangepoint=NULL, cp_order=c("zero","one"), Wextra=NULL, logLambda=c("iidLogGa","tps","rw1","rw2"), responseDistr=c("poisson", "negbin"), mcmc=c(burnin=2500,sample=10000,thin=1, adapt=1000, store.samples=FALSE)), score=FALSE,predPMF=FALSE)) { #Check if the runjags package is available (required for bayes.trunc.ddcp to work! if ("bayes.trunc.ddcp" %in% method) { if (!requireNamespace("runjags",quietly=TRUE)) { stop("The \"bayes.trunc.ddcp\" method requires the runjags package to be installed, which is available from CRAN.") } } if ((!inherits(now,"Date")) | (length(now)>1)) { stop("The parameter 'now' has to be a single Date.") } #Check if all when_i<= now if (!all(when<=now)) { stop("Assertion when <= now failed.") } #Check that specified methods are all valid method <- match.arg(method,c("bayes.notrunc","bayes.notrunc.bnb","lawless","bayes.trunc","unif","bayes.trunc.ddcp"),several.ok=TRUE) ###################################################################### # Time aggregation. Make sure it's a valid aggregational level and # move all dates to the "first" of this level. # @hoehle: Should work for day, weeks and month. Quarter and year not atm. ###################################################################### aggregate.by <- match.arg(aggregate.by,c("1 day","1 week", "1 month"),several.ok=FALSE) epochInPeriodStr <- switch(aggregate.by, "1 day"="1","1 week"="%u", "1 month"="%d") if (aggregate.by != "1 day") { warning("Moving dates to first of each epoch.") #Move dates back to first of each epoch unit for (colName in c(dEventCol, dReportCol)) { data[,colName] <- data[,colName] - as.numeric(format(data[,colName],epochInPeriodStr)) + 1 } #Check now and when if (!all( format( c(now,when),epochInPeriodStr) == 1)) { stop("The variables 'now' and 'when' needs to be at the first of each epoch") } } #Choose the correct difference function if (aggregate.by == "1 day") { timeDelay <- function(d1,d2) {as.numeric(d2-d1)} } if (aggregate.by == "1 week") { timeDelay <- function(d1,d2) { floor(as.numeric(difftime(d2,d1,units="weeks"))) } #Count the number of full weeks } if (aggregate.by == "1 month") { timeDelay <- function(d1,d2) { #Helper function from http://stackoverflow.com/questions/1995933/number-of-months-between-two-dates monnb <- function(d) { lt <- as.POSIXlt(as.Date(d, origin="1900-01-01")) lt$year*12 + lt$mon } monnb(d2) - monnb(d1) #count the number of full months } } ## Check the value of the m interpretation m.interpretation <- match.arg(m.interpretation, c("hoehle_anderheiden2014", "lawless1994")) if (!is.null(m) & (method == "lawless") & (m.interpretation != "lawless1994")) { warning("Selected method is Lawless (1994), but the interpretation of m is a horizontal cut in the reporting triangle (as in Hoehle and an der Heiden (2014)) and not as in Lawless (1994).") } if (!is.null(m) & (method != "lawless") & (m.interpretation == "lawless1994")) { stop("The selected nowcasting method only works with m.interpretation = 'hoehle_anderheiden2014'") } ###################################################################### #If there is a specification of dateRange set dMin and dMax accordingly #Otherwise use as limits the range of the data ###################################################################### if (is.null(control[["dRange",exact=TRUE]])) { dMin <- min(data[,dEventCol],na.rm=TRUE) dMax <- max(data[,dEventCol],na.rm=TRUE) } else { dMin <- control$dRange[1] dMax <- control$dRange[length(control$dRange)] } #@hoehle - check that dRange is proper if (!all( format( c(dMin, dMax), epochInPeriodStr) == 1)) { stop("The variables in dRange needs to be at the first of each epoch.") } dateRange <- seq(dMin, dMax, by=aggregate.by) ###################################################################### # Additional manipulation of the control arguments ###################################################################### #Check if alpha is specified if (is.null(control[["alpha",exact=TRUE]])) { control$alpha <- 0.05 } if (is.null(control[["N.tInf.prior",exact=TRUE]])) { control$N.tInf.prior <- "unif" } if (is.null(control[["N.tInf.max",exact=TRUE]])) { control$N.tInf.max <- 300 } if (is.null(control[["gd.prior.kappa",exact=TRUE]])) { control$gd.prior.kappa <- 0.1 } if (is.null(control[["nSamples",exact=TRUE]])) { control$nSamples <- 1e3 } if (is.null(control[["score",exact=TRUE]])) { control$score <- FALSE } #Checking for the bayes.trunc.ddcp procedure. If so make sure params are set up. if ("bayes.trunc.ddcp" %in% method) { #If no parameters at all set to defaults. if (is.null(control[["ddcp",exact=TRUE]])) { control$ddcp <- list(ddChangepoint=NULL, cp_order="zero", Wextra=NULL, logLambda=c("iidLogGa","tps","rw1","rw2"), tau.gamma=1, response.distr=c("poisson"), mcmc=c(burnin=2500, sample=10000, thin=1, adapt=1000, store.samples=FALSE)) } #Check form of logLambda if (is.null(control[["ddcp",exact=TRUE]][["logLambda",exact=TRUE]])) { control[["ddcp"]] <- modifyList(control[["ddcp",exact=TRUE]], list(logLambda="iidLogGa")) } else { control[["ddcp"]]$logLambda <- match.arg(control[["ddcp"]][["logLambda"]],c("iidLogGa","tps","rw1","rw2")) } #Check breakpoint to use in case of bayes.trunc.ddcp (delay distribution with breakpoint) if (is.null(control[["ddcp"]][["ddChangepoint"]]) || !inherits(control[["ddcp"]][["ddChangepoint"]], "Date")) { stop("Please specify a Date object as changepoint in control$ddChangepoint.") } if (any(control[["ddcp"]][["ddChangepoint"]] > now)) { warning("Some of the elements in ddChangepoint are beyond 'now'. This might be problematic!") } ##Check cp_order variable if (!is.null(control[["ddcp",exact=TRUE]][["cp_order",exact=TRUE]])) { control[["ddcp"]]$cp_order <- match.arg(control[["ddcp"]][["cp_order"]],c("zero","one")) } else { control[["ddcp"]]$cp_order <- "zero" } ##Check Wextra argument if (!is.null(control[["ddcp",exact=TRUE]][["Wextra",exact=TRUE]])) { if (!is.array(control[["ddcp",exact=TRUE]][["Wextra",exact=TRUE]])) { stop("Wextra is not an array.") } } #Make this an accessible variable ddChangepoint <- control$ddcp$ddChangepoint Wextra <- control$ddcp$Wextra ncol_Wextra <- if (is.null(Wextra)) 0 else ncol(Wextra) colnames_Wextra <- if (is.null(Wextra)) NULL else colnames(Wextra) cp_order <- control$ddcp$cp_order #Response distribution in the model if (is.null(control[["ddcp",exact=TRUE]][["response.distr",exact=TRUE]])) { control[["ddcp"]]$response.distr <- "poisson" } else { stopifnot(control[["ddcp",exact=TRUE]][["response.distr",exact=TRUE]] %in% c("poisson", "negbin")) } #Precision parameter for gamma coefficients for hazard delay distribution if (is.null(control[["ddcp",exact=TRUE]][["tau.gamma",exact=TRUE]])) { control[["ddcp"]]$tau.gamma <- 1 } #Prior for eta ~ [eta.mu, eta.prec] if (is.null(control[["ddcp",exact=TRUE]][["eta.mu",exact=TRUE]])) { control[["ddcp"]]$eta.mu <- rep(0,length(ddChangepoint) + ncol_Wextra) } else { if (length(control[["ddcp"]]$eta.mu) != length(ddChangepoint) + ncol_Wextra) { stop("length of eta.mu is different from the number of change points in 'ddChangepoint'.") } } if (is.null(control[["ddcp",exact=TRUE]][["eta.prec",exact=TRUE]])) { if (length(ddChangepoint) == 1) { control[["ddcp"]]$eta.prec <- 1 } else { control[["ddcp"]]$eta.prec <- diag(rep(1, length(ddChangepoint))) } } else { #Custom option if (length(ddChangepoint) == 1) { if (length(control[["ddcp"]]$eta.prec) != 1) { stop("length of eta.prec is different from the number of change points in 'ddChangepoint'.") } else { if (!( (nrow(control[["ddcp"]]$eta.prec) == (ncol(control[["ddcp"]]$eta.prec))) & (nrow(control[["ddcp"]]$eta.prec) == length(ddChangepoint)))) { stop(paste0("dimension ", dim(control[["ddcp"]]$eta.prec), " of eta.prec is different from the number of change points in 'ddChangepoint' (",length(ddChangepoint),".")) } } } } #Check MCMC options if (is.null(control[["ddcp",exact=TRUE]][["responseDistr",exact=TRUE]])) { control[["ddcp"]][["responseDistr"]] <- "poisson" } else { # Check that it's a valid response distribution stopifnot(control[["ddcp"]][["responseDistr"]] %in% c("negbin","poisson")) } #Check MCMC options if (is.null(control[["ddcp",exact=TRUE]][["mcmc",exact=TRUE]])) { control[["ddcp"]][["mcmc"]] <- c(burnin=2500,sample=10000,thin=1, adapt=1000, store.samples=FALSE) } else { if (!all(c("burnin","sample","thin", "adapt", "store.samples") %in% names(control[["ddcp",exact=TRUE]][["mcmc",exact=TRUE]]))) { stop("mcmc option list needs names 'burnin', 'sample', 'thin', 'adapt' and 'store.samples'.") } } #done with options for bayes.trunc.ddcp } ###################################################################### # Do preprocessing of the data ###################################################################### hasNADates <- is.na(data[,dEventCol]) | is.na(data[,dReportCol]) data <- data[!hasNADates,] message(paste0("Removed ",sum(hasNADates), " records due to NA dates.")) #Create a column containing the reporting delay using the timeDelay #function data$delay <- timeDelay(data[,dEventCol],data[,dReportCol]) #Handle delays longer than D. #@hoehle - handle that the unit might not just be days #notThereButDThere <- (data[,dReportCol] > now) & ((data[,dEventCol]) + D <= now) notThereButDThere <- (timeDelay(data[,dReportCol],now) < 0) & (timeDelay(data[,dEventCol],now) >= D) if (sum(notThereButDThere,na.rm=TRUE)) { warning(paste(sum(notThereButDThere,na.rm=TRUE), " observations > \"now\" due to a delay >D. If delay cut to D they would be there."),sep="") } #Which observations are available at time s #@hoehle: data.sub <- data[ na2FALSE(data[,dReportCol] <= now),] data.sub <- data[ na2FALSE(timeDelay(data[,dReportCol],now) >= 0),] if (nrow(data.sub)==0) { stop(paste("No data available at now=",now,"\n")) } #Create an sts object containing the observed number of counts until s sts <- linelist2sts(data.sub,dEventCol,aggregate.by=aggregate.by,dRange=dateRange) sts <- as(sts,"stsNC") #Create an extra object containing the "truth" based on data sts.truth <- linelist2sts(data, dEventCol, aggregate.by=aggregate.by, dRange=dateRange) #List of scores to calculate. Can become an argument later on scores <- c("logS","RPS","dist.median","outside.ci") #Initialize scoring rule results - to be saved in control slot -- dirty SR <- array(0,dim=c(nrow(sts),length(method),length(scores))) #List for storing the predictive PMFs. if (is.null(control[["predPMF",exact=TRUE]])) { control$predPMF <- FALSE } #Prepare a list of different estimated of the delay CDF delayCDF <- list() ###################################################################### # Done manipulating the control list with default arguments ###################################################################### sts@control <- control #Save truth sts@truth <- sts.truth #Reserve space for returning the predictive PMFs sts@predPMF <- list() ###################################################################### # Consistency checks ###################################################################### #Check if support of N.tInf is large enough if (2*control$N.tInf.max < max(observed(sts),na.rm=TRUE)) { warning("N.tInf.max appears too small. Largest observed value is more than 50% of N.tInf.max, which -- in case this number is extrapolated -- might cause problems.\n") } #Create a vector representing the support of N.tInf N.tInf.support <- 0:control$N.tInf.max #====================================================================== #====================================================================== # Build reporting triangle and derived parameters for delay #====================================================================== #====================================================================== cat("Building reporting triangle...\n") #Time origin t_0 t0 <- min(dateRange) #Sequence from time origin until now (per day??) t02s <- seq(t0, now,by=aggregate.by) #Maximum time index T <- length(t02s)-1 #Check if the maximum delay is longer than the available time series if (D>T) { stop("D>T. Cannot estimate the long delays.") } #How many observations to take for estimating the delay distribution if (is.null(m)) { m <- T } if (m<1) { stop("Assertion m>=1 not fulfilled.") } #Define the observation triangle n <- matrix(NA,nrow=T+1, ncol=T+1, dimnames=list(as.character(t02s), NULL)) #Loop over time points. (more efficient than delay and then t) for (t in 0:T) { #Extract all reports happening at time (index) t. #@hoehle: data.att <- data.sub[na2FALSE(data.sub[,dEventCol] == t02s[t+1]), ] data.att <- data.sub[na2FALSE(timeDelay(data.sub[,dEventCol], t02s[t+1])) == 0, ] #Loop over all delays for (x in 0:(T-t)) { #Count number with specific delay n[t+1,x+1] <- sum(data.att[,"delay"] == x) } } cat("No. cases: ",sum(n,na.rm=TRUE),"\n") #Handle delays longer than D #@hoehle: Not done! Just fix them to have delay D. # browser() nLongDelay <- apply(n[,(D+1)+seq_len(T-D), drop=FALSE],1,sum,na.rm=TRUE) if (any(nLongDelay>0)) { warning(paste(sum(nLongDelay)," cases with a delay longer than D=",D," days forced to have a delay of D days.\n",sep="")) n <- n[,1:(D+1)] n[,(D+1)] <- n[,(D+1)] + nLongDelay } else { #No problems. Just extract up to D+1 n <- n[,1:(D+1)] } #Calculate n.x and N.x as in (2.7) and (2.8) and Fig.2 of Lawless (1994) #Note the different moving window definition as in the Lawless article. n.x <- rep(0,times=D+1) N.x <- rep(0,times=D+1) ##Compute n.x and N.x for (x in 0:D) { ##Define time of occurrence sliding window index set (see documentation) if (m.interpretation == "hoehle_anderheiden2014") { toc_index_set <- max(0,T-m):(T-x) } else { #hoehle: Lawless definition is max(0,T-m-x) toc_index_set <- max(0,T-m-x):(T-x) } ## Count for (t in toc_index_set) { #cat("x=",x,"\tt=",t,":\n") n.x[x+1] <- n.x[x+1] + n[t+1,x+1] for (y in 0:x) { #cat("x=",x,"\tt=",t,"\ty=",y,":\n") N.x[x+1] <- N.x[x+1] + n[t+1,y+1] } } } cat("No. cases within moving window: ",sum(n.x,na.rm=TRUE),"\n") #Available observations at time T, definition of N(t;T) on p.17. N.tT <- sapply(0:T, function(t) sum(n[t+1, 0:min(D+1,(T-t)+1)])) #Truth - already in another object. Delete?? N.tInf <- table( factor(as.character(data[,dEventCol]),levels=as.character(t02s))) #Store results of the reporting triangle in the control slot together with additional #attributes for fast access of, e.g., summaries or defining variables. reportingTriangle <- n attr(reportingTriangle, "n.x") <- n.x attr(reportingTriangle, "N.x") <- N.x attr(reportingTriangle, "N.tT") <- N.tT attr(reportingTriangle, "N.tInf") <- N.tInf attr(reportingTriangle, "T") <- T attr(reportingTriangle, "D") <- D attr(reportingTriangle, "t02s") <- t02s sts@reportingTriangle <- reportingTriangle #====================================================================== # Calculations are jointly for all t values. #====================================================================== #List of casts each containing a table 0..N.tInf.max with the PMF Ps <- list() #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # # Lawless (1994) method without adjustment for overdispersion # #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if ("lawless" %in% method) { #Hazard function estimates, i.e. g-function estimate as in (2.9) #of Lawless (1994). NAs are set to zero (consequences??) g.hat <- ifelse( !is.na(n.x/N.x), n.x/N.x, 0) #Force g.hat(0)=1 as stated just below (2.1) g.hat[1] <- 1 #Check how the estimated CDF looks #F <- NULL ; for (d in 0:D) { i <- d+seq_len(D-d) ; F[d+1] <- prod(1-g.hat[i+1]) } #plot(0:D,F) #Compute weights Wt.hat as in eqn. (2.13) of Lawless (1994). Use T1=Inf. #Note: Wt.hat estimates F_t(T-t). T1 <- Inf What.t <- sapply(0:T, function(t) { if (t 0) { CDF <- c(0,ltruncpnorm(N.tInf.support, mean=Nhat.tT1[i], sd=sqrt(Vhat.Zt[i]),at=N.tT[i])) PMFs[,i] <- diff(CDF) } else { PMFs[,i] <- (N.tInf.support == Nhat.tT1[i])*1 } } Ps[["lawless"]] <- PMFs } #end lawless procedure #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # # Bayesian method (simple model, clever sampling -> no MCMC) # #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #Part jointly for both bayes and bayes.notrunc if (("bayes.trunc" %in% method) | ("bayes.notrunc" %in% method)) { cat("bayes prep...\n") ###################################################################### # Prior of N(t,\infty) ###################################################################### N.tInf.prior <- control$N.tInf.prior #Extract prior parameters from prior choice if (N.tInf.prior == "pois") { lambda <- attr(N.tInf.prior,"lambda",exact=TRUE) } else { if (N.tInf.prior == "poisgamma") { #Find size parameters such that mean variance is as target. var.prior <- function(size.prior) { mean.prior + mean.prior^2/size.prior } #If mean & var specified if (all(c("mean.lambda","var.lambda") %in% names(attributes(N.tInf.prior)))) { mean.prior <- attr(N.tInf.prior,"mean.lambda",exact=TRUE) var.prior.target <- attr(N.tInf.prior,"var.lambda",exact=TRUE) size.prior <- uniroot( function(size.prior) { var.prior(size.prior) - var.prior.target},interval=c(1e-12,50))$root #Check result cat("(E,V) of prior for lambda = (",paste(c(mean.prior,var.prior(size.prior)),collapse=","),")\n") } else { stop("mean.lambda and var.lambda not part of prior specification") } } else { if (N.tInf.prior == "unif") { N.tInf.prior.max <- attr(N.tInf.prior,"N.tInf.prior.max",exact=TRUE) } else { #No option applied stop("Not a valid prior!") } } } ###################################################################### # Define function to generate PMF for max(0,T-D),..,T by sampling. # # Parameters: # alpha.star, beta.star - vector containing the posterior GD params ###################################################################### pmfBySampling <- function(alpha.star, beta.star) { #Sample from posterior distribution, i.e. sample from the reverse distribution #and reverse result p.sample <- rgd(control$nSamples,alpha.star,beta.star)[,(length(alpha.star)+1):1] #All the time points where extrapolation is to be done tSet <- max(0,(T-D)):T ###################################################################### # Procedure to generate nowcasts of all time points up to T-D,...,T. # This is based on the posterior samples available in p.sample. # Current code adds up the PMF tables instead of a pure sample based # procedure and also prevents PMF=0 better than tabulating the samples. ###################################################################### N.tT1.pred <- array(NA, dim=c(dim(p.sample)[1],control$N.tInf.max+1,dim(p.sample)[2]),dimnames=list(NULL,seq_len(control$N.tInf.max+1)-1L,tSet)) for (j in 1:control$nSamples) { #Extract delay PMF from sample p <- p.sample[j,] #Proportion reported up to x, x=0,..,T F <- c(rep(1,T-D),rev(cumsum(p))) #Guard against numerical instability: ensure that not larger than 1. F <- ifelse(F>1,1,F) #Loop over all time points to nowcast for (i in 1:length(tSet)) { t <- tSet[i] N.tT1.pred[j,,i] <- switch(N.tInf.prior, "poisgamma"=dpost.bnb(N.tT[t+1],sumpd=F[t+1],mu=mean.prior,size=size.prior,N.tInf.max=control$N.tInf.max)) } } #Average the PMFs as in Step (2) of the algorithm PMF <- apply(N.tT1.pred,MARGIN=c(2,3),mean) #Add part, where no prediction needs to be done if (T-D>0) { #Empty PMFs determined <- matrix(0,nrow=control$N.tInf.max+1,ncol=T-D-1+1) #Add "1" entry at the observed for (t in 0:(T-D-1)) { determined[N.tT[t+1]+1,t+1] <- 1 } PMF <- cbind(determined,PMF) } return(PMF) } #done definition of pmfBySampling } if ("bayes.trunc" %in% method) { cat("bayes.trunc...\n") ###################################################################### #Prior of reporting delay as parameters of generalized Dirichlet prior ###################################################################### #Define symmetric dirichlet as prior, just as in the other case alpha.prior <- rep(control$gd.prior.kappa, D) beta.prior <- rep(0,D) beta.prior[D] <- control$gd.prior.kappa for (i in (D-1):1) { beta.prior[i] <- alpha.prior[i+1] + beta.prior[i+1] } ###################################################################### # Posterior section ###################################################################### #Deduce posterior distribution of delay distribution, i.e. it is again #a generalized Dirichlet alpha <- beta <- rep(NA,D) for (d in 0:(D-1)) { alpha[d+1] <- n.x[D-d+1] ##Note: +1 coz index 1 is delay 0. beta[d+1] <- N.x[D-d+1] - n.x[D-d+1] } #Check if there are any points without data and warn about it. if (any(alpha + beta == 0)) { warning("The delays ",paste(D-which(alpha+beta==0)-1,collapse=",")," have no observations. Results might be instable and depend all on prior.") } #Add up. Note: Delay zero (i.e. element D+1) is ignored as this is #not modelled explicitly by the GD distribution (sum to 1 constraints) alpha.star <- alpha.prior + alpha beta.star <- beta.prior + beta #Compute the expectation of the GD distribution and store this as the delay delayCDF[["bayes.trunc"]] <- cumsum(rev(Egd(alpha.star,beta.star))) #Save result Ps[["bayes.trunc"]] <- pmfBySampling(alpha.star, beta.star) } # end "bayes.trunc" %in% method #====================================================================== # Bayesian version which ignores truncation #====================================================================== if ("bayes.notrunc" %in% method) { cat("bayes.notrunc...\n") ###################################################################### # Prior section ###################################################################### alpha.prior <- rep(control$gd.prior.kappa, D) #symmetric dirichlet beta.prior <- rep(0,D) beta.prior[D] <- control$gd.prior.kappa for (i in (D-1):1) { beta.prior[i] <- alpha.prior[i+1] + beta.prior[i+1] } ###################################################################### # Posterior section ###################################################################### #Deduce posterior distribution of delay distribution, i.e. it is again #a generalized Dirichlet alpha <- beta <- rep(NA,D) for (d in 0:(D-1)) { alpha[d+1] <- n.x[D-d+1] beta[d+1] <- sum(n.x[D - (d+1):D + 1]) } #Check if there are any points without data and warn about it. if (any(alpha + beta == 0)) { warning("The delays ",paste(D-which(alpha+beta==0)-1,collapse=",")," have no observations. Results might be instable and depend all on prior.") } #Posterior parameters. alpha.star <- alpha.prior + alpha beta.star <- beta.prior + beta #Check that its a ordinary Dirichlet for (i in (D-1):1) { if (!all.equal(beta.star[i], alpha.star[i+1] + beta.star[i+1])) { warning("Posterior at i=",i," is not an ordinary Dirichlet as it's supposed to be.") } } #Save resulting delay distribution delayCDF[["bayes.notrunc"]] <- cumsum(rev(Egd(alpha.star,beta.star))) Ps[["bayes.notrunc"]] <- pmfBySampling(alpha.star,beta.star) } # end bayes.notrunc ###################################################################### # Unadjusted procedure using beta negative binomial. ToDo: # integrate code with other Bayesian procedures ###################################################################### if ("bayes.notrunc.bnb" %in% method) { cat("bayes.notrunc.bnb...\n") ###################################################################### # Prior section (same as for all methods) ###################################################################### alpha.prior <- rep(control$gd.prior.kappa, D) #symmetric dirichlet beta.prior <- rep(0,D) beta.prior[D] <- control$gd.prior.kappa for (i in (D-1):1) { beta.prior[i] <- alpha.prior[i+1] + beta.prior[i+1] } ###################################################################### # Posterior section ###################################################################### #Deduce posterior distribution of delay distribution, i.e. it is again #an ordinary Dirichlet alpha <- beta <- rep(NA,D) for (d in 0:(D-1)) { alpha[d+1] <- n.x[D-d+1] beta[d+1] <- sum(n.x[D - (d+1):D + 1]) } #Check if there are any points without data and warn about it. if (any(alpha + beta == 0)) { warning("The delays ",paste(D-which(alpha+beta==0)-1,collapse=",")," have no observations. Results might be instable and depend all on prior.") } #Posterior parameters. alpha.star <- alpha.prior + alpha beta.star <- beta.prior + beta #Check that its a ordinary Dirichlet for (i in (D-1):1) { if (!all.equal(beta.star[i], alpha.star[i+1] + beta.star[i+1])) { warning("Posterior at i=",i," is not an ordinary Dirichlet as it's supposed to be.") } } #Save resulting delay distribution (i.e. no truncation adjustment) delayCDF[["bayes.notrunc"]] <- cumsum(rev(Egd(alpha.star,beta.star))) #Allocate PMF to return PMF <- matrix(0,nrow=control$N.tInf.max+1,ncol=length(max(0,(T-D)):T)) #Concentration parameter vector of the ordinary Dirichlet distribution #Note. alpha.star vector is reversed (shortest delay last). alpha <- rev(c(alpha.star,beta.star[length(beta.star)])) #consistency check if (!all.equal(rev(Egd(alpha.star,beta.star)),alpha/sum(alpha))) { stop("Problem. GD and Dirichlet do not correspond...") } tSet <- max(0,(T-D)):T for (i in 1:length(tSet)) { t <- tSet[i] alpha.i <- cumsum(alpha)[T-t+1] beta.i <- sum(alpha) - alpha.i if (T-t==D) { PMF[,i] <- ifelse( N.tInf.support == N.tT[t+1], 1, 0) } else { #Calculate PMF knowing the q ~ Beta( , ) by the aggregation #property. #Note: Vector N.tT starts at time zero, i.e. time T corresponds to T+1 PMF[,i] <- dbnb( N.tInf.support - N.tT[t+1],n=N.tT[t+1]+1, alpha=alpha.i, beta=beta.i) } } #done looping over all time points #Add part, where no prediction needs to be done if (T-D>0) { #Empty PMFs determined <- matrix(0,nrow=control$N.tInf.max+1,ncol=T-D-1+1) #Add "1" entry at the observed for (t in 0:(T-D-1)) { determined[N.tT[t+1]+1,t+1] <- 1 } PMF <- cbind(determined,PMF) } Ps[["bayes.notrunc.bnb"]] <- PMF } # end bayes.notrunc.bnb ###################################################################### # Fully Bayes version with MCMC ###################################################################### if ("bayes.trunc.ddcp" %in% method) { #Allocate result PMF <- matrix( 0,ncol=(T+1),nrow=control$N.tInf.max+1) #Fix seed value of JAGS RNG for each chain n.chains <- 3 init <- lapply(1:n.chains,function(i) { list(.RNG.name="base::Mersenne-Twister",.RNG.seed=i*10) }) #Make design matrix for a quadratic TPS spline in time makeTPSDesign <- function(T,degree=2) { nbeta=degree + 1 X <- matrix(NA,ncol=nbeta, nrow=T+1) for (t in 0:T) { #Form a centered time covariate t.centered <- t - T/2 for(pow in 0:degree) { X[t+1,pow+1]<- t.centered^(pow) } } #Make the knot points evenly spaced between 0,T not including these points knots <- seq(0,T,length=min(round(T/6)+2,22)) knots <- knots[-c(1,length(knots))] #Remove knots which are beyond T-maxDelay/2 knots <- knots[knots <= T-D/2] knots <- knots - T/2 nknots <- length(knots) #Penalty as REs - setup design matrix Z <- matrix(NA,nrow=T+1,ncol=length(knots)) for (t in 0:T){ t.center <- t - T/2 for(k in 1:nknots){ Z[t+1,k]<- pmax((t.center-knots[k]),0)^degree } } return(list(X=X,Z=Z,knots=knots,nknots=nknots,nbeta=nbeta)) } tps <- makeTPSDesign(T=T,degree=2) ##browser() #Design matrix for logistic discrete time hazard model containing #changepoints. Could be extended s.t. the user provides W. W <- array(NA, dim=c(T+1, length(ddChangepoint) + ncol_Wextra, D+1), dimnames=list(as.character(t02s), c(as.character(ddChangepoint),colnames_Wextra),paste("delay",0:D,sep=""))) for (t in 0:T) { for (i in 1:length(ddChangepoint)) { # Shape design matrix for change-points if (cp_order == "zero") { W[t+1, i, ] <- as.numeric( (t02s[t+1] + 0:D) >= ddChangepoint[i]) } else if (cp_order == "one") { W[t+1, i, ] <- pmax(0, as.numeric( (t02s[t+1] + 0:D) - ddChangepoint[i])) } } # Add additional effects as part of the design matrix if (ncol_Wextra > 0) { W[t + 1, length(ddChangepoint) + 1:ncol(Wextra), ] <- Wextra[t+1,, ] } } #Priors. Uniform on the delays D.prime <- round( D/2-0.4)+1 p.prior <- rep(1/(D.prime+1), D.prime+1) mu.gamma <- qlogis( p.prior[1]) for (d in 1:(D.prime-1)) { mu.gamma <- c(mu.gamma, qlogis( p.prior[d+1] / (1-sum(p.prior[1:d])))) } tau.gamma <- rep(control$ddcp$tau.gamma,times=D.prime) #Prepare data for JAGS jagsData <- list(#Data rT=n,T=T+1,m=m+1,maxDelay=D, #Time dependent logistic discrete hazard model W=W, eta.mu=control$ddcp$eta.mu, eta.prec=control$ddcp$eta.prec, mu.gamma=mu.gamma, tau.gamma=tau.gamma, #Epidemic curve alpha.lambda=2500/3000,beta.lambda=50/3000, #Spline related stuff X=tps$X,Z=tps$Z,nknots=tps$nknots,beta.mu=rep(0,tps$nbeta),beta.prec=1e-6*diag(tps$nbeta) ) #Select appropriate model (one of: "tps","rw2","iid", "rw" as specified in the options) logLambda.method <- control$ddcp$logLambda responseDistr<- control$ddcp$responseDistr ### browser() #Load the BUGS specification of the Bayesian hierarchical Poisson model bugsModel <- readLines(file.path(path.package('surveillance'), 'jags',"bhpm.bugs")) # Load local file #bugsModel <- readLines(file.path("bhpm.bugs")) bugsModel <- gsub(paste("#<",logLambda.method,">",sep=""),"",bugsModel) bugsModel <- gsub(paste("#<",responseDistr,">",sep=""),"",bugsModel) ##browser() #Problem when eta is scalar (TODO: Improve the solution.) if (length(ddChangepoint) == 1) { #Make eta ~ dnorm( , ) instead of eta ~ dmnorm bugsModel <- gsub("(^[ ]*eta ~ )(dmnorm)","\\1dnorm",bugsModel) #Use eta[1] instead of eta for matrix multiplication bugsModel <- gsub("(eta)(.*%\\*%)","eta\\[1\\]\\2",bugsModel) } #cat(paste(bugsModel,collapse="\n")) bugsFile <- tempfile(pattern = "nowcast-") writeLines(bugsModel, bugsFile) ##browser() ## if (FALSE) { ## #Try to compile the model with ordinary rjags to see if there are any problems ## #before doing 3 chains parallelized using runjags. ## model <- jags.model(bugsFile, ## data = jagsData, ## init=init, #Fix seed value of JAGS as well ## n.chains = n.chains, n.adapt = 100) ## list.samplers(model) ## coda.samples(model,variable.names='logLambda',n.iter=100) ## } ###################################################################### # runjags way -- ToDo: parametrize using control options! ###################################################################### runjagsMethod <- 'rjparallel' #'rjags' monitor <- c('gamma','eta','logLambda','NtInf', ifelse(control$ddcp$responseDistr == "negbin", "r", NA)) samples.rj <- runjags::run.jags(bugsFile,#bugsModel, monitor = monitor, data=jagsData, n.chains=3, inits = init, burnin = control$ddcp$mcmc["burnin"], sample = control$ddcp$mcmc["sample"], thin = control$ddcp$mcmc["thin"], adapt = control$ddcp$mcmc["adapt"], summarise = FALSE, method=runjagsMethod) #Extract posterior median of discrete survival time delay distribution model parameters dt.surv.samples <- coda::as.mcmc.list(samples.rj, vars = c('gamma','^eta')) post.median <- dt.surv.pm <- apply( as.matrix(dt.surv.samples), 2, median) #Posterior median of the lambda's lambda.post <- exp(apply( as.matrix(coda::as.mcmc.list(samples.rj, vars = c('^logLambda'))), 2, quantile, prob=c(0.025,0.5,0.975))) #Extract posterior median of model parameters gamma.red <- post.median[grep("gamma",names(post.median))] eta <- matrix(post.median[grep("^eta",names(post.median))]) rownames(eta) <- colnames(W) #Map from reduced set to full set gamma <- gamma.red[round( (0:(D-1))/2 - 0.4) + 1] #browser() #Compute the resulting PMF from the model. Possibly put this in a separate function. pmf <- matrix(NA, nrow=nrow(W), ncol=D+1, dimnames=list(as.character(t02s), paste("delay", 0:D, sep=""))) #Determine PMF for (t in 1:length(t02s)) { if (as.character(t02s[t]) %in% rownames(W)) { lin.pred <- ( gamma + t(eta) %*% W[t,,0:D]) pmf[t,] <- haz2pmf(c(plogis(lin.pred),1)) } } #Store result as CDF delayCDF[["bayes.trunc.ddcp"]] <- t(apply(pmf, 1, cumsum)) # Convert to coda compatible output. samples <- coda::as.mcmc.list(samples.rj) # Store model as attribute if(control$ddcp$logLambda != "tps") tps <- NULL # Configure list with model output and store is as an attribute. list_return <- list(post.median=dt.surv.pm,W=W,lambda.post=lambda.post,tps=tps, gamma=gamma, eta=eta) if (control[["ddcp",exact=TRUE]][["mcmc",exact=TRUE]][["store.samples", exact=TRUE]]) { list_return <- modifyList(list_return, list(mcmc_samples = samples)) } attr(delayCDF[["bayes.trunc.ddcp"]],"model") <- list_return # Extract PMFs for (t in 0:T) { #Extract samples related to this time point vals <- as.matrix(samples[,paste("NtInf[",t+1,"]",sep="")]) #PMF PMF[,t+1] <- prop.table(table(factor(vals,levels=0:control$N.tInf.max))) } Ps[["bayes.trunc.ddcp"]] <- PMF } #====================================================================== #A really bad forecast -- the uniform #====================================================================== if ("unif" %in% method) { #Allocate result PMF <- matrix( 0,ncol=(T+1),nrow=control$N.tInf.max+1) #Loop over all time points to nowcast and put U(N.tT[t],Nmax) for (t in 0:T) { #How many values are there in N.tT .. Nmax noVals <- max(0,control$N.tInf.max - N.tT[t+1]) + 1 #PMF at t is 0,...0 (N.tT-1 times), 1/noVals,...,1/noVals PMF[,t+1] <- c(rep(0,N.tT[t+1]),rep(1/noVals,times=noVals)) } Ps[["unif"]] <- PMF } ###################################################################### #Loop over all time points in the vector "when". Only these are #returned. ###################################################################### idxt <- which(dateRange %in% when) for (i in idxt) { #Save PMFs if that is requested if (control$predPMF) { res <- list() for (j in 1:length(method)) { res[[method[j]]] <- Ps[[method[j]]][,i] } sts@predPMF[[as.character(dateRange[i])]] <- res } #Evaluate scoring rules, if requested if (control$score) { #Infer the true value ytinf <- observed(sts.truth)[i,] #Evaluate all scores for all predictive distributions for (i.P in 1:length(method)) { for (i.score in 1:length(scores)) { #cat("i=",i," i.P=",i.P," (",method[i.P],") i.score=",i.score,"\n") SR[i,i.P,i.score] <- do.call(scores[i.score],args=list(P=Ps[[method[i.P]]][,i],y=ytinf,alpha=control$alpha)) } } } #end if control$score #Add first nowcast & ci to stsNC slots sts@upperbound[i,] <- median(N.tInf.support[which.max( cumsum(Ps[[method[1]]][,i])>0.5)]) sts@pi[i,,] <- N.tInf.support[c(which.max(cumsum(Ps[[method[1]]][,i]) > control$alpha/2),which.max(cumsum(Ps[[method[1]]][,i]) > 1-control$alpha/2))] dimnames(sts@pi) <- list(as.character(dateRange),NULL,paste( c(control$alpha/2*100,(1-control$alpha/2)*100),"%",sep="")) } #end of loop over time points #Add scoring rule to output if (control$score) { dimnames(SR) <- list(as.character(dateRange),method,scores) sts@SR <- SR } ###################################################################### #Other arguments to save in control object ###################################################################### sts@control$N.tInf.support <- N.tInf.support sts@control$method <- sts@control$name <- method #Store variables relevant for the nowcast sts@control$D <- D sts@control$m <- m sts@control$now <- now sts@control$when <- when sts@control$timeDelay <- timeDelay #Store delayCDF object sts@delayCDF <- delayCDF #For backwards compatibility -- change this in the future TODODODODODO! sts@control$yt.support <- sts@control$N.tInf.support sts@control$y.prior.max <- sts@control$N.tInf.max ##Store the call options theCall <- list(now=now,when=when,data=data,dEventCol=dEventCol,dReportCol=dReportCol,method=method,aggregate.by=aggregate.by,D=D, m=m) sts@control$call <- theCall ##Done return(sts) } ###################################################################### # Helper functions ###################################################################### #Helper function na2FALSE <- function(x) {x[is.na(x)] <- FALSE ; return(x) } ###################################################################### # Logarithmic score # # Parameters: # P - predictive distribution, given as a vector containing the PMF # with support 0,...,N.prior.max # y - the actual observation. Can be a vector. # # Returns: # -log P(y). If y outside 0,..,N.prior.max then -Inf. ###################################################################### logS <- function(P, y, ...) { return(ifelse( y>=0 & y<=length(P)-1, -log(P[y+1]), -Inf)) } ###################################################################### # Ranked probability score # # Parameters: # P - predictive distribution, given as a vector containing the PMF # with support 0,...,N.prior.max # y - the actual observation. Can be a vector. # # Returns: # -log P(y). If y outside 0,..,N.prior.max then -Inf. ###################################################################### RPS <- function(P,y, ...) { N.support <- 0:(length(P)-1) sum( (cumsum(P) - (y <= N.support))^2) } #Some other scoring rules which are not proper. dist.median <- function(P,y, ...) { point.estimate <- which.max(cumsum(P)>=0.5) - 1 return(abs(point.estimate - y)) } #0/1 indicator of observed value outside equal tailed (1-alpha/2) CI outside.ci <- function(P,y,alpha) { N.support <- 0:(length(P)-1) ci <- N.support[c(which.max(cumsum(P) > alpha/2),which.max(cumsum(P) > 1-alpha/2))] ifelse( y>=ci[1] & y<=ci[2], 0, 1) } ###################################################################### # Helper functions for sampling the predictive distribution ###################################################################### #Unnormalized in Binomial-Negative-Binomial Hierarchy. Should work for vectors of N.tInf! #Only kernel parts for N.tInf need to be taken into account dpost.bnb.unorm <- function(N.tInf, N.tT, sumpd, mu, size) { dbinom(N.tT, size=N.tInf, prob=sumpd)*dnbinom(N.tInf, mu=mu,size=size) #Direct implementation - appears to be less stable... #ifelse(N.tInf >= N.tT, # exp(lgamma(N.tInf+size)-lgamma(N.tInf-N.tT+1) + N.tInf*log( (1-sumpd)*(mu/(mu+size)))),0) #Compare the 2 ## foo.a <- dbinom(N.tT, size=N.tInf, prob=sumpd)*dnbinom(N.tInf, mu=mu,size=size) ## foo.b <- ifelse(N.tInf >= N.tT, #& N.tInf <= size, ## exp(lgamma(N.tInf+size)-lgamma(N.tInf-N.tT+1) + N.tInf*log( (1-sumpd)*(mu/(mu+size)))),0) ## plot(foo.a/sum(foo.a)) ## points(foo.b/sum(foo.b),col="red") } #Sample in binomial-negative-binomial hierarchy rpost.bnb <- function(n=1, N.tT, sumpd, mu,size, N.tInf.max=1e4) { p <- dpost.bnb.unorm(0:N.tInf.max,N.tT=N.tT,sumpd=sumpd, mu=mu,size=size) #Set NA values to zero (why would they be NA?) #if (is.na(sum(p))) { warning("rpost.bnb: sum is NA") ; browser(p)} #Normalize the distribution - safe this for time reasons #p <- p/sum(p) #Sample sample(0:N.tInf.max, size=n, replace=TRUE, prob=p) } #PMF for the predictive distribution in binomial-negative-binomial hierarchy. #Returns entire vector for 0:N.tInf.max dpost.bnb <- function(N.tT, sumpd, mu,size, N.tInf.max=1e4) { p <- dpost.bnb.unorm(0:N.tInf.max,N.tT=N.tT,sumpd=sumpd, mu=mu,size=size) #Set NA values to zero (why would they be NA?) #if (is.na(sum(p))) { warning("rpost.bnb: sum is NA") ; browser(p)} #Normalize the distribution - safe this for time reasons return(p/sum(p)) } ###################################################################### # PMF of the beta-negatative binomial distribution # See Teerapabolarn (2008) # # Parameters: # k - where to evaluate. can be a vector. # # Returns: # PMF. ###################################################################### dbnb <- function(k,n,alpha,beta) { #Check if k's outside the support are requested. neg <- k<0 k[neg] <- 0 #Calculate the density of the beta-negbin. See Teerapabolarn (2008) num <- lgamma(n+alpha)+lgamma(k+beta)+lgamma(n+k)+lgamma(alpha+beta) den <- lgamma(n+k+alpha+beta)+lgamma(n)+lgamma(k+1)+lgamma(alpha)+lgamma(beta) res <- exp(num-den) res[neg] <- 0 return( res) } ###################################################################### # Convert discrete time hazard function on 0,...,Dmax to a probability # mass function. # # Parameters: # haz - vector with entries for (0,...,Dmax) # Returns: # vector with PMF on 0,...,Dmax. ###################################################################### haz2pmf <- function(haz) { PMF <- 0*haz for (i in 0:(length(haz)-1)) { PMF[i+1] <- haz[i+1] * (1-sum(PMF[seq(i)])) } return(PMF) } surveillance/R/pairedbinCUSUM.R0000644000176200001440000002060314615164167016060 0ustar liggesusers###################################################################### # Compute ARL for paired binary CUSUM charts as introduced in Steiner, # Cook and Farefwell, 1999, Monitoring paired binary surgical outcomes, # Stats in Med, 18, 69-86. # # This code is an R implementation of Matlab code provided by # Stefan H. Steiner, University of Waterloo, Canada. # # Params: # p - vector giving the probability of the four different possibilities # c((death=0,near-miss=0),(death=1,near-miss=0), # (death=0,near-miss=1),(death=1,near-miss=1)) # w1, w2 - w1 and w2 are the sample weights vectors for the two CUSUMs. # (see (2)). We have w1 is equal to deaths # (according to paper it being 2 would be more realistic) # h1, h2 - decision barriers for the individual cusums (see (3)) # h11,h22 - joint decision barriers (see (3)) # sparse - use Matrix package ###################################################################### pairedbinCUSUM.runlength <- function(p,w1,w2,h1,h2,h11,h22, sparse=FALSE) { #Size of the sparse matrix -- assumption h1>h11 and h2>h22 mw <- h1*h22+(h2-h22)*h11 cat("g =",mw+3,"\n") #build transition matrix; look at current state as an ordered pair (x1,x2) #the size of the matrix is determined by h1, h2, and h11 and h22 #Look at all 3 possible absorbing conditions transm <- matrix(0, mw+3, mw+3) #the last row/column is the absorbing state, I_{3\times 3} block #Is this ever used?? transm[mw+1,mw+1] <- 1 transm[mw+2,mw+2] <- 1 transm[mw+3,mw+3] <- 1 #go over each row and fill in the transition probabilities for (i in 1:mw) { # cat(i," out of ", mw,"\n") #find the corresponding state if (i>h1*h22) { temp <- floor((i-h1*h22-1)/h11) x1 <- i-h1*h22-1-temp*h11 x2 <- temp+h22 } else { x2 <- floor((i-1)/h1) x1 <- i-x2*h1-1 } #go over the four different weight combinations for (j in 1:2) { for (k in 1:2) { x1n <- x1+w1[j+2*(k-1)] #death chart x2n <- x2+w2[k] #look at all possible combinations of weights #we can't go below zero if (x1n<0) { x1n <- 0 } if (x2n<0) { x2n <- 0 } newcond=0 #try to figure out what condition index the new CUSUM values correspond to if (x1n>=h1) { newcond <- mw+1 #absorbing state on x1 } else { if (x2n>=h2) { newcond <- mw+2 #absorbing state on x2 } else { if ((x1n>=h11)&(x2n>=h22)) { #only register this if other two conditions are not satisfied newcond <- mw+3 } } } if (newcond==0) { #transition is not to an absorbing state #translate legal ordered pair to state number if (x2n h1, S[t+1,2] > h2) if ((S[t+1,1] > h11) & (S[t+1,2] > h22)) { alarm <- c(TRUE,TRUE) } # alarm <- (S[t+1,1] > h1) | (S[t+1,2] > h2) | # ((S[t+1,1] > h11) & (S[t+1,2] > h22)) #If one or both of the CUSUMs produced an alarm then stop if ((sum(alarm)>0) | (t==nrow(x))) { stopped <- TRUE} } return(list(N=t,val=S[-1,],alarm=alarm)) } ###################################################################### # STS wrapper for the Paired binary CUSUM method. This follows in # style the categoricalCUSUM method. ###################################################################### pairedbinCUSUM <- function(stsObj, control = list(range=NULL,theta0,theta1,h1,h2,h11,h22)) { # Set the default values if not yet set if(is.null(control[["range"]])) { control$range <- 1:nrow(observed(stsObj)) } else { # subset stsObj stsObj <- stsObj[control[["range"]], ] } if(is.null(control[["theta0"]])) { stop("no specification of in-control parameters theta0") } if(is.null(control[["theta1"]])) { stop("no specification of out-of-control parameters theta1") } if(is.null(control[["h1"]])) { stop("no specification of primary threshold h1 for first series") } if(is.null(control[["h2"]])) { stop("no specification of primary threshold h2 for 2nd series") } if(is.null(control[["h11"]])) { stop("no specification of secondary limit h11 for 1st series") } if(is.null(control[["h22"]])) { stop("no specification of secondary limit h11 for 2nd series") } #Extract the important parts from the arguments y <- stsObj@observed nTime <- nrow(y) theta0 <- control[["theta0"]] theta1 <- control[["theta1"]] h1 <- control[["h1"]] h2 <- control[["h2"]] h11 <- control[["h11"]] h22 <- control[["h22"]] #Semantic checks. if (ncol(y) != 2) { stop("the number of columns in the sts object needs to be two") } #Reserve space for the results. Contrary to the categorical CUSUM #method, each ROW represents a series. alarm <- matrix(data = FALSE, nrow = nTime, ncol = 2) upperbound <- matrix(data = 0, nrow = nTime, ncol = 2) #Setup counters for the progress doneidx <- 0 N <- 1 noofalarms <- 0 ####################################################### #Loop as long as we are not through the entire sequence ####################################################### while (doneidx < nTime) { #Run paired binary CUSUM until the next alarm res <- pairedbinCUSUM.LLRcompute(x=y, theta0=theta0, theta1=theta1, h1=h1, h2=h2, h11=h11, h22=h22) #In case an alarm found log this and reset the chart at res$N+1 if (res$N < nrow(y)) { #Put appropriate value in upperbound upperbound[1:res$N + doneidx,] <- res$val[1:res$N,] alarm[res$N + doneidx,] <- res$alarm #Chop & get ready for next round y <- y[-(1:res$N),,drop=FALSE] # theta0 <- pi0[,-(1:res$N),drop=FALSE] # theta1 <- pi1[,-(1:res$N),drop=FALSE] # n <- n[-(1:res$N)] #Add to the number of alarms noofalarms <- noofalarms + 1 } doneidx <- doneidx + res$N } #Add upperbound-statistic of last segment, where no alarm is reached upperbound[(doneidx-res$N+1):nrow(upperbound),] <- res$val # Add name and data name to control object control$name <- "pairedbinCUSUM" control$data <- NULL #not supported anymore #write results to stsObj stsObj@alarm <- alarm stsObj@upperbound <- upperbound stsObj@control <- control #Ensure dimnames in the new object stsObj <- fix.dimnames(stsObj) #Done return(stsObj) } surveillance/R/twinSIR_helper.R0000644000176200001440000002167514426171115016205 0ustar liggesusers################################################################################ ### Auxiliary functions for twinSIR() ### and to compute one-sided AIC by simulation (in twinSIR_methods.R) ### ### Copyright (C) 2009-2014 Sebastian Meyer, contributions by Michael Hoehle ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ################################################################################ # The cox function is used in model formulae to indicate/capture the variables # which go into the cox part/endemic component of the model. # Also, with this "cox variables" it is possible to build up interactions # as usual: cox(var1):cox(var2)... (as if cox(...) was a normal variable) ################################################################################ cox <- function (x) { x } ################################################################################ # read.design extracts the two parts X and Z of the design matrix. # Z contains the endemic part (consisting of the cox(.) terms), # X contains the epidemic part (the rest). # The automatic intercept variable is excluded from these matrices! # # ARGS: # m - a model.frame # Terms - terms for this model.frame (used to extract the model.matrix from m) # RETURNS: # list of matrices X and Z. # If there is no variable in one part of the model the corresponding matrix has # 0 columns, e.g. ncol(Z) = 0, if there is no endemic (Cox) part. # NOTE: # This function is inspired from the timereg package by T. Scheike (available # under GPL2). See http://staff.pubhealth.ku.dk/~ts/timereg.html for details. # The function has been improved/modified to fit our purposes. ################################################################################ read.design <- function (m, Terms) { attr(Terms, "intercept") <- 1 # we will remove the intercept later on # we need this to ensure that we have a reference category # in case of factors (correct contrasts) XZ <- model.matrix(Terms, m) Zterms <- grep("cox\\([^)]+\\)", colnames(XZ), ignore.case = FALSE, perl = FALSE, value = FALSE, fixed = FALSE, useBytes = FALSE, invert = FALSE) # timereg 1.0-9 way: pattern="^cox[(][A-z0-9._]*[)]" with perl=TRUE X <- XZ[, -c(1L, Zterms), drop = FALSE] Z <- XZ[, Zterms, drop = FALSE] ud <- list(X = X, Z = Z) return(ud) } ## Alternative way to do the same thing as read.design. ## This approach is similar to that of coxph, but most often some milliseconds ## slower. # read.design <- function (m, Terms) # { # attr(Terms, "intercept") <- 1 # we will remove the intercept later on # # we need this to ensure that we have a reference category # # in case of factors (right contrasts) # nCoxTerms <- length(attr(Terms, "specials")[["cox"]]) # if (nCoxTerms > 0) { # dropX <- untangle.specials(Terms, "cox", order=1:3)$terms # } # if (length(dropX) > 0) { # X <- model.matrix(Terms[-dropX], m) # by subscripting a Terms object, # Z <- model.matrix(Terms[dropX], m) # one always gets an intercept term # Z <- Z[, -1, drop = FALSE] # } else { # X <- model.matrix(Terms, m) # Z <- X[, NULL, drop = FALSE] # } # X <- X[, -1, drop = FALSE] # # ud <- list(X = X, Z = Z) # return(ud) # } ################################################################################ # Little helper function which returns either summary(object) or simply object, # if it is already a summary. The function also verifies the 'class'. ################################################################################ getSummary <- function (object, class) { summaryClass <- paste("summary", class, sep=".") if (inherits(object, class)) { summary(object) } else if (inherits(object, summaryClass)) { object } else { stop("'object' must inherit from class \"", summaryClass, "\" or \"", class, "\"") } } ################################################################################ ############################## OSAIC function ################################## ################################################################################ # Two functions: # Ztilde.chibarsq <- function(Z,p,Winv,tR,s=1) # w.chibarsq.sim <- function(p, W, N=1e4) # # Both functions are only used internally, no need for documentation # they are used in function .OSAICpenalty (twinSIR_methods.R) ################################################################################ ########################################################################## # This function computes Ztilde # for one Z as specified in Simulation 3, Silvapulle & Sen (2005), p. 79. # See also p. 37 for the quadprog link. # # Params: # Z - px1 matrix or vector with specific Z value # p - dimension of the problem, where theta is restricted to R^{+p} # Winv - inverse of covariance matrix of Z # tR - transpose of constraint matrix R\theta \geq 0. In all cases equal to # diag(p), but to save time we deliver it to the function every time # s - rescale objective function (division by s) # # Returns: # Ztilde, the point at which (Z-\theta)' W^{-1} (Z-\theta) is the # minimum over \theta \geq 0. ########################################################################## Ztilde.chibarsq <- function(Z,p,Winv,tR,s=1) { #The solve.QP function minimizes #-d^T b + 1/2 b^T D b subject to the constraints A^T b >= b_0. #Thus using p. 37 we have d = t(Winv) %*% Z. d <- crossprod(Winv, Z) #Note: Winv and d can become quiet large (or small), but since the solution is #invariant to the scaling of the function being minimized, we can equivalently #call solve.QP using D/s and d/s (e.g., s=mean(D)) to avoid the error #"constraints are inconsistent, no solution!" theta <- quadprog::solve.QP(Dmat = Winv/s, dvec = d/s, Amat = tR, bvec = rep.int(0,p), meq = 0)$solution return(sum(theta > 0)) } ###################################################################### # Compute OSAIC by simulation weights as described in Silvapulle & Sen # (2005), Simulation 3, p.79. # # Params: # p - dimension of the problem, theta is constrained to R^{+p} # W - covariance matrix of the chibarsq distribution # N - number of simulations to use # # Returns: # vector of length p+1 containing the weights w_i, i=0, \ldots, p, # computed by Monte Carlo simulation ###################################################################### w.chibarsq.sim <- function(p, W, N=1e4) { #Draw Z's from multivariate normal distribution with covariance #matrix W Z <- mvrnorm(N, rep.int(0,p), W) if (is.vector(Z)) Z <- t(Z) # case N==1 #inverse of W Winv <- solve(W) #For each simulation calculate Ztilde sims <- apply(X=Z, MARGIN=1, FUN=Ztilde.chibarsq, p=p, Winv=Winv, tR=diag(p), s=mean(Winv)) w <- table(factor(sims, levels=0:p)) / N return(w) } ################################################################################ # The helper 'getModel.simEpidata' extracts the model of an object of class # "simEpidata" similar to the function 'twinSIR' with model = TRUE, # i.e. a list with components survs, X, Z and weights, where atRiskY == 1. # The log-baseline h0 is evaluated at start times of intervals only. # This function is used in function 'intensityPlot'. ################################################################################ getModel.simEpidata <- function (object, ...) { class(object) <- "data.frame" # avoid use of [.epidata (not necessary here) config <- attr(object, "config") alpha <- config$alpha beta <- config$beta atRiskY1 <- object$atRiskY == 1 simepi1 <- object[atRiskY1,] survs <- simepi1[c("id", "start", "stop", "event")] attr(survs, "eventTimes") <- attr(object, "eventTimes") attr(survs, "timeRange") <- attr(object, "timeRange") X <- as.matrix(simepi1[tail(1:ncol(simepi1), length(alpha))]) logbaseline <- sapply(survs$start, FUN = config$h0, simplify = TRUE) Terms <- attr(object, "terms") Z <- read.design(model.frame(Terms, simepi1), Terms)$Z Z <- cbind("cox(logbaseline)" = logbaseline, Z) model <- list(survs = survs, X = X, Z = Z, weights = rep.int(1,nrow(survs))) return(model) } ### Similar auxiliary method extracting the model component ### of a fitted 'twinSIR' getModel.twinSIR <- function (object, ...) { if (is.null(model <- object[["model"]])) { stop("'", deparse(substitute(object)), "' does not contain the 'model' ", "component (use 'model = TRUE' when calling 'twinSIR')") } return(model) } surveillance/R/backprojNP.R0000644000176200001440000003272114431116166015333 0ustar liggesusers###################################################################### # Implementation of the backprojection method as described in # Becker et al. (1991), Stats in Med, 10, 1527-1542. The method # was originally developed for the back-projection of AIDS incidence # but it is equally useful for analysing the epidemic curve in outbreak # situations of a disease with long incubation time, e.g. in order # to illustrate the effect of intervention measures. # # See backprojNP.Rd for the remaining details. ###################################################################### ###################################################################### # Helper function: Replace NaN or is.infinite values with zero. # Good against division by zero problems. # # Parameters: # x - a vector of type double ###################################################################### naninf2zero <- function(x) {x[is.nan(x) | is.infinite(x)] <- 0 ; return(x)} ###################################################################### # Single step of the EMS algorithm by Becker et al (1991). This function # is called by backprojNP. # # Parameters: # lambda.old - vector of length T containing the current rates # Y - vector of length T containing the observed values # dincu - probability mass function of the incubation time. I.e. # a function to be evaluated at integer numbers # pincu - cumulative mass function of the incubation time, i.e. an # object of type function. Needs to in sync with dincu. # k - smoothing parameter of the EMS algo, # needs to be an even number # # Returns: # ###################################################################### em.step.becker <- function(lambda.old, Y, dincu, pincu, k, incu.pmf, eq3a.method=c("R","C")) { #k needs to be divisible by two if (k %% 2 != 0) stop("k needs to be even.") #which method to use eq3a.method <- match.arg(eq3a.method,c("R","C")) #Initialize T <- length(Y) #Define new parameters phi.new <- lambda.new <- 0*lambda.old if (eq3a.method=="R") { #EM step. Problem that some of the sums can be zero if the incubation #distribution has zeroes at d=0,1,2 for (t in 1:T) { #Calculate sum as in equation (3a) of Becker (1991) sum3a <- 0 for (d in 0:(T-t)) { sum3a <- sum3a + Y[t+d] * naninf2zero(dincu(d) / sum(sapply(1:(t+d),function(i) lambda.old[i]*dincu(t+d-i)))) } phi.new[t] <- naninf2zero(lambda.old[t]/pincu(T-t)) * sum3a } } else { phi.new <- .Call(C_eq3a, lambda.old = as.numeric(lambda.old), Y = as.numeric(Y), incu.pmf = as.numeric(incu.pmf)) } #Smoothing step if (k>0) { w <- choose(k,0:k)/2^k for (t in 1:T) { i.sub <- t+(0:k)-k/2 goodIdx <- i.sub %in% 1:T w.sub <- w[goodIdx]/sum(w[goodIdx]) lambda.new[t] <- sum(w.sub * phi.new[i.sub[goodIdx]]) } } else { #no smoothing lambda.new <- phi.new } #Done. return(lambda=lambda.new) } ###################################################################### # STS compatible function to call the non-parametric back-projection # method of Becker et al (1991) for time aggregated data. # # Parameters: # sts - sts object with the observed incidence as "observed" slot # incu.pmf - incubation time pmf as a vector with index 0,..,d_max. Please # note that the support includes zero! # k - smoothing parameter for the EMS algorithm # eps - relative convergence criteration # iter.max - max number of iterations # verbose - boolean, if TRUE provide extra output when running the method # lambda0 - start value for lambda, default: uniform # hookFun - hook function to call after each EMS step, a function # of type hookFun=function(stsj,...) # # Returns: # sts object with upperbound set to the backprojected lambda. ###################################################################### backprojNP.fit <- function(sts, incu.pmf,k=2,eps=1e-5,iter.max=250,verbose=FALSE,lambda0=NULL,eq3a.method=c("R","C"),hookFun=function(stsbp) {}, ...) { #Determine method eq3a.method <- match.arg(eq3a.method, c("R","C")) #Define object to return lambda.hat <- matrix(NA,ncol=ncol(sts),nrow=nrow(sts)) #Loop over all series for (j in 1:ncol(sts)) { #Inform (if requested) what series we are looking at if ((ncol(sts)>1) & verbose) { cat("Backprojecting series no. ",j,"\n") } #Extract incidence time series Y <- observed(sts)[,j] #If default behaviour for lambda0 is desired if (is.null(lambda0)) { lambda0j <- rep(sum(Y)/length(Y),length(Y)) } else { lambda0j <- lambda0[,j] } #Create incubation time distribution vectors for the j'th series inc.pmf <- as.numeric(incu.pmf[,j]) inc.cdf <- cumsum(inc.pmf) #Create wrapper functions for the PMF and CDF based on the vector. #These function will be used in the R version of eq3a. #ToDo: The function uses the global variable inc.pmf which #definitely is dirty coding. How to define this function #in an environment where inc.pmf is present? dincu <- function(x) { notInSupport <- x<0 | x>=length(inc.pmf) #Give index -1 to invalid queries x[notInSupport] <- -1 return(c(0,inc.pmf)[x+2]) } #Cumulative distribution function. Uses global var "inc.cdf" pincu <- function(x) { x[x<0] <- -1 x[x>=length(inc.cdf)] <- length(inc.cdf)-1 return(c(0,inc.cdf)[x+2]) } #Iteration counter and convergence indicator i <- 0 stop <- FALSE lambda <- lambda0j #Loop until stop while (!stop) { #Add to counter i <- i+1 lambda.i <- lambda #Perform one step lambda <- em.step.becker(lambda.old=lambda.i,Y=Y,dincu=dincu,pincu=pincu,k=k, incu.pmf=inc.pmf, eq3a.method=eq3a.method) #check stop #In original paper the expression to do so appears funny since #- and + deviations cancel. More realistic: #criterion <- abs(sum(res$lambda) - sum(lambda.i))/sum(lambda.i) criterion <- sqrt(sum((lambda- lambda.i)^2))/sqrt(sum(lambda.i^2)) if (verbose) { cat("Convergence criterion @ iteration i=",i,": ", criterion,"\n") } #Check whether to stop stop <- criterion < eps | (i>iter.max) #Call hook function stsj <- sts[,j] upperbound(stsj) <- matrix(lambda,ncol=1) hookFun(stsj, ...) } #Done lambda.hat[,j] <- lambda } #Create new object with return put in the lambda slot bp.sts <- as(sts,"stsBP") bp.sts@upperbound <- lambda.hat bp.sts@control <- list(k=k,eps=eps,iter=i) return(bp.sts) } ###################################################################### # EMS back-projection method including bootstrap based confidence # intervals. The theory is indirectly given in Becker and Marschner (1993), # Biometrika, 80(1):165-178 and more specifically in Yip et al, 2011, # Communications in Statistics -- Simulation and Computation, # 37(2):425-433. # # Parameters: # # sts - sts object with the observed incidence as "observed" slot # incu.pmf - incubation time pmf as a vector with index 0,..,d_max. Please # note that the support includes zero! # k - smoothing parameter for the EMS algorithm # eps - relative convergence criteration. If a vector of length two # then the first argument is used for the k=0 initial fit and # the second element for all EMS fits # # iter.max - max number of iterations. Can be a vector of length two. # Similar use as in eps. # verbose - boolean, if TRUE provide extra output when running the method # lambda0 - start value for lambda, default: uniform # hookFun - hook function to call after each EMS step, a function # of type hookFun=function(Y,lambda,...) # B - number of bootstrap replicates. If B=-1 then no bootstrap CIs # are calculated. # # Returns: # sts object with upperbound set to the backprojected lambda. ###################################################################### backprojNP <- function(sts, incu.pmf,control=list(k=2,eps=rep(0.005,2),iter.max=rep(250,2),Tmark=nrow(sts),B=-1,alpha=0.05,verbose=FALSE,lambda0=NULL,eq3a.method=c("R","C"),hookFun=function(stsbp) {}),...) { #Check if backprojection is to be done multivariate time series case. if (ncol(sts)>1) { warning("Multivariate time series: Backprojection uses same eps for the individual time series.") } #Check if incu.pmf vector fits the dimension of the sts object. If not #either replicate it or throw an error. if (is.matrix(incu.pmf)) { if (!ncol(incu.pmf) == ncol(sts)) { stop("Dimensions of sts object and incu.pmf don't match.") } } else { if (ncol(sts)>1) { warning("Backprojection uses same incubation time distribution for the individual time series.") } incu.pmf <- matrix(incu.pmf,ncol=ncol(sts),dimnames=list(NULL,colnames(sts))) } #Fill control object as appropriate and in sync with the default value if (is.null(control[["k",exact=TRUE]])) { control$k <- 2 } if (is.null(control[["eps",exact=TRUE]])) { control$eps <- rep(0.005,2) } if (is.null(control[["iter.max",exact=TRUE]])) { control$iter.max <- rep(250,2) } if (is.null(control[["Tmark",exact=TRUE]])) { control$Tmark <- nrow(sts) } if (is.null(control[["B",exact=TRUE]])) { control$B <- -1 } if (is.null(control[["alpha",exact=TRUE]])) { control$alpha <- 0.05 } if (is.null(control[["verbose",exact=TRUE]])) { control$verbose <- FALSE } if (is.null(control[["lambda0",exact=TRUE]])) { control$lambda0 <- NULL } #Which method to use for computing eq3a if (is.null(control[["eq3a.method",exact=TRUE]])) { control$eq3a.method <- "R" } else { control$eq3a.method <- match.arg(control$eq3a.method,c("R","C")) } #Hook function definition if (is.null(control[["hookFun",exact=TRUE]])) { control$hookFun <- function(Y,lambda,...) {} } #If the eps and iter.max arguments are too short, make them length 2. if (length(control$eps)==1) control$eps <- rep(control$eps,2) if (length(control$iter.max)==1) control$iter.max <- rep(control$iter.max,2) #Compute the estimate to report (i.e. use 2nd component of the args) if (control$verbose) { cat("Back-projecting with k=",control$k," to get lambda estimate.\n") } stsk <- backprojNP.fit(sts, incu.pmf=incu.pmf,k=control$k,eps=control$eps[2],iter.max=control$iter.max[2],verbose=control$verbose,lambda0=control$lambda0,hookFun=control$hookFun,eq3a.method=control$eq3a.method) #Fix control slot stsk@control <- control #If no bootstrap to do return object right away as stsBP object. if (control$B<=0) { if (control$verbose) { cat("No bootstrap CIs calculated as requested.\n") } stsk <- as(stsk,"stsBP") return(stsk) } #Call back-project function without smoothing, i.e. with k=0. if (control$verbose) { cat("Back-projecting with k=",0," to get lambda estimate for parametric bootstrap.\n") } sts0 <- backprojNP.fit(sts, incu.pmf=incu.pmf,k=0,eps=control$eps[1],iter.max=control$iter.max[1],verbose=control$verbose,lambda0=control$lambda0,hookFun=control$hookFun, eq3a.method=control$eq3a.method) ########################################################################### #Create bootstrap samples and loop for each sample while storing the result ########################################################################### sts.boot <- sts0 #Define object to return lambda <- array(NA,dim=c(nrow(sts),ncol(sts),control$B)) #Define PMF of incubation time which does safe handling of values #outside the support of the incubation time. dincu <- function(x,i) { notInSupport <- x<0 | x>=length(incu.pmf[,i]) #Give index -1 to invalid queries x[notInSupport] <- -1 return(c(0,incu.pmf[,i])[x+2]) } #Loop in order to create the sample for (b in 1:control$B) { if (control$verbose) { cat("Bootstrap sample ",b,"/",control$B,"\n") } #Compute convolution for the mean of the observations mu <- matrix(0, nrow=nrow(sts0), ncol=ncol(sts0)) #Perform the convolution for each series for (i in 1:ncol(sts)) { for (t in 1:nrow(mu)) { for (s in 0:(t-1)) { mu[t,i] <- mu[t,i] + upperbound(sts0)[t-s,i] * dincu(s,i) } } } #Create new observations in the observed slot. observed(sts.boot) <- matrix(rpois(prod(dim(sts.boot)),lambda=mu),ncol=ncol(sts0)) #Run the backprojection on the bootstrap sample. Use original result #as starting value. sts.boot <- backprojNP.fit(sts.boot, incu.pmf=incu.pmf,k=control$k,eps=control$eps[2],iter.max=control$iter.max[2],verbose=control$verbose,lambda0=upperbound(stsk),hookFun=control$hookFun, eq3a.method=control$eq3a.method) #Extract the result of the b'th backprojection lambda[,,b] <- upperbound(sts.boot) } #Compute an equal tailed (1-alpha)*100% confidence intervals based on the #bootstrap samples. The dimension is (ci.low,ci.high) x time x series ci <- apply(lambda,MARGIN=c(1,2), quantile, probs=c(control$alpha/2,1-control$alpha/2)) #Convert output to stsBP object and add information to the extra slots stsk <- as(stsk,"stsBP") #Add extra slots stsk@ci <- ci stsk@lambda <- lambda stsk@control <- control #Done return(stsk) } surveillance/R/epidata.R0000644000176200001440000010535714615162374014725 0ustar liggesusers################################################################################ ### Data structure "epidata" representing the SIR event history of a fixed ### geo-referenced population (e.g., farms, households) for twinSIR() analysis ### ### Copyright (C) 2008-2010, 2012, 2014-2018, 2020 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## CAVE: ## - we assume fixed coordinates (this is important since time-varying ## coordinates would result in more sophisticated and time consuming ## calculations of distance matrices) ! ## - in the first block (start = t0) all id's must be present (for coordinates) ## - those id's with atRiskY(t0) = 0 are taken as initially infectious ## - SIS epidemics are possible, but must be given as SIRS with pseudo R-events, ## i.e. individuals will be removed and become susceptible directly afterwards ################################################################################ ## Convert a simple data.frame with one row per individual and with columns for ## the times of becoming exposed/infectious/removed ## to the long "epidata" event history start/stop format. ## tE.col and tR.col can be missing corresponding to SIR, SEI, or SI data. ## NA's in time variables mean that the respective event has not yet occurred. ## Time-varying covariates are not supported by this converter. ################################################################################ as.epidata.data.frame <- function (data, t0, tE.col, tI.col, tR.col, id.col, coords.cols, f = list(), w = list(), D = dist, max.time = NULL, keep.cols = TRUE, ...) { if (missing(t0)) { return(NextMethod("as.epidata")) # as.epidata.default } ## drop individuals that have already been removed prior to t0 ## since they would otherwise be considered as initially infective ## (atRiskY = 0 in first time block) and never be removed if (!missing(tR.col)) { alreadyRemoved <- !is.na(data[[tR.col]]) & data[[tR.col]] <= t0 if (any(alreadyRemoved)) { data <- data[!alreadyRemoved,] message("Note: dropped rows with tR <= t0 (", paste0(which(alreadyRemoved), collapse = ", "), ")") } } ## parse max.time if (is.null(max.time) || is.na(max.time)) { # max(stop) is at last event max.time <- NA_real_ } else { stopifnot(max.time > t0) } ## parse id column id <- factor(data[[id.col]]) # removes unused levels stopifnot(!anyDuplicated(id), !is.na(id)) N <- nlevels(id) # = nrow(data) ## make time relative to t0 subtract_t0 <- function (x) as.numeric(x - t0) max.time <- subtract_t0(max.time) tI <- subtract_t0(data[[tI.col]]) tE <- if (missing(tE.col)) tI else subtract_t0(data[[tE.col]]) tR <- if (missing(tR.col)) rep.int(NA_real_, N) else subtract_t0(data[[tR.col]]) ## check E-I-R order if (any((is.na(tE) & !(is.na(tI) & is.na(tR))) | (is.na(tI) & !is.na(tR)))) { stop("events cannot be skipped (NA in E/I => NA in I/R)") } if (any(.wrongsequence <- (tE > tI | tI >= tR) %in% TRUE)) { # TRUE | NA = TRUE stop("E-I-R events are in wrong order for the following id's: ", paste0(id[.wrongsequence], collapse = ", ")) } ## ignore events after max.time if (!is.na(max.time)) { is.na(tE) <- tE > max.time is.na(tI) <- tI > max.time is.na(tR) <- tR > max.time } ## vector of stop times stopTimes <- c(tE, tI, tR, max.time) stopTimes <- stopTimes[!is.na(stopTimes) & stopTimes > 0] stopTimes <- sort.int(unique.default(stopTimes), decreasing = FALSE) nBlocks <- length(stopTimes) if (nBlocks == 0L) { stop("nothing happens after 't0'") } ## initialize event history evHist <- data.frame( id = rep.int(id, nBlocks), start = rep.int(c(0,stopTimes[-nBlocks]), rep.int(N, nBlocks)), stop = rep.int(stopTimes, rep.int(N, nBlocks)), atRiskY = NA, event = 0, Revent = 0, # adjusted in the loop below row.names = NULL, check.rows = FALSE, check.names = FALSE) ## indexes of the last rows of the time blocks blockbase <- c(0, seq_len(nBlocks) * N) ## which individuals are at risk in the first (next) block Y <- is.na(tE) | tE > 0 ## Loop over the blocks/stop times to adjust atRiskY, event and Revent for (i in seq_len(nBlocks)) { ct <- stopTimes[i] ## set individual at-risk indicators for the current time block evHist$atRiskY[blockbase[i] + seq_len(N)] <- Y ## individuals who become exposed at the current stop time ## will no longer be at risk in the next block Y[which(tE == ct)] <- FALSE ## process events at this stop time evHist$event[blockbase[i] + which(tI == ct)] <- 1 evHist$Revent[blockbase[i] + which(tR == ct)] <- 1 } ## add additional time-constant covariates extraVarNames <- coords.cols # may be NULL if (isTRUE(keep.cols)) { extraVarNames <- c(extraVarNames, setdiff(names(data), id.col)) } else if (length(keep.cols) > 0L && !identical(FALSE, keep.cols)) { extraVarNames <- c(extraVarNames, names(data[keep.cols])) } extraVarNames <- unique.default(extraVarNames) if (length(extraVarNames) > 0L) { evHist <- data.frame( evHist, data[rep.int(seq_len(N), nBlocks), extraVarNames, drop=FALSE], row.names = NULL, check.names = TRUE, stringsAsFactors = TRUE) } ## Now we can pass the generated event history to the default method ## for the usual consistency checks and the pre-calculation of f covariates as.epidata.default( data = evHist, id.col = "id", start.col = "start", stop.col = "stop", atRiskY.col = "atRiskY", event.col = "event", Revent.col = "Revent", coords.cols = coords.cols, f = f, w = w, D = D, .latent = !missing(tE.col)) } ################################################################################ # DEFAULT CONVERTER, which requires a start/stop event history data.frame # It performs consistency checks, and pre-calculates the distance-based # epidemic covariates from f. ################################################################################ as.epidata.default <- function(data, id.col, start.col, stop.col, atRiskY.col, event.col, Revent.col, coords.cols, f = list(), w = list(), D = dist, .latent = FALSE, ...) { cl <- match.call() # If necessary, convert 'data' into a data.frame (also converting # column names to syntactically correct names for use in formulae) data <- as.data.frame(data, stringsAsFactors = FALSE) # Use column numbers as indices and check them colargs <- c("id.col", "start.col", "stop.col", "atRiskY.col", "event.col", "Revent.col", "coords.cols") colidxs <- structure(as.list(numeric(length(colargs))), names = colargs) for (colarg in colargs) { colidx <- get(colarg, inherits = FALSE) if (colarg != "coords.cols" && length(colidx) != 1L) { stop("the column specifier '", colarg, "' must be of length 1") } if (is.character(colidx)) { colidx <- match(colidx, colnames(data)) if (anyNA(colidx)) { stop("'", colarg, " = ", deparse(cl[[colarg]]), "': ", "column does not exist in 'data'") } } else if (is.numeric(colidx) && any(colidx<1L | colidx>ncol(data))) { stop("'", colarg, " = ", deparse(cl[[colarg]]), "': ", "column index must be in [1; ", ncol(data), "=ncol(data)]") } colidxs[[colarg]] <- colidx } # Rename main columns to default column names colidxsVec <- unlist(colidxs) colnams <- c("id", "start", "stop", "atRiskY", "event", "Revent") colnames(data)[colidxsVec[1:6]] <- colnams usedReservedName <- any(colnams %in% colnames(data)[-colidxsVec[1:6]]) # REORDER COLUMNS, so that main columns come first (also for make.unique) data <- data[c(colidxsVec, setdiff(seq_len(NCOL(data)), colidxsVec))] # Make columns names unique (necessary if other column with name in colnams) if (usedReservedName) { colnames(data) <- make.unique(colnames(data)) message("Some other columns had reserved names and have been renamed") } # Convert id into a factor (also removing unused levels if it was a factor) data[["id"]] <- factor(data[["id"]]) # Check atRiskY, event and Revent for values other than 0 and 1 for (var in c("atRiskY", "event", "Revent")) { data[[var]] <- as.numeric(data[[var]]) if (any(! data[[var]] %in% c(0,1))) stop("'", var, "' column may only assume values 0 and 1") } # Check consistency of atRiskY and event (event only if at-risk) if (.latent) { warning("support for latent periods is experimental") } else { noRiskButEvent <- data[["atRiskY"]] == 0 & data[["event"]] == 1 if (noRiskButEventRow <- match(TRUE, noRiskButEvent, nomatch = 0)) { stop("inconsistent atRiskY/event indicators in row ", noRiskButEventRow, ": event only if at risk") } } # Check event (infection) times for ties eventTimes <- data[data[["event"]] == 1, "stop"] ReventTimes <- data[data[["Revent"]] == 1, "stop"] duplicatedEventTime <- duplicated(c(eventTimes, ReventTimes)) if (duplicatedEventTimeIdx <- match(TRUE, duplicatedEventTime, nomatch=0)) { stop("non-unique event times: concurrent event/Revent at time ", c(eventTimes, ReventTimes)[duplicatedEventTimeIdx]) } # Check start/stop consistency and add block id histIntervals <- unique(data[c("start", "stop")]) histIntervals <- histIntervals[order(histIntervals[,1L]),] nBlocks <- nrow(histIntervals) if (any(histIntervals[,2L] <= histIntervals[,1L])) { stop("stop times must be greater than start times") } startStopCheck <- histIntervals[-1L,1L] != histIntervals[-nBlocks,2L] if (startStopCheckIdx <- match(TRUE, startStopCheck, nomatch = 0)) { stop("inconsistent start/stop times: time intervals not consecutive ", "at stop time ", histIntervals[startStopCheckIdx,2L]) } if ("BLOCK" %in% colnames(data)) { warning("column name 'BLOCK' is reserved, ", "existing column has been replaced") } data[["BLOCK"]] <- match(data[["start"]], histIntervals[,1L]) # SORT by block/id and create indexes for block borders data <- data[order(data[["BLOCK"]], data[["id"]]),] beginBlock <- match(seq_len(nBlocks), data[["BLOCK"]]) endBlock <- c(beginBlock[-1L]-1L, nrow(data)) # make block column the first column BLOCK.col <- match("BLOCK", colnames(data)) data <- data[c(BLOCK.col, setdiff(seq_along(data), BLOCK.col))] coords.cols <- 1L + 6L + seq_along(colidxs[["coords.cols"]]) # Check consistency of atRiskY and event (not at-risk after event) .checkFunction <- function(eventblock, eventid) { if (eventblock == nBlocks) return(invisible()) rowsOfNextBlock <- beginBlock[eventblock+1L]:endBlock[eventblock+1L] nextBlockData <- data[rowsOfNextBlock, c("id", "atRiskY")] idIdx <- which(nextBlockData[["id"]] == eventid) if (length(idIdx) == 1L && nextBlockData[idIdx, "atRiskY"] == 1) { stop("inconsistent atRiskY/event indicators for id '", eventid, "': should not be at risk immediately after event") } } eventTable <- data[data[["event"]] == 1,] for(k in seq_len(nrow(eventTable))) { .checkFunction(eventTable[k,"BLOCK"], eventTable[k,"id"]) } # Set attributes attr(data, "eventTimes") <- sort(eventTimes) attr(data, "timeRange") <- c(histIntervals[1L,1L],histIntervals[nBlocks,2L]) attr(data, "coords.cols") <- coords.cols # <- must include this info because externally of this function # we don't know how many coords.cols (dimensions) we have attr(data, "f") <- list() # initialize attr(data, "w") <- list() # initialize class(data) <- c("epidata", "data.frame") # Compute epidemic variables update.epidata(data, f = f, w = w, D = D) } update.epidata <- function (object, f = list(), w = list(), D = dist, ...) { oldclass <- class(object) class(object) <- "data.frame" # avoid use of [.epidata ## block indexes and first block beginBlock <- which(!duplicated(object[["BLOCK"]], nmax = object[["BLOCK"]][nrow(object)])) endBlock <- c(beginBlock[-1L]-1L, nrow(object)) firstDataBlock <- object[seq_len(endBlock[1L]), ] ## check f and calculate distance matrix if (length(f) > 0L) { if (!is.list(f) || is.null(names(f)) || any(!sapply(f, is.function))) { stop("'f' must be a named list of functions") } lapply(X = f, FUN = function (B) { if (!isTRUE(all.equal(c(5L,2L), dim(B(matrix(0, 5, 2)))))) stop("'f'unctions must retain the dimensions of their input") }) if (any(names(f) %in% names(object))) { warning("'f' components replace existing columns of the same name") } ## reset / initialize columns for distance-based epidemic weights object[names(f)] <- 0 ## keep functions as attribute attr(object, "f")[names(f)] <- f ## check / compute distance matrix distmat <- if (is.function(D)) { if (length(coords.cols <- attr(object, "coords.cols")) == 0L) { stop("need coordinates to calculate the distance matrix") } coords <- as.matrix(firstDataBlock[coords.cols], rownames.force = FALSE) rownames(coords) <- as.character(firstDataBlock[["id"]]) as.matrix(D(coords)) } else { # a numeric matrix (or "Matrix") if (length(dn <- dimnames(D)) != 2L) { stop("if not a function, 'D' must be a matrix-like object") } if (!all(firstDataBlock[["id"]] %in% dn[[1L]], firstDataBlock[["id"]] %in% dn[[2L]])) { stop("'dimnames(D)' must contain the individuals' IDs") } D } } ## check covariate-based epidemic weights if (length(w) > 0L) { if (!is.list(w) || is.null(names(w)) || any(!sapply(w, is.function))) { stop("'w' must be a named list of functions") } if (any(names(w) %in% names(object))) { warning("'w' components replace existing columns of the same name") } ## reset / initialize columns for covariate-based epidemic weights object[names(w)] <- 0 ## keep functions as attribute attr(object, "w")[names(w)] <- w ## compute wij matrix for each of w wijlist <- compute_wijlist(w = w, data = firstDataBlock) } ## Compute sum of epidemic covariates over infectious individuals if (length(f) + length(w) > 0L) { infectiousIDs <- firstDataBlock[firstDataBlock[["atRiskY"]] == 0, "id"] ##<- this is a factor variable for(i in seq_along(beginBlock)) { blockidx <- beginBlock[i]:endBlock[i] blockdata <- object[blockidx,] blockIDs <- blockdata[["id"]] if (length(infectiousIDs) > 0L) { if (length(f) > 0L) { u <- distmat[as.character(blockIDs), as.character(infectiousIDs), drop = FALSE] # index by factor levels object[blockidx,names(f)] <- vapply( X = f, FUN = function (B) Matrix::rowSums(B(u)), FUN.VALUE = numeric(length(blockIDs)), USE.NAMES = FALSE) } if (length(w) > 0L) { object[blockidx,names(w)] <- vapply( X = wijlist, FUN = function (wij) { ## actually don't have to care about the diagonal: ## i at risk => sum does not include it ## i infectious => atRiskY = 0 (ignored in twinSIR) rowSums(wij[as.character(blockIDs), as.character(infectiousIDs), drop = FALSE]) # index by factor levels }, FUN.VALUE = numeric(length(blockIDs)), USE.NAMES = FALSE) } } ## update the set of infectious individuals for the next block recoveredID <- blockIDs[blockdata[["Revent"]] == 1] infectedID <- blockIDs[blockdata[["event"]] == 1] if (length(recoveredID) > 0L) { infectiousIDs <- infectiousIDs[infectiousIDs != recoveredID] } else if (length(infectedID) > 0L) { infectiousIDs[length(infectiousIDs)+1L] <- infectedID } } } ## restore "epidata" class class(object) <- oldclass return(object) } compute_wijlist <- function (w, data) { ## for each function in 'w', determine the variable on which it acts; ## this is derived from the name of the first formal argument, which ## must be of the form "varname.i" wvars <- vapply(X = w, FUN = function (wFUN) { varname.i <- names(formals(wFUN))[[1L]] substr(varname.i, 1, nchar(varname.i)-2L) }, FUN.VALUE = "", USE.NAMES = TRUE) if (any(wvarNotFound <- !wvars %in% names(data))) { stop("'w' function refers to unknown variables: ", paste0(names(w)[wvarNotFound], collapse=", ")) } ## compute weight matrices w_ij for each of w mapply( FUN = function (wFUN, wVAR, ids) { wij <- outer(X = wVAR, Y = wVAR, FUN = wFUN) dimnames(wij) <- list(ids, ids) wij }, wFUN = w, wVAR = data[wvars], MoreArgs = list(ids = as.character(data[["id"]])), SIMPLIFY = FALSE, USE.NAMES = TRUE ) } ################################################################################ # EXTRACTION OPERATOR FOR 'EPIDATA' OBJECTS # Indexing with "[" would be possible (inheriting from data.frame). # But using any column index would remove attributes (row indexes would not). # Thus, we define an own method to retain and adjust the attributes when # selecting a subset of blocks of the 'epidata'. # Selecting a subset of columns will remove class "epidata" (resulting in a # simple data.frame) ################################################################################ "[.epidata" <- function(x, i, j, drop) { # use data.frame method first xx <- NextMethod("[") # then return its result as pure data.frame or assure valid 'epidata' # if a subset of columns has been selected and attributes have been removed if (NCOL(xx) != ncol(x) || any(names(xx) != names(x))) { if (inherits(xx, "data.frame")) { # xx could be a vector class(xx) <- "data.frame" # remove class 'epidata' } message("Note: converted class \"epidata\" to simple \"", class(xx), "\"") return(xx) } # else there is no effective column selection (e.g. j=TRUE) if (nrow(xx) == 0) { message("Note: no rows selected, dropped class \"epidata\"") class(xx) <- "data.frame" return(xx[TRUE]) # removes attributes } invalidEpidata <- FALSE blocksizesx <- table(x[["BLOCK"]]) blocksizesxx <- table(xx[["BLOCK"]]) blocksOK <- identical(c(blocksizesxx), c(blocksizesx[names(blocksizesxx)])) if (is.numeric(i) && any(diff(na.omit(i)) < 0)) { # epidata should remain ordered by time warning("dropped class \"epidata\": reordering rows is not permitted") invalidEpidata <- TRUE } else if (!blocksOK) { # blocks should not be cut, epidemic covariates might become invalid warning("dropped class \"epidata\": subsetting blocks not allowed") invalidEpidata <- TRUE } else if (any(diff(as.numeric(names(blocksizesxx))) != 1)) { # blocks can only be selected consecutively warning("dropped class \"epidata\": ", "only consecutive blocks may be selected") invalidEpidata <- TRUE } if (invalidEpidata) { class(xx) <- "data.frame" xx[TRUE] # removes attributes } else { # # adjust block index so that it starts at 1 # firstBlockNumber <- as.numeric(names(blocksizesxx)[1]) # if (firstBlockNumber > 1) { # xx[["BLOCK"]] <- xx[["BLOCK"]] - (firstBlockNumber-1) # } # Restore or adjust attributes tmin <- xx[["start"]][1] tmax <- xx[["stop"]][nrow(xx)] oldEventTimes <- attr(x, "eventTimes") attr(xx, "eventTimes") <- if (blocksOK) { oldEventTimes[oldEventTimes > tmin & oldEventTimes <= tmax] } else { xx[["stop"]][xx[["event"]] == 1] } attr(xx, "timeRange") <- c(tmin, tmax) attr(xx, "coords.cols") <- attr(x, "coords.cols") attr(xx, "f") <- attr(x, "f") xx } } ################################################################################ # INSERT BLOCKS FOR EXTRA STOP TIMES IN 'EPIDATA' OBJECTS ################################################################################ intersperse <- function (epidata, stoptimes, verbose = FALSE) { # Check arguments if (!inherits(epidata, "epidata")) { stop("'epidata' must inherit from class \"epidata\"") } if (!is.vector(stoptimes, mode = "numeric")) { stop("'stoptimes' must be a numeric vector") } # Identify new 'stoptimes' sortedEpiStop <- sort(unique(epidata$stop)) extraStoptimes <- stoptimes[! stoptimes %in% sortedEpiStop] # Return original 'epidata' if nothing to do if (length(extraStoptimes) == 0) { # message("nothing done: no new stop times") return(epidata) } # # Retain attributes of 'epidata' # .attributes <- attributes(epidata) # .attributes <- .attributes[match(c("eventTimes", "timeRange", # "coords.cols", "f", "config", "call", "terms"), names(.attributes), # nomatch = 0)] # Check new 'stoptimes' timeRange <- attr(epidata, "timeRange") inside <- extraStoptimes > timeRange[1] & extraStoptimes < timeRange[2] if (any(!inside)) { extraStoptimes <- extraStoptimes[inside] warning("ignored extra 'stoptimes' outside the observation period") } # Impute blocks for extraStoptimes oldclass <- class(epidata) class(epidata) <- "data.frame" # Avoid use of [.epidata (not necessary here) blocksize <- sum(epidata$BLOCK == 1) nInsert <- length(extraStoptimes) lastRow <- nrow(epidata) epidata <- rbind(epidata, epidata[rep.int(NA_integer_, nInsert * blocksize),], deparse.level = 0) # add NA rows, to be replaced below if (verbose) pb <- txtProgressBar(min=0, max=nInsert, initial=0, style=3) for(i in seq_len(nInsert)) { extraStop <- extraStoptimes[i] nextStoptime <- sortedEpiStop[match(TRUE, sortedEpiStop > extraStop)] # Find the block (row indexes) into which the extraStop falls rowsMatchedBlock <- which(epidata$stop == nextStoptime) # Split this block up into 2 parts # later part equals original block with start time = extraStop newBlock <- epidata[rowsMatchedBlock,] newBlock$start <- extraStop # earlier part has stop time = extraStop and no events at this time point epidata[rowsMatchedBlock, "stop"] <- extraStop epidata[rowsMatchedBlock, "event"] <- 0 epidata[rowsMatchedBlock, "Revent"] <- 0 # write the new block to epidata (reorder rows later) epidata[lastRow + seq_along(rowsMatchedBlock),] <- newBlock lastRow <- lastRow + length(rowsMatchedBlock) if (verbose) setTxtProgressBar(pb, i) } if (verbose) close(pb) # Adjust BLOCK column sortedEpiStop <- sort(c(sortedEpiStop, extraStoptimes)) epidata$BLOCK <- match(epidata$stop, sortedEpiStop) # Reorder rows by time and id epidata <- epidata[order(epidata$BLOCK, epidata$id), ] row.names(epidata) <- NULL class(epidata) <- oldclass return(epidata) } ################################################################################ # SUMMARY FUNCTION FOR EPIDATA OBJECTS # the epidemic is summarized by the following returned components: # - type: one of "SIR", "SI", "SIRS", "SIS" # - size: number of initially susceptible individuals, which became infected # - initiallyInfected: vector (factor) of initially infected individuals # - neverInfected: vector (factor) of never (during the observation period) # infected individuals # - coordinates: matrix with the coordinates of the individuals (rownames=id's) # - byID: data.frame with time points of events by id (columns time.I, time.R # and optionally time.S) # - counters: data.frame representing the evolution of the epidemic ################################################################################ summary.epidata <- function (object, ...) { class(object) <- "data.frame" # avoid use of [.epidata (not necessary here) # extract coordinates and initially infected individuals idlevels <- levels(object[["id"]]) N <- length(idlevels) firstDataBlock <- object[object$BLOCK == min(object$BLOCK),] coordinates <- as.matrix(firstDataBlock[attr(object, "coords.cols")]) rownames(coordinates) <- as.character(firstDataBlock[["id"]]) initiallyInfected <- firstDataBlock$id[firstDataBlock$atRiskY == 0] m <- length(initiallyInfected) n <- N - m ### summary 1: event table with columns id, time and type (of event, S/I/R) # Extract time points of the S events for each id StimesID <- by(object[c("atRiskY", "stop")], object["id"], function(x) { SeventIdx <- which(diff(x[["atRiskY"]]) == 1) x[["stop"]][SeventIdx] }, simplify=TRUE) names(StimesID) <- paste0(names(StimesID), ":") StimesVec <- c(unlist(StimesID, use.names = TRUE)) # c() if by() returned an array .Sids <- sub("(.+):.*", "\\1", names(StimesVec)) Stimes <- data.frame(id = factor(.Sids, levels = idlevels), stop = StimesVec, type = rep("S", length(StimesVec)), row.names = NULL, check.names = FALSE, stringsAsFactors = FALSE) # Extract time points of the I and R events for each id Itimes <- object[object$event == 1, c("id", "stop")] Itimes[["type"]] <- rep("I", nrow(Itimes)) Rtimes <- object[object$Revent == 1, c("id", "stop")] Rtimes[["type"]] <- rep("R", nrow(Rtimes)) # Combine the three event types into one data.frame eventTable <- rbind(Rtimes, Stimes, Itimes) # need this order for the counters below in the case of SIS: # pseudo-R-event occurs infinitesimally before S names(eventTable)[2L] <- "time" eventTable <- eventTable[order(eventTable[["id"]], eventTable[["time"]]), ] eventTable[["type"]] <- factor(eventTable[["type"]], levels=c("S","I","R")) rownames(eventTable) <- NULL ### summary 2: type and size of the epidemic resusceptibility <- length(StimesVec) > 0 epitype <- if (resusceptibility) { Rtimes_notLast <- Rtimes[-which.max(Rtimes[,2]),] onlyPseudoR <- length(setdiff(Rtimes_notLast[,2], Stimes[,2])) == 0 if (onlyPseudoR) "SIS" else "SIRS" } else { if (nrow(Rtimes) > 0) "SIR" else "SI" } isEverInfected <- idlevels %in% initiallyInfected | idlevels %in% unique(eventTable$id[eventTable$type == "I"]) isNeverInfected <- !isEverInfected size <- n - sum(isNeverInfected) # everInfected <- factor(idlevels[isEverInfected], levels = idlevels) neverInfected <- factor(idlevels[isNeverInfected], levels = idlevels) ### summary 3: eventTable by id in wide form byID_everInfected <- if (nrow(eventTable) == 0) { data.frame(id = factor(character(0), levels = idlevels), time.I = numeric(0), row.names = NULL, check.names = FALSE, stringsAsFactors = FALSE) } else if (!resusceptibility) { .res <- reshape(eventTable, direction = "wide", timevar = "type", idvar = "id") attr(.res, "reshapeWide") <- NULL if ("time.I" %in% names(.res)) { .res[c("id", "time.I", "time.R")] # ensure natural order } else { # degenerate case: only R (and S) events in data cbind(.res[1L], "time.I" = NA_real_, .res[-1L]) } } else { eventTable3 <- if (m > 0) { # workaround for initially infected rbind(data.frame(id = initiallyInfected, time = NA_real_, type = "I", row.names = NULL, check.names = FALSE, stringsAsFactors = FALSE), eventTable) } else eventTable rowsPerId <- table(eventTable3[["id"]]) modulo3 <- rowsPerId %% 3 ## if this is 1, we need to append NAs for R and S events ## if 2, only append NA for the final S (occurs for SIRS, not SIS) rest1 <- modulo3 == 1 rest12 <- modulo3 >= 1 missingR <- data.frame(id = names(rowsPerId)[rest1], time = rep(NA_real_, sum(rest1)), type = rep("R", sum(rest1)), row.names = NULL, check.names = FALSE, stringsAsFactors = FALSE) missingS <- data.frame(id = names(rowsPerId)[rest12], time = rep(NA_real_, sum(rest12)), type = rep("S", sum(rest12)), row.names = NULL, check.names = FALSE, stringsAsFactors = FALSE) eventTable3 <- rbind(eventTable3, missingR, missingS) eventTable3 <- eventTable3[order(eventTable3[["id"]]),] .res <- data.frame( eventTable3[eventTable3$type == "I", c("id", "time")], eventTable3[eventTable3$type == "R", "time", drop = FALSE], eventTable3[eventTable3$type == "S", "time", drop = FALSE], row.names = NULL, check.names = FALSE, stringsAsFactors = FALSE ) names(.res) <- c("id", paste("time", c("I", "R", "S"), sep=".")) .res } byID_neverInfected <- data.frame(id = neverInfected, time.I = rep(NA_real_, n-size), time.R = rep(NA_real_, n-size), time.S = rep(NA_real_, n-size), row.names = NULL, check.names = FALSE) byID_all <- rbind(byID_everInfected, byID_neverInfected[names(byID_everInfected)]) byID <- byID_all[order(byID_all[["id"]]),] rownames(byID) <- NULL ### summary 4: upgrade eventTable with ### evolution of numbers of susceptibles, infectious and removed counters <- eventTable[order(eventTable[["time"]]),c("time", "type", "id")] init <- data.frame(time = attr(object, "timeRange")[1L], type = factor(NA_character_, levels(counters$type)), id = factor(NA_character_, levels(counters$id)), nSusceptible = n, nInfectious = m, nRemoved = 0L) cumulatedReSusceptibility <- cumsum(counters[["type"]] == "S") cumulatedInfections <- cumsum(counters[["type"]] == "I") cumulatedRemovals <- cumsum(counters[["type"]] == "R") counters[["nSusceptible"]] <- init[["nSusceptible"]] - cumulatedInfections + cumulatedReSusceptibility counters[["nInfectious"]] <- init[["nInfectious"]] + cumulatedInfections - cumulatedRemovals counters[["nRemoved"]] <- init[["nRemoved"]] + cumulatedRemovals - cumulatedReSusceptibility counters <- rbind(init, counters) rownames(counters) <- NULL ### return the components in a list res <- list(type = epitype, size = n - sum(isNeverInfected), initiallyInfected = initiallyInfected, neverInfected = neverInfected, coordinates = coordinates, byID = byID, counters = counters) class(res) <- "summary.epidata" attr(res, "eventTimes") <- attr(object, "eventTimes") attr(res, "timeRange") <- attr(object, "timeRange") res } ################################################################################ # PRINT METHOD FOR 'EPIDATA' OBJECTS ################################################################################ print.epidata <- function (x, ...) { cat("\nHistory of an epidemic\n") cat("Number of individuals:", nlevels(x[["id"]]), "\n") cat("Time range:", paste(attr(x, "timeRange"), collapse = " -- "), "\n") cat("Number of infections:", length(attr(x, "eventTimes")), "\n\n") print.data.frame(x, ...) cat("\n") invisible(x) } ################################################################################ # PRINT METHOD FOR THE SUMMARY OF 'EPIDATA' OBJECTS ################################################################################ print.summary.epidata <- function(x, ...) { cat("\nAN", x$type, "EPIDEMIC\n") cat(" Time range:", paste(attr(x, "timeRange"), collapse = " -- "), "\n") cat(" Number of individuals:", nlevels(x$initiallyInfected), "\n") cat(" ", length(x$initiallyInfected), "initially infected individuals") if (length(x$initiallyInfected) > 0) { cat(":\n ") str(as.character(x$initiallyInfected), give.head = FALSE, vec.len = 100, strict.width = "wrap", indent.str = " ") } else cat("\n") cat(" ", length(x$neverInfected), "never infected individuals") if (length(x$neverInfected) > 0) { cat(":\n ") str(as.character(x$neverInfected), give.head = FALSE, vec.len = 100, strict.width = "wrap", indent.str = " ") } else cat("\n") cat(" Size of the epidemic:", x$size, "\n") if (x$type %in% c("SIRS", "SIS")) { cat(" Number of infections:", length(attr(x, "eventTimes")), "\n") } dimc <- dim(x$counters) cat("\n$ counters ('data.frame',", dimc[1L], "x", dimc[2L], "):", "evolution of the epidemic:\n") counters2print <- if (dimc[1] > 6L) { tmp <- format.data.frame(x$counters[c(1:3,1,dimc[1]-(1:0)),], na.encode = FALSE) tmp[4,] <- c("[....]", "", "", "", "", "") rownames(tmp)[4] <- "" as.matrix(tmp) } else { x$counters } print(counters2print, quote = FALSE, right = TRUE, na.print = "") cat("\n") invisible(x) } surveillance/R/algo_hmm.R0000644000176200001440000001146014615162374015070 0ustar liggesusers################################################### ### chunk number 1: ################################################### algo.hmm <- function(disProgObj, control = list(range=range, Mtilde=-1, noStates=2, trend=TRUE, noHarmonics=1,covEffectEqual=FALSE, saveHMMs = FALSE, extraMSMargs=list() )){ # check if the msm package is available if (!requireNamespace("msm")) { stop("the HMM method requires package ", sQuote("msm")) } # Set the default values if not yet set if(is.null(control$Mtilde)){ control$Mtilde <- -1 } if(is.null(control$noStates)){ control$noStates <- 2 } if(is.null(control$trend)){ control$trend <- TRUE } if(is.null(control$noHarmonics)){ control$noHarmonics <- 1 } if(is.null(control$covEffectEqual)){ control$covEffectEqual <- FALSE } if(is.null(control$saveHMMs)){ control$saveHMMs <- FALSE } if(is.null(control$extraMSMargs)){ control$extraMSMargs <- list() } #Stop if not enough for estimation if(min(control$range) < 2) { stop("Error: Too few values as reference values") } # initialize the necessary vectors alarm <- matrix(data = 0, nrow = length(control$range), ncol = 1) upperbound <- matrix(data = 0, nrow = length(control$range), ncol = 1) control$hmms <- list() ############################################## #Repeat for each time point to monitor on-line ############################################## for (i in 1:length(control$range)) { #Function is so slow some sort of performance indicator is usually necessary cat(paste("i=",i," (out of ",length(control$range),")\n",sep="")) #Initialize observations for each round -- can be done sequentally first <- ifelse(control$Mtilde== -1, 1, max(control$range[i]-control$Mtilde+1,1)) t <- first:control$range[i] observed <- disProgObj$observed[t] #Init data counts <- data.frame(observed, t) names(counts) <- c("observed","t") #Initialize formula formulaStr <- ifelse(control$trend, "~ 1 + t ", "~ 1 ") #Create formula and add harmonics as covariates -- this could be done recursively? for (j in seq_len(control$noHarmonics)) { counts[,paste("cos",j,"t",sep="")] <- cos(2*j*pi*(t-1)/disProgObj$freq) counts[,paste("sin",j,"t",sep="")] <- sin(2*j*pi*(t-1)/disProgObj$freq) formulaStr <- paste(formulaStr,"+ cos",j,"t + sin",j,"t ",sep="") } #Obtain crude inits q <- quantile(observed,seq(0,1,length.out=control$noStates+1)) lvl <- cut(observed,breaks=q,include.lowest=TRUE) crudeMean <- as.numeric(tapply(observed, lvl, mean)) hcovariates <- list() hmodel <- list() for (j in seq_len(control$noStates)) { hcovariates[[j]] <- as.formula(formulaStr) val <- crudeMean[j] #Substitution necessary, as hmmPois does lazy evaluation of rate argument hmodel[[j]] <- eval(substitute(msm::hmmPois(rate=val),list(val=crudeMean[j]))) } #Any constraints on the parameters of the covariates for the different states hconstraint <- list() if (control$covEffectEqual) { hconstraint <- list(t=rep(1,control$noStates)) for (j in seq_len(control$noHarmonics)) { hconstraint[[paste("sin",j,"t",sep="")]] <- rep(1,control$noStates) hconstraint[[paste("cos",j,"t",sep="")]] <- rep(1,control$noStates) } } #Prepare object for msm fitting msm.args <- list(formula = observed ~ t, data = counts, #HMM with "noStates" states having equal initial values qmatrix = matrix(1/control$noStates,control$noStates,control$noStates), #y|x \sim Po( \mu[t] ) with some initial values hmodel = hmodel, #Models for \log \mu_t^1 and \log \mu_t^2 hcovariates = hcovariates, #Force the effects of the trend and harmonics to be equal for all states hconstraint=hconstraint) #Add additional msm arguments msm.args <- modifyList(msm.args, control$extraMSMargs) # fit the HMM hmm <- do.call(what=msm::msm, args=msm.args) #In case the model fits should be saved. if (control$saveHMMs) { control$hmms[[i]] <- hmm } #If most probable state of current time point (i.e. last obs) equals the #highest state then do alarm # print(observed) # print(matrix(viterbi.msm(hmm)$fitted,ncol=1)) alarm[i] <- msm::viterbi.msm(hmm)$fitted[length(t)] == control$noStates #Upperbound does not have any meaning -- compute posterior probability! upperbound[i] <- 0 } #Add name and data name to control object. control$name <- paste("hmm:", control$trans) control$data <- paste(deparse(substitute(disProgObj))) #no need for hmm object -- control$hmm <- hmm # return alarm and upperbound vectors result <- list(alarm = alarm, upperbound = upperbound, disProgObj=disProgObj,control=control) class(result) = "survRes" # for surveillance system result return(result) } surveillance/R/epidataCS.R0000644000176200001440000005333314615162374015147 0ustar liggesusers################################################################################ ### Data structure for CONTINUOUS SPATIO-temporal infectious disease case data ### and a spatio-temporal grid of endemic covariates ### ### Copyright (C) 2009-2018,2021,2024 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ###################################################################### # MAIN GENERATOR FUNCTION FOR epidataCS OBJECTS # PARAMS: # events: SpatialPointsDataFrame of cases with obligatory columns # time: time point of event # tile: reference to spatial unit (tile) in stgrid, where the event is located # type: optional type of event (-> marked twinstim). will be converted to a factor variable. # eps.t: maximal temporal influence radius (e.g. length of infectious period, time to culling, etc.), may be Inf # eps.s: maximal spatial influence radius (e.g. 100 [km]), may be Inf # The remaining columns are further marks of the event, e.g. sex, age of infected person (-> epidemic covariates) # The column names ".obsInfLength", ".bdist", ".influenceRegion", and ".sources" are reserved. # ".obsInfLength": observed length of the infectious period (being part [0,T]) # ".bdist": minimal distance of the event locations to the boundary # ".influenceRegion": object of class "owin", the intersection of W with b(s,eps.s), with origin at s # ".sources": potential sources of infection # stgrid: data.frame with obligatory columns # tile: ID of spatial unit (e.g. id of municipality) # start, stop: temporal interval # area: area of the spatial unit (tile) # The remaining columns are endemic covariates. # The column name "BLOCK" is reserved (indexing the time intervals of stgrid). # W: SpatialPolygons. Observation region. Must have same proj4string as events. # qmatrix: square indicator matrix (0/1 or TRUE/FALSE) for possible transmission between the event types. will be internally converted to logical. Defaults to an independent spread of the event types. # nCircle2Poly: accuracy (number of edges) of the polygonal approximation of a circle # T: end of observation period (=last stop time). Must be specified if only the # start but not the stop times are supplied in stgrid (-> auto-generation of stop-times). # clipper: engine to use for computing polygon intersections. ###################################################################### obligColsNames_events <- c("time", "tile", "type", "eps.t", "eps.s") obligColsNames_stgrid <- c("start", "stop", "tile", "area") dotNames_events <- c(".obsInfLength", ".sources", ".bdist", ".influenceRegion") reservedColsNames_events <- c(dotNames_events, "BLOCK", "start") reservedColsNames_stgrid <- c("BLOCK") as.epidataCS <- function (events, stgrid, W, qmatrix = diag(nTypes), nCircle2Poly = 32, T = NULL, clipper = "polyclip", verbose = interactive()) { clipper <- match.arg(clipper) # Check and SORT events if (verbose) cat("\nChecking 'events':\n") events <- check_events(events, verbose = verbose) # Check and SORT stgrid if (verbose) cat("Checking 'stgrid':\n") tiles <- NULL # FIXME: add argument to as.epidataCS stgrid <- if (missing(stgrid) && inherits(tiles, "SpatialPolygons")) { if (verbose) cat("\t(missing, using time-constant 'tiles' grid)\n") check_stgrid(tiles2stgrid(tiles, start=0, T=T), verbose = FALSE) } else { check_stgrid(stgrid, T, verbose = verbose) } T <- tail(stgrid$stop, 1L) # Check class of W and consistency of area if (verbose) cat("Checking 'W' ...\n") W <- check_W(W, area.other = sum(stgrid[["area"]][seq_len(nlevels(stgrid$tile))]), other = "stgrid") stopifnot(identicalCRS(W, events)) # Check qmatrix if (verbose) cat("Checking 'qmatrix' ...\n") typeNames <- levels(events$type) nTypes <- length(typeNames) # default value of qmatrix depends on nTypes qmatrix <- checkQ(qmatrix, typeNames) # Check nCircle2Poly stopifnot(isScalar(nCircle2Poly)) nCircle2Poly <- as.integer(nCircle2Poly) # Small helper function converting event index to (time, tile, type) string eventidx2string <- function (eventIdx) { with(events@data, paste(c("time", "tile", "type"), "=", c(time[eventIdx], dQuote(tile[eventIdx]), dQuote(type[eventIdx])), collapse = ", ")) } # Check that all events are part of W if (verbose) cat("Checking if all events are part of 'W' ...\n") WIdxOfEvents <- over(events, W) if (eventNotInWidx <- match(NA, WIdxOfEvents, nomatch = 0L)) { stop("the event at (", eventidx2string(eventNotInWidx), ") is not ", "inside 'W'") } # Attach spatio-temporal grid data to events events@data <- merge_stgrid(events@data, stgrid, verbose = verbose) # Calculate observed infection length for log-likelihood events$.obsInfLength <- pmin(T - events$time, events$eps.t) # Determine potential source events (infective individuals) of each event if (verbose) cat("Determining potential event sources ...\n") events$.sources <- determineSources( eventTimes = events$time, eps.t = events$eps.t, eventCoords = coordinates(events), eps.s = events$eps.s, eventTypes = events$type, qmatrix = qmatrix) # Calculate minimal distance of event locations from the polygonal boundary if (verbose) cat("Calculating the events' distances to the boundary ...\n") Wowin <- SpP2owin(W) events$.bdist <- bdist(coordinates(events), Wowin) # Construct spatial influence regions around events if (verbose) cat("Constructing spatial influence regions around events ...\n") events$.influenceRegion <- .influenceRegions(events, Wowin, nCircle2Poly, clipper=clipper) # Return components in a list of class "epidataCS" res <- list(events = events, stgrid = stgrid, W = W, qmatrix = qmatrix) class(res) <- "epidataCS" if (verbose) cat("Done.\n\n") return(res) } ###################################################################### # HELPER FUNCTIONS FOR as.epidataCS ###################################################################### ### CHECK FUNCTION FOR events ARGUMENT IN as.epidataCS check_events <- function (events, dropTypes = TRUE, verbose = TRUE) { # Check class and spatial dimensions stopifnot(inherits(events, "SpatialPointsDataFrame")) if (ncol(events@coords) != 2L) { stop("only two spatial dimensions are supported") } # check suitability of Euclidean geometry if (identical(FALSE, is.projected(events))) { # is.projected may return NA warning("\"epidataCS\" expects planar coordinates; see 'spTransform'") } # Check existence of type column if (verbose) cat("\tChecking 'type' column ... ") events$type <- if ("type" %in% names(events)) { if (dropTypes) factor(events$type) else as.factor(events$type) } else { if (verbose) cat("Setting 'type' to 1 for all events.") factor(rep.int(1L,nrow(events@coords))) } if (verbose) cat("\n") # Check obligatory columns obligColsIdx <- match(obligColsNames_events, names(events), nomatch = NA_integer_) if (any(obligColsMissing <- is.na(obligColsIdx))) { stop("missing obligatory columns in 'events@data': ", paste(obligColsNames_events[obligColsMissing], collapse = ", ")) } # Check other columns on reserved names reservedColsIdx <- na.omit(match(reservedColsNames_events, names(events), nomatch=NA_integer_)) if (length(reservedColsIdx) > 0L) { warning("in 'events@data', the existing columns with reserved names (", paste0("'", names(events)[reservedColsIdx], "'", collapse=", "), ") have been replaced") events@data <- events@data[-reservedColsIdx] } # Check that influence radii are numeric and positive (also not NA) if (verbose) cat("\tChecking 'eps.t' and 'eps.s' columns ...\n") with(events@data, stopifnot(is.numeric(eps.t), eps.t > 0, is.numeric(eps.s), eps.s > 0)) # Transform time into a numeric variable if (verbose) cat("\tConverting event time into a numeric variable ...\n") events$time <- as.numeric(events$time) stopifnot(!is.na(events$time)) # Check event times for ties if (verbose) cat("\tChecking event times for ties ...\n") timeIsDuplicated <- duplicated(events$time) if (any(timeIsDuplicated)) { duplicatedTimes <- sort.int(unique(events$time[timeIsDuplicated])) warning("detected concurrent events at ", length(duplicatedTimes), " time point", if (length(duplicatedTimes) > 1L) "s", ": ", paste(head(duplicatedTimes, 6L), collapse = ", "), if (length(duplicatedTimes) > 6L) ", ...") } # Sort events chronologically if (verbose) cat("\tSorting events ...\n") events <- events[order(events$time),] # First obligatory columns then remainders (epidemic covariates) obligColsIdx <- match(obligColsNames_events, names(events@data)) covarColsIdx <- setdiff(seq_along(events@data), obligColsIdx) events@data <- events@data[c(obligColsIdx, covarColsIdx)] events@coords.nrs <- numeric(0L) # forget index of coordinate columns # Done. return(events) } ### CHECK FUNCTION FOR stgrid ARGUMENT IN as.epidataCS check_stgrid <- function (stgrid, T, verbose = TRUE, warn = TRUE) { # Check class stopifnot(inherits(stgrid, "data.frame")) # Check obligatory columns autostop <- FALSE if (is.null(stgrid[["stop"]])) { if (is.null(T)) stop("'T' must be specified for auto-generation ", "of 'stop' column in 'stgrid'") stopifnot(isScalar(T)) autostop <- TRUE stgrid$stop <- NA_real_ } obligColsIdx <- match(obligColsNames_stgrid, names(stgrid), nomatch = NA_integer_) if (any(obligColsMissing <- is.na(obligColsIdx))) { stop("missing obligatory columns in 'stgrid': ", paste(obligColsNames_stgrid[obligColsMissing], collapse = ", ")) } # Check other columns on reserved names if (warn && length(reservedCols <- intersect(reservedColsNames_stgrid, names(stgrid)))) { warning("replacing existing columns in 'stgrid' which have reserved names: ", paste0("'", reservedCols, "'", collapse=", ")) } # Transform tile into a factor variable # (also removing unused levels if it was a factor) if (verbose) cat("\tConverting 'tile' into a factor variable ...\n") stgrid$tile <- factor(stgrid$tile) # Transform start times and area into numeric variables stgrid$start <- as.numeric(stgrid$start) stgrid$area <- as.numeric(stgrid$area) # Check stop times stgrid$stop <- if (autostop) { # auto-generate stop times from start times and T if (verbose) cat("\tAuto-generating 'stop' column ...\n") starts <- sort(unique(stgrid$start)) if (T <= starts[length(starts)]) { stop("'T' must be larger than the last 'start' time in 'stgrid'") } stops <- c(starts[-1], T) stops[match(stgrid$start, starts)] } else { as.numeric(stgrid$stop) } # chronological data.frame of unique periods histIntervals <- unique(stgrid[c("start", "stop")]) histIntervals <- histIntervals[order(histIntervals[,1L]),] nBlocks <- nrow(histIntervals) if (!autostop) { # Check start/stop consistency if (verbose) cat("\tChecking start/stop consistency ...\n") if (any(histIntervals[,2L] <= histIntervals[,1L])) { stop("stop times must be greater than start times") } startStopCheck <- histIntervals[-1L,1L] != histIntervals[-nBlocks,2L] if (startStopCheckIdx <- match(TRUE, startStopCheck, nomatch = 0)) { stop("inconsistent start/stop times: time intervals not consecutive ", "at stop time ", histIntervals[startStopCheckIdx,2L]) } } # Add BLOCK id stgrid$BLOCK <- match(stgrid$start, histIntervals[,1L]) # Check that we have a full BLOCK x tile grid if (verbose) cat("\tChecking if the grid is complete ...\n") blocksizes <- table(stgrid$BLOCK) tiletable <- table(stgrid$tile) if (length(unique(blocksizes)) > 1L || length(unique(tiletable)) > 1L) { stop("'stgrid' is not a full grid") } # First column BLOCK, then obligCols, then remainders (endemic covariates) if (verbose) cat("\tSorting the grid by time and tile ...\n") BLOCKcolIdx <- match("BLOCK", names(stgrid)) obligColsIdx <- match(obligColsNames_stgrid, names(stgrid)) covarColsIdx <- setdiff(seq_along(stgrid), c(BLOCKcolIdx, obligColsIdx)) stgrid <- stgrid[c(BLOCKcolIdx, obligColsIdx, covarColsIdx)] # Sort by BLOCK and tile stgrid <- stgrid[order(stgrid$BLOCK, stgrid$tile),] # # Get row indexes of the blocks' first/last rows # beginBlock <- match(seq_len(nBlocks), stgrid[["BLOCK"]]) # endBlock <- c(beginBlock[-1L]-1L, nrow(stgrid)) # Done. return(stgrid) } ### MERGE stgrid DATA INTO events@data ## Note: 'events' below refers to the data slot merge_stgrid <- function (events, stgrid, verbose = TRUE) { # Some basic quantities nEvents <- nrow(events) timeRange <- with(stgrid, c(start[1], stop[length(stop)])) # Are events covered by stgrid? if (verbose) { cat("Checking if all events are covered by 'stgrid' ...\n") ## surveillance > 1.16.0: prehistory events are allowed => BLOCK is NA if (events$time[1L] <= timeRange[1L]) { cat(" Note: ", sum(events$time <= timeRange[1L]), " prehistory events (time <= ", timeRange[1L], ")\n", sep = "") } } if (events$time[nEvents] > timeRange[2L]) { stop("found ", sum(events$time > timeRange[2L]), " events beyond 'stgrid' (time > ", timeRange[2L], ")") } # Are all events$tile references really part of the stgrid? .events.tile <- factor(events$tile, levels = levels(stgrid$tile)) if (missingSCellIdx <- match(NA, .events.tile, nomatch = 0L)) { stop("the 'events$tile' entry \"", events$tile[missingSCellIdx], "\"", " is not a valid level of 'stgrid$tile'") } events$tile <- .events.tile # Map events to corresponding grid cells ## FIXME: could use plapply() but then also need a .parallel argument if (verbose) cat("Mapping events to 'stgrid' cells ...\n") withPB <- verbose && interactive() gridcellsOfEvents <- integer(nEvents) if (withPB) pb <- txtProgressBar(min=0, max=nEvents, initial=0, style=3) for (i in seq_len(nEvents)) { gridcellsOfEvents[i] <- gridcellOfEvent(events$time[i], events$tile[i], stgrid) if (withPB) setTxtProgressBar(pb, i) } if (withPB) close(pb) # Attach endemic covariates from stgrid to events if (verbose) cat("Attaching endemic covariates from 'stgrid' to 'events' ...\n") endemicVars <- setdiff(names(stgrid), c(reservedColsNames_stgrid, obligColsNames_stgrid)) copyCols <- c("BLOCK", "start", endemicVars) if (length(replaceCols <- intersect(copyCols, names(events)))) { warning("replacing existing columns in 'events' data with ", "variables from 'stgrid': ", paste0("'", replaceCols, "'", collapse=", ")) events[replaceCols] <- NULL # ensure endemic vars are _appended_ } events <- cbind(events, stgrid[gridcellsOfEvents, copyCols]) return(events) } ### CHECK FUNCTION FOR W ARGUMENT IN as.epidataCS check_W <- function (W, area.other = NULL, other, tolerance = 0.001) { W <- as(W, "SpatialPolygons") # i.e. drop data if a SpatialPolygonsDataFrame if (!is.null(area.other) && area.other > 0) { check_W_area(W, area.other, other, tolerance) } return(W) } check_W_area <- function (W, area.other, other, tolerance = 0.001) { area.W <- areaSpatialPolygons(W) if (!isTRUE(all.equal.numeric(area.other, area.W, tolerance = tolerance, check.attributes = FALSE))) warning("area of 'W' (", area.W, ") differs from ", "total tile area in '", other, "' (", area.other, ")") } ### CHECK FUNCTION FOR tiles ARGUMENT IN simEpidataCS() check_tiles <- function (tiles, levels, events = NULL, areas.stgrid = NULL, W = NULL, keep.data = FALSE, tolerance = 0.05) { stopifnot(inherits(tiles, "SpatialPolygons"), is.vector(levels, mode="character")) tileIDs <- row.names(tiles) ## check completeness of tiles if (!identical(tileIDs, levels)) { if (any(missingtiles <- !levels %in% tileIDs)) stop(sum(missingtiles), " regions are missing in 'tiles', ", "check 'row.names(tiles)'") ## order tiles by levels and drop any extra tiles tiles <- tiles[levels, ] } ## drop data (also for suitable over-method in check_tiles_events) .tiles <- as(tiles, "SpatialPolygons") ## check tile specification of events and identical projection if (!is.null(events)) { check_tiles_events(.tiles, events) } ## check areas areas.tiles <- areaSpatialPolygons(tiles, byid = TRUE) if (!is.null(areas.stgrid)) { check_tiles_areas(areas.tiles, areas.stgrid, tolerance=tolerance) } if (!is.null(W)) { stopifnot(identicalCRS(tiles, W)) check_W_area(W, area.other=sum(areas.tiles), other="tiles", tolerance=tolerance) } ## done if (keep.data) tiles else .tiles } check_tiles_events <- function (tiles, events) { tiles <- as(tiles, "SpatialPolygons") # remove potential data for over() stopifnot(inherits(events, "SpatialPointsDataFrame"), identicalCRS(tiles, events)) tileIDs <- row.names(tiles) eventIDs <- row.names(events) ## get polygon ID's of events (via overlay) eventtiles <- tileIDs[over(events, tiles)] if (length(which_not_in_tiles <- which(is.na(eventtiles)))) warning("some of 'events' are not within 'tiles': ", paste0("\"", eventIDs[which_not_in_tiles], "\"", collapse=", ")) if (!is.null(events@data[["tile"]])) { which_disagree <- setdiff( which(eventtiles != as.character(events$tile)), which_not_in_tiles) if (length(which_disagree)) message("'over(events, tiles)' disagrees with 'events$tile' for events ", paste0("\"", eventIDs[which_disagree], "\"", collapse=", ")) } invisible() } check_tiles_areas <- function (areas.tiles, areas.stgrid, tolerance = 0.05) { areas_all_equal <- all.equal.numeric(areas.stgrid, areas.tiles, tolerance = tolerance, check.attributes = FALSE) if (!isTRUE(areas_all_equal)) warning("tile areas in 'stgrid' differ from areas of 'tiles': ", areas_all_equal) } ### CONSTRUCT SPATIAL INFLUENCE REGIONS AROUND EVENTS # An influenceRegion is an object of class "owin" with origin # at the event (over which we have to integrate by a cubature rule) # An attribute "area" gives the area of the influenceRegion. # If it is actually a circular influence region, then there is an attribute # "radius" denoting the radius of the influence region. # Argument 'W' can be of class "owin" (preferred) or "SpatialPolygons" .influenceRegions <- function (events, W, npoly, maxExtent = NULL, clipper = "polyclip") { Wowin <- if (inherits(W, "owin")) W else SpP2owin(W) if (is.null(maxExtent)) maxExtent <- diameter.owin(Wowin) doIntersection <- switch( clipper, # which package to use for polygon intersection "polyclip" = function (center, eps) intersectPolyCircle.owin(Wowin, center, eps, npoly), ## "rgeos" = function (center, eps) SpP2owin( ## intersectPolyCircle.SpatialPolygons( ## as(W, "SpatialPolygons"), center, eps, npoly)), stop("unsupported polygon clipping engine: '", clipper, "'") ) eventCoords <- coordinates(events) ## FIXME: could use plapply() but then also need a .parallel argument res <- mapply( function (x, y, eps, bdist) { center <- c(x,y) ## if eps is very large, the influence region is the whole region of W iR <- shift.owin( if (eps > maxExtent) Wowin else doIntersection(center, eps), -center) ## if iR is actually a circle of radius eps, attach eps as attribute attr(iR, "area") <- if (eps <= bdist) { attr(iR, "radius") <- eps pi * eps^2 } else area.owin(iR) iR }, eventCoords[,1], eventCoords[,2], events$eps.s, events$.bdist, SIMPLIFY = FALSE, USE.NAMES = FALSE) attr(res, "nCircle2Poly") <- npoly attr(res, "clipper") <- clipper res } ### CREATE stgrid TEMPLATE FROM tiles tiles2stgrid <- function (tiles, start, T) { start <- sort.int(unique.default(start)) stgrid <- expand.grid(tile = row.names(tiles), start = start, KEEP.OUT.ATTRS = FALSE, stringsAsFactors = TRUE) cbind(stgrid, stop = rep(c(start[-1L], T), each = length(tiles)), area = rep(areaSpatialPolygons(tiles, byid = TRUE), length(start))) } surveillance/R/sts_coerce.R0000644000176200001440000001160014026677433015435 0ustar liggesusers################################################################################ ### Conversion between "ts" and "sts", and from "sts" to "data.frame" ### ### Copyright (C) 2014 Michael Hoehle, 2015-2017,2019-2021 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### Convert a simple "ts" object to an "sts" object setAs(from = "ts", to = "sts", def = function (from) { ## Extract frequency and start from the "ts" object freq <- frequency(from) start <- start(from) if (length(start) == 1) stop("could not convert time series start() to (year, index) form") ## Remove "tsp" attribute and "ts"/"mts" class tsp(from) <- NULL ## Create the sts object .sts(observed = from, start = start, freq = freq) }) ### Convert an "sts" object to a simple "ts" object as.ts.sts <- function (x, ...) { ts(data = x@observed, start = x@start, frequency = x@freq) } setAs(from = "sts", to = "ts", def = function (from) as.ts.sts(from)) ### Convert an "sts" object to an eXtensible Time Series "xts" as.xts.sts <- function (x, order.by = epoch(x, as.Date = TRUE), ...) { if (!missing(order.by) || x@freq %in% c(52, 365)) { xts::xts(x = x@observed, order.by = order.by, ...) } else { ## frequencies 4 and 12 are nicely handled by the as.xts.ts method xts::as.xts(as.ts.sts(x), ...) } } ### Convert an "sts" object to a data frame suitable for regression as.data.frame.sts <- function(x, row.names = NULL, optional = FALSE, # from the generic tidy = FALSE, as.Date = x@epochAsDate, ...) { if (tidy) return(tidy.sts(x, ...)) #Convert object to data frame and give names res <- data.frame("observed" = x@observed, "epoch" = epoch(x, as.Date = as.Date), "state" = x@state, "alarm" = x@alarm, "upperbound" = x@upperbound, "population" = x@populationFrac, check.names = FALSE) names(res) <- if (ncol(x) > 1) { ## names from data.frame() above should already be as intended namesObs <- colnames(x@observed, do.NULL = FALSE, prefix = "observed") c(paste0("observed.", namesObs), "epoch", paste0("state.", namesObs), paste0("alarm.", namesObs), paste0("upperbound.", namesObs), paste0("population.", namesObs)) } else { c("observed", "epoch", "state", "alarm", "upperbound", "population") } #Find out how many epochs there are each year res$freq <- if (x@epochAsDate && x@freq %in% c(52, 365)) { year <- strftime(epoch(x), if (x@freq == 52) "%G" else "%Y") epochStr <- switch(as.character(x@freq), "52" = "%V", "365" = "%j") maxEpoch <- vapply(X = unique(year), FUN = function (Y) { dummyDates <- as.Date(paste0(Y, "-12-", 26:31)) max(as.numeric(strftime(dummyDates, epochStr))) }, FUN.VALUE = 0, USE.NAMES = TRUE) maxEpoch[year] } else { # just replicate the fixed frequency x@freq } #Add a column denoting the epoch fraction within the current year res$epochInPeriod <- epochInYear(x) / res$freq return(res) } setMethod("as.data.frame", signature(x = "sts"), as.data.frame.sts) ### convert an "sts" object to a "data.frame" in long (tidy) format tidy.sts <- function (x, ...) { unitNames <- colnames(x, do.NULL = FALSE, prefix = "observed") v.names <- c("observed", "state", "alarm", "upperbound", "population") stswide <- as.data.frame(x, tidy = FALSE, as.Date = FALSE) ## nrow(stswide) = nrow(x), i.e., one row per epoch stswide$year <- year(x) stswide$epochInYear <- epochInYear(x) stswide$date <- tryCatch( epoch(x, as.Date = TRUE), # only works for particular values of x@freq error = function (e) as.Date(NA) ) if ((nUnit <- ncol(x)) == 1L) { stslong <- data.frame(stswide, "unit" = factor(unitNames), check.names = FALSE) } else { ## we have observed/population/... columns for each unit varying <- sapply(X = v.names, FUN = paste, unitNames, sep = ".", simplify = FALSE, USE.NAMES = TRUE) stslong <- reshape( data = stswide, direction = "long", varying = varying, v.names = v.names, timevar = "unit", times = unitNames, idvar = "epoch") stslong$unit <- factor(stslong$unit, levels = unitNames) attr(stslong, "reshapeLong") <- NULL } row.names(stslong) <- NULL ## reorder variables (ordering from above differs depending on nUnit) stslong[c("epoch", "unit", "year", "freq", "epochInYear", "epochInPeriod", "date", v.names)] } surveillance/R/sim_background.R0000644000176200001440000000414010662666102016265 0ustar liggesusers################################################### ### chunk number 1: ################################################### # 'sim.seasonalNoise' generates a cyclic model of a poisson distribution # as background data for a simulated timevector. # # Parameters: # A - amplitude (range of sinus), default = 1 # alpha - parameter to move along the y-axis # (negative values not allowed) # d.h alpha > = A, default = 1, # beta - regression coefficient, default = 0 # season - factor to create seasonal moves # (moves the curve along the x-axis), default = 0 # length - number of weeks to model # frequency - factor to determine the oscillation-frequency, default = 1 # state - if a state chain is given, it is weighted by the parameter K # and influences mu # K - weight for outbreaks sim.seasonalNoise <- function(A = 1, alpha = 1, beta = 0, phi = 0, length, frequency = 1, state = NULL, K = 0){ t <- 1:length # constant factor to transform weeks to the appropriate pi-value. omega <- 2 * pi/ 52 # season moves the sin along the x-axis. if(is.null(state)){ # no state chain mu <- exp(A * sin( frequency * omega * (t + phi)) + alpha + beta * t) } else{ # encounter the state chain mu <- exp(A * sin( frequency * omega * (t + phi)) + alpha + beta * t + K * state) } # create the noise as random numbers of the Poisson distribution # with parameter mu seasonalBackground <- rpois(length, mu) # get random numbers result <- list(seasonalBackground = seasonalBackground, t = t, mu = mu, A = A, alpha = alpha, beta = beta, phi = phi, length = length, frequency = frequency, K = K) class(result) = "seasonNoise" return(result) } surveillance/R/hhh4_calibration.R0000644000176200001440000000330614426171115016500 0ustar liggesusers################################################################################ ### calibrationTest() for "hhh4" fits ### ### Copyright (C) 2015,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ calibrationTest.hhh4 <- function (x, subset = x$control$subset, units = seq_len(x$nUnit), ...) { ## perform the calibration test in the specified subset res <- calibrationTest.default( x = x$stsObj@observed[subset, units, drop = FALSE], mu = x$fitted.values[match(subset, x$control$subset), units, drop = FALSE], size = psi2size.hhh4(x, subset, units), ...) ## change "data.name" to be the name of the supplied model res$data.name <- deparse(substitute(x)) res } calibrationTest.oneStepAhead <- function (x, units = NULL, ...) { ## perform the calibration test res <- if (is.null(units)) { calibrationTest.default( x = x$observed, mu = x$pred, size = psi2size.oneStepAhead(x), ...) } else { calibrationTest.default( x = x$observed[, units, drop = FALSE], mu = x$pred[, units, drop = FALSE], size = psi2size.oneStepAhead(x)[, units, drop = FALSE], ...) } ## change "data.name" to be the name of the supplied "oneStepAhead" object res$data.name <- deparse(substitute(x)) res } surveillance/R/epidataCS_aggregate.R0000644000176200001440000001736114430705133017145 0ustar liggesusers################################################################################ ### Convert "epidataCS" to the (aggregated) classes "epidata" or "sts" ### ### Copyright (C) 2009-2016,2018 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ###################################### ### Transform "epidataCS" to "epidata" ###################################### ## CAVE: this only generates a SIS epidemic, i.e. atRiskY is set to 1 ## immediately after recovery ## length of infectious period is taken from epidataCS$events$eps.t ## fcols are not generated here. these must be generated by a second call to ## twinSIR's as.epidata with desired f. (for safety) ## tileCentroids is a coordinate matrix whose row names are the tile levels as.epidata.epidataCS <- function (data, tileCentroids, eps = 0.001, ...) { if (!requireNamespace("intervals")) stop("conversion from ", dQuote("epidataCS"), " to ", dQuote("epidata"), " requires the ", sQuote("intervals"), " package") ### generate twinSIR's epidata object from stgrid (no events) centroidIdx <- match(levels(data$stgrid$tile), rownames(tileCentroids), nomatch = NA_integer_) if (anyNA(centroidIdx)) { stop("some levels of 'data$stgrid$tile' are not available from 'tileCentroids'") } centroids <- tileCentroids[centroidIdx,] if (any(c("xCent", "yCent") %in% names(data$stgrid))) { stop("'data$stgrid' already has columns \"xCent\" and \"yCent\"") } stgrid <- cbind(data$stgrid, atRiskY = 1L, event = 0L, Revent = 0L, xCent = centroids[,1], yCent = centroids[,2] # relies on ordering of stgrid by first BLOCK, then tile ) names(stgrid)[names(stgrid)=="tile"] <- "id" timeRange <- with(stgrid, c(start[1], stop[length(stop)])) ### now determine "events" with respect to the tiles # individual data indItimes <- data$events$time if (anyDuplicated(indItimes)) stop("'data$events' has concurrent event times") indRtimes <- indItimes + data$events$eps.t indInts <- intervals::Intervals(cbind(indItimes, indRtimes, deparse.level = 0L)) indTiles <- data$events$tile # tile data tileRows <- tapply(seq_along(indTiles), indTiles, c, simplify = FALSE) tileInts <- lapply(tileRows, function (rows) { if (length(rows)==0L) { matrix(0,0,2) } else if (length(rows)==1L) { as.matrix(indInts[rows]) } else as.matrix(intervals::reduce(indInts[rows])) }) tileNames <- rep.int(names(tileInts), sapply(tileInts, nrow)) tileItimes <- unlist(lapply(tileInts, function(ints) ints[,1]), use.names=FALSE) tileRtimes <- unlist(lapply(tileInts, function(ints) ints[,2]), use.names=FALSE) # there are possibly Rtimes which equal Itimes of other individuals # => break ties by considering Rtime shortly before Itime (arbitrary choice) while(length(dup <- which(tileRtimes %in% tileItimes)) > 0L) { tileRtimes[dup] <- tileRtimes[dup] - eps } # now there could be duplicated Rtimes... grml (choose another 'eps' in this case) if (anyDuplicated(tileRtimes)) { stop("breaking ties introduced duplicated Rtimes") } ### add additional stop times to stgrid for tile infections and recoveries requiredStopTimes <- sort(c(tileItimes,tileRtimes[tileRtimes timeRange[1]] # omit prehistory class(stgrid) <- c("epidata", "data.frame") attr(stgrid, "timeRange") <- timeRange cat("Inserting extra stop times in 'stgrid' (this might take a while) ... ") evHist <- intersperse(stgrid, requiredStopTimes, verbose=interactive()) # CAVE: this resets the BLOCK index class(evHist) <- "data.frame" ### <- THIS IS THE MOST TIME-CONSUMING PART OF THIS FUNCTION !!! cat("Done.\n") ### set event, Revent and atRiskY indicators tileNamesCodes <- match(tileNames, levels(evHist$id)) # event indicator (currently in evHist event==0 everywhere) idxItimes <- match(tileItimes, evHist$stop) - 1L + tileNamesCodes evHist$event[idxItimes] <- 1L # Revent indicator (currently in evHist Revent==0 everywhere) idxRtimes <- match(tileRtimes, evHist$stop) - 1L + tileNamesCodes # (may contain NA's if Revent after last stop) evHist$Revent[idxRtimes] <- 1L # atRiskY indicator .atRiskY <- rep.int(1L, nrow(evHist)) nTiles <- nlevels(evHist$id) nBlocks <- tail(evHist$BLOCK, 1) stopTimes <- unique(evHist$stop) # has length nBlocks for (i in seq_along(tileItimes)) { .Itime <- tileItimes[i] .Rtime <- tileRtimes[i] if (.Rtime <= timeRange[1L]) next # prehistory infection and removal .tileCode <- tileNamesCodes[i] idxsTileInEpi <- seq(.tileCode, by=nTiles, length.out=nBlocks) first0block <- if (.Itime < stopTimes[1L]) 1L else match(.Itime, stopTimes) + 1L last0block <- if (.Rtime > stopTimes[nBlocks]) nBlocks else match(.Rtime, stopTimes) .atRiskY[idxsTileInEpi[first0block:last0block]] <- 0L } evHist$atRiskY <- .atRiskY ### Return final epidata object of twinSIR-type cat("Generating final \"epidata\" object for use with twinSIR ... ") epi <- as.epidata(evHist[-grep("BLOCK", names(evHist))], id.col="id", start.col="start", stop.col="stop", atRiskY.col="atRiskY", event.col="event", Revent.col="Revent", coords.cols=c("xCent","yCent") ) cat("Done.\n") epi } #################################################################### ### Transform "epidataCS" to "sts" by aggregation of cases on stgrid #################################################################### epidataCS2sts <- function (object, freq, start, neighbourhood, tiles = NULL, popcol.stgrid = NULL, popdensity = TRUE) { stopifnot(inherits(object, "epidataCS")) tileLevels <- levels(object$stgrid$tile) if (!is.null(tiles)) { stopifnot(inherits(tiles, "SpatialPolygons"), tileLevels %in% row.names(tiles)) tiles <- tiles[tileLevels,] } ## prepare sts components blocks <- unique(object$stgrid$BLOCK) # epidataCS is sorted eventsByCell <- with(object$events@data, table(BLOCK=factor(BLOCK, levels=blocks), tile)) if (missing(neighbourhood)) { # auto-detect neighbourhood from tiles if (is.null(tiles)) stop("'tiles' is required for auto-generation of 'neighbourhood'") neighbourhood <- poly2adjmat(tiles, zero.policy=TRUE) if (nIslands <- sum(rowSums(neighbourhood) == 0)) message("Note: auto-generated neighbourhood matrix contains ", nIslands, ngettext(nIslands, " island", " islands")) } populationFrac <- if (is.null(popcol.stgrid)) NULL else { stopifnot(is.vector(popcol.stgrid), length(popcol.stgrid) == 1) popByCell <- object$stgrid[[popcol.stgrid]] if (popdensity) popByCell <- popByCell * object$stgrid[["area"]] totalpop <- sum(popByCell[seq_along(tileLevels)]) matrix(popByCell/totalpop, nrow=length(blocks), ncol=length(tileLevels), byrow=TRUE, dimnames=dimnames(eventsByCell)) } ## initialize sts object (sts() constructor discards NULL slots) sts(frequency=freq, start=start, # epoch=seq_along(blocks) [default] ##do not set epoch=blocks as blocks[1] could be >1 (from simulation) observed=unclass(eventsByCell), neighbourhood=neighbourhood, populationFrac=populationFrac, map=tiles) } surveillance/R/spatial_tools.R0000644000176200001440000002633214614123513016155 0ustar liggesusers################################################################################ ### Auxiliary functions for operations on spatial data ### ### Copyright (C) 2009-2015,2018,2021-2024 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### Polygonal Approximation of a Disc/Circle discpoly <- function (center, radius, npoly = 64, class = c("Polygon", "owin", "gpc.poly"), ## FIXME: should add polygonal "sfg" (or "sfc"?) hole = FALSE) { class <- match.arg(class) if (class == "owin") { # use spatstat.geom::disc res <- disc(radius=radius, centre=center, mask=FALSE, npoly=npoly) if (hole) { res$bdry[[1]]$x <- rev(res$bdry[[1]]$x) res$bdry[[1]]$y <- rev(res$bdry[[1]]$y) res$bdry[[1]]$hole <- TRUE } return(res) } ## do it myself for the "Polygon" and "gpc.poly" classes stopifnot(radius > 0, isScalar(npoly), npoly > 2) theta <- seq(2*pi, 0, length.out = npoly+1)[-(npoly+1)] # for clockwise order if (hole) theta <- rev(theta) # for anticlockwise order x <- center[1] + radius * cos(theta) y <- center[2] + radius * sin(theta) switch(class, "Polygon" = Polygon(cbind(c(x,x[1]),c(y,y[1])), hole=hole), "gpc.poly" = { pts <- list(list(x=x, y=y, hole=hole)) if (isClass("gpc.poly")) { #|| requireNamespace("gpclib") new("gpc.poly", pts = pts) } else { warning("formal class \"gpc.poly\" not available") pts } } ) } ### Wrapper for polyclip or sf::st_union unionSpatialPolygons <- function (SpP, method = c("sf", "polyclip"), ...) { if (identical(method, "gpclib") || identical(method, "rgeos")) { .Deprecated(msg = sprintf("method = \"%s\" is retired; using default", method)) method <- NULL } method <- match.arg(method) W <- switch( method, "sf" = { sf::as_Spatial(sf::st_union(sf::st_as_sfc(SpP), ...), IDs = "1") # as in rgeos::gUnaryUnion() before }, "polyclip" = { tiles_xylist <- xylist(SpP, reverse=FALSE) W_xylist <- polyclip::polyclip(tiles_xylist, tiles_xylist, "union", fillA = "nonzero", fillB = "nonzero", ...) ## FIXME: polyclip() seems to return owin-type vertex order? W_Polygons <- Polygons( lapply(W_xylist, function(p) Polygon(cbind(p$x,p$y)[c(1L,length(p$x):1L),])), ID="1") SpatialPolygons(list(W_Polygons)) } ) ## ensure that W has exactly the same proj4string as SpP W@proj4string <- SpP@proj4string W } ### internal implementation of as(W, "owin") from polyCub ### to avoid upgrade problems with polyCub <= 0.7.1 referring to old spatstat ### and to avoid calling as(W, "owin") from maptools (depends on load order) SpP2owin <- function (W, ...) owin(poly = xylist(W), ...) ### Compute distance from points to a polygonal boundary ## since spatstat 1.56-0, bdist.points() interfaces C-code via ## spatstat.utils:::distppllmin, which is faster than nncross.ppp() bdist <- function (xy, poly) # poly is a polygonal "owin" { bdist.points(ppp(x = xy[,1L], y = xy[,2L], window = poly, check = FALSE)) } ## Example: bdist(coordinates(imdepi$events), as(imdepi$W, "owin")) ### sample n points uniformly on a disc with radius r runifdisc <- function (n, r = 1, buffer = 0) { stopifnot(buffer <= r) rangle <- runif(n, 0, 2*pi) rdist <- r * sqrt(runif(n, (buffer/r)^2, 1)) rdist * cbind(cos(rangle), sin(rangle)) } ### Count number of instances at the same location of a SpatialPoints object ## NOTE: the default multiplicity-method has been integrated into the spatstat ## package which we import multiplicity.Spatial <- function (x) multiplicity(coordinates(x)) ### determines which polygons of a SpatialPolygons object are at the border, ### i.e. have coordinates in common with the spatial union of all polygons polyAtBorder <- function (SpP, snap = sqrt(.Machine$double.eps), method = "sf", ...) { SpP <- as(SpP, "SpatialPolygons") W <- unionSpatialPolygons(SpP, method = method, ...) if (length(W@polygons) > 1) warning("unionSpatialPolygons() produced >1 Polygons-components") Wcoords <- unique(do.call("rbind", lapply(W@polygons[[1]]@Polygons, coordinates))) atBorder <- sapply(SpP@polygons, function (x) { coords <- unique(do.call("rbind", lapply(x@Polygons, coordinates))) res <- FALSE for (i in seq_len(nrow(coords))) { if (any(spDistsN1(Wcoords, coords[i,], longlat=FALSE) < snap)) { res <- TRUE break } } res }) names(atBorder) <- row.names(SpP) atBorder } ### sp.layout items for spplot() ## draw labels for Spatial* objects layout.labels <- function (obj, labels = TRUE, plot = FALSE) { stopifnot(inherits(obj, "Spatial")) ## get region labels getLabels <- function (labels) { if (isTRUE(labels)) { row.names(obj) } else if (length(labels) == 1L && (is.numeric(labels) | is.character(labels))) { if (!"data" %in% slotNames(obj)) stop("no data slot to select labels from") obj@data[[labels]] } else labels } ## convert labels argument to a list labels.args <- if (is.list(labels)) { labels } else if (!is.null(labels) && !identical(labels, FALSE)) { list(labels = getLabels(labels)) } else { # labels = FALSE or labels = NULL return(NULL) } ## set default coordinates for panel.text() and parse labels labels.args <- modifyList(list(x = coordinates(obj), labels = TRUE), labels.args) labels.args$labels <- getLabels(labels.args$labels) if (plot) { ## plot labels in the traditional graphics system do.call("text", labels.args) } else { ## return layout item for use by spplot() c("panel.text", labels.args) } } ## draw a scalebar with labels layout.scalebar <- function (obj, corner = c(0.05, 0.95), scale = 1, labels = c(0, scale), height = 0.05, pos = 3, ..., plot = FALSE) { stopifnot(inherits(obj, "Spatial")) BB <- bbox(obj) force(labels) # the default should use the original 'scale' value in km if (isFALSE(is.projected(obj, warn = TRUE))) { ## 'obj' has longlat coordinates, 'scale' is interpreted in kilometres scale <- .scale2longlat(t(rowMeans(BB)), scale) } offset <- BB[, 1L] + corner * apply(BB, 1L, diff.default) textfun <- if (plot) "text" else "panel.text" lis <- list( list("SpatialPolygonsRescale", layout.scale.bar(height = height), offset = offset, scale = scale, fill = c(NA, 1), plot.grid = !plot), list(textfun, x = offset[1L], y = offset[2L], labels = labels[1L], pos = pos, ...), list(textfun, x = offset[1L] + scale[1L], y = offset[2L], labels = labels[2L], pos = pos, ...) ) if (plot) { for (li in lis) eval(do.call("call", li)) } else { lis } } .scale2longlat <- function (focusLL, distKM) { ## .destPoint() is copied from the "raster" package by Robert J. Hijmans ## 'p' is a longlat coordinate matrix, 'd' is a vector of distances in metres .destPoint <- function (p, d, b=90, r=6378137) { toRad <- pi/180 lon1 <- p[, 1] * toRad lat1 <- p[, 2] * toRad b <- b * toRad lat2 <- asin(sin(lat1) * cos(d/r) + cos(lat1) * sin(d/r) * cos(b)) lon2 <- lon1 + atan2(sin(b) * sin(d/r) * cos(lat1), cos(d/r) - sin(lat1) * sin(lat2)) lon2 <- (lon2 + pi)%%(2 * pi) - pi cbind(lon2, lat2)/toRad } rightLL <- .destPoint(focusLL, distKM * 1000) rightLL[,1L] - focusLL[,1L] } ## internal wrapper for sp::is.projected to catch its sf dependence is.projected <- function (obj, warn = FALSE) { res <- tryCatch(sp::is.projected(obj), packageNotFoundError = identity) ## should no longer be needed as the sp version has kept the no-sf fallback: if (inherits(res, "packageNotFoundError")) { ## fallback: grep for longlat in (deprecated) Proj.4 representation p4s <- as.character(obj@proj4string@projargs) res <- if (is.na(p4s) || !nzchar(p4s)) NA else !grepl("longlat", p4s, fixed = TRUE) } if (is.na(res) && warn) warning("could not determine projection status") res } ## internal replacement for sp::mapasp using the above is.projected wrapper mapasp <- function (data) { if (isFALSE(is.projected(data))) { bb <- bbox(data) xlim <- bb[1L,] ylim <- bb[2L,] (diff(ylim)/diff(xlim)) / cos((mean(ylim) * pi)/180) } else "iso" } ### determine the total area of a SpatialPolygons object areaSpatialPolygons <- function (obj, byid = FALSE) { ## if (requireNamespace("rgeos", quietly = TRUE)) { ## rgeos::gArea(obj, byid = byid) ## } else { areas <- vapply( X = obj@polygons, FUN = function (p) sum( vapply(X = p@Polygons, FUN = function (x) (1-2*x@hole) * x@area, FUN.VALUE = 0, USE.NAMES = FALSE) ), FUN.VALUE = 0, USE.NAMES = FALSE ) if (byid) setNames(areas, row.names(obj)) else sum(areas) ## } } ### build a SpatialGrid of approx. 'n' square cells covering 'bbox(obj)' ## replacement for maptools::Sobj_SpatialGrid() makeGrid <- function (obj, n = 128) { bb <- bbox(obj) xlim <- bb[1L,] ylim <- bb[2L,] xr <- xlim[[2L]] - xlim[[1L]] yr <- ylim[[2L]] - ylim[[1L]] asp <- if (lscape <- xr > yr) xr/yr else yr/xr n1 <- ceiling(sqrt(n*asp)) n2 <- ceiling(n1/asp) size <- (if (lscape) xr else yr) / n1 offset <- bb[,1L] + size/2 grd <- GridTopology(offset, c(size, size), if (lscape) c(n1, n2) else c(n2, n1)) SpatialGrid(grd, proj4string = obj@proj4string) } if (FALSE) { ## alternative that usually does not produce square cells, ## but has the same extent as bbox(obj), ## similar to sf::st_make_grid(obj, n = magic.dim(.)); ## this would produce different spatial intensity plots than before makeGrid <- function (obj, n = 128) { bb <- bbox(obj) xlim <- bb[1L,] ylim <- bb[2L,] xr <- xlim[[2L]] - xlim[[1L]] yr <- ylim[[2L]] - ylim[[1L]] if (length(n) == 1) { n <- magic.dim(n) if (xr > yr) n <- rev(n) } else stopifnot(length(n) == 2) size <- c(xr, yr)/n offset <- bb[, 1L] + size/2 grd <- GridTopology(offset, size, n) SpatialGrid(grd, proj4string = obj@proj4string) } } surveillance/R/AllGeneric.R0000644000176200001440000001666314121036765015320 0ustar liggesusers ### Define some functions to be S3 generic animate <- function (object, ...) UseMethod("animate") R0 <- function (object, ...) UseMethod("R0") as.epidata <- function (data, ...) UseMethod("as.epidata") intensityplot <- function (x, ...) UseMethod("intensityplot") untie <- function (x, amount, ...) UseMethod("untie") intersectPolyCircle <- function (object, center, radius, ...) UseMethod("intersectPolyCircle") calibrationTest <- function (x, ...) UseMethod("calibrationTest") scores <- function (x, ...) { if (identical(class(x), "list")) { ## backward compatibility with surveillance < 1.10-0 scores.oneStepAhead(x, ...) } else { UseMethod("scores") } } pit <- function (x, ...) UseMethod("pit") ## internal function with methods for "twinSIR" and "simEpidata" getModel <- function (object, ...) UseMethod("getModel") ## list coefficients by component coeflist <- function (x, ...) UseMethod("coeflist") coeflist.default <- function (x, npars, ...) { if (is.null(groupnames <- names(npars))) { stop("'npars' must be named") } f <- factor(rep.int(groupnames, npars), levels = groupnames) split.default(x = x, f = f, drop = FALSE) } ### Declare some existing R functions (which we import) to be S4-generic. ### This is not strictly necessary, but considered better programming style, and ### it avoids messages noting the creation of the generics during package build ### and installation, see the section "Basic Use" in help("setGeneric"). setGeneric("plot") setGeneric("aggregate") setGeneric("toLatex") ## data frame-like methods defined in sts.R setGeneric("dim") setGeneric("dimnames") ###################################################################### # Conversion to and from sts objects ###################################################################### #setGeneric("as.sts") setGeneric("as.data.frame") ###################################################################### # Accessing and replacing slots of the "sts" class ###################################################################### #epoch slot setGeneric("epoch", function(x, as.Date=x@epochAsDate) standardGeneric("epoch")) setMethod("epoch", "sts", function(x, as.Date=x@epochAsDate) { if (!as.Date) { # return numeric vector x@epoch } else { # convert to Date format if (x@epochAsDate) { as.Date(x@epoch, origin = "1970-01-01") } else if (x@freq == 12) { # use the first day of every month as.Date(strptime(paste(year(x), epochInYear(x), 1, sep = "-"), format = "%Y-%m-%d")) } else if (x@freq %in% c(26, 52)) { # use Mondays ## be consistent with epochInYear(): 'start' means *ISO* year and week! ## Unfortunately, %G and %V are not supported for input via strptime(): ## firstMonday <- strptime(x = paste0(x@start[1L], "-W", x@start[2L], "-1"), ## format = "%G-W%V-%u") # WRONG, gives today ## so we run a naive search for the Monday of the 'start' week startweek <- x@start[2L] if (x@freq == 26) startweek <- 2*startweek - 1 candidates <- seq.Date(as.Date(paste0(x@start[1L]-1L, "-12-29")), as.Date(paste0(x@start[1L], "-12-28")), by = 1L) firstMonday <- candidates[match(sprintf("%i-W%02i", x@start[1L], startweek), strftime(candidates, "%G-W%V"))] seq.Date(from = firstMonday, by = (52/x@freq) * 7L, length.out = nrow(x)) } else if (x@freq == 365) { # use day of the year (incorrect in leap years) as.Date(strptime(paste0(year(x), "-D", epochInYear(x)), format = "%Y-D%j")) } else { stop("date conversion only implemented for daily, (bi-)weekly and monthly data") } } }) setGeneric("epoch<-", function(x, value) standardGeneric("epoch<-")) setReplaceMethod("epoch", "sts", function(x, value) { if (length(value) != nrow(x@observed)) stop("'epoch' must be of length 'nrow(observed)'") if (inherits(value, "Date")) { value <- as.integer(value) x@epochAsDate <- TRUE } x@epoch <- value x }) # observed slot setGeneric("observed", function(x) standardGeneric("observed")) setMethod("observed", "sts", function(x) { return(x@observed) }) setGeneric("observed<-", function(x, value) standardGeneric("observed<-")) setReplaceMethod("observed", "sts", function(x, value) { x@observed <- value x }) # alarms slot setGeneric("alarms", function(x) standardGeneric("alarms")) setMethod("alarms", "sts", function(x) { return(x@alarm) }) setGeneric("alarms<-", function(x, value) standardGeneric("alarms<-")) setReplaceMethod("alarms", "sts", function(x, value) { x@alarm <- value x }) # upperbound slot setGeneric("upperbound", function(x) standardGeneric("upperbound")) setMethod("upperbound", "sts", function(x) { return(x@upperbound) }) setGeneric("upperbound<-", function(x, value) standardGeneric("upperbound<-")) setReplaceMethod("upperbound", "sts", function(x, value) { x@upperbound <- value x }) # population slot (actually its populationFrac) setGeneric("population", function(x) standardGeneric("population")) setMethod("population", "sts", function(x) { return(x@populationFrac) }) setGeneric("population<-", function(x, value) standardGeneric("population<-")) setReplaceMethod("population", "sts", function(x, value) { x@populationFrac <- value x }) ##control slot setGeneric("control", function(x) standardGeneric("control")) setMethod("control", "sts", function(x) { return(x@control) }) setGeneric("control<-", function(x, value) standardGeneric("control<-")) setReplaceMethod("control", "sts", function(x, value) { x@control <- value x }) ###multinomial Time series slot ##control slot setGeneric("multinomialTS", function(x) standardGeneric("multinomialTS")) setMethod("multinomialTS", "sts", function(x) { return(x@multinomialTS) }) setGeneric("multinomialTS<-", function(x, value) standardGeneric("multinomialTS<-")) setReplaceMethod("multinomialTS", "sts", function(x, value) { x@multinomialTS <- value x }) ### neighbourhood matrix slot setGeneric("neighbourhood", function(x) standardGeneric("neighbourhood")) setMethod("neighbourhood", "sts", function(x) { return(x@neighbourhood) }) setGeneric("neighbourhood<-", function(x, value) standardGeneric("neighbourhood<-")) setReplaceMethod("neighbourhood", "sts", function(x, value) { x@neighbourhood <- value x }) ###################################################################### # Miscellaneous access methods ###################################################################### setGeneric("epochInYear", function(x, ...) standardGeneric("epochInYear")) setGeneric("year", function(x, ...) standardGeneric("year")) ###################################################################### # For stsNC class ###################################################################### ### access function for repotringTriangle slot setGeneric("reportingTriangle", function(x) standardGeneric("reportingTriangle")) setMethod("reportingTriangle", "stsNC", function(x) { return(x@reportingTriangle) }) ### access function for delayCDF slot setGeneric("delayCDF", function(x) standardGeneric("delayCDF")) setMethod("delayCDF", "stsNC", function(x) { return(x@delayCDF) }) ### access function for SR slot setGeneric("score", function(x) standardGeneric("score")) setMethod("score", "stsNC", function(x) { return(x@SR) }) ### access function for prediction interval slot setGeneric("predint", function(x) standardGeneric("predint")) setMethod("predint", "stsNC", function(x) { return(x@pi) }) surveillance/R/glm_epidataCS.R0000644000176200001440000000472314426171115015776 0ustar liggesusers################################################################################ ### Formulation of an endemic-only twinstim as a Poisson-GLM with response the ### number of events per space-time cell of stgrid and offset log(dt*ds) ### ### Copyright (C) 2013-2014,2018 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ utils::globalVariables("area") # in glm(), the 'offset' is evaluated in 'data' glm_epidataCS <- function (formula, data, ...) { if (missing(formula)) { covariates <- c("start", setdiff(names(data$stgrid), c( reservedColsNames_stgrid, obligColsNames_stgrid))) formula <- as.formula(paste0("~", paste0(covariates, collapse=" + "))) } ## for a type-specific model, we really have to set up the full ## "stkappagrid", i.e. with nBlocks*nTiles*nTypes rows typeSpecificModel <- "type" %in% all.vars(formula) typeNames <- levels(data$events@data$type) nTypes <- length(typeNames) ## aggregated number of events in each cell of the stgrid ## (prehistory events have a missing BLOCK and are thus ignored) if (typeSpecificModel) { .stgrid <- do.call("rbind", lapply(typeNames, function (type) { cbind(data$stgrid, type=type, deparse.level=0) })) eventsByCell <- c(table(with(data$events@data, { interaction(tile, BLOCK, type, drop=FALSE, sep=".", lex.order=FALSE) }))) .stgrid$nEvents <- eventsByCell[paste( .stgrid$tile, .stgrid$BLOCK, .stgrid$type, sep=".")] } else { .stgrid <- data$stgrid eventsByCell <- c(table(with(data$events@data, { interaction(tile, BLOCK, drop=FALSE, sep=".", lex.order=FALSE) }))) .stgrid$nEvents <- eventsByCell[paste( .stgrid$tile, .stgrid$BLOCK, sep=".")] } .stgrid$nEvents[is.na(.stgrid$nEvents)] <- 0L ##stopifnot(sum(.stgrid$nEvents) == sum(!is.na(data$events$BLOCK))) ## Fit corresponding Poisson-GLM environment(formula) <- environment() # to see typeSpecificModel and nTypes glm(update.formula(formula, nEvents ~ .), family = poisson(link="log"), data = .stgrid, offset = log((if(typeSpecificModel) 1 else nTypes)*(stop-start)*area), ...) } surveillance/R/addSeason2formula.R0000644000176200001440000000352414426171115016651 0ustar liggesusers################################################################################ ### Conveniently add sine-cosine terms to a model formula ### ### Copyright (C) 2010 Michaela Paul, 2013-2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## for S = 1, 'sin(2*pi * t/period) + cos(2*pi * t/period)' is added to 'f' addSeason2formula <- function ( f = ~1, # formula to enhance S = 1, # number of sine/cosine pairs period = 52, # periodicity of the sinusoidal wave timevar = "t" # name of the time variable ){ ## check arguments stopifnot(inherits(f, "formula"), is.vector(S, mode = "numeric"), S >= 0, isScalar(period)) ## return unchanged formula if S = 0 if (max(S) == 0) return(f) ## character representation of old formula ftext <- paste0(deparse(f), collapse = "") ## add sine-cosine terms if (length(S) == 1L) { for (i in seq_len(S)) { ftext <- paste0(ftext, " + sin(", 2*i, "*pi*", timevar, "/", period, ")", " + cos(", 2*i, "*pi*", timevar, "/", period, ")") } } else { ## unit-specific seasonality for hhh4() via the special fe() function for (i in seq_len(max(S))) { which <- paste0(i <= S, collapse = ",") ftext <- paste0(ftext, " + fe(sin(",2*i,"*pi*",timevar,"/",period,"), which=c(",which,"))", " + fe(cos(",2*i,"*pi*",timevar,"/",period,"), which=c(",which,"))") } } ## convert back to a formula as.formula(ftext, env = .GlobalEnv) } surveillance/R/makeControl.R0000644000176200001440000000210013346465003015545 0ustar liggesusers################################################################################ ### Convenient construction of a list of control arguments for "hhh4" models ### ### Copyright (C) 2014-2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ makeControl <- function (f = list(~1), S = list(0, 0, 1), period = 52, offset = 1, ...) { ## set model components control <- mapply(function (f, S, period, offset) { f <- addSeason2formula(f = f, S = S, period = period) list(f = f, offset = offset) }, f, S, period, offset, SIMPLIFY = FALSE, USE.NAMES = FALSE) names(control) <- c("ar", "ne", "end") ## default: negative-binomial distribution with common overdispersion control$family <- "NegBin1" ## customization via ... arguments modifyList(control, list(...)) } surveillance/R/twinSIR_methods.R0000644000176200001440000002270314615162374016371 0ustar liggesusers################################################################################ ### Methods for "twinSIR" fits, specifically: ### - vcov: enabling the use of function confint to calculate Wald ### confidence intervals for the parameter estimates. ### - logLik: enables the use of function AIC ### - AIC, extractAIC: compute AIC or OSAIC depending on argument 'one.sided' ### - print, summary, print.summary, plot (intensityPlot), ... ### ### Copyright (C) 2009-2014 Sebastian Meyer, contributions by Michael Hoehle ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ### don't need a specific coef-method (identical to stats:::coef.default) ## coef.twinSIR <- function (object, ...) ## { ## object$coefficients ## } # asymptotic variance-covariance matrix (inverse of fisher information matrix) vcov.twinSIR <- function (object, ...) { solve(object$fisherinfo) } logLik.twinSIR <- function (object, ...) { r <- object$loglik attr(r, "df") <- length(coef(object)) class(r) <- "logLik" r } # Note: pz is determined by scanning the names of coef(object), # thus the 'model' component is not necessary # See the Hughes and King (2003) paper for details .OSAICpenalty <- function (twinSIRobject, k = 2, nsim = 1e3) { theta <- coef(twinSIRobject) npar <- length(theta) pz <- length(grep("cox\\([^)]+\\)", names(theta), ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE, invert = FALSE)) px <- npar - pz # number of constrained (non-negative) parameters penalty <- if (px == 0L) { k * pz # default AIC penalty (with k = 2) } else if (px == 1L) { k * (pz + 0.5) } else if (px == 2L) { Sigma <- vcov(twinSIRobject) # parameter covariance matrix rho <- cov2cor(Sigma[1:2,1:2])[1,2] as <- acos(rho)/2/pi w <- c(as, 0.5, 0.5-as) k * sum(w * (pz + 0:2)) # = k * sum(w * (npar - px + 0:2)) } else { # px > 2 message("Computing OSAIC weights for ", px, " epidemic covariates based on ", nsim, " simulations ...") W <- vcov(twinSIRobject)[1:px,1:px] w.sim <- w.chibarsq.sim(p=px, W=W, N=nsim) #c.f. (12) in Hughes & King (2003), r_i=px, m=0:px, ki=npar #as npar=pz+px, we have that npar-px = pz, hence the sum is k * sum(w.sim * (pz + 0:px)) } attr(penalty, "exact") <- px <= 2 penalty } AIC.twinSIR <- function (object, ..., k = 2, one.sided = NULL, nsim = 1e3) { AIC.default <- match.call() AIC.default$one.sided <- NULL AIC.default$nsim <- NULL AIC.default[[1]] <- call(":::", as.name("stats"), as.name("AIC.default")) ## I don't see any easy way of using AIC.default while avoiding ":::". ## NextMethod() does not fit due to extra arguments one.sided & nsim. ## Could maybe unclass "object" and all objects in "..." and then use AIC() if (is.null(one.sided)) { one.sided <- object$method == "L-BFGS-B" } if (one.sided) { penalty <- .OSAICpenalty(object, k = k, nsim = nsim) edf <- length(coef(object)) AIC.default$k <- penalty/edf } res <- eval(AIC.default, parent.frame()) attr(res, "type") <- if (one.sided) "One-sided AIC" else "Standard AIC" attr(res, "exact") <- if (one.sided) attr(penalty, "exact") else TRUE res } extractAIC.twinSIR <- function (fit, scale = 0, k = 2, one.sided = NULL, nsim = 1e3, ...) { if (is.null(one.sided)) { one.sided <- fit$method == "L-BFGS-B" } loglik <- logLik(fit) edf <- attr(loglik, "df") penalty <- if (one.sided) { .OSAICpenalty(fit, k = k, nsim = nsim) # one-sided AIC } else { k * edf # default AIC } res <- c(edf = edf, AIC = -2 * c(loglik) + penalty) attr(res, "type") <- if (one.sided) "One-sided AIC" else "Standard AIC" attr(res, "exact") <- if (one.sided) attr(penalty, "exact") else TRUE res } print.twinSIR <- function (x, digits = max(3, getOption("digits") - 3), ...) { cat("\nCall:\n") print.default(x$call) cat("\nCoefficients:\n") print.default(format(coef(x), digits=digits), print.gap = 2, quote = FALSE) cat("\nLog-likelihood: ", format(logLik(x), digits=digits), "\n", sep = "") if (!x$converged) { cat("\nWARNING: OPTIMIZATION DID NOT CONVERGE!\n") } cat("\n") invisible(x) } summary.twinSIR <- function (object, correlation = FALSE, symbolic.cor = FALSE, ...) { ans <- object[c("call", "converged", "counts", "intervals", "nEvents")] ans$cov <- vcov(object) est <- coef(object) se <- sqrt(diag(ans$cov)) zval <- est/se pval <- 2 * pnorm(abs(zval), lower.tail = FALSE) ans$coefficients <- cbind(est, se, zval, pval) dimnames(ans$coefficients) <- list(names(est), c("Estimate", "Std. Error", "z value", "Pr(>|z|)")) if (correlation) { ans$correlation <- cov2cor(ans$cov) ans$symbolic.cor <- symbolic.cor } ans$loglik <- logLik(object) aic <- extractAIC(object, ...) ans$aic <- as.vector(aic[2L]) # remove 'edf' element attributes(ans$aic) <- attributes(aic)[c("type", "exact")] class(ans) <- "summary.twinSIR" ans } print.summary.twinSIR <- function (x, digits = max(3, getOption("digits") - 3), symbolic.cor = x$symbolic.cor, signif.stars = getOption("show.signif.stars"), ...) { cat("\nCall:\n") print.default(x$call) cat("\nCoefficients:\n") coefs <- x$coefficients printCoefmat(coefs, digits = digits, signif.stars = signif.stars, na.print = "NA", ...) nEvents <- x$nEvents nh0 <- length(nEvents) if (nh0 < 2L) { cat("\nTotal number of infections: ", nEvents, "\n") } else { cat("\nBaseline intervals:\n") intervals <- character(nh0) for(i in seq_len(nh0)) { intervals[i] <- paste("(", paste(format(x$intervals[c(i,i+1L)],trim=TRUE), collapse=";"), "]", sep = "") } names(intervals) <- paste("logbaseline", seq_len(nh0), sep=".") print.default(rbind("Time interval" = intervals, "Number of events" = nEvents), quote = FALSE, print.gap = 2) } cat("\n", attr(x$aic, "type"), ": ", format(x$aic, digits=max(4, digits+1)), if (!attr(x$aic, "exact")) "\t(simulated penalty weights)" else "", sep = "") cat("\nLog-likelihood:", format(x$loglik, digits = digits)) cat("\nNumber of log-likelihood evaluations:", x$counts[1], "\n") correl <- x$correlation if (!is.null(correl)) { p <- NCOL(correl) if (p > 1L) { cat("\nCorrelation of Coefficients:\n") if (is.logical(symbolic.cor) && symbolic.cor) { correl <- symnum(correl, abbr.colnames = NULL) correlcodes <- attr(correl, "legend") attr(correl, "legend") <- NULL print(correl) cat("---\nCorr. codes: ", correlcodes, "\n", sep="") } else { correl <- format(round(correl, 2), nsmall = 2, digits = digits) correl[!lower.tri(correl)] <- "" print(correl[-1, -p, drop = FALSE], quote = FALSE) } } } if (!x$converged) { cat("\nWARNING: OPTIMIZATION DID NOT CONVERGE!\n") } cat("\n") invisible(x) } ### Plot method for twinSIR (wrapper for intensityplot) plot.twinSIR <- function (x, which, ...) # defaults for 'which' are set below { cl <- match.call() cl[[1]] <- as.name("intensityplot") eval(cl, envir = parent.frame()) } formals(plot.twinSIR)$which <- formals(intensityplot.twinSIR)$which ###################################################################### # Extract the "residual process" (cf. Ogata, 1988), i.e. the # fitted cumulative intensity at the event times. # -> "generalized residuals similar to those discussed in Cox and Snell (1968)" ###################################################################### residuals.twinSIR <- function(object, ...) { #Extract event and stop-times eventTimes <- attr(object$model$survs,"eventTimes") sortedStop <- sort(unique(object$model$survs[,"stop"])) eventTimesIdx <- match(eventTimes, sortedStop) #Dimensions and zero vector (in case we need it) nTimes <- nrow(object$model$X) zerovec <- numeric(nTimes) # Extract the fitted model params px <- ncol(object$model$X) pz <- ncol(object$model$Z) theta <- coef(object) alpha <- theta[seq_len(px)] beta <- theta[px+seq_len(pz)] # Initialize e, h and thus lambda if (px > 0) { e <- as.vector(object$model$X %*% as.matrix(alpha)) } else { e <- zerovec } if (pz > 0) { h <- as.vector(exp(object$model$Z %*% as.matrix(beta))) } else { h <- zerovec } lambda <- (e + h) #Determine blocks BLOCK <- as.numeric(factor(object$model$survs$start)) # lambda_i integrals, i.e. integral of \lambda_i until t for each individual dt <- object$model$survs[,"stop"] - object$model$survs[,"start"] #Easier - no individual summations as they are all summed anyhow afterwards intlambda <- tapply(object$model$weights * lambda* dt, BLOCK, sum) #Compute cumulative intensities (Ogata (1988): "residual process") tau <- cumsum(intlambda)[eventTimesIdx] tau } surveillance/R/twinSIR_intensity.R0000644000176200001440000003024214405667703016754 0ustar liggesusers################################################################################ # Authors: Sebastian Meyer, with contributions by Michael Hoehle # Date: 02 June 2009, modified 25 Mar 2011, 27 Jun 2012 # # This file contains functions related to calculating and plotting intensities. ################################################################################ ################################################################################ # Calculate the two components of the intensity lambda(t|H_t) for each row # of the event history. # Be aware that the function assumes atRiskY == 1 in all rows! # # ARGS: # theta - parameter vector c(alpha,beta), where # beta also contains the baseline coefficients in the first place # X - covariate matrix related to alpha, i.e. the epidemic component # Z - covariate matrix related to beta, i.e. the Cox-like endemic component # # RETURNS: a numeric matrix with two columns e and h and nrow(X)==nrow(Z) rows ################################################################################ .eh <- function(theta, X, Z) { # Extracting params from theta dimX <- dim(X) nRows <- dimX[1] # = nrow(Z) px <- dimX[2] pz <- ncol(Z) alpha <- theta[seq_len(px)] beta <- theta[px + seq_len(pz)] # Calculate the epidemic component e(t|H_t) and the endemic component h(t) e <- if (px > 0L) drop(X %*% alpha) else numeric(nRows) h <- if (pz > 0L) drop(exp(Z %*% beta)) else numeric(nRows) # Return the two components of the infection intensity related to the # rows of the event history in a two column matrix eh <- cbind(e = e, h = h) return(eh) } ################################################################################ # Cumulative hazard function # # \Lambda(t) = \int_{timeRange[1]}^t \lambda(s) ds, # # where \lambda(s) = \sum_{i=1}^n \lambda_i(s) # # Be aware that the function assumes atRiskY == 1 for all rows of X/Z/survs !!! # # ARGS: # t - scalar time point until we want to integrate, must be non-negative # theta - parameter vector c(alpha,beta), where # beta also contains the baseline coefficients in the first place # X - covariate matrix related to alpha, i.e. the epidemic component # Z - covariate matrix related to beta, i.e. the Cox-like endemic component # survs - data.frame with columns id, start, stop, event; "timeRange" attribute # weights - vector of length nrow(X) indicating the number of individuals # with the same covariates. weights are allowed to change over time. # Note: it is assumed that none of the individuals covered by # "weights" can have an actual event, if so they need to have their # own row # # RETURNS: value of the cumulative hazard function at time t ################################################################################ if (FALSE) { # unused Lambda <- function(t, theta, X, Z, survs, weights) { timeRange <- attr(survs, "timeRange") eh <- if (!isScalar(t) || t < timeRange[1L]) { stop("invalid argument 't': must be a scalar >= ", timeRange[1L], " (beginning of observation period)") } else if (t == timeRange[1L]) { return(0) } else if (t < timeRange[2L]) { # We have to extract the relevant intervals sortedStop <- sort(unique(survs$stop)) # Find first stop time beyond t idx <- match(TRUE, sortedStop >= t) firstBeyondt <- sortedStop[idx] includeSurvsRow <- survs$stop <= firstBeyondt # If t between start and stop of an interval we need to chop... if (firstBeyondt != t) { survs$stop[survs$stop == firstBeyondt] <- t } # Extract relevant parts survs <- survs[includeSurvsRow,] weights <- weights[includeSurvsRow] .eh(theta, X[includeSurvsRow,], Z[includeSurvsRow,]) } else { # if t >= attr(survs, "timeRange")[2], we take all rows .eh(theta, X, Z) } lambda <- rowSums(eh) dt <- survs$stop - survs$start intlambda <- sum(weights * lambda * dt) # no individual sums as in loglik return(intlambda) } } ################################################################################ # Function to plot the path of the infection intensity or the proportions of # the endemic or epidemic component, either on an individual basis or related # to the total intensity at each event (=infection) time. # The function works with objects of class "simEpidata" # as well as with objects of class "twinSIR". ################################################################################ # 'model' is the result of getModel(x) # if x is of class "twinSIR": theta = (alpha, beta) = (alpha, (h0coefs, betarest)) # if x is of class "simEpidata": theta = (alpha, 1, betarest) # per default, the function uses the fitted or true parameters, respectively intensityplot_twinSIR <- function(model, which = c("epidemic proportion", "endemic proportion", "total intensity"), aggregate = TRUE, theta = NULL, plot = TRUE, add = FALSE, rug.opts = list(), ...) { which <- match.arg(which) ## model components survs <- model$survs start <- attr(survs, "timeRange")[1L] end <- attr(survs, "timeRange")[2L] timeIntervals <- unique(survs[c("start", "stop")]) timepoints <- unique(c(timeIntervals$stop, end)) # need 'end' here, because model does only contain rows with atRiskY == 1, # otherwise would terminate in advance if all individuals have been infected nTimes <- length(timepoints) idlevels <- levels(survs$id) ## helper function for use with by() intensity <- function(iddata, what) { # 'iddata' will be a subset of survs, 'what' will be "wlambda" or "we" y <- numeric(nTimes) # zeroes y[match(iddata$stop, timepoints)] <- iddata[[what]] y } ## Calculate epidemic (e) and endemic (h) component in each row of the model eh <- do.call(".eh", args = c(list(theta = theta), model[c("X", "Z")])) ## Calculate individual _total intensity_ paths lambda <- rowSums(eh) survs$wlambda <- as.vector(model$weights * lambda) ## put individual intensity paths into a matrix [nTimes x n] wlambdaID <- by(data = survs, INDICES = survs["id"], FUN = intensity, what = "wlambda", simplify = FALSE) # initially infectious individuals (without re-infection) don't appear in # survs, since they are never atRiskY => wlambdaID[[i]] is NULL for such an # individual i but should be a 0-vector of length nTimes initiallyInfected <- names(which(vapply(wlambdaID, is.null, TRUE))) #if (length(initiallyInfected) > 0L) # not necessary wlambdaID[initiallyInfected] <- rep(list(numeric(nTimes)), length(initiallyInfected)) wlambdaIDmatrix <- as.matrix(as.data.frame(c(wlambdaID), optional = TRUE)) ## alternative way but slower: ## wlambdaIDmatrix <- matrix(0, nrow = nTimes, ncol = length(idlevels), ## dimnames = list(NULL, idlevels)) ## for (ID in idlevels) { ## iddata <- survs[survs$id == ID,] ## wlambdaIDmatrix[match(iddata$stop, timepoints), ID] <- iddata$wlambda ## } if (which != "total intensity") { ## Calculate individual _epidemic intensity_ paths survs$we <- { px <- ncol(model$X) if (px == 0L) { stop("nothing to do, model does not contain both components") } as.vector(model$weights * eh[,1]) } ## put individual epidemic intensity paths into a matrix [nTimes x n] weID <- by(data = survs, INDICES = list(id = survs$id), FUN = intensity, what = "we", simplify = FALSE) # we have to replace NULL entries by numeric(nTimes) (cf. wlambdaID) weID[initiallyInfected] <- rep(list(numeric(nTimes)), length(initiallyInfected)) weIDmatrix <- as.matrix(as.data.frame(c(weID), optional = TRUE)) ## alternative code which is slower: ## weIDmatrix <- matrix(0, nrow = nTimes, ncol = length(idlevels), ## dimnames = list(NULL, idlevels)) ## for (ID in idlevels) { ## iddata <- survs[survs$id == ID,] ## weIDmatrix[match(iddata$stop, timepoints), ID] <- iddata$we ## } } ## Generate matrix with data for 'matplot' ydata2plot <- if (which == "total intensity") { if (aggregate) { rowSums(wlambdaIDmatrix) } else { wlambdaIDmatrix } } else { # calculate epidemic proportion if (aggregate) { rowSums(weIDmatrix) / rowSums(wlambdaIDmatrix) } else { weIDmatrix / wlambdaIDmatrix } } if (which == "endemic proportion") { ydata2plot <- 1 - ydata2plot } ydata2plot <- as.matrix(ydata2plot) colnames(ydata2plot) <- if (aggregate) which else idlevels if (which != "total intensity") { # there may be NAs in data2plot where the total intensity equals 0 # => when calculating proportions we get 0 / 0 = NA # we redefine those values to 0. (0-intensity => 0-proportion) ydata2plot[is.na(ydata2plot)] <- 0 } # prepend time (x) column data2plot <- cbind(stop = timepoints, ydata2plot) # if the epidemic is SIRS or SIS (re-susceptibility), there may be time # blocks during the observation period, where no individual is susceptible: # Problem: those time blocks are not included in the model component, # which only contains rows with atRiskY == 1 # Solution: fill the missing time periods with 0 intensity (or proportion) innerStart <- timeIntervals[-1L, "start"] innerStop <- timeIntervals[-nrow(timeIntervals), "stop"] noSusceptiblesStopTimes <- innerStart[innerStop != innerStart] if (length(noSusceptiblesStopTimes) > 0L) { data2plot <- rbind(data2plot, cbind(noSusceptiblesStopTimes, matrix(0, nrow = length(noSusceptiblesStopTimes), ncol = ncol(ydata2plot)) ) ) data2plot <- data2plot[order(data2plot[,1L]),] } ## Plot and return data if (plot) { dotargs <- list(...) nms <- names(dotargs) if(! "xlab" %in% nms) dotargs$xlab <- "time" if(! "ylab" %in% nms) dotargs$ylab <- which if(! "lty" %in% nms) dotargs$lty <- 1 do.call("matplot", args = c(list(x = c(start, data2plot[,1L]), y = rbind(data2plot[1L, -1L, drop = FALSE], data2plot[ , -1L, drop = FALSE]), type = "S", add = add), dotargs)) if (is.list(rug.opts)) { if (is.null(rug.opts$ticksize)) rug.opts$ticksize <- 0.02 if (is.null(rug.opts$quiet)) rug.opts$quiet <- TRUE do.call("rug", args = c(list(x = attr(survs, "eventTimes")), rug.opts)) } invisible(data2plot) } else { data2plot } } ### intensityplot-methods for objects of classes "twinSIR" and "simEpidata" intensityplot.twinSIR <- function (x, theta = NULL, ...) # formals updated below { cl <- match.call() cl[[1]] <- as.name("intensityplot_twinSIR") names(cl)[names(cl) == "x"] <- "model" cl$model <- quote(getModel(x)) if (is.null(theta)) { cl$theta <- quote(coef(x)) } eval(cl) } intensityplot.simEpidata <- function (x, theta = NULL, ...) # formals updated below { cl <- match.call() cl[[1]] <- as.name("intensityplot_twinSIR") names(cl)[names(cl) == "x"] <- "model" cl$model <- quote(getModel(x)) if (is.null(theta)) { config <- attr(x, "config") cl$theta <- quote(c(config$alpha, 1, config$beta)) # 1 is for true h0 } ## guess and warn about non-constant h0 (a flag in config would be better) if (any(names(formals(config$h0)) %in% all.vars(body(config$h0)))) message("Note: the (true) baseline hazard is only evaluated", " at the beginning of the time intervals") eval(cl) } formals(intensityplot.twinSIR) <- formals(intensityplot.simEpidata) <- c(alist(x=), formals(intensityplot_twinSIR)[-1]) surveillance/R/clapply.R0000644000176200001440000000126513117527513014747 0ustar liggesusers################################################################################ ### Conditional lapply ### ### Copyright (C) 2012,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ ### clapply uses lapply if X is a list and otherwise applies FUN directly to X. ### The result is always a list (of length 1 in the latter case). clapply <- function (X, FUN, ...) { if (is.list(X)) lapply(X, FUN, ...) else list(FUN(X, ...)) } surveillance/R/formatPval.R0000644000176200001440000000141613117532200015401 0ustar liggesusers################################################################################ ### Yet another P-value formatter, using R's format.pval() ### ### Copyright (C) 2013,2015,2017 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at http://www.r-project.org/Licenses/. ################################################################################ formatPval <- function (pv, eps = 1e-4, scientific = FALSE, ...) { format1 <- function (p) format.pval(p, digits = if (p < 10*eps) 1 else 2, eps = eps, nsmall = 2, scientific = scientific, ...) vapply(X = pv, FUN = format1, FUN.VALUE = "", USE.NAMES = TRUE) } surveillance/R/stcd.R0000644000176200001440000000411114013521730014220 0ustar liggesusers###################################################################### # Shiryaev-Roberts based spatio-temporal cluster detection based # on the work in Assuncao & Correa (2009). The implementation # is based on C++ code was originally written by Marcos Oliveira Prates, UFMG, # Brazil and provided by Thais Correa, UFMG, Brazil during her research # stay in Munich. This stay was financially supported by the Munich # Center of Health Sciences. # # # Parameters: # x - vector containing spatial x coordinate of the events # y - vector containing spatial y coordinate of the events # t - vector containing the time points of the events # radius - is the radius of the cluster # epsilon - is the relative change of event-intensity within the cluster # to detect # areaA - area of the observation region A (single number) # areaAcapBk - area of A \ B(s_k,\rho) for all k=1,\ldots,n (vector) # vector of areas A\B(s_k,\rho) for k=1,\ldots,n # threshold - threshold limit for the alarm and should be equal # to the desired ARL # cusum -- boolean if TRUE then CUSUM otherwise Shiryaev-Roberts ###################################################################### stcd <- function(x, y,t,radius,epsilon,areaA, areaAcapBk, threshold,cusum=FALSE) { #check that the vectors x,y,t are of the same length. n <- length(x) if ((length(y) != n) | (length(t) != n)) { stop("Vectors x,y,t not of same size.") } if (!all(diff(order(t)) == 1)) { stop("The vector of time points needs to be ascending in time. No ties allowed.") } res <- .C(C_SRspacetime, x=as.double(x), y=as.double(y), t=as.double(t), n=as.integer(n), radius=as.double(radius), epsilon=as.double(epsilon), areaA=as.double(areaA),areaAcapBk=as.double(areaAcapBk),cusum=as.integer(cusum), threshold=as.double(threshold),R=as.double(numeric(n)),idxFA=as.integer(-1),idxCC=as.integer(-1)) #Indexing differences between C and R res$idxFA <- res$idxFA+1 res$idxCC <- res$idxCC+1 #Missing: compute which indices are part of the cluster. #--> Thais R-code return(list(R=res$R,idxFA=res$idxFA,idxCC=res$idxCC)) } surveillance/R/hhh4_simulate_scores.R0000644000176200001440000000472314426171115017416 0ustar liggesusers################################################################################ ### Compute scores based on simulations from fitted hhh4() models ### ### Copyright (C) 2013-2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## logarithmic score ## CAVE: will be infinite if none of "sims" yields "x" logs_sims <- function (sims, x) .logs(px = mean(sims == x)) ## Dawid-Sebastiani score ## CAVE: undefined if all simulations have the same value (i.e., no variance) dss_sims <- function (sims, x) { if ((varsims <- var(sims)) == 0) { # FIXME: What to do in that case? warning("DSS undefined for zero variance of prediction: all(sims==", sims[1L], "), x=", x) NA_real_ # if (x==sims[1L]) -Inf else Inf } else { .dss(meanP = mean(sims), varP = varsims, x = x) } } ## ranked probability score rps_sims <- function (sims, x) { .rps(P = ecdf(sims), x = x, kmax = ceiling(mean(sims) + 40*sd(sims))) ## Two alternatives via the expectation-based definition of the RPS: ## method = "means": equivalent to ecdf approach but slower ## method = "means.MC": faster than ecdf but with approximation error ## simdiffs <- switch(method, ## "means.MC" = diff(sims), ## "means" = outer(sims, sims, "-")) ## mean(abs(sims - x)) - mean(abs(simdiffs)) / 2 } ## scores-method for simulations from a hhh4 fit scores.hhh4sims <- function (x, which = "rps", units = NULL, ..., drop = TRUE) { observed <- observed(attr(x, "stsObserved")) scoreFUNs <- mget(paste0(which, "_sims"), envir = getNamespace("surveillance"), inherits = FALSE) names(scoreFUNs) <- which if (!is.null(units)) { observed <- observed[, units, drop = FALSE] x <- x[, units, , drop = FALSE] } counts <- array(c(observed, x), dim = dim(x) + c(0L, 0L, 1L)) res <- lapply(X = scoreFUNs, FUN = function (scoreFUN) apply(counts, 1:2, function (y) scoreFUN(y[-1L], y[1L]))) res <- simplify2array(res, higher = TRUE) if (drop) drop(res) else res } ## scores-method for simulations from a bunch of hhh4 fits scores.hhh4simslist <- function (x, ...) lapply(X = x, FUN = scores.hhh4sims, ...) surveillance/R/untie.R0000644000176200001440000002047314426171115014426 0ustar liggesusers################################################################################ ### Spatial and temporal tie-breaking of events ### ### Copyright (C) 2012-2014,2018 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## epidataCS-method ## makes use of untie.default (in time) and untie.matrix (in space) untie.epidataCS <- function (x, amount = list(t=NULL, s=NULL), minsep = list(t=0, s=0), direction = "left", keep.sources = FALSE, ..., verbose = FALSE) { stopifnot(is.list(amount), !is.null(names(amount)), is.list(minsep), !is.null(names(minsep))) minsep <- modifyList(list(t=0, s=0), minsep) do.spatial <- pmatch("s", names(amount), nomatch=0L) > 0L do.temporal <- pmatch("t", names(amount), nomatch=0L) > 0L if (!do.spatial && !do.temporal) { stop("no amounts specified, nothing to do") } ## Generate new events data frame events <- marks.epidataCS(x, coords=FALSE) newcoords <- if (do.spatial) { # untie spatial coordinates untie.matrix(coordinates(x$events), amount$s, minsep$s, constraint=x$W, ...) } else coordinates(x$events) if (do.temporal) { # untie event times ## by default, we shift event times (non-symmetrically) to the left such ## that the shifted versions potentially stay in the same BLOCK of ## endemic covariates (the CIF is left-continuous). events$time <- untie.default(events$time, amount$t, minsep$t, direction=direction, sort=TRUE, ...) ## FIXME: Does sort=TRUE always make sense? ## maybe only sort in untie.default if amount < minsep? } ## Generate epidataCS object with new events coordinates(events) <- newcoords # -> SpatialPointsDataFrame #proj4string(events) <- proj4string(x$W) # "proj4string<-" might change the # string e.g. add +towgs84=0,0,0,0,0,0,0 events@proj4string <- x$W@proj4string npoly <- attr(x$events$.influenceRegion, "nCircle2Poly") clipper <- attr(x$events$.influenceRegion, "clipper") if (is.null(clipper)) # epidataCS < 1.8-1 clipper <- "polyclip" res <- as.epidataCS(events=events, stgrid=x$stgrid[,-1L], W=x$W, qmatrix=x$qmatrix, nCircle2Poly=npoly, clipper=clipper, verbose=verbose) if (keep.sources) { res$events$.sources <- x$events$.sources } if (do.temporal) { prehistevents <- function (x) row.names(x$events@data)[x$events$time <= x$stgrid$start[1L]] if (!setequal(prehistevents(x), prehistevents(res))) warning("temporal jittering has changed the set of prehistory events") } ## Done res } ## untie event times by uniform jittering untie.default <- function (x, amount = NULL, minsep = 0, direction = c("symmetric", "left", "right"), sort = NULL, giveup = 1000, ...) { stopifnot(is.numeric(x), is.vector(x)) distx <- dist(x) isPosDist <- distx > 0 if (all(isPosDist)) return(x) # no ties direction <- match.arg(direction) if (is.null(sort)) # sort if x was sorted sort <- identical(order(x, decreasing=FALSE), seq_along(x)) if (any(isPosDist)) { minsepx <- min(distx[isPosDist]) # smallest positive distance amount.bound <- if (direction=="symmetric") minsepx/2 else minsepx if (is.null(amount)) { amount <- amount.bound } else if (sort && abs(amount) > amount.bound) { warning("'amount' should not be greater than ", if (direction=="symmetric") "half of ", "the minimum separation (", format(amount.bound), ")") } } else if (is.null(amount)) { stop("default 'amount' does not work with completely tied 'x'") } shiftFUN <- switch(direction, symmetric = function (x) x + runif(length(x), -amount, amount), right = function (x) x + runif(length(x), 0, amount), left = function (x) x - runif(length(x), 0, amount)) res <- .untie(x, shiftFUN, minsep) if (sort) base::sort(res) else res } ## untie spatial coordinates by moving them by vectors drawn uniformly from a ## disc of radius 'amount', optionally respecting a region (constraint) ## inside which the jittered points should be located (of course, the initial ## points must also obey this constraint), and a minimum separation 'minsep' untie.matrix <- function (x, amount = NULL, minsep = 0, constraint = NULL, giveup = 1000, ...) { stopifnot(is.numeric(x), is.matrix(x)) dimx <- dim(x) if (dimx[2L] <= 1L) { untie.default(c(x), amount, minsep, giveup=giveup) } else if (dimx[2L] > 2L) { stop("spatial tie-breaking is only implemented for 2D coordinates") } if (is.null(amount)) { distx <- dist(x) isPosDist <- distx > 0 ## take half of smallest distance, which guarantees that new points ## will be closer to previously tied points than to others if (any(isPosDist)) amount <- min(distx[isPosDist]) / 2 else stop("default 'amount' does not work with a single location only") } if (!is.null(constraint)) { stopifnot(inherits(constraint, "SpatialPolygons")) constraint@proj4string <- new("CRS") outOfConstraint <- function (x) { is.na(over(SpatialPoints(x), constraint)) } if (any(outOfConstraint(x))) stop("some points of the matrix 'x' don't respect the 'constraint'") } else outOfConstraint <- NULL shiftFUN <- function (x) x + runifdisc(nrow(x), amount) .untie(x, shiftFUN, minsep, outOfConstraint, giveup=giveup) } ## workhorse for both vector and matrix 'x' .untie <- function (x, shiftFUN, minsep = 0, outOfConstraintFUN = NULL, giveup = 1000) { x <- res <- as.matrix(x) move <- rep.int(TRUE, nrow(x)) # initially move _all_ points ntry <- 0L updateMoveExpr <- .updateMoveExpr(minsep>0, is.function(outOfConstraintFUN)) while((nleft <- sum(move)) > 0L && ntry < giveup) { res[move,] <- shiftFUN(x[move,,drop=FALSE]) ## determine for the moved points if they are too close to another point ## or fall out of constraint -> try again eval(updateMoveExpr) ntry <- ntry + 1L } if (ntry >= giveup) warning("could not obey 'constraint' and/or 'minsep' for some points") if (ncol(res) == 1) res[,1] else res } ## check if points with index 'idx' are too close (< minsep) to any other points ## (this function could probably be made more efficient, especially for ## length(idx) << nrow(pts), since we actually don't need all pairwise distances ## calculated by dist() but only those related to the idx-points) .tooClose <- function (pts, idx, minsep) { distpts <- as.matrix(dist(pts)) diag(distpts) <- Inf rowSums(distpts[idx,,drop=FALSE] < minsep) > 0 } ## generate expression which updates logical vector 'move' (points left to move) .updateMoveExpr <- function(doClose = FALSE, doConstraint = FALSE) { if (!doClose && !doConstraint) return(expression(move[move] <- FALSE)) exprClose <- expression(movedTooClose <- .tooClose(res, move, minsep)) exprConstraint <- if (doClose) { # only need to check those not too close expression( movedOutOfConstraint <- rep.int(FALSE, nleft), if (any(!movedTooClose)) movedOutOfConstraint[!movedTooClose] <- outOfConstraintFUN(res[move,,drop=FALSE][!movedTooClose,,drop=FALSE]) ) } else { expression( movedOutOfConstraint <- outOfConstraintFUN(res[move,,drop=FALSE]) ) } c(if (doClose) exprClose, if (doConstraint) exprConstraint, switch(doClose + 2*doConstraint, expression(move[move] <- movedTooClose), expression(move[move] <- movedOutOfConstraint), expression(move[move] <- movedTooClose | movedOutOfConstraint) ) ) } surveillance/R/twinstim_iafplot.R0000644000176200001440000003063714426171115016701 0ustar liggesusers################################################################################ ### Plot estimated interaction kernel (siaf/tiaf) as a function of distance ### ### Copyright (C) 2012-2015 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ iafplot <- function (object, which = c("siaf", "tiaf"), types = NULL, scaled = c("intercept", "standardized", "no"), truncated = FALSE, log = "", conf.type = if (length(pars) > 1) "MC" else "parbounds", conf.level = 0.95, conf.B = 999, xgrid = 101, col.estimate = rainbow(length(types)), col.conf = col.estimate, alpha.B = 0.15, lwd = c(3,1), lty = c(1,2), verticals = FALSE, do.points = FALSE, add = FALSE, xlim = NULL, ylim = NULL, xlab = NULL, ylab = NULL, legend = !add && (length(types) > 1), ...) { if (isTRUE(verticals)) verticals <- list() if (isTRUE(do.points)) do.points <- list() if (add) log <- paste0("", if (par("xlog")) "x", if (par("ylog")) "y") scaled <- if (is.logical(scaled)) { # surveillance < 1.9-0 if (scaled) "intercept" else "no" } else { match.arg(scaled) } coefs <- coef(object) epiloglink <- .epilink(object) == "log" typeNames <- rownames(object$qmatrix) nTypes <- length(typeNames) ## interaction function which <- match.arg(which) IAFobj <- object$formula[[which]] if (is.null(IAFobj)) stop("the model has no epidemic component") IAF <- IAFobj[[if (which=="siaf") "f" else "g"]] if (which == "siaf") { # needs to be a function of distance IAF <- as.function( c(alist(x=, ...=), quote(f(cbind(x, 0), ...))), envir = list2env(list(f = IAF), parent = environment(IAF)) ) } isStepFun <- !is.null(knots <- attr(IAFobj, "knots")) && !is.null(maxRange <- attr(IAFobj, "maxRange")) ## interaction range if (isScalar(truncated)) { eps <- truncated truncated <- TRUE } else { eps <- attr(IAFobj, "eps") } if (is.null(eps)) { # cannot take eps into account (pre 1.8-0 behaviour) eps <- NA_real_ } else if (length(eps) > 1L && truncated) { message("no truncation due to heterogeneous interaction ranges, see \"rug\"") } epsIsFixed <- length(eps) == 1L && is.finite(eps) ## scaled interaction function if (scaled == "intercept") { idxgamma0 <- match("e.(Intercept)", names(coefs), nomatch = 0L) if (idxgamma0 == 0L) { message("no scaling due to missing epidemic intercept") scaled <- "no" } } else { # we do not use gamma0 -> 0-length selection idxgamma0 <- 0L } SCALE <- switch(scaled, "intercept" = if (epiloglink) quote(exp(gamma0)) else quote(gamma0), "standardized" = quote(1/IAF(0, iafpars, types)), "no" = 1 ) FUN <- function (x, iafpars, types, gamma0) { scale <- eval(SCALE) vals <- scale * IAF(x, iafpars, types) } ## truncate at eps if (truncated && epsIsFixed) { body(FUN) <- as.call(c(as.list(body(FUN)), expression( vals[x > eps] <- 0, vals ))) } ## if (loglog) { ## body(FUN)[[length(body(FUN))]] <- ## call("log", body(FUN)[[length(body(FUN))]]) ## } ## extract parameters gamma0 <- coefs[idxgamma0] idxiafpars <- grep(paste0("^e\\.",which), names(coefs)) iafpars <- coefs[idxiafpars] ## concatenate parameters idxpars <- c(idxgamma0, idxiafpars) pars <- c(gamma0, iafpars) ## type of confidence band force(conf.type) # per default depends on 'pars' if (length(pars) == 0 || is.null(conf.type) || is.na(conf.type)) { conf.type <- "none" } conf.type <- match.arg(conf.type, choices = c("parbounds", "bootstrap", "MC", "none")) if (conf.type == "bootstrap") conf.type <- "MC" # "bootstrap" was used <1.8 if (conf.type == "parbounds" && length(pars) > 1) { warning("'conf.type=\"parbounds\"' is only valid for a single parameter") } ## grid of x-values (t or ||s||) on which FUN will be evaluated if (is.null(xlim)) { xmax <- if (add) { xmax <- par("usr")[2] / (if (par("xaxs")=="r") 1.04 else 1) if (par("xlog")) 10^xmax else xmax } else { if (epsIsFixed) { eps } else if (isStepFun && maxRange < Inf) { maxRange } else if (which == "siaf") { sqrt(sum((object$bbox[,"max"] - object$bbox[,"min"])^2)) } else { diff(object$timeRange) } } xlim <- c(0.5*grepl("x", log), xmax) } xgrid <- if (isStepFun) { c(if (grepl("x", log)) { if (xlim[1L] < knots[1L]) xlim[1L] else NULL } else 0, knots[knots 1L && truncated) rug(eps) } ## store evaluated interaction function in a matrix (will be returned) typeNamesSel <- typeNames[types] res <- matrix(NA_real_, length(xgrid), 1L+length(types), dimnames = list(NULL, c("x", typeNamesSel))) res[,1L] <- xgrid for (i in seq_along(types)) { ## select parameters on which to evaluate iaf parSample <- switch(conf.type, parbounds = { cis <- confint(object, idxpars, level=conf.level) ## all combinations of parameter bounds do.call("expand.grid", as.data.frame(t(cis))) }, MC = { # Monte-Carlo confidence interval ## sample parameters from their asymptotic multivariate normal dist. rbind(pars, mvrnorm(conf.B, mu=pars, Sigma=vcov(object)[idxpars,idxpars,drop=FALSE]), deparse.level=0) }) ## add confidence limits if (!is.null(parSample)) { fvalsSample <- apply(parSample, 1, if (scaled == "intercept") { function (pars) FUN(xgrid, pars[-1L], types[i], pars[1L]) } else { function (pars) FUN(xgrid, pars, types[i]) }) if (length(xgrid) == 1L) # e.g., single-step function fvalsSample <- t(fvalsSample) # convert to matrix form lowerupper <- if (conf.type == "parbounds") { t(apply(fvalsSample, 1, range)) } else { # Monte-Carlo sample of parameter values if (is.na(conf.level)) { stopifnot(alpha.B >= 0, alpha.B <= 1) .col <- col2rgb(col.conf[i], alpha=TRUE)[,1] .col["alpha"] <- round(alpha.B*.col["alpha"]) .col <- do.call("rgb", args=c(as.list(.col), maxColorValue = 255)) matlines(x=xgrid, y=fvalsSample, type="l", lty=lty[2], col=.col, lwd=lwd[2]) # returns NULL } else { t(apply(fvalsSample, 1, quantile, probs=c(0,conf.level) + (1-conf.level)/2)) } } if (!is.null(lowerupper)) { attr(res, if(length(types)==1) "CI" else paste0("CI.",typeNamesSel[i])) <- lowerupper if (isStepFun) { segments(rep.int(xgrid,2L), lowerupper, rep.int(c(xgrid[-1L], min(maxRange, xlim[2L])), 2L), lowerupper, lty=lty[2], col=col.conf[i], lwd=lwd[2]) ##points(rep.int(xgrid,2L), lowerupper, pch=16, col=col.conf[i]) } else { matlines(x=xgrid, y=lowerupper, type="l", lty=lty[2], col=col.conf[i], lwd=lwd[2]) } } } ## add point estimate res[,1L+i] <- FUN(xgrid, iafpars, types[i], gamma0) if (isStepFun) { segments(xgrid, res[,1L+i], c(xgrid[-1L], min(maxRange, xlim[2L])), res[,1L+i], lty = lty[1], col = col.estimate[i], lwd = lwd[1]) ## add points if (is.list(do.points)) { pointStyle <- modifyList(list(pch=16, col=col.estimate[i]), do.points) do.call("points", c(list(xgrid, res[,1L+i]), pointStyle)) } ## add vertical connections: if (is.list(verticals)) { verticalStyle <- modifyList( list(lty = 3, col = col.estimate[i], lwd = lwd[1L]), verticals) do.call("segments", c( list(xgrid[-1L], res[-length(xgrid),1L+i], xgrid[-1L], res[-1L,1L+i]), verticalStyle)) } if (maxRange <= xlim[2L]) { ## add horizontal=0 afterwards segments(maxRange, 0, xlim[2L], 0, lty = lty[1], col = col.estimate[i], lwd = lwd[1]) if (is.list(verticals)) do.call("segments", c( list(maxRange, res[length(xgrid),1L+i], maxRange, 0), verticalStyle)) if (is.list(do.points)) do.call("points", c(list(maxRange, 0), pointStyle)) } } else { lines(x = xgrid, y = res[,1L+i], lty = lty[1], col = col.estimate[i], lwd = lwd[1]) } } ## add legend if (isTRUE(legend) || is.list(legend)) { default.legend <- list(x = "topright", legend = typeNamesSel, col = col.estimate, lty = lty[1], lwd = lwd[1], bty = "n", cex = 0.9, title="type") legend.args <- if (is.list(legend)) { modifyList(default.legend, legend) } else default.legend do.call("legend", legend.args) } ## Invisibly return interaction function evaluated on xgrid (by type) invisible(res) } surveillance/R/pit.R0000644000176200001440000001174114523166474014106 0ustar liggesusers################################################################################ ### Non-randomized version of the PIT histogram as discussed in: ### Predictive model assessment for count data ### Czado, C., Gneiting, T. & Held, L. (2009) ### Biometrics 65:1254-1261 ### ### Copyright (C) 2010-2012 Michaela Paul, 2013-2015,2017,2019,2023 Sebastian Meyer ### ### This file is part of the R package "surveillance", ### free software under the terms of the GNU General Public License, version 2, ### a copy of which is available at https://www.R-project.org/Licenses/. ################################################################################ ## x - observed count data ## pdistr - predictive CDF or a list of such predictive CDF's, ## one for each data point x. If evaluated at x=-1 it must return 0 ## J - number of bins ## ... - additional arguments for pdistr(), recycled to the length of x. ## Ignored if pdistr is a list. ## plot - a list of arguments for plot.histogram (otherwise no plot is produced) pit.default <- function (x, pdistr, J=10, relative=TRUE, ..., plot = list()) { PxPxm1 <- pitPxPxm1(x, pdistr, ...) Px <- PxPxm1[1L,] Pxm1 <- PxPxm1[2L,] if (any(Px == Pxm1)) { ## This means the predictive probability of an observed x is zero. ## Our predictive model is really bad if that happens. warning("predictive distribution has 0 probability for observed 'x'") } breaks <- (0:J)/J ## calculate \bar{F}(u) for scalar u Fbar1 <- function (u, Px, Pxm1) { F_u <- punif(u, Pxm1, Px) # also works for Pxm1 == Px => F_u = u >= Pxm1 mean(F_u) } Fbar_seq <- vapply(X = breaks, FUN = Fbar1, FUN.VALUE = 0, Px = Px, Pxm1 = Pxm1, USE.NAMES = FALSE) scale <- if (relative) J else 1 f_j <- scale * diff.default(Fbar_seq) res <- list(breaks = breaks, counts = rep(NA_integer_, J), density = f_j, mids = breaks[-(J+1)] + 1/J/2, xname = "PIT", equidist = TRUE) class(res) <- c("pit", "histogram") if (is.list(plot)) do.call("plot", c(list(x = res), plot)) else res } pitPxPxm1 <- function (x, pdistr, ...) { if (is.list(pdistr)) { # list of functions, not necessarily vectorized stopifnot(length(pdistr) == length(x)) vapply(X = seq_along(x), FUN = function (i) { stopifnot(isTRUE( all.equal.numeric(0, pdistr[[i]](-1), check.attributes = FALSE) )) c(pdistr[[i]](x[i]), pdistr[[i]](x[i]-1)) }, FUN.VALUE = c(0,0), USE.NAMES = FALSE) # 2 x length(x) } else { # pdistr is (the name of) a function pdistr <- match.fun(pdistr) if (nargs() == 2L) { # no dots, same pdistr for every data point # and assumed to be vectorized stopifnot(isTRUE(all.equal.numeric(0, pdistr(-1)))) rbind(pdistr(x), pdistr(x-1), deparse.level = 0) } else { # ... arguments for pdistr, recycled to the length of x # pdistr is called by mapply, so no need to be vectorized stopifnot(isTRUE(all.equal.numeric( 0, do.call("pdistr", c(list(-1), lapply(list(...), "[", 1L))), check.attributes = FALSE))) rbind(mapply(pdistr, x, ..., SIMPLIFY = TRUE, USE.NAMES = FALSE), mapply(pdistr, x-1, ..., SIMPLIFY = TRUE, USE.NAMES = FALSE), deparse.level = 0) } } } ## plot the PIT histogram plot.pit <- function (x, main = "", ylab = NULL, freq = FALSE, ...) { if (freq) warning("'freq' is ignored") # we have no counts relative <- isTRUE(all.equal(1, sum(x$density))) if (is.null(ylab)) ylab <- if (relative) "Relative Frequency" else "Density" ## call plot.histogram NextMethod("plot", main = main, ylab = ylab, freq = FALSE, ...) ## add reference line abline(h = if (relative) 1/length(x$mids) else 1, lty = 2, col = "grey") invisible(x) } ## a convenient wrapper for Poisson and NegBin predictions .pit <- function (x, mu, size = NULL, ...) { if (is.null(size)) { pit.default(x = x, pdistr = "ppois", lambda = mu, ...) } else { pit.default(x = x, pdistr = "pnbinom", mu = mu, size = size, ...) } } ## pit-methods for oneStepAhead() predictions and "hhh4" fits ## (similar to the scores-methods) pit.oneStepAhead <- function (x, units = NULL, ...) { if (is.null(units)) { .pit(x = x$observed, mu = x$pred, size = psi2size.oneStepAhead(x), ...) } else { .pit(x = x$observed[, units, drop = FALSE], mu = x$pred[, units, drop = FALSE], size = psi2size.oneStepAhead(x)[, units, drop = FALSE], ...) } } pit.hhh4 <- function (x, subset = x$control$subset, units = seq_len(x$nUnit), ...) { .pit(x = x$stsObj@observed[subset, units, drop = FALSE], mu = x$fitted.values[match(subset, x$control$subset), units, drop = FALSE], size = psi2size.hhh4(x, subset, units), ...) } surveillance/NEWS.md0000644000176200001440000030700014615162374014055 0ustar liggesusers# surveillance 1.23.0 (2024-05-03) ## New Features - `update.epidataCS()` gained an argument `stgrid` to update the spatio-temporal grid data in an existing `"epidataCS"` object. This enables updates/transformations of endemic variables and/or changes of the time intervals without needing to do `as.epidataCS()` from scratch. ## Bug Fixes - Start values for endemic intercepts in `twinstim()` are now robust against non-finite values in offset terms. - `intensityplot.twinstim(aggregate = "space")` no longer fails for endemic-only fits. # surveillance 1.22.1 (2023-11-27) - The `pit()` plot could lack some tick marks on the y-axis (for R >= 4.2.0). # surveillance 1.22.0 (2023-10-30) ## Package Infrastructure - Legacy functions `unionSpatialPolygons()` and `polyAtBorder()` now use **sf** in place of **rgeos**. ## Deprecated & Defunct - Long unused methods for `"gpc.poly"` objects (from package **gpclib**) have now been removed and `surveillance.options("gpclib")` is obsolete. - Package **rgeos** is no longer available as a `clipper` method for `as.epidataCS()`. The previous default **polyclip** remains as the only option. # surveillance 1.21.1 (2023-05-16) - This is a maintenance release, fixing encoding-related portability issues and increasing test coverage for rarely used functionality. # surveillance 1.21.0 (2023-03-14) ## Minor Changes - `nbOrder()` has been re-implemented: it is now more efficient and no longer depends on **spdep**. Furthermore, it now defaults to `maxlag = Inf`; the historical default `maxlag = 1` was barely useful. It no longer messages (about the range of the detected orders). - Printing `"sts"` objects with a map now shows the first row of the attached data (if present) instead of the object summary. ## Package Infrastructure - Accommodate the current evolution of **sp**: **sf** is suggested and some examples are now conditionalized on its availability. ## Deprecated & Defunct - **surveillance** no longer relies on the **maptools** package: `unionSpatialPolygons()` with `method = "gpclib"` is deprecated and now uses the default method with a warning. - Long unused `scale.gpc.poly()` and `inside.gpc.poly()` are deprecated; the unused and undocumented `diameter.gpc.poly()` method has been removed. - `stsplot_spacetime()` is formally deprecated; it has long been superseded by `stsplot_space()` and an `animate()` method for `"sts"` objects. # surveillance 1.20.3 (2022-11-14) - `vignette("monitoringCounts")` now uses **knitr** as its engine to work around [Bug 18318](https://bugs.R-project.org/show_bug.cgi?id=18318). # surveillance 1.20.2 (2022-10-31) ## New Features - `plotHHH4_fitted()` can now produce simple (unformatted) time indexes if argument `xaxis = NA`. ## Minor Changes - Various documentation improvements, including an example for `predict.hhh4()`. - `intensityplot.twinstim()` no longer depends on package [**maptools**](https://CRAN.R-project.org/package=maptools). ## Bug Fixes - `hhh4()` now warns about interaction terms in model formulae. These are not implemented and were silently ignored previously. - Fixed a memory leak in `algo.twins()`; note that this old experimental MCMC implementation for a two-component epidemic model may be removed in future versions of the package. # surveillance 1.20.1 (2022-07-13) ## Bug Fixes - `ks.plot.unif()`: accommodate to `NO_S_TYPEDEFS` in R >= 4.3.0. - `boda()` with `samplingMethod="marginals"` gave all-`NA` upperbounds in INLA >= 21.07.10. `boda()` now also works around a scoping issue (with `E`) in recent versions of INLA that led to wrongly scaled upperbounds. # surveillance 1.20.0 (2022-02-15) ## New Features - `plotHHH4_season()` gained a `period` argument to support harmonics with periods longer than the frequency of the `"sts"` object. - `stsplot_space()` now supports passing a `col` argument to `spplot()` to change the colour of the polygon lines. - `plotHHH4_fitted()` can now handle time series with missing values. ## Minor Changes - If the Nelder-Mead optimizer is used for the variance parameters in `hhh4()`, it is now limited to 500 (not 300) iterations by default (consistent with the default in `optim()`). - Printing an `"sts"` object now omits the `neighbourhood` component if that was not set (all-`NA` prototype). - `simulate.hhh4(..., simplify = TRUE)` now consistently returns a 3d array (nTime x nUnit x nsim), even for `nsim = 1` (for which plotting now works). - The default legend in `stsplot_time1()` now only includes plotted elements. - `wrap.algo()` no longer prints progress when there is only one area. - `summary.hhh4()` now prints the number of excluded observations (due to missingness), if any. ## Bug Fixes - The `print`-method for `summary.hhh4()` did not apply the `digits` argument to the coefficient matrix. Furthermore, printing of estimated variance parameters now adheres to *significant* `digits` as documented. - The `[`-method for the `"hhh4sims"` class was not registered and thus only available internally. Array-like subsetting of simulated counts now retains the class. - `farringtonFlexible()` with activated `populationOffset` (non-default) always used the population data of the *first* time series in the fitting step while iterating over a multivariate `"sts"` object. - `plotHHH4_ri(..., exp = TRUE)` failed to use a log-scale color axis if further `colorkey` options were passed in a list. The (default) color breaks could fail to span the range of the data without warning (resulting in unfilled polygons). This is now checked and the default breaks are now equally spaced on the log-scale. - `stsplot_time1()` did not pass `lty` to `polygon()` and `lwd` to `legend()`. - `rps()` was wrong for distributions close to a point mass at zero, e.g., for `mu = 1e-3` and `x >= 4`. It is now also protected against wide (quasi-continuous) NegBin distributions that would consume too much memory with discrete RPS calculation (returning a missing value with a warning). [both issues spotted by F. Rousseu] - Plots of legacy `"disProg"` and `"survRes"` objects are now generated via internal `disProg2sts()` conversion and `stsplot_time()`. This fixes their x-axis labels for the default `xaxis.years=TRUE`. The obsolete arguments `startyear` and `firstweek` are now ignored with a warning. - The default legend of `stsplot_time1()` did not show the fill color in the non-default case `!is.na(col[1])`. - Multivariate `hhh4()` with neighbourhood component treated `NA` counts as zero when calculating the weighted sum over units. A missing count at *t-1* in any unit now gives `NA` values for the neighbourhood terms of all units at time *t*, thus reducing `nobs()`. ## Deprecated & Defunct - `create.disProg()` is deprecated. Methods for legacy `"disProg"` objects are kept for backwards compatibility, but new projects should use `sts()`. - The long-deprecated `qlomax()` implementation has been removed. # surveillance 1.19.1 (2021-03-30) ## Documentation - The project website at has been overhauled using [**pkgdown**](https://pkgdown.r-lib.org/). ## Bug Fixes - The `CRS` of `data(imdepi)` and `data(measlesWeserEms)` have been updated via `sp`'s `rebuild_CRS()` to avoid warnings when **rgdal** is loaded with new PROJ and GDAL libraries. - `simEpidataCS()` now internally resets the CRS (temporary), which avoids spurious warnings and also reduces its runtime by about 25%. - Fix encoding error in `vignette("twinstim")` for CRAN's non-UTF8 Linux test machine. - This version of **surveillance** (formally) requires the new [**spatstat**](https://CRAN.R-project.org/package=spatstat) umbrella package to avoid collisions of old **spatstat** and its new sub-packages (we only use [**spatstat.geom**](https://CRAN.R-project.org/package=spatstat.geom)). The **spatstat** dependence will be dropped in the future. - The `epoch<-` replacement method for `"sts"` objects now accepts a `"Date"` vector. The standard plots may give nicer x-axis annotation if indexed by dates. See the `xaxis.*` arguments of `stsplot_time()`. - `tidy.sts()` (and thus `autoplot.sts()`) failed for date-indexed `"sts"` objects with non-standard frequencies. [spotted by Junyi Lu] # surveillance 1.19.0 (2021-01-29) ## New Features - The `nowcast()` function with `method="bayes.trunc.ddcp"` now adds support for negative binomial response distribution instead of Poisson. Furthermore, additional components of the design matrix for the discrete time survival model can be provided, which allows the inclusion of, e.g., day of the week effects. Finally, the order of the polynomial created by the change-points in the discrete time survival model can now be specified. For further details see the work of Guenther et al. (2020) about nowcasting the Covid-19 outbreak in Bavaria, Germany. - `animate.sts()` can position the `timeplot` on other sides of the map. ## Minor Changes - The weighted sum in the `ne`ighbourhood component of `hhh4()` models is computed more efficiently. - `simEpidataCS()` (and thus `simulate.twinstim()`) uses a slightly more efficient location sampler for models with `siaf = siaf.constant()`. Simulation results will differ from previous package versions even if the same random `seed` is used. - The default `main` title for `stsplot_space()` now uses the ISO year-week format for weekly `"sts"` data. ## Bug Fixes - Bug fix in the `farringtonFlexible()`-function, which for the argument `thresholdMethod=="nbPlugin"` and `thresholdMethod=="muan"` unfortunately computed the limit as an `(1-alpha/2)` prediction interval instead of the documented `(1-alpha)` prediction interval. This affects four threshold values in Table 2 of `vignette("monitoringCounts")`. The default method `"delta"` worked as expected. - In `hhh4()` models without AR component, the matrix of fitted values could lack column names. - Experimental time-varying neighbourhood weights in `hhh4()` were indexed differently in model fitting and in the `simulate()` method (undocumented behaviour). Both now use the latter variant, where the mean at time *t* uses products of weights at time *t* and observed counts at time *t-1*. [reported by Johannes Bracher] - For weekly `sts` indexed via `start` and `freq=52`, `epoch(sts, as.Date=TRUE)` now interprets the `start` week according to ISO 8601. For example, `start = c(2020, 5)` corresponds to 2020-01-27, not 2020-02-03. This affects `as.xts.sts()` and the time plot in `animate.sts()`. - `stsplot_space()` automatically extends manual color breaks (`at`), if the intervals do not cover the data range. - `simEndemicEvents()` and thus `epitest(..., method="simulate")` are no longer slowed down by intermediate `CRS()` computations. ## Package Infrastructure - Removed unused **rmapshaper** from "Suggests" and moved **xts** to "Enhances" (used only for `as.xts.sts`). - Switched testing framework from (nowadays heavy) **testthat** to [**tinytest**](https://CRAN.R-project.org/package=tinytest). Together with moving **ggplot2** to "Enhances" (used only for `autoplot.sts`) --- and only then --- this switch further reduces the total number of required packages for a complete check (i.e., installing with `dependencies = TRUE`) in a *factory-fresh* R environment from 119 to 94. - [**spatstat**](https://CRAN.R-project.org/package=spatstat) was split into several sub-packages, of which we only need to import [**spatstat.geom**](https://CRAN.R-project.org/package=spatstat.geom). This new package requires `R >= 3.5.0`, though. - **surveillance** now requires `R >= 3.6.0`. # surveillance 1.18.0 (2020-03-18) ## New Features - New spatial interaction function for `twinstim()`: `siaf.exponential()` implements the exponential kernel *f(x) = exp(-x/σ)*, which is a useful alternative if the two-parameter power-law kernel is not identifiable. - The `plot`-type `"maps"` for `"hhh4"` fits, `plotHHH4_maps()`, now allows for map-specific color keys via `zmax = NA` (useful for `prop = TRUE`). ## Bug Fixes - The `nowcast()`-function now also works for `method="bayes.trunc.ddcp"` method when the number of breakpoints is greater than 1. - The `amplitudeShift` transformation for sine-cosine coefficient pairs in the `summary` of multivariate `"hhh4"` models was incorrect in the rare case that the model used unit-specific seasonal terms (`addSeason2formula` with `length(S) > 1`). ## Deprecated & Defunct - The original `algo.hhh()` implementation of the HHH model has been removed from the package. The function `hhh4()` provides an improved and much extended implementation since 2012. # surveillance 1.17.3 (2019-12-16) ## Bug Fixes - The `head()`-method for `"epidataCS"` objects did not work with a negative `n` argument. - Fix for `"matrix"` changes in R-devel. # surveillance 1.17.2 (2019-11-11) ## Minor Changes - For multivariate time series, `sts()` now checks for mismatches in column names of supplied matrices (`observed`, `population`, `neighbourhood`, ...). This is to catch input where the units (columns) are ordered differently in different slots, which would flaw subsequent analyses. ## Bug Fixes - `simulate.twinSIR()` ignored the `atRiskY` indicator of the underlying `"epidata"`, so always assumed a completely susceptible population. Initially infectious individuals are now inherited. For the previous behaviour, adjust the supplied `data` via `data$atRiskY <- 1`. # surveillance 1.17.1 (2019-09-13) ## New Features - New one-parameter power-law kernel `siaf.powerlaw1()` with fixed `sigma = 1`. Useful if `sigma` is difficult to estimate with `siaf.powerlaw()`. ## Bug Fixes - `pit()`'s default `ylab` was wrong (default are densities not relative frequencies). - `R0()` for `"twinstim"` fits with specified `newevents` now handles levels of epidemic factor variables automatically via the new `xlevels` attribute stored in the fitted model. - Some S3 methods for the `"sts"` class are now formally registered and identical to the established S4 methods. - Minor additions and fixes in the package documentation. ## Deprecated & Defunct - `hcl.colors()`, exported since 1.14.0, has been renamed `.hcl.colors()` and is now internal again, to avoid a name clash with R's own such function introduced in R 3.6.0. # surveillance 1.17.0 (2019-02-22) ## New Features - `W_powerlaw(..., from0 = TRUE)` enables more parsimonious `hhh4` models in that the power-law weights are modified to include the autoregressive (0-distance) case (see `vignette("hhh4_spacetime")`). The unstructured distance weights `W_np()` gained `from0` support as well. - `sts()` creation can now handle `epoch` arguments of class `Date` directly. - The `ranef()`-method for `"hhh4"` fits gained a logical argument `intercept` to extract the unit-specific intercepts of the log-linear predictors instead of the default zero-mean deviations around the fixed intercepts. The corresponding `plot` method (`type="ri"`) gained an argument `exp`: if set to `TRUE` random effects are `exp`-transformed and thus show multiplicative effects. [based on feedback by Tim Pollington] ## Minor Changes - `W_np()`'s argument `to0` has been renamed to `truncate`. The old name still works but is deprecated. - `plotHHH4_ri()` now uses `cm.colors(100)` as `col.regions`, and 0-centered color breaks by default. - The help pages of `twinSIR()` and related functions now give examples based on `data("hagelloch")` instead of using the toy dataset `data("fooepidata")`. The latter is now obsolete and will be removed in future versions of the package. - The elements of the `control` list stored in the result of `algo.farrington()` are now consistently ordered as in the default `control` argument. ## Bug Fixes - Using negative indices to exclude time points from an `"sts"` object (e.g., `x[-1,]`) is now supported and equivalent to the corresponding subset expression of retained indexes (`x[2:nrow(x),]`) in resetting the `start` and `epoch` slots. [reported by Johannes Bracher] - For weekly `"sts"` data with `epochAsDate=TRUE`, the `as.data.frame()` method computed `freq` by `"%Y"`-year instead of by `"%G"`-year, which was inconsistent with the `epochInPeriod` variable. - For *non*-weekly `"sts"` data with `epochAsDate=TRUE`, `year()` as well as the `year` column of the `tidy.sts()` output corresponded to the ISO week-based year. It now gives the calendar year. - `sts_creation()` hard-coded `start = c(2006, 1)`. - `aggregate()`ing an `"sts"` object over time now recomputes fractions from the cumulated population values if and only if this is no `multinomialTS` and already contains population fractions. The same rule holds when subsetting units of an `"sts"` object. The `aggregate`-method previously failed to recompute fractions in some cases. - For `farringtonFlexible()` with multivariate time series, only the last unit had stored the additional control items (exceedence scores, p-values, ...), all others were 0. [reported by Johannes Bracher] - The supplementary p-values returned by `farringtonFlexible()` in `control$pvalue` were wrong for the default approach, where `thresholdMethod="delta"` (the original Farrington method) and a power transformation was applied to the data (`powertrans != "none"`). Similarly, `algo.farrington()` returned wrong predictive probabilities in `control$pd[,1]` if a power transformation was used. [reported by Lore Merdrignac] - The `control` argument list of `algo.farrington()` as stated in the formal function definition was incomplete (`plot` was missing) and partially out of sync with the default values that were actually set inside the function (`b=5` and `alpha=0.05`). This has been fixed. Results of `algo.farrington()` would only be affected if the function was called without any `control` options (which is hardly possible). So this can be regarded as a documentation error. The formal `control` list of the `farrington()` wrapper function has been adjusted accordingly. - The `control` argument lists of `farringtonFlexible()` and `bodaDelay()` as stated in the formal function definitions were partially out of sync with respect to the following default values that were actually set inside these functions: `b=5` (not 3), `alpha=0.05` (not 0.01), `pastWeeksNotIncluded=w` (not 26), and, for `bodaDelay()` only, `delay=FALSE` (not `TRUE`). This has been fixed. Results would only be affected if the functions were called without any `control` options (which is hardly possible). So this can be regarded as a documentation error. - `pairedbinCUSUM()` did not properly subset the `sts` object if a `range` was specified, and forgot to store the `control` arguments in the result. - `wrap.algo()` now aborts if the monitored range is not supplied as a numeric vector. - In `vignette("monitoringCounts")`: several inconsistencies between code and output have been fixed. - `epidataCS2sts()` no longer transfers the `stgrid$BLOCK` indices to the `epoch` slot of the resulting `"sts"` object (to avoid `epoch[1] != 1` scenarios). - The `ranef()` matrix extracted from fitted `"hhh4"` models could have wrong column names. ## Deprecated & Defunct - Several ancient functions deprecated in 1.16.1 are now defunct: `compMatrix.writeTable()`, `makePlot()`, `test()`, `testSim()`, `readData()` (the raw txt files have been removed as well), `correct53to52()`, `enlargeData()`, `toFileDisProg()`. # surveillance 1.16.2 (2018-07-24) ## Minor Changes - `autoplot.sts()` gained a `width` argument to adjust the bar width, which now defaults to 7 for weekly time series (previously was 90% of that so there were gaps between the bars). - `"epidataCS"` generation now (again) employs [**spatstat**](https://CRAN.R-project.org/package=spatstat)'s `bdist.points()`, which has been accelerated in version 1.56-0. If you use the `twinstim()`-related modelling part of **surveillance**, you are thus advised to update your **spatstat** installation. - The `boda()` examples in `vignette("monitoringCounts")` have been updated to also work with recent versions of **INLA**. ## Bug Fixes - Offsets in `hhh4`'s epidemic components were ignored by `simulate.hhh4()` [spotted by Johannes Bracher] as well as in dominant eigenvalues ("maxEV"). - The color key in `fanplot()` is no longer distorted by `log="y"`. # surveillance 1.16.1 (2018-05-28) ## Bug Fixes - `autoplot.sts()` now sets the calling environment as the `plot_env` of the result. - Several `twinstim`-related functions finally allow for prehistory events (long supported by `twinstim()` itself): `as.epidataCS()`, `glm_epidataCS()`, `as.epidata.epidataCS()`. - The `summary()` for SI[R]S-type `"epidata"` failed if there were initially infectious individuals. ## Deprecated & Defunct - Several ancient functions have been deprecated and may be removed in future versions of **surveillance**: `qlomax()`, `readData()`, `toFileDisProg()`, `correct53to52()`, `enlargeData()`, `compMatrix.writeTable()`, `test()`, `testSim()`, `makePlot()`. # surveillance 1.16.0 (2018-01-24) ## New Features - The `as.data.frame()` method for `"sts"` objects gained a `tidy` argument, which enables conversion to the long data format and is also available as function `tidy.sts()`. - A [**ggplot2**](https://CRAN.R-project.org/package=ggplot2) variant of `stsplot_time()` is now available via `autoplot.sts()`. - `as.epidata.data.frame()` gained an argument `max.time` to specify the end of the observation period (which by default coincides with the last observed event). - The now exported function `fanplot()` wraps [**fanplot**](https://CRAN.R-project.org/package=fanplot)`::fan()`. It is used by `plot.oneStepAhead()` and `plot.hhh4sims()`, which now have an option to add the point forecasts to the fan as well. - `plotHHH4_fitted()` (and `plotHHH4_fitted1()`) gained an option `total` to sum the fitted components over all units. ## Significant Changes - Package [**polyCub**](https://CRAN.R-project.org/package=polyCub) is no longer automatically attached (only imported). - `scores.oneStepAhead()` no longer reverses the ordering of the time points by default, as announced in 1.15.0. ## Minor Changes - Some code in `vignette("monitoringCounts")` has been adjusted to work with the new version of [**MGLM**](https://CRAN.R-project.org/package=MGLM) (0.0.9). - Added a `[`-method for the `"hhh4sims"` class to retain the attributes when subsetting simulations. ## Bug Fixes - `aggregate(stsObj, by = "unit")` no longer results in empty colnames (set to `"overall"`). The obsolete map is dropped. - The `subset` argument of `twinSIR()` was partially ignored: - If `nIntervals = 1`, the model `summary()` reported the total number of events. - Automatic `knots`, model `residuals()`, as well as the rug in `intensityplot()` were computed from the whole set of event times. - The `as.epidata.data.frame()` converter did not actually allow for latent periods (via `tE.col`). This is now possible but considered experimental (methods for `"epidata"` currently ignore latent periods). - The `all.equal()` methods for `"hhh4"` and `"twinstim"` objects now first check for the correct classes. # surveillance 1.15.0 (2017-10-06) ## New Features - `siaf.gaussian()` now also employs a `polyCub.iso()` integration routine by default (similar to the powerlaw-type kernels), instead of adaptive midpoint cubature. This increases precision and considerably accelerates estimation of `twinstim()` models with a Gaussian spatial interaction function. Models fitted with the new default (`F.adaptive=FALSE, F.method="iso"`) will likely differ from previous fits (`F.adaptive=TRUE`), and the numerical difference depends on the adaptive bandwidth used before (the default `adapt=0.1` yielded a rather rough approximation of the integral). - Added `quantile()`, `confint()`, and `plot()` methods for `"oneStepAhead"` predictions. - Exported the function `simEndemicEvents()` to simulate a spatio-temporal point pattern from an endemic-only `"twinstim"`; faster than via the general `simulate.twinstim()` method. ## Minor Changes - `twinstim(..., siaf = siaf.gaussian())` uses a larger default initial value for the kernel's standard deviation (based on the size of the observation region). - Non-default parametrizations of `siaf.gaussian()` are deprecated, i.e., always use `logsd=TRUE` and `density=FALSE`. - `twinstim()` uses a smaller default initial value for the epidemic intercept, which usually allows for faster convergence. - `update.hhh4()` now allows `subset.upper` values beyond the originally fitted time range (but still within the time range of the underlying `"sts"` object). - `scores.oneStepAhead()` by default reverses the ordering of the time points. This awkward behaviour will change in the next version, so the method now warns if the default `reverse=TRUE` is used without explicit specification. - Minor improvements in the documentation and some vignettes: corrected typos, simplified example code, documented some methods. ## Bug Fixes - The C-routines introduced in version 1.14.0 used `==` comparisons on parameter values to choose among case-specific formulae (e.g., for *d==2* in `siaf.powerlaw()`). We now employ an absolute tolerance of 1e-7 (which should fix the failing tests on Solaris). - Interaction functions for `twinstim()`, such as `siaf.powerlaw()` or `tiaf.exponential()`, no longer live in the global environment as this risks using masked base functions. # surveillance 1.14.0 (2017-06-29) ## Documentation - The replication code from Meyer et al. (2017, JSS) is now included as `demo("v77i11")`. It exemplifies the spatio-temporal endemic-epidemic modelling frameworks `twinstim`, `twinSIR`, and `hhh4` (see also the corresponding vignettes). ## New Features - Pure C-implementations of integration routines for spatial interaction functions considerably accelerate the estimation of `twinstim()` models containing `siaf.powerlaw()`, `siaf.powerlawL()`, or `siaf.student()`. - The color palette generating function used by `sts` plots, `hcl.colors`, is now exported. - The utility function `clapply` (*c*onditional `lapply`) is now exported. - Some utility functions for `hhh4` fits are now exported (`update.hhh4`, `getNEweights`, `coefW`), as well as several internal functions for use by `hhh4` add-on packages (`meanHHH`, `sizeHHH`, `decompose.hhh4`). - The `"fan"`-type plot function for `"hhh4sims"` gained a `key.args` argument for an automatic color key. - New auxiliary function `makeControl()`, which may be used to specify a `hhh4()` model. ## Minor Changes - `twinstim()` now throws an informative error message when trying to fit a purely epidemic model to data containing endemic events (i.e., events without ancestors). The `help("twinstim")` exemplifies such a model. ## Bug Fixes - `siaf.powerlaw()$deriv` returned `NaN` for the partial derivative wrt the decay parameter *d*, if *d* was large enough for *f* to be numerically equal to 0. It will now return 0 in this case. - `twinstim()` could fail (with an error from `duplicated.default`) if the fitted time range was substantially reduced via the `T` argument. - The `"simEpidataCSlist"` generated by `simulate.twinstim(..., simplify = TRUE)` was missing the elements `bbox` and `control.siaf`. # surveillance 1.13.1 (2017-04-28) ## Documentation - The paper on "Spatio-Temporal Analysis of Epidemic Phenomena Using the R Package **surveillance**" (by Sebastian Meyer, Leonhard Held, and Michael Höhle) will appear in the upcoming volume of the *Journal of Statistical Software*. The main sections 3 to 5 of the paper are contained in the package as `vignette("twinstim")`, `vignette("twinSIR")`, and `vignette("hhh4_spacetime")`, respectively. ## New Features - The `calibrationTest()` and `pit()` methods for `"oneStepAhead"` forecasts gained an argument `units` to allow for unit-specific assessments. - A default `scores`-method is now available to compute a set of proper scoring rules for Poisson or NegBin predictions. - New plot `type = "fan"` for simulations from `"hhh4"` models to produce a fan chart using the [**fanplot**](https://CRAN.R-project.org/package=fanplot) package. ## Minor Changes - `scores.hhh4()` sets rownames for consistency with `scores.oneStepAhead()`. ## Bug Fixes - The `"Lambda.const"` matrix returned by `getMaxEV_season()` was wrong for models with asymmetric neighbourhood weights. [spotted by Johannes Bracher]\ Dominant eigenvalues (`"maxEV"`) were not affected by this bug. # surveillance 1.13.0 (2016-12-20) ## New Features - `earsC` now has two new arguments thanks to Howard Burkom: the number of past time units to be used in calculation is now not always 7, it can be chosen in the `baseline` parameter. Furthermore, the `minSigma` parameter allows to get a threshold in the case of sparse data. When one doesn't give any value for those two parameters, the algorithm works like it used to. - `animate.sts()` gained support for date labels in the bottom `timeplot`. - `stsplot_space()` and `animate.sts()` can now generate incidence maps based on the population information stored in the supplied `"sts"` object. Furthermore, `animate.sts()` now supports time-varying population numbers. ## Minor Changes - `hhh4()` guards against the misuse of `family = factor("Poisson")` for univariate time series. Previously, this resulted in a negative binomial model by definition, but is now interpreted as `family = "Poisson"` (with a warning). ## Bug Fixes - `animate.sts()` now supports objects with missing values (with a warning). Furthermore, the automatic color breaks have been improved for incidence maps, also in `stsplot_space()`. - The `as.data.frame`-method for the `"sts"` class, applied to classical time-index-based `"sts"` objects (`epochAsDate=FALSE`), ignored a `start` epoch different from 1 when computing the `epochInPeriod` indexes. Furthermore, the returned `epochInPeriod` now is a fraction of `freq`, for consistency with the result for objects with `epochAsDate=TRUE`. - `simulate.hhh4()` did not handle shared overdispersion parameters correctly. The different parameters were simply recycled to the number of units, ignoring the factor specification from the model's `family`. [spotted by Johannes Bracher] - Simulations from *endemic-only* `"hhh4"` models with unit-specific overdispersion parameters used wrong variances. [spotted by Johannes Bracher] - `oneStepAhead()` predictions of `type` `"rolling"` (or `"first"`) were incorrect for time points `tp` (`tp[1]`) beyond the originally fitted time range (in that they were based on the original time range only). This usage of `oneStepAhead()` was never really supported and is now caught when checking the `tp` argument. - `plot.hhh4simslist()` ignored its `par.settings` argument if `groups=NULL` (default). # surveillance 1.12.2 (2016-11-14) ## New Features - The internal auxiliary function, which determines the sets of potential source events in `"epidataCS"` has been implemented in C++, which accelerates `as.epidataCS()`, `permute.epidataCS()`, and therefore `epitest()`. This is only really relevant for `"epidataCS"` with a large number of events (>1000, say). - Negative-binomial `hhh4()` models may not converge for non-overdispersed data (try, e.g., `set.seed(1); hhh4(sts(rpois(104, 10)), list(family="NegBin1"))`). The resulting non-convergence warning message now mentions low overdispersion if this is detected. [suggested by Johannes Bracher] - An additional `type="delay"` option was added to the `plot` method of `stsNC` objects. Furthermore, an `animate_nowcasts` function allows one to animate a sequence of nowcasts. ## Minor Changes - In the `animate`-method for `"sts"` objects, the default top padding of **lattice** plots is now disabled for the bottom `timeplot` to reduce the space between the panels. Furthermore, the new option `fill` can be used to make the panel of the `timeplot` as large as possible. ## Bug Fixes - `bodaDelay()`: fixed spurious warnings from `rnbinom()`. - `vignette("monitoringCounts")`: fixed `boda`-related code and cache to obtain same results as in corresponding JSS paper. # surveillance 1.12.1 (2016-05-18) ## Documentation - The new `vignette("monitoringCounts")` illustrates the monitoring of count time series in R with a particular focus on aberration detection in public health surveillance. This vignette corresponds to a recently accepted manuscript for the *Journal of Statistical Software* (Salmon, Schumacher, and Höhle, 2016). ## Minor Changes - Non-convergent `hhh4()` fits now obey the structure of standard `"hhh4"` objects. In particular, such fits now also contain the `control` and `stsObj` elements, allowing for model `update()`s of non-convergent fits. - `knox()` warns about symmetric input matrices. ## Bug Fixes - The code of `boda()` (with `samplingMethod="joint"`) and `bodaDelay()` (with `inferenceMethod="INLA"`) has been adjusted to a change of arguments of **INLA**'s `inla.posterior.sample` function. Accordingly, the minimum **INLA** version required to run `boda()` and `bodaDelay()` is 0.0-1458166556. - The functions returned by `W_powerlaw()` now have the package namespace as their environment to support situations where the package is not attached. - Attaching package [**nlme**](https://CRAN.R-project.org/package=nlme) after **surveillance** no longer masks `"hhh4"`'s `ranef`-method. (We now import the `fixef` and `ranef` generics from **nlme**.) # surveillance 1.12.0 (2016-04-02) ## Documentation - Several new vignettes illustrate *endemic-epidemic* modeling frameworks for spatio-temporal surveillance data: `vignette("twinstim")` : describes a spatio-temporal point process regression model. `vignette("twinSIR")` : describes a multivariate temporal point process regression model. `vignette("hhh4_spacetime")` : describes an areal time-series model for infectious disease counts. These vignettes are based on a recently accepted manuscript for the *Journal of Statistical Software* (Meyer, Held, and Höhle, 2016). - Improved the documentation on various help pages. - The `hhh4()`-based analysis of `data("fluBYBW")` has been moved to a separate demo script 'fluBYBW.R'. Due to the abundance of models and the relatively long runtime, we recommend to open the script in an editor rather than running all the code at once using `demo("fluBYBW")`. ## New Features - Overhaul of the `"sts"` implementation. This mostly affects package-internal code, which is simpler, cleaner and better tested now, but requires R >= 3.2.0 (due to `callNextMethod()` bugs in older versions of R). Beyond that, the user-level constructor function `sts()` now has explicit arguments for clarity and convenience. For instance, its first argument sets the `observed` slot and no longer needs to be named, i.e., `sts(mycounts, start=c(2016,3), frequency=12)` works just like for the classical `ts()` function. - `stsplot_time(..., as.one=TRUE)` is now implemented (yielding a simple `matplot` of multiple time series). ## Minor Changes - `plotHHH4_season()` now by default draws a horizontal reference line at unity if the multiplicative effect of component seasonality is shown (i.e., if `intercept=FALSE`). - Since **surveillance** 1.8-0, `hhh4()` results are of class `"hhh4"` instead of `"ah4"` (renamed). Legacy methods for the old class name `"ah4"` have been removed. - The internal model preparation in `twinstim()` is more efficient (the distance matrix of the events is only computed if event sources actually need to be updated). ## Bug Fixes - `stsplot_spacetime()` now recognizes its `opts.col` argument. - Conversion from `"ts"` to `"sts"` using `as(ts, "sts")` could set a wrong start time. For instance, `as(ts(1:10, start=c(1959,2), frequency=4), "sts")@start` was `c(1959,1)`. - `algo.twins()` now also accepts `"sts"` input and the automatic legend in the first plot of `plot.atwins()` works again. - The experimental `profile`-method for `"twinstim"` objects did not work if embedded `twinstim()` fits issued warnings. # surveillance 1.11.0 (2016-02-08) ## New Features - `update.epidata()` can now handle a distance matrix `D` in the form of a classed `"Matrix"`. [suggested by George Wood] - `glrnb()` can now handle `ret="cases"` for the generalized likelihood ratio detector based on the negative binomial distribution. It's based on a brute-force search and hence might be slow in some situations. - `boda()` and `bodaDelay()` now support an alternative method (`quantileMethod="MM"`) to compute quantiles based on the posterior distribution. The new method samples parameters from the posterior distribution and then computes the quantile of the mixture distribution using bisectionning, which is faster and yields similar results compared to the original method (`quantileMethod="MC"`, still the default). ## Minor Changes - Revised `vignette("hhh4")`, updated the package description as well as some references in the documentation. Also updated (the cache of) the slightly outdated `vignette("surveillance")` to account for the corrected version of `algo.bayes()` implemented since **surveillance** 1.10-0. ## Bug Fixes - Fixed bug in `categoricalCUSUM()`, which ignored alarms generated for the last time point in `range`. Furthermore, the exact computation in case of returns of the type `"value"` for the binomial are now checked through an attribute. - Fixed bug in the `estimateGLRNbHook` function of `algo.glrnb`, which ignored potential fixed `alpha` values. If `alpha` is fixed this is now taken into consideration while fitting the negative binomial function. See revised help files for the details. - Made a hot-fix such that the `algo.quality` function now also works for `sts` objects and if the `state` or `alarm` slots consists of TRUE/FALSE instead of 0/1. - `intensity.twinstim()` did not work for non-endemic models. - A parallelized `epitest()` could fail with a strange error message if some replications were left unassigned. This seems to happen if forking is used (`mclapply`) with insufficient memory. Incomplete replications are now ignored with a warning. # surveillance 1.10-0 (2015-11-04) ## New Features - Calibration tests for count data (Wei and Held, 2014, Test) are now implemented and available as `calibrationTest()`. In addition to a default method taking pure counts and predictive means and dispersion parameters, there are convenient methods for `"hhh4"` and `"oneStepAhead"` objects. - Shared overdispersion across units in negative binomial `hhh4()` time series models (by specifying a factor variable as the `family` argument). - `scores()` and `pit()` are now generic and have convenient methods for `"oneStepAhead"` predictions and `"hhh4"` fits. - The initial values used for model updates during the `oneStepAhead()` procedure can now be specified directly through the `which.start` argument (as an alternative to the previous options `"current"` and `"final"`). - `plotHHH4_fitted()` (and `plotHHH4_fitted1()`) gained an option `decompose` to plot the contributions from each single unit (and the endemic part) instead of the default endemic + AR + neighbours decomposition. Furthermore, a formatted time axis similar to `stsplot_time1()` can now be enabled via the new argument `xaxis`. - The new `plot` `type` `"maps"` for `"hhh4"` fits shows maps of the fitted mean components averaged over time. - New `plot`-method for simulations from `"hhh4"` models (using `simulate.hhh4(..., simplify = TRUE)`, which now has a dedicated class: `"hhh4sims"`) to show the final size distribution or the simulated time series (possibly stratified by groups of units). There is also a new `scores`-method to compute proper scoring rules based on such simulations. - The argument `idx2Exp` of `coef.hhh4()` may now be conveniently set to `TRUE` to exp-transform all coefficients. - Added a `coeflist()`-method for `"hhh4"` fits. - The generator function `sts()` can now be used to initialize objects of class `"sts"` (instead of writing `new("sts", ...)`). - Additional arguments of `layout.scalebar()` now allow to change the style of the labels. - A pre-computed distance matrix `D` can now be used as input for the `as.epidata()` converter -- offering an alternative to the default Euclidean distance based on the individuals coordinates. (Request of George Wood to support `twinSIR` models on networks.) ## Minor Changes - The first argument of `scores()` is now called `x` instead of `object` (for consistency with `calibrationTest()`). - The result of `oneStepAhead()` now has the dedicated class attribute `"oneStepAhead"` (previously was just a list). - Changed interpretation of the `col` argument of `plotHHH4_fitted()` and `plotHHH4_fitted1()` (moved color of "observed" to separate argument `pt.col` and reversed remaining colors). The old `col` specification as a vector of length 4 still works (caught internally) but is undocumented. - The `epoch` slot of class `"sts"` is now initialized to `1:nrow(observed)` by default and thus no longer needs to be explicitly set when creating a `new("sts", ...)` for this standard case. - Initialization of `new("sts", ...)` now supports the argument `frequency` (for consistency with `ts()`). Note that `freq` still works (via partial argument matching) and that the corresponding `"sts"` slot is still called `freq`. - If `missing(legend.opts)` in `stsplot_time1()`, the default legend will only be produced if the `"sts"` object contains information on outbreaks, alarms, or upperbounds. - The default `summary()` of a `"twinstim"` fit is more concise since it no longer includes the number of log-likelihood and score function evaluations and the elapsed time during model fitting. Set the new `runtime` argument of `summary.twinstim()` to `TRUE` to add this information to the summary as before. - The `animate`-method for `"sts"` objects gained an argument `draw` (to disable the default instantaneous plotting) and now invisibly returns the sequential plot objects (of class `"gtable"` or `"trellis"`) in a list for post-processing. - The flexible time axis configurations for `"sts"` plots introduced in version 1.8-0 now also work for classical `"sts"` objects with integer epochs and standard frequencies (try `plot(..., epochsAsDate = TRUE)`). - `stsplot_time()` initiates `par` settings only if the `par.list` argument is a list. - The new `all.equal()` method for class `"hhh4"` compares two fits ignoring their `"runtime"` and `"call"` elements (at least). ## Bug Fixes - Fixed a bug in `algo.bayes`, where an alarm was already sounded if the current observation was equal to the quantile of the predictive posterior. This was changed in order to get *alarm_t = I(obs_t > quantile_t)* which is consistent with the use in `boda` and `bodaDelay`. - Fixed bug in `algo.outbreakP` causing a halt in the computations of `value="cases"` when `calc.outbreakP.statistic` returned `NaN`. Now, a `NaN` is returned. - `wrap.algo` argument `control.hook` used `control` argument defined outside it's scope (and not the one provided to the function). It is now added as additional 2nd argument to the `control.hook` function. - `stsplot_time()` did not account for the optional `units` argument for multivariate `"sts"` objects when choosing a suitable value for `par("mfrow")`. - `hhh4()` could have used a function `dpois()` or `dnbinom()` from the global environment instead of the respective function from package **stats**. - The default time variable `t` created as part of the `data` argument in `hhh4()` was incompatible with `"sts"` objects having `epochAsDate=TRUE`. - A consistency check in `as.epidata.default()` failed for SI-type data (and, more generally, for all data which ended with an I-event in the last time block). [spotted by George Wood] # surveillance 1.9-1 (2015-06-12) - This is a quick patch release to make the test suite run smoothly on CRAN's Windows and Solaris Sparc systems. - The new `hhh4()` option to scale neighbourhood weights did not work for parametric weights with more than one parameter if `normalize=FALSE`. # surveillance 1.9-0 (2015-06-09) ## New Features - New functions and data for Bayesian outbreak detection in the presence of reporting delays (Salmon et al., 2015): `bodaDelay()`, `sts_observation()`, and `sts_creation()`. - New functions implementing tests for space-time interaction: - `knox()` supports both the Poisson approximation and a Monte Carlo permutation approach to determine the p-value, - `stKtest()` wraps space-time K-function methods from package [**splancs**](https://CRAN.R-project.org/package=splancs) for use with `"epidataCS"`, - and `epitest()` for `twinstim` models (makes use of the new auxiliary function `simpleR0()`). - New function `plapply()`: a parallel and verbose version of `lapply()` wrapping around both `mclapply()` and `parLapply()` of package **parallel**. - New converter `as.xts.sts()` to transform `"sts"` objects to the quasi standard `"xts"` class, e.g., to make use of package [**dygraphs**](https://CRAN.R-project.org/package=dygraphs) for interactive time series plots. - New options for scaling and normalization of neighbourhood weights in `hhh4()` models. - New auxiliary function `layout.scalebar()` for use as part of `sp.layout` in `spplot()` or in the traditional graphics system. ### New features for `"epidataCS"` - New argument `by` for `plot.epidataCS()`, which defines a stratifying variable for the events (default is the event type as before). It can also be set to `NULL` to make the plot not distinguish between event types. - The spatial plot of `"epidataCS"` gained the arguments `tiles`, `pop` and `sp.layout`, and can now produce an `spplot()` with the tile-specific population levels behind the point pattern. - New function `permute.epidataCS()` to randomly permute time points or locations of the events (holding other marks fixed). ### New features for `twinstim()` - New S3-generic `coeflist()` to list model coefficients by component. It currently has a default method and one for `"twinstim"` and `"simEpidataCS"`. - New argument `newcoef` for `simulate.twinstim()` to customize the model parameters used for the simulation. - New argument `epilink` for `twinstim()`, offering experimental support for an identity link for the epidemic predictor. The default remains `epilink = "log"`. - Simulation from `"twinstim"` models and generation of `"epidataCS"` is slightly faster now (faster **spatstat** functions are used to determine the distance of events to the border). - New option `scaled = "standardized"` in `iafplot()` to plot *f(x) / f(0)* or *g(t) / g(0)*, respectively. ## Minor Changes - Initial data processing in `twinstim()` is faster since event sources are only re-determined if there is effective need for an update (due to subsetting or a change of `qmatrix`). - `formatPval()` disables `scientific` notation by default. - The `"time"` plot for `"epidataCS"` uses the temporal grid points as the default histogram `breaks`. - The special `fe()` function which sets up fixed effects in `hhh4()` models gained an argument `unitSpecific` as a convenient shortcut for `which = rep(TRUE, nUnits)`. - The convenient `plot` option of `permutationTest()` uses [**MASS**](https://CRAN.R-project.org/package=MASS)::`truehist()` instead of `hist()` and accepts graphical parameters to customize the histogram. ## Bug Fixes - The `bodaFit` function did not draw samples from the joint posterior. Instead draws were from the respective posterior marginals. A new argument `samplingMethod` is now introduced defaulting to the proper 'joint'. For backwards compatibility use the value 'marginal'. - The functions `as.epidataCS()` and `simEpidataCS()` could throw inappropriate warnings when checking polygon areas (only if `W` or `tiles`, respectively, contained holes). - Non-convergent endemic-only `twinstim` models produced an error. [spotted by Bing Zhang] - The `"owin"`-method of `intersectPolyCircle` could have returned a rectangle-type `"owin"` instead of a polygon. - An error occurred in `twinstim()` if `finetune=TRUE` or choosing `optim()` instead of the default `nlminb()` optimizer without supplying a `control` list in `optim.args`. - The `"time"` plot for `"epidataCS"` did not necessarily use the same histogram `breaks` for all strata. - Specifying a step function of interaction via a numeric vector of knots did not work in `twinstim()`. - `plot.hhh4()` did not support an unnamed `type` argument such as `plot(x, "season")`. - `simEpidataCS()` did not work if `t0` was in the last block of `stgrid` (thus it did not work for single-cell grids), and mislabeled the `start` column copied to `events` if there were no covariates in `stgrid`. - Evaluating `intensity.twinstim()$hFUN()` at time points before `t0` was an error. The function now returns `NA_real_` as for time points beyond `T`. - Truncated, normalized power-law weights for `hhh4()` models, i.e., `W_powerlaw(maxlag = M, normalize = TRUE)` with `M < max(neighbourhood(stsObj))`, had wrong derivatives and thus failed to converge. - `update.hhh4(..., use.estimates = TRUE)` did not use the estimated weight function parameters as initial values for the new fit. It does so now iff the weight function `ne$weights` is left unchanged. # surveillance 1.8-3 (2015-01-05) - Accommodate a new note given by R-devel checks, and set the new INLA additional repository in the 'DESCRIPTION' file. - Made `linelist2sts()` work for quarters by adding extra `"%q"` formatting in `formatDate()`. # surveillance 1.8-2 (2014-12-16) ## Minor Changes for `hhh4()` - In the coefficient vector resulting from a `hhh4` fit, random intercepts are now named. - Parameter `start` values in `hhh4()` are now matched by name but need not be complete in that case (default initial values are used for unspecified parameters). - The `update.hhh4()`-method now by default does `use.estimates` from the previous fit. This reduces the number of iterations during model fitting but may lead to slightly different parameter estimates (within a tolerance of `1e-5`). Setting `use.estimates = FALSE` means to re-use the previous start specification. ## Minor Changes for the `"sts"` Class - For univariate `"sts"` objects, the (meaningless) "head of neighbourhood" is no longer `show`n. - The `"sts"` class now has a `dimnames`-method instead of a `colnames`-method. Furthermore, the redundant `nrow` and `ncol` methods have been removed (the `dim`-method is sufficient). - If a `map` is provided when `initialize()`ing an `"sts"` object, it is now verified that all `observed` regions are part of the `map` (matched by `row.names`). - In `stsplot_space()`, extra (unobserved) regions of the `map` are no longer dropped but shown with a dashed border by default. # surveillance 1.8-1 (2014-10-29) ## New Features - The `R0`-method for `"twinstim"` gained an argument `newcoef` to simplify computation of reproduction numbers with a different parameter vector (also used for Monte Carlo CI's). - New plot `type="neweights"` for `"hhh4"` fits. - The `scores()` function allows the selection of multiple `units` (by index or name) for which to compute (averaged) proper scores. Furthermore, one can now select `which` scores to compute. - Added a `formula`-method for `"hhh4"` fits to extract the `f` specifications of the three components from the control list. - The `update()`-method for fitted `"hhh4"` models gained an argument `S` for convenient modification of component seasonality using `addSeason2formula()`. - The new auxiliary function `layout.labels()` generates an `sp.layout` item for `spplot()` in order to draw labels. - When generating the `pit()` histogram with a single predictive CDF `pdistr`, the `...` arguments can now be `x`-specific and are recycled if necessary using `mapply()`. If `pdistr` is a list of CDFs, `pit()` no longer requires the functions to be vectorized. - New method `as.epidata.data.frame()`, which constructs the start/stop SIR event history format from a simple individual-based data frame (e.g., `hagelloch.df`). - New argument `w` in `as.epidata.default()` to generate covariate-based weights for the force of infection in `twinSIR`. The `f` argument is for distance-based weights. - The result of `profile.twinSIR()` gained a class and an associated `plot`-method. ## Significant Changes - For multivariate `oneStepAhead()` predictions, `scores(..., individual=TRUE)` now returns a 3d array instead of a collapsed matrix. Furthermore, the scores computed by default are `c("logs","rps","dss","ses")`, excluding the normalized squared error score `"nses"` which is improper. - The plot-`type="season"` for `"hhh4"` fits now by default plots the multiplicative effect of seasonality on the respective component (new argument `intercept=FALSE`). The default set of components to plot has also changed. - When `as.epidata()` and `simEpidata()` calculate distance-based epidemic weights from the `f` functions, they no longer set the distance of an infectious individual to itself artificially to `Inf`. This changes the corresponding columns in the `"epidata"` in rows of currently infectious individuals, but the `twinSIR` model itself is invariant, since only rows with `atRiskY=1` contribute to the likelihood. - Several modifications and corrections in `data("hagelloch")`. ## Minor Changes - Better plotting of `stsNC` objects by writing an own plot method for them. Prediction intervals are now shown jointly with the point estimate. - Reduced package size by applying `tools::resaveRdaFiles` to some large datasets and by building the package with `--compact-vignettes=both`, i.e., using additional GhostScript compression with ebook quality, see `?tools::compactPDF`. - Added `units` argument to `stsplot_time` to select only a subset of the multivariate time series for plotting. - The `untie`-method for class `"epidataCS"` gained an argument `verbose` which is now `FALSE` by default. - `"epidataCS"` objects store the `clipper` used during generation as attribute of `$events$.influenceRegion`. - In `plotHHH4_fitted()`, the argument `legend.observed` now defaults to `FALSE`. - The default weights for the spatio-temporal component in `hhh4` models now are `neighbourhood(stsObj) == 1`. The previous default `neighbourhood(stsObj)` does not make sense for the newly supported `nbOrder` neighbourhood matrices (shortest-path distances). The new default makes no difference for (old) models with binary adjacency matrices in the neighbourhood slot of the `stsObj`. - The default for nonparametric weights `W_np()` in `hhh4()` is now to assume zero weight for neighbourhood orders above `maxlag`, i.e., `W_np()`'s argument `to0` now defaults to `TRUE`. - Added a `verbose` argument to `permutationTest()`, which defaults to `FALSE`. The previous behaviour corresponds to `verbose=TRUE`. - `simulate.twinstim()` now by default uses the original `data$W` as observation region. - The `data("measlesWeserEms")` contain two additional variables in the `@map@data` slot: `"vaccdoc.2004"` and `"vacc1.2004"`. - The plot-method for `"epidata"` objects now uses colored lines by default. - The **surveillance** package now depends on R >= 3.0.2, which, effectively, is the minimum version required since **surveillance** 1.7-0. - The two diagnostic plots of `checkResidualProcess()` are now by default plotted side by side (`mfrow=c(1,2)`) instead of one below the other. ## Bug Fixes - In `farringtonFlexible` alarms are now for `observed>upperbound` and not for `observed>=upperbound` which was not correct. - Fixed duplicate `"functions"` element resulting from `update.twinstim(*,model=TRUE)` and ensured that `"twinstim"` objects always have the same components (some may be `NULL`). - `animate.epidata` works again with the [**animation**](https://CRAN.R-project.org/package=animation) package (`ani.options("outdir")` was removed in version 2.3) - For `hhh4` models with random effects, `confint()` only worked if argument `parm` was specified. - Computing one-sided AIC weights by simulation for `twinSIR` models with more than 2 epidemic covariates now is more robust (by rescaling the objective function for the quadratic programming solver) and twice as fast (due to code optimization). - `simulate.twinstim(..., rmarks=NULL)` can now handle the case where `data` has no events within the simulation period (by sampling marks from all of `data$events`). - The `lambda.h` values of simulated events in `"simEpidataCS"` objects were wrong if the model contained an endemic intercept (which is usually the case). - Automatic choice of color breaks in the `animate`-method for class `"sts"` now also works for incidence maps (i.e., with a `population` argument). - `hhh4()` did not allow the use of nonparametric neighbourhood weights `W_np()` with `maxlag=2`. - `scores()` did not work for multivariate `oneStepAhead()` predictions if both `individual=TRUE` and `sign=TRUE`, and it could not handle a `oneStepAhead()` prediction of only one time point. Furthermore, the `"sign"` column of `scores(..., sign=TRUE)` was wrong (reversed). - For `"epidataCS"` with only one event, `epidataCSplot_space()` did not draw the point. - The trivial (identity) call `aggregate(stsObj, nfreq=stsObj@freq)` did not work. # surveillance 1.8-0 (2014-06-16) ## Package Infrastructure - Package **surveillance** now depends on newer versions of packages [**sp**](https://CRAN.R-project.org/package=sp) (>= 1.0-15), [**polyCub**](https://CRAN.R-project.org/package=polyCub) (>= 0.4-2), and [**spatstat**](https://CRAN.R-project.org/package=spatstat) (>= 1.36-0). The R packages **INLA** and [**runjags**](https://CRAN.R-project.org/package=runjags) are now suggested to support a new outbreak detection algorithm (`boda()`) and the new `nowcast()`ing procedure, respectively. The R packages for [**lattice**](https://CRAN.R-project.org/package=lattice), [**grid**](https://CRAN.R-project.org/package=grid), [**gridExtra**](https://CRAN.R-project.org/package=gridExtra), and [**scales**](https://CRAN.R-project.org/package=scales) are suggested for added visualization facilities. - More tests have been implemented to ensure package integrity. We now use [**testthat**](https://CRAN.R-project.org/package=testthat) instead of the outdated package [**RUnit**](https://CRAN.R-project.org/package=RUnit). - `hhh4()` fits now have class `"hhh4"` instead of `"ah4"`, for consistency with `twinstim()`, `twinSIR()`, and to follow the common convention (cp. `lm()`). Standard S3-methods for the old `"ah4"` name are still available for backwards compatibility but may be removed in the future. - Plot variants for `"sts"` objects have been cleaned up: The functions implementing the various plot types (`stsplot_*`, previously named `plot.sts.*`) are now exported and documented separately. ## New Features - The `nowcast` procedure has been completely re-written to handle the inherit right-truncation of reporting data (best visualized as a reporting triangle). The new code implements the generalized-Dirichlet and the hierarchical Bayesian approach described in Höhle and an der Heiden (2014). No backwards compatibility to the old nowcasting procedure is given. - The package contains a new monitoring function `boda`. This is a first experimental surveillance implementation of the Bayesian Outbreak Detection Algorithm (BODA) proposed in Manitz and Höhle (2012). The function relies on the non-CRAN package **INLA**, which has to be installed first in order to use this function. Expect initial problems. - New `toLatex`-method for `"sts"` objects. - The new function `stsplot_space()` provides an improved map plot of disease incidence for `"sts"` objects aggregated over time. It corresponds to the new `type = observed ~ unit` of the `stsplot`-method, and supersedes `type = observed ~ 1|unit` (except for alarm shading). - An `animate()`-method for the `"sts"` class provides a new implementation for animated maps (superseding the `plot` `type=observed ~ 1 | unit * time`) with an optional evolving time series plot below the map. - The `plot()` method for `"sts"` objects with epochs as dates is now made more flexible by introducing the arguments `xaxis.tickFreq`, `xaxis.labelFreq` and `xaxis.labelFormat`. These allow the specification of tick-marks and labelling based on `strftime` compatible conversion codes -- independently if data are daily, weekly, monthly, etc. As a consequence, the old argument `xaxis.years` is removed. See `stsplot_time()` for more information. - Inference for neighbourhood weights in `hhh4()` models: `W_powerlaw()` and `W_np()` both implement weights depending on the order of neighbourhood between regions, a power-law decay and nonparametric weights, i.e., unconstrained estimation of individual weights for each neighbourhood order. - `hhh4()` now allows the inclusion of multiplicative offsets also in the epidemic components `"ar"` and `"ne"`. - `hhh4()` now has support for `lag != 1` in the autoregressive and neighbor-driven components. The applied lags are stored as component `"lags"` of the return value (previously there was an unused component `"lag"` which was always 1 and has been removed now). - `oneStepAhead()`: - Added support for parallel computation of predictions using `mclapply()` from package **parallel**. - New argument `type` with a new `type` `"first"` to base all subsequent one-step-ahead predictions on a single initial fit. - Nicer interpretation of `verbose` levels, and `txtProgressBar()`. - The `plot()`-method for fitted `hhh4()` objects now offers three additional types of plots: component seasonality, seasonal or time course of the dominant eigenvalue, and maps of estimated random intercepts. It is documented and more customizable. Note that argument order and some names have changed: `i` -> `units`, `title` -> `names`. - (Deviance) `residuals()`-method for fitted `hhh4()` models. - Added methods of `vcov()` and `nobs()` for the `"hhh4"` class. For `AIC()` and `BIC()`, the default methods work smoothly now (due to changes to `logLik.hhh4()` documented below). - New predefined interaction functions for `twinstim()`: `siaf.student()` implements a *t*-kernel for the distance decay, and `siaf.step()` and `tiaf.step()` provide step function kernels (which may also be invoked by specifying the vector of knots as the `siaf` or `tiaf` argument in `twinstim`). - Numerical integration over polygonal domains in the `F` and `Deriv` components of `siaf.powerlaw()` and `siaf.powerlawL()` is much faster and more accurate now since we use the new `polyCub.iso()` instead of `polyCub.SV()` from package [**polyCub**](https://CRAN.R-project.org/package=polyCub). - New `as.stepfun()`-method for `"epidataCS"` objects. - `plot.epidataCS()`: - The spatial plot has new arguments to automatically add legends to the plot: `legend.types` and `legend.counts`. It also gained an `add` argument. - The temporal plot now supports type-specific sub-histograms, additional lines for the cumulative number of events, and an automatic legend. - The new function `glm_epidataCS()` can be used to fit an endemic-only `twinstim()` via `glm()`. This is mainly provided for testing purposes since wrapping into `glm` usually takes longer. ## Significant Changes - Fitted `hhh4()` objects no longer contain the associated `"sts"` data twice: it is now only stored as `$stsObj` component, the hidden duplicate in `$control$data$.sts` was dropped, which makes fitted objects substantially smaller. - `logLik.hhh4()` always returns an object of class `"logLik"` now; for random effects models, its `"df"` attribute is `NA_real_`. Furthermore, for non-convergent fits, `logLik.hhh4()` gives a warning and returns `NA_real_`; previously, an error was thrown in this case. - `oneStepAhead()`: - Default of `tp[2]` is now the penultimate time point of the fitted subset (not of the whole `stsObj`). - `+1` on rownames of `$pred` (now the same as for `$observed`). - The optional `"twinstim"` result components `fisherinfo`, `tau`, and `functions` are always included. They are set to `NULL` if they are not applicable instead of missing completely (as before), such that all `"twinstim"` objects have the same list structure. - `iafplot()` ... - invisibly returns a matrix containing the plotted values of the (scaled) interaction function (and the confidence interval as an attribute). Previously, nothing (`NULL`) was returned. - detects a type-specific interaction function and by default uses `types=1` if it is not type-specific. - has better default axis ranges. - adapts to the new step function kernels (with new arguments `verticals` and `do.points`). - supports logarithmic axes (via new `log` argument passed on to `plot.default`). - optionally respects `eps.s` and `eps.t`, respectively (by the new argument `truncated`). - now uses `scaled=TRUE` by default. - The argument `colTypes` of `plot.epidataCS(,aggregate="space")` is deprecated (use `points.args$col` instead). - The events in an `"epidataCS"` object no longer have a reserved `"ID"` column. ## Minor Changes - `hhh4()` now stores the runtime just like `twinstim()`. - Take `verbose=FALSE` in `hhh4()` more seriously. - `hhh4()` issues a `warning()` if non-convergent. - The following components of a `hhh4()` fit now have names: `"se"`, `"cov"`, `"Sigma"`. - The new default for `pit()` is to produce the plot. - The `twinstim()` argument `cumCIF` now defaults to `FALSE`. - `update.twinstim()` no longer uses recursive `modifyList()` for the `control.siaf` argument. Instead, the supplied new list elements (`"F"`, `"Deriv"`) completely replace the respective elements from the original `control.siaf` specification. - `siaf.lomax()` is now defunct (it has been deprecated since version 1.5-2); use `siaf.powerlaw()` instead. - Allow the default `adapt`ive bandwidth to be specified via the `F.adaptive` argument in `siaf.gaussian()`. - Unsupported options (`logpars=FALSE`, `effRangeProb`) have been dropped from `siaf.powerlaw()` and `siaf.powerlawL()`. - More rigorous checking of `tiles` in `simulate.twinstim()` and `intensityplot.twinstim()`. - `as.epidataCS()` gained a `verbose` argument. - `animate.epidataCS()` now by default does not draw influence regions (`col.influence=NULL`), is `verbose` if `interactive()`, and ignores `sleep` on non-interactive devices. - The `multiplicity`-generic and its default method have been integrated into [**spatstat**](https://CRAN.R-project.org/package=spatstat) and are imported from there. ## Data - The polygon representation of Germany's districts ( `system.file("shapes", "districtsD.RData", package="surveillance")` ) has been simplified further. The union of `districtsD` is used as observation window `W` in `data("imdepi")`. The exemplary `twinstim()` fit `data("imdepifit")` has been updated as well. Furthermore, `row.names(imdepi$events)` have been reset (chronological index), and numerical differences in `imdepi$events$.influenceRegion` are due to changes in [**polyclip**](https://CRAN.R-project.org/package=polyclip) 1.3-0. - The Campylobacteriosis data set `campyDE`, where absolute humidity is used as concurrent covariate to adjust the outbreak detection is added to the package to exemplify `boda()`. - New `data("measlesWeserEms")` (of class `"sts"`), a corrected version of `data("measles.weser")` (of the old `"disProg"` class). ## Bug Fixes - Fixed a bug in `LRCUSUM.runlength` where computations were erroneously always done under the in-control parameter `mu0` instead of `mu`. - Fixed a bug during alarm plots (`stsplot_alarm()`), where the use of `alarm.symbol` was ignored. - Fixed a bug in `algo.glrnb` where the overdispersion parameter `alpha` from the automatically fitted `glm.nb` model (fitted by `estimateGLRNbHook`) was incorrectly taken as `mod[[1]]$theta` instead of `1/mod[[1]]$theta`. The error is due to a different parametrization of the negative binomial distribution compared to the parametrization in Höhle and Paul (2008). - The score function of `hhh4()` was wrong when fitting endemic-only models to a `subset` including the first time point. This led to "false convergence". - `twinstim()` did not work without an endemic offset if `is.null(optim.args$par)`. # surveillance 1.7-0 (2013-11-19) ## Package Infrastructure - Package [**gpclib**](https://CRAN.R-project.org/package=gpclib) is no longer necessary for the construction of `"epidataCS"`-objects. Instead, we make use of the new dedicated package [**polyclip**](https://CRAN.R-project.org/package=polyclip) (licensed under the BSL) for polygon clipping operations (via `spatstat::intersect.owin()`). This results in a slightly different `$events$.influenceRegion` component of `"epidataCS"` objects, one reason being that **polyclip** uses integer arithmetic. Change of `twinstim()` estimates for a newly created `"epidataCS"` compared with the same data prepared in earlier versions should be very small (e.g., for `data("imdepifit")` the mean relative difference of coefficients is 3.7e-08, while the `logLik()` is `all.equal()`). As an alternative, **rgeos** can still be chosen to do the polygon operations. - The **surveillance**-internal code now depends on R >= 2.15.2 (for `nlminb()` `NA` fix of PR#15052, consistent `rownames(model.matrix)` of PR#14992, `paste0()`, `parallel::mcmapply()`). However, the required recent version of **spatstat** (1.34-0, for **polyclip**) actually needs R >= 3.0.2, which therefore also applies to **surveillance**. ## New Features - Functions `unionSpatialPolygons()` and `intersectPolyCircle()` are now exported. Both are wrappers around functionality from different packages supporting polygon operations: for determining the union of all subpolygons of a `"SpatialPolygons"` object, and the intersection of a polygonal and a circular domain, respectively. - `discpoly()` moved back from [**polyCub**](https://CRAN.R-project.org/package=polyCub) to **surveillance**. ## Minor Changes - **surveillance** now Depends on [**polyCub**](https://CRAN.R-project.org/package=polyCub) (>= 0.4-0) and not only Imports it (which avoids `::`-references in .GlobalEnv-made functions). - Nicer default axis labels for `iafplot()`. - For `twinstim()`, the default is now to `trace` every iteration instead of every fifth only. - Slightly changed default arguments for `plot.epidata()`: `lwd` (1->2), `rug.opts` (`col` is set according to `which.rug`) - `twinstim()` saves the vector of `fixed` coefficients as part of the returned `optim.args` component, such that these will again be held fixed upon `update()`. - The `plot`-method for `hhh4()`-fits allows for region selection by name. # surveillance 1.6-0 (2013-09-03) ## Synopsis - The `polyCub`-methods for cubature over polygonal domains have been moved to the new dedicated package [**polyCub**](https://CRAN.R-project.org/package=polyCub), since they are of a rather general use. The `discpoly()` function has also been moved to that package. - As a replacement for the license-restricted **gpclib** package, the **rgeos** package is now used by default (`surveillance.options(gpclib=FALSE)`) in generating `"epidataCS"` (polygon intersections, slightly slower). Therefore, when installing **surveillance** version 1.6-0, the system requirements for [**rgeos**](https://CRAN.R-project.org/package=rgeos) have to be met, i.e., GEOS must be available on the system. On Linux variants this means installing 'libgeos' ('libgeos-dev'). - The improved Farrington method described in Noufaily et al. (2012) is now available as function `farringtonFlexible()`. - New handling of reference dates in `algo.farrington()` for `"sts"` objects with `epochAsDate=TRUE`. Instead of always going back in time to the next Date in the `"epoch"` slot, the function now determines the *closest* Date. Note that this might lead to slightly different results for the upperbound compared to previously. Furthermore, the functionality is only tested for weekly data (monthly data are experimental). The same functionality applies to `farringtonFlexible()`. - To make the different retrospective modelling frameworks of the **surveillance** package jointly applicable, it is now possible to convert (aggregate) `"epidataCS"` (continuous-time continuous-space data) into an `"sts"` object (multivariate time series of counts) by the new function `epidataCS2sts`. - Simulation from `hhh4` models has been re-implemented, which fixes a bug and makes it more flexible and compatible with a wider class of models. - The `map`-slot of the `"sts"` class now requires `"SpatialPolygons"` (only) instead of `"SpatialPolygonsDataFrame"`. - Re-implementation of `oneStepAhead()` for `hhh4`-models with a bug fix, some speed-up and more options. - Slight speed-up for `hhh4()` fits, e.g., by more use of `.rowSums()` and `.colSums()`. - Crucial speed-up for `twinstim()` fits by more efficient code: `mapply`, dropped clumsy `for`-loop in `fisherinfo`, new argument `cores` for parallel computing via forking (not available on Windows). ## New Features - Using `tiaf.exponential()` in a `twinstim()` now works with `nTypes=1` for multi-type data. - A legend can be added automatically in `iafplot()`. - The `untie` methods are now able to produce jittered points with a required minimum separation (`minsep`). - `simulate.ah4` gained a `simplify` argument. - New `update`-method for fitted `hhh4`-models (class `"ah4"`). - `oneStepAhead()` has more options: specify time range (not only start), choose type of start values, `verbose` argument. - `pit()` allows for a list of predictive distributions (`pdistr`), one for each observation `x`. - New spatial auxiliary function `polyAtBorder()` indicating polygons at the border (for a `"SpatialPolygons"` object). - `animate.epidataCS()` allows for a `main` title and can show a progress bar. ## Minor Changes - Changed parametrization of `zetaweights()` and completed its documentation (now no longer marked as experimental). - `twinstim(...)$converged` is `TRUE` if the optimization routine converged (as before) but contains the failure message otherwise. - Increased default `maxit` for the Nelder-Mead optimizer in `hhh4` from 50 to 300, and removed default artificial lower bound (-20) on intercepts of epidemic components. - Renamed returned list from `oneStepAhead` (mean->pred, x->observed, params->coefficients, variances->Sigma.orig) for consistency, and `oneStepAhead()$psi` is only non-`NULL` if we have a NegBin model. - Argument order of `pit()` has changed, which is also faster now and got additional arguments `relative` and `plot`. - `twinstim(...)$runtime` now contains the complete information from `proc.time()`. ## Bug Fixes - Fixed a bug in function `refvalIdxByDate()` which produced empty reference values (i.e. `NA`s) in case the Date entries of `epoch` were not mondays. Note: The function works by subtracting `1:b` years from the date of the range value and then takes the span `-w:w` around this value. For each value in this set it is determined whether the closest date in the epoch slot is obtained by going forward or backward. Note that this behaviour is now slightly changed compared to previously, where we *always* went back in time. - `algo.farrington()`: Reference values too far back in time and hence not being in the `"epoch"` slot of the `"sts"` object are now ignored (previously the resulting `NA`s caused the function to halt). A warning is displayed in this case. - `hhh4`: The entry *(5,6)* of the marginal Fisher information matrix in models with random intercepts in all three components was incorrect. If `nlminb` was used as optimizer for the variance parameters (using the negative marginal Fisher information as Hessian), this could have caused false convergence (with warning) or minimally biased convergence (without warning). As a consequence, the `"Sigma.cov"` component of the `hhh4()` result, which is the inverse of the marginal Fisher information matrix at the MLE, was also wrong. - `untie.matrix()` could have produced jittering greater than the specified `amount`. - `hhh4`: if there are no random intercepts, the redundant `updateVariance` steps are no longer evaluated. - `update.twinstim()` did not work with `optim.args=..1` (e.g., if updating a list of models with lapply). Furthermore, if adding the `model` component only, the `control.siaf` and `optim.args` components were lost. - `earsC` should now also work with multivariate `sts` time-series objects. - The last week in `data(fluBYBW)` (row index 417) has been removed. It corresponded to week 1 in year 2009 and was wrong (an artifact, filled with zero counts only). Furthermore, the regions in `@map` are now ordered the same as in `@observed`. - Fixed start value of the overdispersion parameter in `oneStepAhead` (must be on internal log-scale, not reparametrized as returned by `coef()` by default). - When subsetting `"sts"` objects in time, `@start` was updated but not `@epoch`. - `pit` gave `NA` results if any `x[-1]==0`. - The returned `optim.args$par` vector in `twinstim()` was missing any fixed parameters. - `hhh4()` did not work with time-varying neighbourhood weights due to an error in the internal `checkWeightsArray()` function. # surveillance 1.5-4 (2013-04-21) - Fixed obsolete `.path.package()` calls. - Small corrections in the documentation. - `update.twinstim()` performs better in preserving the original initial values of the parameters. - New pre-defined spatial interaction function `siaf.powerlawL()`, which implements a _L_agged power-law kernel, i.e. accounts for uniform short-range dispersal. # surveillance 1.5-2 (2013-03-15) ## New Features - New method for outbreak detection: `earsC` (CUSUM-method described in the CDC Early Aberration Reporting System, see Hutwagner et al, 2003). - Yet another p-value formatting function `formatPval()` is now also part of the **surveillance** package. - `polyCub.SV()` now also accepts objects of classes `"Polygon"` and `"Polygons"` for convenience. ## New Features for `twinstim()` - New spatial interaction function `siaf.powerlaw()`, a re-parametrization of the now-deprecated `siaf.lomax()`. - The temporal `plot`-method for class `"epidataCS"` now understands the `add` parameter to add the histogram to an existing plot window, and auto-transforms the `t0.Date` argument using `as.Date()` if necessary. - `nobs()` methods for classes `"epidataCS"` and `"twinstim"`. - New argument `verbose` for `twinstim()` which, if set to `FALSE`, disables the printing of information messages during execution. - New argument `start` for `twinstim()`, where (some) initial parameter values may be provided, which overwrite those in `optim.args$par`, which is no longer required (as a naive default, a crude estimate for the endemic intercept and zeroes for the other parameters are used). - Implemented a wrapper `stepComponent()` for `step()` to perform algorithmic component-specific model selection in `"twinstim"` models. This also required the implementation of suitable `terms()` and `extractAIC()` methods. The single-step methods `add1()` and `drop1()` are also available. - The `update.twinstim()` method now by default uses the parameter estimates from the previous model as initial values for the new fit (new argument `use.estimates = TRUE`). - `as.epidataCS()` checks for consistency of the area of `W` and the (now really obligatory) area column in `stgrid`. - `simulate.twinstim()` now by default uses the previous `nCircle2Poly` from the `data` argument. - `direction` argument for `untie.epidataCS()`. - The `toLatex`-method for `"summary.twinstim"` got different defaults and a new argument `eps.Pvalue`. - New `xtable`-method for `"summary.twinstim"` for printing the covariate effects as risk ratios (with CI's and p-values). ## New Features for `hhh4()` - New argument `hide0s` in the `plot`-method for class `"ah4"`. - New argument `timevar` for `addSeason2formula()`, which now also works for long formulae. # surveillance 1.5-1 (2012-12-14) - The **surveillance** package is again backward-compatible with R version 2.14.0, which is now declared as the minimum required version. # surveillance 1.5-0 (2012-12-12) ## Package Infrastructure - As requested by the CRAN team, examples now run faster. Some are conditioned on the value of the new package option `"allExamples"`, which usually defaults to `TRUE` (but is set to `FALSE` for CRAN checking, if timings are active). - Moved some rarely used package dependencies to "Suggests:", and also removed some unused packages from there. - Dropped strict dependence on [**gpclib**](https://CRAN.R-project.org/package=gpclib), which has a restricted license, for the **surveillance** package to be clearly GPL-2. Generation of `"epidataCS"` objects, which makes use of **gpclib**'s polygon intersection capabilities, now requires prior explicit acceptance of the **gpclib** license via setting `surveillance.options(gpclib = TRUE)`. Otherwise, `as.epidataCS()` and `simEpidataCS()` may not be used. ## New Features for `twinstim()` - Speed-up by memoisation of the `siaf` cubature (using the [**memoise**](https://CRAN.R-project.org/package=memoise) package). - Allow for `nlm`-optimizer (really not recommended). - Allow for `nlminb`-specific control arguments. - Use of the expected Fisher information matrix can be disabled for `nlminb` optimization. - Use of the `effRange`-trick can be disabled in `siaf.gaussian()` and `siaf.lomax()`. The default `effRangeProb` argument for the latter has been changed from 0.99 to 0.999. - The `twinstim()` argument `nCub` has been replaced by the new `control.siaf` argument list. The old `nCub.adaptive` indicator became a feature of the `siaf.gaussian()` generator (named `F.adaptive` there) and does no longer depend on the `effRange` specification, but uses the bandwidth `adapt*sd`, where the `adapt` parameter may be specified in the `control.siaf` list in the `twinstim()` call. Accordingly, the components `"nCub"` and `"nCub.adaptive"` have been removed from the result of `twinstim()`, and are replaced by `"control.siaf"`. - The `"method"` component of the `twinstim()` result has been replaced by the whole `"optim.args"`. - The new `"Deriv"` component of `siaf` specifications integrates the "siaf$deriv" function over a polygonal domain. `siaf.gaussian()` and `siaf.lomax()` use `polyCub.SV()` (with intelligent `alpha` parameters) for this task (previously: midpoint-rule with naive bandwidth) - `scaled` `iafplot()` (default `FALSE`). The `ngrid` parameter has been renamed to `xgrid` and is more general. - The `"simulate"` component of `siaf`'s takes an argument `ub` (upperbound for distance from the source). - Numerical integration of spatial interaction functions with an `Fcircle` trick is more precise now; this slightly changes previous results. - New S3-generic `untie()` with a method for the `"epidataCS"` class (to randomly break tied event times and/or locations). - Renamed `N` argument of `polyCub.SV()` to `nGQ`, and `a` to `alpha`, which both have new default values. The optional polygon rotation proposed by Sommariva & Vianello is now also implemented (based on the corresponding MATLAB code) and available as the new `rotation` argument. - The `scale.poly()` method for `"gpc.poly"` is now available as `scale.gpc.poly()`. The default return class of `discpoly()` was changed from `"gpc.poly"` to `"Polygon"`. - An `intensityplot()`-method is now also implemented for `"simEpidataCS"`. ## New Features for `hhh4()` - Significant speed-up (runs about 6 times faster now, amongst others by many code optimizations and by using sparse [**Matrix**](https://CRAN.R-project.org/package=Matrix) operations). - `hhh4()` optimization routines can now be customized for the updates of regression and variance parameters separately, which for instance enables the use of Nelder-Mead for the variance updates, which seems to be more stable/robust as it does not depend on the inverse Fisher info and is usually faster. - The `ranef()` extraction function for `"ah4"` objects gained a useful `tomatrix` argument, which re-arranges random effects in a unit x effect matrix (also transforming CAR effects appropriately). - Generalized `hhh4()` to also capture parametric neighbourhood weights (like a power-law decay). The new function `nbOrder()` determines the neighbourhood order matrix from a binary adjacency matrix (depends on package [**spdep**](https://CRAN.R-project.org/package=spdep)). - New argument `check.analyticals` (default `FALSE`) mainly for development purposes. ## Bug Fixes - Fixed sign of observed Fisher information matrix in `twinstim`. - Simulation from the Lomax kernel is now correct (via polar coordinates). - Fixed wrong Fisher information entry for the overdispersion parameter in `hhh4`-models. - Fixed wrong entries in penalized Fisher information wrt the combination fixed effects x CAR intercept. - Fixed indexing bug in penalized Fisher calculation in the case of multiple overdispersion parameters and random intercepts. - Fixed bug in Fisher matrix calculation concerning the relation of unit-specific and random effects (did not work previously). - Improved handling of non-convergent / degenerate solutions during `hhh4` optimization. This involves using `ginv()` from package [**MASS**](https://CRAN.R-project.org/package=MASS), if the penalized Fisher info is singular. - Correct labeling of overdispersion parameter in `"ah4"`-objects. - Some control arguments of `hhh4()` have more clear defaults. - The result of `algo.farrington.fitGLM.fast()` now additionally inherits from the `"lm"` class to avoid warnings from `predict.lm()` about fake object. - Improved 'NAMESPACE' imports. - Some additional tiny bug fixes, see the subversion log on R-Forge for details. # surveillance 1.4-2 (2012-08-17) ## Package Infrastructure - The package is now again compatible with older releases of R (< 2.15.0) as intended (by defining `paste0()` in the package namespace if it is not found in R **base** at installation of the **surveillance** package). ## New Features - Important new `twinstim()`-feature: fix parameters during optimization. - Useful `update`-method for `"twinstim"`-objects. - New `[[`- and `plot`-methods for `"simEpidataCSlist"`-objects. - `simEpidataCS()` received tiny bug fixes and is now able to simulate from epidemic-only models. - `R0`-method for `"simEpidataCS"`-objects (actually a wrapper for `R0.twinstim()`). - Removed `dimyx` and `eps` arguments from `R0.twinstim()`; now uses `nCub` and `nCub.adaptive` from the fitted model and applies the same (numerical) integration method. - `animate.epidata` is now compatible with the [**animation**](https://CRAN.R-project.org/package=animation) package. - More thorough documentation of `"twinstim"`-related functions *including many examples*. ## Bug Fixes for `twinstim()` - `nlminb` (instead of `optim`'s `"BFGS"`) is now the default optimizer (as already documented). - The `twinstim`-argument `nCub` can now be omitted when using `siaf.constant()` (as documented) and is internally set to `NA_real_` in this case. Furthermore, `nCub` and `nCub.adaptive` are set to `NULL` if there is no epidemic component in the model. - `toLatex.summary.twinstim` now again works for `summary(*, test.iaf=FALSE)`. - `print`- and `summary`-methods for `"epidataCS"` no longer assume that the `BLOCK` index starts at 1, which may not be the case when using a subset in `simulate.twinstim()`. - The `"counter"` step function returned by `summary.epidataCS()` does no longer produce false numbers of infectives (they were lagged by one timepoint). - `plot.epidataCS()` now resolves ... correctly and the argument `colTypes` takes care of a possible `subset`. - `simEpidataCS()` now also works for endemic-only models and is synchronised with `twinstim()` regarding the way how `siaf` is numerically integrated (including the argument `nCub.adaptive`). - Fixed problem with `simEpidataCS()` related to missing 'NAMESPACE' imports (and re-exports) of `marks.ppp` and `markformat.default` from [**spatstat**](https://CRAN.R-project.org/package=spatstat), which are required for `spatstat::runifpoint()` to work, probably because **spatstat** currently does not register its S3-methods. - Improved error handling in `simEpidataCS()`. Removed a `browser()`-call and avoid potentially infinite loop. ## Bug Fixes for `twinSIR()` - The `.allocate` argument of `simEpidata()` has now a fail-save default. - Simulation without endemic `cox()`-terms now works. ## Minor Changes - Simplified `imdepi` data to monthly instead of weekly intervals in `stgrid` for faster examples and reduced package size. - The environment of all predefined interaction functions for `twinstim()` is now set to the `.GlobalEnv`. The previous behaviour of defining them in the `parent.frame()` could have led to huge `save()`'s of `"twinstim"` objects even with `model=FALSE`. - `simulate.twinSIR` only returns a list of epidemics if `nsim > 1`. - `simulate.twinstim` uses `nCub` and `nCub.adaptive` from fitted object as defaults. - Removed the ...-argument from `simEpidataCS()`. - The coefficients returned by `simEpidataCS()` are now stored in a vector rather than a list for compatibility with `"twinstim"`-methods. - Argument `cex.fun` of `intensityplot.twinstim()` now defaults to the `sqrt` function (as in `plot.epidataCS()`. # surveillance 1.4 (2012-07-26) ## Synopsis - Besides minor bug fixes, additional functionality has entered the package and a new attempt is made to finally release a new version on CRAN (version 1.3 has not appeared on CRAN), including a proper 'NAMESPACE'. ## New Features - Support for non-parametric back-projection using the function `backprojNP()` which returns an object of the new `"stsBP"` class which inherits from `"sts"`. - Bayesian nowcasting for discrete time count data is implemented in the function `nowcast()`. - Methods for cubature over polygonal domains can now also visualize what they do. There is also a new quasi-exact method for cubature of the bivariate normal density over polygonal domains. The function `polyCub()` is a wrapper for the different methods. - `residuals.twinstim()` and `residuals.twinSIR()`: extract the "residual process", see Ogata (1988). The residuals of `"twinSIR"` and `"twinstim"` models may be checked graphically by the new function `checkResidualProcess()`. ## Significant Changes for `"twinstim"` - Modified arguments of `twinstim()`: new ordering, new argument `nCub.adaptive`, removed argument `typeSpecificEndemicIntercept` (which is now specified as part of the `endemic` formula as `(1|type)`). - Completely rewrote the `R0`-method (calculate "trimmed" and "untrimmed" *R_0* values) - The "trimmed" `R0` values are now part of the result of the model fit, as well as `bbox(W)`. The model evaluation environment is now set as attribute of the result if `model=TRUE`. - New predefined spatial kernel: the Lomax power law kernel `siaf.lomax()` - `plot`-methods for `"twinstim"` (`intensityplot()` and `iafplot()`) - `as.epidataCS()` now auto-generates the stop-column if this is missing - `print`-method for class `"summary.epidataCS"` - `[`- and subset-method for `"epidataCS"` (subsetting `...$events`) - `plot`-method for `"epidataCS"` ## Minor Changes - Improved documentation for the new functionalities. - Updated references. - `twinSIR`'s `intensityPlot` is now a method of the new S3-generic function `intensityplot`. # surveillance 1.3 (2011-04-25) ## Synopsis - This is a major release integrating plenty of new code (unfortunately not all documented as good as it could be). This includes code for the `"twinstim"` and the `"hhh4"` model. The `"twinSIR"` class of models has been migrated from package **RLadyBug** to **surveillance**. It may take a while before this version will become available from CRAN. ## Significant Changes - Renamed the `"week"` slot of the `"sts"` S4 class to `"epoch"`. All saved data objects have accordingly be renamed, but some hassle is to be expected if one you have old `"sts"` objects stored in binary form. The function `convertSTS()` can be used to convert such "old school" `"sts"` objects. - Removed the functions `algo.cdc()` and `algo.rki()`. ## New Features - Support for `"twinSIR"` models (with associated `"epidata"` objects) as described in Höhle (2009) has been moved from package **RLadyBug** to **surveillance**. That means continuous-time discrete-space SIR models. - Support for `"twinstim"` models as described in Meyer et al (2012). That means continuous-time continuous-space infectious disease models. - Added functionality for non-parametric back projection (`backprojNP()`) and now-casting (`nowcast()`) based on `"sts"` objects. # surveillance 1.2-2 - Replaced the deprecated `getSpPPolygonsLabptSlots()` calls by `coordinates()` when plotting the map slot. - Minor proof-reading of the documentation. - Added an argument `"extraMSMargs"` to the algo.hmm function. - Fixed bug in `outbreakP()` when having observations equal to zero in the beginning. Here, $\hat{\mu}^{C1}$ in (5) of Frisen et al (2008) is zero and hence the log-based summation in the code failed. Changed to product as in the original code, which however might be less numerically stable. - Fixed bug in stcd which added one to the calculated index of idxFA and idxCC. Thanks to Thais Rotsen Correa for pointing this out. # surveillance 1.2-1 (2010-06-10) - Added `algo.outbreakP()` (Frisen & Andersson, 2009) providing a semiparametric approach for outbreak detection for Poisson distributed variables. - Added a pure R function for extracting ISO week and year from Date objects. This function (isoWeekYear) is only called if `"%G"` and `"%V"` format strings are used on Windows (`sessionInfo()[[1]]$os == "mingw32"`) as this is not implemented for `"format.Date"` on Windows. Thanks to Ashley Ford, University of Warwick, UK for identifying this Windows specific bug. - For `algo.farrington()` a faster fit routine `"algo.farrington.fitGLM.fast"` has been provided by Mikko Virtanen, National Institute for Health and Welfare, Finland. The new function calls `glm.fit()` directly, which gives a doubling of speed for long series. However, if one wants to process the fitted model output some of the GLM routines might not work on this output. For backwards compatibility the argument `control$fitFun = "algo.farrington.fitGLM"` provides the old (and slow) behaviour. # surveillance 1.1-6 (2010-05-25) - A few minor bug fixes - Small improvements in the C-implementation of the `twins()` function by Daniel Sabanés Bové fixing the segmentation fault issue on 64-bit architectures. # surveillance 1.1-2 (2009-10-15) - Added the functions categoricalCUSUM and LRCUSUM.runlength for the CUSUM monitoring of general categorical time series (binomial, beta-binomial, multinomial, ordered response, Bradley-Terry models). - Added the functions pairedbinCUSUM and pairedbinCUSUM.runlength implementing the CUSUM monitoring and run-length computations for a paired binary outcome as described in Steiner et al. (1999). - Experimental implementation of the prospective space-time cluster detection described in Assuncao and Correa (2009). - Added a `demo("biosurvbook")` containing the code of an upcoming book chapter on how to use the surveillance package. This contains the description of ISO date use, negative binomial CUSUM, run-length computation, etc. From an applicational point of view the methods are illustrated by Danish mortality monitoring. - Fixed a small bug in algo.cdc found by Marian Talbert Allen which resulted in the control$m argument being ignored. - The constructor of the sts class now uses the argument `"epoch"` instead of weeks to make clearer that also daily, monthly or other data can be handled. - Added additional epochAsDate slot to sts class. Modified plot functions so they can handle ISO weeks. - algo.farrington now also computes quantile and median of the predictive distribution. Furthermore has the computation of reference values been modified so its a) a little bit faster and b) it is also able to handle ISO weeks now. The reference values for date t0 are calculated as follows: For i, i=1,..., b look at date t0 - i*year. From this date on move w months/weeks/days to the left and right. In case of weeks: For each of these determined time points go back in time to the closest Monday - Renamed the functions obsinyear to epochInYear, which now also handles objects of class Date. # surveillance 1.0-2 (2009-03-06) - Negative Binomial CUSUM or the more general NegBin likelihood ratio detector is now implemented as part of algo.glrnb. This includes the back calculation of the required number of cases before an alarm. - Time varying proportion binomial CUSUM. # surveillance 0.9-10 - Current status: Development version available from - Rewriting of the plot.sts.time.one function to use polygons instead of lines for the number of observed cases. Due cause a number of problems were fixed in the plotting of the legend. Plotting routine now also handles binomial data, where the number of observed cases y are stored in `"observed"` and the denominator data n are stored in `"populationFrac"`. - Problems with the aggregate function not operating correctly for the populationFrac were fixed. - The `"rogerson"` wrapper function for algo.rogerson was modified so it now works better for distribution `"binomial"`. Thus a time varying binomial cusum can be run by calling `rogerson( x, control(..., distribution="binomial"))` - An experimental implementation of the twins model documented in Held, L., Hofmann, M., Höhle, M. and Schmid V. (2006). A two-component model for counts of infectious diseases, Biostatistics, 7, pp. 422--437 is now available as algo.twins. # surveillance 0.9-9 (2008-01-21) - Fixed a few small problems which gave warnings in the CRAN distribution # surveillance 0.9-8 (2008-01-19) - The algo_glrpois function now has an additional `"ret"` arguments, where one specifies the return type. The arguments of the underlying c functions have been changed to include an additional direction and return type value arguments. - added restart argument to the algo.glrpois control object, which allows the user to control what happens after the first alarm has been generated - experimental algo.glrnb function is added to the package. All calls to algo.glrpois are now just alpha=0 calls to this function. However, the underlying C functions differentiate between poisson and negative case surveillance/MD50000644000176200001440000005741714615346213013301 0ustar liggesusers472c98a214e77359639fdd5a1145284d *DESCRIPTION 8e42e193a1e08e5cf67db9b68ea9c8c6 *NAMESPACE 8f822f60553dc5709b6d17992b41c6f0 *NEWS.md ed6d9ff44df6c59f9f7a5d0fe41de0b3 *R/AllClass.R ee065c99904e25293039a3729e81a3df *R/AllGeneric.R f3624431582d5bcaffb1374bc2f72557 *R/LRCUSUM.runlength.R 0a9a2ee345d98404fbfec562639cee36 *R/addSeason2formula.R aa76ffe9106f413caeca6e046077b167 *R/algo_bayes.R 5ccfda9d59370beb819079be1a71d400 *R/algo_call.R df5365682b9ce64fe2f628bfe5cf2848 *R/algo_cdc.R 1501b12a6cbcc82f72983006f2491f4b *R/algo_cusum.R 76288ac2e6cc9bc16613de9de3515445 *R/algo_farrington.R 1e69afc8a2822e14df2d8d92d83dfd5b *R/algo_glrnb.R 94230463643b06384deed43ef3e9a0bc *R/algo_hmm.R e41d32428002e89cd00597b240b23216 *R/algo_outbreakP.R 7e59e5a1fd0c57754e6f123e04014da9 *R/algo_rki.R 8341a4cdd77a8f34813f1e8c3c3060a1 *R/algo_rogerson.R 94ee0d1256cb17cc542c66192bf98f83 *R/algo_twins.R 842aece8798f40aedaae4dbf8b499665 *R/backprojNP.R 129a8634d63797eeb0e96ef7d40a045a *R/boda.R c25f8b4bb4e2d4611520296e0fc83aac *R/bodaDelay.R b7cde54c917c298070d08e71f98fb7b7 *R/calibration.R 3d1e63fc9377ca0384c7e8ebc0588387 *R/calibration_null.R aba20d89c4c58354444ed763e8c3640d *R/catCUSUM.R 51e2a7edc231c5b7c09d1e042733e7af *R/checkDerivatives.R d9b04a88446501b386e9131b52de7daf *R/clapply.R 7c0f9e2b072fcfcdad9a641c6d2646ff *R/disProg.R f95fa669a61db3ffab41ebc7608b530a *R/earsC.R 3072861cbd9e9b69b158e4f7737d6eed *R/epidata.R a2690576fcdd6f36bbf06ebb6fc4254c *R/epidataCS.R 415fdaff2d22a76eaf973b2cdacdcadc *R/epidataCS_aggregate.R 035d098db7083790a8d5fad3a85b7f5c *R/epidataCS_animate.R 36ffb11b05439ef6fd484a6886d32d55 *R/epidataCS_methods.R 1cacbde157a0b8bdf2ce11c61b92d2be *R/epidataCS_plot.R 491998f588913def16fb23a3f5901586 *R/epidata_animate.R b3b8371ed2efd7f6c8c7cfc83bad012e *R/epidata_plot.R f850f75151375aca1038356a78167bae *R/fanplot.R 11505acf2f9df8da82b7a995c7749d14 *R/farringtonFlexible.R dc25e670264995ba857dd2d1252c1686 *R/formatPval.R 3b2b41811955b4d807ee2bf331fee0c0 *R/functionTable.R 06cd410a82f296f84de6f5f83b793247 *R/gd.R 399b72fce1537556f8b88fa3207718d7 *R/glm_epidataCS.R c943c1aa26803747980b9ec8bb14ae79 *R/graphs.R 3fce7ba1440c82058c4b5e9ca8c3be07 *R/hcl.colors.R 5ac8db2408240fb3f9c1ad696774e2c5 *R/hhh4.R 9870cd9332a62a0bb8bbe51b4efc08e7 *R/hhh4_W.R d4067f22f0eb59ec31478489612fe5f3 *R/hhh4_W_np.R 2143521731299c86cbf6e35242d0428f *R/hhh4_W_powerlaw.R 52f4635978f1b412a7f8b7df6391a8eb *R/hhh4_amplitudeShift.R a4a1c015ab01b0584709a6a47d420752 *R/hhh4_calibration.R 09dd85a9861f610b18ffc03df17567b2 *R/hhh4_methods.R 4f2691e773bd2f9200944a7f8f44bd21 *R/hhh4_oneStepAhead.R 623e9131fad72d578143ce979074fe37 *R/hhh4_plot.R 7e8e9c7f24ebd69744452b075766b65d *R/hhh4_simulate.R c90d90273baea9e9e7cef1ed6ab84ba2 *R/hhh4_simulate_plot.R c6cf6d45c8c0984848b5406f4d72a62c *R/hhh4_simulate_scores.R 6048188022d59e99502d095aadb7bfdd *R/intersectPolyCircle.R d2343ded6d3d37b1f9eff2fc6803de16 *R/isScalar.R 264aee3c6902ee22e5ebb0e1f75647c7 *R/isoWeekYear.R f3c8f40f53f76718e60b4e1362212d92 *R/knox.R 3270bc41969ab64fd4b5f0ec8ba3cb1e *R/ks.plot.unif.R 5ca5773978739bc0eefa765f74693c29 *R/linelist2sts.R 1bd1d40e721c7ff2e8b12784cd618b12 *R/magic.dim.R 6c6ae43c0ca87d3c8de9456c7b527cc2 *R/makeControl.R fdef58b2077783d39c05cd74e306477e *R/nowcast.R fbfc6becc6c959e6692c21107aefb8bf *R/options.R 7cebe7dde9b1a3356996faa56d80630e *R/pairedbinCUSUM.R 0af0bbbb4a1709fe4d5a84b3b21a8e42 *R/permutationTest.R 38af5d6e1a2d93d5b20e2a8fe95ce8c9 *R/pit.R d889846110caef5ca462711c3feff29a *R/plapply.R a2d3b157dba1df89498a7058291aabc2 *R/plot.survRes.R c65fe2d78a51bad4f4b6a7861d944a26 *R/scores.R d76738240acf75767e17440185a3503a *R/sim_background.R 6afde3cf790bed8521960bea4f209b54 *R/sim_pointSource.R 9dcd70a562a9cb1bc9f5e0776c91c2d6 *R/spatial_tools.R 6571f294cec62ced49dce0d11b377d94 *R/stK.R 3d02709e13a3775595b87d2ca37073b7 *R/stcd.R 6ad2788b392adb7a00ab984a5d8f6a01 *R/sts.R 51c8d382619c1f5398f98582f1a0cbaa *R/stsBP.R bcc44552f7c75e73241562acb98e92d7 *R/stsNC.R 08e4d5d1280117596e43d2629346ef55 *R/stsNClist_animate.R be7b375474846e8c95b5d44da35ed8ee *R/sts_animate.R b5359ada15b3bc5f992669d5c279e287 *R/sts_coerce.R 67f925ce5d0690299a87e7eb297b77b4 *R/sts_creation.R 106e464a6419ebf6a41c6d916022eecb *R/sts_ggplot.R 2c00c931f4d0fd00632767437cad2ad6 *R/sts_observation.R e3fc5471a0507efecbd96b6abf8d69b3 *R/sts_toLatex.R 2bfb735fc8d1e21d7d0b3d21fe8c73ba *R/stsplot_space.R c96004646311b81211ba0d81f7637764 *R/stsplot_spacetime.R 19ad745d61cea5be5952f637b1d8260a *R/stsplot_time.R 800b11aeac754cb920addce281e8bf92 *R/sysdata.rda 8100c99b8be621bb8ded3676d3497588 *R/twinSIR.R 7c5e579c38f131ff7adbc5eafd48ccaa *R/twinSIR_helper.R 18e2690b86ac849b22d954c1236fee8c *R/twinSIR_intensity.R 51ae5e9e26c62b52a73c18f4c8dc9540 *R/twinSIR_methods.R 6c7f98ef764380dcae74499a7275bffe *R/twinSIR_profile.R d3e0803224911b205d5b194b43d101f1 *R/twinSIR_simulation.R bd210e1d61eda15817a3a87d13ee2f8a *R/twinstim.R 7f1551908dcd640aedd5bed3f07f4c56 *R/twinstim_epitest.R 0be0bee73bda08d6e6449e50c2ca4043 *R/twinstim_helper.R 40738afb1993a458b104f3c1b774a2c9 *R/twinstim_iafplot.R 95b35cad1bd43dc60f99e56a94f302da *R/twinstim_intensity.R 386ec077fc647018f315bfd6187e69c7 *R/twinstim_methods.R 63b23b1d655f13ec3615673a3a285492 *R/twinstim_siaf.R a536d26a521389ad87b7ff4b83f94e45 *R/twinstim_siaf_exponential.R f7d983596a61c27d75507ef840fa459f *R/twinstim_siaf_gaussian.R f5df6f9cb6cb12747d7aee4af9e0b966 *R/twinstim_siaf_polyCub_iso.R e0db3f82715cf32858b62d338a98f4b5 *R/twinstim_siaf_powerlaw.R e9e70ea17571ad1ce867a7222e4474c6 *R/twinstim_siaf_powerlaw1.R a636e37149f70b7fa0901be557dd0237 *R/twinstim_siaf_powerlawL.R 02f5edebe054f387d8338a0719b71952 *R/twinstim_siaf_step.R 03f7bff1a73f0fae5af8e3bf059d85e8 *R/twinstim_siaf_student.R 3e8c3ef49dbbb81890ad459cabb1a171 *R/twinstim_simulation.R 719a694d264e4e4ce6b52f0fdde7f9e8 *R/twinstim_step.R 20e77210362149a51e0b1ab2ea9ba9d4 *R/twinstim_tiaf.R 3bbb7aff389e653fe8a471dd7ebc02b7 *R/twinstim_tiaf_exponential.R 7a57a31e1fd0dd4f9be1322e8950dc41 *R/twinstim_tiaf_step.R 66c8f5943e735ed454540387ec0567fc *R/untie.R d8c7d51a6043e8ce9ac1f495cf18b408 *R/wrap_univariate.R 3ec92a90ee285de374f0c47c5a6d8c65 *R/zzz.R 9f44c7d34a3203e479f9b2e16e922f55 *build/partial.rdb fbcfbc6788c1c6cf2a6ee00ff1f633a5 *build/vignette.rds 39cd4adbe3c05e3bed5a29e962a30724 *data/MMRcoverageDE.RData bc57ed2de6c59d625e8ff1dc4bcc534d *data/abattoir.RData 8f11226dce910b95b8ef780e1e087340 *data/campyDE.RData a5d19dc926e0079295e7bbb807b71183 *data/deleval.RData 74396784d70b77ce6f94f6895118168f *data/fluBYBW.RData 7f00d8ec6194adc54678c9ad5aa684a4 *data/fooepidata.RData 154bd5f0caec21664a3b42caf7990582 *data/h1_nrwrp.RData 731c70fffa23b3683391557f47000132 *data/ha.RData f13e5e8fff2b55cb8df0169792c821eb *data/ha.sts.RData 836e9f6eb2993c4dbf7f4b975d78eb35 *data/hagelloch.RData d86889b540c46c9b9ea2b42e5dfd3bcc *data/hepatitisA.RData 2aa9e24781d83436f2daaf4db6b788b5 *data/husO104Hosp.RData 21ee61986db098e9710044f7d4e070dd *data/imdepi.RData 73d0974a388e8c0c76d62d296fbe4118 *data/imdepifit.RData 3723c7f472e9782de2011d7885218586 *data/influMen.RData d7e124e76fd06d35ac3de97cfb3ca0d8 *data/k1.RData 1173ed2c8b616486e274967c6a97ce8f *data/m1.RData f4ae714001625bb89963fe0e4e2e9a77 *data/m2.RData b21b89d9b8dab8750e93f944fc30cac1 *data/m3.RData ec915cd8e2ce14bfd9a8de11bdba92ad *data/m4.RData 728cf151f5516831158588b57d194cd9 *data/m5.RData b1313db9d37f054c5185cea5fc215ca0 *data/measles.weser.RData 9b38f5dd970f407ef6eb0197c9f428f8 *data/measlesDE.RData ee301860324a41505ad334d75bbeec9c *data/measlesWeserEms.RData 6e88fa261848741a2927e8a0208c176c *data/meningo.age.RData 32eef47d250194f5decca9c2e78126ae *data/momo.RData 0c08f2d5d556db1d91f1c6a3d3125d70 *data/n1.RData 029fff2b44242b6fc032dd4abb839207 *data/n2.RData 9b33e305674dc2bd24e465592a88e4e1 *data/q1_nrwh.RData f19779c068198733db7f1c95cecc19db *data/q2.RData 8f41ddc82674072f51517b573007112f *data/rotaBB.RData 66338d480d9d6f7541d6b7f5690f1c94 *data/s1.RData 08135e0c5091d08becc0ceb7bb3bb3c4 *data/s2.RData a24280cb563d545fa1f547b5c0959962 *data/s3.RData e6867f5f8b49d82d5d56a6ba21bc79bc *data/salmAllOnset.RData 7090e08b0233c23ad3f7e77f9375ac4a *data/salmHospitalized.RData 177f82cfd139402fd4c68014c65faf46 *data/salmNewport.RData ebc818bb58803591f7ade0b04d956926 *data/salmonella.agona.RData f976fafb219fc04b750e0e4117ba054c *data/shadar.RData c68d5433a3091d766465ac1990b4f697 *data/stsNewport.RData 9b358dfd9210aec26b9017eaa925dbdf *demo/00Index 959fe3c7db5b1e48763fb9674aaec1e3 *demo/biosurvbook.R 47c6e51b6c8209afd4cb452bd313f116 *demo/cost.R 7d1d442f26f72377b7d25f8edc67472f *demo/fluBYBW.R 78bec1f9c129db1bad4fdf06cefb436d *demo/v77i11.R d5aba8730e290193725a19f8fbe5a8af *inst/CITATION 8d9979fc071c6da83979388bf68c2e0f *inst/THANKS 8c1cd745f2001217d3121dd175df5b41 *inst/doc/glrnb.R a8bd52794a60119c5229bd518401f026 *inst/doc/glrnb.Rnw c3550423a14e4a4babe8cf38118e4df6 *inst/doc/glrnb.pdf 2df8066632dc9761c8cc5511fc3b03c6 *inst/doc/hhh4.R 4369adf11e22ece987d07c99ec77f62a *inst/doc/hhh4.Rnw a287f2905187e784c4dc37493ff4fb54 *inst/doc/hhh4.pdf bb2b05e156972819b86fe4d6b61fc082 *inst/doc/hhh4_spacetime.R 395ebcfa94f8617ab924a38a5bc0b1cb *inst/doc/hhh4_spacetime.Rnw 320ede45d7c7694e150414193a225756 *inst/doc/hhh4_spacetime.pdf 4edb89d834b59b5211938ee0ff3fe99d *inst/doc/monitoringCounts-cache/boda.RData bdc19a2321ee2e240ffd30b14a651291 *inst/doc/monitoringCounts-cache/boda.covars.RData a0517d2448a2a64e964b1446ebad59e1 *inst/doc/monitoringCounts-cache/fPlot.R 664394dce780b1fd632e74f6801fb445 *inst/doc/monitoringCounts-cache/fPlot1.pdf d34a1009c327f20686d10285dafcd151 *inst/doc/monitoringCounts-cache/fPlot2.pdf 9b73583a5d7a84a28bcf69929cb7dc97 *inst/doc/monitoringCounts-cache/pMC.RData ff930addd050724319372eb0a51ca2c6 *inst/doc/monitoringCounts-cache/pMarkovChain.RData eb3fcf8975f94ef6e4b3653ddb798f38 *inst/doc/monitoringCounts.R e10765beb701282e8aaf56eac8dc371a *inst/doc/monitoringCounts.Rnw 4ee6d724aa088faf27c7322d53199f8c *inst/doc/monitoringCounts.pdf d7d2e50792f1583414bcffe9a622a994 *inst/doc/surveillance.R 036c06d02b04c33b8a1d044701b1a099 *inst/doc/surveillance.Rnw 1c3c20152caa25cfeaede0698dd50471 *inst/doc/surveillance.pdf fe0cf08a224669c084910c5c19f6ff4a *inst/doc/twinSIR.R 076701f6ce0f86827255115b326737ff *inst/doc/twinSIR.Rnw 0c1774bd6c2c019472d40d2b98df11a8 *inst/doc/twinSIR.pdf b5e043a28fa5d1cc94706c5f55765d1d *inst/doc/twinstim.R 0ecd3abba40c3df7b035e17f58cf757d *inst/doc/twinstim.Rnw 447a00a294133be336b55ca6f4f9e4e5 *inst/doc/twinstim.pdf 01e880f0dcb85b78a1c2be29862d464f *inst/extdata/counts_flu_BYBW.txt 7368155ea8525f22a4039c99101fa209 *inst/extdata/neighbourhood_BYBW.txt 57facd5cc2cdaadf18538e6742158b88 *inst/extdata/population_2001-12-31_BYBW.txt 3cfa159d1f9810e948068fb7831fdc2c *inst/extdata/salmonella.agona.txt 6eb9544879e01cf717999ddf45b1b6b3 *inst/jags/bhpm.bugs 61faaa303d7c5e4e88278dc1026f1463 *inst/shapes/berlin.dbf 6d61b4a4e2ba0197aed611390250f5a8 *inst/shapes/berlin.sbn 4215c8c5fc9aa22fa9277267cbe20746 *inst/shapes/berlin.sbx 57a46753e569f12f8aa48540429444d4 *inst/shapes/berlin.shp 2a29a0fdf04dc5a01a3614ef1096f7e5 *inst/shapes/berlin.shx 34b31cd3345ec052d3dd8b4f0e82aa3b *inst/shapes/districtsD.RData 5346614fe27b9a22fbab5574730f3e80 *man/LRCUSUM.runlength.Rd da3bc824858d6e87e0431999212fd5b9 *man/MMRcoverageDE.Rd 4cf4eca7a105c2e9462693e77a0eabf0 *man/R0.Rd 050377f810eaa62351b28927e9374dc7 *man/abattoir.Rd 2848385412e408f9e1bed525e6e11e97 *man/addFormattedXAxis.Rd e6547bc50ce28d932f9db601a9846cea *man/addSeason2formula.Rd 3d6c91a49a2ee75dcd4003e547a5e01e *man/aggregate.disProg.Rd 88a75c42b99a537c63e7e4a904560c12 *man/algo.bayes.Rd c6d8c06962807df078f2610e30be6fac *man/algo.call.Rd 033587fd70f868905f41528fbc355efb *man/algo.cdc.Rd 4d7ead0bcf51bafaac8d95d8dce3bfc6 *man/algo.compare.Rd f4e54c0a5665fcaaa21ddd7191a77730 *man/algo.cusum.Rd 5ec04c8523c263296dea647181da58ad *man/algo.farrington.Rd ddcf60189b825884760b09415b2f3ab0 *man/algo.farrington.assign.weights.Rd 7bb1f601a5b9c9f0066794189b8b9e17 *man/algo.farrington.fitGLM.Rd 40e0e5e1b7ae6b2e14185260b17dc3f3 *man/algo.farrington.threshold.Rd 166b3ab4810f58756f079ed2cc27236c *man/algo.glrnb.Rd 1cde4bc0ba34c511b862efcfbbdd54c8 *man/algo.hmm.Rd 0d428d1b622d3e0b5af5b6e57cc350f3 *man/algo.outbreakP.Rd 1c14da8f510127817dfea1b516fb9645 *man/algo.quality.Rd 9aa31b24d5cacb427a415a9918ae682a *man/algo.rki.Rd da4008df52c951adc80a2917c5065470 *man/algo.rogerson.Rd f4f6d4df5bf74c1f371a618c27760603 *man/algo.summary.Rd f572fe08d5629a1bf20d38b8843bdde3 *man/algo.twins.Rd eeaee3c5d0e839ef8d6ef83358ffc575 *man/all.equal.Rd e67c69a89d7f343368d411318ea15e3f *man/animate.Rd 2f342e80d91a6dbe78e7e24537c6d3fd *man/anscombe.residuals.Rd 785860fc36b43605c8b250287cd51081 *man/arlCusum.Rd 90f82ed1fbc5f249f942842579b6b680 *man/backprojNP.Rd 09fb22575940aa22c3c155be4ea1ffc8 *man/bestCombination.Rd 7a9fc710bfbc1f0ad0bf34c9d1b76003 *man/boda.Rd 34485f58f151d34ba3f1dcfa1a39e660 *man/bodaDelay.Rd 0874769b413334054106966019cf51b9 *man/calibration.Rd 2b0798d1c1710dd011826721277b3433 *man/campyDE.Rd 1fcbaa6af01c48a52d01c89cbb10427f *man/categoricalCUSUM.Rd b0ba22ae8444a11148025d4b488041fd *man/checkResidualProcess.Rd 5d88a6b64a591a16ff7ae3bb6d0640d9 *man/clapply.Rd 27ef79270ab1c247cc00247a25d96b65 *man/coeflist.Rd d0775edaa087c7a57489d52a7efeb5b2 *man/create.disProg.Rd 7992038b0381a299a5df980c93f233ed *man/deleval.Rd c629a963f9544c4a04d5317179f49c89 *man/disProg2sts.Rd 92e64494efcbbdc583d23a95669268c7 *man/discpoly.Rd 7e557bf7fb1f3dbe5a489e40d68a325c *man/earsC.Rd 728bd2a8a659c11075611c3669f1e6e5 *man/epidata.Rd c0c4a51ad21bd0dfa9af5e566cfe1ecf *man/epidataCS.Rd 1f40157ee8f19816f850474e8f075988 *man/epidataCS_aggregate.Rd a1e9ecc63b73b39b2a172fdf08bb9436 *man/epidataCS_animate.Rd 0ff2c126e9c41509f69d9dd9acecb79c *man/epidataCS_permute.Rd 27062e0c2bd3896847e3fdf910b25ae9 *man/epidataCS_plot.Rd a0f9cef66a8af934d310060a8334355c *man/epidataCS_update.Rd a659ea8198fa6e1c7647d93eda15ef0f *man/epidata_animate.Rd 36024c712cad9831fbad480990582fa0 *man/epidata_intersperse.Rd 7f561161b773aa45f18e830e134562d0 *man/epidata_plot.Rd d2b4122305af3b0f63e2ae4054678422 *man/epidata_summary.Rd f660b9a5c95cb8dccef722142b27d61c *man/estimateGLRNbHook.Rd ebd996999531f5af119ee0372e72dee6 *man/fanplot.Rd 39fe4f6170373a00c234fb840cf53829 *man/farringtonFlexible.Rd 08907427c5e4283cebd965c020e5c314 *man/find.kh.Rd 3c3d71c027b25bd7e483d9a1d67bc46b *man/findH.Rd 02198b044625da79eea751c4ee82481f *man/findK.Rd ddb3d56573409758309dc77fcc6167c8 *man/fluBYBW.Rd 35959432528cea29d91c98631f48a5ce *man/formatDate.Rd c5abd4fb24364663f13b98295ac4c169 *man/formatPval.Rd bbc2674f910b27a89531cb996da4bd83 *man/glm_epidataCS.Rd c72ebd8fbcae1fe3c6ae91847272823b *man/ha.Rd 6a15d58f4e360cf8b7512fed272538ef *man/hagelloch.Rd 8066e0538b9ee18e9b2931bdfaa84719 *man/hcl.colors.Rd 7a992f9f050d817daf9f0246b1e3fbbb *man/hepatitisA.Rd 0236fe8b2873cc351f71cbd12fb17ed3 *man/hhh4.Rd bbf8626c9737a80ef7a692983edf7a0f *man/hhh4_W.Rd f9e8e43bedfa2dfeb84960c46eb1d3f9 *man/hhh4_W_utils.Rd fdca3cebc9604fb81337f01f95814376 *man/hhh4_formula.Rd 1c15fda9ab678d54eabd76c0805c3e15 *man/hhh4_internals.Rd a3c16c2f903f72411e0264b05ee4769b *man/hhh4_methods.Rd fcdd4b5f73d929fc78a68c001a4cb0e4 *man/hhh4_plot.Rd 8fb1b58e0b6fd421b429b03ef7e57dc2 *man/hhh4_predict.Rd 14c9a722630e56f7156dd067e4adbb87 *man/hhh4_simulate.Rd 37e8818db7bc3b3eb7bc989df91cabb9 *man/hhh4_simulate_plot.Rd 279abc77faba3b31df25d62e691693e7 *man/hhh4_simulate_scores.Rd 7ba1bb375aeab457b03623aedbad22af *man/hhh4_update.Rd 5fab8c95ce67a4cd36d06b4a2d34dac1 *man/hhh4_validation.Rd 8f810db3c775c085ade43c8819330eb8 *man/husO104Hosp.Rd dbe20f7f5daaeda91ffa1a822933d449 *man/imdepi.Rd cc94629ca2e37c180d5f08559e03daad *man/imdepifit.Rd cc422432b310f004e3d5991bef193c17 *man/influMen.Rd df35457995a21853415e9af9e3ada813 *man/intensityplot.Rd f71531b2e29ad4331156482341abcb0c *man/intersectPolyCircle.Rd 9d04dc30b863d2a5961247f906ec770c *man/isScalar.Rd 309e45227b48d8fe47a5339a9a280fb3 *man/isoWeekYear.Rd cf51118964e8d55b3deea528e8d99e3f *man/knox.Rd b86fed4ba97df16a1f23d8e45ea34084 *man/ks.plot.unif.Rd de1975c73a2b0eef065a9e4bff55af7e *man/layout.labels.Rd 9624bee6d800b64b6738f9c907adfd67 *man/linelist2sts.Rd 17f5b85b7cb882718c731629138d1909 *man/m1.Rd e831ef76471e187bb7a545b785e2ddc6 *man/macros/linkSPclass.Rd a63d24fd9d091edd1b287d6318ddc918 *man/magic.dim.Rd 009451e574a67923f32f3214980e58b7 *man/makeControl.Rd cc5b26350902fbcfb6adba326a4f8512 *man/marks.Rd 2dfac57188f4b900e2a097cc99e0b8e5 *man/measles.weser.Rd 07ae1224b6941931d59c94539f6ca70d *man/measlesDE.Rd 8a19319cc63bbd198c252b7eff1cbd6b *man/meningo.age.Rd 62e6b96a58f4f6e15b1b13b7ca07866e *man/momo.Rd a7eb27ba88b0d787664f03cf93b46661 *man/multiplicity.Rd dbf787f778527ecad92a7fb8f13b51c3 *man/multiplicity.Spatial.Rd 8e3c9cf6bf6f6e5a79ddb661903bd5c0 *man/nbOrder.Rd 6b18377a598a34b01feb00ed95a14354 *man/nowcast.Rd fd45cd568a0e93bf30d1baec9288709d *man/pairedbinCUSUM.Rd a5eca8f84a6bf82cee45d9de8816e515 *man/permutationTest.Rd 4811ad6bf8795ac03660e55fbbadf561 *man/pit.Rd 11b744e8ea5343fa92699dc3fdca883a *man/plapply.Rd 863d8501d0fe26417a0c0004110e063c *man/plot.atwins.Rd 6aa6a9c1e79b08b2c47947bf7ed60b6e *man/plot.disProg.Rd 8485f24d1e08b929a3980bac6ccf55e7 *man/plot.survRes.Rd 314c502ba6061317abc0a2158e1cdc8e *man/poly2adjmat.Rd 917f484c70a09db6f15e3e5601c1dcdc *man/polyAtBorder.Rd 8fcfd9d601274b15b0a2f2caa71b218c *man/primeFactors.Rd 747966188aa39b5600347f2d98d32aae *man/print.algoQV.Rd 172a18b1405eeafce04a8e024987d8a3 *man/ranef.Rd b46adeab66b32aa5d6b491505fc5e2a3 *man/refvalIdxByDate.Rd 92f2406fd4e5054765f773c694681498 *man/residualsCT.Rd a1250eb509f187d201ee78fec0493dfd *man/rotaBB.Rd 7831a80a59e3bc6a8e91a79beede0e02 *man/runifdisc.Rd 7a98ef0577af730874fae7ba3f654f7d *man/salmAllOnset.Rd 6b358e25a5c89bf0c0ccfd9d5242a614 *man/salmHospitalized.Rd 9f591f22a9787714196f8666077d70a3 *man/salmNewport.Rd 88281097eee429efba0848a940880151 *man/salmonella.agona.Rd e1a425cd33ad772bbcd5b0f6cbc1ce76 *man/scores.Rd 360616c5ec2d33ffd151c4bcd4475bfc *man/shadar.Rd 851df66c37bee39c65a35828dc53977f *man/sim.pointSource.Rd 7b234e3fd1d07a268a6e33ffe065f21f *man/sim.seasonalNoise.Rd 299c4f5619ff961bffb3f805be930428 *man/stK.Rd bb60b62230fdc91b7f6ad6a09d9bfc02 *man/stcd.Rd cce2cf8bbfab4ab2f43d4aeff63ec43a *man/sts-class.Rd 873204f207dfb51caaa746ee2bd10fdc *man/stsAggregate.Rd 92bc8b486c1551513c683d3134e55fb3 *man/stsBP-class.Rd afc6185f42991ce2230cc226587d207b *man/stsNC-class.Rd f656722930a11c5dcbb28a5632441a9f *man/stsNClist_animate.Rd a05769d4bb4c67bd1183a6da950cb703 *man/stsNewport.Rd 819cbd32ad7b842a2f9c560c4d1737ee *man/stsSlots.Rd d5e4f5446da8cdcd0a3d40fd8fd4bd82 *man/stsXtrct.Rd c921e5e6b872539cf7d2acfe54d1ce32 *man/sts_animate.Rd b9d74adc5b1197257a5ee1717d3af17a *man/sts_creation.Rd 0d5e0028548ef56c9408befd077bb724 *man/sts_ggplot.Rd 1fafa879eeb6b5dfde50318d58533448 *man/sts_observation.Rd 0223c2f41f0232fd62fba15122b5d460 *man/sts_tidy.Rd 7d3778864eba4b8dfead80fc72e5fe88 *man/stsplot.Rd f5afba56d5d1951ad86503d61a4938d5 *man/stsplot_space.Rd 3bb496f3a4aca2c3d0e42bcc3c3ee2f2 *man/stsplot_spacetime.Rd c89a16add020d8295da252a656429ad0 *man/stsplot_time.Rd df71a0d4a79ec3dc95e56d86924b8eff *man/surveillance-defunct.Rd 2dcb6982ed381289a7d2533ddbcc2b59 *man/surveillance-package.Rd 4c686d4834a9c759e3ba459465903539 *man/surveillance.options.Rd ad45a8392dd21419f6118c1b759862d0 *man/toLatex.sts.Rd 2e6829e75c6185f3c1283dfd792cc2e6 *man/twinSIR.Rd 7a7c977c0e0b512e2c30b096d05377de *man/twinSIR_cox.Rd a60c1b1d277524ad5f92e8ff879b0be8 *man/twinSIR_exData.Rd 210c13e7cfca2cb979af1a6ed86027a5 *man/twinSIR_intensityplot.Rd ac127bfd7a894989c7f62ca19f19a713 *man/twinSIR_methods.Rd 465865dfa7ef7034cd01ab5ec249d478 *man/twinSIR_profile.Rd f1ba40ff889856e9de2be2bf8e9a2209 *man/twinSIR_simulation.Rd 833c9dcf9d7b6ee084e62c4b854ffdb0 *man/twinstim.Rd 1dff218bed0ce1c8dbf07c76eef6f6b1 *man/twinstim_epitest.Rd eaeec4e023c8537132ac1cf2225e5b07 *man/twinstim_iaf.Rd 64af818d69a2d1b67801af21f612d705 *man/twinstim_iafplot.Rd 9f9acb11b2b0ef15b9dc9763a13d137f *man/twinstim_intensity.Rd 3e59d1c908180389f867dd1fb9d01507 *man/twinstim_methods.Rd 30954d87702654fac94fb92a7170e848 *man/twinstim_plot.Rd deccdbc7fadc8a8ab8f543917de0df87 *man/twinstim_profile.Rd b855e3b6b307ac0933aa0e1f4e473944 *man/twinstim_siaf.Rd c625195f02f957511cfe5a8d6cef950a *man/twinstim_siaf_simulatePC.Rd 714402ea446e5356cecc449f7c1f4b40 *man/twinstim_simEndemicEvents.Rd e3e5edde09850cf976458be0ab6f711e *man/twinstim_simulation.Rd 779060593a223d40c3081cc5ce97d401 *man/twinstim_step.Rd 3977925a2d40feb47561093bd350f57b *man/twinstim_tiaf.Rd c69279fdb57e6373842394a5b4cde78c *man/twinstim_update.Rd 975a536efd321e30e81b66a17c395843 *man/unionSpatialPolygons.Rd 75faa38e6248352866b32184ea0258c6 *man/untie.Rd 1e0120a66f2f6d29accf4d672087655e *man/wrap.algo.Rd 382c0cb7667e12641bbe5fd11a082880 *man/zetaweights.Rd b03b552e9456a164ef4b99a3a73f1e24 *src/backproj.cc d32a71533d7c17c93dc7bca321d0ae7d *src/determineSources.cc 9e68ba946fad8879c9495c4452620618 *src/gsl_wrappers.h 96bbf029ea6b7a73eca060c386787180 *src/init.c e5e7a5ed1f118b381777c489145b23ee *src/ks.c d228c2598eb5c27013e4a8c936234596 *src/stcd-assuncaocorrea.cc 5a2196ac3bbf315e7b9849e60e9f7c05 *src/stcd-assuncaocorrea.h e5123438985a99647bfd7e962137d422 *src/surveillance.c d70bc510b0b2be4ad184fce3d2febd1b *src/twins.cc 978f19dcf1b11af13798fd9097a93a66 *src/twinstim_siaf_polyCub_iso.c 1086b93e93ee5d1fd3cccd0ce5d19c66 *tests/testthat/test-algo.glrnb.R 38f727ac5fbb64fa67d4444556f0c6d8 *tests/testthat/test-bodaDelay.R 80e3e4ed5012169b68e69f0c1a57bceb *tests/testthat/test-calibration.R 2af7bb18b631aea749921aaef1a49b22 *tests/testthat/test-createLambda.R 5494bdb98b2b8171f9696f0f89499318 *tests/testthat/test-determineSources.R aedeb6dc40c500a96881265f112dbfb4 *tests/testthat/test-earsC.R 47a0a48c5d3d765c96bc7d48095331ac *tests/testthat/test-farringtonFlexible.R 8e3c562317e1e4f06f165c01a723ce9c *tests/testthat/test-formatDate.R 2ccc1cb821b5873d767d9060bb992e13 *tests/testthat/test-hhh4+derivatives.R 45c55df2b6fd0384f33172fef63c1fa3 *tests/testthat/test-hhh4_ARasNE.R 8d09bf25a69f34992cd25b19b7e0191c *tests/testthat/test-hhh4_NA.R 3bea03f070e2c7d7e7c21cc0c029b810 *tests/testthat/test-hhh4_NegBinGrouped.R e1051ecf1cbb778d01df69c6b00ac283 *tests/testthat/test-hhh4_offsets.R 747445546c91691be896c2f56069596b *tests/testthat/test-hhh4_weights.R 14104b54a1c8e721aa670259b7771443 *tests/testthat/test-nbOrder.R cf09694c1c9a7d6d0bcdf548155a574a *tests/testthat/test-plapply.R 9187eaf509a5f5a7d0e336c0895c90e4 *tests/testthat/test-siafs.R 9d1bb1687954e12fc5049605a4d859e2 *tests/testthat/test-sts.R fe2feecf7c827ef7404801c1a22aae61 *tests/testthat/test-tiafs.R 39f30f8c12c9c4d9f18cfc518f238f01 *tests/testthat/test-toLatex.sts.R 3b9a45b8b700334fab77fdfc83cb58f3 *tests/testthat/test-twinstim_misc.R b0b804273cc346be4f2e0e39b41eb225 *tests/testthat/test-twinstim_score.R d2cba3fd04dc6277a1b559072f58e46e *tests/tinytest.R a8bd52794a60119c5229bd518401f026 *vignettes/glrnb.Rnw 96cc4acacf3d57d8ec0338709aea5b27 *vignettes/hhh4-cache.RData 4369adf11e22ece987d07c99ec77f62a *vignettes/hhh4.Rnw 71a631c17142aaba9f6efe3c2a848215 *vignettes/hhh4_spacetime-cache.RData 395ebcfa94f8617ab924a38a5bc0b1cb *vignettes/hhh4_spacetime.Rnw 4edb89d834b59b5211938ee0ff3fe99d *vignettes/monitoringCounts-cache/boda.RData bdc19a2321ee2e240ffd30b14a651291 *vignettes/monitoringCounts-cache/boda.covars.RData a0517d2448a2a64e964b1446ebad59e1 *vignettes/monitoringCounts-cache/fPlot.R 664394dce780b1fd632e74f6801fb445 *vignettes/monitoringCounts-cache/fPlot1.pdf d34a1009c327f20686d10285dafcd151 *vignettes/monitoringCounts-cache/fPlot2.pdf 9b73583a5d7a84a28bcf69929cb7dc97 *vignettes/monitoringCounts-cache/pMC.RData ff930addd050724319372eb0a51ca2c6 *vignettes/monitoringCounts-cache/pMarkovChain.RData e10765beb701282e8aaf56eac8dc371a *vignettes/monitoringCounts.Rnw a9ab2abc6a6ffb5673d71b1315e1f357 *vignettes/monitoringCounts.bib dc63fd5df5a8dc56b76f010a0e15f6e7 *vignettes/references.bib 262547eb2d830b485312fc5b0e96e545 *vignettes/surveillance-cache.RData 8c8d8d317e914924a81719a1ada39a16 *vignettes/surveillance-hmm.pdf 036c06d02b04c33b8a1d044701b1a099 *vignettes/surveillance.Rnw 01099bf54aeaf8a031440283443e994a *vignettes/twinSIR-cache.RData 076701f6ce0f86827255115b326737ff *vignettes/twinSIR.Rnw a0200179a7c9c1d1047950e776fd9084 *vignettes/twinstim-cache.RData 0ecd3abba40c3df7b035e17f58cf757d *vignettes/twinstim.Rnw surveillance/inst/0000755000176200001440000000000014615167600013731 5ustar liggesuserssurveillance/inst/THANKS0000644000176200001440000000075214517725527014661 0ustar liggesusers## The authors would like to thank the following people ## for ideas, discussions, testing and feedback: Doris Altmann Johannes Bracher Caterina De Bacco Johannes Dreesman Johannes Elias Marc Geilhufe Jim Hester Kurt Hornik Mayeul Kauffmann Junyi Lu Lore Merdrignac Tim Pollington Marcos Prates André Victor Ribeiro Amaral Brian D. Ripley François Rousseu Barry Rowlingson Christopher W. Ryan Klaus Stark Yann Le Strat André Michael Toschke Wei Wei George Wood Achim Zeileis Bing Zhang surveillance/inst/doc/0000755000176200001440000000000014615167600014476 5ustar liggesuserssurveillance/inst/doc/surveillance.Rnw0000644000176200001440000005523414615162374017676 0ustar liggesusers%\VignetteIndexEntry{Getting started with outbreak detection} \documentclass[a4paper,11pt]{article} \usepackage[T1]{fontenc} \usepackage{graphicx} \usepackage{natbib} \bibliographystyle{apalike} \usepackage{lmodern} \usepackage{amsmath} \usepackage{amsfonts,amssymb} \newcommand{\pkg}[1]{{\bfseries #1}} \newcommand{\surveillance}{\pkg{surveillance}} \usepackage{hyperref} \hypersetup{ pdfauthor = {Michael H\"ohle and Andrea Riebler and Michaela Paul}, pdftitle = {Getting started with outbreak detection}, pdfsubject = {R package 'surveillance'} } \title{Getting started with outbreak detection} \author{ Michael H{\"o}hle\thanks{Author of correspondence: Department of Statistics, University of Munich, Ludwigstr.\ 33, 80539 M{\"u}nchen, Germany, Email: \texttt{hoehle@stat.uni-muenchen.de}} , Andrea Riebler and Michaela Paul\\ Department of Statistics\\ University of Munich\\ Germany } \date{17 November 2007} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sweave %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \usepackage{Sweave} %Put all in another directory \SweaveOpts{prefix.string=plots/surveillance, width=9, height=4.5} \setkeys{Gin}{width=1\textwidth} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initial R code %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <>= library("surveillance") options(SweaveHooks=list(fig=function() par(mar=c(4,4,2,0)+.5))) options(width=70) ## create directory for plots dir.create("plots", showWarnings=FALSE) ###################################################################### #Do we need to compute or can we just fetch results ###################################################################### CACHEFILE <- "surveillance-cache.RData" compute <- !file.exists(CACHEFILE) message("Doing computations: ", compute) if(!compute) load(CACHEFILE) @ \begin{document} \fbox{\vbox{\small \noindent\textbf{Disclaimer}: This vignette reflects package state at version 0.9-7 and is hence somewhat outdated. New functionality has been added to the package: this includes various endemic-epidemic modelling frameworks for surveillance data (\texttt{hhh4}, \texttt{twinSIR}, and \texttt{twinstim}), as well as more outbreak detection methods (\texttt{glrnb}, \texttt{boda}, and \texttt{farringtonFlexible}). These new features are described in detail in \citet{meyer.etal2014} and \citet{salmon.etal2014}, respectively. %and corresponding vignettes are included in the package; %see \texttt{vignette(package = "surveillance")} for an overview. Note in particular that use of the new \texttt{S4} class \texttt{sts} instead of \texttt{disProg} is encouraged to encapsulate time series data. }} {\let\newpage\relax\maketitle} \begin{abstract} \noindent This document gives an introduction to the \textsf{R} package \surveillance\ containing tools for outbreak detection in routinely collected surveillance data. The package contains an implementation of the procedures described by~\citet{stroup89}, \citet{farrington96} and the system used at the Robert Koch Institute, Germany. For evaluation purposes, the package contains example data sets and functionality to generate surveillance data by simulation. To compare the algorithms, benchmark numbers like sensitivity, specificity, and detection delay can be computed for a set of time series. Being an open-source package it should be easy to integrate new algorithms; as an example of this process, a simple Bayesian surveillance algorithm is described, implemented and evaluated.\\ \noindent{\bf Keywords:} infectious disease, monitoring, aberrations, outbreak, time series of counts. \end{abstract} \newpage \section{Introduction}\label{sec:intro} Public health authorities have in an attempt to meet the threats of infectious diseases to society created comprehensive mechanisms for the collection of disease data. As a consequence, the abundance of data has demanded the development of automated algorithms for the detection of abnormalities. Typically, such an algorithm monitors a univariate time series of counts using a combination of heuristic methods and statistical modelling. Prominent examples of surveillance algorithms are the work by~\citet{stroup89} and~\citet{farrington96}. A comprehensive survey of outbreak detection methods can be found in~\citep{farrington2003}. The R-package \texttt{surveillance} was written with the aim of providing a test-bench for surveillance algorithms. From the Comprehensive R Archive Network (CRAN) the package can be downloaded together with its source code. It allows users to test new algorithms and compare their results with those of standard surveillance methods. A few real world outbreak datasets are included together with mechanisms for simulating surveillance data. With the package at hand, comparisons like the one described by~\citet{hutwagner2005} should be easy to conduct. The purpose of this document is to illustrate the basic functionality of the package with R-code examples. Section~\ref{sec:data} contains a description of the data format used to store surveillance data, mentions the built-in datasets and illustrates how to create new datasets by simulation. Section~\ref{sec:algo} contains a short description of how to use the surveillance algorithms and illustrate the results. Further information on the individual functions can be found on the corresponding help pages of the package. \section{Surveillance Data}\label{sec:data} Denote by $\{y_t\>;t=1,\ldots,n\}$ the time series of counts representing the surveillance data. Because such data typically are collected on a weekly basis, we shall also use the alternative notation $\{y_{i:j}\}$ with $j=\{1,\ldots,52\}$ being the week number in year $i=\{-b,\ldots,-1,0\}$. That way the years are indexed such that most current year has index zero. For evaluation of the outbreak detection algorithms it is also possible for each week to store -- if known -- whether there was an outbreak that week. The resulting multivariate series $\{(y_t,x_t)\>; t=1,\ldots,n\}$ is in \texttt{surveillance} given by an object of class \texttt{disProg} (disease progress), which is basically a \texttt{list} containing two vectors: the observed number of counts and a boolean vector \texttt{state} indicating whether there was an outbreak that week. A number of time series are contained in the package (see \texttt{data(package="surveillance")}), mainly originating from the SurvStat@RKI database at \url{https://survstat.rki.de/} maintained by the Robert Koch Institute, Germany~\citep{survstat}. For example the object \texttt{k1} describes cryptosporidiosis surveillance data for the German federal state Baden-W\"{u}rttemberg 2001-2005. The peak in 2001 is due to an outbreak of cryptosporidiosis among a group of army soldiers in a boot camp~\citep{bulletin3901}. <>= data(k1) plot(k1, main = "Cryptosporidiosis in BW 2001-2005") @ For evaluation purposes it is also of interest to generate surveillance data using simulation. The package contains functionality to generate surveillance data containing point-source like outbreaks, for example with a Salmonella serovar. The model is a Hidden Markov Model (HMM) where a binary state $X_t, t=1,\ldots,n$, denotes whether there was an outbreak and $Y_t$ is the number of observed counts, see Figure~\ref{fig:hmm}. \begin{figure}[htb] \centering \includegraphics[width=.75\textwidth]{surveillance-hmm} \caption{The Hidden Markov Model} \label{fig:hmm} \end{figure} The state $X_t$ is a homogeneous Markov chain with transition matrix \begin{center} \begin{tabular}{c|cc} $X_t\backslash X_{t+1}$ & 0 & 1\\ \hline $0$ & $p$ & $1 - p$ \\ $1$ & $1 - r$ & $r$ \end{tabular} \end{center} Hence $1-p$ is the probability to switch to an outbreak state and $1-r$ is the probability that $X_t=1$ is followed by $X_{t+1}=1$. Furthermore, the observation $Y_t$ is Poisson-distributed with log-link mean depending on a seasonal effect and time trend, i.e.\ \[ \log \mu_t = A \cdot \sin \, (\omega \cdot (t + \varphi)) + \alpha + \beta t. \] In case of an outbreak $(X_t=1)$ the mean increases with a value of $K$, altogether \begin{equation}\label{eq:hmm} Y_t \sim \operatorname{Po}(\mu_t + K \cdot X_t). \end{equation} The model in (\ref{eq:hmm}) corresponds to a single-source, common-vehicle outbreak, where the length of an outbreak is controlled by the transition probability $r$. The daily numbers of outbreak-cases are simply independently Poisson distributed with mean $K$. A physiologically better motivated alternative could be to operate with a stochastic incubation time (e.g.\ log-normal or gamma distributed) for each individual exposed to the source, which results in a temporal diffusion of the peak. The advantage of (\ref{eq:hmm}) is that estimation can be done by a generalized linear model (GLM) using $X_t$ as covariate and that it allows for an easy definition of a correctly identified outbreak: each $X_t=1$ has to be identified. More advanced setups would require more involved definitions of an outbreak, e.g.\ as a connected series of time instances, where the number of outbreak cases is greater than zero. Care is then required in defining what a correctly identified outbreak for time-wise overlapping outbreaks means. In \surveillance\ the function \verb+sim.pointSource+ is used to simulate such a point-source epidemic; the result is an object of class \verb+disProg+. \label{ex:sts} <<>>= set.seed(1234) sts <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) @ <>= plot(sts) @ \section{Surveillance Algorithms}\label{sec:algo} Surveillance data often exhibit strong seasonality, therefore most surveillance algorithms only use a set of so called \emph{reference values} as basis for drawing conclusions. Let $y_{0:t}$ be the number of cases of the current week (denoted week $t$ in year $0$), $b$ the number of years to go back in time and $w$ the number of weeks around $t$ to include from those previous years. For the year zero we use $w_0$ as the number of previous weeks to include -- typically $w_0=w$. Altogether the set of reference values is thus defined to be \[ R(w,w_0,b) = \left(\bigcup\limits_{i=1}^b\bigcup\limits_{j=\,-w}^w y_{-i:t+j}\right) \cup \left(\bigcup_{k=-w_0}^{-1} y_{0:t+k}\right) \] Note that the number of cases of the current week is not part of $R(w,w_0,b)$. A surveillance algorithm is a procedure using the reference values to create a prediction $\hat{y}_{0:t}$ for the current week. This prediction is then compared with the observed $y_{0:t}$: if the observed number of cases is much higher than the predicted number, the current week is flagged for further investigations. In order to do surveillance for time $0:t$ an important concern is the choice of $b$ and $w$. Values as far back as time $-b:t-w$ contribute to $R(w,w_0,b)$ and thus have to exist in the observed time series. Currently, we have implemented four different type of algorithms in \surveillance. The Centers for Disease Control and Prevention (CDC) method~\citep{stroup89}, the Communicable Disease Surveillance Centre (CDSC) method~\citep{farrington96}, the method used at the Robert Koch Institute (RKI), Germany~\citep{altmann2003}, and a Bayesian approach documented in~\citet{riebler2004}. A detailed description of each method is beyond the scope of this note, but to give an idea of the framework the Bayesian approach developed in~\citet{riebler2004} is presented: Within a Bayesian framework, quantiles of the predictive posterior distribution are used as a measure for defining alarm thresholds. The model assumes that the reference values are identically and independently Poisson distributed with parameter $\lambda$ and a Gamma-distribution is used as Prior distribution for $\lambda$. The reference values are defined to be $R_{\text{Bayes}}= R(w,w_0,b) = \{y_1, \ldots, y_{n}\}$ and $y_{0:t}$ is the value we are trying to predict. Thus, $\lambda \sim \text{Ga}(\alpha, \beta)$ and $y_i|\lambda \sim \text{Po}(\lambda)$, $i = 1,\ldots,{n}$. Standard derivations show that the posterior distribution is \begin{equation*} \lambda|y_1, \ldots, y_{n} \sim \text{Ga}(\alpha + \sum_{i=1}^{n} y_i, \beta + n). \end{equation*} Computing the predictive distribution \begin{equation*} f(y_{0:t}|y_1,\ldots,y_{n}) = \int\limits^\infty_0{f(y_{0:t}|\lambda)\, f(\lambda|y_1,\ldots,y_{n})}\, d\lambda \end{equation*} we get the Poisson-Gamma-distribution \begin{equation*} y_{0:t}|y_1,\ldots,y_{n} \sim \text{PoGa}(\alpha + \sum_{i=1}^{n} y_i, \beta + n), \end{equation*} which is a generalization of the negative Binomial distribution, i.e.\ \[ y_{0:t}|y_1,\ldots,y_{n} \sim \text{NegBin}(\alpha + \sum_{i=1}^{n} y_i, \tfrac{\beta + n}{\beta + n + 1}). \] Using the Jeffrey's Prior $\text{Ga}(\tfrac{1}{2}, 0)$ as non-informative Prior distribution for $\lambda$ the parameters of the negative Binomial distribution are \begin{align*} \alpha + \sum_{i=1}^{n} y_i &= \frac{1}{2} + \sum_{y_{i:j} \in R_{\text{Bayes}}}\!\! y_{i:j} \quad % \intertext{and} \quad\text{and}\quad \frac{\beta + n}{\beta + n + 1} = \frac{|R_{\text{Bayes}}|}{|R_{\text{Bayes}}| + 1}. \end{align*} Using a quantile-parameter $\alpha$, the smallest value $y_\alpha$ is computed, so that \begin{equation*} P(y \leq y_\alpha) \geq 1-\alpha. \end{equation*} Now \begin{equation*} A_{0:t} = I(y_{0:t} \geq y_\alpha), \end{equation*} i.e. if $y_{0:t}\geq y_\alpha$ the current week is flagged as an alarm. As an example, the \verb+Bayes1+ method uses the last six weeks as reference values, i.e.\ $R(w,w_0,b)=(6,6,0)$, and is applied to the \texttt{k1} dataset with $\alpha=0.01$ as follows. <>= k1.b660 <- algo.bayes(k1, control = list(range = 27:192, b = 0, w = 6, alpha = 0.01)) plot(k1.b660, disease = "k1") @ Several extensions of this simple Bayesian approach are imaginable, for example the inane over-dispersion of the data could be modeled by using a negative-binomial distribution, time trends and mechanisms to correct for past outbreaks could be integrated, but all at the cost of non-standard inference for the predictive distribution. Here simulation based methods like Markov Chain Monte Carlo or heuristic approximations have to be used to obtain the required alarm thresholds. In general, the \verb+surveillance+ package makes it easy to add additional algorithms -- also those not based on reference values -- by using the existing implementations as starting point. The following call uses the CDC and Farrington procedure on the simulated time series \verb+sts+ from page~\pageref{ex:sts}. Note that the CDC procedure operates with four-week aggregated data -- to better compare the upper bound value, the aggregated number of counts for each week are shown as circles in the plot. <>= cntrl <- list(range=300:400,m=1,w=3,b=5,alpha=0.01) sts.cdc <- algo.cdc(sts, control = cntrl) sts.farrington <- algo.farrington(sts, control = cntrl) @ <>= if (compute) { <> } @ <>= par(mfcol=c(1,2)) plot(sts.cdc, legend.opts=NULL) plot(sts.farrington, legend.opts=NULL) @ Typically, one is interested in evaluating the performance of the various surveillance algorithms. An easy way is to look at the sensitivity and specificity of the procedure -- a correct identification of an outbreak is defined as follows: if the algorithm raises an alarm for time $t$, i.e.\ $A_t=1$ and $X_t=1$ we have a correct classification, if $A_t=1$ and $X_t=0$ we have a false-positive, etc. In case of more involved outbreak models, where an outbreak lasts for more than one week, a correct identification could be if at least one of the outbreak weeks is correctly identified, see e.g.\ \citet{hutwagner2005}. To compute various performance scores the function \verb+algo.quality+ can be used on a \verb+survRes+ object. <<>>= print(algo.quality(k1.b660)) @ This computes the number of false positives, true negatives, false negatives, the sensitivity and the specificity. Furthermore, \texttt{dist} is defined as \[ \sqrt{(Spec-1)^2 + (Sens - 1)^2}, \] that is the distance to the optimal point $(1,1)$, which serves as a heuristic way of combining sensitivity and specificity into a single score. Of course, weighted versions are also imaginable. Finally, \texttt{lag} is the average number of weeks between the first of a consecutive number of $X_t=1$'s (i.e.\ an outbreak) and the first alarm raised by the algorithm. To compare the results of several algorithms on a single time series we declare a list of control objects -- each containing the name and settings of the algorithm we want to apply to the data. <>= control <- list( list(funcName = "rki1"), list(funcName = "rki2"), list(funcName = "rki3"), list(funcName = "bayes1"), list(funcName = "bayes2"), list(funcName = "bayes3"), list(funcName = "cdc", alpha=0.05), list(funcName = "farrington", alpha=0.05) ) control <- lapply(control, function(ctrl) { ctrl$range <- 300:400; return(ctrl) }) @ % In the above, \texttt{rki1}, \texttt{rki2} and \texttt{rki3} are three methods with reference values $R_\text{rki1}(6,6,0)$, $R_\text{rki2}(6,6,1)$ and $R_\text{rki3}(4,0,2)$, all called with $\alpha=0.05$. The \texttt{bayes*} methods use the Bayesian algorithm with the same setup of reference values. The CDC method is special since it operates on aggregated four-week blocks. To make everything comparable, a common $\alpha=0.05$ level is used for all algorithms. All algorithms in \texttt{control} are applied to \texttt{sts} using: <>= algo.compare(algo.call(sts, control = control)) @ <>= if (compute) { acall <- algo.call(sts, control = control) } print(algo.compare(acall), digits = 3) @ A test on a set of time series can be done as follows. Firstly, a list containing 10 simulated time series is created. Secondly, all the algorithms specified in the \texttt{control} object are applied to each series. Finally the results for the 10 series are combined in one result matrix. <>= #Create 10 series ten <- lapply(1:10,function(x) { sim.pointSource(p = 0.975, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7)}) @ <>= #Do surveillance on all 10, get results as list ten.surv <- lapply(ten,function(ts) { algo.compare(algo.call(ts,control=control)) }) @ <>= if (compute) { <> } @ <>= #Average results algo.summary(ten.surv) @ <>= print(algo.summary(ten.surv), digits = 3) @ A similar procedure can be applied when evaluating the 14 surveillance series drawn from SurvStat@RKI~\citep{survstat}. A problem is however, that the series after conversion to 52 weeks/year are of length 209 weeks. This is insufficient to apply e.g.\ the CDC algorithm. To conduct the comparison on as large a dataset as possible the following trick is used: The function \texttt{enlargeData} replicates the requested \texttt{range} and inserts it before the original data, after which the evaluation can be done on all 209 values. <>= #Update range in each - cyclic continuation range = (2*4*52) + 1:length(k1$observed) control <- lapply(control,function(cntrl) { cntrl$range=range;return(cntrl)}) #Auxiliary function to enlarge data enlargeData <- function(disProgObj, range = 1:156, times = 1){ disProgObj$observed <- c(rep(disProgObj$observed[range], times), disProgObj$observed) disProgObj$state <- c(rep(disProgObj$state[range], times), disProgObj$state) return(disProgObj) } #Outbreaks outbrks <- c("m1", "m2", "m3", "m4", "m5", "q1_nrwh", "q2", "s1", "s2", "s3", "k1", "n1", "n2", "h1_nrwrp") #Load and enlarge data. outbrks <- lapply(outbrks,function(name) { data(list=name) enlargeData(get(name),range=1:(4*52),times=2) }) #Apply function to one one.survstat.surv <- function(outbrk) { algo.compare(algo.call(outbrk,control=control)) } @ <>= algo.summary(lapply(outbrks,one.survstat.surv)) @ <>= if (compute) { res.survstat <- algo.summary(lapply(outbrks,one.survstat.surv)) } print(res.survstat, digits=3) @ In both this study and the earlier simulation study the Bayesian approach seems to do quite well. However, the extent of the comparisons do not make allowance for any more supported statements. Consult the work of~\citet{riebler2004} for a more thorough comparison using simulation studies. <>= if (compute) { # save computed results save(list=c("sts.cdc","sts.farrington","acall","res.survstat", "ten.surv"), file=CACHEFILE) tools::resaveRdaFiles(CACHEFILE) } @ \section{Discussion and Future Work} Many extensions and additions are imaginable to improve the package. For now, the package is intended as an academic tool providing a test-bench for integrating new surveillance algorithms. Because all algorithms are implemented in R, performance has not been an issue. Especially the current implementation of the Farrington Procedure is rather slow and would benefit from an optimization possible with fragments written in C. One important improvement would be to provide more involved mechanisms for the simulation of epidemics. In particular it would be interesting to include multi-day outbreaks originating from single-source exposure, but with delay due to varying incubation time~\citep{hutwagner2005} or SEIR-like epidemics~\citep{andersson2000}. However, defining what is meant by a correct outbreak identification, especially in the case of overlapping outbreaks, creates new challenges which have to be met. \section{Acknowledgements} We are grateful to K.\ Stark and D.\ Altmann, RKI, Germany, for discussions and information on the surveillance methods used by the RKI. Our thanks to C.\ Lang, University of Munich, for his work on the R--implementation and M. Kobl, T. Schuster and M. Rossman, University of Munich, for their initial work on gathering the outbreak data from SurvStat@RKI. The research was conducted with financial support from the Collaborative Research Centre SFB 386 funded by the German research foundation (DFG). \bibliography{references} \end{document} surveillance/inst/doc/hhh4_spacetime.pdf0000644000176200001440000122235714615167602020074 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4490 /Filter /FlateDecode /N 83 /First 698 >> stream x\isF6-ck++qb9^)#[@" I$wOOO $ ^ºBB8[B [U (|!E(x22FB{ -B+%LUTn@}_X|(Y k(kF 4 ǹ.7B Г H_xm@'r0 - REP t4ŭ`ѸEp!]rn@D75z 8bC* &=x貐&YiX0o" gQ]@GAM!I<J!0 @YY4(+- H8-(ke m@ւvҨȂF ( Ͱl,rlVܙ$˴mN2=yN<_ aOt]:CӍ75y%L/ú^̢>t>Mj \GK`)oF=7Tj>D_Of4|y HU Bţ'LBZz i0{6*jڅo~,HW8dB|?֥1mNoN.C7Yiv]Ȭ*y`Tz]Uz]ud։ꚨDEw&ŷ(;" "<4U|=xv|2LwR]M=gzzVdOJ֡ds'2g$E66N,zԞxR#pDp^, B5|;X/YTܥ=ue[ĔE"8DHj 1΄=ĵulB̧w<"H)$ &QD'6` ^Эn]\s%1Dt]tIw=m:ϪYo ido4./ZM ;bC=fO~b1{~f/ ;e{ް_ـ Fu5a D`:boِ g/.l*dt4h٘f'l `g!:>f{6alʦl6cE[3:o&D]Lq%B=}=U~g_jvN ,YÚN}h?NSdbbW `G'UgF~OLgMQ@ ]xGtI=4g.`)2zx4=3Bsu"EN%e}!&>xÏ'&~GӦ^^X")|&DRJywCR`청s PPe?*CE>3t3A4dcKi`_ֵ yL{;}Fo]F l&~5PO[ ֐uo g&d,ZQ.J{ź_k{;$"۰g?͋ڧ*2m7,])U<2w%UoS4uDVRBMCFp1>l̐mW3E]/yǗ !t}_#SHICE&iZ[m{9-lkF&a5karM%NJap㫆{6(MZ=8fs~.^Ĩa<$Wr.*+)}ɵYN2'.#ee Ks&ƀla(X($Ҥ('L&aLI"<5JʤMTr}2lbBO}~Gm =/Oui;nћh&׳*f]f\#UUR$_u~>boK%"Җ (t P8.P1"Ӝ-h\f8ZQ{M !v~Lv 12)r@F@b8*%QRwe4g.Knyk47pטV\88@ɒ1 0%d쒩Ja Z[cJI^r(jT &EɃ%D%!YC OV\,mc(:ӂ!-RH9o柌=<9z^ܻh⸜ϐ1 ý^Eg\hZ#JxѥM{c`4,4i\o'/K*1l \<1\l3y"6i< 'abƷQeT*OPz mDHq{o/ EK怑ԈhoHJin\Iycx:ɇҴ/55۱DC2G8 D/5radVfZy*LI0E[0-!ת)x rJ ckx֔Ls 1%mA$xSȒ",i1WIPZ.LyUjS׌ٴ.LuKZAa[㭻NSsJ Z0T^L$^/)R83kh x"kB |)}ra(\R(rQQmCXyzӣYɌ l6Ly{^Q r}qm7>W]I8w$c<Ez13UVgb&Lnv"Ħ&jUyVuX~ү(2:~ ޕqka{^`".q((; #H'\i=\;.gVŷcC l#,QpJ*w7D̄v{i+2G[I8YGZ,J苜@G=AĿkqeörӧfb[Eߧ&? "Kc<Nt\XsIe8)EXCNIh :QE-)Wo0U^ A#F#-ÇlTMt\#Wͨn*Rk㔺EB!8MrBC -.$ yBd:^ j 6L) RH7 N'G#?[@-ɠq 5T-?Tաplw&8 ".i+b9\VPpghF)JԐu25h^{+WNZ3YghJ@$EwT;g1ۄxE̕endstream endobj 85 0 obj << /Subtype /XML /Type /Metadata /Length 1614 >> stream GPL Ghostscript 9.55.0 areal time series of counts, endemic-epidemic modeling, infectious disease epidemiology, branching process with immigration 2024-05-03T16:06:57+02:00 2024-05-03T16:06:57+02:00 LaTeX with hyperref hhh4: Endemic-epidemic modeling of areal count time seriesSebastian Meyer, Leonhard Held, Michael Höhle endstream endobj 86 0 obj << /Type /ObjStm /Length 4399 /Filter /FlateDecode /N 83 /First 779 >> stream x\rH}cwT=!/cyTz(HB[Ks H tQØ&vyQ9q+#FZQ"RqmKTF"٪X8. jy=-/xY,'mЮ`'5]O'~"Wg9?n_^yz +,42] |-:{uZa9[=G1-E"[ɋ22`C/숽bel.YήV]V [+Yǜݲɦ Fv<ɮ*QP0'"~ I.Bt]6BIMz!;-V+Z$-nO?zZ$0 [Ó_NߞclžRE @bv搟]#}vd )X O.[ ^Q\فPCg2>Z>mPN[HX,nTܐKuZ{K5g#]j|o-nYK2_+6|Y/\Xw$nyHo;$DoSmB;PMe;_Ύ>ʛoӋd:{N;aV]kۙ=Y ?  \.⹁՗)&M,y9_i1]Y~|d+p@u Eb?Y# v(a`e~=}4٨QV>Ž$vn`hʳ\m=[N$ a왔J%`kuIǨj4z,o-HSS|MrSj rgWӤtnuLŞM7`y z>fഗW9zg9x쿰)޲-1)Db7}9[*<ýFj`tحlg4_jIyٚޏ[e统?/6v]ol{6p <\FTwen\qacU{$Yڧ ZV#+)Wlrd7M RøaߎE  BUTѐ.@`||{~~rQ@sڰm){?{tYGI/ng=,~mH$q/~[r|;w٤RWhͤ߱  9):Ad0_z8]U`oK7 BK,VR~w)ٍA}6<dz_?mo;0W+ bgLmmš FC[>D>ݧ ?؏E^,q?!e5qIY,& evYfWŴҷ!2MMM؆2U+$у?kpεO>B]sAa .0ax/BLt!v߂W#j̗!A_ (f[>+5LdB5GLDLINʼn5:vNMZR{[̾tMV H玒6s;+)h$RS+t 9 'h Mn0J0E &܄ G\$B G????%_3?a3Ǐ'B|ʽR`gD|w/^wӖ4O1͡QzbbXtRl"SvS{}dgl5.ʺbr7AA`rzA_򲹍5\W y䫕 pw.y ~gbREiQQS9(Vwq8j<_{Ǿ A0QdžsMW䱧ȦFkd-{32vihy>N1&-\`,ʬ_2CeoI0뀉-Bi+"mL1D08[IG bMAuiIJQiB= MRXa4 h@Sdm~H,ФS8kN=4Odl)W%TGbt.=[,|I(Z7$Qu$:4;Jhoݽ)h҆()DI"95QZޏ,e H"qj(C(_>(f`Ҥ_DJBA4DI:i*&$~SE!x9 :> - j#llYc ن( O@TdC.Qfj7 LAPi)Rh i`r -&+cԚ& hEbhr4:7k^l=Z{-Q 7 w{يWn7um+Ӥ=buEGyNI#q͂їؼi&N[%5 udL4Tٲ_>6oʬZ:[ciKr#umBCz?j͔=iUNQ:fs/'{֭˷1eR)h:`š81)q2ౠv+:>zN&B!1Qh&c~/ SLWM< |QB^i i%YdvWaOc24qh8k8I\6O)J̠N"#[d~^^Lo#l4 \Pkk(rs-5M@D6n ->Q ;yE#mqMT$~:=~JA1*%SuCTi)]?Ѹ͗FJIKi'׉OSFp[w4^agScH jxtwzEbzJXL/K2$I0j ،y(," F=(2ӔIr:&μI# :_o"w铺:t.9h4~ɮPH &42NFqzH][vO뢼9f$^VR%&X5s$czljeq\f{ eb'+ɣ![ӻ?<4Y,@7c?7tEh/Hb8KL͓γMO*<(ՐPuBS(Go49bAxAACn#_WW IRR:UztJ ~WW 8|r)@AηD>|8Z$7N#HlRUǦi%LS^#l:u $y-Q+TIB QbLbTH.EJo#߿'u*-0pmCSU7 *hoKG!NtA dfpbendstream endobj 170 0 obj << /Type /ObjStm /Length 3319 /Filter /FlateDecode /N 83 /First 772 >> stream x[moF~[CƗ6vmUfl^eѐ8_,IY"%v86rgvfvٵ2*!3&j3l@hi)%1SF 2$:ii1LkC k"2v J4 /d BȌ.qd4XQdƀ=㈩25tf2̂*.脆l4Cf= 2ϔΠ!3BCeNjYa0Ja3.RW>Ry1"^PCf>`*J,[I+i`,6 >BH|EFȢ"~ ! DƀJf ew #K)Gcd* SE)R&Z*{ XҐ441R $+Ж7F&a4Ҡ5p { u,WjI\ZR?>Z-ȶƕ IN4 A[ia4Ba`یfrt+QRmu 5VWLo3-ҮOb|X~8F `$d=|/2%cI^i@G9}ǫ:qbOL*S_m}'IeqIYеu-q#2PLtxF'G9>Y|4ϯyƟ&Y1;O(^b'ɼZrSq OX&ălXH*Ζ$9+M~~GDhWbuG}~͏OQԾ} јXO6e1p_HIO4'4-AOg>! ]ńVsWOʏ ??1O33|v6^\w]>_|g)3^r~>ł_+Zݲj͉8Ey|eQZ1֒/oJ~CxDޞM /xzQ1ң|a947X,Ӓ2i}Q-莧/@ꤜ`(nz Q9[!ɯ@{ZbMo~ݧbo۾b5nW=Q9Î Ɏ^m} k7PS!u+|䪷 2C6] a ۍ`kA$ň8u3"4)jڈjtQl6mmoR4/(N]gEͳ'/yOb2~tXN6Yuy}^zu|mYﮑgC96Wc_aZI JF󼢩kͷD Q!ݮV_h y[k粘]/f~u7O}Q|$'71_bR;>_>KzJ[ۻ Ϗ}A /O3臦dYW⟜?:k s#b1RN)sYrAFڲ8.f|>wJ7.|7̃њY,t2*f(W"fxhg2Ć)+X0nL yqr>,RN*nR#qP&vt9d-%TZzH +f1K M6)6 Hs?0e5nv5مM25UO%?OJt}<{3gT{quDSX!ZwyŠ(U`I675KT^_$g鮌 3XJN3 ,C*؇Q (48L-s{cYx7}" InWq[;~q~{S)§ -mIʖO8q~-1eP L` :ct mcft)t5am(1'm04`Jو2G ^E-'nGR͔ܰ|fENbY΋˫w/7F!P8YhAluȗC}Wou^K0z%\JZo vԖ<~m v ˋ+iZ lSn#٬:0,+0!1t:t_\="*ͮ-O~V gݶlڬ{rtgS7q&~ˬ9PsRm`x]i|>~Bij])`^<.Uk $]X OFP avv&Rs^0))PLEH X>S"5BtDDH.eT/ =62NJCf+D`/0z&؜,ҞB5O'Fg̪\t?OZ<9 La:݉eLۘeX [ea%eKDŽMj3`FP@vF34aiP#& a=RP,2EPg{cq1[ 9.Ӷ C: قLzmb.g>^9^: T!,UﶪښT}gSm7S~Hb,ت!c-tV 6{͒F;Gdұo-=3_L;ИlIendstream endobj 254 0 obj << /Type /ObjStm /Length 3023 /Filter /FlateDecode /N 81 /First 741 >> stream x[ks_tp̤:6fGnmؒG\\z-ۓqHyqf\-Q8qL{+-{-R:*W$  ^ 6<4'[ia&σ,~Fd +1OyhVV IXbQ kZXLc\M NY<֛0;9xO YAx.$78 _~)7r%~>OZ^IfwLTVE=[jQGu-/.@tЃP 8Psp׮W⫯2;LʯA8 %P.lyܻ1_|,^6[9@y x?XE-yYXG[<4 DvwFl TPA[. aXE1Fq.P3y)Z`I*J;urxj@ݔa*l٬i V+LonAe `W(]gYkVOfj ~}c(Xgl-Y oxӎ&ᘢ[O1Q-&R0x[ei͜U߼Z35ac62]r}MڰVQ| #u9r=IȮ[JҚ&:deo[~C1c,"*r"2}y$u,y=Fn@<;Hr^d_n:>|7l^˻BTM٥~NfFݯ0 h,"g]H,0A|ugܗrU{2՟U3yǗK˿^#Ϛ_Nkb|>7tr2t{ԫU}H[GۓF,j&HьdW>1+`Ce'WոTuuQMjVͫEV] ]xeF4 e !OfW)jRt8Oe֚=*Ǐ?|iߏWW2^=&uBSڣfG?h]R-950C.}&j{X;|Oԓ Jt8ʡ#_ujɀdLʮQ=ᑔF%AZFpIن$Mgrn/ NVCב ^\SRL?Sk{HaтBzPpP(4@y 5=JE I3F&T&zɎE0c dYIcɤl'Rpw6ְem-(q&=e }PxہT%AE%QU3ECș̋`8_2 {.P\$׳=ӂ2={YPFy=u0i^qcb"G@*XE4'QpJ Xܐց IOEnd5Ϛ[݌׫yS^/|1H>LѲHf ˉSvC[s>zD*o #>ڈl)^\Y\p[93΋Z@Yj1^l'yZ}}|?Hu86bӳ0h{m>AJPQ9d. 0Lt:ט%brPvRi11boqF9GqWݧVx'{E*Ps귩fV-h>Ez_o=xI=ϓ`}vTFET{TeL4n)l$LSK2ǻ)z *y&Pf=QO:8 - yE@YC2ڶx'!`j[Xf{6xQoGJ\*=r̺/{|O ws, 5Td 'hvX؍r)D/ c!\K& ߼j]~QUG'bop(v<xv{=_=$Uch?V=anlω1!-5y^Rv('u8TuUGABl}Uq w>]Q;sg`)/䆎J:TFd}܆(§<[[?<1J}=^|kfzqQ/7~O6bRtendstream endobj 336 0 obj << /Filter /FlateDecode /Length 5554 >> stream x\KGr6ۜa4t~aZKƮ8řL-]5ѿ׿'YYU3 bwufddc [v= 9l^zS;n#ӒLsQs"?-p ,)m}sErVȦHU;nMvǟWvkҼb)q. 4:|eLWAa ڀj/jAiډ]{E:bQ'VVjxZHcѪ[˾I[oSɧ<c F.J Un%ˋ?\ѫGV`3Q6͏Xmϒ vw, YT]%^]8HjetHI:@\ CF#)*njJ=Q0_GK2n - /9F0W'v`\Tq~I?:tF,D- ŝC-6:#0 CrU4Y!M? %PX={@ V_h,8dwFf@RZ5"Avy>^oq[`*8ZH.( <ۦnw"w *ǭjgi5D}=Rc.-CGV=wBbֲvw~ $ qچkSKf.F5l 6G᪟ZMմM8ajwASdYC81D!}>tQDKc];j&F' $P;6H>HAS0?1|3UtiO¶2$Ǫ` CwRlJqI[%5~2)a Tw1 \ ^B֐qLtJtۜVG y6PN5Яvl9@〟Cֈ񐞃 ]-i`dD-P@ Kjߺ>CAևazGŲP羽* 5mO cgЁ3A=[lP..U6wTRܽ/'WQ u`-9&W^P{R!iF,}Û1]H +Ȟu9&Λ>т")oDQV c섧@Eiȷ06XLeէ׉9B<&1Ac+9 Jeh8^gI`QԄ^c5J۴(۟ۛS.'X}n0qaB@ǘIyXFx x>tȝp  @B7aGM\8Po"Hd-A*=9Ȏ_7h`돠4Rj]B:GApJ#lڡvޣ3NN{iS&)와j"ASk)pVEg4vej1I}6b|}S?*_,|RM|묟dI~Vs/Jg"Z.dVOmw,PT@QL$KD [$R|c[U02_D/~birI AR\8ͤKaY2MÎEZͮ"$)Wdݵ*YRdp۞iE 6X)nHf=ԊzX'Z"bxCmquiĞ+$Te"teEz:]U=VIȗ% &=ݨ>?^BOh0x "F7eMP6(bK:vL9>Ǝ/c}csͣEJY$oX|` u u0Aaj#t혌I?`,:[+]+#k )?#|pW;}qCni )V|7l%*R,9O1/8TiC1{>>|W+Jn(ѽt3kUE\Р|Z,43B(eZW)enMXehrR\)!9U>opY +ah@E±5QQⅉնyZ2 zqk_ >?ǷtSQHZ(9]l'g O% V_UtQxS]tfcF !vG`QƩ_x20-N5}ؠ#^=!E.1' 2$.fT  r40˛U%YOe}͍]!p]0OLS8#M:ؒ]Nj. K?E0hWBcå9BHvEp] ewFCܿcvI?doCӄ !Z ֠>ER8lQ 䪒ɐEEDiFn w4 8x8'eDM+>%6bjvӴ;ldٕ_u)kfhRu.j̏wc2E\Y br!0PB\;lyV]ߔq* :m0#zWTݳ@ ǧP)W5uF*Mӥm Q&O-^7oDٻo A)k7y=caurڤ`eBmcwDIw4fGβ!kAKAs"}m[-Zb;3M8Uxt]9jpX qX)J(>w `lA7i_..z>+wĄ @UiR ||IEOa 9ʁu(l&Ơƈ+B3<`h5-]G,bLx/cG|W"0^sp ""Vsl\Җ >pHN~71d#V+ lgؒg ]`TP_#g>'CV/vEw ,!擲o8oς_-f-*f>Xz4-Z* Eo}i| WKx9ϛ9iMH n. 1q8o4:5YȒ1=<$Lxf"\H i( -YY 8ȆOLXI@#fBQЉg+tuh.z"?Ia-m.cNQqc[<^V| \E7.L;g hصoEb(u^O~i/Niޞ) RA`OI4tcxh6/|Z|l.G [?K'彀 wj.Isݭ«SfdN.xMN*>i9=lj69 vg4"u613 7cqQ_mxe .Ko%9ӛ}?.&P7рȻ+V1(W50V߻\ݧ'.e-"ֆ#LpO-Z9?2q龿 o^ghDApwᐯs$-/ʕ``UM~ms__oC}hendstream endobj 337 0 obj << /Filter /FlateDecode /Length 6461 >> stream x\Kq֙>(|#:5d*)ZZV+K+F8k;}tfVUzfޕYuXu/b[]<摠oWկJJ%unnE\-> V2v~FHC8H2W/o~:5r{UX;#օ)e $X>ã'?/LQ)Nz9cpL`$#-C,Jy vd=v2ZĪpzʪ»֙jw8N] WDl=eH>lNj`-l7ytRC7eG; eѡU({ԉ'KK!%XB vj/T$n| vɽB{et.4šV*RR |8?Vg,N>CݱAz/JNP-IIC+s~hގ$bX&_ Ec춁a(փ@K*ae_'o<-zD}-a:u7ha,[+`eݘLA]{y=NnLݍ˄m \&MdCHl*`(@`2xv1Y9{#XlwUbw^as;,n_=_ ܡtx#M&z{O gO۞25yGK_<ȂNc>ϖB52t>NKS)YGK0yt?azV{T4i,9/& ۰7(f,l{1-]P8ƀLQ@z&_1zCÏ dJdiYx$ƥu`_xC#ݶ`lݮ7zZE.(Ri4)]ri:2r& @ X,u] g-bi#Syr5ti+DO؛;qP!#<-4~3i%qnl7B mFQBRdB B!$EMqQYm!%F/Y'%bFCih,Kꪂ*@LGf ᒥxbʮLg[r0;>lnbWb1,/MT8s4Ed o#ނ9HBjLՂis(< <8ptw:KP=Ptq̈́Sȃ}(n%IRpS>1h\oD?,4d-?1d( I3 $h;a 0LQ[f.g< 4}ͳLk3>:ZK6 uelz {N拢K Ͻ|6K<F\knA2PHaU4\]?$QSyOI.{9Z 9Q!+(eLJ_TD"Zɠr;.0m7Vp-O9J#$f,R+PuYҁuL@iKjW ,hDR9B[Y>P␔PTf߮]X3EI!'nb_ ~-b>:r.=mHG-{#'1\O"KjZ1qpAL[ahpS3Uܼr/m.}rIL#![Cg}wHHAc/=sfXԗOˋݾz^=U1AYw-/$l-H7[&@Ҽ5$oǪ.%lDV 2_eZ/GLJgSx}MwNЇb(ecb .nV?B@3 4IƹBB؍^MʾYTS|pqtz M!\vvJ8'F(~Ugye q(z]9aA #G/uI7B 6Mκ|O IW@AQW0샶2.[i szz (B,X8i56##%$4LO;dr e7t insJGPI0meXM+1$Q8Ab+qP>a>͜oCۑ6B:~ ^ڋVP7~ =xOXdz}p6leuYZ,YR$jW ¾u{|| 6Vժt""wS#Ha a` lū4a(@ T ΆP)^9I!Z aE "\];0Tr1λL sx*Ӎ`R}kaz"+ae(dsԾv# ,)Xʟ'cҿ;Bڄ8 rC/ @8oBOhdn(z.SL] Y'Ҵ*mPl*mɚ mJ!`5re-}ty@vwxs>Jh8Ǟ$ m<]n`+I,WLpRT^_Oco]Sh!mAcWq<,?彣%j@+(2joCr't!rbJ" %diNf˽|;\58diKǁ,Ys4Vs_PVGڹJFpWCauG\M8B_.4b+ A ?`s|Sx4'O0?_g ҧ@? XY7qx/Ei;v"龊ZgqZJvDj'OXڹ\ ׂQ?AȚ2E fZz:Gc ;zI<}#h-dctXh"нKkb)d֣TrQjc%/jMc),R}%4JM!Yw~3jfN&A,˪se(WgD6Д_RXhj^Ft[Tg}M*hASٞ⯦\+hV0 7 n7瘒f퀘M4{Y9b ܬ0 "bnzPf-x?`q>j,)  I3Cny5.F2՝˥S{8N/E`x E`QPX^8h`}oXHҹ VIK'*61 W= ;6.}?>'lq+e@Sj:*2'g*FG~/TRT> Uђ {*gXoLK7E Pq >td u} T:39Nuڙjq\jp6d0'rowa `_Cd|6X34KЄJڥua1 Htq6YDNja|_UR@z РM5W^11%ZՕa?7b~=8]a7u7&szRj3ùd!c=.C"O>m@y¼$  (t&U]a^沂η>%lȳ춴N<X[0iaJeW6WbG7tX1c+N90^Uq >m!jNEF )DvMy>>N>]y RhJK5&2;ް&&tT&}0 t$^w 6.6mr6KMۓŚƨiߞt Tߓv>X|(*~ʒ ݕ-aRw'F 2!`.VŎCո R=[&b4=!},i`gf_}9NEu02@kzt^{R+C7U-D5g`K~Xmendstream endobj 338 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 8555 >> stream xzXT2 j`K4" Ez/"0a{D^5&D,Xo{Ùs]Z]k2BD"+m|}&Mo \WUk)CShMJ,s_=rĉSƏ'gZ:[Ο`74sveVN\J.cjjicGOþ^(g| 6.8`Q%KC:.sZrU.֮mvzy{^7q)S`>2bdQZxل5fRC,jNP#([j$eGZj KS j EEhxN 2JHP&oآYONBCMqD}"- :x6Z-AY{f@ R4s4lU2x< ,~Vt |<~>϶u*)me[#6Ћ$!'-S>lXH#ѥfQ*plẙXW9)FjZjiE/^4 fY{"75"~?!x%~E8Uv}po+ky(5R^I?4n UU <H|& ŢĘ|h7(?te?r7PH7&3ȞF瓫~s̵Dg^~ŭQ,ҢѰqxL,f^G'к=e"QE:|З(P ]iDc7X֭?6,5m}'Uhs@#DZ3\ul."/yM8:h37Rt'zb9M4wX۞`6\Ixd1ų(BU<;bG4OA6ߣ L)|!9*(kJiD85:_CGv6vq]CC9.[.X6صf[VNwZVf]%{n&I,3b>F BidA&%&*t96AժH(oBRHZo$!Yㅆa$O%3#9;҂״+E_S@&$pfd92$ K{u2#LB:9D+6o]J`1cNd.-UHtPHuˏn|jI\v^bDVVvS0A0NcPARBD!5 hbbP7tZIQ),ﴰi8A>'d7&2dud=Eѥ?dp"J]Wc\N-Ah"N?9b0"ŇkTJă),LC4ooؐ 6/.Y^YX\PE=U ѳ'+\+XT9Yk.b+,x\&Վ[cFcTwDhm!pV ǿNDA,Dk 4bPfDAv{S6^03R5C,]mẠ*<Yw{k;,n$o?xZ]l[jY1l<*Ar|0Lb-#!!Y'h5_`|5$mٴfuRuSsg_+s"bcwiLJ_ Io&tހ\H]ڌtDn_`ɜm#Xtn[#]w)/i`Fied5Vp+ 'rM rY gNA/s)wۀQЦP~rgIFuWC9<~Ѵ߱5D:J6n9 +t)GC0YҎ1q$%D9#CbfR2z(]>:B uGcDvv t3aAQ[܎]n<{E 嗏k.:/oS1?ueƀDU3aY+0kGM'3.kjNj7D1?>p(ըGTܛDy(+?kx@}.ȱ76֠&X9oU z}PuZ%%*" YHSm)yhO[O^ `*#kX-3Dt ՞r ŷTFzE Q( n$HL#A͒*&%蚹ԅ/{S+hi;^Oݶr{CFc>$W6*B2$NFڰ{k𶁄{gup{kNA-4f$ 5TϬ$tUB~msiϏhyUIX)Uk5ƴ &Yŏk{&ψjҀɅ"ïط.A;k %&Xa 6z#p T-13w?!BH\X,d8FF?0U&]ё[gJꂞ6us{e䚓܎+n- tuQt Rہq~z8m,魱Ӗ'A?\ Lyxox3gtVگuɟAD>UZˉ(ŭVzY09@R.WB!CfRI"(!!LCXg/IG8D~^A#3=r8;09KWAy<#O{+8L/Dk_\k 5 .'-kt Do%߼~xD>(%zy.REL%DAhd4˃q/9DKkw3"ozOF &"ɷHR!1]۫uRX:dGj}Ȯ iĭ>og% <)'*(NJRm!rlTjY0o tpUA]mR9P\?WT}*tb+)'2t|l Äi"@iB\WǙh.])$/7?{V^#His|&9)tAy;Rz Kgv3|,NJ6+I!+~v-o̥h>Q 1㖒,%ׯD^8/-d= Z? j@fK?7gTH‡fۭvC$u ʛVp(BI͕wܯ8w tʙ#Z0UqņcaSLIIkޛv4qxk QA{@r~h]D7ȶp|0MDgo" FĪ"ж Md"6t)  9VKjn+|l3`@? 1C͎iK!o3_bjӶw7L&z }㛜TuJBڕRԡCQՅr-iKWwT E(Q:rtd6+Wp[]uۉ*w@[HۜyΛ5Yk ee;[c b~I F^"€ȉ$xp{_]qnf*):lt VTDGĔ/Q7<֎$?}F'si6NʖD;^֤a`w9V] @҈b,V!= 2vy[o!%|x_P{Pܩ~$BWX!j•rN^XH<)9iw H g 6'X-b`Cp0=NiSɥ\Bs4[ q_؅Gldܓoٝ Wn޺n[&Y[7sڂK窯<<̢s*{ê\WYAe#'ɦːӟNu51ףƦs'nY^Ǐ=^UGxn_r!bTT6cҘ+#` x]c %eS`+#el[tVk1{ɪ||}|ʪX|:B_?'MGUo蚢ҥ3gU|oDb7\7S Bj;\GE෣2xnK'e/LPK6"ae ypߒS.+1%)u+la߿D} -dTڔphҝ8ı:չ,^$eSvRw![PްE7_[0 ̥Ɵh%dc48ٺGIW/J݉)Hm"kt׷R3tzHhn#̡W?^6wҢbj݂uKs,՜ǭuw>`I7HYeWϠ\zt^Kee!~^%A\EZ CMM.؀ fM{/6'[='cJ1=d k 1[o[G{>u/Ih^nc1[+^<q峺G$g/ C'}znõ-I(a鬩~c쫮-k˖-Y ̌gSw°9{"ߺuLGS0 _¾F:ʋo++YR$@Rnrug/)g3ne[V y+T=2v4h>tWLZK4Q=' :P=)6B!8;0/7/M`{'+ ]v3szt7huBJ{06Suz>%5GO?endstream endobj 339 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2226 >> stream xU{PW{0MI@Ԁhc5d B s)08́FAg M&1Fd-&Y7Ik۰[}s$JPL 3°[ha*qW~L4k䫄ǟ?^W%\5Oms Ն] . XvUv~G!+-)QOӮ z3Hސ%_&j ;ڨЈHmXĆsEyܓݱp%K_\,ImUjj A)xj:E͠)J-JPMEI>WIyD9撤U LaYl][CC!s'/g)\x*eKv4/ ťHcƣwo[YiaH?CM-,wQgFC<6%n+LP ̱a` qOgXijzz4"~d1-eBj; 3#l67hƜ"%l&k#a+ CX N kӸI7 R]1(טJ(,XLLd!EsI>g=dk^PxnG0 7sovini a+(kY ,)JhHsjS ˠHS ln['DcC{w/lB5 V|^,5^G+)4@f-:d#}2&S\q(sJQgvLX5rs}~AJ8n vqsdxd^$o1'/+;%7QuVVW`BMDv--5EVK<(ѐA** }އ%95-^]Wtv~0-wkew#&Lë>G!ph@2[SMBN7!=.?AȜqS13B4xO@TUfVZjjY@l*kh^ٙƌe5 $ Mb_3 Ylbgm|}FmT@_ S14z}*7r7]pu &1wDJLE*y\w8Io&$yf{ね0~y`N܈9*oә6Ўn@q֓}ـ~ i=C``UĽq] FUzSR>@‡-n=-*`$nu|Azfdprj-/,N}*VP]g= SNmqendstream endobj 340 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 455 >> stream xcd`ab`dd N+64 JM/I, f!Cß <<, }G1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000303g } ֫ ʾ_<}aߺ>tqެ)gV.m{;DZǟߝAn5!s%˛hj$Lܜ(5n{eS;ͯZ՝id8\۵%K> stream xYTT־CsUl\G@{@EA@EAm $رˠ&iSi$o_sZX9o(t(@06>Aꇳ~v*EzHOҴv{l_=9lRE&|@`Af)lR35w7[>o}u'b=fqX!V4C8)QoK{خ'7PIJalNrV(Fx,_epT*A~( %}ՆR㒓Q ۀ*iyjn wq/.A>uH.h@b!1|ۿ3(?Ne E-A(sh='lu XU+*;ęQAdT*>{G.%?)v4 JsXrX?Q=oAidl^},^ "o;iW5V^j|Lpx2|l?Y +*Wi# _aph}=sfyVLL֭nZ,qJ>_)8kdpX#j Fq !/Kzwu b- »Oсե̨fĴ*17"%>)KOE1A^U{EĊ)o&us8H )TT`LfGmǷ9Fxr쫦R?O?Bw:LhE ~Xy-6xv/d]tUe OT '獀"Xb# ^&铆` a9YډǓhӠMČ8փ~_֒`;AP_+Qt\lwtf,\к}Z#zu..'lV2gO3לBԟӪć^f0 g  .(^r8l'Qu,Z =Q9'/YV^*V E|?FT{bmv!EEsܳzxYxkXN\!GLMUyf^*FɢA''nTGAl^0[_L#F8b()A`E9[ cLCkw_fqȖ|PCp4)svB$rRqWg1h7hm .EZusQ(\Qu_JW4/i✸?IaN)GU@NIf511z1$J'*W-ӐF4zm>?٫U TfЀ ZGrj'v-^rP+z*~ggc{˪|}^s @89@Q/j0'P}RLah>|&)h,*If fegFF5l&_pA)(}>m>)jFEREt3Ԇ37Ҋ]%DŽ7Åw9 )5J<*uh?9 Xۙ#?V iʕWv &h C/3] gKjL4!p+v4uOK#v)!)bl=%fHr}R5liO4ʄEnbלbTJKrK/V/Oџ.twW\#[U]%BFGBQ8_^^¡RB| wI2Pg tM.Be`VCz$k 67jr)?H`Ab6 Ox>M vGGmu\n߹uf0_vCX7)# V}-ضde}Ҡo e4Xxg4 ⬣b>^8 2t_aR ,"1-< ݳ+m@G}uG<7xO@gs`Wҥ}t>!fHwDD[a|+iYYMqlÖ(:|}z3%Z=̮x?̚L$ a6o_]E}2n5 YFdOP3Zp\1Q-u(!KX%1A4/XE/ >h6{~?i"ɕlTUx5U;syCQmxˮ8 ;*<0u +VxY;y֙`∶MY5LI|ű&ƨ#Ƙ<ňL'Ql)N+ͨASPvfivaVѐ.ļW.ـ"u%܀ڤBT7V-qr|ʹr'XNVq>bzA-PBɊ8%[ʑQ]V*s%ՈK"$ >Ͻ>Ag3aW44zSÄ 1q4ҲRgzӋD9.n\G5U/P/RDYA[Юrv¿2)v3h*0W9 |)j%=-\b[?:sObBE )_GsxH!4141#xUیZ0<Y J _Eܨ(i"ǝuf{_ڱoצJRYAH=]܃ǎHs."?4߿&TQ oYΪ@re>Zn-q9VZn\ڎ2݅e |rТ^PФD&r. gkoXb/ e_HM?cCv!ι1D<"C=`&;ID sY Lƹ^0|Ëqfr1DI0o"kG~(63:L(B*BB#86af~z79vo ^om>eDO9US MK%0ڏMF4c0s!1dW>n~>c a<uG G(1uW9åO0:|N4Wz=Ԟ<*~8r @([~pm|߲?zEO{ fRp` bbO&]hxX$~)`g`YԘQf{jEB\Ȑ=^=`3c&;!r_Ek9jBFt!/7zreƥn1`~}A @/u9E{!o+ eϛ%(b7= 03Ml"b"dz;v֖FZpX* S%/e /BQ;g֢׉I=7CFnBmJ }œ>p?ޟbE)ɨLlk4e*]GN*Z@d_aUVe>N:l8BԀHOXrUEC#$ez&`-3jglZgV$s,k-`4́YWyqJ'@ Yz^ ZOɱ) tS*;sV/Sx@rGλެv^* JwOIFȏQwf _]غrѡuEg99yD3uUA!K~Ih/-੨<<*.9%9D%ǔH=Q D&,(7'7kV4BRrKbKbŽF(*kA@)Hxt54^ mI?R2b$8nґ*Hj SV#ja[x"մEhu5mQr 2|FӺhPl iU 핔-ƕ*)[;WI4OZ|i?'#k )M8͠_=mME!>OIDްK^eoȕ>yL,4WU4w_Krg q<蘾 K#"yF]J _YJ& J)Օ~->-/O.vw *hl-=qZyWT5q9 TyJIv@w'Ck&՟5BW'+1X5m4cn۶cÔ/Dn%X9rl>}|eۮX*߼biݟşY/ozǠpT eYa Tr Yz'wR"! ϴ.4E2& `?LԆǼ÷5ǭ9h}K ՛Mzg62pXؖz^Z'>1%0D5Vw :D_.G"Bz`uqnj)Ҍ˹BWykt1CdSCt;wu}"q8ǜtD{N^{ fINxp寈sc纎^}A+=%GUɋ9h|%03]M޽n;LL:v?q{|SllTDKO4NonUw2Q>bJesTADbqd3揸M0ۄ>G80,mxU/R>t(۵)-7OE[폊MOH!!,ˠ o+%NYf@ga>BJc?bl>t u$ߥcXhWc.]ܮ;Nߞf@ 6Ux71L ""jJr9Y^ |qqE"X[]D+GpuF!1Gseꯜ\=> stream xY xSe>!4AFs ( 2-K)m4mfކ6]҅в+VV-ȦO?mQGG{ӧ}Ӝ{!F 8΄׶lOJI|i܍!1aS8Ω#Ӹl]0 cG9;`"r>\'0*ymRrNjLTtΝ.^3{SHX\RVZ\wHby[yoMcg'%zFDGz'Ezgo~;~xMĂՉk&KI]曾!cc榬١9a[#"+a˟[5wA ? xN"v;D1EΘc~7k`{O1؉ozf=Sv~럾>+U0U`d[i?@@PIP࡭^߂k8=V:o|dbP)(irm@fJvc-]} >򓝶e)ى`taBvx+^st%MGU^:2[!WgTru(c^PeE:FgMEcim< r# 1B$4DQx?u u:8ɟr]Pnm]kB? /J0FrCT N8,K}1?FxhF}Kǣ{xQbL 7~~LvŎc3fZ=*ޗSqs: -qYrz"v "=U$TIfW6/r³hƅ:M4ޏ R@I ja4ж]k: ~{b kcBBYReZPI+1fhUw1ݭ z`/.YܺӸ4FshIv??5g7  56coǼ=.$Rp*wn⣙)mC;P ʠv?[BV#t@͠A$z3Gя\jv- ZFOi#x fIUJT~cJ> Y.";kqv{}RYHՊjRYWh[p7HF'+v_vI]Mם=F8L2 ͉ JB%'1-qp.^"[A)Rћ؅xQqo&yDTReF[YLfr*{]vr #e14u*2V AI[TS\".L Dr Gl>Hy4;yusA1}4Z/ocwL2L9NIMQ{2LxU쿩nMF4LZ-QA)6e+n->@nr]#[[st/Si)!][ƒb)/9W! VԊa\qW(wu5: U9ET:a*K:yůOSf+i`DK>źM4$&h[\4 5%飌pY^nd( % HohFvt ,jSG z K^L6)!uJGq%IA[CwqX|vXMoT cGC T Y F^ TK5JDTMX$$̏e A_-ZGWx)DXDo_HlQ0VX^ZQ K,أ1 ڲȝ"/:GJ [d+7@ë |..-.dM y8c1/aCe !{ZNǩakY.8P,2FBSf"jLPiieJ R.neUl=~] t҇KMрkss~yzFsI|Y!ju~-/q0,+A(UQk؞PI  *bS2% YN@rQ_gZjʀ#*h2Geܐ\h!zEV)dm0TvctltNEXBPfBԑF 7NJ7 r$#]tQ@0JϗE?: cmtAQ)LҒɖ{(]11_FS㜶 寝"7\BIHcC~ mUynVXr +{v u.Zێ찵ٳJ27.=}F; c,}?$!A^:_ry3k/lffƅaWISk9JwW6an$ʒ1kٲ$u&=I]>AP*µ ) 1{ZsRTYtw5߉сk5QS[#цZЖU7ha{ *&,`s?c0?o5Q[RBEV>Q4ZvPN-9.?\#+o!QǍHrZ @J@ d@jOߙۏӇ.l֣* #`\rExq"}9퍟n=Iu.B.>%Hr/.xpl* +HԀU#"?H%J9ʀ*۵*;r$p6xix悬 %3-.NkmAwkЯAXÚY4L>ncyR )K >نV󮠢&{C=kwU723ؙX/P?]T&Z 41noaw-ٟ;#p]N>ZWD6 c <h*ڏ"QS0욿._1*Gyp{@~|͏.n:h56Nmtn'H912*M,v}f`tPy@#f$eMZ&m9fajjVtБoP!V^y+yhrP*& ̨,(n~vt?۾gAg#yi87a-tti5&7ŽdG鋏^?uj3g&F l6Zk#Vċsnw>(֕-ǛctG{ΙHiMug 7DG'S3v=J-ojJ*, u>4h+\6\36t1љ8OpE}7b(_IH2AYlgj;8ݽ8'oz@ )ǔ>U;Q"xݧkEBZ_!lҳk3R/:# W HHܓ ,d5n}DcoN %&+$i%-%%Q7"x3.rn ;GW3ؿt4I,NX9[M* ==_Lyz;5yfG35tbpo}&r*C+9Ցϼؐ7icrTxe'F,2;uSixCyjRytOZ%$1EP}s MvyiaPE[p)Ue݅2prǵwtҵ`#!V T2Fe}Ze‰P%SIN8?}\ w޷u6Ymv~aiid@{?FS#/e5ƪ3.~79.js,5';$ eA`סu%TE[%`!ԙs\ӵ*$-Y T(o ,1QMkexK2{ kƣ\>i22L T D3C㵜jslMQ9p5Jg{^m3F Ux9ܗ G2c>~zϞ( 1>9ZkM#}WyɲDU!--7|}'6ԉqY#{\-! a7 ߰ (,2A)R~ͻw >F|c%;{)Ks,lˋ0@QQb1䓉ӷ._Gh\ױ쳋CB}H fj7* YuGQhT/ZcHՙQp9sԹL,X4(rdxEhנ3=ML*v{8,RFӇ> qdN8]ǒO-Q(eʸ\ ب/-h2 P mӽ"9 wU2+U%zҫArt韉ڲ8JIi@H:x5!_Pv%IBIwPEMXRkou4QD (OVGcڜ2QwT<8uF',4͔/b1(H%#3Th M xmsR%M\׮~YBȄȅ HEGtb/`_,_"wѸ,Ÿ“V\~;i9>|doU5l?%ZYF#>xz!;Snт+`Gh\N,Qka-^4+4/s;˹\Z؇pM*yQ!*)Wqas4mg{ꉑ;w;Ǝ1؎WgE~؎ A[U9k Xwendstream endobj 343 0 obj << /Filter /FlateDecode /Length 4419 >> stream x[Ks8=4:m@.xznkckb&Z*KT73Œ4*Eߗ_>EYE6{b_{~]6?Q~)|^/zqcB~eKQxqz;AYZ9=J>giy`_wƱM}~]f9V RʢmKkvt]_%.boζG8KGްlۛdRz:l`PzS(0˚:/cx)u ;}G\UFD9вwLwP,aس1滚P~cY-ƕ9Ū&NR*!xܱ+/(nAU]UpigGvꖈ(Y,,4LH h@J8B-La)Elb(f21yp)j zu,4Fsɸ9 [B $rcKNxfe ,ߦ8jE:;+®KNrvU z}I'o4g) |qw?;!,)|KD)*",{ ].c/i#zMY &N{*0g^`nw:sX@?;0C06Hevjܭl& غ:)Uɂ8%!N!wطѽ#~%@pq9Uf7ٷ.Pwju5&lOq@)bﴒvf{N,TkX[f0tX8 8yVB8@s`;iM"M$)%b[hyXf<,ܗN< +zXIz8 C2;VQ8ky Aη/2Eڠ %k/] p\bJUlZ$ &j/fώBKbh\N'h\xtFHU C) jC0@dK0)  @A`bRxQyRVNwg闁BC`9!t =yo>tv"l*%}o_,݌y~N p};$RBd{8n׿(K)6;'G}T i۔ԝN7KY{햴KQ:AM뼻Ơ WR&SN}S.q. QJ$+*҉fe ;4DGj( J8W:z>zSc D8v@b`n)HB#*Dԉg2'MWm2Bi#iu@Zठ=7%C{f|wp}Mh]_+욼LW $/#ܫ%SMvw b eTΣUqpf⢑-Zs 1N uq\g[v`ݓ]eu}@# 8[R$:?[ '݇Uf3sL1QW,,[q+K~WN 2.1oK-11hѦsE.d"zOMXOUpJcpRHH1J)v1}A*cR|BCMd1L.#Ip:!xLY ս^3{9ഹn@*tM8;!-3e?f^aFy(UEy0Ŗ쭜M.M zGKǗh/iNGM~v"s:2?Sү&ZcI@ij3&ɜjV?Ɠmyhx)|QdӑPy[Rw: 7۬LMDHsg<:v. 8~x9×`JV?$`/ kq@zg2 T*9t<?d*7kTjX ZɠCMO#~}'Ռ]~9֙t韼`ןҐ7ls[2IFKON8bk7t@$\!s&,Q1p6mmhPdM 9^YR@On;kޏ?n!FhAxR]7ㅊ"] k"?޶B*$EsH@.ݪv`^[Ct DqԽt47aY j8_#'ͫ'$PN-0%lYˮn8<<ۮ2TgMycO"]7ۏJQoqz{fd&΅s.gnX6*g^&k6̨P >$C eޛG htc-E]ھwA7@혠+\՛lZ⪒[.MN˯C:QHVMc7\np;m} OnH}v \שۗh[Ԟ*XԧB,lIEX"`/_|)6[8k839Z@#+Ad$7'Y9Q) ?b'6d(ܿKuֻ{۫:Z42zۮ9n` \D! ;˂y0ECHE;}5ȱ ɡj5 ;`v %@/^b8O.A ̷=KB &ۗIA1? _&^{y>}átH(O_?Ɣ.]ʤE+}i- ƭj֔ŽTe;q>/VP$ p cZToArB5TѹW8i}y*};*s| ƅ(J匴 &3>Om[|.-j(^ȵBz{+0yЅ#z݂/AXEZaј}|J 0O 2$E2]yU44Hdwq*Lo܎}t >2RCu'u+wJmcNL|&vtA` {v2SmR@~`V(QIB,{qHomo ßI==b3~PP%=)@%< pL&X*U>&WQN1_`'endstream endobj 344 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3306 >> stream xW PTWM׫"*7-} &G K&9$ݕ;>!1)9%D%LB%%BP"XD'[%D8"@l#; b'M!>"fē8='#Y!}XGA3q8Z!f^.7k@b; p ά8 ˁ.nj;m6'uWU(!r[@q rsG?j}NPr'ُp1s@-#O#P~G%$Upd &/*@LZ9i)@q?Ԯ0 c}iv3;WhjjƨFې? ]Y凳5pB19$8jjFگFVTYCKg"o}|EO+.HNWe'Xb-a֗+/Ovb P3 O}mӕqՠ djDIm!<8D\(mjQ^/t?:&Zz0&nP!sTZk,"*4yRN$kV0Nh4}wwE.+mnu9Za(=X* LLH&j;\" s=C񜂵/TkO׸nd]߳^'J0fP-׎$јǂ#{i;lh&|&I͐bL|xH =0b>`7` )`N =ؾՈ)r9z%i6PWgDH@ws~W:`+;g-CMOL匄{hCR8s`ȭ8|ÇdUŠ蒐YJT0L(BTgIN퉨}NUZ]~3Ԭt'p Smi̺(+Rro .n9Kћ4 1gpbPHlH 䓖7*~;r 3?L>%P-R#R8w+B0/ '83W;DYpRd8:5 "pS^7#Ŋ6Uמ4g%4*)b1cr'BpO23˽)-gOL'QbǑ>uKl˧'t/;v.Kf V%LYL!洢 (Șy&uiz,%%"20t X}ʡ55fC.)RQX]IoQ&QA]-I}>M/>BYv)WJ@(#dֿތV}h0c^ʊTY5 u=u{F?9ܜ?.D_Wn,oem7(1EIK5 d8$氣*/5*4b yQ rŒ]PR mbHG>?#t>exz遷Q:o1݌)~|٦5?$Nݕ%zQ'  `D|L8PӖSiՄpius^swեpN4FZLS)h ~c*U**5,b8'uKYǰv0Jo6)ܯƟ⏼lTb\1VEw 8?E{eS 30&̗%ظBsc?l%妉^ .G$"¸%^ @b  6D9jยH[s[ MF.8XۈQS3w#ȡ7F ҞyvPlǴTRt#1 uۋ6RrETm=H2Y%.OhݕâePf|R5J٢W? vu xej | _]-m6``R2B^&[eP rC#:Sy8WR,̈+FjL-v4|ΦM? X77 $UCL{Ky5K(-y}-> Uu?cJ܇xˆRK;`vT\f-i[`Q3=Y֩eh3BcK^s$C-QeڲN@'8[ΩK]h mr]vuϯGX\vk҆+/V{փ[SI)J}7։^vLeY>-w9p|X"o~-gVoV)YTe[WC:l2E‡˯tXu.bʗa+Xό)7wR<".ڜ1_Y=7\a<KT79M r$>jvQ'!fB?Ի7_/z Gؔߘ bJR.\pb6~qsPw}z\0t  +/ zPW-u[P ]3g>5344k:xʹtz^.{y9k f`0^⟉ hendstream endobj 345 0 obj << /Filter /FlateDecode /Length 2638 >> stream xYKs|͘*:J:[vc&EȎsN7!TR\ 0x4#Fwfu7M5R#WP.'hIsuѳig"Jh#Y}3+YfZ lalDn;)5 w9;"BVJ;c{2 ;VH08lMo{ }[ְFSE؍rpZJu1Kl, ўwL4+_YjxOI5VN<ˍy  a}8׫Jsʸd&ȧU u{E6y^u;*6Iq9-Y緛.򥾚YN`\`krcYh%ʋ| =G1'Ow<|dZ_w'U_~r2sNAwVUJ4`VTfAkpg`cӡ#!9M-`óӋ EvP-Y=xXeeRۛiWr)t~ ZYK7xN9y%'ͺ=ٓnؾ ً\4'V`n.pG{,4#W3Y?"TKذBIj+zZoh}GW~o?NB>USLd4.Dj19&q-2^M]5v@6|[9%R/95:w#ab# : =!~*ط$z]4mn1(kȪ0TŸ Cjq-dժY#q !*BaܔN] 8ǰ RN<#bt .`tV|yI+.= ^ɔ[moBB}uNRTдggLCDF*M.Vou!=uc5 QC1,(>)ȶ  M%F1>2pW W"sѯNa>.N$ŋ*1Ehbh+ |@O-\oP0iXqjFQJ (&8<:+oӃUa`MojXt0Bp0z~Z,mt%mSp|{H4Μ< uL^9%!]AȑbIŢ'A_(lT/l:WR88 nZ%$/Yd/b K>{)W1*WfP*d, g5bָ֚q_. 2]wko >Xv>Zv×XAM˅7 [ؘk>I+mݦX$Z?Q懲Y07*G|3:/덋3o>@F}ih 64Cjġ =GDkd.[ z]Oё=0.X1T< J l9ϓwǛBZ,faBiulb>upsՋ&I5h a=cSY RkQ*a(15AIJB2L7)Dw~N1@WMuc@[;QM:έU{ %.g^t )gUdtu)R[y$ Y^ mjҪ'1b}(?zUT9ȸ= vTc:o'IN)H{]s bnB点h\ 9xdF5gÆߒEhs#IUQSrxOuc9C֎CtSy½q 4b˖i>#'ه[ΗJ=aT|@[=EEe\g (N)MDxyQ%Rq_DM?JnZ ۰ey֖9d_"1MҙYd˘ҝ,mX rTwۡJ ` { EݤYSԛ Sb )dyRB bO2C4f $7UKwX{w^A~O, O1!$˂WivETn6˹葄hܺyendstream endobj 346 0 obj << /Filter /FlateDecode /Length 19840 >> stream xs\q<PF4bw=mFH,gh0HX903{̪|&@@ 뻲W'֝Ltɟ&=_ٓ_}Y+H4g|҃Wv'%ɳ'_o:S MStTW7?]]=}uө۹d#%i4{;zL'7Oakݼyqs˓ʤ6Foos?]c݅s{ƻg ^'vPi)97_ӧ<g?}yW_\}xyvWDoi;yq~qŮSZui!O?SVqW䀂A h-b.L8i_-'i4SsJ}ű >#Q=ENq;{%TRW#n4V?GS9|%o}?AA7/PTOW= Jg% iДñg})v' w~ͳk/[M'^S׶,FJ8F:7HZɛ+rP%|ubf"`_=qsC, gP-M/zr(M\ئ8C';R!_(]m`ҭإ_ ~u vS]6!]81^F)Ca2 `xn[`]96oɭڨ1uOqhűi[͸l^6~{s~1}szOl{Z灎a\6rqIH,\#v՗'~ 9N~;Osx2)wr!m=y}Rۤ LmE r[F_$1JI}޶̣/Xb|9l}}| fCiY CҌㄶ)vM`Qӈe%4Y4&{Uuvэa 3)Q'Oخla6s*㘊hS5 ósuF*)cnięO?zĸy *ܘazNnџnTyD9kjQ'mEEt3Tc $B1o%یOux(.IFkޏ~ ֪фLdf-0LK=!BjƗD͠Ȥ;\kH$C6A+ L8?,c T+gޖ08 C(9(C+VE~'ZN#ِn/ٸ~c(m:Nʰ.; ŰB,`C5ڡveQqVi'ZyH;R Ԭ qČRx~]J?H/Nu;+6Gy-&x5.y獮DeЦP~T5JࢸYܸ!ĖO#؍ t6NW?vJ;ԋɼCd3НcmC-)mMLʻ n8;cr A,FkUԔVmCRƂg7SJl\1`*Jc]'I1îMRA|o7N$hLUڡcITky;v¶h׫0vhGvV.UO>TTlioKv)c?Ligv+y3[*ۄvyϾvt(;)v XS n帰][=yC;YbuHdpdž^2Awr#e>>YHc/ʐNQВSD2n h:V)QlR`] ruLVTfES`zڸx&1Ndxʖuom):Ao}*x@ E40va,7!.ÿmżCOfUO˴R y9K;pr;q|+*J$TO aD:ӊЇYü`2>~*G5Ճn3`bF?}mS &O,,000 * ̏3Ɉ }JVhq&!٘+0hZdA\ * h|Y!jE+:l;7uWr 5[Ń%y03l[ElR~ G~H%=l5x3S6zxBQԷ:OqeE?8Bm;.T"yZwxZwxJףxʒxyWrď<<50>-LUr_(N*%f)tJS04<&i)c2js4 ۮBӚL>=-Cψ.MEHϏ qig<(I R*7:lxǜ3ʁ[V1H&BR⬨y)f4HH`t\|iȢooIef '^P2(-jy24d6☢cC{P*'"` Xa)u6,3^a)Tc8w]YEpv( JAbfDiq$ yzBRG$(mF,~6,XYŰ4Ҽ~`iFðF;ō0ET{D` fIa*`* +0t2L?Sfru Jk()z2g&nRn(EJQP*[BS0PE20@T1Fsn L u帱h.<^;Q0j`ohv@qM>`O&37ؼ]#FfTQiQ[ T)O=- Oj05]y Kb+Pwj5C@$hУL˻Y*YH* "yjSTSY"L yk{OU,CՓmQDcqƣB %njV:åPu| 6؋Ȭٮz:-LO E }XJSL[ܥl4ۧPG{"iJ4B!AfFDUPU%L\R4aOTc7BUGgz+TMya唪FfXHP8@Zh.H3VXHVK~qR:-.t_*aU$TePU,UBmn0nTڻ#Uq7@UTE"P$*Fړ,j9eJA_ţ05[[{xbAm'x)hNB1xxittxWp >Y[%Ni'Qqt4z²4TlGs6Cuئ[4Zƙ,_I1agR}iqq(ٜU? SK0 'ޝcSLI|xZxʞ`*4RJS͂d^x?:FSs4>4d>MYrGօmz)COph2(NY8%',(M]r,NYS$]U3*pP%#wUNt+@eԸXHPŭljUQ#BEqYqWPeSZuRA'sZeTr a*WT#LM 26C4cPv4S-%+r[ ۧ UJ6)TbG\)dYaT& ƋR@JK#)y${JmH*TCR(IEr724FU\).U2wOV vA&O S̃yta*{ ɐyVDIyISH R!)m Fy|HHyH:݄QΉ`(-v:|*}Ĩg`{2ʊQ;+uJ MyH񛸌Q~P1$|T*kP%0JaqnbHsZ,|n`ޅɼ<0 uz PJOTJ|I|HR H+ el(c0JwWrTR!;i"^AcJ!ʡq%8e( J0`S6#Eߋx خFqU=u zu0 H@QWn^(0F%c8 &͙\( =ȻQ0.C1J`Ei VQ:[GX( _^QҳR<\nByA\;vWIl3SyHpڠ>c\1b/~|WjjrT7okDVY%~Yx*E@FQrUb/LgfjwW̋HhԽL/0_2jVkA0U$+Lɝ:ZS9#T?$TlUOPD *= L LMTa0SyL +35ř^L/n%Xa|∘w;{ex3#HSX〼\L'~dn`*S'z3jv.[IU|R7JiqMFJT7zSFՉ_`حS %T<.Tɬ`[aď Vmj*VuM? VطEb5,Ny~PwT=SUM}R'IRxxӊmļwnPPjxj@u[ԉ_eHʇY eLY0GnTLә=[Yo S-}*P-io*0Tygɼ6YQʡ&j. 1CkD-eqID iwܙ7)P?/'>DA>QY0*G/QYBT0ADB! گ_\@T 粬hM<~%&H*LlQլa*`>1wO KRԉ>7 O*Rys-F H 5E*;87MRUrT5BqTeh`U$XXmx9( HoU6 ӧ*7#VV&4c\e?U܍r3`_}g}G(Xp_T:|dHZyA*o Vc=847P)&*؝.ʹ'*[*)Wy)\JT!{.U Ws~G j VcU!TeQPua|iJ ST~K0fhqTSAy=/12UzS @1U<T<侙 y,呩G3U$+L]fZ:U05N*Wa*KrvL go#l6;O-l PJP=mw4߰ᣀ `qd@%W"G~D/[("y,KMN)0ęgvhCN 4GBSehZ[zLS94BS$sS|l| 64ER)|P642$JYݥHH7Q_\Dcvo$ NA#G]zO4fO$`dfW SӉ`ʄgL~V\%w)b)9rt"{WFSDVxy|[B PL{2_x<~ҕ?=/$5z3$)@Z)}q*|URTߝqJrW%)#(Nd)}Vi U6#OߛiZy$O͹x܊}o;CHi\),+LES>{`9ߋWfd MBxeTQ*9R(Ѵ@)/+JE(9Q$E[%)_c!uR!)q7*ؒ-! 2U^,,nR%i+Gp޸Paϴ;,H+fi8HQaqMNQ1FQf gQd1]@J=9A1$3jsP s_ GAx(4O HOiɼ Ǒt+$euqH$k((P~ Jqs=Y:oDVAlGhdL'LY k0e? SJsDD 8oҐo^yg43҉gy6M6UfN14?BS~3GS>9i3/ MكTM }ASȦSDL{%˥4/?SW SY`0 LAߴ.J[$p(C@)3gOT~<x*S9 f)źwQ)}*4΁B#x 5m&h}4hUi_ďҔBS|-Ҕ|h~Ҕ23 MEr N ;Wh*Q)YcŧNT.M.Qa;n)i)gvTɧੜ6bJݖuqfBGyW%=ţnK0[11YLegTю#ʒG;u?kN}ֵTTH/Pjw*b B5ր*~jO}U >W7ND P}b1ԕa74lv)4͇):mH(FDq7?>N?MqZ_;N_ۧ)߽?w)إ W˧)$1[N"TWx76BO)=)'FS>"t MAPj.iЗ /wixOZ>n@gwwy^ 52<ә?Bys$Xc*KT$h?Le?@uU#T? T 9 UE@U$+PeBgT_4 zL tF7l֘xFʽ^ʕa*Qezy1֎Y1* j_0DB՞N[3Ǔ8reTB}/ *Q f;5 8 P`ˣd /j \U)5V^"|= T9@B|/r5Bhd`c3>LES`RtÇŻ&`* @0R|R7eޏ|hʂa*[;_${ Y>}dOc߿N Nyª8 tZ\g_Rť}8u4<2ũl N^^18-=)6b8x3NsYiÇں4" =?KR}X=G>(J T/l<* T1NEr{^Ņ8ESoH,Yi_`=ORoi^8-5r4/Ar)UX{#}oP( +J}7tʫ(oR9 Yʵ}bxa)5NdiwQ^Q(滣TIQ҉}7E){(Du*8*9:񧙙G*hqWn`7bZ%DB(t(r*~7 *n@(]UNfiw܀Vr—2[;+o8|D~Нr<@Yr'r Zc6I==+Ϣ}PB'!(U# 1O7mW*TR᧜1R~C I佸~{1BN)]!'LnRh=%gwܕ5p2Nhc)8k_=8qcɵ^%N;xDNҳcE/qet9-<=zU[gpd{{~r d?wA5cJgwi ă@(h礤!pQž'4YV~n͔ho2E!RގhZ<&*Q 2Dqo~nu]?D9B=rl0As A AAuan[.jہ x#Ce(7Ҭ@ 3kV;P?\ BΤp|DV {%$ P=+-ePF!)vs;] =5^ܣ@E]1eZ 6|N(Cvyzp aTN +ATtU#y^ J A<<U%^KgJӟ >7?g|uz]4=Ol{Jd2L4]C@Q;唜;&'WÇ%'&r~œ.qN:N|vj`= *9Z σT#>?5>'ډ6w|#). [gpGFrt2e(q9nQt.+:t~T9*oL߁SeAK9OQ5s(eyOD>Pپ5y7ZRX|?T CNeC'g/~9S0G;lK OO\ ,+'Bv.tgYͥY0nw\܏.Z O3@4=: F̱ +nx$Ae1׾nasV$ n6`D_ D/~', 6T{ɃbaoIc_ jDY@P9t9jJ"H7\gW'9P„71ZTtԘn4E9Pj':]SlvU_Ww(+X+!Az@5ۇ@S0*|*􍌢޴80` `̦4Cp.ceg4$eZE#1]+"ܦ{-K4hM1g}H{dε s1Hp;8h,`r?Gڦkhv;Keh}iݍ)y6L^&`ccɍm #>|ggOv]vvJnLr8-B+~%ι,p/݇'#`VmyDBCb#iH\%`(O8phb.RTRũ$\Ǡ`Iibh 94Kƹ`I ղbY f;`>RܘAb0ic`wO H Жit7\%`ˆ6n:{1H`:-<%7 #ه, TbHړX6\R r%B0' kAn&CܘSP0(=$]4s>8-G+[G/28a@ҰQ57!S/uNB=p9[^Ԗt/{Y"c}Z5-Q-r@\%}.1P^jx/o-c~p"DZT28 uC`corCt}6{" $)t7<#G`KKWk-ARG|lAD]nLu|S{%)5x\%`cM*DB\u2xQV/SwAB6$▤!d\%`ʆ6c\;[2ݖA)90)?=4;{-IpRs3玃2ն͌ u['Z}ҝ/Q1!Xɑ|79Ʋq.bXm73jRy+:=,L2=SI]I4$dz&`-E/8QP mRX) + tvB_}xz 40H҉Ā9 v͍E\dwaYm.}9*f;LY=6 `,9&m ލ&V_>8-D/.r<>m1<ܐ=^81!X 5>hn d8wד#*?jvmT̄ܘh}}L`IjSq!)p2uc`I`ҋAAkPtC=}DHIA 5@; g[Cp.cek0Hn%ssc)1sUP N܈=Ff:cE>8PV$ϲ+~1ph1@U4 i-k`Esn `I4s'9. x0`jۍ03OvCq د88{%0Fs ( r(2r᤽Aਐ1)6(nwcFaX5 1BJ[84ȍ!(s1r3E/_ ~anhrC ʤ[kI`K,gMdyh%I\ cDCxG}( k!S84X,bQiIA3?s8/Sm (ң y*Gԇw;Dԇz%D9q!oEʱό]`tvI<&Usc6s;y> W@nJC'NT2!>8-E/"\kV PtCϑX eCvRHc`H%jICMr>8-G+ Dzrg7vm/E SJʖlKR0,r `=%/@7f[oirdCܜJ8gвq.cũl*ᜅvPs.QP)^uZ6i =Ms>8-G/4߾$ ĩd3!GĐD<06xpn"#7qt+CxlF$H,JJsZV չTqUA>ps?[M$T5!ƙ`GlCYVc?Y6;u{:WP4H9n}H.m9ZpX6p.vrΧ/h0 aqZ4p()LKyG #*!u \Q7=F ue3E!EB$1I !heÉ{$ic6a ʁX:Nwe6h;\VdB|p)[V2c׋ABul"riF5Bó[L$T5 MY`Co˅K{S.p2fhnލsɩ"犃s9-=p9[VķX"lQiȵ> ³þ>p[J&ʙ@94h l9zr1eSr— qoT"u{ ۱y B㏡Aaea;Ohpt൵8O[ ma zn.Hxt@ֽ/aצ@xm李1a1߁076ykpt೩>g^p>IH&<. ՈC!x|n,o»%0c߿!|faCxҗ1|6V8üd ? Ot cJ\NWvK@:pa÷ KA#aCZǙ}nӄ40`c3@C7 npp4|CɻÄq!J&<;al4(~;s;5NCѻCp\cK~(|wqcy0d 6|+>cMw)V O.ilD-cxbNvN;$76~C*9| 7*_CÄ9ɤ]{aCÆ' a& V鷃 Fg% 걼zzm<^^Pqx{>:ή)Д7Wg=4Үx~TJBWxa nLf#}I#\`6 8a捉aӞ*XY/xF;:tg|Mw7'lY<|wc{Òaw7W1{3wn̛ǔzre\G!#rO`Z4Q޶`򸹾".m^<Ŷ5h_](^>P=.ذ!9{B;S\ `=Fjm<]{A `\6c@PcRjw.g{]@Pc)* jɲڱq㕇~@{)z7V8.?R\6Whb}R>db\,~έc8âzU*{BJ/JSe6%,l.lʒzB@v:iN(Spypǜg<9k[yJhݮ[EAK8cP-sϻKVxŇ|7k,s+k!]hNعo9+;pk3trVa0ZS9[?|2 kHy8Uof /Cx}u78<1j*GIz|/w$~iԈ`z1knхrva5B[`3ӀWC-h ="\|JLџ/*ov9@L,50 !{"ixprRgo{c#BӀ6gof)#DCi)?7|y3Trrm8D|~I]u_!z`߾,ߝ?(*iA(Zח)n^!N5ۢp [%2d^:{7g%W⚅Fn_/ q 1/3@r׿ի:=%39^k7m1d,BŕȮݮрWڠADMGvv㉗$r} s<\/ί7KPSԞ%}=r M 3>ās˷C%4c/moo9Z^?߯W |t1F_R:3v8j'4o(k'e`0}sd^˧l +l|/_o]wgϱxl*/4d ֐ Va2Ux"[)heݿ*k͠__j,^T6_f^"/Ohf>дu/;B WIj+v srC߾|ߍ'WW/4/_?F|O;]>m^Z{ϠO/eqO9C j>_|߮X0ke%hC7㳇>cFnB8M-S<{px]-,"@bg@2hbj ؛Gm2lr8?{b' ȳJ4/{ggM-bK2KbML'qҦcx;ϋ;Uhe@-2lObI:xGg{!@T±UO D,44> stream x{pSuor)DYU|긠G֖>M<ݓw<&- *_Pu]`YYݝuw2;{Ӳ{g79=ef`<wIe]vNR[ܓ?̷͇Yp܅܁^x*tZ!~xG֮Ohu2USD\*=(޾n:qLmJīeRqYEui]XV)[_\XyOx랝 X?T]bQ*onlRJWTUK 1^l' ۍ X!ۄm¶`c۰,21wOS#+2x ĩUYKQr Rrq'h ;A8 fђlư`hs%& ɝo~p}:hCdZ'dN␤ŨP. t..')aLBODnVRJs{ʁ+痔ӕn2LhF<w(']T Sc2&j3;fӃl"UKx = ^{3S@jK,])e:h&F%EyQR;, Ņ?nbԺ<l3Ϣ̯s={6C Π=ˢ+:(k3.BLߠտ-s!Bq:v.T)pSh ť9!UF B؏A$p\ g%}Hp -x4R\L)S+K DNfoH6ۃGJwm.׭PO;#%`9/In| *[NF ȾkNQBFkET:͈1_W%7{`w!i8T/bM#6p8LkYaQ[ٸM)~83<9vl WiMH4h[jB =34Z)/Wu :+0dl4z :!cЯ3-JHFgîZ_h7qUB+TF_+ev)`/pbD8Xn۷ӞLL#OGބSW+|qll.*)-BKGA7sN='Q'.pztZj9JAy%}??Q>-I%Q|; ʻKs K>|=3Di첸ld `jj+*x|l?룂o+x2vi01UX9bs/vT쐿M _ b0&ˋ.S]{ ؝ʸ wTVi[IiQ}&Qr ogʓGFLJ+o??0Mב |fdvcu* T{P5^mX2jd[>Rk4ƩNk({`D ܓ>f)ɹJ|z:~TYOѧ"Zmd2'w]M df}H -q9N7^mo\{0V]0B? ? %sW4OAɦ-A_δs,[Am%u/khtApFo:DyWw55Im$39791-p }ʦbc hzu+7=E| 3t0Om*皏 Qc_ ^Xb.I!ogt" DwUfkkSOeV *Ko?\q pXݥ+2Mô'?DML*^;/zвWCqMa3)MnA+nWmSj, iiZ[K&vzd\X)^o.i&Z&Z _e /lrIpi6SPn0/ᣜpw:D@v37 \J !ҸN @ =߃)b,QZT ֘^(zFoR-R> mr6)yv&sr[nR_bC+kbKvg 5k)MC4 {:%-Af=r;T"2+s,{!d/r3fgwz.nvً1? endstream endobj 348 0 obj << /Filter /FlateDecode /Length 24450 >> stream x͏%Kr5f@$VN|\ r>0#aY_w*võ[{9,oU@/"KϿː/۾}Ϗ&F ;eWW>(Yẘ+Y?nD8cDQ8G{QT,^con2}(vrwXZfVVSGmeq͕ݼmᰕ-1y:EJ}+KvpV)[֯m=q'meH"nei~neuu.Q8|+˵qЭ,h"k]HJ$a' ƨ(XTQJ]bne#Q(8Pe=$Q,;_Ҭ_;㌵ADQ,>pVcqo;U֌7>(Yw+3`EEuȬ"xT$$Xe#n(YgHE8c#'AN0ǰ g5ke'ҝq*˃_tgq$ҝq'0߂XQze28Yq*Ӆ(*Jwً8@?Yg%ҝUx“< Hf "l'q{DQQ8._3,zyf &qҘ'n(Yg^V(Jwh$ҍE&1W}W|<Ǫ ]SPFUJQUe]DU<ATUȗ}ɲ>= |jdj D%XnbD rӸUAYnMU>F{_%4G=)|jdj F5_G5/y'Tp:p<ɗVu!!3*J'_X'̨p|ž@'_X'VTN$ QQ:F!$FėT !1* '_2u؃=yt fz`GYb`UYv+MܨHVj+*%!QQ:w:rG6x4'Qķ\i&4$*kʦ(G_fP摸BlM_fu~`xwox4CS3$ gxF VQᬶA{eox?ڈW} g8p!3*J'XTQ:rYQEq`J̨:&!t2%U-HȌɔV5 !3*%$MQQ:rl4%T-HHɔTu !1*Xr P%!1*~BPĨ(ljdόd jK+*J'X̨̄(lP`U2'tK^yw MA^!^$3V6M8:3%in' gv5Qs7]u7yws[u7%wOKs7xs)[3-.-i)$X,sx@3Oj&ǽ\VcO B`?y["l.Q(KK`MtSEXZJPAĨ(K`U2tr,UIȌɱVu!3*%%QQ:9`5ax| 6j`όd j +*J'+X ,w!1&+H̨pX dFEdEZ j BfTNV$xDVTNV$5Q,"UAȌɊf ̨:Y#t" $s؊{Mjv!lZ@ g3(J/QLL$"UAHɋV!3*J'/Xy̨(]u)KF/^亮emvSГZ|Pԭ҃BQpH@TU8mva+DCNzljAU;BPS0ڂcyZ=:(Us /p4AO`#4pL8bH )? w!-F#8fG( ~8CZ(q(ѐ w!-F8ώD0Z9dFS~ (g mg iA0Zm P 9]ҿ 2@/ 0c YAcf.b!R 1dha p. p [q8A0q҂ `>/Ahǿ9 iA8q҂@)CQ/RÈǐJi^5AhTMiH 4E\5AO`wwN{Z8pF-'́8R^.҂ '0ޑs ҂ '0f=R^.G҂ '(?Ap̐?A9p߇ P tW,[PF7>AbN1A`.g♑YA ..{bap燴  cAp߇ P + -BiA _|' :ΩO ppNq҂ `-YIY`(nCZ(k ?AXO!-ZีiA0 ,@N5qK҂@)\?!-ځΩV~O n8^$ ksZS ]~ c0nCVH 1D "bpЇ kr~dkɯw+cxBN0xBQcyMcGrr*X;jr[Tk0V @PZ)Qvbrģ r+tSLn~Uxt Gx4BQ4/o7`LZ\V?QZZFjjU @3l~2X΃\: 03*JZdŏQ,'V!3*5rYQQ: 03*JD珉Q$/@c̨( u+*BZdy fFY^QQ: ˫03*JǺdyfFEOPZQ tQ@ +*u ̌ұVYg&AP@>HQa6, 01*u MM2+5yi,A>Ӣh,Q@W`fT8cjdF%б\Y^(KuV+*e ǰұtY^QQQ:/ ˫ 03*JdyfFEXƀ,.̨p2 + 03*JrdyfFEXҀCN(u,O`ՊȌJcyYQQ:8 K03*J2dyfFz=fFEXXl(@A`bTL gqypPAaF"l,@E`bT r dyt,@W2`fTeǰұtY^*QQ:O ˫03*%:K&c3Y\J,/̨()U dyfFEXVZQ t,@YK (+U dyfFEXfAXQ:Z K+03*Jr dyfFY^ QQ:] ˫!03*J dyfFEX~w*P65PuIQ6VX,| TTUȚd:dҡQ^Q$@A`bTB̌ұY^eQQ:V^ "03*̌ұY^QQ:VadEEXZ Q,@I +*JNJ dyfFEX l@L`fT83Ecp3t@O`fT:+3c3Y\,/̨(6U) 3*J dEEX9T Ĩ8c%r3t !jTU0jڷE5%k=t֎;>ĢFϙ9Da'©J:PfG>D㌵ֳ3tgqR;'fFE.▻ϩYq*čl'Q]ʽzj'OMڇDQ̻uN?Kt|pIvʜᣉq2q̨(Y&}2fwpVcq}ٝ(JwG>(Yg,sGE8ciLQ,GBYӬ͆%OGG$ g5g?s,w\(3*Xwp(Yxp"dm%@j҇.Qgg#τpVcq:dngʐv3y|@QQ8Xc;K)O67N9kqfm)f9&Qp HDQJQTQ8X7+tgYżFpVcqk;h{ɒ8cHDQ,qϩYq2f@(Yw!VT,q2l'YռFΌ g5˼F>(Ygȧ?v37a;|ͯ4Vs)i*o'nT$nPen#E⸓up#Tbk3km֧Hyb)6qlPaO9tOkvϩtg83i% %5JSgqd2OvЩj.͌?nQٲ.g,3芞(Jwˬ?:DQ8XfG=Q,s=#JZeMDQ8Xw:S,KOmۋrK!m8jƲmfѽVV:tgǨ͢Se}5X,:Sg,m)Ysj3|aI9(?L7DF0󫆅{'J,38m1;Nmr/gFEβ8>Ʋ?Yq'9)B,3r6̨(Yg(JwzYo?s_軥یyUU/fBPU0ȾRPU0hkTkˆAU҇@G5ZCj F҇W> my=xh] +q+4eӨU;I8œv*TG)8fG5ZCj F҇JKPp:I5ӾE3sAQfSj)$FX2t*}V-Ę(JU  3*J`qT,)}W#@bjzbTM©YOD"l*}T-EĨ(JU  3*J`RȌ gIj)dFETZQQ:>"@fTN҆院t*}@֡3?K@Β`i;LQ:>K'B<] 4OUK 1*YtdEeHfAdFETZQQ:>t֢ ek\+}N (}J%APiQQ4>˫ 1åULn*Oq\,)j6NSQn2 2%k~'@fT8KU 3*JjE=3*NE % ҩX19U8KU 3*Jdy2$W[E eSQjdFX2t*j@bE % aSQC$VtWyB^+2H5+*Jdy "t*jVĘpVcq>@fTNwOPb ZGX2t}]Umk/2 +N*؅pU@q]xPQ,)WVQpwZU-' gIQɺk@fTNnt*0?m(<'KaYm8@bw'֮]rNOU*jCfT>OVN>YR9Z'QQ:U KZӖ*3%k%qP9QZkT@fTVPʇĨPTtTs{bT*U|`EET9Z'QQ:U:Βd23ET9CfTNuSQ,{Mm>l gIIܥ (K.UpE%$PդTT8KJu $@գĨJU 1* u)Oi?D5QMM '}`kG~?h@cOػBc/gq]a]auye/U`$Uj FUQ@T{ԥ@\'9 J|3ߔ@E9!4oV>`܏ P q/҂ `4><AhGz'O D]^?dI zʿ*Qjwr({4)}p" Mt BY^ڊދ.c̅+̪F6b(]sٖsa[Ҹ=(rZ~Ss)+d1lKb-9_=ו+yqG> d؆&͍ 㦎,Sy&:tYconVZ0͕j{9ةnZ^UuS8^Ru/W(P 0}H BV^9vjKJ/I[f!1YAP.gŝF#8:@Z&p P 9x%:.KT -F82@Zp9 P q҂ '$&AGt K,xWP>`L(=+? c{ -}w ۛfl^G__] h}=wnAWs+k77Ph|jFUQg5vZs-j}Ac5h4Ǭz ^D5Q}5}Hk7+6)Y;f( K:& AJl'lDAQ,v#&fFEH ˍ̌ѕ@v3,)YY L ByV^.s'02p43uN!Oh`bTܞĨd=g5!fFEO` ̌ g5uJpy >*n ̨( \diLQ::+:t&(kBȌJ?S,ej,{/b'|fF^.'3'%]!k#+a/7 11*I.!ʭ%LJFV^.?XQ.qݽ̨( ,daQQ:XZkY+Y{q AgDׅiQÕJ^obZTN 9dݿW fn͐]JUQɺ6; YnLafT8]0dQQ::adF%П1CUYQQ8kY!˽4̌JU^.ύXQ˨Ľb1]tsQᬶA{L<̌ҟCiabMBiLrYq|jq6\&#% 2Ƽ>&nPf g jnbfT.rKƽ\̨(rWBIa/QQضr3hո뇒? jBfTGƽ\0'&2fFEO`?߿Fܴjsƽ\4fFEOg߿FܴDBU޺9VS镯>?o]& '5!isW[qǝ g⸻^Wƽƞ2$'yF̨dD513*Y#Q{QV;QncbT(Mx@Uoh#qdEEh#w̌ѐGbSXWN yug3t4fO5Mrj}&|oǿIƿIVhTl>jS+*͓7kBQQUe(ؔMrY~{4_~;Q8^$X+-;1l%DF%M;Seq5>sڴ3QdM$t[IktgY܍X-j,3K|DQQ8Xf/EE8cioLQ̙c4DT88dV9Uش\e; d}EN2Wo6&*UYg\tfޙ)c8o yFʙ =xIѬNj,3yW4E⸓up#Tzeܸyͬ;-|ھ3S8]pVcqʃ;}l'QX{t^1Ȫ@3JW6h^M,-Ymg,GE8cEDQ8dITbecܴhHVem}t޴hdG5XfѴLƝ+wD;hBo|Mj,3v;KΛYd|DQɺjN l'iҢ23%iQq2x(Yg,(Jw 6s@?YdzfQpVcqi(YtiLzjBrF̙<8c2w2E2qb<ds0ĨIf( hpgqv7tgI01*IS &*~$X$ҝq2>wtgMݴ󼛅;?2q39XX4S,md:fm$QFGy7#(*Xg,3V(Jwˬ@>(Yg,-v1t>hHVea!DI[J:sn4=fu#Q,3,-p3E*q(YgB3Es(Y%gO<ɣ9Da:Fiߛ(v>Lk9oeFT"XgABS0S(8P塅w(YgBM3E8cj)Jw113*XgmrgFE8cF2E8c~;vf< SeJ5j\}ms W׹A[+܂tunA*{M~[Fj FRj=)i[>'m֍C:_C: m}[_k{[>5UG)8fTG5ZFj FRJ5KI:_Eg[DD,)V-̨̀(K5Uk' 1*$&2F=3*NJTT2t*V-̨pjN@fTNSi(J5UK' 3*%: t ɺR H T@0"l*V@"YR^6)c8o6 3 -*Ykӫw;_)`&Q,@SETZqQQ:`Kf gI jMdF%nqw}d[ UH}HΒ `*Ȍ gI?h(&%BS%GqP5QQ:UMV1@fTUSjdFET5Z#QQ:UMKf gIDg:@ `y!l@ Seϯ@:H gIlP-vĨ k+F3ET[ZQ8(̨(J0UK" 3*J `ՒȌҩY6U+*M&dI }s(J05mܽ9SN%S jIdFX/5SN%E?ƥ_R$`2޿Su,x alwW+XP`qsԴU; AG(@B̛/;D~ZiT z %^c4㊩Qyt_涙B8 piLq _ݓ|kKfHߝni BfEpV0dFEd<K:X&xCX&d j+*iLYQ:F0dFEd<kt2U`Ȍ g jCfTN3 QQ:63dFEd<˽`H  CbTM3*cRq`<_qQt4U`@ExԴ jCfTN3 QQ:F0dFxV5!3*J'X̨(g`U2t2,L!z4wW1B+bytunA<  h܃Z+7n&34m &3D5 QMj2CTS}`k7k`k8= o݃̓ط}X[kX{+܂yp3a$U fj FUQ`@T3{ԥ$̓yܻmT7׈ !-0nBV0mf\6mVӂ`n/p `3md82p兴 P [q҂ `.Ah%}cH FJa 9u#΄!斨=,[`}b c6bp\]qse0rHy!'BE8nBZ(q( ? i¾/pܼ $Y%w!-~[sӂ'p3rKD0q҂@)>g-F|}N!4nCZ.1pܴ P ;q҂ `tf-A m`H }JaGsEӂ`tsѿ N0B0 n~.`ܖ P ;9=Yҿ /@܍ 0_P L.q҂@) XH  7^!-F9غ9olԛ98]PL0:6jFW8nBZ.p` P ~ϙ `trv,A-Ahǭ\H -?I\m.1lZI?gmQeCZ^sYZck9}ez{3؞yѰ!Ji+?uGظ7UN4;^.8ACZ9p% PJPe#'C.Q/iAXCZ{Ji>?Ah]wH 7 N9/t8} d9{ {'Ja8CZ>pO {SiA09tҿ)L{YA`,9sh__QA`09`l=s pѠ9w!-Fc8CZ(MyGiA0q҂ `4;Ah#g9 Ch·C5cݛ@0ݛ@Af|/v7͞n  VTmxlx^Mwj6NXQ:r3t}3Gu3tUwȌJՏQgGbY:S?t$}5{,w13*Y{j5cܝ̨(K?fFEX,mH)Yj5@Dzd=l( Y @0=&FDYyAP6 {LTQx:Sr3Y\2,w13*JDzdQQ: }̌ұ|X:U%ڴtH K[OgJZz-fF%kuq3t,)@;diLQ: =̌ұY';%D:dgk\3̨(K cjydF%бY^-pVcq\M̨(3%q/WAfFEOPʀUN( Ju$O!J1ּQ,}@.3"SLJ!\a ZD, f߲ܠ >*Ņ:deбYc;ŠJӻU0 k03*ŅžұY^QQ:@ KZx'HNBdy}^ A "u cQf)JdyfF8Y^QQ:H 03*J" dyQfFEX(9T, /bĨ &u1**ǢjE=.*DExQ^ӀQQ8P 03*J" dyfFEXH,w'13*̌ұY^瀙QQ:U ˋ(03*J b< Seފ+sJq⊞n1K9oNQUFUnüx9Aj Es\QU9qvZW[/kY{,W6 FCYM`T-mpt<8 @QUcb 2`'9p匚_a#WeѨPԶ_ Ecm sEUո׹ F*1d!uYIΪW3;,ɅXڤ;S8)2OQbvRT]If~{bT,'bci$ 3va;I/cࣉJ \jg"J<||Aٝ(Xv[f3l |T8mNqvAVT^Yg,)Jw15H6Q88Xu;S,l Jj,37?̨pVcqZ鸝(~$Xr;$]1~$E%>x/f yOj,34E󖾝QQ8X@̨(Y X;S8axϬU8@u$JA23%hg8呙7 C6)ұDE'I eF M(YgIvgҝ5Ieedҝeq4W3ieF ?Ei<2tgq O[(YǨ-S._VyD%kq2+0tgq= z%!OdF Yq2#'Q,3OJj$~myUʜ48cHDQAr3WOuTg,si&ҝq2_(*Jwǝ!c(dFEn"QTnYp34E⸓%-SE%-—<! YpYj,3tL;UU$AN0iL8,ke7OjTg, (Jwǝl$(^EI'#*~,}' g5V}L;Qg]v;Q8B CH%Je~!MDF0C]HwDQ8XfDE8c>߉tgYm\=mIρ+|z9'aPEڋj=)j/zTS\ڋ~QiLp^K{zgҩXڜ;S8Kj/AlTĨ(j/ iL6^B@bTN*-zfTj/U+(Β `Ւ ȌҟDXd2t*@L +*B `iLQ:hL@fT8KJ4-3ETZ8Q,)?K%@%ΒjE=3*N%މl,@d )*UlZ2Q,)Ѩj6Xk!Β `J ȌҩXڹ;SNj/ MzS^@ZTBL HY( 0QQ6^B** `Mҩ;SNedҩX2YR{Z QQ:^B@fTNSwP^B@fTSEgR Z@E-HA.1NaSQj$FYLL,qPTQQ:U9@fTNEکs(*=۟Sn9S*USQj dFEXTZQ$)@5?aj-dFET{ZiQQ:^B@fT8Kj/Uk! 3*J `ZȌҩX2tV 3"YR{Z (j/%]SET{,/ (j/Tk! 3*%Sl6aSn2k2EOXZ2Q,)V-̨(J4%ȊЩDZAFόJSk}phkt*vΒ `Ղ ȌұDPfBIRZ2QQ8hL@fTN%SYQY/qPQQ:Ur\⊋JS%jtV̨pTrVV@fTNS%lPۀĨ*9u O!yec%ji$FETZQQ8UrtVQ,VVTNΒJ`պ ȌҩXn2Ycߜox=n%Ǻ#4C_+:FS(~uP>oU*OBQ`G;^DZ剫ՄxUcj5ZFBհmmGG(xw٫ZWxdqwy' p5ǶVl@TS0Vl@TS0Vl@TS<Պ 8OM(mjIE"J xAX/ P m笤,[P?w@ a^0^YA.j笞,N ^7YA`,hK& +Ω=- xp@)\/ k2%c=rX/ 0eJ xAX/ P ^:_ĺ*O[NZ ѿ uww:+v`A;K# -ƺE S.΍`@%䕭xll{HN7b`0A.Vg `4μu# SV?R8nCZw?ymy@)\1 q҂^(iA0V t,[X!JหiA!K,ܽT6&=@)\ge" qrT/ +<AXir HDv;& 룠`t3Foa:ܵV8Cl3XOS9:Ck?`cV;{,-p<M: _V=`xheLCL\a0 =?~Tl}6G RƵ|c=a0a 07Cq8ۀmuho?<|~7hNx+! ^c-Wxwu5ͧ' 'D<䶑n#٩//L,0ffK~ֻp&7vn&w X?MZbO¹+9dS{&'Xŀ5UL7О&׷j\4&]5E,=w9;Uؤ]{i .UI~ ~" q#|@96) w~f fc7e5L?3WN9 v7nxn1ش}@Y@%pA0ڏirPBT'vP@W*XO9 o,46XQWD\v{F6,1RiPYstcY&+XQRp$L7"4h㟰Y??7 C?,l>>P+nK{x AUO6)EAuaY烽jrF͌<5  Z$舘.}`=y$d65VL+ZM㝈nq;#ձ[̝܉0az 1y"g}VsX4ρ),K +69ggy}^&wQOE7_ir#Rdʳt.DĹ ~>k]k]Ȋ2c(5lN97CH$b'H=l^}dSp-1yu+f6֐nb\[}ux:#Ly]%Wc6Kk>«x@ir{oI3֚+7Oor>Pg荮 0 _)*I2<RpxWqp":Bީ7ۇ6%|z[m50_ôq s?:> S61 ~>"'y:M$31;P=M)`pX/s{T I)RU`]N7ԑP"yaAL`ruܓ< з}:9nd0i1g܈mq`0޺!-ǹФyqn05*.{60ks?`*9$n?==*ץ.Ԝr)hzz):}Tnby԰A{-]SKw:`6aXS&y̜ALY΋0^Hcp0߃2"goZiTS<fq€Оy5ŀՇga0w1ra++-1^j 5FJ~ز iwUOԁA?g3έgCWUݰ=10%\VO9GPýS5[$P!{.Boht87 rue &j;7G24o;K"Ü$u0MϚL=lq61Hz"KN5hik@QO7UA ć9g}naդ}Yv[>"inSiD;6>|)2I6g&Y#V2HlSc7rY>O^*\i I5S]|]1ؘÇI%NVޫ_X6X|[s!֠?Bկ*wjm^v9]DI֭Og5lE8 p_zP cjo/&Ы?o?[ָ 3mAw#*ZL~st-O Ns>wfjV470fx^=s]?U^H؟/8-ɼ N.>##:xFO<7IuܰM.JМƤG)3gI>m߼x߾%zq& dni<~'.bJGH8s=mrʫA4 }8R7GtqT 5k1Dl®+j._#OZ} S~lwkm#z,kuL5/re=>N )ϛ*0K0)\Yk9ky}%+5XTMX"|pnӔqoKʺy§)B[mROeLqo6>l"-mNb\F,ۻ--]o8ry3􆏧=>ZOS3)}1|XDLb(k ipVŵfްv;:w||IR,G)p_Z K|x3Ye* ۨkp "1z f> stream x͏ƕ1\Orb-t{ 0*/RRRFy`ܗ^2?x>r,W՟NO?_ӧo)T29/__$7O)[z[>?_9θt~cfoΟ]6.s>ܗOr{nD_^ڔw͵Ipa.,.o*Ώ)Sޭ68&a{Z{]~],LMvSYŴ ~?}yK-'b93i6%x;pz=p,ε̜+Lvq'씌Yk릜}:ߕӻ󏷷=nDoo'[W6_W6w:?<>?]ֿ}ń4~b9%'WhY+xV)-c]?jL)UK CէW]ZcBf 9SG[4~u);O?'z(-d4qѥ~E2cRWwk>$ÌKYm>r=F}1./9ÊѢshK .4MEe!f]j2cx a qT5pe嗥d"_1Fjĥ!+qѥC 1ܾ Y e~pjHɌy(L=$ÌK2s4N&2cb˦AIk C2R$cSpsHk:AF] [!I3d d!3cWPpuaxhpqCt]W yogUZ)/\-}z搌-ޖW ~ZxpW#B7EZO~="bC@˗ I.K.4a !3*ݛ0R,&"Ṡ.4al !39ʼIk [$I. rjKWcBV MZɄC.ncL#dfyީ氎I^GÜy;Ԟg qѥa搐EK=$dpQGaf] !3I4CBf ]!! H|H;P;gՈ 6,BKZ yHb:3 m)2 otTaD[Vqe)uꜴU~:kqѥE!3[ⶨ}[ E|TEk'J-'+՞W:&Kr\tPAPܦNb4yydžK֯ݠ^ 3y+MV^tdm`PM9ۦG乆GNΓ'u5bBcK BfF4iW2 0B6ꈐ;W]i  d4qѥNyAȌᝳ-.IIFZ@ 2RCwQ?MY2T=R퀥W#) Iypࡪj/ n%jKF2cxoFj+$;]Io Ɏ̘RZ{T|h^aqѥs 1\tib:$dpѥ eͤHk 28yI7aNj2X&0E@20@&v 3.u1\ti --.ɆEa`O10I=2󘘊4X daPJ/1Y]j`P231!Ho AI*]`0R dN nZOؔkQ^ iQ{_x犛= y&5 5iA:AȌ k8  C0=E&whKu= -E9.MrHȌKF2 b4ÌA,dEZ; 3vw71PSLf e>jO0C2҈""0(eT`!fa2@İCBMF̠H f]j L:?YHȊ9EENZyhѢ,oW5Bf ]0אYH<Ð$ Rvzԥ:$}5O6IhI$ÌK-5IHT$dx$sM2K<5YxJ28.ܡ@"Io OP[^7o@3$=. <$!3~|]*Ob3<$ r\t% 9v4bb!!Nf[dI,דdq\t쐐EF?$d1:4˒ 3.5H`t*Ry%!3LJUiCBf fx@q&9;k" $D`+t ~'ɰx/_?}^k3ua@[Ӽ!YIƺs?˪KYL1NzJBM>/E&"$d^`y,  XAfI>* :eΐ;@Z!Mr\t̜6uK%2 dQw!f] c!3I#5" E>Df(A,kRk&{Eչ)2Ң"&"a֤I<$ÌK V VO2󐜚~( E^AS0R3esHȌK=,2|*M|Z2K||[!)aqѥRKBfoR<Ƶ"_1JBfZ֎c>&ÌK-˖,W3 kExjKK D.ahQuaKBVVo7[#BM2\Tic28'fy?KeSo$ueMc>K^VrM24eI,iM5A;^\$%5!4i!!3*5Kaݧ1^+"<8h+aC2VK d dfU'wO|K],; kӿˉlը]¸b]0YS7$ 3.YHȌqHo a!&Ƙc 0R,>1!`qHEHɄ1&qC28ۙ}L?+1je1)}tLE:#d Ƥ.b!!1M!2˘va 'cB2xqZ{ڑK5/;foC0O4BBfI.3 283ƻY@z„*2Y|Rf\>$ÌK-( Y>Pz+Y%>H҂ dXq\txA|* wd:1oig\ >Nɤj9۫㗥g+c[_}E/KѻVX lB6 E∗lJUB9e!"/ .L#Y&B6업lv,,Ddl&Yh>O?_ӧosMf7o;/sZZU?oOWr̳~6 O}jO?^om=6ˉHjo DžRaYj[_YjT{OR`-–Yj}۶}6򲴺ۚzYn[i6gl%^o;_z ,~ڝJ헷ykv$?տNJ\;16R;,uC.KmvwwIM\3nߦlt l|V5[1S{t{{~h9ߕӻ󏷷=jrYucuux|~|S+x^jt +g?#IP!.HBfPFBI JרȧHBfѤ d-PFB=I?HBf7եx@EIF^TJ-( Y>R)RI*>K!f] 5t$!3o)RPWIo 8PѤjH2QPCG2;HBfWPs eX)PjGaJ*uHa*l$!zTiƜDBf#VJTd(JF,2b>*HBfPGf T$dy1="GQ:=@|F|Gs0K3F"b;Q yLbE v$!3ӣIqdXBI Rq<&"M|dG2K|]H.HBfPGzSACkR(# AM@IuzT)ۑ̠N*b;Qގd(:0 ӣ*$deUiRPIkBUIF]%!3QGKJ6@ @IIId9Jt$dUTiĔDBfVBI hRo0% 3.u|,I2s|JFLI$d1`)T̠8& S0Rz. yuU!(U8CPFe;Т $2XM_֥`V;@”DBM& X)M3$aCJPhIocJ"&="MH, z^-$''l1&9.4`!!ӐkjN*O`D2 PHz>H2|*MH !i  0 !>9PHj҄Ƨ&U$0KPHZ@$df1>)4̠*MH,a|JiG 3.uH񉡪4!YFTiƨDBfSt u$f.:J`RPGI2L(IBfPI.PGIaƱTu)SIoRj+2 ˅H2R$ L>.$ Ֆ$MZ(ԤJڒ$dT)T[̠P*jKjҤ-I2jR /!Jڒ$dT)T[̠P&3& ag OE e$!3 R <"L{P@#0dt05$L `*S1B%IF/Ҁ ""J_ҤiD2҂H$dpѥ  OE E$!3I dq?KJRG]JVj^ʛ2 Ոs 7e$fA$U e$!3J$d4i#0-JIBVP-IB#I %iR~Vi:(y$ YA$U!!3I$dՒ4iaxHEZ5AB$jR&yDM֟)2cdq\t)TZ,/[Jt !IM,(I, T/HzU(*€J]@P Uj0$@M)U $!3˧o))XM2cڭdq\ti4@J BfVCBf U ÌKL#OK93ngk6:b#X1.u0/93I#$ Bi>&ÊK '230'Kz>Yy>@ELI$dpQwX 3.5H`*R$d?\W S % X)}xLEZLI$df1`ǔDBf <)arr $EZLN$dfa& ؿDBf4a"!3w2 ,F, 3 IJdx* ))YeXEZ 3.u<( dpѥRR2i1f] %!3I# d!`5i Y9HIAE: 9I# d!5i Y9i1f]yyI 4B BfÊ0Aaqѥ3 kE' 1\tiEBf #[Jk/9ahQubYkF!+.MH,a\KiaJ ÌK-f.2׊4Ls<$dpѥ 3 %k)M Ldq\tEBf ]̧I $ S$dCsf]0LVa Ef S$d1׎4 jRa*9aM?M!3. H,`T+ s+! 2iHo B#aE{b$!oRz mјPDLG$d1X40Aaqѥ 1w$"j2bbJi\$f]j1TX0@2Z4a!!)x 3Πd1 9 $i҄yF0R,&" |*@bJ]DBVK׷c.$=@ !I3 d!Xic28.A BfWQA,@j !*e_Ej ÌK d 5i"&͐EZY+0RY+9iM!k!1H sf]j k!31I=b:Lр !3$4i¬EBf cZJkOsdq\tŬEBfcZz.I~҄Yƴ928.b"!31HK2 _4a"!1-ii 3.HbL+oKfZ$dkiէes|@vHF] U/St2e^X̷wDZy t+E:9J# E>AfY~}ocjϘ$I.^Y/Ӥf))0R'%HBfgP$dy'%HBfgФv))0R'%HBfgP$dy'%HBfgФg0R^@E 4 #?-/uZzIk8aqѥv:de'pAf"M|$WnXN>עik,mztqU+-j9۫+R*k3^Ϯl6RnY?-u!s0Z!l兼,z쥄i ,d)9oWB6 /,DdPO. ,l^]"Y(֎0ۜY(ϣNe!"/ lz,oraqɝ~]wx_dCfOwomlj͒[)>)WO?퓽\zS"g"m؉ eo7KYӇ76K –RB۩YjXR۶훶m|o&k4s?ٽBeҊ3!'NڳS+턯w_[(+;,uC.KR])O9-9[-.kncٞG[;?|=n9Yw1]JϜixv;?٤)-)c@כb_]47Լ??=<}߱FϻM5ٝ?n_ Yw˵B6ԯtwC&ڽWC_e`#'xmvpQX/oѮ[׿mvDw#/~lk^X͞^m^}VO]=VL:_z Jښ|/ChM6ܹw4Vunk֝7NNz\oy5u|eU;ܞ <ǼqzZlsu 켞?h_OWnno5M9Žo޶R*۵5]m}6QQQx_εwA[?ߓǻ;}mRW]ba*9QHfI⚚s,^꾁tDGxO#}-<]G8}ڛ;D:r`~5$Is\}|ׂk~ݛ'R0{zw/ywۿ_~'7?K'/[5n˷9/w7V+ׅn&i϶F(. V_o=y;ez7ѷvGvWڿ|A7в퇀&W3CW^lդ]y`9Ճ<C,M]ruJ7C&$vΰX9M^}~XWo,Xv=EX[on‡51_.4בzw~+Ao^yX[Mey7o\{bj66eoU֮j;W-#^<kHAX 73f&ۭ*Ϙ >5|+N0֥v_SP{/hm!Nrv ~O7{&}?_wϿпHꅉ#m=bw/~Ro[}_ϖW~(W/!ꆅv_?U}WQk,g.ը޻[,EEv ]rϋeyp[è~{:Bݧ'ݗ׾!'QIXuhiu)v|7N^9|]׎v RYTO[z~shOh>Z{3 oÛ_c[ͺ7 /Ҟhw*n*[Մ)x}מӶg5ssZq=3zt923[?/2=~O ZW~z҄ BzK2Vhg˒@gcn2r_󫶃כX3m:x__W{)eoA]B\rKMzZy޲ණ+;U!k_gOۣ0jbn#KOY2]xкK9hۣc_)Ǵr?i_!C]qw _ ;mctsS ^ npW^ziggF&_hoNny5){C,. ܓbzX-l7ƷUݶ8wtԶ5ƿ_6r-<+ۯԭu(/T;oz7|~w~JG'zܟ1hH{1q'SoFz2§_cFe;[S:7|ƦYl6 ޴lz}:^ҖXjl :A^2>;M\>=}Yy !jA2]>;G5f,a$o.MmNPX7Ƿ}h*3?>IHFtaѲNhW4Zs_xoR{.wAǽÄyGrzYhMe"zcmZhrcZ7u$<{}T}^{K 7=̝'Q:Zny󛇯i=֣?^r5y\ Dnq[C^z@.{v\}'KLl;S%Ke~qt/|D?1N|6nQuf6lg~_Y;vփoh8-N-NI&zj'/{k3<'w#񻗱Q]ˣZj[5<1ٻu㨶eeQH!Yc_W#C5>|o@_[K^Jỳ=Z|כqtϪ?U^?EiSM,nȖ8>caO3vճȵl.֥W>қ3f8uLǝi3t?_;638\OQI9_LRz=`KicjN~=ݴy,[2&kn[;Ow}?R=Ernb:[ҥ?^v݇i2>LKM:e>nlTxz6֊z{9?{`iv>Wࣝl8FQ{ryzu֡?ףlo[b ^U, '?f*&xDa;ϧ_wE{G矽pOVoɛv=yNcˁ->}Xg8~G}Ioz==4 ͬ#aYt>S0?X-;Oxv݀3/X24ꌹȟ tg,Q~̒7}?{f>_?wk-=qDzfμLg~3]ABg~*op Lp[%xlsO"&}ӈhyL1}Vb,bFOm(7\n3P3t=KEI@tυp9u~/~84_&#OXԺcd?*_B[wH{Yr+"c7.OA7zyOU7S]rJ?YbNwٿ\!?]󠻻>_>1jM7t{6: 'xr7o.94jBD'G_v`26e㡑86<~GP0>ٲF7M ]endstream endobj 577 0 obj << /Filter /FlateDecode /Length 6324 >> stream x\s7r/Ö+U&cGe]N%%a$QԞvR2ק̊媔ĝF?f_Nɏ'/wO홶n_OʲQnZN*}z7hkeVZ-?unOQ°w mun5Pan%n% }=;*"q1cqG'F2la'oO|0\bhe-J[S[ ݁6Iϫ+,c: LkDp-@w/.#F[ĚqaMe?u - Ұˀ*z4`mPV`Jk9鲁Q6thD FD#Kl- Euu4V(P_ԙ9fZ\ b>j- m!Zd6]_ IrC7w%ڞP%9n%H vSp}9ڭ K~29~?nFw;rURjMWLb)Sm')ӑ]#" 雟28Ip&$^} g?L#M}tqvг3*dqT:ǵ}3ae nGˮ. -H8'f|_Dnv9c.vY#%-r륪o_>i7KT/Wreɟ ZƒׇWg&YiDdL9,\&AyXGm@~gˁݐ{b$@ q0kV;W[U@|[6?:V wɛm96Аcͪ 4P4~B¼^i,D&rRVՒ rJ/+H3L Mc2 5q* <5I,^FL-ɭJcV"2{weq>D@/(uyP6͍w !2/?] |wnNr 8r8¯K Y[Kl3c'~78?wHm scn^Dm] !Wg 1+>qãmέImv);GTuեaoo9TL׆68/# q7R.@%PW=`<|3ɟO7q3'?ZHQ8柃ћZ1vcf6Yk mR*Y:F7;6dCi X-~& æ/ɏ T l I$4?:dvTh$ @w]r)]O .L:p\kܧMs Fz+O[E=ZIn?$C.hX wvj>ŚK>BMQBZ:DS lnvhl5k 5bnL}ʚ)B5UVV ,ϡ/NLkOESS x[d{C|t c_BXo6nw9Ȥ b^?X.0vYM`' O L(vDd'*uD`׵d_\BL!3ĜހPMw…l$Ί'"<{ո#i¥$&vlB~KQ@ySzZSVCGa(HܢHɼF/FLq: LKq>\0ZVēwJ׌AĔHQ&*FVS U0q1Px"`'Ks”oqҘG"!4 CLa9+Y7݉d2'ۓ#tƇU4w)-us*%sGXN (IVݑ56FH>DvS~IcE] 2Bt₵l1od ڂG % tY7إ5fw|Тl1Rf2g> s_'(ua@[L0Ѡk̄ v11˄)9fkTZX݊mJDXn?)(u6?pj*cpmlJux|o2*Ɉsa(LBD'T`$вV 67yX~|ΕETpP ,X#&mj>BKTk)ܟ6AA6 e?) &*{R!@D >GcMQ $\Sh°G m'L@"o4!bνA=!v.ф[,Z\%]# *&'_EIRR~V4O{qʛʄ+`x܅=F}Owc,Tl^=aLj8YhjsnHv삧%--1Gy᎚DZRvaLԟV øYƶΌCQ4%,W!cQ%Z,EhBiT岤˙#_f(vb!Iv"s=Hh I|~Z(LD6_K-Vfnz5[uis] O]l^q3ZL\_$('X&ॕeb:tt-"Rp6_H۸3mkq(b|0ڏÏ_B6<<<_S]qM4^)Xθɘ6%r]^OI{s7> 1%?{_+2at>8,"56YKXefd(:pڊ2MӚ9_(&wѨYZQ՗c itx^%y& K{?qqYտ|<Kygݦ`!J0Pg"f0&%bW|sr >{|ڏkpCbZHc-N ;D%_L"[B$V͊tż ]aU_X'IUm8m",U/嫢(Bi_*o7[WVLk !cVA^f#.ҹ+t>`KabέͲZLI<P#\Oh!I2r~@o%d˔.뫅mI֎ǁ!cuC`?xΙu 8"3(V_QK<4Z%!aKǦ|vVM_硡!{1,E,6/ͳ.j7r]>B05@B.!k3%2}ͣ"?ɤ!sˉU$RYpX  ǽّ7X> wTe>> CyfT9Lzu{,=$%5!^(T!?yWLO'(^Zs<4M *AرSRDKt[dm@KW.TC_2t|@TOaZWOiuh1m+Á:T)4lzVv>` @\pn4?o ;jW[ xpj~v \KCuY*&q҅q޸xm%܃0I+1ݝC\񣎚C~;mzc瀼eIKVC{sɥ $]׳wR1S5׫5ڇ] 0TnyVtAÿwl^_T7{|6t/?}ßܚ'OB?.NO &ĔD].Pe#X]]W̄04gכg| cpΏϦtXU _'ThP.Z,UZ "÷q~(,8Mcg kWdIqPX$'OInЉS&Hmn~.NV2IpyD}9=`?qp6q5),E K^+ߗؤL* Ϩ>@e5o ;!ػ@H0%I,@qQO=&Gy|tR6x 횄 n&OJYwݗ'wz߇vZ@1?B41P|1Ipw!(h‘2OLGFfqZ ɩ!SM'=ӳ ]k~}ĎaQp%toNғ0n3I`4Ol$*}L#_bDhbdbzV)ۣ_{*#,Xn[֏f[؍LNXmYOb=S*:}tHgV4)_obQdo+&,de#63d6D o~uf;Ew$@!-DA1QWd': 'e٢+|CG2SN' }"WV#qvJ"zHgםd2$?rPe,=0=ֆ*O٩-n1C lybX>_鎙X]5ejqXP~sPtqde-EyK[`{$Ͳ8K>˙Iw̶R)w]Bzż Mڳy KPB{҅m0n|rOݭYs 2 T6!WIYv ,iqR-\onx/Wr zK7@+ h8Xވr=QҽCߋH GJsAxl L$cZ4[&nCvm;+qiSm |d.)H/W&Is7HNo =n6~;܅b>vS7ߣ1bz}~:ll @`R52uMф5Oxm1-X"'8@^zWFIb_0 ssRƤ;sM~3-"<|HS>WB8{܆!L5pm`=1rt뒤D&o3И2.;mq滟/;Y4o&݁}^ lK&> i.'q P2&n L9B7˩K%WY%V)%ƺc;yFGP.q 2S`-6endstream endobj 578 0 obj << /Filter /FlateDecode /Length 3462 >> stream xZKo[!@8İ_$;Hx⵳ X+( %12ɱsNUu7MrUS?nmgݟ$On7W'SxD݉6,qMX ڟ|-=O$M$yT\'GﷰDmɌ̐\D_Tݣݔ-QJa8,a (%ryԑ(TmeXT`GՆ,iʳJsTBd1hI@d`s)\8OS1+>s%YwEWˡz^F9hhKRS f峦_?x46v%g[<(j9}:P͛'V>{˕7G-G}XJ!|z玛XF>U9Ng(CY>ߵEs[vn$<=,4 fnIqQy_is>W}pbzb|ՠ9ol \oO Ȼ+j.n:!߿+n8/Eo]e7 Oe;_>TM(PWN$nfLx.&=:T쇢h{po1UuT>ɯUsm %?8s[ % c [T530l49o#&Å:[h @Uꥪ7 č,qo~E|#rڜд̝t `ќGaF )[ |g֌x1K|^祒_^MkXf ƶ-K< N%<` ~,O>@Ϋe:@,/OD8F,F ŻY"#3؟0|ijl6қ"s0a@"j dQ@ij39f3LU 0U7K;' `2FS7( &hi DT>j8,j3#n; vG򢞬Lp֯;X\'c5{;wIYU< !,V"b)fٝ" V u " Xd;ОUtVH"tE 9ɱ]͍'&w ! f*Ž67]*HĠ=y O޹07PLS>Z玫,QΣگ B9`hgz*/v_ gN^.|d4|OµH!+$ dR./, /nh+Zv/=T-2/'^d!O՘iX\[ johILtILY- ?T?l? vղ;_D*ԃ ԂotL.O u50f\Dɳ>0B?+GLΥHn"c&!%2*rl]& 2o̶{a `A?i4#SǤkÄG!D^|F{<ͤ^xH Z ~Ϭ~xԂGB+FFY~l[NE:)]L@̶GkyaL d o_hu-3m@ܸ+e"h0<8yԯ8cAAY*.tj=1vAg*t48`P;Sn:B)u5E(3˘ 3W& X!87E~62zX8-Hx,li ICnLkNs:g[6F 2Sˡ8"NL) +G@j0!pe]476dJ)K/m|f^#vłð/% z2yMo̓P g-6 Df4^}&LRTf q!s0f&ȶ[p:hmNXkMY)D0Djڀ`A2&q2m=Vt `РYWH)gx('}ׇy?/_8ub#E@d =9q!7#BEg-Zr+bPvK}Pެ\SSf>j3'te7q5 e lوTtͅ}BBya`@2 {u]GuEed93EͅI|3| J]ws7AگntffxČ_msDàJ Ǒ&ެ,ҁf m i@USk3I.p'Ć K%C:WSrNEzXZn-@bZZA&t4-2HCfT~.|y{Eo !~H0.Q+qH!%I_8}IdxZn;WQJ0U,}*bgItioƿa_]DGV=R=DU*34"O$C{Pz_Vi1R4v,/?{ &ii93T{gFr"j# (/^UjnvaMIlg$ҿ0~q4/zC0J!-\ Э]k@6ߚ,W QEۛu>nNj>Y YpPTKqg(zXe|:\D/4v!v༯z|$azܫY??}aendstream endobj 579 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3789 >> stream xW T׶PDlWh⌢q~FEE28Ƞ4Р ݧglhhq@yCDF~5&oUKɛֺkսUg}v s3B ج^ifbtk 'hZdIZQAf=(ǖnG  $%-*ׁ EޒtHf!!*r  ,\aa$dpEIsW,`p>sW>ùbas]Uz8IjD5` V>gb$h?Ugc!?A*Q&ADͳֳ5Wtܱ .Q5%iNn5izA}/+B.11O<LBhf!|o?<}.C 35GwTQ8WW 7zޘly׃{ma>$#zKl7Nts<քMi^*3}^f$á6ojϊݵ*k3ٺ΢F:-Mu}@WԚiYy@eOyqua;ёQTcR!?pk䤿C`!T}]a_{I|aNBRUEA,+J9^o=9΃1 WL:( DI%(J499(oWZ6K`gߙk8f䇋||4|SΠp8}^p̻!l}6%jSk/<2領?5܁a,J vZC3%.U?C-0@t'zBXM;(J(!7{1tV4̚U3 Ԥh|STg&T"j>6z͊n?\߾6ڜ|-<\Ѣ̰ ԤwQ7ѻ_4\:.N< ڊõ!JP)kgZ/ȼ,} owd#E&6 z} @N?ges+Z({Wwk{3Mt]c$1sNQeöTDU1 HWe AsTtu<5oQ9ӨTKdexLhﴧ+Y?y3ًIh.{QJmN4%?G *F=! @T) II"'- d*in5ϧ*]e,񩐾ŝd"iLQy'ivr11;8"E/ZjUEM݆]![YnfDdY{lŏ#<~ m"ejHtմwꙤ&Iҗ/8t<;`1•Z"O?";Y--iwpXX aepQw_=.?k̾ MSsn7d]'8ND%Y:*Z o0_ށh9va>OmǏñBڳgK]A1ꫨߤx'xN8kqCLMxxLLxxMLCCMMxQ<_ޠ;$12*"%G&O]σXjqF:OoSt.A#=m]lxc@ |:ݷ/\\V KȐ3E2Xc:P_¥%rc޷7?Bt2nA17[so^yjN'-hyOȵC0?oذdtE _+:ݵcsg|JhT}Չd4 OƳJbyZ^"}rj" Dĕ ?%'T2QTJ7גEIk,LTjZ81$!gA x8 EMrhxZ*/K+Ou^Fl|XP+ (pFg wۡ=~H+;24 Y3? ,Dx`- 0l7= YBE #!|O &un=60`p#jN* 7wdH])P#9N[R‹r"㠞 s//_+KWk:O^2jrZmNn+r1Kendstream endobj 580 0 obj << /Filter /FlateDecode /Length 399 >> stream x]n@ D|%k'RCDBIΘnj-o4r͟^/v},]9Sl~_gs9\jaR6jVS6,t.tTVG71+Xrb1PX  'bVy{*6pb#GPDPCC_mj11b(c("P6xf<},eUXǩ|骡kendstream endobj 581 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5668 >> stream xXixSeNG(` A<  6M6mɾiZJK,Jbq\FquySO/MQG纾WsscL&s5kRٯ Si ݘUZH>ft,- + cO̜Ȕ{듐{2c"-B6X]qYa-LxbsE {% /KX[(.''f^B1O]X7#;5/303as-oܔqݖujj^Qv ajVj~~j^jԢ"~Q6TZZO-3G -/.Jffeooڜ%iK?7>~^9}}\c!#M͌-e3+22V2dL|ΊNtn_Tg%2@)MUʹ4|>t41 *_[ZS3f}WtkM@sA-j.i'ZhxM^MťPJTP}MȮS&mѐ尙+€ܯmhf"\ E7]GO 3cMËmb&F\KHk7;55t46 uH.D]/4f+tzaBe2'Q7n]9H-3N|3#S2/9f 'F ɢbAi]Ryv```kv6nߤfG[ v^LI:ޤ  &pk~^:ZMDyZ~#sw>I?9`#>t sr*'K bwj^q՛Vxkx ̀YD1^BnGiЩ dNBbI.mX<t1| lP b(F-{|!{PF_.bFSi1Tw:Tn+_I'PkSS@Bl}R4XŮ+v JAi0cBBl뛋Љ8,U—T2ʍL`GjZ׊Ee;t{l`54MBsC$=^Ytj-{.؅F WϡdbN ` {8V?ApVThJҠU$ tW]~pَT7{ǿ{rud#$O&ۙU(HJm) ^Z"RdUs*v8yo?Cqͱ>u 1\cE_'Ǯq`644d@.:6tˎTdEx DIP^T{,e>GϢXpzѬֹϐ_r7Č&bzt6T\UbEOjPOni=硣`%rޠԒD%PjiMY.牴eT&'ZuX+@#dyfYYłg+7G i6{d V6Ԉ-@|uMm°facfF8E=sl=|ȶE52,npRFJAoؑ \ZU&!6l΁gt(s4rcڦsuZ.};6Թ&9 A8L6q \ 62\:-x, J{,k'Ѣzf0.>6bj%):E6H aPVcƟ2\E 1߾B#+8]omYQґ4lz2@?4o9qS&c)^ ].O#ymQi$mo/螫U-i]&@X\ZI$XvHmA^Y֠1Iya]gϤ[s_|8؏iBZ w%g~[H~xmh: 봮@뷑|'vgnqENu4Zl=-4d-j1JFig:mS ψ~+<Dz/ ⮵\67-ĂbxqS_S."G_QfފH&/8OO'? \FQϝ>Ig~ M8H e0٩(Ƴ? nʖ4BJ]ě*(|t~iGd~0tp8uaQ_^n /YG0x:fLf"R vD*DDRGQ î bx~3%^A+kHƁ7R0,>^-0@OzlN@u,5V*ZRF(8a%t<}=فץ? '`9hVM՛jV0:& CMgL~/yl˕q&Hbֽ(~&ZiB/‹u89r]Fl2hV46mh6=fЩ4zQӼ2S/O^+Mfh>1}dlVC31U (*,f`V#^hڽs_TPFAO,qع1_Nt媟֨ԓ◄S(tXe* [Dmm;lȠ1h6+A6w w&/#iҿG?zWI7t?WA : 3Ħi[!gptjzy=ְƔƴ]O> DC:p2suo'_0\i%N%]j kiP"JdWeF^G~nz J\iT4DFRՀ'w)=}dcs˻s> ";&z5B)&qqaQ볺ܤl6qV.' c{nrbTOKDK .x.ZIo?V5V⨱e1GX>qh,8q4C+xh>tw[+gB {A9w5|]ҷ=E'p.]*1f]~c:uxv esyLǠ_U!CF(lթSFZ-d%^E8".zOL3{3 "oRI@|~>=7BsUV 2jl8vLG_8Ҥ쌜2|+`qziД^4W.ʠP-WfH2 TjZ;ȂTP 1 `u5>QAL}- g@6_]@AVĺ&ՎLx }L2譢WV7h^rci=bMLڱWpĹg9XnjAw!Ƀzْr*})&@@mj!ھ: HpQ%+o`[MK3OrjcUCtnd2x~Y $Ҡ@MLe_Q({Ey7"Z1,><ܦI&s{)|Ơm%da-5f]#3LP"͒սϵ7zǷ"$azzT;[X]hOa%*A0A5Um:;tǫe3ܢ轧1V|z v)d@JRv  aC-KRki|wm~/b|ELpV{E9Q贳Ő*_3_t2t<"nkqhχϢ?/!26{E//|cgsWGQh̝ЛH/oO_Eδ;ߠռذ'MѼ?rb& ֟dE'̠ܶ6;Nc]=ww0@ϧuWz" {xeRF];N={;X0 !ҘbJ*һ `5D"Qd$ΰ=^lף7'> stream xU{pu%mXhx3nZPJEAZJ[KA-Mڦi4Iy'ͣm&mR"o RQu":28wr-m`377s3~~^?K8>g bYs2q]M +č7%ÓOK> nHLdf7(|7R݅v8Ni7<#*keǗ,2hU(_\^+iiw66JZ5zQYER$Wlm.ZSX$ZWXy<Iiu awlZ'{VQ^ST;gYİ\[mb%j,{[,܆`942H[LI?3]5}?j %fʻc $|BP|4< g(AΤcu){2]im$h{{vEDi0DL F.ihˮHW+J4 ?ag|[E{pvBbw"Q9>Wz}<gxɥQ\]lo'7IEFBG:+~d%dTE5hh-il* 9_{Cz2m g+F]HeaR%T?qwӃBe0jiXD6B 1mL9 Z0;XXlj5vEWƵ@,`hghޗש? 8h?(@Ki ڝNMgv7hi\s@jX5[*eh6B}ǩ@mL'v+v≻@-R7őMN Ny5+M6Kl@ȵDR#pPRKc(7WW;:vVVN_uhjWZXj͉Π@R;@# cTMV[+048@XTwL bSHa+֨jX V-Z`$fg"9u=@Cw`WRr>>7㺀ч젾N6VMf}r9eaxxg'%,3v-nYfkАV,x̶; ѯSn9Z 2n1 >LnTYr+ ?h8}t7#E]v7%T8ZO8MAys`{7+(kS 1*H?)R~KtMfry 6L|tǣgCoֽp6P_fA Q?`&g<_$wy{?>KdʐT _C7}NYC}ӞNUt`(6LFn5 Qk5hR5tGOG>E#%||EbV7o rMCIJtfrV2QuHB4ͼKE8uK~86&IeEO~RkBj}VOqv:IljvMCmvש@`Fj\F*Q=dܫÐqxNOO./7A뎑?=X46LKJfakǢ{Nʃ(݃2S[tJǃWqTqOvsäIa!5 ϖ` 2Wb\)wy[=} hn]m}}G^ڴBrSaclq,>"KUgP10i${K6QԑQCN(*8nD>v[Y.uݺrIZ!k*5@c&8 oaBԭ\פ@78 ]Q$\;k/X @t3'?QAjsM^nH%x,|u Z ^''hFʒ#$ķ>ݜ JiR%A *Y_H9%|&DJ,XANʊVur8>,xw?? շ| ĩ$w"o9*XM@l1|yo_^y~8 # ܛR*bd;8u>9_o%̗Cll#^u^: Q 9/Ym.]J/yyt|b%Q h$->J~t'P?X7Zw҉QP2wnۣChCouFl.IfͤAe/V lqT_ 4 WErn@k|(hpuYgV%|9YPt=gHˏϼAL+d΀̌;hqq9B+3 I;endstream endobj 583 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4410 >> stream xXyXS?1jcIsh:E₀;*K0@$yOdc d jݵZU^ϴ38?y,o{?1~pl$LH^tڴg__~-zppgLAiQZ!K_x ؛ &G$G[P?+LHDn~f7m'b{ɫSּ/JMKK"{cb6oޗ%x$fAL"E&6!D(Jpb5XHO|@|H,!>"7b9@l$IL%b}ēt-߯'w=j)ۧqIE~3j_B.V gpoSA6VG$UVc K kdz2Iy1@MPuiAEɨTCN1TBR9l]dRHV06nf]#E`Hgyh=e}OqW Eyzmv>OYlYc;hvе7?oݵv'4/B0"Lf k!9OCbs@C.*NIN1П cd(< 6GKIH]0Ki8C>ȍ hh!e(,{U;(ؔI me$(Za/u>w ST J3Z 1**nriM[c(ř=e)`Tb^Bh (zΗf+u%3mbtu [hQ9֔oŚrK`buIOL9ggoz'n֞JENUdUj>A:;.6WF1Ǹ s2*?d㩸ϐa=A[]h 'QEu2 5oVSSi,o~xVvdu%y*X%^y~=@κ?Cs Gh~Ԕ8!險ʑ?ڌ`)˳ "lN#Drl΋YX3}xvZSPj ?ئI鄥aE.9zH٢[WEK)( }[F]xޏ&庥I>IIT$MS4Δ"dYﰜÝ8Q暧.e/͏!9fVz?Bb'C]h%TD%gLjC驤TWO7!P8C(' aE$}*(9,;|LT!)޷Dby_6mϩ&t\N>rsUX`B &$#A^//N^a'`wÕCjinĮJ.rVF4=1gMKU6kx-בF7N`'=, tJ᎐m=*scQ]cଇU`IWf{Clቑ)ٔ)%9@阍1ΛGtfmOU&ґ Y(t4.k~Iz뺪)sj@ԇ[nx(Z訡Gʢ)+Ab\S5yX2? 9#/͠Ӯ]oZ`v8Xqy$ADw;ߤ4zBImYЃ31握Cv>] ZcFm|;f ={R_ oxbh&.'-ȳCWBtz&cғlq#$@#g(zcAkv4ˀB/۽ Rt % 屾bfY[Vhӵ]7bf ^XAPabtfbDIa}A ^u_d ߝROFk= _D9WP;JhsS^xTo[y-(,=]3IG#ߟ}(1vځt i_t]/nᖻ׺$t}48|MNWQbgxky:EF,"oG,䃈ɵ `RZZƾCwzq]v:{ykD[ێ@4^N)-W8&Q Ap |;jx OKZ1<:<0m(^hMA~?5|P,ۜݽ}1NVSyWPhϻ۱/"&^H@' E<_'8gguZ*jM"OTmRƫDJβė Z~ bwSx sLJ<6XT4Xڿ& ey5r'ho_]Ԣ}\o} LUL\P;Mr;_/)$% Sr+\u 8pIm;"qN$]~ pw񉹐Lpp<ŝ4نw~Ō|2%+0{͛nl$2rQ\rtb5P NOmeZ#GQ#[u 1 ;sh ;>3!/n/(tBH4"`75;@4=ON 4I3?cfz&M8եWOC:{e`L>Mҍ{ȳ.#fWz`1xRql6ڽeg#2CgbG{kY4E | k6VP%@!9r񂋃v\^8:>QJTPh أMt!$Pto~93f)XTM{O hC,dsL)d ؉w~=W6hc* lb բW|j󳵊mGm!Fp[zRTzɳ] ȃfsrPwRq{*xPLJ}Jcy3vZ&i!Ô0FIc |endstream endobj 584 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 516 >> stream xcd`ab`dd74,ILf!CGߏ=<<<,~d }W1<-9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5М200000020=0 [O|z'T~W~67frԴI+LZfv^ݽ#sEfmNjAbɔeert\[z;6;2"#;`A_ߌs8f/έh .ӵfɞ5-[{=O|+grGwř퍕re15eO%4luY]'o˶T>y53+Z :~kug/!Zֈ-3]η\a m-ýcVL> stream x{LSW^CglRu8uf0+m1PDQQh+w/,(g},K&nc.fleْ?6r.2wM̒-INn~$B$\_Z_YT]f2//.U4Jfs03E%1b@.y3'%JHr vjE .嚲&9;LfJ)5ҬѬ7Cfɨ)U5r&]fs 6lXBο$qE^Wm(5t4=Q+7,tC11H_OH!ӧ) %ۈ"AnHr"K6SVI!yM2:+Ղe<,[(b1n;WooR܀-K7Ze--wXu^ zNi?& 4bwXndSh</ P7Pmzs'Ltvm<)cy'|K%c=hNeE]CЩ㷸 z:/C'T|Aa ڄ7ihӉDx7 @m:oQQKd -&fڷ0waߓ;*?We:B'S'%h1V<\!B 2+Xzz;!(8; S;y*l1* WxmJ P1k՞4=E\h뚚7v-?_ɩ( F`$/#i \HDL Ua!wqm0jT,q18ۡ=a#!yҎ-0g2;Ba15'ɑ~ѳRnh7> stream x]}L[e\۔1`7:`D&S&& Y`- E(V8G- Qt8qqY0c*2%*$j4{wffM$9G(Jz~ƽiյ |"'b 3 21"^K[JjMmͺZhv \UŊjDE)@܏!45}kbތoG~Q@EY_ݟ %:A5Xf2\*(]"9:AΘqk aV+|;r>W1\a8u-߉8VjuW ~[[u͖T`$S |6X-߅ Bsn7+77l⸍)j2˱w{A;0$Ɖ8v̽+E䬲Ȳ4'yfʺ2yE`~ fy*{5QH ~I7oU6P8fh51 F=+QkT~NhB2b~.ؠI,ã0^hqf 1J!'U`;Z`:$=SmtI&^{i30Q._GlgvC> stream xz|T a..1("M$H @ ^6le'ْd{K7XX,>S|'|fΜ9{QQvvvcֹGFDz튈{u̍abI?v} N}kE0>=vf9uB;ÒߊJ  s3{ܙ3".gݵ'42164eW^gL$.S"#\v p psFO9uֿ EQElY+cVŮ[+i=){1+tSXlɫss_K /x⒗Nz)S]LcW(j<@yPej#5&S^j5LM-rj+5FfQ>Jj5ZMJܨZj5ZG-ܩBj4rXʗzʑAeO=O )5gqj(5ZJ FPoP#QԳFb=Xc7 [\&!ߦ?~&tȡC3#G=QUyѡ!†? Dnoc fcRC+r_8vEȯݑg FU1q4T8Q5]b;:1NvW@ LǓ8o4ihq24K5h#ꡄ oxiJV KFo8󺞋35;d) ">%KGW\>}]xmml N6zc(j4DpnMf:$V6 t;4{+(pW0QXm<3KG "" ʗ+|Tfَ&Bx𲛒G'`h/:W:u,m7J|GW*^:ՐO?? F5,~8MhIlyV|w|AVE10:11Ē-m ]U٦df>lbR-d 'TFN]f_д:4_eh%*}e Ju R Y)1*vχy4?-'c3$eKeEiY*|_Iư&X-5q_*q5g[Gw[ }_Xfv95]xJ!Nޱk;ZvyObZqMN?OP^mEf|AF-ȥ'&!K(ۼTM`ێ1GAZRg(8RW;&EP ӡ3F7^Su5 8 ˒'ɏ7[`x{%o[ ?!sl hb%7U1)248\I*^inA_(}*tdadIHOh|&)3:@_$0dy< _~VOGY+Gv &U/-&mc--3_#{5؞&QANh&(8lM&Ar@-Bxs%2^빙/F w Y]ڛއBDhUVcU؞U:W=}ސ84Z\O<*VE s;[A~6:+E6XǂJQ$K p*P)w7U;CfvT~**tHqIfL3Civy绁́#;\3zpׂ-x )ņotqfX U&ס?|H{!N)m>O+怒]v- 08Gk $v8LvE#ZZۓ+{x8a< f!A+WA4)2w8xOvA$z4q C%2,]$׋keޡwcdzw5pw-/8{ۑ#D ęgTf}E8fPB$ ;DS3y_g'7yKz'ΗL(hk:HOhf;_KaZHXQb !Æ$V{C~!H /tC8C+>+ *bڐ+kOIߐwǞʿLKr9d|R^}D}HqQ[j:2Yx/#}f\\%;eH_Ԓ7vegWg@) K_Wj0U2aedù.jaXװc΍V?5q ”pvv;Cx6<m3_6GZqh # }1kٓ8'?ؖTx lS)4 Q%<*ʺ݌Do5- 5 JC]K$ ^.e@ RhX3/J*U=!Q յhﯻQiu>\'#?3cvb/^@^;6fyz^G aa+U$#6#% sT>"ց WYRJj)"p1.Qհ8W.8İUY҃OfkbS sn> O|s2+{Zߏ襏#I؟kmR]8z~_&HQ6cMnPHgOKHz1 rMFROy$ۉt"j6vV G<0 xv⑉_NBbgA=Bb\A_t21O_C%+:F!w@렡L2+7%z'́PyBs*\h+ 7MnoOwMfKe7oXo|Fl` QXC:OMa,V-9&wsӕvT65r(5.I:fkvcϱ-:>$8=G[1+T2*2.lV!HH;"S9yESRUz&soc+ƚJڛttCdEBfr(Zuxq(~/ /;_s3b6 yU ^,iY SaPd>NWՑDFh/,X Z,6}qX^t0:׵rnOahG]43ô&UFEJZxPw!I0wiٚc}נ<K >o)))U k֎7wTVfgFP0ȼٯlK 0}yfNi9Y-=[6a8z@7i@fvG>x!ytYO&oˑ=ʛzMFcmF3^˸Z dPuqb&ga5T9gl%2ŷ_r~EfP=?<>hɈuFdWoop ;g/ڀ&QW^yNhyc!'x΀22;\BÄ#{/!p9]%s v핷ǔ*g[ͺDHvKw\&Zԝ$$lٌVs%ǏrڽX% l7@]m_(49k߬ɪSѯ#U%H'-PQ]r--=՝PlCNEΙbޅПY[6*ǕڠZR);|^T}  uo)NC.4XўjB{HY kxS/5' @,C_'E/ZԢI_?Nr驱xB3:!x_o)&[Ygghi@9}#uUm:!prj#Tea% `isTW9U&_7uHPeƪk&"Jspшqgzxf42mzbz6 _:@L^IŰ6!KS.!s$}?| ~G=$65IHK'u]>, {f-.PHT_o)*RV9rT,`ّ:Wc6LRk>m9"E 196;b]NnW#ZWpGWdz!K9S聸۵xPIY6V1gܧ+_zXv͈m·hᓻw Nrqᕀ 뛻u?St3px'}:ZZiՃ18Ӥu\~ Tc6d:lC8&cC5fp-H>j4K_ZCIL:4u7(@}BK}#)M/T+T)qJe0(* LIΒJyKhl,- Jډo֗UUmA2/}ߵKG^_|@u$c*@%&Ҧ$_,MIT)[H)#ivm9/!"14jGŌ&Fe?0|h#B*CpIΌk%e0Z+?mltw^#=/ѐK `R!T+]xuHFU {>uhf&1I@ ^)޻uCLVU*r~lIb=Мw<4"gwx 5Kcs[gUڜbSħp I[&bJ?}hMi2( 25I]\!~!m;8*ʒB:OTNN-r<'GWlE#"юwOIߕ)Ӹ-3avfQ D!4o𼰲ˆ3~PiK;ވfkK{Jݜ+~Sw&gl\巜e9lz?+ԇ>pGb٪7=yU`1-pd]EQ;>Pl:I&K~\V*$4@; .F$}$>TS,3nYG$aNٲS3L' N*5F]ѤVBB+J4nCۘ^oo\a'E׋uޅڸƤ(U heرm; 70$:FX;ltz3ޔ Na Ф;NN 9ޅ'RoGi䂔*h&}>4&> $_7DhFcP0u2>Cs I[oV{^O]^-4oLLפi8^h,lU̘*% 2c4?Eio,36S0U'<}1,X3 SC7-SXk :]q?*>2˴}_ɼcg^41>v˷xowC܇i-|OaX:XYt7NJQ4J$+0 3h5vHӍ&t; qW@rIωnFt6ِz18`PC<\52鏹?Vr Z$I*ݯSw}5g4 ٹǿG] [aGڲe 'Px:>O$dHƼjH) W&C"[VEkՌ/>M~DYxk4kMү@O婼9y[IX3k/d_7+*:JEV|w !@⇴)8r_/3Ȣ!Zo!Aւ!] `ڠ] $5KK !=3NT0) q2vKW 6pʌ+K/%lI]Shg2Yz9%*29ܖ=2qhy<-0'a-6l=#Z`!2;Ϻ7dDJ4,^ԉv+f$jYJMvxlmw8 " K g # LRDբuh*I>|7h&G(IXİa_w>?nBL@Xc8^W?NwML2+K7mB?(ɰ,>{о!m; ue2b4W[sm!uCruD[VԋĈY$$YI2 =8<#M)Uiꈃ^X*:MBeLwW^U+Ɂ!#Ux  MraJ% "~8Si6.&+*@ hP˰>_j*ûr sMg #(5endstream endobj 588 0 obj << /Filter /FlateDecode /Length 2299 >> stream xYMsrM8HÝYVJdKTL8R+$VZ`݅\-cKT:h;3ϓIbrs o'zR[eQ$La&FZ 5O; 2,,-komXQÔ+%YMSmoP,JRt&E!gR0 Yf%]W u΄T\c 2dqXNb*..Mp\ќ fᓙPjRBs$o/|30ob\Lr#(c\oRYc.N݀pKZq]ߦ"J>kI$Op9S;iH۸0oNh23ֆC~w&o/7~`~Uon#@"0B .}tD՘xADʒ1Ua|M>ߛS@Sdu2c*[j_JUHݧ!IW \˧/JAUrf?Mmb1߹Iжm@8sCjTnbY!Ec$v;xҩ7Q帺$K-Y DV_[F4UZ YaŪ4W#CZj'Sa=pJ]Nfan=HОTNݣ%ϺvX%v!EmTg[ y 0By3qdFS/RBi&iMSc!-I7 +W }vU?tE}w)v y`7|]]##͐' ?kx|yNmX/؝%:ZݐVK6Fvۅ*sD\g+~S}d7|^+,{y"y6E:DSuQDǘCX2vj'lʄN@bFy?N⹏c Ӏ)JѠgan6@=M8J.JlNJ`EZ0Ldv/bgKΌ ژISD~rK/ 6|%NiYWA>fw1;.S3HuMN/h;3"șȩ+uM>UH J{{ݺnW6*3zbb /|2JȌ 3$ w?odt!:^츜1cN4>y쪾1ϊcgB(1:RHԐg| uY0d֐ l]g 1U2e}i%Zږ"hRÈ̌>\p:bytZvtཅw' @AeNW9}]YIqe ~+%{ǎ)7:% SIMN O] qԺr :E v8q3֬jǔ…9_yG) /'%5wCxmwzdSR2ڟpZ)'}_;g%.ſjfy^~0B Rt屜{nvV8o=5endstream endobj 589 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1546 >> stream xm{l[ǯ=!))K5 -!֎B4/b7včS?WGׯӼ:in&:\VF`E+"!1P2[@BttQZBD{թ,,*c;3ۋK_]Wo21%;*=^E/|0uŮ;w C\bDn+T]m5u5z]G] F2hFFhn]cb_?tMcp&bcYV^UI/#D(L `(L%2RY $$D+8.rqsqzȮOiٹtaxQٷ PI8n9`BQb¡Fm465+GhHG/o[utxz~vKf4pNu]t׮.^̦i՟z•qż\`K9'[=$XB"U CK~ԃ*A<]7;;5.O^|<9a^?ÒXfD'fp5\>Y$|3B/tffוku/+ Xvoɓ[vQq Z8 ~>LM|L Qx> Ҭ뱘X39kjned 1tD4u.H*b(,ˌ.=qƺ E%iHg`&7ov, ^K?Kw&^%gmpS6su_ݷO|HN _.z5{u(KpޗMv,0YH`Z;ruxg]-\E| -sm:ڣ,H# F_CUr) mk@k7 Q(Ő54CD+C/,pPXCh3::iag ,$(Me.}_b+n&˰ 0teӪnMh2HFh ;򻆜\CYS;ݍ*Mn#.|u>v_=}fPu2QOdfgqlc={(7x8d7)6N7e8Il :۔CH&.'\ޖ>dv xPcfMiehl# J5zh@{`ϒ>(NA2~-1tz&<5Nm|ᶸJW W-|3rG/|ϗoO~+fn ~Hfb8JM?w(endstream endobj 590 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 424 >> stream xcd`ab`dd M3 JM/I, f!CǮ<<,~}G1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000202g} d)?V3+_}ߝݿ:9w^{gtfv{wU8eu'v/W}ms7f\u;ϖ.m{ӏN3~_Gئvkb_ޝ+ڝ͑¾lzٳTR> 7s-<{ 6qb ^;wq {'Oaendstream endobj 591 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 376 >> stream xcd`ab`dd M̳ JM/I, f!Cg8nn }G1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000:20(1012t|_YCk~D3[S8~$ftLhn]DcAYe7GsWw=p~Iݽ.(} [%sûؿ+9!{Yپ |WS'/`[u[%${yL;Y&N0a"/U*endstream endobj 592 0 obj << /Filter /FlateDecode /Length 5994 >> stream x]KsǑ7a =%Ү%(|}h 8#όHy{̬GWt7HGWV>̪s3b3asw AM~{ > Al_]&b# g\\_};vRnRJ('Ѝ}.?loRF//% e^_JZ&# pL[[h( CmRY.Fum٬V_De}-*\/$ s_Qڨ^NT6jZ ݫvEwfg W\c]\?RVn( Łt^ xNZ>N f]X 9 jz`#!\)^uXxh)w gJ niiZEJC@VŠ6S`YEu_Nʵ[S$(^ +ax*qsJ.Ql Vb"!J:FrNQCAE@CVZ퍞HV2Gm7hE裔i"Z@,>ㆫ"ReJRCRc/lB0ARQV}/]n/44Sqyejv %$^vH*d{{ եNGL:l5n*}V] SOBwߥ@ޥĞD#oBtbЬ"zE8i`ޤvZv?[e;57U,}NJx+A+04z '("7b 惨]7Q;&'X`o禓VG@lelgJB)A9/'.ڇ&QLc-X]݈NC2&m/KSvڪ5i=c}L#EJebZtujXFHK{c;ϼauEaGގi)S*Al;w28adaXDy!}Vť%x{Ö%P%Bo0gM:Ç:4ݎ1|Iz<<# æQ!󦂛hhx x7[)Lޢ4Oq6>$- e(Knhlc9d2ۆ]yij<f*S2»FTģ\g.d݋n*J:zijQ|Hk&i$wEa%z/ۯ?u(;kI ԰rY(Wg%Q)Эb`g' a˫Kt?NqHŸ͊hP2#}j 05Џ%IgmS6P4&J<E4F5cP]LU#28LU !h2̭SPĮ`Fh(\?m*y'% IQo/rdd&C=O?i]ܑ2l}{Ӊ HU<33 K2!E=M"]џT*㒐o`e%&a~|sf0ʵ*N[E?+/pC3jk iB𮆶b_ fm GcČ.G֋5w\8 -%Edr/m(ۍUb 8c]YΣlh Lvwt{v/Az/4bz1 ?n\:I kVIpI HuQhҐ쌻`RG˜Vo&x*p~h&04{MJ0J .aNw=ey=84>ҩw4RĐ-T^?{3mT U|W@scclARR)-̜8؂iNel$rP)B QYG~!6{iG@بEsmuSUXT(p൥S;\FQ$V1$zX@Oq;BB}X!HM|P Rb(CxIywg |U< E cZlnJjG181#f<,YHPM6c`gI,;[E~pvZ}nhu\Ŏ]xaN}z²uF@t^ŇSv5@pbb3mjr_j7S 7 $򳙠W>N[;uK lijch><cqd~}҉" =˜/iڭ9+i<*Sj T#|ϨY| >6Y;{(b%v؄@^śӝR@|Qx>x%$ 7s-VA~jZ5bZ[c;T4LGi eI;nU=yP8VQe@8kwJ!C30[m@Y/H͚c?gX3XFDz6<5t 84yUp[nX *ɣ|Z| =JK&`A4sTuac92j?d>_cKT;T( m_:e(}Y5 _# ȍ&]%1#d *sy*0Hm^O^F=3endstream endobj 593 0 obj << /Filter /FlateDecode /Length 5486 >> stream x\KsHr#ۨx;Ow>h|HZ7G45p&P̬/띺_pU_~R:w!4d֭{{]Ե v|{ߵ]^Wwws[ꦶچjon1xWu[uD+u[fm0ة5ջvUM1{EQZ?Ғ\P HSiUo7pƹr߱9Sy:ʨV(gz 'f8lѨsLN>yVIjdS< ?IJsjf0,?Pn|ζu5Iӟ6Bh_s Ϗ 7%9(F~gO1"ڶ-0{Dz`)voXh$/yH;=G -5:z]B)#]WAuNi4yri}0p[;#%`VuD8^sC VnuP;-IQUՆĻySt7Y|Cu [2,(Tv2zyGӒ4"@N”t *inԬQ'PC!X (=^R_~Cbv9.3T_3-G7&{0-]պ,Npw"vS6$qؒ 捐4K{1}TI. SEna<']] 8MTd|x  $`$؍E CСք#ArCuu ?#/AvG$iK ,xs`sgwH2D  js!scFd7BNI@.+a^}w*DY7Ȣp@Zt9q>Z{v~}[XYg\vCܧ-oF^DWyu/h tu8#|Β6S>x᧛$k[ -(a6`ǩO.;/ >kx84= ]#T;g8St.H(J,Fu@"/.f-j,  br^JIsڻid)uCa-Jizt&+a,!Dj.uh<(m7?ֿ oSm6@`L`Sn(^[=)'A/ ޖ NSyikR DmzvzȚ06i6+hiɬpw+N/q; I uqpZ!91ְtDA&9ٯGdj٭ㄻ|+t;m|3(H6T bXX?SAR eCw;m_eK3$9|6G`Xs:IN{oAp؉ 2tiY1Εͦ6ّ& p=͓(bA+VnA^`vLk0>YSn0|`BVW۝W0t[YRpآ4ea'x4L/B|uv-y4t'la0dmKIvj-ǥ;R3P*L{h^:BcY$пx.7Kt\$of4){-fc;7ȳd*p Q.&:Fޟ<"Y%a81<n ƿAWy8Ro(ko \{(AFP?[ (y lj7"KPflvp یNbϕAJELEpq}fWmy\q%)>X&SL!ώ<@ 5O| qP Ӛ"g[R]ľB$ ţn'@E|' Z][QAap쯋i<brޅ80'/!=weza0w7a-)S0)xtyZXdMYOO# XQWF<..*hZ\ ƉjE2rE/b(M$sx/=|Cbo򚜺۴:Fѱ@9D+h0֨!%jE&~Y >I'47w1P{3NMTعiJoEjB ;pka=y1egemV?V+(EǦ!척(HsҘǹmx$£`[mV <&Ȏ?`8*8aEBDrG E<顣 ^Fp ZttB ^x$a-Vۛ`q*ʒN( oP鑟}Y&DH71t c馨;RϪ m0\̺Vm8 I;3 ^xN ;ø=.hQ52H|׊m?2IE-= 70ΠE*W;hY/^ʉ8iXyn#Z:lNYTx&S[:UB4DppuT z.= *>$*;ؒ9[F2`,BaQ`Sâf ۅ52T)Sܔj,PG Gk/44{%,%lL1~B9'ucO?/ؒ39}@Hٹf0gDp3m$(r@`&J0׀sSkfO/BfJ(H0ˡC&eيKL "3ŭ1,)~0Gאon$pzd$kΡg) 4 HՄR]Tu'Vbr 49T]K!镥`0*j>y6X!UVd;q "T=;44Qf4y8US}ubì7aD"pdQdlD;% &l˻|}%ߪpȗWu,.\'=S4meok,!Qr1d`'>` 8lwmv>-I~7/<-Kv:\iX]"/ >s4ZS.PZHT2\,h@ZlΆT aSy/OTk$RzNL0&â&#M׫6o¦vV얛k3nz.814% h ǛXAz~V[숕vtyo>f Radʮ>J5a3"c*h 2K!$T(ޓ~Uk1ޅ_* ?m 詞?X<6+ *A~HT-_.e~s!&~9Dx0*Pϊ~ۏR7ALA!լ pH# ~,Bȧ]\2B$^ 7m_|(~bz};@VTz8Ghd/% cJ*0<#~^߇{Awܣy~1ncFJ ,y+ñ/nMSeV.E y/xux,,BP sñXvٰlX O=D U@ja<~HٽyفlXo?`sŬQxŴlK;fe}$øac0,cYrb>zjoVi->d뀁`!U\)~\'!zWִ~e}P+2GFqn)L{a ; RABIP`ӢpT|O#TW<>ָ* ڦR3tErĤ_3R~ZX.-_ȞրE*.`0Y&I).huZ 9nY+z..W(+JOWV_/X|Wcendstream endobj 594 0 obj << /Filter /FlateDecode /Length 5070 >> stream x\[u~9@0vͰUv@{ݬY ) =Cm%)9.:Vi HXY:<\8߯*/{V_0*s_}yy//_JW9|sna+VF _ܮ/ $-+%˛WEn]w*Wޯ9\efk ~QNZ[ly︵ηVtڹ)eYUxvpL ,C}lڇF^:4'HnοEIȠ\^–]X%Rpx_(^/*anKϫk \D -N@< x%JLECXq>=n\V5crJH[ujɎci9jiw+kg%V?dPOGg% qXe=RXE೙* 꺅bsYJ`G 8# )D] 3/J 4 o氽jnX`D[>C{=tK$87T*B]%DLi +uX#[&PtgIYDPR4"#وLӇNcJ* )V.CW٨P 1.{y0 ~^KXy 899vhHK@k1X*_kʲ.Zo=ӥ'LO@T9&.PY M3<x9Do?egqCNtȄ m粓c"'g̍~1r,Ww[s=vv)ط0 (p*!Z$4H=v)>}Gd>x.n$xSC+ѸSX$M+5 2S[CIFg #FУSC.sibS& e8K?* Vאgp@@Y8ǰA^60 CUKJ +Nj@Z_8nӮIT(}E<@LE!JgA9ޅ_1wy߯7aAhʳ?SBC(ߴWi~kзcO b]\rBD",xm㣪_8 CtCn"B`IA].1ꏲN`&V)p~K0lu'w;w+nCDX/\I,HŷC2bTF7"ƹ7gW8 b*S}SU aiDS;R`T"fHA/y ;pT|mV|QX>: w+/q%F0P8,B4ʏYgx#cA>H?k!LHdz:ǰ :GcDwf!>{ԻǮӛ5ODO4!ܼb58 &q(C8Gim܊xP6eEӇ pU£Ţ#^ОKsfB*1n㞎=0}Qwgg7‰ ioԌ/ r#zFCVMєRL]wh8h39FtKz7pI|S n7B̌[NQxoV>E?5*Ri<P(L@>gVN(2vUr;DxU<*)|m@8, $5쾱}B9'гOӰ,MƎZj%V^OJmT>܆*L;p JZ>S2dBʤ%U%X>ZDpʰr}Yb%Φۅbtܠ(Å)Ȕ77' z=OQr<&B"°ͩ5.7jF :}ۦZ3nʽَYIrlF_! oG nndd#XwCxR6* ΓS }Hq*]:VK!Q YAqߓ`=j{{xF3Y G['.j S*{>KHblif=<=Nq=Hcf3]>h,e0b۵ҳkrZ Ŏ5 ( `Y>$IhʥV.|ep Dɾ羺rүztX~ XeLeXngIGj8uJ+*AŇ/cJ',{-!~'\5()u$5u$"TCGgO@+14B]u(M=@&,wzG"n 4&(0N1!Ǭg 㴦1$̉ I;H B]Us@Rc.9r ;sH&퓉$AhvB蝌55CoR ԏ,p.0^*EhLa}r?z. ,ԩ{p_[7#^epvn,_eplb5з~(F}z:t/Nb8sA&}˃c úU$c}O@!y/XIQ O 0? F O0,(F:OЙ3v R\1Iƿq;B.$m# L W(ߎC7#~UſnN?k^۷-ջ==8htX*؆ ?})R}CB~g& )3X]l:Q럇9̓;gq3M~e[gxx= Z|^/?]J endstream endobj 595 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5142 >> stream xX XWRqljPq_0$&&*nQTT4,) udU6h 5fq_f&j4!q2o1{TW1d~.K=&1 ҭLC"Ev`nA>~?#7 G>`spDg\&}Aoٍ mmlJns[x ?ԫ~7 u~؂E^Q]mظw2Mzc7g<<~0C0ƕ,a7f3YΌfV0cwf%3YfV3s 3qby$f>,d0o2[ !s`xf b,[K&fЌ2fLTQc^d)fRP)ڕo)s7cRkz5׭ގۛ6χ}'-﷠_ie,pբ xF5XK~)V Kt $XƱ$o|nw(؄.1>t<$.Jg A3asR`HkEKk,Q%e ~ GcTbOlRmWХ+ML!F ס̊,MNX>;Oc%ܥаg5a Wa?~, '_>BUL2t~5 MDd`M2E蘡yfW*q{ߩ4J5wlS (\OnfV fzeAFY c.J V$2u0bII8B ٪i@8"=o? GLp7webLa}bJ=#U );bcA8r arY|ةs7g}<C\Wr5e&̚v|~`Cv āx/Mס{i :E\oV1ͭWBa=b2p*ؑ\V 8+&aEM3X~l8JizЂmÑKl* 'q:wWp(ZMj28Ew5ko#7p{Wj *a9QӧODV?'ϝr%L%2oШӸBeSةQq[EIoe8TQ-k/ѨV-ƈ":ًrq{P!!%:S*X f!cGvIt CXM2јq!ɽ+ ڂmCV5aH0@^a_OlN\u9ha}hhmŋqĆZ,CXOX \m8G@sxRxHo"/[uCS˅5jXΎcMa#9+[w,_ A˯-2CW1h QXHH[F6ba ^^KZpqI&T[:7ix&=I6QaIU76C,-kϲ8"+ҐX6iڋigֺh\ HMѝb>.)V=!,6(N:Wp3liq ١cYB,ڪGt2K&"/s3,~F ¤mJ!5= ԌOz6JqѢVKTU;(2|NHĩQU% ErcV9witzA&DE\͇ޠТ,ɄR5qǞSW{wKOg-NyҴ]IcH)vXcۓylL.fBFÖB~_,g;z ;}-n$DHѮ0ARquɫ +/(6Yd&jC=Y_I  K(.XISF> NsEGȘӀPE_G)2|w!#S(' Opn5gHZ6qy ȏtɮKO-WXqui{3[X\X\eIm#U#tjDuc, XRN(j@L5F eV%l8 dUvX-J(@0mV9ǢKCbΠuNs! b@nH΅Zg?~x~gz^Z9+&S5P1{E_ \-nc'R=șB3Dtzurr̍XjQH)HRKf)JJRi6YW{+iYE$1t_"fMcÊ?ri:b2#~x mN+6Rf|凞+}lI@<5{ Sgˠ G?JUF Dx?a; a>9:AزpA]Ah:TTX{Lg -bA8X{Yz"ڨHДr@v|*21 ;BCGJćG y*)of&5O{\K5zLtg;LS\)-nP O!'gT54q$\'/~a@~>=_`1uŽظmέWZXM7`k_cRL+X2BǸ.S]~x[.d@؊j%N>Y[o>Z/$ Ea׃1m*|=z 3%ۭnO;l#Ɣn|zyq|RsI8AL?-X85u+-lZi[P S+k-M.X?Mޕp9 *&^6x44 4igBFtj}~]7ߗgp r*ȐQW!k1ikf *RA_=k`4CJVC x{l~n}+ ] +9M;l2QW]R#^]AJJVӵyg|[oiZ屒3UHe<̻8[ߒ%0P07YA,㕟j&\ MIȭ*ڔI<6Xŏ9Y$Eް`ds˓w%%$QA Q_e(eK*R7@{Jqgedkc#|l: b5zT~݊jVL*ԆI*c+'W%!a#^dvT-jN{ZtCo ABiJʾ"ޔ"ɝv!ԟ xf3z `%\nNW7v Q׏CW?pX3E0]=ÿ"n8{4lot|%\J*g7aU Y/TyzW> `u I\ wB.FБkxҁ"""5К޸(%j + Cڠ+&9Z[&Chn^-~[tu1}.!!ۖNq%0u`OujSV~ TsMAU^?3(s/`JX+-McPf#VBt#F m> stream x[KwFkYxu7Zi#Bwϙ-qq$y&wY$-3 Y廿[U)PJ"' @ꫯ~Yg{޿8ݏfO7/=?}T߷^˽ɴ,JS*[(`gg^o 4Ne9v*]i60V}Wv|p -6$3544;Y!QY*W#KB3#_਌KJJ[pv>cRNݛ*R|~T [*Tz Jvp*DY_&dj7=)m6)bZU'^q64~ϞLX(gOhӈ#SBiN漐л*=p ?W5|ػOx^89[ڲ^BeW7EĨ0k ,[-Tڰ hg[Ltxo.ӫ)wpS. vF}yuUuB4;Wm1!pS̤0ċbB^%)_/L2I2mcDA x~^Yh‰f7Êuڷ%2O)8lA<]9LF ^/PkdEw ]2'Kat>LH~D>NzWȼ$E=1UO'袞yGBerH1w BD6k8Hv7+;nzYWPl ;_^ȼ/Qa x~ pQ/$pNFd*Ai~8 E@n 5hى>X WxRO4& U`Y#Z7?NCgPE[vL4gۆKũY\ϺfgEpV_?p&)},& `ʾ[3ġ%"ꂖ7`J߃%ĮA? G?vۑ4 g//Kԑ.:vfGp jˣg)0,}#*1˪p`$uHږa W*,))6HQ-]IX2( =G~]ϗ=O"\Q@OEa3~i`ZP6ث~y0< n2 t9<<:}8Qo,j_ëj[{5{PFT;*EERi(er/XNR0.4=b×QOj5?UnfRe(JD_4}9t[f^uiqySRA+}6[L -)A.e"΂qd4CLZQdSr}P.UBpY)Zu2ɍi{\0XNסw$z` cbmJl>0E_&0CkŰyos0-p^Ҧ>!zXeƥT兠>H)@w%fܔkV?YyoCTb؜4#s81cAzq,ֳE{x|v4G;|Գł!\SGB+ !lB#Vv^Պv R&Ob`An1^a CGD4]#wV\f ) ‹fWfxW\nhgqqr ;#rpdE#ruJaDDd!Q9N&З-3dY ͟d_Q42GMĖ ^9UeKL׵Od 4 81CX$#ٞpp}} ֣=/iǮjRʚZ srkm<٧P0==VlL?(,{X$4мj(@nf8cb3km6.5wendstream endobj 597 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5193 >> stream xXiXSW>1䜣RDĶXgUegȜ!9 " DYkP[Z>w:0+WwI3"wGg&Eod&.PHkJ}zmb&Xrhdp+aŏlhRh򅈏y1CWA.} )B.l:]ߝ-H__gtz0:R,N6rⰪ}MܹwΨM ACp+lMZ x ~kt!s/d%R;o`vpf=Q^(9{ee$\Nxw)N΂.p.{#Ä++ݤ'%@\GMzKVRGDGϿ,UzUFp:Иd> H\4֊ <ѦRDUeKB|Q @PfA"H-˩Nhɾnp3^kg=aO* 0h;yQb(,|ت)dq,w(%;T31dHT+Z`Eվr_0#xXePDAq&!_'xjI4ѡ';8$vI /p}Uj&7 Ǫ FI> \] uAϻ3"߁.Gk5j 848.?Sy )!cF3"76΂>(1 (q ſ) / IN֓U5?Hz>Os*phrCjME =CY=jzs RR00SZ ۜzU/f@vjK8uX8}4*Ⱦe?.A T*B.IS$rMS8}™}Afv3awg+fx;SO5B{$\ڐ}3wp2Wu'&٨/ar$:X" p0y/uڴHxϿhNoK_ B}>D{!!peyy\)7~<`05'f(}\|_fUT1xh]GDni1OIτom\륐8_4-! oC7:tsFؕ{oV?#z*՛ή30ۉFm<__i n}vUpd25YY'9!X]`bql:R'@b1erRdRƨ񂴌3eNdpīOZ@gcJ 3cǛJ;  mMhIHIc Ggs_}FP _PC¤J~u8Ly 7N?w1٨@Ƥ_<ؽ/c,=d"Q(4`t-A&84U2vPBY (RYܸZpDm-כNm Ƴ ]Pai;Q>XĹƖcC:lQG Rw$zVz:M >_VDV\≺LH'\Y9?i$ Y*6#Pn}2%//0> זUϨd[Y]Dl5S:u~Ȣ&qJLު쫍eDh'dڈ 2kJ1v4 /M]+@1vZf^Jib HN:re_H_ ?r\S 8Rkw4HFh P JHY`+64C(D4ǎ!t@gApVuI"e=4_FbD& EE^:w Nx.x )`=gIa _78 4l&FjZ_d}oo#u_mGt9NRh?jq#' :O'}j4o o/YqdL'%OWWO1 g)gv;6Y0 [)df}tO D)ٵփ̐9ya7FbI)m+v?8vǦ G[2D8Nd_nqvv)0tG[oPHC|Gl~J ҮJ8Gf#R@p׺6PedD՟ٽN\s}uhRk8h~V X#<a `UЮ  ȸ-~?kqo݅6Qζ4t_WFI nO}b^[-^`x_ꙺ+ugbaMP̿`Lj"N/:ȱUb9ghcƆPLs]W!ǐ^Ex'Wͺ l87*)==!!51I& kҳ]FW'EoaZėendstream endobj 598 0 obj << /Filter /FlateDecode /Length 5848 >> stream x\KsFvlRI6Lfv*bNÊvI. .$JY@wqItB@;ƟN4~9zgoNԶ3ׅvҪB<쿠I[ke-?xSuxkF5mum|w(+.wy8Vڲ0S)e4¤`З2hSc7TQ[ehʤt o䬝_DeGkkLZ֭b]qlr*V'BFkQzwտD+kkTu)aW/mL˛]W/ cF|v'LǠꢛ:)ph5llgt#״li8,hM-u GB=h%SO)iN%v1&Tu5 q(!⣦)<δ[VZ\C8R" cTipnuܳQEF/ ,oYt ] t7ѪOTE2Q[ɗxH /ᵓ\|Wk _r8V^G+xVE|+B)P3 a꧘@S~yϜJU'㇪R.Z0yM[K+QT}w:p 9qm*Ҕҳt{5H P9m5^Es%hn$M p=4N Dq; п'vVtЎ-weA=Hx ">ۈ{闘eS%7Q-xÚg>Y(-؉TY~=S@]Sy&\+LW6X:o ?_uWZH Mo:U"b/Ű+aA;fۊ4QA'¸Z,ZЍMIqnNʆSTkNCĦ%}fq98eQ܇M-&:㎊ ˬ 8Bl=n`$"SyE 7SXM!,$;4V50ظCufb/BU籟Fb݁?ĂS_GyCH8f64$#mA'WSk{υH%#ԕ;9DV 3 ݡ1@Hc8ZJ x015Aw H'D@HIZIWw}7p~hKs`38:p 6_r:"w{韷j%]r:Y_СES~gs+@LN!O(zjvy-6frp$+nWVhn௑Vk-z{S Q:o a݃vքQ_o .PuH)aoWW9 g0#3@q㔳mHm aaAH?sølJwC"./ V 1OnhU'ѳSaX2.<гs6=VD7P)C0drRX*A#{z&6F-Qoh?9ҋJ3 3\;vV\Uboၨn/~8ZT g6ehd|Y][\Wz<\0{{wrNQe>4t6^^6D+N8ߢ\n& ZנSXNYO r72#9!4C( I3nU-3זXd=JqָP6n1{y#mSԮ7ǯSJ`{hhRp#y芽Kጡ^;!aCVGZɍ 3}t!EޯIySDfpLmxMMN!uFJ0mJ_z7B#{#O dؑ|7psWa$Mʷ2e`1!uj-qkbn^ʃ)/~^7^LN`))bLVP-FamC-t-m4 'p VJ`o mi,t. Ö MA-0f2m[k4愃g_4ҿ/j9K! mZHӨrY ."▟1Y\MH&L-@Wqx,88Em!ʺ,|K\ҦT%v[bH-6՗œְmiBTEwW#k.ќG\#B\Ft|&X `L݂N g7Ju*آ,1,H\7 UZi8i,Eq_忺Kɸ* PZ;?u3bȣJ. B|hQ ǂՐ&V0f)x$bgYgďӿ,aF^s iV j~%Qu3;L9`y6LH] _ǩ u)ŷ˽`(iPi÷cNr«VMM( @q,a@< V]w͊fmyJQ/x1iE.Se;,L̖}9g׍1LYDnE72!!-zXo7wx^c[ugS;OO`pu@9pDe_ Z]%.VJwnqPs'@4jVI7)fP2"nkܿI{iK)گ]G#ͤ]HkC `xiKWQ et!54F>qm&)RqD"+n$EExOSimݦ>`'IrgIBMR_B׹:K0\i,oG %ˣ Gh#I)aMpy:4Wg`XVsb f/67IZ1>  J*SY:RHUU7&s`)cNˋ+@HTv dh벭dIl.R!8l$tX%lv<6R2t>Ќc2wb̓<,,patߑ11իn^򒍫S:v52 d/^.UiYUJ]i v&oTnp[d62,F[^(z`?Ic>!9GM̝@9gхnT\l1;7[AENx֡?p.gR}!1lh䯌YW(?Yh elٹ.:Y:v0 1/7@{CKO>vioCL )9iØ~*aZITj>5*U PjXXx+_8ٹ+Fϕmz2,ÂgNnLh(7ߏZ} f O-ny$H\r[ұ> 1uT?Юv%^s󲃨u;GlH/΁ ?ӥ0k}3:GG-OӝKܣ|5ኴaf^cL/9ߒaڨfeி2P:=9&TFf] ;mR2a:W5M||Y.jb<"fKE9+'jL,b; 8o#(NX`l+H>m叄P7V{C&9Hh`ڡ$3ZqajE, j`8)-G.feUqHKo@P1nWBSU]=<~σv*N}dϷn6KI[Yl=ilVЂ'$>Ss(4ݵ/+̺6xQ3sJj޼*4ajH |~8NRmfIS1IԠ ?euy4re&S(SZ̟i ~u+BK4ODK%m֬Fzk*M`bFG8hg&ŨڰxF^|X?5[ǵN͔ēGk<\ @ڄ%瓮:Xy/t-m\D~C7V$R$Kz~;uF7E+!5CW8EV࠘Ki>ciH$SK]qwۉ x]F Z/ì߷t{㸯FxC+w\Fpc'@$A b6]X-?e [l%Yf8bG}>*Uw>7UǤ顈|;xA& $ǁYnPjBwCL[G9+ݘ3K?*n/uto!In5jY ^r)U,痋.-e0w\Gfs 3,X#uI1T܁MBQB>$֔f[juҁPU͐m(h%)> BQSpxmӮU-kEX7ҙ6ŒR.VAd꼝ӫnruKͺn7[1- e4hiQ> stream x\o8rO^'yKr&9`d6[c{~AEWݫ?EzW7ut+hŅ3ڿDsy'j6Xuc]JUخw}0n ԝ8u4FeZ x&jEkjpQJ֝ Y$ OtՑ=tW0VV}Br JvΓXĹQN^l[kZ;x@>$|٥ aqZGU> -4 ) &ᕑٿ@*4p߅98xFV0qY56%60i %*[SZ[ kՊZ+ lұP" VYRw]ڀhNDna:JWLC#+ /$6J9?ւz - D1MI1pJ!u?qBZ9e  4V1i5:ne*mZN-ka9kԡ0?jzSr< QN3!8 S48Cm qd[ @yT z׮!0v{qCWecFT77d"Su][hmIWRK7!8E[p*Қ̜4yL>aBHo: mcY8u-,VͬuZ=cr=߆|RPm"$y*ȮE;,: R"eWv2` 8^`6P&z'*ZK " lP;3fA]HqDcќ`d*vQ% PnsKz~qf'NQR&B*>% Oi8"9 :y*![R/OǿMvL܊Fm+qS)Oiڠ~k5-XH ` $g,*B2U.qpqXD0wq{e-%ph8D8j N[Eл .̆\rhk,Gax\mwb<^ՄO 6ٜ[_o==W1N g>^8tw%.{͈Q1AiJInDil*\5h `0Ho4Y; ѿ2kV}ո#pKzKiwJ |1pww}1pҦnE9 x2`ᚼ1n"+`O=:!$qBbo 2#;Ybx|/܎=`WEAN;@5WP,fn X+ّppSw5{ԏknd !Ch .toEƠcH7>ێG˒ky8P["fVYM9 ,P Au0(K"lc)chjUzyKC9k=Q͈ |I,Tz0B(4В];|w$ђ Q`J vm|dY)Y/SYsNi>DQMR@Z2Ket)k_^”m"MG@T1z@ז9 3M,[k0%ew. Zߥ̭Gwi0DU}oׅp@ R3K:3a`\0s"a6;ⷚh,T`s5"_xDe%rs bkВгGCѰF*-@V v"^Cgl,AOTDlu`a*L|"&}W&3h6 +e`DT{TC#W=+'Ԉ }^cK$X۔f@) h"Bg%0*B|%1TF,@)K(11iiWuŬ.q`ˢpxPbPvc>.,雤N-&߮+&#Sqw8b|j5$OQ '$A.}OM,֧w-Ĕϝ\F{B݆=o(&̥}4C7C"Ye!'{L%"H>(D { Z0cJO 75I*o(=lx }gm4n*IZDA;jд+0f[메GWweRTNznv7WMĤa@V,BbGn/1akmd~nh!X ZTg8eCCޏ H{A+Kud{2 Vhe Y<| "tO%Us x4B& r`mic49ob XVfVOfƹW~1;({+=ENdBf)z1WEc*,q ߽yބYdɚ F9sv; p/0F#zns<+6ZWDc FRmy_ +Ŝ`B+4Jfgbփ&6?%qŬ UbHBr ]& Al4 E0=x~Ų8BȫThoٗˆd jAǯXsXOAm./#KԲV TỲڶ?^L&[ ӌTc|T0[8*Yp$_§홞lW pǻ,[8*E" 4t=B 8q XgvlGҔ'Ə.û2KO.&g(|}n~3y|ۼ t@;bbӂXqG˜y +!-yFbO/s|wBsz)2n(k);6)5;`j ]0o3B )>hXt]V۩]̺ńuӥYݶgHb ôH)( H#k֋h1-ʱ%'W6B@2hu:epfd|=jDy c qďUY,DAq@'<ȩ5uV1_[[D1'py>kݲ ¯+CSr~&bۊ%FTT71+)-3)χH\H(mk(eKHTt Yɾ@\+V$mC{h}?u| ޏR[dKT1>meUºy6 3Xڳ1}'1aAH?F3OPaapO=}-=p.P D4^7lPwWvG0+Ycܜu '^ *|z&%sJN-؊0M -:-MN@?{R,tP&} 8>ϵO\h[wx 5E- =Oᥝ≟߃ !TYX{?%?Rh+W[ ael=PnSz 4Xys\kX%;<r٭>304~Hf[Rk0,oD|!u:Eygh{ͩ%,{=>{gL$%r%҆W%'V*qLYesSc$դ{s/ODi?qwz/2_/ϸ _nmOU$~`?`?{B 83 PMVQ!"8c1-Qߗ;adn4" ";K-(v$ycH2tc> lՆBОiN,t=_M,psIPУuAc'ϊSR['i}1VjPkz9[g.@ʈ`<T:tܲM|yso;ASCBDRvx8֠jkR}=W]oy̲=Çpv?E|dΟ..wA[mq8ex"& ߸)Xp&Dt8.c]C(6oߍu.+#S(%. eZ_O9카O9 g-qumZ#Y,| P&~62K d#y~{w[`F9=.%jm iڍT l)DA-++NbBaj@)crzKĄ[D3>|T2="L—x*bYצ!xzevV7bW9P4-AKCLvhxߗťR2s;`gX. F'"VWoI }>t`Xbl^/[pC#;Z/ig.ͥߩJ(I˰r xPu@Η;l2?'(S)ӳ[ _x :zj&x؏όoGK^RAGi'2X((Uu&&|lVH&n8?pDiI2S.b S{4G$,?w[R߫%]h)QZi}@b \tMr?k uIKtՊ. *߮ Dv$?+{M ~q0l?;OivPChW|6=xްzy c|wE@4#]/,4`W,ӡLҮYvK'2bS{."0, wVœOH{{w_0jC.\{ʤӊTM>@lӱ4>e7+Rj8y^}oh?o24js._~ o~|6R)i}T.26'^O~][aͿr>jɝɦ=POʑk6_KxxG)w\#O$A3 XJLSJʩXFjg!H~~5Tt .aJ6]<ݵzQ;S)^& \XynuR7U| G8Υ1x.-3Ӊ3S}[)IZ]l-$sxtO,fڀ6{__K]&!KĕI e.bQ Zi7 JZvYNQ*2s> stream x]ϓcqϿjoR߀orqYJYTvvD-9Iګ{Ư r4=]fq,7~7򵷀a ūD g­3nܾ|3}e^좥npw#?F9i⿅v2LIb߶׹Y$Ӎ hos |ōPR(bf'",BD/bVX9ۄ#DžQ3]$%X.b,"f.ì"*M0f2"Ð} Ф:Ⱦ g[1X]tmLHt:t\N>"f#~vq.4 $/Aox#1LJ{'gcɻ# @s]7 F!AnsT]`A]n$؇YZtDdmBS"A ؤX,DYU`pEYD,uЏH={gh$4<= )C|0{"l*\"Ɣ+HYc D ]jeM1SVJ]C} N5 M"㗈eO4B;E,G0`{@I@V?۸,`s~xpeȟS 4 j.SC5)X}* Ԍ+Rݼ&\o7O!F"(]JW x>UR"?6xnCzXjB2הdфnߢpLJݬ4#K/B33#:d>0*>ʜJflKHdM3 3M3 3_QFEcff 4.YwP)T3F( oB 6!R$Ͱ Gf5b!]5,cUf^tXU] BIj++Tp`ZZ|6@~H]qxmɝq?B!pVL]eA i ?26GCT&.q8tU㰫BWu5$<1LD9@eBjܬ eJEF )mZ@E*t%l"x셝 ?P}3G•2KmٟOYOYOYOYOY||X.Р`x/M t/:M5"@JY3H&i+0h3@mpшv GxbJ zxpmgሆfvnɠvNDzvp$#O{mgMbk;8}_ vNc֊*CpïR`"5x>nk3 I$6<3 yI)t86ҴlEv] cR+"IR@WPlTATPL>D Tʂ eϫ bDHY*R**V*m*yPlTAָ"DذU"T*[,"U*e0FcRRي)i}RJ*U*eBڮRR`0@ Be,ρ Jl+BRRrr+B xIJA0 *ҹ0;S"%аݵ"TJ;z5'r+BBHb**q22HVP) c"DJ)soP ZǞW*d> B48"ֺ"T |btHJer@ B X*B'RR$|E6|!R2Z* *~zj]/y39F{N"u՛o!RKOZUfd߈&RSFH ` imи{b1P3EJ^+ zAI/ב^nRvsb*!D*#L@c,c%Rd勉ïhI,,A^X~8\?I/})ga`'=I:P!p )!@nch p_nk7^jv { |~I$tEgI<"5}UjpU)tU3"0ИXf<};m#ŴjEi&Ƈ('K:0VS~"":Do6D,Ԟ=#v 6B̖ SVi!a1)1D b%A 1#@mxIg%fs0FCHV@a38Ώ ]PB!MY[AFV3 F䫿хcDCl:@sx-3FX QfJl(.F0L5`_ gU.hƈg $ LS #,xAIWcox);61 qHfQ2]# +Rb0gөrTW vjߑaO]mú8*k83 *9VTzT&(ÂJQI6($M YM3 3_QFGE! 8V.5*;K|j8ʨۦr:!j5pү V6Pf$LVu5a$Pal6Dfm9@HIco}ifw$w+ODpXX̺ru BIco+Xh㰨R8ctP>jBHRW_&y"G @j+-mϋj+1VjڪUVr:|HeڎJQ[MJR?SSSSSSScX}˒E)) Ӥ%+&W4`|)%DHi*nRFyO.լX,+4u:N)K *`ݴY`hځ+jg,'@Ž)h⅝Wv;s˝~ PYJ%**a B<~&"VfP)fDŽ2@eJوU D*HuU*-_ ƀ="T*\ J99)Y*њIJa!dR!R*IkVJI8TRXBTAL &U"%OҼ>yE]x}P)oYSR W)*RXX*. &TAҞגx*~t&U*e$]*B3NJ) TF ^"TʸTMJJykxWHy wET&D T*S "U* **ta ]*΁ϱ"T* "UU BW~zO#}Λ#IUfU X"58Djpʈ`7"z;/g٠sfi=*V)ZYWje]"uUVU)RY׎HNe/?j]GsrT>W:f C]#(ջu_RyeFWƛJ 7_n*eHB۽u~3};}^@OS.h_z7a{PJ>>wgd~{wKBd,"U~kPӛft8˫i}bUvy串=0E)P` 9ʯu}UO8IHW2?^PNyT ӹymҀYl}.]XЃG4)扈Y._b04WDv7/i)j/g,`I?A8 pϾȏLiH CTwgC(zL=.>wWMk5IVf"I'5b㬔u3c?ŝ[dsms/q[Jw dRe!v{*UӁFJ.~G?zZ#Gi>_D?9ݫH92 ݼIN y⺠T ._Aul >+.6tѸZFjyە!I҇DZ2 `*aL'/S@Zlsxp`2ySplnmrKIv_꜏l[MaC;EmJCSW2RYF??[w(͔hTh8 ~2KI_vrp56 þ/qGW5i׺:f-5r3llǼ4VHy$Vc^Oj#u64d+sz/jT͔rA]J;eN%죣y9CtF|`7A 1y|Ằ z `|d\ܳ[SQ{SW} Uӡ,8!O%LxWGiE\] pw_N]ȥwW_XrӼO& `l'm__4!NKhhs8xlIUk /yOb`5d P3,o.R DV1O}˼[Bh#8=ˆr;f':?+̩RlgٸdxSZ;k @y\9⼽+B_c&7lEKT2gys;wt&"F$;8T:v|ACgdCuJAڨb:QE%/κ7̭+0ҽCӆqxqò ;Y@q="'}`N팁2Әn6sNd7EvHl`bGZxt?.VeyR$9C^+{)䑬9ù(m]75՟3{>@_ݱd௝SEI!!*71ɗ;{w2)͝(Gyy"=N|'-,=d*,BfSPL,mR` 75wɋ.^>ߤCs|c$\\|#W{PRJm+>Ogd}l"p:f:oٕ-~qV&D3W;+ I ys3bG}.`DHZ'/"deHW :f_>zǦT|$ }sj.!)g¯?fQK-:29Ix˻΄_Kdj7%YE ]ʅu7xM tnOkpD[[G`|Ě)uֹʏK$L`l|%_ʮToKs|a0|n)ֻ7) 3ة#$]8nj>&[WRg8# [MyB]s? w /՚UFEzbTܞ\k=8uz+|,g/awoF\k4RW/fy[ıXzƴ6Y!|2VN]uMm0[.~YAݷ?ԭYixڈV nf^(rX,򭸌CW ?^G #إ1FQ@/tA6g %+WUV43Kw\*endstream endobj 601 0 obj << /Filter /FlateDecode /Length 184 >> stream x]A EPFҸhԍ Q/@ahX ooo|:{)u$Ò4G jUT$|EM_Մ޶>ͤ9*II4V%6`& $鸐VDYP.הJ= KJs=.i1+ \endstream endobj 602 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 542 >> stream x}QkAI5kVc2*&X!^7uA7l AWMI+u6_[\b.y,_q6Ll"{ &sR4D!y#)[Q4ԬSO `ֈYg'qh0.aYEq: eqKb:C\.tKL` (G9!0/@]ܞ*`@oc x9 H;)5RXuw9%kvmqn90|Y7Zd7PIL-{2qoqw;qf>$<9:GMfǥzziZ-u͸~Y*D5>~ןں?莜˭'XV7 ;UUiF=:VΩQ~ÇjjSlFGRgδ[CA¨=١f!_(RRYYPʫb%\ endstream endobj 603 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 397 >> stream xcd`ab`ddM,,IL6 JM/I,ɨf!COVnn }O=N1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5:E!e5|dh\mrl}WVUV&ֵ͑a /}_m%+U}=[rq–&~;sf`+jhkon뫝=[֒z'.;GlӦ}/XkKH>g7ޞޞYsL0kQOOϔ=}Sxxfendstream endobj 604 0 obj << /Filter /FlateDecode /Length 227 >> stream x]1n0 EwB74 \%C d 4DgKRN_I}w)v:+.R*>ghGlSJz{(;~SrRpnʵ8O(!b p yWrHkV F*=.c/*Qp *%*S#=gO|A7 o{]_HyEaV̋I.)_e.2eYNx!endstream endobj 605 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2049 >> stream xuUyTSgȈpU\i:0ԥDEHM’w;ڪ#GTz?!5sp2hi/L)|0cc&3T +ZX+kczmdmbumP*pfsuU,H*de'=~OFgn{͒n M{l'zB}Kwy%]3)"=䕴n0C)pPQ[Wk5E/`aj,F_(l6p@SDu`yHG.I`h#+!(T#R`i]ɧ)ܑ?W@`uB>hvB3Dߢo鿌b$=d"īrH~^VhWbleyg*J<:9CP^l*ʢ*`EpV]Ly pңp2:UNMe&l,  p"K&}Gk6C1p_ fGH> \ډ%P9 i-՜C|t9''B!%ŠWB-riʇ's:9qus1bvdRU&M q}&tZ]8Frrn;﵀G]B[6tv<|m;8`+4CQP \#0'E&e ) -曕p-*[ Ґ|H¤mVhePeH~r)-n. %*K&5 wB!V F|Ij:`6+G/Ԡ0%\ـsOfb} ~8QeM_o FP_k[u'2~-tk 7 `,Scġ炞*5O43Y Q˅-ATH(J.& TP 9mR# h%`*_[}?1' ?`~|~ȑ'k²18# ~hڠ~W7yRced<+qOW}ƪEv WʣNfA0mL ŝA6Ϗe`\:23/CG(l5RD]Ii֐ ȵ<" rѣ6i e6oqbO' < GMT3CK9W-H<9Cfjͦg] m6%Kz$#.~OgY/-᥻4`*ߐ^On*D<DS>kEI+e3p%UC$k&nbYTxGV{|0o>ӑ̦!vpYjċhpN"d6Y@1+`;UZwܕYŗn̓Glj_mPOsuKĦӍzB?JKCCK )|?RQtH<-E3jc?qd-hhJPU Tj1a#V.2 whʜEC TAd6šh'֋&EvHw|j6Z,uF_ö:{#N}a R[endstream endobj 606 0 obj << /Filter /FlateDecode /Length 5745 >> stream x\IwFsS#j BےmY2sR MAd?7w'"2M>XK"/X~9-rvZpRO~9apᓼ,Jvz=N5Q&/:=;o-BK5nBB Ê2C{E4f6yPJۼLg0MIYf:P*{U.UDf#Lso@TƢ䌣.N26g:JNBVk'DiyYfU歟Z"$Yhk Rgba\å4H^ @CݺoRCWUi xPL݄MV~`Ʋ}(UuSOAMa}Jim؆4!tmaaQm?>U]E]."WL]z4HHI]&?eH ƙD͖T IEiKt:ּnջErZT@mA8“J:ҍʩ_V{Vxab w(ᐝEhpLbwk̀zיerjh0ػX2*M=ɶԴkӓp|}[i m"|B/?3t 3A#%3ۿә/LT;^GgPf8H~4!~S@n&.bxN rٸ1JhT?1mNJO3hCޤ'f$.i& FSa;~Id0*/~PG#FsͺD EL-Q/:ݨI7UFȎ-> YWzK;(Pr`T?k^ 4ԗP#`2H:g:x㹬OFْ,J y~~yvDZiέ'Cr>qc)8Kt;0$/}M7Lbm.xa,8Hp6k%Ĩ{|L=l3"j%s؂C/{-YѮY=3oQc ^pI`1n#ڧE"&B0y`Z ~va06eJuh 5.яôJPj]-݂ *D!k)SI|O6^a˔?9AiUې*NW_xwVrUUwhV94pa-qy900}e:-O%5Tp@vw )C&/9oJ3GL]jM Qz &ډ:]c:w  ,/_&kE>_X\+Gr䄒~OR&?Zwc-bK7:%|^EN[1N}/;"Dn`phG򍯗d PD>G(JQ\ʉ(X;dIQˆK+TS\dgsvH45r#6)Z;i[<C\;`y06Un~HGޭf<c,Q9yw\$4LЙ!Ú q#oXoHάLSG6~`zd E}TVla%A, &rhu f!I(q ^ȇ~'@-gT}Ƹ79m$B]ڲw4`&{ѦAK<@gNnDfK(ΔʅMea8v% vݢdf(&Y 4/s0* .TDѹy~vYሓ^9w-A=f0Iiq 1n{tAk }!6D Fvr(!M S(zu|Gp%c"Nm)@|F 簭sT6k(s3ԇE6)P1pprxLISуotS%`rpM:o08E1i(9#gdN^,TBËau.Cf?/2їa2`rі)IM\Q3Na4dlu}IF?4 V%1?f'iD?%8DY5S$/cʭn V)KWáoLI)  P`VX*0X,慚iIXxkDHHjyԺ̅;Hu:>b`}$%kPqQvmon0rB%+¼[,C$ )4 pcPv>xi)j /px%UK!z1e]m)S,1D`!K hdܾPI+dzVR[]Ra+#YZ,:P~e%Ǟma2 >u7.ԓ*Ҋ+lcuRQ %ap!dp]WEK8 Ign);!RDR-|XɈ s esYYijhC:@Z=O#O}&\$#z/WB:8!A's2P %eEMpcr [vn@)D![_[~# Vay,p:U:\Dga 5IdVyl}'b)PIqhIۃG$Z7)>}~ om_8 trmGu7ҕ,1Gx;UMuxr>Y$c Wf4ë#*jc#7oa&,M7ʑY{ M<ǡ%b^%>}e^L2 8$].N.f!QmH|:tkStw}J VIBjNL.= 5S'bX#02]JzQ?W ..ӑKl;);[U'wLuW$"&ݦ2OvKk. x 2tc)䟻3 %tt<JW8z| !<"r%Ǟg,G}y i.JKudw*f$ٜA^Ug4)E?&V ݻoz}q &c'aSZ-&/ˇz<h|N[ W-cf8]*_djW@L(\WpYՕw5/'/:F)@%vII؍>T_UX=a곐ҁepDAwUW{Сݯ9,cAM h3~Z%XPB*/dt7f>}L9?Hqa$ڕxYu󍻗Tc7B{~49ͷ/W(_#̄5iȫ]zi^FN8|&^$#WOF6t8f/E0 4{3>2,TP a^Mد50:v; XggFu?a~d:Z$f2~]c8: ҃>j0ٓvulrrI `8_]')&]T0uj'\?m]"t%{un칭y ۶ qi=_ gBօw48UŞA_Yf`+lkc0凎2V?tw58jLAWo)υĢe"ϵrѐs:^a=d -)shB[n )]lf O|#!սB 2w O(Il&r5;?]7ڇ.XIiz\bJQ?D泗% 8A!^9qPxl* /' Wy'1%"6~i6yޱ$P 7I:94+Xޛ[;ܴ^OZ-z9O͓֋1zMC̞|CӦ$i:ŔUb?:*D2pӺ=솮\t`L!nl*~8(]a Vgr1-yܣ 0Z( aUZ /!Ȝ>$^e]BSs ]vV2;RZƨ4(Wendstream endobj 607 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 300 >> stream xcd`ab`dd N+64 JM/I, f!CǾ<<,$ݟ3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k; g```te`Pc`bddq?SCO|o8 }b~ wwwsN>}o.6{zngug+]#`-ýyVT#3z@| Itendstream endobj 608 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1445 >> stream xT}Pe厽KUFmD-S&L1AeQ8X8=48PM̲ŏ:Kt!SSz9vvvy=yIBA$gShs2 Ѥ8C|IE7'dC"Z> E'd$Tˇk :mZ:(008 @PS֨#VM:uRf:RQ/MҡN=TLIKHU긔xE깋b/}UwTb C3y1jUr´E:'bD,Gsp"J#Hb4!!' A6{lO^9ӳ*փXǚfӇbd6\Wnݖ: 3`~ZRdB jGhm3MԚ CGTmrxgu}:8g'sLl"*y]n.K;ۡz;2rMPŝSUR?DN-.8qa)Yk pqRgN蔉Z /X嚉ӽSClF]ϝ/^:>8 ?Eԭ;<=~~^TOA_iԱ؃*0>jpUQ2CClf7K-DcWY6wT6ިgmcK淁r?8͖%l=rAgfо$;Z!,Q.j`7\4Xk&)`h)מ,q8ƹf-H'Jbn)KZ6[E)EU󳱦Qf#TsTw$;*u;LLE$y}i#k-] ia]w9b4fie{$<&M@wvh$RD8#f$](V1Y`aK*JoYYB"< =-^l7Um֠7zl\u8|(k?۰%w#|SNPvt j}<{M~<ˈA~nd ۨ_ui_:%bz+XMdIj(n W!6=솔ݷ{KVDLfǢ-O#K%t_-P~l7}ɉ9uҵ+zv#솒|>=y>,îkɶ[* 6Ш\CXYcU(2J (*eVhk!'iD޶V0ن 8~eOx/ C(O."݃JA\&q$qn)'ωq%Gbq|N8vhQVfUUR;Dǫ^ׁOy]vj}kَR[/Ty|3endstream endobj 609 0 obj << /Filter /FlateDecode /Length 6674 >> stream x\[$u_'ϱ TGJNPK,8~Mli{w{Z9U$3%y yky=<\X]/[\`vyvh5i]0ʴNœ.W]NrizB͟uYonw7CYs{:u6la*%EbmI7kha1LA5-IYfmv4TUZfYM\h>7\kn_Tڦ´#..ˋ?RlqNVu_wL x $5.bjq{А-6w\; Vtƶ\P? خd.hp%r&::Wm5 |HDžvЯ/IGgӭс\hP?32d+ZdI+$oF0O/2tR_%cOV| 1=97™O[7jM[7i+X4iߤ@0Τl~C at ftpTpÉx c.B5En@d@4+TP8 os +9W84|3u:7I[S*73Dhq$Ay<]1X#`[^$/@/s_RsFX.8-N#Ga~Z*Fb@S M1~]c4=r;q \eXwg,]>vqixv~0˅H-5tRL.֠ үd}4%}^.KJjE\qc*q/3H E2 pP'؉i+1PsvBjhDpGb'6cMtmx-$RDN aV6kÛlpk "| -Rro2[mѧ,_;3dk sldi&m24I15Ûlac mi)$--(=gysl\Eǧ4y}? t,,7Zc1\ @Q,1C8O[n: :|^8< Uj 1XBh)`gŽOlhIJWtz@ Yzy+~vrl> N(?$>N5BRlg ϡWvpoqo 5WI=r2neJ6ߑGl1&jq}6:lw1f۔wfNxd6@4n] (`.xFlZeӾ}ÍCE&?|v8\Z̬I"߂ G44+3 E=lp^!?)Ow4`0Y `Qns>Hx|{*脘P l*HG2~3ȷ]Ԙs~fp ut9: JbDk=K39F"V4kW:%&e e5#PIf}h O-0}˙Yc`4 \g*e78^=nȂ}ױVU{E:XI0|آ4X EC@ iyηx獊(r. +t/n5y%;uv)HZ0 ֪ǁk+AC}>!ʪg}XQ92)N.LhslkBx׀.=P44yv)E;M 8 -CP3y8$oa<zX T(CŁoC%/8w} 2z `]Sz牥Y bY.= }jw;Ds% ƴ?H%pw! A#41{'0g`0!8Xu Q(U:faĔro<z[ Qk!A9}D&'MB޻uEQ\Rfxק fY3s7zw6ofV6wk c91x + 7Y a ͅ怎oˊ ㇂Q`>wbi~^, ;Ub(ꛙJ>)xD?α\&XA`#Sk`P"b*[bŁ#4OU>SJ@N N'BZAQ,5bMW9D#ę|ɟߡ>' GD*9+G1֝ap`'ntkxL} MA={(z=..SɻKq*GUk.7aSV~rNq>i2G8ZoɌ9o^A/6QEl'i~W:?RO<Zi;áOLRj'fSŠZ%%* @k/Ok _$jޛ}Qן7&:в4,.LKW-d+z0%`\{ZTMZ񩣓nD4=oN czZ!?쫬Хnh2Lybs!IhJ~Z]:Ƈ>ON,G5]Ͷ1'ZM'Z8tgH&k~0B37c[^ $d; ՁL̺~UV&d5<^p0%]Ai:ۊVKK2-idSX;-a l5 t!!՜pϞt|R[!$;1wt沙]Eg431x\VX/Lk; `iξ`/WR\A;;ټͬ֜P3!&?S̀E}dnvq#Mf? 1ޘq)\z]ej%Uh")qס&0yeE:sБ߀ϗz6Ls~SQrRSz+{Gexl䫽 SfE:cXhfG#%]`^YwMrכ#ヷ |/ '%iy?\KH>hv7sr5vҡU 'x ;7NnV/[ 747FJdIFj:VbԱhyc/sRP`IuF~^jq?#C>G:jʕ^& ɺXuṘ 7Gr aN:sRfmdp`V䣖 qJ2cE9u s0Wo֜8L`? U Jv؎).N+a9*CUjnΡ/Ƴ:(t9d`l;͌r'ͿRp nx,^;@Eu 7] hA{DpY];z(aT7lo4kJyZz*՝CjlTK(p*rYEB$hX,ݶr~I $=s=d1Z!Wŵ'mFɺKE8u :Zuy-&Aa)ڢNj|{7:"2"wJ&r'2\gn'X+ Kl⠲*(Û|Z?sofLZ0eP̥16Y~:jЋ 뺿AٖIpɧ&LR7hS5TK,[L2a-LmpնCG0T!1+&SGhx'9Iף P!>- ~fh)(#8F.#7Pxu~Hk{=~4A.~)= ~}BC:udD:LyPUf˄j - O=!1sifXxkXp.feDH}iCݳSBEBJ/mYTMl|iZ_!(JXi60 Z|nW-HË/*x L+8븨p&nj'}k0Wכz</fC˺2yrHnjL`:I73e(_O#q2QF._R;H%BCٽYhC|Զ{?IJS~544^$&W_#Wrzǯr&&tCTr1#LV4t @+VIaz3Rf!ʰ}D_%g$UCzvSn@ M`AAV_s&t|f7 @Dž٥<o{r~h]W oendstream endobj 610 0 obj << /Filter /FlateDecode /Length 9998 >> stream x}K\^Fe6v7<֠1EHJ,GD᳞FJUMBA_K/Ywfo^7JzytׯO>KkR7}ŏn dW &Vg^}]sPkZ?ji?<>?t{{{\1.?i7.Jӿ,|s{ad(x*1z_oF yxmyg͖}j`D[ڍ3$B$fKĭiH ;wJ``ā6&*jj¾Hܯc͖ )bmi@}ڟ"kDLHIgd䍯4Αȫq0^M 2P{3u^bY%-ՃfOz=`F! V \ 1ZOeLvJ+ؑj(SzA)B@]U`ݞ eSE?>Gb)KB=C, DcF5EӋ0BG1-"<Ě=A;lX'!Qz-! s;!U[A<:O?EN|=E@;4#0:McmGm㲶 ĀXD+c9=^@OX 1t*L9t5Vbh!TD5C%RTeȌ̀62z,7p4T I|ZD݁N+s| DAI&m!eV +$VJ|(1NSo7y輢hqKDcUDG=(Xyd?o,xsfyeRr-[ ` #:q-{b!4sc)*|,(U-Y%1^YK.i,3[03`.ʺoW]4[ 9մ+%_8C p^c͖V [, !3@ZA:Wz3چ<6O{IZ$yDO(ELJWfH_w)3 F q_!9޿իʒ`@2AˊR8ح,RŀH1WJ,,!AJeT w[[i%zD+sʜ+!Ж~c]ID*af^ r8uV3JHk=пI{xfy Kh.,Lbk K̗tMXrϪ KTڄ%`˶QYB upd`8e/[lHap sc[, !5)1VV! WYtcXLTbBڤ4zݧ=D&UWmC fz55)I_ˋf5[&kSeo*: _6Teح Yfr.H*<3$U)fZ(UfC PI{%l3\Sg L&*gV+SϤB>&HIO:Thr˔&u&vsI_0ЩVW'ѤH_fxӐ9iRtdUf4}W:)4.*49;( 51zm'f=Bb,>crt5-ݰvc~4E5}PkRjk41vV!wk #ަI1MR(lҋ Il;ӕil۶UٶgsW h-sd{lb}DX;kcϔ61>vg+&oLlf6qnHifIdd=|fIae>dh$d Ҵ<&A24]_1,7DC‘μeқ fyAg2M;L}Nc&I nR~5x8iu^q N;=sfΠL> NDP F!I)g>7K;}89G뮌\qRlu ;Nt8T ?n[nR5* 96t`ȉaukhr2]q/p'34:0[+2n#22M*;Ylo N;ef'0}:Lێe5=>ݚb Fd/ey`pØTKY(wb汨:̴;١"BRr!߉9E} W)btL“1^u!͒fm Oh3a4 Oe1 OyՎBh KCkKOww*Kq*H'm\Cz)mH'^8"H'T-tCz)vWE:hKAFtR B5cQ M 0;džRv3tRjգnH/e7oH/VF'UN /\Cz)$A N+א^ji"ٮ"!HntR(ϮHzJtR/`7ⷳ-^7Brq6~U)'%u0?imq;ac9&(+Gwoay V`1FK~>EM_t]̣889/ a语_cSo]W;ƹJ7Uӛ8]~Cy+~49<|Brï®-wxh*-^&tXOOapsCHB7:a6%<6v[*tڿWODCم<āEna0Q<ڠ;(wX\]?`GB-J9ޕV7ԋI ĠF̊;>,MW3h{iڴ߿z/_/O`$)f zɩd_gne-^i쏇yX2_c0.0_\e6j~s>}ATDc,~7 N8eT7*.wUCߏV%ht.|< }ڑڿ]zX~A0V0( x\AǧW)؃!AynLnK}|M),F'x1"X/|Љ^ .73-}I'aH3^.)Mx&1YR?ݖv Q0hߨ5GUb݃}m\M{qNgٜޑXVa{{FЇ_ybʝ"y͜ѣɻ eCܫ 5oWd6`e L;~ZƮ[7x %E;v~4p.o6i4`#AQ'XaݪwgzN.ԉr>niSwDt%/LN[aky[~_Lټ~]sʬ%%~9y H&9E+ y|ω D;7䃵>EK%WY/ D?AWe՜-G0^^8~U C89ÿ]n}o`ni5tc ",<{Tf5ٟDHѷW庖t.|)Vdî$نXpcH2SKCcȟ(I!p}0:_b(»?>8u1 Zv!z;"?W T"NEˣX M/Nm@Os/XbwT.g/c[HCۋfl(]}iv9޵yS*@inO&gg]zw09!+~K#59Qp"CEUr^B%Y m C&&v{0ECxܗH]_a0u2?MkwSM.,e_@SrW?ڡ]ru$r&WsəL` 폢& m(%ob\[a[o n˦?1]-JWvyv{3+s0<2s6tG/3ɒDN#6Fmϻ S1ZWpĊovLMvWn ?`>k"O?aF:*?BGo|&"a,ppohV:̤ Ix. m]j:x"W oߖNjF?J9q? c\sH@RHbոSKuܳɸ/GKx?Xf6?vܿxh]=c)aɊr.nNBT7w)ЮoҩͮߟG:k)?"4Px)q{,7[0bqnIUip($|芦 e_0i6Թ]p"X<*{(]: \ɡXOSY49lUUſc4 6zkN5b;P6ǵ678#JD0RKeLyy<;tOҏ64X@|u 쏠g0Z!x^v óQăL߿$9ۓﲔOwإw %8H+8wg鐛~5N OKSj_ U< X>Ix/g䎷 F1_7ϣ?r%ͧH*Ltd~@iT;=&1YIQI C&2P_.P6ܯC.RzNmk&:2`ճy.=4VRЙkx:51O;.u6TgT䇯q SC2b3-$= X+@)Lө=-|~2׽YNE_S%ƺ&%&7)fz!:$`"[qUwMoiGt"gutᧇwxl2flI;ܓ挞4jʓhLFg/U?().Es,ᝬ$O',o xA-]1^6?}x[F_Jé(}ToMJ~.q  2 YO}'/ʇQ4>s Ür7~05VLMj9Op ZY4;|o#mRSV?wibY3V#a2a:\QgϪhiudx1vj?81}\I#籄߽j 14,aO>\6'>#Yi}5Wo ܇}ǁU&rbs7+xm]Lպ L*o<+]ύ-f%wTn~ٕߦt:du-Ox̮M>[r*OV*mX$ms/[GX/.zY1oZ1LqU:)Lo(31nOzo:yLD/Ϡ/{`iGendstream endobj 611 0 obj << /Filter /FlateDecode /Length 7665 >> stream x]IdqdɀakK"Al Z҇EvwQUE""^p8A:+̈25E>xn^?]Zo?'2gWO*DMq<}xީYK;kt/Ziwpx,kM~\rH%z~k0wv֤Y9/;P0=(%t i: Ksc_'d`< *$>UY/L>>}t{mls({c27Ǘ7y|hnS􁯉Uy.g7Gn lU0 W'=Wj0٬k6Ma/0D`c5p DŽk8&\ *IWa\ Hˤ ȥA@.(&[C5d JPBbrUX.Bbh` $k8&Y pLU¸t& H(tHisYKq˜p Ƅk0!\1`BZuYC "sX*1\7YE:- 5x 5"߂c5Ҥb/Z'" pφc|.8g1>Nsl<-%AZzWK=[xb' UR8 @eGi7TTXJ4|y5׊xZU0V7p gbn 6 ħ_kKa!%Kj)vr<Ԓ< 0u#e r8KE.vqL86- NKlji (18h%Vc)q! 2Be[ 0%qI691Z>Le+-sMXqlL9 \FQJQ iL8᠘Z! TbőPCj+qX(k`("㊲Mܪ`*XqP0 69#a[$a9,9:Rg0J]0z9.z8G c .9!y`˽7#6)cdc(/2`ý/XW7l .H{ $Sp\ka0flq L"H,"' eA !!@y`#<'Zs3E)JÒ1A p\ҁ|lD22؈) <-bh#"Ft"kL ZnIM''lF̸ sP4z`\&O0nVa0n0+lI:jM:L 3$^ vG 1aۆ1*`B cl&p\4e,ea5΋9J T3 78PJE|@'H ^+,żT·ءH(džk86\"bbe: +ގ9Be1+hpHDiR>lA$(숡KXD(<)5։ bkCFepƎIqK~g3[tnISVVO0Ar@8Ny7Hd8qsT(V) 8, :@8d])  *z2_u* 2G!Ȑ:DdN贺(˜i0NÎFߕ,6i&`  ‚[l؂[,ւc6 ,)Yv)BJbFOM xrc鐋;⬖G!P1urC %]E 8k p5*]5Qj('. fw5V:NpL[8!]1*I`RǠ.#XJcޓ]r`’{!0]sچku/(A-g!džk86\ÉʝM6\Cqx"38eI"s0ʐF ۀ "_q /nHWlti(sou:NfɌtE&!pmW[j }y(9K=RЮ.2w7!~܁5uWdNf~r{GfZwLJù*3S-LӡMo <<CBʹQN?ov<] g͙;7kiC434Њ?ScXWq"4tw' -&:<퓧Q|$\z,Suh٨*ioݨhuǽVZ|\NcK  6-{ttx?3e։>(x[H3||ۇ-~,x?"gE?<9? ڵV%PxI =Wh?mMsH6tWT6]GmmBX9|q;D~zh;y8}aVfRA9s{Wfv>Š}8Ǧ}4sҠM=`w0 /CPfaHZ |Hko7W !bO׬ .z5wN2L5Q?c& YځnhPyiPm\lҧGEU3E;*']*|Q"&9f(RFus07fNP(?dm;8(B\Z(ϝRKqUjAK;uk\ qŸ|JME4 ;:qr찙h+WѫOVlN79`;lI=5@PGNM>a.^swY%LѥAE-}(FP8+v_W4PlʀX]F,4g320lzϫwyp#a ]K_M݂ˣ(zGio> rҟ_je-ƣA_![ir5i.gEA j*FZTcW>݇5\۽!닽{0d,IyGWzCmo glKۇb=žh,X鵄'6wmKO~%n55_l&r9叶-1,rX}9GkBw-o*\O0gbE܌uP(uM[&pT֬5sz-.M Tѿ9Itؒh@崛w+|-e lkR@!a~osw 1ҕ7k`5LYSrSulnԩMPc5oMy^l-Z]! U'~s:*w;=tB Gz{5-kR_N{o* 2[YhӼ][b.z-ȉ\WqtQJumU[1$28Dcs\VJ Piˡ:ce>kMF:J؃m\K=YDqcQFceAω.UnX{s-B<5$8rfO/ F|(+>+>&ys9IJ]27D{Q7ݸ6$S!]XU^P6dbO D_gIrn&==q'DCRľ$ d{0˛&KrW]g%K#(,#RaN^u;?wZQkiW4|lP-cUmE8Yb,_WxZh6V̯U*EVNG1U'qzZ^Ic񪮈+YldudEc!6(Hc`VI@TΪܵX@ R2C1&V0> X^};;!RWtޱ E:\Zi?d6P~>SPKRSp0BU__~[ņ+u%CMF.._V.I{* mΉZEϺC*Y_jQ욥զ%f?F`u%b?ZcY׻tߩC;u|IQl򒶕dw/޼[i9as`9Dh34#-YKW1U+H6FE57۾x %@lw|^Y@PŎ;s'7Se; "`͏{Y!/ݍ'Չ h/*sE￸b /*wyPރG^T\:j9*:hr⤛xz'u1T<_.Q!5=C])BjDwia9C{a׿@d?W+H?]?[N.h@;"%׽nDy u2"y~ۇIM}JäjpӼ9&9graZā;z4[z3Y h-l!,' )nmoIqDk'\i4tyS"%Ueo nU?K8C-2Er>}M |q/:_t^g<4cHʭl]]Uy77AO,@ K^+o_OX^Ynp3>TnRC2u>%=+ש=F ̞y:\b3|{{6r-`6 ]&]@,&?Unf;qf;a`)6Ea_,޼hK28D,WӶӑ_$skdNLzkfӶ4r2㳭M*rr1 T Y3ߩT&0<կS$C5g[bPz/WK: bY򶐐A<^VTOZcrI?i2s?GG>CŮ]O=j!0S~_ZH^$V_~kcvW~$V)?$ܾ[Awa˕С]UJyٮi>߾Nr4ב׻t]&$Z4iqzlxtG29Ny(ό|٢nf֧tL}TGY Wg|>\NbFuʑ ՠXaCeO2le)W}UݑoH.h {RF=M[=+RDendstream endobj 612 0 obj << /Filter /FlateDecode /Length 5808 >> stream x\ݏqxF(B ل;Ŏ퀲e' 0<cޞwW:QxSU=3sw qv?~kߋ[]Ubyji=|u,t+WVK:ߞ5ܬ*K2-5ߖ3[ ʍo.a讳o ^9\?phuiT˘l>LI}i ǝq~z#h6+ꍐ9.3#%li`P͍䶵buD6w74r&SW5_eY>٦6\(Z&JQ@=\! M&{*mNiJj/W|a%MsTԴLhV1 xfak$dîn๑v"k\B+h8 05ɂ"Z_mCpA8TiNDˬi&ǹQ@SQ(|Z|2YC:\nA~AOfbw wO"wSFxg |wND BQG7X$hš=Z+8Dy?!ցyqf~zy_g@9q[Ϥ'ze<"3i+^ glŻdga8&A4?fͶQ ܿ٩zN-fO[-6^+)]keVHfPIGඇ6͎SOfm92gg@_Q E+Yod8%.l&z%<֏.t͑~Z 􇄻VK fDXMs?W'8{% T8y&T72W-vu,J  ZqN$ 9H )J.TMi{m^ws^Ǯ׻ɫ=m V'.&wݾWá=(U&fw]zjvMI/b9M`W <_!ha58\E,*Y"п=9j!B\x"',ib ^1`D?y z%iTVG& 9typuht—yl>p>=JWwL-'gȐ[6$Y"w Iы2~1eO=eZa2y(z|LW .\ *kyO$'/' ҞYA:o~ ~3Y cwe'q8s3a1;.xcz1P@7;<+nȫ^Yy^ˁ-:{pDmh1Grw]n 9`OsQv2N3Ƿcz/C 8G 22MjH,7ͻ +ֈ5Hx,1tWxg؆0qu/p)\2oÛ֚i!LIFBňØYဗ[9dCg^nVA\)gGKٚYus>G!B!h͊+XCؒLM< "nibA81 )'E]=lbХ,S(i;:!QZPuLz c蚃40<$@0_24&Ԍz cbL0*arNo ZNtsH4[f۲$ƒۮ/Rycg@VzCe_s \EѶx^Fht֤ 02'5HF40.Џ ;PTtRʌMӢ"B\Uqդoj Jx,ë8|Ҩxk>ums4Ry潏:\>)<7Y}&mE,.x3ѱ~Z|-Ʀbpg3B .ݸr D'Qx/QV譲ѵSDhZԗ2l!u M4Y' [~#).b qy C?颛dxK+8Эny{Le2/O+]$ք"uR"z$Mc"0 $%< NWis%D37uhKx+֔¯=])59C'5'˧QDgy*=[Ep"@G,ꗆ=ɷzD('0K0Wu,{k&}0PoHvb^[n`kwVSW6f6U |` @\:q@VHd-}_@T ڳSƤJxl[C2E\̥JtՂZ ׯ }GP[a7_}im\`%2b$**UM‚,# J}:$(j6T,w_]g[BpzOiA;\Ɂ^ !%.p8M F2vF9 >T|()8q\4bRSk2i@X0k9F^%\xevLYMj!Y%uvۇn.ZHhPb d\;Mɦ+$ZRS:hLYEPH:R1q,qŖ/' i74%ۅ BOtIfLgf${nHzМ&)W25rCV¦xNPK NסyC>\bq*Rׄ1Ao/$5,hdg>G8B4`֪ofZ-R>^/.os |3tGE 9F}.ozPuEɟ.W]TrTςC' cUP%I'C@8hoZ1fo.3IG_PMl]OF5Aa o+-YEu6ӎo(2Kԗw FR ryo>ѕ453^X\`aq4W:_Ь+Zw9Z"M|LH EcD ,q$Ƹp"0mpX RLIY1-Ǵ6,>&4y!4\Ej/6B)ZT5/HF2Κm|Nd }uP .1o'}n`*coh3x :Ү63B-;~!6"쩛 IΥtԉ:jO|8$,!-ܻH(s{d=v43N%Ґӷ_V1E^9dYf4vfvC(wj)JE=:mU?FT0e00-6]3H*tC/D^pP{PIS@q>7|CⳚ/A*o?#%+B>lNc)_wHP>REhTL(]: <=89Lc>Pԧh0@;ы>;C_'tBPd%7n3\1#pM4}bK3 MLDT<ޣVz;mQ3#& ݵتN2zY!L!_jm\6=j4$9XPLu eT#]sm?#p /gW:$9j1Ԍ?%bx)P$6Ck޽IЈRfN%Èl?{ɺɊҥAN`اآm ._f`l)eLg x)?Si+0Mn)Mn]UBο)BTĥFKyP@ΉT,p-U2hf2t6,pO 0:>YV$nbSWSmHi [i*S#Tַv b ^ 8څ_{2^+v>{Y |pYZ*UJ7=)y)!=K埩,"*!Q $\ɯZ~\0LTE9AU~+9zzW39VxC7D si452$RTݡ*#}i3idGMlp?RpsHfLAbR>8v F" \zTut LAdt-cPH[E<%9)lAw4zq ,\:E0M/.%3w8e8PVN#) Ebo.PZ–XΪB ǰ/Re_] iZQ SYpV$m9Up}M"fZ7<&MJ˩(Qe~`T9 nْw (%ť)c 0[!mJ]ĭ|:^]Urmg =tq&nKx<\Fҟ bRh6Sc~Y4qksg+r>&Zw LH|_}[2[ÝS!]@Wa1jz{HES,BpRV$ t̥1A+c~4p jxJWi}ls[M/˛;t]f_~, '_G@hܐ# 4\ r0C8Rh,<~yj&tz 븚z屸bհz }W;5ͧ0Gs +!Gw6Ҟ%*LRXe?4͗?ynX oJc MWZOƢfToqr:8_oj=endstream endobj 613 0 obj << /Filter /FlateDecode /Length 6288 >> stream x]KiloD߶zCS.,{WʒQA8[ꞦϛxBpD tg%^D旉6C6߮Q7aᄊ(ܼM؆Y[6F 9\}}1c{=$B~Pf 0lpݸ?;; ht0{$a a 8&MIYfN4Tw),E}9޳i57J\TBq˫WusTb0Lbsy :掤WLipb"Qc))+Ӥ X+֢ nn%_;"8K"838Р0ñ0@D|0H$0fzH(ܶ(S]HQAaL:B+ѦwgqxL2!iF І(IKRm . pBZWzUlR@#8uh(jSLoiϬEѢ7 )'@qauA+Ѥ897I|A/Rt/VL21Y)Q2&x)?2Dɘ`S1̘"%1O"d,Zɂ'R&&&eŔ(sh}sH ebC#1%JƤ!)R&& dJ jV0EĤrL19PSLLZ xϙ%crxr@Xt%K$L,,x%ck,-Ia6`J (-Q@+V0M t)R&&\2%JY)ٞ[2Q2&)R&&"abH'Q2&AL21))Q2&#z H4)Q2&عDdosDɘTL21Yp6ebrJDɘb%1%=yDɘΘ"eb>ybJ^)R&&L1!+"eb>󫑒16w{jyhɮGĵ2qknN\k,Z-QθVĵ׊ne;ۃP/0wj̛chc1]J0iM?@pd@Ȁ0_p" f-m`6`¬9u1da"pԛoQi<;X4C젙%@r Aq\aWHe@a}, iVZ׬ĵYkUWYYjY= Ibž&}^xJesnDU*K.dPݻ7XXɻ#E{EZtAO+(MB{j=ˮXRO'Zzk;FK /5&Uu;싒C!I2!㫩80A |PđFP:_.7t܇;5+ӝR]xϡ5/g|UTOGt/wCU5?ɹBc&^)f,&Qw/mݏd1`PH~?iӽ4¹a$pJ}V<8k .M;G94Y{ދ Dw9r)GnW_cΔ'*1.HTmd@g0,( .,d>j< H^nܰQ+_xM7%ӂ\7K~aJ5^p]uܲnNf~U[0m]K@^Lm?zQ~?.PwUMkA*pFAt{>VZ?N).AW'xXޥ'+<痢{5k8(#:/Y<ѥ9 ; mq0c8lKh;ZTԁbsu-yb~&tTV)ve+ce xF16:O jOR ?K^b/!{cStUދE GFn(naXhxR9lVxKMj t]qF|fSHu"*,x.Unla;:laK_BI)ykpr a4k+tta82#t+Ì8 Zt`!`RΖ~I8~/CWBet$V0z *"O<-z0}UfxtH,7)á\%s8X7ZrK(T/s@raYyBA-!KwA(T!Sњw{̆7|ao#*&ݩL= . k-em[ KgNɓ;4* i1>ݑar1M ] F F<v~h`41-Q!##*LO6ρ?}|9Z7+0"Id4/J&Y|$/L;O[Ģa&Ά@Sr8QNaiwF+RF"ͧ$ec^GL qӣA|޽oi{Pz8B;!ק5" b~whU&!)034AbFCOZ ΆM|8A?Ͼ$n9)s}(_jgdIst|<|k8P|ZJtA9\ewƥ= c.c]ŀ*.S 0gEYxd4K_TЍOˉ 5X`!\l`@[2.O|2oeBcSF.jKj #(:G3|ɟ[V{Y  T"R-)7Z꾢r7xEb%V~xEbNʢ_1+_*!eҜgywJqaJL1yt_C5P㯹L R*e iYy&{2*EvղO]opm9TyªGL SyuӌEv Ia1_۝/S;>QXËU]EMOn|% 袢 eX{^3A\v]=Tiy~h 1{Ǿ̸)q{HKc 8vMh9l1`U{>"gOoE?Znu_X:_$ej1W JJBxMH4Źi0'k;TTGjO6y,ڛyHV/@H {wstռ#`)ͺT;/=Lxx}J^GuwX1x(.>Mp798(fw醐a.&rO._Mxv?Urhl^%qgE_PezhWNt;Tԕ*wB9֌M_\(3yϥg ќqJf[kئp->WńΡW7}DC%v(~ Owዩ.j_^CՂyM, 3Ut`plb2p Ii5aH;d!;O$:zh|v̗oAU&1^ S=NGJ}dN K) !,NI[Ib*'~80k[|AOW j 6l0fÄ륒qTM8 X&+Sua~V~hL?bK!8QY4]k@<"HEUEvjڿ-Tx!0@ۊ|+\0o> stream x\ݏFr׻{ 'O6qőbXyn3%?YovO'=,fw'߼]ӉO|qYkںSbnsiX1 :\\>4܊7~I~{9i窫\Cthcv]6ZiT\eZ K9ᬫ? \)YwVkgӛ!vWVVCBr oTZObo 0\nٹ2֯Eպޜod &luu]ލ(`۔C/["/e5N@j7 qnëFWo5{oCwЇ]ܖ?_g[;ӬIϓ-~;X%`5$j4NURaٳ&IUvoTG/?"5z4^'(o4i Vv;F][6m=}W;Rv ldd|C;LT-luXRrSU%zZmUW1A2O[?.ЁߖD^'/ ,me>~ aeS?^9j$50~ B. ;y8_\}XIW +ٌsvq ZœM{ ӡn0 .-짴龣xH ,>LV:EHxS߫F>uŘjA l6VkuZRC1CNWdD$)x[K! A:E.mB6_6dv a=jTlz$apVB˯8g; xR7,m+R}jW4K&7 ?jwd;Dc*861S:I.1"S0n@\&ߝvt&BDuh$x4!Ba \ }J-<7 _o/48XnI!\uIR9R\-EvY]"pJ涪[36]v?C ԯ-sI*73o4_0<~8 NiB8Mu{XVNFj=mqPf?2j)4%a1G_fu3A *F1LZۀQ!igp9`[ aV:ɫ$ @/H3t`%#)k &jTC\Zn^)gӸua?uIh j:R;-h(D2,iu&vavko>Βpĵ 0':D݂ q { G0c,`)A0Z kq$zwx4^DGGF?^Y p]©>?&@Z6Vq'hga_&"<r@@<1y< ihc єv`k]) .0)ٮ`xØc 'Zpv5x0 +G E8l>mdA8 )o3JNFI{Ô~`>c\x#_EVH$s9烁d A5~9+!v;7cppJiI0\~wHvFEj!p8 :8c:1I%I9D9<-u |py2QU%7-=SEw-”EtF2љ~$\T1P;Bz MC_&" riя%C]7S?8O". >}*\wA3돓^Ё.}Fӯ)4.'7k}i2 [qVhB#`(b8҅mW,u;:v\-qYRsC3ws?0A0#Fudc Kׂ?Ұ wv܎v8H,rli74Kzq%@Gc☦cJe);W~dp31?VлH,ŧLL\*Եn̙lRb=]cN_(Xan_ay:}$SO0Zd2g1hN/pfZ C/i&]QH5iPc`6Vz{W }~s~6+SRKƕx9%tȨV@cLna*hH~DWL5eǴ'8cG#|Z;ZِFHj@VGZAbm"VQw8IhӇ;n7kis#m۴11: Md'&E_ (Ucu6<6^l)lQXi}nKklVJg) klVNbWS6&?Dɕ\AtyZIykL8 \45Xy~ayH%5(i밟״cgTb:zJHDs𓶷' )RyŽJcUĬn4\T+P%֏Ӯ쯽_JF1>DӉ:OHQFҁ_$EGuٝfn?WwwJepɰ~){jRB㎀Q\эK# N"{D$P{Zy,4qK ҂g:2}QfZɸ[Q_'w8TRQsʎ9N##z{R1' -ZhaސvTv6>O>XK\&ej_G1gYΟ^?6cip<ÒSGQ7SR3dRyԈc`Zpԫ{mp[7Ts:WʑM>=&',/h ߭0l\ \|Ldс 3yEiEYU ܖ >AtvſSl66y C1+S 6d ?۰VtT4û(eIѕ ]z=szN1sj3g>{Wk 3ޣ: Z_cIPEtg і.FǷVb?S$˂O'I$@zďqHM4~?ą Pû=}B;&c[ng2J>֧rfƎ/a+]}%+1 ?I}] AmPE ځ2s\l -g9QBi6+2#Teov"5ɴe={(1kU9|uf?ZƤU 㩫u!>h і! P 1lQ<=0JB e3?|_ě@tQiېC|u:f)V҉/)F<'&*}6`iO ʴǛte~k㿷kr"O y5~_"Z39⒱&nb:/1ƙds%!K5IZ: LpHi(<}GmypӨ󷢗ORݱEWxnӵ*W-2Gµ#i1%r / gw ax49%b9O͕ٜO +X,["4/A70-Kꭳe#f\"aCʋ@th6kzCV&e ˅K¾j5 ݈9 U/T? U_T-w2WE@˹:4g#1RNǮ z<1|.q?!,?3>grmW|jʧÊhqܕ1t5X q/sۇ&b*&O>%Hl]A~$a*A5Lp(?w G.=p>4re׶L)F֪vzDOS[=|7'KEG* EAzU^(E/{#%L[tUFlyΗ ⺕~t{,X ]bs!QS߂N*UTFܘN P+y#K$+:0\|Y7/ J8q~7azUiowUOendstream endobj 615 0 obj << /Filter /FlateDecode /Length 6314 >> stream x\ϯqOɁiػ^x{ $zLrl&_{Ω=3CJ+ Co{_WCV}yVwS$]^V_ӷуOCRw|Zh*'V7Yo~6vNw3A 'lЩR4ݿN狆\ra*gMfc?X- <,F9@W$U;Tr7;x\mؗ՘=ü^? Qʘ+ Yw@Mk{V.zЦ 0;:ZitzY  Y/Ѻqa}H,Ld/$F$%$$`vXw( $osA;GPE"9jNT(2$0D޳Ļ>k͒4_{ҷWwW$t7`}M.7<KPK$(Ev['- ^|UQqY2d'3vYRvYKd%I̞;,}EC x# Ĭ%1,JtI' .H@t2N(m~s-{W(q/ N;,_S`%_xgM?BD2$ Jͨ! aYp 1*tm64` W$S.L], B5/ 5$pEbvA$&\%NKK1LP^Ǔ\. K fhiba6vE˘EIi?x% ȡ nY08jسHI"CdW$ zJ0ڕs7>.vëՋWߟ_d𢍢 pp8_WO4L<`W;0قԯ, P] LY`Ȼ/*iPf15!+ 8!LA|[QLtcr dN*Ƒ@4R"ɜgOe3]*!ɚ{kU1i*aTf3CAQ~D1-IgSQL xGPf@eAbXQ̂f6Wme4 Rrb&4 ]bB-B@78cfCua3f>4[R@Lf ԼLz1'0(*YtB TOWdZ4[2XSPl(Xt(FӵcZL17BI͝઎|bce4>@Ub4]Q%p37֮BY"ƌE 1@b5DtD 1ZJ$ hТDPXc$J$ qk*('Jjb*Qz$jHI} H$ ?բDB DK5TziR*-H ZkQ"Q@e;rsɈ*n%H@ J$ʨDعJ$*;W@[U%#&U$uHL[W@9,}THvXJTH[THT 6)QE"Q AU"Pkk*L]H$e Cb5|C܇3@ȯu# լ"07@݈#zlFnj z3ω~y]W#SN4qxHɬ| yM7X8dWN6鸲U.J|rlcQO*d"iP a{ T4(?]W4ceI-PBix@lHV0SA6+vc4" ̔,Y~(U TbP_WU>u5v# LxGjDq>NC1Ebk(|LWuQ2Ѣ5JuDU@*QӵՏOX›d !b\wD|3.Ÿj:5!',)jh% X=A9pAU$ *Bĺ~j&R1 !7@O@w-jZD Ѱqzn@sA p:PC,'_tczKP 1~1c!P)R ģ~DRL9pJqy1s?S1.?QԹC)z)'$+rV~2'eqjE|0fC"'y\cqM|@h~U5adz>3`QoMME˖KLA^% @`z/ .VڞGt]ܠb2}m>tYb#Լ(ۆVgXGgNϻ `zrw,bwCz+/c E^~o~L^v|mWyPQhGC% NNЍJP!mg TWZXҬ 3e@FrWV8cY]Peq3w i*hJx_=wa Ɨ|;1ǜqpݦ OS=%XQH& AgqUKQk2{' t#Jhyd{^Ek@o:MqvI ("|ɷ&~Ag7R8v=JVvBL1zi|l<{&쥧_BQ(dօ%2}u}a͝ƘŜC t؃Hixʣt*;WV!z?) }eeq3`Z״^;xQPPf<ڟk\,[lX2!Q1M;Uү<&ScktY3Pi)rJ,8zh֎}4\;0is:ƎbsZJjda[ (RbU q) 7ʙ/`N[kHcSv߬",V|‘Z5[=g>qwo xH+k!cؚ՞=nQI'Ȃ(,%OltxPfI1fjy.8F}&TrMڗ)q "paOWZ ӆ/:i%_ [LFk|K+b 2vtBaμ: byԎ Ƕv\*CKS/+ulE}j~]OnơUB[8WImcȜU 7H.Zm^xG*ǓYj$8jR@WT=ub0DDY-7qW ;}`?v!M&L&N 㔧Gy򠨘y\tDBb-=C"55tKK!UT9> stream x}]sfq^v]\TK{kUR,KqNE3f(:tsI)jmO݅9 ~q\?_]勿e*D9WS_GE9s݋u/C%L̾M˷/^4o.զzzws{{Wk(W/M'tjM~yB8O?ysyg[z*rzx~{w159EtOOC_qOtܺ8TtK ^_<֝>s.>ſ]|Fٝ]R؋waV^^^Hclӷ%({@^xS2҆.޿^VŷF?acgX4L[OߗϮ_qeAs܅`*2T9; =jɥT1Ō^Utl`PCJƜ;ݔvpAFo4d9G˥xNc M$s\6dF[QWms6~ps;t7p|#1ˊq, K_4]FB=ŨH|XiTcٸ9g{j7Қq)7H:>娭0ޘIQiTHp?hqBHV.GlTmAImz%]}d.oOjl3}+^n}ώd=6Er\ph*y{f5-2{Ϥ2)\fan/$EbǐP()BJ%#|h+Zipyӗ3њ4;.WhE2y CcCo(=<8HQۣzu 2V!lH9[WeyBU`쇪)LQZD7.*9Q_GCq|4! )ǐmͶuұl@@NG%H ,  ¬)_\t2RƏnI߷U&#DҨ&C"Y0䯆|ob(ý! NHoJ̲ko1O*0x d ~IMu g,4ZWGʽrdX!<}yL:pyŸvHXt&5H c'_¤C@5 0+q86EB)P&>14]0,@C"#My)X-LFd2Xo3D"ҲG&PG梾 'e\i:N'41тƓ$`?;+mFJXV() mz&gz`_INpN xh/CJ;, 8 ]U5`K{ҹ$:wNcD(- !z|˄b1-Rl6C3j3?R&'/@U[,-6J(˕FiGL&Ѡq<ɧ GQ:?*T8 gqn}S<)Xԉki2(ˈ,"S울982[ ?:ڥeo2fqn<rیFW*& `8ޓ@xRYH  Z?-bvlL+eYP3pFxDžkC'<1sS^.*0+ PaM 7Majf2^iBC쏰bWsR E9;[nfci]oq \=6^ҰUup:LPnB9F +5ի-`4q%"4}̢Sn,0\dI5F5V"Q}ױɅ]C([)1Ŭ/vaZ&C$p_$XI2F!Iސ&pjIW^`jk< .h".c %Hko8#޸@֋U\uFgi mw\֙dHSIĵhWhWy,t[bF*9^c+zۚ&&j Ý8  sjUF$9`3Q*@ped+튉Z$~YkϋZ m b*v-p)i %*dF&Zs1εq׽7ud3LGqi0q]^s!{K(vQ]6NbJԈ6E.vl^$orj쵸GVP 9Ĕ.9ʜl\K/tX=S F+B( D?im1 .< [է()q4;z5WK^WD=ԱpF`*T{r$s@×HGƣ.[0E˓Mf *XCl&,Om 9.O!JQ:f-:?MEQ"7&.zrD\u([NN']4?-*Qo=Ȯ?<OqQw긨ssO3/?"UG8ߘdݪtWY2O{S!:?"ք$BaUi--UxS)}ݙE}][ + sE^Bh"4Q7ԢG4F7-&00t]Te8cX-5hmY"Y ao+Bq8S}ۢT/"qHn{V&ߨiy.Z5ze@G1eg+ZpzM‹Em{іuBW'XmTꊸj\#װ>pL }kczbKCf9jڪLL\mU4^7dV[6  z-Ø>fB>ЍC#,$ wMMȇWYlV@: 7Rd"4s8leѩ1Z Y^V/6+8Z 8!›^Y(lYΙE.^@\^̻| !IcׄJE6n0 Vv,yaGQS> `r) =DJŮ OQ4\(Sٽ1Eju Ǣ@pP;\zԞb SRoSLm!yAHHL&[>*O!%. H)5T,JOZSk? G!q)l>$( ͨ>qVHH N&Ib 0]VӴ/.M-+JܬBA6+b&#F _Le*y!=2Q2 %y_no3Z iYfW>Å"Ĕ0s!@(V]ԞC5f7jZi 1FۗV8E!Hlr?55_hr2ceT7A%+*O=6b%)[m^Hi=<=͕/:^]^" QV_/:6 JbU{:SGfA\{|y]kK k ;fV HԴ nd+c,9?vfVخcŧ%7%+d'eck 1-0Zإ,F3Gᑅ&*>EMݐs0dʹ]iFAqՆXޱq5?*t;:*N .lYyFC&&.F8oEUWzpx Ҩ@02s5Z'͐uS6#F²uWi["Fpռ*>`jHQJ/70Cvo7U= q BIpJplŠT,j/0{|Fn4=h$DAG?Xdi$`4Eʲ͑"U{0b]}qUI/UE j.j/0C8c U-Fk~,jTI\ygJwZIߧ@q% U9PªԣR>l"#W{BGETq 0%mQx1R Zծ p: JƐR}Uw r3RYueED!'I|::G ǧ!:YRUjr_92Ȯ|Ӡ MܹQLW('CwkP4!D:Wh.~mͅ(ԯP6Blejkh8s:EseL߸Q{?Asm=Wh. inS48k(Jk&Lmmͅ=nnN&6K9k .RI&EsGqu.Wh.@4qu) sukhAw@~mE2g~mŅبkP4睷S4W(N\a;Ġh.866kF).6;׊%.|WŠiqG4x /ȟL/B3UZqK^x?嚎W _?߮B̼y'9U8s}|7y߸>:_WXZ;DD_fiCpZVt˾xzJp7_?ۛ[̈·$= W7Xg8{G_IJd:Xq>yQΕ$j2/0VW Z_?v+YڱQӌs~pX6 mԧe~3(("S3 P}y>EQLI[,3)D-/'y/Oq\' = =7HpBINy>(sYt'&+,gа Kj(J$Dm S GtG &<(-`7FZ ' otLr|(J)F޹JAi6BE&et #E( 8 Jx"-3,ޔ{3bdݒ@k ĕ<ʙ&7D,Tni"N'-x>784Q ȧc0^Hj)L4sOq;/ )Jdn6gycZ,\; !CڒS G:q=\XZQw] s;YU"LK2|$SPh!4YG|N,p.˫E pBOqvKN^("9s!]ѿĥILI<{+)d4-BM}лPǬS,䓘 )Cc[ޏB[(Y9"K8K  "+( u٢ :m߸c-EW9̄PhcH ߧ'εS$ )Y(L8'ɻH;ăU}<3 LH7C%$F%9v}MBa( 7Ylz4YTJAJP8텃aQ(Emr>}hV%8CN O!$dWQ 59-;(D!yv#F1q }6S[|q) QB؜:GtDdLX`PXg688t |d,1~J&8xo0H; }vHX-Op ;NuU,klɌߨB`Icki=A,n2[Ft'vAQx:-?N6/SE=D7[WFI\ Ͽ"z?'$v0 H1rتDVyU >RTu[^BAe}ƓԄn/Ae݉^-<`K!-SH N"5V(I4Ѿ fm WeG^0#SsVVKCYhhS;lK(z"f$blef>3+tq!2g 69[5 각# H$҅-l$TP˚Dyds+ `GM`'86f"Պ){AkoCx1VUƸ&[!ݬ}+A8f#R:^a " E@q]+5`%˹{D FYvK9 JI]bqqe+coR *Aa%pV=rehC΍eJ0B|i^pKH4+w|'Fݬ6OHbHq=rKYӰUy(7Q/}4v9cjSSɢ̊KL(8D40Xyd/JZ\d;Ug tbN^`GGYyg$>QZA|x87I("쾊; zKWy7)*_UD٫p)"츂QZƈncZ (i\Q6V|G RQ69Q(M[d%BZ9ΟXaĖallc>+ȅ%La1:d@qԄyݜOdϠD+EDT`)^lƔ>EP"^ڑN)I) ѐ!-HdYVb{jDBA: UܽFҽB-6DYE>$?ҖgO@jYv\-L^r.7񯩈WA!|w&ؔ ;e ϊX'}W&&lM@$E@̼S6_'ƷFN]%\7ob`L0n/.W2%D pw8qE|`ҿ$:P(Rɠ'"A`ɢP0P[W%cU ֔fbwW{{4\nj+7ǭze o !p,ƴuM*RAC^ z.6 [^D~&+Zk\cbGJC}eBp?DQ HoJ)yi1^mpn&赈 8guG9rT:`Cpby0EcKܰG&51i^KX9$ +~f |FE* dP.j8Gނp#{!rJ(gÂ/(%s/-gFn}30zzxwyrJ_^7cOv0n=_7B)oo'U|5'ݥ-X\^qtM<Nr?rJ%qx= M7Gck]c3N7_^saJZ%ѧ'PZrU򮚩yx%8?xNW?=<|G GPc \D#? ~yR ϠAߵ7KÄy]L45;R}|4X#Qo~>x B` v9{/hl1ANO7wN\~ ;__i_"ӎ&*aӷ+|i>|i}yG9M~wW {t/h }?M.㊝ΏO Dz?#W_|hzlow '`WW䘑y|ͻj Z 5ƍz9m_?_Mz3޽훼}-ExóƏ>r%Y *~Zr~d:I\7Ǭ1Tlo>V XX/7m n|&>hP$üX!&,lwOM.t Rg_)2 VCbˇJc[1>Jg0k01εjce^nԿګiI^Y|Vb{㶗 k`836~\iCo58O"]yIG7Sr9Ap&|#ڝpzzL,+x5U[o׏b5#\\q¾g0XrBAσ8nez2 % .Hq=vaZ(~ ,AMB0{H,4*_:lkWEȻmLi7 5A+@h^l =J@@<?SA? "O$p?ov@o3Q7a%x3iym+$ų!45 4 ܤH~UaPG6`y(f<^|,U`:ڟ s@QUw'”QB ;hk}8:Cww=<~5{!81vT@WՀɟXm )#6#e6"mv[}>Y^9N7 @ >gNcO/F^;71ɊUk#DK{+X]|Jg)sM A|׿)\x΄|.xnuGR^|r󧆦owNCLy{{x)/ ћsR B#0&su|zZI$<_N;}=a!X'G/"yR>?ڝ{yGp36*3 $TMwꪵCڧɰ{ۧcq ̙q5I;9Og nP%-p-:}h3gSpp%$ߧr[עt}un"mjsYlyU .w{CD'!/Lv86Mٲ@/m Q6| G:8]$A,Gelt{#B/%nbú~rt?]>b8/t~Ɂ{@`YM4F*iƧaK6'w_+yk+$=fKfeRFC=ȹ~h9&0q{$SKX[tZ :c/5o/[s:h/O<9}p6C].z.97ҹ??kgb$_'N*Grl.)K|Wch=珏l] A傽dޏDܛᅂ͛"j6f35_ȴ A+~s-L$ xpYp^Wb={Tuƾug|uw8/V_N:9%Sꢴ@x\EGo=LJYgc9ޜgUYV;;Y|qP&u sƳ.PY9NαМqډo%K_~*aC/9[DС(hՍNmŭxo.z vӯ/WZ {Qq+ȹ\VNܴ߉{ wΝAf*Wrmf%) 0KqsO@1~Է;,x& 4G/uȱ>G۔9\)K  b NHwSVh{7q״~إ*n?]oC6@Np'KNe~5{8x/ M{*;w~ʹ%==T0NSzUHϖz* }ɯTՌ-˚Ժi~M29"B^؊oz3U;$iK cЮ@F{9eqT4|}Y:C3՜?gM;dcV+nGřz>`-*.0n}QPi!$Ѹ' ^n "GefVM'klM{;ubwzŬ/u?y ~%>P`,ʛ便뇵J?T V}o?#ÜwTt0:3P3Kd+w;ڰ%-endstream endobj 617 0 obj << /Filter /FlateDecode /Length 5391 >> stream x\[oGv޼2yu 0 't:b/dks}h9=L?=9TUwUu5%A`}RalI9ەr_mӲׅ5(SB'/o^oэVz#ūA Úvf:sZ+/kߩI5ۺLWoZhX SbzMKRYm0ٺ!I. W7۹fk Gm|TBq<󫓊N6RFj_T_ٌԢV:V視%a_u.kf~TU|U}S^Cԧ: Хm+YD0ckm l;C2gT ٭.jwfw(nb7Z\fD.k##^%RQ)'֪"k;5v$l!%Z #]_)eyD%ЌZuCT#©q@$zJAx9M#Ičz~oJN xT*mJ : 4)gE0~QDΚE#l#93-3XD#4K;Ќ"QX][BO\΄2lmv eؒ5Z'{1Z!aTk%*Mfz|RbXD֩BD2e hT o&_Lޑk{FԒ˅DyJv!@l*N<\$KPU,b2V5<_ gt2&L&ѱM2 kWŁzbqikk 66[3 ]8>0Q.⌹%m5㸍"'BfF&#5ѻy{%T&&*oO u;)z!G2621vR*E1U_VM 7G>WW]\ WI`έQ,ꕣzd~af: pY[Rm`m!D\IO3z% {ڃӕ0Xڷyp"m 9* Y1瀚Ziǯ]!>vT\ZRD}/az\I߄O2dgL9'T:)( $$~$xۻ͚rib~MdCYLh-Y wjY:ky8Q&_,0cx4Ckl ߋL,%Na|[yY9V/zM>CF˭% IX|Q)V.D[7fro g2 mF} #Q dOU,Bmmm9C~pHUàr_ʀSu/P1mm1X҇-~b"*8߹8"11Fu`)wXikڏDzIu^fw']r"͗sk ԱX^i\?G'Ym5C)Gq KXJ`r ry ^UIh#7Bj1v#ưXb\4!ERLP 2Ͱɳ`'nDm36Í,UL64(:'?G;rͅh:]L"}hjG]sS\MEQql~ d7Gލ΅9GUUf:&UK;'B"Yju#b(~%}vܴccbїX)A'=_nxS.O$\'Y*bD5K}LM[ yM4n1DjӱrXm?CNw}?b%;>-;1{#r| ie#tRK8CDB&[Q*nVQi>_>y1x:?FwO[)&SӘt0dh/fRvޕʶ6d'tp,ZG0>F8vS2nY3:3a4&8S2AFhۘ$8hZ 4X% *#sK*`sAW͡)Bur}N;T eZÆޓ> stream xcd`ab`dd M̳uIf!Cnn }_1<%9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5P\d$2000]2;N2n]{Vջ8} Ņ7\{o^[ߡ~|_rMVV*J KtI76vې3@ٹݛz3v惹'v?>aץO;Mhvp%kG^}I&;_Ӿϝ:m?w>n9.|nM}=}'89 &Θ?դendstream endobj 619 0 obj << /Filter /FlateDecode /Length 13223 >> stream x}ݏeqyJ^be@ssۉ D"˰G$b!.5MysWTGӧ779l/m7_?ͳЛ/_gW<n><nBM+|~o>|y.' og4ˑZ2ϟRۙHQͱа4nr>OV#+U9+9}Z31bscBg+sNk5r06ώEL㐋JˊT ˠ(R*qNQh\VC8h$ԉlja7tׄ!kUNu9<"aҁȒ:~š͡C&Bgj1`Wr.zu:ICm}J^XלEsJx|5g%zE:A" zPmW} δW1ӱZHДlo:VXk,kh1@sևh6Tϵo$. +:'c֤HMKO, mm -p"&[X$"ҷтg֢'"mI8$msݑj)Gz$kCZla &B?ISDIzRHU\_Ցj &@-UW"^^Fx+ULĐC_Hvv tDA"HfG3[ՠ4~cN˱mUi皯= ΞĭYH$ l˹;\Ju:wJ5{&RkTOeAO]0HfG5kwJEzC !FLRX#:-3D4i"3My =hpxX+ dTyAFGbxzb,Cmf=NaفEUL{5 'He$nrXjܼo f# ʳU:hOXz^dw7%F}aw2FX$\"~mIJT/< z?2{cIML*vfѱHnEEC;/4;O΋3Ԁkq4x}]r4+mMNB7YOάE]?dnt>HZ."gG@R.![|a%vX E׳XejkEKk7c/\&)p(>ԅLhu k`'$A6u8B7PgI%]@Rz2|Y{=h=/YkMM6C|\Lի؍D%]w׎S,n̄&<b&9C=L2`>Zf28TeIXX±T'=Hz!ZbU׹ @zFyxO2\s:;jH)9fA"s/Bh$Z=y;P5\EpH]$rC0{hBrlgTgE8ANA /leK:2yT7J^5!LNOxG2 Bžsg̉wAR9jŇx14) bLdX;ZǯXK+6(1ǯ'p nLR7݈̩W!"s+]IP[A_qXz l1c5t+$u YPM&CXJRKY,5n{c ]jVVߝX;rXdmt5\SIzQ5QK721UWmD˦6u%߉dSIi%]; v Z6Ĩal" wiZ+ ag/l[1 1aBƾudǹhiq 5,nFɉ@ 24d 3r`#eZQ9 z軤K݋`V#HzY5iYIfxL~G[ Nս8H88x;pClWq Iͽ,d/ɨDWh lqjgF,p*N@$/v;'=T qA6eUJFX EPh_o$ŶFP >2'9in@dfK.зDP 1ƅ k\DPTd}c^f6Ca @$Z]M&˺+҆U`Pz|YP@HIW} ,['mNbyD$rYc,3PCi#HUWD[=5œ\gO @K< ^~7[K^#@ h3Xw1ϥ@"BjΕb̵CjbWDq enUWCX uV`' OS@&׈jVq| H(ޑ!=bxhJSb(H7a cz")~ Hd7^n1yN*F0Xs2d-5"]/9KÁw$0N`j$E2x.F8*jX} (l֔IB{q8U~ `ٮ@RשjBPSE7=rҖJlC%I;@Ey3 oe3 81wb`;rC u𞋁L 9 z6uBa6NDRz+KشH9x.F ê9.FFҨKt]:L;qSHQ%~)J1q cNG^ÕoaUu[ %^ V ^} a/?[6V+}B֍v8NFEx"XWG!θ5G5Yu dAjXSD"z+S|Ikc␾rLQc$xvj亹^ d6ԎdC}jB a* '"ޮXիmGz0rTZ1*I\GfѐM$r RuZ81tTFH&/RTSJ JծޔPX p(pW*y=7IvJPHl *^(5f-[ҺÆ**::-SZ YMCrk5 'ֳYE-pTPPtDy!$դl(vzV5gC^P$MB (aU/1_%k4*Љ= Izfj9iZMub(8^Uv:+I6,Arq1N8Ը`8dgǽ;2 '$w%ߖjho$3R3Ä5:28،y%δl1opJq:!P y3Z25~Fڌ՟q`K27H1Kn:zʛg{ ?oFCF;6CA=OxvAQn a5ӨKD8q> B^*s٫u5Z6FXíu& 9'N;<K`/S ?=VR(C'{7 QGS!(zbEw^o9C v?:ԽK;t R,>JZ? %3Qe;b ƶb@hX3Fb%db`Ubz.EQe_w -[íYX I, 1X8dX|H;b-X;bu9 jvq|X *+bEpB "o< {bqX?\V帔bŪrJ`54X;D"D^]XIbj#b`PdWH!Rb X&i,T-_! C,#ƂC,O,: kH! QWa Xy,x@,-ete4X;bm XH#.x@ gܖo<  ɳeBb53X;`!sX,_YX,.: mX+- B4{YbTbTbyqb%idv*bե`N{? @,V&b I?X e+b!bXB,֐! İXbX*% X08h~X,|[Xw .X;`!~X+X_! BbbZ X/88b8# u@,ֻ$U˪bz;/ ,;_!+mW XMk,e kj*b XQC,hRzkqr]XX,t-X&p%ԂC ucbR[XX2},Nj.-bXB,Vbs[j*b|X,.]X,o< +dbXB,.x@,e+`6 Xp"q^~wl_~F/+l-ۻB-W22fAKlBX5.V`!}KY YŎ5! "e[$B@A*(GFKRp0@z L{7N>Ü;7Gs/*grtFeWJX_+}`weVIta"Ǜ|ݸ j9sWdI mHqK m 2$\\j NSEH35$rglYT T(]!;ӆÜbă+!VpED MIjL8W4V D$h<+mbq@GK5|◣7O03 ] 8i' (2NQp$P]qa'T0B&U+b@D3nEBqk5Cd}68EoM\=|+ &#&5pG𻂴= G)OI܈!򮖍3 }*כFA6at!XѨLV#)Ō|<Xd㞸1$oY̌itYɢ(/%Ȩ|8Y'sHE7q-)Xg>`¬)1'uvgHeVBuy(sCmE44(O肃R'$B"[!Bp~"8<24~.At󞒩AZYV!T6!iט{ƠčψV; 0pD6 Rѽgu**!S GigFyAEW,؈0 ":8}Mz=l69b扪2'vj a7 HcQEk}[zpb]Za_1gv;7UaHj YT:F0vfXu! vz%%q )nfʫ&i{LlX3b?yf- Xŕ )aqqLVvAܦJ8U*l+Dފ.àvUstIUwxPyU9k6 P}&HLxe/=c4D`@!ML8a8gN~g`ɄqE4}5{UZ Ҋ(G!S8nj! L&sp%MXy%3"ounjyEj +z8pY`"NiorI-Oͤ"۳BB *VZ[d1#XO5>qtƽb6qHy˼Vy+br)+ڎ@Ð *7" D)"Q/#  7\Y2Ua8gu2mq!{(᫓+pC!;|%8SMF\38ʕ }h$k&P+jև0^A6q `)Wnz@ EGҵiIHKb!6 ,dAVWuE̔!֕go41)SXT!U+7!:.`!K"!(UBHu\B&J{ GMC Es6rhEMDpe')\ I߇A&o:'dIWtUܽ=>$&43X ]Ztʴip,b*))p`pPH>W%tpf@8| qq F֛jma`=d1gZ n6G".|HRI.-jجuƫ{pvwe)c068#4i:  J4؊IƉUu I*a8h^dj=ऍ[ dm7L3$g ^=~kR6&I48dL&l$G3Ob8J'Jn6g7/&npJmK2* @P7ypBezbx&G yHJ68^@ [1Bf9[)ЮqADeS뷰@BVCĵ0 A%`m<*d+M{Yrt-hS75h2'i uqޮc6ʘbiV@UXh9bAںBɜL'k*.W\8? @X% +)9I s0mbf{;kuW.GF30@6,ee`8YXXi6Yg=c-,l!3$a a mZ/u270` H._w.:3xT1&s𥆕d0)9/( t s og.SbLT1jk*#ݛAy0TFwSڱfG;#Z盢 1Ldo$,RXxm:ܿ$#mMv4Aɝbmbza`2J:J4uoD!q %٫ld/ZNY=Ʊg"Gd9݆ȗs8obgddkd0!Ud:YAk~l73As8Ts$ڦ!c3\vbl $W3}m>힁zf_!n߮2-,|FeK={46ES{5#2`Q ezC=K14&ϼQ8:@5&\%2΍9}AZg] 10Xǹah#v>&mb*-m,.KAuI X`efrLr&o /CHQ,*RĊ(+ $BT7N܋;fw?Oo_~-o`>!|v9~{x/xxy ~DŽ w1}x~7kK,2ah%_=8==%k c?"5Nw`~ho혯C";ztN¿XO0@%aMK?=¶)d;|C=}iqF盉o̸o?wI o;HRNo ſd $|c;=+9ni .,c@!=?|Ƶ;N~Nz;)s3A w{;)ea_?721 Uekys:X2N_2L2612}Fbb!b\;>0x ߡ|ۻB,pFoC63Z~=ϴeKq?Η W]/)F\W;Ayg8}ŋW?x{_=ݿ|Ĩv>}GDoQN? AW7/y3/Go޿}8 ??\ ۇ/^c G>zݭWOQt7/^ӋuFFBxS>X"y}|uUGQ DBJOa:/OUئ A=f v7*PWDJ!6`.Pp}9J"Box}V %#[ !=J.wD8\!{/!ȍ]j;sM3C%J0Y;1ÂiY61$`~i"?qqzZ3ß22,~cr'xW:h35FwI^}˻%u-PJoGL% kwFn %^(?$OLNE7mΗS1 ~Z .{H'Οkz)ר:_wJu"~ET0(wZ|c%&D#JWF溾i?F;wB e 8ׂ;քs>7f\i؅QIx̨_Cɖx3@OSU_)5\wHc_*9d+QҒJ$>Wk]ε> T3HdY@vpx1)yafE]i;~`+Ļ \PEAn`SLՔNp}"{!*BjU/Vr^ëk\5Q!{Lwc  !ӊm!qzw~)gw8܏߱8 nAA]#/^PAq1%gԖ BHKs;NZqMDEN*$qy 6TȀ4C6:mOI}Uh},kc[% v̿y'SjT觿DNJApI,dq#Hdzy(" ;vmdҿ;sD,*"nώ~m 񘥬&?Oꅻ%¥ɥ6Ů8AdVŘViÑU[Ge|s!izoAZK>`o&+MwL]Vj՜h/z>zz|wsܯ=bS -e( Ϡzo+3 Ц*'Gp;6 K¼1?Y2#FKB~anmzM2LwZZWaҷx /s pɞ- 1ʛʘ6|8ݗ UWps _R/rGXПx`>3Ѩ;G_P~cr~xǣ ğm`4- ߼YBm-WKot[v 4 ;6Hl&pHO"+=eذ7Wʣ?=J7"׼xj wvCY7E4b6r|eXGK|r}ٛ9%e9й)ԯEض,G<} |:Nnf/$endstream endobj 620 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 520 >> stream xcd`ab`ddH)K-LN4~H3a!]ct< <<,~l-={3#SFhPs~AeQfzFBRTF%83=OA (K/M+M*-VN+Fh$(C#SA!a1VX"2Z|_@ɕo2n{}SzvEzhwqwZw~oP2\ހ,vi{]o^ }cL3@5e*9ف z8|S}DpM9zK;jŇ7%n m푝[o/ھsفnm"}Ck%76n~hKH?LlaXmٳvnWǼT|b6.7f85A99+]뻂2uI˿G~WǂY߃gdfϽ< 0!endstream endobj 621 0 obj << /Filter /FlateDecode /Length 4973 >> stream x\Kq}}q9).lFhJIf[aGL'=U]U5jەH$޵|r̡Y$2M- K/7g3Aofo7uhXߜ.bWe盳J6^׍Q]lMv nno0A{_]/xHږ !Jk]7~~03%B^xݮ=tJ)Yc+T:N]A[YuŔ9mpq ͕vrRƵ]eY},lykSmoҳ2]i/Itv\[U!9 =kO^Sn?$|-[6!M'H޿gI.wPeXi-9Y4nq|iEw$g?ze (.@J%H 6޻^ {~; r}RFW8m)3|mW=!=NJD7F^'_o6\S+'#4CSѤ8(ìD{tZqh5ƟR[uUM^3%zy&P U9)"K 6g?s/ؾ*R_npAGqbz:_Ymj;jZ 9|ȶg].E#2V[,gos>;&N@r)vQ&dDc3d']>|VvVDŽ/mUrnN ȁz$-("ݢThcQq (A/CBUM &LCB3CbyAQ(26'Y)\zOʽ=fYn0D \6 cPG6sS` 'x6 Ҧe"le(',H'M!13Jl~$ih؎FB s69ƆoʟJ97&‡1h{?楸XMa+4t&=ⴠSy?`-t/SN0ȹ[=LpYn[in\:lSof[Oy شe@D Ki`gv)L24\1* kS&Z[2~T.Iٌ5Շu td'J8t#f6#CE\kTq\b`xtMlibK?=[-_y;P:, M~2?o ,fwQ:8pȆ'B kO#9$,7+vO`"t}]Q)}ЎuGg'=f簵ko#MDW7Hvxl 8 tlvR٦=3cKm4{?A2q;&*=WRd$lqyZztV A1 d I!"Gd08h$0M_Jѐ~&v6lHMsg:>:,0;poݦ_ qF|~!ϸ@F"$la:v>&KDrO.5yilLq}_:qNϟEI)/DZa&ˑcH%A8/J"dbCّ9~( A(G.Qv^M ei1TؤTݯw \Zݡg0"#Ca,Naĝ#1` G QesG7TC5ivEEP9*b>;.G%Z eO"b$u+xP!/ ͐$tމo[jB!ib 濮/CWׁbB3|qիy{u\Ψm9M=D# %l˩ݶ~Q]B_=~2IAYx ķw 1E%,dӡ.OH@@WzSU]Sx'&ӟy&7oɋaɮsn7m}m>ہ⛿vi71f7C篾Htj}udJWxr]tڷ/cE`u}U_ݼxxIZcD-J}8r(zIHzi˄mqMA"Kt4 0#iPng83'2=5g*tO<gׇe;;ta|"eƨ"176 Ơ ĮG/|XxbOwMvR-`!xI0 B^,j}c0~lk0v2!tSWL=-Κ7g@Z˅nT͙ȿ>PXp *9GgҚ|F:.ߥ&?y4Os&v:>C=q5n`x1ְh;* *ooںHnRYF-V~(K(0Ui߁_mXݐǠЁ?-S@tbh76a&x(qlj߸Xm12%v`Nd o?'*d~ }-V>A%6߷rR+B?vǃ rA> stream xZKo670޸"E1 E 3,vrQ,z$yfyDRj{2VKb_~G|mNNwW߶Y}{qy w".D/+(ϊUH9dכ8X ޭ7ID$qʺiLLy^ufQ{k[)wkG){p7%P W@1ߑH*ybf[Pz+j+M¾KVkT~*]U%Iq 9a/~.=}nMPBas4׾nZ;Z2͆*)B`~藬!sa9r"-r}t_ޤ!aJJxKb!Ie47ױ l\xK%~, sHèȷ*K %+{o( hcoʥVL&gV`k1xqҪ5ix 9"]W -ĭcZQX*ɺG[V9RYҥ!NO1U6İ,^g/ ~#FRe~˷˄"J+ ڪ]1Sy;D22IRChiA]($r0 w(lr`~Y"dd^CJ?_xa~a<7*Aq(Pv+!8P<5!H-r%SUPX|o/ߗmuыpsk5uj}6!<ͫuv7eH\у=OOin;}YE? (cZS=-+%\z8e}v *aqԮ~(Dhx{佳GU+wvnq%=߲ʛ| GFEO ۦ*7v뷯>~1}[@+Aff,4m*% ɩ}2c=&(T4$GywpA"p˜:]ypZNSα .Jﶛ0*GD]]ϐ6IDx+bgH.L2y2h,;L"5uN& `%ܞI [OӥTIYX`EBvA$bz٪O?loCLЭ:NgS2kY50߿Zh'Z'|o^M|@+VN%~QSd<{g%7ɑnXw}uNި椙Y]u=s3ՈS"ᐈP<-7NL&ӄLŎk_목ܤ]RAg;<+PCk,Rfꔏ́6]au횠gy60][,S )unyJwx=p!@)آoqAo7q-  !+paq-ڟMqv gܙ%)CX 5{'%nYT4 Pl{C1ؕoF2IhI&)g$?%lCŇ#~ 'wNj>݃3O 1yZ֫PEm5:z2&~L'PM3mغOhlw8]؇ L{"G6 <}adF$9Vo iJa0'ϝH:+iC 2f兝տ[<(qr0oU8эP`[>?$=T*2j7v<8k|5jςU)WA;v BmHOCp&莚*9>)!cK!V\Q(kG mƪ.a58YOR F58B%xRDRIT)K$iX,/ 4DErx9HzkIˉWȤ \ޘ !9=5ztx?uHF~2l$)L /Q6%;7[E}xݗ[x.E"]?L܁)wq &QA)8B/ UAO0WpBn+*qL`N96@ ^z΋ Mmէ1z*NxDcuq}{Yy#=bA;hiN1G WO陸 45endstream endobj 623 0 obj << /Filter /FlateDecode /Length 10999 >> stream x}KsdGv޾ZIG 4DMca1d(d#0{ ]#Tpϗi ATWyqPG} uХb˗/~UHr*닗o^l?I_D._ `[/><~Tʇ. }C>ܞw\^.^}sȹv+Q){o. YM-%B:<<\?_^Ykهk|xx~t?5S7}R{ 9nC<|o/_OZQ o?zwl|˲eD14ף. BDmP ho79cQǣKs61 h34[BړD$Ahړh<0kO*j m-=%"31ƥ@9.=`DOd #;1cx:e׈!h^$o'F;n!/+?w]M&V#R ~@ /тhD\nH*ll2GOHz&N4#3fZ ~b`6&.-Q~췃Au?[hiƙp4M$hn4/OGіӈ'm;OL$B'ڽ$[Og7[8=c C)^{VҘ,M6ABrH`< ɉ,m6zQR{}.jX ሸ \㢖H+6Ht7y$[OlvD{]iT`m"pX$" RY]}<:aAItBr \;"JX: r#3dB<!y&d-E59"tcFRVN:5K̜td®45$BgϜ49:Hz]!.U1, ֱ#ʱvC5PH+2R:gA8b)^` "z]'ёLivz&Gz<"z^!ب#fHOӞ)BeYFҘN:!$;1 Y#G GH X })ZU [>2 ynJ"#ot˱I;Ch%ZGB;,e? qeĴ%'$A!4 ґog땃fb ~aZfV4TtBjpXIhG wL+ 8=$ *iDŽ@@qZT iOiUYbqՆ$HxHѢX'Z[K$6 K:bXl b",a>aei/[@!r J[ZefB1_@Nr o@J!W+ Dt@{n$b.bn%,cFC'Q8yc~5 "G$it&f'`=V6 6.Uw~rB4_~B]TyBmлKD`|-IJcPңH ;TmPVn)nx"(";SNqK"Ct6t Sz AGwTmP~;P۝x/ Q\^>hkߩ-d%h)(z(jˀkP{ˀjoQu Տ'.!J)4aWH-kHl%}0ƧG[,``XݮG }^8RWqU.?G{hF z: b'&P#!n#\gyErbWj=E." $\$w +E,dz_O{iCՐ JСh ' _^PnȠ<9"vM|ivW?D!!K j8?DqJm+tlژ=Xg z輴ܡ%Lz~ZJ_Sk9|&V6 ` $Sv"ФZgdž/0GgJ:d<"ґU#'?1lm5&I0ڎ66 ݝIs_5,-ŝ83Z#3IMC -8S5;Vj&J,i]ngTӏ94:lQQ(GǔB>>MTh }~ \=%:X5'٣QlCx:qO?g# ViƺA.Hv9md. SC#C;H-ﶾֳ 4^81j:ġjZ9 W2C|? :2aȶ+?{ 7yIv/c])8HY2Nq}RUc)7((7d iK68f33F #"rdG CkAp*6v"h8~v %1 !(,G,!1Kj$QR yj]s~ݔ7# Dw(KW"ߒי-K-ﶾֳK?-[_c+[-f^hhjoI>DvٺG TV 2@iF1}`EzGLxXu`kl50qdYG֑$+7˴?4#j[;b1jFJ1zّ ,Ǡv⼗cF_>I188'BA3F.Kƃ7!u 6qOp;S4DjZhi:l_-yTqVP hݷSc^DQ[c!<Ƽ$wϣUL{t(KmE9DZK"Oe KQңhuPCY=6:jqKoPC9={CwOziA&>j`tQ1䵃#^^*Ż*wMlO w gw}2 YO."s`.9.Zg]HO x%9~*>Ȇo/@S5N1M TTYl}G5f7q1#KX0t]`LUY) {*j:)Gbޒꗞr d~*5l\&A*_ȊOw䧯ZQagcK vˈr,͘:slVZ0߲=pl| $~}]GLxץ&ݩqƁH"? as ~EW;"fq+R#rJL?/.qDŽ %O_8/-F8o6vlb+ͅbbt{wԲ?ph= ϜZVQKHVV.$1")lynfhxaOvJUH4^DC>`ȶJϷl9+¦lC(]1ѹ_%Ą+& Q6Y+&(%k}=G+-s]1=hDePIQAC' m. 2cjCk˻/?'oy \8O--v>@^H07igk7ޒ 5GkYiɀimL37Gk5v6v1t_ͪ N LqbI`O,xqDҎ 5FXFw }: 5QN's/rX+q}lm5S`MdߎstxkݶUnd9AŽTYy#n+C ecK!1s3L=]Аxf.PP:- 6fٶ743(A/Dq#l.#PBL fVa{ ?Y?pȉ* ?Lu>ұ}((yaP8GDvf#$=A#3q&Z&]t@QeӔ ґCh y8CP&XXFLQ=0RZۓ&ȎVۑqL[В{On+Crd/bqJHmRc܂a3K6I !]J= .c)nJYIco!,A.Ti;U9(- E}GrGՖI }qK-oGTmP;}mQ'7q] )h %>He (yRCHaE ŠP!PaEqQ}pkC}J ~h,DffTcP+=^(6B]U??XhsJ(9bBE-dA ;SٲIc% @gk6 I, z@A* Rhe s޴$ clhQ@0 @ JoY/]IjXL{,H*^%;_;im]-do^k㍏]G֏3s5m+Iչ<-NoE"nY<0]Tv, R!^0T9miB0* {$=Ҽ-tvxiϾ#'Ym7Tq*ϑ=lZ\Y9&+J b^Mh.*!n8,)Z!WkM;pX:uLVBAyHF;qڮK}D:A]uHBpp}? +dyfv.c*PF7j;A9kת\BH th..Y gU-$ϐw]aFaf 6?v^78#ޒC3ST>5c6%!J.=/ drѶE.Q ңPBYҡ^GDnPGᖆ"M#ңpң-jڵ~?)؃7D(?5î҇K$j=``8è.3>%؃|Xg|$֓6e0^ sp'rGgc=#_] s}Hzj!<  M#Cl5lB٫+tVo;OJ0:re4jQ-XFxOj:ٝ/⼴ܡeuI-ﶾ9(LBY>ۖ&݉X"38[] ʒ)v-ܞ@" ;jj'RNP(tynCt_jmy4ߠ]E$*L ~ y.5HU.JKOCRP:^o6AdMw)aaث7Cn i̡vqFm\+P/q4ܪa.oԡR0.С޶`l%CWPq[0_WЧ(HC6l?vJLPVϏCK8FN Ǩb% \pJAs$nBIU{L xy`!=EnBguA0ڐ('nrD,B=׺!q$\£B%.,Dr9ysO}ŭu"?bbV̿ m#*<';GvWd,u2^-zJR@^,2:=6oR+=FŰ%T?K>3Y`pt^}I3dUhWV_H/+ es7-ᐅ!\=:a,> k]?8MIAi.m΍|C򄃍gHHD]yݼ=CY|!*őv9oy#j)r:܁Lj~#p~!G_?/3"P *]2.hr)MAp/yp~~vc+x!\ 0卨Ɔ,rsK{PyQEQE#FqQ]Q9bT9P9rSA3n$Z](_qƜ~PY96կi8hpn__\?>EI㭓fi¿p'"n򏧷.QL׆ʖwۃ6 9۩M:<+ K-÷}O6pDŻI6Nl>Ew'|p~D_D\,B{V~=;?i4FL٩\CNǧ~6Ӹ:liu\Y4K+ \?˓RwT 5hzjR/_!/<p!8M!EG*w J: =:MT-Yv(2u0M7K$HN2L\9+ʔadXPU\~Ǟ @}:D9ūDt$oXPvoΒ.)[[Mr8<28~F~Ld%g9?\osC+ī$9RPa>uW;"Uoo}QFGRo )ҧ?/^Xߴ=~_oNqh?/>a</S.H_AqXecm8 I[k}LmN<\?@dQWonvt~:A5?];YOnkt|fyvM}m??}wg! mіO푵_Wmp[E:w?}U_ h1N6(6۟WYfRק~ksK%YN o5>]sAHXAΛ:HU?R兢{t/'Qw[܀㟭̡uÒБDw֌@:?T 9V"(Ԝ0~t`U[xM==~B xqV0LZJ4V߾ys9ݾzMdȖYywOo4endstream endobj 624 0 obj << /Filter /FlateDecode /Length 6617 >> stream x]]$u}< l5*~i$F,6$Vp=f{gnάzzWV\~y/ީ2X,X%y.Yropyw^~_* Ho3^x}LK=^Nr /EՋY B$.^v~_1tT=ڽFhmyZaRF3յ۫k%|[HZpwWלHսr8"Mݑ79.vȱB/]fJbT8]bOPBLSC|3?A2(ta{0}K3y1pq#t᪇/#RCc&Gثd+9*x?bU$[ Oz F!|2Q!AdC/T aS@n XFArc38*1mITleLfck37ZM>*OdefdRg.{k~TwXA`4|=!3Fd ah W9@Y:я22 M/D15D K 54&kd4Jk=Y~ܫ R!&OQy#"ɳ"&'pba{2F^C =xFPxr`k#L= t0mzYYPv&0( fk0&(WǤ 0.`b.V(R[%Ӌ.Kv(lW଀JQ>MN(l'*(l(PUSZ"*]ԮS$t¶f:+$8+`[5|(lZD3 ە2?:]W҆E¶jzvHtFa2c(lW6Yۧ@3 ۪ijT"퓳avM}ZV:m(lewDg+Cffl,2:]nFg+veQخt+SveQخL3 ەxpVveQخ3 ە K  ۪(F3 ۪ Q>q:+`[5WHHtFa[5 ' HtFa[5+, HtFa[3b଀mtͦD3 ە=ui H3 ۚie]D+3 UkWA%.*===eyyyݶݶj-ˏ݅߿(¦ _tFkx Ie|3Ag3KƉ*ƫlicRj86<v>FR;#Tbh`zU;6dbqpݳgN.Lh&d&`WĵHїrUAÌzN oK$HJ-\v &,LљcO)a?|719^,oB(׋ֲ22xXRf`4f~J`cd֌`֌`:q ǁ۾^BkP6:D#@Z4&R4&B4&R4&b4&b4&Ɨ~, F3Iz6a0"D͆)D+MvǛ"[Pf |3/%M>w{aG2rƉO n85R5AtY@\b% 97C#55 ܋ M jg!133 yF'ojd* =y򦆀T!qYC`P2 Ltg@H\Ne2=<}SC +!QYC 'RA 'QYA\>B BFeQ:-!HH75 qy e(; }i9pUjzJQ"vJHtFar$8+`rm%:]Qخ\(lW.Dg++3 '((lB)Qخ\J>y1+!nz yހ[@7 3\G苉|@͆c!'ՏAs1?*#kYG9֌`ӄ5#l$afȂ7A,X#+!qGd -@qR 7$VB00e֌`D #l,ᾢf1F̚IL#=D2"q5#>%\2Yhf)Feќbs>8fGIM%8fSW@Fz,#~_JfGeqLd ?fDf "MJb"flB8!5 tf^qBKWfq4fffiQDsBk&VB0kd3kF0K"Y0鎤Yf*9!0k0=C&!$=|Һ G39H]%*9!5z,#%aќb$fQ U V}CXMCXMCXMYmCXMCX C8MYmCXMCXMCXMX ڇڇڇpڇڇڇڇjڇ|>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}}}z(UM٪O:z4ifȜI ]?cCP)8#e5(Xib5?M|4q󧉓ϟ&N:Hib󧉅ΟXq٘< #iiho44@ ?ih=s48W^ZDZYDZZйzйziȠIqh~Р}{.G|ew}~@u{ę^o"wwܷW}tVk)* g [ lް믐p{BBuqx_bو  >Ub Q%.Gʻ@*&/e_]k澴^w~=D=r¨~h\9'Yxi.pAFhѻZ˲MKPoF isa{zjz8|" 04]^D&%+0k+D#nM+\ldh.'40=[J2ﯘ(gy]6W-/4tAԃ7VW~wv5JPOݷnxӒ4y5~7{/shp}{0GFwwlɺ1^?f'f^d4y}@,nrv}' vs@:n_3̮*aؿvvpn{||9~j|[}ѯ5-bta&'sN\jr%vemolη[7/ZPzuՓ'{Pėn@vfo[|]~oϿԂ 7W'$^q\K Z۽n\b m[ձ# 78 >S7s%J+ɷþ;x;#R(-w7{ =7~%7T.o>5hti_v7T zGlPq=:vNǪmnBAyD;[P^eobOv' J?kne(L/YոS) &.9eqcOF0叓@c3 ld꿛륫™@B ȧb#jDT} ە CT̂-!Jx}p }~S+Yc نVR\W~@5_,yZ-Y 5$așs\rk7 7hK44TD D6'!|R;HɢPHM H[߇ {GN2ݽ銿AIC &6G]DBg(vɦ/s.%Fo BRdBEڇP -}9#tH9F{?P+c 2)Kš wI錥 7HiE]Lh\:Օq]C\^ߗt_-C4sd~$p!rikY~a!`ݸ<ſT7] {L&L8$mD)q|lӱ 4cAT{D%wOf5ut,>(t푴;)"_G_4ۀ"4ah:?(>%aWD[Bendstream endobj 625 0 obj << /Filter /FlateDecode /Length 6274 >> stream x\KFr/bjP%B%2b lMP@#ٙYU@eUa<ꙏ/WM^5?QKWOW_=}Õ6z{۫NwQ%맿ýb˾n<]7w6_ [8Û>OlMk][cmh;T4zz'`dJ.5Էi·NJQ[mk_p]tՙ<#.YQ!!6sC⫹mWwj'u씑xz릣FףꅵanV£ZLieuq-dkb<?#>;Vo}S^ lwv:"Qš̥5Ο_E4 !LT1y2?zI'͝Кiu5)a?F'9 ^ZYkeg 'Mf腀֘v>v8fg@V'Jf7.=s_]}ycͦx_X:?繦=$QW=_)K 9f$<̯/I ~+ŷ04D9-txZ`n|mqp : #_:_N7j0<[MlP (Ә ehLxjcy[ӂ4K|~2KTH9C\t/W֝mE߶Xae Wߐ);%-@ok>y6>M^VxȰun>I۵0U'5雯.7Aݻ(IBԪ??YQ4`SCʂieZZm鬀nכV/#6#x/Uu˝M`}K/4bmS9R6F]EV;h:+t]O4]єVWV4=}#mt_H+@2 k~ie4:)ֵ:Lx!}&A~rD˚YW}:ҮcJ8k4 nnc98q^i=R=J~w h/ܸ7P$b>by"Ƙj XJ5DJWl$mޓC,+G 9u{K>(uABkw ߢZTrG p솼JΡ\86LHIi`&W7=W4-:Ht6}ip$|8UUGB8 J?ӶV/kQZ hڌ44}3. y{d[ hbEW.w#r;I$H˒D -ՀX 1"Doplnȍ5Og5[kjW;)ϋpL#lٽqע՞C2+Y(sؔLzI)oi`fCwI{*ejLW0Ֆ~&.N4q"Rϸx X+E AQ bϒAҁc<{!( R8gw'$Ĝa8?f[["ysӹ6`9w 4}_Xa|6>ae#Y}V]7NW$!1Qn} bـJ8x8v$׳ r#ԚE -C;l^AۨP`~~cRP41ǫvu6 lTm@]D,$tX@7vR kW)@EՁ".Huo\ |XSP-A5GKc8m!\đA9 >_r^I[ p1π q!.efrpvNȁ:GB;_|F4_ xo깼U7L !M0Kа:fpϏĜĸ%H+](,%XuOʿ^#t:i=LXe]4F@ Z8ԊKi @zX50!*Rox<:Qyb}CՐ:>bTl?:Az] gnP>%aHZV~)*"Xܼеi$9ijW*&kgM?Ζ9%&Ğȷ|4N٠Z?bB*ų=/u6]%MWL] DMb$M_GBv3CAbBB~ aqEzn)NjE*hqr$%(A;R>  J[f8/d4H0C ?vt`YP\z!$lnOK^D&ER+͚8yAq?RN8j7aCA6JE$(bO!/G9C̵-xV5wJK⁉ǰ?:#g\@ ʡk~ABbʴt3#K-JW9A?g!IWm "yMZaPIr LrC`c),Gl6:`x@ SgfK2M} b{Hwd f dn5-5 rrf BIUoT-=Uw-3 )jzљJKlչW2yLD#Q08jw\rP/e2=@XdKqZJ SxM!Ȋ'?jb쑩e#aِ*$Zqs߆T>GGXqAǝ{D.x#qJ`|_vA&\Pf#x %GM5Rסqx5KC\ŖSmHuθIQ*0,gO٣R 3(2ށ\ɷ舤tB#n ~ im2?#HSfxS]1=CGMfIaCSV!),l[M {]E.UrJwH)GwS2t*, [8S6Z!mAOo|5 bzё$T(-ق !(3Z#p< t`1*{2 &@RS7Yr kev{5hiTCO!, s}KT5 vtKE-!K 1,ڰ鶈 )[YZaZp.g{1Pid8YwKsYE K!P]TV|^[|bT [Cx69lPTӁVhX9(ĭ׹`[ _wTJ(|T֧Nw1YZ]Q)V 鮬|M)֬H#]1 ƒAt:}4.,*R3:yhI%WhFsX`soӈ!{ؐbu!7YWOaĴ;C"a$;t՝M}R>QpGC$.e˼:۔Q0g%~RuR6e`t!fw # *,7.<.8Wz4f Xe\6X$+::`!#-c6$쪯<0uIS2w0%"=B^I3BM,S#[3Ί*C:%a-FdEN>LXa^)z~|zf@=ۖ7r&`2aZAL*#uxu>3@J_~aEs[};N{6ۋn|ppQus3%yOV񖃛yTd^UF/kግ te%\T46%aʈC 3-fÜR7WY*Ei2$2O"a\8xh6\. R3}a/L;>ZAc<{N+x7L>$N4hR]\ G>:^(kZL ̑ȼ[0jꥅPC4M0+ԇa' ;iSNy^GYCem<3GP AIdqr0O{c1mfZ|.}þ3(GjfzFg!KOBNg 2ylKq1l,mA7]'mKH=!G:ӕws`um9c U~8 +J]n ssibY`y_}~.`RVl ~fyƗKpGG|,W endstream endobj 626 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3282 >> stream x Xg'2#(CV;jT[M -ʊ70"$H{-&@BUhEZTVwzZ[ϸ>B~u}Id2H$2`*VhΚER9$&;p/Iű'n2\H^UTG+eϙ#/m)cTZMLL]%J+܌PɶEDɕ2U,8"D6h ٲ5װFĩ՚Ĥd`k/xͷf̔z*"XMZb!|'x wbAL"&gBE@p$L/L5?'78~K[FeRgF:Z2eKjLĘ=cjXw{,n8hC@ F;$\-Q`eNBi:'%y8k#א[t$1(3(;Oſ|ugeW1|>;yZD~C̥`=>]yzw?H#2  a-[rrK >8 prv8Gbjy! uvmZ.ARn3k7$m`Βc~P~M[٧Qo~Ƅ_>z &e hl0{k )'iO[OtNk< Owؕn/>ƃFq-͡DHBO}ey~]KwIُ1cjh]J" %l^1'Aw)|mJ>0WPS;H4.} m/c0ddd(딦h;|BbV塬ތ]%O=ڟK4@Nw'wAF)/)4/+*vTov]: v J/*z8NzJ|OP,oliv~T7^Sj|Ix?%1stSt,"aaœ~2cyOA~4ʦ=uCO4P"hQ%\^XfP2OO)InHt!W7/KQo2Bc;T3vr!QaA7TCE$Nq)ua_N?Mm+mqEۆ γķ. B[ғ`R 8Vɠ/)X5HMzc|vWcSuMcWhMNJm@ ,JZ[]NXG^dStM>ǥsIlO88 a=K#;E/Ep3{#lsTsw=#tJv}~P6gKO٦\ѠS yCV #7d)5`:qWmg;A; *O ]ϠM}Z'7ER|PQ JA2=z=6kbc5MssCPpl.«ONJ|URjl)X%ܼtPSOh=ٮ`.>};9*ZYƼ’&ar~ѯ==$$Ӂp'/- =#cC剛Et &/KFWa7UX6+/MX ]owuQ/vm>o Q Jo& ) ZzֹV8g^X9|~N+B1{ /`ŘfV%5@#ԧy11Cn=kxkCspT%1 ܛ'$?Å8L<|ׄ|{CWNq]se{sr2G\⹖~MY~Q'TAH|%W) V|nqBQQtvR70v%uSxG]V[kc藈6ME4ylޤ`Q8E3 9)Øiw`%7-ͻ/Sx 9V Rյqy~H8Qނ[n7?i,mژ*@6gsCť[eم9 9-r T&MA.&itBo;51^ %Bx8[q"SSVkuU3KNy -e5|]~P(~0Yon)d2,+~ѝfKx*)e=TGF4bIA1HAB!ܘ_kE\ZѦqCk%ɸvx=XZo1Z雙!4\*ǔe. 0gA>%oZяgxϐB Ky;.ی2XX_E90+5_^4K ?]}J29 bQ^5ݐכOף?COM7I},JYRzc~tv4-"J\ %jWÈfR{$vۣg0Q2!/_ \PZX tC**dendstream endobj 627 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2078 >> stream xU{TB ~*klKjViO{uQ9R*pM[ry ! AnAVj):ٵUk9{6Y|}zjwN=)1uo+1/a eAr%b{d,K~Ƕa۱X<R2plf [fE7DG|ɰY7+^:k:op~m|^b@-i* yps*JX~ҏp9# 7PA%|i2q6\;,GRBK&3ϧвF[.C-y:LΫJgiO?DkE:r҈~9o҃y%rErueh)F/ۆ$;9xivcύg5mfzwĻCQC2.fR\Mfbch}`5A/tʠk]ݝ%uWޥhlx-נX&ʻ%BsN-D dȹܘWGUĄ< }xQVl&&L0J)oj&F/BRB.}bLVhd:0bh"S 69T025YNNT&؈Uu Yc;9 5龴/΢h UՏ'-[tcN]&vI^rxg#OLv&_YUqD`WvKgu9dLmzSk#aPUN#3rC<>:v@uCH}v8D:̟l7)r4 f< JFRj-vh[c%j)?Y!Kڑ OSFRy@IuF}Mq`Q\|+F\b[uEqEЬ 2AVIH[sskaX2MO(TD )5PR\Y\UVY+<;ؖFhd:%τLs_rr}IR65`s:=8 ~u{`p<\F"7g~3D<A^@:9(t@ޖsЁ.2Ү{OZ/ G=2Q QX:F饕A7,a: xrQ—9+gG6ė;`oV*A":,F4V*;*y8֢^(l2Q(h XƏ \q$f>5K-F./._r=lm`p?\i= ҟe*q!6?tBQbַe #9 \;@Io&ҦZH;K|fOC *CM4@%ݏ{{PєZ%eT𙭍zD1/<%9"{ШorZ"#G.`1"0_YTendstream endobj 628 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 492 >> stream xcd`ab`dd M̳uIf!C<<,x }M1<%9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5P\0000302H,g} &U <,os+iIq?~,{3).cr%vvN).v^CX@CRݧO5iKta!294H bK.g]EW`/0|Bפilc`YwnŦ,@onwCS͝=aܬt̕&=$LW?GNg[%${}_oO_ϤI3nػ⌾zf20endstream endobj 629 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1602 >> stream xmS PSW$s7"ޛq[+.E(>Z@!  QYA%ȣ*q:ZMkUjXnk;uN;h۝;sf}4 IRUrJjMEաa)<&<%A*!)'T``d~Kgn6[4I\SܠIOhJhUnh49U,4 JMqiyIuyk5 r.JUm6T$>R&\"($2 -E?"GDJB)NIH=26?/IT'Jd-)%|?A`2,_X`1HAP2+uWÏ?LL^u|4=GxTjPdzwh^䗏{0:'AHNk=.1ZZ1F$D5umnlC/MKrJY]&ۑyfNO!$:!' f&Wjk%2Vxb1 lC>Yoľcn4bw9cˋi tWZy)Yg.?rB~"!h-D7yzɨ?d{3wCGVrBX*bzWC͎2O6ԎZb,=(9PWLdS +:|sǐ{q٭PΎݝ~GOx3~N}endstream endobj 630 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 371 >> stream xcd`ab`dd N+64uIf!CO/nnC/ }S1<%9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5P0000103012_i eO_^Pw*ˋ T\)S^m. =wnw6/ i^O mӺvKc?{oi~}/.cA<_qsg.a][9\Ğ{z{&>&20endstream endobj 631 0 obj << /Filter /FlateDecode /Length 3385 >> stream xZKoaLv6 #$Aw819OU?nڵ_}Uo, s j.?_ :tq[BE!Ts_ƒ_abLrp@$4ioiɶ['K!PlWDy(ZTZ{?$K!DeN 4^#HQ+Ҷjɒsj 9 _mZ?vkOs]X;kؚKN`%s{d!rNќ"Ӛ< ʺ~3pj%Q;P|tpKWT"G[ ԃ)y¯)>l3KٹVࣙq>G.+.KX)PKe6H9H9yU s PSbPiG-\\6tpc3]9P6Q[q 3]^/վ5ĭ/y;G400Oh\aj%s"j܁\WD9g$b'H-A&/:fr1QXDg!:9@/Œi\,MfA}M M~a/.Q"NEʘu"38éM$"c?1q$fi-gcF@-uxq,Kj7 c"K0Îd.98z>/;^R!u.O=+$}&!A-3bRٍ/0 ޖݖ͡5)Yo)᜚<̐:O#uDfa{)ѸBxt1ABýN*}BhX!`ė' 22 ;,m@f)̮A@r/vph\)4 B8]Yo3frɥ`g)B(Y%T43u1ƇJ@yD3c*'yΐ; dLь)dBitAn2h a?x;Gz') !~7u{y*͡pe).Y څw}I#b *` i7,ŬdbI" ;v)u eE~n))$9"sIF!pT  #!!X%X j `P k%nH c($tސ5WCG7K#hP-ly \hfN!4,Љ,сi=GY :΍\nG< qh#Ӎ'h\dZ7FaXu6”LAHIh1μf>3@–BeVh&k&Zqh:w#%9pEڋ+dUSC _!It>nnz\䰋9(Sxϧᄺ:S$rkFE3ϕ(bM.p1*PxDt33"B8M3s09ޘ!5% ppK+d2srNa{HDXaƠҒ'waC]z L:mxѯM]0a`)3Ev79 ^p1ȓFR(xdh$q&1 2գ3,FuȠǦKhRYQiz[[hLڹ!45s| ֎>h"/P' 6fgmXaaz_Xa< m#bx>Dش9lj![hP_* @IaٝOͨ&M7T\A!g?^@˓_8uaA8q|N!F/֎=, ^u,^ wx 5ho(LevxGn_\Q+װ IwW:V t ܴmlś?^&@\Yľ *8hzlwƘV8yw;4C/٧;"]7ݮZW34Dk"uxzEFzd۶EP 8i%kPklo XW'+ Nz;VݤT]i:!~n^;Oh_0 ;_'%zAK3H96=,oGNOI< kBy!F Tʿ=L\<[6/_n?#vy> stream xmLUhf.cy6]ܨq q0 YG@ ](sUЋcc0pk2hfb0nq&8?/J4~0u,>,&o{;J4*B)ͨoq6ZiOSjWv-7 ӫ^sf'E4nSzb[hijXK˶Z!?/oiX 1s˞@M[xG=4۳m*)&$I&z N4ĩ>z>P5:U!3I rȃr5DvUYZ,a"6>B0B*X04lbLwRoK煓=Of"![ׯfBgd^B XռfR* MEԥRm\t8:)I7X> stream x[KsqӾѱ:,ښQC>Z+!iROlrXwUTr,TeeeUUUwG+nѿ~o5)f#75(SBNvGq*+]I.m^7BRa 0f3+7Ol2|a)%Eq涬$}} 0#Ēj[tTq:BdBnDݟa[7Lsysk0%(&yndP՚} DdW'N_n$ f0wE{?v+ʊ?4%śr]\vvsÞ q"H۵"nV!3Ç;2I}ho%|]m?gLՉ=֥ʛ?z( vo*aJ !V /ekKE(58SӢ$)27JS|vpDSE"<(x)!JGiK AD%O\LhlE'l'xKsaՙ "4*X[9{ 2W>fD [?%7,a|O%/Ăt+%2v,W4!+OikPdmѩOcm@̽Q\)ж*d]j{Ah݄)װ7#cB!uÐFm]<$Pz~3Eijz pv71xtgcOf2zݿv==D/_KL~. ~uΊZ#E9r|"Ge3Vq (*8Rpf;ENP[~3"6(t1t~{1+rzp7*pvi1/[wVt^;+n W_&;fqLq ba-Vvф JG}_~j4?H9 畗CCj'֜t#&ǹGt֚~"ozDj2YC w3o%J[G/\$~J- aRUh੃ c֟t\Ν.BEZD}K.pP@Ʒu[<*wGȡVF*PoImK7 &P *Sj;-Ίl]$^bKJ$%zt(e Bcrf¨$o-Y#T΄(0y@ Oz&",_'}̻H$G>>D tU&!h!Y|t}XU#h+"&}0[4hu* ]l{!&X(+)<`O*NFC/} `;>9[OFLrPSHӹN%iڡjaH=e+X.A$M*vck0bhK_N4>m\MkFIF>OZ7D36RvO4ul !&Sa%/ƓjP n͘/q0q>4F&/weYPS'Pzx) y豎,aYBeTD`7.]QNW$߷~"hBtg[3G޿T N&F%ygԄtCԴc< U1*L^[?}px]qf׊ʰh$LӁ_>bG^G0ϋq2D tUDrm vż?g&MvsVXO3tk0os(LBNnVJ!_6 _@e*xB,wN*+UJ {#꣬ԩcxԈe8U2yEA$1P4n>Vo$(+OAsWD"FyR Kdʑ3'l"l; 9UqHPkB=8| UBxRqxkdMR=G2(r Cʢz(#Qf:YN&u)锡kH@S\nZ]}F+L2 [JgQN Ow^`PiS *`ZY=Iۖ怑TO﬍[~ױe?|_A,sđs@T1!Ў4_XE)i [&NLmQ䵿n '=tѠ5F Y()eߴ]8aқV Svp?+6eftl-0fp~2i٬]LvRWK g򚹖*C!Jgz# 20@,1[W:HbyZ)K@)?/^JcVԠ](& pej:[/Wak,cXu_271ʸ*LAiL֊tʄ/.i!)_ Lf&,#)vyY.MA"!T(%3K 5IЈRh SQF0l)܄D[؎qGIzxD6r匚" '!eŋgd付>c=) (Hl,4yhvND'f6֊@8-}@nLS%T߯-&܌WPd#?$Oi.A>0JWXӗa Vq%V[oX|:M.]U^쨷>+5 aU^\vxqz35qySlæϦ.b"Gyu:|Ͼ9@G/;qߍ63F5>eo\Z5++8Dc%?_aΑ!7h縕kI {ថR& Yi"iWBř: }řBؾko节c&cխnoB<+^qF`Pp9ߒ* WE^Jz~R.ejVQDyA-_i-]IS7zBbr1 iHu&#cv LsVs`i(Pfط튙42κCw.zzA+qe:ybVa^ x~;VƬ0 XZV.%,T$.U~4) }XDj2楔3l̠\V6jXq7pnrj>10|Ȯ.PI5^*n)a%/l,URPz?z䂳6cY@'w2@m<;e/.ѶwCfIn9\ީ3ByI|g,4'2T1- LykpϜOq鸥z{O*;>&KiI.iV]*nG%kvO$gԴk8?t-)*f,4jAwypQl=`7g.?h$sH,$WvLRقŦT#8ޮwEz'6QQ[@U5YVD6+d5llJ1^ږ郭Yw3|d7uYixBF.匃/oLRrWW֟{1ֈXiHe*@endstream endobj 634 0 obj << /Type /XRef /Length 353 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 635 /ID [<8c7cbba38ad8f41ccf9c68c57051a866>] >> stream x+DQs1k532v,BvJ!+ 5V?Qr(ĚQ({RVa<{ůyyi1 r2XТʽ-ud yïtDAZG%-=-HEe8OJZD{ZʾEPoDia: Fށw6%NWi^A fR&`r}-+1Mha"-91s`3{Sֻ̾ۗyUE֯<-k8 7x\N>'g=g v񿧙<| p O{k 6kvPF endstream endobj startxref 360858 %%EOF surveillance/inst/doc/hhh4.R0000644000176200001440000003167614615167541015475 0ustar liggesusers### R code from vignette source 'hhh4.Rnw' ################################################### ### code chunk number 1: setup ################################################### library("surveillance") options(width=75) ## create directory for plots dir.create("plots", showWarnings=FALSE) ###################################################### ## Do we need to compute or can we just fetch results? ###################################################### compute <- !file.exists("hhh4-cache.RData") message("Doing computations: ", compute) if(!compute) load("hhh4-cache.RData") ################################################### ### code chunk number 2: loadInfluMen ################################################### # load data data("influMen") # convert to sts class and print basic information about the time series print(fluMen <- disProg2sts(influMen)) ################################################### ### code chunk number 3: getMen ################################################### meningo <- fluMen[, "meningococcus"] dim(meningo) ################################################### ### code chunk number 4: plotfluMen ################################################### getOption("SweaveHooks")[["fig"]]() plot(fluMen, type = observed ~ time | unit, # type of plot (default) same.scale = FALSE, # unit-specific ylim? col = "grey") # color of bars ################################################### ### code chunk number 5: readInFlu ################################################### # read in observed number of cases flu.counts <- as.matrix(read.table(system.file("extdata/counts_flu_BYBW.txt", package = "surveillance"), check.names = FALSE)) ################################################### ### code chunk number 6: nhoodByBw ################################################### getOption("SweaveHooks")[["fig"]]() # read in 0/1 adjacency matrix (1 if regions share a common border) nhood <- as.matrix(read.table(system.file("extdata/neighbourhood_BYBW.txt", package = "surveillance"), check.names = FALSE)) library("Matrix") print(image(Matrix(nhood))) ################################################### ### code chunk number 7: fluAsSTS ################################################### # read in population fractions popfracs <- read.table(system.file("extdata/population_2001-12-31_BYBW.txt", package = "surveillance"), header = TRUE)$popFrac # create sts object flu <- sts(flu.counts, start = c(2001, 1), frequency = 52, population = popfracs, neighbourhood = nhood) ################################################### ### code chunk number 8: plot-flu-ByBw ################################################### getOption("SweaveHooks")[["fig"]]() data("fluBYBW") plot(fluBYBW[year(fluBYBW) == 2001, ], # select year 2001 type = observed ~ unit, # total counts by region population = fluBYBW@map$X31_12_01 / 100000, # per 100000 inhabitants colorkey = list(title = "Incidence [per 100'000 inhabitants]")) ################################################### ### code chunk number 9: hhh4.Rnw:266-271 ################################################### # consistency check local({ fluBYBW@map <- flu@map stopifnot(all.equal(fluBYBW, flu)) }) ################################################### ### code chunk number 10: measles2w ################################################### data("measlesDE") measles2w <- aggregate(measlesDE, nfreq = 26) ################################################### ### code chunk number 11: plot-measles ################################################### getOption("SweaveHooks")[["fig"]]() plot(measles2w, type = observed ~ time, # aggregate counts over all units main = "Bi-weekly number of measles cases in Germany") ################################################### ### code chunk number 12: hhh4 (eval = FALSE) ################################################### ## hhh4(sts, control) ################################################### ### code chunk number 13: controlObj (eval = FALSE) ################################################### ## control = list( ## ar = list(f = ~ -1, # formula for log(lambda_it) ## offset = 1), # optional multiplicative offset ## ne = list(f = ~ -1, # formula for log(phi_it) ## offset = 1, # optional multiplicative offset ## weights = neighbourhood(stsObj) == 1), # (w_ji) matrix ## end = list(f = ~ 1, # formula for log(nu_it) ## offset = 1), # optional multiplicative offset e_it ## family = "Poisson", # Poisson or NegBin model ## subset = 2:nrow(stsObj), # subset of observations to be used ## optimizer = list(stop = list(tol = 1e-5, niter = 100), # stop rules ## regression = list(method = "nlminb"), # for penLogLik ## variance = list(method = "nlminb")), # for marLogLik ## verbose = FALSE, # level of progress reporting ## start = list(fixed = NULL, # list with initial values for fixed, ## random = NULL, # random, and ## sd.corr = NULL), # variance parameters ## data = list(t = epoch(stsObj)-1),# named list of covariates ## keep.terms = FALSE # whether to keep the model terms ## ) ################################################### ### code chunk number 14: fitMeningo0 ################################################### # specify a formula object for the endemic component ( f_S1 <- addSeason2formula(f = ~ 1, S = 1, period = 52) ) # fit the Poisson model result0 <- hhh4(meningo, control = list(end = list(f = f_S1), family = "Poisson")) summary(result0) ################################################### ### code chunk number 15: fitMeningo1 ################################################### result1 <- update(result0, family = "NegBin1") ################################################### ### code chunk number 16: hhh4.Rnw:496-497 ################################################### AIC(result0, result1) ################################################### ### code chunk number 17: fitMeningo2 ################################################### # fit an autoregressive model result2 <- update(result1, ar = list(f = ~ 1)) ################################################### ### code chunk number 18: hhh4.Rnw:510-514 ################################################### coef(result2, se = TRUE, # also return standard errors amplitudeShift = TRUE, # transform sine/cosine coefficients # to amplitude/shift parameters idx2Exp = TRUE) # exponentiate remaining parameters ################################################### ### code chunk number 19: plot_result2 ################################################### getOption("SweaveHooks")[["fig"]]() plot(result2) ################################################### ### code chunk number 20: neighbourhood_fluMen ################################################### # no "transmission" from meningococcus to influenza neighbourhood(fluMen)["meningococcus","influenza"] <- 0 neighbourhood(fluMen) ################################################### ### code chunk number 21: fitFluMen ################################################### # create formula for endemic component f.end <- addSeason2formula(f = ~ -1 + fe(1, unitSpecific = TRUE), # disease-specific intercepts S = c(3, 1), # S = 3 for flu, S = 1 for men period = 52) # specify model m <- list(ar = list(f = ~ -1 + fe(1, unitSpecific = TRUE)), ne = list(f = ~ 1, # phi, only relevant for meningococcus due to weights = neighbourhood(fluMen)), # the weight matrix end = list(f = f.end), family = "NegBinM") # disease-specific overdispersion # fit model result <- hhh4(fluMen, control = m) summary(result, idx2Exp=1:3) ################################################### ### code chunk number 22: plot-fit_men ################################################### getOption("SweaveHooks")[["fig"]]() plot(result, units = NULL, pch = 20, legend = 2, legend.args = list( legend = c("influenza-driven", "autoregressive", "endemic"))) ################################################### ### code chunk number 23: plot-fit_men_decomposed ################################################### getOption("SweaveHooks")[["fig"]]() plot(result, units = NULL, pch = 20, legend = 2, decompose = TRUE, col = c(7, 4)) ################################################### ### code chunk number 24: ri (eval = FALSE) ################################################### ## f.end <- ~ -1 + ri(type = "iid", corr = "all") ################################################### ### code chunk number 25: modelFluBYBW ################################################### # endemic component: iid random effects, linear trend, S=3 seasonal terms f.end <- addSeason2formula(f = ~ -1 + ri(type="iid", corr="all") + I((t-208)/100), S = 3, period = 52) # model specification model.B2 <- list(ar = list(f = ~ 1), ne = list(f = ~ -1 + ri(type="iid", corr="all"), weights = neighbourhood(fluBYBW), normalize = TRUE), # all(rowSums(weights) == 1) end = list(f = f.end, offset = population(fluBYBW)), family = "NegBin1", verbose = TRUE, optimizer = list(variance = list(method = "Nelder-Mead"))) # default start values for random effects are sampled from a normal set.seed(42) ################################################### ### code chunk number 26: computeFluBYBW ################################################### if(compute){ result.B2 <- hhh4(fluBYBW, model.B2) s.B2 <- summary(result.B2, maxEV = TRUE, idx2Exp = 1:3) #pred.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52) predfinal.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52, type = "final") meanSc.B2 <- colMeans(scores(predfinal.B2)) save(s.B2, meanSc.B2, file="hhh4-cache.RData") } ################################################### ### code chunk number 27: fitFluBYBW (eval = FALSE) ################################################### ## # fit the model (takes about 35 seconds) ## result.B2 <- hhh4(fluBYBW, model.B2) ## summary(result.B2, maxEV = TRUE, idx2Exp = 1:3) ################################################### ### code chunk number 28: hhh4.Rnw:670-671 ################################################### s.B2 ################################################### ### code chunk number 29: oneStepAhead_rolling (eval = FALSE) ################################################### ## pred.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52) ################################################### ### code chunk number 30: oneStepAhead_fake (eval = FALSE) ################################################### ## predfinal.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52, ## type = "final") ################################################### ### code chunk number 31: scores (eval = FALSE) ################################################### ## colMeans(scores(predfinal.B2, which = c("logs", "rps"))) ################################################### ### code chunk number 32: hhh4.Rnw:703-704 ################################################### meanSc.B2[c("logs", "rps")] ################################################### ### code chunk number 33: createVacc ################################################### data(MMRcoverageDE) cardVac1 <- MMRcoverageDE[1:16,3:4] adjustVac <- function(cardVac, p=0.5,nrow=1){ card <- cardVac[,1] vac <- cardVac[,2] vacAdj <- vac*card + p*vac*(1-card) return(matrix(vacAdj,nrow=nrow, ncol=length(vacAdj), byrow=TRUE)) } vac0 <- 1-adjustVac(cardVac1,p=0.5,nrow=measles2w@freq*3) colnames(vac0) <- colnames(measles2w) ################################################### ### code chunk number 34: hhh4.Rnw:750-751 ################################################### vac0[1:2, 1:6] ################################################### ### code chunk number 35: fitMeasles ################################################### # endemic component: Intercept + sine/cosine terms f.end <- addSeason2formula(f = ~ 1, S = 1, period = 26) # autoregressive component: Intercept + vaccination coverage information model.A0 <- list(ar = list(f = ~ 1 + logVac0), end = list(f = f.end, offset = population(measles2w)), data = list(t = epoch(measles2w), logVac0 = log(vac0))) # fit the model result.A0 <- hhh4(measles2w, model.A0) summary(result.A0, amplitudeShift = TRUE) surveillance/inst/doc/monitoringCounts.Rnw0000644000176200001440000031401014615162374020551 0ustar liggesusers%\VignetteIndexEntry{Monitoring count time series in R: Aberration detection in public health surveillance} %\VignetteEngine{knitr::knitr} %% additional dependencies beyond what is required for surveillance anyway: %\VignetteDepends{surveillance, gamlss, MGLM} <>= knitr::opts_chunk$set(fig.path="plots/monitoringCounts-", error = FALSE, warning = FALSE, message = FALSE) knitr::render_sweave() # use Sweave environments knitr::set_header(highlight = '') # no \usepackage{Sweave} (part of jss class) options(xtable.booktabs = TRUE, xtable.comment = FALSE) @ \documentclass[nojss]{jss} \usepackage{amsmath,bm} \usepackage{booktabs} \usepackage{subcaption} % successor of subfig, which supersedes subfigure \providecommand{\subfloat}[2][need a sub-caption]{\subcaptionbox{#1}{#2}} \newcommand{\BetaBin}{\operatorname{BetaBin}} \newcommand{\Var}{\operatorname{Var}} \newcommand{\logit}{\operatorname{logit}} \newcommand{\NB}{\operatorname{NB}} %% almost as usual \author{Ma\"elle Salmon\\Robert Koch Institute \And Dirk Schumacher\\Robert Koch Institute \And Michael H\"ohle\\ Stockholm University,\\Robert Koch Institute } \title{ \vspace{-2.2cm} \fbox{\vbox{\normalfont\footnotesize This vignette corresponds to an article published in the\\ \textit{Journal of Statistical Software} 2016;\textbf{70}(10):1--35. \doi{10.18637/jss.v070.i10}.}}\\[1cm] Monitoring Count Time Series in \proglang{R}: Aberration Detection in Public Health Surveillance} %% for pretty printing and a nice hypersummary also set: \Plainauthor{Ma\"elle Salmon, Dirk Schumacher, Michael H\"ohle} %% comma-separated \Plaintitle{Monitoring Count Time Series in R: Aberration Detection in Public Health Surveillance} % without formatting \Shorttitle{\pkg{surveillance}: Aberration detection in \proglang{R}} %% a short title (if necessary) %% an abstract and keywords \Abstract{ Public health surveillance aims at lessening disease burden by, e.g., timely recognizing emerging outbreaks in case of infectious diseases. Seen from a statistical perspective, this implies the use of appropriate methods for monitoring time series of aggregated case reports. This paper presents the tools for such automatic aberration detection offered by the \textsf{R} package \pkg{surveillance}. We introduce the functionalities for the visualization, modeling and monitoring of surveillance time series. With respect to modeling we focus on univariate time series modeling based on generalized linear models (GLMs), multivariate GLMs, generalized additive models and generalized additive models for location, shape and scale. Applications of such modeling include illustrating implementational improvements and extensions of the well-known Farrington algorithm, e.g., by spline-modeling or by treating it in a Bayesian context. Furthermore, we look at categorical time series and address overdispersion using beta-binomial or Dirichlet-multinomial modeling. With respect to monitoring we consider detectors based on either a Shewhart-like single timepoint comparison between the observed count and the predictive distribution or by likelihood-ratio based cumulative sum methods. Finally, we illustrate how \pkg{surveillance} can support aberration detection in practice by integrating it into the monitoring workflow of a public health institution. Altogether, the present article shows how well \pkg{surveillance} can support automatic aberration detection in a public health surveillance context. } \Keywords{\proglang{R}, \texttt{surveillance}, outbreak detection, statistical process control} \Plainkeywords{R, surveillance, outbreak detection, statistical process control} %% without formatting %% at least one keyword must be supplied \Address{ Ma\"{e}lle Salmon, Dirk Schumacher\\ Department for Infectious Diseases Epidemiology\\ Robert Koch Institut Berlin\\ Seestrasse 10\\ 13353 Berlin, Germany\\ E-mail: \email{maelle.salmon@yahoo.se}, \email{mail@dirk-schumacher.net}\\ URL: \url{https://masalmon.eu/}\\ \phantom{URL: }\url{https://dirk-schumacher.net/}\\ Michael H\"{o}hle\\ Department of Mathematics\\ Stockholm University\\ Kr\"{a}ftriket\\ 106 91 Stockholm, Sweden\\ E-mail: \email{hoehle@math.su.se}\\ URL: \url{https://staff.math.su.se/hoehle/} } \begin{document} \maketitle \section{Introduction} \label{sec:0} Nowadays, the fight against infectious diseases does not only require treating patients and setting up measures for prevention but also demands the timely recognition of emerging outbreaks in order to avoid their expansion. Along these lines, health institutions such as hospitals and public health authorities collect and store information about health events -- typically represented as individual case reports containing clinical information, and subject to specific case definitions. Analysing these data is crucial. It enables situational awareness in general and the timely detection of aberrant counts in particular, empowering the prevention of additional disease cases through early interventions. For any specific aggregation of characteristics of events, such as over-the-counter sales of pain medication, new cases of foot-and-mouth disease among cattle, or adults becoming sick with hepatitis C in Germany, data can be represented as time series of counts with days, weeks, months or years as time units of the aggregation. Abnormally high or low values at a given time point can reveal critical issues such as an outbreak of the disease or a malfunction of data transmission. Thus, identifying aberrations in the collected data is decisive, for human as well as for animal health. In this paper we present the \proglang{R} package \pkg{surveillance} which is available from the Comprehensive \proglang{R} Archive Network (CRAN) at \url{https://CRAN.R-project.org/package=surveillance}. It implements a range of methods for aberration detection in time series of counts and proportions. Statistical algorithms provide an objective and reproducible analysis of the data and allow the automation of time-consuming aspects of the monitoring process. In the recent years, a variety of such tools has flourished in the literature. Reviews of methods for aberration detection in time series of counts can be found in~\citet{Buckeridge2007}~and~\citet{Unkel2012}. However, the great variety of statistical algorithms for aberration detection can be a hurdle to practitioners wishing to find a suitable method for their data. It is our experience that ready-to-use and understandable implementation and the possibility to use the methods in a routine and automatic fashion are the criteria most important to the epidemiologists. The package offers an open-source implementation of state-of-the-art methods for the prospective detection of outbreaks in count data time series with established methods, as well as the visualization of the analysed time series. With the package, the practitioner can introduce statistical surveillance into routine practice without too much difficulty. As far as we know, the package is now used in several public health institutions in Europe: at the National Public Health Institute of Finland, at the Swedish Institute for Communicable Disease Control, at the French National Reference Centre for Salmonella, and at the Robert Koch Institute (RKI) in Berlin. The use of \pkg{surveillance} at the RKI shall be the focus of this paper. The package also provides many other functions serving epidemic modeling purposes. Such susceptible-infectious-recovered based models and their extensions towards regression based approaches are documented in other works~\citep{held-etal-2005,held_etal2006,meyer.etal2011,meyer.etal2014}. The present paper is designed as an extension of two previous articles about the \pkg{surveillance} package published as~\citet{hoehle-2007} and~\citet{hoehle-mazick-2010}. On the one hand, the paper aims at giving an overview of the new features added to the package since the publication of the two former papers. On the other hand it intends to illustrate how well the \pkg{surveillance} package can support routine practical disease surveillance by presenting the current surveillance system of infectious diseases at the RKI. This paper is structured as follows. Section~\ref{sec:1} gives an introduction to the data structure used in the package for representing and visualizing univariate or multivariate time series. Furthermore, the structure and use of aberration detection algorithms are explained. Section~\ref{sec:2} leads the reader through different surveillance methods available in the package. Section~\ref{sec:3} describes the integration of such methods in a complete surveillance system as currently in use at the RKI. Finally, a discussion rounds off the work. \section{Getting to know the basics of the package} <>= ## create directories for plots and cache dir.create("plots", showWarnings=FALSE) dir.create("monitoringCounts-cache", showWarnings=FALSE) ## load packages library('surveillance') library('gamlss') @ \label{sec:1} The package provides a central S4 data class \code{sts} to capture multivariate or univariate time series. All further methods use objects of this class as an input. Therefore we first describe the \code{sts} class and then show the typical usage of a function for aberration detection, including visualization. All monitoring methods of the package conform to the same syntax. \subsection{How to store time series and related information} In \pkg{surveillance}, time series of counts and related information are encoded in a specific S4-class called \code{sts} (\textit{surveillance time series}) that represents possibly multivariate time series of counts. Denote the counts as $\left( y_{it} ; i = 1, \ldots,m, t = 1, \ldots, n \right)$, where $n$ is the length of the time series and $m$ is the number of entities, e.g., geographical regions, hospitals or age groups, being monitored. An example which we shall look at in more details is a time series representing the weekly counts of cases of infection with \textit{Salmonella Newport} in all 16 federal states of Germany from 2004 to 2013 with $n=525$ weeks and $m=16$ geographical units. Infections with \textit{Salmonella Newport}, a subtype of \textit{Salmonella}, can trigger gastroenteritis, prompting the seek of medical care. Infections with \textit{Salmonella} are notifiable in Germany since 2001 with data being forwarded to the RKI by federal states health authorities on behalf of the local health authorities. \subsubsection[Slots of the class sts]{Slots of the class \texttt{sts}} The key slots of the \code{sts} class are those describing the observed counts and the corresponding time periods of the aggregation. The observed counts $\left(y_{it}\right)$ are stored in the $n \times m$ matrix \code{observed}. A number of other slots characterize time. First, \code{epoch} denotes the corresponding time period of the aggregation. If the Boolean \code{epochAsDate} is \code{TRUE}, \code{epoch} is the numeric representation of \code{Date} objects corresponding to each observation in \code{observed}. If the Boolean \code{epochAsDate} is \code{FALSE}, \code{epoch} is the time index $1 \leq t \leq n$ of each of these observations. Then, \code{freq} is the number of observations per year: 365 for daily data, 52 for weekly data and 12 for monthly data. Finally, \code{start} is a vector representing the origin of the time series with two values that are the year and the epoch within that year for the first observation of the time series -- \code{c(2014, 1)} for a weekly time series starting on the first week of 2014 for instance. Other slots enable the storage of additional information. Known aberrations are recorded in the Boolean slot \code{state} of the same dimensions as \code{observed} with \code{TRUE} indicating an outbreak and \code{FALSE} indicating the absence of any known aberration. The monitored population in each of the units is stored in slot \code{populationFrac}, which gives either proportions or numbers. The geography of the zone under surveillance is accessible through slot \code{map} which is an object of class \code{SpatialPolygonsDataFrame}~\citep{sp1,sp2} providing a shape of the $m$ areas which are monitored and slot \code{neighbourhood}, which is a symmetric matrix of Booleans size $m^2$ stating the neighborhood matrix. Slot \code{map} is pertinent when units are geographical units, whereas \code{neighbourhood} could be useful in any case, e.g., for storing a contact matrix between age groups for modeling purposes. Finally, if monitoring has been performed on the data, the information on its control arguments and its results are stored in \code{control}, \code{upperbound} and \code{alarm} presented in Section~\ref{sec:howto}. \subsubsection[Creation of an object of class sts]{Creation of an object of class \texttt{sts}} The creation of an \code{sts} object is straightforward, requiring a call of the constructor function \code{sts} together with the slots to be assigned as arguments. The input of data from external files is one possibility for getting the counts as it is described in \citet{hoehle-mazick-2010}. To exemplify the process we shall use weekly counts of \textit{Salmonella Newport} in Germany loaded using \code{data("salmNewport")}. Alternatively, one can use coercion methods to convert between the \texttt{ts} class and the \texttt{sts} class. Note that this only converts the content of the slot \texttt{observed}, that is, <>= data("salmNewport") @ <>= all.equal(observed(salmNewport), observed(as(as(salmNewport, "ts"), "sts"))) @ <>= stopifnot( <> ) @ Using the \texttt{ts} class as intermediate step also allows the conversion between other time series classes, e.g., from packages \pkg{zoo}~\citep{zoo} or \pkg{xts}~\citep{xts}. <>= # This code is the one used for the Salmon et al. (2016) JSS article. # Using this code all examples from the article can be reproduced. # computeALL is FALSE to avoid the computationally intensive parts # of the code (simulations to find a threshold value for categoricalCUSUM, # INLA-driven BODA) but one can set it to TRUE to have it run. computeALL <- FALSE @ <>= # Define plot parameters cex.text <- 1.7 line.lwd <- 2 plotOpts <- local({ #Add lines using grid by a hook function. Use NULL to align with tick marks hookFunc <- function() { grid(NA,NULL,lwd=1) } cex.axis <- cex.text cex.main <- cex.text cex.lab <- cex.text cex.leg <- cex.text stsPlotCol <- c("mediumblue","mediumblue","red2") alarm.symbol <- list(pch=17, col="red2", cex=2,lwd=3) #Define list with arguments to use with do.call("legend", legOpts) legOpts <- list(x="topleft",legend=c(expression(U[t])),bty="n",lty=1,lwd=line.lwd,col=alarm.symbol$col,horiz=TRUE,cex=cex.leg) #How should the par of each plot look? par.list <- list(mar=c(6,5,5,5),family="Times") #Do this once y.max <- 0 list(col=stsPlotCol,ylim=c(0,y.max), main='',lwd=c(1,line.lwd,line.lwd), dx.upperbound=0, #otherwise the upperbound line is put 0.5 off cex.lab=cex.lab, cex.axis=cex.axis, cex.main=cex.main, ylab="No. of reports", xlab="Time (weeks)",lty=c(1,1,1), legend.opts=legOpts,alarm.symbol=alarm.symbol, xaxis.tickFreq=list("%V"=atChange,"%m"=atChange,"%G"=atChange), xaxis.labelFreq=list("%Y"=atMedian), xaxis.labelFormat="%Y", par.list=par.list,hookFunc=hookFunc) }) @ \begin{figure} \centering <>= y.max <- max(aggregate(salmNewport,by="unit")@observed,na.rm=TRUE) plotOpts2 <- modifyList(plotOpts,list(x=salmNewport,legend.opts=NULL,ylim=c(0,y.max),type = observed ~ time),keep.null=TRUE) plotOpts2$par.list <- list(mar=c(6,5,0,5),family="Times") plotOpts2$xaxis.tickFreq <- list("%m"=atChange,"%G"=atChange) do.call("plot",plotOpts2) @ \caption{Weekly number of cases of S. Newport in Germany, 2004-2013.} \label{fig:Newport} \end{figure} \subsubsection[Basic manipulation of objects of the class sts]{Basic manipulation of objects of the class \texttt{sts}} This time series above is represented as a multivariate \code{sts} object whose dimensions correspond to the 16 German federal states. Values are weekly counts so \code{freq = 52}. Weeks are indexed by \code{Date} here (\code{epochAsDate = TRUE}). One can thus for instance get the weekday of the date by calling \code{weekdays(epoch(salmNewport))} (all Mondays here). Furthermore, one can use the function \code{format} (and the package specific platform independent version \code{dateFormat}) to obtain \code{strftime} compatible formatting of the epochs. Another advantage of using \code{Date} objects is that the plot functions have been re-written for better management of ticks and labelling of the x-axis based on \code{strftime} compatible conversion specifications. For example, to get ticks at all weeks corresponding to the first week in a month as well as all weeks corresponding to the first in a year while placing labels consisting of the year at the median index per year (Figure~\ref{fig:Newport}): <>= plot(salmNewport, type = observed ~ time, xaxis.tickFreq = list("%m" = atChange, "%G" = atChange), xaxis.labelFreq = list("%Y" = atMedian), xaxis.labelFormat = "%Y") @ The helper functions \code{atChange} and \code{atMedian} are documented in \code{help("addFormattedXAxis")}. % and the respective tick lengths are controlled by the \pkg{surveillance}-specific % option \code{surveillance.options("stsTickFactors")}. Actually \code{sts} objects can be plotted using different options: \code{type = observed ~ time} produces the time series for whole Germany as shown in Figure~\ref{fig:Newport}, whereas \code{type = observed ~ time | unit} (the default) is a panelled graph with each panel representing the time series of counts of a federal state as seen in Figure~\ref{fig:unit}. \begin{figure} \subfloat[]{ <>= y.max <- max(observed(salmNewport[,2]),observed(salmNewport[,3]),na.rm=TRUE) plotOpts2 <- modifyList(plotOpts,list(x=salmNewport[,2],legend.opts=NULL,ylim=c(0,y.max)),keep.null=TRUE) plotOpts2$xaxis.tickFreq <- list("%G"=atChange) do.call("plot",plotOpts2) @ } \subfloat[]{ <>= plotOpts2 <- modifyList(plotOpts,list(x=salmNewport[,3],legend.opts=NULL,ylim=c(0,y.max)),keep.null=TRUE) plotOpts2$xaxis.tickFreq <- list("%G"=atChange) do.call("plot",plotOpts2) @ } \caption{Weekly count of S. Newport in the German federal states (a) Bavaria and (b) Berlin.} \label{fig:unit} \end{figure} <>= plot(salmNewport, units = 2:3) @ Once created one can use typical subset operations on a \code{sts} object: for instance \code{salmNewport[} \code{1:10, "Berlin"]} is a new \code{sts} object with weekly counts for Berlin during the 10 first weeks of the initial dataset; \code{salmNewport[isoWeekYear(epoch(salmNewport))\$ISOYear<=2010,]} uses the \code{surveillance}'s \code{isoWeekYear()} function to get a \code{sts} object with weekly counts for all federal states up to 2010. Moreover, one can take advantage of the \proglang{R} function \code{aggregate()}. For instance, \code{aggregate(salmNewport,by="unit")} returns a \code{sts} object representing weekly counts of \textit{Salmonella Newport} in Germany as a whole, whereas \code{aggregate(salmNewport, by = "time")} corresponds to the total count of cases in each federal state over the whole period. \subsection{How to use aberration detection algorithms} \label{sec:howto} Monitoring algorithms of the package operate on objects of the class \code{sts} as described below. \subsubsection{Statistical framework for aberration detection} We introduce the framework for aberration detection on an univariate time series of counts $\left\{y_t,\> t=1,2,\ldots\right\}$. Surveillance aims at detecting an \textit{aberration}, that is to say, an important change in the process occurring at an unknown time $\tau$. This change can be a step increase of the counts of cases or a more gradual change~\citep{Sonesson2003}. Based on the possibility of such a change, for each time $t$ we want to differentiate between the two states \textit{in-control} and \textit{out-of-control}. At any timepoint $t_0\geq 1$, the available information -- i.e., past counts -- is defined as $\bm{y}_{t_0} = \left\{ y_t\>;\> t\leq t_0\right\}$. Detection is based on a statistic $r(\cdot)$ with resulting alarm time $T_A = \min\left\{ t_0\geq 1 : r(\bm{y}_{t_0}) > g\right\}$ where $g$ is a known threshold. Functions for aberration detection thus use past data to estimate $r(\bm{y}_{t_0})$, and compare it to the threshold $g$ above which the current count can be considered suspicious and thus \textit{out-of-control}. Threshold values and alarm Booleans for each timepoint of the monitored range are saved in the slots \code{upperbound} and \code{alarm} (of the same dimensions as \code{observed}), respectively, while the parameters of the algorithm %used for computing the threshold values and alarm Booleans are stored in the slot \code{control}. \subsubsection{Aberration detection in the package} To perform such a monitoring of the counts of cases, one has to choose one of the surveillance algorithms of the package -- this choice will be the topic of Section~\ref{sec:using}. Then, one must indicate which part of the time series or \code{range} has to be monitored -- for instance the current year. Lastly, one needs to specify the parameters specific to the algorithm. \subsubsection{Example with the EARS C1 method} We will illustrate the basic principle by using the \code{earsC}~function~that implements the EARS (Early Aberration Detection System) methods of the CDC as described in~\citet{SIM:SIM3197}. This algorithm is especially convenient in situations when little historic information is available. It offers three variants called C1, C2 and C3. Here we shall expand on C1 for which the baseline are the 7 timepoints before the assessed timepoint $t_0$, that is to say $\left(y_{t_0-7},\ldots,y_{t_0-1}\right)$. The expected value is the mean of the baseline. The method is based on a statistic called $C_{t_0}$ defined as $C_{t_0}= \frac{(y_{t_0}-\bar{y}_{t_0})}{s_{t_0}}$, where $$\bar{y}_{t_0}= \frac{1}{7} \cdot\sum_{i=t_0-7}^{t_0-1} y_i \textnormal{ and } s_{t_0}^2= \frac{1}{7-1} \cdot\sum_{i=t_0-7}^{t_0-1} \left(y_i - \bar{y}_{t_0}\right)^2 \,.$$ Under the null hypothesis of no outbreak, it is assumed that $C_{t_0} \stackrel{H_0}{\sim} {N}(0,1)$. The upperbound $U_{t_0}$ is found by assuming that $y_t$ is normal, estimating parameters by plug-in and then taking the $(1-\alpha)$-th quantile of this distribution, i.e. $U_{t_0}= \bar{y}_{t_0} + z_{1-\alpha}s_{t_0}$, where $z_{1-\alpha}$ is the $(1-\alpha)$-quantile of the standard normal distribution. An alarm is raised if $y_{t_0} > U_{t_0}$. The output of the algorithm is a \code{sts} object that contains subsets of slots \code{observed}, \code{population} and \code{state} defined by the range of timepoints specified in the input -- \textit{e.g} the last 20 timepoints of the time series, and with the slots \code{upperbound} and \code{alarm} filled by the output of the algorithm. Information relative to the \code{range} of data to be monitored and to the parameters of the algorithm, such as \code{alpha} for \code{earsC}, has to be formulated in the slot \code{control}. This information is also stored in the slot \code{control} of the returned \code{sts} object for later inspection. <>= in2011 <- which(isoWeekYear(epoch(salmNewport))$ISOYear == 2011) salmNewportGermany <- aggregate(salmNewport, by = "unit") control <- list(range = in2011, method = "C1", alpha = 0.05) surv <- earsC(salmNewportGermany, control = control) plot(surv) @ \begin{figure} \centering <>= y.max <- max(observed(surv),upperbound(surv),na.rm=TRUE) do.call("plot",modifyList(plotOpts,list(x=surv,ylim=c(0,y.max)),keep.null=TRUE)) @ \caption{Weekly reports of S. Newport in Germany in 2011 monitored by the EARS C1 method. The line represents the upperbound calculated by the algorithm. Triangles indicate alarms that are the timepoints where the observed number of counts is higher than the upperbound.} \label{fig:NewportEARS} \end{figure} The \code{sts} object is easily visualized using the function \code{plot} as depicted in Figure~\ref{fig:NewportEARS}, which shows the upperbound as a solid line and the alarms -- timepoints where the upperbound has been exceeded -- as triangles. The four last alarms correspond to a known outbreak in 2011 due to sprouts~\citep{Newport2011}. One sees that the upperbound right after the outbreak is affected by the outbreak: it is very high, so that a smaller outbreak would not be detected. The EARS methods C1, C2 and C3 are simple in that they only use information from the very recent past. This is appropriate when data has only been collected for a short time or when one expects the count to be fairly constant. However, data from the less recent past often encompass relevant information about e.g., seasonality and time trend, that one should take into account when estimating the expected count and the associated threshold. For instance, ignoring an increasing time trend could decrease sensitivity. Inversely, overlooking an annual surge in counts during the summer could decrease specificity. Therefore, it is advisable to use detection methods whose underlying models incorporate essential characteristics of time series of disease count data such as overdispersion, seasonality, time trend and presence of past outbreaks in the records~\citep{Unkel2012,Shmueli2010}. Moreover, the EARS methods do not compute a proper prediction interval for the current count. Sounder statistical methods will be reviewed in the next section. \section[Using surveillance in selected contexts]{Using \pkg{surveillance} in selected contexts} \label{sec:using} \label{sec:2} More than a dozen algorithms for aberration detection are implemented in the package. Among those, this section presents a set of representative algorithms, which are already in routine application at several public health institutions or which we think have the potential to become so. First we describe the Farrington method introduced by~\citet{farrington96} together with the improvements proposed by~\citet{Noufaily2012}. As a Bayesian counterpart to these methods we present the BODA method published by~\citet{Manitz2013} which allows the easy integration of covariates. All these methods perform one-timepoint detection in that they detect aberrations only when the count at the currently monitored timepoint is above the threshold. Hence, no accumulation of evidence takes place. As an extension, we introduce an implementation of the negative binomial cumulative sum (CUSUM) of~\citet{hoehle.paul2008} that allows the detection of sustained shifts by accumulating evidence over several timepoints. Finally, we present a method suitable for categorical data described in~\citet{hoehle2010} that is also based on cumulative sums. \subsection{One size fits them all for count data} Two implementations of the Farrington method, which is currently \textit{the} method of choice at European public health institutes \citep{hulth_etal2010}, exist in the package. First, the original method as described in \citet{farrington96} is implemented as the function \code{farrington}. Its use was already described in \citet{hoehle-mazick-2010}. Now, the newly implemented function \code{farringtonFlexible} supports the use of this \textit{original method} as well as of the \textit{improved method} built on suggestions made by~\citet{Noufaily2012} for improving the specificity without reducing the sensitivity. In the function \code{farringtonFlexible} one can choose to use the original method or the improved method by specification of appropriate \code{control} arguments. Which variant of the algorithm is to be used is determined by the contents of the \code{control} slot. In the example below, \code{con.farrington} corresponds to the use of the original method and \code{con.noufaily} indicates the options for the improved method. <>= con.farrington <- list( range = in2011, noPeriods = 1, b = 4, w = 3, weightsThreshold = 1, pastWeeksNotIncluded = 3, pThresholdTrend = 0.05, thresholdMethod = "delta" ) con.noufaily <- list( range = in2011, noPeriods = 10, b = 4, w = 3, weightsThreshold = 2.58, pastWeeksNotIncluded = 26, pThresholdTrend = 1, thresholdMethod = "nbPlugin" ) @ <>= con.farrington$limit54 <- con.noufaily$limit54 <- c(0,50) # for the figure @ In both cases the steps of the algorithm are the same. In a first step, an overdispersed Poisson generalized linear model with log link is fitted to the reference data $\bm{y}_{t_0} \subseteq \left\{ y_t\>;\> t\leq t_0\right\}$, where $\E(y_t)=\mu_t$ with $\log \mu_t = \alpha + \beta t$ and $\Var(y_t)=\phi\cdot\mu_t$ and where $\phi\geq1$ is ensured. The original method took seasonality into account by using a subset of the available data as reference data for fitting the GLM: \code{w} timepoints centred around the timepoint located $1,2,\ldots,b$ years before $t_0$, amounting to a total $b \cdot (2w+1)$ reference values. However, it was shown in~\citet{Noufaily2012} that the algorithm performs better when using more historical data. In order to do do so without disregarding seasonality, the authors introduced a zero order spline with 11 knots, which can be conveniently represented as a 10-level factor. We have extended this idea in our implementation so that one can choose an arbitrary number of periods in each year. Thus, $\log \mu_t = \alpha + \beta t +\gamma_{c(t)}$ where $\gamma_{c(t)}$ are the coefficients of a zero order spline with $\mathtt{noPeriods}+1$ knots, which can be conveniently represented as a $\mathtt{noPeriods}$-level factor that reflects seasonality. Here, $c(t)$ is a function indicating in which season or period of the year $t$ belongs to. The algorithm uses \code{w}, \code{b} and \texttt{noPeriods} to deduce the length of periods so they have the same length up to rounding. An exception is the reference window centred around $t_0$. Figure~\ref{fig:fPlot} shows a minimal example, where each character corresponds to a different period. Note that setting $\mathtt{noPeriods} = 1$ corresponds to using the original method with only a subset of the data: there is only one period defined per year, the reference window around $t_0$ and other timepoints are not included in the model. \begin{figure} \subfloat[$\texttt{noPeriods}=2$]{ \includegraphics[width=0.45\textwidth]{monitoringCounts-cache/fPlot1.pdf} } \qquad \subfloat[$\texttt{noPeriods}=3$]{ \includegraphics[width=0.45\textwidth]{monitoringCounts-cache/fPlot2.pdf} } \caption{Construction of the noPeriods-level factor to account for seasonality, depending on the value of the half-window size $w$ and of the freq of the data. Here the number of years to go back in the past $b$ is 2. Each level of the factor variable corresponds to a period delimited by ticks and is denoted by a character. The windows around $t_0$ are respectively of size $2w+1$,~$2w+1$ and $w+1$. The segments between them are divided into the other periods so that they have the same length up to rounding.} \label{fig:fPlot} \end{figure} Moreover, it was shown in \citet{Noufaily2012} that it is better to exclude the last 26 weeks before $t_0$ from the baseline in order to avoid reducing sensitivity when an outbreak has started recently before $t_0$. In the \code{farringtonFlexible} function, one controls this by specifying \code{pastWeeksNotIncluded}, which is the number of last timepoints before $t_0$ that are not to be used. The (historical) default is to use \code{pastWeeksNotIncluded = w}. Lastly, in the new implementation a population offset can be included in the GLM by setting \code{populationBool} to \code{TRUE} and supplying the possibly time-varying population size in the \code{population} slot of the \code{sts} object, but this will not be discussed further here. In a second step, the expected number of counts $\mu_{t_0}$ is predicted for the current timepoint $t_0$ using this GLM. An upperbound $U_{t_0}$ is calculated based on this predicted value and its variance. The two versions of the algorithm make different assumptions for this calculation. The original method assumes that a transformation of the prediction error $g\left(y_{t_0}-\hat{\mu}_{t_0}\right)$ is normally distributed, for instance when using the identity transformation $g(x)=x$ one obtains $$y_{t_0} - \hat{\mu}_0 \sim \mathcal{N}(0,\Var(y_{t_0}-\hat{\mu}_0)) \,.$$ The upperbound of the prediction interval is then calculated based on this distribution. First we have that $$ \Var(y_{t_0}-\hat{\mu}_{t_0}) = \Var(\hat{y}_{t_0}) + \Var(\hat{\mu}_{t_0})=\phi\mu_0+\Var(\hat{\mu}_{t_0}) $$ with $\Var(\hat{y}_{t_0})$ being the variance of an observation and $\Var(\hat{\mu}_{t_0})$ being the variance of the estimate. The threshold, defined as the upperbound of a one-sided $(1-\alpha)\cdot 100\%$ prediction interval, is then $$U_{t_0} = \hat{\mu}_0 + z_{1-\alpha}\sqrt{\widehat{\Var}(y_{t_0}-\hat{\mu}_{t_0})} \,.$$ This method can be used by setting the control option \code{thresholdMethod} equal to "\code{delta}". However, a weakness of this procedure is the normality assumption itself, so that an alternative was presented in \citet{Noufaily2012} and implemented as \code{thresholdMethod="Noufaily"}. The central assumption of this approach is that $y_{t_0} \sim \NB\left(\mu_{t_0},\nu\right)$, with $\mu_{t_0}$ the mean of the distribution and $\nu=\frac{\mu_{t_0}}{\phi-1}$ its overdispersion parameter. In this parameterization, we still have $\E(y_t)=\mu_t$ and $\Var(y_t)=\phi\cdot\mu_t$ with $\phi>1$ -- otherwise a Poisson distribution is assumed for the observed count. The threshold is defined as a quantile of the negative binomial distribution with plug-in estimates $\hat{\mu}_{t_0}$ and $\hat{\phi}$. Note that this disregards the estimation uncertainty in $\hat{\mu}_{t_0}$ and $\hat{\phi}$. As a consequence, the method "\code{muan}" (\textit{mu} for $\mu$ and \textit{an} for asymptotic normal) tries to solve the problem by using the asymptotic normal distribution of $(\hat{\alpha},\hat{\beta})$ to derive the upper $(1-\alpha)\cdot 100\%$ quantile of the asymptotic normal distribution of $\hat{\mu}_{t_0}=\hat{\alpha}+\hat{\beta}t_0$. Note that this does not reflect all estimation uncertainty because it disregards the estimation uncertainty of $\hat{\phi}$. Note also that for time series where the variance of the estimator is large, the upperbound also ends up being very large. Thus, the method "\code{nbPlugin}" seems to provide information that is easier to interpret by epidemiologists but with "\code{muan}" being more statistically correct. In a last step, the observed count $y_{t_0}$ is compared to the upperbound $U_{t_0}$ and an alarm is raised if $y_{t_0} > U_{t_0}$. In both cases the fitting of the GLM involves three important steps. First, the algorithm performs an optional power-transformation for skewness correction and variance stabilisation, depending on the value of the parameter \code{powertrans} in the \code{control} slot. Then, the significance of the time trend is checked. The time trend is included only when significant at a chosen level \code{pThresholdTrend}, when there are more than three years reference data and if no overextrapolation occurs because of the time trend. Lastly, past outbreaks are reweighted based on their Anscombe residuals. In \code{farringtonFlexible} the limit for reweighting past counts, \code{weightsThreshold}, can be specified by the user. If the Anscombe residual of a count is higher than \code{weightsThreshold} it is reweighted accordingly in a second fitting of the GLM. \citet{farrington96} used a value of $1$ whereas \citet{Noufaily2012} advise a value of $2.56$ so that the reweighting procedure is less drastic, because it also shrinks the variance of the observations. The original method is widely used in public health surveillance~\citep{hulth_etal2010}. The reason for its success is primarily that it does not need to be fine-tuned for each specific pathogen. It is hence easy to implement it for scanning data for many different pathogens. Furthermore, it does tackle classical issues of surveillance data: overdispersion, presence of past outbreaks that are reweighted, seasonality that is taken into account differently in the two methods. An example of use of the function is shown in Figure~\ref{fig:newportFar} with the code below. <<>>= salm.farrington <- farringtonFlexible(salmNewportGermany, con.farrington) salm.noufaily <- farringtonFlexible(salmNewportGermany, con.noufaily) @ <>= par(mfrow = c(1,2)) plot(salm.farrington) plot(salm.noufaily) @ \begin{figure} \subfloat[]{ <>= y.max <- max(observed(salm.farrington),upperbound(salm.farrington),observed(salm.noufaily),upperbound(salm.noufaily),na.rm=TRUE) do.call("plot",modifyList(plotOpts,list(x=salm.farrington,ylim=c(0,y.max)))) @ } \subfloat[]{ <>= do.call("plot",modifyList(plotOpts,list(x=salm.noufaily,ylim=c(0,y.max)))) @ } \caption{S. Newport in Germany in 2011 monitored by (a) the original method and (b) the improved method. For the figure we turned off the option that the threshold is only computed if there were more than 5 cases during the 4 last timepoints including $t_0$. One gets less alarms with the most recent method and still does not miss the outbreak in the summer. Simulations on more time series support the use of the improved method instead of the original method.} \label{fig:newportFar} \end{figure} % With our implementation of the improvements presented in \citet{Noufaily2012} we hope that the method with time can replace the original method in routine use. The RKI system described in Section~\ref{sec:RKI} already uses this improved method. \subsubsection{Similar methods in the package} The package also contains further methods based on a subset of the historical data: \code{bayes}, \code{rki} and \code{cdc}. See Table~\ref{table:ref} for the corresponding references. Here, \code{bayes} uses a simple conjugate prior-posterior approach and computes the parameters of a negative binomial distribution based on past values. The procedure \code{rki} makes either the assumption of a normal or a Poisson distribution based on the mean of past counts. Finally, \code{cdc} aggregates weekly data into 4-week-counts and computes a normal distribution based upper confidence interval. None of these methods offer the inclusion of a linear trend, down-weighting of past outbreaks or power transformation of the data. Although these methods are nice to have at hand, we recommend using the improved method implemented in the function \code{farringtonFlexible} because it is rather fast and makes use of more historical data than the other methods. \subsection{A Bayesian refinement} The \code{farringtonFlexible} function described previously was a first indication that the \textit{monitoring} of surveillance time series requires a good \textit{modeling} of the time series before assessing aberrations. Generalized linear models (GLMs) and generalized additive models (GAMs) are well-established and powerful modeling frameworks for handling the count data nature and trends of time series in a regression context. The \code{boda} procedure~\citep{Manitz2013} continues this line of thinking by extending the simple GLMs used in the \code{farrington} and \code{farringtonFlexible} procedures to a fully fledged Bayesian GAM allowing for penalized splines, e.g., to describe trends and seasonality, while simultaneously adjusting for previous outbreaks or concurrent processes influencing the case counts. A particular advantage of the Bayesian approach is that it constitutes a seamless framework for performing both estimation and subsequent prediction: the uncertainty in parameter estimation is directly carried forward to the predictive posterior distribution. No asymptotic normal approximations nor plug-in inference is needed. For fast approximate Bayesian inference we use the \pkg{INLA} \proglang{R} package~\citep{INLA} to fit the Bayesian GAM. Still, monitoring with \code{boda} is substantially slower than using the Farrington procedures. Furthermore, detailed regression modeling is only meaningful if the time series is known to be subject to external influences on which information is available. Hence, the typical use at a public health institution would be the detailed analysis of a few selected time series, e.g., critical ones or those with known trend character. As an example, \citet{Manitz2013} studied the influence of absolute humidity on the occurrence of weekly reported campylobacter cases in Germany. \begin{figure} \centering <>= # Load data and create \code{sts}-object data("campyDE") cam.sts <- sts(epoch=campyDE$date, observed=campyDE$case, state=campyDE$state) par(las=1) # Plot y.max <- max(observed(cam.sts),upperbound(cam.sts),na.rm=TRUE) plotOpts3 <- modifyList(plotOpts,list(x=cam.sts,ylab="",legend.opts=NULL,ylim=c(0,y.max),type = observed ~ time),keep.null=TRUE) plotOpts3$xaxis.tickFreq <- list("%m"=atChange,"%G"=atChange) do.call("plot",plotOpts3) par(las=0) #mtext(side=2,text="No. of reports", # las=0,line=3, cex=cex.text,family="Times") par(family="Times") text(-20, 2600, "No. of\n reports", pos = 3, xpd = T,cex=cex.text) text(510, 2900, "Absolute humidity", pos = 3, xpd = T,cex=cex.text) text(510, 2550, expression(paste("[",g/m^3,"]", sep='')), pos = 3, xpd = T,cex=cex.text) lines(campyDE$hum*50, col="white", lwd=2) axis(side=4, at=seq(0,2500,by=500),labels=seq(0,50,by=10),las=1,cex.lab=cex.text, cex=cex.text,cex.axis=cex.text,pos=length(epoch(cam.sts))+20) #mtext(side=4,text=expression(paste("Absolute humidity [ ",g/m^3,"]", sep='')), # las=0,line=1, cex=cex.text,family="Times") @ \caption{Weekly number of reported campylobacteriosis cases in Germany 2002-2011 as vertical bars. In addition, the corresponding mean absolute humidity time series is shown as a white curve.} \label{fig:campyDE} \end{figure} <>= data("campyDE") cam.sts <- sts(epoch = campyDE$date, observed = campyDE$case, state = campyDE$state) plot(cam.sts, col = "mediumblue") lines(campyDE$hum * 50, col = "white", lwd = 2) axis(4, at = seq(0, 2500, by = 500), labels = seq(0, 50, by = 10)) @ The corresponding plot of the weekly time series is shown in Figure~\ref{fig:campyDE}. We observe a strong association between humidity and case numbers - an association which is stronger than with, e.g., temperature or relative humidity. As noted in \citet{Manitz2013} the excess in cases in 2007 is thus partly explained by the high atmospheric humidity. Furthermore, an increase in case numbers during the 2011 STEC O104:H4 outbreak is observed, which is explained by increased awareness and testing of many gastroenteritits pathogens during that period. The hypothesis is thus that there is no actual increased disease activity~\citep{bernard_etal2014}. Unfortunately, the German reporting system only records positive test results without keeping track of the number of actual tests performed -- otherwise this would have been a natural adjustment variable. Altogether, the series contains several artefacts which appear prudent to address when monitoring the campylobacteriosis series. The GAM in \code{boda} is based on the negative binomial distribution with time-varying expectation and time constant overdispersion parameter, i.e., \begin{align*} y_t &\sim \operatorname{NB}(\mu_t,\nu) \end{align*} with $\mu_{t}$ the mean of the distribution and $\nu$ the dispersion parameter~\citep{lawless1987}. Hence, we have $\E(y_t)=\mu_t$ and $\Var(y_t)=\mu_t\cdot(1+\mu_t/\nu)$. The linear predictor is given by \begin{align*} \log(\mu_t) &= \alpha_{0t} + \beta t + \gamma_t + \bm{x}_t^\top \bm{\delta} + \xi z_t, \quad t=1,\ldots,t_0. \end{align*} Here, the time-varying intercept $\alpha_{0t}$ is described by a penalized spline (e.g., first or second order random walk) and $\gamma_t$ denotes a periodic penalized spline (as implemented in \code{INLA}) with period equal to the periodicity of the data. Furthermore, $\beta$ characterizes the effect of a possible linear trend (on the log-scale) and $\xi$ is the effect of previous outbreaks. Typically, $z_t$ is a zero-one process denoting if there was an outbreak in week $t$, but more involved adaptive and non-binary forms are imaginable. Finally, $\bm{x}_t$ denotes a vector of possibly time-varying covariates, which influence the expected number of cases. Data from timepoints $1,\ldots,t_0-1$ are now used to determine the posterior distribution of all model parameters and subsequently the posterior predictive distribution of $y_{t_0}$ is computed. If the actual observed value of $y_{t_0}$ is above the $(1-\alpha)\cdot 100\%$ quantile of the predictive posterior distribution an alarm is flagged for $t_0$. Below we illustrate the use of \code{boda} to monitor the campylobacteriosis time series from 2007. In the first case we include in the model for $\log\left(\mu_t\right)$ penalized splines for trend and seasonality and a simple linear trend. <>= library("INLA") rangeBoda <- which(epoch(cam.sts) >= as.Date("2007-01-01")) control.boda <- list(range = rangeBoda, X = NULL, trend = TRUE, season = TRUE, prior = "iid", alpha = 0.025, mc.munu = 10000, mc.y = 1000, samplingMethod = "marginals") boda <- boda(cam.sts, control = control.boda) @ <>= if (computeALL) { ##hoehle 2018-07-18: changed code to use NICELOOKINGboda, but that's iid. Reason: ##The option 'rw1' currently crashes INLA. <> save(list = c("boda", "control.boda", "rangeBoda"), file = "monitoringCounts-cache/boda.RData") } else { load("monitoringCounts-cache/boda.RData") } @ In the second case we instead use only penalized and linear trend components, and, furthermore, include as covariates lags 1--4 of the absolute humidity as well as zero-one indicators for $t_0$ belonging to the last two weeks (\code{christmas}) or first two weeks (\code{newyears}) of the year, respectively. These covariates shall account for systematically changed reporting behavior at the turn of the year (c.f.\ Figure~\ref{fig:campyDE}). Finally, \code{O104period} is an indicator variable on whether the reporting week belongs to the W21--W30 2011 period of increased awareness during the O104:H4 STEC outbreak. No additional correction for past outbreaks is made. <>= covarNames <- c("l1.hum", "l2.hum", "l3.hum", "l4.hum", "newyears", "christmas", "O104period") control.boda2 <- modifyList(control.boda, list(X = campyDE[, covarNames], season = FALSE)) boda.covars <- boda(cam.sts, control = control.boda2) @ <>= if (computeALL) { <> save(list = c("boda.covars", "covarNames", "control.boda2"), file = "monitoringCounts-cache/boda.covars.RData") } else { load("monitoringCounts-cache/boda.covars.RData") } @ We plot \code{boda.covars} in Figure~\ref{fig:b} and compare the alarms of the two \code{boda} calls with \code{farrington}, \code{farringtonFlexible} and \code{bayes} in Figure~\ref{fig:alarmplot} (plot \code{type = alarm ~ time}). \fbox{\vbox{ Note (2018-07-19): We currently have to use the argument \code{prior = "iid"} in both calls of the \code{boda} function, because the procedure crashes when using recent versions of \pkg{INLA} (\code{>= 17.06.20}) with argument \code{prior = "rw1"}. %(the original results were produced using version 0.0-1458166556, %and version 0.0-1485844051 from 2017-01-31 also works) This means results in this vignette deviate from the results reported in the JSS paper -- in particular we do not get any alarms when using the \code{boda} procedure with covariates. We are looking into the problem. }} Note here that the \code{bayes} procedure is not really useful as the adjustment for seasonality only works poorly. Moreover, we think that this method produces many false alarms for this time series because it disregards the increasing time trend in number of reported cases. Furthermore, it becomes clear that the improved Farrington procedure acts similar to the original procedure, but the improved reweighting and trend inclusion produces fewer alarms. The \code{boda} method is to be seen as a step towards more Bayesian thinking in aberration detection. However, besides its time demands for a detailed modeling, the speed of the procedure is also prohibitive as regards routine application. As a response~\citet{Maelle} introduce a method which has two advantages: it allows to adjust outbreak detection for reporting delays and includes an approximate inference method much faster than the INLA inference method. However, its linear predictor is more in the style of~\citet{Noufaily2012} not allowing for additional covariates or penalized options for the intercept. \begin{figure} \centering <>= y.max <- max(observed(boda.covars),upperbound(boda.covars),na.rm=TRUE) plotOpts2 <- modifyList(plotOpts,list(x=boda.covars,ylim=c(0,y.max)),keep.null=TRUE) plotOpts2$xaxis.tickFreq <- list("%m"=atChange,"%G"=atChange) do.call("plot",plotOpts2) @ <>= plot(boda.covars) @ \caption{Weekly reports of Campylobacter in Germany in 2007-2011 monitored by the boda method with covariates. The line represents the upperbound calculated by the algorithm. Triangles indicate alarms, \textit{i.e.}, timepoints where the observed number of counts is higher than the upperbound.} \label{fig:b} \end{figure} <>= control.far <- list(range=rangeBoda,b=4,w=5,alpha=0.025*2) far <- farrington(cam.sts,control=control.far) #Both farringtonFlexible and algo.bayes uses a one-sided interval just as boda. control.far2 <-modifyList(control.far,list(alpha=0.025)) farflex <- farringtonFlexible(cam.sts,control=control.far2) bayes <- suppressWarnings(bayes(cam.sts,control=control.far2)) @ <>= # Small helper function to combine several equally long univariate sts objects combineSTS <- function(stsList) { epoch <- as.numeric(epoch(stsList[[1]])) observed <- NULL alarm <- NULL for (i in 1:length(stsList)) { observed <- cbind(observed,observed(stsList[[i]])) alarm <- cbind(alarm,alarms(stsList[[i]])) } colnames(observed) <- colnames(alarm) <- names(stsList) res <- sts(epoch=as.numeric(epoch), epochAsDate=TRUE, observed=observed, alarm=alarm) return(res) } @ \begin{figure} \centering <>= # Make an artificial object containing two columns - one with the boda output # and one with the farrington output cam.surv <- combineSTS(list(boda.covars=boda.covars,boda=boda,bayes=bayes, farrington=far,farringtonFlexible=farflex)) par(mar=c(4,8,2.1,2),family="Times") plot(cam.surv,type = alarm ~ time,lvl=rep(1,ncol(cam.surv)), alarm.symbol=list(pch=17, col="red2", cex=1,lwd=3), cex.axis=1,xlab="Time (weeks)",cex.lab=1,xaxis.tickFreq=list("%m"=atChange,"%G"=atChange),xaxis.labelFreq=list("%G"=at2ndChange), xaxis.labelFormat="%G") @ \caption{Alarmplot showing the alarms for the campylobacteriosis time series for four different algorithms.} \label{fig:alarmplot} \end{figure} \subsection{Beyond one-timepoint detection} GLMs as used in the Farrington method are suitable for the purpose of aberration detection since they allow a regression approach for adjusting counts for known phenomena such as trend or seasonality in surveillance data. Nevertheless, the Farrington method only performs one-timepoint detection. In some contexts it can be more relevant to detect sustained shifts early, e.g., an outbreak could be characterized at first by counts slightly higher than usual in subsequent weeks without each weekly count being flagged by one-timepoint detection methods. Control charts inspired by statistical process control (SPC) e.g., cumulative sums would allow the detection of sustained shifts. Yet they were not tailored to the specific characteristics of surveillance data such as overdispersion or seasonality. The method presented in \citet{hoehle.paul2008} conducts a synthesis of both worlds, i.e., traditional surveillance methods and SPC. The method is implemented in the package as the function \code{glrnb}, whose use is explained here. \subsubsection{Definition of the control chart} For the control chart, two distributions are defined, one for each of the two states \textit{in-control} and \textit{out-of-control}, whose likelihoods are compared at each time step. The \textit{in-control} distribution $f_{\bm{\theta}_0}(y_t|\bm{z}_t)$ with the covariates $\bm{z}_t$ is estimated by a GLM of the Poisson or negative binomial family with a log link, depending on the overdispersion of the data. In this context, the standard model for the \textit{in-control} mean is $$\log \mu_{0,t}=\beta_0+\beta_1t+\sum_{s=1}^S\left[\beta_{2s}\cos \left(\frac{2\pi s t}{\mathtt{Period}}\right)+\beta_{2s+1}\sin \left(\frac{2\pi s t}{\mathtt{Period}}\right)\right] $$ where $S$ is the number of harmonic waves to use and \texttt{Period} is the period of the data as indicated in the \code{control} slot, for instance 52 for weekly data. However, more flexible linear predictors, e.g., containing splines, concurrent covariates or an offset could be used on the right hand-side of the equation. The GLM could therefore be made very similar to the one used by~\citet{Noufaily2012}, with reweighting of past outbreaks and various criteria for including the time trend. The parameters of the \textit{in-control} and \textit{out-of-control} models are respectively given by $\bm{\theta}_0$ and $\bm{\theta}_1$. The \textit{out-of-control} mean is defined as a function of the \textit{in-control} mean, either with a multiplicative shift (additive on the log-scale) whose size $\kappa$ can be given as an input or reestimated at each timepoint $t>1$, $\mu_{1,t}=\mu_{0,t}\cdot \exp(\kappa)$, or with an unknown autoregressive component as in \citet{held-etal-2005}, $\mu_{1,t}=\mu_{0,t}+\lambda y_{t-1}$ with unknown $\lambda>0$. In \code{glrnb}, timepoints are divided into two intervals: phase 1 and phase 2. The \textit{in-control} mean and overdispersion are estimated with a GLM fitted on phase 1 data, whereas surveillance operates on phase 2 data. When $\lambda$ is fixed, one uses a likelihood-ratio (LR) and defines the stopping time for alarm as $$N=\min \left\{ t_0 \geq 1 : \max_{1\leq t \leq t_0} \left[ \sum_{s=t}^{t_0} \log\left\{ \frac{f_{\bm{\theta}_1}(y_s|\bm{z}_s)}{f_{\bm{\theta}_0}(y_s|\bm{z}_s)} \right\} \right] \geq \mathtt{c.ARL} \right\},$$ where $\mathtt{c.ARL}$ is the threshold of the CUSUM. When $\lambda$ is unknown and with the autoregressive component one has to use a generalized likelihood ratio (GLR) with the following stopping rule to estimate them on the fly at each time point so that $$N_G=\min \left\{ t_0 \geq 1 : \max_{1\leq t \leq t_0} \sup_{\bm{\theta} \in \bm{\Theta}} \left[ \sum_{s=t}^{t_0} \log\left\{ \frac{f_{\bm{\theta}}(y_s|\bm{z}_s)}{f_{\bm{\theta}_0}(y_s|\bm{z}_s)} \right\} \right] \geq \mathtt{c.ARL} \right\} \,.$$ Thus, one does not make any hypothesis about the specific value of the change to detect, but this GLR is more computationally intensive than the LR. \subsubsection{Practical use} For using \code{glrnb} one has two choices to make. First, one has to choose an \textit{in-control} model that will be fitted on phase 1 data. One can either provide the predictions for the vector of \textit{in-control} means \code{mu0} and the overdispersion parameter \code{alpha} by relying on an external fit, or use the built-in GLM estimator, that will use all data before the beginning of the surveillance range to fit a GLM with the number of harmonics \code{S} and a time trend if \code{trend} is \code{TRUE}. The choice of the exact \textit{in-control} model depends on the data under surveillance. Performing model selection is a compulsory step in practical applications. Then, one needs to tune the surveillance function itself, for one of the two possible change forms, \code{intercept}~or~\code{epi}.~One~can choose either to set \code{theta} to a given value and thus perform LR instead of GLR. The value of \code{theta} has to be adapted to the specific context in which the algorithm is applied: how big are shifts one wants to detect optimally? Is it better not to specify any and use GLR instead? The threshold \texttt{c.ARL} also has to be specified by the user. As explained in \citet{hoehle-mazick-2010} one can compute the threshold for a desired run-length in control through direct Monte Carlo simulation or a Markov chain approximation. Lastly, as mentioned in \citet{hoehle.paul2008}, a window-limited approach of surveillance, instead of looking at all the timepoints until the first observation, can make computation faster. Here we apply \code{glrnb} to the time series of report counts of \textit{Salmonella Newport} in Germany by assuming a known multiplicative shift of factor $2$ and by using the built-in estimator to fit an \textit{in-control} model with one harmonic for seasonality and a trend. This model will be refitted after each alarm, but first we use data from the years before 2011 as reference or \code{phase1}, and the data from 2011 as data to be monitored or \code{phase2}. The threshold \texttt{c.ARL} was chosen to be 4 as we found with the same approach as \citet{hoehle-mazick-2010} that it made the probability of a false alarm within one year smaller than 0.1. Figure~\ref{fig:glrnb}~shows the results of this monitoring. <>= phase1 <- which(isoWeekYear(epoch(salmNewportGermany))$ISOYear < 2011) phase2 <- in2011 control <- list(range = phase2, c.ARL = 4, theta = log(2), ret = "cases", mu0 = list(S = 1, trend = TRUE, refit = FALSE)) salmGlrnb <- glrnb(salmNewportGermany, control = control) @ \begin{figure} \centering <>= y.max <- max(observed(salmGlrnb),upperbound(salmGlrnb),na.rm=TRUE) do.call("plot",modifyList(plotOpts,list(x=salmGlrnb,ylim=c(0,y.max)))) @ \caption{S. Newport in Germany in 2011 monitored by the \texttt{glrnb} function.} \label{fig:glrnb} \end{figure} The implementation of \code{glrnb} on individual time series was already thoroughly explained in \citet{hoehle-mazick-2010}. Our objective in the present document is rather to provide practical tips for the implementation of this function on huge amounts of data in public health surveillance applications. Issues of computational speed become very significant in such a context. Our proposal to reduce the computational burden incurred by this algorithm is to compute the \textit{in-control} model for each time series (pathogen, subtype, subtype in a given location, etc.) only once a year and to use this estimation for the computation of a threshold for each time series. An idea to avoid starting with an initial value of zero in the CUSUM is to use either $\left(\frac{1}{2}\right)\cdot\mathtt{c.ARL}$ as a starting value (fast initial response CUSUM as presented in~\citet{lucas1982fast}) or to let surveillance run with the new \textit{in-control} model during a buffer period and use the resulting CUSUM as an initial value. One could also choose the maximum of these two possible starting values as a starting value. During the buffer period alarms would be generated with the old model. Lastly, using GLR is much more computationally intensive than using LR, whereas LR performs reasonably well on shifts different from the one indicated by \code{theta} as seen in the simulation studies of~\citet{hoehle.paul2008}. Our advice would therefore be to use LR with a reasonable predefined \code{theta}. The amount of historical data used each year to update the model, the length of the buffer period and the value of \code{theta} have to be fixed for each specific application, e.g., using simulations and/or discussion with experts. \subsubsection{Similar methods in the package} The algorithm \code{glrPois} is the same function as \code{glrnb} but for Poisson distributed data. Other CUSUM methods for count data are found in the package: \code{cusum} and \code{rogerson}. Both methods are discussed and compared to \code{glrnb} in \citet{hoehle.paul2008}. The package also includes a semi-parametric method \code{outbreakP} that aims at detecting changes from a constant level to a monotonically increasing incidence, for instance the beginning of the influenza season. See Table~\ref{table:ref} for the corresponding references. \subsection{A method for monitoring categorical data} All monitoring methods presented up to now have been methods for analysing count data. Nevertheless, in public health surveillance one also encounters categorical time series which are time series where the response variable obtains one of $k\geq2$ different categories (nominal or ordinal). When $k=2$ the time series is binary, for instance representing a specific outcome in cases such as hospitalization, death or a positive result to some diagnostic test. One can also think of applications with $k>2$ if one studies, e.g., the age groups of the cases in the context of monitoring a vaccination program: vaccination targeted at children could induce a shift towards older cases which one wants to detect as quickly as possible -- this will be explained thoroughly with an example. The developments of prospective surveillance methods for such categorical time series were up to recently limited to CUSUM-based approaches for binary data such as those explained in~\citet{Chen1978},~\citet{Reynolds2000} and~\citet{rogerson_yamada2004}. Other than being only suitable for binary data these methods have the drawback of not handling overdispersion. A method improving on these two limitations while casting the problem into a more comprehending GLM regression framework for categorical data was presented in~\citet{hoehle2010}. It is implemented as the function \code{categoricalCUSUM}. The way \code{categoricalCUSUM} operates is very similar to what \code{glrnb} does with fixed \textit{out-of-control} parameter. First, the parameters in a multivariate GLM for the \textit{in-control} distribution are estimated from the historical data. Then the \textit{out-of-control} distribution is defined by a given change in the parameters of this GLM, e.g., an intercept change, as explained later. Lastly, prospective monitoring is performed on current data using a likelihood ratio detector which compares the likelihood of the response under the \textit{in-control} and \textit{out-of-control} distributions. \subsubsection{Categorical CUSUM for binomial models} The challenge when performing these steps with categorical data from surveillance systems is finding an appropriate model. Binary GLMs as presented in Chapter~6 of \citet{Fahrmeir.etal2013} could be a solution but they do not tackle well the inherent overdispersion in the binomial time series. Of course one could choose a quasi family but these are not proper statistical distributions making many issues such as prediction complicated. A better alternative is offered by the use of \textit{generalized additive models for location, scale and shape} \citep[GAMLSS,][]{Rigby2005}, that support distributions such as the beta-binomial distribution, suitable for overdispersed binary data. With GAMLSS one can model the dependency of the mean -- \textit{location} -- upon explanatory variables but the regression modeling is also extended to other parameters of the distribution, e.g., scale. Moreover any modelled parameter can be put under surveillance, be it the mean (as in the example later developed) or the time trend in the linear predictor of the mean. This very flexible modeling framework is implemented in \proglang{R} through the \pkg{gamlss} package~\citep{StasJSS}. As an example we consider the time series of the weekly number of hospitalized cases among all \textit{Salmonella} cases in Germany in Jan 2004--Jan 2014, depicted in Figure~\ref{fig:cat1}. We use 2004--2012 data to estimate the \textit{in-control} parameters and then perform surveillance on the data from 2013 and early 2014. We start by preprocessing the data. <>= data("salmHospitalized") isoWeekYearData <- isoWeekYear(epoch(salmHospitalized)) dataBefore2013 <- which(isoWeekYearData$ISOYear < 2013) data2013 <- which(isoWeekYearData$ISOYear == 2013) dataEarly2014 <- which(isoWeekYearData$ISOYear == 2014 & isoWeekYearData$ISOWeek <= 4) phase1 <- dataBefore2013 phase2 <- c(data2013, dataEarly2014) salmHospitalized.df <- cbind(as.data.frame(salmHospitalized), weekNumber = isoWeekYearData$ISOWeek) names(salmHospitalized.df) <- c("y", "t", "state", "alarm", "upperbound", "n", "freq", "epochInPeriod", "weekNumber") @ We assume that the number of hospitalized cases follows a beta-binomial distribution, i.e., $ y_t \sim \BetaBin(n_t,\pi_t,\sigma_t)$ with $n_t$ the total number of reported cases at time $t$, $\pi_t$ the proportion of these cases that were hospitalized and $\sigma$ the dispersion parameter. In this parametrization, $$E(y_t)=n_t \pi_t,\quad \text{and}$$ $$\Var(y_t)=n_t \pi_t(1-\pi_t)\left( 1 + \frac{\sigma(n_t-1)}{\sigma+1} \right) \,.$$ We choose to model the expectation $n_t \pi_t$ using a beta-binomial model with a logit-link which is a special case of a GAMLSS, i.e., $$\logit(\pi_t)=\bm{z}_t^\top\bm{\beta}$$ where $\bm{z}_t$ is a vector of possibly time-varying covariates and $\bm{\beta}$ a vector of covariate effects in our example. \begin{figure} \centering <>= y.max <- max(observed(salmHospitalized)/population(salmHospitalized),upperbound(salmHospitalized)/population(salmHospitalized),na.rm=TRUE) plotOpts2 <- modifyList(plotOpts,list(x=salmHospitalized,legend.opts=NULL,ylab="",ylim=c(0,y.max)),keep.null=TRUE) plotOpts2$xaxis.tickFreq <- list("%G"=atChange,"%m"=atChange) plotOpts2$par.list <- list(mar=c(6,5,5,5),family="Times",las=1) do.call("plot",plotOpts2) lines(salmHospitalized@populationFrac/4000,col="grey80",lwd=2) lines(campyDE$hum*50, col="white", lwd=2) axis(side=4, at=seq(0,2000,by=500)/4000,labels=as.character(seq(0,2000,by=500)),las=1, cex=2,cex.axis=1.5,pos=length(observed(salmHospitalized))+20) par(family="Times") text(-20, 0.6, "Proportion", pos = 3, xpd = T,cex=cex.text) text(520, 0.6, "Total number of \n reported cases", pos = 3, xpd = T,cex=cex.text) @ \caption{Weekly proportion of Salmonella cases that were hospitalized in Germany 2004-2014. In addition the corresponding number of reported cases is shown as a light curve.} \label{fig:cat1} \end{figure} The proportion of hospitalized cases varies throughout the year as seen in Figure~\ref{fig:cat1}. One observes that in the summer the proportion of hospitalized cases is smaller than in other seasons. However, over the holidays in December the proportion of hospitalized cases increases. Note that the number of non-hospitalized cases drops while the number of hospitalized cases remains constant (data not shown): this might be explained by the fact that cases that are not serious enough to go to the hospital are not seen by general practitioners because sick workers do not need a sick note during the holidays. Therefore, the \textit{in-control} model should contain these elements, as well as the fact that there is an increasing trend of the proportion because GPs prescribe less and less stool diagnoses so that more diagnoses are done on hospitalized cases. We choose a model with an intercept, a time trend, two harmonic terms and a factor variable for the first two weeks of each year. The variable \code{epochInPeriod} takes into account the fact that not all years have 52 weeks. <>= vars <- c( "y", "n", "t", "epochInPeriod", "weekNumber") m.bbin <- gamlss(cbind(y, n-y) ~ 1 + t + sin(2 * pi * epochInPeriod) + cos(2 * pi * epochInPeriod) + sin(4 * pi * epochInPeriod) + cos(4 * pi * epochInPeriod) + I(weekNumber == 1) + I(weekNumber == 2), sigma.formula =~ 1, family = BB(sigma.link = "log"), data = salmHospitalized.df[phase1, vars]) @ The change we aim to detect is defined by a multiplicative change of odds, from $\frac{\pi_t^0}{(1-\pi_t^0)}$ to $R\cdot\frac{\pi_t^0}{(1-\pi_t^0)}$ with $R>0$, similar to what was done in~\citet{Steiner1999} for the logistic regression model. This is equivalent to an additive change of the log-odds, $$\logit(\pi_t^1)=\logit(\pi_t^0)+\log R$$ with $\pi_t^0$ being the \textit{in-control} proportion and $\pi_t^1$ the \textit{out-of-control} distribution. The likelihood ratio based CUSUM statistic is now defined as $$C_{t_0}=\max_{1\leq t \leq {t_0}}\left( \sum_{s=t}^{t_0} \log \left( \frac{f(y_s;\bm{z}_s,\bm{\theta}_1)}{f(y_s;\bm{z}_s,\bm{\theta}_0)} \right) \right)$$ with $\bm{\theta}_0$ and $\bm{\theta}_1$ being the vector in- and \textit{out-of-control} parameters, respectively. Given a threshold \code{h}, an alarm is sounded at the first time when $C_{t_0}>\mathtt{h}$. We set the parameters of the \code{categoricalCUSUM} to optimally detect a doubling of the odds in 2013 and 2014, i.e., $R=2$. Furthermore, we for now set the threshold of the CUSUM at $h=2$. We use the GAMLSS to predict the mean of the \textit{in-control} and \textit{out-of-control} distributions and store them into matrices with two columns among which the second one represents the reference category. <>= R <- 2 h <- 2 pi0 <- predict(m.bbin, newdata = salmHospitalized.df[phase2, vars], type = "response") pi1 <- plogis(qlogis(pi0) + log(R)) pi0m <- rbind(pi0, 1 - pi0) pi1m <- rbind(pi1, 1 - pi1) @ Note that the \code{categoricalCUSUM} function is constructed to operate on the observed slot of \code{sts}-objects which have as columns the number of cases in each category at each timepoint, \textit{i.e.}, each row of the observed slot contains the elements $(y_{t1},...,y_{tk})$. <>= populationHosp <- unname(cbind( population(salmHospitalized), population(salmHospitalized))) observedHosp <- cbind( "Yes" = as.vector(observed(salmHospitalized)), "No" = as.vector(population(salmHospitalized) - observed(salmHospitalized))) salmHospitalized.multi <- sts( frequency = 52, start = c(2004, 1), epoch = epoch(salmHospitalized), observed = observedHosp, population = populationHosp, multinomialTS = TRUE) @ Furthermore, one needs to define a wrapper for the distribution function in order to have an argument named \code{"mu"} in the function. <>= dBB.cusum <- function(y, mu, sigma, size, log = FALSE) { dBB(if (is.matrix(y)) y[1,] else y, if (is.matrix(y)) mu[1,] else mu, sigma = sigma, bd = size, log = log) } @ After these preliminary steps, the monitoring can be performed. <>= controlCat <- list(range = phase2, h = 2, pi0 = pi0m, pi1 = pi1m, ret = "cases", dfun = dBB.cusum) salmHospitalizedCat <- categoricalCUSUM( salmHospitalized.multi, control = controlCat, sigma = exp(m.bbin$sigma.coefficients)) @ The results can be seen in Figure~\ref{fig:catDouble}(a). With the given settings, there are alarms at week 16 in 2004 and at week 3 in 2004. The one in 2014 corresponds to the usual peak of the beginning of the year, which was larger than expected this year, maybe because the weekdays of the holidays were particularly worker-friendly so that sick notes were even less needed. The value for the threshold \code{h} can be determined following the procedures presented in \citet{hoehle-mazick-2010} for count data, and as in the code exhibited below. Two methods can be used for determining the probability of a false alarm within a pre-specified number of steps for a given value of the threshold \code{h}: a Monte Carlo method relying on, e.g., 1000 simulations and a Markov Chain approximation of the CUSUM. The former is much more computationally intensive than the latter: with the code below, the Monte Carlo method needed approximately 300 times more time than the Markov Chain method. Since both results are close we recommend the Markov Chain approximation for practical use. The Monte Carlo method works by sampling observed values from the estimated distribution and performing monitoring with \code{categoricalCUSUM} on this \code{sts} object. As observed values are estimated from the \textit{in-control} distribution every alarm thus obtained is a false alarm so that the simulations allow to estimate the probability of a false alarm when monitoring \textit{in-control} data over the timepoints of \code{phase2}. The Markov Chain approximation introduced by \citet{brook_evans1972} is implemented as \code{LRCUSUM.runlength} which is already used for \code{glrnb}. Results from both methods can be seen in Figure~\ref{fig:catDouble}(b). We chose a value of 2 for \code{h} so that the probability of a false alarm within the 56 timepoints of \code{phase2} is less than $0.1$. One first has to set the values of the threshold to be investigated and to prepare the function used for simulation, that draws observed values from the \textit{in-control} distribution and performs monitoring on the corresponding time series, then indicating if there was at least one alarm. Then 1000 simulations were performed with a fixed seed value for the sake of reproducibility. Afterwards, we tested the Markov Chain approximation using the function \code{LRCUSUM.runlength} over the same grid of values for the threshold. <<>>= h.grid <- seq(1, 10, by = 0.5) @ <>= simone <- function(sts, h) { y <- rBB(length(phase2), mu = pi0m[1, , drop = FALSE], bd = population(sts)[phase2, ], sigma = exp(m.bbin$sigma.coefficients), fast = TRUE) observed(sts)[phase2, ] <- cbind(y, population(sts)[phase2, 1] - y) one.surv <- categoricalCUSUM( sts, control = modifyList(controlCat, list(h = h)), sigma = exp(m.bbin$sigma.coefficients)) return(any(alarms(one.surv)[, 1])) } set.seed(123) nSims <- 1000 pMC <- sapply(h.grid, function(h) { mean(replicate(nSims, simone(salmHospitalized.multi, h))) }) pMarkovChain <- sapply(h.grid, function(h) { TA <- LRCUSUM.runlength(mu = pi0m[1,,drop = FALSE], mu0 = pi0m[1,,drop = FALSE], mu1 = pi1m[1,,drop = FALSE], n = population(salmHospitalized.multi)[phase2, ], h = h, dfun = dBB.cusum, sigma = exp(m.bbin$sigma.coef)) return(tail(TA$cdf, n = 1)) }) @ <>= if (computeALL) { <> save(pMC, file = "monitoringCounts-cache/pMC.RData") save(pMarkovChain, file = "monitoringCounts-cache/pMarkovChain.RData") } else { load("monitoringCounts-cache/pMC.RData") load("monitoringCounts-cache/pMarkovChain.RData") } @ \begin{figure} \subfloat[]{ <>= y.max <- max(observed(salmHospitalizedCat[,1])/population(salmHospitalizedCat[,1]),upperbound(salmHospitalizedCat[,1])/population(salmHospitalizedCat[,1]),na.rm=TRUE) plotOpts3 <- modifyList(plotOpts,list(x=salmHospitalizedCat[,1],ylab="Proportion",ylim=c(0,y.max))) plotOpts3$legend.opts <- list(x="top",bty="n",legend=c(expression(U[t])),lty=1,lwd=line.lwd,col=plotOpts$alarm.symbol$col,horiz=TRUE,cex=cex.text) do.call("plot",plotOpts3) @ <>= plot(salmHospitalizedCat[,1]) @ } \subfloat[]{ <>= par(mar=c(6,5,5,5),family="Times") matplot(h.grid, cbind(pMC,pMarkovChain),type="l",ylab=expression(P(T[A] <= 56 * "|" * tau * "=" * infinity)),xlab="Threshold h",col=1,cex.axis=cex.text,cex.lab=cex.text) prob <- 0.1 lines(range(h.grid),rep(prob,2),lty=5,lwd=2) par(family="Times") legend(4,0.08,c("Monte Carlo","Markov chain"), lty=1:2,col=1,cex=cex.text,bty="n") @ <>= matplot(h.grid, cbind(pMC, pMarkovChain), type="l", lty=1:2, col=1) abline(h=0.1, lty=5) legend("center", c("Monte Carlo","Markov chain"), lty=1:2, bty="n") @ } \caption{(a) Results of the monitoring with categorical CUSUM of the proportion of Salmonella cases that were hospitalized in Germany in Jan 2013 - Jan 2014. (b) Probability of a false alarm within the 56 timepoints of the monitoring as a function of the threshold $h$.} \label{fig:catDouble} \end{figure} The procedure for using the function for multicategorical variables follows the same steps (as illustrated later). Moreover, one could expand the approach to utilize the multiple regression possibilities offered by GAMLSS. Here we chose to try to detect a change in the mean of the distribution of counts but as GAMLSS provides more general regression tools than GLM we could also aim at detecting a change in the time trend included in the model for the mean. \subsubsection{Categorical CUSUM for multinomial models} In order to illustrate the use of \code{categoricalCUSUM} for more than two classes we analyse the monthly number of rotavirus cases in the federal state Brandenburg during 2002-2013 and which are stratified into the five age-groups 00-04, 05-09, 10-14, 15-69, 70+ years. In 2006 two rotavirus vaccines were introduced, which are administered in children at the age of 4--6 months. Since then, coverage of these vaccination has steadily increased and interest is to detect possible age-shifts in the distribution of cases. <>= data("rotaBB") plot(rotaBB) @ \begin{figure} \centering <>= par(mar=c(5.1,20.1,4.1,0),family="Times") plot(rotaBB,xlab="Time (months)",ylab="", col="mediumblue",cex=cex.text,cex.lab=cex.text,cex.axis=cex.text,cex.main=cex.text, xaxis.tickFreq=list("%G"=atChange), xaxis.labelFreq=list("%G"=at2ndChange), xaxis.labelFormat="%G") par(las=0,family="Times") mtext("Proportion of reported cases", side=2, line=19, cex=1) @ \caption{Monthly proportions in five age-groups for the reported rotavirus cases in Brandenburg, Germany, \Sexpr{paste(format(range(epoch(rotaBB)),"%Y"),collapse="-")}.} \label{fig:vac} \end{figure} From Figure~\ref{fig:vac} we observe a shift in proportion away from the very young. However, interpreting the proportions only makes sense in combination with the absolute numbers. In these plots (not shown) it becomes clear that the absolute numbers in the 0--4 year old have decreased since 2009. However, in the 70+ group a small increase is observed with 2013 by far being the strongest season so far. Hence, our interest is in prospectively detecting a possible age-shift. Since the vaccine was recommended for routine vaccination in Brandenburg in 2009 we choose to start the monitoring at that time point. We do so by fitting a multinomial logit-model containing a trend as well as one harmonic wave and use the age group 0--4 years as reference category, to the data from the years 2002-2008. Different \proglang{R} packages implement such type of modeling, but we shall use the \pkg{MGLM} package~\citep{MGLM}, because it also offers the fitting of extended multinomial regression models allowing for extra dispersion. <<>>= rotaBB.df <- as.data.frame(rotaBB) X <- with(rotaBB.df, cbind(intercept = 1, epoch, sin1 = sin(2 * pi * epochInPeriod), cos1 = cos(2 * pi * epochInPeriod))) phase1 <- epoch(rotaBB) < as.Date("2009-01-01") phase2 <- !phase1 library("MGLM") ## MGLMreg automatically takes the last class as ref so we reorder order <- c(2:5, 1); reorder <- c(5, 1:4) m0 <- MGLMreg(as.matrix(rotaBB.df[phase1, order]) ~ -1 + X[phase1, ], dist = "MN") @ As described in \citet{hoehle2010} we can try to detect a specific shift in the intercept coefficients of the model. For example, a multiplicative shift of factor 2 in the example below, in the odds of each of the four age categories against the reference category is modelled by changing the intercept value of each category. Based on this, the \textit{in-control} and \textit{out-of-control} proportions are easily computed using the \code{predict} function for \code{MGLMreg} objects. <<>>= m1 <- m0 m1@coefficients[1, ] <- m0@coefficients[1, ] + log(2) pi0 <- t(predict(m0, newdata = X[phase2, ])[, reorder]) pi1 <- t(predict(m1, newdata = X[phase2, ])[, reorder]) @ For applying the \code{categoricalCUSUM} function one needs to define a compatible wrapper function for the multinomial as in the binomial example. With $\bm{\pi}^0$ and $\bm{\pi}^1$ in place one only needs to define a wrapper function, which defines the PMF of the sampling distribution -- in this case the multinomial -- in a \code{categoricalCUSUM} compatible way. <>= dfun <- function(y, size, mu, log = FALSE) { dmultinom(x = y, size = size, prob = mu, log = log) } h <- 2 # threshold for the CUSUM statistic control <- list(range = seq(nrow(rotaBB))[phase2], h = h, pi0 = pi0, pi1 = pi1, ret = "value", dfun = dfun) surv <- categoricalCUSUM(rotaBB,control=control) @ <>= alarmDates <- epoch(surv)[which(alarms(surv)[,1])] format(alarmDates,"%b %Y") @ <>= #Number of MC samples nSamples <- 1e4 #Do MC simone.stop <- function(sts, control) { phase2Times <- seq(nrow(sts))[phase2] #Generate new phase2 data from the fitted in control model y <- sapply(1:length(phase2Times), function(i) { rmultinom(n=1, prob=pi0[,i],size=population(sts)[phase2Times[i],1]) }) observed(sts)[phase2Times,] <- t(y) one.surv <- categoricalCUSUM(sts, control=control) #compute P(S<=length(phase2)) return(any(alarms(one.surv)[,1]>0)) } set.seed(1233) rlMN <- replicate(nSamples, simone.stop(rotaBB, control=control)) mean(rlMN) # 0.5002 @ The resulting CUSUM statistic $C_t$ as a function of time is shown in Figure~\ref{fig:ct}(a). The first time an aberration is detected is July 2009. Using 10000 Monte Carlo simulations we estimate that with the chosen threshold $h=2$ the probability for a false alarm within the 60 time points of \code{phase2} is 0.02. As the above example shows, the LR based categorical CUSUM is rather flexible in handling any type of multivariate GLM modeling to specify the \textit{in-control} and \textit{out-of-control} proportions. However, it requires a direction of the change to be specified -- for which detection is optimal. One sensitive part of such monitoring is the fit of the multinomial distribution to a multivariate time series of proportions, which usually exhibit extra dispersion when compared to the multinomial. For example comparing the AIC between the multinomial logit-model and a Dirichlet-multinomial model with $\alpha_{ti} = \exp(\bm{x}_t^\top\bm{\beta})$~\citep{MGLM} shows that overdispersion is present. The Dirichlet distribution is the multicategorical equivalent of the beta-binomial distribution. We exemplify its use in the code below. <<>>= m0.dm <- MGLMreg(as.matrix(rotaBB.df[phase1, 1:5]) ~ -1 + X[phase1, ], dist = "DM") c(m0@AIC, m0.dm@AIC) @ Hence, the above estimated false alarm probability might be too low for the actual monitoring problem, because the variation in the time series is larger than implied by the multinomial. Hence, it appears prudent to repeat the analysis using the more flexible Dirichlet-multinomial model. This is straightforward with \code{categoricalCUSUM} once the \textit{out-of-control} proportions are specified in terms of the model. Such a specification is, however, hampered by the fact that the two models use different parametrizations. For performing monitoring in this new setting we first need to calculate the $\alpha$'s of the multinomial-Dirichlet for the \textit{in-control} and \textit{out-of-control} distributions. <<>>= ## Change intercept in the first class (for DM all 5 classes are modeled) delta <- 2 m1.dm <- m0.dm m1.dm@coefficients[1, ] <- m0.dm@coefficients[1, ] + c(-delta, rep(delta/4, 4)) alpha0 <- exp(X[phase2,] %*% m0.dm@coefficients) alpha1 <- exp(X[phase2,] %*% m1.dm@coefficients) dfun <- function(y, size, mu, log = FALSE) { dLog <- ddirmn(t(y), t(mu)) if (log) dLog else exp(dLog) } h <- 2 control <- list(range = seq(nrow(rotaBB))[phase2], h = h, pi0 = t(alpha0), pi1 = t(alpha1), ret = "value", dfun = dfun) surv.dm <- categoricalCUSUM(rotaBB, control = control) @ <>= matplot(alpha0/rowSums(alpha0),type="l",lwd=3,lty=1,ylim=c(0,1)) matlines(alpha1/rowSums(alpha1),type="l",lwd=1,lty=2) @ \begin{figure} \subfloat[]{ <>= surv@observed[,1] <- 0 surv@multinomialTS <- FALSE surv.dm@observed[,1] <- 0 surv.dm@multinomialTS <- FALSE y.max <- max(observed(surv.dm[,1]),upperbound(surv.dm[,1]),observed(surv[,1]),upperbound(surv[,1]),na.rm=TRUE) plotOpts3 <- modifyList(plotOpts,list(x=surv[,1],ylim=c(0,y.max),ylab=expression(C[t]),xlab="")) plotOpts3$legend.opts <- list(x="topleft",bty="n",legend="R",lty=1,lwd=line.lwd,col=plotOpts$alarm.symbol$col,horiz=TRUE,cex=cex.text) do.call("plot",plotOpts3) abline(h=h, lwd=2, col="darkgrey") par(family="Times") mtext(side=1,text="Time (weeks)", las=0,line=3, cex=cex.text) @ } \subfloat[]{ <>= plotOpts3$x <- surv.dm[,1] do.call("plot",plotOpts3) abline(h=h, lwd=2, col="darkgrey") par(family="Times") mtext(side=1,text="Time (weeks)", las=0,line=3, cex=cex.text) @ } \caption{Categorical CUSUM statistic $C_t$. Once $C_t>\Sexpr{h}$ an alarm is sounded and the statistic is reset. In (a) surveillance uses the multinomial distribution and in (b) surveillance uses the Dirichlet-multinomial distribution.} \label{fig:ct} \end{figure} <>= par(mfrow = c(1,2)) surv@multinomialTS <- surv.dm@multinomialTS <- FALSE # trick plot method ... plot(surv[,1], col=c(NA,NA,4), ylab = expression(C[t]), ylim = c(0,33), xaxis.tickFreq=list("%Y"=atChange, "%m"=atChange), xaxis.labelFreq=list("%Y"=atMedian), xaxis.labelFormat="%Y") abline(h=h, lwd=2, col="darkgrey") plot(surv.dm[,1], col=c(NA,NA,4), ylab = expression(C[t]), ylim = c(0,33), xaxis.tickFreq=list("%Y"=atChange, "%m"=atChange), xaxis.labelFreq=list("%Y"=atMedian), xaxis.labelFormat="%Y") abline(h=h, lwd=2, col="darkgrey") @ The resulting CUSUM statistic $C_t$ using the Dirichlet multinomial distribution is shown in Figure~\ref{fig:ct}(b). We notice a rather similar behavior even though the shift-type specified by this model is slightly different than in the model of Figure~\ref{fig:ct}(a). \subsubsection{Categorical data in routine surveillance} The multidimensionality of data available in public health surveillance creates many opportunities for the analysis of categorical time series, for example: sex ratio of cases of a given disease, age group distribution, regions sending data, etc. If one is interested in monitoring with respect to a categorical variable, a choice has to be made between monitoring each time series individually, for instance a time series of \textit{Salmonella} cases for each age group, or monitoring the distribution of cases with respect to that factor jointly \textit{via} \code{categoricalCUSUM}. A downside of the latter solution is that one has to specify the change parameter \code{R} in advance, which can be quite a hurdle if one has no pre-conceived idea of what could happen for, say, the age shift after the introduction of a vaccine. Alternatively, one could employ an ensemble of monitors or monitor an aggregate. However, more straightforward applications could be found in the (binomial) surveillance of positive diagnostics given laboratory test data and not only data about confirmed cases. An alternative would be to apply \code{farringtonFlexible} while using the number of tests as \code{populationOffset}. \subsubsection{Similar methods in the package} The package also offers another CUSUM method suitable for binary data, \code{pairedbinCUSUM} that implements the method introduced by~\citet{Steiner1999}, which does not, however, take overdispersion into account as well as \code{glrnb}. The algorithm \code{rogerson} also supports the analysis of binomial data. See Table~\ref{table:ref} for the corresponding references. \subsection{Other algorithms implemented in the package} We conclude this description of surveillance methods by giving an overview of all algorithms implemented in the package in Table~\ref{table:ref}. Please see the cited articles or the package manual for more information about each method. Criteria for choosing a method in practice are numerous. First one needs to ponder on the amount of historical data at hand -- for instance the EARS methods only need data for the last timepoints whereas the Farrington methods use data up to $b$ years in the past. Then one should consider the amount of past data used by the algorithm -- historical reference methods use only a subset of the past data, namely the timepoints located around the same timepoint in the past years, whereas other methods use all past data included in the reference data. This can be a criterion of choice since one can prefer using all available data. It is also important to decide whether one wants to detect one-timepoint aberration or more prolonged shifts. And lastly, an important criterion is how much work needs to be done for finetuning the algorithm for each specific time series. The package on the one hand provides the means for analysing nearly all type of surveillance data and on the other hand makes the comparison of algorithms possible. This is useful in practical applications when those algorithms are implemented into routine use, which will be the topic of Section~\ref{sec:routine}. \begin{table}[t!] \centering \begin{tabular}{lp{11cm}} \toprule Function & References \\ \midrule \code{bayes} & \citet{riebler2004} \\ \code{boda} & \citet{Manitz2013} \\ \code{bodaDelay} & \citet{Maelle} \\ \code{categoricalCUSUM} & \citet{hoehle2010}\\ \code{cdc} & \citet{stroup89,farrington2003} \\ \code{cusum} & \citet{rossi_etal99,pierce_schafer86} \\ \code{earsC} & \citet{SIM:SIM3197} \\ \code{farrington} & \citet{farrington96} \\ \code{farringtonFlexible} & \citet{farrington96,Noufaily2012} \\ \code{glrnb} & \citet{hoehle.paul2008} \\ \code{glrpois} & \citet{hoehle.paul2008} \\ \code{outbreakP} & \citet{frisen_etal2009,fri2009} \\ \code{pairedbinCUSUM} & \citet{Steiner1999} \\ \code{rki} & Not available -- unpublished \\ \code{rogerson} & \citet{rogerson_yamada2004} \\ \bottomrule \end{tabular} \caption{Algorithms for aberration detection implemented in \pkg{surveillance}.} \label{table:ref} \end{table} \section[Implementing surveillance in routine monitoring]{Implementing \pkg{surveillance} in routine monitoring} \label{sec:routine} \label{sec:3} Combining \pkg{surveillance} with other \proglang{R} packages and programs is easy, allowing the integration of the aberration detection into a comprehensive surveillance system to be used in routine practice. In our opinion, such a surveillance system has to at least support the following process: loading data from local databases, analysing them within \pkg{surveillance} and sending the results of this analysis to the end-user who is typically an epidemiologist in charge of the specific pathogen. This section exemplifies the integration of the package into a whole analysis stack, first through the introduction of a simple workflow from data query to a \code{Sweave}~\citep{sweave} or \pkg{knitr}~\citep{knitr} report of signals, and secondly through the presentation of the more elaborate system in use at the German Robert Koch Institute. \subsection{A simple surveillance system} Suppose you have a database with surveillance time series but little resources to build a surveillance system encompassing all the above stages. Using \proglang{R} and \code{Sweave} or \code{knitr} for \LaTeX~you can still set up a simple surveillance analysis without having to do everything by hand. You only need to import the data into \proglang{R} and create \code{sts} objects for each time series of interest as explained thoroughly in~\citet{hoehle-mazick-2010}. Then, calling a surveillance algorithm, say \code{farringtonFlexible}, with an appropriate \code{control} argument gives an \code{sts} object with upperbounds and alarms over \code{control$range}. To define the range automatically one could use the \proglang{R} function \code{Sys.Date()} to get today's date. These steps can be introduced as a code chunk in a \code{Sweave} or \code{knitr} code that will translate it into a report that you can send to the epidemiologists in charge of the respective pathogen whose cases are monitored. Below is an example of a short code segment showing the analysis of the \textit{S. Newport} weekly counts in the German federal states Baden-W\"{u}rttemberg and North Rhine-Westphalia using the improved method implemented in \code{farringtonFlexible}. The package provides a \code{toLatex} method for \code{sts} objects that produces a table of the observed counts and upperbound values for each unit; alarms are highlighted by default. The result is shown in Table~\ref{tableResults}. <<>>= today <- which(epoch(salmNewport) == as.Date("2013-12-23")) rangeAnalysis <- (today - 4):today in2013 <- which(isoWeekYear(epoch(salmNewport))$ISOYear == 2013) algoParameters <- list(range = rangeAnalysis, noPeriods = 10, populationBool = FALSE, b = 4, w = 3, weightsThreshold = 2.58, pastWeeksNotIncluded = 26, pThresholdTrend = 1, thresholdMethod = "nbPlugin", alpha = 0.05, limit54 = c(0, 50)) results <- farringtonFlexible(salmNewport[, c("Baden.Wuerttemberg", "North.Rhine.Westphalia")], control = algoParameters) @ <>= start <- isoWeekYear(epoch(salmNewport)[min(rangeAnalysis)]) end <- isoWeekYear(epoch(salmNewport)[max(rangeAnalysis)]) caption <- paste0("Results of the analysis of reported S. Newport ", "counts in two German federal states for the weeks ", start$ISOYear, "-W", start$ISOWeek, " to ", end$ISOYear, "-W", end$ISOWeek, ". Bold red counts indicate weeks with alarms.") toLatex(results, caption = caption, label = "tableResults", ubColumnLabel = "Threshold", include.rownames = FALSE, sanitize.text.function = identity) @ The advantage of this approach is that it can be made automatic. The downside of such a system is that the report is not interactive, for instance one cannot click on the cases and get the linelist. Nevertheless, this is a workable solution in many cases -- especially when human and financial resources are narrow. In the next section, we present a more advanced surveillance system built on the package. \subsection{Automatic detection of outbreaks at the Robert Koch Institute} \label{sec:RKI} The package \pkg{surveillance} was used as a core building block for designing and implementing the automated outbreak detection system at the RKI in Germany~\citep{Dirk}. The text below describes the system as it was in early 2014. Due to the Infection Protection Act (IfSG) the RKI daily receives over 1,000 notifiable disease reports. The system analyses about half a million time series per day to identify possible aberrations in the reported number of cases. Structurally, it consists of two components: an analytical process written in \proglang{R} that daily monitors the data and a reporting component that compiles and communicates the results to the epidemiologists. The analysis task in the described version of the system relied on \pkg{surveillance} and three other \proglang{R} packages, namely \pkg{data.table}, \pkg{RODBC} and \pkg{testthat} as described in the following. The data-backend is an OLAP-system~\citep{SSAS} and relational databases, which are queried using \pkg{RODBC}~\citep{rodbc2013}. The case reports are then rapidly aggregated into univariate time series using \pkg{data.table}~\citep{datatable2013}. To each time series we apply the \code{farringtonFlexible} algorithm on univariate \code{sts} objects and store the analysis results in another SQL-database. We make intensive use of \pkg{testthat}~\citep{testthat2013} for automatic testing of the component. Although \proglang{R} is not the typical language to write bigger software components for production, choosing \proglang{R} in combination with \pkg{surveillance} enabled us to quickly develop the analysis workflow. We can hence report positive experience using \proglang{R} also for larger software components in production. The reporting component was realized using Microsoft Reporting Services~\citep{SSRS}, because this technology is widely used within the RKI. It allows quick development of reports and works well with existing Microsoft Office tools, which the end-user, the epidemiologist, is used to. For example, one major requirement by the epidemiologists was to have the results compiled as Excel documents. Moreover, pathogen-specific reports are automatically sent once a week by email to epidemiologists in charge of the respective pathogen. Having state-of-the-art detection methods already implemented in \pkg{surveillance} helped us to focus on other challenges during development, such as bringing the system in the organization's workflow and finding ways to efficiently and effectively analyse about half a million of time series per day. In addition, major developments in the \proglang{R} component can be shared with the community and are thus available to other public health institutes as well. \section{Discussion} \label{sec:4} The \proglang{R} package \pkg{surveillance} was initially created as an implementational framework for the development and the evaluation of outbreak detection algorithms in routine collected public health surveillance data. Throughout the years it has more and more also become a tool for the use of surveillance in routine practice. The presented description aimed at showing the potential of the package for aberration detection. Other functions offered by the package for modeling~\citep{meyer.etal2014}, nowcasting~\citep{hoehle-heiden} or back-projection of incidence cases~\citep{becker_marschner93} are documented elsewhere and contribute to widening the scope of possible analysis in infectious disease epidemiology when using \pkg{surveillance}. Future areas of interest for the package are, e.g., to better take into account the multivariate and hierarchical structure of the data streams analysed. Another important topic is the adjustment for reporting delays when performing the surveillance~\citep{Maelle}. The package can be obtained from CRAN and resources for learning its use are listed in the documentation section of the project (\url{https://surveillance.R-Forge.R-project.org/}). As all \proglang{R} packages, \pkg{surveillance} is distributed with a manual describing each function with corresponding examples. The manual, the present article and two previous ones~\citep{hoehle-2007, hoehle-mazick-2010} form a good basis for getting started with the package. The data and analysis of the present manuscript are accessible as the vignette \texttt{"monitoringCounts.Rnw"} in the package. Since all functionality is available just at the cost of learning \proglang{R} we hope that parts of the package can be useful in health facilities around the world. Even though the package is tailored for surveillance in public health contexts, properties such as overdispersion, low counts, presence of past outbreaks, apply to a wide range of count and categorical time series in other surveillance contexts such as financial surveillance~\citep{frisen2008financial}, occupational safety monitoring~\citep{accident} or environmental surveillance~\citep{Radio}. Other \proglang{R} packages can be worth of interest to \pkg{surveillance} users. Statistical process control is offered by two other packages, \pkg{spc}~\citep{spc} and \pkg{qcc}~\citep{qcc}. The package \pkg{strucchange} allows detecting structural changes in general parametric models including GLMs~\citep{strucchange}, while the package \pkg{tscount} provides methods for regression and (retrospective) intervention analysis for count time series based on GLMs~\citep{tscount, liboschik_tscount_2015} . For epidemic modelling and outbreaks, packages such as \pkg{EpiEstim}~\citep{EpiEstim}, \pkg{outbreaker}~\citep{outbreaker} and \pkg{OutbreakTools}~\citep{OutbreakTools} offer good functionalities for investigating outbreaks that may for instance have been detected through to the use of \pkg{surveillance}. They are listed on the website of the \textit{\proglang{R}-epi project} (\url{https://sites.google.com/site/therepiproject}) that was initiated for compiling information about \proglang{R} tools useful for infectious diseases epidemiology. Another software of interest for aberration detection is \pkg{SaTScan}~\citep{SaTScan} which allows the detection of spatial, temporal and space-time clusters of events -- note that it is not a \proglang{R} package. Code contributions to the package are very welcome as well as feedback and suggestions for improving the package. \section*{Acknowledgments} The authors would like to express their gratitude to all contributors to the package, in particular Juliane Manitz, University of G\"{o}ttingen, Germany, for her work on the \texttt{boda} code, and Angela Noufaily, The Open University, Milton Keynes, UK, for providing us with the code used in her article that we extended for \texttt{farringtonFlexible}. The work of M. Salmon was financed by a PhD grant of the RKI. \bibliography{monitoringCounts,references} \end{document} surveillance/inst/doc/surveillance.R0000644000176200001440000001602614615167542017327 0ustar liggesusers### R code from vignette source 'surveillance.Rnw' ################################################### ### code chunk number 1: setup ################################################### library("surveillance") options(SweaveHooks=list(fig=function() par(mar=c(4,4,2,0)+.5))) options(width=70) ## create directory for plots dir.create("plots", showWarnings=FALSE) ###################################################################### #Do we need to compute or can we just fetch results ###################################################################### CACHEFILE <- "surveillance-cache.RData" compute <- !file.exists(CACHEFILE) message("Doing computations: ", compute) if(!compute) load(CACHEFILE) ################################################### ### code chunk number 2: surveillance.Rnw:155-157 ################################################### getOption("SweaveHooks")[["fig"]]() data(k1) plot(k1, main = "Cryptosporidiosis in BW 2001-2005") ################################################### ### code chunk number 3: surveillance.Rnw:217-221 ################################################### set.seed(1234) sts <- sim.pointSource(p = 0.99, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7) ################################################### ### code chunk number 4: surveillance.Rnw:223-224 ################################################### getOption("SweaveHooks")[["fig"]]() plot(sts) ################################################### ### code chunk number 5: surveillance.Rnw:317-320 ################################################### getOption("SweaveHooks")[["fig"]]() k1.b660 <- algo.bayes(k1, control = list(range = 27:192, b = 0, w = 6, alpha = 0.01)) plot(k1.b660, disease = "k1") ################################################### ### code chunk number 6: CDC (eval = FALSE) ################################################### ## cntrl <- list(range=300:400,m=1,w=3,b=5,alpha=0.01) ## sts.cdc <- algo.cdc(sts, control = cntrl) ## sts.farrington <- algo.farrington(sts, control = cntrl) ################################################### ### code chunk number 7: surveillance.Rnw:348-351 ################################################### if (compute) { cntrl <- list(range=300:400,m=1,w=3,b=5,alpha=0.01) sts.cdc <- algo.cdc(sts, control = cntrl) sts.farrington <- algo.farrington(sts, control = cntrl) } ################################################### ### code chunk number 8: surveillance.Rnw:354-357 ################################################### getOption("SweaveHooks")[["fig"]]() par(mfcol=c(1,2)) plot(sts.cdc, legend.opts=NULL) plot(sts.farrington, legend.opts=NULL) ################################################### ### code chunk number 9: surveillance.Rnw:375-376 ################################################### print(algo.quality(k1.b660)) ################################################### ### code chunk number 10: CONTROL ################################################### control <- list( list(funcName = "rki1"), list(funcName = "rki2"), list(funcName = "rki3"), list(funcName = "bayes1"), list(funcName = "bayes2"), list(funcName = "bayes3"), list(funcName = "cdc", alpha=0.05), list(funcName = "farrington", alpha=0.05) ) control <- lapply(control, function(ctrl) { ctrl$range <- 300:400; return(ctrl) }) ################################################### ### code chunk number 11: surveillance.Rnw:416-417 (eval = FALSE) ################################################### ## algo.compare(algo.call(sts, control = control)) ################################################### ### code chunk number 12: surveillance.Rnw:419-423 ################################################### if (compute) { acall <- algo.call(sts, control = control) } print(algo.compare(acall), digits = 3) ################################################### ### code chunk number 13: surveillance.Rnw:432-437 ################################################### #Create 10 series ten <- lapply(1:10,function(x) { sim.pointSource(p = 0.975, r = 0.5, length = 400, A = 1, alpha = 1, beta = 0, phi = 0, frequency = 1, state = NULL, K = 1.7)}) ################################################### ### code chunk number 14: TENSURV (eval = FALSE) ################################################### ## #Do surveillance on all 10, get results as list ## ten.surv <- lapply(ten,function(ts) { ## algo.compare(algo.call(ts,control=control)) ## }) ################################################### ### code chunk number 15: surveillance.Rnw:445-448 ################################################### if (compute) { #Do surveillance on all 10, get results as list ten.surv <- lapply(ten,function(ts) { algo.compare(algo.call(ts,control=control)) }) } ################################################### ### code chunk number 16: surveillance.Rnw:450-452 (eval = FALSE) ################################################### ## #Average results ## algo.summary(ten.surv) ################################################### ### code chunk number 17: surveillance.Rnw:454-455 ################################################### print(algo.summary(ten.surv), digits = 3) ################################################### ### code chunk number 18: surveillance.Rnw:467-495 ################################################### #Update range in each - cyclic continuation range = (2*4*52) + 1:length(k1$observed) control <- lapply(control,function(cntrl) { cntrl$range=range;return(cntrl)}) #Auxiliary function to enlarge data enlargeData <- function(disProgObj, range = 1:156, times = 1){ disProgObj$observed <- c(rep(disProgObj$observed[range], times), disProgObj$observed) disProgObj$state <- c(rep(disProgObj$state[range], times), disProgObj$state) return(disProgObj) } #Outbreaks outbrks <- c("m1", "m2", "m3", "m4", "m5", "q1_nrwh", "q2", "s1", "s2", "s3", "k1", "n1", "n2", "h1_nrwrp") #Load and enlarge data. outbrks <- lapply(outbrks,function(name) { data(list=name) enlargeData(get(name),range=1:(4*52),times=2) }) #Apply function to one one.survstat.surv <- function(outbrk) { algo.compare(algo.call(outbrk,control=control)) } ################################################### ### code chunk number 19: surveillance.Rnw:497-498 (eval = FALSE) ################################################### ## algo.summary(lapply(outbrks,one.survstat.surv)) ################################################### ### code chunk number 20: surveillance.Rnw:500-504 ################################################### if (compute) { res.survstat <- algo.summary(lapply(outbrks,one.survstat.surv)) } print(res.survstat, digits=3) ################################################### ### code chunk number 21: surveillance.Rnw:514-520 ################################################### if (compute) { # save computed results save(list=c("sts.cdc","sts.farrington","acall","res.survstat", "ten.surv"), file=CACHEFILE) tools::resaveRdaFiles(CACHEFILE) } surveillance/inst/doc/glrnb.R0000644000176200001440000001425414615167536015743 0ustar liggesusers### R code from vignette source 'glrnb.Rnw' ################################################### ### code chunk number 1: setup ################################################### library("surveillance") options(SweaveHooks=list(fig=function() par(mar=c(4,4,2,0)+.5))) options(width=70) set.seed(247) ## create directory for plots dir.create("plots", showWarnings=FALSE) ################################################### ### code chunk number 2: glrnb.Rnw:92-94 ################################################### getOption("SweaveHooks")[["fig"]]() data(shadar) plot(shadar,main="Number of salmonella hadar cases in Germany 2001-2006") ################################################### ### code chunk number 3: glrnb.Rnw:101-103 ################################################### # Simulate data simData <- sim.pointSource(length=300,K=0.5,r=0.6,p=0.95) ################################################### ### code chunk number 4: glrnb.Rnw:106-107 ################################################### getOption("SweaveHooks")[["fig"]]() plot(simData) ################################################### ### code chunk number 5: glrnb.Rnw:140-142 ################################################### getOption("SweaveHooks")[["fig"]]() survObj <- algo.glrnb(shadar,control=list(range=105:295,alpha=0)) plot(survObj, col=c(8,NA,4)) ################################################### ### code chunk number 6: glrnb.Rnw:161-164 (eval = FALSE) ################################################### ## control=list(range=range,c.ARL=5, ## mu0=NULL, alpha=0, Mtilde=1, M=-1, change="intercept",theta=NULL, ## dir=c("inc","dec"),ret=c("cases","value")) ################################################### ### code chunk number 7: glrnb.Rnw:173-175 (eval = FALSE) ################################################### ## control=list(range=105:length(shadar$observed)) ## algo.glrnb(disProgObj=shadar,control=control) ################################################### ### code chunk number 8: glrnb.Rnw:181-183 (eval = FALSE) ################################################### ## control=list(range=105:295,alpha=3) ## algo.glrnb(disProgObj=shadar,control=control) ################################################### ### code chunk number 9: glrnb.Rnw:191-194 ################################################### control=list(range=105:295,alpha=NULL) surv <- algo.glrnb(shadar,control=control) surv$control$alpha ################################################### ### code chunk number 10: glrnb.Rnw:205-207 (eval = FALSE) ################################################### ## control=list(range=105:295,mu0=list(S=2,trend=FALSE)) ## algo.glrnb(disProgObj=shadar,control=control) ################################################### ### code chunk number 11: glrnb.Rnw:210-212 ################################################### control=list(range=105:295,mu0=list(S=2,trend=F,refit=T)) surv <- algo.glrnb(disProgObj=shadar,control=control) ################################################### ### code chunk number 12: glrnb.Rnw:217-219 ################################################### getOption("SweaveHooks")[["fig"]]() plot(shadar) with(surv$control,lines(mu0~range,lty=2,lwd=4,col=4)) ################################################### ### code chunk number 13: glrnb.Rnw:225-226 (eval = FALSE) ################################################### ## surv$control$mu0Model ################################################### ### code chunk number 14: glrnb.Rnw:233-234 ################################################### estimateGLRNbHook ################################################### ### code chunk number 15: glrnb.Rnw:274-275 ################################################### coef(surv$control$mu0Model$fitted[[1]]) ################################################### ### code chunk number 16: glrnb.Rnw:283-286 ################################################### control=list(range=105:295,alpha=0) surv <- algo.glrnb(disProgObj=shadar,control=control) table(surv$alarm) ################################################### ### code chunk number 17: glrnb.Rnw:291-295 ################################################### num <- rep(NA) for (i in 1:6){ num[i] <- table(algo.glrnb(disProgObj=shadar,control=c(control,c.ARL=i))$alarm)[2] } ################################################### ### code chunk number 18: glrnb.Rnw:311-319 ################################################### getOption("SweaveHooks")[["fig"]]() control=list(range=209:295,c.ARL=5.1,mu0=list(S=1,trend=TRUE), alpha=NULL,M=52,change="epi") surv <- algo.glrnb(shadar, control) plot(surv,col=c(NA,8,4),lty=c(1,0,1),lwd=c(1,1,3),legend.opts=NULL) lines(surv$control$mu0,lty=2,lwd=2,col=2) abline(h=surv$control$c.ARL,lty=2,col=3) legend(1,20,expression(GLR(n),mu[0],c[gamma]), col=c(4,2,3),lty=c(1,2,2),lwd=c(3,2,1)) ################################################### ### code chunk number 19: glrnb.Rnw:325-327 (eval = FALSE) ################################################### ## control=list(range=105:295,theta=0.4) ## algo.glrnb(disProgObj=shadar,control=control) ################################################### ### code chunk number 20: glrnb.Rnw:332-334 (eval = FALSE) ################################################### ## control=list(range=105:295,theta=NULL) ## algo.glrnb(disProgObj=shadar,control=control) ################################################### ### code chunk number 21: glrnb.Rnw:342-344 ################################################### control=list(range=105:295,ret="cases",alpha=0) surv2 <- algo.glrnb(disProgObj=shadar,control=control) ################################################### ### code chunk number 22: glrnb.Rnw:347-348 ################################################### getOption("SweaveHooks")[["fig"]]() plot(surv2, col=c(8,NA,4)) ################################################### ### code chunk number 23: glrnb.Rnw:358-360 ################################################### control=list(range=105:295,ret="cases",dir="dec",alpha=0) surv3 <- algo.glrnb(disProgObj=shadar,control=control) ################################################### ### code chunk number 24: glrnb.Rnw:363-364 ################################################### getOption("SweaveHooks")[["fig"]]() plot(surv3, col=c(8,NA,4)) surveillance/inst/doc/twinSIR.Rnw0000644000176200001440000006131514430704663016534 0ustar liggesusers%\VignetteIndexEntry{twinSIR: Individual-level epidemic modeling for a fixed population with known distances} %\VignetteEngine{knitr::knitr} %% additional dependencies beyond what is required for surveillance anyway: %\VignetteDepends{surveillance, quadprog} <>= ## purl=FALSE => not included in the tangle'd R script knitr::opts_chunk$set(echo = TRUE, tidy = FALSE, results = 'markup', fig.path='plots/twinSIR-', fig.width = 8, fig.height = 4.5, fig.align = "center", fig.scap = NA, out.width = NULL, cache = FALSE, error = FALSE, warning = FALSE, message = FALSE) knitr::render_sweave() # use Sweave environments knitr::set_header(highlight = '') # no \usepackage{Sweave} (part of jss class) ## R settings options(prompt = "R> ", continue = "+ ", useFancyQuotes = FALSE) # JSS options(width = 85, digits = 4) options(scipen = 1) # so that 1e-4 gets printed as 0.0001 ## xtable settings options(xtable.booktabs = TRUE, xtable.size = "small", xtable.sanitize.text.function = identity, xtable.comment = FALSE) @ \documentclass[nojss,nofooter,article]{jss} \title{% \vspace{-1.5cm} \fbox{\vbox{\normalfont\footnotesize This introduction to the \code{twinSIR} modeling framework of the \proglang{R}~package \pkg{surveillance} is based on a publication in the \textit{Journal of Statistical Software} -- \citet[Section~4]{meyer.etal2014} -- which is the suggested reference if you use the \code{twinSIR} implementation in your own work.}}\\[1cm] \code{twinSIR}: Individual-level epidemic modeling for a fixed population with known distances} \Plaintitle{twinSIR: Individual-level epidemic modeling for a fixed population with known distances} \Shorttitle{Modeling epidemics in a fixed population with known distances} \author{Sebastian Meyer\thanks{Author of correspondence: \email{seb.meyer@fau.de}}\\Friedrich-Alexander-Universit{\"a}t\\Erlangen-N{\"u}rnberg \And Leonhard Held\\University of Zurich \And Michael H\"ohle\\Stockholm University} \Plainauthor{Sebastian Meyer, Leonhard Held, Michael H\"ohle} %% Basic packages \usepackage{lmodern} % successor of CM -> searchable Umlauts (1 char) \usepackage[english]{babel} % language of the manuscript is American English %% Math packages \usepackage{amsmath,amsfonts} % amsfonts defines \mathbb \usepackage{bm} % \bm: alternative to \boldsymbol from amsfonts %% Packages for figures and tables \usepackage{booktabs} % make tables look nicer \usepackage{subcaption} % successor of subfig, which supersedes subfigure %% knitr uses \subfloat, which subcaption only provides since v1.3 (2019/08/31) \providecommand{\subfloat}[2][need a sub-caption]{\subcaptionbox{#1}{#2}} %% Handy math commands \newcommand{\abs}[1]{\lvert#1\rvert} \newcommand{\norm}[1]{\lVert#1\rVert} \newcommand{\given}{\,\vert\,} \newcommand{\dif}{\,\mathrm{d}} \newcommand{\IR}{\mathbb{R}} \newcommand{\IN}{\mathbb{N}} \newcommand{\ind}{\mathbb{I}} \DeclareMathOperator{\Po}{Po} \DeclareMathOperator{\NegBin}{NegBin} \DeclareMathOperator{\N}{N} %% Additional commands \newcommand{\class}[1]{\code{#1}} % could use quotes (JSS does not like them) \newcommand{\CRANpkg}[1]{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}} %% Reduce the font size of code input and output \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl, fontsize=\small} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\small} %% Abstract \Abstract{ The availability of geocoded health data and the inherent temporal structure of communicable diseases have led to an increased interest in statistical models and software for spatio-temporal data with epidemic features. The \proglang{R}~package \pkg{surveillance} can handle various levels of aggregation at which infective events have been recorded. This vignette illustrates the analysis of individual-level surveillance data for a fixed population, of which the complete SIR event history is assumed to be known. Typical applications for the multivariate, temporal point process model ``\code{twinSIR}'' of \citet{hoehle2009} include the spread of infectious livestock diseases across farms, household models for childhood diseases, and epidemics across networks. %% (For other types of surveillance data, see %% \code{vignette("twinstim")} and \code{vignette("hhh4\_spacetime")}.) We first describe the general modeling approach and then exemplify data handling, model fitting, and visualization for a particularly well-documented measles outbreak among children of the isolated German village Hagelloch in 1861. %% Due to the many similarities with the spatio-temporal point process model %% ``\code{twinstim}'' described and illustrated in \code{vignette("twinstim")}, %% we condense the \code{twinSIR} treatment accordingly. } \Keywords{% individual-level surveillance data, endemic-epidemic modeling, infectious disease epidemiology, self-exciting point process, branching process with immigration} \begin{document} <>= ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("twinSIR-cache.RData")) if (!COMPUTE) load("twinSIR-cache.RData", verbose = TRUE) @ \section[Model class]{Model class: \code{twinSIR}} \label{sec:twinSIR:methods} The spatio-temporal point process regression model ``\code{twinstim}'' (\citealp{meyer.etal2011}, illustrated in \code{vignette("twinstim")}) is indexed in a continuous spatial domain, i.e., the set of possible event locations %(the susceptible ``population'') consists of the whole observation region and is thus infinite. In contrast, if infections can only occur at a known discrete set of sites, such as for livestock diseases among farms, the conditional intensity function (CIF) of the underlying point process formally becomes $\lambda_i(t)$. It characterizes the instantaneous rate of infection of individual $i$ at time $t$, given the sets $S(t)$ and $I(t)$ of susceptible and infectious individuals, respectively (just before time $t$). %In a similar regression view as in \code{vignette("twinstim")}, \citet{hoehle2009} proposed the following endemic-epidemic multivariate temporal point process model (``\code{twinSIR}''): \begin{equation} \label{eqn:twinSIR} \lambda_i(t) = \lambda_0(t) \, \nu_i(t) + \sum_{j \in I(t)} \left\{ f(d_{ij}) + \bm{w}_{ij}^\top \bm{\alpha}^{(w)} \right\} \:, %\qquad \text{if } i \in S(t)\:, \end{equation} if $i \in S(t)$, i.e., if individual $i$ is currently susceptible, and $\lambda_i(t) = 0$ otherwise. The rate decomposes into two components. The first, endemic component consists of a Cox proportional hazards formulation containing a semi-parametric baseline hazard $\lambda_0(t)$ and a log-linear predictor $\nu_i(t)=\exp\left( \bm{z}_i(t)^\top \bm{\beta} \right)$ of covariates modeling infection from external sources. Furthermore, an additive epidemic component captures transmission from the set $I(t)$ of currently infectious individuals. The force of infection of individual $i$ depends on the distance $d_{ij}$ to each infective source $j \in I(t)$ through a distance kernel \begin{equation} \label{eqn:twinSIR:f} f(u) = \sum_{m=1}^M \alpha_m^{(f)} B_m(u) \: \geq 0 \:, \end{equation} which is represented by a linear combination of non-negative basis functions $B_m$ with the $\alpha_m^{(f)}$'s being the respective coefficients. For instance, $f$ could be modeled by a B-spline \citep[Section~8.1]{Fahrmeir.etal2013}, and $d_{ij}$ could refer to the Euclidean distance $\norm{\bm{s}_i - \bm{s}_j}$ between the individuals' locations $\bm{s}_i$ and $\bm{s}_j$, or to the geodesic distance between the nodes $i$ and $j$ in a network. The distance-based force of infection is modified additively by a linear predictor of covariates $\bm{w}_{ij}$ describing the interaction of individuals $i$ and~$j$ further. Hence, the whole epidemic component of Equation~\ref{eqn:twinSIR} can be written as a single linear predictor $\bm{x}_i(t)^\top \bm{\alpha}$ by interchanging the summation order to \begin{equation} \label{eqn:twinSIR:x} \sum_{m=1}^M \alpha^{(f)}_m \sum_{j \in I(t)} B_m(d_{ij}) + \sum_{k=1}^K \alpha^{(w)}_k \sum_{j \in I(t)} w_{ijk} = \bm{x}_i(t)^\top \bm{\alpha} \:, \end{equation} such that $\bm{x}_i(t)$ comprises all epidemic terms summed over $j\in I(t)$. Note that the use of additive covariates $\bm{w}_{ij}$ on top of the distance kernel in \eqref{eqn:twinSIR} is different from \code{twinstim}'s multiplicative approach. One advantage of the additive approach is that the subsequent linear decomposition of the distance kernel allows one to gather all parts of the epidemic component in a single linear predictor. Hence, the above model represents a CIF extension of what in the context of survival analysis is known as an additive-multiplicative hazard model~\citep{Martinussen.Scheike2006}. As a consequence, the \code{twinSIR} model could in principle be fitted with the \CRANpkg{timereg} package, which yields estimates for the cumulative hazards. However, \citet{hoehle2009} chooses a more direct inferential approach: To ensure that the CIF $\lambda_i(t)$ is non-negative, all covariates are encoded such that the components of $\bm{w}_{ij}$ are non-negative. Additionally, the parameter vector $\bm{\alpha}$ is constrained to be non-negative. Subsequent parameter inference is then based on the resulting constrained penalized likelihood which gives directly interpretable estimates of $\bm{\alpha}$. Future work could investigate the potential of a multiplicative approach for the epidemic component in \code{twinSIR}. \section[Data structure]{Data structure: \class{epidata}} \label{sec:twinSIR:data} New SIR-type event data typically arrive in the form of a simple data frame with one row per individual and sequential event time points as columns. For the 1861 Hagelloch measles epidemic, which has previously been analyzed by, e.g., \citet{neal.roberts2004}, such a data set of the 188 affected children is contained in the \pkg{surveillance} package: <>= data("hagelloch") head(hagelloch.df, n = 5) @ The \code{help("hagelloch")} contains a description of all columns. Here we concentrate on the event columns \code{PRO} (appearance of prodromes), \code{ERU} (eruption), and \code{DEAD} (day of death if during the outbreak). We take the day on which the index case developed first symptoms, 30 October 1861 (\code{min(hagelloch.df$PRO)}), as the start of the epidemic, i.e., we condition on this case being initially infectious. % t0 = 1861-10-31 00:00:00 As for \code{twinstim}, the property of point processes that concurrent events have zero probability requires special treatment. Ties are due to the interval censoring of the data to a daily basis -- we broke these ties by adding random jitter to the event times within the given days. The resulting columns \code{tPRO}, \code{tERU}, and \code{tDEAD} are relative to the defined start time. Following \citet{neal.roberts2004}, we assume that each child becomes infectious (S~$\rightarrow$~I event at time \code{tI}) one day before the appearance of prodromes, and is removed from the epidemic (I~$\rightarrow$~R event at time \code{tR}) three days after the appearance of rash or at the time of death, whichever comes first. For further processing of the data, we convert \code{hagelloch.df} to the standardized \class{epidata} structure for \code{twinSIR}. This is done by the converter function \code{as.epidata}, which also checks consistency and optionally pre-calculates the epidemic terms $\bm{x}_i(t)$ of Equation~\ref{eqn:twinSIR:x} to be incorporated in a \code{twinSIR} model. The following call generates the \class{epidata} object \code{hagelloch}: <>= hagelloch <- as.epidata(hagelloch.df, t0 = 0, tI.col = "tI", tR.col = "tR", id.col = "PN", coords.cols = c("x.loc", "y.loc"), f = list(household = function(u) u == 0, nothousehold = function(u) u > 0), w = list(c1 = function (CL.i, CL.j) CL.i == "1st class" & CL.j == CL.i, c2 = function (CL.i, CL.j) CL.i == "2nd class" & CL.j == CL.i), keep.cols = c("SEX", "AGE", "CL")) @ The coordinates (\code{x.loc}, \code{y.loc}) correspond to the location of the household the child lives in and are measured in meters. Note that \class{twinSIR} allows for tied locations of individuals, but assumes the relevant spatial location to be fixed during the entire observation period. By default, the Euclidean distance between the given coordinates will be used. Alternatively, \code{as.epidata} also accepts a pre-computed distance matrix via its argument \code{D} without requiring spatial coordinates. The argument \code{f} lists distance-dependent basis functions $B_m$ for which the epidemic terms $\sum_{j\in I(t)} B_m(d_{ij})$ shall be generated. Here, \code{household} ($x_{i,H}(t)$) and \code{nothousehold} ($x_{i,\bar{H}}(t)$) count for each child the number of currently infective children in its household and outside its household, respectively. Similar to \citet{neal.roberts2004}, we also calculate the covariate-based epidemic terms \code{c1} ($x_{i,c1}(t)$) and \code{c2} ($x_{i,c2}(t)$) % from $w_{ijk} = \ind(\code{CL}_i = k, \code{CL}_j = \code{CL}_i)$ counting the number of currently infective classmates. Note from the corresponding definitions of $w_{ij1}$ and $w_{ij2}$ in \code{w} that \code{c1} is always zero for children of the second class and \code{c2} is always zero for children of the first class. For pre-school children, both variables equal zero over the whole period. By the last argument \code{keep.cols}, we choose to only keep the covariates \code{SEX}, \code{AGE}, and school \code{CL}ass from \code{hagelloch.df}. The first few rows of the generated \class{epidata} object are shown below: <>= head(hagelloch, n = 5) @ The \class{epidata} structure inherits from counting processes as implemented by the \class{Surv} class of package \CRANpkg{survival} and also used in \CRANpkg{timereg}. Specifically, the observation period is split up into consecutive time intervals (\code{start}; \code{stop}] of constant conditional intensities. As the CIF $\lambda_i(t)$ of Equation~\eqref{eqn:twinSIR} only changes at time points, where the set of infectious individuals $I(t)$ or some endemic covariate in $\nu_i(t)$ change, those occurrences define the break points of the time intervals. Altogether, the \code{hagelloch} event history consists of \Sexpr{nrow(hagelloch)/nlevels(hagelloch$id)} time \code{BLOCK}s of \Sexpr{nlevels(hagelloch[["id"]])} rows, where each row describes the state of individual \code{id} during the corresponding time interval. The susceptibility status and the I- and R-events are captured by the columns \code{atRiskY}, \code{event} and \code{Revent}, respectively. The \code{atRiskY} column indicates if the individual is at risk of becoming infected in the current interval. The event columns indicate, which individual was infected or removed at the \code{stop} time. Note that at most one entry in the \code{event} and \code{Revent} columns is 1, all others are 0. Apart from being the input format for \code{twinSIR} models, the \class{epidata} class has several associated methods (Table~\ref{tab:methods:epidata}), which are similar in spirit to the methods described for \class{epidataCS}. <>= print(xtable( surveillance:::functionTable("epidata", list(Display = c("stateplot"))), caption="Generic and \\textit{non-generic} functions applicable to \\class{epidata} objects.", label="tab:methods:epidata"), include.rownames = FALSE) @ For example, Figure~\ref{fig:hagelloch_plot} illustrates the course of the Hagelloch measles epidemic by counting processes for the number of susceptible, infectious and removed children, respectively. Figure~\ref{fig:hagelloch_households} shows the locations of the households. An \code{animate}d map can also be produced to view the households' states over time and a simple \code{stateplot} shows the changes for a selected unit. <>= par(mar = c(5, 5, 1, 1)) plot(hagelloch, xlab = "Time [days]") @ <>= par(mar = c(5, 5, 1, 1)) hagelloch_coords <- summary(hagelloch)$coordinates plot(hagelloch_coords, xlab = "x [m]", ylab = "y [m]", pch = 15, asp = 1, cex = sqrt(multiplicity(hagelloch_coords))) legend(x = "topleft", pch = 15, legend = c(1, 4, 8), pt.cex = sqrt(c(1, 4, 8)), title = "Household size") @ \section{Modeling and inference} \label{sec:twinSIR:fit} \subsection{Basic example} To illustrate the flexibility of \code{twinSIR} we will analyze the Hagelloch data using class room and household indicators similar to \citet{neal.roberts2004}. We include an additional endemic background rate $\exp(\beta_0)$, which allows for multiple outbreaks triggered by external sources. Consequently, we do not need to ignore the child that got infected about one month after the end of the main epidemic (see the last event mark in Figure~\ref{fig:hagelloch_plot}). % ATM, there is no way to fit a twinSIR without an endemic component. Altogether, the CIF for a child $i$ is modeled as \begin{equation} \label{eqn:twinSIR:hagelloch} \lambda_i(t) = Y_i(t) \cdot \left[ \exp(\beta_0) + \alpha_H x_{i,H}(t) + \alpha_{c1} x_{i,c1}(t) + \alpha_{c2} x_{i,c2}(t) + \alpha_{\bar{H}} x_{i,\bar{H}}(t) \right] \:, \end{equation} where $Y_i(t) = \ind(i \in S(t))$ is the at-risk indicator. By counting the number of infectious classmates separately for both school classes as described in the previous section, we allow for class-specific effects $\alpha_{c1}$ and $\alpha_{c2}$ on the force of infection. The model is estimated by maximum likelihood \citep{hoehle2009} using the call <>= hagellochFit <- twinSIR(~household + c1 + c2 + nothousehold, data = hagelloch) @ and the fit is summarized below: <>= set.seed(1) summary(hagellochFit) @ <>= ## drop leading and trailing empty lines writeLines(tail(head(capture.output({ <> }), -1), -1)) @ The results show, e.g., a \Sexpr{sprintf("%.4f",coef(hagellochFit)["c1"])} / \Sexpr{sprintf("%.4f",coef(hagellochFit)["c2"])} $=$ \Sexpr{format(coef(hagellochFit)["c1"]/coef(hagellochFit)["c2"])} times higher transmission between individuals in the 1st class than in the 2nd class. Furthermore, an infectious housemate adds \Sexpr{sprintf("%.4f",coef(hagellochFit)["household"])} / \Sexpr{sprintf("%.4f",coef(hagellochFit)["nothousehold"])} $=$ \Sexpr{format(coef(hagellochFit)["household"]/coef(hagellochFit)["nothousehold"])} times as much infection pressure as infectious children outside the household. The endemic background rate of infection in a population with no current measles cases is estimated to be $\exp(\hat{\beta}_0) = \exp(\Sexpr{format(coef(hagellochFit)["cox(logbaseline)"])}) = \Sexpr{format(exp(coef(hagellochFit)["cox(logbaseline)"]))}$. An associated Wald confidence interval (CI) based on the asymptotic normality of the maximum likelihood estimator (MLE) can be obtained by \code{exp}-transforming the \code{confint} for $\beta_0$: <>= exp(confint(hagellochFit, parm = "cox(logbaseline)")) @ Note that Wald confidence intervals for the epidemic parameters $\bm{\alpha}$ are to be treated carefully, because their construction does not take the restricted parameter space into account. For more adequate statistical inference, the behavior of the log-likelihood near the MLE can be investigated using the \code{profile}-method for \class{twinSIR} objects. For instance, to evaluate the normalized profile log-likelihood of $\alpha_{c1}$ and $\alpha_{c2}$ on an equidistant grid of 25 points within the corresponding 95\% Wald CIs, we do: <>= prof <- profile(hagellochFit, list(c(match("c1", names(coef(hagellochFit))), NA, NA, 25), c(match("c2", names(coef(hagellochFit))), NA, NA, 25))) @ The profiling result contains 95\% highest likelihood based CIs for the parameters, as well as the Wald CIs for comparison: <<>>= prof$ci.hl @ The entire functional form of the normalized profile log-likelihood on the requested grid as stored in \code{prof$lp} can be visualized by: <>= plot(prof) @ The above model summary also reports the one-sided AIC~\citep{hughes.king2003}, which can be used for model selection under positivity constraints on $\bm{\alpha}$ as described in \citet{hoehle2009}. The involved parameter penalty is determined by Monte Carlo simulation, which is why we did \code{set.seed} before the \code{summary} call. The algorithm is described in \citet[p.~79, Simulation 3]{Silvapulle.Sen2005} and involves quadratic programming using package \CRANpkg{quadprog} \citep{R:quadprog}. If there are less than three constrained parameters in a \code{twinSIR} model, the penalty is computed analytically. \subsection{Model diagnostics} <>= print(xtable( surveillance:::functionTable("twinSIR", functions=list(Display = c("checkResidualProcess"))), caption="Generic and \\textit{non-generic} functions for \\class{twinSIR}. There are no specific \\code{coef} or \\code{confint} methods, since the respective default methods from package \\pkg{stats} apply outright.", label="tab:methods:twinSIR"), include.rownames = FALSE) @ Table~\ref{tab:methods:twinSIR} lists all methods for the \class{twinSIR} class. For example, to investigate how the conditional intensity function decomposes into endemic and epidemic components over time, we produce Figure~\ref{fig:hagellochFit_plot-1} by: <>= par(mar = c(5, 5, 1, 1)) plot(hagellochFit, which = "epidemic proportion", xlab = "time [days]") checkResidualProcess(hagellochFit, plot = 1) @ Note that the last infection was necessarily caused by the endemic component since there were no more infectious children in the observed population which could have triggered the new case. We can also inspect temporal Cox-Snell-like \code{residuals} of the fitted point process using the function \code{checkResidualProcess} as for the spatio-temporal point process models in \code{vignette("twinstim")}. The resulting Figure~\ref{fig:hagellochFit_plot-2} reveals some deficiencies of the model in describing the waiting times between events, which might be related to the assumption of fixed infection periods. <>= knots <- c(100, 200) fstep <- list( B1 = function(D) D > 0 & D < knots[1], B2 = function(D) D >= knots[1] & D < knots[2], B3 = function(D) D >= knots[2]) @ To illustrate AIC-based model selection, we may consider a more flexible model for local spread using a step function for the distance kernel $f(u)$ in Equation \ref{eqn:twinSIR:f}. An updated model with <>= .allknots <- c(0, knots, "\\infty") cat(paste0("$B_{", seq_along(fstep), "} = ", "I_{", ifelse(seq_along(fstep)==1,"(","["), .allknots[-length(.allknots)], ";", .allknots[-1], ")}(u)$", collapse = ", ")) @ can be fitted as follows: <>= <> hagellochFit_fstep <- twinSIR( ~household + c1 + c2 + B1 + B2 + B3, data = update(hagelloch, f = fstep)) @ <>= set.seed(1) AIC(hagellochFit, hagellochFit_fstep) @ Hence the simpler model with just a \code{nothousehold} component instead of the more flexible distance-based step function is preferred. \section{Simulation} \label{sec:twinSIR:simulation} Simulation from fitted \code{twinSIR} models is described in detail in~\citet[Section~4]{hoehle2009}. The implementation is made available by an appropriate \code{simulate}-method for class \class{twinSIR}. We skip the illustration here and refer to \code{help("simulate.twinSIR")}. %-------------- % BIBLIOGRAPHY %-------------- \bibliography{references} <>= save(prof, file = "twinSIR-cache.RData") @ \end{document} surveillance/inst/doc/glrnb.pdf0000644000176200001440000037516114615167600016312 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4115 /Filter /FlateDecode /N 68 /First 564 >> stream x[Ys۶~oMJd&^'8Nhʢ%q9XL;jpG d$&(MI E(I$')I!LVL-I c%F@„b$*Icx-QKDpDh 6D "P1"Sǀ'@(}IJS€n2Mz,%ZgH]TBex5M4Έ@s1@= ]IDB8%f) n_(ށ>,'NӘ@$6$Ǯ%Js"@,FIeƁ%huP '2Ki(\B@\W zG@Y#De@(A22@( T8GGr\e)4H(K DPʤ c(h"$`PV1 Jt?JI2#:j|ׯ uN>ԟ#KjyYɯ|2cX%ppq+h==B=c_ÑѷDgG<ϖE9;Ȗ9yp_32PsK~~Y|-8x"\Ƚ(zO_b͋%1Q UޮGJZ:{y3(kxR0ףO$Ί4!jlr_9ʖsuye]]O;Vl{U,Vɱ_fKTE@43Τ7p$'6fwvo&0%Y<}sM03gr2Gøwk8Bl$~9[3Z̩|\d{ Pw*gdb/q/|l!OOJG̼vO( rl{i n̮-c bxv:) I+spte~hJc<;09|fh$[^:XIױX 8",cmvcD]7tQ e·tT^]e"%bDnu%.wWa@ NQxKPg* k.5:1PF1s !E1{0b? cG}B#>/1=/+*8s:0-g^9iN-I[ _AߗNBzhA2WVfҒœX8ӿ_rϧr9EX7t1EPmܚB=t>xBakuY Uer*ppUg9+{5٢o:N󆶶lDžYyǕu[=kGnrf_k? t'2-oOC?t'jvz&My ·E.ޙ xl ]X{p+o@;%' 'oNY@ iG?\WTslV)r~@JO+r][?Zg`Y֕4;.l3QKwĖ lh88WײGRR5FM1 %H@&dabg&RzS\>s߼>zgrw}qwv"{k)~ x>F%l ܸW$sf-4_,\骘wI=%q W}x}1ĭuHtOYds\#F@k*.~ji{FMZru|hVZ˚FΦaMR܅jM/„,p̮3zBSt_dmR[;ɡ$9pmVC2h ٷlpl&ui0jרGvCi:YTAM@l>@7ԉLip%[+Zb>Z]M3]M>f1*e19/hW9ː QC6E w|ӓFî~<`zh+bc.1_ L{1VTp &1Kژ>LMXLmSMt屄gl3\q_F9Vͩ`-JDesPfUȅlfM96ł$CچcMl?ĕͺ9W({SAf.29|}lޜq˳ ϥ_ŭʰLLӯhg|q5 tPp:Y*q9#=nb:;;[]Eq1lZ@a.vCvsNw6c՛%S=+2BD° DQ*pݶ(#\=S9S&Њx"#0eD֘+, f~$Sⵤd;s1jҚHH1N"LG# &zH$dtYb1ȫ $@'T|O9QS!}hm) wgbppwH @)Jqqk(ۭƾIu*5n)eCX0 ,Wv 1;WO9ʧ_e1S*,YCwC=͉\v1WwǼ[ PLw }~o-aV,}eިivdHM/^6 S07vNM5\`C(뙘- CRPM,_n@pBdv.;xCPWݍ?Coa5X]?j'|^C;M"l°uڔ*Zr(Uyk~xtKO%}XlJ:zkv Xu` 3D=(Jv53ǕχL3>B?Z1Zo09ZGB{h;2d7ܞ,Q*/Z Hk}x-rC29,yUgxtmdw5 n!..~ fuh%DryqqXr.}׸ |h\,Y;f&?ºp/7 ɛ/N+}[Y7| hv. XAŘ?D'Z PNV蘀r@A~S -B*xbwce!tHq߮/2~Ht݇z!-ߣ;z|h}u۠J]Z'_6UWR" ߤ4ܢvD 7effHi\oJ\k!]n bqKvPL&9x%膠\Dkt6Xwoj#Ij>alCM8MdGkTk28ܤE@3X]? s{P@1;,ݰm?9E~Ysښ3F:ޘu^=o.G n.5Eendstream endobj 70 0 obj << /Subtype /XML /Type /Metadata /Length 1556 >> stream GPL Ghostscript 9.55.0 2024-05-03T16:06:56+02:00 2024-05-03T16:06:56+02:00 LaTeX with hyperref 'algo.glrnb': Count data regression charts using the generalized likelihood ratio statisticValentin Wimmer and Michael HöhleR package 'surveillance' endstream endobj 71 0 obj << /Type /ObjStm /Length 3008 /Filter /FlateDecode /N 67 /First 586 >> stream x[koFb>bb'Nvq["Ӷ6rÇ)R%[iXp̽gc 5V1oVyL;&J7"#XKG2łb)Âf*z\-P2M`1bdhXG3R:2eQ0cE`Q2dQ1+45Z0yi@gf3b10-E8^^FhQ#*Bb`@+È UDGS01ץhGJ *`$/i0jG0^S$WaEJ!)BD(ZMwAtnHMTF[*eِ e'Z,WkCiWajB!yjQQ?~'y`N ?7j7 hXz2a'ɿ.vpOUW eb3!l7=XGm\ 3|YKfzK S^zN`5p֛U@AM̌ uUHaYUףוLy4K(OEA8u DgڟMRiU>`_||~Q_bĀ!O_^~`dx^RثIZtj|x00~z3oQp2=!44#?Z䗿miD~\/߽Ep*_]lFe v.<ƒ16:sy Bjib2~Z@@!>(4d6<.(5_k0:m)znH*EwI_~WY"r%چKTK%EVj#.C4":wr!;bm7%W=88%to-CϨWQaUzYnKgc_Ǐӝp[^&_T^tX\3oW{/y^ >_Q0ei P,||dMYGE‹~fnh(kYmzV'}F 0ZQj0eOƹw_,OEKbA,'R#ۮJcC# P/X<ڛMN7 m_uP:R˸t\wE(? tY)cH2c|F|Pϡ:G9MTpu696s~>χ谝$/L\f/ղ"?8)Ӛ Z䦘PbUs==h6S8uUޣB3ח#W>Fp^t'IøH>chJkIf*OkQd֦M V^2TQL 47e2x4 s$z=iWiZ@0&M| .H46*Q3CKO׃gVP.fk@!=&PƊ *{AIH*p&3֑h}AYvAR:S+p *aޒZ*vo@3ٸfbY_E#62me.SJZi*jS&W-mWedW^MioW6%j%WU|EPAUYVRJWgS ]QLP񂥧]ZCDrڊw$UJr^gBW$ں`~SeL m :cwh-Tݠz@juF|s vޔ2FEӧ6@+ \61; \me1AJ)Lm73!i#$Bɕuwxǃw>*pH~g)51V" Q‰'dݷ>jH1*cK%h;P5&eô>$k/yJt^qo K@vBÓYFSAI%ٕj޸O |xy9L/w0-F_KAnV}UI_Jendstream endobj 139 0 obj << /Filter /FlateDecode /Length 3644 >> stream xZISr`vcKl%7U9X9 )NG\9oR˥* { y]y߻ݬof?$=?w7O_J?RҚ͛/s|嬚;WWb7vs6n/u!T6koVg]U Ne]::h_([EK]*xF7FUuEt#6::E1hij'XqGl⾠ Ilih5eV:&6Z ~4m׳5U0ϗ #]` kdڂZج-)3b51/Uکb2aۅy:1b+VHmE׀rL2]:䬘B }| %^̺#}R,XJKxGa`J$YKEߢ䰻ݺDWt4D sSik$k!ِUkc4cLKUh zќ3>NCJZ-|9я٣ pC/ڻi{ߠR5Z/@(/ҫx^7y y ,eT+HvI}`<+ow NB{:,/oY uwl{iVApڳh$ȧ`K+As axbz8^F^sI"$.&@+[ ;Ze(m߲]X) >V9ƥ+v1@bP\o_;{"P xwbi%18; .Lɒ鷍1oF3$>H~dnvln2V6_+_F*'h +J)6 о JS )+mt2oH1P^4޴`Ư!aSA |5M4/HylW!t#ptmĪx VA"tmXsS:rQv xxkKo&[g:8҉.a';lЇ-G;4X {9lj;Co{~kxAN{i" =;JMpBlgOlW+C!m_{Y!rTªXBptdA^y`mic::5_dM01vֶkՁ졹%@ V/r^Y^H0]):Vql,T ! u Աr>fSҪ$c<2+BeP%Og( Y9(*?B7E*F7Cω xNWO m!ZO^93ǕՐq$b.`d߬ߏ:zWs=n싲],lFɞ iƭUbFHm?ذQx+Pko&"ZR&##@vēȢL7Ȓqd+H]l2YDt\JJ!_C#Pa YB#i+nȹ5+X.Bi䞄I}nq Hv͹)(5rXG * h=f5gGʣh} vf`ۙ2hY^{0.-J%s1 +k.$j͆la@}jQoeNv?QޙK$#)R s)^_K"aQw̕ AnV(VqC=ȥOZ1ڥ|'Z>v1O&dJA&b/lheIѰ-DSWc| BR)M-%F#MRnqb{IeCR" Nӡ<޳E}PPyH nxnvI 1P+Tt.M4%i+HD +1RF)َ|mz`k^nQ)z(Rn @nX/Vk˞=9"I:Jo4oh&*p%[+, I)%+ MԕZ u@LlSΐuB(E$Tl;}*K'Ahj=\Y&etlWgwgkjA4RF&{1o2Na,Pa1t`bjO:4dm'HxZN-4۴6ܰgB2E<Qԩ;ޥBǔQEQHhK-_Ƌ oHy(UbF֔;.iUGpDVenU *I?HN·s)\7<#pD,h6fLJss 滙, '٫_8UAc5}]2r}Sg*i%~S\g(/ěW/wDC_ #K#vu fs{D3F]`rֈDOyendstream endobj 140 0 obj << /Filter /FlateDecode /Length 3794 >> stream xZKs/Oؔ*WĎMWR `awi+9g@rU=yW3AoW/.&J_ܜ)J+t.=؟zU䅕f[䅩Tax_ڔٽTҖY~/6,t^]nsk'?VցNU*RC%JnmV_NwɯGi l)iJV*{S&CnRӂD֩n@L x`#{XVyQ5UF2/&+=*7,/?+қD(+9Ea*[~IKvfQ_~=KFI2{L7ljPjRv w{̯Nי/W u!s\$YCqZ p3|K sq.fjzF+4nx&( ]V  #_g 2ٷ}^!V,V- K`0OQhG-`&aÄ6']caug[Bc3Sۺmm"Wڊh[Ċ '-DH)P8sy$J"k0N謾DIelj=B%)XӽViHӶ5KI,`\W u_L{cHƝ=1 ak ~U%l{Fϛ :Z:47u QDGt̎7P#3`K0܇6 i"7}&_/pny7vvShiq^Ě丩>B2FC_Ngwc;6o"IͱmF A n~e!Ój>&rDn\2w>*T3u01 .6oC(b/YTHߔ61!t fU'벻8ٻf,0E&P T`YfTGN.@=o!!BG"v6Q,,4&m@J|c*f.]N=CH`1 ܳ2CU I 3<}33֛N-mڟO$UJˎ'Ϸ!-RKE\Ou*~y~Z)qJT Պ_{>FdH79| !c;c1(}\+h&Y5/ /ٚuZ<eaeDYuUZR:ϪNb/uxUϳ e: $i@ EBHza×jX% OX*Y.j >guFʾ"1 xAU1"/0yBUPHgGWqPCu"DGCyfxQeA -a!4y~_ K?Mj|TBoR8m{M0ˇ{?[9u Bm+3D5CA~`IDdP]Sg9@9Q%N,(b_sٴM1 WL"ɚU!.̃aCkUi7`(ݸZzBp4oRR pc%*V٨MhCʳ y9(hhIb(vS($mBn#gX/fݕ5눟p38 ,և?OB/AZ 6%wA4?'`B!+`jBwu_xNW鈧d7,u.4Qv]~~^ITx z4ztL2L B{u kL"Ț8v(C㖩"f[KͪCb܇{tf󄀇p?Pf$Qa0|_W]gknI_6΅ƾD[E.<®S`57k76cI awPf%b,I{o[**w!N1O|iYaRotMF:ĩ+}!MhL!e]aH[4O jfY,$T.C2CLt|}[¡h,}Sc(C]Ԭ~Oܙq̨=oiZׁEp%MX_| .MO;8*Ŵ̜&f`kUE<<`V Z"`| `KU%A:l~$.z*,4:o13]{V[-qAwRX>v').^w!8 ZQgAp $@ˎ2}N0u-˕]LŚ6 $ CC9\F(]"UN'\)WOyI$uZC@2fb$3HBU)Bk2_⣡e?~:8,Q9l+v bT#8cBCUVlۃmR>G*!%S]JISGpgUV .2`|P1>ibmp[$4aBu9(_3D E~f fzo6D~KUcIUOњ&"1k"Ti7=~܄mz,jhYB\:9+1/y-7m\1B!%fg5tz''.S_i񃈞Eb[Q6I65uu 7 APΡSn%Wy]?y鴳D0bM3c@Omw˦a=L{q p;>|)^(+=x?82$ n,fQKeXpmowwcM+.SK[dž|Y>ms ȋj=q=xg㴿p~4\8$M\;`t;ǟ(8n_r'Y s,-8뫋mO9endstream endobj 141 0 obj << /Filter /FlateDecode /Length 7800 >> stream x]K$mɇa(Y!Y}}cuPzq dVuHL`D!Hd"Ǔ?76ɕS1O)|,iJds?}x8ƜCionw9Tۛڞ 7Ͽ4e~~z\O8tÇ֩=9c'_b{ W;T|>yws~yn rY')4io=yf2ۗw-L>T@M8lY쓉?~ ?\Zsl䛯ρ%%XJTF)ؕ&n`$R[r*O.(ɍ9MI+Q(5e *6h)u~)S89z%v*@YAnɻɤ悛;j.:#"⁞rv8N) V ^a835+f4Jnoh֎m1 (&KS;N=zVӅQ><4'8e?U?p200pJƴՀ_*`ptj݁@q>Lq!Le%npz"xtw+Myҽ T灈8WP9#«/g`d29cq&Z|TLHU(~ke('ÌQnXNOdKc)!uo%Fa !t,$8Aj(RT l?+|BDTf4M.Ĕ X$#kJa@XC>]jHY} i8+ARp̰4)LtV&d.֐&@u>f|KϤaIQw.GgIX=sb+j(7v2FpP'4}ns&xTqmTP`"P]PHӦ@E1PhR|..j_pGbܗ,CSPP̀zh>CyH*ʤΉ`9T\"# *nA GΠr(*o4v/6CeX4 AH DF ILN)iFXA_o`MM /Eץ6U`p:E,%L6rL+]}Q5f6r_@y?XʤPta t,00wfDZ{'-KhHe°rB Vn2 \2 fQ2 C!y@P/%4k'`>$FKM6U\1|@"2HDC T W6¹|8=}V'DsuHOF`Y!SjzB95=!'(0'i!c-ᜒV`D"S&ʍQh`Vݐa} jBp,A1 X~BCڰ>cfyy@}It]Cz} JFMw";%$X>DdD:/1=>gJYFS_LOA`).ҥ>YYEC:zٰd< >ʪ9&K=hHoϫyza [>Bw0^˴h*gؑMiWĎNTLՎqpыj4ʼnDelW.AgF)A_ {X9{Ռ\Tcd5|U36,kcy@g  iJ8WXVeהkR;SV;jQ;BuH ql0`;L`aP8L;U0L; ! &aLq2<蹗`љD.7 b#)Q@Z!3Y3ؠo-)UEr~DVz~9ȱ9gvO9,]Y@_=HG GU\bF_ .GČHo$Uv΋d8w723Zdb =F %P}xR? 2? jHa2D` <@IA4Wԏh< 0/ iJfZ}gpZH0jqj%(!,؇[К"͕!EͱDZ+'FM=Nh)4NxLL Ȍ7VfVN+MVD,̈E懐xZ+^em`%5XPKx^M;[OlT"FwH$L*lT+B@ P*WB 7TдcZJaTwZJUmQ`YR!T0QWxp(L+B,PϨVR&Fj4gY͊P*X1jE(7bjZf^kxhct\d@f9%m ںk#Y_WL^~>l9[[Zk(ak j XzE<@cLS?Ak^]m:΁DT,#s+B>l_BDET,C!T;녻kL" w} J#*Jh 3B *BdZFHJ?lWmL/~C8GE{C4<6=8C4>߂~>  E7o p%{~?Ox]NM9C&[R9\H?lK$7(.o//7x_v&2;O9٧.}joXf?^.Oo)rV_WϏ/O/b>- W7oo?kVD(B{DiN<}oZi(0υN&?>?_~QejC](ݭ&7lj!|ktp`UWxr)z θN:~-]5bU"^^>zf` \`V[fm4m]=?R=~3fӢĄ9q`b'4 ~-68V>+ v!nÜw۟_=H㩍(VqkwJ|yxO1_OM_|SdǦx|hk us a8 ~ƥ{5:|*޹ pm  oUxQ0g<aԖthBB`<y%8%SlpJrx4x1HF(hS{am.QMQ+J 8MrDݭ: ,&\ҕrj6<DAӕmF5 :jYKDsu'~+mDs-7 dG2iś-r'F] R5/ tY T8꒍ 8N@5) ިdh䠮~m# a.~MQ*>cz0&981A81AT_PpcKU18tuxKDx wx^f>XE&P giFQ;l ɉQi{|̠Q$>!dQ>jIV<3&FT( 2ۏZbZ$iVFŷ{L MIݏ?JQV] 8~l9o*f[C#> :`%qs`AWWpˮ]GmlsxLmrv@&P}-rkܲ@gy#ΉH nF > =.yqTs r;qqToEMC`239Rb=KY{ ¦]s.wmgwߚ( 5<}9yw9 oC!=,yod jм!sOǓ7d.|#J_Ge1}EMtop‚PӡI-ciеSPh1<4}OV]@FI4} WxPFDX @lRAl;SF5q bet776a>u|^݂^5|D (ޝe W9:OBt^ՕA(}Ex"3{)4 Q'Upyc´8)l8Klx&764H+i[C^DkJ7&%5.TYNk:' Y.;͉qqDI/6zߌ%l* ,@)lN&Ng H ,Taw$Bz&GN1̈[UC0p2>727>#F\4 qE&,:y\1wK[v8;Ph+ jWq8뫈- 899p9w4 snSr{wUDı6rKA3RiFxPY_ 8:kOFSАKD<{F}}VDMbaˀw>.yqtVe΋}vG"~A?]7Y{D~LC^5H'=`!;Zri2ہ~9. B +n5L6VaA`VLuf7Ly!X-7NiA’2X_0/̔ՊPVOWY)d6^+ByIW])$6^+rBְˣ!W =~ժZy k81V @8KL*}ecP^ee }qc+$EΆPV8RDPVi٥XamZk?[fY]y]«k+/j4^>Em'KRiUfXbû < 7k=NЮۏص_Z<$[+Q+Omx?W ,KC>3Ab[} s#ӥ/@!O@هU^ο͇?=Ѱ^Gk-:ZfǃϿE8?[>|mMwooanL-^>R;DB<[+p{M?ϏSªerS+ϛ*\DK>0VOVtW5jc[Z͉*dΏMwޝP+( i) fϝ]VQ>0LwӰ7ie.Ve&C3aϗK/fps#Ҵ5P)<]mkfYmr_,G6;Gi~hF ^[cƷiVVᩄX|qS{e[pf%ܠ; ?|x .yfCZzwP$2TasˉaM|f#bKZN XVS- pLk6֗ Wc7LfQTַ |xb߼[LK8w`$Jӥujm&Wԏm?endstream endobj 142 0 obj << /Filter /FlateDecode /Length 6236 >> stream x]K#GrB0=][0dc!BZ{XYlG䣪"U53|DE;ZOJFԍ[ZەխY يZ~ջlX _P;pwjlcV/_`u{߶V6U+㼩Xu([K#;1nۀXW!'Q,2Zo'tmnѦbfqnpFo|yx#"u^Qm&2Vf I;v񶶚C<X3#Yڴ"xSāOֲؖH# X*] bBAٍ3IN~? X^@_@\@l[HEtbqMC=mR:9rZJW֮Vr C%Avi5#8Dq o'@ TN, "22  X[yKHϝFT#Ts'1[@!dӚ,i vƻDyq43]@P u9DIu9D{*ObUR;BR@FHb?`G2TĸBĩB c.4b;Yn<1XobVz_ XVM". tY]*OKC|/@m3^- k@/Yikx%DKqd$%ķ(yH 0v / ȎC+dA 7f_ ? "] C D ^@ W~ܟCeC W,"&S$O~C ~rc<ƛ nF!K&&"O~d. S bj0 U!gCR'M>>8QqWVex]PcIXmmz BX~2H)k0.b~ڀaeɑ&6>2"`],陠A~$4krVCP1 *TA~{cE}(2a+*5֬ql謭??^'8C \Ul[r NV]f6Rꏗjzym/a}z}>˽FU뿿 nvVBkG[~+ {L`BEb~د!dk[i{Xi owa?CGHX"OW'(pςbЁam"A%2łJ.b?PhӰ;I(Oz]Dۋݙ @Uvg6&Z + CFAaT01[MD=I‹Jk}Y@ RG3U9+ƹYJRT:jN<9s,([pBSd /[h LS=M}d Ze n|?hD{v` 4,MJem shP@(/ :vgvFZDedˆUc}yu@yS@{yָE3q-S -XvkY[k'І-VEǶQʟq%wy>/*E;@y`E/?oW33/ц0Ox؎'=a~)f eW-̟]v'aEo@Yg؎4y~̞qлeEl%wg6Ze9UtYvmǣ}NtxXǵ(ڝَkQ՚sxwg#U앇 'hwg6wguvx<ڥgPٔW*mF}x'鴃[zߝL(Pfwf?nHQ&AM1*@W DiP00@70B0i@w8//kxxW I]U^<m1:/*}BρFK}P{?i SНw e[=`^!sd&Ds*?t2؆nK}Lq>4,:v@p!0*3ivTal ]AzdHsL"M&OgJy2T_x='R_u`Oc`ƆdTQ g`kEhboлFT"T]@Rƪ; ;K$F62?PѠQ0~<*!dTt4jD> B׆ъѬUV>b%J %%&|V8D6gۤw!D]V~[K%QK"Hk#n`YSH}@KQ[Zm3W<$޾:MxLxqsR`{D!tBU5J̖Hhu1g+ֆ1x(cטP !D- )|ט"F_W'v mZ%ǧ4ٴpF6fpO`CZO%5I􄿝LJoFVǗLCm<&M|>Ԯ#LL<bRKvAƑpۨv>lI [ݑ^&W>l? ™>QTGBxlZ `~wN>-㖞J0D^/sdnӈC^?S]@+|a Ma [c[@480(yַ=6x' ۠ Ho䌕KDh!QR"f/k\7pqCƢmb0S=0t7VΨ0h@%P!N&4>>Cvr0U!lQ~L|'`e6Q X2XS èULLO x|85>ɀ*]ԏ{.΃{φQmj AI t0B Q!N vHcX:񨒒:@ &zFBXpwi G~^Wz I*qzgQ>89X0F(W-cb9NM:Ė) H'|Nq_ ' $gd ku0 hMf@,nȂ@_k*rKĽIw0ia>6{K""A >~9 +Fq}Jq2sH %GFQۖy9t1x) J6Ϸ\qw7lJ!NV]ƜΌ-ߵsm!=,DXysʧBEu63U"L$}\qzaD⯹P‰Pߡ@?asPk_flrpT:oj@jT5Q)i dB@>”!uѕat_TkN*T$Mtg̗X;ަbX]WǼ,|$c&J{I 4$©D *2%A2|!۲ v89d=W s<(Qz|u-4f6jsU%n ߐ'&G~}dh'.3qTم07ois!_2gYʚ6DC}u ,HHXXdh:08$8 ݴI aa ԞaK-!?~%SEeB2IIGsEn-dhET?)cƦ,R L(3k&{mx>XR>74"^}&ǧaq&OX= ]ȾE |ԵW1u|?-]JLb]b*B섅AsuIMc69溚,*"'@Nj7*B)o\ ATSv $Clmm}f1XۅF3orj{v |Ό١hb FD揾6aJ4:O]l[٠>MƊ4J" ^؝ Ou[(.KRgp' +q I4^K*v羀g yB.N-\_[Hdj:.sDc??n//-79%_^u^ҿ}@$m4W(endstream endobj 143 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1013 >> stream x]}L[emK)hiۛ- &l2>q /Ytkt*+TL,udYFiECDAyڽl]79swДH@4-{X!;^>LI!{h Ե BAqJDez~ɖF]gTYiiᾛjs':^00?7:>EWUk55/.珨G;GD[mPŪ22KٱS@Q2*SEI()OEDT'u.jP |e$^zz= o+ώź~+if}mn_ gujp}K˰f:Pqkt7l\{0 w8L7GT ^0h# }ZqyIONrUKROgאjIu̴.|~?{m_zu_}B>|]a9V^h1}îO,F'CdH2~tV{˛s`Ϯm{(I$t@_cBPnsj(c^ CTx;ikaʐqGI")ɘ6SػAϢHAcQI#[PCONc4&^l`:[+ʻ9@x=)"bG 0i';h ]`;=iQ"O6_$/I&I{/_ygX(em%?.`?]i3Gf0`` >{ \J + 8 5o }3^za$.M^[`WXI0 AvɫKWI/I"4aȶܺL84n;P`r,MՓ)\҉cn 2>ќDTF4ka;38/z 4endstream endobj 144 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1402 >> stream xmYPSW%@/`7)nE+VKر2"@Pd [ KX7܄f'IH@d1 uU2V;N>LiKO{Cg:ӗ3s9 U%ʢJIªR|d}u<:(H D_Yb\HIa!8QR$*TriaRn|{7QJ'N$9Y"QHEmJZrBŪ}!ld5ۙZ(=NsԌ2XV[j3?lK V4Ch(Z:Be~tGU 3a'bXTO=b&7b5tޠ$S* Tэn`/YVunui$[ hhVV64B+qh/&.wX >b8JS-䉢Y+x QLzbƸ#Ձ@B$@mz=(G}Q4 @p~ެUr늚zds]> stream xyw\TWrĜAcb/M4 V&EzGD`( fP`D}DbILt߽{@M7y 콞5пwϤi?>,ZZV̓U|\/n-W.寭'Y/vN>68zT׻=x6F]Qd(_,9/%#AL?ʢֺow0~/zDxz]He^ 3xVS8?Av,) Stˬ6x\AW,vOd k))] s%p^f~̤r\FoRB 2#S*`-ٚ_t1ў1˸iG6l@M93O缰`)<~s\_3 MKQA{(>BA6 Y>jA{%b1?BI. J؛O맬WV5Ӈr)%N 5}2vVT VU,")?"K^??C,7-S ^9`sYЁ}p NTq`{ë\\`%x0$kӨp} /:R)nbِeKZO"`㵻Qt uKPS29 CRA\"ֳaQ`d<`w4۠h3$G+x5FK>Tj#cәe}z-C,~/S=2#3,:-`P_!|A\LhA4hᚣVOfƝ$"^_5Mޟa 84Xk}dʏ+n3/$Jy{WdMF{JѮVTxE,T7in?%2CFӏsyoA 3?tG Qᡱ1ANYކhjwZ&&Tjzu} Z~Z9^ ]b8db*GaڒmSrh,M4:N`&l2#i v-}Xi6 @nqeo!Z}-hjРfx yrO;E^C$S}FqQUL=%h$T:b+S D\b^w ;dNCݜ鐳00UI&i%;qZR{TvҨz{,t. . V#aTw\>srƮ:)Do=Bń,>5\v뒒 O8,Gfa|z҆s؞;m'Hz&GOP-6AmbtLP^s2F6ĵftFVEֿLw} n5i%8^T"Ĉ4a(!NXJ& &e~t&' BBJgʰ)UA*eUse"uku~EHUcty@JF,heqIC*޼.A?ƲNh6RWvA@?Xoy=njuaYX(goq`{ͮWopL.FXA7EKH"ۊ:C 'Xc CRc,pT rGH?TC@WP:'F\b{ *cIo@:ײ}]zZϨA nLU/YވR7WOP"mƣG 7xb6zeRڟ!'ZɫqsӺ Lȿt[UuqiUnrF|GZ`` qOzЪ|rQ)=w˦nGNBqs_{#D{Zl33Vkj_"f{4aI2>&CKq.dX Do`'2Z#[fW8B.Dw jM0j]l.KɌH6\6S6ltK((*2l4'mWA9hKeNvda劔 O*Q-#' CM|3Lȋ&KHaX5LJ4;S,v-y]Ԋt|csF<ǒ.NQJw}%p e`hb)sxU6gbPڜ¦S'3+`?4WxTnF&d@pHC$bG'awY.%pxp 3d^XԸApK~k  IIkdX TRyUP/ (BV ,ٛ@ZZ1iBjkaXdx#OBv$ {3f.A3+%BKxY$FdBDk;z%( -c2HzP<ţF$Ж\`=Z)J"4\K}6I.U[)_D IM! Rip+B s5u'Zr]E1U ӫҟnjؿ_Sc_ Vg~5(hZ le:J EtZVFwE}8gofFeDbGY)swb臇@R&0rGMAiQk+U"o^_"vSA)}6!ï:hI@3iQ߾2'rPyׄ&Aazʑa7,XZ!D åEq#nupl𨌐no#;3*uk+a9ij.MࡖҦfu 0_r11\ް!m @5 Umyq%))i|$ƅ3 ^TK=V`Xt:[7GݸOϝG0YMm5e*8E{1%CE|7yt܀uHKڃJ!'V IN9;*CјcȢ.[Uy%0'6oРuΈohx-bpo`أ^';nݭpat~'x8Gt'WkgjGT?2s]%ׂD̿{ lxTiMrAL/o]KVJY#Kd`HPy]Օ\Wnȴ9fyIԥ//Ă -‹EwlYd>z-O۔iy3#^Fy׸5O M\PFA1TAvJ l!Y  LxN]F=&/N {O>p;aj^]qD*d{B8x,Z ӉJv.;]xc!e,d+ "c_{˄0]]]/9,nSm:d hjlO yzKuW񐑟v+='^#"HRK! 0:];UNft01a:/{c_s;ێy*;14jgyr t݌U*#S n(##v׈Z|R>!1a#%Ko}XvwǙOx,Ps sy 4 KY,߰EIԄ$A&I"} FA]f'48~ޏuB85KR~6s[P$i"8<^uƊLjE Ȣg}mS#iۿ/|S\8f2ei]Rsq^:-IvhI:2a}BbqL(wؘTWU!1ZQӧr9'cP13Sxdo u Խmgvl^ɱ+V㝴QΖ&_LO% ߽4 Fn}.QAEA D>u:- bTIs.ő4UZN7;V['{*[!G,2O xUĥm8ZѢbර&YMMq)b}/gO"? ܆L`6/DP9eAACF[/eXYæ`6w'Rﻀ,xHVtFާRrR1 )4({l-^eɄ}b;6Jʼnˉk ܶ2` g7dcknE 7ywdwvAsk/˕uHLtږdPDFG358;-Er}SnF3_Wh[ZZPZSSQQ[h^ݪ{Sh`xǎVZQR/,5}"=hѩ1t+p?IbBdd ȅ$%P*ǫMo۹$ۻ~˗ ?Iu!#L@%?׮8*푢gNoV!s_@sv9g$P6 0[MⰘ؍9Ilv8T}[^ *dfL"JTCJIx"`"<$vmXJ~brGI.=O`|1> YU%;Ϯj{"Kyp tMdĺq?5cv,"qJ/6MNA~zvIh@ՙ۷m2G ٝb1Av3x%MH2 "T9'SjPoK><{ ` IRĨ$B2FI#L1( Bz.\3} ޻V8{F `Fcf 1p B$= vi:8,(!;ؐq dF?4#IADe96$v²KۣzuCc^ۭSB!s<^> stream xWwXTW+7K\#Fĺj4 *hiJz@)^$,5qTtuS4Dcb3<~+~QF(Hd~qXBtV$L'x?Nju5Ffbdf7 H0IX$,_)ߓ 8lw]@ ;W]P;vPHY<3pMvk6m1[S59Rg%zM8]wm %p|LJm6RQ)ʞfP^LʛLVRm*ʁZM͡\5\j-OR ZOS eN$9TJ-tJl-V9Ks  f_,17L50er sKX'O$Xmaq1tLgFlx BZN+.E)O32QF 0ToD1(;7=;{/Je"ZP5iBx7l ?#YD-HEsa@㩱^ Z+P)P2 )[N,[vT[A'+Ţ+uݛ/֧׻?opn#}l |BV,L O6r-0-=Kat굋1#Ԃ ZHљ2}e5"%χTy}DF;b@#`ygv]<ܠ\߅V,F2YiOiwIJjQCh\pĂ$%wE ܃g_=t=ډmهCtJJ^=xq7ւXbdTZv|&yrG%8:EA,6*X_A]? X 4;᧏a]ߌ#>gZB Bta C0 fb>w3B$>iF#|B~5e֑kLK{ۣ;Q\~ҁ6^嵒*_cyt_f~07ܾQѕ$)%U]e\op_`^Ӻ50_'5n- K&I㰩>4lm7b /y!SⴖQv2n_zh UO4m:3 gX?+X&ijDm}sY#|q ,5>$,/.[io bAgyȀŒNjo/PdHC6|sY:qwqшBGY_IØ&GoR*+0R@8G%Mq%aؽDG4;wiZ2A?wгуǎVuqzTc;HW5:N0ш`m*ri#zU4X7UA֡z45Ckˑ]X~d BJRdr \'&ZQT*С18#[9|+Ű.\u lX'Yn[U/IJDD-O AuY80ֈJofpGqu,)( ZEZ֝cG8Žق_Rqd~5 ү3zp,}5ve lko lbm~d+qhjPvblr6>_]6_ &#Ka"=sSTTRγN͉5 =')1ާ9vc2kP wBH77>NMጘE+|wZEa[>CjMinN` G9x4g)(&Cᜠדڳ u<WfD>iّLg>mR %b<3ųz )%qHƳEdpGa?1/)y{),*,*CС⯠u&2/fө_ր*?BYoag {VǺ#hcYΪ W>r^O=C\?maHR< 9i){5_ K6SRׂ& yYyxMcv" 13'!!GNE]@:6ey Oq:H^3 Jq-]1߯3h@Q2`AM7ba(wv.#Фa&tH/YXn\1=,pψ7*Є, ~|{σٿwGl=ݤڨsb'QB`-mLhJߖcMڝW9-LYaB*%ic'956 k8u%~HAYMgTy e ^׀lP၊1?x.sB$U}YSay~ƬÈn,kZ,nDZΞGt"ܠ$9:ȥ+Kg]c6_{px6nFr! WQ^J> Mux$#®'7np?Ч+ItkS mF!:BT *UC05!K-KVLR)|<<=,/ D=ǽIlY1W[]7&G4群L.ӫ̇0i٢̓d1[ʾfemGvqGϫɫΫ zX6WpDh/\.>'ba23&)7K@ J~Yi)!ݣDh<$ƝIME-cx>⎫-{ ԝM`-`\OQc2RtipsTgK ?mz_6IM㰑=`Kp&˗ ̀':- pQZz(ܭ" |˱u~JA 5j/?ޡ+"!Iv@ B!!㷌:Pȳ.]]΄3hUf&I wU Q%sh_]T$ָ~8s+׷Z-EuM+{!y:G#FRUb, qa:܇RVk(#iWDKxB& RGw7qK֘hM9#Oxdf]U)+,63?Px06'&Pendstream endobj 147 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3043 >> stream x TSgoHȽ,E۰7XwܾQ:uApRQE4/QP, H,Ȣ KhdәVԪ_OG =>_|vgΜ$'˻<pbd2٨աk ɺY/1$ms\(ʤ1NX9'a.wŹ1*<"&UL԰=35>6nf̙sO߁}f JDCFZbFMrF z1^3ɐGb4ͺ荚ֆkB֮Y>yO7 ÌM1, JM ٹknm1aqk㓒g͞33&3:fLa0ә f̄0 f e^gT ϼĨOƃh<,::N S(6(PN<|..}:cn3o1 6luR-* 7̋Sd^].5A,2oxI,w^#j r *4t>jX,D@$Z>-ɳabcMIܭ>RTSP&aF`%9q\gy@\;sUg VdS 5Iv ]޴|^2d21Y@Wncs6i& Kcp|t2 G0i!?u8 GaHƔDmZ0 82E);p%dD- jzH|:;Jb>@΋HI?בֽMQɕe2_QݠZ&4QTsq%OTt/̂LNo:~rG3E|Ƕ~*4E5a8/__pkGyTP{z(kb"{r}%%ژX pbRt[872ELYCNn(0C1Dsp|E6IeSQxxix66ͨD afo-I:X ^v:ȕ'K_{ĎʀZ, g3ѳ6 Pe^|׋\qڮ`W$$Kv:4)rҤ.MҦ.\hY;$QҮs$-Z]`y Fͯ/Xyƿ|ˏ\JytnڄWҼrFT k|ttfNCDeK}>Kqt7Kc-=csux[X] a;#N\3[[; f,MP@Ot%ɜ-D>˟{o߄~ehIL|Ko 2mwߡujCzˇ9lT딅tiy|lJn-!PR^VY'tKqt|(6ۗvRB`2MbIInr"lzK|6*G(ZpcrGVJ_6L]u[Z&!2/:K+usc}h@Sj bۅNeZ8P!bx .%oy#JM:>=3]UL~[F_"[,J/fΌX6gsНk_d9WY|vdͼ.PRUEM8;ׅN&ɗbK4܍(^}+D˻u}*ޞ(kNNw0FL}Ƣ(}\V9*Q#7aWuDʚ6hzRZ_H _}x5Ji|iD=mSP9d"-ff!'O CO8k$Q#C{lhIM@WU|qu7.N YfCRSQj7Q+dW0{;Ɨ3M3ViZ߁<(ԞV~Z> stream xWMs6[:o6&LqDl$Ѧt{.J,ttA{ocF/V#6^G<jn:z{-+*(.c-u-SK3Fu1aY嬓+``Bֳj m!F=m p 'e`Yiɢkb"irIY(k$ehj``z뼗F 2f#UwƑ6QZ% ;֗ꄁ;^2xoizZux{*{R>oڶۋQP2cPk㱖4vRKm{ rJ֮pUy}ܢ.A Cذ Kf:-SC0Y17p\ y&*44oC?LG0endstream endobj 149 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 858 >> stream x}oLuU'#ehdͲ0tb̲®Ph ]w-OﮅntY+Dhb|Ľ]5уaL\/y=C: (Xw;<COp ;=fs~n PhF/jh߅[$Z(2fաFSYz#E%#[qL7!s(X00x .jZiۯlpKϝ[\Nfr> =i'A bccǒ̜ @sJ2 { ^ߚW/ڤ4&){ppa`{8{yHCL藄_/@!&vLh8t49;LB5z[rb{iX\^Ra3O/~BU;M g ݤcg 9Eq. >{{DEVqqj> )`xQT!2$S[$0īHӝ.|Sm\VcVYJW`ńZ#SG8~1oW0~7#4O%y?B.|L?4@~Fjei4) tQSiH'$nD6&5Rj(說J*Εebluڭ}8ckYΩert($Us<_ endstream endobj 150 0 obj << /Filter /FlateDecode /Length 277 >> stream x]Kn@ bn)&dѪj{L""d)]tYq~^i\S67NiX1?(۔2_aۯYnk|}/pAߺ>8X(kn4Ivj;ey /؀Vl@;Ն  *c -QU!*" l!BDtP61BTTM"#46"=EJ5Z* /Xn܀Qj;I_RwrJlqǔo˼hhendstream endobj 151 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3276 >> stream xuW pSיr &D^-J7!4!ü[6O!t_-YlcY~!&SI6I)m:L4{DwG@hF3:? YI@ X%##G^IS\rŲLѪ✊ģş% /&zO2!eEOl=\OR {N7s e£ԟXj2#WS7+u8mr>*TAG/W5P4԰,OiX rj ]dW]~Pd0;{X|iLp_NM'΀Sd j.C7#t'cgCR>V]O~0<Go@~Ze,5^ کiJN-cԫkM AWU|9_ϯBB1©qw}> +:=@Y,~ [;ne'km1 LZ 6R,Zmg:|O@ȫJ4~` (qp{@vէ#ͧ1K'vC+9@n dapO3`*k \Q;XwT,yq| 1yscw0k)a\ZlkdGSgRfؤyQrTM ݧ>5x:p.2c/>bNcr}-"?>p_jܫS^(+9 pS|d̦e?o%w%0x F_O4fZ @䖲sS]cN^>jl*Ç44՛'+s?K%+/ -k_?|ToCbjK!hKBx{r(i^"* jg37$/ŧ1kj՘x?hb͟qH4chQh^^Lh?=iU NE1UtVeU@ݟ%3>T8F$3 Re \R]v.U@U\<'-j\oaY3;$|yUX8CڧAK'0AmM;֪w0%#wHl05#q*9V@j3}đvC&8z7^CK &>E7?J|`HEqPh*yk߂J_[uLFsDw rZ_͇r'P ES"_9ʩ?(LN޸0ml k[B?zKo,i?;q9p`b->3vBk k~恊֞w{Խ*꿊$(,Eg.t0.zYV~mCFsPv8pt1M1̉ƻ}$B0q;*S|-G+KJ*+KJ+h,+F9A7\YeLg(;ꧻ5{lR{3JlBuVb|sjuv91ކwڥl=ggT`{U6_c)aB. w ~DZz_FMa!ʶW T{}~Cq,kŻq1l+*j "Cbe۽}f'W<n|gJ4p=J%b XoC-5FJh݁sż$aS뾜mOo8K-4qXjZu.ێ_;׉3/9 ^ʇDҿjFwAȼxƷ̟b{KЈf& 44+FGo8?-:+Ņ">}l& lvvν pف&Mv`ՁYсZL G.ja[\1=hއHKit59%BYiTje YqNk5.B,f0b*GOsOM^J%d*`q^h}g2I/%.'!Ho˲nΏO9w'"#HXO86uݺ}~6qGeQUCw쏦%8P`"v(π$Z1G%l:45:tt QcM*Ɵޓ0pqZ VcT*1ȨHN(^wyݬul6zj5UF :-%E!.bSoMp6&cX01dVQE#3A:SW(oF M{`:.g^|:+Ey'yS4ԏb^& \ }4rĹ9L/6le:٘rOTa+zxX~|j]SfCʜ87dmtX%Iendstream endobj 152 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2723 >> stream xV PWaFqIU*VmBT\h=_%4Lo 1@]8h;]}@¸D`cRG]ayv ؟]an  ]e#1O]>2]P4*5mFF**˫k7>Zʀ|L(h@Tk΢nYQ0vW/D-2r" ^x-FK?9w͢v6LTus+;_S <O{0QhF+rpyhg{GFF&:"ۂ- ~KʏOu$ tli,zImQ}}\5U39:M6$Q)5ꦖjs##˧k;pФe909Ccm\Υ{_rEaMc35{!U 7=6©5$4Lp&X](bl P_kTuM@uhÎz%G]eiuZȡҫrj*Le ^ $f&IQo2V[YPy}s"QGY?~sEz1]VكD?Aڊ@ +N%1 <؎kcEnk P֔V%%'=fn2?=QX(܁ʧmcS9>-,H'?rwb)+ ~%2jur!\BM|\q{-/$yƮ/aUWʓ+n<|PMP-ZvH`yq{ Z5W.\0X~ބ?h6ԘfWJL ; (uخE(=1t-Wve)̖WB옾Bh5bbvt h׏WB3l|Pܻc \ff!Hȴ*ԮfҔn=pOZCɰ^lh jNpj7}}BO2;L ͈b6myh;*՗䱴:uFAvD8.UwӍ}b~8~Rb'p55!7Y[`+jUUZҭ{vt9Q' ~cz,XI䖖߲B* ŜՖ5 K80eJcyyT^Lj3-XZM2<-,"Uu!.őNfY=i>PMP_KM`fq0Ɍ~-;6p;%LeTK@3$%"Iєnt}LSƑZ8&E$eE.g8OkTshj!!8Lڀvlłֽ+ XrObUu!A ni@$E%Iu|=4ٗB +#Cs_+mD_a!$Ϩq.4(-6a0հOxjmdO!If0fPj%LkjQ|eEj0L qr'Gh0 eF#w͕K9+)-vHTMendstream endobj 153 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4287 >> stream xX TS׺>!CM8NO85O}7ԵSu2?oEm"rc9{d[!QҨbF8F/r3̘bjF@%V!=4R.hUiZ dZZMҁ ʌwL$XUyY;衋: v M6FTeqto Bpw~[h6\"P*)@0/\MU@םA`$ܱ{"J~2% /[./ځ\\ ajOlT*EZZ)Oj)՘k0S9Tw se&U {N|َ)O=@.ӟGV .ܿ Mnz.|HraQeH@ TVi#lF2-|}: .{yC139 mC87ѡWf(f*' f\kvoX?<Zu ٮ&~ru)32s.m".^* 19sRỢwzw[НNtyyo~e=bGNj ZHД%Զu1WC1L#aV|7Q(Rd*zu˗C.:Ѣȋ|=5jX.kfͨ]1I)|J2m|B(@$Ϡh,MJJ0iRs{3 *| V ]`*7 tk.p rDf3W ;VQ⍳+ߙ+`&ғGaalvqUp)ʓ<0r]\3^ؽscj r6k1qF43SpuׅXG^cl@J@%]B2TrHfv5{ EPƧA-SId,#lP*WA 7 sVsi,mqL(PhMT J@}r7)("3 @,G~ ;SZo(cV[ 1G]Dy.Ffȼl=;d礨%=P_!>Ľ <#4C8YJRLhwUv{xZ)_oX !߿@po=,Ôd^~fSgqJUPLJM 5-"_"nVPNJ!Lj<%NxmQEnvFA􎡤wЋ]hrgm]ByV%ɗQoį f67;+z ՜N`y\l el`hJyQmq3t=?^:v=^[QP0 @SIk=*Kejj=W"0cm>sӖzc%Ԓ]1 XtjzHUu X NX!-- =WQ Prٻl=dq;rWq]ex,)I*Ha/1Gqj vCe@!(=eęµ;!Ff Ƽ\UL対FifxU_7lj9VTyJVb e;՟nonMUXl8o}'M 2Bϸ,%՗gH/G/ sj\5}&'VdRM~Ieni׃ w;(}6VBԩ `2T#ysa[]ȫWF?—F/8Iv$IwAH'IL:(( X>/*Sf)U I4R yr<Tb]%hŇ~"amv-aYƞQ.*TZA^@q9WQioW>HNwWy7Z sE'}=Vd>ǬT.7CAA.*jo.4z+6Ekďw0n^&o)r*qY?:^8N˓E&A1ҪceԑrQff^rtona!NM#"ᴢeNY^]!J/gAc/v:S \:ܳ<"5X C9CdJJ|H0sˎo~fsK)=ؕ :jȊij)c T48l999=z=!ݘ{FoWXT/Zh0)uGxhGfՌ$}5MEER*KOM2]ڨo7cP璏Y=kWiS;/9EEcvy=k{L:C%}U{#stPA*=J1IuR/ny`^v'rA\Ώ\Ţ3xf]+y /~~ۿ_Lmjh/Axg90J2/{iv/+X ЋϿɝ̭/tTjmuRc,6h/&aT…C.f1TRU ='W͛ȕ9Fӌ3*g*h@Fmv) D:^&CQ<)9XhQ[H"yaڵV%=D2r YQi2kujkl-茸\8$El4?1#ܣpl{mJU< P\iKzG≮&gUs2qzg/:(<|'0n ڻ7]`ؽ?/NVhw*P K ׮tprRcq@[+P &]AzԤEaP(4B @9_UꁻPut8LRek' xC/} UǰR+~ 9dsn+[$Gamhp\͐ !ɒPR(Q5wqт{_%Ϛ3kLtP)Q4^rHQJ2I E !\G!hrq BhAlVldrG5t-h> stream xY @SGy}ޕHҸUUH((**^ B! 9 C.9ŪUVkViuۭK"q̛F7c6zձ1ҝ1I/Ϝ>lotg?3qcqpO _aǙ1/_&Y ',D(Kg>\w}3^aV{2Js}a3ze ]ί^H!HvDhErl Los 4@'18%[Q( ͶhbG鈰W_cȕYE>ȋVҥwA'5E=Yy] ;QqF]Jnr'P%*rKh0JB5vՄKwllg,gCxPV{t>l~L"f$K }}=Vr$NxZy[4\K,7B=46;%?h!߼eN#\sh&~4U-rf'LD4צ5Mvc3,ôOyZQ՝KBU?QuREcehn 6p:&*44FC"h:PH*]ٛҏi973U5;"gVPuɫ+GtOsZ o=hhJ+mEX={m(ն:Zhlu~kR~FXՈ&5xH{>)Si&P@n x`O,~R6omϰɹ:ye6fإ-hQcaOl }"hn\Phu(25/wgĞh b6{(NE9+݋ c/gϊ,SK~z6O8X]raWFA] S%XݾFoEnc*xnZyiZsi_-ԁSUA@((ĝʽ@OTSt*9t?sO ihҾ=Q~idT$kիsj9OS}4 ߦZ{EIqlmy]}yQ=S@W9j@7*zEDrq잺bdwpuHQ?+`YsQwaqAAmayAO4k)^âSV\yI7|Tta}U'IZ#\T0mvȑN[ y'<^DRAg/BAq|lv'f\#:jNg==(5g?{\` (Ւþa'9lQ2]H Zsx\<<m1S/+aD4E hWe=9Q}vbw+(x*#M\@~F#E<YX[ԖNB͜ZofG& JQ:BvF܄Ɩ)̸K`.\u)$! 䫴U9˵,c2f^@{髜*)'{|sf>eUv{:8Eȇ"~.JݫQ;YM>,\@("Uχum80ӐTfPrJ(r Tw᫏ly. [e+ϊ=V؍0HB ?->8~a}j&̢yB+P05RR[/Ex+PIYE>{ϻt#Q,)"9CQ]1 "*@ ez!NgHшd} *]vJ@U,{y_2]Gj!рL ۍGȿ$ _z'g/i83'b#Vshz ^ G+j@L2+YKѲY0duN1-PIͻwXn P [|k"ȳіf[~5rNj5s K>|UMjhJ{5-D65ivitAF x;P|%R=]P lHgu7mI$Op>_%MU4F >圍A˧Qu媍v|L-?8wĖnH;68&;gop"am(aK~>TUM2(wX"KS23њە+9߬AyB_Lݪ63ʢ=/΁LPf.WXˍ*0M% +L:)Jh4;+ؚ{ eP^PW.*h!]Z `qz}J4=P`$+.zG_]URikPʣ0Șt#W*{҆f\T>u ƕ$m[i3*Bc{"P6 OX(~7J>*,9RUzHo!$Ɩ ĚYכt Ynz'(6bm܎>"5_7 HB6' \ВZKlNnhw~ՋE-Q]ͧ>8qȟ^ O.:z$r6l!f/ʘ\y"r5k>| bhfغfª(gEa`./o>~H*߹& !U#7^􌭀,+Tx[R\q ?GIgYBe E|lW$l~$da wMdwn6v$קxyw:&gX%Ւ9I%OgֽVE/ lqgCu$NI@ڐҿ}.%b=kOp07B?pMv/x䕗!x<מTxiߵݏ5 :ލ:ܟ=  ?^I,k Ѱ#3b3:0(El2j!UէKN.iл}Ց߲'{+N?"iJ=X!J鏸7~BE/Yey?2SO "/<~=?x͟h$zZRa<YLڦhH#܀&~:Lg^LēaE#MEe`fw*S 'KMbG2jH&dh2fYF6ET莰22[6G/6&]A*ڬdf6 iIɺԼtK:9]--PEҬJY'ip*+:Δ ֣'I5._L2uhkbi49>)RfbuO]pTL VpJWD]MՈ" xq'Ш p8͊XAV};خޞ܎֋zZ=*mT(RsڡFsIG;6t*.\;)gMFsx@^)&T=W2 U rwǠ iFݸD@ |{ICPZCyDݾ P4h5ZX!o"^dSw쇾_&|Y1o?D̶jL %l} %ՊY=<&G@bԲ}I߸D`"B7"o@Oy<绕c"aa塾umᘹ|& Q3[BSj+>qEaLH27TCEy k!(6TF;~CP7AkH367r<<fD; gN⧧M *(H4M&}H/BRA(RFu-gBUЛByz[=WmhHțRмhe4Wՠ-BSWdGE'h b.`݁*N.T1<\4?FgDh"%z'H[^<2_ K-M6(>`D#D?ħN[N ʧ6(7n4!,o0jv8mn{wsUCܹd܉:r+7)sYL]REW1Sbv2U)&5a",|%YBa8Cj ל2,ņYx3U|J<6oSD1]s6SP_,.%O.#?KQEFl؟fI'Ux([K4)jt Tfu~)/߾H?#"mD< MV7U2MBa,@E@MK))Q'—_OTUI*QhTN ȷ>C"kGC+^PXQPO$ v`m{yߏismA};dIDZ4TU{$*-0:4e9JIkX*7F~/@@17EZ!̯k@ =QmבNj5rDFg:eB ? +/D<^@\RCdҒ!B]2N69g^9 (,FJ*w,uXcq4Ưޜ$E'˰UA; Ѡ';o@1ƃE6`ܯ_!屺W\UBW }䶲{-.5! 6 =Ti*k az K ,E%K 6!endstream endobj 155 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2271 >> stream xUiTTG~_?Qh@*nKTf@Jw3j&4Ҁ,(.(GEO&d<5qpT199?z߽߽DfM}F%FOE-6ub9=t tZCpHAhz,+VL4y6^,1m|N3*)6Z#w"Qqxu&9 V)%IIbnMQ6>1;9%|."2 J6}l)5 S_PAT0LVQRjIyQS)%MP )JJR4@xR8JDS-ڙ261o0 Չb2ZfJ ɖ:B_Ni2lux7b[OuiiRV#f+$ڕɌ4^sBᆞoA~M"mZUՐ sM,SV"o>1v% z W&!J7/E`#&(Ʈ bVg<ʏ(@5.s%w (,U4YO]`M:n`{re3&KXwG *eut*>ߓ#_9 .@nT6ꙘГ$G9KjVˤj;6w8t'[Yi* C Eve2]DQ Њ= !% U{"eW( nm&iLE/y6]+dgR"נ`[?=;W]w FgòDܞ>K?6ih}n sZ47c[&s+b]7l&[rϤtyTɀc'҂t0tsDK{dX *I2H&x#wn]W|>gا&ȰZ-y  2 XZLo97endstream endobj 156 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2477 >> stream xV{Tw!̨J:R &)X @ "PZȠlmAPՂGBA>"P1ieժ흜_879{{wopo8>1L[PeMfN8l:iDΰ[c˯sxnMS e*;ޛ9;$CIAvfJ+/I/$TQ'q~)r7(yleBɊ]Ba$/P6#Z|]V\v|NJtyo sc1 ,s`^X(&|c"(l>M1!Fc1 Ǧ`3a|lkLxeCll N ~ !H\$@*m2/xALJ%P͸R||VlaH`v0j6^ھ?hg{Z\;I;{.X t L2%2}U?;oC&P$3,pCh" B ~ZQlbn}Ax o"}VpJ`s)ac.}٫-zة]\PH3`R)ú"fccEm>>#*XPg՗\wivltNS^>J eZh◍`.M"3_=n?dfk`f.RG(pD.0AV%O|8MZ(CTprzpO衝[V˷Y+e\Lg_$F8mkXu}mak {,ß8{5 33 4(pWXN6/S퇰n*F3|p@,.%hɈ Z$0f%Zy]۩}2p/uG1-~2XGS ybTo"/|ih.~p L#$/^I( [t&Pa[rn1r%^TYCpAU\\ ̵:B̤w܈I-s,DCܳv;-D(5ף7-x82,xN D@@BT { Ǖ\XA jGqt/αq~yhI"L-,ǛM#;Mh%K+Y%L3P*c72g ~iGxhʤÙuR< C 4ɦ.Ѻa G)B$=jj\m0eƒy+r.YV N,yٍ3O;_r#Fags c0a9Q{9/$~r?:jFl`LOrF^|\iXC=+Y: 쁍0L$_MK=[XRlpN'k&Q9m)pl۽7`>\ @^e"Qqc 2%9܌-9{)kQB^>pa#HgNxF])5LنXi.xH\hp'C=VLgP"tulU~Ưp]xnSayp+p =Co" ddb?"dw8Ҳs1r9Gg&8EBYƕ q;> stream x[o$IV8Z,CW4 فҘCݶs-ghʈvYnZb/`]pzVtuKoZ<_]]) L\z#h8lFIaw ki_W l[ü[qVWv_olZgV TҔ?_>xo`!WXjXmxk 4l}#ԳR9h1 Id:Q L)r>qHn9U"s l˵vfNAUXl ZR0mZiQMHV9x5ΓΛ߆qέ|08nZPӫ ؘYg)LʞLY[8\aIYP}'.dQj& ;8\r5:BN8++<U*% fA,}~Uק(fs=iBNZE)6ؔRZz b؏<Ð<&KpB +m@%@(*Z͌ $nQW!6#> f8( .ś~} !𒝅10]E lR7ݚVeŭ|a=4đmil5SR0R 8A8@Z)Js4pǜ*##it^4)QVN^^"`?YsuGAPf?ѷF#*redYz=8i{ʻ^H0FQJ DAۏeH.4 FFi(&9cwݘְ@l tdS@x G}g(UmeSLPEbB 1#f[mqG%1~mfvޤ狪`=fB4}?W@HAF=o߄-0f  ?O>]sEllJt@m|$|zAXODML`k4nn #maK(oӷWɺ^,!nvOJ* ,g'J d8,9È5 5Np Ð`pTK,JaRIЖo%UԸٟU 2#*5n?|:R@K4_׺FUBT0NʮںQ(HIEjRJX`B&J 0Dy (,̅_h+c0Ц['Z\%5-z> BmxbW!B?_]{=}/'cW%*ɑ\B * A8euihλU)Lc~V l97GRQי_k;9G65@ڵ4}Vnv s8AH B2fMϸxi2ԑ \{#U`Dn{ݹXE` t݄q$.>r$q.zR⥃ҐS")>\S2BSe2"~ TQĽ&TQXFƎ\p$C a4j0J\蒆j \Ykĺ,҉M*v0Fњb`\V1m.ٯ}Hц޵;u# Ce#,ұzkUTkrw&2E,v X47좯!ːL?).wx@`İN%z*/UupS)G$q9emJ9N():]îsXQWci/=ѢPkxrm~|[E-ߢx%LElA<`QNYೕc%6N|nE,BAc_?bS 16W*(_*iL0axu~c`GgVp\欞+ )XH^FnX ڒq7_Sg=scxss"9D{%8HP#CToOkP'JPGnipKt]_Eө ׃9g?lǸ6M:}9gv`u+q[cԸxe>;*°!"%!Vt3 {NJ$ ]dsȣTW/+(<\c-L0]elj7oEۛņw1Gԥsll8/J$d@+%zĔ҆c6pQQ,.~ :es7C&AL7mUl 9z"kiW ?w+N,дg 55!bSZI` kY Y7qBr)=Q!S4dE>mw]G-WpGp|h9Ǣ?@P1Me#(W1Q\G w Z >YboB! /"H`49xF>0h VEsq2QEJ:y)}P䮼ޘ'sYnC2vL8 [D;! |C3LJ5i;$JlWi_F-P(5S;!K;s!6˨ ^-_lQ'G´1?l3G|q=toEX@r֗}s\7/մʢGcMp/"t?7`endstream endobj 158 0 obj << /Filter /FlateDecode /Length 176 >> stream x]1 EwN th%]24^/8IҳoL#L&N0;O|VHXW@؝G{c& QiH@7nɕDւ,8ITAQP*xkDTo)߫1E l[vendstream endobj 159 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 845 >> stream xuRkHSa>NF.Bʪ_]d%VmM9G\svq=tbY`] T ?EJ*";Q}}E2B fwZ6Z1v4Il4C숋UU @n 1 _NL-g[nzl9.,\noYᬯsR.?ǐíuI;7YYfsڸ"&p3+^__Njs[ee`/Tau8=k*+nHan(J:}V& (H(%u :g_| W/wvCty!bӂ׍WVƦgq&b'j7w G^ו6$kOmLܢoZ= |M[l+zHJ ~27j ?rI`zEK[Ҡ [\8H_<{;| y<%d 똸<X~wɅͷ>rS. F&.d rvA0(FpDڇz6xHrġO8q8$h$Sؤ1OCb#g'Fّ5?uؤKdЀ=m1:Ubf!Х3󈺒?"E?R6B4h}I*]q*iolsm04ϩXb m6ht[疽`7XqZ%eK]AH|,rj&&;;P0= CaE> stream xcd`ab`dd M34 JM/I,f!Cܬ<<,7 }_1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C50\``````(a`bdd?3qG߷0~բxy؜u̙[r| 87mBU\XBBy8yL;ódKމ}}}&201g>endstream endobj 161 0 obj << /Filter /FlateDecode /Length 6780 >> stream x]Ks$q7;>9{Q o`q,;Vb؇z]fsW>;*$:zs@"n5b5bX]|w!"Wr}C @b+7^(/~xyCj?^FR~nKo^J';Ll^ qqp$:)\w>Ozn}B,TҌd]^Tv^/~u[#a);/"/JuOu2RQiS0K o}Ϥ}[,uU0J^F(y*mor$刺dwf|x(|dǓn~&\o-+Q1+|DIHwE)r HJI%46nuN5R>*ϿfA-e/|yeUݻa۾no2Wޭo?{uٿgÛˤ0 ǧ ?5矮WRJw7wofU8qhS_iX+!_oWzf%D/jGg7wfX8`} 024P_\TNV8}I=ҟAxq ]/""V23 *,HAuC:Kw`|LF_,#j5 ޳4R7 ]Ҧ% 8ks `AA[X3XA(u11dlLhhӄLO؀ E^f`4,2+$ިeBD(,2qh5cki;qEjSwÉ3J)#,Ǻ goz&3n1&1XI bUu Qg1-#9#{D{ 5 Q -"4tDbt"e@dF-!F$"`1cztHYH\7#3S\20Ba 6QH5 R-H% 2LY 0ׁCN*B1Hş4ѧ d f/ycd-8Tc⢑`XdOiL^I)!CE@cʦ `g.1v1=r$ eY`=F&,2Rѥ {nTOX; 5ekf! hׄL]b1T {9Y2`_JdP횐f_C R yCuA ~wB&Yxe?4~wBfʐ؎Addj 9edjiH=6$R1, =E e=@o,̽ <x u'u`S R+Ls*HšPX;`28d_);=ȁL%dJAp0H% a< qKl9,Wg;@/Tj40H Dhb ݝd3@.l Xg06T&dZƨQK L#A0%D@. `mF1vsUsXg Apb;" O.#2a1zdq_WKC;w ݱ4dGCm<2x%PMZ#9 >O R([:nEvu$+_>^Xsݏ*VOvay|y8/rjT!W+!9G0ŭ\iVWNr뛋o/t\\!;rpV䓉.!A_BB1u7s)㋉;( L]|xO!H_0é΍hVLʍhp|f91M*#ۨ3+7i* Ӕ: GTNMPl7N^MT\T\)xn*'(ђȁSS#R,m,V7zo uVLFKD4ω- O |)}f0Dk`MW:JMvS@OPP:~bQX6ϥz4Z:3e׃4j./R^t֥$SSgהya#uEZ ,5a~rMxdǥ(JSU:qpԚy}jKk3 izUN8>)5(/K)sX\Qtd{[$Ѣ(k͛it2\ )XrRT_AM)̴:bz?O"|5E^S9o&iN4KNxlϥ9?-o5GМ*2ZBj+`ٞ,L>GDG (%ʣJrhe Hj |`ASK̇u:XTr`q͕s"h5'x4GN G=|0~qF_>P )IR_ qҀy"ѢI&ZZ9GCsb|ъUk9q1> Ffg{4Wl/pƉF(?"Q z+zZARsQ"s|޻i8z-!9ؐ=Q5ÑEu=Qئmy~@[jOtLnFOt#3lˈhC+!z5Ci:T;/0ϣü;yyA^aN;/0o_a&_a> ;yyy yy;/0^/0;ۗw _a& [\T/p'" Xe6 <*&7Nc 7fFTo\S35k; ~L(0%n(fQu0!E:JyG])*s:eR`Hƃ䫯'0֫[Ac #:is?;Gy^CH; m?;l s?gp˭Hj$С%3t%ڎf!c}#"<#DC/Vi.2/ṣ$״AkdH54>XtvnH {4D_IFzi`J؀w|B7#{PW5#hzYg<+}>jjBVFX][MHժՄ̭`ՊMLfjG D׌Tϭ&j@t-[iX \N&cώ) 6`qK(#Ł(4X<dd0Uo@|t0˸9Ɛxx#[t?#dn!2nAf(8 b|$ZE Ibl#)$e#R:,Ө_]^A8 Y/a O`JƢ:(VXgR7ӕF[U+Q1 ";N u x1!z Ԁ>vK]akoovx"lnS\Uk<#x)yHP0#Wuӯa1)qV%(pG"WE԰H a-grSD6{279FElTP,AȊ]oqؤTn"uXT!L8m)/Cl I/џ&4;-$m6|u4 z #C46St?!6 t{:JMsfqpŽ7?O+@aHN (*Va1~ӽ(DxJ[|28`TQC)!A&Dm `UV WPOٛW{rBwi!J0NV\ޔ \io*1ǎրݕ)]+ vOP՘o`uS.t{.$Q21=U`(Sp"^_ rcinv' &8ص ihL#鐣 yUuy1OeNgLJ5h ]$y@xW˛R&#X(`b>$k7NZ{ _V6j fQa(=Gĺ>{@Qm}6vPQ-۸3/9)?Tyk ^%CHXfKc P^41s 4yI~J4sCT3iP6@˛2il }o48D{tP]7.lv0ޢѭkPMu.L$"nKF pCZܺRyg7^^& A}<&X:m1%l7M"SxV.I3'6۫- !A%R'ݚD%!XqT1>k+NohȽjvӥ2n负C$ ,Bە(:[z7oE!hhc'-}gj2WnNX}RNO:Tm[\6NGm)=R%>n0(@tp:2ʴ$*KD`ik K=& mk#S}1:1^Z7b7r񃎛7$DEIQM 3g9?XE&Q@yFqI§py8%3tw'mlaMS-!2a|C! @E[ ^gKHn8A,O7e1Z_'Ɓj$C] tm~شwsʒ@Gcn_q+&ۺ*iO)Mڽ&ceeX_.yN]NK 4U{WmNAp\p/Uݲǂ: VOCO1m Vyendstream endobj 162 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1030 >> stream x]Lekܠ+K%ztCBmLGb")0[ #cAAq~x`peIn)G;e 7cpfqh}oy ޲5Pj2;V/ Dx^ EP$K<_<"3@aV:q:l:jV-99R'P9惕tە6l?DhM!ܴQi;e)-7WQt_*0fT! ϘyI lViyt z օ"1¶c$E-+G@qrG|<Tka3iA-;Ԭ&6}lYs-ۇO}QVh7 +7-#M\R|9[9q<B1R8"v'*o%-/ZBJ2*I_x(OB5a>]Pm4Gߟo/.soAXEˈ(77&;OA̅JsyVV,x)mpyIdZ0\̯5GxX' 32C/ uѐ{ EM0 'f|8:$*/(!SP:x҈lSy1lO;0zqfZ:p +lvfkw^ԙJ'QnC kGu( q{o#BlRVVFZKQӡ-X !.,!epixBv!A5p5:U 6S]zΪn۫a ,炙RZ~uC ;A"@LXA*k1+]]f1:j"(> stream xU Tg03*6cD;OݪR=]ۊoBh$Mx#$W+lhkuwbUw.{vwRQ{j{zss}|2B"ȃCIgƥ'F a+)ZO𒂗ؗ T"٨Stq=̝;l^))WGF'i j`?V4+gQ]J.eX&ex貐P劐Bg3Adu@jڞ謘8U|B"XK#DNl K2b9XE&`—`Ģ Q@|!\[K"/3zZ26އOߛqB|{3v 4ts(˽Ǿ&z/Ur)o.0|N>˅Y8 Ǡ9 .}"k* ]>D]f&υI wvey$!VL$'DZ2r8R_{7I=X]_0Q+VySgJ'vz3As4A})6UydEX2+|@ߖMORJ(sHF1FݛÚy&#tt$0gbiep:]MN}:ёis$^c _Ffy-Q:3_Vj6W3, NhHdx ^PQYMCEKS,c!ϛgG>5ӟI+ZjM R6C,nz@_۹zֲ%~'~bAΰ1]'?̞l(9lqс@Tux y3D4VQjh#\Zqfy3b#4 Q'a!(m'Z*hBGT O$QS!Ot,>G94Oǯy3u,J6fpٻ}R4] l}LgwcwMOK.-v\<{ߛgK%& IGK3I񅙾ɯDh]'4q \M@{m(&Po Tx~S_/Ig}dԕ#",~#D@DcJob itd%%`z5W0a@i;WDF7 ;zڑڞu!n˝= omfdQL`1A$5U%ZVH{\U.5% UTvdlGEf:D"}7<L[{ ͉-p*vo{VП\peIjZjW&#gly+jXb/B ?t⣖1[a:˼6{kc2{S\B$qG9QEYjwweK(0m"R,>W`VSSLς$A]8ߨUNgyV3F0 v!xR|ד8>P!)Z$( mFvj3Ygkbl+651+ S{qfsb)+r8-eKIIKendstream endobj 164 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4051 >> stream xXy\זT4JQ_&(nD5!"A)6; (tF@P*DC܈+b2f3Y4˛۠Ifoޯ~vUs;$%H\քmUΜ5mM@PLoiu8V"3"4/,`i~z{ ]^BGRRd}pSXx|dHPp,{Ӧ_[x[.TQBl}[l]MuSIaJ[`@۰@۵l==u^s E s _nLoۖuϜ5w_'M:MNQ+UkjjA&QdjB9R^Rj:zrS.j.Fͣܩ(ʊb)kʆꡆPC*D0)=H$3 6/53i1"YvVיH!zp֖y=GX(K^QJuVkP(\-VB]ub@k`+ >zЦ*FX>,yi^Siko0|xn'ۖD7vyRaٯ3zX/DV^yrF\:CR+1/ U 4@\jlJƺ8j y4~ͭ<=貹Ԍ(*+8s|0ͪ@6&EO+S,/ڞX}{}$9C\fj.dS ׁ\Ťq{Cs-_aK9T٫YaȍozxY-OU6J}&%Mrn|ŶƭyANCنK`IqqWLWe>A=hw3<(P#/D5nZ{ _}2,}bk܈HB. ws;ZPNXO*U (( `%NL?+i^!y@M>$2-AEsj 4AK8?<͡ϟ Y< D>E>것L9K^TRQ-N$)Vj! %}XkIUwO l%:MA:RaPQ^ODr!G[F;#2ɉb>w S?)=Rq}+r[t[gW&Vг6]׹kP7T@3ScoHtDb.?88Dܠr](˸ꃫȯRT~%?AJM ӥaѱCK|qptQkkZ`'_}xE 0>}ya,6'm-Ǎ[){_Б{:Kx^|^~Ǒ-*jsJxnܛ֬՟ LGC ؠ`_R7`6&La`gzšhrg\|њ݋I .ChN Iq hV!"o2FƄGT6kIuNvTLDr8]+6{K̕oUx4oyx&vq[7^X^CH/]0kr|ӖMgK? ̒uK{Vg\5[drsC lM__$x̠VGghÁIoOJ@MO+=܂].l#{@Ia<9}ʠ(,bSQb"oĦ>}<|Wؒx˳OPOS VI8*HʟHknV >A>y]6ZMS UnG&usհT8?5 0vK-,vGd]X\らT!I9+ѺQqSy3FXϷͰϤB(=[S̋jTqQՄgj :H{6B#~S%\EO#2ju[;{lcdԵ;R֐c}JlOcm 76=a)Zi8Ǻ}錹^oYAZDzp:U󠮳^?XZe;z7fWں(,Qzc֜~< I1q{KSs+zd~I|Fd*qĻlʞpi3B`H)WHx3<@ѢIdZQMk1k6@:~1?܌Io9ڇԇp2uW{:GH ~mVkOK띸~Vx79j{? k͟7ݿ~W_ةQ%-SEEWʫph[~pBD)3d<'rкp̠dr]N mJvۏeK!0}_^ț^hbV!K$`2t h'7^ IB nf^wQ5Y|/E%ȩRg/ڢ74r,@^}>CB6 7m:;~Z!)DRTV;p3vX &ΗW'{DRVG&  5_f9,3dԷZZVՕs Yz}vNpODGendstream endobj 165 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 479 >> stream xcd`ab`dd M̳ JM/I, f!CG4nn? ~)__PYQ`d`` $-*ˋ3R|ˁ y I9i i ! A Az讂KR2sK2Y~_IXHr# 'Hn*ڽ,zz销e &sO6aڄc$M6{)ǬyUurg~3{٥5]rU}US$~3^\7[`w&cڦModoohkh ((hHh.䨙Q1g}g^[UxAkWkTrgN!=cvl7Ϩ-9gƼY|e ~8?u5\׹XBy8y =,o⤾ &20Qüendstream endobj 166 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2095 >> stream xm Pga4= $&nEPTx 3J{uM\I*jyPYO~w{OFL&sY,tYziخPvȻo7,/]JOM"f^FO_#at~B\/-HϠ I5Agzܖ5o*Oe.{ѨƉ3A?хU9@ (Hsu3;m) Ykuo~PUq>ն&4~L 7D*RfTƸ춶[/r: ݢw[-̿刳Q e$U^wzy.K &8بE$?m_rnӝ3/=:HpVYtrSEA+y!`.?L?^ GT|AoBH -Q%CH&<bg*$JZHFPgzϤ4Ϡ `GjdC2HVOZ)iVݔݢ{77A6)fQNYkqoA}*0g/ zSxZ-u=D%61@($\Lk鶋 Pt["A=2cfH8/-̧ -mxWd߾ްx!hvCZQX ]lgFSJ1'!Zv˭< V kگ'I-;ZN褮 {s sZ@K3k\d΢}exFKTx![VAKuT+&>{;^2/*L0k{הmΦ>_3p_N75k1|9ryq pWBK_lgh0/EmbK;qk :?4@Ꭲ&>k}!LSsZlvڳڤGIGsO'Љ/oq: ʒ^K J%پ?楍`wDUH> stream xcd`ab`dd N+64 JM/I, f!Cß^=<<<,*=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ g``` b`0f`bdd ?SUe/>0oaWw[V}GoG~zw#/ KUؾs p+]#`-ýyVT#3z@| НVendstream endobj 168 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 447 >> stream xcd`ab`dd M3 JM/I, f!Ci<<,~( }=R1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5]'eg&d0000j10v1012?S ÑN?f7^g7ޞI=l?JT^E9\endstream endobj 169 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1660 >> stream xT LTgy[@.k3Q flQW<,jD{`@ Cy*ρ(TU"[jք-fwlIe˹7q/f7is?s|GSr?} ¸bδ\W~Kt P>4c ŲL WWR2~=۰PTbαhc7m-qڌ|՜?F*sQBmFfN5di3S)I;RtEm+4̖odfl*zJ 2ESTSt0m5"'hE2VY <"GeP[i/.1mˠ UUe$|xE%%'gF`PaDWTPp Uت"OP$0zJu , )TA Pb֬_%0\r*)ߡpl;1:Qr$¦3֐ vK}նއ9`f jp5}vOʞ6e>5/"[2{/SP ,1C7:|2<4AbDCBg塀)qj` N;7dxmsMrv{˰70-q8*uvwv3=(&ԄLTb Xs/d7n;kl7n=Z髗A`vc]k}]};pExaendstream endobj 170 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6051 >> stream xXXS>1prHVuun((EFI!@Bf{o.:q FZVmo?$(XK&}Ѳﯘk  \Wb FL! 1$jb'E8k:b@#FbL,$6qaMxb! &6-aGp=aIMC 'F#Qhb1K 58$p> 9Kr,Z$Z|j9,H^ݣP 1ߍ5uT#sn씱!cَzu71K\OB'Fb;6cewi⺉3޲zk[o1l ^t5mv P{i^!4FSf/LАFPE{dIh3>+I~)rQT(/A5M3cizxM+ \6 ̟%9Y!'ӠxZ+s\VZr+<H=۷eƉF.x,ƋhY_7E; (}Z3+'uZjg> =n\X7W.G8b.$Y jB C[=35h*$O))a!,#K1,h1le.9Lb=a:lcyXC1NP[I?@#k*w2Do嵫uŒFR*b?] ! YJPxlۦ(]t+4| Իt VhDA\8;<-$,aSJ1j˛79 p>)UIW{"jĬ4t ~;ȿa6![aH=ZzZJ#sfP: jh`_Ĕt:r'_-8Uf:b~7\ vPa/蔪}b@ɘ<5ӧ΃*L%u$=+ pu$efZ z ^SE˴E<dFC ޸h0b1X(^%l%MB߳pYb2JޟGd3E(Ϯw^ гR=Jq=̩V !D&sx)EĐnsbXSJl:qr@NBIPo0dChOa~TJPa;fi elaQAW8Ez#F9u2!-IB׾H*XhR!Oׁ&<6/ݮd_RS)4d9WZ< *@ :m̫?[4`m^lYqorE ȋa 3ϐBTWW֚{nʪ:@}~OZ~ip*ۛVA+ ! OFw}zw@+k]* 9'Y"Ka Yk[LӀphXb0 D QQoȒ+z8L1 \g̬U/W-zNH6L1IY )M/H Nا4DE_L)R-+ )HKO7P÷/l%K"()2#6cdAqV3}~- h%yz]`o`c.+AB'U&NQuko?_^ MFܘ\ƪۓZCc5T:/vE.ciVk1H-dHV'J?oj!95 MnVŜuy)G W3ɰ^NN]Gى-7d]ʩ4/?<:?.IaaAIc5!i3Hi_VohOAcNıpf#􀂡p{Ɋ?_u񔧻YI  '(GmI` X!{BcdU 肔ӏH̘oT8Np;o1Iz9 0#1M9HP7:R-pSM#w= 5$(:K$cb rtVU+~0MjK4lu*+8w}{{OqEgww>M_$BX4օWk7IƫOʒY3U/C) [D!* TH&'z\Ulˢ>r. ѺA{)|])me6GP5بNAHE(-Y Z ̢BC_W# kb9%gY Cdzј!-6V kh6~yg`nO _†Ц:vWa`~LΪre(su+MggbY5F8gR2ļA ?4g'GwgTԹƠ2GeuƘ1*֑{͔m>;|z%W@2~ϸԤ=ccc}QKα  0K t0:p).]\ȪVE7WWq%y2Ar u{ d-s8:+ h3Gp'_448=1 !hk4@#@%r zllTY"gD` B~؃2dIfXhc^i~Lz5P 8z8FƁ)x[<-"V)S0G?_"S)YabݡU Ƥ>ueÎr=-v~ȩ!+/]÷kK.[yi9Lѣ X0x/ptw aP2R4|C ihT,pԛ0l8ewmš21P%;υo @&J4nE5m)| J8 TALO=Go| 6yU:wݰs]xM\}}uU.0-noԃ\@LD|\Wc|磎7.X}2fV[`4YꈨhE88Oc}A<^RъQT,Ι}9eE`I8KS///ҒJPEU1čEM':lֳoa]~52١"2f*c*%1(;I.CAaLiP,c5Eк ^| MpL;G0D"W-fek]yuK&@plUEĊ|ZqB@YNzS`=wm ܇b@_=!nA<5%= p]XUr9}3NjQ^oEwɔx2Xf@na6a׊%hޔvtP{<> \ g)M˯7~FQ ?\y9Ϳrے?OyKǑ;t|ĝ;^;)ذidӹ>xs.x1fՏ_ȅ`8>!P+.F^H]b-EE: A7 q| k"I=YN^a`8vHDn]fdrIdmCOz-nۗ-߻qmt4!S&Aρ ?gΰP$,T*illm'?~ !>m|\l(J=_⛚V Ww )L1H䴐`:S8+TCLU 7*)(]N8v+͖qαqP<p}A^I>+0I'A U~|BmuZ5ݾ{zpY9;N叽zJ&P@,<:4ݢ3$ш%0 (aS b3xo-AA`mJJ׋)eŪGq/] b"k99Zm. ~NjlWUZViD{w{D8;afMun:^HN{Ƨ@LzsKiDC,] W bxI߀NP@|E&.YAW5a#bI6ryadxQҙh4i\xUz\*RҸʶB z Ɂ|oܜTiGӆ\;6LxukUExi9lYiseOƖEbq?*dJEEW ȳTȮ.diHHz6`Ȯ6[S5V-z~h*oendstream endobj 171 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 464 >> stream xcd`ab`ddM,M) JM/I,If!Cϒ<<,~ }^P1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5U45'575$'841H%5|D0x B?%.*m[7?f.^dWR7wo{~vHwnln'ϒӢ3'4N|ϛ>q3ֵwv6{}mKKkwdwԶm?^/1cԩ3]2[miwI?.CjyO-.býw䞉=z,3wZ^܃endstream endobj 172 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 347 >> stream xcd`ab`dd M3 JM/I, f!CǮ<<,$ݟ3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k; g```4``d`bdd?SCL~]/^wK/r:3DժM벺߫>d3.yz}ƺgK q+[ym-ýwRO<<z7O;vendstream endobj 173 0 obj << /Filter /FlateDecode /Length 3360 >> stream xZKo#+9 d,'n# `N`;^um>hTUWMQtАӯz}U5557g3Af ~U&Y#fBZX1sYŏ0Cln$LXUab2hg.~wY]MhqP>Ϣnl~Їm|eCpn.}4BU?Uuqa^&7lj(U=]M-U[UQ3<̡TĿ퍫fwm8eӃfj۬5f!?ȸr{\7(XuO: glkoY!\SCŬ}޼/lu#LفyP6ce&zqZ]eCPp*@h.PVZzUPrV-' 8``XPc]2x/x=v  @F:: :kOwnmJ`eJ0ߚ܆jv|FG#@PAc$PI$eDs{* 1ˠNB0.SQz䠇aє8ܠ$j4|'ڦt0ЏA;]a&{kM>HCrɹBZ7*ZӐ*w۾ۭK հXI r@^2 k53qo5m .$!bHB@ r^=ݜ|.yKx 7xJΊ%!nwՏަ ?/v6Vi1 E`~n$uREKWL57SHI]LgotFɻ73aRЇe۷o# Mx6Jq&J6TjO˄`D [MZ\3OY.)#^ nWvjn'lN.hFĠD{#NR&m?EQtGi2T/#QghEbĶfbrRM^ɩV,KKOX3ֆSȨm5eݻbNd̳tT`3w9^ ̛yR^^5+mP=)^='4}&Z=;کF˞ x%ǮMDM -J "4a/H_=>u)RI^*MX{KYc‡T"2su X1α((!*vZ霎t*5&"K/fŠb? J<ѥOVlj ՃkkH \:`Z#.XLӀW:2NTQ"How]THy87mF6&p('}tg@BO&zцgGILיeQxiѶfRsGLoW43wt(HEdAv9$s5cj@n'ϠI[E] (g(A6fyCT&I ia_;@-Hy`Ĺ|v )j ph{Ŧt_3tZ9N* TCa3VgAtb)\ﱻG;A :Fӎ;?ȫ 'FYAPZN$i`f2(ƫ,fBIe-ôvXzeUTHJs(!97=%z6՟BDRad]O3c]un${-Sq9}AHx1TTИXn3Ž<z-2'nBM}>;CT`)6=$+njI;,G/ٵ ;G/gv n=뙣!U;K.wKDd3FchƺBšsl9%3=Kg `N0Y""1hvÍm;uFܔgRMOGQ=l@`mM)7fy}a6_勃W3 M>$HPzɍcL5 f>/(ǚK/H nrm2O] Sq{` Y}m'-pO?M:oЉ.Dcj/W,՛ѓ<263xN XtdB]]'?I,A[&._%KUO`C\1-r·$i=# w$+NPƚv%﹦A^q wX!RKܮY5vdxM+ K]*l܎(;55|\ Tyu#o*4K?>'PA0E\j0v}D?C&y/4)h|+ *i͈פk|nNo<6 Tg!ui{!W1F2y&=(_Z$1ُ_jS]J\qɯ~ũ))O>,O  %m1~/a>^sTl1a1qoP =b)|-N1ӎ/Se5GTr[`Oy mǑ,Ў)M(t S1#M3!;)-!9ܔVcB 3:GXx:`nL-CVݩioGG-p=sڗjx)W| :v$za|K5xÏ\)k8jɧCGk[;WU9P:,jbIYnL2UP_uߦmbOӮzFD)RMw5זJBAЯ:'pA)2BbC܅o>S?w=')j% JZz >H;endstream endobj 174 0 obj << /Filter /FlateDecode /Length 5668 >> stream x\YoIr~>4\!k> c׻Z~"]l 9`xȬ#/vi05#3###ްo7{;͇xnn?\{c,tXz.j8{g\uvuwxswt}~1{\ی#x~vx|.vu7<<<~^_^v{iwu']i6;{ڙ@Pe/7OlOƥRbjQ=m;> KbZJvg^Gma.!7_rfq{Vn%)6\xs7I/{+ ӛϐܐ?qG;^+l '!1NkٟϸgW6c2 '&.{#3&.$ gbdBDRHXZ%d(f"ۯP,AgW-JJ2Y `(4y&SS9uhtYEsP=UYטvO]fC!_NfC`UCN[4!%z:'(AS}T}v;C MW*eR#WҨf{"AF7ZjOTw#Ҡj$#Lٟ(|?/gKd&˫Ed$IV RZX,*jVZS'jXT:n-|XnPdF`}٠0m#Ws٠(fYb(YE +m 81Bӣ2$%.S_ءi; ]f`rvG=;xT+ڝԡ9=ʩCs;E3uRۧ'\Yd($aiGEBԡ9f %e1һ3TUsU`NmaX֯*kZa.ld;D>QLVmL&S鼭Sh/hԔ;l2٪S]*xG)jJeLU-9FI(35%(6KѲ))4=j,)qŊf˦T-*wfbw~M0Wg`e%h5 x֩'e^V+P=6:LNf['׷0U[_"\Sm\uU[DkgP0f['^-2/]J<-+)B$yVS]"j5 Soo3Of0f'_N6?Lj.Ej<8R,gLR)eMc^P_FPQp<) j{{<))4=J;SS9|4JĕWHk*J\0͑(?Isԡ9Mʩֶ&Kk iRERv'aYg(Ӣ j[ FT]h + L)3Yg(euZ[uj`Phڵ8j|KdYK.=d%:*JfXΔ]"Z-k)BL%*V]"XK/x%w()PK']"k&&a:t&Qo8SX̀]fpZ;cl>G,(7 7f4AhFGLpQ YF>K2#.FŻ%k  ·@#9J PHimchE"hbRGpH]2> 1*AEt)L(1\V6=C?tc+  5 TIAl)!LAu DɬJ.u,}W `D ijR0(~Ԗ@zJW(qSpP <8p+p1c7.[2歖nɧ7RPYi)'u0 ّӉ Qp@G JdVA:1x0P\x$/ *Ql&-DP=N|Ɛ2C^:cӛ^-zC@a6=\1 6iƦb!MTLQ&p*&)3*S1ۄNh ~ʄgft*cuF\T]OwB;S!n§Bd  q&\Tp<'y ~)uF' 1nFιXѩ`># 1n° n OЩ&"ARf*@BPƤ!ƔtTѩS.m*t(3O (HBPYi䘑4jHgx)P+CJӪ] >G)Qv48ku,xo]I <b˂ w}cJjUDLIEIBHQ1%t[ڄB(am@E씐R%M׵zQRToc%X0ǻps|؃~.yϤ#Lqda;~q!0Fۆ?plʹnbx73+܍L;ƛ0D~9']6ɴô)3ЛLFOi8`7]Ȕ OZ)6u.ͅqQǛ 7Um.h` %?Ŕ73v7NKorl9驏{z,OIñMJydРf Ta%|4eAA)b0]Bi:JF>AoFJMt_FvaD#xn7}ǏG hݧPxG*ʍY'^mn?R ]!r)Gt\n]V(gΤ j8AJ4^0kH>jso7Y5u#,imTx~ii5I]#tѼݧ㱿40;-i主O?mLJJq|9"4tɿ&M \w|Oo|$旑 ^;۰wpR_/ðq?8dYa=B}į,hj{ݕN#vyQF-y݋)dPs2nx|u1tw~ZHի<; h?MxXzx\>?nï3 |w?\we .o?}{>n1L$ĩ@{yh](ampwYo߾}xbon1%+^߽{7i::Nj͎~=<~X'ToooF%MbF[Ĕ{51,Y=LI /ߩ"h&nKzhvY Tendstream endobj 175 0 obj << /Filter /FlateDecode /Length 2497 >> stream xYK A0|h-F4ncXo8'ęMc䞟~le:9s_U}2M2?;,ӂڧK;,pxVNRbyyp#蒱4T/T$aqEy֒J^LR*?Hʮߐ=x{yc;#X?-/"Sz&cLHᅵhZ;,Cبh>l7³kHgHEi[twMO fgh2ky@pƎq:-`?鏛kkͩ&b{!tJ1)a-J*95Q0@]7^C|Ou2 UܵKc'X''A߶znnGTi~NbTA2fr R'vvk(* aٴs_T# G aoh /t=tҊ*S1QK-trtj2Z}X,Q ٰ>(OnSCn9KsYV84mX)Tx8~rAe#fF"+MdGHͱڸkC3@afdKGwJk{hzOOT; ~\$L;EǑN?"WqCI8RĴ%(yFGG.&>ܯ֐V8t쇵4/;l:Vff g>V7Mb oȾ67~xK_d>Vy5 -^/4ud7VETKk(:ji$A.u(T-~SF Ye{,bRHn3JHʜ)hGW/]S Гj]PYS6HYv~0 ຩƱPc'.S̝{j"8今JgRCcH$|X˟̤iK(G@~Pj&*+ESB%34 ux2U_iC[g8Pa!> stream x\[od7r~s0Q>9F&l&w,'#?޾ȭgs*ٔP``uX,U$KΆ^/z}6~=׳<b C˻F̄b eg/A zhtys]?,6NTtF{?|vˇxEw_LPߤQt%U\3AnB#>>xS具_젥rs{aC)vݞEpG9-@&Iie}? s-% 㰙2ss[niz>ZW~~ͭHb$4s?`/1\=yQiY~hoT($Ɗ x[)(m&SS <VNf:Q'FNuҝ-[~z:AKK҈}ow׷Z=ύiߜ}dKRBxQBadk2[jE4mJ⻓o4sH#;T#31}á]CWM9%񰃶QaG N˛?I&Anqm .}6[.bZ4F^*l{p[ W{6:+p3 wzM-_O첬j!}\wۮ EmHؿZG49ЌS% D OX g󖻚쥣}\~uG^ʉ gZ?&.EzO%[d-[Gܾ^t~va|箰WEMe/JT- [m+1b!&K+qU57kdSxfj{zB m{~hMsp=اMiSk3q a%;7 D&Bnf`NvZp{󹑴uwݐ[-WݎRku͇L/.Cn77.?ǫiL&d7Os D?=U&==~o+Rt2OH1UYТqybU7BC }ÅoWq=oO<Ğƨxj}]!(]r)4->]$q#>=(7C}>=!}`d#.f!X!g=>ٌ ^~NȪXD`l"GC9db&rh:"= TwAҮBVR4#p'E UR O T@|o!nd!@ ә[!1B@& B4_Gн'z\ `6mp'#{:Z\ q%rh;[D"$7c6 ZB*DF{x@r%u 8 q qI 1rh%0^mO ^7kirh"c+:g1`x:R c Bh"$DD4< MDICBIYDVHN Zʜ@||Ʉ6BE:a=hkAF눇bDCMB =h#U)罁[qt*Y%SրfĸC#VTU\r@&>zuD"-wDsF,bB&B: J1Ih]4 jk pb!$5#7BpXD$L`*"9 U(D$ĄA0⎿Q#E1ϣ"ioh3HMz4!Z>s4aiNfP2єx'c|F$ZEc#Cc!? >2~v0K:oxl|/ȥ,V3T}yZ>ͶwΞ_ϐfwN!9[ىW 5Ps]Aa423gco9gݹuۛC:2L2B)X<`jTa !aȾ$da2{#"_EJ†dLɨJrg+Gg>u~cJ4 ^ Uu,RިB*{LJr=VB6'o c%ڴ:Yl+W%3{H3f3*a\1d%ThRz*-$*sqx0V䲭**/ /RL$v%Uf\9-U^0U֙TY*`1J2l[Jf6i3kP@i6V'9HS7&̫D[NRrҦ621mZn6-NVܴۜj{4/N۽Uis+AY%7mxó ]1WJtƜyUhmU~cRUh©a6GXMS/p kꌾ[Ưߘ?0mK^)h)J%6o]&9ML=mcW  YDTd5UD,;WC+J O^c>:󴯊tp4i#VQ d%^a KPc#81Ӏtu0it5t`OTԈd9[jD~l>- Rǖ f-ys!0abvMe1'Z"Z :C44!@Fѳ%dI<-YЁDAUb=Pȁ 6u@TZ@'fL*Y^=*#(zDD9h~+iX6bᣤᆪ^ZΧ Zq3yڭ`Τl L 0="Z(!pW1ՈRFPPq_N#Y^Qi(!"QFD?a%dJĜM}y8% D&ڐ' u݈N%=rϒHʏX =T@=!FdxN+`[8x/614CTeq(ADDt/D 8bGO4M@/}kkFDsGш`@IV]2c>>:BK')h|k5%,fff"@5@,AL(-IH򘄄3& `}|@@6o1Н @Fّ!"};M B/7>+ȈbFC÷;j@{:ph"]Q>c(!d| c6#F} &}{HQ=mFH9f?[F`8&# CzW@KPI !҄B@4 ٲ=5'2&DD!=+Њsuz|@;B(OVFWkC=O|b4i•jLcTQp,Dy)4#DL4&"42hؑh0n?|o58O1V0N(s[BxE=j)F/i,xg$ks8J$GBŌhKmF|r$^Hħ]'W貋Q] </2SKǻplh36:%o7Cyu!1%$j=H;CO#GFӈWcVI[`2{x5>l? Ll3&&^zMX'[SZ08'"4%[( J4E:%6 9me̜sbT e~d aFaQSCHbA W]jHz?~kE!'~oEvxpG.V] VS^*Z%cXehT傎KJ@΁>S`*R1QF\\i幠/>TGsCa=_@\AߨX 22(-V jL -h2,](L^.IImXɟJ.lw7 L,…6?:uuNQ]>4Ҋ%cf[ȥYMN%*b8b.1TT2^+fau&g)Fw/T*TJj.wdE+H"'LaVϷ崪q':.Rz>Xq&E]a-gW]?N +wG֝FZ˵Ƣ. ]JӒn~T?xXuCZQ =L V fReZYeYU`sE5wՐKBL6&g+J3,ƹ+¢.d63Ř!Ka57HkDUFjEıS9,^@OYʼ {ʚ۬a,цZ*KU.`$ c<3<^%O+@?Oq"\ZlHu JaFb"-~q@rǵ}rXm\ ;m;t_GJtA祉:^Jܩ}\;4svN9pփv,[\rIQ- ZTUd?^rtlŵ`\=;dmݤfn{_~yj seEᑾ 9$/-<&3.֐嬄\7-\"* ` an"#D|U+ZL$t!,L8虶qr2֐钋z!8FMxz"T`˄4Qme>.ᄐP zOfKsZM,Bnу >0c#Oݏ9w58ƥtiսg:۽Aw݆4ך~ .blRkQzuݷWo`o/`jg*lWL4Nw?]+JyONv,VY+[_s}zd8|0g:Vwvnj^bxa . n~Z0J[ w@.V0'lcFw4œy:2,Llס3@$2 |D `qj"Ûo>el<>,0?ǻO {q9( 8#OX;S$JfS|x:zT!gTqDpIO߀GRuRw4pȅXX*0XpE!ӡ!p[8ls53R/| dQyAP%ŸK~&~E{Xd tVHA,Is[&!^~bI./k%XFTOu: הi\5ԅܻr.~޾<s7sq*Juw]o{`tfLJ|`h,XA,&FFA-~a }C+ph77:  k5~ݞE{[ܴL@@Aps\5A,\5; A@A-o"_4_/ baQ<1KBp=3A `54威 CyAnH Dƹ9g^'MG\L6 J Tk"vyBh&+ik=BL**ҧ> S QY`Vu-yZ/>g ͐~]23fx_?.6qtDwG#Hs9fTua|ODX!A nZHcR`^뮇ӇLp] 汄g|!`=C"FʩQf ƂTF1|8Q\!Y@%zgHHTdFy#3$ $UH˪!sb̷jGKKJ%Iw_# Yiy,.M#JXgE-$:68)YQT)?JcxwO1IC4csfF5'>sj (D?b<'('% E@ib)@IRt:A k %W1\J./K3J$H DG.ۗل%V OXf%0V ^Ԓg(y.S+kF)`KqNl,bK M)KSc$RpfBf+,K ~}ڞ0I&80Ʉ.F+N*(X01Lt!<3]OaRRHTR)&LiQazu1,L33ƅIC#äMa)8L!~mJ"F&?] ʹ03P3&3h%VL"B"8 YR)()$;&OR $ HmB*$52PȳD*`AL: )ěiyԙ3Hr{@ %ЍTH~@ ^*0MX!Y K}RBC6\ &,]gL| 0V=cJ-)J1QU!Y*x*}SE6ad9&,19A24gЍb~y(RĄ 43B/P39HR9ȑR.)9%,kb6tYaL\1ãjTM2:*Q1ǣ"l2:RJGըY.f 94E>fcYm)6u"&l?:H_#uDys}-[׷o1_b\b\bAo1_b|}-[׷o1oo1_b\b|<\bżb> jWяߠ Aww} m<è 7CN=܀)zuOޤ5= p{/SO'eGwǎF7ӊ.>;܅wHhdYOpd bBA_o!`Tѿ;8 l>7L"Mް\h8uSZ)`%2dj5"Y+NFdj%H>H ,kBVFpoV#r2gL$]Nd91!Yr;ڐ=x i5{ؠMLJAKWp`m>O B1%zn`kw2`np8Tden@#.~3~'*sJ~MT?ۭgQ{-)V |Ń200 ID$o%d oS0QJbL˙}<mj@w,kє( Sɑ&3kezbc׃ك1`=.,%;`)6j8 :oL@y [F+wv uDoYMT˾| ^xq2+GX'A*|ߥy󡔋qɱxgٟ`/ܗqnχ}PU$*Xՠp/$Tі5TrBǼhY&_ceT8&RIS@:mh~52*α`uZ+Wq/b*~akg܍#=_Y% &?|5|^')+Ø TTڵ>ޏ{trcw:6UVJ@*`©\,MV3O l\vOi $~ \w8UEwx]TnjLU)8|Uū޶bqsԠ ǖ Ҏ󴈥V-/*!d(feh|YHeVǩ^*6{;k$(r_Y1{f$ЃTX>~衘RgElןP0jXQ-YѲ_ ꜎l<:l(z׆6/ az [H,Eߜcn Yջk:,'j~B51lkz}/S{n(:(}d|> eHf?Z6 _슪+/k)/[뻋>+j0R4c/2V/s[NñvcfyZýL&\C^$/endstream endobj 178 0 obj << /Type /XRef /Length 188 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 179 /ID [] >> stream xcb&F~0 $8J"?@^ - G"Fh0/@/"He %D]2-`5 @$d "H8ɫ"HA) (bsZH.)D2."` R@l%X ̞&%"%v1k "@XFn02a endstream endobj startxref 129186 %%EOF surveillance/inst/doc/monitoringCounts.R0000644000176200001440000004036414615167557020224 0ustar liggesusers## ----SETUP, include = FALSE-------------------------------------------------------- ## create directories for plots and cache dir.create("plots", showWarnings=FALSE) dir.create("monitoringCounts-cache", showWarnings=FALSE) ## load packages library('surveillance') library('gamlss') ## ----echo=FALSE-------------------------------------------------------------------- data("salmNewport") ## ----echo=FALSE-------------------------------------------------------------------- stopifnot( all.equal(observed(salmNewport), observed(as(as(salmNewport, "ts"), "sts"))) ) ## ----echo=FALSE-------------------------------------------------------------------- # This code is the one used for the Salmon et al. (2016) JSS article. # Using this code all examples from the article can be reproduced. # computeALL is FALSE to avoid the computationally intensive parts # of the code (simulations to find a threshold value for categoricalCUSUM, # INLA-driven BODA) but one can set it to TRUE to have it run. computeALL <- FALSE ## ----NewportPlot-simple, fig.keep = 'none'----------------------------------------- plot(salmNewport, type = observed ~ time, xaxis.tickFreq = list("%m" = atChange, "%G" = atChange), xaxis.labelFreq = list("%Y" = atMedian), xaxis.labelFormat = "%Y") ## ----unitPlot-simple, echo = FALSE, fig.keep = 'none'------------------------------ plot(salmNewport, units = 2:3) ## ----EARS, fig.keep='none'--------------------------------------------------------- in2011 <- which(isoWeekYear(epoch(salmNewport))$ISOYear == 2011) salmNewportGermany <- aggregate(salmNewport, by = "unit") control <- list(range = in2011, method = "C1", alpha = 0.05) surv <- earsC(salmNewportGermany, control = control) plot(surv) ## ----farHead----------------------------------------------------------------------- con.farrington <- list( range = in2011, noPeriods = 1, b = 4, w = 3, weightsThreshold = 1, pastWeeksNotIncluded = 3, pThresholdTrend = 0.05, thresholdMethod = "delta" ) con.noufaily <- list( range = in2011, noPeriods = 10, b = 4, w = 3, weightsThreshold = 2.58, pastWeeksNotIncluded = 26, pThresholdTrend = 1, thresholdMethod = "nbPlugin" ) ## ----echo=F------------------------------------------------------------------------ con.farrington$limit54 <- con.noufaily$limit54 <- c(0,50) # for the figure ## ---------------------------------------------------------------------------------- salm.farrington <- farringtonFlexible(salmNewportGermany, con.farrington) salm.noufaily <- farringtonFlexible(salmNewportGermany, con.noufaily) ## ----farPlot-simple, echo = FALSE, fig.keep = 'none'------------------------------- par(mfrow = c(1,2)) plot(salm.farrington) plot(salm.noufaily) ## ----campyDE-simple, fig.keep='none'----------------------------------------------- data("campyDE") cam.sts <- sts(epoch = campyDE$date, observed = campyDE$case, state = campyDE$state) plot(cam.sts, col = "mediumblue") lines(campyDE$hum * 50, col = "white", lwd = 2) axis(4, at = seq(0, 2500, by = 500), labels = seq(0, 50, by = 10)) ## ----boda-cache, echo = FALSE, results='hide'-------------------------------------- if (computeALL) { ##hoehle 2018-07-18: changed code to use NICELOOKINGboda, but that's iid. Reason: ##The option 'rw1' currently crashes INLA. library("INLA") rangeBoda <- which(epoch(cam.sts) >= as.Date("2007-01-01")) control.boda <- list(range = rangeBoda, X = NULL, trend = TRUE, season = TRUE, prior = "iid", alpha = 0.025, mc.munu = 10000, mc.y = 1000, samplingMethod = "marginals") boda <- boda(cam.sts, control = control.boda) save(list = c("boda", "control.boda", "rangeBoda"), file = "monitoringCounts-cache/boda.RData") } else { load("monitoringCounts-cache/boda.RData") } ## ----boda2-cache, echo = FALSE, results='hide'------------------------------------- if (computeALL) { covarNames <- c("l1.hum", "l2.hum", "l3.hum", "l4.hum", "newyears", "christmas", "O104period") control.boda2 <- modifyList(control.boda, list(X = campyDE[, covarNames], season = FALSE)) boda.covars <- boda(cam.sts, control = control.boda2) save(list = c("boda.covars", "covarNames", "control.boda2"), file = "monitoringCounts-cache/boda.covars.RData") } else { load("monitoringCounts-cache/boda.covars.RData") } ## ----bPlot-simple, echo = FALSE, fig.keep = 'none'--------------------------------- plot(boda.covars) ## ----boda3, echo = FALSE----------------------------------------------------------- control.far <- list(range=rangeBoda,b=4,w=5,alpha=0.025*2) far <- farrington(cam.sts,control=control.far) #Both farringtonFlexible and algo.bayes uses a one-sided interval just as boda. control.far2 <-modifyList(control.far,list(alpha=0.025)) farflex <- farringtonFlexible(cam.sts,control=control.far2) bayes <- suppressWarnings(bayes(cam.sts,control=control.far2)) ## ----boda4, echo = FALSE----------------------------------------------------------- # Small helper function to combine several equally long univariate sts objects combineSTS <- function(stsList) { epoch <- as.numeric(epoch(stsList[[1]])) observed <- NULL alarm <- NULL for (i in 1:length(stsList)) { observed <- cbind(observed,observed(stsList[[i]])) alarm <- cbind(alarm,alarms(stsList[[i]])) } colnames(observed) <- colnames(alarm) <- names(stsList) res <- sts(epoch=as.numeric(epoch), epochAsDate=TRUE, observed=observed, alarm=alarm) return(res) } ## ----alarmplot, fig.width=8, fig.height=4, out.width="\\linewidth", echo=FALSE----- # Make an artificial object containing two columns - one with the boda output # and one with the farrington output cam.surv <- combineSTS(list(boda.covars=boda.covars,boda=boda,bayes=bayes, farrington=far,farringtonFlexible=farflex)) par(mar=c(4,8,2.1,2),family="Times") plot(cam.surv,type = alarm ~ time,lvl=rep(1,ncol(cam.surv)), alarm.symbol=list(pch=17, col="red2", cex=1,lwd=3), cex.axis=1,xlab="Time (weeks)",cex.lab=1,xaxis.tickFreq=list("%m"=atChange,"%G"=atChange),xaxis.labelFreq=list("%G"=at2ndChange), xaxis.labelFormat="%G") ## ----glrnb, results='hide'--------------------------------------------------------- phase1 <- which(isoWeekYear(epoch(salmNewportGermany))$ISOYear < 2011) phase2 <- in2011 control <- list(range = phase2, c.ARL = 4, theta = log(2), ret = "cases", mu0 = list(S = 1, trend = TRUE, refit = FALSE)) salmGlrnb <- glrnb(salmNewportGermany, control = control) ## ----cat--------------------------------------------------------------------------- data("salmHospitalized") isoWeekYearData <- isoWeekYear(epoch(salmHospitalized)) dataBefore2013 <- which(isoWeekYearData$ISOYear < 2013) data2013 <- which(isoWeekYearData$ISOYear == 2013) dataEarly2014 <- which(isoWeekYearData$ISOYear == 2014 & isoWeekYearData$ISOWeek <= 4) phase1 <- dataBefore2013 phase2 <- c(data2013, dataEarly2014) salmHospitalized.df <- cbind(as.data.frame(salmHospitalized), weekNumber = isoWeekYearData$ISOWeek) names(salmHospitalized.df) <- c("y", "t", "state", "alarm", "upperbound", "n", "freq", "epochInPeriod", "weekNumber") ## ----catbis, results='hide'-------------------------------------------------------- vars <- c( "y", "n", "t", "epochInPeriod", "weekNumber") m.bbin <- gamlss(cbind(y, n-y) ~ 1 + t + sin(2 * pi * epochInPeriod) + cos(2 * pi * epochInPeriod) + sin(4 * pi * epochInPeriod) + cos(4 * pi * epochInPeriod) + I(weekNumber == 1) + I(weekNumber == 2), sigma.formula =~ 1, family = BB(sigma.link = "log"), data = salmHospitalized.df[phase1, vars]) ## ----cat2-------------------------------------------------------------------------- R <- 2 h <- 2 pi0 <- predict(m.bbin, newdata = salmHospitalized.df[phase2, vars], type = "response") pi1 <- plogis(qlogis(pi0) + log(R)) pi0m <- rbind(pi0, 1 - pi0) pi1m <- rbind(pi1, 1 - pi1) ## ----cat2bis----------------------------------------------------------------------- populationHosp <- unname(cbind( population(salmHospitalized), population(salmHospitalized))) observedHosp <- cbind( "Yes" = as.vector(observed(salmHospitalized)), "No" = as.vector(population(salmHospitalized) - observed(salmHospitalized))) salmHospitalized.multi <- sts( frequency = 52, start = c(2004, 1), epoch = epoch(salmHospitalized), observed = observedHosp, population = populationHosp, multinomialTS = TRUE) ## ----cat2ter----------------------------------------------------------------------- dBB.cusum <- function(y, mu, sigma, size, log = FALSE) { dBB(if (is.matrix(y)) y[1,] else y, if (is.matrix(y)) mu[1,] else mu, sigma = sigma, bd = size, log = log) } ## ----cat3-------------------------------------------------------------------------- controlCat <- list(range = phase2, h = 2, pi0 = pi0m, pi1 = pi1m, ret = "cases", dfun = dBB.cusum) salmHospitalizedCat <- categoricalCUSUM( salmHospitalized.multi, control = controlCat, sigma = exp(m.bbin$sigma.coefficients)) ## ---------------------------------------------------------------------------------- h.grid <- seq(1, 10, by = 0.5) ## ----cath-cache, echo = FALSE, results='hide'-------------------------------------- if (computeALL) { simone <- function(sts, h) { y <- rBB(length(phase2), mu = pi0m[1, , drop = FALSE], bd = population(sts)[phase2, ], sigma = exp(m.bbin$sigma.coefficients), fast = TRUE) observed(sts)[phase2, ] <- cbind(y, population(sts)[phase2, 1] - y) one.surv <- categoricalCUSUM( sts, control = modifyList(controlCat, list(h = h)), sigma = exp(m.bbin$sigma.coefficients)) return(any(alarms(one.surv)[, 1])) } set.seed(123) nSims <- 1000 pMC <- sapply(h.grid, function(h) { mean(replicate(nSims, simone(salmHospitalized.multi, h))) }) pMarkovChain <- sapply(h.grid, function(h) { TA <- LRCUSUM.runlength(mu = pi0m[1,,drop = FALSE], mu0 = pi0m[1,,drop = FALSE], mu1 = pi1m[1,,drop = FALSE], n = population(salmHospitalized.multi)[phase2, ], h = h, dfun = dBB.cusum, sigma = exp(m.bbin$sigma.coef)) return(tail(TA$cdf, n = 1)) }) save(pMC, file = "monitoringCounts-cache/pMC.RData") save(pMarkovChain, file = "monitoringCounts-cache/pMarkovChain.RData") } else { load("monitoringCounts-cache/pMC.RData") load("monitoringCounts-cache/pMarkovChain.RData") } ## ----catF-simple, echo = FALSE, fig.keep = 'none'---------------------------------- plot(salmHospitalizedCat[,1]) ## ----catARL-simple, echo = FALSE, fig.keep = 'none'-------------------------------- matplot(h.grid, cbind(pMC, pMarkovChain), type="l", lty=1:2, col=1) abline(h=0.1, lty=5) legend("center", c("Monte Carlo","Markov chain"), lty=1:2, bty="n") ## ----rotaPlot-simple, fig.keep='none'---------------------------------------------- data("rotaBB") plot(rotaBB) ## ---------------------------------------------------------------------------------- rotaBB.df <- as.data.frame(rotaBB) X <- with(rotaBB.df, cbind(intercept = 1, epoch, sin1 = sin(2 * pi * epochInPeriod), cos1 = cos(2 * pi * epochInPeriod))) phase1 <- epoch(rotaBB) < as.Date("2009-01-01") phase2 <- !phase1 library("MGLM") ## MGLMreg automatically takes the last class as ref so we reorder order <- c(2:5, 1); reorder <- c(5, 1:4) m0 <- MGLMreg(as.matrix(rotaBB.df[phase1, order]) ~ -1 + X[phase1, ], dist = "MN") ## ---------------------------------------------------------------------------------- m1 <- m0 m1@coefficients[1, ] <- m0@coefficients[1, ] + log(2) pi0 <- t(predict(m0, newdata = X[phase2, ])[, reorder]) pi1 <- t(predict(m1, newdata = X[phase2, ])[, reorder]) ## ----CATCUSUM---------------------------------------------------------------------- dfun <- function(y, size, mu, log = FALSE) { dmultinom(x = y, size = size, prob = mu, log = log) } h <- 2 # threshold for the CUSUM statistic control <- list(range = seq(nrow(rotaBB))[phase2], h = h, pi0 = pi0, pi1 = pi1, ret = "value", dfun = dfun) surv <- categoricalCUSUM(rotaBB,control=control) ## ----include = FALSE--------------------------------------------------------------- alarmDates <- epoch(surv)[which(alarms(surv)[,1])] format(alarmDates,"%b %Y") ## ----CATCUSUMMC,echo=FALSE,eval=FALSE---------------------------------------------- # #Number of MC samples # nSamples <- 1e4 # # #Do MC # simone.stop <- function(sts, control) { # phase2Times <- seq(nrow(sts))[phase2] # #Generate new phase2 data from the fitted in control model # y <- sapply(1:length(phase2Times), function(i) { # rmultinom(n=1, prob=pi0[,i],size=population(sts)[phase2Times[i],1]) # }) # observed(sts)[phase2Times,] <- t(y) # one.surv <- categoricalCUSUM(sts, control=control) # #compute P(S<=length(phase2)) # return(any(alarms(one.surv)[,1]>0)) # } # # set.seed(1233) # rlMN <- replicate(nSamples, simone.stop(rotaBB, control=control)) # mean(rlMN) # 0.5002 ## ---------------------------------------------------------------------------------- m0.dm <- MGLMreg(as.matrix(rotaBB.df[phase1, 1:5]) ~ -1 + X[phase1, ], dist = "DM") c(m0@AIC, m0.dm@AIC) ## ---------------------------------------------------------------------------------- ## Change intercept in the first class (for DM all 5 classes are modeled) delta <- 2 m1.dm <- m0.dm m1.dm@coefficients[1, ] <- m0.dm@coefficients[1, ] + c(-delta, rep(delta/4, 4)) alpha0 <- exp(X[phase2,] %*% m0.dm@coefficients) alpha1 <- exp(X[phase2,] %*% m1.dm@coefficients) dfun <- function(y, size, mu, log = FALSE) { dLog <- ddirmn(t(y), t(mu)) if (log) dLog else exp(dLog) } h <- 2 control <- list(range = seq(nrow(rotaBB))[phase2], h = h, pi0 = t(alpha0), pi1 = t(alpha1), ret = "value", dfun = dfun) surv.dm <- categoricalCUSUM(rotaBB, control = control) ## ----echo=FALSE,eval=FALSE--------------------------------------------------------- # matplot(alpha0/rowSums(alpha0),type="l",lwd=3,lty=1,ylim=c(0,1)) # matlines(alpha1/rowSums(alpha1),type="l",lwd=1,lty=2) ## ----ctPlot-simple, echo = FALSE, fig.keep = 'none'-------------------------------- par(mfrow = c(1,2)) surv@multinomialTS <- surv.dm@multinomialTS <- FALSE # trick plot method ... plot(surv[,1], col=c(NA,NA,4), ylab = expression(C[t]), ylim = c(0,33), xaxis.tickFreq=list("%Y"=atChange, "%m"=atChange), xaxis.labelFreq=list("%Y"=atMedian), xaxis.labelFormat="%Y") abline(h=h, lwd=2, col="darkgrey") plot(surv.dm[,1], col=c(NA,NA,4), ylab = expression(C[t]), ylim = c(0,33), xaxis.tickFreq=list("%Y"=atChange, "%m"=atChange), xaxis.labelFreq=list("%Y"=atMedian), xaxis.labelFormat="%Y") abline(h=h, lwd=2, col="darkgrey") ## ---------------------------------------------------------------------------------- today <- which(epoch(salmNewport) == as.Date("2013-12-23")) rangeAnalysis <- (today - 4):today in2013 <- which(isoWeekYear(epoch(salmNewport))$ISOYear == 2013) algoParameters <- list(range = rangeAnalysis, noPeriods = 10, populationBool = FALSE, b = 4, w = 3, weightsThreshold = 2.58, pastWeeksNotIncluded = 26, pThresholdTrend = 1, thresholdMethod = "nbPlugin", alpha = 0.05, limit54 = c(0, 50)) results <- farringtonFlexible(salmNewport[, c("Baden.Wuerttemberg", "North.Rhine.Westphalia")], control = algoParameters) ## ----results='asis'---------------------------------------------------------------- start <- isoWeekYear(epoch(salmNewport)[min(rangeAnalysis)]) end <- isoWeekYear(epoch(salmNewport)[max(rangeAnalysis)]) caption <- paste0("Results of the analysis of reported S. Newport ", "counts in two German federal states for the weeks ", start$ISOYear, "-W", start$ISOWeek, " to ", end$ISOYear, "-W", end$ISOWeek, ". Bold red counts indicate weeks with alarms.") toLatex(results, caption = caption, label = "tableResults", ubColumnLabel = "Threshold", include.rownames = FALSE, sanitize.text.function = identity) surveillance/inst/doc/hhh4_spacetime.Rnw0000644000176200001440000015676114615162374020076 0ustar liggesusers%\VignetteIndexEntry{hhh4 (spatio-temporal): Endemic-epidemic modeling of areal count time series} %\VignetteEngine{knitr::knitr} %% additional dependencies beyond what is required for surveillance anyway: %\VignetteDepends{surveillance, lattice, gsl, colorspace, gridExtra, scales, fanplot, hhh4contacts} <>= ## purl=FALSE => not included in the tangle'd R script knitr::opts_chunk$set(echo = TRUE, tidy = FALSE, results = 'markup', fig.path='plots/hhh4_spacetime-', fig.width = 8, fig.height = 4.5, fig.align = "center", fig.scap = NA, out.width = NULL, cache = FALSE, error = FALSE, warning = FALSE, message = FALSE) knitr::render_sweave() # use Sweave environments knitr::set_header(highlight = '') # no \usepackage{Sweave} (part of jss class) ## R settings options(prompt = "R> ", continue = "+ ", useFancyQuotes = FALSE) # JSS options(width = 85, digits = 4) options(scipen = 1) # so that 1e-4 gets printed as 0.0001 ## xtable settings options(xtable.booktabs = TRUE, xtable.size = "small", xtable.sanitize.text.function = identity, xtable.comment = FALSE) @ \documentclass[nojss,nofooter,article]{jss} \usepackage[utf8]{inputenc} % Rnw is ASCII, but auto-generated bib file isn't % (specification is redundant in LaTeX >= 2018-04-01) \title{% \vspace{-1.5cm} \fbox{\vbox{\normalfont\footnotesize This introduction to spatio-temporal \code{hhh4} models implemented in the \proglang{R}~package \pkg{surveillance} is based on a publication in the \textit{Journal of Statistical Software} -- \citet[Section~5]{meyer.etal2014} -- which is the suggested reference if you use the \code{hhh4} implementation in your own work.}}\\[1cm] \code{hhh4}: Endemic-epidemic modeling\\of areal count time series} \Plaintitle{hhh4: Endemic-epidemic modeling of areal count time series} \Shorttitle{Endemic-epidemic modeling of areal count time series} \author{Sebastian Meyer\thanks{Author of correspondence: \email{seb.meyer@fau.de}}\\Friedrich-Alexander-Universit{\"a}t\\Erlangen-N{\"u}rnberg \And Leonhard Held\\University of Zurich \And Michael H\"ohle\\Stockholm University} \Plainauthor{Sebastian Meyer, Leonhard Held, Michael H\"ohle} %% Basic packages \usepackage{lmodern} % successor of CM -> searchable Umlauts (1 char) \usepackage[english]{babel} % language of the manuscript is American English %% Math packages \usepackage{amsmath,amsfonts} % amsfonts defines \mathbb \usepackage{bm} % \bm: alternative to \boldsymbol from amsfonts %% Packages for figures and tables \usepackage{booktabs} % make tables look nicer \usepackage{subcaption} % successor of subfig, which supersedes subfigure %% knitr uses \subfloat, which subcaption only provides since v1.3 (2019/08/31) \providecommand{\subfloat}[2][need a sub-caption]{\subcaptionbox{#1}{#2}} %% Handy math commands \newcommand{\abs}[1]{\lvert#1\rvert} \newcommand{\norm}[1]{\lVert#1\rVert} \newcommand{\given}{\,\vert\,} \newcommand{\dif}{\,\mathrm{d}} \newcommand{\IR}{\mathbb{R}} \newcommand{\IN}{\mathbb{N}} \newcommand{\ind}{\mathbb{I}} \DeclareMathOperator{\Po}{Po} \DeclareMathOperator{\NegBin}{NegBin} \DeclareMathOperator{\N}{N} %% Additional commands \newcommand{\class}[1]{\code{#1}} % could use quotes (JSS does not like them) \newcommand{\CRANpkg}[1]{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}} %% Reduce the font size of code input and output \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl, fontsize=\small} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\small} %% Abstract \Abstract{ The availability of geocoded health data and the inherent temporal structure of communicable diseases have led to an increased interest in statistical models and software for spatio-temporal data with epidemic features. The \proglang{R}~package \pkg{surveillance} can handle various levels of aggregation at which infective events have been recorded. This vignette illustrates the analysis of area-level time series of counts using the endemic-epidemic multivariate time-series model ``\code{hhh4}'' described in, e.g., \citet[Section~3]{meyer.held2013}. See \code{vignette("hhh4")} for a more general introduction to \code{hhh4} models, including the univariate and non-spatial bivariate case. %% (For other types of surveillance data, see %% \code{vignette("twinstim")} and \code{vignette("twinSIR")}.) We first describe the general modeling approach and then exemplify data handling, model fitting, visualization, and simulation methods for weekly counts of measles infections by district in the Weser-Ems region of Lower Saxony, Germany, 2001--2002. } \Keywords{% areal time series of counts, endemic-epidemic modeling, infectious disease epidemiology, branching process with immigration} \begin{document} <>= ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("hhh4_spacetime-cache.RData")) if (!COMPUTE) load("hhh4_spacetime-cache.RData", verbose = TRUE) @ \section[Model class]{Model class: \code{hhh4}} \label{sec:hhh4:methods} An endemic-epidemic multivariate time-series model for infectious disease counts $Y_{it}$ from units $i=1,\dotsc,I$ during periods $t=1,\dotsc,T$ was proposed by \citet{held-etal-2005} and was later extended in a series of papers \citep{paul-etal-2008,paul-held-2011,held.paul2012,meyer.held2013}. In its most general formulation, this so-called ``\code{hhh4}'' model assumes that, conditional on past observations, $Y_{it}$ has a negative binomial distribution with mean \begin{equation} \label{eqn:hhh4} \mu_{it} = e_{it} \, \nu_{it} + \lambda_{it} \, Y_{i,t-1} + \phi_{it} \sum_{j \ne i} w_{ji} \, Y_{j,t-1} \end{equation} and overdispersion parameter $\psi_i > 0$ such that the conditional variance of $Y_{it}$ is $\mu_{it} (1+\psi_i \mu_{it})$. Shared overdispersion parameters, e.g., $\psi_i\equiv\psi$, are supported as well as replacing the negative binomial by a Poisson distribution, which corresponds to the limit $\psi_i\equiv 0$. Similar to the point process models in \code{vignette("twinstim")} and \code{vignette("twinSIR")}, the mean~\eqref{eqn:hhh4} decomposes additively into endemic and epidemic components. The endemic mean is usually modeled proportional to an offset of expected counts~$e_{it}$. In spatial applications of the multivariate \code{hhh4} model as in this paper, the ``unit''~$i$ refers to a geographical region and we typically use (the fraction of) the population living in region~$i$ as the endemic offset. The observation-driven epidemic component splits up into autoregressive effects, i.e., reproduction of the disease within region~$i$, and neighborhood effects, i.e., transmission from other regions~$j$. Overall, Equation~\ref{eqn:hhh4} becomes a rich regression model by allowing for log-linear predictors in all three components: \begin{align} \label{eqn:hhh4:predictors} \log(\nu_{it}) &= \alpha_i^{(\nu)} + {\bm{\beta}^{(\nu)}}^\top \bm{z}^{(\nu)}_{it} \:, \\ \log(\lambda_{it}) &= \alpha_i^{(\lambda)} + {\bm{\beta}^{(\lambda)}}^\top \bm{z}^{(\lambda)}_{it} \:, \\ \log(\phi_{it}) &= \alpha_i^{(\phi)} + {\bm{\beta}^{(\phi)}}^\top \bm{z}^{(\phi)}_{it} \:. \end{align} %% The superscripts in brackets distinguish the component-specific parameters. The intercepts of these predictors can be assumed identical across units, unit-specific, or random (and possibly correlated). %\citep{paul-held-2011} The regression terms often involve sine-cosine effects of time to reflect seasonally varying incidence, %\citep{held.paul2012} but may, e.g., also capture heterogeneous vaccination coverage \citep{herzog-etal-2010}. Data on infections imported from outside the study region may enter the endemic component \citep{geilhufe.etal2012}, which generally accounts for cases not directly linked to other observed cases, e.g., due to edge effects. For a single time series of counts $Y_t$, \code{hhh4} can be regarded as an extension of \code{glm.nb} from package \CRANpkg{MASS} \citep{R:MASS} to account for autoregression. See the \code{vignette("hhh4")} for examples of modeling univariate and bivariate count time series using \code{hhh4}. With multiple regions, spatio-temporal dependence is adopted by the third component in Equation~\ref{eqn:hhh4} with weights $w_{ji}$ reflecting the flow of infections from region $j$ to region $i$. These transmission weights may be informed by movement network data \citep{paul-etal-2008,geilhufe.etal2012}, but may also be estimated parametrically. A suitable choice to reflect epidemiological coupling between regions \citep[Chapter~7]{Keeling.Rohani2008} is a power-law distance decay $w_{ji} = o_{ji}^{-d}$ defined in terms of the adjacency order~$o_{ji}$ in the neighborhood graph of the regions \citep{meyer.held2013}. %% For instance, a second-order neighbor~$j$ of a region~$i$ ($o_{ji} = 2$) is a %% region adjacent to a first-order neighbor of $i$, but not itself directly %% adjacent to $i$. Note that we usually normalize the transmission weights such that $\sum_i w_{ji} = 1$, i.e., the $Y_{j,t-1}$ cases are distributed among the regions proportionally to the $j$th row vector of the weight matrix $(w_{ji})$. Likelihood inference for the above multivariate time-series model has been established by \citet{paul-held-2011} with extensions for parametric neighborhood weights by \citet{meyer.held2013}. Supplied with the analytical score function and Fisher information, the function \code{hhh4} by default uses the quasi-Newton algorithm available through the \proglang{R} function \code{nlminb} to maximize the log-likelihood. Convergence is usually fast even for a large number of parameters. If the model contains random effects, the penalized and marginal log-likelihoods are maximized alternately until convergence. Computation of the marginal Fisher information is accelerated using the \CRANpkg{Matrix} package \citep{R:Matrix}. \section[Data structure]{Data structure: \class{sts}} \label{sec:hhh4:data} <>= ## extract components from measlesWeserEms to reconstruct data("measlesWeserEms") counts <- observed(measlesWeserEms) map <- measlesWeserEms@map populationFrac <- measlesWeserEms@populationFrac @ In public health surveillance, routine reports of infections to public health authorities give rise to spatio-temporal data, which are usually made available in the form of aggregated counts by region and period. The Robert Koch Institute (RKI) in Germany, for example, maintains a database of cases of notifiable diseases, which can be queried via the \emph{SurvStat@RKI} online service (\url{https://survstat.rki.de}). To exemplify area-level \code{hhh4} models in the remainder of this manuscript, we use weekly counts of measles infections by district in the Weser-Ems region of Lower Saxony, Germany, 2001--2002, downloaded from \emph{SurvStat@RKI} (as of Annual Report 2005). These data are contained in \pkg{surveillance} as \code{data("measlesWeserEms")} -- an object of the \proglang{S}4-class \class{sts} (``surveillance time series'') used for data input in \code{hhh4} models and briefly introduced below. See \citet{hoehle-mazick-2010} and \citet{salmon.etal2014} for more detailed descriptions of this class, which is also used for the prospective aberration detection facilities of the \pkg{surveillance} package. The epidemic modeling of multivariate count time series essentially involves three data matrices: a $T \times I$ matrix of the observed counts, a corresponding matrix with potentially time-varying population numbers (or fractions), and an $I \times I$ neighborhood matrix quantifying the coupling between the $I$ units. In our example, the latter consists of the adjacency orders~$o_{ji}$ between the districts. A map of the districts in the form of a \code{SpatialPolygons} object (defined by the \CRANpkg{sp} package of \citealp{R:sp}) can be used to derive the matrix of adjacency orders automatically using the functions \code{poly2adjmat} and \code{nbOrder}, where the former wraps functionality of package \CRANpkg{spdep} \citep{R:spdep}: <>= weserems_adjmat <- poly2adjmat(map) weserems_nbOrder <- nbOrder(weserems_adjmat) @ <>= weserems_nbOrder <- measlesWeserEms@neighbourhood @ Visual inspection of the adjacencies identified by \code{poly2adjmat} is recommended, e.g., via labelling each district with the number of its neighbors, i.e., \code{rowSums(weserems_adjmat)}. If adjacencies are not detected, this is probably due to sliver polygons. In that case either increase the \code{snap} tolerance in \code{poly2adjmat} or use \CRANpkg{rmapshaper} \citep{R:rmapshaper} to simplify and snap adjacent polygons in advance. Given the aforementioned ingredients, the \class{sts} object \code{measlesWeserEms} has been constructed as follows: <>= measlesWeserEms <- sts(counts, start = c(2001, 1), frequency = 52, population = populationFrac, neighbourhood = weserems_nbOrder, map = map) @ Here, \code{start} and \code{frequency} have the same meaning as for classical time-series objects of class \class{ts}, i.e., (year, sample number) of the first observation and the number of observations per year. Note that \code{data("measlesWeserEms")} constitutes a corrected version of \code{data("measles.weser")} originally analyzed by \citet[Section~3.2]{held-etal-2005}. Differences are documented on the associated help page. We can visualize such \class{sts} data in four ways: individual time series, overall time series, map of accumulated counts by district, or animated maps. For instance, the two plots in Figure~\ref{fig:measlesWeserEms} have been generated by the following code: <>= par(mar = c(5,5,1,1)) plot(measlesWeserEms, type = observed ~ time) plot(measlesWeserEms, type = observed ~ unit, population = measlesWeserEms@map$POPULATION / 100000, labels = list(font = 2), colorkey = list(space = "right"), sp.layout = layout.scalebar(measlesWeserEms@map, corner = c(0.05, 0.05), scale = 50, labels = c("0", "50 km"), height = 0.03)) @ The overall time-series plot in Figure~\ref{fig:measlesWeserEms-1} reveals strong seasonality in the data with slightly different patterns in the two years. The spatial plot in Figure~\ref{fig:measlesWeserEms-2} is a tweaked \code{spplot} (package \CRANpkg{sp}) with colors from \CRANpkg{colorspace} \citep{R:colorspace} using $\sqrt{}$-equidistant cut points. The default plot \code{type} is \code{observed ~ time | unit} and displays the district-specific time series. Here we show the output of the equivalent \code{autoplot}-method (Figure~\ref{fig:measlesWeserEms15}), which is based on and requires \CRANpkg{ggplot2} \citep{R:ggplot2}: <0), "affected districts."), out.width="\\linewidth", fig.width=10, fig.height=6, fig.pos="htb">>= if (require("ggplot2")) { autoplot(measlesWeserEms, units = which(colSums(observed(measlesWeserEms)) > 0)) } else plot(measlesWeserEms, units = which(colSums(observed(measlesWeserEms)) > 0)) @ The districts \Sexpr{paste0(paste0(row.names(measlesWeserEms@map), " (", measlesWeserEms@map[["GEN"]], ")")[colSums(observed(measlesWeserEms)) == 0], collapse = " and ")} without any reported cases are excluded in Figure~\ref{fig:measlesWeserEms15}. Obviously, the districts have been affected by measles to a very heterogeneous extent during these two years. An animation of the data can be easily produced as well. We recommend to use converters of the \CRANpkg{animation} package \citep{R:animation}, e.g., to watch the series of plots in a web browser. The following code will generate weekly disease maps during the year 2001 with the respective total number of cases shown in a legend and -- if package \CRANpkg{gridExtra} \citep{R:gridExtra} is available -- an evolving time-series plot at the bottom: <>= animation::saveHTML( animate(measlesWeserEms, tps = 1:52, total.args = list()), title = "Evolution of the measles epidemic in the Weser-Ems region, 2001", ani.width = 500, ani.height = 600) @ <>= ## to perform the following analysis using biweekly aggregated measles counts: measlesWeserEms <- aggregate(measlesWeserEms, by = "time", nfreq = 26) @ \pagebreak \section{Modeling and inference} \label{sec:hhh4:fit} For multivariate surveillance time series of counts such as the \code{measlesWeserEms} data, the function \code{hhh4} fits models of the form~\eqref{eqn:hhh4} via (penalized) maximum likelihood. We start by modeling the measles counts in the Weser-Ems region by a slightly simplified version of the original negative binomial model used by \citet{held-etal-2005}. Instead of district-specific intercepts $\alpha_i^{(\nu)}$ in the endemic component, we first assume a common intercept $\alpha^{(\nu)}$ in order to not be forced to exclude the two districts without any reported cases of measles. After the estimation and illustration of this basic model, we will discuss the following sequential extensions: covariates (district-specific vaccination coverage), estimated transmission weights, and random effects to eventually account for unobserved heterogeneity of the districts. %epidemic seasonality, biweekly aggregation \subsection{Basic model} Our initial model has the following mean structure: \begin{align} \mu_{it} &= e_i \, \nu_t + \lambda \, Y_{i,t-1} + \phi \sum_{j \ne i} w_{ji} Y_{j,t-1}\:,\label{eqn:hhh4:basic}\\ \log(\nu_t) &= \alpha^{(\nu)} + \beta_t t + \gamma \sin(\omega t) + \delta \cos(\omega t)\:. \label{eqn:hhh4:basic:end} \end{align} To account for temporal variation of disease incidence, the endemic log-linear predictor $\nu_t$ incorporates an overall trend and a sinusoidal wave of frequency $\omega=2\pi/52$. As a basic district-specific measure of disease incidence, the population fraction $e_i$ is included as a multiplicative offset. The epidemic parameters $\lambda = \exp(\alpha^{(\lambda)})$ and $\phi = \exp(\alpha^{(\phi)})$ are assumed homogeneous across districts and constant over time. Furthermore, we define $w_{ji} = \ind(j \sim i) = \ind(o_{ji} = 1)$ for the time being, which means that the epidemic can only arrive from directly adjacent districts. This \class{hhh4} model transforms into the following list of \code{control} arguments: <>= measlesModel_basic <- list( end = list(f = addSeason2formula(~1 + t, period = measlesWeserEms@freq), offset = population(measlesWeserEms)), ar = list(f = ~1), ne = list(f = ~1, weights = neighbourhood(measlesWeserEms) == 1), family = "NegBin1") @ The formulae of the three predictors $\log\nu_t$, $\log\lambda$ and $\log\phi$ are specified as element \code{f} of the \code{end}, \code{ar}, and \code{ne} lists, respectively. For the endemic formula we use the convenient function \code{addSeason2formula} to generate the sine-cosine terms, and we take the multiplicative \code{offset} of population fractions $e_i$ from the \code{measlesWeserEms} object. The autoregressive part only consists of the intercept $\alpha^{(\lambda)}$, whereas the neighborhood component specifies the intercept $\alpha^{(\phi)}$ and also the matrix of transmission \code{weights} $(w_{ji})$ to use -- here a simple indicator of first-order adjacency. The chosen \code{family} corresponds to a negative binomial model with a common overdispersion parameter $\psi$ for all districts. Alternatives are \code{"Poisson"}, \code{"NegBinM"} ($\psi_i$), or a factor determining which groups of districts share a common overdispersion parameter. Together with the data, the complete list of control arguments is then fed into the \code{hhh4} function to estimate the model: <>= measlesFit_basic <- hhh4(stsObj = measlesWeserEms, control = measlesModel_basic) @ The fitted model is summarized below: <>= summary(measlesFit_basic, idx2Exp = TRUE, amplitudeShift = TRUE, maxEV = TRUE) @ The \code{idx2Exp} argument of the \code{summary} method requests the estimates for $\lambda$, $\phi$, $\alpha^{(\nu)}$ and $\exp(\beta_t)$ instead of their respective internal log-values. For instance, \code{exp(end.t)} represents the seasonality-adjusted factor by which the basic endemic incidence increases per week. The \code{amplitudeShift} argument transforms the internal coefficients $\gamma$ and $\delta$ of the sine-cosine terms to the amplitude $A$ and phase shift $\varphi$ of the corresponding sinusoidal wave $A \sin(\omega t + \varphi)$ in $\log\nu_t$ \citep{paul-etal-2008}. The resulting multiplicative effect of seasonality on $\nu_t$ is shown in Figure~\ref{fig:measlesFit_basic_endseason} produced by: <>= plot(measlesFit_basic, type = "season", components = "end", main = "") @ The epidemic potential of the process as determined by the parameters $\lambda$ and $\phi$ is best investigated by a combined measure: the dominant eigenvalue (\code{maxEV}) of the matrix $\bm{\Lambda}$ %$\Lambda_t$, %such that $\bm{\mu}_t = \bm{\nu}_t + \bm{\Lambda} \bm{Y}_{t-1}$ which has the entries $(\Lambda)_{ii} = \lambda$ %$(\Lambda_t)_{ii} = \lambda_{it}$ on the diagonal and $(\Lambda)_{ij} = \phi w_{ji}$ %$(\Lambda_t)_{ij} = \phi_{it} w_{ji}$ for $j\ne i$ \citep{paul-etal-2008}. If the dominant eigenvalue is smaller than 1, it can be interpreted as the epidemic proportion of disease incidence. In the above model, the estimate is \Sexpr{round(100*getMaxEV(measlesFit_basic)[1])}\%. Another way to judge the relative importance of the three model components is via a plot of the fitted mean components along with the observed counts. Figure~\ref{fig:measlesFitted_basic} shows this for the five districts with more than 50 cases as well as for the sum over all districts: <>= districts2plot <- which(colSums(observed(measlesWeserEms)) > 50) par(mfrow = c(2,3), mar = c(3, 5, 2, 1), las = 1) plot(measlesFit_basic, type = "fitted", units = districts2plot, hide0s = TRUE, par.settings = NULL, legend = 1) plot(measlesFit_basic, type = "fitted", total = TRUE, hide0s = TRUE, par.settings = NULL, legend = FALSE) -> fitted_components @ We can see from the plots that the largest portion of the fitted mean indeed results from the within-district autoregressive component with very little contribution of cases from adjacent districts and a rather small endemic incidence. The \code{plot} method invisibly returns the component values in a list of matrices (one by unit). In the above code, we have assigned the result from plotting the overall fit (via \code{total = TRUE}) to the object \code{fitted_components}. Here we show the values for the weeks 20 to 22 (corresponding to the weeks 21 to 23 of the measles time series): <<>>= fitted_components$Overall[20:22,] @ The first column of this matrix refers to the fitted mean (epidemic + endemic). The four following columns refer to the epidemic (own + neighbours), endemic, autoregressive (``own''), and neighbourhood components of the mean. The last three columns refer to the point estimates of $\lambda$, $\phi$, and $\nu_t$, respectively. These values allow us to calculate the (time-averaged) proportions of the mean explained by the different components: <<>>= colSums(fitted_components$Overall)[3:5] / sum(fitted_components$Overall[,1]) @ Note that the ``epidemic proportion'' obtained here (\Sexpr{round(100*sum(fitted_components$Overall[,2]) / sum(fitted_components$Overall[,1]))}\%) is a function of the observed time series (so could be called ``empirical''), whereas the dominant eigenvalue calculated further above is a theoretical property derived from the autoregressive parameters alone. Finally, the \code{overdisp} parameter from the model summary and its 95\% confidence interval <<>>= confint(measlesFit_basic, parm = "overdisp") @ suggest that a negative binomial distribution with overdispersion is more adequate than a Poisson model corresponding to $\psi = 0$. We can underpin this finding by an AIC comparison, taking advantage of the convenient \code{update} method for \class{hhh4} fits: <>= AIC(measlesFit_basic, update(measlesFit_basic, family = "Poisson")) @ Other plot \code{type}s and methods for fitted \class{hhh4} models as listed in Table~\ref{tab:methods:hhh4} will be applied in the course of the following model extensions. <>= print(xtable( surveillance:::functionTable("hhh4", functions=list( Extract="getNEweights", Other="oneStepAhead" )), caption="Generic and \\textit{non-generic} functions applicable to \\class{hhh4} objects.", label="tab:methods:hhh4"), include.rownames = FALSE) @ \enlargethispage{\baselineskip} \subsection{Covariates} The \class{hhh4} model framework allows for covariate effects on the endemic or epidemic contributions to disease incidence. Covariates may vary over both regions and time and thus obey the same $T \times I$ matrix structure as the observed counts. For infectious disease models, the regional vaccination coverage is an important example of such a covariate, since it reflects the (remaining) susceptible population. In a thorough analysis of measles occurrence in the German federal states, \citet{herzog-etal-2010} found vaccination coverage to be associated with outbreak size. We follow their approach of using the district-specific proportion $1-v_i$ of unvaccinated children just starting school as a proxy for the susceptible population. As $v_i$ we use the proportion of children vaccinated with at least one dose among the ones presenting their vaccination card at school entry in district $i$ in the year 2004.\footnote{% First year with data for all districts; more recent data is available from the public health department of Lower Saxony (\url{https://www.nlga.niedersachsen.de/impfreport/}).} %% Note: districts are more heterogeneous in 2004 than in later years. %% Data is based on abecedarians in 2004, i.e.\ born in 1998, recommended to %% be twice vaccinated against Measles by the end of year 2000. This time-constant covariate needs to be transformed to the common matrix structure for incorporation in \code{hhh4}: <>= Sprop <- matrix(1 - measlesWeserEms@map@data$vacc1.2004, nrow = nrow(measlesWeserEms), ncol = ncol(measlesWeserEms), byrow = TRUE) summary(Sprop[1, ]) @ There are several ways to account for the susceptible proportion in our model, among which the simplest is to update the endemic population offset $e_i$ by multiplication with $(1-v_i)$. \citet{herzog-etal-2010} found that the susceptible proportion is best added as a covariate in the autoregressive component in the form \[ \lambda_i \, Y_{i,t-1} = \exp\big(\alpha^{(\lambda)} + \beta_s \log(1-v_i)\big) \, Y_{i,t-1} = \exp\big(\alpha^{(\lambda)}\big) \, (1-v_i)^{\beta_s} \, Y_{i,t-1} \] according to the mass action principle \citep{Keeling.Rohani2008}. A higher proportion of susceptibles in district $i$ is expected to boost the generation of new infections, i.e., $\beta_s > 0$. Alternatively, this effect could be assumed as an offset, i.e., $\beta_s \equiv 1$. To choose between endemic and/or autoregressive effects, and multiplicative offset vs.\ covariate modeling, we perform AIC-based model selection. First, we set up a grid of possible component updates: <>= Soptions <- c("unchanged", "Soffset", "Scovar") SmodelGrid <- expand.grid(end = Soptions, ar = Soptions) row.names(SmodelGrid) <- do.call("paste", c(SmodelGrid, list(sep = "|"))) @ Then we update the initial model \code{measlesFit_basic} according to each row of \code{SmodelGrid}: <>= measlesFits_vacc <- apply(X = SmodelGrid, MARGIN = 1, FUN = function (options) { updatecomp <- function (comp, option) switch(option, "unchanged" = list(), "Soffset" = list(offset = comp$offset * Sprop), "Scovar" = list(f = update(comp$f, ~. + log(Sprop)))) update(measlesFit_basic, end = updatecomp(measlesFit_basic$control$end, options[1]), ar = updatecomp(measlesFit_basic$control$ar, options[2]), data = list(Sprop = Sprop)) }) @ The resulting object \code{measlesFits_vacc} is a list of \Sexpr{nrow(SmodelGrid)} \class{hhh4} fits, which are named according to the corresponding \code{Soptions} used for the endemic and autoregressive components. We construct a call of the function \code{AIC} taking all list elements as arguments: <>= aics_vacc <- do.call(AIC, lapply(names(measlesFits_vacc), as.name), envir = as.environment(measlesFits_vacc)) @ <<>>= aics_vacc[order(aics_vacc[, "AIC"]), ] @ <>= if (AIC(measlesFits_vacc[["Scovar|unchanged"]]) > min(aics_vacc[,"AIC"])) stop("`Scovar|unchanged` is not the AIC-minimal vaccination model") @ Hence, AIC increases if the susceptible proportion is only added to the autoregressive component, but we see a remarkable improvement when adding it to the endemic component. The best model is obtained by leaving the autoregressive component unchanged ($\lambda$) and adding the term $\beta_s \log(1-v_i)$ to the endemic predictor in Equation~\ref{eqn:hhh4:basic:end}. <>= measlesFit_vacc <- update(measlesFit_basic, end = list(f = update(formula(measlesFit_basic)$end, ~. + log(Sprop))), data = list(Sprop = Sprop)) coef(measlesFit_vacc, se = TRUE)["end.log(Sprop)", ] @ The estimated exponent $\hat{\beta}_s$ is both clearly positive and different from the offset assumption. In other words, if a district's fraction of susceptibles is doubled, the endemic measles incidence is estimated to multiply by $2^{\hat{\beta}_s}$: <<>>= 2^cbind("Estimate" = coef(measlesFit_vacc), confint(measlesFit_vacc))["end.log(Sprop)",] @ \subsection{Spatial interaction} Up to now, the model assumed that the epidemic can only arrive from directly adjacent districts ($w_{ji} = \ind(j\sim i)$), and that all districts have the same ability $\phi$ to import cases from neighboring regions. Given that humans travel further and preferably to metropolitan areas, both assumptions seem overly simplistic and should be tuned toward a ``gravity'' model for human interaction. First, to reflect commuter-driven spread %\citep[Section~6.3.3.1]{Keeling.Rohani2008} in our model, we scale the district's susceptibility with respect to its population fraction by multiplying $\phi$ with $e_i^{\beta_{pop}}$: <>= measlesFit_nepop <- update(measlesFit_vacc, ne = list(f = ~log(pop)), data = list(pop = population(measlesWeserEms))) @ As in a similar analyses of influenza \citep{geilhufe.etal2012,meyer.held2013}, we find strong evidence for such an agglomeration effect: AIC decreases from \Sexpr{round(AIC(measlesFit_vacc))} to \Sexpr{round(AIC(measlesFit_nepop))} and the estimated exponent $\hat{\beta}_{pop}$ is <<>>= cbind("Estimate" = coef(measlesFit_nepop), confint(measlesFit_nepop))["ne.log(pop)",] @ Second, to account for long-range transmission of cases, \citet{meyer.held2013} proposed to estimate the weights $w_{ji}$ as a function of the adjacency order $o_{ji}$ between the districts. For instance, a power-law model assumes the form $w_{ji} = o_{ji}^{-d}$, for $j\ne i$ and $w_{jj}=0$, where the decay parameter $d$ is to be estimated. Normalization to $w_{ji} / \sum_k w_{jk}$ is recommended and applied by default when choosing \code{W_powerlaw} as weights in the neighborhood component: <>= measlesFit_powerlaw <- update(measlesFit_nepop, ne = list(weights = W_powerlaw(maxlag = 5))) @ The argument \code{maxlag} sets an upper bound for spatial interaction in terms of adjacency order. Here we set no limit since \code{max(neighbourhood(measlesWeserEms))} is \Sexpr{max(neighbourhood(measlesWeserEms))}. The decay parameter $d$ is estimated to be <<>>= cbind("Estimate" = coef(measlesFit_powerlaw), confint(measlesFit_powerlaw))["neweights.d",] @ which represents a strong decay of spatial interaction for higher-order neighbors. As an alternative to the parametric power law, unconstrained weights up to \code{maxlag} can be estimated by using \code{W_np} instead of \code{W_powerlaw}. For instance, \code{W_np(maxlag = 2)} corresponds to a second-order model, i.e., \mbox{$w_{ji} = 1 \cdot \ind(o_{ji} = 1) + e^{\omega_2} \cdot \ind(o_{ji} = 2)$}, which is also row-normalized by default: <>= measlesFit_np2 <- update(measlesFit_nepop, ne = list(weights = W_np(maxlag = 2))) @ Figure~\ref{fig:measlesFit_neweights-2} shows both the power-law model $o^{-\hat{d}}$ and the second-order model. %, where $e^{\hat{\omega}_2}$ is Alternatively, the plot \code{type = "neweights"} for \class{hhh4} fits can produce a \code{stripplot} \citep{R:lattice} of $w_{ji}$ against $o_{ji}$ as shown in Figure~\ref{fig:measlesFit_neweights-1} for the power-law model: <>= library("lattice") trellis.par.set("reference.line", list(lwd=3, col="gray")) trellis.par.set("fontsize", list(text=14)) set.seed(20200303) plot(measlesFit_powerlaw, type = "neweights", plotter = stripplot, panel = function (...) {panel.stripplot(...); panel.average(...)}, jitter.data = TRUE, xlab = expression(o[ji]), ylab = expression(w[ji])) ## non-normalized weights (power law and unconstrained second-order weight) local({ colPL <- "#0080ff" ogrid <- 1:5 par(mar=c(3.6,4,2.2,2), mgp=c(2.1,0.8,0)) plot(ogrid, ogrid^-coef(measlesFit_powerlaw)["neweights.d"], col=colPL, xlab="Adjacency order", ylab="Non-normalized weight", type="b", lwd=2) matlines(t(sapply(ogrid, function (x) x^-confint(measlesFit_powerlaw, parm="neweights.d"))), type="l", lty=2, col=colPL) w2 <- exp(c(coef(measlesFit_np2)["neweights.d"], confint(measlesFit_np2, parm="neweights.d"))) lines(ogrid, c(1,w2[1],0,0,0), type="b", pch=19, lwd=2) arrows(x0=2, y0=w2[2], y1=w2[3], length=0.1, angle=90, code=3, lty=2) legend("topright", col=c(colPL, 1), pch=c(1,19), lwd=2, bty="n", inset=0.1, y.intersp=1.5, legend=c("Power-law model", "Second-order model")) }) @ Note that only horizontal jitter is added in this case. Because of normalization, the weight $w_{ji}$ for transmission from district $j$ to district $i$ is determined not only by the districts' neighborhood $o_{ji}$ but also by the total amount of neighborhood of district $j$ in the form of $\sum_{k\ne j} o_{jk}^{-d}$, which causes some variation of the weights for a specific order of adjacency. The function \code{getNEweights} can be used to extract the estimated weight matrix $(w_{ji})$. An AIC comparison of the different models for the transmission weights yields: <<>>= AIC(measlesFit_nepop, measlesFit_powerlaw, measlesFit_np2) @ AIC improves when accounting for transmission from higher-order neighbors by a power law or a second-order model. In spite of the latter resulting in a slightly better fit, we will use the power-law model as a basis for further model extensions since the stand-alone second-order effect is not always identifiable in more complex models and is scientifically implausible. \subsection{Random effects} \citet{paul-held-2011} introduced random effects for \class{hhh4} models, which are useful if the districts exhibit heterogeneous incidence levels not explained by observed covariates, and especially if the number of districts is large. For infectious disease surveillance data, a typical example of unobserved heterogeneity is underreporting. Our measles data even contain two districts without any reported cases, while the district with the smallest population (03402, SK Emden) had the second-largest number of cases reported and the highest overall incidence (see Figures~\ref{fig:measlesWeserEms-2} and~\ref{fig:measlesWeserEms15}). Hence, allowing for district-specific intercepts in the endemic or epidemic components is expected to improve the model fit. For independent random effects $\alpha_i^{(\nu)} \stackrel{iid}{\sim} \N(\alpha^{(\nu)}, \sigma_\nu^2)$, $\alpha_i^{(\lambda)} \stackrel{iid}{\sim} \N(\alpha^{(\lambda)}, \sigma_\lambda^2)$, and $\alpha_i^{(\phi)} \stackrel{iid}{\sim} \N(\alpha^{(\phi)}, \sigma_\phi^2)$ in all three components, we update the corresponding formulae as follows: <>= measlesFit_ri <- update(measlesFit_powerlaw, end = list(f = update(formula(measlesFit_powerlaw)$end, ~. + ri() - 1)), ar = list(f = update(formula(measlesFit_powerlaw)$ar, ~. + ri() - 1)), ne = list(f = update(formula(measlesFit_powerlaw)$ne, ~. + ri() - 1))) @ <>= summary(measlesFit_ri, amplitudeShift = TRUE, maxEV = TRUE) @ <>= ## strip leading and trailing empty lines writeLines(tail(head(capture.output({ <> }), -1), -1)) @ The summary now contains an extra section with the estimated variance components $\sigma_\lambda^2$, $\sigma_\phi^2$, and $\sigma_\nu^2$. We did not assume correlation between the three random effects, but this is possible by specifying \code{ri(corr = "all")} in the component formulae. The implementation also supports a conditional autoregressive formulation for spatially correlated intercepts via \code{ri(type = "car")}. The estimated district-specific deviations $\alpha_i^{(\cdot)} - \alpha^{(\cdot)}$ can be extracted by the \code{ranef}-method: <<>>= head(ranef(measlesFit_ri, tomatrix = TRUE), n = 3) @ The \code{exp}-transformed deviations correspond to district-specific multiplicative effects on the model components, which can be visualized via the plot \code{type = "ri"} as follows (Figure~\ref{fig:measlesFit_ri_map}): % exp=TRUE plot has nicer (usually more) axis ticks if 'scales' is available <>= for (comp in c("ar", "ne", "end")) { print(plot(measlesFit_ri, type = "ri", component = comp, exp = TRUE, labels = list(cex = 0.6))) } @ For the autoregressive component in Figure~\ref{fig:measlesFit_ri_map-1}, we see a pronounced heterogeneity between the three western districts in pink and the remaining districts. These three districts have been affected by large local outbreaks and are also the ones with the highest overall numbers of cases. In contrast, the city of Oldenburg (03403) is estimated with a relatively low autoregressive coefficient: $\lambda_i = \exp(\alpha_i^{(\lambda)})$ can be extracted using the \code{intercept} argument as <<>>= exp(ranef(measlesFit_ri, intercept = TRUE)["03403", "ar.ri(iid)"]) @ However, this district seems to import more cases from other districts than explained by its population (Figure~\ref{fig:measlesFit_ri_map-2}). In Figure~\ref{fig:measlesFit_ri_map-3}, the two districts without any reported measles cases (03401 and 03405) appear in cyan, which means that they exhibit a relatively low endemic incidence after adjusting for the population and susceptible proportion. Such districts could be suspected of a larger amount of underreporting. We plot the new model fit (Figure~\ref{fig:measlesFitted_ri}) for comparison with the initial fit shown in Figure~\ref{fig:measlesFitted_basic}: <>= par(mfrow = c(2,3), mar = c(3, 5, 2, 1), las = 1) plot(measlesFit_ri, type = "fitted", units = districts2plot, hide0s = TRUE, par.settings = NULL, legend = 1) plot(measlesFit_ri, type = "fitted", total = TRUE, hide0s = TRUE, par.settings = NULL, legend = FALSE) @ For some of these districts, a great amount of cases is now explained via transmission from neighboring regions while others are mainly influenced by the local autoregression. The decomposition of the estimated mean by district can also be seen from the related plot \code{type = "maps"} (Figure~\ref{fig:measlesFitted_maps}): <>= plot(measlesFit_ri, type = "maps", which = c("epi.own", "epi.neighbours", "endemic"), prop = TRUE, labels = list(cex = 0.6)) @ The extra flexibility of the random effects model comes at a price. First, the runtime of the estimation increases considerably from \Sexpr{round(measlesFit_powerlaw[["runtime"]]["elapsed"], 1)} seconds for the previous power-law model \code{measlesFit_powerlaw} to \Sexpr{round(measlesFit_ri[["runtime"]]["elapsed"], 1)} seconds with random effects. Furthermore, we no longer obtain AIC values, since random effects invalidate simple AIC-based model comparisons. For quantitative comparisons of model performance we have to resort to more sophisticated techniques presented in the next section. \subsection{Predictive model assessment} \citet{paul-held-2011} suggest to evaluate one-step-ahead forecasts from competing models using proper scoring rules for count data \citep{czado-etal-2009}. These scores measure the discrepancy between the predictive distribution $P$ from a fitted model and the later observed value $y$. A well-known example is the squared error score (``ses'') $(y-\mu_P)^2$, which is usually averaged over a set of forecasts to obtain the mean squared error. The Dawid-Sebastiani score (``dss'') additionally evaluates sharpness. The logarithmic score (``logs'') and the ranked probability score (``rps'') assess the whole predictive distribution with respect to calibration and sharpness. Lower scores correspond to better predictions. In the \class{hhh4} framework, predictive model assessment is made available by the functions \code{oneStepAhead}, \code{scores}, \code{pit}, and \code{calibrationTest}. We will use the second quarter of 2002 as the test period, and compare the basic model, the power-law model, and the random effects model. First, we use the \code{"final"} fits on the complete time series to compute the predictions, which then simply correspond to the fitted values during the test period: <>= tp <- c(65, 77) models2compare <- paste0("measlesFit_", c("basic", "powerlaw", "ri")) measlesPreds1 <- lapply(mget(models2compare), oneStepAhead, tp = tp, type = "final") @ <>= stopifnot(all.equal(measlesPreds1$measlesFit_powerlaw$pred, fitted(measlesFit_powerlaw)[tp[1]:tp[2],], check.attributes = FALSE)) @ Note that in this case, the log-score for a model's prediction in district $i$ in week $t$ equals the associated negative log-likelihood contribution. Comparing the mean scores from different models is thus essentially a goodness-of-fit assessment: <>= stopifnot(all.equal( measlesFit_powerlaw$loglikelihood, -sum(scores(oneStepAhead(measlesFit_powerlaw, tp = 1, type = "final"), which = "logs", individual = TRUE)))) @ <>= SCORES <- c("logs", "rps", "dss", "ses") measlesScores1 <- lapply(measlesPreds1, scores, which = SCORES, individual = TRUE) t(sapply(measlesScores1, colMeans, dims = 2)) @ All scoring rules claim that the random effects model gives the best fit during the second quarter of 2002. Now we turn to true one-week-ahead predictions of \code{type = "rolling"}, which means that we always refit the model up to week $t$ to get predictions for week $t+1$: <>= measlesPreds2 <- lapply(mget(models2compare), oneStepAhead, tp = tp, type = "rolling", which.start = "final") @ Figure~\ref{fig:measlesPreds2_plot} shows \CRANpkg{fanplot}s \citep{R:fanplot} of the sequential one-week-ahead forecasts from the random effects models for the same districts as in Figure~\ref{fig:measlesFitted_ri}: <>= par(mfrow = sort(n2mfrow(length(districts2plot))), mar = c(4.5,4.5,2,1)) for (unit in names(districts2plot)) plot(measlesPreds2[["measlesFit_ri"]], unit = unit, main = unit, key.args = if (unit == tail(names(districts2plot),1)) list()) @ The \code{plot}-method for \class{oneStepAhead} predictions is based on the associated \code{quantile}-method (a \code{confint}-method is also available). Note that the sum of these negative binomial distributed forecasts over all districts is not negative binomial distributed. The package \CRANpkg{distr} \citep{ruckdeschel.kohl2014} could be used to approximate the distribution of the aggregated one-step-ahead forecasts (not shown here). Looking at the average scores of these forecasts over all weeks and districts, the most parsimonious initial model \code{measlesFit_basic} actually turns out best: <>= measlesScores2 <- lapply(measlesPreds2, scores, which = SCORES, individual = TRUE) t(sapply(measlesScores2, colMeans, dims = 2)) @ Statistical significance of the differences in mean scores can be investigated by a \code{permutationTest} for paired data or a paired $t$-test: <>= set.seed(321) sapply(SCORES, function (score) permutationTest( measlesScores2$measlesFit_ri[, , score], measlesScores2$measlesFit_basic[, , score], nPermutation = 999)) @ Hence, there is no clear evidence for a difference between the basic and the random effects model with regard to predictive performance during the test period. Whether predictions of a particular model are well calibrated can be formally investigated by \code{calibrationTest}s for count data as recently proposed by \citet{wei.held2013}. For example: <>= calibrationTest(measlesPreds2[["measlesFit_ri"]], which = "rps") @ <>= ## strip leading and trailing empty lines writeLines(tail(head(capture.output({ <> }), -1), -1)) @ Thus, there is no evidence of miscalibrated predictions from the random effects model. \citet{czado-etal-2009} describe an alternative informal approach to assess calibration: probability integral transform (PIT) histograms for count data (Figure~\ref{fig:measlesPreds2_pit}). <>= par(mfrow = sort(n2mfrow(length(measlesPreds2))), mar = c(4.5,4.5,2,1), las = 1) for (m in models2compare) pit(measlesPreds2[[m]], plot = list(ylim = c(0, 1.25), main = m)) @ Under the hypothesis of calibration, i.e., $y_{it} \sim P_{it}$ for all predictive distributions $P_{it}$ in the test period, the PIT histogram is uniform. Underdispersed predictions lead to U-shaped histograms, and bias causes skewness. In this aggregate view of the predictions over all districts and weeks of the test period, predictive performance is comparable between the models, and there is no evidence of badly dispersed predictions. However, the right-hand decay in all histograms suggests that all models tend to predict higher counts than observed. This is most likely related to the seasonal shift between the years 2001 and 2002. In 2001, the peak of the epidemic was in the second quarter, while it already occurred in the first quarter in 2002 (cp.\ Figure~\ref{fig:measlesWeserEms-1}). \subsection{Further modeling options} In the previous sections we extended our model for measles in the Weser-Ems region with respect to spatial variation of the counts and their interaction. Temporal variation was only accounted for in the endemic component, which included a long-term trend and a sinusoidal wave on the log-scale. \citet{held.paul2012} suggest to also allow seasonal variation of the epidemic force by adding a superposition of $S$ harmonic waves of fundamental frequency~$\omega$, $\sum_{s=1}^S \left\{ \gamma_s \sin(s\,\omega t) + \delta_s \cos(s\,\omega t) \right\}$, to the log-linear predictors of the autoregressive and/or neighborhood component -- just like for $\log\nu_t$ in Equation~\ref{eqn:hhh4:basic:end} with $S=1$. However, given only two years of measles surveillance and the apparent shift of seasonality with regard to the start of the outbreak in 2002 compared to 2001, more complex seasonal models are likely to overfit the data. Concerning the coding in \proglang{R}, sine-cosine terms can be added to the epidemic components without difficulties by again using the convenient function \code{addSeason2formula}. Updating a previous model for different numbers of harmonics is even simpler, since the \code{update}-method has a corresponding argument \code{S}. The plots of \code{type = "season"} and \code{type = "maxEV"} for \class{hhh4} fits can visualize the estimated component seasonality. Performing model selection and interpreting seasonality or other covariate effects across \emph{three} different model components may become quite complicated. Power-law weights actually enable a more parsimonious model formulation, where the autoregressive and neighbourhood components are merged into a single epidemic component: \begin{equation} \mu_{it} = e_{it} \, \nu_{it} + \phi_{it} \sum_{j} (o_{ji} + 1)^{-d} \, Y_{j,t-1} \:. \end{equation} With only two predictors left, model selection and interpretation is simpler, and model extensions are more straightforward, for example stratification by age group \citep{meyer.held2015} as mentioned further below. To fit such a two-component model, the autoregressive component has to be excluded (\code{ar = list(f = ~ -1)}) and power-law weights have to be modified to start from adjacency order~0 (via \code{W_powerlaw(..., from0 = TRUE)}). <>= ## a simplified model which includes the autoregression in the power law measlesFit_powerlaw2 <- update(measlesFit_powerlaw, ar = list(f = ~ -1), ne = list(weights = W_powerlaw(maxlag = 5, from0 = TRUE))) AIC(measlesFit_powerlaw, measlesFit_powerlaw2) ## simpler is really worse; probably needs random effects @ All of our models for the measles surveillance data incorporated an epidemic effect of the counts from the local district and its neighbors. Without further notice, we thereby assumed a lag equal to the observation interval of one week. However, the generation time of measles is around 10 days, which is why \citet{herzog-etal-2010} aggregated their weekly measles surveillance data into biweekly intervals. We can perform a sensitivity analysis by running the whole code of the current section based on \code{aggregate(measlesWeserEms, nfreq = 26)}. Doing so, the parameter estimates of the various models retain their order of magnitude and conclusions remain the same. However, with the number of time points halved, the complex random effects model would not always be identifiable when calculating one-week-ahead predictions during the test period. %% basic model: same epidemic parameters and dominant eigenvalue (0.78), same overdispersion (1.94) %% vaccination: the exponent $\beta_s$ for the susceptible proportion in the %% extended model \code{"Scovar|unchanged"} is closer to 1 (1.24), which is why %% \code{"Soffset|unchanged"} is selected by AIC. %% random effects: less variance, but similar pattern We have shown several options to account for the spatio-temporal dynamics of infectious disease spread. However, for directly transmitted human diseases, the social phenomenon of ``like seeks like'' results in contact patterns between subgroups of a population, which extend the pure distance decay of interaction. Especially for school children, social contacts are highly age-dependent. A useful epidemic model should therefore be additionally stratified by age group and take the inherent contact structure into account. How this extension can be incorporated in the spatio-temporal endemic-epidemic modeling framework \class{hhh4} has recently been investigated by \citet{meyer.held2015}. The associated \CRANpkg{hhh4contacts} package \citep{R:hhh4contacts} contains a demo script to exemplify this modeling approach with surveillance data on norovirus gastroenteritis and an age-structured contact matrix. \section{Simulation} \label{sec:hhh4:simulation} Simulation from fitted \class{hhh4} models is enabled by an associated \code{simulate}-method. Compared to the point process models described in \code{vignette("twinstim")} and \code{vignette("twinSIR")}, simulation is less complex since it essentially consists of sequential calls of \code{rnbinom} (or \code{rpois}). At each time point $t$, the mean $\mu_{it}$ is determined by plugging in the parameter estimates and the counts $Y_{i,t-1}$ simulated at the previous time point. In addition to a model fit, we thus need to specify an initial vector of counts \code{y.start}. As an example, we simulate 100 realizations of the evolution of measles during the year 2002 based on the fitted random effects model and the counts of the last week of the year 2001 in the 17 districts: <>= (y.start <- observed(measlesWeserEms)[52, ]) measlesSim <- simulate(measlesFit_ri, nsim = 100, seed = 1, subset = 53:104, y.start = y.start) @ The simulated counts are returned as a $52\times 17\times 100$ array instead of a list of 100 \class{sts} objects. We can, e.g., look at the final size distribution of the simulations: <<>>= summary(colSums(measlesSim, dims = 2)) @ A few large outbreaks have been simulated, but the mean size is below the observed number of \code{sum(observed(measlesWeserEms)[53:104, ])} $= \Sexpr{sum(observed(measlesWeserEms)[53:104,])}$ cases in the year 2002. Using the \code{plot}-method associated with such \code{hhh4} simulations, Figure~\ref{fig:measlesSim_plot_time} shows the weekly number of observed cases compared to the long-term forecast via a fan chart: <>= plot(measlesSim, "fan", means.args = list(), key.args = list()) @ We refer to \code{help("simulate.hhh4")} and \code{help("plot.hhh4sims")} for further examples. \pagebreak[2] %-------------- % BIBLIOGRAPHY %-------------- <>= ## create automatic references for R packages knitr::write_bib( # produces UTF-8 c("MASS", "Matrix", "colorspace", "gridExtra", "lattice", "sp", "fanplot", "hhh4contacts"), file = "hhh4_spacetime-R.bib", tweak = FALSE, prefix = "R:") @ \bibliography{references,hhh4_spacetime-R} <>= save(aics_vacc, measlesPreds2, file = "hhh4_spacetime-cache.RData") @ \end{document} surveillance/inst/doc/glrnb.Rnw0000644000176200001440000005454114405577243016310 0ustar liggesusers%\VignetteIndexEntry{algo.glrnb: Count data regression charts using the generalized likelihood ratio statistic} \documentclass[a4paper,11pt]{article} \usepackage[T1]{fontenc} \usepackage{graphicx} \usepackage{natbib} \bibliographystyle{apalike} \usepackage{lmodern} \usepackage{amsmath} \usepackage{amsfonts,amssymb} \setlength{\parindent}{0pt} %%% Meta data \usepackage{hyperref} \hypersetup{ pdfauthor = {Valentin Wimmer and Michael H\"ohle}, pdftitle = {'algo.glrnb': Count data regression charts using the generalized likelihood ratio statistic}, pdfsubject = {R package 'surveillance'} } \title{\texttt{algo.glrnb}: Count data regression charts using the generalized likelihood ratio statistic} \author{ Valentin Wimmer$^{(1,2)}$\thanks{Author of correspondence: \texttt{Valentin.Wimmer@gmx.de}}\; and Michael H\"{o}hle$^{(1,2)}$ \\ (1) Department of Statistics, University of Munich, Germany\\ (2) MC-Health -- Munich Center of Health Sciences } \date{6 June 2008} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sweave %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \usepackage{Sweave} \SweaveOpts{prefix.string=plots/glrnb} \setkeys{Gin}{width=1\textwidth} \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl,fontsize=\footnotesize} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\footnotesize} \DefineVerbatimEnvironment{Scode}{Verbatim}{fontshape=sl,fontsize=\footnotesize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initial R code %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <>= library("surveillance") options(SweaveHooks=list(fig=function() par(mar=c(4,4,2,0)+.5))) options(width=70) set.seed(247) ## create directory for plots dir.create("plots", showWarnings=FALSE) @ \begin{document} \maketitle \begin{abstract} \noindent The aim of this document is to show the use of the function \verb+algo.glrnb+ for a type of count data regression chart, the generalized likelihood ratio (GLR) statistic. The function is part of the \textsf{R} package \textbf{surveillance} \citep{hoehle-2007}, which provides outbreak detection algorithms for surveillance data. For an introduction to these monitoring features of the package, see \texttt{vignette("surveillance")}. There one can find information about the data structure of the \verb+disProg+ and \verb+survRes+ objects. Furthermore tools for outbreak detection, such as a Bayesian approach, procedures described by \citet{stroup89}, \citet{farrington96} and the methods used at the Robert Koch Institut, Germany, are explained. The function \verb+algo.glrnb+ is the implementation of the control charts for poisson and negative binomial distributions for monitoring time series of counts described in \citet{hoehle.paul2008}. This document gives an overview of the different features of the function and illustrations of its use are given for simulated and real surveillance data. \\ \noindent{\bf Keywords:} change-point detection, generalized regression charts, poisson and negative binomial distribution, increase and decrease \end{abstract} \section{Introduction}\label{sec:intro} For the monitoring of infectious diseases it is necessary to monitor time series of routinely collected surveillance data. Methods of the statistic process control (SPC) can be used for this purpose. Here it is important, that the methods can handle the special features of surveillance data, e.g.\ seasonality of the disease or the count data nature of the collected data. It is also important, that not only the number of counts of one time point (week, month) are regarded but instead the cases of previous time points are considered, because beside abrupt changes also small constant changes should be detected. CUSUM-methods (function \verb+algo.cusum+), LR-charts or GLR-methods as described by \citet{lai95} and \citet{hoehle.paul2008} can afford this. With the function \verb+algo.glrnb+ these methods can easily applied to surveillance data. A typical assumption for time series of counts is, that the observed counts at each time point follow a Poisson distribution. If overdispersion is likely, the negative binomial distribution provides a better alternative. Both distributions are provided by \verb+algo.glrnb+. In the GLR-scheme, an outbreak can be defined as a change in the intercept. The function \verb+algo.glrnb+ allows the user to specify whether increases or decreases in mean should be regarded. For each time point a GLR-statistic is computed, if this statistic exceeds a threshold value, an alarm is given. The function also provides the possibility to return the number of cases that would have been necessary to produce an alarm. This vignette is organized as follows: First, in Section \ref{sec:prel} the data structure is explained, in Section \ref{sec:glr} a short introduction in the theory of the GLR-charts is given and Section \ref{sec:control} shows the different \verb+control+-settings. % In Section \ref{sec:extensions} some possible extensions are presented. \section{Preliminaries}\label{sec:prel} Consider the situation, where a time series of counts is collected for surveillance purpose. In each interval, usually one week, the number of cases of the interesting disease in an area (country, district) is counted. The resulting time series is denoted by $\{y_t\>;t=1,\ldots,n\}$. Usually the data are collected on line, so that the time point $n$ is the actual time point. Our aim is to decide with the aid of a statistic for each time point $n$ if there is an outbreak at this or any former time point. If an outbreak is detected, the algorithm gives an alarm. Observed time series of counts are saved in a \verb+disProg+ object, a list containing the time series of counts, the number of weeks and a state chain. The state is 1, if e.g. the Robert Koch-Institut declares the week to be part of an outbreak and 0 otherwise. By using the state chain the quality of the surveillance algorithm can be tested. %The 'surveillance'-package provides standard plot routines for the surveillance objects. As an first example the number of cases of salmonella hadar in the years 2001-2006 is examined. \\ \textit{Example 1:} <>= data(shadar) plot(shadar,main="Number of salmonella hadar cases in Germany 2001-2006") @ The package provides the possibility to simulate surveillance data with the functions \verb+sim.pointSource+, \verb+sim.seasonalNoise+ and \verb+sim.HHH+. See \citet{hoehle-2007} and \texttt{vignette("surveillance")} for further information. \\ \textit{Example 2:} <>= # Simulate data simData <- sim.pointSource(length=300,K=0.5,r=0.6,p=0.95) @ <>= plot(simData) @ \section{LR and GLR-charts}\label{sec:glr} Our aim is to detect a significant change in the number of cases. This is done as follows. One assumes, that there is a number of cases that is usual, the in control mean $\mu_0$. The in-control mean is defined in \citet{hoehle.paul2008} to be \begin{equation} \label{mu0} \operatorname{log}(\mu_{0,t})=\beta_0 + \beta_1t + \sum_{s=1}^S(\beta_{2s} \cos(\omega s t) + \beta_{2s+1}\sin(\omega s t)). \end{equation} If an outbreak occurs, the number of cases increases and the situation is out-of control and the algorithm should produce an alarm. The change is assumed to be an additive increase on log scale, \begin{equation} \label{interceptchange} \operatorname{log}(\mu_1)= \operatorname{log}(\mu_0) + \kappa . \end{equation} If $\mu_0$ is unknown one could use a part of the data to estimate it with a generalized linear model (GLM). If $\kappa$ is known, LR-charts can be used, if not, $\kappa$ has to be estimated, which is the GLR-scheme setting. For each time point, the likelihood ratio statistic is computed as follows \begin{equation} \label{cusum} GLR(n)=\max_{1 \leq k \leq n} \sup_{\theta \in \Theta} \left[ \sum_{t=k}^n \log \left\{ \frac{f_{\theta}(y_t)}{f_{\theta_0}(y_t)} \right\} \right] . \end{equation} Now $N=\inf \{n \geq 1 : GLR(n) \geq c_{\gamma} \}$ is the first time point where the GLR-statistic is above a threshold $c_{\gamma}$. For this time point $N$ an alarm is given. If the parameter $\kappa$ and hence $\theta=\kappa$ is known, the maximisation over $\theta$ can be omitted. With the function \verb+algo.glrnb+ one can compute the the GLR-statistic for every time point. If the actual value extends the chosen threshold $c_{\gamma}$, an alarm is given. After every alarm, the algorithm gets reset and the surveillance starts again. The result of a call of \verb+algo.glrnb+ is an object of class \verb+survRes+. This is basically a list of several arguments. The most important one is the \verb+upperbound+ statistic, which is a vector of length $n$ containing the likelihood-ratio-statistic for every time point under surveillance. The \verb+alarm+-vector contains a boolean for every time point whether there was an alarm or not. \\ At this point in the vignette we move more into the applied direction and refer the user to \citet{hoehle.paul2008} for further theoretical details about the GLR procedure. The next example demonstrates the surveillance with the \verb+algo.glrnb+ in a learning by doing type of way. The example should demonstrate primarily the result of the surveillance. More details to the control-options follow in the next section. All control values are set here on default and the first two years are used to find a model for the in-control mean and so surveillance is starting in week 105. A plot of the results can be obtained as follows <>= survObj <- algo.glrnb(shadar,control=list(range=105:295,alpha=0)) plot(survObj, col=c(8,NA,4)) @ The default value for $c_{\gamma}$ is 5. The upperbound statistic is above this value several times in the third quarter of 2006 (time points marked by small triangles in the plot). In the next section follow a description of the control-setting for tuning the behavior of the algorithm, e.g.\ one can search not only for increases in mean as shown in the example but also for decreases. \section{Control-settings}\label{sec:control} In this section, the purpose and use of the control settings of the \verb+algo.glrnb+ function are shown and illustrated by the examples from Section \ref{sec:prel}. The control-setting is a list of the following arguments. <>= control=list(range=range,c.ARL=5, mu0=NULL, alpha=0, Mtilde=1, M=-1, change="intercept",theta=NULL, dir=c("inc","dec"),ret=c("cases","value")) @ \begin{itemize} \item \verb+range+ \\ The \verb+range+ is a vector of consecutive indices for the week numbers in the \verb+disProg+ object for which surveillance should be done. If a model for the in-control parameter $\mu_0$ is known (\verb+mu0+ is not \verb+NULL+), the surveillance can start at time point one. Otherwise it is necessary to estimate the values for \verb+mu0+ with a GLM. Thus, the range should not start at the first time point but instead use the first weeks/months as control-range. (Note: It is important to use enough data for estimating $\mu_0$, but one should be careful that these data are in control) With the following call one uses the first 2 years (104 weeks) for estimating $\mu_0$ and the the years 2003 to 2006 will be on line monitored. <>= control=list(range=105:length(shadar$observed)) algo.glrnb(disProgObj=shadar,control=control) @ \item \verb+alpha+ \\ This is the (known) dispersion parameter $\alpha$ of the negative binomial distribution. If \verb+alpha+=0, modeling corresponds to the Poisson distribution. In this case, the call of \verb+algo.glrnb+ is similar to a call of \verb+algo.glrpois+. If $\alpha$ is known, the value can be specified in the \verb+control+-settings. <>= control=list(range=105:295,alpha=3) algo.glrnb(disProgObj=shadar,control=control) @ If overdispersion is present in the data, but the dispersion parameter $\alpha$ is unknown, an estimation $\hat{\alpha}$ is calculated as part of the in-control model estimation. Use \verb+alpha=NULL+ to get this estimation. The estimated value $\hat{\alpha}$ is saved in the \verb+survRes+-Object in the \verb+control+-list. Use <>= control=list(range=105:295,alpha=NULL) surv <- algo.glrnb(shadar,control=control) surv$control$alpha @ to get the estimated dispersion parameter for the salmonella data. \item \verb+mu0+ \\ This vector contains the values for $\mu_0$ for each time point in the \verb+range+. If it has the value \verb+NULL+ the observed values with indices 1 to \verb+range+-1 are used to fit a GLM. If there is no knowledge about the in-control parameter, one can use the values before the range to find an seasonal model as in equation \ref{mu0}. \verb+mu0+ is at the moment a list of three argument: \verb+S+ is the number of harmonics to include in the model, \verb+trend+ is Boolean whether a linear trend $\beta_1t$ should be considered. The default is to use the same model of $\mu_0$ for the whole surveillance. An alternative is, to fit a new model after every detected outbreak. If refitting should be done, choose \verb+refit=TRUE+ in the \verb+mu0+ list. In this case, the observed value from time point 1 to the time point of the last alarm are used for estimating a GLM. Then we get a new model after every alarm. In the following example a model with \verb+S+=2 harmonics and no linear trend is fitted for the Salmonella data. The observed cases from the first two years are used for fitting the GLM. <>= control=list(range=105:295,mu0=list(S=2,trend=FALSE)) algo.glrnb(disProgObj=shadar,control=control) @ <>= control=list(range=105:295,mu0=list(S=2,trend=F,refit=T)) surv <- algo.glrnb(disProgObj=shadar,control=control) @ The predicted values for the in-control mean in the range are shown as a dashed line in the following plot. <>= plot(shadar) with(surv$control,lines(mu0~range,lty=2,lwd=4,col=4)) @ Information about the used model is saved in the \verb+survRes+-object, too. <>= surv$control$mu0Model @ The $\mu_0$ model is fitted by a call of the function \verb+estimateGLRNbHook+, %% Instead of using the standard seasonal negative binomial model from equation \ref{mu0}, one can change the \texttt{R}-code of the function \verb+estimateGLRNbHook+ to get any desired model. which is defined as follows: <>= estimateGLRNbHook @ \iffalse To include own models in the \verb+estimateGLRNbHook+ function, the code of the function has to be changed. In the following code chunk \verb+estimateGLRNbHook+ is modified so that weights are included in the model (here always Poisson, ignoring \verb+alpha+). \begin{small} \begin{verbatim} estimateGLRNbHook <- function() { control <- parent.frame()$control p <- parent.frame()$disProgObj$freq range <- parent.frame()$range train <- 1:(range[1]-1) test <- range #Weights of training data - sliding window also possible weights <- exp(-0.3 * ((max(train)-train)) %/% 12) data <- data.frame(y=parent.frame()$disProgObj$observed[train],t=train) formula <- "y ~ 1 " if (control$mu0Model$trend) { formula <- paste(formula," + t",sep="") } for (s in 1:control$mu0Model$S) { formula <- paste(formula,"+cos(2*",s,"*pi/p*t)+ sin(2*",s,"*pi/p*t)",sep="") } m <- eval(substitute(glm(form,family=poisson(),data=data,weights=weights), list(form=as.formula(formula)))) return(list(mod=m,pred=as.numeric(predict(m,newdata=data.frame(t=test), type="response")))) } \end{verbatim} \end{small} \fi The fitted model from the call of \verb+estimateGLRNbHook+ is saved. The result of a call of \verb+glm.nb+ is in the standard setting an object of class \verb+negbin+ inheriting from class \verb+glm+. So methods as \verb+summary+, \verb+plot+ of \verb+predict+ can be used on this object. If refitting is done, the list of the used models is saved. Use <>= coef(surv$control$mu0Model$fitted[[1]]) @ to get the estimated values of the first (and in case of \verb+refit=FALSE+ only) model for the parameter vector $\beta$ given in (\ref{mu0}). \item \verb+c.ARL+ \\ This is just the threshold $c_{\gamma}$ for the GLR-test (see equation \ref{cusum}). The smaller the value is chosen, the more likely it is to detect an outbreak but on the other hand false alarms can be produced. <>= control=list(range=105:295,alpha=0) surv <- algo.glrnb(disProgObj=shadar,control=control) table(surv$alarm) @ For a choice of $c_{\gamma}$ we get \Sexpr{table(surv$alarm)[2]} alarms. In the following table the results for different choices of the threshold are shown. <>= num <- rep(NA) for (i in 1:6){ num[i] <- table(algo.glrnb(disProgObj=shadar,control=c(control,c.ARL=i))$alarm)[2] } @ \begin{center} \begin{tabular}{l|cccccc} \verb+c.ARL+ & 1 & 2 & 3 & 4 & 5 & 6 \\ \hline no. of alarms & \Sexpr{num[1]} & \Sexpr{num[2]} & \Sexpr{num[3]} & \Sexpr{num[4]} & \Sexpr{num[5]} & \Sexpr{num[6]} \end{tabular} \end{center} \item \verb+change+ \\ There are two possibilitys to define an outbreak. The intercept-change is described in Section \ref{sec:glr} and equation \ref{interceptchange}. Use \verb+change="intercept"+ to choose this possibility. The other alternative is the epidemic chart, where an auto-regressive model is used. See \citet{hoehle.paul2008} for details. The plot below reproduces Figure 9 from that paper, using \verb+change="epi"+ in the control settings. Note that in the epidemic chart not every feature of \verb+algo.glrnb+ is available. <>= control=list(range=209:295,c.ARL=5.1,mu0=list(S=1,trend=TRUE), alpha=NULL,M=52,change="epi") surv <- algo.glrnb(shadar, control) plot(surv,col=c(NA,8,4),lty=c(1,0,1),lwd=c(1,1,3),legend.opts=NULL) lines(surv$control$mu0,lty=2,lwd=2,col=2) abline(h=surv$control$c.ARL,lty=2,col=3) legend(1,20,expression(GLR(n),mu[0],c[gamma]), col=c(4,2,3),lty=c(1,2,2),lwd=c(3,2,1)) @ \item \verb+theta+ \\ If the change in intercept in the intercept-charts is known in advance, this value can be passed to the function (see Section \ref{sec:glr}). These LR-charts are faster but can lead to inferior results if a wrong value of \verb+theta+ is used compared to the actual out-of-control value (\citet{hoehle.paul2008}). If an increase of 50 percent in cases is common when there is an outbreak which corresponds to a $\kappa$ of $\log(1.5)=0.405$ in equation \ref{interceptchange} use <>= control=list(range=105:295,theta=0.4) algo.glrnb(disProgObj=shadar,control=control) @ If there is no knowledge about this value (which is the usual situation), it is not necessary to specify \verb+theta+. In the GLR-charts, the value for $\kappa$ is calculated by a maximation of the likelihood. Use the call <>= control=list(range=105:295,theta=NULL) algo.glrnb(disProgObj=shadar,control=control) @ in this situation. \item \verb+ret+ \\ The \verb+upperbound+-statistic of a \verb+survRes+-object is usually filled with the LR- or GLR-statistic of equation \ref{cusum}. A small value means, that the in-control-situation is likely, a big value is a hint for an outbreak. If you choose \verb+ret="value"+, the upperbound slot is filled with the GLR-statistic. These values are plotted then, too. The alternative return value is \verb+"cases"+. In this case, the number of cases at time point $n$ that would have been necessary to produce an alarm are computed. The advantage of this option is the easy interpretation. If the actual number of cases is more extreme than the computed one, an alarm is given. With the following call, this is done for the salmonella data. <>= control=list(range=105:295,ret="cases",alpha=0) surv2 <- algo.glrnb(disProgObj=shadar,control=control) @ <>= plot(surv2, col=c(8,NA,4)) @ Of course, the alarm time points are the same as with \verb+ret="cases"+. \item \verb+dir+ \\ In the surveillance of infectious diseases it is regular to detect an increase in the number of infected persons. This is also the standard setting for \verb+algo.glrnb+. But in other applications it could be of interest to detect a decrease of counts. For this purpose, the \verb+dir+-option is available. If \verb+dir+ is set to \verb+"inc"+, only increases in regard to the in-control mean are taken into account in the likelihood-ratio-statistic. With \verb+dir="dec"+, only decreases are considered. As an example we take the salmonella data again, but know we look at the number of cases that would have been necessary if a decrease should be detected. <>= control=list(range=105:295,ret="cases",dir="dec",alpha=0) surv3 <- algo.glrnb(disProgObj=shadar,control=control) @ <>= plot(surv3, col=c(8,NA,4)) @ The observed number of cases is below the computed threshold several times in 2005 to 2006 and alarms are given. \item \verb+Mtilde+ and \verb+M+ \\ These parameters are necessary for the so called ''window-limited'' GLR scheme. Here the maximation is not performed for all $1 \leq k \leq n$ but instead only for a window $k \in \{n-M,...,n-\tilde{M}+1 \}$ of values. Note that $1 \leq \tilde{M} \leq M$, where the minimum delay $\tilde{M}$ is the minimal required sample size to obtain a sufficient estimate of $\theta_1=(\mu_0,\kappa)$ ~\citep{hoehle.paul2008}. The advantage of using a window of values instead of all values is the faster computation, but in the setup with intercept-charts and $\theta_1=\kappa$ this doesn't bother much and $\tilde{M}=1$ is sufficient. \end{itemize} \section{Discussion} As seen, the function \verb+algo.glrnb+ allows many possibilities for doing surveillance for a time series of counts. In order to achieve fast computations, the function is implemented in C. An important issue in surveillance is the quality of the used algorithms. This can be measured by the sensitivity and the specificity of the result. The aim of our future work is to provide the possibility for computing the quality and in the next step to include a ROC-approach in order to have a more formal framework for the choice of threshold $c_{\gamma}$. %\include{extensions} %\renewcommand{\bibsection}{\section{REFERENCES}} \bibliography{references} \end{document} surveillance/inst/doc/twinstim.pdf0000644000176200001440000166554514615167606017103 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 5559 /Filter /FlateDecode /N 91 /First 779 >> stream x\YsF~oԔ\W/qIcg* Jp(Rwʲ}kLS8}4dXD&"3$K"MT6K4 Nd#LF@6z4G΀D\PJ*@#[zP02e)P dN/& sJ3Ǥי¬PSM g¨Evbz'a24ۜc91$:CbRe5@i0$-Bc=q>#Ƅf,2á5xS^d%ONf=+ _qɛWyŽ~8O 62iOsBigדe/.qyo\˜֗.͸6n%yjW=7}hbpΓ t\pv/Fowb}\&e>珋dU"W4u9) IfZO4Vsy|^¬gviSSEV]mxy>m7@5}UlNuLEh[^w{/^ix¡7xc%/d-*oq|CG #ѧO%mW l[cl{@\.Esrr1Id^/8^'?M@6M2+߄﫹栂x#gM^:>^lkDH7,28ԅ)_p9>)ʇ$yGe`ͩ|Xea.ˮ-ˮ/y)_Y𤮰8^JaLNу'APLfRxa^x*3yc<4@7=].Ƨ뇏1o;[0jā#KޱɵWzٻH :|3bM6}gI%-@RTy Gcg:RwMvGso35 ڑ:NG7T C2qH&"db&B1PLb#[ Kb#!$J;BF<<^{?_^L9|ђB57 \B4ۀd;֡g_Thn+& "{GcWaȻ yc}ssC>w8)Dr4 A# _tyDd:eV]t њZz7C4՘XƓšyq~QLj`G{{^vF쌍x1[لlʦ_#H;g E>g%|Ub+ȡXLؚؒ/ylf'Ǡ3gU0 T{c ?,GKKF^y|ϡAj R ;]o)ZoYKD{WbN RmjůPs`UneT & _LattT3Lrr6c,ēOy.faI%)'=Œj%oɇWei.f-[JafI;u4 })վ7U09/>n"0Eo=ʈE˒y5NE!B7 Q !U*napt(tL$)uI|u HuP_D}-ud|̞C3{+ {L+{~c{; 6vgl9(X'4ӂdQg;ڬ청:ŮapiYsа:mY<$Fǫ[ͮԽצ'_.){Q.uY捺ܯkJ1TSޡGU\h&⠞lEQ~ql6{}l!pՍIдԁxNiߖ+**:QXt%IPB}@'O{x(3IػrY^?|VcXazmdmsC#íX(:{4}&?FN Z%UpS %>BFlB.mA+zm JS!|iG)\U)ki5_bܶ,F8`1{FmBoR;Z=B5GoREi/S߽g]y'm1Wr;rc|U*E 9j]Tvot?^_ilX붮Wt>̭zFcdW]UER\pmG|>ΛWV/,_j4cy1FIf.fK1!L`Z. !1]wtU_ M9T`O??z~|}LW%Ce(R 4(MD혫;M tw;$Nŋ-N-Cn PZQ[-Mluל۸rOYdՠϡ:30qjEi]r 7=έcPE|?.E&ueBl[+:ݕv? ddp7Te39_G顓)$$|Μh5'џSJ5V}mwk2+n LXq3")Z\j;]}tWfgpOGQNˤÜҺ&Uq/G?BǻR[_-CYU N~>m[0vžl!m|캜CDYQr+ιp!R~Acڴã^ Uc\:TaZP2>c;=Zf 0}g,_7 >g8Y),dLzm(N6Ӱha* 9X+*iX,'\.XOʊx%T: D7UE'ToDk> v&S/ʆL-/vƠWp`]>?EʹhB\\ U]N@Vښ/xitM`ҵKtU%^=~y匝"YTHצ!uoն?Zi9LT>3r/-THRY!o43Z]w|V_%S%r+d,ByGeoo$ϪwyJc?V eh W64.o}}n=on(7y(v975Გeo.Kyeo>xyt`r0bOާt,[r .&lye@ m%%齺g#x0 NAr(}yZwXZ8:d6YuXA笺WnvZ IϗfN[m)Zݭ/d&۟bB!2=eGo݁#z7oO;=PwP%7(upкS;7Nk&BL'ޡx\"[s]ORf7\H*/)fL J^!R .)yKV#RJ"!OitRޤ:FmQyfeҺJBJsR:) Nv/"C0:hEjL"_EJ&Zb,z`zB{@yv\Үv%V:u' TJ}6&Q)%AD`ۄҘ5V%zJNckPYJU'dK"F25N(AUZJ9Z*pP`uCbMi[w:;̛F3]JNT2f.P8]lAiҌZ"B!}fpI`<%8)8ݞzqEӌl2KĬt `^lP@ :%J)̄0!>H ܭk@sHmO_$M)KBA=bڤ&׀bsi38{G!3{_O BHz}c'Gғ{WMsvjtbxscHh2cRAoDb$9zU7՝?O#PI)8wIAk/*?B7i_8BV/#(5)+;]9tp_.U~,dpvB t5ETU)9͡l;s,%R J?9z9"]-{|W*wTeR>{∂|v#eW!P{oVݮ;mxl"v6'~]nS'J:ޏb;M佹 ItrA.,ܲ2&"#SGfg hr%2T]e" h17xqIWϊ+jzuquBP\a z8S\]p1*j - 3q[cR *miLfކW>,VS T&9@vzsN?@qx\XO@-)㦎aUiտ2 !\R՛Y4|WX0̈́wѩ0^~!"RNli6Ǹ *>Υ ᩠H7 S Z.D YJܗ_SD`jo[4$Ld@p@3by؜O9A Kg 4U $kErM].F01ӌV5R7+񳦢 Dو9?4RUÔTWU@wh50.u^JF(*m^ ٍ&ZvZN+J&{XL6B_'5 b%]Maަc0]w n5 I,Mb/mȦ_X&rGWX1GC!0*l[KTy1IO^}Kĝq]#_.7E5[h%ـG:*5m!Ig_f7#idV]L8ʄ;:m i!!I|SCŤlZ;HBvG@})@J5Ga>ꌒ^];oW'%r$ʊukFv WDoٮ\0SFtKvS`@endstream endobj 93 0 obj << /Subtype /XML /Type /Metadata /Length 1700 >> stream GPL Ghostscript 9.55.0 spatio-temporal point pattern, endemic-epidemic modeling, infectious disease epidemiology, self-exciting point process, spatial interaction function, branching process with immigration 2024-05-03T16:07:01+02:00 2024-05-03T16:07:01+02:00 LaTeX with hyperref twinstim: An endemic-epidemic modeling framework for spatio-temporal point patternsSebastian Meyer, Leonhard Held, Michael Höhle endstream endobj 94 0 obj << /Type /ObjStm /Length 4093 /Filter /FlateDecode /N 91 /First 856 >> stream x\Ys7~_1I4ltX^M$<r5 9CJC6X9h4 $Dʐh-+LB"k&:x.x$+L@2!2e闩Nړ޸'˿X#!DQU @]|K8Ll2űc5R=0׿g˫G'석׬>]v2λ+v..]oWوg6`C6bcMiƣ]kb_MfvMsxMńM436d=f7o}c&Fڵ'{9Ÿc場~_EɭN|;nOfA?d(N)zJ<9e7q\ aE8;=+:ʆ}W hڟ?ʦleS)2Zv?'2rcɺhK@\~гWpATȟM纶[> ڞV~Xx_u3hmI` U^z Tkk+@[+ڭͻg'X T0KTԉeYd5pHJb1X]R:%% ^BaSU~D>64'%,Daב)15~PhB'y~`a7&D 1c`&lO><<-:4m] ְ@v% I_ץV$mAL(o SHx2EIXVRQxHU> m1LI`KUuSgH5-90{eLUtҶT{IiHHCZӐTpv7Ҋ3> \8p[oj+jQUl (LZ\,9/IfX_ԗ%yC]YƚZ!-Bj]LWKi ̍i7i D 7 .l9=lS47Gf?;H;{ד=O.1 {ٿǃoAбE! bVIN}o`;sY ~%SiuL)'䜩QnӍ:XCE\7 h U &.,mLp NxU;IVU<).Rx[nXXJ]hn" uzs$]kâD݄K_JغX9]$"qNsHE./ /E")LALAϬH,;SLj%m9hbu06S>xZ߷a& RNwn,PZI9ph~P 8 *"s-S/fO)xy^ΏI`h)A6i;ew6uge6nD)(kPChUX DVҾ]2UjG*ᘿq4SM,(HlR-,lɷG6{3J4^(dHiNCؗTciz^.f 8vlmR 1ξF\BXH D8-L)FbH5,mSb]_*75JK*<ߐ@Tk(*uM(AkuS9\Xз2j1׷5VDj-5 \Tڊԡ+4)wMlY*R;b?v<,09KueI 7_oZB%[YmoOd[eo$s+,tMjL 9# M @CHX{s ~EJ:"&"xsc WHEEch.^ΙдayJw3 !@Qw߁ |f&hc+e K&v]PŠ*ҒdnBi0qq3im{L<)Ù(rM" m.г(t &;Q-UL-Ք Wendstream endobj 186 0 obj << /Type /ObjStm /Length 3464 /Filter /FlateDecode /N 91 /First 846 >> stream x[ks6 4ݴi"Ӊ Q$eӑd{ dL0Sю(ßGϊI$n4Je4Lqgn.KoWMdXŔL9#q nifZ*! LN{K_yf3 `W̸`p#HŬA35:Y::N[Y僧g6 j9d R9~fCJPc˼^[3oiw^{!`>]+5 ڣCmXk˂,D1(H4JKG5I!K-b1 1f a5T(H BEj% C2ЭppU A ђ,H!)HJYYDj+@IiEfxBo` 1`!@ FWx_bFhGhAH戈zvC'9Έ:)a mA0v]9x<Б+b65[C;4'/_~ɪgz~gf5ao QbZ U?7RU0<4\ :qu3!}crPs|{{z\3jUs}wI׹:_Ʒͻ^ž=ؙ{384׫?nP N9d-ApDp, vP{)FP[݈#!Y"R%]L|yg2K_$1@ugot.~pqHK4)Tyde~c;>]^u9\#',ȟWMbizSVSkMr&,_l5"ZVu[o9y6o1.E·# h6i}YrҬK_?DnХkQBˎ2 m;Y,5&GaF0\C6JᛮoH0 rePͧ_/D?F02`$>լ^3BD Kb9;Ig! 퇫zWwx'1 3$vJw5ԣ|5jdK#ی8223$%}X帇.BM &L ]]ioQ1 3Fo_xJ%5fMGaeL/泓;Jf54B KxqS_xZk)-OՠQ3F=.wXP QQ sjk+=n5iiB58kBښ 8ࢷ;Z]-H-Dy@ =O?9[ 4Y^NI3H{]Fڶ}+V;7^ll\(Vjf'm}7[}WBg8/`˝]Y%Aj)ٷL@JMi)Bt5n64j"~}ˏ../nD/4D$PڌK{z2nOO΋7p?.{DM<-4{Y$c}eJz;<A]`56$7cRR9mjyMK/? J &lZ#G̀+@ SETxG ?B& SP'i!H[(@.ǁdQ@Bk/6/[~YW?^T6dE*/mJ 0#qNtmd3.mGf'y0ʃJ;:(icfg҆6P]7)A^i70Ei,S2 :G ۲u^8,EATOw;LTZ 0RuhBVI D3˴&i| 򢢎f`G,s[\2\\\\\FxŽX*Q!»U^Y&C$nT^?9b oAQ. v @ˍcJd6<< u8AY=e[S8L m.2%,;0{MCSCԌ٤hӋ~eM?ǮM_UGCGn]Cf.yӝJ%9J4QxuBNK%~}4"(LxLY?J.Gs=gPܬPr[|Pp(!(vh+"s!9ʼnӏS##*شv'P7.Қt=1;qyOIҒHk8GhWO?B䤓Z9-e}a쨆qO`2t٘}^[L`ڬt3j 38eӋ5f􄁗g͟oO7 ngSw yK03͇~":0~lg~oa\u}g%LA&Jdy齦#endstream endobj 278 0 obj << /Filter /FlateDecode /Length 5575 >> stream x\K6r>OA=ԑ嘢7 GXޗ$7£=p{l[߰'H$lM(b jjjY_JUf^镯zu}w{hcj'YYƬW7yQZՍUwXˀ?(W>ܬ:#x.@cވ][T 4W)Pws3T7S _U{q WIYnw4ݩUk]xtTSZ7:~V0߻KJWmP]>w9?~$'m۵A iMTq3$jmp7^&u^ﺛ6o mxm,0ӵ3buhqe_m`@psݬ BUvyy߷]!uUt:=e0r`0.wG܎`Lvw"/movQ3QAښRL}(?S֞/؋,^noF(uQ?GK"X޿3 TzC͙=gHJd!{oi6h*=SƂA//6jХ˃*n:>䧡z8oGXB1=gQLuKxzۖMx AjLϔ>W}'d~ATA{0?^y|dS[_xdwZ+jch= Z OpeldZ0oK+;ij\٥%G?D`Lr0 ioP#4fG?7}`XF[+a-5VIjm PX6۪v8q v8A\F d}4VN0H f9+m!D{ơm]fmR4MNrA-0v1ԕ?OjV*t 'jB zCP=n9 H]ʨȽ&+(I4AI0rCa ]@ \^{@'1J0;m)LzQ j_s.^"uhHaٖlTHZ;cmstӘ$CIY^T|1CMMadˆ;Ƕ|'.U˴ECOWQGG;bwyjJg}Gµ+!?ݢO68 vR^JgJc\=V#F !?YUne4jíHvܪt jF(B uRT¼iǼ!n\;u)`vSj٠kݟ(:nx"iC8o, r+bp60Dh5bsRr>7)3h| cC>g^^!C5abh|$(p]_M5Vs\Pd+46ͦx+li1mwgR :Ė ۚ& a7T kۻm @fmZs.`?Zfpd.|{yҗ|Y=6js5i ?n>˙MuT0ŠUyc[?p\< u}aXz('7n2sKegy}|LhQ2~ϳb~'W5vY>Sh(W cȕەr(ǖC?8&eZL8Zخk/x Ŝ+>p9 X{yfIw^,r0R,$C+!3OWUu[X%cSb :3 ĹA~Hxeq !5dF”mSK-Pon`I /6|kN!nG;x#fY(KڠL,x#hDY{:F"կK,FY jpuq(M xoxOgj逸ur$kU?ȸKl_ˆ@`ygWyqDC^X/Ι LOP5I{'ů IgMNc`ofXͤF<1HS&%$VeE$U!=iϩ>u,R#BE1 ){~S* MmlM~А>O6?CɼRA])TL lBs܃bH]( (юK=v9S'=fP|Ne~XOd<{aC&T[2`= +)RxgY$螔EoHZ+Zs,y, $$&73E8;?A4vw ꧛Sw1L"v2LZMr>@{l d?1IW9nhsb-⹎w„˝>~G 9DߥTtw,6=|\Oghsb2T><z2Tr &ϩ?tNrD(( [[M}K[8EçfO1wJ$`KM];-^Ci>_J:6 A6GMz@l˂^9Sb}D8p{f->h$_1*%'S4AUT&pkʾ)u#k[>mx'Eb$՗RUlԪhz#Mfy˟O0ɦ3pyɾ C_Hj1/CWLKκoФkafrGJKMӔrl$ެ weNg.rzSPrw#iv"('r0*CM0<5o N^+AL xK2l^+JbUVؔ~*w|+I$Ә6%$YK NP}??M%XoZЯgo))KE-K*FKj7)OV?^KyUH]C0X֏B1UCА>E6 䜖h{b6a/ +\@%srmS[+\ ^"⩐Ty- p@xn QxPNtS}w vrbb^n"T,57tB/[!hs4*]:a` <n#91r؜ b!fAb~xP u O;hg+X$fQIRE>7ϡ:VzU<6avQuwg :E 1`ekI=B_{RsiΉ_]h,_^0ci1htoSwd2x&k? _]jLmI R\[fg ̇i`cyL:lmIk ,ClXA8r$i̡/g@pc͍; Th 5 1UyjAT~2e35Pk:Sv~()ϥ%>;ޕ9QWF "Ek=}9t4f1-34ۏ!n%ZMemj%eYq]HX G_Q+-H|3$w_п/$mt4:鴥tak#0^OSA=}]﷏ӿ޵v)_&endstream endobj 279 0 obj << /Filter /FlateDecode /Length 6646 >> stream x]ݏGrw`xX$7̙s=A%9^AVw+]2II+- ޟ.V\t/y]>鉠_/כ| ]/.._< /.qmI#?B[mk7O-3˾o^eor%~Ug|Y__5ez}tPJslK s ޯ_enۢپ{-.0VqB089Qd{O 9e[R}o>lyK*;6y6:o[qxKejCƥ_-ڶ=.6gy/x@xՕ |Ź4 P-e+e556аiJWp8ϩ˚ɡ҉V:sOױuiM+~p]/P.R+ҵ^A@ $Cڳ9z?BViZac׉vz m)֡MQ_5/3źރ^1 Hztc/ 7'Ӽ\]ÛaH׬G8ͳl*Wc ԇ f2u-|4ӎ]fV yZӻeqzYP{烵HYYqC{T9䤤6-9hIT>=1lkZ\Us"קɆ]a:ø拜×$h):. =>zDB[[pFлAJNU6UKI4 ߄5eP5;6_M1a:(m7|@G'ʙZIЛBW67 U>N13gi`DX.ay>PJ5m:)2А,Il`F`0Ξ*]`խhxwQ&ϧx's> Ƣz˟ZeÆcϽgds'™xzW2v\[R:%h1glwU\e:$}/hU|I.OX nseʷB%$ZVkЫqDw ҁ;vn9듏 G\9ǿB ja۷|0~_Č]V|˹uϞIC"{[ksvBmQﺊ- 7˰Ve%˚7sLsJVUj&&YNh\YxB R1A z}1/AÛ07N(sFE,C)0Ö'ab ﺯq)Ԑ/ZX&;A &TLQ1d3n}ƐY3|25+u Z}T=, ~1ma6|H( "s: h|D`j, bS[Iҕio[zdzzQ ZDu`mw4b`k:?C4QFn}Cn;:x w`kuFZzsfl Ws!NdLE~CVz#~9luOt&""_iU2k; G:+c^"=ރK.lj.=1#d g'G\'x]KQ9EMzm`Kv%8QБ ?%؋qVi2Q$/Gh zYߔTf]^2A$3"A4@^4±['nؗg'W W:8@O~tie} 1LsSv^u[ʇ`V6}%Q)8h)MbÊɃCCu#VYi[# "d׏IBu>4 ^ D4鿩<J3 ]^Oh$\P״j9ePK;JJW]uLK o N-: ݋s[0R(twu9'䣆q, +C" \ /wq/^Tg'0 lUWIoIra"@GB3a?O*z4E_B/aBk{Eqx8+\E $#bO~8=!h[FH 1hQYu)"Z`yQ4ȉ&\Mu&ѲF`Enȯ`&/{w%QKCG!0XhLԗ@wA. gNzlwKtսW_7\zd ".jVFE=OMcmOƨx=ŗ#'!O-ALQ(kDۚ:cB)s@R3,zQ":K̷_3BU6 t-:H|NVmCS=d)$ ;DbIQ#7wf 7 ePVw8|Y8yBmq-JOO73`! M;xH҂N8Uˀc *%b+p1<&!!z4A}WVϛN΄v5v)I0' hhu'pC xi`&HR<%\,C>@Ǚ t>XjťS4wa%l$}/\qVu֏gϼ`*҃JXwM=1{ AB줟w` w0Cv#&?Ř(NǞ x+Ĩht'GÀ:0Ts4 kئj~j,Cɋy ",;ר>{,Z,5^?eռvuA^^1g ٤ Յd"< ^x>7 /<)[z^1=Yy!6] 0S[X%0b߫*m(2 J̤*1&~pC4d̋An-͝--~V&1.pee$(+/(= 95KB plƥtQ'poKM%&ZxKVJF{jC eR&b@|6WQޯ.|N~tEU?:h&~7,y&D9YS.p1ܒͤ.7G2}KdȹSDբq*~Mړw7Ǖ9{r_oP0[-d#O<=cc1_ڙ%k`N`jYVɄi,'5-e|YVAx}˼s7Z փХMKӢJeu)>R Ϩ[($Sf $d&24,$@v36AsS ޢn$E5&' 3~4~Sf#dT^)= \-~JDnR׍ykCҹa5RT,3sFMٚg@*D$l0lww @'!It`/A c0à M[r&M(#ɰGöCk7k1K$`Jv3O(GPi.DVFyL& O*HE4㛙dm A>ךj7JmYY۴e4:ChS $6ϋۤ$ H2 5? ]1>}ڷ]>ӓpm=/!Dp,pq:sY<U10Cg9|O&k ;_j V^8 uʒɹ LK_^n|uԕGʧN% DLzo:@~6B-dfazur-2ciHQ1HHo$EhG2F3Ap{=؆]]DmrW5yGuZz`@X(FJ`|ar _Z@LyOϊfoR$o.f{j{ %qv5+3|c ŢjwC.?9M"GlAtլ4rvI*¡ 8!*f}O䩞j! l]bm|Zdl/TU*UƵވWm*/ץ٪ﶁXZPTmò$qo4s -8Q*,7./t>2 E_U4|E 6%% M+02\Jy#:I=dm_w9^`DZ.nU'=[ y$v.!@65#5W]C3+chȯתogCbfiiGLFTvY㜧Nk,OG%?9*$X.w3e-j?ٶnrӈsJ Nf]W %& uNeoYI%SK{_}zp֙s+ ]EGdYB,O66qCt$M%͗%ؔ_|2wM eCpѺx4 ގE #:MVOV(jN|aro <261S~z~@K#xJGfR˃TDzmBcQuV8d)$,6WMƯb.xp"]fj 1);Z&7X`&SM-LMFA:#M&U/)kˢO]X;7oYMJ=hz`qn6Ch}jײH# `t : o`&*'.DBb曣{{I)]%K f {xoCNG͙!Y5qRd<"AIS%<6{; #4O/ ;K P -@u7CUV?4bs:t`(*qg6b%G-ވX=eu^j}O1k n IgUz*PC%_WʾÍۊnLwW4J mW$)S''RaPO/*=❉x{^=J{c~@zы[/|!~6[wZcѡH'/e5aڇ\cq&CW,^ n/z*l/:3\"q- 7.~GrLnӲ̴] EyOHWՌ\8Sa@P1VhA\}gDc SfԀ3sޗn.~\(XP-@_@&L~8۫,n}F4n$;<5QO@ݣܛTStr4*̑3zendstream endobj 280 0 obj << /Filter /FlateDecode /Length 7331 >> stream x]͏$uw+#91&!ՁRflHdCli~)HVX=3Eb绋|yA^=]|v_i/Gą3핹=j('yZ?<ͳ4lnWk$<߳WҶwOpPmwm6=|1^fV+O޸MKQɇm0+ϗ3]N;Lk F.yZ\ko-~{ G^0IUZZ/dWSs_wxZwZٷ YʴBN!W?g r}{r9Ӡ/6Ͱ qg_dq^M7'_x<ٌЌ{iQiG\2q00tۻ./֢ xeU^WW^5*y6] ApuVY/4&|?z|mO|1VkaAf{2=_oO/zU#kR%}9grߜ^{mٴ9==_2$Ȧ5KbE6U5w.G@k-с[:!WǺQ6q k빟|I/ O:[ R:ΰ6 0 N(Czfl&m'-]{0a((+RɠIo{,[7;G|qaV\OAfғmEؾ;0T&O+G\J,uzTB#$[MzW3âX z %kCPA)U#K s5j%#=42iL5z/:Q$͸"6iL9oܼ:o+L`Z pBNƁNj̕2g +IHs`&}Ky}{/ ,t4?/: =CɅ*r#jطABNۉ6Xd!\ cSs|K8CN7۠8*s=7 ECRKt^2J܃$GbT9$d v/_|oGEdƹȩ yW VKVeXbfJ+E]v̶q@yd҈> \tᆵ,d~PwMAjhMB*ShRH-(&7˲_d1,E ,xsCΒ7ƪNkCKQaѺb@XՃ|P?z[uMta%[;p6Ιi>:Y]o~}OZ+ K'|r>Ⱌܔr=dmdO#B|+ua:la9wM]1)[b<|@yfgw#೚/_YEca14]>ek|S l·adA=+\}Rd#H!^j.k?~۳Q[p6(F lSQΒ䡔QUjѓS؃)% aӿۅYg':<уEU,!h^!Ym 6+zAai:|KW-{I |`h5%` ϒ\Kl{鳐'0^ix2duLSQ\ϒu|f{k Pz]h8J| &}1WH5.Eadi 159U"7d nQOjP\c'iVAiP)p>ygo܆E; KFXa>3!FoǐDeG~wA嘆9-J{PfǪ +u~)JxHg$\>e2g 8d+YL σFCGerӾL5סܳ0 WdBp;xO9&=3{aXF r»޲$#0|t<%#=`4,zl \Y~:YڥĐ b' eKa@6iȶ@Z-3 kZ-V_1΅G'|:lZi{Iin`4_xt:y ALExez|:T U2.jl kq?B8iM.ՌF |>LUit53:g$\-ڟZ;Ds( oxu kbZq 9ŒT[4pY̴])Y|SE_x`<2s[\')TaU@!q3wWͧ _UZItit!Cjga!2] E_8a֍zK/̳>WtPDYr#)يYXfrCݓ+uz`Q (!`ta\r3cwEɟPȼtT8{[lZu ˊq#٤҄# .M-6L厅kZrN2[-gx *SmXCn,:}>=Ow0gIa3on9L0P=%3TTVq!e< <y8FJ g1t8[aFSXKhL}1 NkQD?~gzH>1)M,X0˝E*o'2eq%j ̑ C!c/҇1+`Nѐ#b݋>/}PcSr1+}A0M3<6 ׁN+ /PDiIC{%rNb-n72p (䀟n7I25RY?7H^ !̲ |z90,1]oNv׻Z*#^^#QeX' #]H˻"Hf K_UVs"F[d#UUF/ C!i†怹A}e׸֊Q\RxgO7AN /1|;9QQwEGrU {ױO71hH0cA0`赣;e>+8^g}Vzo0ܡ+H!E/װwnV"VgZqp^JYd1knyrSV[ R,e,> pc z=Vz $uN4bmf،;QP*fJ7+C mwwK#80ɔ s|=][:aGT+\EV&/vnVN ٙlj]ܡ xbJ5OXVx&'~Oixw^ a})U;OL|,pPz*(yjRٍiΑ|mx6|Cœ/02B4;";m>Ytocd;58ops}RhpGe#/wK\ 4i¥6pSQv9>lv,lv81͖AH nQ*|:镔lG3P#c.fq^:_ )bSPCR?^"ʤMaPp 7Lu0>Z z p/P/~6s MS}bF5sz`>Ӣ/|CO?*AbMYX?0D]?~XޞĪlkD8*faQhrPD ;Dz 0$,;pwŽ >?;w}YEXbT@>Wt;!.%F1.Ĩ8yLV9s7\F"΄c?Wr'뷁5o^OO̊W"UT edPir 7]yc^u+xcEɟs^q;aD5h0~m 9Ϛ@v}33u_L< s%pv'w=2Lc;#diE Ah(aC#ϤMAvEQ Kϻ{ÚjRώ~8<3ߘkUWow7Ȑms[_ IyjL(l0oJ^Hʶrj~J4Bͺ]6TSYf;O oDuI+ȷ"8EXq6 EErܹ۾azqnQ2bSV`󮮂ٻ?M"-V[AZ{(s9ĭz!lt~E& >摥 wey b%1E:W>9sQjqHY1Jw[:r{'0? nYx Wܣ/+h浝yӹ (RWMwkwz J SUR gHok eX F54!; "  f&|>7N Cdʳ̈́ǁ ͉0,v5*\̷|{TF$ajNؤb_‹t>!GQ6ivYjS!kϲEv1P/My}ʮ.dn1&&r#W3*/yoR+@{Sp4||aLyP"LI3ƶ*1'.i7yN-pU]bl$\:Kfw $}(;?&~r1'(qY~ )~_$܆Z7prq[^vZHZ҃':^2.[g 3xS5 %5SM[ Z*4 f;}Rp*~h( _b$LA5(#ǹVʕh?- v8޵6<>w.\۞8A_Ԝ6Vmq>n ;a#xFTVY@b=g$q=uzZO* Bd/44=@?/Vb&I6)Qn']% !=SAc=I}rweK>Е= C:@"u+"%li^ep g[%ӟE"8#璥9Z/q> stream xX TTW~EQ=R,!*ܢF.iqEEMUfTȮ d)D*4ؓ1$t$$vBxL$gfΜ9q߻~?d1k룵1]4YIO;I@=,T\_Zz\& T716bw~s~~}}j]z jH}B\dZSzF Kz1B=E Fa 67-_^十ASg~0c.[e*Cnm⎀v9[w7Ìg^f&0:f3 b60&flf0[/Y`B?Yɬbf39Z&yqcIFɸ3'hfl$KctWKЩ\Üݜ*()n{>?_1qĥcFf0.ZeQ:FԘc1O>wk 'h|;٥ Nwt6VƁW,2$g ٱY|}'hzjL]/-% =})|5lB3|u&\L%9PWХmXQQ!I=v,ҽF/ NQh `j,):!2v];SH$Bzq?Z.I8$pb;p)#, h,ο*2?S.߹TUU Nʵ 'G mWٯuT6lԲӴϊX~Ё`]]Ficc0M1T_Qv-ձ_o{ji);O!_{N 7ɼ_c ]܆Z \ S8GSIIuu"]Raŧq\㻍7 4UJϚPkXĿ%T<yEI.R FW 2L~HN5ffwMqc2U֌oNJAx)nz\I PC )VE\(>x?%yDu#eCQ#$gN㹙[ꮈ'~ 7{潘m-zN)n3M=YõZPu]LAfIץIJ]&,:TnTd)&JlQ\Ma/:G܊X2k -E'q>ó,p1%Su<-5 LYiM;g kL9QY):`c~ :+B >*O$dVxxOj/ гDn[9 ̈́8[jeU:@9u/ys͉ Ug+I%*ѱkjG#_!r?n5۹*ash.vUP"8B;71rzo4}sTC95ȣWɱ4ŀ/ WYEcn2LG0DF:Џ Laq{@~DtpRP oVZޣ]t_%s7vR |=2NnB]$E6D򓝛S>ITnqaQ!i.>6o DXL4-AY5^MegI) K3kXP$V]ea:G.Arvv9AIlt9t5&eL2l_YR8[㪢 GN!i^R6U*VYZVWHN] iLx`ʙ8N?5=У)&Y|bymKR]c.#_N.Gj&>/tq~v#(u b8Itcx{,ěM Dk˿ OK~n/ .7&Ϝռt%úGSN />ZN9zK/ 6R6J.RHfJv'>b*HM%66s(KT+N ;,HJEz:`w$j鋟Sc$$۹W)'&j2ߣו6U0',~,ԿݜۛS/S}VsW { jn4=?K4e 9;9Cܷz!.4ɌouV&oڂs8O"nD>Ϟ;^JZ:rڪZ+OWi(I, P%rien2?"Exqҋߨٔ/JKO9ֲs#ۚ1Ytg}.˿!d&*k! nLngfo"nxayTJ:N\SVuIؿwWZ\u]ClRfC,9T$ sJ]9ʟiM)V5杰dgRxU"5M B!3n^7m*Z(OQXJmDQ R Pk_q`KWNW^Ik -m7 /?::k[N/bi)Ŝ`2ed|Z/ Ba r[BT&h;bt`\μ6?}#xipWq8"MwOC>Mz3&PHz^Vh a̡CRjohf`}oMpCCpK1ئq;BDjD ̑z(L- u4U^>OQ(M& ׻nۚBJBO-ٖlS -IE O=Yl).K a)L c3B%c*iW'1t'sEԋqFϗ8$R.D8Q$^ٱi=Q:5!._]{-=tw op[O/Td4Fy&TD>:> stream x]A EPV]4ltӅƨthX.0Ƹ$Gs-3wqyL?Dt`t Sڕz@q/]d F{duQZwOjhOeTT 8&ܷں9/7KgJI)#'7C_endstream endobj 283 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 767 >> stream xm]Haǟmk5J}>лjsc_:G[6̞wGr+GE." 2›@.8^ 8s.0BMM9.g_ynp"Mj Ne23=^Q2D$}ɇuHq|04:uuvXbOyF_u36cY^m\^I.'o4Y v32'M)V=z  F#V!09luZBHfCLU%W,&X!$1%i{p ɀԙj$)gW ?b$ :UDI\b]vZ ]GY7ձN`N"3dK-'gH}1eJ5Ff~3̏E&[jJPsB Á"JwQ d@R{'8(i% ?ǂ擟V.)F8%mEm_עV$ Nۦ崘PhrR|nYAPLr_@k崎E(= ҄:j~牌2dzy 04dwCmXBMOKͥ%@ ^q 5";tYr.Q%U_ysܲWPF%▯o^|~>pأtA> stream xzw\ ;cWƕE,{XbI5vEA "#"e}٥DhXcnbIL<|g49sy=H(ND"Zn7P PDIxC /ԭqM ,N Jz(D3p@D6M3ja;{"gWo`m~[m]:v8vJ5N;8wwZ8bEQ+fvN  taآp]D.ݱurOm^+|Vg7~IߞeG-REDj15ZBM-&S˨)Toʊb>KS֔Q)ubmTg uHR)?=OzIHRd( *z.nb`iPXgΖwddYyk]Fv)R~ǬZQһ7r^HEwP_ڤm"MwĀް{#gtAe M`rxȝ!? e>lа_q1\ܗ!*]Z*s#!("bN'Ch@֒* Yz!dm@vIՠu·3\>(SCeݲ?F(K^eB"lPӗWCv1ȑ{EzٰaRg,}k 딸ޤ-Ҁ,-PA%ZB?]l'Gv9V /)ouz巓W}@oƚ=5-6岛zHRdly%/^7K9<d9K|T*e9n]=u0{6$V f-4]!hU&aQRՌv5Ko%G}=qX{cOPgLjdB7nҀCA8C+TlƼ(=ikX}\ui0X=\֨x*. ё,CM) d3oF1d ;NWBVgN^n0|6Ah>?aJ ԯOB1gB.i%ςhcu\<~v* كhH2-Q@LJ(.tF1Yukl' x vEoc; M~Q^ţF2Y= ^B#vl1ysh8wfbR\OWoVyYҙtjd?=Fr唾g4pQ % >ǫVl)u{_ BT8JAx>/%=E&(6jVT8$KG@S dm6m8A:ّ ,#_S;E?F-r#;<)IE+,n.O׃Niu14rj8h91<:Di@k zd bel4ooiE!Vt^19k7 Pt`r,V.RbGˑ#Ԇﮘ r,S[xuJsqBjs&&AL4inU.lMʚ*'Q {è2rN5'{Rb%V; !;59A_T|}O/QAQ0Ĭ+oH[Q"a!AAN rW.fufY/a%wөx]mlh+Hz:C?8Pu -Rt/Hސ}#{ĵ5GVA6tDUM;VMD,+Lx QR!UL bievKhTCp[u.T4@)X d_=1$!EcH'33% Y[̲WWJB,EQbd:c&n=m:Ajgv]u%Jvn趨Jf]oƵϲ R0r1.r*yIQ,i9Pj(C#Ԑ=g*MN PB"}S ~CARVt:7}$JsS^KPKT>9odQFEDiy?:ŏ>E%^Rg[KP"ȸGjn"׫7HD -Aj`*6 [f }KvTTT$ޘ=]3[+5K|gn Z V5Q+.ٮ)·B9.gGٶiKMhjPkk !v8}@ ЬǿnOsm@D'+]L94bP'eFCVD{k.[֬V%Kf;A>C=Z^5]w`.|a>:,-MʈG^:]18@~~fI2撝a!9@5H aIa@T+;f!!7wa Un$a]\jIͤ РەdRU7Ƚ߅HO6 M߲!"CvfoMt݅K,${Ma>n^N<51ȅbH.htF9r mI wdTGxYm6!Qĥ%M.z}ep8pw0{.HaE_Q[Eڑ?+AںX]RbPS`)2jRHUC (l(l؛^ħd^3g94WQqxrh%GBa~(&XMT'q~cŸj~4 MdEGEh&(p3ý<Nۯu*TU( ~!}!t ؿ gZ i0X] JPL#?;Fd!#%Z+ۮ^&Zcs ԋALBҗ dOv:w یc/t6^nuedlgڊtjb.E-n{ȌI֥J(] q[f;+ '%8v kuWHu  P;oG~A$-V.D6r+KC#2YUٮߡSLML<|<O.ݍ<B&np7&5 4͹8S\]M*(AWޗ֞zݫ{@7# x1G0CB> & :{@ygp 9>fiÿop[Q@tuCOn8 s?j 0p8.e2e1eVhgaYJ cjoV8s,Vvv6;o{n0e/\7>~pe QNm]Ns׎:C{eLRtK#{oja}C?^NPt;@<:iD'ڷ>|-Oh%8\ψ XǣnG-{, GQK>!. ^v^\Gi RPa|^4<#u'Gec4d髡B$s)ӄ$ϭ2( o&A)Hi 1&f|'C-&ٰʐ mAeT!<Ѵ*>\ LO~9K"Sowxʦ4.Y m4x :]L[8HtSNξ2aWB{i`x1sΙ7#*n)%].+/ >5=YRv]h!UǨ]*H/Z6/ 4!rAE"$73Eқ&-N @.?$*¥o8O 8}0ԙPF 0I[g km7OФhAd%j@! a6Ĺ ?!  O\AGdR\{I b<ٕ]A6B$f|NFVsY7KE駍◗DYRA4G<P!4[y%1N}́Ma}f;g6P&f5..-W宋w}US 9pBջx b0y*|d2anлᠹ;ZQOz$>'UelR]6O[K[^nDCxBWH\PVƋQЫj0ǷY:+~Ytnhg ETm.>55 wytx 7vxp?L 9J&<:ުE5ڌoޒ?ҕxV^'HlsQB.%)tB"R=)gr<+m$tb` y %1mhkU \4UHUimimگ2(|UtfVqق6ت0JQFT؂nNO7~?avXyb8cG|^z໚63%GNh9_xhM"W!\+Q2MDrDl>%(S0/MiY![JsNT0m$;[ao'|tϏoM\so؝ 0x34qNS${`Yow<ڜƊ $i˧iSexg+K-u0#2뤟\p$AcI͐×KnYek/'|0j ^|Gx:.&iEfm ].8)u :eTP}Y?0o󖙅z*ky#eJ6v!|#gFPT9?LXO@LӊSE|m*(ڴY\('Hmf鹼keH+t4NJ:=ՌuŒpcOZ~-l^ruSL4˔Kv'G=}MMP) +Q.|1U(Wؘ4ޠǸGKRS_ 0m̈(po%생n$yprLJ ;s`e]h*/aLبdKD{|%h4JpO~.ψ€4RdGi,Y!eR5͟.ZIaPY7LVMЬ6™-rĎK绯YΕ;^ޤfv&Ƃ] 6 %=)vrXkwxo$%| SG;Pܪy,"wX!uf \BۈVkd$j v!Py17'=K*x0&6:468Rw9(2ű\)cIt]9ԩ5m/Z' pqæԴˎ2X73\3n.Q[{^wwi@!srVJY3WO4BٚKws}aY~Uviԋ$YԗrdWشs 3|c2Λon\I';Q]Fm]p.bVP>eHX"a#\c jc{skٽp2Twʒ:s\rzȫʃ˫9|O a#xhLh`fOl]'ώT&&$̆aiaDag̝;LƙdN(/K8S9.MRUYqYY N02Hin#ø6OҦaj s4ғg a}×HUUٚယ <,'"(44/2qh^?]k&abr2/qϑSvZ)8+vTzGŪ՜.)I'> )/&9b*ĔDՔ}E 7_k?&a/vKpXcBYyF=Q܎h X]έbxٸily( CwOGM [*}%G=']FѨT|< 8ShҲ|SW>AwUt#$'Vqߟ4W>](ܧRm!=^;9[s3i 3xە(HSĶԉGh i󔰽w*.R'R&IQ|Yض']UR¹$!..++ʦYcq5XaGSRfoh%.]GbN@<=ٜ,2Ҳ96oPu:И.mD., j˃赠~=%k6y./ea\}f%̔c/^~~Sݚ P@Yf:1{1zu'EAb'~ѯGǎK(dV4!0J@Ј MJ!8NkOk`Q4Zىѐ({f\v^JVCx1;5R4;:3j \2=u{ov$r~jL[d =1Hmؿ*H'1 6dI?ѪU"nļWz56oo籍 ;#Z璵 9l/ߚ Y">,Mz9/;(\uXrsЭ1Y/tp[7S!Mf0RRuOr%endstream endobj 285 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1892 >> stream xU{PSwo{UK ۊպjEuE塨CEgD`@򊠈 zص*clסjv;ι7t~3w̑QnL&8݌K;Kq2)Mn ;xz0%f{1ҋro-էv%oO̜>}Vp랧7hhV%S5qDʐOC4lW1Yi&ئoDmDGEDjG^99䏚~QX+=#.>aƬ̙!ECERQT4ZJ-RjʗƸ)*+ˑ]ut{t SxJ}k*"gٲWƊSRJ^p<v?` kc lf'\3&?P+h@Za z Ēx@ErhCx#{0?v@)@E.*\.y.FKذ*G9 ?kkHȵ *vWٸ} ?Cn]|gv{{w}2vإqJ̿rYQAO-Db{Jm5 מC=./SZd*ZGLTCN"VTNDМڼ[Jrv4Ȝ6ؓ^`!28b9)_B3u``凔 ߈i#E5BR6Y_ 7Zxlw%C1R˔Ldb|њ3?wyWH">veD՜VЪjɃ<>j鲛drQki贞=`*OTv-.THfD+^ogܢ||Zwj괼]1 ^pf'.qp4zK^` $lex!a7547>~:' -D%7@$;b9fk@F &e4K@@:j G>CIq^jSN DtXTLZ2gߝ!V9+Y0%~?!8$A!Q27eܥ±"HQN+(GAfJjb_A_zM럂N u]p*B,ER PnL:x2j't:yU?]T?CaqTg~>E~q'X4iXTuԆޝ ]x"[ *gTWZ:X"]}[hpuXH2s SR2Hv *Ŋ3YĪYu4\[]e`m>qSwn!wj 5WxⶽL?Gh"-۸a,?w[l,fhbP}nU1-9VG<ͭ7i3K yQ#xb񡽻d&?EA ?VHG#=#s)b9}S<[[Yc>6{.endstream endobj 286 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6874 >> stream xy XSgx\uI%jAk]ZuZj(.Up}NBB3`UZd6Vۨ:L"@(8XXPv MD<##%/Xyo;v3-@ f7"%^ߢo8'+u~^[e :WE2]SR\kЕg:p#?m߷boi (H͉ okZXڍT͊S @(a2U9ZZQ#Xr+ f(ZbvAQ/hk.0}[;ZFc|H'N5RO 88o*[bG;h-Եu5 lZ+@9Y +R1?IRfMAH9h̕mzѦ-u0T+l 4 =̆R?]A`u*C#Ղp*b-zeX:vF _2J.HӳrM>@+qNF5;:ฦ|u@ ||S4G1y ˡ+ ^*̀Z%٩Ge1 PJyhF@ǡk^fyɻph'~eK0}zIo՚蛨z^!iCBn›\ 9X>쬙}G|)#|N+ܽ'pᑎ[=uvd O5w~EO9\c׵5hM` Ac$o( 6ezi|0C;.|Kg۹1d3=f-wOݫP Gzڀo'5R[@c wݜ(ʄ4e &ɦו(o3]P*10 *scfJ W."2x"j7&L Qj!l`(uT5) Ql)dP|*fu1)Jj%G Z/stNsP3dn訫DBG 0BT%L,(IqAf][%}Bpnws]$S[ [1=dA!Fc>Rz@g(/#缫٪`,]bT)ww Z#`5]k,%1'n5 *|ҝJa2TZKcpEb}zЄk|x< eN6iUAJJL5euݡG6#C_ XsUԠKO&؛C8nC(=5!;p{_ԇv46ף 9/iN*[Tb`)C%We"McрT iԒy@[q jOET6?Sf|}.HG :v4Uǁ, X8P@V \rdIj[G:dBaW:b94\9ߚ&rI/k`GKz5?EKM%Xp\xExэo5iO_S|=5̵_F1C=.ی]+\7U"\{7BtCaڑںtv囯|eHglAͽ%=k=6١i7Xv>0٭G:Q#'bd3 t=Iwᣢ>r|F+Z4Hq%.9)fh-j-XuxAk#ЕT6moi a)˞y4|K{8:s?H4; H?_SVϤBѮ@@&dsS81LB6ީSA d(Egw{]6K@PF6vsg!`ŴŴTCן;Xq#>odvS:_}?Y Tk9V!dQ`h<Ro|xeɊ{pdw䑭3ؗfޯ\`?]t^'Z=NV7=AչrМ/F-;v†R6}/4 @( )8p ]ȅ>CM4>W-_vnUwf:O=й 1r* \o}ȼmPE@#)d%%M$Y֜:Pa363^uyhv0,P.ʉWR L+VR?:tgຄf3{i=xhh$s#fbtL]GC'Bx7{֩v 71xGGC {Àʄ*JԘ؀;a/=sN_W#;,1ARX(")+N֖wݭrPWߵlB#Nе[PLF3"_1gsnng;FJ r+lz:,8Օ7W6w^/8?I"gc3 qZ<5߬6eCe2oh}8Tc{ьmޛ7[#3:ܧBUTޱ9DLh-9A&9c~P|P 927Ytfk QmA?8M:w!a⫸C2PQ}imFFΏa*qCup5ejD(ϤGE0I59^1P\{|ll\lZizcs<Os6p(QޑԜk4(u1%A~~.I#WQ/4 {*+5wQex#%&Ʈ(Qyε0eY6- ȅg/Zz -yjwI\PaTZB 뚭EmWrOESЄRp8Ympv󛐏F6w 쐊,?S)HI! )N֝@^5ru>)-X[ {Fix80I!@71gEWe@P-چԏVK!v7V/?1V\co.pѡ!(d(yrwfHGȎV̀\;#OWQeW@# C5J<7((_w0MNݰ'7Q.T[آV!|qk\:PRO Z6M>tZҞ&- BQkfz˅]lc C)S /ʤA Č ]z褏C7s4Q C-9`G ߴ  ܒcājMϣrWI4b{9+-{ИVB*2ĐG #oϓA~hlljKCRBI6Pni(?4dfe9p&B#zۓ=-%@ hө i&O̖8SQ*Tl+K>rj5;z֌¶֞ #ϽBF+(rcb{_}]ɬ 9R֏]A&ٸR >ʬ9tB̻Ɂ6?TLV*)Mݣ9Kń1OlKG>J\oT`PJJeɓ '(['RL")[E+uVA- GWU#}W=r ;>%`'-V1r&6rHYl1ZlT|ʡZ%S=#ٹ*wV ˔֊"[jCL @pI#v-S.y74[Iu6`2ju%ٰ/>/1+t Ҩt`F, *,UU:޶ZHd0؈:L^8[xGen0:h_Z$&JwzK-RX]).N PŮM=Z&m?qf:Ӹ.L7J0**7#?2,8ǔ0-vUS($>َ=x@hI4z Vଊw`ifuuaFyYBTYPb(6bWj7/ddz #-ʁC E`<*k\-绞gњ%]\g> Cs~sFޒZ}#c3gG'XŔItkȜ 䲛︡G7R%[ v7,޼U"Cڝk9rpUy/|ڴL4yqr%`.^ۛԆyC {KM3#J$ Qe=*!`ǡ&S :2Zhv ¹$AEȃCh~XpXr0ZZUV^`R߈Xq\GHj(rQ !Q]T F*wޭ~A9C7@ sGų~d<+` e)BI ý$|} _zui)+:8$$>2JGE"!Rj.nnٻȕ0\His׋8eKVlx8@%(RD_e3[vwMEtx>u[%)4jȀ CnqjKLMӗ~|=Yrz l^(&lf*33!y`5uivJѕyQFS4f$mI)3ƌi/ÿuZcjs0endstream endobj 287 0 obj << /Filter /FlateDecode /Length 253 >> stream x]An0E7HlM0fXXYY<<=]Η<}KLs+ݗGMdιq`9?kҴX> ixr[(-#KLTcRsӄ ߖ0 ;D7(xGNCݣ+Ƞr=_z:bxP'T JsC@*PQa*JFR^|-W:3I8endstream endobj 288 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1786 >> stream xukPwH1Q+g%?Nɴc3N86v;'`( KPVBϣJHZ <:~N\O$yM:6iq;%)+Vh:ܝs90e{(;[uæZ4JB{VqOWfP,VH>} ~}0:VZL~T0-7>~poQ4Mm:MPj+v)WZNU4ZfYꠢ@f߁JF!KPRw+5*mJmVk՝&`JFעnRj%jmJoP5uuZ]@alÛhV>z=0=V l܏xg qN{)oFT+f(נߔUc^A+<{4 8)K,}^sy\: ly݈}14} xDOܴ(uě.Si"QӱЍ @VS:e^oY4>{( %""ƓC&‰`j EAu{;UUlhf!kvU5>R`"2Ǚ;3'gI JLۭ۝i9:qzП ƢCh(%7uq$ˠ zJ+$0d4Bw/^A2g% r& }&!7 Kҏ1 CJ5ڔab" qgi>qx`Ei 4CI8\F>a&N LC2X:3 ֵVzI~փbv>|kx ԓqXXe ۥ[ s#`.3 tseu/F..©3O쎴AQ`[qu!Z ^l4ڑs6P ;@Gd%t&S$lQ޽}y&9 GN_eT`= -BKXːp,MCGln'zB6K;6NHuqG4Ͳ$_8|} yBP Gإ~ %][zhA9wA<8 #h7rfӈ/6+ _qb.It&Wl(jgjj7+Ddak滳EE3|ó*nߒ;˲rnVX ^27+;+CNJOSW/lu;w POlq]%%Ϸ}ɞ)oGƱ5 WuPs$wIU/l[ 5[_|kizra"_J!rIqc2a̽'( }`"nnOX' lD0ʒET%N`,fħ";@;c<},sG]>Ci'2UXxaف0}lDVnYs頍ǡ~ܗ|*i3BYVʉ%/D8eSdNcDTV^ Zu)C]\)T2O(BX;1S>ҵn/TC?_zʟl`$ "/g߇pO/^^% ty %řLY(}|[CP\ ":跊@ab Mg/@_endstream endobj 289 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2511 >> stream xe PW{a9DlbT$"$^DQ `D>tifPP@`klbtL94>*FTRUU}}(%W%'F&y͚6j*ėr 觅`/{EK-X=q\&{?.Mږظ ٳfyϜ)6i|<މOVoqL{jɸ=9mSt\dB[r[pZ˂V- X=/ya(jbrʶ f{ϙFifRTHQSKM&RN+(ʖzRNJAPd'Yuʧ)&)('YW**yq S 2ؤbӚYFA<4(q '!OTf y0,7J" )T pzM': 'xfKDKB4 "k,a],yf'X7Ďc D 2 $O-Ky s/kj'ҿ|չJ[%PXRư: %e./jZPVkڽU]W3xS,]7m﹏Nuu[9ijT)Oer:joف?uH: LSg VI%?Wq_ޝ_ 3޷t wz,:3 _6m`u3o rAa̚>.em@=ab`;-2LB.>O{;ymC7ďJQa 3RKhzv>~`qʾȰ BYk{d6o͋+&9Qwy-̓w͎nɷn;KcnPs&+p\9ӱ-F.7 LƺC0L L%,gϣљ*WXZ Vsn~zu폁MbO09tSRRzzR)dju_lR ,\S*s[2;{)Tw̑CA׵8&qO )ٱD ?  dQ4ttL{n ً9ڋr7D~-Cn9VA=ǽn2\&,~u(((҆}РV6NtRFha;ѿSD;)Y.uQCQ|+Jg{;c`(4KP!®c(M!Rendstream endobj 290 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1071 >> stream xmSkL[e>X$d.&悢lr1+K[X (t= m`8e&ƨ$F!.پgbL˓y} /SyblA({Hz ?y>YJ?,++Ose겞Œ~J+ RˁrT.KeJCH/R皚 o5UOc0 \ilð4vƲ0Yߍ f (=}Q~UºaIXe_6p;HMhA0CFtg3S>08G֯W?Nl٥_hXR>\lߗtj(xȗc4Fۼ̇ؔ+%xΗ(c ITwQ5uzBKzRU:n~ Yؼ#SG_YFm6`( XfZK$HҨ8" #4:ߠT6Ika$(~ ==uAXpdҼTZ87ѸcQ&-~'/,Ujk*a4P 1$[ax+L xp: ni+.OT˨IBT8HRޚ&He"ڵ_ o\4]R1}Rxջ$<-n2rr}{gյ* xgEbsۼ[,NyMA+( )H=Ol"v|I<긐;V b!HD4$[b}VH ZB %` ;4tL X`KTݜߎ!?RO]˘97gf;v́qxLn槢4>Y`g.h8msyOyYګ\H34mwx97-nϭq~0]endstream endobj 291 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2172 >> stream x}U{PSW@"j6]FZqnmvV[bA#@!}AMDo R*UkZuuu;۝z.sv/j;3;;gq;88 DEYrd>N`$H@JSYADD`Sp<@|+eJyAJl_/ZWK^Z,Y#Y(K$kg,WTrE$_V(--Qd˶H6mL(YՍi'ڔJˤJ\ZK{JZY!/#0lF]E˧8 6a tl5[=æNpf` |,A'x\p8N$}/d,Sn,X]7Ku._,' =#msIwɀК-AEBS㜁l}[*mI`\9rjNڦ1Qws :bUj0L[c_z"H8bChUoϖrB6PV0YCH"g 6W>hr[kvݺj=jc8=!#4t[e 6@ T8z#j5rKd 7#WB44SׄŪ4^yD~i4,|v8}g}OJhHUaw0},v-ʼn'L kbq+B!Jva |a:+kAw'~6w>"@|*`{y|*>[ )}D\nOoh8h^I9ZXMVs嘚KGփgѽ-T ށIPu18usa F_2ڕirʰO߿J0nGw*[GsF[[\:bҤ/ Pr"U3_f;@ pFxŪÕe*tD3!r\ =DgSo(2^lo'aġ49Bfmu5&c5T}[OWIG,_(@GEm&UyiŞ&mNTGrTwa4w7}cL4޹B)'1 /!o")=Te𽧋m:jm }'c܅T|p1Euъ=rMDIJ"C;aNA'@^8zm Z}/jDn5ZyiW_D{uH]Z, *OF PJ/"(8;ol "T znE*msJG@O0  {]N^S\DI樝:)4ӓW!HGxj rcB.'lOj='2E[NE:kyGLM{W\ ӜVI?lr116c-[7 3& W6ںzۆ+n"7d)kRŌ?1sm&: }a/9Ƭ5%:փxЎÝ}>.&sc 2#:Sq(JQ*#X 7 |.?'+bਥiA v4?aVഫ◙/8*N8n?$,⻋8ۓ NďF).gTjoyMߎxxA߮jr%}v_Dofzf[PIEu_{Og"8{.ěڙt6nme?)0oq_|5tܵ#h|CpqKDKd.zsd>ėk9s8;>.VB ɍ m?z#NA +§^ʐ6 G<{$Z8i]LsE{N!Kq.fGtv\6JDa 46z@p;9U\5/pEO + u+2 Vawidrb"e*Lt]nƵrb.vէLǰqtendstream endobj 292 0 obj << /Filter /FlateDecode /Length 337 >> stream x]An0E``R &dѪj{lL"Ytų{<:]Ηy}[gq-ݗSu [_5NҘùCq}cQ4B1sk VQ2.A2.8j @[j# 4P(Ƅڊ@}Ÿh(jY`ȋ"Ę:R!a* $ED1aF ~=6z٣e x+(5̽(Оs<"&h;[QQ_\|Psض4:?:iN#.+Oa[endstream endobj 293 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4038 >> stream xW tSu%4^M4([Ex<7Y+eߗtOiӦMifO~s5mӴ%7RZ@QE9:mtdtԙ={NIιIGƏ1c}zXF..d=pBqiG v8vstԧ$>LfiW77 U6764(.QJipLuikYe%ibiv ^.V⋒Ҵ̜|qanZqnږi[7ܴ9mզ [36?˫’|qf\S(qicܣϮy/v( C45E;zï\z^aVMS!ڿ%ȝUgDSNYl2Lvs«3*q5Tgk6D-G!GGEzDם{.@N@obŝ9MxboSdzneRXkʸK;K,x~V?Qp;,P .j&uH%;^vz&4EWS?ɕ ywcmoim7~KM>hHyP[?id0Cg\㣱Bg3^|kJyJݗ( /5J{1څ`v T^2!Q̴3CPGFu %Y}?{7ZK wsM2yiJPkvjN WcGYb6YL0=6G}7SDVT477S̘⟚z};4o"}Cm $D' s9 P/ڱ]upPaTXjhlGVUӝ?-z%[H:}k+ɋʦDPs8$q=;lPhS-O\< d"[u zs7m4f}XV[dJyYW4MK >ce v%J;-(ݨj+yL/D/\  Zb0Yv+=0ցST<cV'$۠ @@VZ N-u\T_r1.h򯃖g4l[lӑ& :$z6i?nE :vl/D\c?`ouX߂M#'/8i79`wv[٠X]$9Y9bjfT挽cD 2!/aQA%#X56-9d dnODT94ֈp|G[FmeRiYT\ܖ$`mW q]$ط~-G!݊x@Vi [_h2@6ͻ.β3mV_+}-4_zD#cZ`&k ջ G :K-1 [}}S~OEkB=ZX9RY<jc55 љ fЊ@7,6:C&H&{^~G5q>^.=],-.ɺBa7\N? Nb%'ߡ ʩk07$jc_~H7WVaK/+3g?L.j5Z)jknĹ@ф${@CF}+dۓAvzjY\*7{hs{ZwA G:FinagP4C =Ι n3oӍ<ZG?M4V{dz1w!5}m]UmE0/@{ y3z:tmxI~p`!7KqKY~%R6zņý}DF5vo=*gߎ:"s'Y\ UQqUVas ި7+rO%v[diiq3-T&P$M@ᖗ>"LGBYcr(t+ ![КI.ͅ]ıI|B]jCֿux]gOpaztvNZvy^aCڕˈy`j,UjNk"k:ֵog)vlhRؔ\F Md§pɵ*jy޲ EMnCbkOF6u0.sj,>/vW:*dbcI&87# jz]aH>l2|NܾW%+S1߅c:^Nģ ǀ<A]Es+b)wA^n0CǹIWֺ+'JP?Ӫ8{Oދ]X9\Dh2ZPÅi4 - !Q.*̮kz.G#BzJ9n`wSoٲtwt%q:&Mjqt:'M<=endstream endobj 294 0 obj << /Filter /FlateDecode /Length 10324 >> stream x}MwǕ+BY`79B1;;j=>sd/ J6 s{YYhjΙۧEԫzw#2?ǝ9۳^ܞ@ˮŜ?L/1ٜvŅgB\<yq7m)Kf,%?7<_lru\yoTHιݘp{wqiMޛWj3oÛ(0_Jpٮ2E s!oZ.4-.ץ13,j*%U\r9s8C,u@ƣ %ݯo:PMV`jvfu  [pqWأ֘KG 5w;FU{<<]=a,-}@,pvn#ꁿ\D<DZaUUD< qZЕItq\ranp~|5#m{] ,T 2o,n~ʊ-2x^*]eǖ +c˺ZY_{DԴ)xl9^*[depʎ-ke}AVdزVt1yl鯚+ R&ٲU 2R:aYW_+ aZٴQoXVY+}eYW/}htf٪/z"lSͬ-q6%Nd69v.m"flgt3\մml!'.u5WDUl 纞턳h;|BWl}"lfu;\؉kω|s5e'U3v9NRyv*{v-<"'rϮvٕ9wF{;\yg?';QlM2w"?Sʕ2լmgzU3uOTWg\ (e$"2I,cXr^=nR!,wRaNJ DᨤQ?u19jg@ x1GRZQ˝#Qne-h2 %hI $G4ȷj'khI;ՒwbVUR upIt.wcnzvc+Ib )SkHHH;qu 01j+oj հ ho|C2DqT2vD(b dK䘐wAp_fe-cV85F03X2a@2Z o + `td;얓 QdF%}PʲZ[\o)\RQЎא:Z"{/X Z-3b % 'MZzU(z A-\ai khqnjswwbB L #zZ$%:!-a_)bZ«I`0G$=zd9v\ ؑ#mU60&1xX>d&'OK|bC-@ȱmi{1[jڸbO,ij-OC* K=X"YVtc94!j$%DtE:# &$LW:: 2p2tϫ #0$A-**VX$P^r:+'.D|V?l 6^ ~QE$p ֕ 912IXdQm -.dq> GC2 関X܋b9O@A*,/ebm3-D?NSC'W$P>_bo #Xdaq ~4KqA25,GXP$2HR 4c@/EX $PFm0*!+EF9Zɘբ-1+3W+ tjl-j#KEU/ڗZO#^io>sا@Ј}掍 ;wZM+WjHN֧omgR-ztsB̙>HևhfO,ҜECS4jvUZ/nb#M9/}QšE#/)mƤҋ'vbtZ.'IlQN2C 眊UG:ih}}RỔ:7k}UhoPE r2lLToX>n7k}iE뛅FSkZ_nQwψ7r}LJl>N#1;RUlPBa͍7j>h}Ų 1k>9Y[yUgO>*}QXLR ":N*ެQ >vBGm GA|&BE u>uc1|3Xt>y`ʘ;$޻N$E[8NrH}$ߡuonhH}VI}5)k>xyF%wR_SJX>j"ReEk[/P'DS@{YVzQA{a4l>NTqgaQo>J(}^5F#A̝dAnVȼlDuJ_=ǭN]Z/#ډ9 }LB|t&|EWɢ2@WfsVQYT>fY+lmU>m* ~rGOκ|HY#Wˤ򑬧F2{YClH2mȻoD>k:ϑ؈\7|)UD>]DD>79\Գ Ysd"]M"X"2ڞIs"M"•Ys&YC iPh|c1RFsJ"V!ة6|~xAFfR7b^T>tsV^*Hp֓';| 5" ^ŰIV䣅d0"eZ$ ",,eEワJ6h|d=GYs bGZZkD;>+|alWDZ(|0ҩY#0k-J|AZh|~]mg?Q<G P{`W|Iԑy2.(poL+"'ط*dYdćoe<|oJM~wMSyuQM(M"٬g -J}JJRe3*QhhA!QQ~̪QJUDK:TbӋ+G INk, J"ҝT=,Be^a{J$`x\=qëJeHyĝ(G0_B'Z X*Ev \HޕSm%9>e|`ޓ'c+^걕{^/Ja(Q;NfDq3?VVyq}ZSjPy=,I^^NC^6yQP^y8=d.I I;J|hlS*&:X"VK^C)W^eU,{J|a}aBf1K|ԭ+rwUeTV]算R.{W%ȊoҎݻsB'+nHIt6<ʖܴyWL敗c|!ˑy ״{4W'ov xٴ{%f\kJl_!ev@nv"0F>8#Y\jIfo!rh?6Ƚ{q<c\phXhG;Pj}Y;Q{GNJ ik~^}D%4ؾ/kX<''<Y\ 6k #q|pnb\:2~ Eaqwu}sCؘSq+zmxN&8ₒ\ɗ<1wz7axp/% `" & ~f愒"s|`U%IZ(T,__BRjZBaҨHLQ"s6/?[uR%* <̹{_<']m.48XEv,ozi+{eFZgUiu갭B; eߴQm^7\\ j17?9c?$XJ4N6 Wo5zSK`Zb" S.M7w3<@#ա)OMAXW?Eˇ I1&kG )x[MjF\KqݵZc`f\ŹUlK ՘[/[.pKe3p_ntľ{{fu-.LÑ?I@m)M g-|-#_!brϸ=n ~-#!A˻oQԀ<~ӎ0zacOaޓgMj8`@Q/>࿼zE~҇zxgin"O)iz̑ _t %>GٳWһDi]_WC]=p0_1Hr"e@㫣I+7A{?(Xж'Ow,hi}{^M,taBv~s3Y7_D|Q_F q&P}8uXҦ >W}~yծ==\-=Xw9 O4 C3x|qM1wvW_={y ͏o>rx8mrxTU?;}e_dS}<ǼO;b^3 ã.ˏH'sQl0"x{PN |Lg|z$=w a1{̫NKL$oH|)Yݍkd MGBTYW*]JSrʹV1`mqkex﷈-",rQhBV#ى=$a8W?=)ky\b`?[c@!gO_ AG2a'n64O曅m3_' .":<79_Wg$}:4fX`N2P$w>;\ -#Y(!VMRͭp,΅T;jk8iCw"3['?>FS6MjlhlqȳL=z)0Tm$ٖR2BM BJ~l+5B{Z/N '}#/ο5|Z@Q%pywhS@O6WSC݆@"H;Okyuǿ}?H>byoOWA0%Bh1- {]H'Sh>3usס>=v Of k*00yq0;ipe8-Ox(_(^EqiofW]yQ,??s@ o/ s@~waױJ}GQ:&Pc:f ih%ՇUZzpK1'aNiko7WVcݢſ_\(ҫ~=o,4n ϐ'\Y^`a/W6=%.gʟz2RT5_FJ =_?l({x{lRs $:m!>]N034b&AVlP"kJfo5asyKF|t!LݻRE(TX2;YH$7|sѥ'9pXJ# ?!g=|B*d-XA[0+e_Yo YoEHSmax֭"Uz@C u.a&OS \,&N_ϣ\Xk#"amt{SN'n>#)(Uz*N4z:K~G.V~G~LUuiD*MZiz`*5P`4,gFݴW/[W<Өd VH> sĠe|<6ip䐇yOo>X\Rw\ݓT_Eendstream endobj 295 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3230 >> stream xW TSg!zUD6%vu:u}U+Z[* " I @x@aGAF vZ:vt3~v(:s~~ ޵{_NVbv41;e$iri96̏'~9wX| tj!*|@ѭ9EЕ˗Z  M* jb#3BSB_ 'f.M'JSCsRC%CQE)~=ji_A{9M{-pm-ps6u/+*Ahu ]lӉ߶ze=1i/lqBnDuYFTcxU`4RD_gFlC K@w|xU0pDgk"<[vǚQЅX7xB9'< h9q!ZgYq1ه ]o)b<4 BܙL(۫Pw,= }=k`z;xizW?lCr~{N)kU]к骇[7!V:d64Rk,YɐT_̪8&EBO01 eA.,} (!cA_eDMɻ`=|_){D<@ O#TuW%$2pDSӗITB~T8ӴM@?އ4 Pv3PhH'8=F ]W5tBx$B8ӊD _MFN/Wh978ډ;J.rЛ>9g'd'js;%$j]%ɮۀlVJ ƯM*%F *D*5$(.b"ʢ96cnG[+&&oj iӛˠ*]tz,`04;n7qH4 ƮW ‹v=#pZ ъTI*0'cYgI#Y)YFN.#&Qq*ps/IiTֱ^):b1?>M`$2LX•&S[!܀n уQ\M|6.Ϲ\V3)w_U7O҅bEU־̾؆7`lUd5B;,Zzur a8d%N=ۦۑŬ8hc_ʮLmg)zs)l ?~V i %3Bb _][gLD2~F7 Ti0],x+o늵2L_RppzQrW`f,LO ),#vsxȖLN_F'o :Bpiu, PGJ5YUO y{{ 갡|J;SZn[_,k@qaT~يV5w`SfUj ۡ-'(z]M!ȏ# X(@O 0>oa VΛoTxXuJZz#/+&/ƭûfGxNɭ]|cBb1l@Tj*fՎ65Od ~2 }5={ы~ZֻLQ-m>|~+r8HZŸ97p0':;EfB]OoHb !֭ŧ ƪ{ڼp9V @B[pϠXaPT*/^epO핟O`kCL`r5~%C'|_`GF0&'!WmuO7| .D[vLB/~jsuOhPL }LGl|WڵEf^"cbDr؅xp81nyIz'\<7 ḪT[Xi ۠M1rIhߥf͊q7č7rG`$cϳKFug M:&g]I&yH^Q$#tJ^89AMqV(0?\{Ipl;E {Bd8j RQ`6775u%|r#koyyIO)*eBWlW4@ L#\BY"7'(G 57S^giv:=53(m>unz\Rx"/`\ufwЄ-5{8zgb?*Үq<ғt_=-δX'|S.f`ڃt> пkl&scM$tWv: VԚ 4μ vgfr/E/{xv| 6u64qњK_= VQj~?"u7F_FRA\O$_ *Ztlmsk׊[U*wjC%S|e5 /[S1UCMva) K8m3c"OƥI_ȏz*l>Lӽ^7~ _tiL4G$϶W?u1fxBwo /ވBsKqs.HA.ʵ6ۃՈ?cm.@xh Bxq?@~6OWۃZWxI@J׃ReZ؉f^[LKAِ.Ha% e{r7eۭn;grsfC\`4jJ@dL&0 :7endstream endobj 296 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1697 >> stream x PSW_< *kį(LkXQPl@@ϠP4N H@YPei2[[PQwǮmuU>Fvfg7o{\@HsҕڹIn[=/l;{ B;UJQ/BnP ؝٤צ&dk}}/ل|6ȏ U&iRYzdžkTKf(ӓXM?nۚ'bZ~M׼P"!B0"R&#™p!7#QAMpu*f":9]%_!c|d[CVla+蔢ϧ 7&ڦsr#^{7e;$}.uR>+f^lcT3Ƴ`.3zj~V=8smLw@o$us?rz*CUKU,=d" P/EUF7?b@ّsJۯ!8 w85`\3ZKUigQ L LHĸv+s֥S Yx||[:umр-$Uynj8Wp4tLP 25ܕ*Hܙ12|hGI\`oYp>q=KyrQm)"}C(V2]Y>@DV>ۿRO:&EEo9~|'뙻6L;m2Y:+ۣ;VY I-l6 ؚ~86> gXX? tZN.5<׿BP v X;ѵR.lDBt.$7<{hНv#(?mZ69\hkk^` L:^mnMk10 $*[Y,.HϮ ,TJHMP5 .c2jp`1pZ"U y" n"2 }W+*A'G,^ڃ[W*JJ0mP_ǠeD!ӖFc.@nv!jF1{~_$w^{*PrLHsL2.3]; sOM1h߮9"^@endstream endobj 297 0 obj << /Filter /FlateDecode /Length 179 >> stream x]= wN _ KdhU1!Co_pgY?\k"e "ƪ[:d,)+*g o¿?hZ=挭rSx!!;銂wZsV Y6[=dO[HxWUvppx$r l?0gg,^g&/Zendstream endobj 298 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1590 >> stream xuTmPSW' ׊v,$~ö2nvڱ Յ]k@oH/C— 64ZDQ+A;.mvqvٺZ*N?w>y9"F&aBSR5VX74UWfК'ćKć,c b V <(? >7GCw1L1S˸Nf7,sA܏xeSqYoQ/KHXt)Ϩ+ԫկiZcxW?n2uZCڔ6֤RקoH[Edt]%[7us,i8^ zi- բ5Ϭ5L"rm4w$gP0L,7cb 7M  r#"ډP5iCTЇe#ҕsE컒t'r^vh; RQϓ&*>YG0, 'd18( c .6k"icaMmMNG34B3!8˺;s \.xߔ=@'aNsugkڻZGS}wp\dM.47t3Lu2!\,@Wi >LB.sOAsoEFy(žQP1Jrh猒]9gIvip {͒?DGs)>39|mn }ΐ\o1djߧ}7&\WyٍAD5wQ9$iI PN 5G! N@;Α ƶ,Ól(8 5➉hg!nIОk<뻶o_WѼF٪Q:jOsL,,!KXapyPw5ay\,~4/OcaF?V r l68+m=o;d$} ?]^h?G:φcqB?p,|^~rGEO |•frA'-s ۔4!#,I`a9dT0^)7 T%~P"$s??*{|px/p.WjZib9ϲJ'S@+^k nPֿ#N+e6k}%Ýfft-v׀,/ˌ%ݔjG(*9 mUäR~zh{'O8bK80im߾sڠ'| 34;3wty=ño>|+vJendstream endobj 299 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 553 >> stream xcd`ab`ddM,,IL6 JM/I,ɨf!Cw:<<,~L*={3#cxNs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+kau Sf73? , տϸw&C⫿k*g.qcu~.]RWW4f%+ȭS"5U:"?igX%V)HM=pHըmM3gM'́E˻9O+)ol-RY)YV]3Ї%?nB7 30|YDWO.).]d%+~7{&޿Y]KW7Ϝ?s܊3X9C^gC@D`dG~O|_fwϒ\]8 4-Tsy6~Y)WiӾ,`[͵[%${eoOoO߬9S{&lg)< -endstream endobj 300 0 obj << /Filter /FlateDecode /Length 1675 >> stream xWMs6z-#3=8I[O7N{P$b, Iz.J"gڦ!rXv!cg zIJчOoOG lz=.R#O0;' )c6sEw!gG{Y-%9/5jp E?fhf16}Ӭ;)5 7]hߒ7v!7i-r p @1 I;kKHlhlɺ5\iCj$uϨ@aV$|'6BC5QCN~wA Š "^KA`KUF)9C~`:Ъ˂n=[}jtfL[gwNrcT-GJ2>Ca"ba۫nU%];hOsz$MZS |KUw/)uk.jGNs ɺsj"]ypmtϷiJ2/|9Bh] ( 71D2q2 Q_=mBC@1F3XO9M=ج2-F~V50Y*T4E{,cM hBT4Y$EZz! &jjre_}SOVn @,g`z^*+AMFkD3 dxu\TEF1.d )$ΐM ,| g\t췁X>T c"s\AX//BOGF[vG[rTp+ҡenGM.y?zl'xAQ9EC1|᪓Lsk򾖀ӓf^+w e@"qeAzmmQ'FRae+>{YlZGD\i I8^!u(ZWyKf͑'ҿ5Aat:VůӜvl Vg'qcP,@| ^9pz`_YpuH<߹'|Tv&mс qE9qH)s>/U0s?¼kxy]>tq^kJF.g\gUKk4;ʽ:6[Y# Jg3mp2lQn+}$ƁX?G(-AK #:ӠuG߫߫endstream endobj 301 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3428 >> stream xWkTSgހĭ"U8 m:j;zfH"Z"j%!r7! !$ᖀDQU ZKk;5vVj33mL8iu$Y{<_1+ Y+!vݚ¼g˃φ >ߑ 0uˢPB ڵ 9͋KrrmXn榋[rweEy4^&wڄ|0gfsY%q97kOA<m+)Ei̬9 [ {D"H"7CV0#o׉b'E$D4 <1# ) qXAاt;Y"֧EVQͥޞLD`#"dU@B'‚h)\ݞWupYHjwڽ-mE%f qv6%̮/\(.K I&5fQwWWK4n FFYqG/*sD.giࠚ?9wq:?% ϕZNedrwУ~㢞f'v<,hB^;Fx ׎}H4ŠTCY[ ΏY_4;6*Bl`,XcA ^JuZR+J)g7Wp&Nc˙W>B.5)B*KV,=<`,D-zWac"X(̆e(fqaom}xR/OIj|@ֵZxfHƋ{C= ZZR%di!7@XPMɶ${v-tA]m:vhhUVTPAu-3#}r֥ ꊽeW6Q^, 9(`?yjj.p.eqYj\:zΑSnQʼTXi *KNMKRVfYdnoGSF_eQLLe b^eƫNK#7Йԛ(aÌ-)7SP `tl ~%:_ r?'O CshG/I^eMI|fL֚JB+HQrHhoU/6txW:M0J(.0{m #bTTiҚT@ɹIv ҳ|TgkmC׿ 榺^! R-&^} =Ow4`0 Vm T#ԖM2X̲³']6}WFiIƗ<$6|[ 5S"RJdaKZW_L}N[ma؜+`cTP}㋢/w*؏13ՖTV/Ρs=u=i{-G’'2ڶPLa:*UASQBgV*[ Uiv2:Q(Tv'f^Gs>Eџΐ(1fRkS"q>2mPhlpYn3ĊY'3hv0h1Yʙ:?oL$@-"jUN9nûuڡx!h,%[L S{qVGwϏ&)4 Â3<楊#j2Q%OXG" [u&I[gw ]d`zE\ȾvMgz҉gt"tFz;+fo2udg@4 X_e`Ҍb=U0^[ʔlZq}=p88RPd10H[J7 Z~'@߳c蕩eCQƞ]I }F&\,3F0EYT`*Ln:Q];}5^r_: b`emR h7bg>E+cs,UˏO1,&8+\JS@, M~a$aŻ0F3»rOX0M,7 2uXKiE ANnꠢ}衷 q;~CŲ.1oeDjS@[RLx'&[bzU)ތLն6y螏ۯܜc',ۇO^h?t䨐j Jq̽Q47;+>{zD{]=еcq.ПUZx>m7[h錩TըVU1M_f_ N1ɠjP9_{mYLz LP#q% x&nuYmuVhrX&??B/a\ف@/+cZhfR퍁|cf>jA@6l1T{4pɎ!APy]Y<%Zhg1?mjFC $s=R]uiLpޅ{~J<g̴ǔKtJҖ1g50h Y.?C^ r)H0t`6w?Ig4C5| 龴<sp\$:k Ƞ,*up3zj*>, `;_zG$W \s>Cx]]F{ʯыRz6^IbBѽx4mO \&v&.`fTY#amlҘWMh(YP%=$;]eg?[͈]jщ%) 8ၬ0O7FAroiiF n%:00v; ,'"U ̝G͝1" 5'?fcqh6b>ABendstream endobj 302 0 obj << /Filter /FlateDecode /Length 6529 >> stream x]oFrϳC?QMڸŹ8'XsҬHrקj6GK4]jx¿wgُg=\ߝ/`k:q~?"[q;e/*}q=mts5ia닦nneUhjw?:՘?7VSm[)/4Rn {n--OiQ^&fdsܽ kq'%[,Uc\EV|f>1pk{.,e$|iQn/6Y} PpJS9?uv%t!))//6੶6|O%źpl6B4%')%E-`ߝ]$zc_'}>[J^#?&i#44I))y`22Dww|iO{?|_Jk͂k;<>dտېn$Ri#Tmt'=mq> daΐĎIAl?';,B:by~kL%uH~Ѷz9Ngn\{XПJ;*U)dyj8Hb98Ew%0mfH2ߜb tm5p۳Eu[F?ZھIJVz}mq"8>N vݯ=}g@nDX ?wz_B# 7LnZ!WЦ*Kn^~KFNFFfXm:'[79\15z{qU}{ꢴ-`RMvʼn*vUh4^n ʹ0ւTE ~K ͼDVհԳU3r1F bu\~v|bibgݜozwL^润Z#3QZ'8 ,;%BpHO~y]Ԫ{]~@ ֆTʈ8qˆ880B 8Gu,xW@d/o1KzF-抱_b4\0yzkP,6 *}VKIenrO[.6tx_Zr}jɧ}Nir`[ԮCN3!Y0͢MƄ!/WfigK/RV=Nť@NVF>nr9 q`dq

*KN>}`‰6xnaw'Yu: vM8453 iacN Ǣ#t|`[Wk4/?? ۏ Ez1RR;Zhƒ ֜>u{h:-@ڡjkMA< \x(`G a5Lw20RiY4©Lds i$7YF*] HgH #4EšV.'d\\[:eTx%*J:}nmpo@wKWT {%2Թ=ۦ;K2ųFX(oխk[\,nimcrfK M:|k`٨0!֜ :s`댯J'`sC~_Hs JBB kxuV ;\E0wsWN @ B/g戁{Rj5KxMg%25]#r/~0z/2qy;ix߇ۙ+Ge_;鷟!xTMR.\Gʮv.IGUnRy {E,Wi|+/p:µ7٩p~pfMi|DP<DžLe%@k|,mi%|!)t=Sc4Dg-Na팡*ՇuŒac 0!׆~{S渪Die3]5F2ˬmO6r}%k*J~E!ߏ ܢ͸' v :C#ʐu>ʸ ,@<BM"uܤېzF vd]ؗ0~,尒gM|15*[̮FF 6td_R{2/bXJUwz.-9C֙8*nOڎ|VV.R!Ś“W0@dΘWj`rA8h7y@O{Y-%\j:4bVEw4ov[($:"Ӯ55c,J^eu:,fa>ғ㽾􏶔?Xn+!jUhI~Dl' S(0SٮȶrQ$c5^F3sW b. WpU=~Mn:mP٧0` *,(ܟ%GC03Uq =(ʶpbDh.-Ot$ "'<瓜fSv1NpOq 7-Gc's :01KfROmDmgXr 픴'sfݥM(A%3Јz UYyqgs^YÙLG*Ua x`:]uDͤLcݤF }ʂvj8Ixd|4ĺ ܾ隆ʴ.הQr#dIrŏl }cHCr^=Σ$ɷvVye_QO"Lf$WW֑=}U~k]vyV2n)Q*aE 77|o-tொUvug.t[Rqm#@&ߟ%8\>B^)]7gMNf;fkhs۸%jR\g]hj-} i(!7T A0jϢ/L$Nwh`u) eƇ)4 !>t. X|a;{vADwC]kBpULb1 YNLuƟZn; U\4ꕎF,1RJ>Z8icLxݻ8 ̈Z(cфAa؆"Rh1Av:{Nh'&"܆ijBѵvd' D˿W'2'=t 1t#\eP:#=;܁>UEe Tcۏ67AYB䶆kޙ_yU<` %$$AfqZ_*H|S!]6n1K̎}`ݥeߧGE9mK~,7}kP<K_!>cLEk^h]أ(;k^=it X1ыj]YeiPr{/@ڌ0+y|3@`L%0^d0D+!zŮ!J$TMvn@ծ4JҊ6A#2լ]dE.w\Wj(M'4RtYpyXg@:@P{w&![T7oOi*2ETѬ&f~ϱfJ ۠n)=2}-hRTo.ŵ)Q_S a#fwGeo/:L%q}SBlb0Ym(1{/@Rg5E0Z{{x;[%VPendstream endobj 303 0 obj << /Filter /FlateDecode /Length 4875 >> stream x;rFw67D/FXh䞠Gђn[bHG*ҰjP^.@f",#7J?ZܞrBۅzxq~77e]dq~sbѲB UL,w'eUV)Rf tq|hmcvuaIeYk%b)n`eUї>SxNG\b^N2Ȭx^/)GTt֣Šo.eJIՏDҎ1Qw>)gXA^e pŊsX2-%(r%(/nk(g5}kyؼ"xj>o,,f|,ۮ]e?.΄pݿx\QRUHˮq@u^r$ؿl~>:<2Gg,q8LF.Y.nk ͝Ó%/%v,ybhY/ '|$HHkU zsA<E~cHqq''FH*ukhXXӆhv6!2>F>_^ LB~2p˙8ij Γįµ=j._J:%vp+^4OwR[P܅@o(pՇvc *G/PQ jn CA{v{^,Z<:OD0b#‘s9RZT}bҨZ iC;_3[é>'N8}-:00}}~ÉubwaDRRMߝ ,Bx_C8oLzc{1~SC^st,]!6є1q7(a*H @뚀YC,0ؔ@a^lbKلف]07ieDaU-ʩ _ܾRp7^ogWY̕uR{Gy6!2 A:}Ƥ`bshGIZH.)h p,(2CY>{͔RyX vϊlPP#]6*(-hQ I$͵Pt}Dl*4+/R&B0k_"޶w`NSF`i£NwZ\*iໃ+툥~n˾>h0]kdɐ6q([~Э*Ts_7 ;ck,}x C)#!8$HM1겚I6ckmX]P^.R 2F˳lBЎk! ,y zn{7w@M8gIgxy8tv l 1cKLa  #]cU+I\J1.ô ~ӕc>Tq_}T8?_<Ϸͦ>?6?z:E(x1'ڗv{?7oKgv蟿077#]m< gϦ.drh}e3 qvqЂx$=ŔoR wh$rq>bdJqHyN^{pD(04l5acq67 9Ȫ RVߦͮn _T 4g#qI?xl`u)vh9Tw/j> GwKkD vJjsꌪzk0vFC& x\Q ӏg1 $$_ 4rLgO?E@R~SM$upT$7(%@2&Z89-im)}2tP̢wp8U):T:t µ*E nK2 5I62uW̅v=1|SpZ1|J5}iӁBrj܆9]m"#8 B'jINf FԌq+t:@(k`n{q2 =,DYbFn!I<8ڸ8 Kp~LAbRi΃@w*58Y3զc)G/N&ɃA:{ճJPd;^Rʽm+ 9_WA2Bc6ʖ7[*Ul:r EX4df]Uқ[FkA3 bg^|W%㣥uotv%{>⫭72[Mg FlAMRЭY[@"cxѺ .uI{6@VBq_j>Z)a7g .t ׆e[fs2L@!o(1 uΓGU×Z%J+l% * E!}jWqG4Lu!)?9hc7Gd2YuJI?$Q; Dx&q4],s!fd ; HPM<0"I{d Ę#! lYNI*[#2F(]ϕe.7 ni[Ʌɜ+šPRNa噲ƠP1~Ë ǰ*ud) 1qR`'!Y *" _'O (-3NAuV=IgFV9hʜSZsFG5jYT#qVlnۂ_*RkE< Ɯ]cRx`D [Jڟ_N vͪRi/mEzmWKmˈ?I@_mE%̩)-}e˒x:37XJq5iMz8R\ML[d~Ix0lj< Mg4g~^4e=ML&qLȨC׺ ۿXNVOvMfiːQj'}8]$w Y&=:6\b2<hdhm,#1H[]!uu.мK Pg M% ~㰂QREc .$vlrj>8fwܙ7.n Z<e0hw+Y$4(&<-ajpw73IATHGyF~kkZ{c~*euXzTt=iV\v"Q=`SǠ?7mΐ ;;LW6<;HV9vQCrz gM\צF v0D@͐ )lw[HYd)8jP̙x-o:?I:13OIwZ2Rn>*u `lgiJ,O;DX|p'/>v8e%OòZP{kRʛ_f!ғ to{)wSU?ӛ0S@pp.1IW&XCijUJ~ǎȭG=1<[O.sF$cŋfƊWd%p$"'/ 6wZ%h*"#N+bYT1$8^;2{hRnPɬJz8CcO%BR&N N(Vw@`7$l4f)K\-P}gڛ {p8>2pjڡf~87ϸWendstream endobj 304 0 obj << /Filter /FlateDecode /Length 3911 >> stream xZK=, 0'$@,?rՁ]1I2sNU?nNH`^9Y^Nj/ypϮ/&ׅ& ;,y!(sz{qXy!XI P0Newj\1FaʾF]RkUx '(Tmk ~}͕6ìae}/)GxhǍ'e_/$/ E;D9z}.Z#V ))qMFs/W }^ l_ 4V=k-3x>%y4kPm_ޥȤVlqok{F6beCqE3LMj~'UyrbqLeVLTCon2S2)M`X(RZ:hHTε1 ?YlmH 1y\Td̑6!sAN-ʈԂRxոZ !DT`?6{aJFyD+8m̲Ma=t2c)8zVLJe6-!b< 9` HM`H-{ `i.5v>WG $$b9i]x lqj"G`?RdkU{e!݃'A z$G$F$+U$CzEʐdE 0GzH z=+f"}F\zӿrL:ʈB!T"5}6e79{ 9Qr=ةlf&Bk[lXMd>]+C1:e@"D¾ڎ#vm0Db}}Ls!XuM0Pˏz$B 1kc>5)A L޳2GFqTmhYc_JWչ,Z3݋I="F_o\AEf:t'Fdp+``;y󊃮H} kN"`ו慢҈q\#Z9A`OKAcs =z*DTer#r`#@frAV~;D% ֻ$]Ng w67"v oV kg1etq>;@B´"6\9 Q*Q-1)rt᫩;v16t2OPv~z?]/˫T/Sw oMkw uyy56=v}~z7LC Ð9{0FeD{`@endstream endobj 305 0 obj << /Filter /FlateDecode /Length 45026 >> stream xK%K_Qۋ p!RZZ3MM3- 3ss2=!t݊xWyϿq?֟o8?I9Y?~-:,_9s?p||th{uo7u^u_wy=l馺_oo]_/5nz/:%vdǿ>\WJgK}3O?9!_7ku\RJ?+h9}=7i}/y۟3S'N}أׯ5FˏTJgGg_uϺ{]?NS9;/j)}PJ뽽5WGJ=\5v^/j5gL+nt1ί#=9nZjk+] -\:@y kҗ׌Cp},:Nku_5,뫕޾m\Z5l8/OS?25]k9oqmwo]i?eճLJ TfmLtԎ>},ƹeP~}YL3~r,5e17tvh侌i輜y__vkrL1x!ǹկO3ӷcue-q׸26B~~Z~!z^kb^kb^gzy-o:`^v{Dk/oy﵎۵rw{5򵗷jGy-AW]F5Y'tny﵎~-֦}\o-o:ۥnyNv{uLK'kx3ʥ뀮w-oƱ˅v{w{|k/oy۵,_E o}&. }A⭓Zu^[{u^{y{u^^`[zȾ,ox˅O;nױ>n-ֱ}\{y˫W>]+Bo:륓5Ծ>.N_\zy[r[{z?_-)/[{5:5Ye }q.[{_{y{u'-򨮽ײ}n-y=w{2/w^/K[{zC_-r˖7-UW]Wzy{^}k%2Mw{^^^g'[zn-;^-lx-qMw{eui[zcox-v5/[{-^w-f""[{-v-oy5/[{-k\{y{*;^W?ݳxqǿξWXQʳ_w"v| G<[^?ZoZWYAZ^%KYX{?___Ͽb$)ͩ[SO^?u{yv[FBK^kȗ^4{/kyՏe/3[.^rUrE,⭗\zyw_/KZ.r Z.([/kyc>CK:-;d#k /WhˋzkJZ9dS?uٰ,~nrhNi>(/2*EH@O# A o?,קѹ3ۿ;Tȸoˠ_L@/~NJdpo~\_pP5!a,W 4Mm8`XwsZ.k7_wc]|x y]v\ҶYj<=5k-gq^-ko#x/o4׳%OL29 ކt8zkY_!qto)ml׽__eY MN._\zհg-3d[7n@r8ՒO΁yz[/cpa]-K^u[65$| .Є.ce֛-Xchw-y{\a{3>CǴND_85hakcZ]Q+x#}L a"3 f6.RKbkhf\]KJB[-e_ri]/ʯ -!S_skhW FEfA*OR}eâe@s-Ů[UY̍B|{c͝;D~\28Mp=ݹpiS[gM& .sVƯͬz8 vo\'[m>9ԚczK b]ɿ̳r-\&֞nk֩c)aᐶyU{I=~78M[<@KüUǰMbkdoA &Ir --.C_/+g=ߩ=p>&~& "2U-W#kWd˰+'Mm/.3GN$).3QЂ>zYxAJÎvB'?~aWi:DQ*t ku[v]^:QQd6NwMrBO BĎ}CEqh]>+XZӀ .!Thi4SpR(z(NuXZ#S(\9p:ObY`e绝++%MkdoNck,lj(:O瑬F(*냵odagZ_VNn wU#֍&Z)cqy{$dzXd$r6;ŷchڷ᳭߬L֟& >Fj c)l]Y+:C<țxhNFdt;xFRs[4RpOoJJ o>MzZ]vZ M5\ךVL\:љv!mKwb`?4 ad68?vV'6\m65`;&`&֬Y7#䊖aт;qEV2^?>|bF.!L_ukt5:}̇etRuLmKL<֗ 3`b[-7邝d365 $tH}xHe_fym|gW4qhUbU\wq[2qYťVX!eKָ /`ҵ:kֳ"u,'YO e <;n,fFj7[tΖ#"6>.tP@T0Rv۲R:I] 2 g6s-(v.Shn^1I& .'LRP=&b99P1nU|79alY\G @`=N9х6cg5_y(޳[vT48A_ѕu`!g{ɏmqdUpV_ώ\ǽv  OYN}h)B `;LV?vkJr4u eNs x6 n`M9fфd6cL' 8Xђvǯ:50>IK;1f#qg<+n;yӾG3?t'H8dΡxViy3,foGٖ}"6;q7y:eZXkKq3.V6Z㢭`MhUF~~XDB\0S\8@njhJ*VR3ۻ ֯OC߻fFvOtsP$ѯ-| GP1eվ'ltDTh v8ͬD?~D6m/5@9 >L{mYȌ,N:|YAZKmE _8g`Ω֛hjȎ) M`Uy !Z$aqt t9uVͮ0y0"q$5*z*,KY+ io0+8O\=nҊ>. MM<^Tl )[cj2=?z9 @ /1 ՞o8֩.S] Rܑ BҲށ #YIg@?פfv^-7h'XgMfL|c6kd vZBfK68+%V'P&{K8+Z4ώz>syvKdGpFC,? ݡX/3ɍIs^ ԽArZ|om=P<8Ű!ɺXN)HqHvi\i}*hiQa!UV!Oj>4@nzlB0>y":dV|͹)!jav&Ǭ SYN'ctv4ߏqXX=B-DB."xpG<[zb{ dχT _=b,b8-E7"@ d ~]'/J6 Nge`GSӅ @`IRH{*`ŽdcEfRb0`-'sKKmݧm.3j՘r. 8D-?ZNBD{(oD#Z|,0$P=;ط5oNfї$稜DE;=m40اf0C!n>*^2oFykYgxrpIvi:5Sj=ٕ'+8 0?a\Y.6݋l%2&5aAaؘ^?B>C!"Ty0XYVvq#ztnVlq=ŠO{{.gHaͅ;*Y ^bL gw\v!Fa@j9*t"6|5އ\qv7)W&7]P7(f2u$Æ=. Q˰Ia*V1@OsjXHx㊒F׾mfB0݁A=GsGw$7i;AQuCI#Q a9}6]gƠ: -q pHl*_(ybw_DU ,~0*6\{YN .=͹ەpșYۑ4䧵S;<7#2@wrd7Gt$IG"u$[# [d:t7`i@5?ܟJ=>{wE=u~I1_0vp#8*42- >۔t#`.Y/8uk_I$ AL2F`q.008[I/k yX:e:G>^60iIS{]Fx~vH$DID N NѯsP 4 QV4A( S22c3D )tqYyU{8"2,h ؅C ҙx*;INYa":fCCGژS޹c_V5T`mΆ^9iиQX!gr;u,"Alzr B.gœbCi͆ᒧ:}pTy 1> ]˜CA% F\֏0cahk|Luj!޵G>YɎI" [ٮq^ ՑɵZ>:ޮnm}BU ߦsCs{o\@# \)U2]ƅj w6SNgS/qK:ZRhދ$T!S,B c25sktE1僡#~Ѥv;- UI2#Cn Q Ÿ}@QlN%17qY-6@t2D$"eW bvK=uǑr*PY7`18pDҩauܸI-mz2PNDusL)tE:j9mO ) ؑp'53 x4W݉Cͯ;eH8S5Z]}o>v“ d*NW(J t[;wE._ENo0r `Pri#Jva#{<op Ѱ ䷦I 7_ǒ+.G:1by(Ϊ/Q\}-FUf-v&iJ5/f쁠űsh-:snQ4YOi;꜕ &2p۶Ї,At ^w øgs(>Z#X,r𼕣S ᱰrcp[\'G׃thz ]*N2so2"h)3fX$kG$N̔JDLcIa6]lD" ݨ {ԡ}}폀 ^[!N8E\I4w4{w7,rnҨl6Bd\{tP,ܴB6Xzj*PRZ,- zuo܍}ߕ10ʗ4=8%-?6sexᾟ=~7E]i #ޒjyMhDK&;w?DB b8^W ! /imbVfbtI̐F.߲ rlG5q  {n'$!¶iQondSF䠿A{n3G[ ?ot>&骇)\4L~j>ȩ1R(2*gT]y~:3war8As; ˇRH/TH- KBd· \lS 3s"xH;7gGQ֚5 "naʍͿo"1(O^$k޼2=]ZPO΢)Ϳtvz1tE=o(g+g#D CWeᖮv9Fh{%'NhcmL}H؍I̐yO3Nټ%H9M@b>VUtՇ+SI#Y;v mn`fZ%E[).䫃KOde/CS\-@x=9aQt8ύӇTB$D͝/$hpBD"(pm\;6<`,7@@G?=%#t^2R^&ߏ~y GN#W cnnozxi@E@Q ,Ht \{K76{ϟ}ȱq &Ґ4KrV1\^5Sqi-RNkQL5 Mֻlcdsm8[$򁏆MUё-j=CAb?^4$y|pn`bq~_)B45pRӰ?"24;_tQnY+š_iѣ%se|%=B7'k)Кa~6$.,#޸hi6~dym|kfC+O LUݜNEx'q;uh(o~AHBRxGR,0OM}^]s>=^^ *H7;k f'S_c>"+88Tĝg,kH~ HfK.0 Gg 'n8"_Yڏ ynr[&,4|W]2G!.nƪ&kڝK eQEg }D:*]QEl\ö́(G L:i9Kh| 9i.mRK/$q_{]P{>ǥfa(g->7^-n|7d) \+N"Q99?>Q}ջ?)nXI9}v~5f( f c)L’ EfS*jEi<K+C2Ԣ做h$XɸNl6NwsKɑjVlC1UŽ1UN'Wa]Ppm`? feo2~\q;[FTJQ-6y JDKD KcT˖6F%#0Wf6it2xN r"ʤ˔ nBXo[*Ѻ_텑3kAXS۩{bQ#ib12v] c$7ݤ-A?VPfY`d# QIh,ʬiy9v›<l%%JH\d`ز3!N;5=&RECvdmcgN&snbB;5 eNo@%P5$JVN~w&V(n@Y;9"ҁ '5HbP3Qwgy!kT*u %3 #^+Ѱ: 獂"zh~%%v܎7wnP,Z@SZC"p\"&re"&0nbyP:~(%MKRJ+yFr8v|8 MF1ŒF 7X@&m3nD5޿9m>,ҰB{A.⎒LL$w!ZxqUÐMVQȺsVuYhMO9p>_.}F`D#%2jŅsqHN9el[qjeґ'= ACQĸH&K2FnJ3 lӑu]a{QDzMSW =3[s=\7 Ϻ6_EZ^b5PP lWsIzm}?6@1^TPڻ0&eCCv(N+ 3ۆ|Z-Qbݩ@k>b^)oɁV39)G3+w-+aϲ`\!Mul$6I-1yJ]؈V7~G70oe1S,6fpL4/ o8gyuvV׊\V8X`3GB~o&0[~dR@#3g%RS҅|p!;CD8؇cb8r`(Ln1L7QOqa<1b"k&2k&2t"3`U%BPlPܳpLU,40ϗH *fVwV9T/[ߪǴb%9x+K"!L /C [ܥf-eh_-].&q.LaP?z,J ZC>Ouf&ϱF4URIsvz]=p"+jG=TBh:A!A|*{` B#[V櫄r͌qŰ~~ nbI"Z81xW9ɸC2 $]t%!WD0PNmJgȪ~NE: ۅEr3yOYQUP 6|rg\~v/EF:b9hbX9M;'-x +%Y, iTRڔ%_1u缺f9xnx,յ F <-<5XۊQT9VH;TwA%OMcS^$C <[wTs-e۪厵be䢾[ Dҵ٭ W.Sl;rkѶ}?Ý!OZAb) L` q)mLPk>iS:8a=gzVi[f߻%`.oلcaI>v~Hה$AX,j+"v/.$[VW$eÀ6q"58 1(thXLSzzC lb E*mր_>|c)«',wp_~h}(d|u!?L^cTmR;DIW.صv>%I#-)=qڭ}~$*a_Zjͪ6XT'N"PS14KTw㫦Ӌ Un!W%a}FJp,A/ˡPM9ukB5)3< !Fn HBGdid+ ETBKLu0!cSnRs;"| dUeFZ;%~eE.y,PX(mY\QAc8!Ln-MmB^#X+wbV7O C\EpxFxhIr$wl\iaLj5=G'Chjkuo  Ex56N%|rx:~_}9]J)>6㍵ۙ=5< nG Tf7>C:ΝЪ0s瑆%x6GVT8bY}ܟ <&UW5O)T1 r΅9's;)đY28vF 3OQJA^=wƧU[Ǔ`(dх೻*oiy&KLRo,6^VUS;mv%J0 g3r_Pmy)4 jql YhY"2*E :ZmWE*nWd d_2.<;GE]}rYRM  Qic^i 1YBs KoX;plI>O!åmM4:'/8O5Т˔r.?Drbn`$ғ^(:3b΀kyJrj2X̢n5W`ǶK=bR)MBX題S,AŒQ~\mꀽN]VXV'{=tgseRuf]p/J<7OWW- ;2aֱug V>=Mu5P $1ż~J2mUZPMew±Q3^ÕU 0lj%}\N|"$WY&Aڵ>aЌ:~ ?ʽ^6Ei?mfJxY}ف;53_$"•jB s0r2r3xd?!4ƴԘZ"8rM"361vG.Txan#~8z~dRN'rT b'*w=j=Teɱ,DerGVQyaSrv'Qo i4zݭ>ƹ`ncV:zϙ3STZ2HCU=/!ʏMOįw]5 >dyy0eB0V]nsO9v1/|;o*$\[ S*/JJ ;,'QUR-ˢ|Mk\KBu|=FM&*oS9xCh-N w2}D>o Y]pC=& Ĉr E-vwUC,'ٞA ~(+6LQ6a.l2yu]gSh烃њy0x~I%IEE'Yf)[aN$*{4m r}p G\G3q%K}^s;l*NEEvX;& "@X[7UݸAǚ.{N|=b2)fƗK 02}O ;'*pR3e` w1QAֵ~P߼ TSߓI"Y\6sY%w8Eq2~:)85K(cJtuS4i,6뢘݃]ū bZUFl~l6Wxex&} GNVFd (G7ɕvVrl,Nh?tXrK>1G兜JΕU4o{sBu^µ#C:/7.^QhʻƃhYD1MwtI}W 4ؤqT)|a jDtr]߻EߗoAhyvtQ`LuP+1m$򴙁96t.q#=fv*y >"HT y CPE gz p}W;e-TriFPAjt6bO w ge IUʕ4 dHbE(oz U>1YoXrbۮ3B5k*% \ӮG׵O^2-ܽS5X=RwUYE.VaBf#s/RUllkVIeōCYSGd0-tN/s翋wIN,F{mY,aabo^ Đcgdy ȺĬcQU^"@e7Wuܭ!MЇd6w8_hX%,}eelV5č4Zؖ}8ȘFj$Q;2 e*IHeљ`9?ىYM͹U2UtpM^wZҵ5FFQ&JDٛsU/!uzZT2xi8')DM/`e>}W;}u>cTOH"MHT-pv=e)vKPcFE h1v~Ev֭^%n(a9U-m}* *}v9fT.mG)+L_"CgT? v4B: |p<Jzp!eF Rb9N/ie_RXn~oڤ߮ŨB$f[5 }mكXT(k sҵakJnI;UO:s0-wnc2C#GڼbuϜ7 hdAgp}Q/$Љv)׻W'\GGhN[Q"#m2XvΟ׋ĦKIU74ms\n ,&>6JT')AWov*Uúayg0Lm[,nwV.rz}7:º"2؄2EZ,GZ]HḑUVK.JQHcQKj T2Y*O,'w>/U<%f!ˣA2 GKaDĘ8p=!M_gRH`Z?$xbIC'&]?GvgK$t-\՟i 4NjF ǽjc`.b|O|.SygaœRgAxOwVU6a:&`u*048?!eꁾ <~U2fU;#NaVD)Vx$M5P O͐,J,-U(tqT(Cp)0rguꖣp֦e*W(̱pFP1̀ҍut rlEϢI$ &4l[P\ ZΡc?rYfM%U\zqy%?T W8nHÙi'drF1*?wTޒ$!Wj|b 9a'G0+^z3AB7}ǡRݏCP_C?1F1!qM5 o YR/[ FM8$&Mq`iʕ\[ G*[w 0Ѐ(ԧ)\sy]R|n[y*;(4A%Pd8ߴ0EVW,1Clwbq4gp2ҥ ?[WQ,i-e6%R;;5dI;O`Md$pP T,]@h2 `r 4=5(a./5%LK=o!a4,t.Ɠ^FԈI9fŀՙ/D9+88Ğ `P {PY )یzqnî*x E z\rg{-#.0?+ QL[RyRi3G2ѷZR-º}/ `ܼDrFղ&w[&o]1u^jY`F){[L!>$GU\n$]R!PujŖA5&p9;q%usT8 fU54RDǾ5K@"BMiԿv&E]*G0UHm۳wC H0*]l?[ Gݨ{oP*[:鷌e{h]Ř_ ii<"] q?eMgba?% EWIsfCL I!6&x?=.c ޘ}Q,hEP3eJ߫ ǂılqR4F&`5W(1YUsH&% Waz bg[,2\TVՖ4%#|+X%ITbkuV"(ݶ3UfWܣr5G'Z<;Rjk]Tݢm%g1^j@|Ǚ _R)U5(ideXCfp0OQwu!n5m̵UlJɔZU~AOU/ J0@7"ASO{VBsϿcs36 kʗw>_f*d O)Ōk'(*mSeethL)TCA>̧oT3^R桪GG༕;3G`6|v2(!m""wϠrs"1QGAk&Dɚ{WL yc1~Ef-w(ܕМmhVL~phK(gyј#7i2ȇӒT{c[As %cX:K<J*ߜB“fbgJIÔ,J^]% Ҿ׳ûldYL8vs>] G`퓣)Km$:SCkF:w8=ER@Fن@KdsSӉ`&0@~_'nB30}Y =ðcl"+M@*n+VP!U2NhHD"=ww/( `bCP^ "WțDڠI2(͙(I'#sgUgDp|{v)'|1z+Sr†3dݐgK&xXA*dRLq_\Vu6(;c}Jeн]5 SpטDrgOE9S%>( Q=+-\$Ғv,HޢE:ju,ZIRJne #r 4QXѭ#RUߏrVA*b=HgEy(ep5i]* 6<%`o]~Nr*|+c~k|7{s^'d-&2r$ac (Ht,Fla'۔끫ҴC=wkDJG}fHDzI, h<Ӂb%. [Y U{cX<2*v.ZL3ue].k $PhٗPQžZ8Fs.> J+vȱoVF_3hR`ךU QOwY>"[7jEv̸u7,q4gV3=.j+"':K:9T%i+* \#\4ʵ^*jEo쮣RM{0([O;F7(erS"DƤ;C{/O|k11@/Ⱦ57ҕelX7ENzx}Z=}Z(x~T}4zkCJld~'|бK#NX>8hmǗU-ϾZI51R fcwbĵ5֪c{X3JaX dTtv\si(!E8 y!1>#:燯W(n9OHp)OְPgww :A)}cXoj ͞.| _ʬ{KCtV"8"2TqYV 5B^X"K=d Qq L6VkQCPP4XxwT!r]]Sɕ}Fudˇg{6=N,XM-WZQh'/VFRL&a%IgH "q+]99͋eMq@OEz߅{ ݉f4cbiwSCujcO_5(v.\Cz'|mh }JV*OR(ս 5EOb@`A< r y*rZ/[Wb:m Kel^!(-BVXb7>"["DlXr Ml>h-qVgr(6Y#0~^ l@Qk0nlukdaʨ]Y]^J^Xkt%m;PIn bswj"Ykxq"4M݆ @DTQNl_ĮAHEĞ:iW팎i]_.p[uA(4Ո $w#C℈#gND79axNMldWq"TIԴewV -4+Ф(&.<{|Hy:ÚzLpJ~BW~>LzH8mpRVnC9:xR*bWx=׊.rY:U &_o9AS'D $}؎'. éMyY8󨟼u2wEfLCyK`BoC4@n 1Ғ}-ZDh"kc90,FW+DzĐa' G Ydޣ|byP+銥p(![5BsGb00vEo>\M@&(9EH(z=MlRRGQcv@R (f%%%̑t'+ Wd9L&A.k?C1#o}QA/D5cRwz |Gja`Fb$1V@TD0#1nc1Pcjf1+Lе_:o`#rdM+KVGZCYغUUÜôg/XṚ"zTM[褗%7.&DWeSivh & ]*:~ghg l8R0'VD lԙv^cUZд6e.jm- <"͚ڞ:Sd) ZKw R!UE%UBZީH4h8S ~X|y#~圈.^X ts3F6wީ D}XoEh A?'KĊ5@0E2^PJzѹN/_k/}.?1>#հ9[bvRI v4Sj(`ӌWBMo[Ou>GS3]=թ3! YRbMʐk!z۩Z4}ms՚Dѧ$T*fRa_ XiSP -8\rQȗ=r^YIwf$_CSSc2A3p ,x !ksw13O%|YpھuHO{szW=]WWQo!Yfݑ(E`P℁w Tn'۳Na:#aE>|d-Фo+<ӟlRU< Ўz7 p%<$4^)Vșirc8d壋VC.u 5EcX4/ 5N? 8c,l$I+gn5g1,b@ 0 ƚCi<`G qG0@eCqR6I!jqE(FcWI>HG7Zwjw푷zU#[0'uzN2$/yrHMFseA8y0o ͤ{]eA":HGFrٟtH.'}`&;mRDjj YL./ aL\x9wI Hy|U2ŭiC!^|%ߝ_X 9ޝF?udKeL1T 4G2\W)o?ڐ,*(:TM%mh)k"Zn֒N} @qVt&< cSKNiNg4o8W?mCtO;4a8QK^/ruYߑ1>x`=ڊ\ȇ@%0k%>c..ыT IEp 2"6+E`Y'g=jG21PO#@_#܌Nm '#d[Yjm_<ȸ0Ǻ4}(cSU”rm%nxtOv7(.SCyLMH_w&"zmrτ?$dޢ2mZ# ؉[ʡҽR0D-Z2'pmC2XbcjhID¦҂pesyb<:ҳSsd5UB؍Ha2Ta~`;&FstϘsFc^)JJ;E'銀`y <5G aindžw-h-25:DLK'8 M^j+pPJNy?oS<ܡ1Ɣr8'3jmmZ4eM&xBԁoZ S)MU펦 nxzfe7?[9~߮4c'I-B)Rz$8lsGbiX9ԇ5C BtI~rV0'%y~+_{,-4VV !:^ySDbT$3R$hǕiMc+ ^fuͪWYu=$=]-;u 7{.eSε@W Z^GźH|xˉ:Qv'H$a ff8 Tm ti d @&u0u i;%&R v[@6Ha ߊ| #䩹 $rb:U%]u!o"^,z3^A)=]_sKj>dDI(%v@M B !NxFC=]X1SZOEnuCh;3"h Tz&CӌD8e\s6U)Se r2҆P'?kxy2V8Ҝz و{(U0M+tN>YazWA뮛stǰ0RGmf (GM!Puv_μХsJHˇ.d)h,Dj:Aꪩ)RU4XCU^C4M*AfV]~֠ovE_VAy`z^[*Q6#AtK_Kcz:KpѣjHkb 8`,*^A>Rx P92A6f řL}xktz\jJQPi aPU3eT f"Dmg1i[]JV8` &Ows6o\)Twz̓d3fɕ *QtR<5h؇:^!~LD&2+Sҗ=s@ytQ ˞D\dqhm3ZCCqT"#6; +D =6BI:R#@_җ t?/UFz$Dy{54#yf/ go`п,&i]((Z'V0Nl ZX ,G!TEIjĖld2=E[`t: >$,b3|HȣJ?CAg Ԕ̆n(QtB4`q " hw3Or&eȩօKwN:(R<%5-2QjipI@7H v|Qv& vXy]o=F@ KR_`o1a UdK1\YJ YU,]ʜj'D2 tg0Ȕ5r?a)+d$Ż~o${CQ]˙\e$۵2QcƬH/zBZ3fQ@ kj!%ͽF Ief;MPeftb[QIlL)q U{WÀ Mb m3e*80qbbS/fRI̎f=ED@*yLZF,aU4:vBDS!Hb`NZ'VZD:sBbKb:_tel dսg$[TT&l{lTAۑ8عL>6&n%Ix J eU}Cr ɾ Үh}UhBv^T^W*Lsċ%txi;@:ĮG_mɷ}؎t +BןZ]/ Y?r@H $򀫄e18=bҒOeUG jcSNGYߢ[8 ~ vNaY&5_ YYv):F敊XfS+b3e3rGD: {S)HU5Jz L}+VBXlJrWn߾{B. aw9=TVEZRfU(fɦU|J^2|ɳw:wz<TAY-bVbaa $Pɲ@IL$QXdH|2@/8q!൚[MHh帬W|W*ĕIkW3 m1WMYY#h/%fH^.i^M]T8!%? * \R>Yy"5l%ZGeDTّzpS΂'$'I$5{/w۩!_撰LrD#R?KTצ-#r<&kՀxysԴ( Q^̰)驊1+N2CZE]`6U>kO0".lBcNO_4SRq1," lTn̛>F4s0Hro^n 7kӎT훌>@]Jrsn-#`E9R)0_/nr|YJU%üeܲ./W=!GQ.P[U3dzՌJ|'NM6DÅҵvVEwU#˖*P;Lʝw:n7djm 5^Xյs<] VgfE7*c΅~`ݶ~^ ߻J.#jBEdU]6ߚ0Y %0`Q#E#ϖ>w:ٔNay՗`*%XsŻz`g|װ~`h2Kwδ@\ᆾ@|D}p 7а\GT1ԏyeag'6WZ S&.6jdM7DM8/ALYA *$IB!:W>Ȩ*$9،" jC+\2+J2 ui*W!קM9N,I__Z| 4Ql)jNnW,'LJ0A\VK7"jǂ~W$ZZ9K2c ?Y5.,&EDx3{qC1-5 12]bZ;rrzeb]{3ZDH:^L@7({|kLaQGV&͵B\ V UhkI33"G Xl{OWNBH#Qf WyJTגwv]Sx. soyV!XMPi D ҞZc m W|\0 .4rtΑ]: )iI?{ߖjrVQ+%rc%"WUlC"C婜X&ʥg{B,NDj\'eX/wFImɰ9=>W=e_cQXC$nVE8i=U wҚr$V=~DḀW1 ]:X+RW G):DGp,B8t+gx+ޮF >,__HZlҞUCjm}eK k%BIY*ܷ7  ~8jWn$]j`e/-Gv Q~ji4 $m&3w N$G )Ǣ, ahBZ0I,[/TRD-vmjD0o:oKv6!cZ ?, -4`T)&4ȃcŢDG*0"8LkֹX}{&᯦>uwٽk5]ViQbf/|i@oA^bH֓ekrd]dT5MDJyVSM3z&7о"'z * F>5voYLÒAZ, ܧ(0tPG;h4y5=>o}R)2/rX!L { Y!b:TŊ'q,kGv\m=)<|R}%!_6򥥫Im"tKbɞ,`zE ,1[Z X*-XAjWtLEZ!yd6P;WS\E5ٓj[c>k6ZV,jPڲXvD]#"\)-: "UᬑIx6;~(9FJ`fbv;U(H qڋ|:H Лy?n@$("Y/ QG):o62\YSC+>Z\3X-b|bYH}EC<'00E >jS(ef1ϛ1ꂘ7~FMbd L/lwC!PCaSơi Cl f[A;r2fIK*4dSBDvHHX_ &TdИs@)V䠺N~"LUiD4 [v*R[1EŹN#RzNnfY\ۛ|AۤP[g|G ^cH c'L  zNVӗ0CEn˱%Ƌ˃>41ևea egV(SA2 Ji0YA#U^4!<5I{E;{zW}dlgFeVnV3X(9Q@xN6yg);":;:@C >*jKNk:zmau5kZ$`0Ѩn#~Gnڷ^w^0OA=xCAbCB>,fj A3ysRď%p8/_Jk=;jSx^] wUoVE}ӱ@=w\nЧ v^Ud6 E~p88 :7y=۵}O-sJY  uhK|Tt&{LB,/dq!v.ߢqSU[Kl9kbmŗ+O bV%5ֈܾ)]3gڍ*63F} eR4[ș=mYx/k1 Ŋl.,4;"?AlY#`=Bԓ) gf$qnYcO*Sl;t " :YݮFȿDž?=>G\ r_Pa%/+I Y="u͵`Z<Ǣ##/poc L0$gG+aL:o-9:kVU7ـ\BZHmhq=%LV$p]d/T^!Q5[ej*?7˰'\2 ņpHjs$&"W{}m6,$4RP<ʼn/[jzo 3앵4s k~+u_r CRۥQlj@ eF  Atllv"H~_ 1Uy5j M&R/puR$$YYvYΏlʶZ7Zi*\KKm˭WN} e?F ^> /eO!чR%A|m&1 T 4^߬dztf#^9깢٭2̗[x$$0hȋ$&"( L s66V,D@] _ZԹ\DM4LթY# z=kat:& }bkUxN!!{(@zYmX}^F&HޫշzSv>[53)<)yv(yq<AW¢m#J{gbd*2\'mZp):-hvl |\<Xdn3^;eW$X(ѩ*? tLk$b,iZI+Zt_l)R{\c[H|Xq|umZ<&^ G>J],@W+;jm~(\j6*6(΋"JqV2+ > 2'<8RDw#j[5`^}оqDWekkh;Ѡ2і[Af>#|3SN{k޾bȗLJUv\K뽌-k%,trk}Wzj_f$R $KVJ 4gy$mᮟ N0)¨M[܇ ~_Ń.+Q"f_` Yږ=gSF vzIٕ~y\+Do,@9u}u᝜Jv &#i @gLbe9S-jq^U :Oդ9}-|P/Ɣl9PN):C,Uz{ETw {>5+?d55!#Hik1ґmdʡ%b4F +~LY8 )lf(A5:caEQS!hx+FOFLcͽwASEXnBae__LiPX;Al@U4:'{~1,:>^8~px# WXt݇;%4rYQ0q2?_孯YD\РPN zEe"]X!QHQ %P՗E6D T UQ8ٯT] +G-oB m Z|[2]T7#`䗬ksTd22f?µ') E2筑Bef'-֩rMw_w~\c KS kב.[y'%s{[݂ÕT*TӤf߱_)` #4b5A< ;cW.Y @/Xn:6u0H=AJZL{qDfu އ^tʫx{N ׆.ṒO邢>n`؃")В|%v²9ڂjq ,.S%Y"BN~DgAʾ0!?q#菤 V M8EFAR=P*aK=mH)=9J[@5B&JP6>_ -rCxL>|}D{rĨw( ߤ))[A%@ƸVw\&yL&$*Uc6li٘MY ;o]/j>.02E1*ɻ⫌H0K7G/Y(i2 .ފs}*13iY2Wy,P=qe'/@6\$W`2J&S'w}cTaO,>eZDtiVh>hE2i-0nZ.3ەw堻@ dDBf%ZcFo Ɂ:"A mc5\AGlu]3, 7L@">W`*NE_轈ʤ ‹PYhD:gw?uLm2hWj *#Ev^MT7Mfe+b7s븭{hA][ueY ^R;+QVk}y <':='׋](G`"+禾yefhBV$O191Gؔ_r D.jTy .E8/wwQA[B󕴿u5 ff O!(ģh%5{` ź"x旮5Bf-zy@@D z1NJEmCd7Sބǃ] U\JeJC(fy /Mj6**!E_?s *ExQM!ʖ;c*(L&7?>*}_GO$fUXj`,ֲXQZtFðm@@R`>Gߍz6dv%5+,bH> "~XP cÜw UD!UyJ2k%} 1mZ~UT>1=]NWL90ccuQǮ4Q:l 4R5Ԙ$$MjUB Ӄy@YU=BzC=''JzmTSr_Gx0Y?Лu^.(T WZ_ D/af}VzJ*gV(Q~a:ɂ\橂Meg,W!5}%l~VG>>^o:֛%N0yY ,yLt@SL}DKTOa5zXgF4kXcc}ر~zthWxMPV"Xi6`DOb(i67՞$([*؉'6V*:}Q͏_v~H D`8wiwJsrjŵNfyCNhR)zW(CE N{,?;- ç0+mAVvBI*~IF N|us'f(DPRݮG(/rT#F  SBi0Ij9%(͕bz^de!y$MI-16$Rwe1oDz=G^-tR3U`@ř4ז&ɤe)  6Lo&vIw+qkJDUAea-zP{⯈s#QLXiՙMdŜ؎^.MӔ1՞7#tK4â9cG$4m}LY嫍SkЛ9$fo",ETH9S@ Yvmwr2sa絏HMr ;7 /s=*hf(S}ꉣKO5m}vi)n={K.kG@OI# _q u_ ؠ^F6gN[v$#9{K6 )rc.Bdp)sZM;{LwR"M BMi[PjyhsචI=DEz$+{Fi!KN$s5SHėGݑ?K cL-:Yںґ̫q0ڣh!gpfy2QC\5亣轻ݙ˘CQ6Sd[5q\gyetXu  qFQZB4' 6EV9Q媔%D |W(ͿÁ?y>Ƿӛc>77Y}3xLsx U8o~ bGFx۱vM~JPfYz VxgC&rعQ<@t:KGx >E!#Q`n fc])i%17GOU>l^)%-^٫ʹF{Wq^FKP+٫3}yn-罺Ѱ߷~rޫ{}yןi?o͛uN0㫗]ޢ@@ =7_ݎ9fz>Nbw凉4-dk[ &6KYiI_7cbW,Oo>Xu|3/ۯ!t$ܾ}=j S}|=m]?|{$GXn9_z7WqȀCw]z P<=vպWwk<|zܾ|__l|Gt\fЏ[}?4?C*>\MͿwwKxç#YϏ|,˻o~یs'>Ͽ7?>Z οɯ=؈nm̷wD/՗KsGi˗ߜ#gE̜y /vX&G+Qn&~8>[,GxWt|ǧO?GćO{#M| }z[~CU HsoHNeZo͐QKm柾iLG=}|\uA$^qz*~@|Bۗ#{=c#{?=P,, Џ?>~w\hٜ~z*yiN_'yǟqc+d,#~˗}tG}{.y|֐P_'nJ'ce(%]ip}AXJ:}9Fwtd6=c,7hk2fCC#3Oڟ}U<ؿoG&g?f}ԫ+[N??s;8~,cH7C|1#-M3f8;v3@ܚ<LJ"WNS!yA=(⃄i`Zl?H_-n#YOOd`|Gr%Y>.+<}v2qXo:>XЇW>D [-&~S34óhg*#tQwF 0?rT%G89rM8nsӎw͓=;"_$e9eplSͺti9.t7D1L͗S81dЗk=| |Ph՛mqwc}eȥf{a 2B=dߍ#=xzR&MO*l?I蛭G_z| ͏{W-ye?/XuvnEO]td-#ڏSWcY>Rƅi}'N$qJyCa}~rmV3`sͩ a^ Ƅ%v_!(O6G4IS_ݲtWZe9;ay࿑C?p59oD(p.BZ5a{%VGZыX˰N,7=7N\ev|*wibx\Qnd|Q)Bψ UО^2|pQMAYy_[r3tˇ]Aץ=L _P(wJg&`[٤/ӚAw};K`a R 7]ҩ<~ɁG7)}w>\rTﳐ`!%p椘|H[AA1bl\J-K7btEe.Vԍ%vodl2e]F_~xLO| f; #A-:^z:ʬч`K?0]͓ltD"Qa Jc;0\[~fLSSCɃ/(ciokL/~d埏wU?ſ%lmwT~%qBw_˺??oATKy`?n[ +{z=5\#2EBgږ9ږ7 O].ٲo(nseMtݦ&}H$2+]7tZFl*]͘@l;3jG ~WtzPS2H0}0-.1f7WJ4tPhPul뼺!ދ~*ZRK̞fhbр~WlշF0r˟CS_^)H˩/'˩4'X^zX$8(3W6/ߴ\~g'O"z\HIrRm6 jFDhb}W·q3O(|A@"Q} h8`s?O|3T6ޏrO_8~秇/ȡ?|wPD> stream x[oSއCVGsAąNgw IKߙ]rr1;;ோ"g/v'bs _'g ˢd7-,[eR$czy e<؊3^„˓"/,aE+ٮpZfVR6gpoh !D^suujglKɲ z5v*7gr7/4ptYvYrlS.sWBVk73ul0,m]tTcy+zMz1:Hiyq~'j|dr ,p$$~z@<^,˪?LA`̐dD/qMAűȴ&ͦYo*#%lkQXqV-YP,z Pf0MhEkdsŊ\ɒ~`/K ȰG lX9e)4:RXy> u-ezrcOߴ N%؊Io4wP<ט4`fTE\h5_:$'f?Q8G &>"O*}f(Qj#oާLZqfsֈZ/Lދ7cBS)ePwMۘKA#0YtrզWmHuQ)D`)7oȱ|HXP#kaՁ&%nta|GLKpe"62;elLݻۜTZV_~ʞ~z?>@`cj,vqYТz,gQc wWF9 y}̎> |~}l֗?źmԙ1jٷIR mmA/&ykS3sFvd_Q\B*5\c8]9V+c 9S4\x8ŵ~7"{ps:ܮm[B2\K:zKÂN7a? P!еyoSOSzh-v+!SrG?ok=Rj,jw7Hdx9ghOSc@ J\`wRtYդ[IND=˩Y!=K? C"*#cڋ`/ 6k&&Qjq;^~G"AKt"<;ol\hZyQE J1h/C2莤}fn]Ɓxb 0Ԝ+N@xesF͘ ٛz>z D _qk]Η$AACx`<^-* ebw7 qA_8O>yJE{T|ܓ k]>GYtxp}1ʖ9>{z7p:ABX?JԁoDGVS \ѣ).TTB$%֫f'=h! R1+7>LT.=( H}Me"\y#ZM|6*);Z_2 9Q j(|Nfާǵ ,xy6<LV? C _bZ pGI,n+V=A>p':ZDem~!5ƺ@/mWrXhe +r&@wK<6@"B-FPJށqL?0v`0zV%yهx@.g% pzh:($!%$ gkv%oj9#[3D [BO.(;Øϧݟs%umA$ b0#LɜC½$ֳ\V GG$>IÈĜӶK2Ժd_HǡK$TZtyHL;qt!f:2ŜOl'MF#`6qQTm7NbߺÚS4ɺ<7S #AHeQ@!P (/xsQZEQ o!M XN󔿧.Ť=[" 3e^v^($NmTW+1E$iHg)B 7Mq]BI%6̑{t'V=`1qOֺڞ'@ԕ~4U6mZ\7JiuH 'a7F{Ü8ӉDr':DOWr,syިFquJ>[˒j K LA#T.$+Ps-h w5גx3*0R#86TL ILU)a#bꦴB"6Sb $WB>k@.PzNd#"27}9Ck!7tgyؐB,|B.g%*"JmHL<Ĥ@]z@h7p(텷n&X蹄KN.tq?@Bz$!o{{VtOKQIgZFSv":=@fuuUd٭ |.=չW|%R}\6yo W.*jx/~vl0Fg~"ubZ/?;+h ~&rU4 ?tuF'],v>$4&p[L$A:S(0 (qmz%q9a~9nXghi'o"9‹C|~fjn89ңAP7D2 n3/!4#XlVlש S`P3?$%H9[QI¤("W9{dd~YsF^+ O&IWq4(HYb|K?qX@;1{Y ].DLPp`XGx=:">#]r\䥊NĴ\e (QB?]T3KE8Q)F&qHHɒ8=j=D.qYA'W;!\%f Q&a}ӺS)ת;smD%}PRD)^!۸_V>: yȄA0ӞIahU>֞fmW n.jrT2V? h)H2䦷39*-|L.gpL<RHUåi}?ǿ 0e?Np_nBus{͋~Gp7N8% :* EI#9C3FTeH_9k?ĜmoF67yrys2gBY*lu57JQqcr & J<3RlOiJKkYXs.d_E{BjDо_ !%\<8I wae֧,D]EkGbMXe>HIO˪R,f l>s[=I:ҸY9x)r?y%T9G|6a'HaWIEx)Jtbʏ8$^[t. E_%S;r_H e"G OO}sW,xqR2v/h L]43apgJ+jhwN3 [d_zsX*FW`.)7Owi ԃH _Y:g V+1zݽӪLrgOa͝ dxF^ :`i~?BapR3-f٨2_,בaЎ@>/Wgg=^|vWG-EBeA )]pV@ saN0k}dQ)ߞ? wM` 3DvFl? {F]Sk9`1Q\Ast'~[ߑhvhԣ<X6ڟ;ƪGrnAy#:D).Tc'1Zu] >W0 fogfU6 b2{GPbU_/[+MK3rgj,=}Ore?zrEv6Qr[X6]wuހ:HŸ27 }l/^> stream xX XTC=ʴ4LTpn|su()(兓[i'-S'צyv9szyaϷZ}oD('J$:P`V`DTw<%3I>u ;F76q/.PTenƍ>}ul&ӞI:F~i؉GxaJ42ϤWڒgǪ![SݕY+*qw΍M^g :9ky:АCX%ƒ$F><ÜgЂ'>89}tQ%h *\l%m@Qi68LçЪؗbal)a[d`)(5$ G(T{u OTYO8N5z`/Nk.LZWB:"oc7NŞT~@n3)Dʭ-[Ta¬)o$u{cvB`jC?i 3@c/WP,^KCKNi9Xs0_IIX.~m7܁EXcӤat1H.5@ +^^sY]>5`*7ػAs>YUP͵z| T(BzJLaCTMH#`M5,l!VWZ2[QK+0#b鵺%WSC8êL<道j]V=z /=!eӗoݼw *%)H:÷"Jj^hw$||s.D6"2]* WkVBe>PYQ䈏%C"uG~Rx54 Im% ЮowpҤ f5{6k)u"P$;Ԫl&o ΊvZQdEd%\ ݧ]VlNLyza ;y|~e;6K O._ќܙm"*j;=frKX6c1ya~^P|Ŷ 3N+Pܠ0A8` ƣPM%hpMB aU&wioe@꺄ࣄ*aex%6Ey/olJ=>~Μ%ju\E[oXijeq)˃BY\9]էSvҊUِ$իZZvg=gbw,==d\^ d"/D~APSxtAޘHydp4t"lLᤱp(Sρp&iA+J,f 2 xwJDMIK K7Z [;>EP~^oy4>w14w7iXݿ~palN(ڝi k*ߒ>a7'u%u!p)my ]f-2 N":;Qf7^J4?O[Xb&Mݖ{Lt@X ?}Cˬ8'+r=vI=, }'t{:Z8ṭb^ILE;Ipṟg-xBGAșf=>99>9/B]@;ʰ-{4x^PVK?Pr۶5OC"S9SASyψϻ]z}n!Q^>~[ax9l*oݣAc[t{cb912=i{nL%cx-2ړ5Cwdd ҺL|S"UTNuKтV4}+AbC6C1s"C.oBNOz"t8Z zs{,PP0EтI/)L@  Ɇ ODkّ7.|x:HN&o"BbYҳr cxD&$:z&Mݕ >y\#29Us0u&GDGnA[|ح?@8$֑/bwp 챝 ֜^el S}'||x6O&aIЌ:}rώe5~ aJyXEo^EIģp^{5í_:Έ[Y/qz =~uΗ~Wg*aKyJbӑs;p pd{:SͮE,JT8z)ڪ7*ի$x:8}-]õ86u݁̑Ů[oQWba;Z&UHt99YE }2x仯sh^W|L/3gCV-Qтk8̭}3O^ܦ2 oT#)>+I2Ė$;b?kF$JDsXK 7c.={ۘʱRkb3s?]9h2B&%ZN =]\;l&\>d0T_cBWِ6r o9(anZ(ZcE~V1>$uE'&&%2[*8h`X2MD?0²>D.j=c4'>EAޖ b)Hy%F!C{BjMkʄoPhZr󓛦^/Rؙx!5$&%&6l 6-/Fy*A䚎\Ջ}8 Bϊ*MpVøAeVbb ʤֻJW,O ˉC-ݿi:X[> stream xkTT00<3RJִ]QD k`pF%*{ K-(am0ZcVlk5]YkLƬp]GBQdmѺm}֫5;Sl;a+)g#Q Msk'#SRdSr~{fJ&!UKV\ De.N\Os:e:!:9^WnP)CCׇ(W "EQn:CδX&!1y7EQ jBmB&jGmS+U{TH\(4'`Ɉ?KHM8D; |qt*}~1G; x}Dm(J!ҙe!vc*DܴqѬ[{-g&_]M\ $nY[HBgw6X!/GDVwebKhdZɿ+tu4rb|5;$#OFjFrOn]ԩ)9 MN3slsQ0G`Qy9{J50~)SQWѡ;7op/2ّ~:ZWth "3`_]+[zȥ6+^<e*k:<ſ*ݕz;Љ'ND6l䨌P7ӆhl{6NJK$TBCBh~4KXzCuWwг??j>L+e.Tm0faSJtVnOsJrohqˈK188U%J֣찥lDuHNmk;zY%8L*CC9Ǥ@ 42L?Xz$[2w4H80+(&0Y|_{}dיF. 6NሂL0`.&d7ڡGuG]| 9z͹N$q9_bGs|W&5`ߒNL2ċm`#spPNe^p%*p#- \#U Ip5ϧ4Mԇk JLECeM}p$QˈSuG^0_ǡQ^k.DIPUzX\RLJmfkkml'+V{ 08< ϝqIagϞ8 }ٍHŏcp"576 9vrՇ1F-c^2n~'::3Rl M4{,cXT5JUFwiQG'ܱ>Lo$7ti_Qֿ>yqs߱hbtA o֌/ })K芊JHJs lcq8npi)5KM5C2ɚJ(Sbendstream endobj 309 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1576 >> stream x}T PSW!Fjtڢ֑Ziح#AcBK`HH*B# E:bUzզ>vVm׹әWgڙ;w9swPJ"DNK3O.YYR1،b$ƒC&b~FB ىKsٔT"Yјd4rŋ-߉j]"N)(1Z7uj\Zz*nP)-Rم/sVff3s2[k$rfC>kESRkl*zZA^R5L%QXRaΔdH]lGDtPi~*s7j IL~VسYR20@'7AwVxݹnTrZBC_O>{3} B7/y=J~V5\U DW%x!^xS:N\fv8N䪫4 LVxū_QKxQvH{PKU8oYzo-q0?\Y. _^tiCy~œ(gy?5 9x #^ߕk[^) u&M*|ƲTl܈}:X&OEz]*M|jtflVQyXza )|5 NnA/jAq X*PSzr`I?'o+@>w@I1Qb2iӟ?wWxI` N!V5dFd͒A(MsOԶ{-pWY .;D|QsPD7@WϽK]Am}yqVc_|/zwm/:D;x BQ(zڪ6?ɼ@b4 -mCnnw^157 ki6B2n}LՑӭBbd_D&ߪ*6+&#d̻/!nQvtn`~b!Qrl="j^GBHb*v4+/qy|5=}.x4cm^:p ƽa/ Xjk/98ymj Bʙgk$0q,UGå`b^zץ%gA(JoBZ||)ď̽CG2M;v!.b ~U3Vg |{?'NKTj)Wv7~| ajyj2U4ij_gЉ>\|ƾ mga#/PSWSϦp>C^t*lsw̍g{Lh(Re:}U 9,^WPa/4U=fSHȴМrOw.:y-?fz$/^dF P?fU?lx^+fR/Nhendstream endobj 310 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 324 >> stream xcd`ab`dd N+64 JM/I, f!Cß^=<<<,*=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ g``` b`0f`bdd ?SUe/>0oaWw[V}GoG~zw#/ KUؾs p+]#`-ýyVT#3z@| НVendstream endobj 311 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6795 >> stream xYXTG׾K{UlW.{@EAAEEARg#vX5q$&Q1%f|ɗGٙ3}%o[`[S ~ſ#o-u6ӹ8yCXGi vn~=܃M-XxHOS MBj3Sj J-(kj95ҧP"jHDʀ2(#J2&QMCqAFQ(=j4CQ(k"JxTpZkV@Oۺ/)Ѓf#&81rHQFyMK=:lc>S3Vk,W6~ &7DEULȝ=qİ&12_=׍Vu_O3~דޙN;9čoL1139dbrHoD~m|b33BP$£Jø27E(2`zTBע r[5Su$ۧQ=,6?Ou;CVlS|^3"8Gsbf)[Q!Ό$գb)84t1Y]I#lEMo=o%y yĚCV }CC)ZYqܷ~9Jw*7FAzcBd,fsӢGT[yǬK8,Ph7fH!:6,`x,~.h?>gηZgjjշnݽwrGQ 1%\# Habₑo* g,X̆{fĴJ1',)6!KMFQ*  cl yBe1T I%*.}auSj˟B_CLw:kE ~Dbs6Zn\,w_(ҿvW͖p2y KllaK}Y ,% ;X9tfڗ5d#ؖm "/pM6;:blк}J셑!]R"~"kcb/(xxjG5 :^fP g+! (^p8ҢNHMKQU,Z=t 7|iV[N^xX<%h+7|?>|ϖzEEKܳrht*(RUxݵ`4'*!3Oշ%L&DvC&<nڍ(&U0G =+yGϢc+kSoB1SW><<=?tJ%rUHJBa  )wv3 ,x%' F.la l+wr]nS ~uVNRX Q%ԓ'@LQCЈףK֠)a/azmF'UU%Ṫúෙ(!#? dD ni +ՅraNGu9bxߧ;^ml/JM$pQYηgIOʼnZV5ݟmxbtѴB +䗁$h E^/RTn'dY\f`K?b(L͎ D2T{J,j"Ʉ^*ԈThN#Tx\Xp&͌ .rJȎ/L(DE878#.hjgb C.%tuWj\-[UU)@eFGBïhxO2C]nQ*8~,]*Q 3AU."QC"g,=K!eXǽ[FNddǸ~VԾa p֝];m`BB4@|wXu}~i4ʧDEf#MC~f 'ak_J{iZ=2j.8*C C?"p?S \Ȟ]q~hZw.) DJ6Jج q@4yCFڲ+>'IDW4oúebzA-PB 8]JQ]R*%TŽ$,/o2f,.YHgq%ir bbhY&S2ħz 1Ryt]BQ٢Օ/Q/j /ۃ6]=r¿;?]3%X(*xŶ>i\|k:}ʍᢛdO:*O>#9q8a<I݌Zա(Y" 2ƈ#QQO¿X{ y<} 5?xöDY)U72,tq=,MjiX;I#fCRxdvî L1sC!QdW¾;Ci솱 mVx j̱>~~Xm%\ީ5r(&x TP 1ev;nfUMҬO^x߼yrY7[sU8q@N쉤cdU_QoQ_8H"e,Ћ|qG=0/S%(l*B9d1lz;t[rX&?M)*;}$+>_UjЎiu]o츚`GD % ~?ɊԈ(+"o2L^<QXN=rϪEH_s 2V1֣,֢{|aA`dFc_`XOuf :o,9ϲ#W0 f(_?=s:Yj 宪ݾ}'?Dj/Jd4-}~[ZSp&@ClVZ0 yJ1I _@ *>/0HR_Dp$71%Y9\sc}i1'W]Uz5ҚʒjTޯݔAwa&«W-!׃PRZKqQ(Iϼ0e5L-7 7f-,!~EKJH#x5? !@°{j3!K+a(<3+?kh,Jy >ے{ُ8/78)44'75Z=C;w7|ɟۑ` ^egû=yҘ$HT.,kr41p,蘽D/@נGե6-w)$\lmz-*fzˋMUW+ꪸo_щa(1(D*vWFhlz`l/++hⲠ恙Zeyz:A7|\pa/:g9'rpT-'G(#7X&/d^FB ]앶vՀ5Ӫ/Nu+̓e(6~ ݲ}Wa<|#6VfT?N\?f-v.D6-7}ye3^d3xF!)p,ŽȌFTe ^y +zZ 75J"}Dg,'1/ :OqxYsECK3QSV( *@C[e|O<}Dcz8OX2 `?׆ǼSzt|MRc-^ %OFQ )wj ;#u#8!֊ڲlL*oG #gg1L|`5p ՕrG0StQ:Ξ=֓>qؿ%_'Q'H適=v\+]v[γ]G>@-,%HV?6&Ǧ&#iiDEmNyA& o7eg }\Դcspe~ƓEE>-TOӆ'+ +t-*rcr10 (UH #Rd~%F#"3)v1,H#]ZQXݝ'w|8϶"״B1Nv19;Iu*tqy( 6?CY^<1`)y c1 jc+K2y2W}$uu!&0QY"XPf+I " P$-k$T.OɢTy`٦b &5OPQjDqrS7dy(I"E $FY _8ֆ>Iw"Q.b*KTZx;I ;T;B#'lzgb"#PU%|8L*S`*=Xx0ӽ])x*=XT",lDi6c?v<ؖ#O"GD'Ǧ%, /khqCHt.;oBjLs-kUq1.=d]?LSS_yI՘}Z*ۙlIJ$*yBDBFa%9%E|> stream x=KSq3Ns (\HȜva, &91Zuэ6'Yl˗e%D=o |'({lu)+.iDȀ!mR; FT U/k߸w\ J$ Q)Rm#Ե R V%J!CmVrDr0RXL3) dwFHBtZb L+09 *^QvN0 #lbi`-䱩T-܊f[1p:1Y țkdW wnUfݵԏ,9xi獏'MRE9Y%f5- #/ $ V}ba%^&Oȥs\# [Tf-3 ̸jZ ͳ}٬~ endstream endobj 313 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 454 >> stream xcd`ab`dd M̳ JM/I, f!Cg8nn? ~#_PYQ`d`` $-*ˋ3R|ˁ y I9i i ! A Az莂 @t\? 5#(g-ݧqJu?IR]VCƂn,}v^ٽc {|Oݓ{'L]Pÿ5&wvwKweW; sCDw}~? ?V9]`5:7Ͼ@.)9XdGqʞQ#Ŷa |ԽlYN^:KH>g70w}M;aD^ݻoendstream endobj 314 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 323 >> stream xcd`ab`dd M3 JM/I, f!CGO]nnW }_1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000201012~_)Y{ӏN3~_Gئvkb_ޝ+ڝ͑¾lzٳTR> 7s-<{ 6qb ^;wq {'O]wendstream endobj 315 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7328 >> stream xZ|T!D41FZ"Cv6lv7{-ɦN)R\@aʳOԹ?w7$>vsgΜ|g9vj3l4jv#S^M Mt3{ܙ3E{R=g{&DFs3}m Ov}6ڰnfG RZgVįLX:K" L޳&eϾA}CB7m ?9s3_ /xWM}a3vΜ"EQ(_j"Dm&S)5D@mQʓJNͤQ˩Y Ej%5ZED75zOP>Zj!5rXi*Sc(Q# 5rDԳs8j(5N-ej$A "4 b= ^5(v;98ա ;>|p'~GY>QnLuKcB|r[U?33?E}zlsy. Ƶ/xz~x4a8ctNT=|-Xeៗ:u?uEW)U$H0FB4AzzT TLUv6Cz0[šqBHA骎JaN49 1Gaf:o8jE~Vv?_"6Ɠ JxRp] [’fԗu ,/XP ̻?>/ ?ҥ={kA+D_8v1Y낰Z=1v$Zb+r#q5W.מ? gfU8}klYvO> wla1/8|gE?[y3Z*6'$$ٰ4/|xdq}円(HeJmj|ts`bn(Ϡ1x]9-貀+xVgQ_c;H=e_$N48`uԜG URF76]G (Neh*Lݰ8bE"kUCɗ{)Z7Ԇ&U?q f@H[ .É:}#Dt.zh ] fcĊ k-"|۲ m^= dABOlFn}1\C!Gfp5Ap=NCғMSa ɂfMrNRvF_Mal) Pb=ll7qt;6͠H ;?o--:kcF#_e77%%i"vor$HʍM= g4غQÅ_U>4pؙopGl\;>KO:'\-('5Fb.U= Q8m.zclI*F&/EJ;ج >v[R[vtM4i9-`ʮCNj́VpLhcq6oGJCoرzD5) h?"֞KaJjlaI@)EvݢW$^spԓv -:0ڝx8k#Y4ԄB8%ToV", C>"8Y_f 9!^"òEyHhvߡ`M!y_IbO7<&x4{30KCiv*%'½`M[n4'VK& ?,fRJa ?OOHbgͪC\X0CQa"ݗfF-S]TK0{76M(x0]xaWG@u\0 #q#/xԎDRD <Cf>CF1zmu/G fo-Y|V 5ZE[ю<߹>>8 m;_'&Z!tٴ9FOE:g_BzYZ?2:ZjD25%BCFCwL._eS+T^P͵ař'^QErEW~'nꨪzrB4xs[Ӧ3|?ݺBV8;Llg$$HS} B;LvI܆1h1 msa^t'h*:DHS|< i-=}h~6'*}O|^  D¯h$w$z;jA- 4I'v`S}TtWK#B )g4d?mg>& 5v HinAwR+ G dZ`[؏|koh+Q#(V*9X)J]C*hj3RZeh13&湱Ɠm>Kprj|_6]o+!p n MɉS6=LE(NFK[9w MFbcs4YZ4;#vk])4:::BVO¸)>vExl\)vtr4Q_уETNv9vo5X@PqmtFz)x"G ; Lx7zڀD U7:>\Z e JCvJ`B,2՜$lQ} e׬!KWVMVVbA;-kxƴ_NÑ =E/΍ ߅ܖe?|7*ԖN# !|L7K k2},X/ g|(~HZk(ћcs ~!zPn,/S (4YQ[6*b~͠t *Do<8gd.΋ЈIGJn]"UU Pnlmi,*dQC\~[<0Q_h~)Qt+Z#-ηe/go[9]@aB+m!zW?йaku3QXz䬭)sbCua?a/+ETt /{(w%ge$TvWi߯EOr+SM<_K!yZYR}-o9PCa5ڼcnwkDs|-93 BbB^x;v$ͫ?l# 39v :vX X{ LUo翣,kn.7u)50HG8nU+ZR_*Ł썥m]m5Zu{bcp%E Tᅼu]̢k]-K5I -`)J $ %VGF0↴ qf Iol`^yfBo \X+WHI(u qfnkņ⋸uLeR34Cc=l5*lAŅR|[Yp|ѫnfn.PU"LԌNbRHa՝^% XIfߥĐ& jҿWWW'a;fXc-KK:Φ]nϾc!U#VpW]wp7zښK\~_W>Ԝ<+Ԧ*"B]Ã" F!3OǰL>7/7_n KԜWÀ&iTt(Օ= ڎs$q/ߕlU8wc>!W4 ]= 87x!}-?]ؓ|a/"i̠h<"셌HYn.=o1h™qPj̭ĵf67D_Y"q̆i NI@KHNHwVx`؀a_4~6'/xn5y'6ؑVc>{+0W=p >.1Ү,C0Rsj".@ݧ舯 '0Bİ_襐{x!p!=ZFwzd ZűǺˎ9VEr}X%eܛxL1]8M|4I ;慢y.jW})xhHku4u6\m`R%иHAU.;}~5U*ݹ8K{fZZOiW3%Ն{(l*)Z}|#Pԉv=z1Rޖ FNso@ EFyie+ yڒN~@L+_ZNRkd=i9wm8_&s9m8oBֶT KDa'xe{Juxڶ94Pj*D2K% J ׆h礃:qޣY}8:k}kf^(J9b2HK]^Ox>>]>h$ xxBb%@߈3ӈdPUa1i2:Y^UJXLOMLOҤhӊ~EOln./BWeeK:xZ+jk=YMYgI<tzi=`mWh¢vU M MbKCߜנ 3T&4o|ƙO|@GŤ|,1HJ CܲVP CInMV͍V|tLo L[*[еf^_*HvkgN?PtHae'A['lz||ۮgA|~ a"kz; ɲ tā/ Dd@2Ds$8ӦĬPAJ%g<"uv%jRMT%PJ9O'GQ3N'M.7M&}qDCb*BFmbbTr/N_>Xڸϔ\0F^&_A H632BEGb Sg`ݎu%k$(5)n]FgSB;Ib.сx2QM!xN I)JV(o(~~$/DhF;cHu21 @K+8[?(9ɢ"lX}ԁq9Gd[LM&D$x0Sh"!'^ (W3^Iz92sZqPghTHI4s;e ]h* r9W}u __7 ЅBG.b^7Q4w1sWKYyq */+WRȆ]eҳ5 ܬDqWәI)6\L@,\ mkM.#  I.OZ.0v+Gy%"E>>L&WAHII..TB++S)皓XYN!Sh/Wh*%(\xl畩 ixЗ ȵ x`A Ur t$IK0xxKM[{~F0W5WG~ާ̒겵fQ&cL<_:eNR> stream x]O10 "uA,tЪj8(NߗNN>zK X&었EUq0N:txj w=|-4R> stream xcd`ab`dd74 JM/I, f!CL<<,o$={ #cxz~s~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ /,/I-KI+)6d```Tg`b`bdd ˾*p?nv.WVUUY!> stream x\[oȕ~o~Y*+L2`lz a,ض[XjyDu8~9ua"%F?4%U;˦ ./ .{}o ~SwM'._GĥiNEeW{]۶5뻋߯1ɮ>dwtZtj:W:脳zL%/RnZYKuÇMxZTӢ[_G->)q*`a=G:qYq?ij<_+S;k=g`VfZedsql_# ğN;UroTWk{d \ӝ㲺]!{FBO+{az6< 5>q Ѷb:*{A?2VL'8TW-1vQ0N\/$-BFw.SG<2D%nVa"SQޅJTk̲zR!t4;p>]xҘY> //'2WaLwy`D^ddrzk J*h'sƃF}?růIl(3[KiM[V~3e%Q Zg%Z8sDZf,D$e}ϸ9K)m1ǭJZ;ZeD*cl@Mmlc<7$6;/w> Odhb] c7p~ d-\'cǝW֐cac>܅:? }'ZVY%L1>Uhqp5~+QY炑0,ZV=ѴNFNr@ Q 麦Ǵ%eq;dÄ%q߂F$4x6L@}OD;$&{rr$)F#s.d{q'F# 'F5XҐ-!(7@X*x:q0Qh$ bNAu .۹3:ν8̂ c>ӲFsz7.N{sQ}x6' UȝYS;#dpf?`X >:=wԓ׭.49 Hn@Y0sp93%]g%ی2Y[]& ^NKy NJƽD.%ODJ;oIY70Ѐ8Q DLjB0+r+L߿-鮩[*u*ڸ?58)I}$ڕ-HQ "hS,H\F58ϏU&s~ڇLL)"JJBfJlTBIH7'݀nߤ; gq0Y+(6搓9)]?DL)u'c^h_z;ϭ>X >Dەlj)/vO`6US]oe466"{oH%gq)Є5|h 3G/F̲ZƺZ['Tz3B~cޗ'JɷfO/Fl@ykQ b_{}7]r"TCv4dh@M%b^cCF6῰4NtֆEMb{BKZva: ΢6MRGH(=9FWF>UP T=;ֹi#iƌ?dR/Ss*|%`tu(H@iIqXPٷ1YnHs#c_< j LegBCo#0f4:< P4S)݅A^ƛ 0KKCeh_UĘ3ޙ^ ]bcDZ2Ljm& j|ތ?2C7wwc~zoݶϰ<֛ׯ77բfA)ڮ^`Iu%Q5a=g%3J(Բo[A~|~zp:"pwqSȩ 1NT'MFy>@f[֒պ;&ҷ0v"F)ǢxÝ*XE?ir*-JP:Ⲃ-z)aVKfj5mule˶IwueV%YGi^6@w>3|^;5. 7tWp;7,Z>y)्I\fI#NPSmB]1Ksv>A1. &\2C j9Dho٭'Rն+b)l")xD }\8Q*YXX@ HN|֊m_8jvk3JrɞBTz,&xVhJbG.++-URvMH;1_oO6d(HgzZb$d)^ 9QҲ Wk}v ְ)tο|$L58U2wS,C_eدۮ-9k7VsYZHe6/3QpL n1{kC/ f=6OmA/n!*PQ,|`Uhd-_i- e;Gl9*~<ӶC32npb`ʔK4ElI+|J1nn `vZ)Z +YW2琎<O8|sz[6/-n *| ;uw9;   =_H~!SȚE8Sh1})C!ɣK`0_hԏ B[lCfSؾɟ?cL/,L1;ihGwt  ˆ䠿I/#ޱ3*Sgo4:jV)!)a H, oLwV)fXyݺ-*P%+g˩F6sq=D:Fc_%5Ϯ3(;#*z4'MKYnxԂѢDޯ$)(r!{]׷j y"sYa2.[T{Lj‹?[^CBDi!9e%. ,^3R#T-׋UA}^ZS e ele2RG f \kmYgN,:8 ӔA_aZ)_[-Y%KF^,p ҭc Tũ3Ql/[ МO.;Kv'Nϊg`RHo8,֤ e9K4*ba@֘ÞXķTkJQd}4,h!{2cirq Ep:e`aO7im;94!ʪh C_@)9 q2dΊHuO8_>ȅhmzC2.ɫu[7LU t%-5&MB5{pJȀMwD.&'`{D s6 ]Zz*)^olȋ ݆=?o+-#LbfރsG4H\que5ŋ" WWMEEFi2)2 #wůNѺG.1We>EONM@ϩQ-HEjJ0fʜ9rPZ˿џ #cAx{y 0Y_/endstream endobj 319 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3416 >> stream xViT׶DD Qey04""㐨񠾸S& W18Ŏ BKli{f[WuSooӔ(iԬԼ$ʁu{uEB~ LĨ|?V4=g}L䊙Nksr3\][.+iVv&?5km<5;/4Czz}3EQkZ?Yz ISBSׄgDEgf]渺ϝg~xFP-A͠(*bb)_*d3PTNͥ*@Qbj"Q(s,)MUP"ʄQnaʈi:=J4yTƨ/AN7F^  w 0LS˼rD4֓]~jF/;ZiLW:{aoG_zN$nWn]roo%j]P<чՈLuH ԰Im֥.m\kڱuյFtifWbޙMM9 Xh=6AU}yTa9JFu_ p@$V&,K:xp氽52 `1}%o< vbJMukxes'vG3Ѣ@46m :2cflʖdx'g8 A"n1"@4kpw$87po.nk\/bc S5@'ͅQX*̔K$vfm1{qs!DŽ.tqq0FsCHVϵT$8@0A@C,۰XOp(JGRW jz@+e㧫ӡwQ yZØBJb> \|yrRTf- >]o/jVg{W"S~Hö~ěrL;xԥx|"63K6Ȏ֍هǶG4޶^9)<]qTct^uvXvBMדox@n'9K*7fc Y +fcg"߼Ȅy,D؜y0 @o5]$VƙC;G svEoTg~UJT/vmٽi[KkD&<5iz?6A$l%sLpG‹EmQK~HYȹH)7/\'f _2P; 2,뽰En!X_&4dx mbw坄3NVƙ'%wC,vwPAmz'ځϏ-ֿsޡR$sʿ^2D쓋kcDӊ6oƛvfn]Yam*on|s*}b;s2Vؠ3M׫+I<W~!R3 RĀ/.!X!|ŀ$9N2C:_4Kh& ZdԌx䄧HJvӎ]ˎ߅պɄx O!02 ӗg.(^ST,{EGyUowؑAt )Lxǂ4epkl}׀XÄ0T:)*яa<7w_S*{s%`қ* w+'a4T]7-}$$n"l&Fx9>S0W0 {%n 12 Vh7$? A󥰙C_]t>ϳq&9n%xɀ5؃IO;0e$ ih9Zybm}/Onds["Yk,0yb!!ewfh1}Q-%ڼ?],u =|BL)N ߪ_|P@m/0ma!-[X.z?$7oHg.> =~ 2<0,oU4˘ƙ8IVK Ċ]d(aݧ죑f˿/ @̀*ui\ K\88V^&ܕi @ѫ+:q7W_$"DYXP O-bN-[=~N?MoZ&v#\ߒt>vh 2edb*:xMYlp9[ZY#-tҁL Jwh_IpFͬO$iR^7;-?[c)0~clm>ijvI4LI+.֟+ ^elߚ3t7;<8wM_jC5$"hp.`XD:iޓI§E٣-}d=#<;|w>q`Dڲubdum޼OM,_-8!\vB!A@kAxpGP jQh#0-H95a2tVb`LpeneoBЪ *&8]B-ֻjrS~WBf?u Sl!6AAzC"ܔk`2 N_"K4OZν;``hFmx"C9v^n383?{ 8@[];Œ[T% +8 2e@.* K/`#('C/jm o{s66ӼrD<<5֎kbSj2 cendstream endobj 320 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1361 >> stream xTkPW yIfA!X**Ģ#"&P"ګ*(B-آhb焆6&=OidC~zvN!hJR汉Zcl FysLZ]Z>67hJB("C(I  O$AFGP?wdu\K\J Vw IFXkf^6X>Ӱi3A7@7'y?y)F +ظND3`>Da(R$Bfj_r종kϟ_tb;q%3U!vhn׳5KN+ esp Y,i*&fo%[ .?0H+2_Ži[]AfA]{0V%f WYqO{l\R{*v$W(00u)1댧Z۪-_+.6,2NeLs xd*ܐdQ πpzx %Mtŕc]Ug V˭lBa[d|E=&06RNL$Ջ򃫛on;;kmhpcNB>sfl{iwKg,m:ۓQ(D;4i[`ΪְIanck/->pnW;N??U9b-Kyۿ.%Q ,=q@\lj}s2K{ RK*6_N_iyh Ewj &9'v46??oֶb~BAq1Wȼ,QxkDc:I+u|!iR2&:R}KS7~Lôğn85͝-d($2#~?|C#H?j`  n1Mfj+eq' wO3~B>^:‡@ =}wdBV=}U҆ek>|9S7W5mB^4z Ց-t7pͥ<<'r$PKxҩendstream endobj 321 0 obj << /Filter /FlateDecode /Length 176517 >> stream x,6Om2 5u du%/6`=6W4L.V.Cǝ6bE`>m+HoϿ}?~? C?[H?>˿o?[I{؎hӿbeۿ|_r l[x?~Կ3M9rk{o?ۿGkW򩤿_Y_?{WޥT~ܷݯww;;n{?|{L~>VSC]$ߟY.G)M?3eIwB}wkiҶUׯ+~1Wm?W^p[N_Ő[?WU'\)Z~?QFL'|I byt OO|rwee\~rSm;Pc.jfm.oO_bsk?}5ZN_i-O_W~گ^-O_Wy>PaИCߴG=-G |m[@k8e̝cjDՋ:3N4 @ a;Bǟ.H:xַֽo<ߵ'my?ORIߠ~F+Ē_s_mc=\gw2R|~7[ӥ,,t<˭x-U_׺?urj>Z\wojcr?9|?evEsYD{$?m$_V Q1#vl}>n][ ~qԷSzsԟ`}ԟFs'Ogە-oٞ>Iͱu?D{.maJNZ7Hi~t7 |3]sߨMO~wi}i uwZn'pۓw3vQNw B ##пA_mbtҦ7$[Ӻ^)N2 6iFUgyg03wsa?sHΙw?rμ̛~^yۏ3 _z{{7ze/Fiɜ]~{?t|Wksqpݤs,Njq/V0&O\}׵377&w &M|=1ƾ8O߭u0h/&ꠝS'VTCu>j%,X~u]3 'ɘn;w+snorJvl歈I;LhɃλ_,~W|{eodw# 6b_|Q9__ߌ~_|a+ Fs"yW# 6b~ok)bt?8`dq[3;\NYv$GOYߘ} Hk1|d fp\>1 tVw(F|u%8/'~7 C:5ӯ>s@(s+w(r@ۏ4n}ڃ 8p|7aIG0:>oX܍ow&_h7K!'$7c-9]x1 եs[#?5}:^Yvnzztmm]u^@7n@|}RC q>Ptgt3 m>g63C6F4GX,š`rX ҟA@oV0Xh3wWonpr;G۞=?2^kCo=Fwp`| srȸ@/wm{}i:Wr Z9p39F 𛵚sG!Bu=Y@K[4vrv*H>Lg}7݄N} Nj݄$4讧6w=9~cr3~>`][n?rl^`szpn{Gp7 ]*o[~cbwu`ׇ_]LG.۾i`w#9}i}mwPJHGO3|}#~ptț_yc7ȯW70ny#ͯ'5IoǛd ѱMc}4@?jixqePh_. "O}5DR`'C ?2@PiweoI&7o?֭>qA&F[ڎ_kˇ߼ pzɇ,hr@>W3wxm>yG{k¤ۏn¤&}F}k~?Zɳ5u(O- !tt?R&tov9'cO YmxKbS txwS~?8e0xo{.Z2,O-Yúް_-^H|2t^,R8 qWp |. ;o;؂7a+7s:_Lg0W F;#M) vF/F_ұ3dm0pMk6<ϙ~&[kߏzZY.-?4E?~JιcgN0WSrzF-lyPמ~')ʟFZKOZ9>n-SoGyszx`ϾFgovq8/@=w|5 ޺|t ֕r;Aw"wx]O]N_S7S|3ڋ?|ytlaߌ7} pSpz|;B=!ߍ4A7=ޤ|Z2RnJo:~QMG.) b [ %ߞ*0֮#U>,o z7q7]K]M(Js wcF9'Zя `}]Tsѕ}l3롣wzQZ 4Gm@: BoB1R߽ET7&mX٪0tKZ n ڒxUݰ#qmlZA}ã?" E KZjߜNފEnJ礼|Sm h頱댷`ecV_2%1 j Xa]o+Z~"n{Ze{U&)C.wEz1A _Ϛށxu˟-ӎq1TkgC_ɶL  s}+ z$Wdˤz+Ru'А H{DTu1T6pWl;qB t>չ יط*tRvc2r>~kCCg\)";Do ڄXPk38`R!*U\]@fvJՉ iMfXu EF]A:@ rR~vrR,:AʗZ;d(]%\. A2I#]W9#a+C[:KfuDXwerp0֡sCӒJ>2dr%;]{6<6oBJEj/Mq8E ;D{OkYΨwX5:DUeؤ} jDKJ)s :g@w?d^>tNpEGNmI˧wb~7-xŦrRFG`QSpJ.J.d+r!bc$҅N$Pm8JZ4ԶYZ-Zc֠/z|pTSS;y-]X+16YIח9HW;> f;kl^~1+} ejǝDVãiKTat ݻ$'ւ'MiV l01~ۚȁBEqT.!i GZ{.mAg[P!:cGgݒ0h?F1xjVޏŞֳ9Ċ+W+qMzBQ$er*۱Dd?f{.9| Xw&ɇ =#zר"IA i0 bKAd.d 0 F$D&1z&e;Ke ^7=M?~gpHPYDjϵ*&lF0G&+lw jKy(=#Bgf`a"#|ЬK2/,7ֵi|:asG9!FZ:)+.mL:BmeՖawwOOk>чI6xw'P]gZA𱋔jہP*]9z?ux[r ipcKO{ 9w$)hjv eWTf >@?C6ncP]D`_t@Nupڜ:`4]YyUK]XgZ>D VN-]K.y.c]!AJ<;7Hb53Hu/lܺ`j4=|a6s5EquL`luvɆ56&Y؇ 4z醎-u >" c=L`U,nr Ìo/+^w(PzFr`UH\TY|4{\+mN lpg9 &I7'KXj~,3v0;Eѐ59|"6n +ab#ܻ(Mm3/xw֮Xբ7ZrUNoHnbQyi5ͱPveՆ'VoW܏ m"CIJ$5ٝl W&' O%+*"($X.4Y g`a'2L33ᡶ=!fF"cHNBIBkLA#SSSSa_a+-%]T)i^ uH&Ꮠ:}u%Z@8k 1*E6>2mPJMT^?b!d )*C/.^S&"H.0-a }9|d\_V!nBp? vpV=kGX6\, iVY~!vZ%Zpj 1vӯJظpϡcToTc¬1!2pMtFzhW 3ޥfkr"9wu4vA5IBmr7~i_r]`Fa9ԎngMgfl<,%ga7+4- `uU.V˺*V3c#cg~hՌVMRIYm]\;%dA[4pG*9MƂG׈yhGQ@F$S6"8ڛ{o7F,Xza)ĒʄT5Pʻ[bڵCN )~YB, E"i3/*U!7_met&vz8 YoO<°ѓrI;JcTF쌨R6rLGRƩ~xP>i;4aϕ/ݍRɊ)+)1 6TMz'MD?LotNԗWIoR .zr<& P1WUvLZYT;pH]DQpYcA  I9Ha문FǸc06#WUF):Xթux^fNIp~@#g&-52NyW,o6\R5"z|ppT,zRJv̲=_>fպ@uZD'eY ƅ!ԙzksLp]% sg`zEF8UKCc2"Xm]I66o"*L , Il f;í(*(];Tro@ VQ>El6f_ A2K"Tc{xxQQOGJ$WtUUy˴{v y jdWRN|_[-I #0T=A#e %sI2MNJ'a-=6̲̎ gx Q3?U]Mi7=ȞbXLzA${g(jR~[¡ۭ5$XdR1spM NrKf0߹QbҾrDO:FE =:LepCs]})QwKgA  WAI5}?)=2,5=Z pkN# Og kb 0IsެM:!+ ŒOOg ]MF6+ !L8-qN<@l2قIca5֎fȖ</:_4CkPd133O00o110Ufk Y^=$ʟKU$Ң\(*e*"_8:fa20̐Bcs  {U^= lK#i^,X!A>ү.S&uFWq _D̗}3fK;)IRY{G=epRn1ZjPlFv;ި]IWzyԕ)M ^oŢ:+yeסtx08hME;8-]]1{#Գ&ju*D8&njBHu]IgEE4Y$jEզK_mo!^BZˡ)Iz)MJ()#!vZ ǡ$Suz b/.^4n?O '7-\*#㙲OGDX/QIZUFqW ޠ7=xh bXWlAbY^h!Ԣ %/aOt= gB}GQCbJȒYdWk0ޖc -J-T4Ï}?"?kIrɣqck43/Den_yYcxU%-%o1GZueQ?vRoru㡮}.+2+p ȭKOoD&{LjCER&^u ]'2nv&2!/E$&1U: r|[G m?Ӭ Ŵ?R3گJPQ~ĸ 9 ]B/ÃC2"1c3ܫ)Ax W&O0^c)"MK&'Q xdAJLnLLLLAԔMP|دpTEpwBi7 *X@ɲl׭,\ͶG65iD|5i0gEFOFX-?b{D˸[ aYqx\SQQڮ֑q1j$I%`tYշÅG ~nXD2}K/)CBTfW,9碩2O> C Wر5~qSC9uЈk`,tVH˒7xP6PՕI Y}[堛E}ǀ Jj0Gi%xΜf3nh35abf}yIfxxvw(]Q3WI0UNTuH' wI@ :=E\v0(1eULT9{ֽ)kcyZǖMQٺ?LE#'DDoܒM d !qAttx.gu3~'\CCtAh& $FB@!R+V=53v:]~ǡXӓ gI”.o3?f)\ VhEؗ]5lamn1DNmY@,f`.jN-(I}y}e-cS&H2s!VLo9,/S76EPC # 5aBo:l[sq$H4,3YJPg͒u Z#* &|_,K|hHk^W3ZP-J$ -uؕrk/+'Rf0 utilRrtމV\]%!\bv$k  y`'77Qg =tU%03 Kq`<9 2hp;.ͯnqޚ길inإYKv^UᆳHˡmhhF`3Rf13|IvoH'/9LG!)a=6_̥rt /q{A|;,Ñ7]$VfUɕE;C~jˮzGEf2s_jX=.47謱ZBTc֝Qn-mSi܌,X;0PCg.|ZQKv)s_Tݲn=h9F]U̗# oKdh7X5a~$S~%V=. %GgX5*l)O 3˽z?ЫI VC_L`!Y,^8`g4Aeɀ.|or_snn z]%>YQenj~Jov3h)XILnZhqk#^׽jɝewKI/K3i]a4':CWx,:x|N'//yؤ'紜^rfEf9y Oˢd0^,0وXq&e:dG|x"ΩE9"+"s!g7$x'2M8oļW ~Uq, jA`\+MLt ?,z%⩖EkElP5@I"!b p_!!P-v([7{KK!VBߪ&::*hyp7#,j.AISmKl+[FHbE Ii&υ OXEp6+`+H5Z^zpf%ML$,gM.Х]Np}vFOfr_;>g+HOaPj4uueуH.TAY ô,R$ yPcG,ڲH o\N3UȄ3PZ«Z/ԉϒwki@&{YP3˽cA6IC(#J l,KɑP\Bf/1RTY 7*.U<`H"bɤƸHk2 sqރH$/֭׬H49VWP<,EKfmWJK^ޭ3zy,_ QĪlF_1s ! 3E W Hcm%K5|d3c>~Uq`R{k^ŨJ&z frs욾R]EOP!.j/wāQr1ܳW16͆f̫Zw6:Wǹ<y/6uU.eiid[ 5u9,><rha3,F.VA+]ƼaD,DenkxyT5;.;ro>hϥ^ǨINiQp>F#*.0P}"[fe<_2vwOb>-9hƢ"vhӮOj-A_ ӷaQ<3łrK'ncCbR-l@k NJSCVvve[%.71@rh1 a+eVQWJ*`j=b+3D(Y>O]/F|Xx1ӷh|x!|~ڂlrD罖XVDI[܆nթdi(*Ҳ>eހ5hhW12M*MoΡ$Kl)}= %Xos7cGbAw&#ai%2htxi/JF\{C+51hh}qV2b{U/#+I f"`BA'\:QOK 5ĚkS|Q̧YDPp, qL*b(z=1C%VajT “@.IOX{f/tj][6Ooh׸FU0`x4Y) +Oxʘ p+pICChniGyv ~[mLɤk>AUW#-Ih8Z E\9No-G3(3'2JE_Fpqֳ%{ieҮZ6^q Nϸ7?'Z^?渗24g(f-S ‚4毜x0&$FXnbL֕^!vRp*NAYSLlWl͠x(1t8 %b;\"s9@(CRx[(IƤJ|ڽpiQZ{E5uAzb!z鋼Y'UZ<&0lqXG'(= i9u*SҠy ug aMJ!8"2> EYą!7;x: .9o`f$xeD%1_5Z4x f-!5fɮ+?r,WOE^5kG! Wp͐ΰϢA#FP-ZP'cV9jLX,vcaU %$NX,RRO8Kxdeպ"<4jF aJIS8 '_AٵOK+S qm|f cWDdd`%P`p;iʅx"g&yfu~\g:_..龑n$G'l֩QԽes$VV &4oJ.zY  /JPhͼxPHś@R% (^𣨒cS!ܶG6-ưz::䦶"ytlA/򹔦$ph0),M#1h0:rۗaD b#Z4@h=J D˝b)VݨHI/cGXgG #R=׼~oNzj*}D;чz yE:i+47g&ojK.xi vپĖYϢWsըqѣMCݔ ea$CwYd5>%[ ԗCz#LL(|V||L ڡĒ|rD%k112iR%"U!>^˱<$f3ȓ@W"!3 ̰ wxo{3 aᜁAAF" j7S$zTbtc僣 ѓA Z&i0vXSHCnIߡv)G::d&G_̰e{Ea Ğ1_+5;g"4VO Ho9-;\y-LJ"Ey> `kU!h, gR}`(V+rGu٬j?yBȚkzB"u?r6<㼩Xmv62o}sU Gi/sEūk}>=h@j}_0XfMBf =䗛e"F+t;\X{w}r?$cGD4!ZHM0aʤƯ450"W,H`p6,$qa+kը = *0 < c{xsٳ> (H9aqIQPZ*86^#!k8AiPxv4GMRHQY=Q[̅lʽ!z@ ЌNA۩>|LXJ>Lf̽?4ƲԾ{mE.q-{ \Ѵ߄:j wA`ɺѭ9Yy25ΥX^,NU9 P"OFqAW9}+Oϫ_Y|r~a*o'eծ1G2;n pLזC4~|XCX[Z({vlg[XwS9%w?9j#>a kp#Owx{Ҝ^gZũs`-{qς^צ@E-be@̕|tZ|SgʘYbƅXPWu=; nc ->8'1 I_SX<2Q4HN̓=DR!^^ 'ŹSiQQwC0ƢYv|Y/WCb$MGdkzЇtt=rGh#^n%>{f)9r:'=C1?zlEbtccᚠQ;ʨUJCHߴz0۪=/xhwp? d'/V;Y5Mꯟ%Z07"[<u -nŎ5H])2X gMy )u1-q3?Էak^+D.Kd 3 iP*ڼ$#Z2gM$t5| 4;X+B-y12D%K{˥ Bsq>h=cSu_cSCG2;/$ӨRk0&WK!p{bJx/(.sP9Ȼ.Nk2')WB_[R4H!}UzfA\`E: 3B#&esq;;~)mQ8'|xHlۗGC_4-ۻf"`Ba]QRYZ-)30[S\2 ߎ1&Z nZ~yЙI_}QWbcM-5N,ijHcQ$~Z Ԍ{կgil^PmNPRCPz(ٯ*vR,l006MuoGoMRZxӧ

,>šϛ*nѧ sYtf.b@33̐ |ۉyT 00BԅYI' gԦf2gx|(ŝ,fN^DrN 4(^=!r&o;#rZ"*Wn/mBⶄYDhRzgjeB~: ם9ݥoLswܲƛBv&mIId"Rh kd`>MYVں$Mjޗ0hƹ9pXJni)#:"{U9#Ln[lYmZ%9 [5Y]̰K*HCl߿qyHMmoV@)m&nA2J dϤBoRĭ7:ǮU} %};}ReS ▌bE{Qqf0&y,-QJ y!h"A- (،,c5=uSʍXx*i3[yq9*d "iE4h:1kR%nOc Q 47BduTӦ|o?y2'iH^-` n/2]loϼn݋m>F<%Tw@ 3YES=W)RbeM=wIf)1>~+y!wX䀜'ʩhW;DQQ@́M U]Ml&EHCOzh;3j?UEZm=TSt*:;ۤňc[M A.("ki8$fŲ- z;tp)W jEג87ѷhpfz55 ;vlj‰ؚ/KbTRRS\Dӈ#*A}>c 4E͓h WْBEԂ׋ClD5Z_2),eARU_Sr0 ZvzeT6s2Y!Og$*+5*_ٝs~Vc|x΀CBz^Dgh5Yd-,]i7awӹ.HF*97la0EWyCR 8E܅3(Y KϥbF"i %Qip%9i%HfّT| h!m"5ڮQ'QYEJ0WoRU YӲT0:͢:+tCU@4~u7p^T:=Q_=^p~$IpVDڧ;eVzvtWN|cE!=La ">3 aa#aEd'YrYu1c :,dfAX\(VX}"հqΓu_`i6W٤eML&6ГcA8 i`_Xy)&YB[DP"L4ͤ?VLfAv5pDIǮA>P/Hy8*t{5K>g Ah]uX`uhC]Vd3Zw3TKj:$4׹D>i-^HZ2u81zv&l`!Ard5omK[f6As X2gpPЇ iVXf! \z HBr%5b=~ cʻGWU $դx3,P 5UTP)5>3-8tf0^0լ=V> 7l,L2&e.*S6T+Q#GkQ,7\wz6A_IP(.R|l1Z S'.hNZStbxFHsG-*,Q>q+|QGTh/^tYHr1K͌3tOֽE/$\}Q`Zi $84R8b{u ˭诵[7M5#Vo}mWuHYA5]ZDY4eJ^d䒶l*`2cxCVYVA~;)XOn~X4VuV-N(2NK94^܄yIy \,Z)-UMVGˎ#)&$4ٹ鎕á-i48}~duӘtldKis<%k e@)ۍWjJzRA(*iqF*3 a_:1Ylq39tWOr`A'DKDo;gf|_đOhYtR}V W"DخF ]"[P;h2H{:b14-7%;X4Y`"D##`\c0C#>Ț/ZNW>5ѕcR=ECWrE,iwLg acKG@tXҙ/ȂIgh_]OK~X8QJLVKH M^ 'ϓY%iAD\z 2USA Tn}Koɕgxi{ɪ VB菖ukҋ7B^Ka跳ogx^w1YfAZL~LKI=Is $ ͯ]fKVe*-!fʗ"4K?&ve-@eXbwȚqM [ЊX{Qjt3<;0N?2UXa|*RLV|J#q@ز܀lCR)OV%M652.zPb7QF>q}߷dH$ C"$CV\E͘=tT<=@Y-[r-c![k'2`!'`:.r{q$0;$[DsZ!-4Xc7 iJr Z wj$7r%[nX~200e\*Q[:ip$\FzK xf:06&0`Mt3-`r%2R_zg"ԉ&[ Mׅ? qrc{x}Y6 mC՗`>Cӱ%wf,Ai^ pI&.`X}8xwZ˦fm눸:4ahq&)bྕ +ON%R]:*#zz2gaO ;s>!fu ך;feX'T^*N-$RXZ)N|ĮWrDA,xhcY2  8PHhɀ:5Y}(HW5^L:yk+MԽ`QIvnkQ'~Vv ЁX8ꤝ5y<9e7Ѭr!mx\GIfр$ο1R yWG&U.qcWs|$2[CY?ul x uh*UbQSaWҏEiGjn5eVզއ\[tϵ ѨGhݛTޛ< w)wp6'&M]lHr\&5T` ZGP*(<nY9gu2I4۪LWߠQ L 01U鐖lIsz  '+ <12nQ&t H3ό̸bؙ DhC5>7 8ӺH`]@CکȖ&0ԡ6ITf\1mN-@;jAa j>.i{uŽ <^dE{٧zҞԁ@yʚ pQ?īTYx%pCâb؂{-"ض[FLUפ/˶Gl x.$,D&)bHC/vsuןˎrd)k: IJ˔ ^ΐ|(,mOHmwcyפ2ڝvL*f\.C&av餷hTehz'kyM|!Ηt>_Mm|%?ҙ1;%2M:>8>\ &eķ-)XM-uwTocuKfYWBxQ(vN~.nqW| Ax0y-!B841Hʓ"ʤ̌\28glO0Uw4sm(ȤM,4JXsҲr" f7{B+ݬ{UOS ? K:c|j2öy+Sh bH'և"f EY~,y^vM9Z"{zzGG{*VM+(~A!#lNJ˼X^RvC]Vzp3XI:-Sšd U|3jm1O+ ¯hI(r{UjlyAsZyۊnq  ^+t m Arb&{]Jn6 l foa$'M曭cM-Еl9vU #v(W +v {zZA=]\ʊ :,Yn@RsXcؗaCQ8oZG~klĚzRJb4zFXP-L.KzgDt M"_&Q[œJӡT00- z>E>ʷLZ/Ί#JEH,^vsz JU9> xd ȭzh,5"BSewikt6;,^bHəINkq RτI7Kq ΖGIU7SSU5"&R>*w5 h9,Z础o>2@Jkci,Q3 W#&,3qß'i3T˚%`%)M'*M4IVzڬ,8SSܬԄ/3h-3$zeiS6r{I0|c/볤Cc2P Y뒶,)p~9{?ֺ"@K6n]gXp]ZDiTY; ڄbn>"ҴiR9X;To$gy4fo cq&3#0$tFK?Uړ<#zϻ4u͋ 0D8U&{mA n_aOMD {jbң(dK J ]IcVְS ڒNT䍷9f[E%"şV0%ƭ#D@J;3N Tt p&Abl?OMzߝid5DnNwx1k_m_'~VUM&@MlM? s~2UT; {o7ѰGZ/ml5\aXufMP0EWh|lpFálJWqD=P[4 ΅_u8{Jv~g߀}"y6ۇ"l,OL^fbm<#ea< _NƮ4\;xӼO|,}8 { k'[_x$D,\P% q-pxAG9R8bcύq/:J0'@sք2wp -BQ8/@@3>ޑ[%q8L,Q7yhWeo[}1K{o þ@NˬmL5pOZKL\Tα `1dd^۾-y+g e}6g/5f_^e- j'eoBlT̗ vO_&OB_&{z|-15ۓ+uBnVҬG8tf5Ss3~h鶤ӗ4u8r==}\R}Sh#H~qHKL,cS߀ Xuכsǯ s}OR~kۓۦ߯Gʩ4lڽ2Kݜ닖؛mm?tB{Q*8̶נ%h;eݶw[moſl-}O$/_k8rIۜG(z{/ AClT}'O _mz2m6pok[mdixnTK V+ZRfp=w2m_yc;mp?9իk_BCEM[߯>͏:Cv:ƦzPd9寎'^aSub:&k~2)! 80CmKa"_,Ե &|qOtK LAX g]{ow}C~ʿ^oo ٿK۾5ܙ +E*&$KbjlͥH5a\9' 1 =#`ӌVX"_q2'#!8EDnFZɇ /] [ǐ{OX^/Y Qڏ$VbX,C:zh00o+?D8F X{BosQ.K2\MsrSJ>"7b_+ 7}׷y7sl./nU퍶Ӿz¾wgߝ_~~ힷ9v}?q9~ݵv7EVݓZs/BeM׽}m}ݗ}W}D# g=gEOܩpjĶ s׺qU)&TZ뿸w``#aG.]WҦ mh7b 8E8HnvY7Lreab=yV, yƹoaqhn7E>ZC<3ܜVKOc=E4+pD+6Z`r`u$mVi<nc2Oւ7.4*dKfJG՞ُϒVG$gMYu:PmqU+!ucamVq7oN ֲY+/t|>!6ߗ rC_{+_ڴ/^X:Q%yaS:i߸bVz:3~nϳxv&FRu" 2S wċ>,= eB$d,1EJ)-{9fxi(Qʣp1*S{t %_,,aueM6:dV[<~P2uڃ"]VܹZԬV}co~QdrW'KC9(8f(x-4v_6_6_mޗC>dwvZS;ǒuA^5~/;b\}_"L]>s5/wӺ*u~} ޗRo;?|?cOq_ o~[ʱI<+XRH>^kߏ{}qܷVx.R3jmeҡ~VW|bۤTyttSV;OD %Reܬ !nG+tŋ{l 6[* o;"~!}E;"~_|֠΅N|9 oַm_2עYgsnҫt-@2 PоYY`fp3 :_PNsD J8"2byC׃~ا2DL_.Mk>~U%0*7ry',k5q]5"}PaGt _kl{*oU/pW{yζBJs+MM$aAd'v /t|2j5+ ᭃG33ޛoM~O>D/{bd]{lt߹zI|G#Bq7.w hH. /Vw?"o:^K10hWbM 㩶Rjjײmc`⧊f/N21|#?f{IWz̹b骶Ǔ!#}J:ꪁZhkrU @+!E@8"T8VoI5=\֙f=ls;Ϙ%T' HB^ԳAYHtFJb{`1 x4vjto{k={\O/]#GYڵAh}>Nqp-o+r]?t,W &O[|m޾Y[ln/|P2 QKCy|G3~"i@~>mAM>~-G(7hqQ;9JDv/&AGp#.NT曞0 nĭ1Tyk5A+H~2.x0oMN8l܆pt(!x!C9b@PA`%Q|>"WbD_VFɞcI&zDmo#ydkhYm7z> +ƈ/_%*9] VISZ3?'g|ovt(-o5?oD:2[:{]7ot|Gv&4O՚Ƭma7:ZYUeFn/dnVso8p[ӝc_ShP70}c3Knʗ=ewC"Ɂf<69RIpsJsPlkgg<SίP_f*Y u[ʨ٧fF%CϢF0a}a딌 /P0*r<5pN>A)samؿ>owޟ=W;v )5Ej{Uk &޾.ߖ}ݗT?LmGgݼg@Yd GYxl;B:q01<"\ڝm*V\B:VXPȎƩCmSmp?}&m2Y>'fkm^TSP쁽*U[fr%_MLl! +Tϻko}c_}'\~W\o$ j-Rz Q8^4ϷCxXi׫cx鈶`JŏXOmkW6mcn8|W1fE-lcs6 m3v _ 2m=^d9s'?UR+T7%mas3FJ<m}b @C"o<<5$m$aB$^ٗ&'BM*6crhRo 8`,} aGj0ax`9XwYlC4Tq_em"¹}:!{,EQY_E;qTǧ.GXsq=I,YHIsr5'C11t4FCM}Jl^)|KT[>z}u?ۆp }}ٞl7^+ ΡyX hA SN/Lc_fm6g!+gkd^6sa\y攁| z}%*R]` J dhUZ. Gb֩@b,_!=M6o1/'lOlvBǾ} E1~ip" _;$}YrOdK]{5`_%D8hE oEmP9uLCnmd۠'>$ _͙C `ٯ-Xw1\uV-#nN t7;\mw#\Ax0qG'cE/TvsD!n;96+{r'zx~ߎ}2/s>oKJ+ɾ+ҾjO|+7g[~ˆ|۴o}'~y۩a?WlG/Ǔ/BL-ˢo n{}O6;o}5h_kٿ7 eio\o؝(m֗m[~fuoF/^{G6e=1&1#2ވC;(\ay2!١Jv4/od7ݝwޜEvn^Xa;؎BFu^? #z_ \[,)oDJgzvfD91|þuA6h_8sc~ȶ91Y0i1}`Wm {;r:EB7*7}u2.ML䇁ώT x.aX{5gNh9^*'v};$ZҬϲ2-*ϻK3Ǯ(Msul?p8.l{(yUTPǗns -+i5yD.q8qFuxpɵGa^9^iV!`C} 8Qrla\`+3߳lP,QuGg&D-{3i^aؤ3*aM#`H#QT?q~H!ZwNPa_{G*!ŝ(Y F*>펖>Eb@SOQon ܔmJeuW[7S(gȜFџ&4+ϣ)#rZGf>‰I&yDj!01NQom2UDQ¯WqZXN.Qwehj K#? Fݫm6{>>>%V^ݳ~w4w=_d;O3&&x@8. N2@#{6.yڦmg}}Wg|젠@ӶFvЕu3-?yksܧ}&gݭv}ݡc2!S^/[}bC$Y`8\{;5!zX,\y:NeN[G  EsNFLmO4OtJWp/uS~п_6~9 (~\2՞o6omշ%m[ii5&ߟoWe봄[>Rf{`Ϸ~~s>S>-S>}Wt;0k6*8R,;pK̰ч6WMv@s K Q QiXDW&cD!d~ VZ9w lX۔yۼ#ԨZlrH=7=<36>e>Ί:QVRwA1uB;WֿL)-v/ )uzǻbNNjk Z $ !E y+J#9&mׇ{%d/Ot,~ r",>JGėCP-,.1v8`߆?ޗyzaC_\q_u3}gT&,dN+g2g;^޼%9{pEA@o7G\m{g + yŸ4p=_<$PjyO=uINw:XT[N$Sz0%b%F~ɝP9[D} 0_xw;{wܿ-[J6eɧG[lͼSkB6v^Y~~%p.,6H@cUU%x]<5>s>8ikV[܃Ţpzqs*΀C2⪭??车Ip;>H~.vC{޷%A]9L@Vpl$H޽6B y 쁴p\"L 00yHbLjctTkg~Z%,pQ$z0y1{6WH[7%Df`. "¹wrӅ j%‰o: DѺZ8 SC> m-܊p9 !-NEY2\*aa!9%.ZfhT b;f1SɊp9@Adyщga[?XҠC;9w \fLYc RQ{ Z\k!Sگ'>`BZp254;fi'$Jf 58 ɶO,0(">l/fsg$[ȧ08u@ĽsXhj$\pB$tLvmb&;{Иlt9 h,Hlf4f]ua4S:ۜ n(Z6(1E|6VJ4FijhA} p1zW|1-- =ݤ0Ebm6wyrlYR_zj/l{sZG~D8P2\K[doK"XK* i8,35T8f1"Yum^W1N~!wAjQm+uk ^v YI k@SfI 5 S`pGp*nᘀ׶G2QZm;%Q( ApON `tRΑ=f xT- gl&v $]#a֬\ ʶA@5~Eo ()[v*$L}?Ӱhű04+XR3m}>%.IC-)0.}nK9-Vv-8_U+Ӭ@h,WY$.Z8s U!f?? 9~^s9p2]84K2pno8B c.پf@.a4UCM)ڎS`4@ 砲Ԑp}nEHvভ~W nڒn+xBgǑxj{{?f(8 %b|OU=$%>DcOB+\­t q?V/f ʹ < Z0+DB 47s?Scg苄)AhWx1b/K۩OHAk&$.#a-ı$g /[) qpNHNN5&XpoEGkARVbaSΰH7$*\Mt A+*"N/nDAb`*)k?7ˮ#Kd5܀3쑞|?X~AyYa4<%AZ; Q OHIFr#tJgm8ȅIr&I^.H a4߅QWm7<1u+nASwl~tyiL2!$hixdR9|+RQ(tN\\< #noJ@Z4V"8 _JVD- qmlC1Y+<d` }Ĩv N 4p6PSA~vAa4H[ %JRxq-7( @:]s>'XCjK$T: > @b(05SB4R4%h/ Z8k4tto_U_461?!ZtѭHU?? +9NdqarސF-#vQ Agp= jh`ǣѸq!!+CsN,c@oza|?O:.Vp kJT6n8'SC47%JixCRp5,hV`8=c:8&-.`Rαˏپ}@=p1N MǁY#H@{4q7)Q'%o4\?M+82` Pد-ԥ%aop/:':U`?8.9g\ (˟d~A߅sd7߹;a)pvIkp}sPmj>HkYn4<ǡ{(Vj]]|Lud3iBA'nQ34ckb=K ĘN2+^gԟh<7w6'3޽yyTa}"¡*ftle_S+Ϝ, DȋXټ uvP:Mp0Z| \U&q" YC gqOC mA"F(p=|~:4f)x#J a\ π mO8:a!\h>>? C!/ +B"얆8^^KÊJ0 H]V0)Mqp"].| ҺKȒw,.F*X*TG_Nu>$tp A'-u55T*D ??MA ժ7H+67s^2B0Cb5]CWEut]?8224\E(pR{W;:!z',p 5<5{qn/lgvӄmF2Np {htVk|=2!$DixB3K[U|p3Mn3Nc/J`9x)f `A3 [P쥪YPO' KfhxK\t˄q22Xa_ \F#3=ݢ#B7kmlbNVSC_:,SX4%HrN> s! …6fouWBA!"Yp*2}ƪ'+\­t q/1$</ N5;v!~Srl<4wM<8~ofS?iHkdi9O=F H&&/$+!qi GNJ8?S4(eK9(*w]9Ui_.#PJ\'!䉘αr^]˵AZJ94q _Gm[p>hJBP`8luJtp(5px4۠ў2N\vef+kB XwBPi9!Ϗ ?j?.<U~9xՁfˑց%58>t`!$*kp>Hja4<ǡJp>? '3" (zdqikqK[Ra0P&/`F8UR+C!Paj:)18؏iE9 yCVtAh۫VM,Xpu]07BpԤ= ~>$Wgp!GR`KEnkL CfaԘE"{&4F D%u. ԼaM0%D Su_ N_Xp RX7tV rv빸Z?!S 7[S!A֥66%njxC%JZrPvhXi<*;N4XLZAߓ'LO@A'1=̇*C!il{ 7)sI;LOp`IjugZ! 7R t)tî1~WSkBFFU<."A%Rtq3-П@oB kC'SR'aHb(88.9']C 1 a=:9 *>],R,w=b%hJ?y.754[Xn4<ǡ3Th*ŅJ87A~"?giW4,*І{E6@X-QRtJߛ+{*C3-_Y%CTt&Xiݶ](1~Vg-ppFwAwTCR.48>9']!<6 0Ya4dj́CHX͟#!#,dIe9~cv򳔔UXXkh0AZ.V84י,Tǝtj-}!XPv*yvZ?? ǧn`K=?sv[DPMgUheΊVZ9մJhKip]h!ha~ AIA~.VKc|;ntn{ؙ'}-̘א#vҟi$G|ir"眇R؉>y5M D Ng69JmJCZ; ?i j4_`ܝ]UWO{o[e4~=IvT&yH_}.e'˓:CmP!w}*Cb=P4)܁EЁ,Пd~VjUo R{ܴ*nr/N8R)!a(pG&- (75dܥ>H[nK9mt\^qrD"yY"&ơ"Vv/ˊCaGNGDH0QDrB @?+؊딅]MafyXdYjA# uDA!3pi,g]4yws fS]9,Pf$ b8oU߽aБJF5O*S]s O AX>{3gdH9 0Z͟nz|*ZfdRiAk? Ӈ]4@ pO|W[ ~<$njxCXr4\oi)Z*aգΩ H9& ?>5{/6(1І<~|cȃ\{c F͓F'O`>h9rJtR;>GΎ߅3J@ܽ¿jq <9'08j`|YuS$8'ȶԙߵܟ-vSX@A|T")ȣJ"n n+xгoԈُՈw w Ap@khډzwaK, gn`hyO (¾ xyh]æU"޺ K9DYړҺm4 ^cɢR*Q\"rXC L=KX48>tX*Uzq܇uJp+\"얆8ȹz*]9' Bc󉐗,?^ʫ;`]CЧ;`|Ph8E(/.V8!i.1U`X"]PuYв4LNw (O}L+\­t qh DaPg}Ϭx6 !9AQ28'㒼\ +$VSs#8TsS56w äJX6h:+'8E4ϊꃴ`*V8뙤nC {b8˟a +\HdeZ8E{CIҘSeK0=8)u? _DCaP̊]i|jY=C!! ]cFveK// DQl95hX@eEH7< pҼ =h+Ж &{d V}B=CR}i$D*xAX5۝A<&1V؇806oкH(*4LZ( EEAnKp,V ^Mn-!/ K d,w7 8d 4d]?W'Gh@ ȀA~OVuFb{'ف:_~,'PV09{2]I6U]87 fQ])bjp}|~צ΍>nXmH@su~*[h89>p4o`: 'gƃARQ0FuLDd|2ϛ?r0`CHV jacWk\.䥄D?\D$KA@wagW+p6IvY< JKDK֪U [h% AZ`,\ UzHW/f^>޲g5BUg ~ӓ?K[~(AfxhIBFh9v_Xa4<mU0K /زN$ =/W3c@@4GɛʜSTQR nB9j)JghV?"Iǒ$p 'INQM*{ګGNk[5<ǡQ+pQbsNBLUA&6Y˰KWbS Q9KKY !0 m)ɀ]9@VCp\q'ڑIèJ1jt[]`i郴n$JixCe9miZc?DDCZ%*,SCY4x&/]Lw7ћ?ya*9QYY *Bļ,) N^9 !e#b$1ˆ9vʮc;uƩބ6Da /uaEP_nn4'/c윓UAcs USp*c\yϴB;8,MŤߕc$̷g:nɚېH\ #9go~Qr .&Js {qr2*?p:㢥%kH".Z!U^|i9z޴+nZVP\vspMVKc`-[4NE%%aitrOaEHH)xBI~ MXO&9᳅p ; HHp;N A+*5,x01x]Xu0a:XhUn`@ahp]sNaE[n<|?wq1R?/8xx.=QN^9kP iAZ}up+]s0}ZJRcPKqȕhjXiLm OSfh,SÉ$鉁aKafjO0={t 2Z^CuZj0cH.D+ OuOS QYp]xcX%0*qu_5I pш)!#]c 4 N&3K"=VtԘm{cןP`9Kc遴~sp 58c[pV* L~zYw=ET!*8P|&:8T ?j= oa@ɹ$zAW EJ !tqrgNCX]4yA9zihp sJfY.vKsqTufeGUW+$1)90iĹT]V{EG<\PlipZ}s^*ǟCdEHh+!):`{>˸U/doEXX]z*.>? '5uգ !j)xO-MVs/DndKFDE ͚6u N\AtqMNCF(hxfLp? 'Saqp6y{Z@j]YJyWЈ$nWH'R#L4@s2BC7!a$Gds\]*+ݳ &\M55>4SYM5  (*vSkzdNq^xWp+/#K'3!䬗S=(\BSŸAy ek'Azx*!zh7zOh8x}WV qq3΁"#41*2w֠X쨐(..B @BNĝ}*!+\­t q(Su^,Ae&g045M fSzY*1.252RՁd5 +BBV89'7E\9R ]+⩼BW^2$.GD\㥤ax<qVD- qhjNlrU]qG)îL*!CEpwGX[nkx#liN(~\o.PYp &:ga4<h V α_ӿ /D#A_KT'ك5y-f{4)K0!\"xkV2WbE#AsS6ϨlVTzHxi*292s#3xكh[iq 7ё cP-nϪNNWu&7sYt Lm!1pIND ;m邴m`BDxj݅p 9rҔYΠbWitC@EhY-]L#\"([h봊>OO\Y݀xΠ\?$.N>eFgF,Qv }{rpR0U-$JB֮E ѼDtм6EnkxB@ZJ]uEŁYn+4aEAЧ;|p r{e,vs K͙Wإj?(<8U|4NcF`따S|Y4RB?Eh@n5uD.!+CsJNJ6ՠ*:+T`"3נqzNOAGkp]3N$IiieK<Åip7qmY(tr9 -jdM("gXVџ!$h*xA^VSB/H u6FJuACv%-t*yj3gП} \"L"7; G߅c1tp E)1X58<[fr rҊ;W[ !#.DN-'jy:H`8IS=5JD*VJk?² b3.>r4B!p&}tr15cZ! 7R \+GWlSkh5Hg\Vs )C7l_*4=?˴?o5Yoլ?])0޼sR|~))TI{)xhտ.X[10RlBNr*NzOXnX#D"4,tO19nf?? rGDµ?/ce)i cD}_WYu N?`Bv {\V Z #P,uf'Fn-꜖ϯ SC?ܫ^4CA} I|o"[ Wʁ!ΠLLxs4CLAtvOsnY(#yaXnkx{Fn0 NS\s .ԃƹC` g~:EL8) ҩ)@!Ui[筟,VX>t qEb *+B}L+\­t q\G ,e33Ý~y&D!$w[]r.9m?N&EDop{7l2T,)@$!.xi P9%s܆)V{(Ԓr~eZA$nNzʧ gRN9xE-j)xό%"xȬCP M-\I0Ei2aS)J5zwtaK9"eAQ'I,4*ULt=WІs"c, AJq r]4y9%#,Y v&`h^^E NK͝~]SDcAv&] ̭޶BK($F9~d &ύ80aPgge5żX;4qA3p  P0lL8f ;ف<#2LJ ;pi0\mhKRW 5<I)tIrP[0`Vvl#!dv/mg+IY4a8nA34mp_ULXJm_%m95r^aHC8RمVL5ybgҼU7 հP\նi`4-gbgRA Y<{ BBFuk`:Co%*t@95I>cDž!!+]sB!e9Ί]@ ZSڳ݃V&!'%d)x@D\!E& :+`nUNKY3+8: &|NޗXĹ Shfh %^ɑp諄Ǣiٻ  tF0>H&+\"얆8t+8H~.V8xW"(~Wa k\OF}{A>lm2}!!5{/wp]s#Hu b.,"5%ԡ!pp,3^!0ذ5QCDYEi3L:޶U"c;EQ?8#T#[L0&<[#djnH`VҼ@i/A#r V NZ<IFt))G=F80m 7E&]Z:N9MNG [JGbqr(H, !αT{AK=!&Jk >.B| ='")99( #ᐒnBj#*t .8hehF>TúSc'膃 :!n j<(:QD~g]p<cS=h@쐧R='V&- A 6T8Pd͌fz?K)ഇ^N'C+ #\"(ίwXT}}3&3V C*-ه9}lUmKږ.vKs|hU{| X,8 `/} -˺H~Ҧ @:tɩ T4beK6.MlYds]KJASW A g U SilDjᦐ6ugɼXWN!ِ9@ZZ,*q0->N }tŗO+\­t qH&w ONe>$>4@%qgu*q ih*`yaK9:[ ^SUpWJEuD%EMBY6 ,i$ܿZ2` o|Yvcm=G {[BE*ZdySٝYڿh/ɟE岰kS|:sfVL$-:MX=Ui 5"&D Av@\b(=/4b{[%&nC$C}ݧ?.v3,EZ)rJo󌌷b1{z%مR;bܹFп!}l2A"ρNI`E[fzT>n=:[zBh6 gm<a,[K٬DV-HkTx|!ɊolڢཇTKHm=<ׁ_rӹK BqS/_okmc" 2h7_6_J SS_ۯȕlHw/|}7T`7Ms/䡩~ɾ߀ 7ﳓgߚ*`vN]\?Kjh|g1%`܆xT2MjJ~8Z ԅo7aoN1>Wԓ$SWs>}uoe0+ky|euZR>7v [}foom?PM,67|[xj2(o_i$׿J.15Yc/wH'Miʘ&!DN)V0/_O__ïVd v"Mᝤ:Jٙ?[?Y~"vhM 5>Wq9 Ev/, ?YNG=yњ7QRR{ܿB4*UBzz޾-Byw0 A ܢ+kUP^+oy|1ؿ|C_(F)n8zN_q{֪j&m󾀲7 g Gr}}}uܾ‰>?o}o~шaEڞBVCB~ֺ%k_ڈhPvN)+|#U'Ս00;a:an)8IT)%2_+zGӡ?: Y%=>j=>ڎ#nSB1"Ȗ=UTѐ%o}''R#^ԹY֓JMٕgU oAGxyH)| `/Gڜg+j8:; kKeG)*xsDɉG;ש)= ;㗱PB<:U~ELމ`pH`1/$eBҴXo//[L"UOV=utBsn1Ҝ`~^MEهHD8Zxə`ݓ'Go5~'o]ߏ{)q^Mg9NWwznwz_mҷ3=ٙ Iq/[9nSEO 29.F'˿˯Egԟ,bXڙtjΓ6}[ł)sܶƠY-9K,imΣ?(Χw\~r?YŃˮVu[1ԪP:C}Y9l1>oRgՄV+KAvI5ArQ\,Xn5Um9Hs)\s#V=uf[d̶șm93۲'gHokqvZ8o Ro-}e˞:_->bB՗|xWv2^ ]E>ꜷsޗ<˞ Y';}Yqpg`Usur3qT4_d,~\,3/w_RǕFg}zMy͗yf1ǔM'T_]th8=o~4G_}@2/|2~4bVvwѤ:ftRf}ojm}Ǭ/sZ?aG/3X.t:8-sjtUG;c"shuXjk98qdƏCƪߺ~JULjozÏ#j˕: ?2Xm%SMdsT|3%`LdW?|.;*-~sbJ ZuݱfCb E=~5w:dR-ƻ FMjJs]_c#ǜpsSsGOJߐG⨄,m?I|ǣx7@'qxtqZuƫuO; 9|u,9K8cuG$j:,:eٓ3(_1C sO Q$R9~ٹd5dٵglmR3YNf%>_nꩍ8&ٹٙk9%gՔ:/:/|nX@g֜>%Lw pN:hB_f9ͱOFr]mtg9RbŔ.Χ_6`Eq(..2IH|`ڟRŴ_vci;lhPZ|u&=1w2N7b~K_v &!ם|Xm@'G9`1>@gOJ(EG?um!ޙ01Էf 8Ք&$nm:sñj'HsFZȉɣ3Ҳ{FY~1.U2iтn!V꼵R|N竟L??4(:W-wѢk=:+йfu~IN)џկ:۬_&|\ͪ뵧&M:O,9f5~eO1˞9~|0cspYRlxP4`cVwXyaٓªN>0b͙Xw4h)u>XY[t1Ə9 S̐?/VȪ:rN돌W.V;#X!2'tuNIH'˟9'pb~k+MD}ѯıiı"E5>ꇿnl{`E/IsO"*gT e z:ւEczH˳?~ʉrm(T D]ܣ%kc mז(CEUbӲȖPJ:ch̥.ea٥Zh@TE Ԭ-w"]ѰKaF2 \ZNN]=iH{ցPvK4;ݽ l')D6@3ڰ#MGB"3(5.,8XGR]8v)Ê.wm;[0kK}RMȈ}cm=lڂU RNL1%(E[,mp8O"-{Jm̨Mv؎F6VM9_e ]6OVutlKȼbtC׭Myn@$P]ԗCf ZP7; $?zR|4tk6n3EZh@ϛmʾڎ$E_PFbؔt񄏚mwB=T$"4wDI@5t, N@v:}SK]X>OgOz`mx0Jc Ln5:*&֫a'A ECjB(9gߍ"^#*DQyTc 䛫֐*ۄD hRhh ~:V-40jahF)ՈP 1!5.wGS&־VZé%ؕ1Ά(B9l%e h۩1)NpVͯtQa?گT8ZK1.SI )0E1ՍDޮeۙJK١Z0=Q-Z5}u>ETSO2МoLZ>婢N"˪ XtυvNqpt Su/Å/|1^^(tH^ 7@D.Ι_Fc|Ѭߟ.h} Uku¬?G5l ym[b`j$d҉J- 2x/5RDO噶iɽɕWF>ȑQ۞&pwtË܇¶uq]g}[Hjmt?NFtW s?7_~i2tlsnU &#0PkD\oVUX ;7a`#V7xq1 8FE("aݬ~Cֺ[ i&;bB 愽iv$X]Q]V55DT2'ܬ*NT42ٯxwU 2тcx}XULnծmN{Zm ޘ! yԴ l0qHmMŐ*u[`&4EW `CΪd/[v7˲K>xln_HbՋ3acF<#@22̎P M&=:p0kUM"{Lfrkb=s2ПpvcXوYؑN=EyFythHߤ  a!Âk6VC;嚝 -f j7Nq$XFL4ɳKm>Wc0]v$2 ' y[07-Wa.Z]k]ʆnVEtĠTwNӝ<@Xa_d2|UqfxdOMY4HZ"CbP\4D-mہsTI̘ b|쐟˴a9E{(ӕ7S|'3껕f;gcT#?*/,SIb=^ni!x*5MR)Qq:}2EwcZA&57l)O3R5W=ĝN^etRuH[M -zJ r Kg0x{kWTj^EoC7xO<-2Bs89>N>x[O?3[WDHT8P[ڃq@ 6{:aoՇumJ,R!-bj=g;t蹝޽]7zCƿGp!d-N9\+[P@z,D~sgI~_7]/4<]Q%\tOSp|5CMZTgiQp8LVrɃ)CMfT_Gvwx;iY.|pq~L~Y/bYA't^J+e/t@"hGhvBL1 +=X5zё7̳t֋Hwby w懁a3y1 W,0ptK|~O5֊Xs]Vfn-2^"8cX ̋=ao6 1 v:Md@zc[2(Xc8hϬP=eo6!3km@̢DQC` GlKA]qW CkZ]ZTF҈l7F.;nYޕ?pwFrjcژZLc5m˞cQB7uPA5\X,.ؕھK`C:ZPJH2ZU<9ZonE娕g?wR&m:u4nlx#5ͩ ~tR8VV9<I BT+V*<:꜖bo*8&w{.\iA#. TRj-M* /f%Cu'Xjѥz^]< TRI\:HcJ3`b& *R$ A- y fkHUċy{vtLP YTӬI5+K/%bK:3AMM^IͶf['LA:6?dYݏ- [TӾ9Tm-~86g?:u''xӾyi~V|7Cw)%d"u/ۼԟ K<< !SKt'ewN-ԗRU/e7_J[lLyMFE?*}#Ly$<& 7¤cGU mFb~;D1pP&\4/annP#ޥg(H+|V#՚٘ ",; n0Bփ綖&ɠʼ.G"BxO nBDL})2InX76RGs! ']= 4,VU}X 3l.J Uc^.@"(Y% `̨̄fLw7C5VYg a"^*>={=\YppguVIugvİu\ +*f|%z[,7y[>i?yt+ Ru1"8h2-V "5I{j0RɊ'{:6jW_O[{nLd"I3*}ǧM~<3)1mE9vs(pលčfpyAsUͭE#\apW]M"[ߛE$I&+vsvS#d-#_̤2m6:6®A47lbTS/,~*IԀ7uM$"ZכݛllMKHIb3C1b%q=q `(%2x2P2:A Se<=ݲ(vĥĄ ZMb[Ii9K B@$$Tl-ڤH#t P1&sE%X֢ΛX3=MȰXF[s6:at̎q/:#Yb]Y/PPn V˱މPoW*[zp{s>4 ͜EΧ4rA|s4cJ!|0>9 _ %Z-. P^kŧt-x1]4Ի9M,xdžX;9D$m+K"l=j$cdSk9nj[4yaX X -*iI }6Jݫ`8ܙ6&4? Mu\8UX ϶o D Y`eЛHQ#xB=U Xɘj\xQspI/6wl挷y"MS{~6$Xf$a*mRμH35M#PC=OaB$k@Ph1AQ04[w0-$&ו=DeqG&DV_hpy,/X bhR]øvX6Uh,QF(b%1> <*f[13o"aP;^!0]r%WLv(zdhVzs$v%<@gd)qش;vg ƒdJK>ԁjKTD^0$46yQT?^gNwEe.yhx$NE?V`]#)ߛHC`vOa9*M<)?Rdk\#1ڌ Z|b<=.{ѓ2҇H+iU \k 2`M;@#"&MI?L Mɺ ;cg2+&f=E܎ ̫,677lE:y=g+b=Nf`frҳ%-i!T)8>,>P: YŊ/lOU|Lxj=p8 p- ᩆ# n;jQE+.DdU~kN)%OLnC+ 4d̤09):_aGp2QwGR&j@׀oE…3R$b>\Q5l,@u٪/<럤o_I3Fc4xPV=U P]B[20+$C_q5/ $TU$ErЖ=JAƘ{jV~6d4Sȳ~ =?w 2i ^jP,v^#[oI!JD` .sٸ/:緶udwJ4N^+3ғ}]5Uia'5sβ;Ĭ4M3rRlnƟ_ Y`P#햎wBL%LIX|̠#0-HI!IL18,\jBOՂ :㮳m,sK;u4dY_ΒkT KHayba( 4uxeKuzl?;2lHK[j[rMݗDq2Џ͙o|-b*$4^mقlUn*LcH{n@K*u1I~~u{ZIw\THݫv <Tn^R֬z0tV2EQdvJypOD{PaA {vS̄vLkӁ}R\$\9JD7UnꃉV]Li&KV >l0+%C"ɮ72Ȣ|X||#]>ͼ؃kE~`+ds~ipbu3V2-3BLpW~pS{^g~|_?ܢl8/KEMZ糇aI|& ݃kY*/ ;aǻX4G:MG  >bYb3dun}[WyM&΋E}k)cL)&oL46 >>߳~&Ctxʼ3*v)p4ݿ=>٣4-,D$dɤ;J U0ʮsuX٣Lgr|8;q%_rט(9~Dd?\AEB޿f8$gUgfTe=ʅ{RQ;-(,8 ca1<ϞxJ]dPVGRs/Xy䬚@fW8g6I/9+&gΜdפ<#5WY>T<'XS&94%xc<t_psr iFE@Gi⻺$VO|`̉W6Pߗ9D]Ne}sDbzݭĜz5ޤh?Xk*>ȋ6=Hb?1ݟ]q 62 xKsE ^ȁT&NI_C`֋[hZDQ~SѰ11ڦ8RRu{x\w aak?@%Ua⮏ui* 'MWE=11+עk,e2eL(? M=YCUQq=_6'l=EVAaѯJ>@{9:[[m&ۃ>(m5TaPqs=g/|t^||L#ZW g4bogx?$M̚Qlb+e{3rov8H&Nmw${HD}*NNO}BL=LaFXj#`i=V'Wh z u ;X71͏E{jj ZLSdm5N~g~7QQ;x 2j&<,מp 1xxi}2g/,j+w+<$B<$#A5-Z$(NiKL-aMzp3<1jV>a8|st6e[D&d(VS6yi0xO ZЏqf\ŘxԒoQѣ-QZNcJI-vVY>W)#8k+y+,_8S-,زrEo̜3/ )àqf8I$o7@2VZINT7hYz&59aZ<9@_iggHw  aahL[\A,V6TļMW?k0 r-l#+AjIaU;ruC<%v {gda5'$9t+0>]]9},Gw ) u@T!+,ԴEmլYJDUTJu#-nd!Βs$:XEdu]HE+)3VgPMh⾚$Ϣf*Q'*''O$#QeR1Ey.jSznܠsxblޓ c\T3I3OX 覴I;UX2tTK eE"xR*;RCw$"v_76 ‰Yʋ=&nO҉`&UIXcȆ/"XemB2n9tWT}aڱ;j bCqc2sY [rŞg)?EH ##+re irUadrc:RǏ!ZI-JgW?,,sW{F2ˏN׌ěXXiQApS6R:Cڄ)kΖxμ.Z;d ,@χU *$g* Y;D^}XR黵rJkB(6@#2xGUXM&%~cA)Wr]}K=TɋH;*~[ÂSHPLs.7<+BYD!+3۔ɀHEG;ϑk`EV&J+V}~'rۙ?!""G#vF9,S{jO}4STCSd]V,WM {5]UL[)ڲy5|#pdy rd=3Q@A:^dΕg^:JC`VZXTvVEE'tMV"!UZJK#YxbgqouUU' !|b މ5,%]d?Y88S?#9|~>{b_*Ӱ {<'BիyT_;p&Ko9B T\Jv ^zv) pf >.]#K]֭XUyu&tn`3JH;gux^ƀ|JٓdV}aE RbRT b/wY9r}$W&u9yH!1أ5x/7e=ye>=I^Xs!ճ' X*U1ɶ9M%ZI使4ʋؔ>cfxܑ9JT}g- ],YGj01~^97wwO@x|[3FJ1"^l{g8Xx2!+e)23-Q/*3cq;BB/N$XL "2A<=EEN֢? y<0lB_Fes{z7 ^FhX7s":潡 $ ˒ş*c()X,*rȭp @к<|Rȩhޏn4$)CT,=< hHeAZ/ͣѯEx+ 1Eu8)+&݋jjSCkdz[kOz'O؎XwpO  0f0B;!%άJᖻk@(؛x/:옙&}b6S Z*v\b+=:{zl{C!bduSHamgXbLp@D=]GRxx_u9Gf][|^S掆x*}Э694,VHQcenr/V"^!%'lˬMwD!X[=n?J@g2j3Mr ADI<p3o}!]'7CpjKVql<VԀ6ؼ~ k9\PZ`LgX T|.]`2>={F5<KH5vO瞠a@+=/-›ꦱuoPTKR7*]LLP]P$ܿhxP|S;tgM^u8'GG$UR>e .f̟L-H㯔λv{Ϋzz*1*ba%*p(T[Yt>SGtܟqw8jb3J5Ō/gMIĻʧ$3 diqW#)[s>Oݔm7B@{VkMRyKiIZG]T1%QE io{>M` :5J'uWQ?Km {dZ{dmM<^/'ڴ6Z0ř~nTr1j2ڥKHc*<jr|L>x˦u|`gUYl%ӌd(Ϩ[i2Mg364HJ}Eȳ!Olxq ^"J/bT{]gU >5d=H/f0&SȢHGY{M AMFTCKv \Ct|(FP(J=spV=.CO d="6shS뙬֪zfx'Wzf(u?}9gj!<[+ &])2Xf՜wII(r11122z2Ž(Rjǧ {Xj:Z]?BHs Y`}5aȒ? X$B&Y`ǰV^ZV}6e:| sw/zz(+(C ͆AE:{:UyFͨ 6q ߟ6Nb_-H͹}t{Vu#㡷-9]Sh#uzbjBrvȮƮv?wKR6^z8H]fKTUD0&3HsedeΞq-rX%훚-'!h0ZJTTzб v*)^=u1EbBf ĿSs4,4Rz窘I<8 l?ΨRi!kٱ=> 8uTʬ3}hjgh۟$!n>=w kri󓥈} vI2O7 xVFE*MO`НX|G0=z!j "-"VLYye횴<YU$uTדHd$oŽNͭon#sj YE/qS1Af%HHm=%:p'mT/~Lfɨ)M/WVYMdf'`yK}pMQlMqJ9w9!}4hA6;}6vLCh{܅S9w H0wRWiڽ=8dp/ s O㹻ߊӂKr;[>()VK SqWb!h-ѯUr쵖f(\=bq2VԨUvBx*{6btăm=w;IzE=q?ngSe@5T^t.JWd @dj|/j9k{:tee Ǣ N1Y(E4)TNҡGjsZt=ʄ/?+**R RU݁RO_gMSw%$A _t |P%KA|x%k{6}^!mSSe'-J, tXk_4@2b n]|^& 5rpr/\)f)A!CK/mYɶ k#i: s\В($)%uRUvtH'ϵ.^G팓2'A",'I >7QK穾T]kjFMqTfyE6csznUR IP` =z WIv#zj*MΎ98Hl$AIy%KvAk)ɰ3jD/ #F^zt|MA-ΒJlݦoP(ZK/cEcc%KgB-Fp30z(͒;²国nM^aIu:X@c0߱{%kzZ@ڽ>pfrS/@!b rDX|Ϸ|X{-cԏW'cf'믐$4\ TOvٞC4@N&&8HyĒ[#Nn^.oO߁m `Dx5" F`ddډ-;ⲳт1a:c ya e9E7âE)̜PMHx#S|HrЖ+/x2%|y}CsSTcrҍe.[C:a]Yt1x &+v[xq`bkBMDq#QN(9h4#\# q2O!*#),x1I1.c3浐͐P澦!&J[;yj(EYChb=eP%߰Exq36u_F^7|k TĴN\r9/$i3U52E5?l792_"IgjƣmEILWvw/̜ J,\H0ŋgfgxVfq12Nt)(Xa"5*[">"WB d>r̓P9% ʽr ee ~>IgD""?R9B-C_Ʊm>jaY$ J© auh؏뚠Dq6=oLosvڳBhFmI"]5 ;l*žnI*BF@, 3jC-E~dX4v#]G䤊*bԪS?L)+~,ڠWV4Z"\ Pߋ޷oj\оoa|Pʦ(9tN%X-iS0x%Ⱥv &OϹh fE߬ET٫– /fˬ=xg|"lc'i :2hq]G.&X4!d~ %VJ"^:8jmCfa2nNV9iZeQԘ,м[H(--%x BkmXj1j)HK7UUBVyW #6rB sݺZA N vg I~$P1UM n erm] db'hq#`XDhثZ4~ z U7o'6-Ԛvu!ŏN= 0ȉ I/;6}J^=T$'S _;ϸT`W5@_Խ{.P&2QYtlsQ?4wVW3k6=@TY};~s:yomS՟\;m!H<ԓHe;+=W%Zx7:r;lUeݪ='4)U5{RLFk &ʔ0jDnYUԚo)ExYu甕Π>>QLaqզNw& jfi;L#}lJȖ@6 S͡+/zkanݚ'UQimCȮ#;ά`lI=wJwg;4*(r* bG&~HzO6~ Mmj/"Gt#usܢh+>S5@sߪ 7 @!DccDN)rmۮ^ݨi}=y;Tzh#>vm FM<|hoR %dUNR龺0󶎬+%Լ9ŢeO훠ל&%M+B84`!gwnd/v-7lfWc*{Q hL@QYD󩚧[cf*u XS/GE| lYY?Uq rh +,@kW[X!BMJ L=Tt}Hca{.X-&RXz0Yee*]fwɽ֬:2((_5h!Tldc{Fڪ8zٍhF56e{{jDEr ,\H0A RXHO_3F&aW/FT|-BSX$bƳ20f t4gPԩhe+,Ne~cp4NZNSqYL5Nt~m%| Et~RV0k5{]%בg7:,<3f!tKx2NQ+ê;KBzFN. {40Zt6r}qgM{L->; ,~[vAvjR@C+m{ܣQ _ǯ* 4ه̰bwXA]{ yhV39LNjqC7nⰤ.0%!ntb֕U恦HTJ"lHU̺lry{rNGYגsŢHOO7 _U ZV8n]=ME2c%]Ls\A9>:| REIA8.+>gct+/_v\xQtN`B+#=1.{ 'p>[Y7Z Oz`AqXB?}9 >%2Or2lM7vN(hZ9C>Y#18Nxl~,Xzn+{I *M4h/#X<|S%j 6WnO?11U^ ($W}ۺIYsT_D艹1EF}T(Bj(XA'AeFdQa45*"-ᥟ4-D~d%~bbbjN\҄'js3]sTdC7!ѩ9^ @fӆQ>VeHJ`شW4ԏI Uzkg!P1ؕ;DMU YK.V#}\fwbc~e\b%}h,Zr}j=IBFCfWSX)媼#A vqw^ *1D2%nER)X[|]ɪ=Bt )ǃ]> LnkigV%-s\Ψ4Scd:s?""Әxؽds&MIߒe1G0 5BZxʔ9 'H`l98bZmrU(~C|Erp.+7mpX-Zj!ד#[nnXw~330wunAVr)v2 k$ca|'9ɰ l_M@2շ}ꬪOapBOrNQ ^&+$z0fJhߨs8Zs B>Jql뇥_0 ΰ$¢-ڂ7Uu;~-ZSڞjިŝ¦Ij (auNJy}e,XDكS@`И˨NQd-6Ll;la;CC A@Ӎ+aڽQICAV_~ԝ%)V!*uM!\$bko۬5E2Eh#?DK)qs.R]K}{c^k W %ݻ5]ϳQHP>;A t~$ō*R{k"o+Sٟ6x}(S^5&U˒=n|Q~T ȶ\=c >='-!PP#7kQ5{Z =U,Tp G IzU` =cQf{AuȽj[=3AB'0ª_]5W.2 =B\rE9uI3*~n|kBHu!u*]=jE4tO?.Ic%4TSJr0YG &CD7C1 fjs >Nnb +@}iON3): qip*pt' TJO=` UbU lk L[6#O K'܃K][J? E9+j0q~̉n886B j3e1ZW0j'~EȞF/CkNRi3fg<տcv}5(4QkɾmXwSUi=jq>i'`6L40A/WλKT42AB3ui"L`qӇCP dd'6b5Ǻ-A)`1 I]@Űpq'd:v=Gg9JUVyX+bʼn *#F|x_7hVP9O.7|H=u-'0Qz cMR#C ~M]jO(׀o8-aس`pcռ&Ԓ!KOU꾇rExpv>X6~Tc F ]ohѮz)1!*moyu A2/AIFaiyݒkq^>5}7q~7^Q&>QF$93qM%95R{J`2I ̡&:ѪF!+YNGvʻ@991l~HbK/jY8eCDi!J -' V9HZ k7#hƥOvip ;ijCGs=4v (njjY${D&W&ՓhZU =bE% x.S\v<MrTV{ُ[j*I:INqC(}.E,+EQˎh&2{5oøY<3HGp{-e[h$eIm:4/8{y%2- z*|^\$_4tWP+Xns{X:4ȄKv;îzx|Y*`rVvTެFoa{0kX *@Nn2 b+KYlV "c#gfX`Bkd*XqUmp({Zdo38baqԽ}lv7jt 6P;XG? ?ы? !l,UZNir5%-`+N⧙v@U_c{ Ϡ4'֮H#ؓS-([.虼<jlX亩p2I~V3hCw}K]9u'ˇj\1j"ǩͳ*c'j"$$,mX@݋=EPFYFbFPG~z_Ƚc;RPjἓ\"~r,'i `LVH@cj^V8/b1f331 m,I?e͉NJzL'}n{6HZl ~t:7m@/L)),WqyPHM5 w125Yg=mJV7l./YSfF2kP+-]&9(T5iՂ%Z5MZoZsnlrGSbٞ f8$pՅ )Mfwx1#ӴG7=q-M%NROp*'PO&Lڠv2 {:5 z "pFS R&LgδSD7Ba L,q'T+htB4g 19A?5gM6}G>J}8bINhhE?`4s BpSiكj9OT  fw & )NܤOmc ^ӞytᰈuUTvЌ T@$qp}^<bh;2׾kġA;KoHFp嵓:hܲ7k\{zz0` ҃s0T[Z]e!0Kp鞡ä~#:Z!!)EI\h-(VLRC52fZ1v(j^dw513e$lI<۩ T7eVЃ~P].E$ (*:s塚d:#k NqRpR)*'iXi{Dhŏ޿fIQd9F'yH9W)6C KtYbӔaG盙;\"zOm &Y~?R Z P %Q}ɸ8k*,qc #32^'SKm@0c2PW.8ڦ7Ӊr5':_ڒ7gtQF` =rVIXȀ1 ~Fz<#lD'>͢kFued 7VfQ?}~۳uܮ}e=_%_e~OY^~f$dy7#1(^6y9=D8m(c7 &XZTINErɏDŽOjK}$?qwxUyǵ?k'mPEյ˿SXCg}a 1kl--Y MlܟdLC(Ztu;t6\,Y&9Fegl2ZneX݃{&޴|8 Է{?PLs@6TD!VAA<s<̮+]?!S3NC\ĩKy[C3l +eOf悦xY Ygn\g[a `V]d ?d AlKgGjjq:A`0.g4 p!pNdC3&M.Kpo-CT^3ć&$_[c~*STt ¥ Y~J\kVc6 k^8{|}fEVxky(dÁ]{$Jg_e|}g*7 8tbEc.4>zڇ7~f gf;grLF_`:ه/!(Bc?'`"j@_ fKE^d߯l{59dfhb|y~g×{.ٜ܁0s6~݀{vf7wOJ ͹̾2=,V@ZzطUڕ{ucHN 7cv|\4QCXB/?}QS{_{:Uv4]ZZSW-)௜о ZXl~ |{m_}V|ۭ;ű̽?V}ZHsL+űMR>8%}4mGa/15js@s7;޾m>5g|+?}~ڦ}5W}UW}wm -Ɓ#=3m~XX7-{,[ 4!oe D @IhK6%l\zITR잌ގ#v]F䦲zfq2& I lC+}-Kk\l^-}@ nk+c4)^DԵ Al//lV@I[ӌęE3{;jȝzKϑci1/=f`U 8g"6O}k'^Y<$4x^ (EQ*hKbheF tL"(bh&2W=dyl 3`[z[tI:3B<6@)qt>t}9iA) ?Uro O7\g*d5!mR5y,F(@,(KUZb Iu1xjʯMiqha1p{ 9Z bLj:'J=7V_P+}5mWe%ZddI4 X͓k ``‡ ۛe^_od KoT|1 OChR$kQpUï|#> oa=X6`20߄cv[r"0|Rf@;G9 hCj'ϺvUJO55 FD'#M闀?˶&Ȑ-/\ jeM6ά!=PѨcC'~7C9~Wv,>vTDFXRf&7kWek/Hmuk7UXPyߚ>A>>am> +ۚ%i_NK(k9@;XJfٙY]|s~:ހc{b`7xtK_Rs"; .SE`on.n3=LP&$McEB% 8$јrnė9RBX88]q#z]zcm Grۦύ߶7{^%H:{{;z8x@j/YV};C~pdqG#CI|%0\Uw2/rh==Ӷrh|~-ۚ߱QOk~_B}A[7zAq_@5v_{9~0Dظc%RY~~퓶Ծڷdm_}?',V[.[3of[^>u X7G>5ZK _+ƛ)vrU:|lY 2ԴT 3Mڷ[|}.Ê{~`0Or|SHpia,Gw#\Vݷ$=]=|Vj11*pGX{e[J"}܇oGmힹo[K]&FV9M;{6Z 7Bp(Fh$>=q {8oxܿV}~PSvOǩz[QU'3ZhyDm׹q?Zn?V_P?n:DsvtOk}ד5@4jo;ˁuiS(쾱,7> -w|P9j)Vlg[+C (c5"aí1gJ'( ]- i1u WZ~bYcx aб=2n5b.AFZE8(*\V5yMϧ'> q'vi{{oܥzܻao]F$>+Bok~\>?n/=~q@? -_ˈ$̀<05T%PmWL ݭ썇ձ 7tm5K{5b $rJP+[xx-E_V2nF-`?tT#*)]3S/;Q :R T;{ӦI(VwFPaGڣp<:*tV @q[DTCM}?oϤXL6WGy@q׺"ӻNfsT&`a2BfEU?tI3#j-qx_mtBi[;0,oN`BiDSڎh9ӣy-@{fk!U E]oVG?Qx??sD5^Cu5\[l& % N~VܫNnos󯹧y ]28%NsXye-0\??}zاLOVlDvۑz8RY JٕE|jB0lgGf|sۡMJt(z-S5?œfRGz'w7TdGt!МCۖ|Qq$ >Lh8[!v3#O5dfK =ߞ.| *]5۞(?TL=q{C#fn6b$ %x$Z4!% 9'6S'e3v>[Gĉuݓ`8ODϓϢKGU& m_;>l6ONjcXȷ_/ۃށ S+}FZ{}뾷MC| 8($~ "NJ|,rwho<'a?&vūp#vC7}6%/kF6P{=%QlՁ͚Dٺs*)sW;bīmŁGYEWgܴCqq?r6dg# =t;d^̏~lBFddka>G0_8-3״`Tzyisf?>6]*ݘb^O˲fzbT%kzFi[r[4{NΖAB=6od9ȱ`)L)~(߿3ߧmئo<#N40ҳ/O?}c%2b=Xۥ~lX0EEr+>4{Kҕuvw9;8{@R_ξd$hn[?uvD Z*L{owB&rN3[QAcߗD0ϾA%TSiqγ?r"}d-?&}}}:?u>xp)4Ot/,/P"=_ nWy{]7ہ`?4|+~~~`:?ϓďv"qjO6?>ak.`(L|o8|߻}AFhj9w h_~,db/?Nbim;g\*v}'e~ݗو8Bщv  0?~k[*ENi5BXxlGIxZ^-qSAQݛ: Nn *|rq!*WH*ppHťqV%88/Z /=5 =qzjau%Nj]GGD }x>8Ǡ*;89 ;x c~_\ӦYTl'JRqv>3E`Ħ߽cĩ'1lx29tb ti ej)"o-/gU ojb}DrWE&|'%#2yE׊u 1zs.YTUu!lS*5qm ծ!la?Ʀՙmg}&}}>l:tPd QXb%e2[I'y jB(RT0&( ~K^_~MOS>v|~z vwADtiڳ*ڨف/tzǡ?Q{`M,ϴskwp}TPmu ]n^ul؎;oPF IH3_W.72Y#]0Y󥯒%1w,sƲX!;:“I֞׬|Ϡ,=(b}sk]?ϭsoUzϾD2B6ij3߃5eJ-vtOY۬5fץvfYD󔽫p'4~vND0k*| {;dMËP~&}}./sL{܀+x єV O?_qzݾo=Cn/} uR>8W~)O~|꺮g]=6s>r4aw>9a7.C#g[U*~破|<wXgjwx(K|41r5$dCvt?c_~cOoVH7d"ElG:݇ln|Oi{~9f=.g{og H\Y[&myϻGja4\(!ATG[9p+ܛs(5`_?+۟wL T9X/io:x sJm1\p@w%z+qOF){Q#k|bÇٿ}~m(ό-tO3SQ==roE ~94y6^u\]?V]d! 1Q~/V*a'ɸ7l'fNK߯iBHD) Dh_Ƀ`PM2TY58>9C}ƏA+B"얆80ZאPp2@E"'4W:Y\-Ω!' i 9 >5 ?y8X9 Q  ȆV6E-vjԚ}nKXYŬ:Eح΀Y(d8pt߄諄EC5, 6at!]Јp#]cw^v2:Է%6|W@4TbV N4DW+`۪ea/_ٽN0G[rUD }ɨ\ }@D[Z20?FA#܅O+5w7SbMra45\H­p 5<0@ g}HKPԛނ:h&c :kn+xsX$ aJtFM ?JrcHJ.P4z@gq*0|=*&Bm&&{k$.oQx%*/ <Մ'8'mvM-p09 s#]91~H]rVM5\z;РA :{ m dBju\͕ěnyN[)1% pQ =@^ DBfa4<)$.l3FሑpU(6yN%~0bkp]_ SE1 4"$jixO,]8oR5J BpE⅂Z9 5G$n+xr[5Bߜ ~LӛF1b MJ\@HDkm |>dGn4<ǁ6.aZHfȆs0g/m4e…u ApX٦ikVt qpuN~59HEK%} -7Hc˟ 'uSS;{p~>F`@MAr dݫo!<$ئ 4@=@살p#\t QaYPAH(PbmOAdɐȍ%l\C-ɀmsg ߯i&z j@D4͔3p=v(WP G|sڶ:따h]X 眍G|p&nǼ8 1PǛM'>;5}i%iCCYG. hA} p+]s\Fg¹:#>Ic3?Z;ur,++ԋD' _#*(!$h*xns'Q AH υ{j{8mN)D4@ sN !W­p[jLɾst6Bfl"NۡRlJ4Bه΁%!4XAZ.vKs|nE_Y9|t6JxۮͼOU_77XU, DW0Zy4: .& 80 irPi U+݂ ')ahN"#!Ul6lI_sp\|G"^ 'Hd"fD6ՠ9Q z4A"8y6/:nKҰOU[UL #iDh4^l2!h/Z=_ R`c rB lV8z?n\Լ0QHm{bѓh5vrN\Cz߯iK9 !_"oݝQ+ vۧx. j߬]V{u}4PQbA=ˆ[-AhH`"y ,#JitYB\CбBҸG>Hc*+\"8#urhݏydN_NH'#T`j`肤 9 ]4:mL-Do0ќVO 3iY+$,1.H{ɼ #pGpZ%vKsZ©q /[h_esfOv pp/q.I_}j+؉v" gaMBW*Zv0)mI,Ndp :}ƺ'+\BF xit6Am2 9)7 Fk6}NەNB"ߩ!h^9ioMp 75,#ѲL_˨UY98`hDRmPEi+.D!h~MNO`jHtSG߯iK9o~ݤ܍p pyqC-)0>KqGҺo[ctx!KV L4.@\]3ɑ j am5UD>Jh`v J NKle$d1v2ؓpta@=Fo5.:ES-SyVX m-܊p9yl*`jŜ pIB }Ω E_NH̓k9+&A ݯW45bJ 2|>s9{'M"D>_ `C Qu'OWD|/V}~p.Q8\ 7F~O[%,&qQ =%\yCiNdK 5 >NR oNXq SäOR.SS}ul^$Jw7gmGp+ĴdG(0Ÿd[$c IvFERl^qK<;~1&NڙvaYBl;UEmn1%Гit`8la_҈.cV|T@*kCb0Y5>8LLc!Z\%JՂZ&I3L(i|Z9Aq/AQV4zxP]2"$f)XA˱ZqddуW`H(p_ 8״!$d2?+=]yr|kL|̆rZAc#b&8y員a4«߅@P@CQ0`a?CWf:9P29CGi88 *7 3υܢyIӪ&ǟe7@_5Օ'NK)-ˮbRbUԎ$1d8̆\IS5i}ssi>6&ޡVj$Tseu-|ɇ+KBƃCܳ`E>D#ЖV[|8׎,nlg>k'{HLp>\kJJ_k'(.5ixy| `)mipXi椖k:N&ƁXHUs߯ٿK}9v?}1(8_XQlyG\7B*1.:\C~`iK {׿Do_ł[`+0wrz**V V`ZpjM qH.V88115ONFLI Ɇ+`3Is?8hsC]?=w0 Vv;7ͽ6(\XϠ&1!\P1!hp15XAZ!!+]s*BuX;}r0UGeBR*$p4w9' <94N2%hix)g^)m\m;&VE3j:CvNG&p(W|Vrüt l@wrm_gl3HY`q!1NkᘩѱQH .&s%%"8wNO8@V b xS¢iAPp= m- 9W"q:9Td]p7ys ZIC!"SC^6r.LrU"얆8YxBJ 6Tvm$ j]J*uEi-s*ܿ0IEN⪬27j)xod&P2X58zBv!h̪R*Q058>g4N oKq 9 Nmr D1 "{oBƜ uSäO-8vg}f>H_ p+]sJƁQYΡKyp%3h^^ˢ!䉼i״%Jָ .C6ʗ "#a(dDBW( .:(o}F~'JV|+v\:@  ٢'\}BK4̛0ҖS|!Y4 K6Do* + N4pS! 9W Y !pM{GLeGr5IuY6I q4Ch7BoR|[W6%59ɧV i+Nz.mi4;P/9Ȇ gPi45| Bס~Yp {/Ea 1e̛Vh`')u - Ap8nQgT,yvщ:m"@IxWH81\C;@vs\,x'{@n3ΪFlKJ"|. )i}Ƣ#nkx茟%gt8o[F: byBdO:9 -=fsX_+#%+~r̳8΀͂$y (m*JYY 025AVkZa4<nZ>n~if;`YN5ޯs` ȝ9B&D( A0, 8T4Ii6Ubpth:)<80 nf߯iK9\| 28V}Vš>ujzW,/iY 8IyF{ y&@ج17 q3Cp:ɵ~DCͩ!w;L:E8V0RD/!vKsxf#^qSr TbMb/Z*a''0{ m 9+s _s]ehY9XXs*C4p IsUmtQ+c-TwrJpv3;c\+Ӄǝ\4Vp AFpHww7ћ?bt򷸃(L [7v+\̋ahxC*T/NcN|vq ` \:HAA7WtQ'i .VKsBb`I1sbysL(.TBMJXl/q}$ uɦzKKHTi?p?Y8'@ W~99w@xfhepv{~ SmV]'Ocpel.Z+` 19b׀+k![Vxh/PSne RL4 Txpp8ixrM>A\`H}_kqVC!]s5BdFﰤo'߬Vi hvl  F!AH {o(!^\ Pݡ!qQ/rH.@jy-wszdHZoaip薃D;+bˊ}(AL"K kt59`Sf7DX) _wXJry΅07P5WNY%` ۓC8Й}t+\"얆8)ЈLiK* ? %^9V}0|hp}p"‹4n3dK}ca{ .Bx](&+,]`T40'BmMTSFU8p]c ^VR}Ž%,p*p2v7'V FS o[ v2n(nbY1zn(X+ܑJ0^v6eǽsXdvr?qsXR͏dHNܤ! ©1-&'5B>p+\"얆849jǢn3WMc:pݺJXaEHy1`i,+2Ahj$)÷'!;C>N1|d5)2-s*/}E@ZJRer/sŧ` 'Z{i8f &>SC?}~!vKs:j\Ghr [ \#FGƂsJJk:y̢8}t"}JmITiҊ9y;YˡT,Qr`[>jY=tYtݟ|Y%r!֫ksS. iW.V8#@8&Z47cL5iZ%*Sh9ҀG &/a?!-aC4nÈS?^DLG)C:*Q0,apx 7?K߯iK5^11LZ= i), tDV܎SͯAdhcEiHɆpN>ǠƔ.a58 O,XX.fWV@ǹJ؁0/>7{AE~ )sr`g İJ MIé!g$  48.ޯC?k0'G]6d~@&kg n5oɫno-.͝fat(uPƜ&D- A(qk]s-B Tq-L=WTpfJ%'1 5Tx0f՝&aKZAlj5!&YMˈoNBUYH4:Bgj:M }F؂p 5<ǡtKQ`l햠M+Ͻ$X~NմY8i *!n4%d)x@+ +Ts#\ưx0hG*aCtyy,; ~M\" k{<69LPaL"s;0g)8X6b^z לP\O:{=\wT)q!V`jZ`h@ J-]nK1 <)9Z8b]5h }J\s yk)Ib5AVR9NXض ’龶{$CN&7 Hfd@Db|:Ĝ@M7^w9uxk~삤5pB@6(xUT&xvƕ40 O 7SCЇc:"hj}~/լ\­t qu cY9NM.5wnng SCЇ*Abd 7ԥҘJeK9x#BWg |r&Re}7Kk'#]fkzbCBMo#ޮ {#̛ojS]]VI!wWBM \|i?kNS.ILUF7ro#ؿ j_@VhDCxpW*<8SCϬ}t_ 1E[b*TFlMvFW'A$G͟ rh}12SA&zt=p !ht]삓C_~ <,^:Vu Nb59!@UiV[TjԳ: hI,lQ-7a*2KSAОs z .6(\zAjX$n_Lf V[%FNK3 ;@5 !&e\2Ŝ`Tvk!rԠmΞ80ikFDX- Q(ăHd3#lG{h?WٚblQmvW99 YuiAm?5hUw.ahp}_ ibAn)Ya4<ǡd\e4;2/DN, {mzd*-hnt0IA8}8[EkS+, 5<# G<;,ȪK:7(D!-;AA omuLq)K LOh^jblUB(1XAAZ$,X<|٩88ݭFDXM QĜ?49 EȠN-PV{S= }n?Z_G 9e$^ݞ!"w^0$_l:ZYgҊp+]sCSmb/''!r򦙏 9~8@[%,&hQ TTd lr6?V퇰9涪vg]a_89.nFbּSQS7b ex$;O v-ח>H[ Ba4|# и+nJ%&JXpӵhp}xŮt kh5"Ukq3l9#=$ħ.eH[ %JG0F'} fԹI`nX-IGiae¿/ < dsr>p qN8+p}} Vx%N804@ Ɯ~-}4*+\"얆8x%[|# U:i. Nkdf+嘆2C^,BoܫaD+$*GdbhS>HYnkx#V{թx{|<^AbkE)@Wu9*P,Hi_u,9͏B`IʩT{K#6#sYkAӗW <(0bQ1KADۙ95#  "߬<3iv~-S^ЀwɉI;j)xBI^*/PvCdI`q.H%2 N"H8\GZ4Af*xAɱ Qي`2:hJïrDP]$QR$'8_QFT{QLz%b:eKT5agݷ/s ]޺ DD}of!kjEIp9ixeK͍t[8 B,Ol²ыĀ5Lf,8w p$ހzVH"q=u`|HÔ6:%^!ی[~3zH N!\4>H_ 1`Nz[QmAEX.0.#vS01[ /IcqP!Is=l 0Yy\8,^Y5vPhcC%55]u49u | >i%5|Cu MNe3e¤ 侚ʎV&-8 AS\Ҹ.V84WSqe@yuH߬c$?58>9E4QToZn4<}VA}K1΃Rjҡz9mo>2A58.9=`0[aunEHRJreA C)WN¶i\UٲW0i/D/dhHm^XnkxCJ8ә{˞^RVX%95E9L {t6n7B^P Va:,wrtM̲J0'ǂ럩kZnkxC~SuvFq#@3n8&J# i!C0ej`~4beKHWD c>čߥ0 ߟiA+]8%jcj(6 HLOE|C۬"b N9UY 3U jϜAt4@ 簞Bhks郴>m9bjY8Wanܻr5J j\U ]NN8@ټ\쀴u&D- ArUU\sf"Bt5/þF8Jb#R4ͽm5?~.~O"+;4j7iUv{A"k:9hBU߯iEHƆxۮqrh6ÌDx o愧E>袉18kB=ӟK 1,?y9Dȟ c(~-'F fUrOZ$PK.8IPIs>9DX( ! g3"gX$Mh޸@@KJ֮ HNEhc mH[%D)xAӱ!f`)p0hO57 RU 8]pNL . M\ (X:XJ+x{TrBbHp ,O tNcNz@%JwYCBf+_,&KP]mS߯"$JixOm.NsZjzk%N]N /۹4wL9Hz @H*M&D- A*8 ^0X6u RJH(^jU zj:a p~.}2n<!G ~#tE06]f=¤OOBC+8~74,]C6[?FX# V *!7E_<褊a8TxCQ`4%D e068cɆ6XQ}J t)H E5G 9hthԮНxEAs$DH,GX·Gw2^'`6] N5*~ UvA.Iˋ]!3d9.ΙH)݃88L7]1\`^p@"1fhᜄ/6G!nK?2F(=&By ʶ;vUDxk`t]|p.`\\xpZ9ryp+]sParFcDe>F/Ĭb p:F/Rt At_~.H &#zTF:jO-|T0D6pt8ͅy ]G:FWE,cWA,U(`IA鄊JVf b!'!W64$$>H+a48XQ`EAkxЛu]EdlP{a'~M\",xj12(p^ 5C=!Ј V) F삤UmtQ63ӁGʩ̕:QOI.\%ITJys0vnkx;*[OU䝜 uZ u: dy|&, jhpT܅Rf~.vKs:DO\&mMgdS5DWjvͻs>ӹdK9}g)\pe&؁DahT@ͺ!}Dpz׷, aFyͫ[P gg [A., v\$ E1{H g7[?4bԚ"oTVm\<3h;fi85 *Btѹə6n7B7\ьRwF؉Ɩdhl@׸􍟫D v6s&RN)D_aBH؉lEN&Iw 63 G*5FaQPX1`s1Pߺt6e7Bd5 #8#ֽ|iq-uNiɺӖHKg;V[ۘYzr}6JgTEJ#G)H+7`+p+I/ԐXջH^5lZ r"i^%@p[XAW `ͳӗmNN}kW$0ߨsXOR X XB jۙb r85}s΁`9m-dEHm Hip bma"dKXe,i.->h9)(uE;iJٽ ui?ENɁo#Dz2@}VzH e` #X8uİq{.I~IL|? w_FcpAͪ}GfAi%nixCǰD ܥQN(Ad^8 ߂6Y* f© r 9Ils Ո]CMF} F~HJ0\%qhbdһɊ r5t:^FbÀ8!hvpkA[Ba5<q1-)ci|wՀr!8)12Rɛ`w9/^C%0@ws `?Q TZR]c(BM3fki45+bxE<^<3:w 7V Dze]_HvSxK\p'AAfFs߇~Z*~Ź"_pp, <|φG`+-2ΠC4YY4@ 8ήH>~܊vS8x\XA MfEEƺrXN$׳,ArL N$:ϳʤ-D- qxՊt(^XwtVjWýJY f}&I!#5AZc9A#nĂS N@ƵA=tH/)p]s^rWIB9 %CZAͬaq,rӐeɐsm&7{IꇼsLq4oP9va0?&oI/;nBpx( bȌI&J0Xh:npai r=6b`nBDLnJXuhpzM8G5p[f"2zn3ZaCqBKMlJ$SS3'Fk}>jC.VKc{d+W9YxӍRb L6^VR6If ijaPѪOqO|70 K>FԽiZu ̓>s50k@oLp 75<UW=3y97UjrfhVkʜw7=O z"5͓ͽMp0Ze©pz:|~/.}Q rvFA3`v\" t݇vS49(%gF'ORCi;+0p<\ ,Xz~ !FKs }O UqbJV &JdA9{7*&?-<ӳ: 6a)o˦ivq4d}z߯iKRDv-H5y3=ESzmSj iG}ː0X48>ة4( +\"얆8A:Rr2Z+Rbvw7a0%ymKX%285]TfSA4b4eK1 ! `suLJ\83(JK,)Eߑ7R!0JrA+c28y` y]w6l Q(VAiB=NY '3ðH#\)Pdjp}r0Z[LY#zEx]ۯWՒK^|佼$$>ulW({#f yym$C Fx?\Qߎp[ QlFS.z |(Q<0bKoWn;&olQ}!>N76\^EHY}=_N`ir \䈠QA_V,C[=/V@(i6ЧmU.?|}}Qbx* Jkaah ! Q5'4c$~ފg>.b+x%s>5DyC|Sv_j@kkedr(JП72Z7.li _Fw;mbTō,Tv%!Y2;O'_l?/K_߿|Yݗ{6}p]}Hy}02Vj%?5:i[Y> ;ho=cg{_lx<~d?=_:yojي5;!ax޾zn0O_8ǰq_8痴<1q?ԞFIc<~<;>l<eӾOn-v{sQ\.4 /2#iPJ_.*WE E3Q<:_&*prpMd]|z/_ޞ.7c?iJTM>_ :Wvh0z~eۨN?~?~~~ǟ~e u~ϿOoM?}dRX7OOOoO|1?f K9?+K4緿xkt~܍_=e{^̟??󟽥\"ۻߎ9C{[W9 ׷cbMOHx{]cm忏oo~ y%OlZ\~s~={?b}Zo;<^hs|񮧫_ou|ů3O X>?29?X}۟9Nѱ}oWs=ݓ5KṀx /y]a堪eCJ.JGvb/X&ҵ(e}\RޮK5_xX-v{|~W㯞;pEVZa}v5[]Gf_X(+3W~ez]T:ί]]Tޮ́+oe t.:ǿ䋉GoDyof}3/~39~%̀wg?J=Eg;;^g,i?K@o}O֞F|fn^*Cn-ϓ.ȟ]z,?'K{f}w{*~7?럞ۢ1v9x>o<6x垛grbg,|Vcs8nW3Ͻb\OFˎ7S0Tl&8owQ~`ܛ{ln$ ~o~[{pTmO;bʷF*ϧavyPbve9 NY7E9+[/6dWĹxVO{>8_N'I[-ϵveZٮQ+vA-mE`JU>|mG|{oǐt~m/n/vmr5*6xçfܘKzʔ'͋%x Z7 JR}b{r2AZ/tn_q;|l<JKCO\e$}[d(є]ۂ\\f{[;`ZN|58-+x"b#kxFi\wG[ֺM:jvqڰm}nv,OO_^ma:\+krݭu]FvڰFdM]Z/ZE6N\΅׆,`|v$ Kt>[t.O8\Tם\躜NvI\e }Jk[t.gDt.*o{S]R:u.*E庐rҹ|mF2{tEs(KSW]GW범>z)zҹ|Mqҹ|sQy>vI\f:LE<-ҹҹ:ҹДL::^YR:չ ]ຮugh&epmɵ%Wlҹ7ͦtj**z:(hpS,t{y s*;׻}tI\gܔu#GM\>x }]6>ätct;/5̆5岝~|S:0NڔՍ 5sbEsP:ݏ4wޅ]ptJ7Ӧt}x2JяPW9GWI=5,ý>U7t;hJf$ҹJ纆{j(G5ֵY:s24޴VzKpkzt_hUǾ`( )?y)8R:WK]bOw}rw sWJopKu,Xq JѝJ{uײUUS\'b%sm9J\uJ\,s|BS:ݏ7|ԷKu/XlS:: ~T տۄҹ~ֿ)My =zB\J:]2iҹ:F1zڶ5^G.)eM\ìrS:4s Y?MyzsgJ M\FU=t2ЅҹTי1z)c~)Ƶ:~N=C\}O1߽Cy5ep]ilrpi|زytk'v~+TJڇ>u(:t{Px{4epotcJJ߼CyuH\xOsŶ_tsҹY¦t{|2Iy6[c}tϬ4epPם2 s 1 H=tM9տҹ<Ӧtc s9sQ\c;˶PQG1~;e%ҹjjNZ܇b(4Lrҹ~&@۳uQmr(J-^]u s 9MM\3#u 5]&^RpOҹ5J\{r5xҹ{+۱ P:W֒ҹ7-sC&5|R:ו&q]߯єp|k ZҹW.6M "U;ε}P:1']Wz^_g0C\zM>DҹƱP:=2}tzC/)uWu-J\ N[9$t!+)ost߯Jj^YFx'2x]߇2^ҹ꿖P:Wҹ-E۳-ØW(js!C"ε P:ŴeYKJZP:Gx6{Yux epɕ41MY}2'z#fs *s}s$xx/s  gE_igr5Fg(k| a$5fXҹ! u PtsIyeFCB\]+uOP:5C\}+5p@2sL+fad>.)k4s=>u ]eRC\y~RS:טJV@6V%epOP: ep:Ʊ{D(k`4s31u%8|Ot{ cT(c s 3ҹa*SC\0J:S\$arS:5|ҹ!"5ܕ䮔橎<ձ!&5ivCS_ǧ54]탎uƍ:3Φ9ӓR:טmLֵI}$ε}P:W\_5sCR(oݍ$ !j)kW :e2{H5tq0k]lPFם\߼Cyط(*+G2~(kւҹepyt}% }\R.[ٻ ~ 58'+!:Շ2P:8&۵Ot{]1< B\5!sztkXSe.)WxsWiZ{ s-a ε~Ln~3ε ϕP:12kPҹƕ=]/5fs2yP:9t{r]˘JZqP:6nB\=)Kҹ~OB繆'h(k*1b?^J*}QBن7P:1UntqP:8:k] s)3Go[2}`57ss.5f-ҹ!4/C\uoHJgL+^J3sC\xN~j]>NƸI\c,5e\( Ծ(qo;v,p4;0? &iR>/;pA;lC+4_ yAܡ%q2y΅@A>/ɭB߷ۋpBC .iWΥ3Ptg.RQCKZUC 4zPv*vaR}^w(r .i'B\zρ MҮw(tA͛EZ\(3TdEԘB=RN*v*nܩڭ pBp.hiܩ%*zܩ%;ҧܩ%p(zܩ%mUSKڦ pB N]M;TB? N%\r .ܩ%؋ܩ%bS 44;B=Tv+zܩE<2zܩ%mSS+]B.i' ]._~ \vX. JEO;UEO;pA;ciw*tI;#zܩ%p\7pB-w;0+v)#ܩ$RSڹ(r&:S 4_iw*tI}_ ]qNi-C4;$٧ܩEBM~ -Ҵ'Tv(nܩ ڥ pB74;B+hv*tI} ݮOSKک p\=T[-Lb' MҪb'JsOSKڥ p4| ]VpBMN.i;w;n`[o Q N.j}%$? N%\jD |;pA;C{Qð? N&i7{og*iv*Piv*Ⴖ3f!#TDSKڥn4[#EBx ENp;U|nB/nB3b ]nNn;x$J? N6Nl;튝v*v(vb۩ Im@cmB mWhUN.i;삶SKiOOS [уN&JS=^={, @lBCqN%\.,d;=EPNb;xBWJ튝v*tIӎwnTǭlv*tI+=T? N.i' \]v*tqeQ SҪ lBMNl]!#TĵS [B.joiv*tIOõSKZUkG*kbv!S  ]ʊN%\6Htv*tQ& ]6ENP;B7OS+!<.NL;ힾiv*tI+v 4Qv H1OôSIکw<ڭȉiBcHi@MN.iUN&IziBKN.jhHW4D;m9TmWDS+ h.h7c'=U3 ]ҊZ ]Ҫ!<xv*v٧ >; KDU衴FHPBMqhOS+SqN.i>ipv*tA4{zT0v!#*v٩} ].N4;݊hv*tQ[WN]MT蒶3z٩ i}OCSKfBDHBbORWULWh'J9Tv+hv*tQVEO4;9T;rm@#bJ];S kuQS+ fBT蒶oTv`v*tIi`v*tQ׈ *Ⴖ)z٩ZU SKb' M.N:=v.(DSKN.i;S+> N.i' ]Ε}`٩%AfBwڡ fBKN.jע\BU"z٩%mWfgTdv')0;pfI`v*tIsܧ٩%rOSKN%\Ю`v*tI=Tv(' ]6EO0;6i`v*v*z٩%OS`fWhENЪ' ])f.h'J݊`v*tQ{8.٩%mcSqWvF/0;ԧ٩%bSKX@SK |N!L.UN0;튝`v*vާ٩~TVWN0;m N.iUN.i' \]dv 4Ag# MҊb' ]i`v*pOOSKک fB[N.iOXŅAf@ fBI٩ QN%\KD 0;pA+mZ&lHv*p+n0)ɥd&hML.[P> N.iU1N&Ib& Mi0v*tQX@b".aUSҦaSh&Jv*tISv*taWh}vbإ%~v H:W ]v)tI#vKں2vBإib'=vNpA;)pA;RVx`@N!إ4k5bqX}NP@K)4`Bx ݊v)tQVEmv)tI..icu\EibR aե%TK++UBkR)#iS쀪KKZU쀪KKځT2)I#'R]J\HR] ] :DKKBK ]{R.z$XA&pA;JK͝#vե%(vե%L C.&i"/%m_%D ԥ$mcF'qR蒶+vԥ% ԥڍlT.E..iE.%\*V .%\Ў.ib| H"gC(u)r\#vB-bw!B;IpA=PRfà%(zԥ Z=X ]Ҏd +zigD?R蝓".jud$SGsoإ튝LT :2ԥ%b6'WK *#v R6(u)4I7熨 کQBq;FeX )4Iۘ?KUE&Rv(r@ԥ5pKZ!kCu)tI+u)Ⴖ}gUP@$6",NE u tP3Rڶ2u)tI+u i K kPB46PB5CtzK+P\mu)tI=R A<ʸ&>] ]E.%\>]JՈRv(K?Z.f.%\Tvt)pq R m&HbǺ)tI t)tQ;9Bx oTV t)p\kӥ%TK+N!<.=w?d..ib6] ]v.##6] ].j:z(݋b4]J"#4] ]Ҫb4] \ݩhDچRhcg2ySy&Ϙ癌>cg2yy&O癌>cg2y3y&Ϙ癌>ag2y3y&Ϙ癌>cg2yy&O癌>cg2y3y&O癌>eg2y3y&Ϙ癌>cg2ySy&O >'0yy&O癌>cg2zžXag2y3y&Ϙ癌>cg2yySyϘ癌>cg2yy&O癌>cg2y {>`'F03}cg2=Sy&Ϙ癌>'0yy&Ϡ >cg2y3y&Ϙ癌 >eg2y3y&Ϙ癌 >eg2y3y&Ϙ癌>cg2z'0 zyϘ癌>cg2ySy&O >cg2y3y&O癌>eg2y3y&Ϙ癌癌>'0y3y&O >cg2ySy&Ϙ癌#}ag2y3y&Ϙ癌>cg2yysy&Ϙ癌>cg2yy&O癌>cg2y3y&Ϙ癌>ag2y3y&Ϙ癌>cg2ySy&O >cg2y3y&O癌>eg2y3y&Ϙ癌 >eg2y3y&Ϙ癌>cg2y{>`'F13}cg2z3y&gygE13}=O`<'LF>'0y3y&Ϙ癌癌 LF13}=O`'0ySy&Ϙ癌>cg2zy&O癌>'0y3y&Ϙ癌癌>'0y3y&Ϙ癌>ag2y3y&Ϙ癌}r{*yy&gE13=a,y3y&O癌>eg2y3y&O >ag2y3y&Ϙ癌>'0zy&O癌>cg2yyO癌>eg2y3y&Ϙ癌>cg2ySy&O >cg2y3y&O癌>eg2y3y&Ϙ癌癌>gg2y3y&Ϙ癌>'0ySy&'E13}ag2 z3y&Ϙ癌>cg2yzSy&Ϙ癌>cg2yyO癌>eg2y3y&Ϙ癌>ag2y3y&Ϙ癌>cg2yy&Ϡ >cg2y3y&gy&Ϩ#}=O`cg2ySy&Ϙ癌>'0zžX <'LF23}=O`cg2zžX<'LF23}V%:>W?hEIՅs^ )+ 3]}u}-w?}q5lj!Z S˧V|C롭n\sSu.8.HOOՅcڊ׃|hTq`j˓%Cq/|5ƬjVpO[.#z&_6Ծ{$'n M{A؇z z:[sp=ؐsuaCzGH`#*a"׃m 롂׺|r _{ITUT\ݛ}9φ1>b '׃Md7&0p=TO~97x*lWSu>T\6x~7T]8tO^D?Ut_/Oy7A҉uꎗ/Mq͛Iph>V\/g`/bw+׍OeF<7)犃6n/n5l**92N|Y涏=#Ɩȳ1YGg^}z~hgnǞ8|^GQ?Gߡxٜy}du =z~Ɛ3y~gey<Ν;3r6.oq_GA^ϿK+Dh,rN?ߏ@C@#g !B8_`1u9_r|S Y)ă|=}R^Ǡ/kC繽s`%qm9x Ųx6$x6$4" = m- = m = m = m = m = ׺гpݙ6!ޏCyhYո6<,0th6@\N\z Z# =m9= =m-: =" =\x$n+/⑸Һ♸m׆kCDˠeCqmhSո6T&p6׉kCOZ^z,֍,x, =m*\z.Z~? =}$|?}h1`\z4ڈ) =-_t힍6Ʒ?<o[=Xoǯbs@__֯_,fxo Z#>,ДTlP exK~<3C۟y/UFvD(}[ _ fWsD3|(R ۟>f܄ vծ +~w#*R9Eo(ӎU?v"#"d )Ymct|l;YhܴUFv@(l!P#4kO¿#P,q-K 9Ua?FR* ;@UpaWhe;1C1,Z9t0[/T_0aW}K(?Cޯ{9*G;+YMlG0p(jП횵XbOځ:\mGӮesLzcjPmTN1*-`َ`P?>J 4rSvj߿-Rkvر6jPmkY`{ֽ(q<-b(z>WpSV-hza+Ul_Ƒ{5X}= E 33Z]0_Z؊6po˞uvQ{i/3*zaԵQ Ot'[~(ӷ[Tే/Eٞ!#:lxQAs@(*c[({ȡ>~ēW5e|jy:;e/e{zrpi56)n5omlG( 9j=[KJ+ڬOlxjX8l0@e4aHYNYP0cC1,J7cQ~!JXqǵ1o|aSL|}B8\e@Nۺje;.~?%y,u/ۉG"~qD~,GŦrxf@Eobwfn 15' xl bͲHj۰a;Ӣnvy,;vQ QFv߳yvV""x;wQmY(ճw0M%De{VbQws G * ;BJEo$j>@َPr(JПWFn!/wی3ZllެX>wA:D^j‡B(آjmlG( :"J0ÝS^DžXjw4,ͮ$s>-0VhÎ5>@ČBE':m Vvlq{62l}Q@^wSL`]8&V[r(FПӹXZ(d3zOVUhT=vC`[eDM62rB 6m4cc 3 lL:;c;.@ -Rq(Cq`aeo¾ ~DW&P& R5tgt|eRv`9@o6`? ;Ö$>Pm Gٿ #a_g( ;BVq`Km_CQ<3z,G> ]m]&`jk]kW7f@e4KSj5 QgM(oTOajIe{ DžeHYYGke9EP̬} xHノ'M{KwbEm6eS,#Z*DžɈ!ކAl`Ehe;BQq<0cCy'n bV< ;6²>TAe?TMh5,3gke;BQȡ(UC~nY;ќP>f|S5(q٢4`]sTԷ TFv[$6X6X#DcTП]P6SlTܿE{Xom#]W * ֨ػWUP!jBe;A4dY>ݍת *{27Y9{TF>Z%hw!p0ʨ?\< fb+ذ=Z`Ǘ! 0*yG󸊭;b?q4$[rH>Vނ)QbU- s@wÆ ov9sܷdk}>hܑT|yqZ&X#D8*xB Vߦg8Td#b#F2F-;TF,ue&PXŠ+Dޟ:;;S!>/b$ímf逛<*\ǎ%QʛRC)Im5XՄͯwxnwW{ސoR QgEنAQV$:`KE87kU F6fSvߵu='}2G=%;٪E~ fthe;@!A$`z> :-WϭOG^Qw۹ڗkpـmKAf*HXwg5 'yM .;5ظ 4nN|rY$W pԕየK6 ?gŧ3^vn{;l$ 4H5T *{~c)ښX9mڂCA,um;SR[-`;1hfQhç,XC|GgD*=v;^5Cp[ѐ+oփğ<*{PE! />}X Q5'L+砆bWF 1Ide 99 AeᯥT.D ⿕(¡Ype؎1z#0$e^p+k5K1l8:5Pux@W_! ϝbCGnQG_ @ERKZm_-l0p 8;'Nǎ 1yJ[8@"V*ℲLێ7W:?8|pݔl v>TϏ99/AeK(Y!Qj /E8eПҕﳮC5=/Һʉ+mJf#]}9qjPm*o5zg =QQ<6i+I oߴ%[l=wA' 0rl7Wt}XJՀDƮO#CQac/-i Ȩ\2nˡ(UC|$x:Ҕ 8͑~C ZQf?c$jPm M5_ [F,+'T yn$ ¬I PR/0eOpp86Ն!rjxN]P* P券Yp~ݚ}ah8n--yUg ?pؕ!ȡUCH7=d|*s.fy39}y z\!P|@k"QfvmI05 l˾D!CA$s[SdSej?,;1>GCr\F *W6eÒߨ`p*@kR5灉x>Pʆ%RxM"ڤV TPn2iy*+Q|!ȡUC茀{`a;ވ Y!"uݵ!OT2%TNj5<,{G( BŨ hoR$nCe61gk[ e)5FF>" ¡ YADFS|iDFTOXtmͼHdgv{^~@eCTT-[ (!ȡUCq1.` H; 2{l=tWee{ƕ[Чl% jDP?nlۉ F-}D_ }OdDơ{Aoeo) T R[˞yYp|QӁU hM]xU_%s!VTԠ2#X585EIb BIp}ߨ&/䬀3&f!qaTbQEu_ ޙ~^ A'vyfvbJ ˴|sޢÜ~Glۗ|ՠ2!G*řQf@َPr(JП$Jvnq61qH{UǏ6]VhWBYo-G ޚ@MAgqx~bCo\`qfs>hw*0Ur_[+!epukXL@9"#d ywe@x,Ȗx)ɪ*69X[A lZ]5 >j>ڨiQȡ(Yp Vwxo =3嶃rzbhl2FǭXCNѼa~3 9jσ 0ōD5͖tm'eC_s|ՠ2{$H[ ~dr(JПÙ`ͅ4DMP@@:HQg^Ϩ@e4GP)rT,hE;@1ȠUA>9HsCx`ݫD;wr//jPy( a@,&Pv#f YpzyzOSl!Y9Ο شOvL~ϧgaYfnr9S~Z,SC lq>/7[kb%a8}`pFG@Eu,ȳ aF25#9jϢP쫔>b9(kxzAeyj( !UhMߎ5;H 暙an1^9J0 k2`rWd`>CQgAe,W,gjXA06PG!T yr\1DFR?w . # (#Aa[W QF9veqX`S`,QCQ`\}|BVEKS,!؟#/zSB0tؔ ]>ySls!ַb<03dQhRٝj.(P?\ׅКR4cl,eT(as[!RV$kmFkQQ<^E}ȠR0P|eO_®d?`TF>K;[ OQ(P?i_V8D_dP`8 &a _a72Ұ'U;ZB'-luE5Dy isǫ 6w R5tgȍk)b}ȉ{̹I+6~|iUUN9U!!x6^ r\mѓ^B9@.<?l<>x*6Y &~|i^U ȅ&P!G bdY ]/l} d9x6 kɁb!ބ@nsO+ظ@ٗ09$kς e}[dx岢Ka<=˩䰬! R=հ=ImlzO(P?`U_ 9_yFRV3B'6Q Q^8  < ʞ(P?<.۳7 ̰2@ʞrcZmʉ`״ =[AiQ<>oܹP,uH1Xhȷ;Yގݻw΅R}5M[V6r" 9jσKy^as&H`HyaׇoTf?4BV5N[,&%97k۽ȴW[(,"M=!!EYP- J͸Z o!@ٗ1 :"J0W."y)'e2f/OhNJ]<6eb=W/̒6Z_56|M/v< E!T ypCڐGєu seFe})X8(j2eTΊY`9SmB5 yC9}n?e,/lZTQ>k eg·jh 1ȠYprQL.~giSlkϝ`p؆  &IV}L8 P; k,1/U]. d#厲ݚRt\%jPmP,arj|[6X#E8eП!tl&v e FIn E*rJYK԰b5j5e bTY0o(60<0͊n1}ef8eۮ)!ބu.$?l,sikecr(HН+Xy)=8@t(Ew0fSsr\WjPmT->j๢o NG`ȅU.qL,2;}цSհ߭ (P?@g!Mw*_Frz.[ mC1 3ʹ]N5XnMv g q65סsbߵpl%%({`plYAeo]U[&MTZr(HНs^HK;/;6X:*;W罣T>c)nQdqBEslw3~D@~$yT8nG Q^mH(eVD5Nikm(P?ԮB7k׋k/:Vd(oʟ 8bհ";.XKra(Yp ;m!dO٧~WOvp0x@S8nVe P/jr  ;{o6ZVyϳvq8l/\@V|t}/B8jOyGb  wSUA׫W0E@5,L!PK$( 9*N¯:Tz`^ +xkI6a6'2:,7c QFbD A3Z(1 Q'@bplE m{Vi(P=AwlTFJ`u0bO#sUX e[ tGk"׊`fו9j@YmT.Ϊb|Oo!Cq<_91 id ݅-I鸱=ren>TFkeHBtG2O+7eZm=}#rzerUb@'^Al B#Bd I2R2B2O(\ekT|nc7\&s]D(.qemU^-e2"kNk ݰ-q,v&cQhǗF }ygr(JП"Hd6^snl|`7C[SH ˞nlљ] \Xcl0d/ }NQCq<ҳ*~O #'|њfoxc)vxe;nYƣ]gsվv|5WBm3, tO$4(s6"1;jPٛ\ OŁ`hhCBxTl߯D #bMD{-݉?|7fb@eo۟Zc -͂ Qt60Enrc5IF>3ؘTGF:/D(BC!p`yp3 4.cԦ37xDܧ'4sThNqE &P6 bTY̸w A,`wוBψ;2 ?z`U`ǫ !T Yey?M: Ÿ O rT<ن砯X4ڈE8j.T;{+ 0/l~=b]X] aDŽsTe=Bb @ C4 UA} ߖwlt/n[(P}&RcdqY0TK2H }c((m=>!#POWKr*INsui?XmF%u\,sFH - s|7Do3'Va~|k aD6oYl{A?P*}2)R 4bdgTh蕱,ӇNx!FuE} F?Я%x}wZI_*ϾNvS2NO&*o5:-,|(71%'^0؄6} ((ezSR2/҅ C*(4R .Puo Ŀ/ˎswu ㇵA{dk3`  91"#@!XCz> .VzIp=A8ٞ7o/F\Y}0?M~hLs]jmr6u\j9q_6 2)$D[6CX>wDž~%v8ޛv`Wbu.w-|5ss0S:ցpfbޓp_045h7wOZߘC4z.'Hs[xstΖ ˭&o\ȝpTFXTXeث2j3 9ZB)T%FeY09Z$/ BE ,f,\Η;'x6S˧T5KWeAX.0B Ѷw_>Y3v EmI㮉-)駸xM 񖜞J=O %0\\Ǡ'!'eE;3}Zy=NT@MT;%[H|/ ;_>4O$fEǾLRIxTף7yr| .h/D>&om7/Lg"i%q,.6"_0Hn@$d\r0{[!H#㓅?3෯ ̱»F%=-[2`|mIx, #\ahYc[V"͇(f︦>AIrL_ ޹s.,P$(qtP ƅOO u$sb-NԒ͒#˦! (b X4ސB1xEG'4t= z(WH'֓.}0VNF4A5GHXL0! L`N'H h Y7]Qd 巢) L@cm4i^e.4J uY>A 1Y(!${w+HFjab,I#~u`LG2y. R޳PM& t44)%Qjin~i!KrzYH(TT(eK2pY>O}A|2+8FxςjJ?+ܖδX%;23&9!Axj(m*-ǓǐׂtQuތr!  ޳P."УY ,Qg4.:3:As{a$~i!(~|Q㶅<*S3mQY\ ?$Fi5:cS, ӂhnGd(m=>!7d[W.nb\O^Q"Ք LKL{_ZE,XsC"5%-H&k.)d,TcHov] `C0?\v+k_vtEbc,kHbܓGOQ<n +w *҈U^RDSGβc.8#b e= 6&Rf&dعwnc6j "jYHmimC;i8DOA-b4:[phr|=Z/2HHgIⰢ[Nt5BOsxTF Zzj/$ƱeɲFq'gB鯇cNfk#Ehb+p$`;iJ꟭mrR2 <>z`1Xt5 |q[&3Xۆ5DQuX_EƜ[ق|<%!a3pܶ[8r:% ¾ˬ[XU[Z#s`L jH_u]iQL yh>#nD[7p9h}羙+,# j$9A̶,L)5%- n v~pc7+/k rh& a^a!,40BY.=+ idg[aB=IH=xrQJ5}Fgs$%S:hޗnfig5տ1%gpGN[dj,%9y% xƂZ>q϶e(m=jY8O)bߪv3^N[Ún)pM >$*AJLȑf =z ^T%Wt JE* "Ct@/(gI~?ȁJAr0G' V-OdHH$aC#5ad)iA.0@%6p>\.z= ", |̧Rĥ`LgIFa-t^Ч+ ^k~(A6%jj/U 0\/ y)9$ k By?wDҠ50WKny)=򅧺l u<oT`˱4L%9jh!.|Bu'y.Q̂_ŋ1yaxV"} WT\ lb͂2( dw<}~i`({ZG?dP`P`,D:HE Fy-Yeij-w^Pqō|7}J蒪n`^a/]Y(l |6VjӇ1~3Yq{j$_OtHBN"Y"%p]sFg/`L:やMb^+ k8J[xσ,PL 3G[TP6g{ _ mȳRv ujA8(p6g6/,Am 8qv<׸FU$ISnl,$Q0f>߾ F:c,tl乒(!%=hxcm!u]Tn8cjDB)&e!q3SBJb PH>2 k8J[xC\O W=ޗh#uԩfˀq7lJbm?6Tf\y+~5 }V:HX=_gcV;ԈXJqu(ҥK0y,sSPۄIIG@D>:QS{4ɑ, o%U$QXQ{:% 4ޱA^XWzLeTDE-Ӄ0~%5=<0cKJI\"ę  ɺMX ,Ipŗ9>R6+}<=%tH^s-vTȬ0P1[JZ$'Yrdwt@|Vp|GJܻʒd穃}I.!VmzZw^huW1c,xDx͂ 4w9:D̝GgָPǷ,_$S. cmn.Q0 m5 &^ =68a 8Y"~(zyd t=$EypAZ|Ea iIpkt|7Ios^WpTHa5Nz҂qnJlI7m\he !z{|6t+m/U$tpB >H ֔k[cl0e `Y|((m=`iwH#\/NΉ҈4zBCm6 m(m;|hbidܲrW<ϛ+ GWS㇝i:-wTe wb( idg`UR?&Im:~$?q , >e>0BY/5-#[ ʥ~7&~52ź`L:RJ¿,D~!|2`i5$qlJ;JIC JX/]?Գ*uw]h|p9?"}== YI VovEc>6G4Nl[06S[d!hY{Ea Gi ylq!35HAJ(}яgORs3`L"Lҥ@\eY1XC!zk \\vbba% 7\+.1)5*JӀ!=`$I$Iy fVҬ[q.SKKBK31+maa%(^ʺb"%+jT'!&qtF&MdL̵ ,Qt\Q)xe02 ti>rz{ "uW$H{}Xłݠ&S]sSc^ 纒W(_hpsw8H h Yہ%w4z2~uMc6Ncx>)RHx!#Ej(ʴ6҅$Ge%)| (kq]k.{Y0瓒sG["`Pʇ0΂Ej(ʴӓPg n%ޞL ;ֈ 8miLEI i%'9iN~Cd m5 ]Q!tꕴuA>HԪQQXQi,7Պ. !BhbŨ+}== I!wG-0.Xs0rAI BbxVZ,!.e!A_bI( idg#_K?\gQ%#<*v e, ʤ+v JY.N4< q $1@!BL Ip(&W9a)ai\!aGKx8j:$qpݗ=v!C$rHi޾`vL(v`U-b>ڽ\sӈs`LڽPG0(]>Ap2(-RX_Q9AOkmgJE׆a,,{QK yBUm.U !z{˙L.M2 Wa$s}%]zZ_m'm1KҰ_* 5-!fന#g3ѷQ' h[}ots6줐 ɧ J$IQ{ ! T3~M&˙^y^~k1*mYHLX~HR.v[bg" k8JY3M mOɜl]79+>4KM#s`L!I?:7 SEa Gi yp}o7X;Ax>(+trXylQqm|j-I)JeXݛb+ k DW~65'!,byApă- IFTM/#>CFk8J[xCƒM%,vqlvC|_S'vKА5HtU<}rܽHp?Lt|Wa\0cYH zPp0"o~>DjdԴETl"%'Q|s&yNϧ 4ZDY4!Ag%po G PLA;볪zJZ.r[Ɉ5Y2BbSyKf, D,C%+ k8J[xClgj'֒2ChweMjN`LgIi!eA#42JY3d)\gI.VD =Y7k4Ef@tK# fe X ޓȝ4rx>6ɍbb/rqHm0xiumxbq,eTe:X2F( &m&e"RJN&ġ{9pΉ c2*si\\c@2$bnM Y>u(m=x%i :|Rm/WZc` T|I nkb=5-, [ m`RX;1Hpi!t^.:F) YXDr"^\ cązj|Y0$mO pЍH_ʧkсsb!5P'90hyHO F' .4-('_nXektG(o/ t{N3k8D[xOB9dd-اh_b pJXw4[{gY0Dr[~/x02phb{MqQgҳv+ ,Ӆr|(9Ҙ-gEa G-I(i\, 㴄=[,cs, ؙtC M.k {c@%K93}Ak{\Wݬ_(t,_1rGw4R h+0p 亘. Cņ.Q/QY$@5agq7 %~̰΃ <|X y;&Q2i,rʟY[>t!]q(X{n#$R B 糂,J8Plv 4nyb : Fď ٥BeAcE!RCrS敜GU(>=ǦQJ_ZsMq#G%džXՉe_J/ny+w avj vN Dz 4],E| e= mXxܗ$)cWЅZo$0޲̵Ok(wSCH.nl!8߮|kF4k8n[xCuAV",i::x#1\ׯi>0BB~ɴp`2}XQH#?63̥j䎋j CԓȀpMN$ׯNe}1?%+! p"B,R}Áe/<G.ﺖC:$1`<Cϣ_FVS%sgx2)"aܼw|r!wt^Ɠtj|NfLZÍZqI*i3=Z!X!{2(qs1NA 9]7nLzl@rjEh^7zp k(s-)!b.չ\[^y舧A biY0<%9e! u s1sIBVU?fA\٩DvAkήAҘdNO t#,wslA|VP6׷L),f@vpb6p%@‰x~|27IZXLcJPwJITF& HR{λC3I`6L臐ַm3Sr B|kGpqxr:U,+XqN$֙`5F#-q$)絶cASDEa Gi yd72Nę VGJ~"PH>K96 :oHjdZ3AHӇ0,X㞬OגbO5]"lkAEj#/H `g@Uq PVp6(ylImS.=*_jhcwmkC>/ƗP JV{͎%W4//RYF6 ren4;XaG\>QR(qŸyp])^;xR]:D#Rײb%sZ|5@T(dQJ&jw2(/@EwfaU5F_ SRQM 2݂B.b`I;4襜מjS~_&6Fk`"yw8^.qwm;<G=xuv%km7I!οwwcKT. Q/]XȀ1]<%Ae``\?A "N e6]%E6J<N>W,Nk/$$B|2hρ';*-hof߂LX7k҂p'@z.(am5 !Faw :o m<ҧ>'$PH9gq0> fvbBT{ N9nǹ7-&Ӡ +X~Jb, 2[ $aekA;@OAYH.$nT܂ycdTY\$͒|+͈̓}?42JY38cW[pݼ5_ 1$<XU< HF` td45{oO{m,2H"s`;μ: O*/܈),,|;_J"i!>q((m=7X`ǁ>`]Sd-O-nڮfX- 5<.2ʮmapG-".+6SƸU5"uЗ B]Ñst.ºK!C?S3Ů9tWIypJk1``GNt@'("#x]P^NI9y<V7?1ؐ.4qmg-g(ίeἑ>qf(RCQ|0 -C)߲PI1BAX1{~eOГDMFR+tTש$Ok06⒀tu rabČ"I[́?Òk t]Kck{{׸cq fWS 75:Z>~e=iߊ+-Hm+zcCm48`'n%%=?!5cx"3-,{1ƒĖ0Ӓ;{Y]ܑ +Ӳ7҂1}h~j}* R-ˮ(m=]W.ɭ3%dbΪI8,i&KFZ>jFӊitXB$'ڒO:1ǬY~@G?+đU _ANɉJo]ӃR1{#GSݓeVp^<}Kb\,\<i'I6i \? ,ܹF1uQN?5ƿ'pj0&Z`K~TۣQo\cE;Kn֖B{r;q&X -FF- Yhq\t1$u-%n^Yt2A?zoX@qnvEa Gi yq(K:8񳼰g6ŒBdwwҟs`5<19 G ޓzlK0P.| r]!'Pҽd 1=`1SoA4k|` )_wt* '%q *L{ |ZB G0)8tLrцSp5-gF u$ a:M92+6XqTڲ>p"IAea8|QXQŸyPxd-a$%= ?HǙ a+UtZA&V668DV p6V/rdpf 4d&bj(SQ֖҃4el*b!kNmiLԦlJ&\ sil'YDE]jDMBbPB%xdB4\*1 LBfCS2;wQaƌѹ;DaZM1YigP) zqB87'c,4;β x4gbʧ[dax>K6(aAkT,>px "Dc</~ؚ6W:Ay)% IBusEHZ޳=:kԒܦA[xRP`/=7~bi>b%A.x[~;vm>ϊP'J#%7?F[5.f/t52Ƒ(RV1-Yl-LC"5-7 @W&$_j ?h˗F#ix7nn&!iGOmppc6K^Y=Z-fx +sSy2{5Ň1)CF9g ->'/-mvCjo_1.; qq#l-O1R2P5]T Q{ܤN=%qvw Rc?4:hNrMScx>KRxWA|Vpgbk,Q)0ƅn˂񡆇׍wR`9ˏ!BL tYEz%i[H\_lهrb|/5㪢%):CYA{NEa Gi ydJ&שLJ D:䁚^0y܉Y˦q31-RKCP` }+)QXQ{*[|i&M _4KON/cQ"ٹo%,iE.if3+8FxBӇ~憐}HG&Ve&F͉4OYXl›~c98DܱBC}\wT77lg̑OH9~( 1N wP)YcNг;Џ=Ē;;vVrEj5$ c[UyS4"gO('$YGzbˁ0~`$gl) y6ksVnׅMO0va-M-1 0ey(&ޓo[Tqy/AT9_!>5-f qZf ),V ? -~ -þh fe.Rd4[ʀHx AC*8FxBzЕAb` *9{.+i_u&~Hڋ>ֈ̀ AO?4Z}a<^SeZ)NT)ĪDMzysKd 7.ɿeq\b |2pDN(-T%N<6] 3RGbOikY0>xI&?+ k8J[xσh?u EoCRJnb/E 7~+ΙT)6`LXKrVmavT ޳BXOPblA7򠺢`Vt691~O<5m .QӶ^ůͳr$7ϓcofQ[)Dڗħr-62gz6 !7Z4/%%@*ě`Iޅ!4~|$n-78,ů~ٯz m58.,*Feb7QϣYP`$I%1B('i9k` ( &g1kIzfH2u˶ w>Xk۱ (9=tU6Y;k3p𞄪mn-i {Tx:=Z]N%ق1}<%/-ș[>ϊBWy68vؽIΩ6'ݍ`~k Bլ ci.t ɸ힊!J g`:` au\Yt&an GiRCDܺ@X9Jl^stXBluWƿ1Ȳy&MkƳ[3'}%C! AP34|h!Srq;·wQ\ GdZ7bpZxŔ<|"m>ϊ`Zy1np}?#vD%B^LdߥA^P:qYTӼ`}~x`;zww9/c;T+4Bdw]B[O|?9v | 5 v_7M2vkMMsbq(`Y7Y!X!{+ k8J[xσ)+)}eqENQ# <5`|y%%.F -=ac1Ԙ,[TϔRˋ`3Pıo/X,ߓ`L(ړŲPٻ }Tw7(QŸyh _R[Qt'k+^撢Df.Vaa"c՗QXQŸyhM<iM,ԁxmI N..DFҲ`<6#%}r l pm>&V(eKY_(h҃+y %3F-̕#Rrn!-TG& vXqŸyQ3T&jKpdD5eCbLK 2T^kPmY0$rikn QP6ߓYb 5C,-h_wT zi.0Bxc," m= Ȟ RDymɔy[0|HIs",T%:YQXQ{*g0+Ò]:љF=v"6?-H'"[Gn,p|xstS zqe]۹<8LoIX{,Dm悐߈˱utnfMr7bL+r# u.q5LYVt( Pꛂxx,bqh8 \setZ->,S<ΔacN'`Vp@uCy&~-kvY0.ɱIK NCm?Vȸe=L "kg>%>+7ޙ.Z; OҘdCH 02*\\bBxu | pܶ_.[uKq4VӫDD3ql:NupeƇJ SkzjӃRC1,ZqܷH ÷h D~84 "_hm L-Y#S!XCzkʌR[ׂ^9Zx=٦Fʹi~!'g ƭ9֒ڒ A+B~@mlǷ_yMPkDwa( -Y̦b5 &reN`ؼ7Ic[2О)`G#΁&O 7ѨX կI#D^c[. l|PQXQ{0CDžJs^F7ZyV$17qc;oa҂,DzB#/wFxUPj8J[3>~"+GKrN Xe5MF<$fxLJƝDð0NgEa Gi yH`&j n*,oإz乖nilY0%%C,) j ƙ$[;q$-=I8BHY'_hN yv$X- q6|>+}Ak{ܤdMoLGqc^k7IoI0[[0gK*hzJ?RgoLq}-.A40Yw V',\dC-ɋc =^0r  ˷4 H/Ae^i8㡨!ŸI)OL ^ !PZ5;\Nh)` @)<E e@_"|Ѹ+&yp>y|w܆Ycֲլ%j*,C+ k8J[x#u1jYni;Ct[C]B#I))]78Dkc~>Ej(ʴfe%٘F ɈȨF?mc4ncHO A! 2+8Fxς~1 騼T_ nx>ggSqĠ4e'k{ႆRӅcQ_, um8tp2ı.&9U-8޼%#elNBd7$~iB UZYI7L*7K;Zf>1glFeo_[H g jc& =]#3ZAH#,u M(dH~APY qݯ $HI,Ri (u@bc?PtH>Y!qgn=F'0YK7VaHD  sPV?w[C>%,> -ьUvA!i DkenGuxbVfd8`qn]̰;\[ƈePtdXxlmY~>?51TtIeM>sinzN\Bx&瓂k2UAc4/?5-gO}g/ʸIoN|P؛lğljtՈ$ѱਛybdɿ5_ہH5L47 9۵Bs3DG9 OLgId %F s>wm0 JA{79lgV]"!.1X#2* 'Ys >vjt_ʚ)4vrfv3Vǭ>gKN^ʂ1}`. ~.˅O+id4gz6/]I6jQ$UqID kDJY0%YnB"5-VU'a'?%q1 6KMck$`LvIryp]>a(m=8>SRAkG 0 1Fm>p.oۤp{bm(m=J>-LI e7qψW?fb0ڀ`!9|Q4%Oo_4"Ο6)t$GiG1m= 1%lzY%xxvHgJ~k`J ,Ȟ䪢XV&wkתQ㶅<8w+r$ ǎ'k&n&yK3BLOv'YQH#?Ԟ`xJX#]<S!b $n:e]1X1Y0-h/dxVDD2ka$ ƣ:SEeMMAk͖G>r%FI/f# ll3h }IrjⲊ _SCz+<0ģawȐ<71GönFaE CGԲ @"~!jId8{,%'/fb(<¸xg-9R2,  |>++8FxBZ&VQ %׺ݤP7~HsXڂ1]׆T AXcEM Y,0&9(?OM--1il>ϒ JA4Ea Gi yho}3%$0@6 #'AZALHL؛Q=g^cyƑcH Ř޳ 7S]RqrŨʭ&0~ȯyM +SIs`XfBSVJu}c^^59mrm,k=L˃p P =5KU>o" y)iuK\nW7$}) IthHNrBV@^FGGb},\[Gq'ƽ⫶ďniMCi@t n6}.:-q m564؂`Y38/vϞakS1 \ Mx4BaliIC!kk\BMvn(>UMEVLa{Zԍ3[F^kt\숛rrYlQzy(>wni7[J(G.رf1K,DE_i qRC!j{ \3]EK2Ф>T^ Ͼilbv>NJ)kAg5cUuXtKgkJvj6.I 77JIecP8.ke Vp68ԵZkwcR6ȾCt+);ܦƬᡅ& 0HZ^WD*3[ocIoxuo=mےItK RmֻcxB7` nZ:GЫ4^~X`XbZ0VKx9{ފSa{93Pt|7 KqҝYݺR"M!Fz $ M 2. ,eLݫc,1q2X0xCqǖ $BкiT$/ p|< T$l,g! R޳bc1o>Xpb7$YK"RM0ˀ1=`-oɁbxY-JupQGKcܤ*eʰ/"Ɓy_hft|x& AӖ BRw*Hq "%G7/XƃKqrO_Ad^`^Oo.c,vbcI7ufFlzȂqhI\(,|5-R7]'7*DMLSdg<8Fu躨cކ6c,%Qˇ0~%HCQ<8p ICݲPٗ&}Tw((m=ǩR9꿟 &|{1l7c*_Z"fb5-+^p!{KIg!ɼ?OuDqr-,ITHBb! k8J[x# jwчIIA 5 /x=oEZ4H &, E@M}ZAz.'H Gi y$\oU4/$@*lO/S4-Yˌ޳Iwqi[K"jy>p/&$i.ϒ j<1X1{Qc$;t(I fa5o -J@͎Agї at`pgJe$C{%*m2g{Z<[}hfl^rZ2;)eDYØ^q:k8FxBd)85 Mgb#ָ Uֈ/}] $) lPWdA;@OAYȤwK8II\pz|dj|jr!a ,zQ+u[fx ؇(R#㖅Wfp#2*&R~w'L@Cv?OIEi`:E **rx#15-'7,I$3t>P>|2<0qw|yx@) ?tn NyJ7'o##W7xE{+E]i![Y0 e-B xqpp2D$9K a)v.㯙!3,vָQ@'HXcz z_S>IP ޑp-qjPU$ Ĕ\oehNBkS`2`\U;$`6phy8Tbc,D֙_q pTգ9s֨';ق1}`%q Y;?؇0"T!(eKSȸe=Oq^<#H8P`e-HAP! JVVkx[b-)!|2pܶҕI*fZBIQR!B! 9zvZcײp $T8a%禡({1I,4$h^O Me8q&05'n`,I5TaS{?6'%uɖcPpyJWn7gdj4%iʬȴ^7έl~)p}&>Hz:&_S; 7e*A_c WxvKpK/S<<Ǫ/XذUR{+-t^>;`gP6;O#yYR'V+Bx#C_7tQQ9ܘeW#G[|苁j322|4`XY7ÌahK-MUVk{dD55Y  |Dh9C/'vw뾣4֝j%‘7z!3|i@@i JP;sAv9-դ/'7iXgiUfM ?~Y]h)qg>O9ÍNDPp*?m,@3]0 s4 eb Waa3VR?t/ЄmL ؊950:H %FNm$0C2*m"C6$U\[) nh*1$0aBL`އu t$#/S@ 8 88}iEqI(Y"iYI$p467wNP/W u$%E<栍^@@0iZ]$Kg*,> -Q$,N, o]s}|z[$E(_[P~8}$r [EkļU"hQRB$r@`4mXl70 4"[H+C-"qfR= +&L Hӄ&9Mҕa^=&ym YX?D9GVh(y/Vԣ2 Ւwx*g|^W 5ʣ)X=Ҷ32*.͡(eYTIRᴾ̮w F)_IwT He2rN9iY hQ*i4 ͷxȭ75il-l\Mc.a~u<5܌"Yv?@MԧI5= 7 zWahMTR/yp]5X17㴄GG Vj"((LɳDThRL90dG3̆z^{I 79U,jm(q4/6l: a!`q"ҳ%3 U1e} `Lbrip6dq 6tqR'(NB,}h:q.Ch}ɢB!% _4]P9sw Dow 0/M:ܢ1;s(Ku1h.*$@DFÄ"m7 ǡn`/HV ^,= :64_iu!ޜ-b lcY2DQ@' L}f\d&e:'#rz2Ȥ/5$|`4l\Na Fdp{xaiX灃QHu`k*,;ß=(H1偆&!]e`4l0vp 0/M:2~%bd^Qzs\5}hpi됐q`4lr aӰ,l~Ze^yiy/#{3N<-'J\QlEJ Ě*6Dk0zov휍Љm&$za75*t*/G= TGwx@a HӄVs`Py y9.`^u Gh$mu'o@Q[LN&@$L]tx[$]6CIxmO)I;LmL6/I) q2) 9+Q}pA]K԰NgcM*#zr,"AI9vyֶw`\tn.M%%EӰNEI珨XTsr$o۽C+i BV4l!蜨I+C7 к:&a^uy4t:kE&hz(/a=8G T(&As$ASNdžr[hiJƀ-f)!!n(z=8 tMC-h.Ą#ʡF(N9xڈq8  D@>kT 3]Bq`t&(HP+hݧ&aNR: &EW"H#f³MC-{N_ЏG MdҴ9ʑrR-DG <$a~uSu (PFKh Y=>"Ѧsڦ' j'i WfPFpm8i9X4/'%g*X@Vlzp//<Ufcmiȟi4Hqɵ+yL=if+4IǦaoD܄Y ΎڟGn `J-Rpar 5@ӕ@Z.`"5LOy `q ][LbR"QvDҭ& J#S‡'p@>Ls6|u Hs8aPKIԾ9cG'Ʃ㏊G3@:%C*XPpAיMgmh>;3 4ncc=]?{31ypv*k.3ʹ1\,+'Α@2dV 0'`;TwC9[j&E,vB\B4)0:Xclt wn| ` " bch]MkOY|Í`u[KOkpp8sڢ +Nt ,0 ؀"(@oiBKmƤ$-<2lx< ZAiX'{M+$_'ɲۘVّXwsVCӰrꝝTT [p/flr-#5((*HQA>N -l%qr!dw!OL &Al>Ukw28GZi]mcv0Jn=i/7sNi(Z&UhI`%u}׷wOn+ >TzҚ`]BJV:xĀ3rN9I ,x=8h>"zh 0/M:tWf NF:#OHZSzM#~MB^u`4lDj54wy5 Jp3K4_u ]C (8TCi@8Dchp6.WCr \CN2/Ip3,U'$ŋIۓA9Rq418 ! 6@k^4$v 1^9m<6$ 0+F˽Қ)|4l4M9uG6vɄ\$EDG$Gh&yZNMy˓h@"9H 1 $KӰc,%16(Lu(9%gU֩RpM$Ѱv FÆ-5#j[Cmmk6Ia#mR[+;#KXsMNؒY")`4L"L9,q ;Шhz `޷>4Ԯ?~: I_Ow?>E.; zkȆOzs+圾D Ȁ!eYaE2IgR1Yb3KIL@]8͌9NRG۝.׻x8C,%>+CzEz7oBD҉]D H3QH܉c|/>[a@l1VTRE0 4,&!rf) cJgh:IHq>4ÿk|7nAz_n_/ע~ 7o</R/{%Y|ȱ&@AfvrG ta[#/FMվyx:? /iR۟R:2+5->^y۶E_G?u-羮l\^ "d_ˏ_}??<Ͽ>|z.e'A ߶SS[>8R8^C4eg+>ضx<~vz3Ƕr~Ir.~ߺDko^6/ϘNN~|*FGzq$aחeڟ?Lb/5[>hk>qE>ӽ%&ate݇w8-5}2固wQ;s}^=zy}rzwI: ' G*_/a.^^f'>kq{#7eQ.(Ha~5E]s_O_EIY7>>$8thJ&(wގ*7`0U$ӽ?@~8Jdz~`z y}  /W~y~&ή<}~ ?r)_=~~yJoǕ}پ_Ǐ/)m?/r?M*.^&aJ ? ~ ?fv, ;/ ]1#endstream endobj 322 0 obj << /Filter /FlateDecode /Length 3807 >> stream xZݏܶH[l:,~J4 ."]Ȼ{g%qξ ȟ Ij/8o%r8o~ԏ"bvy 3b3ы“N/N> 3+u[g3r^䅖%/,[3Q^LJ3+<y;&USC Wɛ6:^]E VU[/@dϛ\~JE%+*}x 3Q~{/.bIs|{̌j-pHe021|$}^iEX]fy^oMuEn?:9}pNEgrZYV)$uu.`U|ifM|:ܣMN'J7Mz8C*S)4[rLDy;h `oXض6蚶SQ7(b?`7sQ8jgg&N~ۣUR1+ޮU06*Y`e^T_\ZYvo6W4KU‚7~y @L[!R?\GϷMA?\E?گ^A$dw#ayPV^xJ\k|F}zz͉˦zϢυ,*ʍ3Sye-Q&Iwg@1H*1ٳcm|,oFqIaX?e, e.;p+j%ypN=- qN\ZڢsrNTFu閅-{S.OUꨐfq-HI3IPt.8kr9Z}}~68cfRJvY8jgjBJZ$2@OLdZ*NYaъb~ys=1( 3W^95=H|n/# $T{Jpkd*8mBp`.\/ ~u1 ] n7q`,T९•OZ+--OH O'%rP2iTI"I.kz{Zbۥ'9^7]o[c}sX[#B 2scm7eLUnUM*+i>➷|J cR-H$ G%CpQ,^`s FB682>;g^?^sEr}>HrX Up\Vm[M5ć/Pà$KJbY T"k;Gfj.tP5 Y2-كUvQm plB\DҽvPW?̴%%"SP+x WJ$K`$Xa V}MeB¾瑂Y AGAED,W@0tb, ;C ?ӮZ-| Q"vcb/D8aƉv<*vAw0Rj֦br ~v!~2'8B<>i~ :AIX%@hGRP]r,09.qtirLQFPҭ8n{\7͂J*uh_t&֩kQaU9hYa\}9 6 Dz>;cX"Am혡oGCf_Ǽ:6"Ba\Hjs#E\$4ڤ-agoQKGۣ6&h nމglvH*Dsy"Ģ:HNC$^Ins5bx6Hi樵hϦg1H,/n&P3 "u#Bl]4[]5# 5$:, E m׬n=(B(foח*Fi/r^A+V Ϝ6 G^M&K\>a/Qh5}/39^=6Iyl +9K:{bQW~4`=Y 8.TR|@qqp;2H|H]c.3k#`T{'歋pRnjN31FEulb7C!t-GilS %{^M,bZey [bZN x?13oD̂'=krN* U`qTӂ[zduVHKuH#sS n9QS5B EZrAQN f<*V0s| H['b y,d)'ԏZWs.Lq6{E H7Ǩ~AUz܁FzTu;6\Gwz@'ki)y";R[@N$,JuRIl6u{{d+uKH69i:ÌI^?i{@%[1TǨ)J ?w*E^x;>٭..Eb~+@_S:}yُ}Ǝ+JӾZü`mk27WÛs?f[u~ΞmUX]uȍ Pؾ4k,\V0D'h3SɅgdC2n"oǔ$UexFRh0* g8*$%)\J2,Q@gCy08p"~a#[%Y%mQbPVYa% {*$ua#*>(d|B<נ=TeY1zl.E;r8+B? 2,~aP Hh9\Ƥb7iR eb|Js.ͤ2ZfRarA)8ݺh[ ߬˰P~Da;3 wOxq-3պȾպy-,P[nqHj7 wa ɐ,~rPE4\ơJH'\ "a:DUP_AxUy?}nuX%zDKC"6z[m.~3kpsN5ZyW{Zޓq|\-AkdE%u;5{V0A;>x]zqJj}A($ ])~(4M9KГGBzfci|"JɨY9bF$PpCqz0S1wsn/b QI=,DOQ71#4vUNWoN۫s( þL|7G/^2E(FNR"W(FT`KJnk ںnt;$& S44=P 2}>87i.ƌm75!]5Aal/Fz"knҏ$6R?Zv>sYR<0)U32oyܻ$=U%d'Bg#}>1yaµL$b|4nYːh_'~z> stream x]ێ$qljSg K.~ؕ,94=rgGdDfDT,iQ ɩKd8'[f[?e?ptՋP2v޽[/Bq:]/ pÝuy% ?¼,u7;UW9!y ߓXts_Zj='G[yMoJ~,}KҼFW/&ļsn^SxEnw՜SH ԼwVx=j_].n.85q]svD3Om/oiiJ7=^=+X/ UPf ~v/S;}Eeqsw}+ay8#r㑒o+\JǃPKwjDok?mob۬-Χwniڡ\׸ҕ/igc؋9paNqT߷ׇED>|73} u\]DF8/*aiվFrN+)L5NmQײV˸ⷿVt+Z޷5kt?>Vm_77hs,ԟ;#y }{FŮ xGUZN4Gss y&Af8#c޻e6 }ڳ@QlOkv gFTo`Qt/L׷ﮟ7#' c9Wc=]_]ٿ;^oӇW%WmKW|1;_8gB_Q|2.ȏIq>YĎ_gۗ%l_>g.whIB[ XLeݧK O#@h*ņ5@F,h@¿-ĴGLn5{jaZ]ka+}N[rl.X'}5#5ݓOҏO 1sʻT cX-GUgurEZwlkiYw}=e>]n0.58Űu<qđ6@~<;oNJt4i('cRtt xFf 7f4"u7UfFǧkt4_c}PV,@56P]_R!n.14o\͵{, '#+>0@bF@ƅ^0X[C?۹!-6xxfcȢwsh'3nmix`vC 7g@&.TL|м43g(G}ڟ`X21twջ92LJYMj;ۭ7L)IzLy ^ չBDCÛgKt4ǁ<9-C R;YOW4Ouy wG1Wf (\c;0 0T8`}ڒC`޳0 ymz<;_3'O RMhFt ݉? c'!}i!SKT?߱Zq73jhYX_4R'KsF0%Del'v 7$m)9v{v:w WDt;m/bK/yF[^*XqvE]5JU:uQ/^i6 k>Fݺ :B!0fD֟Euya\*3'O?S9."ApVB8q$"?UЕ*% V}jX~u⒋}b/1WIO%*JNKu) 3q.~ s.SlxaWX?EC,-2ſ@z{{Cg\JN۽zi߷IppAD|[}dKvЯ-/*lv5ΣS{  yE}|>G\`NjYgWPFtp=@\za?Xsa3g͍a3zÏgMgʹE@*UJnl ,5|MpX9.DV 65W1x%~䘱$VQIL.w㣽[]jFG*iK݄I F\]PK%"n5 &yK`J`J%u H&*GGwLfbغ wJYpA$[ `&n0JB ؆ fA9POq[_3 (i&?%m D&㉩0m?X5puf <^4&.ihjir7 |+lv%^lWKb q E xd,|`] &좲gGt _m @ 0pKZ4pK,ǚF2 f1e) $La`#a 0E#!p,#a¢0A( &`tMGB[zV@`&j0L5~``0UaB2`OU!ă<> Wop``!QsY2Pk4XXG rCēbbipm3T6 j0gn@C}o0; y5&B Q S"?0 ƕfa,0;F0d0 qmi0-CU|D mQ3v52]ūC)ۺh` o!qk<Ġe-DijA2 >p1!p\;hGhD WDh)X;v!C"CPEtYCcÌUC 3*BPl3b Y##OTq%+V 2.d &kB($F1ʄS"3b+X:L0^ Sd*fUpN+&btB0)hdRA#+ #l #a c!c+7E+⦮7Yجp)*t*t8; p.LKvapŽ'5(]6:kXY 8[ζ+ke\kJs-[iPL!kPL Cr[PDqy#Z5(t.r w4$(lY7'NxEqq%GhtՀbu<7 z *"fՀbĮV&fX60 &&fL$13rġP]h3\vIGK'qkLDLsIe 6$4 b0ENbD4V">x; RIL$Eiii5YZ9.%Fނ3 T"@*;@Tz P+{VfY%4^b Z%@XJ<"F"Q`DR`,`VH \I .]?3鶂˥C˅@eW{>F|$Ju cPc>V=VG&=v.챜YG> zD_o4ؼO' zb@n3|.,,0Ug<۽D'D9b{ҕO鞜terg? VO$?bг.AOpTݺ\:a1AO$':sw>G49 _)+Av=M׮ jڷzvMг+lkj}JiBHq^^cGءF@_#τ*u wFE{ |EuաA,!S^4^Cgx}ҕN꣮!Y%ꬫG{*4g]Duݠg/a=G@O>."+Lj-4LKd c]x1BC IVBi6&4=BLgÒ:1d4,&Zhch:0^ڱ0/ O|VKt;tNto22i1+?Md0F&KǤ&slh*鵃MrI>bo 6ha [(φL\!,(22o}FmpMؐIL:+)'46`g/F. rG'G}>hd&(_Q1";Ev',?a 7YX}ᣳ?ك\d=ك,V_Q،H L>V> H83HdB"Y 4xhPO4(8uѧx9*`ߠ5҂`' ހ *_b_B \ejI- c=W}ד>:}fV 7& =+FĊޠ0#62`PZXeepPTlPv=B6(lPUCq]! :klP8;!%A:#qSYJt Pkټ nv8ʧ(^=k`w$ 'YWBfA cO)vN /^ʱձ~GGulo^\\dN%(BqN}Qt8AQp96ԡI3;I١o,ʉɉ~)uxGMV"VVVXɺy;r'^K6oG q V@IY(#[sZ'wA`'Ja :be->e?%s\:71p|P88μ \S>Vp~>z5Yu敠PyM:%k .<'^˭5IIw޷(),ğK7f: Ms.j@j۔q,6qm`E%UUVQUFJ*}|6qٵ;-0=chc`T<^f) dp-4't]I !HO$[NpUӽ) gnrK*MHv"* rl993HKRnbj׈9qPcmPc|aAl\N#Sef:M~q?*[&㙁OAQ[I!WT4a*}J ~VD =$X7o4[jeH2sg^iQ70~hWϏ냅Û!l[IN hٝ), BOR7T#LLnKb<⥧kczr̼nsY7_9`43w,B}~dDz7YՆ>XUߧ3M9B +^NwaA~O5MtUL~MLh]5~)٬ܟMӈfis#*~^Fa>O_N[yuz5mM#t@N^/x|嬅n_nokosS_k?Y_[؆ ĈSnrھ c9H9m~n9tOϵyrd/;Ma']!wkK>We0^El݅s!7|8)@=a 6ɪ7dj}NRū|챵=TкxuGGI[ esMnovz<<~od}/lMD[9,o(X:+<+I!-e7,}T]{zJbuygfB6oYendstream endobj 324 0 obj << /Filter /FlateDecode /Length 3510 >> stream xZێ3-WQN6ۉ8m^e2+i*)gg<ԢdΩ^-/r7ǫ|zuׅ9.zsŏʼ䋛+ _X(tR/nWa-Vf^^=c,,ʊdzKײyvޔ2ז덻Vҥ3"!ByhܤN>EmηTwѐϫ.qsiٹy`@#,d]ETr*W.'+(A0UJ4_+-TVmzw~k|q^ cU[۶Nafp{${_dA״NA_W7?c5H905%9RÖsaXui.4;kσT0긢B>Y!beU)aBo$wM-WJ)2͋tmR*Lizn]n.i9YWQ^ ̈kt >4fS&PPa'KLeYhy2S("ş8W@ӐO[?43S? )eXf$jr>sk3@X$hswol>m!}dHgQ6ڜw1\Io&'ϗR!ݞOvW5Yܘ_Mh T TQ*AjL\\U}"(Ȥ/q@.@uͼGU'% dpQ9:h(G1Vp>?A8-\* >?ܒubU!8(fYwv׈m;SB4h ,d^r0P s^*["ա=$L !L,5s,`kgiħ\؀NS4woJf2\ _nW0I_TKs͡8a NtKSqx-VCpk sy^z>20@,pis-H*x[\7='6otjQ=)å[Fꂅ0 Xb/EŒjDz:qL0PјRHC%[əTڕJgNj33D62NlZRefa)lLWP|  3 ݙQoMCDWta׀ݘIyiVFcHaVS%{Hm12TY$M=as)b!e[ ݛN VWab#TLk{:W$WAnK7d۔ ~v>NΦ&ZOk7۪`ūQk߯!)`s)$"on^IgL>9;ߦ>b;@18IJ܄9Ž`nUs(#Ȣ 5M2.V(طuvgHa=* Ď8w9_2`\UXusMܼ3b*NX#DdbzV=@69F}d [Q)8Y{t)mAy/&g„0>06vU̝(8o-{}!cSsrޏL4Q`zYbYHOr90!ss>Ct0N{@orRۃRdӧC_} HPlj? + C¤%o jD8NFI5Ux[/*5.=TE;5_0xXK4>p5cq)] զ~1hGmhOҷ\; 2qWqGkzCrn( P}շIq냠;ͣPx#NAC# MOH@4&BZyjPz8Vc5 \F4{ǃ/ė:#NW 8bE?STcm  x=rz$a g?hj8q-~S>ׇa/B{?P><R9)\2!'gendstream endobj 325 0 obj << /Filter /FlateDecode /Length 14510 >> stream xϏ%q}]P?'!2d`-‡wQ)k\Uo/_20>Lf F09_~|uܼﯜқ/?Wڄ͛^!|>MIBy_#vzw?7>ݾˑϤs% 8O˹^v\$Z凞9ʙTt(o}0Y9ooIlv!sb7o_\}[HM;79!sHkP~qzkJ:ӟ-s(s疒3Ƿ_?w޾(7:tx:('\zy/^y?Ikgl/G7}jӸîŶ\mWw+8 8ODžpRH,Oww[_ı&ׂT/^F;VaxMYΔר_*8=~9zzzo߈6=IqzMA#3fwzki*0_;%Lo8I~Ui܉^t?!s͏D.#Oz @N50>-:1#6+f"hK)f>|O]3t\`Razwz1FRǯr;9'="i[$r۶͙]J?ȟi]|}9NkGjRwOT_ӑ4kHhI)eܫ.&jc°.K`6 FR&lcO?ݣ4s\UB?G8'=s.ҰH|ckZoSry9J^GؑQ2$;WΣ5µoщ{lTb mN:˅wկuͥqKdZ|C80DCz\_-3[}͑Ձ O?i <<@PP~ I \n_{B.`x~Wc6.,._{i_\Gc6SyјU%ť!~;TH%3K1/gFHm%=bl}gƾ"Dtgsh#"N1|A]\?(Хψ5cLJIWC_XAt7qWi^wB^r0}14KvWLWA3y>qu I}/kHVi}ɣ[PџՌ,XFI0FF~&!J؞_4oIu-p#6Mr*k-dk?> owOG02NAh<.)M_2EԯG*dt:uM-ڶqHZax0b9w5~ZLsP{kaoO^O,U[@cV뒞=9Ku[O0x^>aN?UiNl/M=nb!L=>>h O?%W?{qoTOE_$Ig8NcCza⣛jXǟVWMC+e0{zaÇq^GsE;.-^͟C=PYU7xD q9ҿ?ީ_hsE{!UàtC^Qı>=$4[nmۄwz_G d?;t(hyyxOs{šd!" vo"{xzt % [7.򣘖wgqypz鿿hؿ޵?tq Qg2No~~&!ŋ[8gӐ6r8go^+{n?oƣ>ѻxijq>:ë~?|r.mO!qt8k4R{2#c7~fJ쨗)1 lZQ wM͊]#3̕l0, ź7\yڝˁ99R:Կr^t2I12w&w۝~@r L8$Ѯ~H*Jg)_S 燘@ ̈́ - cYU/T"8J_f׶uh,O3jsiv嬑s76Wv< N$p2s䦏qzÛC$Dޯyw/~Ïgx(^)ǃyS8$j7íq",oכw7zUvUw$8xA& px؛E+ D p%: By(Av A4elDA^Pf=$\MYMo'R9sHE+IiPάO*3Ri0v-Qn34M*gF<)/)aMh0 *#|D0I`>=M=;|2+ $PG5c8Z%zIHF ЈFa爈4ZBqO~G[]-BPO&ڵ4$ qA0RqN(9&`XT"+:,[RmD-+b4 l͈偽LT2 4#1'u\\,(O@`B1Fɽ$kK>kE%S6# CW-Ti!*Q7+$ F Qkp}PIU4nE#dG,N/"Â.A`Ag'#A'k f_ LQD =PhaAx4w1@bzq] UOJqH a Eo4JЊ)!U]->@ĄD+Z@S7/$"Â8|TsL*"0eJEE{BZ &ZH`ES+' &^V h`; F&ъHoCB9ZQICC^{Ox^"G[K |g(aj"u`B/Âg13f#ppDr36J^¯&̮#Äsyd=Ř1A`BՂN9 :~[GO0 \gRJa\}-~(deN#~{9EboE_ȼC0Im4*C.0#"#Bhg pTD[N._e9P=u ]zm8Xtn3u\{rMo ,1_ޥt?j Erh  VX&`$N]{z^#> oJ-Ax@h8];5HKIhsnCi$2{"]0"D ZGh`.#;Cѫ$UY7@bfDȦf8hN6w+NݺmPш6QvBm"6.Q"$># A_ Dא^:iJ`A-BB+l\j5Yu+ssm& ñ6〙Ңh.k뼍IB:x^ӝq,E8z;HAV @L<45KuؒJk CN+[b<ĚEFfkN(D@_$Yـbd ,DC͖-4Ԭ X4S-j:g9j>-h>.BMכG؎mW4,nXCyP'vi/XiV@q&MgZy!xV43sIw:X3Gk~xeRCc',C+x$ 3nKyoo@qh)ƙrQ8S#H83٦$@0h,P,ʜ@O)x H?͑x-dJ׶" LIL$^+;Y>9KϠ1TsvH>0;ia}*zp׺z\XB #(T,+JB>^ܣFtE=5x{ro=R3dCnsjB\x$j㕕ԣYxzzmG\BH=4ۍE!^;f%@ a5a{dXoH;evL->5;/yP 1%ku8uR!Z2lg4J g"ܲ#0(g@uhz . @1%hG~r,5- fnD%Y0!Y# Aa ,H5 L$ 0 %:9fԧ$83>gh+!J Liwgc1">ɡqbW}!F }1vׇC̣'BFUKh%z/ܐ} N X}3Ϩdebտi``Ѫ JR2mFI(Szy jͭ5L= H?4jyji @)di=42!H?DP4<$o:7@c)DJQΊN}o- R{hC]B4.Z3obCƙa=2<ŅDdNC+t#&Ko4)H<\oYܼME$dDH3t!AFwѶx ̵YH(sxoF421r%9(3Ǎ1W-l絹E9!yG1yDElA&==j oڌ>yX`|h{D1[G=@DHLldH>b4RQ4V|$mn`F*̬D͍̒F6fGf8 9rMCd"Og #"0SzBFa;zlhznt\DH"t.\$rOlI@6P4̈oYUgW"XYA0sLlDdi#nka-̬}.;&kh#{AaәyK4 p>/ߺG0S#Q#}'$5&sƙUVlo3+goA8ܽV*ֽܑX`""׼ ]2|6NpkՅ WxO. YTm=ׅ\T/|Eu! I[E\4wxQFKnٺ`YSXō g[)r|ON._N񷹚ie3-'ѹ+zQ-TLC.NHdUizTj)dY T%Ǻ6 TT t1uW0a^z?E4"q7|V?CRV#^P< W c],+weq(Ţޫ؃U U4>6 \RuB*L_Ruª˪2B*Lskly!UAiQu*J2*$ReU'*]Kq;U-*RYTJ4']ʻU"]U W2ªNH.}'҉8RaUڳ4}2:aYYUFVU;l E5ȮmWնtTFXUubU!5Ve WVZ&a.z#RɿD'ّUedWӮ򻽰>g;RUd4 uBd+U'猫Ȯ lUuBKWU'*۸8,U\UFXә2Bf3TVDRYTn=$*]ҮOª8ɮzT/ky]0H~oz }$,> luU#IH KH1LB+EVU'ۘ3 ڱۼVeoeoܐ֊E2ljU!^~zUpU!š U}$2 IXHeU$jWj/?JcIXىAXU9T9noVe5'aM*#Gت*##IX+V$&aUQwR-ÚU~*nhVCGRa$U%CΏ_T*n >"!۲IX8#UIHGvUܯVp= VۃVNHmբTiI'ad k;aUݼ 2n[U3IvU*XQU *_;aXHii-]F*#OBzlyV~:a,lVuª׃JvNXUlUǕ44 >^UFXնv3২7ªŃ*WTxODHgdAXնHiRc [D2ҕ*]J9sz0 *[Un&Ua!MTxJB"7IdUYm*#n'! I5ȮjuWs R!Uۘ1jFAXUxdRIVK_"}"9w*Hc^E*l AXnV ª="K/Dd)g ªx,R@=!UYŭ*#[OT9n *4#!UM;a^T&ԲNHVNXU,dVss = gA Y/ 좲k?ۜdWq26 tWH8aU ULg2T)JUT{Ϻ'aUkږBkTWU'GAXAX646^ B*|VDXW'ڞwuk@&auR V-Uy!US'*] xy T% |NH]ZIH%&ă*M; M:628`p42Vm+&aUFAH/<vB*|/ *4Txq x):aU5=*| 'UaUyIH嶷&aZ laV-UNjU\LB*:e*8Ug&!7;a?s`MbAH^ם*o1 RL0eR-V+7>B*`;aUIX)dW ]vK*W#{Z{l/W.W'U)쪴_|m[Y5 u@j{;qUϕpl6 ª}T1Vc ڞ}LB* j!U|VmQ&a6ihVyR%yAHq!ެ'msRոEjaUkR=U`ZIXUs B*$OUu7!UțaUfH!Ut{[Y8UsAH60-aUFAH^۝*|ד= J ۼ W NB})dRŰAHuU*0!&;U ª&aU ~&*VWoᅲ;< rj9*nc J{mwªm ``]g%4n!wۘ7cRG ªyAXU75Fn~mc Jj*ngV *L !):!UވdWq—v>͙ AX9AX}`]پ^:Qƙ jAXAXAVVl MVU'tmVmgR]=n/<ny!UɛOTȁ ۼ *uIXy]j>bW-&!'!Ut<2 W'*]w{dNH56l;\$qn3M,Ļg{vB='U —+"QtBzIvUض'ӓ*X86B*wNXdVm3гH>@oRm$[t4uRO&U9_q$j[;ɪ7魖IX$JH7![ *[=BTq[: R< 禓ʶXUjaUbAX;8J ڕ]܎GAX}fVEU1 ܶ2oV͏ªEփ筧 B84Q5V`mpRmR. Vm$UW&YTؼnCy3~cP򲯃 a~=VYG߲]?9~vnf;v/aR4}?v`C07Z?BĚ4.5'`W4}wF-y!$o;qيj{1\-tLlB|.$؋Z+ɶ1vUƔm|!E_([HBm|!ٮDL7t/LƁ ird칧zl ǷHκo-$Jm}e`Sţv+I{%U'e ios# 0WV=V` 7 VswUDD}H1s!~W 6$GǹΝݴx%b4u> ݆WҜmtk>ZWR5X>Tx`[$+"pЩskN`$o[;/jfP][B`$ۮ{lǁuOV÷.j~niiS㧷y3XU4`^+]w+l-`!Pcn|!0#b&,iEB|wALXQxo%Ui,>!fB|@e!b;,cX侍$^bRtZf!zj>u`j-/@Z@ WPtwO{ukXUIzmw!&6ˈ_'\Af~WjѶ+l/Lv D`8ټ`EcRlwhX7/tYl4B`;GDl8h{+ 32أ2lJm!in艔wpowf&ɶOf;/d|CO]H-/YvH6ҝ<e/$BΕ$ɶYf.qBnjp+m:& ح73G^Z+iG^LwtЕD[qBNDwy_I=݅ѷc!#7cX-[>^A}a`TB`BxJQB5*IM^HtN.tO4NZD)c^(/K='m||>Jv?t?XIJlBSfۧ^,lqo|Jz!fWb-$38չSU΃gQ"ԷO:\KLMBO]H{8O &:U9G>3 @4lռL&JĀBn>^\IB}p!s!|!0!ܞH24Ƽj!.Xy巷lXq IB|! %}qI&bj'tWSfb jVb3_ַ^_NC̅E&B`B;A(B(s!{Iʤh~+i}IjWW_@_t1b/,h],ȠwiH;O+/$ڞh+7JƚxhNF?1OQ|mfr;t &}%JyB}ku%vqm=tZԅ~nl؏}Ra>bIRԕ$5/!H*too!,'A 2,)sβ00sβP'$ k.$iyXWؚƅkbl2`/^ H4Μ`.鼸fT Z.D  2/+&+PpEcxAMV^HwDV||eKmr1X^mxb.Lg_Zבo}WҦ #3W|0AIәd}[sbӭZHMT`=zX01^{(u!8JSگӆo`_H Vω {GF6҅dۋe%B`Y,WutLQxOB +e[m zy"Fbc]Hߟ_KDµj~B}{%" ntfZ#WHs!`M)\}|!cb/ 4H#"Hs!" DRk%Yrl[o[db STD  "\9ɯ^7_~7n |^9s%1hM݇7}7zx|@Y\ݧ>9//=a97S[Y6<^_oDG;=}5SQE,a:,_?{˿R-8Jt+t ?}/QO߬}}+K;}NԯG;.[Rp;-b#Z;+IMUtǶR5catZ[;ۛzTyeyVzX%3a8VOq[`lk .TV3VǪ3ѣD:>O9>]_|_,;_4TŇLagNo GL#ے@,T|@FjϷc~?DZ? ԤϺrER>=?id_zW_H?Gwz{zXCr:h$(:=}xЪqҫGg+R:ޱY:/.@솱fi=޶bɧ{i1W&b6Cٖ֪V;Vf]n(.,ޭ^^Xw4,Owxkz/e-`"aȉP#IckCJ`{4w8/z_mk<ݩ,cGx}4߮ǮBob=pdc˱4(%T)I?9ZV>ʤ_&fufti-9B4$fhaI˅v3F>>GK|6:%h`! e}} 68'2 hEu8ofSs<GSx:nK(t @!W6@h]endstream endobj 326 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1835 >> stream x}TkPWa3=I6la)M֠ A02afQY~(of / xT fjW0@"!VSlRu lmw׭];ߑ.D"~+ZA g{余`b␞PHLl^j"COO7%0|R;Ď-Yog&t翦FF5 ֤bz.]VQ-džވzK}'kRJAٿ`ƅj&;EHNRNҊG7gg5ٝ8EB:YєU Jݎ+?`ePԝ=,X}c`Elpf.:˧;o"BZQ)7/](L4<[]ۏ\e&ecc#'vf^KDSN 8c0I执+يJp^/H)ҋvfMj 47=,=[QU Hm=s攘)RV|-%fFZTdTe #W'vh PQ\ui}X'999dmZN?s kQF,]F@Cq3z9Н[oGϛo O^mT;-"T7 ֟C! -ek^W3{f+9%[?$\ 9KP›‡CiÑ0;:9В銗 [6cP->("}ׅ#"}b>sW O7o KcMn8N8n̢y8" zdN" {\fa8GH=΢b=Rk>;dɺG6t7av=rֳ ΓP?ys *.W*h&ʀS`g4ڤ<%P/{8Лg95@^xD( #ގWb/w?^wZ4 q ʱ/fbMs4!Z#Z|"OHSe3{;{eu¶:2 /rg> stream xcd`ab`dd N+ JM/I,f!CǗ^=<<<,o$ݟ3#cxZs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k9 e``` b`0f`bdd? ʾ?}17/w<~$.S@w_>.|ԧ+Mؾ>Z_7o}8,WG .d;[%$${쾞޾ S3flendstream endobj 328 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2078 >> stream xU{TB ~*klKjViO{uQ9R*pM[ry ! AnAVj):ٵUk9{6Y|}zjwN=)1uo+1/a eAr%b{d,K~Ƕa۱X<R2plf [fE7DG|ɰY7+^:k:op~m|^b@-i* yps*JX~ҏp9# 7PA%|i2q6\;,GRBK&3ϧвF[.C-y:LΫJgiO?DkE:r҈~9o҃y%rErueh)F/ۆ$;9xivcύg5mfzwĻCQC2.fR\Mfbch}`5A/tʠk]ݝ%uWޥhlx-נX&ʻ%BsN-D dȹܘWGUĄ< }xQVl&&L0J)oj&F/BRB.}bLVhd:0bh"S 69T025YNNT&؈Uu Yc;9 5龴/΢h UՏ'-[tcN]&vI^rxg#OLv&_YUqD`WvKgu9dLmzSk#aPUN#3rC<>:v@uCH}v8D:̟l7)r4 f< JFRj-vh[c%j)?Y!Kڑ OSFRy@IuF}Mq`Q\|+F\b[uEqEЬ 2AVIH[sskaX2MO(TD )5PR\Y\UVY+<;ؖFhd:%τLs_rr}IR65`s:=8 ~u{`p<\F"7g~3D<A^@:9(t@ޖsЁ.2Ү{OZ/ G=2Q QX:F饕A7,a: xrQ—9+gG6ė;`oV*A":,F4V*;*y8֢^(l2Q(h XƏ \q$f>5K-F./._r=lm`p?\i= ҟe*q!6?tBQbַe #9 \;@Io&ҦZH;K|fOC *CM4@%ݏ{{PєZ%eT𙭍zD1/<%9"{ШorZ"#G.`1"0_YTendstream endobj 329 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 420 >> stream xcd`ab`ddM,M)6 JM/I,If!C<<,~ }/=[1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5 U4$(8;(2Luo:cwCu';!]'uϗ\X1^諾3X̨mn[ɝ=-ݒuef_Z].Y:~Ƥޞ徫> stream x[m7r~B$ank՜ʥ~%eZ.-)KRo/cG*0:\c99y z/߯?ܓ~/& yÇc?\=_>?O_H:1Ҵo>>]+zw߾|v4{jw$_DqaryG?{~$~xiP.ǟ^w~9XeB~_'(1R}y]Kӷcbe<Ow|\W=?F?wR{{ GDPVңRM0UL~R#}Jc9TV~}VR9cnr7oק/Jş|ɇ+J!ݗ|5Gowޟ#@ 7}V#할#vp,UfR;>l_Y _W4{Tӟ~ç?|)o4w[h4f;^1zxW8ZV&ϸ*٩ W{fDcP2S)+LuT Q_e:TCv@yFgf2iI0h ,9VZ x6%:̪s'6K"χ\G5ރ VJ;iFe4Nytmh3Pj;9̢񠒳hpdLCWe5/: Ejң,GThZITuZNғNKNjT5ڵZ|g7٩ΨQ~;#e+Q~;F$E)e*|Zݏ\66޻SZ Zu(Rf 6걜4q 4 N|t62zzYSiR9fuJz _?k-vG]Vi-fZgZ洔i EF+>r7P Bj0kc4,-Uc@ͧ2=}==jllGȨ@);D`Jt6mJcbdC1z1k1ꏔfVɮ%> j %*u1.JvfZÞ˵@+?bZ i (tìuk3(Ajreh{hQ0c|t0VTG6ӑ̘Y(dB H[1˕V(MHuFe:2Ecl0[7vf31imvIҝ]ikrìW TE+*k6Iq1kZ]ezaخʹћ)*.+Nk1ksWqvfy$v]hi)kLuqvy< 3>G۬T!=@+ܫTQk3 q-j9Cg,à 8 F0ة<ƴezeUZNjսf`^ h@RkܤuiGqaP^ taL6dř5VZk~TZR]TT}"تI||hP0K<0Ji-v2Gvf>k}~y߭u3fNZ8Do 7CoZ>Z1'ݨ0+5a =2L'ύ'ZDSYj~zcWZD< 7=TGW<6=,j7f#h E %gAS,b*m.BEaz5M*~piu_6w%+)wxLY2s m2mCfmq}P1 |DS VwTsfwNPPKv>c5xwrZ]L0տC+qkMFZkMFZkř6ӒJs)CdspwV-ZqajHgFV^dS6aPc~Y)fޛ{yۊAHw}2mgB^zô cv?MiC+2WFJM*e͘wTZ6:GvCCZk]= d;.Y#vìee9,f:FJJ =;LiR)mJ8Ki3P iJu$C*d[0@gElk'YTF" <9'^~MZ/^2fJw5j3cBTCV U޸V7NfݮEg6T*"im9-[1fýh=.? mȪPk!|oZ_0+1͕a%}[ERZk&ZV~x62G)5Z9[6o;Nb̞a~%PϱGq*9W`T)]s3mb:i)De=ìx+%LK]ݹԕ]nuRi rPh-/>kmfZ+fz.c &8*#+mfVə.b%/78 ǖñ?H%0S*k4JRV}Q)gZwIƬui6yޝ_Nd<{'ucИhQ[)9Iv9a˪2'BC01^UtJ*_XϦ0$}9Ib!{fB{fˮP⊳lSt5H:FfYq2P*/c*eUT#ʍ_C>G45F4ɍw*Z-ft#8ETe hXI2jw@O5)-JL+-fJy-{Ud: Pd:{Ƅ夳>~ss 6i;$d-ZƮE; J56C0[&L+d5SmfZcD '2V^tej=iu] : ?f *٩<)it{:Y}RfZT$<_<)<Zv SH:J+L@Vd:{B:ة6Ӗ<̴P*jt |*ӐN.΂!I/xmI0%?t1R;US*m U.Lc+mEe'z\(_A8cU9;!^Vbff%;hGU/+A;f [!6vua#Б n|r)u(~H"T06)RݍV_0Hs O8iI')0}E8Aw8zT$20ӒH9>V'Xk1{~lA n- $ȁ@}yO OD OI^reځZlJZ3]e\ ZZfV(W:Oi9>hgTgLy ԧ_N:+ U;Q(^&3a̬j/#PRV?[cV_1HcW.Z_TƎV,orҀҽF)4nF sidt+µB"ERpNsfǵ6w'Y J+0@S1Z] %2jx2fv:̴zgVlGP0]$qLcgt:׬ah5f Z lfG9 ~?>ehGh%q;f> q]ASehUS;fVZ;a%Yf`W>Su\ǗT碍x*1zY)Q#̊N,'3ON-'t.ld:xlt31(Sdc(67: Zԓ7GQ:ͭ+B㢝\Tf2] he~n'VTbH|x?gp c(2N2 +5 \ ,|:FV'l?vQg'nl~tt~%n>g̴d ~ֺ3L6(S^؟sS,2jsC5cQ$UZ7a񶲝*f;Uy< گOZޱy\ݲd̴9-Ug3YL\11m[hC"ܮ8 Fީߌ9IVcQ"FkJ隵|0X-VfuH0^WЪ@i?bLi @PV ah%~=;q>gw*4fٝ*᭸3UYX6Co5VŵVdJs9R ݩ6OkhFiթGnQ19y.1].7VVIVUN_H& P ^i3PZ0Ii!T4c|O/0O̬ŝSJ?̔nWJeŵ#@)X잝$΃\Zٱ"S)~oAhOGSu_6FTݭ ҫRzQHv _D킠;+FVL8R Miyw ܵld~ zץu?;dL}'e=S)Szw1К[Y@șgɀҘΝ}Qct8(5.Y/>YeVNpOiEKk:̴KdeeZJ."PJ+9)mfJ)"R*3|C̕f#PYv*:6'(窒{־a3J3-9e$YV|Hy(Y꽳R̔$ mrZ";WP*=tTG&\WO4?U_uΫ̞[E՘-Bj0[Ӫ;i)19i2 ku6 Nk3[Tf^"*5nH=G=(3^<]e$5׌x0 +WpWZeE0 oYC|YwWJyEN"єf, bZ wT+yhŀW@+djMIf` ~ߊ2ˣ;a"ݨ0 5=n!yi'a6Xnr9z+^e6 Qe:;Q ώVﳄI밣1)5i%{)t}VP\Lk:LkZrZV,eGY .VIj#*ldF#IMRY7aU֮4:̴BZi$h ?EIQvZ4И](y LKJ3ъdJ$ɅرFT(JU0L]!PiEe+4"_^i N~cf՞7U:{ERwRs$֜Mptėf%1FfU/vk&jweTG LIΑ@Z~*e̔nJ(k)Bx]whEntCL^)e/ӬTY>suM2Y摕2Ӓسimvu ˳f%;(ӽkI]p.]-=.4tr8LLvw;"%yd5FmV̔۟i~e̔۟ ٓWlXzrR/J{%ј)R.o6F\,:ݪtV@rV@9 z70{ޚ۽uYk ĝuPZyscPyG)Z])>Y AM.iS3R;b DŽ9i"->KcT*IU>?쩋8a̴Y:̴^VTofڏƜ N`D+2 w^$'k!VN!$p$Ni#P*k=r*TA*4UY FY3-:z,rSxi^ _^흊O'9dT.Hk'dE}Mj62xJ*q+BO+S%99gu;)k|2ՐDv^Ν @i߃MJRR~YVLtn7UZPfStnٕ҅0ӒkV.~1*/{Crl(gZuE!$̮|<eP5{F$q|fVjV׮XTfUR^W ̴f`]P,rծì-nL 9}={-܌ P޳L)^(NUy my0AY% PwNDRm;Qa/[ɾ^fJ2^u0кvhVȔOJR{xjޛfo{cf&R~'1jYGuL\"؛;^4oE6Xvf@HuEgUN TFvrWns>@8BV4kQ::̔pS:Hm M O1鷕0=kő2\2)]."PJ OJP_3o'tcB4 Xf$g8"-ENqF2n3d:hi ~kf$T:+mJcvv}3S}ח[锁kH-Ե@A̬U==ʬun@rK`_9iJ$SSFltᗌ[9@vuF:JG d(Dj k/i5j"N,EhLBE ڀ2TBVUV#fO hUJc4^4^ R(w%U"#dWi@PkoCP+p9 WZ6au&jmBv͓chTZiAimJuRsShUɚa9`]vo&!}0 !"v>j}~͖ *iZ%ႧzǨpJ߄Z.Ш+ݕn]3x@ڻ1^;|-cv'<@;%PqAAaS|9|n4`D' $ 12jV;=\Zcw'Zb|޿IkFIViM:$~Q6J⠑"lK ZZsC1*dX>*&sFcCKv{#O 7;(&z9Va>%H8OnПА8#{R=mFW$,Q i?$xA\r (?6w::ͮMֱ +u KS: m@JT S/WULFsRhL)0&ҔcJ4jyHsPYU֝`Ȋq״ҝ8@MOTZ#A)7N $zjF v( %w]RZqP*n*VB 0]cK+5:`VV V~YR#FPKJ́3W,'i=VN (kVugܥ%@&4.zFP+uO *_`6Ax[%p.#X04ZoJF hqk5i:mTap*5CH?iOFP^|!y;g;˱މplv?[+q\[i.61!]p#h\N~C r&~x0lB9|f+%vJלFH HIP#!TJH`4m4~9:5v`Yŋ F Nǀ(TţaW@JǵO# N5"4H5țl*F߫ԉ/@]vJ ٭˕ZC:6C`& h\NkVmjmޕ\2ALU3EWZ/a7v/a7ZmCH+ 6#UQ=J> {VO#dW`@!_v<ݛ*<)+{ӫ{Wg[z3Qr(x Hi|#RS,oEկ΋V!u(Xeq&jTRwZG;-VpJvJև\_F`OtVTI=!iO:#)v%J+ JX P~[ֆ@PvY)AFǀ2 @l- h2ɯM5F^CPGݡR3ȥtR8xr^B]24ҺT–X qqFPs~ZU%CHY~ iɞc(jѭB >3lCluu4@:S'RǭRO$1xP2tS$ :V_1@=_RIBp{z\mJ{(\ e6J j}iEk*3j25`흄9Ǔ04:r8I *uԗ+A񊅧-:|NOg(!)!- 6r@<)*Б8U:crS!B PBaJ%g_;ZO#hUs#XCJȪ5GAn+hbvJوi Vi7Rj+r|ݬT"inF tadu:͂EM, ǛZE;\bmAW& *|*F YU0rZWTVjh\ 5_qE_)v%F+9En4ҁET`8G݀ x5S xlMa`Mi$Z+LlWs,8"imBvͽd"n2Y5#|o5# R]y<]ּ肴ao63"\y=P@*ᑰrXGK\z`m/yz:oB`te/wpzˊs+U]@kҪ+:h 4U^E.BE/SoZ j-Zcv=VO#o@JmICЪT!{zQv7ZD @]Ы@+2wUknOu J_9l%ـJGPlXyg@T:atn6:[L&61: jtb}7 ȢC",? RxEԣLZ=:jeiG iWQuRJتʟ@v$4(CPKN&dWB9,6ZݣUJ#VJ@;8-kyɼЩ} PP=a)\cCHҽܟ{"JHV82z/טE%X/shm JŁӕO#CTVi 1:c@L'p N Ok@Gq(_N<?ZwBLcCpNTԒQ(!;e界` /fϗTaZV'̞/۩v}!7!7{=;Z{)rEvls:m&z&ݚP* DzO)vVJ;ZvP%O#"TK5U8FP!@*sZVqq%US i[֊ZP;G 6Vv!cHzCX+` hwr,Jl`XiTqXhϲBNXބu[hVkYu)H *)JRJs%r@V2|Nn٧Q:Dca·ZR6@x(mBVń7>'"qZ:1h[Ռ!Uw,$[Rcr־ k}6!ڄ i`y%)V D#%e3{PZ9!dWY9C0xjՆQm@PA0iGe )&9J*a!XMb~S< ֒+JFȉg^<ڈyVIX[0*Б+ΰ:, T|ht[QSDdQ_ )IZ=hɪ6!@n{b )` ޠ4BJN*`URKH)g>jfrڻ.=%%3.Z>*V@Jw"+V`H)-/(-6u=t ׉>yu:xP@HA*!6ILjz/idđN\{ gT p UxQuV! ͟XqS#P}͘VA?0^:n] kuviݺR+rHeSehwZ{;P;![!X xKf*=]J~![Te?N-!X{;oOM<8Ҽ?ӥOgxiu`&T9ZF> 2ڄ(#%3iZ}FHWP)Շn4N(/q.,,C^əLtR@J~vP: = (w O#'Z*˽UEw3On()JuO3LkVhZP*߉V,TM\ *m@J>RtWVZqbQɸW{ޔRu;U{ VBZH߾ڋ-ɹ5)nBZ6@z'4O6[Yu9n7L*@%9IF' RZ~+ҽy!P!d^=TnK !ҊɵSJœS^0y}JMY-ƑԒ賉6!:vmBZeQkҒ=uVT^Pu!X'(&X Cl?Qau"ES3:xIGܠJo&tm sl@J=JXiUAl8PP*X5dO k*\zr#%'n%9 G.:ݿv xϪ ؾndnS&A6 4m&iR**Uڟx\+:,FPkCPKnVnui?Ye6~4!?qHu*`:FK|A% HBJRY+jtSijUYA:kh0j ԕ6!Qs`宔xjn VB1 hQI3gV|O)[+u> nǜJrVv0*!%À NUJzg@PK0*A\x*nԒH<r0мҪ+!hvLP> HI"qV fJ@+l*-%% #Fy@ jݳEMȮ;]PF0rj!XҖw+7HGxh͸ gR*^)-/emBex~!!$#֍ d6@"!lTR›3@m :n6:n3:l4@9+O=lQ騴)&To^䫻N )^`4m@ysFl{=Ju/<|_~<5^/^I>ʝ5~wy~IN~~Q4o_~<O_Wzr{q}?Vֿ{o# x74I9wo 9=)hw+'޾T?i_Z{6H^(ʷ~؇ LVүq[ӿϊQ]Bwx(ݮqI)շo)W3ǧ?|QgfԔ/1[3\*$[lڍ?T̑js%o^z1~?{Nӧ S!o_߳FvcΏ >ǟoj<vYj*> /h*~<0Bkij!T}3-{kǫO'?aX5q4-%8.{tr>)/n` Y\~Bb47B,㶷߉=;`ߟo~滯~o~W?>~|"oOif/?}>o5= G]P~W?f o?}/,wBWyW_tۿ8i1ݑe9߁Wy$/yxvN)mc~{K1іsۏrEs= ?C[_f,{Is_S33KTJ S)TA9f4H#kc@*̡>㊑< {CCf>Ȱb<ǐ[zW *uC>HĿ?Id߂M}czDY`-k49MwliZܖd}1JtZTʗQ.mRu"1\D9zW],*IȥAmMyNOs8pB 2F4W?pVWwK:މzljc.2?~^1^>\`(D5ͯJ{O_&dCBEQp퇿0R#+Y* ƴKQ NZNy[\wT}Tc|*rj%Yaz- 4ͮ8&-hR*~;՘]]}' - Z+$Δ*ԹZH.Ӈ+T:R9ȴ$j͕=^J¡oԭn KA1=Rrߒ%D,dzb{sdkj꫖3ȍ{o"?C-rы8\_*3ۯ?Ҳ=:uӏYUߨUn9J\f_[|HDKA<⒝35/I2~Gx T׶{):49Z}uH<>Cx-JZ6˱NrAHKqyݯE꾶_tol_[%1ޮµv-6mJ'r%2Chr]{W rb~%9ry;3qhÝ{??p;1} -4D_oăqu~3F6ke_CEׂRmZ.ʲD<qo ^-ת32 3xK%{[ʫc !Pǘ%{|AWo8Agĩ}P]AJ;Yz oGN[xktdzm-^ߚҝuߜ9gB99?'ޟT~3s"?CyNS?'jr?jI|fNzN~3s"dޝ2̤=L|Y?+rCgE^YWzVRO͊"ggEYfZgEήE~gEߟW3"yKyOYyO'z^S?/rEyY?/r3"gEߟ"7L̼ @>3/r̋/~f^D#Li33"E~"O|*=_@߿Gܷ6{rޟ=ywgOnLٓgO>3{s'?yޟ=yޟ=T3'ggfO^ٓ{>3{O>'ggO~k?}ZN|Oߟ>9L\35@s0fYfm5 _ ľ8BjZm'6c<>@]<IL#/27 i2A:Z8HmABҔ&vƶyՊu1 ]zM\ߛn9k=y94578,rKхv106 F-<&@.D$r%gD6Ǐ|J0tӼ;5aIxec=d~kv ~F5!~|tI$[epY}#$0oiNY%D-DΥ * he]cE,: qƨɤ^|#Bk~%"W+\7(~[(癧W6(#2{PqoIHq$k&ti?ȼ4ufX?kc6G{X@nM&aPG)-T{)٩)]ZI-a]!HMW9Եykl[o8COR:r>D<,|0몎iq6ǎ95U,ᔗ -x)˶Q^0̫\Z:5JH3IfA8! 0iiohn5(;5]Xiz*̸bXM f UT*,[gdIvI5sf}UsNe?]Orη"MNL!aނ=&Y]ԙpz2%L?Zgv-Y+_i(-Gۻ?B/%FJKˋb^$~:c#a_ED&,W]Uo8s0UZ__;r\S@F/mC×g ; vi,!qEIJ$z}>IaBIzD/g!;k""Zi4v=\+W+.$q>yAH%f󋴇/yk/,N F]{"GՌcu _)(^k=<%vQDGr _IJ"u},r}$ NȴHU*A4cy y_\3JGk/s>*Z×1b y _U.jI˗/cTE9(2te!N9Hc& {%(SɗFfjŠw;% ]1\a `(9c0s~Er؅%3,y|*5ŏ]ZQ\X7aMDq=!L FIS 2o͌;lZm;JMõxm+J{ KUmGl( sw\ KK$?&ikLD% L(M13(nLyt_oh×A|ueU.96w+I(>v!Rݽ$S5| iU8ע e".F/A E~Gӣ1K׋k$<4i\ypkį%MHk2LciE8y}Y?>ȏ(hDxbKyO?$SZya5+<3#oDC%2Ø/B.dfk1A/'R6zH%J`4݆5t !r>d4DQٔʬhrnYժW'$ON{1I%HIۘz 7֗In %2]_uq:Uy~5y.2g1hBi0oܥ ;i$YVf̸tDbׯ9tYq^8^^q?H$Qe޳e WG,$Xžz̃1-ïڸr7^C疊%+r׊Fr̼4eQW!ORe]o6XbuY8o U J?Kmђ<8L{2w|*GWWso.RzmO՜K+뭁rщQht]۽ώU a^e ^^ejؿ~ Zlpѿ.#Nw\Z^1 ٽ^O{L{}Ȣ{}Mѽ>oZ$Z E;:ý\`sv}]Tu #пה /7ӼwQY_=,Ƀ} vyU:%e ^}Խ.;dq;Խ.qԦC[^rV{)oudo,mt}!ܙo=!聖']}2S([Zj1et/_|ѹ.Du:s=ϸ\GznKƜ~os};>sCNo͝[oo]FZo׺LZ3֥Gv\\Gk\Y<WU`K@ɯ~]W__̯~ͰWp' oͯV=z=0t@_ݕl|=/BL#K˙Fvoo~n,'ڻFc /@_WGs"O:?=gg=͋ouyo]-HWz7cuJ[\뻒׺Nk}O֝浸}]\sSAŵ~/b/KZw\kQkѧk*ܿ/ RZ*]ӵ~xXtGυ]p>]WWXd/}k͹/ 뤫qq_r+,up˵~;~- - v? Oҵvnõ;zvQ`zé9=<#T?[~n:ұ0JnnՙjI?wVnO5it wdQ"7(*d@@oQ/ | *@Lvt8k˂=D׶|_Pf(FkOWy?l8Sb(WWaÝo: Z塬z7ߑ:kG|?%/gQj -6ثcUR9\窪>o. Ηg]~?cmI 9t*|?'*w/y- |dfz*[xN[? vQT}D.,9 hUp &"3m/puiV~v:Ts\5J.ks uӧ NT͡!ʆmu e.cQ<7:jw!;$2T%B9 Stb9ϴʒסAfw({im9PwV?%~ZtZp\_op3h!K/>'ܗ>-r0.Fə?ׄ>%<;1.n]p#IC +iͺP9PYm),s dCY/}a.VC*Ra^v#4;OD sc]jSس/SՑ};<f+R|L^uȧcxDC%3Ѹ/d$?8,8{ ?y@ofN (mGʟy<_)3Fun:WM~LAG)sNO.])X. O<*ujst563pnc9 )Os8y1 =x8+/PRt{u'v4lBov]~:a!\epGңѻ(S[~BC4d%5u{MP{p6I< h˗?.V3.ĩ8'oܘ+!~J'dZal*ӱƝsmz{!C)Ia8Cb0q\0iUN^f'ut1B?$NE;7mj_QE K78ڔCg1dԖ{3-mx!?5|8v`Ysh׍6qyo=,09: isسReJ)''ϩp+eU~@.>)4{y97ON9;gU pGYsu+ Agc+v]՟Cvw2 ,^ƟLDMU1Z%UߤtԔTJ<臝,fC߶xY3U`+Ρ-o [:73K}|߸i%^1\r>) z>m5ARS DxŽE &ç";#\qQૅ˻83jt)+2F`T6JaEͩ2tSnǮa_i|>9>#pT78h艇3ήđ9wRUCbv%$DpC-0_4;~}5G;`d8%Cnz_ȳǸ}ciŻ(kUlzL&*~fwۙzvƽs~MnʭN+kK;5͙psU%Gԑ Kty?Ww =C2qG bvg|Е-O=m Z[ \ށ\qd Q@NcqL<%DSTS狎O=[*NLҲ؞g}1L_;UUf.8sT\K VHbبza'r Vxغid+p @yĦZ^HՄJx6<ӕ2źLu_5@_j䡲ǧ_Na px`֔JF,ҸyU?:7HEaI,q{T̎LQq`p9+?ڠ<$T]珎Y$Un#V 5'QvYxx !i4}8b͙m)x ?D*r(<&dD뙩0[;65ұHd/f"~pq݌;7>+4Ia2oz' DEܭJ,⮪2'g(կKZĂͩiRO/X!FFpB+ Q[ z6Ntx!}NÎWA(S1&i#^Gב9I%:l{?9p`(fgD!sO`HktKLo<͎vʒ![gS;n! Kwnaj\(*zC559Qvhm;4F؊H὎W?;jl@tݙn>;Jl:ϳq@<2d Is NgN9aC ].'ˡ,P$AňTJpkMjʛޘj;'}҂Hངw7ޫAWY반H)Ut$n(m=HJL wMH Y E*cXp\:\`-ҊJGD}\!iLfoZAEs1BFL024V! d}Gk\ 5|>GDIHIaZ 5~TF KL*4~,Z9 cKJyolaE81aҜLL ;jsgZaC.'毕 mGEV WN D[DLߖ7'"B)g`A^Sl4K`S85SCК#.iSæ œCVDXmEvqH*S `I=Ç}hgrʥPvӷǾHr 5$G&aDH^_|e'ׯ<d(pv: L )?ACAК#HԠjB$ )V[{7-!sw}or.B:u$IGq)0"9,V"1 l ޫKIUK:흥(woX #Af6O]!*w8U?5t&9D4h+B" ul|~c#amzGem3U4SAl:sڂ^| c+r&ppoq̍!@М K!SCUOBx9hm%Jk 5 _O=0UR Ne^HШr@WJlζ\'&j)$&JL Ak AaR!r%&SF"U( CKQQ:0^BjMeMJ\饆AA35Ta9Dj+B" uxq ,ڭyFh# /`CdJTuHL AkH"S`ChEH^?B`r΢ wDaWSLx>%IhG* :䜁$&|= %E#w~s0۴hRD;,M⓫(i^/>iMpq 0 |F ">"C 9|m^ Aoh{s7j+xⷿ*JM.Vu }4݀1] ^ f ^@61ƿ༞`ʑO[$YG|M3 S[P0A&uZޜ9Dߟ4i|[V<d=5"oyh8 &Hu 7hXJ*+5$98œJ?P0}!V:~ ?qU֋j*$N[Ef9_U}cxq ƀ $B+x/A]QdDPɩwk|cEӤor7%td*ZS`Dpԛaj@ӝ!#lDཊ82xLZsN78c82N-,D72tꖈ tIg=Z[AҚ,vI y VKURT" >MeBO;k#>EJ0` B1ÈRa[^0lԽɁ (O4I;SG9@J1LB$č'}SCК#HjTѥ!v[{%WÑ}SCIK{U9d/v2M>꜠;,4 KqʩɩA>Q KA3H0= 7A9E?Ioh^NjLqNԨB}ĮPjHs8Y4sL Bs"$^@cfshr:Om/#uZ8" Ɗ9\D Uh 9M4ދM]#$prp\^C/C堦ouڮEBl7ns[&87i\|ۛ E]oፈյf@Ahsi.WAS;aU#ԓ.rM!v$&#QGwфSƔ6ijHsp9SQg7H [Wo\N=h.թ ^:1P63%#!iApp:S!oniWmYͭxurWw9(A|;蠥;Tx?|̀ DhߖN:5aS9NrĊN\JM5}#3Bd.Ԑts?9cf2hsƈ"$^Q :IgB1^|;t$ry:UG6)FgO7Xziƿ=]EO[c;ިJ@@ěv,E"}jZs6ggл1"24*I?e@)`ƅåi|FXc/O[^)Ԑtn+91sFϴ"$ld(x-B MmgÌTg%#~.1莞F7O f˝sIJS"춆:8x~9a#g-ۦfE5cL98Ȩ7㼘ŝOPJOL./`-3[h99 c rlv!qHjHz~sr\JʱLPy|)=^Mɹq%ҧiD׶LBäw'nN]Xa93R㗯B3EzdD<ϸ$uTߟ>A9z Ji[8SsHkmDçQDE  13X# 7iAiCH Z:*Dt*)TG9M.>SCNoRΎsLR!V:~(t<NΰC9gCVq9W(>0%5GMAνC4DmEJ^Glܮwoi>vvh*O#ONy]kbMbpBzyH۟GYBr߂<^bTLho #mhH eryְ)s?ӊ+C{?_Q׆|>W'd:7as.*!cX A 79,  øpi߇|Bg9Xn2O+tU>=&g.ERCSd(aEH^ฯi+pބh7MI'^nLe8Mݣzzga_hx@]jH2O*nXQU>$WX NIS:*Hݟi/^gK:kè9K2\ -9%V6pCjM"JԠt̰;<rߗlMAsu:f92vcyh1<挠 3 J LR&"蒺Ͳ̄Q26!A,#켮QZp@pj u DD,%pYdW9Fkt~]l5Fԙ4N;3Sug$55Y˜C46aEHm\7-q2#5t` DLyO .M`Щ@-J]HJ#B" UnI2@r*+٣C>#BRA { $4d/]9G 6{M40%,̐@s*R3ܟöSA_NQ/ޫ\x Nd8%R85Bu&} l/D3>5$g!Kp65g0i4|[.oKMV^h˘ضkѷha.asĩaSߜC4VDZ) ֭3eW׌Suoiie850Wxa)a+S{?9 X:C4q@[˄7lIJr.5G}f2hGhi5{X! :&hKZp~M1%Pr-QΨ6ms?ӊ+C{??? h(C3zB7?/׍8;Pded v;|DelB"L 5q& OSA 1.)!vjHGL!8=hԕeVDXm6h׵ywQPL"}QAk9 { # !&"~`]}TWNa5 "~C&gх)dui03G%~'  zf wh/>/|Zuq'] kS)HhHZsuv;Y9Ds[i5a#p~Ex4-j"HzL|z=]𠥟SI/?|v% DOe Rk߶znjT{w3aP?:5I2m~V ${& ,g M00 i)B@O'giV]ncJSCR!YḙķDm u0cr)sL& 8&&WtySAК,.rhkS߸@ZmU)PiMQlDXc&\0 Sw!$@oNboi566h}2|<FÛ2u@֒7uB 05$mtam=4!$аzEm~RnS?8l017`)`vIoq7GOǐ9w#pd.Ojs0\9 'C7vvICڤJ\* Ic$oXCpe"$^l*p.}Хl01t]y>HcrQIef!f3\"1ܬcS%qO AkHN!5ts?ӊHߎCHJc69B4Xg&aMISCO0gj@}Y}!VZ{Jt+ῬD]ƿOg,HӞ,B`XE=EߟbJ^΋Q)p&PDOfo!9}@ECҚ#fERij3DZi k8J?78;}v?t*نVD߆Z.xLFg݋^ -@l䨣tƣ塳w>0?=\pDt,E3[bZ\|7Ԧ2ƱG]'2FzI!,Pl='q<~/ Nf&GiR?P['ͺ,&DWkjZspDpvs>H! SPn̂ANǑɂJD5+$5$Jm*1g yYü^ӕ,&Z9.qաf-iU-hHz}rT*鉱!VZ{ޗ }uri!ZBפkxqsS9T1%.ZCҹ N04T60sf>%^b[4~szSSEӷZ\ $f)H2 m'>9E&!6Z{NWݔD$;fw@!-ϭ $j4#ɔ0, KzfN 6o\^k)f&zt +@jCBD1-g3iBC%XaU#sF9sb+,VZ÷u(;]I>l A37hW&!0JkjH0$x9L3+MVL uh\T؍ow'g!yq҃5AsCrh..MΡ}rv ;k 1 l1W9[U4bf@iGX&<#Ci̝^޼7M`[rN!L#B"*~,.BJ0WrN=ʷ/vxCi^SAlP@Pqsgac(xKz}}Xа5Ȇb@M)sҝ0b_lr#Aϴ"$JkWQgNpt;Z*j*Hdr9  H@r=(iCH 7KΡ[k!w@+mcwVY_YTm vL0aBHὈΒC_ "o{O!6a=w=r)fO IgN裑6u@!vK÷u4[vt #frl=p;t>f(E" ,^KaW˜ ` !F[{:2Ks  nq|B,9ԡ-$va&Twj:h~elEH὎\}h* Z*y14cG/%T7598"8rK 1"H,}X<{))}י4wƬǦА!Rposf֠Ԑmyuyrƨx\gI3䱹E%vASCLNg8ej|9?ӊ+C{I  z"`(r|l M M RAU QTs,3?_c{ ?xV_ CpVI}[*H-9_R?9Cn҆1qF6˘sW=JФ=*жfE3* 4ཨ0nm*fH-rBb~s۝vxrcTwEFbE !=0'ݏ5K91G"$nkx} ~Y;a,.AJҬB9™;[.zx䨣Hآ=zoY;۰Hg׳+0'#I~~/^&LF`5{пE~KaǿO$5ھIBe>ғse?欅jC 5549rgiƿӁފnLNOrU"n_S $

!#&$%DE{&? p=o 6[)6K{ ~tNvN(| VOCmS`5q*ZSpDpL x giW-&S`=:NU"!߆QfO,YXX?$M)|i*B6@ ޫ 2d'zo0&1ݥ1T(5 Hꤓvg)BJ xeVDX`PTwt 0M3Ƈ&dNЈAFIiH[/_L!#ˆ E[/g>s[wOޒa;f~(f&5C'S@4?/6!%hkx/ȩ]m/jqȅA HP0؋'wO9:io 9~cB߲&" sXϝ"&.K/+rFqs$N u\^>03aEH#H6N8`Ucuc'Xr|z_ 8 8(Nܳ9hP|%f)x/AAu\埪mL-]re#~St.v!E B t付xA_+GPEX"IL'm(GTt#߈>y H*~m^}1fV}cDBCz>O+eۊH὎<. `>qVrzPr3dQu$y d&z* Lߟ $-҉% ]8t{+:{l \J Iw%] vsgZaehxB8=Cl D*)4S.DSZ]jH:}9LG:Ê+C{Q"@g~k0э=Ӌm P@;10!А?p6bj@t]N "$^G0d_AFӕ`ծă}T N<g9 uAhCHZ(ks3 #Ip }}aHEH!hHzsFrNCRjYgUK+B" utק k\D6;ȣ4ySbWKjHڑcԀcXͣYfˑr6L1)^jHةu'Or و# /gG% z'HԭXeL xD!b 3!VZ{?4 *ZTI&;bdžv$} p!v_4$ݜ!9S5 l_9lEHoI~&9l> g%b߈SB=5}êct!ڛXZi5FOMe9kAHD@hZse~BURhVDm uE H)=/qh C41494%Nc*7njr5iEHpN!l^Q}/ʿTZ>WOrSBSC[4 hT]AM?24!y*[V2.vYӈ/s>O)Dߴ wRr}#65IiEHH+x/)ji+>ZLj+cj&}+s/v-.ޞ$!ج"4q-sf櫭24wMUm 9NQbZg=fkS}(-5 ,sj+B":.Z>)Vu mGU9F؄HRC=yjX7aEH὎_k&}U(g?y>jO yfa{\^W+H"'9)75B+9I> a P^龨a&,CxӞ($IڈL6X &%?9R.9qi%F+_萍B No-.-vrzF/k$CMzǥ"3ӗ&Dm E(|*2*JKIV9)Ձ4ߕy!y7iÇ+s'-4Y -Ar |$Gt5pqhAJ W Akq65;B![aehxC|I=%cW":=H#*%c(-1 ҂C{ ?h7B:@$q W[}`˒!hNwȋ[.5g,sڥa\124סN:/8`Wv#V#\%" l&8TEs\ZsA[FNj&T ةgPu\E bDrN"Ee4؆C{?V7z,%39Cpy 1ZO|x&R ,+5$]69'~SC99L&VVDX @y'Oʼ8)D $nʤ䄛.ECКz)N y~.sƈ"$nkxù5M8.34h0 i6}F ZU>f} )aC{H=N3u) tqXbQEb)qM&]}OWP*S5MD)Vy_ *Sv]qDasyJλ-4$98"8UM%Cv]9Dd+B"햆o9vgy9K88:}XC^ 9X$;٣gO06޼99}@4SomBJ^Ŀ7|0i;6 g4%w԰7}BV"vӂ讣K%t"۶-!!h;5GUZa5G h{F  ^A$*qA2|^o !Yʺlvg0;eg/P{ )µhH c:l32324ajaѳ~A>}*Ikb`RMb>y1&V G~09BuiBM;(E$8Ԑt19%O s ۊ+C{?$.[}boWb*BT "ت /i1 uxJ|s 6SCa9h+B" u+"h#EryMr<h \(w& <>Sbjjǽp?SbuB4!fK{ ޏ8E7Έ3dl5[(>&5ϐd%b8$섓^~ۯ)UlDq y]0 cK9;#'\!iחDd6M%h/^T΂p}*q+y=~5=o*O gr@k(s%aiEH὎p{4\nNNxC}$zmj$?‡/~1598"8z٧$!6zEV70Z1`RPƳT#+" %K IGbrJnhB9jH+: H~6&`%`k;A= +( AO`Z}Qp 35`7gV4-00F /p fh'o~>BLOjf,I*Ab;( I7P^35lnSi|[/*UVnM#ͬ20^4 J7DgԐ]]r;b kث_ɞcw"$^{QKA9fusNXJS(H;kTgc(UokHZsZY ڮf9vK÷ueۈpߒRTsօΉwB[S"Bg4JP!2[aehxCy BQ0hYT\HB_D24krM' zåp1)g1(Yӗ`(aFv i뻚lM#NB"q?ojZspDp65섒sNVDm uV}j灎fgcfEEm$oWOs|UkVU@k$2 l` E^= qF%Mgn$DI$S6$ +P9E4"$lb(x-³ӵ| e>* ˵D O:3R5?.}1UtĀ+,h/CfԺ 7$$k4Y FD-3?ӄnc{ ?d\.jax3$ s;b=H l+.K&ss3tV+ H"Q#tr:ڈ0tNf+Ɣ@k]4$ɧ)JM j0(|VDXec? *9RWTEQ"pNpY5l#PP-2I&{{ ?8;'Qy}8$,InBu _eOZ`@r6Eh9A 촴 $f*_:ZlpN<VrFe5ŃSّQsvьxH=;]sm]P1:Wt4_#0 :+=e-䀅h"Qͬ4;jH5pg/mƚBW3ybM C'It;43[fGE?IW]OOyN W9N+B" ug|RP.%%Lt{\%:\4[%m~1@9yC;93-kkAhyM>z ciʕr:#G)Q]Ã>N`cޜb4X?;in5g!M]̪ۂ;Uj!qZhH:ʻSZæ⭜c"$^HR( dz q0CJp* [bEBh9>ɪp|2EyG e[f|6a`(x v'Θ3O3؅ ,&l-oܹH95ށS$<])Lߟ4"%l)x_ǜAKs2}/m=Yƴ\dM3WR2@859Q]j@,sfk[i5tgS4p F6trFCPdx͙F "QD&gCL4FȊ)V[kڡVՍe&*ʙۼ6i얱H(05]edjx9Dsl+B":l ܠ3 %._&٤3O1|i꜠jZak`eU\rDdV6h؛[}(+'4$-9ݗxh'J?6 HpNF(tx $!&z%g՝bSiɸRC&Fp\G% lra_ Dc@Xi '򓗜pDm䀜I?5 VffvHxe|'@9W(%i{"K V$}L?so0ⴙ6X"M^U49ta~%4ƾAV3{J.\=SF̞9榚 Km?$,trL:RuO ڞ8hMDՓP[S3@/C Gd)+didk 95$ܐj?SC'לCDX0*qڛ9fG;_J-p q*ρ >\ۛs@koDLۮP tQc5l fu0E ԐG*9SPccD뢴"%lehx޴ޏ.{_ɞ4|kЫ $k# &_1G`Xi5!PѓsS9+F%[tSg0i`%ij`ȜB$>m?#v'cNZ);:꫄kCKG8S.֜CS@hV6 !3IuVT,1 0W)ԐR/T>sӄCòbk`gup}PMi.с!iÅ8z=Ŏe>\ЊH:SuHfP= 7tUڑ-$U$}Qav'gc3T>Bs ۆ1U@10%ڮ% ᒁv-M$u ^ܝ,f\YRG8dN҂DIcIпwc<>cc8(z$)xAOiB^?묇BP 5ܐ1$AXqVqfyks\k9B4lP}A%˨#);eld wESTv\7cc,D˷)qbA"6awT.r.G6}2 Zl`w!w]h5/yՠ:2DUk#O0#&TUg9>aDZJ0]+!^ 3Pt9xI_hȸֆ$W4lg+ap(]4%9>VH5 <6Ap$/$.?H?*bw5_j,l?oy+1AX#,>#8p@3IVC_ 6id8M >JrEZ8Yn>fVp~'(,PHf4 nۅƢ+YY;`Z q5%AQ>zVX,^8 GfX$ޞ76+\\ۀOv|8(['11X1kc _"=6*E_<ӹQf{$RYS#@-+ 7e*i!15$ <'M5Z:icu׹+C"J[x]qYb& ǩ%H _1|( kdܲgwIy 7{]s_|_cEOʂq#$Aರ|,b(RqsbT8/lv<܇(M7…2`&bJmL슎  d<ݷ5u1X1s_%>/d 0C (+mR`RZ0J|C=@gfz ~U d1? s%?ʋN*`ܯL*+{]"5,cl( DƆ`(Rqs_-٨~ l_e Cad3W lQZ< k1MCݒ&#}8q okd4 u5`},$;\H]yśJ7ކ /.$IAGu >IĺOgh)| U\-VPۀ[XcE1@sUos* ΛyS EaR6 }}l<*Q 6[[/+k5Y00I* )(qscDz0M$E,k@>18:K/DP+wrTe9OX8ۺq_DƑt%2nL*ź47;g(6Ϊ\Hdts 8\+/ogiֲ>%쨓Q'}kC!idܲ'e-kYr`okXŠDwK33XnJI%%6}t _F 0? }.VGD<3_i YBU32 т4u ܲo 5ݧg_TpvjɒM N-ޔV,Fg3(EJm6hvN7dC2aiQRC!s_,p!orIP7BvQDbI}Wy7Xe`GH誈㮂I\IJ}̶rAlz`ZI]8>K.>N& C".[ORr` G:69 W#H(),^uJ6>bE= d[4N.bBFג6ղ_Bhc-1BQL y|t 2=oKEN~0a* SIo8[oL>_o4*nZ0J@Fi}[һ|YzL4A[10^/dS,D\:N1X!, 8CW:' HYg}_r_O5īs-[yXqm9 2*$9ّ;v.~f >N z$9@Y>>}(qs A~q9%d žu1o(ήWY0@RC!sjoADbӽZ+xpVwHYHVgȸe9*&Wk\YLD [EEA u 4{hiLH) KRYr=cF- y|[ ZHq-R[``ekpDy0~9Ƞi1r\(d${#~dG/8'\ ʂ1}`%+_k0άb@+ kdܲ'.lCX3ǒ,F©|mor<S0}`% di!cA* kdܲWuH0ՃX32+,D{N"5b;з ikt8'}`$gc|1$&,~ ]=۶)(- `AyxM@t<a+_ϐ59I6d$6Ts\7a&4]NR D\cW\AX1s %DI.A, dѩLQlxFnot)YHa }'Y}* iTa_%_JrMIQ~D(WWV0{QZ& t}¹}{: iT]k<>هjd:Z0VEbx^٢IcSOxu'Ɋt _/ֲybtȿ5/?ⱊXvv$ 7nE,^=}҈Olԕiߘ5Ge0>#JDZܚQ,=Rl!"|# G <%@Q}wA{kd4;h0&dύx.HʖoWkac-mLp,<Ν;tjmJn=y_YJ׆vx8hj+㕅ě>da7HY8OvS[F,CA},KPxŮzE^Bc k~=>9,|J =9 һd<>bd`bJ3n#eR/a$n3QqJԸ X%dgZ&e8F8 kd(ҬQsH4ۘNY:6ZWAG֐S몒YH<2In†3FF) y3 z""ɌP'߁T8+@ =bJxvˤIq4*JZ0lU4i %qejEqJx>Ѐ 8  %ayXNPWis,vfӾd0k5ɠe3F3dAX>TGM xBN[~eqsؖ:!%+ZԎ@ojήpt=`*d>bDJ~y(qsZa$=-E̝A̒si4xiIb=2_99 ~:d]lt K@n,XYÃupzK<'l{/Iq>%fo2ip-ǔgCuk.~|q%Ū#šOP$|IdS4`L: d冋-4a p e9O6x̢~%<V Xo ߐT'MBb=&d-[ ))52JYxCE$#IM_lr/F-qd,hGV lipYJtXQH#{&BYbFp*\׺S/殲^:]jXY/-񋜑 _ei!qw%D,,쫞>_o5-<Me[/9ZJ:k=eY쌑MԈ󶖅z$沅F%|H[*-E NXfqʿ!NUQNÍ,~N =>=1yAj8fxNͨ( "~Jt{F+ '{ n¨9C m>^o:H1jH52nYxoȜFۮOD\vqCo>k_hV4*[q.wNǾOhMMs[|ll8eo&͌z-4`H8d5bufXskmHsk&%7AzgU}WccXĶOe!qSVJ7cL>Vp'u5* culDƧ6# 9/I5e vRX!GKQH#tĈM9nSo7FRo~魮9 OKGs^BRC!$ZGq0C21$lGcvrY};~5^oDvVbl#*pܲ$cMg%2FJBKϦk]D`)sQQ,(Qq‡y_"{( -7fKh$/ź<qu=3d!q3"%fgTpW/<4tx_G ; +D &\ 4ʃ-cHs!t)HhH"j6z*l#,WYWQ._E  :DUQcB_. {Uwdcô < )~'0K r2*eꆱ@ )A%w%rtpy[FF, |˓V,#PͯboEFiT7PxzIb/-ll>E(Qs_l:Ū2hSp\"IllV2oi5g6 ;id,73jse-<>t5 <&oueI`'m㽅V98v`&9IAYd{L$'  <8A` $5 0<@;cI}SdiH8X6z|js _n-kWٓ$6#Y)g`Iڙa  >m-j'ĺSEj8nYx>8} $")hh6zb욵XFL KD5|gIm:]t!X#C$trxQ>I.nl5R2ǣk5<؂!-l>w(RqsFI Q<[;A ; hLI i!,?F#- G'}ݼB,|X"CG)a:cP" W bJc@YHw͒`[&bֈ>J0($37E*Xr}҂1}8e¹}$52nYxzd֌[)`KQZHN ֶ ,Iԑ"<ʇ-H[_aȿ I< ?5|c^a,Yj! .gS\. Qc:Lދ+IV9yvOւE@p@-}2`LZrPc4ػ.=4`f Ȩe9ORV%E\oJYHDdpa#* #S{l iD60=;4 p*ևM˻?f۱;w,C%%vdhh˦NgbLqC%AĴ\c QßP>Mpܿq#g\l/MG (Rq'Cis,$$AVY>vWe(e9ޫLZ'TE)}ï{zk ٲ?%8ǻ~`ܢz&~#:r^J#q,HWoe``?\a i YɝL}g4KZLfDZ0>x;z),SAc0o۟{oGoEEvO~~B~R~1=lygq%q}}?۷۟Gix˕` r RX6FOט¯h{hҲFPWYH١}sX^.VWȨe1yh6|!I G91͊1ǿ['F F}U>+ﺞr;'åEC Kv<MejUBE?q 63\cV RP j̝Dm9~UmA)5m{`bX|$P]4lY?#dpХb )^DѺEp4F-S-E `Gng>MK8 RQs1)6V$ƿu<@x9'%;2Y-A`n~MX~"|򛷿'{濈ސ9]SfG;DbyQ+!Yu#_~_~޾ߏoI-kOzpMޏA?FKk~ݷOWW .?$[??=_sy[D~ե_fkR(endstream endobj 331 0 obj << /Filter /FlateDecode /Length 5562 >> stream x\sƑοWҥ*؋<.Y)I,rUbqW$}Ћ%m{f$A`~t^W۳3Aߞ_\oŻ38 {^29؞^/0EKP*{=hcK$Ye߰ i* _PyQT+d澉9"6ڿcj]Uf>fV7B~S7}fşwyk Xedz| _Wo 7dMLT ]ev멨P-;в{a.b!%9A1y "E:/(!lp~Pe"0O:/e`6u{yM6dl;M\f> u +ck0%9I'DGJgpNDZ~̬0 LJͿ}t{@ko!uK)l.53;&GIg^߷.Fw~uZ L{.aC~Yz ѹK4JY8I41xm:,tqvіك*OJ袉$ً~U4`ٛ=*:߶}nzhiI_;Zui #'OށcaI>p/&t,]}ӯ2ɭ|h#}2~ tEL8%`[2{v >)_߶g`' ֿ; Jh1T!]KFzSsƩIEJDS0\7&M+0'*এ~f!Fq%Livk]'ԑ'Q. | a!胖a_YczƜ*0Т;, ̓{NgO;`_o׋ߎH4sc# XN Cf_-H8[Y{d9X^CL(dÈ˧Xq[c0=DqU8=ʐ_b屟;s">8 ZH!0c 6@0QH%ڳOpt 8%RP$4VV`/˴D&)2R8!I0#z!&~yء(2N%q!v $pǽhr)}RiĻ|d*ۊ/vC0|\=KRMl$U+mLV->a*J 9UsTm  `Qt?>KoH>k__|2s@ уJl(He̺x gu?TggE>ܣtM㾺̊<ʚ]Dms(^hJBnQ^ݻhnG3^)\#z}4W-0a&;\!?SMr}bβ5:*K3S@} }"J"]o|rz8mYޅyHcfeZO%7h)L汆`;UI!h,D^\ ۢi@rmnZր!~ ?k|o3bqp@,u*+̵m⚎1,J,BHT>tmS6υH. 'EC QV {\T#ABPcR%7PRTNwBi~亰߱?P(SIHY= Dd2 +mxX&piK*ڰ`) ODi kK6 –Q1^ehَ!'kF3j69;ʿakOp%21ěm^͏lNoF l%wbp@G!T܀U`)uLYCpt,'\et$x'iK ĒPօsl9XErҼaSԮƁF1N8N_k0iKr/H/lnΝ_ {b-`O6cuBy.)TfPQs]JtdQꓛڢ 7P.z3_оk> ޕ'5diog>1ՋhMV8Nh ͌gnjہ;b"KL0usitoY0Sa,H2Ө= BJ:Frj/XΨXٔ8U >ov'oi&,BtF@xJPf 3qT8q Y Z#řBYVyiSS z{ _Kaܸ+H,n5m"5Rw5.|Q I*0aCAt0U` m؜uO-=9.8I*74O(lsGOˢD.߱Ij+V&f{G1EeVA unkv<C"t9)e92rJ(9DMEǷQ25ǭ=5;#B$M/,[/B>8U٫P$hPE*jw@g7 q%6ysL/SN@r*6t{_G3tg6L}{˝탙lzjŨe(x>Լ=GgXI\aQW0(lQnr>*Meˡ(vw\/3 OnRu.M8qqh?&c1H3Hv ;qG(^0FRC23m_Pz- ) 07Yah_Ëd,Bjw}MWKfoa\EQ&h,VL"î-樫>`@+6wA;yfr蕬 ˜rnF8jHk7qOS4QT SUjʙLYҝ ko&/Pw~FML/UPJ`⯝jNŰ%mY.O/6}>G|r:с:97UqzL'C&]l&@AeY0 ށ&WS\7ϝ c~{`;++a-χL(Hf|>i'k[Q?:*qtTO91C)gQrRdrz3 $d`}{[nw_~7w3j[-|ۮKSF :Na OrJQ9()^˝s CE_ErUGWHf'e^Z` gP}#Q}Am ALR %CV|L/x3i AYo^;C!#tߩ/Po&*Ys8-T??-"T7]|F*5/rF b$\Dް$x pᘩQϬSKy)e ]0҉Vx 5. wtei8MsuCpi"(+ [Q2c]hHItUƈQ?GC<ž97>*B&~OG(LLP YMd6ҲaR5Zw.Ǟ"Mj>TTt፩qeޭܷhM$naށä ·T)e%{O)]E}J3-<)4o'Almf|<2{z͇w78 n.3 qRtQ> stream x[ݏqcC00᱿/V`lrn5;5_7}TUwݜJJq9buUuկ>ˬ٬梙]r,̾;k]^G̲QvBͮ6bVԜq\\8oFI˝ ] W ÉFj-Ym*kOO)' Bԍf7_p`*]zOwiVnɒnjf_vvOr|o~@-c| r9CY?տ_vc:\H+]pg}Cvשu6¡_V Z&Lu?_XHWZFmZ\{6cqՏUB POsFPΈa%Y r` T΃rɡ`a趰ǁxëU7\_o7-jP5>nvw[>y~qUvi(<ԻHanU^׫_ނa!%|ñ}^z뗻5=nh/q11V}c41LN#amꗼ%v)!ra _Toڻo2S6C0n}Qn3h584DKrh'rL.p"kI76x6^wCg%y:O l[|(?,sqhT9JO_D:sFjQ1wbsvۧbZCą-0;C{Q0vY=A4<$D^Rf \8&Ba63U:*5uw 0 HtzjP!UYZOoYOM˳bh[}n9ߧ6FDҶ/o]jqTCо{d7x- d&97qDd 8J0DɁTA!mߧGUpDxme~mePzChF.\9D67ëTu$^/Ljwd)"auddd%PԱD%HzFex[` Dh9s"M`E'KMv1W"#k hRY lJX6%BS_>w$ A0qv>+O))\J(%dMmIV,>C Ҙq= nr?s1ՈHjifkјFЫ>:Ϧk l>05L1t]HXJW>)xdQEr9_9\+LRb ߗ MTWiǂ=)y1DDRf!lu9 ,b3h* ' ) (;jvܙX{y$(y\ BQ1)msp_9(Vpvݡӱ\L䧔 G"lMVPȋw' = 0t$'7C;dx(Ojd8>1yK4 7{ d[bz'1twٚEM\Nv$dqXwoVB~҂MsR8acg w`ØfXиa;lAz!\}FM+ȇc27{!r1FRCm\L΄v5H$F -d* $I:j9c1i !O2y 'X)t1,䥜3}zLeqzXN !I*KPEhGoylO|&|UjOK Nb?q9DdRk#qN%(e&yL dP3Ǜa!pkM40 ej\=Y IG$ڎNl5$ m{=)c.n$?{dTFNbT 9fdH%(U3;(j= /FҎIԘVG `t1ׄɇރąWB:I%s#` TO KqO]) `7EB2ۘ 8m;M,L dKi\C}}zU|;R+^T/v}@)c{JiIJɌW]T6QE4b#M 4|3/G/cý9Etr6*"İS9iyj%#8qp a:2PŔCZӦe9Qj7rE"(M m@7l:18'̩6#NLFAR#)M@wꁮMՠ.D 0-,5,+yT(v>utr8Xćsd(!vz" ݀aE [AO|* ;iA9N ѡi @1XkpcYJy_Mg8C<Rb\whxi/mT:= 0Z,[ߑ3;l"V6&Շ}11)R[ (L<`:YzRuYeW #Ga;α'M A"&66q[p MFqSC< O\*d ӈy/927|1u)ӉƞtK-" 11χ~};{rq9송a6H( jIҹy#gƒtvk^Ӡ**Vs)!Cɐ>2S&DұI `3\qD?Wd#ҥ r8iEo4wູ`\i|wBZm^ 8k(]=}6_0a'XNOG[3Cikx:Z~ck KJK^8e"s p߶?Wl:;O: ? .4 7倉Oa_WL< +&oxIiW8ᾢщZCԴ{ u-3Ѵ|2l  K=U֧F1p{ya%6>2j<@DϩI7_gZviLjg2瞙$ SnmJq(<6tE)̚S(( ?3>+twV]KF,1Ž3jAC\Oyc L`u)>ZI/Zendstream endobj 333 0 obj << /Type /XRef /Length 258 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 334 /ID [<75293b2573893023bb66a713818c61af><2f2f5b42025b3196a6b8f333e89aef61>] >> stream xcb&F~0 $8JX b:ˀloz4R2`:l4NFI|z?T))D ] 9D*pH RD2HPɥ"Y$#uY R@Dj?e$D`q|`%OH 5t"a R%Gz] lZ\~ռ+]˷5@yE] R9,f6U l?,X Ug0^ endstream endobj startxref 485712 %%EOF surveillance/inst/extdata/0000755000176200001440000000000012655404667015374 5ustar liggesuserssurveillance/inst/extdata/neighbourhood_BYBW.txt0000644000176200001440000012031011736057020021573 0ustar liggesusers"8336" "8337" "8315" "8311" "9262" "9172" "9163" "9776" "9763" "8435" "8335" "8327" "8326" "8316" "8325" "9275" "9189" "9171" "9187" "9182" "9173" "9175" "9764" "8436" "9780" "9762" "9180" "9190" "9188" "9162" "9775" "8421" "8437" "8426" "8417" "8317" "8237" "8211" "9272" "9271" "9263" "9279" "9277" "9261" "9183" "9184" "9177" "9778" "9777" "9761" "9181" "9179" "9174" "9774" "8425" "8416" "8415" "8231" "8115" "8235" "8216" "8212" "9276" "9362" "9278" "9274" "9178" "9186" "9161" "9773" "9772" "9771" "9185" "8135" "8117" "8116" "8111" "8236" "8121" "8118" "8221" "8215" "9565" "9372" "9375" "9273" "9176" "9563" "9562" "9779" "9577" "9573" "9561" "8136" "8119" "8125" "8226" "8222" "9576" "9564" "9363" "9376" "9373" "9361" "9572" "9461" "9663" "9575" "9571" "8127" "8126" "8225" "9675" "9662" "9574" "9474" "9462" "9377" "9374" "9371" "9471" "9463" "9679" "8128" "9676" "9661" "9678" "9479" "9472" "9464" "9478" "9477" "9674" "9473" "9677" "9671" "9673" "9672" "9475" "9476" "8336" 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8337" 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8315" 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8311" 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9262" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9172" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9163" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9776" 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9763" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8435" 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8335" 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8327" 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8326" 0 1 1 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8316" 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8325" 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9275" 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9189" 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9171" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9187" 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9182" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9173" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9175" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9764" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8436" 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9780" 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9762" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9180" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9190" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9188" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9162" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9775" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8421" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8437" 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8426" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8417" 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8317" 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8237" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8211" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9272" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9271" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9263" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9279" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9277" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9261" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9183" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9184" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9177" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9778" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9777" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9761" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9181" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9179" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9174" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9774" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8425" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8416" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8415" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8231" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8115" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8235" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8216" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8212" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9276" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9362" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9278" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9274" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9178" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9186" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9161" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9773" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9772" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9771" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9185" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8135" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8117" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8116" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8111" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8236" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8121" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8118" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8221" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8215" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9565" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9372" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9375" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9273" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9176" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9563" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9562" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9779" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9577" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9573" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9561" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8136" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8119" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8125" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8226" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8222" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9576" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9564" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9363" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9376" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9373" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9361" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9572" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9461" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9663" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9575" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9571" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8127" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8126" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "8225" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "9675" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "9662" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "9574" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 "9474" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 "9462" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 "9377" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 "9374" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 "9371" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 "9471" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 0 0 0 0 "9463" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 "9679" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 "8128" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 "9676" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 "9661" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 "9678" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 "9479" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 "9472" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 1 0 "9464" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 "9478" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 1 "9477" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 "9674" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 "9473" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 "9677" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 "9671" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 "9673" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 "9672" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 "9475" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 1 "9476" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 0 surveillance/inst/extdata/counts_flu_BYBW.txt0000644000176200001440000035307012655404667021151 0ustar liggesusers"8336" "8337" "8315" "8311" "9262" "9172" "9163" "9776" "9763" "8435" "8335" "8327" "8326" "8316" "8325" "9275" "9189" "9171" "9187" "9182" "9173" "9175" "9764" "8436" "9780" "9762" "9180" "9190" "9188" "9162" "9775" "8421" "8437" "8426" "8417" "8317" "8237" "8211" "9272" "9271" "9263" "9279" "9277" "9261" "9183" "9184" "9177" "9778" "9777" "9761" "9181" "9179" "9174" "9774" "8425" "8416" "8415" "8231" "8115" "8235" "8216" "8212" "9276" "9362" "9278" "9274" "9178" "9186" "9161" "9773" "9772" "9771" "9185" "8135" "8117" "8116" "8111" "8236" "8121" "8118" "8221" "8215" "9565" "9372" "9375" "9273" "9176" "9563" "9562" "9779" "9577" "9573" "9561" "8136" "8119" "8125" "8226" "8222" "9576" "9564" "9363" "9376" "9373" "9361" "9572" "9461" "9663" "9575" "9571" "8127" "8126" "8225" "9675" "9662" "9574" "9474" "9462" "9377" "9374" "9371" "9471" "9463" "9679" "8128" "9676" "9661" "9678" "9479" "9472" "9464" "9478" "9477" "9674" "9473" "9677" "9671" "9673" "9672" "9475" "9476" "1" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "2" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "3" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "4" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 6 0 2 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 3 0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 3 2 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "5" 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 1 5 0 0 0 0 4 0 4 0 1 0 6 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 12 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 2 0 4 4 0 0 2 0 3 0 0 0 0 0 0 0 3 0 0 0 0 6 0 0 1 0 3 0 0 0 0 0 0 0 0 1 2 2 8 0 0 0 0 0 0 8 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "6" 0 0 1 6 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 3 0 0 0 0 10 0 6 0 5 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 6 0 4 0 1 0 0 5 0 0 0 0 0 0 1 0 0 0 0 1 2 4 8 0 0 3 0 3 0 0 0 0 0 1 0 1 0 0 0 0 7 1 0 0 0 5 0 0 0 0 0 0 0 0 0 11 1 0 0 0 0 0 0 0 4 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "7" 0 0 1 1 0 0 0 0 0 0 0 4 0 3 0 0 0 0 1 2 1 6 0 3 0 0 0 0 0 6 0 3 0 0 0 2 0 0 0 0 1 0 0 0 2 7 0 0 0 0 0 0 0 0 2 0 3 0 1 0 0 9 0 0 0 0 0 0 0 1 0 1 1 2 1 0 9 0 0 3 0 0 0 2 0 0 0 0 0 2 0 0 0 0 3 3 0 0 0 7 1 0 0 0 0 0 0 0 0 6 1 0 0 3 0 1 0 2 11 0 0 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "8" 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 11 1 1 0 6 0 0 1 0 0 0 0 3 0 3 0 3 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 3 0 6 0 0 0 0 2 0 0 0 0 0 0 1 1 0 0 1 0 3 1 6 0 0 1 0 1 0 0 0 0 1 0 1 4 0 0 0 0 2 2 0 0 0 1 0 8 0 0 0 0 0 0 0 4 1 0 1 0 0 1 0 0 8 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "9" 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 4 0 0 2 0 0 0 0 0 0 0 6 0 0 0 1 0 1 0 0 0 3 0 1 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 2 0 0 1 0 0 3 0 0 4 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 3 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 "10" 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 2 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 3 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "11" 0 0 2 1 0 0 0 0 0 0 0 4 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 4 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 2 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 "12" 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 3 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "13" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 "14" 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 "15" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "16" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 "17" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "18" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "19" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "20" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "21" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "22" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "23" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "24" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "25" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "26" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "27" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "28" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "29" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "30" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "31" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "32" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "33" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "34" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "35" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "36" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "37" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "38" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "39" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "40" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "41" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "42" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "43" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "44" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "45" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "46" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "47" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "48" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "49" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "50" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "51" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "52" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "53" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "54" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "55" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "56" 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 1 0 2 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "57" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 6 4 0 0 0 0 0 0 0 0 0 0 0 1 1 0 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "58" 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 3 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 5 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 "59" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 3 3 0 1 0 2 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 5 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 1 1 0 0 0 0 0 0 0 0 5 3 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 "60" 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 0 10 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 1 0 0 1 1 0 1 0 3 1 0 0 0 3 0 0 0 0 0 0 0 1 0 1 6 0 0 1 0 2 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 3 1 6 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 "61" 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 7 0 1 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 0 5 0 3 0 1 1 1 0 0 2 0 0 4 0 0 0 0 1 0 1 6 0 0 1 0 0 0 4 0 0 0 0 1 0 0 0 0 0 1 2 2 0 1 5 1 3 0 0 2 0 0 0 0 8 1 0 1 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 "62" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 2 0 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 2 7 0 0 2 0 1 0 1 0 0 0 0 2 0 0 0 0 0 0 3 0 2 0 2 1 5 0 0 0 0 0 0 0 3 1 0 1 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 2 0 3 "63" 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 7 0 4 0 5 0 5 1 0 0 0 5 0 0 0 0 0 0 0 0 0 1 7 0 0 3 0 3 0 3 0 0 0 0 0 2 0 0 0 0 0 5 2 0 0 11 4 0 4 0 0 0 0 1 1 12 1 0 0 0 0 0 0 0 7 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 5 0 0 "64" 0 0 1 2 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 4 3 1 0 0 0 0 0 0 0 0 1 2 4 0 2 0 0 0 0 0 1 2 0 0 1 0 0 0 0 0 1 0 8 0 0 4 0 2 0 2 0 0 0 0 3 0 0 0 0 0 2 1 1 0 0 6 1 0 0 0 1 4 0 0 0 4 1 0 1 0 1 1 0 3 14 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 10 "65" 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 6 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 10 3 0 0 0 0 0 0 0 0 11 0 0 0 0 0 1 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 0 4 "66" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 2 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 5 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 "67" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 4 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 "68" 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 2 0 0 0 0 1 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 3 "69" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 "70" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "71" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 "72" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "73" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 "74" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "75" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "76" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "77" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "78" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "79" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "80" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "81" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "82" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "83" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "84" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "85" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "86" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "87" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "88" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "89" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "90" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "91" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "92" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "93" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "94" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "95" 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "96" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "97" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "98" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "99" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "100" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "101" 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "102" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "103" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "104" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "105" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "106" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "107" 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 4 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "108" 0 1 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 0 0 0 5 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "109" 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 29 3 0 0 4 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 1 0 0 0 0 2 6 0 0 0 0 3 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 2 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 "110" 0 0 1 5 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 9 0 0 0 4 0 1 0 0 0 0 0 0 0 0 0 24 2 0 0 7 0 0 2 0 2 0 0 0 15 0 1 1 2 1 0 0 1 0 1 0 1 9 0 0 0 12 7 0 0 1 1 0 0 8 0 0 0 0 1 2 0 0 0 0 4 0 1 0 0 5 3 2 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "111" 0 0 0 2 0 0 0 0 0 0 0 9 0 2 0 0 0 0 0 4 0 1 0 2 0 0 2 0 0 19 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 14 0 0 0 3 0 0 2 0 3 0 2 0 3 0 3 1 3 1 1 1 0 0 4 0 2 7 0 0 0 8 16 0 0 13 0 0 0 12 1 0 0 2 0 1 0 0 0 0 2 1 3 0 1 5 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 1 "112" 0 0 5 1 0 0 0 0 0 1 1 10 1 0 3 0 0 5 2 11 0 5 0 2 0 0 0 0 0 26 0 0 1 1 1 1 1 0 0 0 0 0 0 0 2 45 2 0 0 11 0 0 6 0 5 4 1 0 7 0 9 21 3 6 2 0 0 0 5 0 6 6 0 0 1 22 51 0 0 12 1 1 0 30 2 0 0 1 3 1 0 0 0 1 5 14 1 0 0 9 6 10 0 0 0 0 1 15 1 0 1 0 5 2 0 0 0 4 13 0 0 0 9 0 0 0 5 0 0 0 0 1 0 0 0 0 0 3 0 0 "113" 1 0 11 3 0 1 0 0 0 6 0 9 0 2 2 0 4 5 2 8 0 10 0 0 0 0 1 0 0 37 0 2 0 1 0 0 0 0 0 0 0 0 0 0 2 47 2 0 0 11 1 1 3 0 11 7 5 0 8 0 16 0 1 7 5 3 0 1 5 0 3 10 0 0 4 21 57 0 0 7 1 0 0 14 6 0 1 0 0 4 0 1 0 3 4 8 5 2 0 16 18 13 0 0 0 0 3 0 0 0 0 0 2 5 0 1 0 2 9 2 1 0 14 0 0 0 2 0 0 0 0 3 0 0 1 1 1 0 0 3 "114" 0 2 7 9 0 1 0 0 0 8 2 10 0 4 0 0 0 1 0 6 0 7 0 2 0 0 2 0 0 32 0 0 0 2 0 2 0 0 0 0 0 0 0 0 4 23 0 1 0 8 0 3 4 0 4 2 5 0 26 0 4 2 1 9 2 1 0 0 0 1 1 6 0 0 1 12 12 1 0 3 0 0 2 15 16 0 0 1 1 1 0 4 0 0 13 4 3 0 0 12 20 9 1 0 1 0 1 20 4 0 0 0 2 14 0 7 0 9 34 1 4 3 7 0 0 0 0 1 0 0 0 3 1 1 2 0 2 3 0 0 "115" 0 0 1 6 0 2 0 0 0 0 0 4 0 0 0 0 1 1 0 4 1 3 0 0 0 0 2 0 0 30 0 4 0 0 0 0 0 0 0 0 0 0 0 0 4 10 2 0 0 0 1 1 0 0 3 0 1 0 12 1 2 0 1 8 1 1 0 12 2 1 1 6 0 0 0 3 15 0 0 3 0 0 1 6 2 0 1 0 3 0 0 0 0 1 0 1 0 0 0 4 7 12 1 0 0 1 1 3 2 1 0 0 0 2 4 3 0 5 8 1 4 2 4 1 0 0 0 3 1 0 0 5 0 1 0 0 2 0 0 25 "116" 0 0 0 4 0 0 1 0 0 1 0 0 1 5 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 6 0 4 0 0 0 2 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 1 1 0 3 0 0 0 4 6 2 1 0 0 0 0 0 2 0 0 0 3 0 0 1 6 7 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 4 0 0 0 1 5 3 1 0 0 1 0 4 2 0 0 0 0 1 0 0 0 3 4 2 3 0 5 0 0 0 1 0 0 0 1 10 0 1 0 1 0 0 0 0 "117" 0 0 7 5 0 1 0 0 0 2 0 0 0 1 0 0 3 3 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 3 2 0 1 0 0 0 2 0 0 0 4 0 0 0 1 3 0 0 4 0 0 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 7 2 0 1 0 0 0 3 0 0 0 0 0 1 1 0 0 0 4 0 1 1 0 0 0 0 0 0 0 0 0 2 0 1 2 0 0 0 0 3 "118" 0 2 2 2 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 0 0 1 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 7 2 0 0 1 3 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 10 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 3 0 0 0 0 0 "119" 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 2 0 0 5 0 3 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 "120" 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 "121" 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "122" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "123" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "124" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "125" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "126" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "127" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "128" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "129" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "130" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "131" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "132" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "133" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "134" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "135" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "136" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "137" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "138" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "139" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "140" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "141" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "142" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "143" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "144" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "145" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "146" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "147" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "148" 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "149" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "150" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "151" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "152" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "153" 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 3 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "154" 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 1 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 "155" 1 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 "156" 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "157" 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "158" 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 "159" 3 3 5 2 0 0 0 0 0 1 1 1 0 3 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 1 0 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 7 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 "160" 1 0 5 10 0 0 0 0 0 1 0 1 0 2 0 0 1 2 3 1 0 0 0 0 0 0 2 0 0 4 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 2 1 0 0 4 0 0 2 0 0 2 0 3 7 0 3 0 0 0 1 1 0 0 1 0 0 2 0 0 1 0 2 0 0 3 0 1 0 2 0 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 2 3 0 0 0 0 0 2 0 4 0 0 1 0 0 0 0 0 0 0 1 0 4 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 "161" 0 0 0 1 0 0 0 0 0 2 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 6 0 0 0 2 0 2 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 3 0 1 1 1 0 1 0 1 2 1 0 0 1 0 5 0 0 0 1 0 0 1 1 3 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 0 0 0 1 0 1 0 3 0 0 2 0 0 0 0 0 0 1 2 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 "162" 1 0 1 0 0 0 0 0 0 1 1 4 2 2 0 0 2 2 1 0 0 0 0 1 0 0 0 1 0 10 0 2 0 1 0 1 0 1 0 0 0 0 0 0 2 3 0 0 0 1 0 0 1 0 2 1 1 0 4 0 1 4 0 0 0 0 0 1 2 0 0 0 0 0 1 3 3 0 0 3 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 2 3 0 0 1 0 0 5 2 1 0 0 3 1 0 0 0 1 1 0 1 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "163" 1 0 0 2 0 0 0 0 0 1 1 1 0 0 0 0 0 4 0 0 0 1 0 1 2 0 0 0 0 8 0 1 0 0 0 6 0 0 0 0 0 0 0 0 1 4 1 0 0 1 0 0 5 1 0 3 0 0 5 0 0 0 1 0 0 1 0 11 0 0 0 0 0 2 3 4 9 0 0 2 0 2 0 2 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 3 0 0 0 1 0 1 9 6 0 0 10 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 "164" 0 0 0 2 0 0 2 0 0 3 1 0 0 0 0 0 2 0 2 0 0 2 0 1 0 0 0 0 0 7 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 4 0 0 0 1 0 0 0 0 0 0 0 0 4 1 0 4 0 0 0 1 0 12 1 0 0 1 0 0 2 2 4 0 0 5 0 0 0 2 0 0 0 0 0 0 0 0 4 0 1 2 0 0 0 0 0 1 0 0 0 1 0 1 0 2 0 0 4 0 0 1 0 0 0 0 5 1 0 0 1 0 0 0 0 0 3 5 0 1 0 1 1 0 0 0 "165" 0 1 1 5 0 1 0 0 0 2 2 6 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 3 0 1 0 2 0 4 0 0 0 0 0 0 0 5 0 2 0 1 0 1 0 0 2 0 0 0 0 0 3 0 0 0 0 1 0 3 0 3 1 0 1 0 0 0 0 0 3 0 0 2 0 0 0 2 1 0 0 0 0 0 0 0 1 0 2 0 0 0 0 2 0 0 0 0 0 1 0 0 2 2 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 6 0 0 0 0 0 0 0 0 "166" 1 0 1 1 0 0 0 0 0 1 2 2 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 2 0 0 0 1 0 2 0 0 0 1 0 0 0 1 0 5 0 0 0 0 0 1 0 0 0 0 2 0 4 0 0 1 1 0 0 1 0 8 0 0 1 1 2 0 3 1 7 0 0 1 0 0 0 0 1 0 0 0 0 2 0 0 2 0 0 0 1 0 0 0 0 2 0 0 0 0 0 0 6 1 1 0 1 0 1 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 "167" 1 0 5 3 0 0 0 0 0 2 0 5 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 4 0 0 0 3 0 3 0 0 0 2 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 5 0 1 2 1 0 0 0 0 0 0 0 2 0 2 0 0 1 1 0 0 2 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 1 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "168" 0 2 2 2 0 0 0 0 0 0 0 10 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 2 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 1 0 0 0 4 0 0 1 0 0 0 0 0 0 0 0 3 0 0 0 0 0 4 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 "169" 0 0 0 2 0 0 0 0 0 1 0 3 0 1 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 0 0 0 3 0 0 0 3 0 0 0 0 0 0 0 0 4 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 2 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 "170" 0 0 0 1 0 0 0 0 0 0 0 4 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "171" 0 0 0 2 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 "172" 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "173" 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "174" 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "175" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "176" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "177" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "178" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "179" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "180" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "181" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "182" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "183" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "184" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "185" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "186" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "187" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "188" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "189" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "190" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "191" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "192" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "193" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "194" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "195" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "196" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "197" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "198" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "199" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "200" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "201" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "202" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "203" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "204" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "205" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "206" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "207" 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "208" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 5 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "209" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 3 0 1 6 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "210" 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 2 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 "211" 2 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 1 0 0 1 0 3 0 0 0 0 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 3 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "212" 1 0 0 1 0 0 0 1 0 0 0 2 0 0 0 0 3 0 0 1 0 0 0 2 0 0 0 0 3 14 0 0 0 0 0 0 2 0 0 1 0 0 0 0 0 7 0 0 0 2 0 0 0 0 0 4 0 0 3 3 0 0 0 1 1 0 3 0 1 0 2 1 1 0 0 4 8 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 3 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 "213" 1 0 0 6 0 0 0 0 0 3 0 2 0 0 0 0 0 2 2 4 0 3 0 2 0 0 0 4 5 12 0 2 0 2 2 1 1 0 0 5 0 0 0 5 0 6 1 0 0 3 0 0 1 0 3 13 1 0 15 0 3 4 0 0 1 3 1 0 1 0 0 2 1 0 2 10 15 0 0 10 0 3 0 0 0 0 1 0 0 0 0 0 0 0 1 2 0 0 0 1 1 1 0 1 0 2 0 0 0 9 4 0 0 0 0 0 0 0 3 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "214" 9 2 1 1 0 1 0 0 0 4 2 5 0 1 0 0 3 1 2 2 0 1 0 3 0 0 0 5 7 26 0 1 2 0 1 4 6 0 0 11 0 1 0 1 1 10 2 0 0 1 2 0 0 0 0 10 1 0 27 9 1 2 0 0 2 1 5 4 2 0 1 4 0 1 0 12 24 0 0 6 0 4 0 0 3 0 0 2 1 0 0 1 0 5 2 1 1 0 0 1 3 1 0 0 1 0 1 1 0 9 3 0 0 0 0 0 0 0 1 0 2 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 "215" 10 0 4 4 0 0 0 0 0 4 4 11 0 0 4 0 7 0 3 0 0 2 0 1 0 0 0 3 0 16 0 0 0 1 4 4 7 0 0 14 1 3 0 5 1 1 5 0 0 2 0 1 0 0 0 20 5 1 38 1 5 3 3 0 3 5 4 1 0 1 0 0 0 1 9 8 32 0 0 21 1 1 0 0 2 0 3 1 0 0 4 1 2 7 4 0 3 0 0 4 2 4 1 0 0 0 0 1 0 4 1 0 1 0 0 0 1 0 5 1 10 0 3 1 0 1 0 0 1 0 0 0 1 1 1 0 1 0 0 0 "216" 5 1 8 9 1 3 1 0 0 4 3 5 0 0 6 0 8 2 15 1 0 8 0 1 0 0 0 7 6 38 1 0 1 2 0 7 2 0 0 4 0 3 0 4 2 20 7 0 0 8 1 3 0 0 4 8 11 0 19 0 5 2 6 7 2 6 9 2 1 0 3 7 1 1 19 10 33 2 1 21 2 1 0 2 1 1 4 2 1 0 0 2 2 3 8 3 6 2 0 4 5 3 2 0 0 4 0 0 2 22 1 0 3 0 0 4 0 3 7 1 10 0 4 2 0 0 1 0 1 1 0 1 1 3 2 0 2 0 0 0 "217" 10 2 2 6 0 1 3 0 0 5 7 6 2 1 33 0 5 0 11 0 0 3 0 3 0 0 2 7 1 37 0 2 1 0 1 4 2 1 2 6 2 2 0 3 0 17 7 0 0 22 2 0 2 0 5 5 8 0 18 0 9 6 3 2 3 3 5 5 1 1 9 3 1 1 28 9 35 1 0 21 3 7 0 9 11 2 4 3 0 0 0 1 2 4 13 5 19 2 0 6 15 10 6 0 2 2 0 3 6 16 1 0 6 0 0 5 2 6 18 1 10 0 4 2 0 0 1 1 1 0 0 2 4 7 2 0 0 1 0 0 "218" 4 6 1 3 0 0 0 2 0 2 4 4 2 2 0 1 3 0 11 2 0 4 0 3 1 0 0 14 0 35 0 0 0 1 0 3 3 1 2 1 0 8 0 2 1 13 1 0 0 11 3 0 0 0 2 0 7 0 28 1 11 6 7 2 5 1 5 8 0 3 10 6 2 0 25 12 40 0 0 15 2 14 0 12 7 3 1 1 3 0 1 2 0 5 5 5 12 1 0 7 30 8 5 3 0 6 1 4 1 7 3 1 5 7 0 3 0 7 26 4 13 1 4 5 1 0 11 0 0 0 0 2 3 7 3 0 1 3 1 0 "219" 6 2 3 4 0 0 3 0 0 1 3 7 0 2 7 0 0 1 2 6 1 7 0 3 0 0 0 21 0 60 1 0 1 1 2 5 3 0 0 0 1 5 0 0 2 11 1 0 0 16 0 2 0 1 2 5 14 0 17 1 14 4 3 7 1 3 3 0 0 8 6 11 4 0 24 6 29 1 2 12 4 9 1 7 5 3 1 2 0 0 0 0 6 2 17 4 13 0 0 4 9 0 5 2 0 0 0 4 10 9 3 0 8 3 0 2 4 0 12 2 3 0 4 6 2 0 2 0 0 0 0 3 2 2 2 0 0 1 0 1 "220" 2 0 2 3 0 0 1 1 0 0 4 4 0 0 0 0 1 0 3 2 2 1 0 1 0 0 0 2 0 22 2 0 0 2 0 1 0 0 0 0 2 3 0 0 0 4 2 0 0 4 0 0 0 0 1 2 2 0 2 0 7 0 3 2 2 0 2 0 0 0 1 1 2 0 13 7 10 0 0 4 1 2 0 3 2 1 0 0 1 0 0 1 3 2 4 0 2 0 0 1 6 2 0 1 0 1 0 2 6 15 0 0 1 7 1 0 0 0 10 2 5 0 0 5 2 0 2 1 0 0 0 0 4 0 2 1 0 1 0 0 "221" 2 2 1 2 0 0 0 0 0 1 6 1 1 1 0 0 0 0 2 0 1 0 0 0 0 0 0 6 0 17 0 1 0 1 1 0 0 0 0 1 1 0 0 0 0 4 1 0 0 1 0 0 0 0 0 0 1 0 0 0 2 0 1 1 3 0 3 2 0 4 0 0 0 0 3 1 2 0 0 1 0 0 0 0 2 0 0 0 1 0 2 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 2 0 1 0 0 0 0 1 0 0 0 1 0 1 1 0 "222" 0 0 2 3 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 1 0 0 2 1 0 3 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 "223" 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "224" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 "225" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "226" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "227" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "228" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "229" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "230" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "231" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "232" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "233" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "234" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "235" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "236" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "237" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "238" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "239" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "240" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "241" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "242" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "243" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "244" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "245" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "246" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "247" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "248" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "249" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "250" 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "251" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "252" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "253" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 "254" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "255" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 "256" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 "257" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "258" 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "259" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "260" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "261" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "262" 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "263" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 "264" 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 "265" 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 "266" 0 0 0 0 0 0 0 0 0 1 0 6 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "267" 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 3 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "268" 4 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1 1 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 5 2 0 0 0 0 1 0 0 1 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 3 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 5 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "269" 2 0 1 0 0 0 0 0 0 0 2 0 0 2 0 1 0 2 0 0 0 2 0 0 0 0 0 0 2 9 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 0 3 0 0 3 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "270" 0 0 0 1 1 0 0 0 0 3 1 0 0 2 0 0 1 3 0 0 0 0 0 1 0 0 0 0 2 4 1 3 1 0 0 0 0 0 0 0 0 0 0 1 0 5 0 1 0 0 0 1 0 1 4 0 0 0 0 0 1 1 0 0 0 4 0 0 1 0 0 0 2 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 "271" 0 0 0 5 8 0 0 4 0 2 2 1 0 2 0 5 2 6 1 3 0 1 0 0 1 0 1 4 4 14 0 1 0 0 0 2 0 0 0 1 0 0 0 0 0 4 2 0 0 0 0 3 0 0 1 0 0 0 0 0 1 0 0 0 0 4 0 0 0 0 0 2 2 0 0 2 1 0 0 3 1 0 0 1 0 2 0 0 0 0 1 0 1 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 "272" 0 1 0 1 3 0 0 1 0 4 2 0 0 2 0 10 0 0 0 0 0 1 0 1 0 0 0 0 10 14 0 0 0 1 0 5 0 0 0 4 0 0 1 1 3 4 3 0 0 0 0 5 0 2 3 0 0 1 1 5 0 0 0 0 0 1 0 2 0 0 1 1 1 0 1 4 2 0 0 3 0 0 0 3 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 3 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 1 0 0 0 0 "273" 3 2 0 4 3 1 0 0 0 10 0 1 0 4 0 7 2 3 3 0 0 1 0 2 2 1 1 0 8 30 0 0 0 0 0 0 0 0 0 13 0 4 2 3 6 9 3 0 0 1 1 1 1 2 1 2 2 0 3 6 1 0 3 1 0 2 4 22 0 0 2 0 0 1 1 3 4 1 0 2 0 2 0 20 2 1 3 1 0 0 0 0 0 0 6 1 0 0 3 2 0 2 0 0 0 0 0 0 0 7 1 0 1 0 0 1 0 0 3 1 0 0 0 3 0 0 0 0 0 0 0 3 4 2 0 0 0 0 0 0 "274" 0 0 0 0 11 0 0 0 0 4 3 1 0 1 0 23 1 6 2 1 0 0 0 3 1 0 2 1 10 29 0 1 0 1 0 0 0 0 0 10 1 3 1 1 2 12 2 0 0 2 0 0 2 0 0 3 1 0 4 0 6 0 16 0 1 3 0 1 1 0 3 5 4 0 1 2 4 0 0 2 0 0 0 13 2 1 0 0 0 2 0 0 0 0 3 0 2 0 0 7 0 4 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 0 0 0 1 0 0 0 0 0 1 7 0 0 0 0 1 0 1 0 "275" 1 0 0 0 4 0 0 0 0 1 1 0 1 1 0 8 0 4 4 0 0 1 0 1 1 0 1 0 0 15 0 0 0 0 0 0 0 0 0 2 0 0 2 0 2 6 3 0 0 0 0 0 0 0 0 0 0 0 2 0 1 0 7 0 1 1 2 1 1 0 0 1 1 0 2 0 4 0 0 1 0 0 0 4 3 0 1 0 0 0 0 0 0 1 3 0 1 1 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 2 0 0 0 0 1 0 0 0 0 0 0 0 7 0 1 1 0 2 0 0 0 "276" 0 1 1 0 2 0 0 0 0 0 1 0 0 1 0 4 0 3 3 0 0 0 0 0 1 0 1 0 3 5 0 1 0 0 0 0 0 0 0 3 2 0 0 0 2 0 0 0 0 0 0 0 0 1 0 0 0 0 3 0 3 0 4 0 1 0 0 6 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 3 1 0 0 1 0 1 0 1 1 1 2 0 0 0 0 2 3 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 3 2 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 "277" 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 3 0 1 1 0 1 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "278" 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 3 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "279" 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "280" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 "281" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "282" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "283" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "284" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "285" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "286" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "287" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "288" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "289" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "290" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "291" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "292" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "293" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 "294" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "295" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "296" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "297" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "298" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "299" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "300" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "301" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "302" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "303" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "304" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "305" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "306" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "307" 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "308" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "309" 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "310" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "311" 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 "312" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "313" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "314" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 "315" 1 0 0 0 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 8 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 "316" 1 0 2 2 0 0 1 0 0 1 0 0 0 0 0 0 2 0 4 0 0 0 0 0 0 0 0 1 3 5 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 3 4 0 0 11 1 0 0 0 0 0 0 1 0 0 0 0 0 0 2 2 0 4 0 1 0 0 0 0 0 1 1 0 0 2 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 "317" 3 2 2 4 0 0 0 0 0 0 0 0 0 10 1 0 1 0 4 0 0 0 0 1 1 0 2 6 2 11 0 0 2 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 2 0 10 1 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 1 10 0 0 11 0 1 3 0 0 0 2 0 0 0 0 0 0 0 8 0 6 4 0 0 0 0 2 1 1 3 1 0 0 6 0 0 1 0 1 0 0 1 0 5 1 0 5 0 0 0 0 0 0 0 0 0 0 0 1 0 0 3 0 2 "318" 11 3 3 14 1 1 0 0 0 9 10 2 3 4 0 0 1 0 11 1 1 2 0 0 4 0 0 17 0 43 0 0 3 3 2 16 17 0 0 1 0 0 0 0 3 6 1 0 4 24 0 0 10 2 1 2 2 0 26 0 6 1 1 0 1 5 1 1 0 1 6 7 0 2 1 8 17 0 0 29 6 2 8 8 1 1 1 0 0 1 0 0 0 0 8 4 5 4 4 3 1 0 3 0 0 5 1 1 0 1 1 0 3 1 6 0 2 1 2 1 7 1 4 0 0 0 0 0 0 0 0 0 3 1 0 0 0 0 0 1 "319" 9 8 14 7 2 2 0 0 0 6 17 4 0 3 1 1 11 1 7 0 2 6 0 10 6 0 8 13 17 84 0 0 5 6 1 28 16 0 0 0 0 0 1 1 5 15 3 0 4 15 3 13 5 3 4 2 23 6 20 3 1 3 5 2 3 1 0 2 0 4 3 6 1 0 1 13 36 0 0 37 3 7 7 10 2 1 0 2 2 1 0 0 1 8 30 5 7 5 3 4 0 0 3 0 1 14 1 2 2 18 5 0 3 0 48 2 0 1 3 0 11 0 13 0 0 0 0 0 0 0 0 0 2 0 1 0 1 0 0 0 "320" 6 9 8 17 1 2 3 1 1 2 27 8 1 3 1 6 12 3 5 5 4 19 0 19 9 0 9 17 5 109 0 0 1 13 10 32 9 0 1 3 0 0 0 3 17 39 7 0 4 17 3 8 5 6 0 2 18 2 13 3 10 0 2 4 0 1 1 0 3 8 13 4 4 2 7 21 33 0 8 12 5 23 4 13 4 1 3 8 2 0 0 5 1 7 15 4 7 7 5 12 4 5 5 2 3 5 9 7 2 9 2 0 9 1 0 6 2 1 7 2 17 0 15 2 0 1 0 0 4 0 0 1 6 0 7 0 4 2 0 0 "321" 11 10 8 14 0 1 3 3 0 8 15 17 4 5 2 3 12 5 12 7 7 8 0 11 7 0 2 41 3 52 0 1 1 14 10 29 13 1 0 3 3 3 0 1 9 21 57 1 9 15 3 7 6 7 1 18 14 0 22 1 10 1 6 5 5 6 12 20 4 11 12 34 12 1 27 19 26 0 10 17 2 13 2 25 9 1 7 3 0 1 0 2 7 9 6 10 19 14 4 21 2 10 17 0 9 10 9 0 38 6 6 0 10 0 1 3 0 4 5 1 31 1 18 5 0 0 1 0 0 5 3 1 6 0 8 0 5 9 0 0 "322" 6 6 3 14 14 3 0 3 0 10 10 5 0 2 0 15 12 6 7 8 5 10 0 23 13 1 8 3 10 29 0 2 9 8 14 12 0 0 2 6 0 3 0 3 10 37 8 0 4 15 3 13 4 7 4 8 17 0 11 9 6 1 5 11 2 7 13 9 0 10 9 3 5 0 24 31 19 2 5 20 3 0 0 17 8 1 4 3 2 2 1 4 3 13 18 11 13 5 1 7 4 14 18 1 3 3 13 25 35 17 0 0 8 0 2 5 6 4 8 4 18 0 14 1 0 0 0 0 0 4 0 3 14 2 5 0 1 8 3 5 "323" 9 9 6 1 10 0 0 1 0 5 4 3 1 0 1 10 6 8 0 4 3 8 0 11 6 0 15 6 13 14 1 0 1 9 2 39 0 0 0 3 0 2 0 1 14 20 17 0 1 1 4 3 7 8 4 8 5 0 4 2 8 1 4 5 2 3 5 3 0 16 8 14 4 0 5 12 14 1 5 4 0 2 3 16 6 1 8 4 3 1 1 1 0 6 9 15 10 6 1 4 3 9 24 1 4 2 3 0 16 5 7 0 7 0 2 6 0 0 8 1 8 2 5 1 0 0 0 0 0 0 2 2 8 0 0 2 0 5 0 3 "324" 9 2 5 4 6 0 1 0 0 1 1 0 1 1 0 5 2 4 1 2 0 2 0 8 3 0 0 3 3 5 1 0 4 2 15 26 0 0 0 1 0 5 4 0 2 11 2 0 0 2 2 3 0 4 1 4 5 0 3 0 6 3 2 2 2 2 5 16 1 3 6 3 5 1 1 16 9 0 0 4 1 0 7 7 6 0 6 4 4 0 2 1 0 3 5 19 2 5 1 4 2 17 17 0 2 2 1 3 2 6 2 0 8 0 0 3 0 0 2 0 6 0 4 1 0 0 1 0 0 1 1 7 4 2 4 0 0 4 1 8 "325" 5 1 2 2 1 0 1 0 0 0 7 0 0 3 0 1 1 1 0 0 0 2 0 2 3 0 2 0 3 16 0 0 2 2 1 8 0 0 0 0 0 1 0 1 3 2 1 0 0 0 2 4 0 3 2 11 5 0 1 0 6 0 0 0 0 3 17 2 0 3 1 2 1 0 1 4 1 0 4 3 0 2 0 3 3 0 1 0 1 0 0 0 0 2 2 8 0 2 1 0 0 4 14 0 0 1 0 8 2 6 1 1 3 0 0 3 0 0 0 0 6 0 2 1 0 0 0 0 0 1 0 0 7 1 3 0 0 3 1 1 "326" 0 0 2 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 2 1 0 0 0 0 1 0 1 0 0 6 0 1 0 1 1 4 1 0 0 0 0 0 0 0 1 2 1 0 1 0 0 0 0 0 0 0 1 0 3 0 1 0 1 0 0 0 1 0 0 4 1 0 1 1 0 3 2 0 1 1 1 0 0 4 0 0 1 0 0 0 0 0 0 0 3 0 0 0 0 1 0 3 1 0 0 0 0 2 0 3 1 0 0 0 1 2 0 0 1 0 4 0 0 0 0 0 0 0 0 0 2 1 0 0 2 0 0 1 0 2 "327" 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 14 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 2 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 "328" 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 2 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 2 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "329" 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "330" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "331" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "332" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "333" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "334" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 "335" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "336" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "337" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "338" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "339" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "340" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "341" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "342" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "343" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "344" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "345" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "346" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "347" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "348" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "349" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "350" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "351" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "352" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "353" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "354" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "355" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "356" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "357" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 "358" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "359" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "360" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "361" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "362" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 1 0 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 "363" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 1 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 3 1 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "364" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 2 3 0 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "365" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 3 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 3 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "366" 2 0 0 1 0 0 1 0 0 2 0 3 0 0 0 0 0 0 2 0 1 1 0 0 0 1 0 2 0 2 0 0 1 0 6 1 0 0 0 0 0 0 0 0 2 4 7 0 0 1 0 2 0 0 0 0 1 0 2 1 1 0 0 1 0 1 0 4 0 0 0 0 2 0 1 6 6 0 0 1 0 0 0 6 0 0 1 0 2 0 0 0 1 0 3 2 0 0 0 4 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 "367" 3 2 0 0 1 0 0 0 0 1 0 2 0 1 0 9 0 1 2 2 2 2 0 0 1 1 0 1 3 47 0 0 1 1 4 2 4 0 0 0 2 1 2 1 1 9 4 0 0 2 1 14 0 0 0 1 1 0 13 2 12 0 3 1 4 1 4 3 0 2 0 3 12 0 1 15 13 0 0 3 0 2 1 19 1 0 0 1 1 0 0 0 1 0 0 4 0 3 0 3 0 2 0 2 0 0 0 0 2 1 3 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 8 0 0 2 0 0 "368" 5 8 0 2 6 3 1 4 0 4 4 0 0 0 0 28 7 6 12 5 1 4 0 1 1 1 0 7 9 58 0 0 0 1 3 5 1 0 0 9 0 4 5 3 4 7 34 0 1 6 1 27 0 1 0 9 11 0 22 15 5 2 7 1 2 2 6 6 2 2 3 12 21 0 1 17 27 0 0 19 0 3 3 22 1 0 0 1 1 0 0 0 1 2 7 8 1 6 0 7 0 4 4 1 1 1 1 2 6 0 2 0 1 0 0 2 1 0 0 4 5 0 1 0 0 0 0 0 2 0 0 2 0 1 1 1 0 2 0 2 "369" 10 2 0 2 6 1 3 5 0 7 8 5 0 0 0 13 5 1 14 8 4 4 0 4 2 1 4 7 7 76 0 0 2 0 2 5 1 1 0 10 2 4 10 7 2 21 40 1 0 2 0 28 2 1 4 8 7 0 16 9 6 1 8 0 3 8 13 17 4 11 4 23 31 0 4 29 23 1 1 11 0 1 3 28 2 0 0 4 0 2 0 2 4 4 12 5 0 7 1 9 1 10 11 0 0 0 1 0 8 7 1 1 5 0 0 1 1 0 2 0 6 0 0 0 2 0 0 0 0 0 0 1 0 1 3 0 0 2 0 1 "370" 6 8 5 4 1 1 0 1 0 6 5 6 0 0 0 4 11 4 19 5 6 5 0 3 0 5 0 9 8 28 1 0 2 2 2 4 1 1 1 5 0 0 2 6 10 25 7 0 3 3 1 12 1 2 0 2 6 1 28 11 11 0 3 0 4 3 5 11 1 8 3 8 6 2 0 20 48 1 4 6 2 2 1 8 2 0 0 1 0 5 1 2 1 8 12 15 6 4 1 2 9 7 1 2 0 1 0 0 9 7 1 0 2 0 2 2 0 1 2 2 2 0 2 0 0 0 0 0 0 0 1 10 3 1 1 0 1 2 1 3 "371" 16 9 8 10 4 0 0 3 0 6 10 4 0 0 2 5 1 4 9 6 8 6 0 1 4 0 2 6 4 69 0 3 1 3 10 9 3 0 0 2 0 0 1 4 6 10 9 0 4 3 0 4 4 0 4 2 5 0 24 14 11 2 8 0 13 3 5 0 1 3 3 12 10 1 19 12 35 1 5 8 0 1 0 9 4 0 0 8 0 0 4 5 1 9 11 12 5 3 1 7 6 2 7 2 2 3 0 0 11 8 4 0 0 0 6 0 0 0 6 3 9 0 0 0 0 0 0 0 0 0 0 0 8 2 0 0 5 3 0 0 "372" 14 7 5 2 4 1 10 2 0 4 6 5 3 0 15 9 7 0 17 9 2 6 0 11 4 1 0 3 13 46 0 1 2 1 8 3 1 0 1 7 0 0 2 4 4 6 10 0 3 2 0 11 0 0 4 3 2 0 13 9 2 2 6 0 5 9 8 10 2 9 1 1 7 0 17 10 31 3 5 18 1 2 0 5 2 0 0 2 5 2 3 4 2 3 17 7 3 3 10 11 1 3 10 1 0 6 0 1 7 6 2 0 11 3 4 1 0 1 4 1 12 1 6 0 0 0 0 1 2 1 0 1 1 1 3 0 3 2 0 0 "373" 16 7 10 7 6 0 1 2 0 1 2 3 2 2 8 11 2 1 19 3 1 9 0 7 6 1 3 5 10 93 1 2 0 5 6 3 1 1 2 13 1 1 1 3 7 31 5 1 2 3 1 6 1 7 3 11 0 1 15 14 3 12 4 2 6 11 13 6 0 3 0 6 12 3 20 17 37 3 1 13 3 5 0 5 4 0 4 5 2 3 4 4 2 4 13 12 19 0 4 4 1 15 8 0 4 5 1 2 10 2 1 0 1 0 5 11 0 2 1 2 20 3 2 1 0 0 1 0 0 0 0 3 3 1 4 0 3 6 0 1 "374" 12 1 3 2 10 0 0 0 0 2 2 4 0 1 1 5 2 2 4 7 4 4 0 6 1 1 1 1 5 42 0 6 1 1 18 1 1 0 0 13 2 6 0 2 4 18 6 0 5 2 3 2 0 5 1 6 2 0 9 1 1 1 3 0 4 3 8 11 3 10 0 3 3 0 2 3 8 4 2 9 1 2 1 6 5 0 0 5 0 0 1 3 1 1 9 10 6 3 3 4 9 5 20 0 2 2 2 2 7 8 1 0 2 0 4 3 0 3 4 3 11 2 1 0 0 0 0 1 6 1 2 6 4 1 5 0 3 10 0 0 "375" 2 2 2 2 6 0 3 1 0 0 2 1 0 1 0 2 0 3 1 3 3 4 0 5 0 1 3 0 4 31 0 9 1 0 2 8 1 1 5 8 0 0 1 2 6 14 8 0 1 0 0 2 0 0 2 5 2 0 8 2 6 0 5 1 3 4 0 1 0 2 1 0 1 2 16 19 16 1 6 9 4 0 0 5 0 0 3 1 0 0 0 0 0 1 14 4 3 1 1 1 4 14 5 0 0 5 2 4 4 4 1 0 3 0 5 0 6 4 3 3 13 0 5 0 1 0 0 0 1 0 0 1 1 0 3 0 0 1 2 1 "376" 6 1 7 7 1 0 2 0 0 1 2 2 1 1 0 2 1 2 0 1 0 2 0 2 2 0 3 1 4 21 0 1 1 2 3 2 0 0 4 1 0 1 3 0 1 8 8 0 0 1 0 0 0 0 1 2 1 0 2 0 3 2 1 2 1 0 2 9 0 0 0 1 1 0 4 5 7 0 0 5 2 2 0 3 0 0 0 1 0 1 0 0 0 0 4 1 2 2 1 4 5 2 1 0 0 0 1 0 1 5 1 0 1 0 0 1 0 1 1 0 4 0 3 0 1 0 0 0 0 1 0 1 0 0 4 0 0 1 0 0 "377" 4 0 1 3 2 0 0 0 0 1 1 1 0 0 0 0 0 1 2 2 1 0 0 0 1 0 1 0 1 4 0 0 0 2 0 0 0 0 1 2 0 0 0 0 2 1 3 0 0 0 1 1 0 0 0 2 0 0 0 0 0 0 0 0 0 1 1 3 0 1 0 0 0 0 2 9 4 0 3 1 2 1 0 2 0 0 1 0 0 1 0 0 0 0 3 0 0 0 0 1 0 0 4 0 0 0 0 0 1 2 1 0 0 0 1 0 0 0 0 1 6 0 0 0 6 0 1 0 0 0 2 0 1 0 2 0 0 1 0 0 "378" 3 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 2 0 2 0 0 0 0 1 0 0 1 1 0 5 1 1 0 2 0 1 0 0 1 0 0 0 1 0 0 1 3 0 0 0 0 1 0 0 0 3 0 0 0 0 0 1 0 0 0 1 2 3 1 0 0 0 1 1 3 3 2 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 0 0 0 2 0 2 1 0 0 1 0 0 1 2 0 0 2 0 0 0 0 1 0 1 6 0 2 0 0 0 1 1 0 0 0 2 1 0 0 0 0 6 0 0 "379" 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 4 1 0 0 0 0 0 0 0 0 3 0 0 0 1 0 3 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 5 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 2 0 0 0 1 1 0 "380" 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 2 0 0 0 1 0 1 5 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 5 0 0 1 0 0 0 0 0 2 0 2 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 "381" 1 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 "382" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "383" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "384" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "385" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "386" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "387" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "388" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "389" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "390" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "391" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "392" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "393" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "394" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "395" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "396" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "397" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "398" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "399" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "400" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 "401" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "402" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "403" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "404" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "405" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "406" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "407" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "408" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "409" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "410" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "411" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "412" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "413" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 35 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 3 0 0 0 0 0 2 2 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "414" 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 19 0 0 0 0 0 0 0 0 0 3 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 1 1 5 1 0 0 0 0 0 0 1 0 0 1 0 0 0 2 0 1 0 0 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 "415" 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 0 0 0 1 0 0 0 0 37 1 0 0 1 0 0 0 0 0 0 2 1 1 1 0 4 3 0 0 0 0 2 1 0 1 0 1 0 2 3 0 0 0 1 2 3 0 2 0 0 0 0 1 0 0 2 5 0 0 6 0 0 0 6 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "416" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 15 0 0 0 1 0 0 0 0 0 2 0 0 3 1 0 2 5 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 2 0 0 0 4 0 0 1 2 0 0 0 0 0 0 4 1 0 0 0 1 0 0 0 1 0 3 1 0 0 0 5 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 surveillance/inst/extdata/population_2001-12-31_BYBW.txt0000644000176200001440000001527511736057020022251 0ustar liggesusers"name" "id" "popFrac" "pop31.12.2001" "LK Loerrach" 8336 0.00955704642962118 219149 "LK Waldshut" 8337 0.00724420011321107 166114 "LK Breisgau Hochschwarzwald" 8315 0.0105990592491612 243043 "SK Freiburg i. Breisgau" 8311 0.0090836619332578 208294 "SK Passau" 9262 0.00220966550402911 50669 "LK Berchtesgadener Land" 9172 0.00438828082276013 100626 "SK Rosenheim" 9163 0.0025864978792549 59310 "LK Lindau" 9776 0.00339502377170787 77850 "SK Kempten" 9763 0.00268222141398706 61505 "LK Bodenseekreis" 8435 0.00876330426303345 200948 "LK Konstanz" 8335 0.0117248901250817 268859 "LK Tuttlingen" 8327 0.00583787093414831 133866 "LK Schwarzwald Baar Kreis" 8326 0.00921566883058548 211321 "LK Emmendingen" 8316 0.0066702513931154 152953 "LK Rottweil" 8325 0.00618217039050841 141761 "LK Passau" 9275 0.00817051610466703 187355 "LK Traunstein" 9189 0.0073625135299438 168827 "LK Altoetting" 9171 0.00475447240414782 109023 "LK Rosenheim" 9187 0.0104709772348066 240106 "LK Miesbach" 9182 0.0040435016584811 92720 "LK Bad Toelz Wolfratshausen" 9173 0.00512048954629225 117416 "LK Ebersberg" 9175 0.00525131897872801 120416 "SK Memmingen" 9764 0.00179240683418067 41101 "LK Ravensburg" 8436 0.0117995937310025 270572 "LK Oberallgaeu" 9780 0.00646798909056973 148315 "SK Kaufbeuren" 9762 0.00184234006756032 42246 "LK Garmisch Partenkirchen" 9180 0.00381184634344819 87408 "LK Weilheim Schongau" 9190 0.00560573591119647 128543 "LK Starnberg" 9188 0.00552047873105917 126588 "SK Muenchen" 9162 0.0535510160649821 1227958 "LK Neu Ulm" 9775 0.00702597661990823 161110 "SK Ulm" 8421 0.00516109028015815 118347 "LK Sigmaringen" 8437 0.00582936702103999 133671 "LK Biberach" 8426 0.00804810336571798 184548 "LK Zollernalbkreis" 8417 0.00842524100961945 193196 "LK Ortenaukreis" 8317 0.0179450446608073 411491 "LK Freudenstadt" 8237 0.0053065289992159 121682 "SK Baden Baden" 8211 0.00231498319713989 53084 "LK Freyung Grafenau" 9272 0.00360012071195633 82553 "LK Deggendorf" 9271 0.00508307232861562 116558 "SK Straubing" 9263 0.00193261237594099 44316 "LK Dingolfing Landau" 9279 0.0039779997226416 91218 "LK Rottal Inn" 9277 0.0051942337363752 119107 "SK Landshut" 9261 0.00259535067084972 59513 "LK Muehldorf a. Inn" 9183 0.00478543536982428 109733 "LK Muenchen" 9184 0.0130778408957106 299883 "LK Erding" 9177 0.005143733575455 117949 "LK Unterallgaeu" 9778 0.00588383567474408 134920 "LK Ostallgaeu" 9777 0.00577345924357911 132389 "SK Augsburg" 9761 0.0112441791805019 257836 "LK Landsberg a. Lech" 9181 0.00469280813165976 107609 "LK Fuerstenfeldbruck" 9179 0.00854181003391971 195869 "LK Dachau" 9174 0.00572793060109147 131345 "LK Guenzburg" 9774 0.00532536843748664 122114 "LK Alb Donau Kreis" 8425 0.0081550346218288 187000 "LK Tuebingen" 8416 0.00920419945034194 211058 "LK Reutlingen" 8415 0.012174856153039 279177 "SK Pforzheim" 8231 0.00514604489542803 118002 "LK Boeblingen" 8115 0.0160409967109481 367830 "LK Calw" 8235 0.00698258485815037 160115 "LK Rastatt" 8216 0.00978207305341068 224309 "SK Karlsruhe" 8212 0.0121923436871746 279578 "LK Regen" 9276 0.00360744716017273 82721 "SK Regensburg" 9362 0.00554708071565444 127198 "LK Straubing Bogen" 9278 0.00418806818132262 96035 "LK Landshut" 9274 0.0063017921015655 144504 "LK Freising" 9178 0.00677679016092892 155396 "LK Pfaffenhofen.a.d.Ilm" 9186 0.00493274931074694 113111 "SK Ingolstadt" 9161 0.005115910516157 117311 "LK Dillingen a. d. Donau" 9773 0.00411829248402355 94435 "LK Augsburg" 9772 0.0104025098318318 238536 "LK Aichach Friedberg" 9771 0.0054294650558947 124501 "LK Neuburg Schrobenhausen" 9185 0.00393465157069456 90224 "LK Heidenheim" 8135 0.00597694262082752 137055 "LK Goeppingen" 8117 0.0112361113655017 257651 "LK Esslingen" 8116 0.022037781795695 505340 "SK Stuttgart" 8111 0.0256055876378397 587152 "LK Enzkreis" 8236 0.00845476485153912 193873 "SK Heilbronn" 8121 0.00524028569659259 120163 "LK Ludwigsburg" 8118 0.0219457214850711 503229 "SK Heidelberg" 8221 0.00617118071818381 141509 "LK Karlsruhe" 8215 0.0184448567025227 422952 "SK Schwabach" 9565 0.00167976269285349 38518 "LK Cham" 9372 0.00573102689765911 131416 "LK Regensburg" 9375 0.00776668925654867 178095 "LK Kelheim" 9273 0.0048371129956364 110918 "LK Eichstaett" 9176 0.00527813901237734 121031 "SK Fuerth" 9563 0.00485189672150164 111257 "SK Erlangen" 9562 0.00444436303946426 101912 "LK Donau Ries" 9779 0.00568388469217143 130335 "LK Weissenburg Gunzenhausen" 9577 0.00415060735383518 95176 "LK Fuerth" 9573 0.00495102182147713 113530 "SK Ansbach" 9561 0.00176235967453126 40412 "LK Ostalbkreis" 8136 0.0137521357904845 315345 "LK Rems Murr Kreis" 8119 0.0180090638630791 412959 "LK Heilbronn" 8125 0.0141314539249266 324043 "LK Rhein Neckar Kreis" 8226 0.0230170837072875 527796 "SK Mannheim" 8222 0.0134486115072336 308385 "LK Roth" 9576 0.0054496127884898 124963 "SK Nuernberg" 9564 0.0214258053205714 491307 "SK Weiden i. d. OPf." 9363 0.00187831816148015 43071 "LK Schwandorf" 9376 0.00629594838691671 144370 "LK Neumarkt i. d. OPf." 9373 0.005552052234087 127312 "SK Amberg" 9361 0.00192829500467061 44217 "LK Erlangen Hoechstadt" 9572 0.00565841656265727 129751 "SK Bamberg" 9461 0.00302634643110391 69396 "SK Wuerzburg" 9663 0.00566556857163042 129915 "LK Neustadt/Aisch Bad Windsheim" 9575 0.00432417440086661 99156 "LK Ansbach" 9571 0.00800972673220349 183668 "LK Schwaebisch Hall" 8127 0.00815359549807201 186967 "LK Hohenlohekreis" 8126 0.00474998059363419 108920 "LK Neckar Odenwald Kreis" 8225 0.0065454401145717 150091 "LK Kitzingen" 9675 0.00388580858258521 89104 "SK Schweinfurt" 9662 0.00237970015638478 54568 "LK Nuernberger Land" 9574 0.00735666981529501 168693 "LK Forchheim" 9474 0.00492084383239529 112838 "SK Bayreuth" 9462 0.00324975949189337 74519 "LK Tirschenreuth" 9377 0.00348023734203436 79804 "LK Neustadt a. d. Waldnaab" 9374 0.0044064661138687 101043 "LK Amberg Sulzbach" 9371 0.00475708899279653 109083 "LK Bamberg" 9471 0.00624086919586125 143107 "SK Coburg" 9463 0.0018664126831285 42798 "LK Wuerzburg" 9679 0.00694752257025759 159311 "LK Main Tauber Kreis" 8128 0.00599669786512532 137508 "LK Miltenberg" 9676 0.00572897723655095 131369 "SK Aschaffenburg" 9661 0.00298121027691358 68361 "LK Schweinfurt" 9678 0.00509685302883219 116874 "LK Wunsiedel i. Fichtelgebirge" 9479 0.00371895744641881 85278 "LK Bayreuth" 9472 0.00476432822139131 109249 "SK Hof" 9464 0.00220901135686693 50654 "LK Lichtenfels" 9478 0.00309080173148393 70874 "LK Kulmbach" 9477 0.00343095825581689 78674 "LK Hassberge" 9674 0.00385563059350336 88412 "LK Coburg" 9473 0.0040207809470481 92199 "LK Main Spessart" 9677 0.00576547864820053 132206 "LK Aschaffenburg" 9671 0.00761326994211234 174577 "LK Rhoen Grabfeld" 9673 0.00378171196417716 86717 "LK Bad Kissingen" 9672 0.00477518706428348 109498 "LK Hof" 9475 0.00474230526693129 108744 "LK Kronach" 9476 0.00329070910424576 75458 surveillance/inst/extdata/salmonella.agona.txt0000644000176200001440000001046012003613027021324 0ustar liggesusersweek observed state 199001 1 0 199002 0 0 199003 5 0 199004 2 0 199005 1 0 199006 2 0 199007 0 0 199008 4 0 199009 0 0 199010 0 0 199011 0 0 199012 3 0 199013 1 0 199014 1 0 199015 0 0 199016 0 0 199017 2 0 199018 2 0 199019 0 0 199020 2 0 199021 6 0 199022 3 0 199023 2 0 199024 1 0 199025 2 0 199026 0 0 199027 1 0 199028 1 0 199029 3 0 199030 5 0 199031 3 0 199032 4 0 199033 3 0 199034 6 0 199035 5 0 199036 8 0 199037 6 0 199038 3 0 199039 6 0 199040 2 0 199041 5 0 199042 2 0 199043 1 0 199044 5 0 199045 7 0 199046 1 0 199047 10 0 199048 3 0 199049 4 0 199050 0 0 199051 0 0 199052 1 0 199101 6 0 199102 0 0 199103 2 0 199104 2 0 199105 0 0 199106 0 0 199107 2 0 199108 2 0 199109 0 0 199110 6 0 199111 7 0 199112 1 0 199113 0 0 199114 0 0 199115 0 0 199116 1 0 199117 1 0 199118 4 0 199119 3 0 199120 1 0 199121 3 0 199122 2 0 199123 6 0 199124 3 0 199125 4 0 199126 4 0 199127 8 0 199128 12 0 199129 9 0 199130 17 0 199131 16 0 199132 8 0 199133 6 0 199134 13 0 199135 4 0 199136 7 0 199137 10 0 199138 3 0 199139 11 0 199140 4 0 199141 6 0 199142 4 0 199143 7 0 199144 6 0 199145 2 0 199146 9 0 199147 2 0 199148 3 0 199149 4 0 199150 1 0 199151 2 0 199152 2 0 199201 0 0 199202 0 0 199203 1 0 199204 2 0 199205 2 0 199206 2 0 199207 5 0 199208 0 0 199209 0 0 199210 4 0 199211 2 0 199212 1 0 199213 3 0 199214 2 0 199215 0 0 199216 1 0 199217 1 0 199218 3 0 199219 0 0 199220 1 0 199221 3 0 199222 2 0 199223 3 0 199224 6 0 199225 2 0 199226 1 0 199227 3 0 199228 3 0 199229 2 0 199230 2 0 199231 2 0 199232 1 0 199233 3 0 199234 3 0 199235 2 0 199236 3 0 199237 0 0 199238 2 0 199239 4 0 199240 6 0 199241 7 0 199242 3 0 199243 1 0 199244 4 0 199245 1 0 199246 2 0 199247 5 0 199248 1 0 199249 3 0 199250 1 0 199251 0 0 199252 1 0 199301 3 0 199302 3 0 199303 0 0 199304 0 0 199305 1 0 199306 1 0 199307 0 0 199308 1 0 199309 4 0 199310 1 0 199311 1 0 199312 0 0 199313 0 0 199314 1 0 199315 1 0 199316 4 0 199317 1 0 199318 0 0 199319 1 0 199320 2 0 199321 1 0 199322 4 0 199323 3 0 199324 3 0 199325 0 0 199326 3 0 199327 5 0 199328 3 0 199329 3 0 199330 4 0 199331 3 0 199332 3 0 199333 3 0 199334 4 0 199335 5 0 199336 7 0 199337 6 0 199338 5 0 199339 3 0 199340 2 0 199341 1 0 199342 3 0 199343 2 0 199344 1 0 199345 2 0 199346 1 0 199347 1 0 199348 0 0 199349 0 0 199350 1 0 199351 1 0 199352 0 0 199401 1 0 199402 4 0 199403 3 0 199404 2 0 199405 0 0 199406 1 0 199407 0 0 199408 3 0 199409 1 0 199410 1 0 199411 4 0 199412 4 0 199413 0 0 199414 1 0 199415 4 0 199416 2 0 199417 0 0 199418 1 0 199419 1 0 199420 0 0 199421 1 0 199422 1 0 199423 2 0 199424 5 0 199425 4 0 199426 0 0 199427 2 0 199428 1 0 199429 1 0 199430 3 0 199431 6 0 199432 1 0 199433 7 0 199434 6 0 199435 2 0 199436 5 0 199437 7 0 199438 5 0 199439 4 0 199440 5 0 199441 6 0 199442 6 0 199443 1 0 199444 2 0 199445 2 0 199446 5 0 199447 4 0 199448 1 0 199449 6 0 199450 2 0 199451 5 0 199452 3 0 199501 4 0 199502 7 0 199503 6 0 199504 10 0 199505 2 0 199506 4 0 199507 0 0 199508 3 0 199509 0 0 199510 1 0 199511 3 0 199512 0 0 199513 1 0 199514 1 0 199515 0 0 199516 1 0 199517 0 0 199518 1 0 199519 0 0 199520 1 0 199521 2 0 199522 2 0 199523 4 0 199524 7 0 199525 6 0 199526 1 0 199527 4 0 199528 6 0 199529 4 0 199530 2 0 199531 4 0 199532 5 0 199533 5 0 199534 9 0 199535 8 0 199536 6 0 199537 3 0 199538 2 0 199539 3 0 199540 4 0 199541 3 0 199542 3 0 199543 4 0 199544 4 0 199545 2 0 199546 1 0 199547 2 0 199548 3 0 199549 2 0 199550 2 0 199551 0 0 199552 4 0 surveillance/inst/CITATION0000644000176200001440000000223114425016044015056 0ustar liggesusersbibentry( bibtype = "Article", header = "As a general software reference for the _monitoring_ functionality, please cite:", author = c(person("Ma\u00eblle", "Salmon"), person("Dirk", "Schumacher"), person("Michael", "H\u00f6hle")), title = "Monitoring Count Time Series in {R}: Aberration Detection in Public Health Surveillance", journal = "Journal of Statistical Software", year = "2016", volume = "70", number = "10", pages = "1--35", doi = "10.18637/jss.v070.i10" ) bibentry( bibtype = "Article", header = "As a general reference for the spatio-temporal _modeling_ frameworks, please cite:", author = c(person("Sebastian", "Meyer"), person("Leonhard", "Held"), person("Michael", "H\u00f6hle")), title = "Spatio-Temporal Analysis of Epidemic Phenomena Using the {R} Package {surveillance}", journal = "Journal of Statistical Software", year = "2017", volume = "77", number = "11", pages = "1--55", doi = "10.18637/jss.v077.i11" ) citFooter("References to the underlying methodological papers can be found via", "'surveillance:::REFERENCES' and on the help pages of the functions.") surveillance/inst/shapes/0000755000176200001440000000000014006036350015203 5ustar liggesuserssurveillance/inst/shapes/berlin.shp0000644000176200001440000001624412625315364017213 0ustar liggesusers' RZC 08Ae@`/ d=A^i(TAXZC 08Ar6n@@ d:An7KA(&p68Aoq:AZC 08AAtrE8AA%Q8AA at8A8{RAM/>8AjA8ApXAZڵ8A<Ae  8AdAO_E9AdA//9Ag_SA)Y9An7KA2Ī9Ats<A + :A3sjAj|e :A َA;4 =:A.|=A d:A5)AئW:AT6rJA-:AAl+9A7і@a5p9A9fADQ9A65AcZ}9AevxLA*/>U u9A\h#Aj9AXYGA'JA9A0rAd$8Ajf$g@d$8A[@SXJ8AGi7Z@z5 8A&7@`8A ))L@$8A~@o>z8Ar6n@@<8A\76@"78A&7@p?o8A}@gb8AvzM@^':PV8AFAEtA8A+d A&p68Aoq:A2Ī9Awx&'@ :A^{< Ao:AAYCJA :A+nEw@zye:A{EHb=@6LY:Awx&'@I:A6/Q@E0ƗGi:A:1@>dj:AQ@(04:A@72,A-:AAئW:AT6rJA d:A5)A;4 =:A.|=Aj|e :A َA + :A3sjA2Ī9Ats<A$f9AA)$+:AA :A^{< ASP:A13 Aٯb:Ar A4K%&^:AaAc՟:AaAF:A :t$A^Z:At%A%:AbQA WA:A25gA :Abh[AA 1:Ae5}|6Ao:AAYCJA0 - S8A8{RA78"9Aj5 `A# at8A8{RAf/uW8AlPA - S8AVULAVhza8AiAaIs8A*4A0ܽ8A(݊ A OƋ8A/` A呺Z8Ao A[aj8AV[AVk8A|2PAp됓8Al+xA2@8AwAir~k8A@hVAVhza8A*1/A˕58A[A>8Aj5 `AFɄN8AZIA`<9A}!y*`Af9A@hVA4J+-9A,3a LAA.(9A Q!A_d9AR0AEm%9AR0A78"9A\r e A%v9Aֈg Aّ[9AJl߶Y A켑'9AJl߶Y A1C$9Ao AeXU8Ar Ae  8AdA,Eh8A C.AZڵ8A<A8ApXAM/>8AjA at8A8{RAeXU8Ag_SA :A*ARUV|9A*A1#-9A;b( A 9AE Awo:9AEdϑ A* .9AR#-# A? :At Aw:A]*W AJgq:A k, A :A^{< A)$+:AA$f9AA2Ī9Ats<A)Y9An7KA//9Ag_SAO_E9AdAe  8AdAeXU8Ar A1C$9Ao A켑'9AJl߶Y Aّ[9AJl߶Y A%v9Aֈg A78"9A\r e AEm%9AR0ARUV|9A*A̸e9A13 A7sp:A9?fDA!*h:A9?fDA/%03|:A_{YA6LY:A~ Aʎ:A%zv# A7sp:Ay A=Ҝk:Ax A7sp:AO 4 AF:A$jg A6LY:A,< A$C_:A@%+ ASP:A13 A :A^{< AJgq:A k, Aw:A]*W A? :At A* .9AR#-# Awo:9AEdϑ A 9AE A1#-9A;b( ARUV|9A*A̸e9A%A]F9AX#pA.P7:A!~]A!T:A^j8CA,>U:AJA!*h:A9?fDA!*h:A9?fDAc՟:A|_A]*;An[ A$jD;A|_A0";AAs"Ao:AAYCJA 1:Ae5}|6A :Abh[AA WA:A25gA%:AbQA^Z:At%AF:A :t$Ac՟:AaA { ":A44> A5Y:A{2* AB[WU:An[ A:A=Y A;A ۇ$ A]SZ!;A%aNA 2;A߆ A*;Aޱ6tA {1 ;ARlmA\~53;A= UA3;A:#~>A]*;AmP:A3;A&SA$jD;A|_ASP:AaAH;AzŠ A4K%&^:AaAٯb:Ar ASP:A13 A$C_:A@%+ A6LY:A,< AF:A$jg A7sp:AO 4 A=Ҝk:Ax A7sp:Ay Aʎ:A%zv# AV:AzŠ A^:Awd A#PH:AF A'+;A AX ;AQ)R A]U;Aő AH;A@9 ATc5;A44> A::A"GTk A/e:A~"r AB[WU:An[ A5Y:A{2* A { ":A44> Ac՟:AaA4K%&^:AaA/e:Ae@`/ d=A"GTk A<3;A&SA]*;AmP:A3;A:#~>A\~53;A= UA {1 ;ARlmA*;Aޱ6tA 2;A߆ A]SZ!;A%aNA;A ۇ$ A:A=Y A/e:A~"r A::A"GTk ATc5;A44> AH;A@9 A#Sa[;A  A Hn;A <(A-h;A+?CAgu;AD~A/5;A^A'LA0-;A^]AA A <=AԮ~ŃA=(=AY(uAqM`LA*L+;A^z5r AC ;A1 iG AX;A9=FV[ A@;AH*( AQ|;ADC AFt;A(}A֋;A($:A]K;AAoq@A/5;A!`ZA1W5;AO #:Amf!;A/-e~GA_;A#pS(Amy;A.*IAA~>`Xg;A:AƆ;A!A1W5;Aj)/<A/5;AU JA]K;AXA/5;A_)QAgu;AA-h;AAHA Hn;AF-A#Sa[;AlG AH;A籑y A]U;A޺ AX ;AbzT A'+;A A+ܗ;A@ Ak:A(` A5cM ;A,䗟 wA齊?;As5AҤ/;AL#SAi-;A~ vaA*\ ;A``+A yb;At2xA910;A'iAi \O;ABtNAB `Y;A<7b&A h:AF A"7f;A^i(TA.mj:A,,Adr~:A"5Ag:A6@GA%r5:A7*A5!:AR{%A~ˢ:A߲>A̫;AwO41NA.J:ADtdA+I:AymmA柑 :A'A?م:A[wA%;A^i(TA_š;A'A⏣ ;A\% AHδ;AxqoqA  V;ASLA"7f;ATٱA|Hb;A=pAY{tF;A,^5VAuM6:;ADblAi \O;A?uKA910;AaA yb;A9>vA*\ ;AV8 Ai-;AMAAҤ/;Ar҅A齊?;ANeKmA5cM ;AX#G_rAk:AI L[ A+ܗ;A@ A'+;A A#PH:AF A^:Awd AV:AzŠ Aʎ:A%zv# A6LY:A~ A/%03|:A_{YA!*h:A9?fDAh:A\2AM00:Ag51A\J:A_ZA1Y6:AJʼnAN)I:AWS AjL:A#A4%[:A.xW(Amj:A,,A 0=8AR0A!*h:A@/A#&9AP)QA0^9Ahv[A1Y6:AJʼnA\J:A_ZAM00:Ag51Ah:A\2A8X:A{A!*h:A9?fDA,>U:AJA!T:A^j8CA.P7:A!~]A]F9AX#pA̸e9A%AEm%9AR0A_d9AR0AA.(9A Q!A4J+-9A,3a LAf9A@hVA`<9A}!y*`AHm a9A&ŁA=8A`5h>A5N9AkqAVH(d9AՀA~ab9ANKLvA?d-9A"5AVJ9A֟ApwE9A֟A<9A@/AP<9A@/A)}9A5ej!A49A2Ab@`9AfAX\9AlA:/v+9Aw8LA&9AP)QAsurveillance/inst/shapes/berlin.sbn0000644000176200001440000000037412625315364017200 0ustar liggesusers' p~ A80 CZ@eA=d /`AT(i^ ] hiv'sVx ` d׳ v$m Mr$V^@El\surveillance/inst/shapes/districtsD.RData0000644000176200001440000024410414006036350020241 0ustar liggesusers7zXZi"6!XĆ])TW"nRʟ#ߨaTYd{gdG/5BlP*NxQzVcʐ9A_Ҁ7;2 «k 0xj<{az“ ;o[h6x:ka9J,gDïѓwFi9x 8z gzW…V,$v[/Ԇ[\KW%5/;1zh<1^DvN $+SnrdЖ>Q`@Ӿ5tE$w3T궱5oU-R~+Tn*  tIOX&<<"QNek^ {Jpwqv]K1X`֎EHXJ~Q%onA(7kw9RU"%Ċ& oi})S~zHp/dbSǸ 9K wf-461ւaR$Bϖ|T/゛bC΍1) E܄on.O;Rߞֶn<.7V~u0DHis9g˪!\Ӛda>VbjQYRxyz) (rp,Ig :-z-8vex*O.rujoewK G=F-vtȑcJyZ#o"Aب-r=*UCSu~ MXn7 [ lMep.;36pk̨ `:CP8]mI4Rãr~Xòv]̑;G F_s(,iaN : CigHU3ˋ'qZoYrE0lsIfdy"T Bfcx7ȸɒW ¯m~$% Ȟ[ՌOv:K@wiQ ׉ӓZ1Wt.71ddIB |C2VSC(vȣNYؑ`"I_$c{04v_?RrCoQqܴ}qTs޽ "w?13>o>Φ sjCpF"K--<'Tʉ,]h!ar>J?h"s{G{:^q] ur`{gW_n$+EeFCzV Kot0wq#Kg5?T}R~e:Љޯ>\- ̗c6TLTo^Jb%;`iw;{;M]O!}ǐ2 !EKQ th^ D3蠵;YE/dOjYc%.J{ C誌/iKWedIci0]2Lt W":F m#6a cX۟^ATD5^V:owPMZtx*fMj#hHo@xJ=utow$eHť<^;IAp57'5gO:ܬv~j.LX֕Ã{J"(<9JzQ~ACaF= xOkd܏ambi'Zu$ ۾3~n40g:vXj u%|)ېPF:D[ٹ\te K:Ur *[&YJ(OVJ?}fc⹌ԟJUX!2`,!町1@vc.|`f ԅIp<V %";!|*{dnB+ŞUpk6@ΛL`}v]BV۾q)9 iRc #Jeۚz0 5K);h&]5R!!ߟ7m{^~UL|1lMS^pjؠylC`Q1ؼ+ud+Vzix471J~c >p,oaBɵd^#}| %Qrm&N;<o:KDwUbr[}[uBRi_QmOC17R,Fd76gG||Ϝn,̐}N"x7i/(;5G\C j./jpz-U7KT ,7b~a/0[ ru^1Db씇;iڅ(r+ BuKz#BHh\F)OO*]xW0궭dGTZ;s%cW퐾KԭQGNYgCA%Yc1 ?ǯ3 AM#V֊XV3؏'RKA ~#Ȯ)RzkB|1nf Wߨ0A1clمxSSV-_8P[kE]P+-@C1J ]I&Ͳi=S/MG24Efp&Z)՝G,a!x[sRkY(H씁8#j66xǜ4=\.[u^.Z8+r1Nnt=fx$RvfpjG#i=@qÜWb>>iX/RނpLI_nN {FenNDS{Q<1&'\g+Ss +*wgf9* #`C 51\O&@'󩓇\6e+!ޢ:/7QpT'|D<2wp!\z^Qj1iO )mb>j5aU10fgI!/bn0Sfcl.(mlG?J5FŕM:A |^o((J{:>? W_&k {`R ']̕jlfe:aқِ51Qpuk:Vcc; 1T6Na+z3 R; 3Utz?~"Q,iQyYYeo2Syhlk.ҫ?3y?ƝX4 yMu1ݽz #Z滒S-3`Oh,BJր(Mg@+4ƣqEHQ&#!OڟaC#CxQJesXkW- Wrr3u?hp^ %筭s4٫ղ\XYs$+Sy6}& *j \Ʉߩ_!nW(/޼.D9`(iF,.*>S/Jo)BܹYUf eW6ѕ6nb nQ@ E}+LV͵H:`e!G_c+~RnO!]{BZa Cmtϱ_xaٲ@~'!'}A&2!WxUAm0(:NNpl,ň,"v\e@־*ҰwԾeԻL5]Ԅymj{gR ^pKWP 35sɲp dIt|*f<7=_t,%OjSĨz@Gg0A1Pz P+ZSH>fOEͩɝA|,zUoi|щC隋@?izWvl >sLiUz)Cli_LzK}xY /Oht`ImZɪc QB'>z! V0O%b؀H`; 0H/]Ƈ"+4z8pHЅ9]Z'IVKg f%܇j!C v;x̄63-.^J4 xDl;ƒK/a(W͐EKN6i\"t^T"T//DcT3Um}02WZC!iq.yL ǣ9WIWxDY)zqwAw:#tx..o1JD@uqs[q~:t+^Jt#F8hCܰN\'&b2-o+@^,] 4g+{" X(щtOniuRc`=)Zxw+0}p=fg}(dbFzHғnL"M+QV>[畍ށoyo`bq4k;KPe'<;12nE!?.mVsӫs|8J^Y`Mx [[iy tF{}b?tݵE:30xk~t5<Բ90?#ML/D!+ x>Ec}dxP>ռӟ+sW6MkRXwNKuÄYn @Z{j KyYvt+X uȽ{lhB^}pa,b}[SY>7fah 9RQ; "[r1i5#m|¤ :6Ҧ# ~)[N.?,?htyݱPܰ*4BθTP l|pH JzzxmA^n3T6xzC[{LmKtFOaзHg\9ylɌ# #- SuuKSeȗWxɱa;u cRG7Z~䳤*`|wx&=5Ԕ1ʽj|}i{lOY(ɰkpH~}b{6H,<תLjHY!BAClvېZU d$Ul?pN1"߄m1C@<(Қ.5UTGs +;C+>ieœu@~PqôL 褤[NxǕ#?kSMe|q_( LEDw"GV};a#D.eƞ [Īs'vL5κyx^Ҁ!ad(]Vfaryyd9~ f~R_G %XM&4yBfz@dҌh8X^ {F`UpJ hV/ BOOChpU7D;uy7x)Ox$Bv|- @[!W|&J 8S,Ƴ^ aLּGA`y֔I؋A6d6*͉F@)"3; aɣKwX_Z]IC#n>S߄:aA\Y`jL Q3] `ޟW7h- y 3aEaLd-*C7RCPd7(ͬy( yfumժw9tFHZ-M~{PBW|5v A}Mc31/O e^ O_fm|^ CʼnL݄&&8fʎ =74ގgs_Nc׳Phay`evXE^XO1m)TyH$cC,"fM#= zo@l}V:s\C uӜЌxjV_'eTV &{6 P+s'&UU)}z˺HCpܱ5X|pPDĹj3JxRZhR5^KFokl9AcU1uFEn W=3t ( s%$+I㋢[7NǗ\9vQjcPST;5\]2"x/].b:M> P`)yh'=,3]ZC-H_cJT? L`G?Wْ 8ČLH9[| 쨈_Ll*սAt!x%U@aSr}NuQ7'~~\\A[F-b:KU&j"M1 Z\~ aOx% -i o|nVV*Żw|ܸP#Ȭ;0%GCV+{CW𮃌߀ڊʻAkUOClJhn'f;gK[U BU\{:2D1 Aؗ 1(s֚tb7!̉k/0 :r\Tė#c{C-v]LٗEx TI3'ǭ NY1`c2F"Y-);vMR(mѠ%IK5*P]rYIMD%Cz`rJ{W,vڀC[{) [<0/'܆N n6\keb;]tte=BzЍHzy^ o2G&GM>83P[j@$IH? ۾鴆AxZDM"pa_2AA{V1!"\Fx@>9nĨS7f8~zߪ1#aJK 3a9ϛ2握r:.߰>Hi=H13)}7Y 70:p6WD!w`;L'#[FDOܪmn:M^D'99FȣǍ_hy3 𓨜un DƧFxoW1kY* u{;Y;zV7ZAxcxCXC B|ׄ9P`mѡcv(ho_ESC=U(9-6 ~>┾]݇Z7N) qr׌Q E4Mf ,./78 qkL*ǏL=rL|1WrðtX!H=EO4u!/8'YL,gAHnT"鴜cQ ˤ"%ŵ"/ )m7W8ߗ׷P :R" %:'X,ck ďhAjոPEv2@G[?Sn\Q"ߎ[5;ڔJ9.m2OE3{̀?6S[ur&ZL=2m:@(a`6b*Dcmo+ ]l5AL4Z=WG7ZP<,'M|s(CuvIH4Q w>Q)DW3Oΰ>K"X.~a#i0A8Bv:H*d[\߶7VȁI6jWs쵄yN &:Nr86闐aR\n ]^+"zDFòz-6\} 7 Q,~GЈ+q *KudUv*Vh74J` rsRpΑ:RD-F2+kH83Yiշ7J7x$0x]Ru5߼Bfpz?F~8! rt}͓)X0%Zi r ǜC [ RoUMCD SB*:{'hujs:Z`n^ۛfpMb:K9g?"NGeĉA TW֑,PcO.m fjKLJ9mͧ>YUn jkɶJ4,#< !:Vp0adM4)u+h'dx|)K, ,~E W]'Q bxWn$LB/( :V<@l8yXi;@yX]DzHa /MR%$gHʌڣ!q9H:Zs"6$;co+s ȩkxIhax;t7~Lzr9ZGHӟlPc0i_Kz db$KӼ=p .$k;`2Ӟ Uz5`A& ! !&ʗ?.t7~~΍NxFIB@WW<2F@MڭBtnN҇gc8"G@S'Y;1plP_{/ U?H%$!A¬._H>8SՄ/16oFQl ե$D'Ձ0Tޒ xM`GJG6{P4/jIIxϑ'v(vץS`aϘ̈W{r5`G 49JI^ "?/& j9FD&B[ȅ[f%q;8奰[Ƥr.yð5U%x"*ȷѳ7ʾV=E-Q:8IT{'+$u%=2% L-; Q?m%=QOM ru+B-ֶH֕P&`#w ~k8-まϧ_vm>J#KS 4ČGkkJvZBI7֣`]8 ˙+=&&m: GJAJ:`ŰZW \rC/ɗ]~L==RRz;rf)GtiC˾ a?VW׳PM>sܲk3)ҧQBH^sekY(Uby!{Bzq[H?{zΚAWEruY+6'A/KBcU10({VOPHp3Ѡ 4< BVZ&6PfOY] 鐫96= 15$2x*u:9%۰@mI4n}k5yCnȪ這RP_t-ac*艗±B ôҥ >b$QW<6 gʒP91ăȱ\=k)7_U N8nx虭s_T`1$^ z4IM&W3湤iM _(TZN :w:udL{4}$G[dz}@G[Yu^4nQnPB"D#,{ P^]ZԏpS#!lqZ8kYRm>Ӧ"Խ&|c hL/l| ,v!r2Q<ֶhEGjl}X:)̸[܄~9%in&TK=P J1nAՀzr ; ;sĨ*?mM'5%M\7*fD@0B^Qn/AT+1t4IXyK1+C-\3$:v;Vr(߆K7$ݫ 䲸݊333Դxa"6şH{ Q o:a1c=pzЇ*:J8*}} h+(Jix5˰6 }#eSBv_ wm:_/~O_0VŨiۺ|DVp2mTw7l'%lm=fOOM=!<7"T#MpǨ|]H~:%vʃ7Ĝ }ݺ$)| gPv?W32b8i#.c$N)RF[7k+@l!_ 8@OX8~2}()c!u퐸4ܰ@9"׃L^֭чRg5tI,By Cf7oGQNx N ෩^ tjfVD>%X+eq &^iL[QݬyYTE=%%@ B I>^wvp@4~=BbaAg)'լ'b9btPƞ-̛uY@; Y:@^ksM$w0u*0Z^.\E\gE3&=iU5e/ܠwقr]iGBƾ))CZ q}ܘ3Dg& NtVχxZsilR8f<%J\ \u!VzP|1Fg)@,97  @hM)+on8 ,KJoq0 d`9h\{.*loD<`Ux-8l9Ɗy蒡鄧 C_[e"=p a`5D?546:'&L(K"EƔT/s=G RPf5elAɓev|ϯ">OvV m͐TL$=v{kntNOgR13c 9[ BzVc$ue uX8#^9L߇X nFm}v~xSp)2XgZ8{A~f | #qrjͭ񈳕 Q}Olg\kt)~tE5cIVS.ߜ="g/V>9BD\ [,=@74P<*(^M>b&P BP_ߜK2'q tIcDBjc[𵱘x#;ۛK`q-! /6J vzm&<`f*M} !%d2 O/]-.>O]ðE8(fXLPZ 2s{ZV,:漗^ZHЦL@N(,|WVujpL!ǬO}8}/E[l(F3ۄB1r($d$`/dOyjq -KCs_oQ{Zx8҇ 7N ڿ1cBmDwD[.jKw/'5da_zH(#J*<Ldߺ2NrLDrJ0k3{Zj#' 搢(d.ZzNuȍ+>XvGOz @OhSMᮚ9db ߈F F :EfG^j?eZ$]M\0VK"f ԑtj:΅ O u^BasOuҾ;{L`7}Q^C0, /я#a{TЊ NH%!4Z:)ӗqp snN?ND3\LWUTv3Mkڇ C\ݒ3dG Oˠ^=H҈ç2zf*2 Zt<\dNB_*1<x#fyqx8wjÝ|a^9c_p/_!ŏ7+42{,F1>C\4r #"4__qiTX[)0a[s,c.!*lia7fFcB` @7+Z!Tc1jbA&ݟVw)'.M\KSp7*-ۘ~-D3xn^Q֐d JTi.ZqZC?JYr_7ͣoD{VΓ/j1GGĩFhdI#7rYжǢë Ɠg'PV*\~.EUP@L}Jm#>D٩)ExC(x > 2XJ2&·7 rQSKA(r<5j&ޒMNLPE97i7@X͸mݨ_Dv2#j3 :lͨh<@_@܃v=[1̳D:UgX$_{M `. @Om5A|v+֯l&YATk%6=%É;-_J9!3?v[8!XۣfQ߅$ջ!sJTnU>&-zC Rh=؈~?SDI(x8؃o4Euv?8j8ȉ^=z_ ŰB]oAw@Ӓ+4:і IֱRH`e(K3uVԈV9.\ǹH!J#{@QѠ'BLN3Q`(*qxlg{<'غl10Uơ8d-eWb5R@l$wIQmcqQ֎>L3.NAmn v3 1{ c&Q\5spNoq wIŻZ[u$ߺ!"sU2厠JT4&Cw.#1zM⧣-_׷.WŦߔv–.g Eu3;^e*t.sЋi3me,$.Gǔ'ͅe@Bh{? zw޷Q J,,3CU$a8xT1A9<$/fƆ.djL_I(ƆZ!=pe<4U41` #lD?M| OK^O&n "x[&QU *sA!p vEI2ɡPKw\E.b$#sr%/$~ؑ&^w>Џ}D1+prX|sG-DBګL0m<D16f[a0BY~1(e p=ȭz_)}XmWN.3PB;#>bS!FwǟhީtC `$\6n&uQXFw0n)ճx5[( BpHLb&J>> aZ81}#["+4>jOU ,Pʳ*DR@%P/^-J7VX5O H+DiL9ksq%KK11KKj @{2nZbe`VbaN鿩D`ֿF}ÄYn$&&Jnf:hCqK7 t^<%A+o5b l`YnAFFpnp~QSv*ݩi[qߡ(h[_r,ws]r9 aܴs|V^YY lM|9ZPا~ਉRwkȉ? ,p6*l1k; p4{i7tW^A.4\(Gg;0(_'7-%s]?vOOڀ.BȔefĉ8v-M NGqQ]NoNyOnYyҖ&Ide_גL e/_[g7yIyii\`ƷH5JcY_>LSxsy5 H[X]z$/e^LH3U׺Bh.h#T~`!#0VSŰҤr!^)/:%Yd$Qi<$#O4FSw 5APdH~G$3Rv J%XO^ g2X*i 88kb#2{ڟ)Loi@n<߫\>K 3 0%O8 {]^x fb#Kro?"RXfY1ۅТp ,D^0B}!!s_q=CGT>*\EI.", GfDI+$3è Z% O-'8.,}Gjf= k׉`4 "/tA@4G? w]Z7yFЊ٥EhЮrI__ֳ祜= K7"`ӎ-1oo$wk(y X,8$CH=(^>rɉeG^F^XRX"!S\G`o9rBŨ<GZ"Vv់#$<;Hew8~ lq"˟ s$=B1flŝeburU8y5+M$bѫl@h}*yj@v+tuόX v/ N߀UzU4iv :R%U7N56l?Pw$Qp @hDVRȅ&SPސ>>kex!j.생<~@>F59=x7zyxxޖn!b8> W \mе,Wu5ޤH#dGqD,E&л;ᵪ̇ʬ-#ȒX>[_N"Lм q3,6=m)"ٻ- ~3^=B[lcE5d/1 (;>oFH35 $ݒNs@"_ExT7?Lͨ߼_'1{M~ov#4gϨa[F$+N o{h@zmNhP̡6Ѝ 'I.}BjA姌Eq?H[^o(Y f!;:{ۺpĕڰfo]APcE˯ ;w[5KpX07lEbv`AVKB/xj曭0̔4-Tod[%M =el.J%R8W^9~e$uz,p9nF7hm(DӸ!y;}'z@ޡ EH#f_6(P(>KjQ~Ɉֈf=iH 3I( P4{A85zY= *cԉ+]-ŸLf~L+_=Iм,^MK/po Є LK}LoO[, ]7U?+ 54H,I;2 Y;?ۈ}׭(7ruE3s+SFUqȵ a3iHUT}[n"0^~G ^5Z8 6[r.'JscÈ&\7[m0isޒnQ38BvPaJ{Bp~!Ɛ?nU~a1-%3:aPΞO-tN#prʨ4`*Q:3ץG;sg,D9%"7S1288p5-shro91U;S<R];GW@lX+v!%|n1M-|!iP(MbR fb}K{_洬pWc❍rK<۟;xfGH~]=?ך)*~b~%@SK!3ﴞD4'TZ@a v̬k~mWz[hzc&Hٺ ;:|dg &I('(>=:!O4*޴뒓(xPZ^3 #}8!#9X=>1|{=.WzӐk(NT$x|CoJː.YZl +U&gK9bҞbgnUY&$7\^ B4θ z}NPd6#1h`,p~Q؏OZw%@]o{ۢ@=[Z8@dž 00~ Ij[+5vW"?1W׼A@ &fz"_̗7\gUG`{M/Օj#u5gr s|tt+PS$!mEvvgrԍ~Cq[+E'h9"vJ̚a|/ ,#BǝXy+c Fgy?%b^V!Zx̙< Ǚ!LAmy#Fr\ز? MoLvv`7bPBt'_W][Bʴ\z #P=ЧκNDmN=&O]ǁVaZ B<7>@]@Y3fW茼P3ظζSjiDtJ|;Y"{}4LA6! !8&b?PmXOfy@ qu2S jc13ғ=V3 Q(WM'x$9 S 7_^}0cu@~%|6(U( kI㘙IY:[|iCJUt\*føyBB$b<n#r~`7}-FcpdoN5(1V_2Apņ4~s FK ߹!r#.#.fزP*x)R;ȅU!+3aE鿌p-?.̌9 N]ۑ6Qi~U߀OUm7I-`ORUd9:g.w,p}^n*|mVci0Tŋ+мWJ4Dv,1tȆ_Pe{5.^3Wm!%MTGg] te/7t z}pd4;th9p[ʃr"`,r}%]t1 ;.HU mLXqrVΙﯫ`qr̓WRC;|:?'Kk=n@ ٯ z'xoLݻI P7mĎ[hXRM/>a3Q(I+(4nQ@ic$rpۖ8[/}ŵ_0޴3.d4CgU vBrGl-jZQ޲AMx6""ZdӐW{H5n<m_gs=сT*qM7Cxko++#ryOͭѼ#mwce'j|^D"(["H n9Uި<)ֿLM_1cxDz7+ }e-`atGme* 'F+eFz3{C+1}?mvUc +6g-/CC(D -ݫG:9 ڜ:Q}Wj,ͅNrls Ig#Vza 09^PdPc;áv<;ij5UAk5%r;)>DڔJsOm.3m}餎ô!W5[\-m$qEg%⨃mlD.^+Y)'^WeruhD-NUqFd'#*V'T0?\2"'~* ]:R[D["oNI1YcTJ֖MC5Ļu'w}jrc_lQ+8 _; $qFhb2 $p]  aǐ<$J9F@1ew]5q:)`萼%h_W+یe!mr~,L{b މ] b%. M@7>8Un,W!>.u/?UM-p KЪgOȜ?a!jMSF|gR6^ß&SrYc>ABi]hW-iqji AlPF ;2aM<(y;`6Лӯu06H6֐ ;q hŤKŠj~]Q<ݰrq|X3cqO+Ր^U'}s,d])9G-XW\9淨6rYl 4SYnvof^s+gHp*7`078P O~˔HDɅ" =)+<96936PE ԍǫz;;oÌ:<@;`Fz lLιPu=\Ė.Q=mfv\o|v>{xk;\Y9Gu\i zB_8r0Y'Rj)F?f?iwHƅdtz`%XߞǍD#h:{apR̅hz>- $Yt#KɌ.ELhW;F;Lg(Rǁi0iة zJ QcCg1zɗڔ We ;|<8ĨGR1#'2 *6`A$(a&|‚rL5 W M /A= ߕ751#VТ qXvlᖅNЬr-z< #cwpܡcި7 ̲^]~K;,PvZ)-`.S,v"#>qKT^Lj=ٹUܷG#6gw.z}܉*)N|Kyݍr|?58#Q+]geGq߿mQP9Q]P]T@qc`^a*òcU=JF$OU8RHO"ڰ-,BFD.]c577*PIQ?%nxOgN*>)Tv!9J%l <Ÿ* MvmP虾JO䰙?Ri^Vp𽨜}QA2 h ?es|W1@"O<&2XrpTt(kEK #"KAE;{k> rER몆mV/NTt SeqRO]RMf`qvM"FSaQb*:{Ҡ+S:I*K¥DA='^QT"J,aOg \3Gi4ӡ;&O( c$ZU҅'.vyo."l}D+.GN{UBrľg1mr&˵)j,PfQgNP&|v=Y{;7L ֦(u ַ+Ϳ[@m;y`~+8/sRUgΐ4^Y_\ޖu 72wWΛUߊS)w˵բ?H@wH}9|(?Kw)9"Q(X9B+\[֌H_d%&M3dmN܂!lWv2W@/:ޙkc)C*ll>ϳK!H"oXNKGF.PKjp0X/`(q6+EeE|i>m98\q|L:O#̴Mss`~_lqkUF?q}4re©7&H$vXɷ%tgʟ@܂\:q: zG*prک êǍnN$Cʨ ir2*>a곌6Vʉ8wj݀D)ܯ!/[Жʻ.P~n L!yXš!0H":Q+DDE `:t.\/BG24fXOo-g (;̵*CိK,:G?P;.޷ag}_0!$+qn!Qj^+n\1ӷ>屨#({&!i̤L7a,,k~l[Zpzj1hEUyybh'??N.< Iii@g:3/+*` ˃nd=3sCxȗۂE>UGxxR̪. 遫PQ/E\q[aa76py|iǍ` F`I J`qD\KkndAٕ! &wIRc//9qN`EKP6?[:=>Ͽ%BmFi%\}+s(ʶ+ݥb81xڊDhbV(|P "kd~w ȜT7J$xG,em 0NF梡ia9*nʸ-우Rplut(:Q/| X<&|4WRq=كJCWCrcsM 9ٜR9w ݘ0pdXĶqW`k5%zb4@ nM@@Ҹ&40=ܪ> V4,! NqٺR.EJE8w. 膛]u2uBPMZSKY ;1 *@+CFD#d'uy%!91qE[|b%ob%-zވiq=CoKpN!=,[nLIGVb_Gtw@`#|?u Խ򘲞[Z;{%V\QJQeܨDH!yUSh@JݩheMeۑ,9@~Z4MCR-y|bZ_^Zb'5 VINl(n3,eNHx0߭~IPU50(%˜DKعeGG龹ܩ{O #c%Ch&Wj ZO{sgQWt&,)+_}YB۴N\hH_WnҢ*.Z"6gu:X$!υME6S ]7nΨRfC FwX h Ά,$Wl*!I+#|ȒV(861쓡j/.Xՠ1mf?TUŌ7r;*g Ub8-bmA{kg WoX<׍؂e(W=K`-oϤr8pX Jjjd"uیdW>\>էk3M4__T0&g%rڥktL>RNgmL$n)= rPGͫ'&ǣ*"tt-xFplzI'`fqRXD|,Od+3(FS-:Tg>Ͷ6@sb*G \patPm7lpWn#M0tO~:ܨ}(UIՃWd$aT_nH@(v_l&>?1 xVd'y;/RWXLR"pLhsr|wD lѴHO=sNA]?| vv/@(^MRʡSUI#$BÑxp/\|]";3(E>,=Iʴwŗ!?j@YM<\镆iqжm !Q|RųI`VN%EHszw(IWFϥħwХ SƦ:{gK@hUq&l 10?xi ^!73O~B?`I9IP0~Du_ (x6 @Je&b(]X'jőO[-;hy]\܍+Q]oP0wJ!؊d1}|ubEڐ"ݪ^G4xز_ IľW@Dd)HVu"a bpcHʇy/VlFgFFdk@Ma ]z?}Y:)n@T N؀Ik%nN}:QUϲ,>r%@F[m~G26E(tx=a=iD ͩ2 n{eXDu?f݄ Mԕ zkf!Oܖ;66Zh/CZ>Ja>XfEn6::p HeI:GR(xhA.FWGO.֛ԯ@fD< yKi2{{$n7PϐsF#(ѾEfF%|U]YarCGȢ?|5/:EN=G~I>R~Ij RH'ߓbr"N9},& |[q<_APˆXz`#fGQ&w]tvӲT.y w DἺ{za EkbVJ?IAg8`9Hj3qQzҦ9z,+QcMOV{w{0Z҈0#=j+_O |$,ߒ4gr֨G{LHM 6~*AZE8 b5ʑ)gM$Hh* %d!溝ټljs[Nv'Y[ boL ] .$DҀӜ5m|X:7kgaoFs[EIuN[^3(mFDlkH/'YC.ke8HxQ~"b[Y8mKpL+k 4 ^u@X,R>).Щ)h(xn m"5ij}>ó - ؞LK98eqP5ꆙ@zkF֗[zX@(IǞ MvLa +o^biZ1AF!*B"]3qj]4pϮ? "?Vьyt+M/qFKs/lkDCP9lD B~"ሴRofwمtpBc[טcYzo*i =醏?.Ώs>eym!0+Mn/H9 91MxtƲYBA\ªf4殓z%Ѭ)۶:WpIFҞ(pV~fէ9B~ WX%Cڰ7R9-{3mJ<%g濙7 qYYkk;jmMIo3a>;T/ ԗYMF>WRi}\wXqBh[鯭Sp c.V/#=)0 [ҿάm#k4 ժO|}Ŗr|m~Lű(wrKC1LY,fKBi*:Զ;OX |+ (?2dƣ{ܦlحIR|@,QVEFpj4] p/8{{hۦ|W2APw 49^qx\w(V0-"q¹qN?Me'w*Wm`FR+(ޘAD)yo},_Y0Qu*U1{ W(QRx$YǶm~9z}ѲSG ݵ9Ygw 9` e@<+²&AXP~M|/Qh? X-  ԐDxQdCu`Wٌ)zqyA'V(2e q1,HGL>D]inüX?Gix|~wfވH5d2 Ӆ HRd bqK=*f'v~uBfY+[IަϓmОCAL:o"Y= 2\͐:N^,$B(oƚ8Kiݑ<]<KEr.GX1u1a~ۼs*3s6eSfԜ.dnJ8㻕ud$I+ʈp5VAa5>- %߰x{Z={Sx[u]*Ob>u|9Ϊ}-wTD.}HS/xthWf*ͺ):.V9M0Y[i?0t2=(ŮgN˻23CZd4Ao󗀴q0:'ǬLw]pq5<_/pNJiGŗ1d _fj'!(w7$!)T?.\aUB{7€F{%HԴ%ޯJ_B@ T)j]D7t"l{DFOI-/8&`qokuw,IBQ&IeRn[ 6^ʤi7auS03BSb'JYU#>!&;P/JS >ИB^[j u 0T'oj͕e#΋FltL櫊mNJh+2a"gäNM^weGmIwTWzhr ʬޘs?9ν?Oe,B[۠mfeu?JSFϷ*ZX*ڽ/^+8%Peio]\n^KV\e`g \AEq_ǷIu*ye^v!Y*{]DGHB?c@oծ{ֻYXV18Ja bOMۂETҘ;s>(x_^ o=ذ 1Ւ&զEɺ|G/=;な\ta_O v^jJΎ(^3aT8@yc *`{˄V,2sJKS8SѠOP}UaXh;X0 8amT61$K**m:Rtr c(.!Ȇ}fD_#ƓeZJjĻBG[ ڌD.5=qqjpRhTW#`^ aS)Z%ϑ_  犖Jn)0Cq{T́5DM&-> ,`7_7#Vf0R1truTT)JX_^}=ؑ"^D=V[p 7OSpʮL#QuHrr4>Tǰx[;lB^!cyX/-R@ĤEGQS*Kg\_ ǵDԁ-an=C7kPIxk IKJ~eYw#s B@k͘܉s!8"WigetXVt 6+ aԆ?/Х㿦P–kŽWBc6EfbZRovideB;O7't\+H<>BUx/   f)1I~vkY/Jc|.$tNt(zh[2P@i͡8qQg^wV%F=6ݖԏ/l jۭDsJ 9@[u׭hyCAdž}{D -/7Sew.Zp|x&Ob"RC;qU[{b#m~>\@}iL<wŁ2nFy#k*Z6 TFb.!i XShMAC&ǼX+[2KZd۔Z MP1>ce;e#1Lpw>08Jrj^\EV*w^WN(71n7 ؋/TJYa@ N5&(15NZf2#o/'>\Gx_ΐg1t{f]Y{6Nɰޜ䊫)_(" 1ɉ&u>,#^0V)tE@6 p:@9X H1Tf0Q:k )kg`o{󺦎#m 0S~2}~cH睠e,GA#$Ǧ#*`73,愎?5 .dr^:u z 'B^K["e㚏- 6Wss@N(P@s5'3ṷJ:f޸_;|ёK`)tle6Ixy{S5֛F?/L:<1X[&dq[ɯǎν69!i'㶒!u;M"řR#αw̒zsN7hS4NvE0Ir)k7nG_g@QFP2ˮ/+9WBG]Zׁ ,I;n-xJ.m&_,]FÀ:pQ{[-/9c,h!PkYh9",'0Ѓ"BW, /3ލ'Ct0_g geJ> n#K ul%oh"qXQ/qʂ)٬+#D[x(I.JyI,w߶4'3N|{Ƕ(_@A 3Y;HAf;_z&J)Bt*AW<!6);ʎLi|`4F̟|mYHd⩯D^%* +b\2 MOډȠs#+ܐsCޅs`du/vHeɸEmA8Փ0&|ֻbqgkI]R9Q2 wx`Jbb PqE Wdl% DqPBH貦cδzD؏s!>MCw"=WyZW uP8FD)yXA$GHa3CzlPҧ6E\PjM~ǒYTif($w$S>Á%ӓt~Z2U쵥ʌc{^0.0N$ˍ>GOnXp/X!/v=Y6p⁃y~yUx*3<$E<\nOtm 1AK+wT*<ґV{K"Ug+lxWݼU3TH M31 UCz vJ}~?EǘkplϝC`'!.K!(C EF7ԴI6 0WB w߹H]Vܼ=|hL'W CCg%Ͳ6 P q#u *K D>ods@iZmeN^!} MQ픕A/!-#4< E-7v7eB.S!c3Ymk׾2*spS!E 16q|9{(m]"JM/ (TBڀeDE m~="T(&0[bS|y[,b7diI|(o_LB#F[;o~틎 A}V͌d\D&fuᔘn*ꀅnZ%𱅕N{ЃԆ9R!}N΍e$j#"R Ooʼ1,ʫ80A ޳ه8yųO6͞4aݒfα2܏aurC-WW!>?Gٝ k迦wrLJA5'뉪 ܯn12rɬ*\J.MLa;R;JɛZzp6=p"L₳RpaD<ފ-yPiyʈ fZh^t#ycaNyHA v|1j?(.y +%瞘MaU ؾ (qޠTn^YVfkh dKmêu2\E6r ɨ#EjZ~6" 7U^Tө?KG`{՗s,WVO!,;S *8ϞWu-$WVhqGNUaqdj[el`^2 ͽjI8JM zﭚUбb\]ֽv_8jqCDP玲~3zV5;9cI -) +\jM5CWŦp)yъ-辬=C&Y=a1Qų&//ѱɋM4 cPkأ%|AMBڈ~_ߩR_œ^~~C5@,Ld (HrA:gom&.Ɠ`;%'?c7~MPP&ϰ\k`9herxa{+nn*N[kqD&3\941[>lPd`#)T-uq[;$4{ҼȞ[5 x Qyz eH^T,ޡ Hծ'R; ;WPFdl: 6-قtOva1ܝH"U07C A0ۈ taIA̍o{Ϻ8s;lٜ}A`hKF˷Ϡӎf) uX6FG~B|N(<䥚̱š\ pIӪu-CA™y+kn9׬9EN5P[oqz\g,襈4k.IݥǦgNW1-,y&ċJfő+cJKM1m=[`ǁ ѾG_sS`wq٣ p'YX%ؖzLRʬ1~xC8E*p_z&; mloSߠ~{e"P,q(aGr!FAmBOQMQȓa%&g|jzڻ PD?:T|TRʷeHWGEjpZO+.}NU PHKJLb5F1աt 뙞|о4!淼ar?|-'B-3ACfP]ILM>`76o#@JÖ:5΢. Ldzb]i:(+Ð0?"jEki_G9j翛N~d +'TY)R_I3d[e*:mH|$פ50T4/@ؘi5Tۃ-U(w>y"^ o|BKZ=kE \OBV:o25cbTiwk|OMmW𼪾Q2ڒ_Qfi'CG˹nWC>S [j횶T/VL}EQ'h;0J9?VPՀHAqŰbI5,3Sv^薝d~`zspƋu:ePo$V@m+9viFjd|c.*M}mtJ@f)5R~j[Kd-f%[Ų.T1Fn^lfCj0jJhS& ""1d0÷aWGx @ae⠯!RD-rUW>m 'up\e]Cl!BQV͓2.Og̷0$q>rwill5G ] dS[P]"C e<@ާ!R$um YR *坺,h6iiu5Ú(ɎWipPU~VL9 =̥k鰶I`jM.kZ B.߰ h7xB 78n9V2/Aat`K<thX:Tl=@*8DJpC+y~Hu"TkC[ 6!=obU7ICDZ8u;=b6WtX O1S(s)oZ>xlwW96 ǔ5 VTj+ x%)g>[m`e/BP"׊ z/ )Ku4u*/%_D :| "t$K9خM?Q#bGQbr4p" kX$k+J 19ΑBa"kĤ0% O.$@-{ǘ'%LI/$HIm9o4 D\ҨJʼnf cv{RvrJu؏(SY5ip(#~Df%Rn{H}vb%`h5τ1YB?h!PW76q&Ha Bb%f W$GF18X>;4E o!V>囏Sގ Y<1IINrx<_燛os*ƍb'=/"BG6PUwF+.Yi9"Yíuq|شφ0{u^<)Ƶw˓yQ""bltjG75js?M/D(*?S?7"][uB0ĠR^Gzvg/|`PР`4{ܷ!; "y5ݞuJNy}\@Fp~CMs*1_&o0O""|Թ,*M{Ř⿼V#u+qBvb!|oQ׬*JIEs ::%)?#Cjc4u_aAt{Rdh\ TFeag#E~ FUefTsW(#V;lg 5f1Oj`m8Db)=^% $hN-7eqo"{/b-CU5{k4Ɏ1#w%a1/`/OA(JWWUƌ^Zo G^awYxV8dk+hb ܧ" \>;xO_8~=Eg{U+`2DSo FI Kv`QiM Ʒ)}x7)x1T=2b:g>Vo Or2㹫vE]ԥ! '&qo 2DG _ —RcTBPf6J d?=BMX(v8<=JjP@1vT*;]㣡+xj)u$Q$Lvl-ۡ'Pm*"+w#sDzoAf̘%Hj\zwk(ś `tV:l-;Cg<Q ZS*my瘎넆Zib">B[[.zM숺_fv2 Y]soyG#bRNzJ@y( lg{֘\hEm'v0so# l֥VKekg 1+C֏C\Z!^ߧ_D7W[L*сCځ'~%ZC^˿n }S`i6`LsSnyHq%!jwq07wo j{j}ݎ+sK@[%8}<0dgM|m>4D _T0%g\I9dzqY)}+8X_}U.p]P\mSbiFBv8ժ[WŶ20YAբFX><[levRjIzkQ"~b#]Ɏ q|;kFoxO/R5kf DmD/*mt)'O\7*^_\+ +txP GrW AԦmd y[sEK@*wRqșYUzɂ2ۭ0N_f/!W6!cUРl\N-0aKrn,`,{g,o3Wы?;d/ -KyHG XUǢZ]=;"Q q#gTZ4?I{d%RT?ީO= iy5 ?MNJ9nW͓=?GG7!0xӖcJ횃Cda$J٤ z}t H榭'/|o\\k:D6m b T욋'oG IPJA[EհM%jyBTCxJ!6ANo4Z|򲢝db`´͐vFn\N]QyBx*$gu,LMz0 LQ ^Qh>IkNl216:&YC-ܑWۣ"ckLQ g]0)2ʼ yfJNh{ qNWIpxuH~9 1y [o<ี(w702HPJQ~3Olv]̂"~#O@٘|m=٣5^*s#d*']Ek*Y2!!V񞊿9NHmw]IV1Npl&a nEf>E6}O#&'isKӆde+/?!_/>K >uALCXPLʭ1]ܘqǡSCi!*ZueJGYGSZ(tUH; *\PHA;ֈBչO:fYD|ղn0$eT3wΓjǬom*'3S'Մ3]d}@s/U\kb4 ֠s)i=2ɾIlJ#n*%Һ.4%hNy %F)M#u|N`j R8*5GÝ⺊?AnມhvJVco\Yb;8\༠{I*ofC%g0hc%&B+_'R :w{1{y&bn\~139׳(8ANW9g ~͖!'{=\ \ '_> ﺁ'=~\Ԉ ?_d0n,ҏq>`/O4@jvf Z@f_7&x='g[Bl.o$J}C?d"{}.ַG# !nHAsƏAo}aY-mwW#ǗQͲגױ㡫|G "yJG(ҩd=KS! Yޑo4tWثPGִ7TP`XTkښK8vBXVПQvmo$2{hRbNMFu*L٪ʑ w>ii5kt> (׋a? qO\~!^,<~4e`F>E 7Ju%jn:kRFBdM;)~uENz x y4tbVqzW/ARl x};J^X b+_Tu;&. .Y!⩻%-N0[,/G{^?qHrdˉ)]l*/{e􎪵ƭ1+sՏrSCVDUY}j~0 tK0Ku vty.k2kF3q3,$EId%W?HZhwObr3֟CQ a{&\C%8)H?Px6j){1F )Ŭ-ȴO)pFØ_3ዢbB|Toވ惉(' 'HdV]~wRnLySet8j)C l S>NLtF/T&ua]*[]&y1i_8 X$hr}z°%+&8ށop)X =# {T޵P7|;Vh3)scDǦӄ?Cj93~7Iu3-x*TiU1 T\i#),T۠\CL,*^v2YcVÚIɼߣfk)y5遈O YPkvQŶHiP+8s 0ĉϡG [D,{삣A]WuYib$IP S'P]Dg!H^Jq#j>]W#:%kriia ?6U= ?p;8 6Y[kvmeNA$<nv&?[k=h"rDY:IMxn[K? ΌMy75 Iw7YC9ooru k`7z?xwE}=;c2=w˘CGtdYf&m/kOUq6\A޸a44LSh1ͣ& pKGu39DeB re {ܟ9ʃXR}C0N* EMT"ae>NLYO]_&^|䳫bcz 7\MO@+2 ɧq?' ao u0{h&t,yc!I{gZuvjU~ƯASN7| yPr5vG~ͶJNצ_̓ x=C AVadkE6hZ .LK[_@ oT>t$V,\ȸC)rYIC" EA~P#\R)܋Q{|&, !=) S24-) kiMNZ%ۯ0Ift4ՆGH-9D) W-c< 1$aTtPYh =q~=F&9~l8׏M>a=bx6ߗp]xLt_M5BݹE:ǭ1Yb"Ůs& aRNJc&8KawtR;~ ܏;rxuvs;X~M'i7[꼉b{l}W(KAfdB,mwIBL1u-N- .l5MfYobFRʹYi7[:p zpe)BpCROJ{uۈr$DǺU9,\#Os)Jt9 DfEp?Ůb mPʾMz:bq<({C("ޛv,<ϒ$b7CH},F\ɉAU#'&T̟Lx؀ZBlM(>/GwPq u $buY/^FMӴ] !Velo07l$KDw|ޝߵ\wªp߯sdC8m,0eWO;]XK*c]pzD+˃,+h_Ήm̩e\i:<#5(:Qob[4TE8qx;],DJ8X8`"*:dհLMCRc}\ kJk< 6%5':TcN?^ 2zj66(W:uI wV8,,Z%_oRmMO);^c]MT ׀n: a>0dckLTytm'$? 3>ĽA}6b Mx=riĹkV?~ H\2 mqIfr8fAy:4ygͪ53)Z\SEנv#F؄!sqȖ8V !/h]=H3 36\lgXf%G澸UGBA]2eUHS!qo# bhJb}/`NTۨpjF߻(bfi=-?qeG^펫%3qb($&}Q]2PR1i}͇˫?e [OEȢX$_iD^xWq| 5h/6B|&F$c(.~#(އ 31l,[X;叭?k_o ߋ$});څBKro`[&%1ʃ 7h,:rr7o͌QU*ŔJ.¿ři/@+~B;``ŭPZ?d*; Yr E( *Fd!JPn_^ :m/!W0[:_^LUkttҫ%R  j əH-xu[tL֦ tn3SeR)7dlxYU64(Ϭá; vx.CsQtp{#_cOV ̆MGux>=sVS <{ۦ<=i[u )]dbzw#f]=|KO"e>w (@8t([0$JpUm}3V)85iG G-R ]w9&nzW[P3opV̫ӽS]R5SS:W8< <%bd^JL8Igo0.,!c}F"V,OH}ɓa EM7h%/3Մn]ѹvOLz/< ,/W7K=7 \6Z{21թuJ>IR*vҢyL dIBީĤUWDGt,M[3]>}'`bn1ہ'`K3$wmYGxyV!oGj97KT^̉M% ϶@L~o ` fV ZAdrAg*潃z2ήPɆXZaPs]밈|.S=7+)R"G;J;Q1ZӜ!  ª;~5#'T _SX߹_=O rw?}^,(/Nj< -U%kyT<=fnhU8z泜d <7Bsv]gn[իMEbO k-~3qa~Zeʅ[6 We[9Zlrh(clwrz=Źi9Rv(){p&.ŗ9z7e)pSK^']Qs,(Unvn/]">q>tIjj*Z}reXO6UFKc J'~ l:Iă/\ ٮ:dH^h%K@+c mtm zOR I 1WrC!aq]'ȷZa]$Aa@ q.{Xl^CB=oxnSNT &P@\²pSV7BAw 4٦"Wj>r: -=R!_zыR ‘ە.FgnєېV< ?PWz *l?6ad#!7*MiVHsIBeB4{Eh<.֊k\ ɜQL.&pCJ uhQkXjW'xFcMw_aʖ^{5zP<ˏEMAż0jZ^3{kh.m+ҕԀR(p&S<`\Ʀ[Xs飧jֶ{mAN0p l[֗R)$ zÎ,8X%TUQ%9j2(즲qtbeg_-1v85-C@Ir-?RYe[uSOByWinE&SOc&J2:rQh Ӹ.WKG^;N94Gݵ8* J/qEX}hH3Ƿ~K_hU8BwɧV\nB(CUTEۏL 7pHո>i;|vB^3V8kdbo(=t]'΍Y/auE ,bp.g^;^+2Jj["2|څT ƶ2PupyLkش@wg5CNgUbqa{RΞ2L0#_L4"c- Ox q~v fz-AʴTL(\pUrTMpK2P5uuF:! p4-mW*Y@[[I E5,sioD'"[f.gsHrC1ȁNFfũrQ}5[x͚{~J$p趕hI;MeqA?`[霻TԞqwo#Bx<"ݓ"_a fxp} ɹ䙤H3ᒝ^kts ɥ׹a$33KZQ`IuSD+'Ltu?D@G4rlp[CFPZ*Q*h Vr`ǐ;uIbCT/1Φ/OWҀ4d]1IOxX+m)7Jp#l㜩0a?wTyKZ$.+o%-tO9g¡\MwF-3 cLw2T q[x3MHv`ZoJҋkG]9^|Brux"HS;m*S[,_[ZhKAc;,Ȭl kʊD>̤v5l]RxځU9%TiXG~w޲I:Mzwd۱q!jOyQ8]txu0nʯJx O./.j"dNYZ rl:znH1zD ,Z&Cda BI IUNsrxg'|E_aKhE  q (9*9R/n d1׆A?l 9\aC}r?2`pA x7pR.tKWt|̾juvN휕\jUH{:rQY,->p6ֳq:łHQ.X7dtlN[lfh#[mSl٠|'_iM+&z<K"Sxrw)XR3O:&fiPYRNt,o2pR#+4jJkhm\k10Qj~)O4I/V?hS[21KFL[J1IVf~ŢMDs'xDݟs"Kw5ޡ ~x?0qTxj{УM݇o|9&ȓ ]yY/ߊ':(r]fxQJ#30p)_δ6 =x)sl{Ǧ5ļ>=otaʩbտ(~i=1HΨ9?ֿu9_xvQc$Jj;E)4~unj{ /5lĂ̜̲*7֊$3$ '=[$T]6EaR(E6/FUj];^DR?$r26j|NS{{=|o zWd~汑 ]saq@EfQhE7Bi#kDp;^{q!3dT/ _gN~'ū#HLv:Wl%oݛTƧo PKTC*%a%uv%%R*yjOϓB\ƙ! Ͳ5SR[y ql`,5PuSQrM'.y@uQh+"<(C%iKX)DB6ԐWAh*xs_;;Ӆ%6RY )u~i93o / )+&Nt 3mNYFH Q;[3d{>T,g|~şg4s\ؔ2x9bhm\\M;YӰ_eY^> MdGmo`.6{ˑ< H̉) NaWM.ȠЯ-ݜ W;Tdh-@SO_/{g}Rp<-T#w`Oy_RL NlSԖ!\E8*O^$.;~ ku2[@c~PVf'')]iy<ڈ8%s@e¶0VS!2S 2OW^Wgy5./2GSéB=(ǘW"qw<;CȅN=S-;oj`qCjR^l;r!&gd$}͠NL 3'bĎuYKU[Mf ݥ0xIAjzVbDYdۦd"6/ߌoN9j'vN(f*E7(S9X99ܚE"q|q"ZޱbRVq6@_8ϱ"ojxMA*.w!DE69 B3!_9d!zuQ]szTJsn9A}*ފYmq8^QR唆i?Y]~pau/P6b)tdt}:2h #8)53h7ԾQ,⍰T]~k,k"t[} 6 QTbݻ:kAv&@Ro9|[WE$ߓw.9=O.:\wje _m(!47fQ Mv*{6sRUG^W Sل]CE2NtǿW/vb j 5[+ޏ@xT\p!%{\w;<:/XǙ:ֈFl.N.W{xaޓͰ'O@F0UyO3cdK$RAo &֚\?2BŽ3*>_JإR:7i}fVz.t O o^Kr~¿Oϥ5aE`%+X20&\: C'YT86I+xI&Y ^*xWSy,^zpܶЬ$L7̨Dʚ^ ݁`Ԯ/>7i zKϫ'~ #kg_=Ng6k.-Ky)qKКo>2(EDӤ  ^'i}(OgIeBcȭƩRkA.XGM'Tf!I8-`[c}x- 8]I^2"pl8|K$Hehf2݋e [h%i[LN=7EX qj),ǢXw}ͅ˪̐\ם20Ur䘈2: 뜐*ᨲvES\8k}=cᷚa$Ώ.Ώ##q' UEr37ӄ^A)?! ;_{>=ZUP'J^e宲jߞm6Ϻ@t+y qtr`GEi)wtق33tYxioGng]MidyيZTyS$cE09WFsFvYv[ uH[|JyU`mػX )Zcv={LƳ7Orh7&"*d}aE\ R!*51#MOI}71 }yVPIX׿Gxmc[>ʼn a8U!kY.6܊#VDd k9b,@-)/Rܢ2P#'NJH Π:x뀤0&v3Z܌uz=!hS xK܎w"{;9VrK%6jˡ7BnR{4R{SSƗBp60%K>3U^gyR|W_*R`u^ӮDO.|2$5;jIfi7jS{zƾUN.04ݭ4>6e8SCo<{OzXFBh}u3 E7@!Ԗ=ʫ?']׬X^tƤ,?O^]5O[PM_\Dd V'غG:i,Bč!$UtpMX$?}NrJZ- 6 >pD%VvA4d#<6^t־Ըo'$F-Aot ԩ8K4 p{]|k0 i8UK11zRЌ"=蒁&:E9Y.A4?(ְc]!lPYdcR`w4b[ǝ>v!xoSI=?QA§Vk#iX$ֽDPBxm Z[Qn(Ahi[>m?cʻ( ,4^ j^ & p~苠|sG)  t}O^XZq6o9vA6YDoQwُ8'5LbB(q*|g\+4T}܏%^s!:xcéR w<ĝev[my"iw8WtIhipln(ءXJ$ab!㲠s)d -59l#?ك)mhh̓d#ΤF˥ B v[r_Yז9!-5՜ ?=̵z{U? .qZM T_Wn~^Ȱ ͸]v \?W탽װ M.D!KL 7\s mЖܹvljuOHu(e=^M<g7ܼK|m(TNNhrZ7]UV* ᓯQ7 \l2X6224_J4yoü(-L ܱPNLqzE?")lMt5 stO0e*s _(#Fr6w@4f`Z¼ VZATŷ zs'sQJGwpqp@mag2s6"m]6ڶ)}$<ٰѓ?a|N o]͘Bxu^/Z85QG9?{~wCVYHOQ{>< x_l"LhxvV'ZMz,0y$$ $.B+JqDJ<0&,u$y5y=Ec7I6"ö!Xp* v8q}&2_AZQ|FWtq&t0|ER͈X%TyYB=E.Tl_nԤ!T[̵QRN`i֐ZSĖFdP7|MKԮU#=p$F݃SǦPPS:v %e4+zOJtRZ\N~8(+Yub!A3 7ɃRPB`+;b@5! HMW{-m8F$yQNd8k}t͵e-ǝ"WܟPKᲽa%j*I'TPSSu`͡o~`#NAƍwONu)h'y"J#dk9ÕHBAifYVxgC>AD:w8?RMJ771|Μ }&8 Z Rȭy(Xt( _Ĩs364aq1f88Z=m9FwS\a Rz8qaj !ܔnl_mC<:vya+糹#>՝ ƯmЎ>vY5]zlqm1'p߂r=v_oD9/|S,.TCg!+}r b\AkBpv:%+7Ctx(G4NeַZ-?y3-A; 3[ޜuA&\ls14w+ idZ7b/`inNrBC>*ed'Tk$x-۴&5Dvgqb:6nfC>:oˋMz<=/9ʃ^t1Z7ʾWf2L)a@?5rF0N x(M^xdes5<*ɬƫ!P{pI O㳎c~uqT1ػfwai0wIʵepqd]XFp?WoJP'׺ _X[MB8N+2՞Ep5IwgL![Ê"Cx3t5ۏLB3uh PYUJVS\1J)?B]NReU ABNv2Ƶ@pQXiR 7d_m}GvO)$Wۗ87cBCKMgn*X55kjЛr+=@VZw#n}#8zo ī*7ߊfgL$ӝ;*li V*M00dIsr헿߀$7EJ5wF]U>]M-S"o1rxh` \Q529\`8FTs&O'JbHy.sL-+8WZǵݑݣX8]]$UDgsaKIW8 eeP.Q'CFC{Xgp ! ; :d_ ֒3lUZPqo:FXHRKiz{Kq3 u [}ݍ]ښbKT)d`;rItbW8yԅZxJ-!GZ,\P-LpxWlL=[U#" xmggJK] :,%W\ɼs|/+99tZ"D=-Y$n&9?><ՏM/|dOls(#4}֋ѿR-NuNROoӫh|:}A1˚nI!)6x* h:&74*uϝ}$dX/ AF>S?Rp7,8]R[:4\L?Ӂ_`{̣:K%^DJaJI\,Ew:"q^ B΢(#]I[b0;ktА_pWZl$ !D.1g Qq3G:߭5V0Ye{ 9 fQjZYFHoJ~ٝ?6췶>zCowhظYz@45b3ߪ¶FLJцnvXdJQP yU^fkE#Y۔Za6PI&CUWm^}”tnpʜld ?'^%Wp'u(lBu~6@. nĦ tPʑb。iՌ$'mZ/Mg̀: lʼn\m_MII4~4 ]n<2MNGVa L+VbP5;-A2ԍ[ 13+O%Xë.ްs]ŗmoF8 ч3^@$h|$s'縋pHZᯮS4vPvL'MXe<[˹֞EDV.<.@ NLtZ@R*sZ WsϓS)r/ֈ{9d%?`.HYpsv_yU?,"sHah*-"><ee7e:H&Dtɑ%zA4ൠĤȉ?J'PU&c~Ke~aZR9<QlALuאJ.rcꢧ"(٪ K(Gv;$0gV\ qRLV8m ;W;FV_~cY!`A22Xd+I8ⅴBQ3>ֈYVyIqi`<'ÈRYw[9ܞ> 5 "ODLLv\Wi%TJy:1e~ju-m]9JN`dd"T!Mu&P.٘kL_ff0G>0pEpRWnjݖH[u<.sPLZFm/N&јX̄t@%Y ;fEq2$4n)W%CYSuu^ Bgu[ϷY>עԉYJnqӿ:h)ђ䊂!up$[O]7!=tzQd;"wgWS ;ly8i }W)Mv`tHj(D<zMU}CP,OAH{%;NI1h׬Bjyj?Ez16p`9AB<o::֝]K6i9ti*YVÆ7¥fg m "-lR@rIS~Տ"bT^Q%6;:lGK* 荛&zj/ ǹw5ovSzL,g'+֧J>/14UeT-h$"v0n,|y2oG%.s[յjh-1 ^7z(stiiPPɱ+̀wo*#Pij .i/P lHZ)=וplӶePß->ˁG|oOĔp$Xu 1hqƮsjCK.3e2۪筕)Y @76jX9o6/8xsWjycd:HS 'Q#XѦ BA鶪%N'e\\㹻h_@ fUlg6jd(ؽ 0s Q/<@x(bpch5I[,Ej{kx 9Wޱx `'"ZLv ٣#F\cҒA;Pkr&kMbܻM|MA<F @V@oJhdǏZ#4Rj]!*)6EIa`3Ϯu!~5*zoGpC'icA=3frgZ'S$A 5=v#QMACzhhpT]c]~L4U 2ǚkOC%T"*`@,9,FN / G. &bi|~ LFhm?|!7䭟ZyJ৙>sul"Ӂ⥖2-ܚfggS'a?*fƬuiى3+uO3AJ?^18ekNKS`4O~mx+_TRg$!:5%>'Tj<--N-2I*љű.9R_z2ey&`GvEn6AK;X]̬v™wF3R/3suL+oy}֢To )cDd_aʰt_F(owb\׎np~,R: #%I>hzåKĂMF∯>VP 6eiuϾIkU6YEܕ6apj4T xir&m/e^ؗƔ΁FTmt.g[H1~o:Q*GIR?/"=IWc [xo@zu']G3 \ni[{&a^~&v">{%zr\=ClXi̴UO@[gW%3M6tU(Uh]\ΎGm4׶:\?S&sdstchfHj9>Nuz-Y`S7#V4 h:i~/͙7~KLهwY7r,%e~?ۙW*YT=FN.)>A=maax 9.Zc̛`YBp/qD'V0u0ZǡSQz c4$'\f Q_+.sd_* RɗOLԙFC spe?+&INK?EljԭO/!o^LAS\#-o] eb>i{ÑK8E5;&Z'ZiVׇ}m=Vp-dn+l%K#;i63] ɦCF-WV o>]b pΌ} #mB_ч5&TwO>&Uf I<$B*KYAIa{ ʘK"J'8p+t#8T9gb)1L9HE)o`vߞR%눥b{t\R OQDC*BS=Sx}S}C%k"#V=A>CқD\Lb z &eJ,cs*|J指2B.\Q]]4?82a%c ?;ܲ: y.X|a~+@ryE B,8kEID.qL .X T^}=ㆼFF4@ nǃ0y^8 [|u @Dz<{C{_fr0 A^2ΰz4SJS! /G'Cnq!ܢҪSʧK`ʥ9n?Ѻ+}~QtQ#f&~k]N&3P?7:;Pg65f1h\-6 ߯. R#%2Q^}.dIoִHkC:Nf T*RO7GE8k<ŸkxXޘ列sivq.RC +.G0F =ךc4 1٨[]g)_tcd 7]m='(5h0C^o2鳖d#Z%pu˚+%'ffXX"VrNgT%jk<4p>Aȋ)Pcɐ"1Y acPe\#V`AGT!&PF {̛ -jS*=GMh(ȄJ8dX? Oad@PVݜ;zW ih9\FqʹEZ;~gm9dX7-Y lgQ, oZ/Q!~y^,&}"wׄN#(v7 G _4Хqk@ h`0G%0ɧ8W ԝ|@4/mCD!뚗~#vYbVX3FqX:0`=Q0y[ !U co"(Sv w'D dvaEm->+0_OXo `<4/{TJ'Z{qj f+ Eݜgr=y\-܃w͇4v>=Oոeč}W>@s#X5Vm2pPyVJBp0a2Tl'0HWWN`4=q;U/]Egĺ@w1|~D@K[m9`FF}LujڄL CčC)c gn7q KQkiQ,cC]yh ! v\uE[Qyx F9׏ ><Jw7~*=W[b׈? ,:XA¼hz J eisP^~9: c[:21/ 1Sl.a8{fQ;-AFFvUbܿ!.IKisr}'ؓ/؋2C"w9e.WIIVMvg*qHWf|5|؞qXAgWd(4P_OJkЈCvʧ PC͘Z91_ %ͦ :4H=M6g8O5h)AٯJBS!Nggn~q%zf 7dsO~<K=Ғ?F-qJ9y鯔ě3{ƎCL&㇇ 7h Ay}K^bIV{Um\nu(@.ЩxkDPV)y' 5UJ;F"@;W~Fy?-ϡ>Ȕ9{8U:#HZ,"ZL[>yO[|Ra*CBc{.5~ 9aRon't+(A3m߇8샾@v@b(-1 Г"+0bE30瑤ĺ: L Pm-ݖ@[`HoFcjA n(ĩ@>K`nt,sdž!6,mZ޼n{y)Ѳw^])GhCr,Mͫp}Y2>8<7bĈ,4L;'Ixƣb> . a|[]/H&c09H[hw` h73>U1<ʊ3/YqHp5=5'.m %sRZ5|s_ޙh :W81C>|(\|>D5f +!wdYLHq\B?%.-[DI! xJs^wiV'KPItQ׌wXg O?MjCha_df>F1`N!\@JχQq> g Tb3 3^{Pgk`!HɯFWq$ex =\ #H"VqAMuAJtCp Iina'd|m B"ib`O/%g$˄ܽz)eN5NicNzʖ ~nrt;nan愵Q=InX<0fʘH?'xq5U5 bC7vPɒR\P *ع ¦{!.Dx`YIOXI|鋻h}JID/ wZujY_G FDQ ,{`>Cm˕^SxU>LR6>~- Z|E9Wddr24 ej˖](.Z.(N`[xnzTPIź[Uf~\\ iaնO@ ĝ}-,Br]ӯVvzK>&9"ݒgy~`?qUPXu.}/qLKiiǦU6LTB]>p|SAVFN6V9\߭:ؽ2=9*nvh3PM 7&Q(+'F>{hNQP{҄+fǕw8TmP4((28~~\׻ǣa~3W۾Bh]`42l9%o!W}?%śM݃#(4rP:t rUiN9nPa)ߋPH` grUH6|qrz+զS 2:*¥hj lQ݆$Nbx[PC"r+7 hUµKLa_P v6V(UF[i3q)>^6.M{DS,S1$^`HX0Ug>߾0[TyKVyl?peP1+ FaT]v).F^HP-yD^nrPpͺ h?$wTJ I˼D``^ ̠̱Aj[XJv$[G ~&$NN/\r~gNG&G7E K"jRJ͹6LM k,\ਏxAL9I\z#=}Ӫ'Qx$-)S_C)oW.a5i"l7&Z#ˠ8Tj: _נxy|%v[j\uWٺ mMz&#m2ۤH/jEiowDף )l!@^yHd Cmث-XYH섡2.mSEenf7@g!=ћ+ sH6+gI[i 8YO`:=>2XK3X)mGgߤX(: ZB. # " v0Ȥ7 4 !$p{ًJ,ѫ<-PP^9׋Lv7Bĉr/Kt I'@4iYּLpƏxx&1 -bC'S}yWj3WowqT 5m1_\쏦 wDOfNiksrK^g!A4kp a@ޗH9/8m pSD\%ʌo] #A. u'CLMD64HrIԡ&ѕկ[Ot#8q*8"o>="px2 DF\9{@Lu~PlZ( aKxjԑnX07B!kTa=*WIIu':7/ӫ|~cEsI!NmT!p_͖q|Dnsg~afynR# )QB0j؇Z.D *E) pO!1"gQU'pڜMdCG'RO/ |+ iOsSrIit.@Nhg cƶ, *$ָ- ʪAn'IvFhgmcj$a6R62j}'D+g| [|>}iXb#Ew"LJxPۡOӱIu]S'y<26#l5qJn͉zݦwHCO.|D_ދ Vv(g_GYI nOO:E>@ܫGyiڅ>ߵ#rI'l_"=X|+< `A@"'Ӻ"Lع$h|y+wL,GڲdK`aT/t1B<݅husI_l^m+16:媆uK+$XC3 RpXωkm= }<8[{D_uBJYls*16V GK²wBQ  b&pڲ އZkPzz]Xz/RݫGF2&^ѧo9]>}H@%yf, 툚Y:=}͔Fb ]#qzNXscӡ)PmؐDc$[8]S:{44Q^.k@GqO+Sn~BoW ֌ˊHDNz-Q*ar}"MOy-eyz,EzA#J g !<,Ed!peR+Io"%TJ`9,jXYp 'ݲ'hso"zB|eDN\i j^:`pcW9&NU#9WV?FքɎq_ض>g"F:3C~44~.e11P^F >O snO~* ,;e!0Ա3dG>^J}y8rlfעgp)>0 YZsurveillance/inst/shapes/berlin.shx0000644000176200001440000000030412625315364017211 0ustar liggesusers' bZC 08Ae@`/ d=A^i(TA2X0rV R V8  0surveillance/inst/shapes/berlin.dbf0000644000176200001440000000161612625315364017151 0ustar liggesusersj AWIdNBEZIRKC2SNAMEC 0Steglitz-Zehlendorf zehl 0Tempelhof-Schneberg scho 0Spandau span 0Charlottenburg-Wilmersdorf chwi 0Mitte mitt 0Neuklln neuk 0Friedrichshain-Kreuzberg frkr 0Treptow-Kpenick trko 0Marzahn-Hellersdorf mahe 0Lichtenberg lich 0Pankow pank 0Reinickendorf rein surveillance/inst/shapes/berlin.sbx0000644000176200001440000000020412625315364017202 0ustar liggesusers' pB A80 CZ@eA=d /`AT(i^2 BV fsurveillance/inst/jags/0000755000176200001440000000000013670366030014653 5ustar liggesuserssurveillance/inst/jags/bhpm.bugs0000644000176200001440000000777313670366030016501 0ustar liggesusers###################################################################### # Bayesian hierarchical Poisson model for performing nowcasting stated # in the BUGS/JAGS modelling language. This is a template file - # based on the control options, the nowcasttrunc function removes # tags or inserts extra code - i.e. this file can not run with JAGS # without extra modification # # Author: Michael Höhle ###################################################################### model { ################################################## #Prior for the TPS ################################################## # #Priors for the regression coefficients. A joint distribution # #forces the updated to be MV metropolis hastings (might not be better as slice sampler) # beta ~ dmnorm( beta.mu, beta.prec) # #Random effects with automatic smoothing # for (k in 1:nknots){ # b[k] ~ dnorm(0, tau.b) # } # tau.b ~ dgamma(0.001, 0.001) # #1st order random walk prior for lambda[t] # logLambda[1] ~ dnorm(-10, tau.logLambda) # for (t in 2:T) { # logLambda[t] ~ dnorm( logLambda[t-1], tau.logLambda) # } # tau.logLambda ~ dgamma(0.001,0.001) # #2nd order random walk prior for lambda[t] # logLambda[1] ~ dnorm(-10, tau.logLambda) # logLambda[2] ~ dnorm(-10, tau.logLambda) # for (t in 3:T) { # logLambda[t] ~ dnorm( 2*logLambda[t-1] - logLambda[t-2], tau.logLambda) # } # tau.logLambda ~ dgamma(0.001,0.001) # #iid lambda, which are Ga-distributed # for (t in 1:T) { # lambda[t] ~ dgamma( alpha.lambda, beta.lambda) # logLambda[t] <- log(lambda[t]) # } # # Prior for r parameter in negbin # r ~ dunif(0,50) ###################################### #Priors for discrete time hazard model ###################################### #for (d in 1:(maxDelay)) { } for (d in 1:(round( (maxDelay-1)/2-0.4)+1)) { #coefs for logit @ delay 0,..,maxDelay-1 gamma[d] ~ dnorm( mu.gamma[d], tau.gamma[d]) } # #Prior for change point effects (now as vector) eta ~ dmnorm( eta.mu, eta.prec) # #Alternative: Separate random walks for each baseline # for (d in 1:(maxDelay)) { # tau.gamma[d] ~ dgamma(0.001,0.001) # gamma[1,d] ~ dnorm( ifelse(maxDelay < 3/4*maxDelay, -3,-0.1), tau.gamma[d]) # } # for (t in 2:T) { # for (d in 1:(maxDelay)) { # #coefs for logit @ delay 0,..,maxDelay-1 # gamma[t,d] ~ dnorm( gamma[t-1,d], tau.gamma[d]) # } # } #################################################### #Loop over all time points in the reporting triangle #################################################### for (t in max(1,T-m):T) { #Time dependent delay distribution logit(p[t,1]) <- gamma[1] + eta %*% W[t,,1] #haz[t,1] <- p[t,1] -- not needed for (d in 1:(maxDelay-1)) { # gamma's are unique # logit(haz[t,d+1]) <- gamma[d+1] + eta %*% W[t,,d+1] # Two subsequent gamma's are the same logit(haz[t,d+1]) <- gamma[ round(d/2-0.4)+1] + eta %*% W[t,,d+1] p[t,d+1] <- (1-sum(p[t,1:d]))*haz[t,d+1] } p[t,maxDelay+1] <- (1-sum(p[t,1:maxDelay]))*1 #since haz[maxDelay+1]=1 #Observations -- loop over all delays. for (d in 0:maxDelay) { mu[t,d+1] <- exp(logLambda[t])*p[t,d+1] # # Poisson distributed response # rT[t,d+1] ~ dpois(mu[t,d+1]) # # Negative binomial distributed response # rT[t,d+1] ~ dnegbin(r/(r+mu[t, d+1]), r) } } #Loop over entire triangle not just the moving window for (t in 1:T) { #Curve for the expected number \lambda_t of cases #Spline model for the curve # logLambda[t] <- inprod(beta[],X[t,]) + inprod(b[],Z[t,]) #count the total number of observations at time t. NtInf[t] <- sum(rT[t,]) } }

dowY~5*8tֶ_YjO>s\kol~~-'Z9߶_ɳVvIgWս]Yצ?ykejOzOzO+kZ[w.i[lJ.l};P̴r}7Z5F9.Z'oݣ.uQQ1[=D]Jc(=ӻy!4 a|nZZws1a"cG߾~J&kWQLrZwoۣ. KQ5ң~ P6cMW_dToꤣQSf_ |VQQe}QQu)=jؕwTaC6daP{m^PXk Gt+(}J.0Yk;zQuTw՝F<{kx/ۮJ=naw-S%Ws;-rf󋞙6cr,YX\8]0ׯ]Q+x= ^꿂wE]wE]Qׯ]Q+xW+x wfVpf3-RԺsյ_1W]uWU~EA]uյ_QP~E]u}Pkʲ9g囯d5WYKJڎwhD0Q8 {^T׀PTtUl EzPTU%Wd0ٯ`-gOj>wb=񸏳oP1,?\~_yu5c8FznQo8~(Jߎ߾+:>=ǷS×=>|{g_\q/wO~((gO).+y{He'ƵI__~Yg~Nxy/׆l.׉|yVYj~|nT<mv,r? _oeʓmW; Y~ÏnOػq;~7%_m ʙ5c=-QykǾ?ὍϙRN.TP~cðso"e؟hRc?ʨuՙCSe?_GN?'˄2핣\+Q\YtYs;?_-䒻?<Ոy~xݰu[>O]^~x>g:Ӣӄ{(wnl0|Uz\y;Wpyne.zѷ(e. 䏟^?܆w^7^,f[7U\P^q?|x;,c#N~d};_ꂟ:3>?O:.vRo?qiRϷ:/Img_>y?jMxO^?O/Ef'6î~[q~Og6#_r*.9޼v !ݟ'ڡy+qu`r>+q|O5}-/ƨ\4?#>WG6Uh953ŧϰC畜.5?}6@~:Ⱦ1?_oX̸'4_r=cǗN>o>4ߙiuG}>uFy:9_[wb^˽e6>o*tʢe?ȰneTVvr.kxNN.6S˪ڒn3w_Y]\/!_ǭ~`=7Zp~뢲^jw|F XAb`8#^pX=գ/.Q D'; g) ܹa5v>w脗'8tLߗvٲ(&N:oa捭c:/*nLדim"aTG̵e/? 3w~$m_l;mZп|S:%Wy:>~IG9nI{=X>񥽩:Ϸ}ߜov}n  _zQߪ4(?C^@7[u>߻=G,>|^\S}< y_!ozeخʓu/ wY>poyf+<_ݝ'ՃB_.^n0Ok k{SC-b/sADZ\fH~ ðװoD8(_׷@4ҟ]Xi%%+rVFpf%ў CMOD[QǛUg>ټގdξ<ۦ owx*ْir^y$^"4qz\Zu{܇v3\|H?R7xtG'zJleI{BO]'뀱| a/z7e.7:և65rf[LӠO'2"د3a`TW-OۭvzaV_rX4{] lZpGۦO|FkS-v^Jqkf,y^dFVEWL<…O?74Znm;/DGܙWnsy<+q{2o}mncmGYcNc&(|'FyɌov=\_o̯yO;-~|i/s2]Kh-}+,e{ZG}hѼgk7@xo2Dtٶ!sZaauf걗v|: x/JIMRWM~9nv o?tIt v&oYGi55nׄ{9k['IC2ૼB,=e?\ Wm(G9pa㼆c7~˪?X4endstream endobj 349 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2786 >> stream x}VyXgdf@q'QQhn.VEr`(j7$\r \kk[mm>}qWzժwDj1R8P2usO?fqtlZbxHG&q$ %8Y67lJ.-K̚OJKL?~Ҙ1TMDfXM`xd>#%!^?V@!=׌4q1}fIrMH`M!AEySR3#GE'8Q j5 P!Rj5ZA͡R\*z;HMS (RQ%T(J]M8:**k"3)guUG?/8Up.?8B>!{!ΐʭ 9,l]Ozg:cFa*decA'R`rBmD@|ojiplF" ;[)v vi|iO3C+) u!3rZ| DZ,&]< =U5x(t(]D.;.Dwzt &q{wr ĽLZX 1]g8 8^Rq V]iBZX1RDvCd{r՘B_Eh&] PFȅ o/go,[2,qL0{sC[Q]Zs ,ܤQ0NB}&N'ib{)n[flܳYa4,{H8(XNmʾfݾcYK 6uBAP)o4L U$oa2H\م[AђKm/oZOmaeYG+/˱*8ؼrmklImYH`}jY?h|.v9^jw8BEP$LɐaE̒K 9$5(O 4q5E=>DzUU8^e~$n֌clztĉHԽ*)2Z{3׵ijpBX{fSsK=ZwqU:!F oMrh-Ko ث&H"R;*%i>!0Dwѽ+SZ;SU^3Rt2FZsl"dP2bSZ)́ xlhkA\4 I]kUrQsdyifB,$eufuq<+wʾ㙍!^S `tܐfT.A^!nSbJyc[wŤ9!I-ߚoI!ђ{iHS ƴtɐ|?-J΀`tH/3'[ uff0\lRS >2}9K::ٗb̆z`4= ~ WEajK dt2-wwVkSG0 ;iMчĀas J*wu6tC3ز횼l;8&=O{1PfO&o(ߔϧ,X)ݧtVļV,:qD5aDˆ裂'>V=B;i sH`&dnrqTu(qG.Ҟ!O~O3b۴ֳk3vR}6}'nFȣܓs,ٱhSE} ܟN4HEm(ZљrumKR^yo>9w ǒa@X~h}dK+NUڲ˙˟Lj)WW(&jl]'KGÂs|ϝq]W.}Xߥ??!TS_x~OW繷Hrք7i y.<zqqAʓk=|яNY3Ͼ*^'5ڄBKG׏am} SAoQKw=}jbޒ],hOEdJK哒ZW^d$ kZZe˽VߙD68GMoi/J+yiu}g>o>:_ ޲|>Al~p~s3C^e6#3\zgY,ϼ9ݒayn!kў[p(%kind=+ /C0Yg)y+lϝ YؙnчM{k=RS}V,:L F-]u=M:w{|dDpܙd"Y !;KT0k ,Cx eWĩLD1sxb>e-RB7Ni],邬q VŠR -+'6wR,;;V\d5T^rv+Ql.:endstream endobj 350 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 675 >> stream x]]HSqMo~2>.$T4,(͵btsns[I:I9,Yj%qI=%TkW!LȮh8;0_gnp5[WyvB!vJ! t/@K=]5X+ Rjm8‚T,aM^08felZfOsTl16ճ\=7e U'uUlNk8SW5BHpZ GTHP~b'2~I$a{>}ߒ,p~Ywj k𐚜rDJHLVq F9GLx-YM}jZSmV|j'>EtǕ+; Ζ]0{.1X L9kkfi»5ބ//F#Tkv{L*xUI&:oX'逮^&^C/x)Iu[%oV h\)Il4G$Lgdztz|v0 Nҁ`047#Bendstream endobj 351 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4230 >> stream xX TS׺>!sD'UlG* jD& LNPfD&! *-V_o^עps};뽷zV8$oGDQ"hJ5g/ 2'8f(1›_X 110rD\Ca0J,mX+.J#dlƴi䷧L'[0E{XrS)!Sl En [xlɚU||'N^EQ[Ăȅ-޳4FX;h{ώ5J߰3cz9͙!Cm߳6 3\kyحgE@F66v l+tA>6[2_iL=d!d %+t_U%~ kˢq/"k~ \a(|#Ž1-E?̾9k]<#"6Hy<.Z-9<*`粹tr9> X`j ooTj^T6P6b"< gC;LYmf#}Pȕ9fD]%w ?o*fr"`XVAQt\Aܛ{%II(Q%X7-G|4^DE_tӼvtZH Stؑ+޲*t6+4“a(<Z@Z)–BB6/91M7_tRكp\ F(6ڑnDw=TH%*<1x.^@>b.K~S P(8b&a[4H" ɢ.yߢkES + JDb {j=TI iv><;>J_ʑR.V1=Dx@F2^$5:|ՎF5s.(jPc$!&Q{'7jaTZQ wC,L^wc)YVG Yt`Iqe(.ES(y?Y1 a0,.NӧF--Q(ygRmXYɥhB{xL{QJQN !0`D~kO`[a@?zYxD*Y 0ֈǂo ?aB=\'qmnXőe&X wQ{"t?3jA.1g xߤPF59!|>T.\Zi)iV~zޖOȱ#ּ$zg+o{FN;lu'U܌"SUjwHsi)Ӓxl,.%{ԋ.Vݤ4,ݫK@N(G{<_Es"SWeW0JoWCJP 8#4K˒n W/JXW][STr,>VRho { myvC0uHrP9R>+.tB@=>(0;t״i N-^Q:J@Y:mmjbea*e@[/n;΁R*iKƟz:/ +iJF*wpTdH) RIPF;=NCB!uCBjqXEpQKCU#YI%ȩeɇ^3G tI5Uj>&L].|5&)ZE ='osfޏf?7g pp3 & Ԋ[M-#ZE\ |k)HB]WB h?Jݧ8^LOrՀ%.H_*PUmʝ@զ9+ò$tY ?8Yk65֟*7%hvN0B^= sI[wM\ߕ/d"[L|ZiYxbǝ(o,j39(?s`9p@M{r}@{,whxceha:Td0}0N=G6_ <˺2`J+ UcJEPg̭}gqX ƅWcljѩ{ּs})9^5Q 䁢Vg'4{m} ;ԕڙrSzpn.0OG> 3 28ze`MݵJKѡd؎5,xTzatf&~Öcc{kG<3=lI4!~DŽMTMʼfR/QEڪۮhkj7^-+X Rޏ sP*d:`2.S4Y|NJ&)o*Fk̼X1djϞ1rу5h#W=0_ qc(3eL~V'M䱘Un q )ncm\5>ɼrB:QE]̎='%mod4ŅK.RG 1N@oYu!';GwQ.C;_~ 694+ƊaH[w S(aVwk_R<{SX@ZS(};JOTGF6=A ְKTb]s*cu#+$^`` [ְ"v`k~ܯ5#w4KbQ8WhʷʧdRtT塌6@Ʌ $F+YsVk#m,uM63Sd߱1>[pD=l3 *endstream endobj 352 0 obj << /Filter /FlateDecode /Length 190 >> stream x]9 E{N ,E4.EI.`QEn8R|gӜsoM-8cŭA`2QGʩfQsH|yt嫜+ZMʍx H;JjOgcTTᐑTp~1ٖY۫ylXRyycI 6`endstream endobj 353 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 614 >> stream xmO`ߗ¦P'Ta܂bh h0 z"k tsfsۭ +vvzZx`xz5<<47١aVc LGlOPCI@ ݧDlSX:X`nuܴW`931f >~&6t GarL7d&<^?SS3f}oy<}ݠg8>/> stream x]An0Enh6&VU `c*DȢCEŞ?32[}x[Qz~-R5Nm~ۯ7_:_{)56aZi'/eR0HUߒk4<&q 4ˎK ȎK-zQD1&yj=(qPjdT=k\`jEHm49C 1T@*R1V1Ęmq"eGOb!CV(Qֳ6`%jj(o1栛;Qu3G7oDj7Α׏x T4_N0pSTiHSe^XUQwendstream endobj 355 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4659 >> stream xuWy|T>ÐaAzN@ "*}@,d!L2d}}g[2l$da M"Ulxۢuj{sjJ L}}"wBZ`܍9eҒĭ'G15FI,g?<>&IJƦxb$/'W %ߋR3ԩ楮f/VKef^bdqQjFv`_jSlZqSmYi?*-J3Ҭ4GZX(-fdIeypkdC9(Y*&'q7)#KD::qK?h6z1ðOEψPy&$9L/ o6f2vUXpqʾY/ܬj71gtg+~3t@n )=3?Fя& 2I:6 `ۭZ3y@+ufUD' tf(xzMZl3Yxa\JiۢRjzK_?'|C~(]8d2*F鴸 >E!.>hi+pIDp `YC}V(f8M4k/ ?w"\ w|.O%)eUa9ҵXmW9n燌zpx^8unM@aNfT阮 {iLݮ< ΐ\_ ZG8*91 LP"]W4[]57w'iḷa%X<Aed4(7Ԡ-f‚,'$6@9g߿u%bc f7de >f_±˭#ݷip2ѷFai#$%JpDW]pNħ4UP`QOك_T]$۵z_vqXw\w:XfPo4˅owL6̭P {:C$ѝ2N_sDZ}()]u h/9zj+SJ>h5z/5Us `7ӨcuX-j<O?O=V#Oړz`e;vlU@> t|sw諑E&d7'z#b T%}+&f01K!GgEvH7w߄},+X~ /c}bv!N)d0~4VOG]&jﯼ2}Q v{y,vUNe KH Ax"pֽx5@E iCu}PQT61R|UL'=,1kprs@GX Rν;]7I*P;tAVR(;yC_${m/ F2N8 ј Q)u)vI7pylϴ@O/`"ʒn$ZMI4cptaZ7P$k+Z^w"Fa]6Mh G?熐>>%% QCVIVXw.N9sZ"dh}4[Z*"qPVn_~\fk"00ӿ.uM.haA#b3VQ&E Vs#!{oDZ{bzhS/1o?_t=&`su,~_pRm& `]O{h6Hz/+.nB)|ޥSGZ; ^U"opp~\ MNm:&;(=8x]bpY<[pR7|bÙz߈ +brB3YGo)I7ī*8J[B.(2FYSK!`mBХoaº@~KQ2 ͅ"z WPpq.h& kqJN 6:Kpm_\bJv@kmʁ?A8<; -v]vVm^U.._uȀ¦nK#ĠC&3|&:4p3)ќ>Q e$1I')U}"Ejқd$ {?^< ŇV9:?X=$[ z:/Yk0زe9u}a_/4}vu:ΰ+|+hP(Dn|Qbx9.]Tk[) [i@ 6`hyO%6dIEDSW| 23Ou I]Yڀ9o (G.'iq|[Tِ% f:!>aNL=,ڏ'l Uty!qpOG$OkDqd@:Ihと[tBggh$Awb!¯+{MoGd? -1,mmrs>?Z4:+"m澧:Mma?ޒ[_J%R0bF xs8|?ex7,LD=EJyV>ߣa񭬑ux+޶Tty&4f.B2.GWzz[˾-a%HLBMDV|64oF<=qx;86Nȭ>ɵ-sLAxD7 }5(,Ef5V9x, 69v}?0jҌ2f-i$iv]!Aן4 M"?D2GCaZͱcטt:ά%v[2x-eƪ7<6A~L8v8N?Zs\WRffVh/߲+k3k/G&w9tos9H6sVh|~̦%+_e ^ܾg]ckz߆e$@?O 軄W1jdX\߳мz8YpEcތ!M(o{-r,`' QaL? 3~ Vq:[MxΐǙ<xFendstream endobj 356 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2595 >> stream x}Vyp_FY*H+PBɐp0"6m|ȗdI-뾏iKe!h 4@Äɝ6ܥӮBLfvg~o`gގbYvYqUye 5Œ䗥g8gSϥJSǦvOTHO 4?l|s8{jjF!+$ŠJ`5[}^PlZ-*.5J#٫;EPNPRVY\S. vokwNXRƾkK+u ڲb Rّa~Ut1!`Xۂea밷ؓ88XN4CrzSʴ'O+•>~4<c 29uNw[d6Kl -B!"WyPXY<@ʜWcQJ6|d=n;.Ƽ=^eOR(v@ )kdu{֖ ȥ1zeRUj7Lڣ\cX | 儏;i C4m!xZq4 *FAh 89 /AICv'́M>Kͩ'bz[C2/ɉz3}c8t\8SV۷uwur~ 7Vrs=)0Ξ+ :GW9SYߦNKpqm:6 ,x4d(6_&STz =Ԧv'P+2P-F+~@3]cC Gk%Σw_J*6MV*Hez>{oUZSlO|FmwZڐg2 [hӹŀUnaڻs02F2LDk&خiV9Ț+z.[ ύm'2E;="15E0+D`E y|XkhE*C[d(g66Q71^E[Za;<Vne17|VL/U Гgb]8X<'q>VM:΢a񒚇 iՅgM`32|c0 1s"lv$lԁΥo5m Ղtv6p쵯nԞ yh/^):@u=A:=}h Q'1?l]endstream endobj 357 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2790 >> stream xe PW{fDԺF5j 1#>9nc`oofpDPǪlHbl4zk6jWu}"ڊD|Cw/Z<1**gX" $`';?;"JM%EI5 ;S-X@+2Bccw*BwE(6y)OP ;v)"Cv(v(")}*;6rbch|XD(ANw3n%K=g MfN% ObE8ML' K0 1i aM[8Vߋ׊?vlbi yE~YhePoV8,Ģ29"9Dw-VHm|I 91-a5$xQOHzđU}b#O&DYk$SGX;񥋵> $FeDQu1bdhڬx2vEC6hfU SSwm6&M njafwX|l1;>AMם'CQl"48U =WGőXZYj j@Xݢz M΂@==eo( p4*-6E#޿*+otSgυ/%Rg >mW Av3gVVu)mCxFKoe4xȥ(;Z>]y-x*6:Qȥ0c`YDhFC<2 =h '$+Io*)mmUB:5n !`l8d3apbL'i+jJ˟ #eFY _4X/.(U23!CxWJ_qꖚ80BF-).O"Ab.r|isüG55ҊZ#MZZW \N43ٲe:,'4Kuu[`S9Έh(3cC Z3Ѥǧl "]lY Z[$ h @42r//ݿoh'@%pZUI Ce+bB¼p Zuݍfj8z fjVvWן:}ocIo"kX2Yh;DONwK? h\V 4 δ܏(kOiߩLHNlMaf~/.X'# P5Aי/:7SMcruT%p3]7DxwyS(x0+ XU>W'`6=R~ F-*xG^| M挻p%2 ۯ56R›=,"_:KkjX,){;Gmx#sgb㤽-8(\W{W'-'?:ѿh,YZ_]T. d>}!evL|Š$M-=Eݮhg?WhʋXچ@FYSBdt|(b 2 *\ES7ẃUM;B2{wIs:EZ8mkOyLsLNtQ KKF"kDp" hWVZƘ\KJK T4IRb}]e5.x;v,9#5)pgZn"yuj#Lwn^4n7;mvѷ2d䧋> a‚RBa/ :Ē83fԬϡL` .#[s#: !bF 3г9).lc5~_Z2<sbBb<""YK:0w9T6[lfgi+mX"[=3~VFϊ \$9Ƣ̀ZݏV)ȡ~B=,`z [a1,x,9PTEWQPdpM&!7pvKJ(5dg=G^CT옛'\CJ*jns)dUpzW>$'t뀻Q J% w=w$Is  A -' :lR=f##k%h*pH6*ȂҒL7~GX7A^ORa/Wހ;h<8o$v}_ӌvVI#$k?`;5:^Ws\2olendstream endobj 358 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 744 >> stream x]kHSqͳv\1#sD4؅.RҠb:/yL%K6}Z3Q'X}bTZQB}*AY&Շz_xy~ QGa [A[ÕYs( POj^nHBA\bݥr\PSVjRSR''*AʰHmELU6[ieR\%m%\"Ky9sMv$YoWBe&&C$h& Q9l`2:Ae$Jɉ 5fWQ:BaѮZ3p܃G4 rvn?ao`iig (pu9 GC#pt#`>P%5_Z{eUX>QNҳn֚ 3ҩF4F}cYJ;%MhfLfwE$(RQ.!=ǘnUȇiQlS-՝2s0$Rz1 l#ϲ(>36or0_m5.ws]2pu?>v4䷶ 4J2D0a +=&jD֊=R^7j8N%:njzhB.:<=wt 0f~P=/tV+QݳOv?a?9zOф/Qendstream endobj 359 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 746 >> stream xu_HSqmese`n3Q=vͿsvjAQdPP/EA %|z ]MfCy89>_QuB(lY76n+0Wڭ4Wڊ$fM̒QL@f8ۈooucw;fg0kbORBba9[[/ӳiamYY{#[mcklqUEM1O_ lyi^3# W{k+;#,.(JI: (|wz7vMP ^b;; I_A~|<>b z`JvI)%%@\@vH=N'EѫG 7opzK?tzhxEymRxzi3He' z;z={q `ZԉJ﫥mhgٓ椝JzNnP'h> stream x]n!<o0۰61\⡦Ѿ Kp=jLv!Uug\eL9T-QxIYh!꯮aϣӇG%8 Rvÿ0Ƿ KmG+؎ nY70z؆ -C_6N4QΩugE\27U{66n> stream xumL[eǟK.]EGlB#^",M97^;\  ޖҗ9^e2MMFݜN5~}؇Jyic*جV%Q&˼tg`/xL:;R[`>PT\A_ [L-ŠB֯~n2-15еGU՞~ [Mm^j>h1YM=sb7wB( ږv""zB)4O"XV!Ԍ$"Bl姅*rc~EJʑʵ1zGF&Ӎrg&y(nq!"-B op kSj[I{*Ll/:ġTzX~PŲG K܋~XOg{p5YvE,Lsν1 E"F4(, `tvu pW; Of`z{@ARbCu:|pX5\t:UaSױKmaNh`c7\ F v){{G|cA_WoVW셅2 -UַHR.AnĆ\8A`YwnJ6(&6ø]/FEhŻ8  &xs'~eB:?3NjrsaR/^Θݼe\}$M}/yJ/fLm'o+01o;p]}Ӕ&%hر>O,ͪIG⋛H~E(ݞr]`gum 89٠FbSapnT Jά[+ʂLOfCLWX дXr쫷 @>Q3'&g(& rFէy r2{(bMh̅DC yf.G"$J%#endstream endobj 362 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 698 >> stream xmKSqϙSVji5MQô$#*iVΗ&nm^[e;Ͱ9ң EEQBwe<P8~B6kz]٪:/?9g 2ro/W(D­}y1+B&~EЈQק5UU5>OjF:9Y0XM:R=Mr`By0Hjzj}/i%zTdRx?f"MYa.°6܏daB,og߂ӥ=+Cg$&'\679O/ k>8=2f6]$ Ӭqjx"i*XiQK,$aahtD--%Y&(#6W,@w-OFV@$^ZF10j7!W)vKKE&! kɨ;fҩD`L'[&|_+Ww= ;HSmw>ľyͭb_8nwk@Ԫ>h6VEB.|41cAO O=g4 EA=|Dr($}xs=0b+֥#z-if W 0{}& Py\BYzOB@0X6t ajzZt> stream x\oFrr)9) rKF4MI^ub%>HyQ&f,g眪nIjfAl~$>~U]O\89DSO>M^8=u⺈SQyQZcZŦ (l9Ç Uems؜)%g}Z>ldו5|9vPyQTٷKwƾ$e'Ժfz5ګfRT\Ruo;-c)eZίO29}r8=UYۗYY9*u%k \ƏL(UIuֽU]9ktCm8`zĜg1.uR4-a;j.k LĨ@Xd ET: t2~M=^) oƳNHri @No_op]KeܨR~Lvwa3-dn9=*70۲]G. _Nܐ:uxUUn$|v{< _|,yͯ(nG MDX-I^f|sKA;uHLvžwï"(SkP{#`َ=EITXٜk .A$&ԆJi[|!n)=f8WC05~ei.~jLKeOpT`lvp1|\jO.cձef"P$(Iic߲u]!A˩`6 5 KWIh=9Y:@7m6|#)%6a`DTfTV#+% !]{DU&?29l9c6kVگt},xXb #F{rAP&2-/3nr[toܸ?Y]*TX4Z%b ˀlAKy~  そJ諷0DYpǡ`]!K&%vM<#3/RD!"IE5W#ڥ^.½tak+RvWE:`EP㤶8L~=뵴&ծ1,"DY@T=-ɿ({z 2P2EbG,#9~;Qa ě.rk ecbɾk~uIBbJ\*)V%VxB #|D%U6ӝ'.%/& -|AA)20L5qo|->ԏH'S]*~! 4L'b | 0ҰxH'D G^E{:DAdh]0n>a\i׍pR:σ"L*,hF% V\W nSUp2NçGG>Y#$/mvlߎF=gč֩ Y}]Ҙ ;2Y4kwdžҦbKL '%7[* ?47/:Hbi yTUb.r?}g3V` IĄi#|77z P8;c;3M6@TRg3 0"$/6^.6@mv.|ҶܾnOa31KsߜM9.CH_GY3A2׵f\\VATrML"%\j98u)?޺lS}0SمGTso0=O5-1`x۹1U|a7 j9j޵[d)%uaEwzܨ}qZAeN  <%Ėhd*=s0.JN#JLBu GG=˝{6CzYH ѹU~Q^d\I!R8!9@;l=S{r=v[iKӼK[p~ 44I uxmXIW!rָ19vn=RΘ1k-(1cNú\Yl|bw`7esֱd:!ڵRA%Rg\#>\~_o9UE]swݭgJUT*0Z&rœ{&3=e&BIsLplKkcT7fECz OMXfrd,`c{h? XPd)?)J_[ 7ɨتFuM|Is[Ul5/ Ok4&%Vmu `S;6*U |t՟A%DwB!9dϚ@ry 6T5MM%!$>z]aܪrht\$C3ºZ񃐏B|B@ eκK.{~?,ibNR$ě~*TQJJV$E بĬL sB/2lbS"t\ "F'tn+S*qZ&:`йa I]ĉe cK`IDZ>RoW!M-39\iF[)JؗT%w8[.){nq`Df1,0=*\M]e1GōxP:ZZ }$ċl? >ՈD;F/H4ϵ^Q4"e:hϴ! ԪftpS FNXft-SCUIb'i@ ~ϊu5/kAuWQMu#Gt8טyD^4_ɖ 0(FEp7"b?_.L]ӇFLU5jKXNYi"fU;Np&k@7AH@BM/48)0hXz`j@! ڟ %ܑ %#fe4tZY<)m9`z1LUJFa4ˎӝ/d';*c{dwBR5j"-ɔ0EVuJ&l˙§ nJ+FH(ZloZ~@)<h_Wp8,_İL0IN/9Krt`/-j~!\bh-0RXjF4aħ㔔CG_Ié7 ʥ+[W*jH.y.(7J }tiyS\Yh`sI+mNFwަt"SvwްMECw3h1.eͮ5)4rClwCE^|L|Ug;#I!PR0G ]o_E.{P/Ͽci&MZH4nSxXUwS`6^d noӢn᮹چXR3paS"j|> stream xy |SE-%װkA첉 ȦTdkPP֖m6M4i^)Q Pp{onJ[?HZ~sΜ99yDG999X6b{Tӧ N?ωp~0?9rȅچ(g''wcRBCgL>sTsEܽ ćo5{h  u#0d{D{toukYlͪu>k_?kDmXnL쒸'z&I'X{UA>!kB׆X7]l|ff9zW=&m \^b +kuΆ~9syh Po_ò?Ф:t[NKU45"!Tj6 tqQ +7#W$~F£Β{8Ί^K!RY1w.%Jm hy[kPdCmĨ'倨XAJJҗ*Q\iTm(+db褪BJ@ @:9\MJlv0U+_Y |2MvGFѭgn/ ɿqe&rA"cSUK_5S~$fr:h[t o u庂XBtf5Afw|Rh|#]DfZVNJ nV\?wh-aFTPMb=GIMA%ő3 8 jIOJŌBfqZPU'x8c'fsaEd,7U@h oxN̶H)@szshFX|+5HiȰ|n$؋yށu~IgBHbs~$] 0ۜ\P{άCD/ !dFr#oKJsLq{ Y͜e&Idz{: |hZ pvAOF9ơ9`i5B5O/w,4 M'`w|< i5>yToĎTx2%I30H7^Cip V$ pnJ/ ym~bJ .ySH'i&<5LtIw4d/;i. &AmO34(ﰧVPAnp-+Klu6b_Mnm _SF"}xZRAʔ,RS둊*՛ՇSd?eq"5<1c>Lڈ  `כqA: 'PDHՙdqb{ HRbUw< 3Z L򘡆K{9w"MFN"sC:$3-f;0V]..az&L^K(,6{\s/WJ:Ke*}Ֆ_ +=|7O 紪V1ܖ]} \ ~DR&(2Zcu}zPn ԍPj3#7UFx}+D*R!,3xq΄$XݻCsADM '{% /g]:GAKz"?r)9w&' K:gpT#o^GMzP!ٮyxVTxC>[0 9MTW,)~\^܅o,c[v 9_:@ehe+@DeLŖ|!o17e57֚cUPufLW?XN O? )hBNzc*` 0󁱼4Ml# vp~9׻fo%rUO%m[n3 u*"s F3A Tdž\MMfcrUzՎFk΁oocKr?|{y ]NJ᥉,2?*" m⏡Ӝ WQ&Aͫ4-=dn]іЕqۺj{Gjkf:ZdjH&M̊D'6@Ww埝~\mh(bAeQٝ=r@O͎'+p5bMeKUFDAAn2lc!;nM$1OԬ?@ \p(GOՕudSmG9ԇCL2S&d/uwEnvi {aoXϕ3duGu?hJ?eθ2'=nlEX֣9A{7d<fTs;=:h샧G;ңv7ф3ƅАgKWGͨMt %u&`2 1أE$8%Eͷ!!?"%b !>h o^ZH+=h9?\DC5]ߍj}E}{̯8shV8sl\U$ <>||Q2mG8ƶ;_^Rh$=DthX>' \\y H+--d-G e-{R%[8E(`?l1rZ(hG3Jt7)XM +gj؏+®84H:UQ8|4h`X:'_eX1̍qJbey7ŚL66}XWjTߔ[jæBi3u̍h:X+ m$t$uV&VzDiUbh9wy>e#P.;E~Phi{lu..duvYvC0B1\I"S}6Y-JqD8꙳DgCHisA2ZeC(3ÓͧI%>=|djV?,}f;Ph,ɐsgM 4{B +b+Skb,V3?|_-(Dx#Jd2?W62XrJ=ƒJd:6\D.ufwa VgADWίllީޟ[ӗjªv? YZcG>9.ȤĠ8]nu 4Q!=3Vg\b:sXiUƑ'ӄfYrGiOP^*%OTFGI$UyŒԪPi\j,,QJ~Cnoh(-|Q&\l./.i6;Hr/~}&3FBA\oѤZZչ*4>U4N+Q媚> I#)w.)4U(-Ho5p/4[,e"hʟ C_؂ְHrWJMx`)Y -$֖mh]ϟMlsO[y9Js4 2Ww\]p@ G 4XXhE7o^ n߅6(V4jZM/jMGcNM"x~>=_iy hU]k5_ni'q ןȄPJ&]ZD2o+O'W(07@ -r`0i:ĥqEs "YI8 $TFgtylA2|ge~h‹f ~>f?NæLLRHvrl%M$nY̷,hx+$B}o?+^|֙>&JwYہ#O4܉tևC DFh"TA- _o!Du2BQ}wŶfnPdҵiڄ<%Z:v -!Ru i )fD jq0TcjH*ez uUh댥,rB|D[=rz?x*(bZ' *4%hhM& ($ۑTZNVZ NJD EnFG,< sJrnB)9V/UwjY6YfQq) <‰U.߾\D ?D*: !] c2) ɤF&iB:i;n|yZ" M.W|3]疕P^Jܔ]Qh'o)&_xJ&i!u;nEMˏg;s?!c\W"sC4);)XZ4+(Z5w>,BK(>ml4SWƃS0LN,n/FϳE99Ɗlq']R_1;G7LDexb_Q*])Z69_]z>i*Z+qgiyetOM^kӚgnP&4R[Zn,&h}7NQchJJ4X{&”FS^vAٗ^^Mk#4#EczI501,Bo!T!2ۃ<ҥkiͼcЮI~[aM(SXG 9ٹX,QyZIW"r>U=;;:]{yѧиߟ)}={;rt'{==GBWzqExҗ*TZ7xA`j_G zūEz"^,瓝`|SRZIx.$[x)_ |* w [:6}Z?Je3œSuendstream endobj 365 0 obj << /Filter /FlateDecode /Length 8801 >> stream x}ߓ$7rߓ0qO56] 0BBd7L~hwۜ!{bHDU 5G-8nwvH槛qgnFbyF7Ǜy?X_hsM iW\yy|1ۗ9/yK_ݎ1lK/>. wRp<֯䘇U(>х"]8vcB֠⧷׏śa4?'+%ď]y73=:pCx7hcix:4_O߿`ltc?O7ܼ直]ӎn":ng=ٰ%"Tdv/~\°9,̔XD#61]?!?0Ιu7!vgͱ<Τw/͖쌽JѾZqe^cߠUR[-vW)׊zli]JW)WK=ntaUR-øJОqY Rj.@awp{aλ%S0扩mO넎F+S+  t *ED_QE*WRX T]w3Yt8?R!pab)ebb}LoK71_^lĭ݈T&!6n2ƝpXvr/S6% )&w21'MaLw=^Sʻ s/HS9;S&-#"Rꔷ)#EԨ\vy>a98O1żsei+ ,1gw"n/>ľ IvyVOdvݓ,u30󈭣1r'1[td@݊l@ Sȉ:~ k#I) %z[DSqx`Z #3L)pgXc\&2)Q7 I\J Q&A(DnF]mPb$F3X'B9X! z:b^[XryH]sc:87͘ ÓѠ'`F1 p;{p1VcQ)abyP2<&ac9>V1REDUEi5-2ՕZe(xdVbLC敮^q ֓G|EDi gQDttcOR[Zs' *`Srf刴)8ŭf)SoFw1T?(4I lG2L#(>X(HHfK]gH 3*~útk[5%ިɐ'q2SZ"=}G阇MYJY1u5Fc㥥"t긡wnna)5Xz q;20%QTg6lآЁe}um v="`d59XVh) 509@ab)D,&$è!f:rci6޶V,I+aTB8c/$/wt':&jG/>(# :rl,0 gJUHTI@hvVyI!L㫾*{*EfΆ.Sn+ Ɋ#QC&FV%cfXxD)[ j z0֘G}\|7o~j^à@A5@ݨ*¾QnEVt,U|+<þȶ4%1HnƬȟCn]Z+RH zUY+ }͡KQ$d(T|߱5RO ʫ)(K [3',7 yɓ\udV0CkjX H( +a(z rq_~'m4J#৽R\<䑪KY)ղIj\ M~PWr`-5)WȒCxITR=ϫլB5`7զ+{EEYQoi<0E;̔KѡXlaT#0*`kVkR="  ('#4IX;'KC\Xp֚+ p o۱.]8SI1  QBx ]i2"iB J+AjOƛMCS@)S]lT# m?*P9<& #LQP!M W%bpSMn/ӻ]_(®ؗ7ʒ]/o%Ѝ2bCW(^>~1+$z$W0[ ړUY5<@ !U6r.s>/ZP %❪2\szbuQzƻ:&gbX 'BDŽL\F]"^<<<583[e{cNc/8l%HR'ϥr}ק}٣k'}ye] 4}/lVYxZFk]wXk&=$Î!G&Mc-X]Jne$㤪‚Uh.1oЙX˒(~b\ fNM?eL*EEhi?UL\Y 9~D^v ÔV|6m7 쬶37DDzGVE/fV`Xp MP}αx+\T`O&䊸yM<՘ksl$Az7n:/孶r*tՙNB2sRѕ:rhW2˪}+vu+Fq1^<G|NKUL?w3;*NǍSrt=Z sL6UABI_LـB=\ u]stk-R%› s jy!Γ2Gv0%s!U6J}}9pdؕ9tfKbJi5=R[QZћy qGgQxo^$-R*UV%>vT8꤭εܡkb`YPԈ ma2#إbX9ޚ1-АWaFw4p*TXDMt9)*Ac<I.sيޚ'm8S.p?֫/\p}@v_\+).\[ry\mԾ\Ji1-*RYr)᪆ઔZłRj Ji &b;WU S%4᣾w$j4Iix+}Ci; pigpᢄXjOA#J{дJd~D? D sy;D& aI/7N. :3| {h7؟20LGWN/M6_i~7Q9jty6r_1\Z.dnׇ^w<4NpY_w˗W=M‡2/[=Dßa7j}܋^/u><.eLp~v,4ߞZ@8 0}I< _L|NVB9+^YE|n3݌exאc}`ŷ/>{?b<)#ݩe>4_Ou<<yYCFϳ{ uc.ix ueiIcᷫ-([|Voi;Y8OɪO pKee\Vԕ^+q+y&s;ыPp~E˔,3r[EBwM2{\zlXKD[UbQ,Gqy:RjI[{[zMKym5Oqķmxi WY;m߇SZՇ;hÕ7y#/R q>%=ahzV^8ooo6, ֝Qzf>XUE43g7ѯ;;f[ ,^zLJǧkSKyz<~ 8^˰~ _٤(օ׆TKGz~Scg{xp+ua$X"NF_/:8?#s9؟7/=f$l͖,ԣ aLmFЖY݄}>2ϿsvlMiTϿx2;qA= ȫ+t* T~5͜8VE~io8c+H_C/tbp˩8lB]+x:|'#l]?2FRMn_d}|gRhp*5}N@lXEEW0OK=Ԝc D,{T v|^.=X>¿p r6Z9 vĥ&Nd8.'k6zs*#_eȚ1~n-HoDGXet II^m:!g@ûPtZp ;kw ٟ8k+%YQim?&)RJ'vYoW~nR]&>:VoK~QƈoLu;Ʒ3R X2 y8ZU)F l_Uhq?|4o|/^o@, տ@Gxb%J(:]#@wphV\/vEzN}'Ϯ;\{Wp/t: "ʶsؤ ܮe_ O\q!nR :.Uj1BS[Y%⭋vCO+zu9;mY򟚝~,z+.>it]R]ߺ(ĔKv,woh93xh-D`?.rcxֶ*JTiLb_ (la0S ,*V hvygF:+Z֊NpQD,4 jtrU]Net֌~|hqA:L6k()rC:X,|QaCVaPTu-Uk/jḗ;'6Nok}Khh? cYj/iJA!V'O_sIenFn0̛*^ tŚL0$Z.M"YrI6xllfD&Eiu}^akXX"LznkҬ枪| ݿ6rhZ]͔ϩS-$lQS$J /،?(5*Aٷk)oj<`wowCsd4uI eߟu=4S]x>-*0a.Eٿ[P.`/9*0g(P b|nkt%odå6#ORcO˲xPoNJۣꦺ?t%^WˆʚGp+=Sl\w Y׼V^v9qܩ$NeڠG9:a|V0RE]rwpw>a14#v0dz89r~Hԇ.&-*v@t4 ,e*"ϺG*S%8=gP0v 6V1M]Nw^+ϲL[DFsF+^ۧ?jy,[rK;V|c_MՑn@PJ>knQ>jD`Ίeg⬏_zއaӗPweW7!=>|!ƅ_ޛPDt{>)XxrԾ5ek/_^ZM$m*d_īo/4jaLm}u<]tϻY_\coDuZN"y޾;o.UZ>wWendstream endobj 366 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3202 >> stream xViTW *e v2 (iYd'bMQqNKc@QKNP@(MVkk9O})c#i5 '{ɚl$Y>Խ˥I2!SS6f= GCJFswEEO1aqֺ5)JYnUIYFnӳe$gX!Go)ef1!? )8yuHJiQγ\\fQu7q&ER˨*JST$ESG7b(D-|YOPnRj6HQs`j,eA8JSMYQCFS3 15*6 0#wF*4 cxu(J^Ș3LYW6~l!2?(&kM2L.P)ĴKΥ YS%ú 96eѡ /LdÒ)KuT kI-PyuÁ.KkT&˺7^x#1P%)ހi -ψ4,m+P+3۹bL`+,ﰃX% {xL̰6ߦ K]۽|])tY*& q`af3zaGL ̅wb3aH1boC',_;><㻎\ج)&쭺޶9q̓bB M?\Ɍد0-}K0OQd"d6rjӽ B3\,`§&)oTkYZrOBbv[C_O9Wyd_TSod20e4T8L`;'VJerCM?nßL;LSƉVrM$*97zhLFرoڍOłWEκnz=k-Llߓ5x}zXwggs/qx (kgAvU@\@ź{W}GJH8S7daE8Sx"A€J*}-hBdGɞ:gO? آ3N.[am_o0>jBe~h#<;y[>r`|vSU>WkNnǾ;)95h,$I% G`^ߎwspmHhhqrIZ9ui2vxږ0fSl'/{O^:}qb=?OO*s .䆓g4t;`k`l5,~d3g3 ?8.S/-y> z#&J?^^sqN {#>ZUZO73_c[3VBߌG|dWB,Pc y"UrB@&W-6/񺹴2q:`=~f `^>*Y,_ޢf1GNR‹e3ϟ^/$Cn`Ok [*lhp5Oݢ? Œ“SWP3lǺ~KN)wW%xLVN//# ~sP"<&~E co;|X0t[He{9WB,᧍ײ:'`VPRWhTy~[I.z벶xB#jMCAk[6tY6'4v7XI q25ī-7f3\-; FHp\Jrpa Qe|:>,".>"<^fzC##1-IGOкĶj_XHl$ g5r5-]RA_@|OA{ay)8I;<7юj?`jUljFQendstream endobj 367 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 360 >> stream xcd`ab`ddd v541H3a!#kc7s7ˊﷄ ~ Ș_Z_PYQ`hii`d``ZXX('gT*hdX뗗%i(gd(((%*@\KsR=Yt^:^cS]}S͚=gnMwulݕUsgkPW]U9{ulsguϝS>yoݢݳ6T]]񧗽tJ%of)sv+q웹6sq\7yendstream endobj 368 0 obj << /Filter /FlateDecode /Length 4040 >> stream xZܶ/"(Pm7>4u6+ ݞNj#|ܙ!"ڳ|+ !X9[]oϊg.vX o(Ma fu^Q&/Zo^e/E^(aXQfr2PCS+!8̴ًdÒ뼴F'8AEaɗvѾ":Q6\-,^4%GyLI%+n+";c Rίβry`\.ʼI8b%%[`Gʾr˒g~E~S7/Y? Evjl9|bGjow],/KϿf ^X fKв7e f)+!n",~9y2=~Ҕ˹K,,かnľ;0 eaachQa%s ax&szUY@#WGʀzO!6v*^2GY>C"qDeNBƋ\(%r{q\Q'\xJFo~ʡSY@IKK j<]7%zv~jѝD!:JJ49:,cO KVF^e#FsVaW8.zklV֘Xf*+dgსWL`s("խclA]_H ^lN V^M`Zq̿yG'ߤ7>0i8<˃\=gp3мv{&Eao6g/1r-Bń5ɒqm%y,!w.4g4B -HUkx5Խ\I**"\/X(%<=7 h2غnԄAQ l1G`т*3ƾkv DIv%D]@ YsnEe%QZ5&d[O} - yCEA(7n :UxlnX*K둃ui.ji@+'I48}q2x$9CC1Pڐݰ|BZİkwzW#JY/$WIvo:fhP;Kh>I(xxlhg˰|;\PRB{颽r\t?FdÜ [(+ 5Q"9 !C>k³K Cu L,Q}>"bN1ĎpTAImW(K~S@KCIz}h^*A4Qv~`p =EeI%ӝ8(MIŎМT:v0l#wuWovhLy,Ur" H5!> is3ܰ9ܗ I$TT~Fh,!Y v0j&d8GΑ"Ox2odLj~Zz aX5fca0"/O'PDtAqd~sbÏnB e _8NlŴk氠4G?QѰ9ďcowN FLIGOf%65٬R@1< ): 8=}Ht.W}&Yf~KY &$'21+Ej,YR:OB5sz*Q+97Q%M @LSuoD% ;e!R :#p)HqST9V7(61cr&Ps1-TBC\tCTc"@9F)DٷPr϶\ 3ܻ4xf&a;OxSе;dt^¦PN 6{ S>轜BK;êyn܇ QWSQ<)AM|I(m.M8asՏ D^!r|rn-G;bq`3m" !@ps=:!%-JTt,n VۣӨ5fŤu!| rY^H!5S[ MUii]C˩8'm-7@^0m:D]>^%{Q_хF^/j| fdj4{QqARP7Y6>A5YQ m+@aL{n9.D=,=Ju9tMGg,~C7֏3w:Ac)R!9/=YFE%'AF6<$9TURe,N!) x>nyOfA865mkx؏p|1r1)H {A MO,@ gjl-WKs BdTu`C+ kOM\|;˷3T[EcYM,ձ8Ls p#2DZ+l\9y/B`a+Eɝ-(r5UU.[LA H1MGEetՕ@6x94ka9^r8?fv_SةaNv*c8e{n [ ,z=!#'a*zMuI!Һszn]}:!:ƉG^bfsEv5]չ¼ɶ {n V$zof@~pM3lKh^l(6 \vOMj}׻~ @SXVXY(:6^b9gJNendstream endobj 369 0 obj << /Filter /FlateDecode /Length 3844 >> stream x[Ko$Y!p  ܓh:7i` A^iF]ys9UE_aG3bXՋvQlQI9ѷv񏳓~f-|Sʱ_ LZmO΋'˪0rz?,iCvJ[|QZr]:kTΠ=*[|Mx?Ki&0QNZ[lYgQ|\.9G˜U&"m|<+S2U| f`+r]cp-(sXdU}ܶ_!UY\Uɭ19\qgސ|Wl:_"_]yR; r%%%Q P>t6(le::iwJ©_RILEd謠R -v0ה-Ӏ}ytpl+YCqaEuyT 4Y} IꗤNэtm 47rV܂yXA$VNRH8] m4yb9lK8yX$)J/J%zR#I*{:X%ukNQ4so+Hw *o oLݿrxHyuvu> %U](LNKX:-sJSSV+5񑂱lQqvD  6zƔ.M[=Rkb0 5JaqO ]3*x7&XBS2c4d>-3h64ͅ LSL(HV SL/%KJU0HRZg%2Ѥx{6aҀau(h(f<;& 3usY9gw=!l]xtOS:[TqQrWEfs=)!-A*VrMRX#7).OjH1}5(D~׀e_sIACbddR:Wn;2ldqEVTVby(:l;B4/w9x#> V72*ǫe @ЏL^X}ibes5mwy4ʶIW=OXM>;[G+H.$(fJFqQDhˡ|m3eJ@,W;WLh$) #9BP8*9ZRą3ͤH≞{ Q`,$cJG(P7Aq%v3I*IyKEz7,%|(``}( B3m):*>hmBU Ni>s1X,0@WET 3$uo̼e2 +(N\'Qekny4 (M%#UwΛ&ɺPg"|h@&hI65PF93.ݶ'2%/N;W/$WRaa|^9]d%st[>@<&5gU`;0T\mWmTXHNn%'A|R ~tasnydC*lti+u P*/ k Pf* qKo1+^6WPׁӥԷ㼀tQ< R׋s}~顅@g0B`b)uZ%q8': abҖe+XM1Td' >桓-C6;HU6oȃ%Tbdu?GUC H7@W4y} :B OS4aD,CToOMVT?,z/Kc!8qF]B?F`1tuqdžH].kX`Xu7o^m}bB^j4a0qSGd1c f?IBdRگg_H,+sf{hE>ށg=1苫4`LQ2XU;Xkstpq ߋ?^߮\|O {h '/mU*@a~u3F?Z?hͦn}R]޼2!x"hopÙ6 7J"c?[TLqdiaȩlW ay%P<E.J# @ut5fBԛg9kCšA'd'.IHE"ZA+r2h 8c&;!@~4șHPh.Wy&g/HNUjCݍk&^rXcЖF(z>C`PX '&N盛n;JB$Q|~H~Ћ!⽏pz m8y=ّ)@ B[PSzAifl8h"C샚60ْ[2UhQd¾`XZ#6>{`>,F./դ{Q|3lS{䖍ޟL [en m~ _Iލ3[ ,/L{2NJBqKSUI9ׁPk=muɱ^H3AeK Cg3buYWb&#q Fx('1@?6, V)RiCiA g|b:#)m5R,d^AFAԩ2h>|M=4 |4 cSUCAf@VA¦Ť̍3k RCFiw"_ ta47- ޹ +yLO5f[6bAݻ[ҟCYo1ml$!r}H^sK|#Ċ&"}`Ńǹմs=M"5TUIv;? uܐ"=`Xyջc=|varKȒ![RѿH٬OY?#BUne < $ à '-F1JetN œaf~|fTp< p"?$X>cMIE]_[`U_dDk=<@/VBv=x {H^663rjx|IcW籜S6}92%\ph~ԛ&osI[KZIx5V.EWt<@g@ݰtX+ڎ f41]81f5G٠eμ>ggZLZ .T0Q|DWtevZ%V¥S0E: m ;qBo.SZ6O."vC[xnwn7jV\uɂ§q*fbΞAP7CtP?ݷmA. `N.;:۷P?' Fנ;MÅæw&2b)JT1~zWendstream endobj 370 0 obj << /Filter /FlateDecode /Length 3519 >> stream xZKoA80` =7y!N86hڙh$WK~vΩ&9JrYb_zw/~t-tycIQJ,.o..JS2Sd nT)x6`cϒu7~RJLǾFYJ[T4NP}9/uu\IJ/Siv $+MssQيۨb_;ìV3NvJ`jy R/Y8dX`=e\󯾸bMm7ݣ~s<*}u<ڴU|벷Z..Y_p]X^.Vp a}\ n8*@V8!MU[ZUQ Ʉs% S>S' d"@) !srl+VQs5#vX{@N\,Υ`uqf^s}P_3t&HºXߤP%nLJ6<:𮄷!j"nny~vcЮϾ*gv G[&uK{Uo32A\ACQmQjG_ي}dY&ǰz(dppoxz6 HߤnUBCZ$L ;N'@< )ʽՍdprA1vidToWCηM@V,4ϒS!+PHℼPF Fb 1/5H_S:.=#|D/uŅ}wO\wE{4({'FU,I~,!ok4Bx>ɭ9Hj^T-U=eHHudW m[XǑIh"E:U2&poop&@߷̓9dfXFfڞs!d*xzXÌI t,C . ~/YM ,~S4?MⰷĈ$Aq&ZVE1SxFm~/ Y_+_8;yMyA*aokOV~L x!cc,G3< {'N=i<>7g䤤[:,jڗCe1+RI#chXi:gm#0iRfF=3"jds_CUC!6 1E^Qm33w!Vw{'T-; c[Ldr2\aqx~ꬴp`8&z Լhx{iW+%힚Y[/é>Lh.=I98%-=I"BkQ?x=ZFsl U-vdwA0M[v c Jv0xnd@K ДEF/?sd^"m]2eˆ+[wiЬfY?~ZFSW]"R{B(DOߌ}F|,ѸTBmӆX u @d1&NZt3)Ф#Sˍ1h-='qx5:z<.EVNt~i`ZR.IBY֟{உB@ %JpG K?`53+@RKj/.{6[P3 R.H7Pꉴk$TR+IK.~"~ҡ<ܨ ̦Em/7%$95i*gG+[J٢u2 w]eXfVӨ_]妑pn ,`0hU/!`:rJ{~\ [pSBmJʹRse k Orp0֕yFl{CmoMw.!,+}x~<#蜺;Z*[©USzhYIqJ߱=:{/BӏajʻaU)y՟r>g$2ƏJH w'ӏS#'Թ|E}U,0᫉ VNG(:?D lr%n9>ӻVMz9.mX39#u /JU8Ň[qq 8s7`ߠh߶+l5L..wfֳ^-?EUk+jʺ+ݷ~Ԝg?lO=>hE@,>F< .meQZtٝ#X _@%- Yn΍Ѳ/h*Q(p yYGcM/u-=fG\p^'W|ضC#9X(d% + SJyJ+v<IH-Mh &.K)c妵@qrd댶4'Nyz\|NWH>6s&ό7tsϟ+SIH\U}Vm텖dO.~2> stream xX XT-(!;{8̎VVb^D+Mf af0>04p~2(v\?Acyg6ko}{Q#(H4nUy3W'*7' D£N_ĀvW1yt|;vRb(0\TEG$xϞ53yRx/ R&GEzl^5e2=E-4"X ^{MU~V˺/(Uq$&%l[b{hXxDd(Efϙ;SΘ)Jʟz VSkZ*ZG-SLj C-S~Uj)7jZAF)Oɨ ԣej$BPJʍIGEnx' qÈ/7KV:1#_KK@}g1;[88ww֙x(h8qOO6d@x~',;Ne2mQ.// G ޔeHXg~Srxza'`5 TJ%=x9ˠWtr teD䂮8.OmhD d›y]@3h5 נY7Z|`t%-a$` 5f5Jt 0~U ]rf?x;eVr8cI l~_,H)|vdoݙȍcBEysr0`[dpv[6`l aw~Ov)}wem98w0o|07nm.0hr>c$;jxE݋w?dXiktK '>$ǍeX2P[.G% $N vg}m}E G[Y7xw}n ʎ{?F%:\2tNKPHΒWQRKG17$KQR:j*-r` UTFmHbCu(X )JnJny<`abZ;n"l3dB^0`ߢw5S N(:X.<>Qަ؟{4hnm[ 2OOIdrb}a&0鐓*N.-48saIYAAǶ.y9YADG˓SOIk4VzJ~Y>P Ihύx|>MɨIS&0y5FtvQ^  5t,t<8U6{5qoXAG4Q]i$e sG#c2+Lb"4-y/ 6s_' KO*WjX+9Kyk :gcz`. ^T]Tf` }Z^{I$7"1BV='09s\9^xLڦeӖ=_hf!7!h#hHcO4_k%I ?.*0hU$: ]YvZZy ZuF0;ƇbAdu]?bl~*]6 ЪouoI fU |cdYu" Y>al0ty߁7hnC_m(Ct".sOMmPs<=?n?oyK^ MykcC)B6ķׂ![hBOCIe[ב !ʁnI7VJԓӱ;oM:K\ !ͥ7V^!W<҅Sk>ԓmv|VVZ!Y9q @yDa۠AaV $ۇZWBiY;˴F`/j{12!.5MvohЫs%U{^DHϜ%Blі/‹hT Z5vq bl14ͺ}G.OON&&v7vto<KL%EފF[1,N$"/zU(*~^{e8A8S7 ?ihlD ci&&J H Ü] ^%P`5[iUf; MIBZ\Aʶ9=Cq+=Y wh67Ñ0 ŹyOR>:!8XB]ɣUvj;gw?s/zRB1Z!SIoƷl=TZs5&s$=6}r9gJ1hJYZ9ZC@Qf^eYL`(59w֤7h䇶Ti(nO${C64k&4/G'qW&l5^C'CN`(peUY{]y9c~wW>JH0I-IƉvI9WӌL]o"&z &r}&DzJ'}m'BEC`1 51xsq;J0v蘁-`v@!0nњo>zɋ#S dƭ/%6(%-#; 4?:HlBb0i{{ncĢLHf*C(7k跃dI|?hgtnR3lmdJ ;֭!)t_\NȾlL近ӹ֌:}j+_!J DQ9q')G|^bQ5EXj|3uߡE 3TJ,$,y9+X5x.[\rOjxG'di{E(Xxe<9hɉO8I8nŲ''&^@O#3HNL.p\7 X؆H^L%~E= 9/̚SckגThA5\m懽3OZ@9^7/ 'ώDLmZk~' OShoh4h=ݒkxe<#M|S` AE ?2SiVD7\hm8p }B$Wl'NvI{|P`YjU$efȬDb~ 4V>r}pJ+IRbdRl`wЖid%`/:YVj) da~x.RCPW7Y=Q#o ^{_%QbN@icښ9шx{ ?~yH .HVU 9?7'|FSk~x rys{sM? .mJUTĦں&-_ҒEߟp < "h _@O Wl4Acјs3Ţ5V,9]n_.$R`erIf?RLL`t9ZQkɕ~,oē6sKoD=[ ?re)%RQ^lʁk@C@%R 8+*AMb4ճi=D IHmqJ өGI|w: rc2b-#uTH.s`ynYLfah_Nendstream endobj 372 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2447 >> stream xU TSW}1DTJҾk:ҏj+ `$!@BD"?-~TqƱujM{k бzkݷ=ܽ9WDyD"+fqD}rlL_$<>NxBjy={"#H1"k]4)i$|X)/Wi ZR!>_Vc Y<.!)6Y!(&lGmX~| WU#K5)iZ#ALlPg(*QW(j# Q[ j%ZMLQZJFSөɔ9ыq+<<<[iMߒ`1񷼦{5z9~E&}rHףSBu3Lvdn98z[V:`/cPlw;vBKۿrǪdV%V8;nPG/ ջĂ%ːO]=fas{@ 6BЈ780~B$i<ǣޑ-|?N4Gtl:y\M4£iǮc'A;/2ua;c%)=zW=ˎ!! wZmV!tU*YAjaXCM.@[WXkqGx#_$;7l/WAak`?0Ry4sDzm*؄- ^fZx\{0;nS3lfIs7* 0 tج왤@ julD^M6.p]!lLv$rBU[5^&-@kt=4+X!%$ةr+s%}xcD)'RN1Vb7TҞ^ڭ| ,j<QJ\JCݬ4xWi_yϚtA‹jP&̐uD۞EtAyL(  Lu9 stASDoFo{#DڔBv;oT$4"uCɁھk%r}mDAT=n[O< BM6)*2X(q˷̈́`uSfK^R|zzZ/)~0,s s+[?%igVPy2x?񢡮?shdt]Đ n-XLY$vȁuam(b¾2G3+fsy`#@UP puV頭j)Om̳^_0,Eltvw=YCOtwu8[7qäHB_ht{[%}wA!D?=rN| zb=9N#7~~xrsOEYFI}v 2Hy,ܳ6DZȐۙNe s8iS1͡$Z.\?qxCuv8$~?^x B> stream xVyX2t&Z@D.(R! n(n@ %@T\ZD}U/Z < (P "Պq|uiQ[QЛ|G9s欿;L(SgcDn#-7Gf߼%"oI!KSdiV52ZCdh+`QEcƎuZ8~"&[/>Cp!5)iP&&+C8:5Ca )rJMK_Z6:&6.~~b:E>~I(}yDQ|jZL¨%R*ZFRs(?ʟRR@j.DP7eMPrj(QES0ʁY3&eFP{;mbcfm5fZlkAb/)ă-%sR0u`!:G&|g:vTe'fnܘ+ی2gf{Evxrcݮ=qiJ۽h  756oUe_*;X(qexX2 uՅ~ GpB*?mu#p ndL<+$[7UKX(>Nv]$P{sU8Ru#n3{~LawHzň|}vہZhMIUpo؂_C[$uD 1x-.j{C<[%?C/!70 XŃ+D{P>rg0Ml\ p_՗^8J"".O)o]մ$]XPZ FRNLq]|GY~k˵NOZ&oEXRΚ({Ff}#7HDP&Aq.6BQ kHɨ_V8#1m;"X f +]lNWXot54,H__”rUh3K!6b1-7@-Dk$x;N0D߂%bA1k$da2}9Xdd ؎3PٟDAĄ0Mɤ%t YsBe C`֛TbրHf{h uFNhMf,J@i6rPbGCqo"cC2zl`c`JΡ^F?ĮxdOƯ ړ/5gȚ'!dg5_kP`sC[t\ڍomh gEEMl13yxB8OvLpHt p^ L[&qwigE5͈=_^0'&[1&#f؇z[O -pSp!pm"Կ[1l^kY6[/T]vYCzOw#,29[QJP8&PDQ <0Sz2"2L$4'N\?aaY̆Eso}Ol ýb¸QB^W +=[Wy CٟE8:|ਲ਼, 7+&ڐaCV!{ͨ"`.-djux,qA 2J!} 4%#^qh**/_]udt]lNfGTռOzvxcp^}Χb.ć- j<)_u%bv@Td@=AJ b5ӏ =B׵o %wDoBg3A˃`P\(ڷw_E%M_\u|;95C{޽cg wb-6 NyFR• .v.,PG%U,Bb XZPh9 endstream endobj 374 0 obj << /Filter /FlateDecode /Length 3254 >> stream xZKOF.F Yw" bc $$9wř-2soOU?n5UT%T鮪wWľo'7W}))Mem!M6J0 j5Bիz[S}fTh;`X%tѵoGMŮ?.aE!ᾱ$cehCC{I߹GIQɖ_Y$b.@S5ΊёTJM>L ҉.o?lwCE)З I$:RBUV}fxfRŔF\d`Ͻ'IlsxAA:'o$ehx//&, S}_cɊ>CV(Yl^w=pZ;$:MNS]D71DGgé!8S4p8wVy(t6Ĺ) %޹B@jT܄0{ Ox`bRK>C7z m5q~ :P+4 !$]8X@aUbb4ِP Fg(7SRr#RH!O! L)߻ Rnlůۨʮ%J͎vᔋ0 &^SL8S%ar#jI(߯f%S(Zf34urm}G7`T1I|Ȓ]+s:oJfu.gJeo Nsk')x$D84lyY႒(pa f@bÇ FrVds. "d Qr c8 UI@@X9h~ c*]HTY.>j23sPP *g%W Y(VF3[ayccsn׃G&pG |6j?8OuZI- ƴPhH>T%*fRe}bG($wMXyIjԀ(]*1zj&O9"]5Qj ]k 9X%KZp\FM; %N" Fښ{(ڤ~bMa*CNܷs_<3d8Jy]P^WUٓ2JWH02;LK_fʻ7q XJm{1Ɓ: ੄}ZPc0)f2n0y2Ųk=dWsS|ixc^3U+eH&:y\ΚVV+L 2W߯& FPݝ#+!` )}BNH ^/`3šĈ]r܊fVc RUUKǢ%C׭)xf< J+m{y S#FT=mm t.Y;; BDl.U)(n<}]x!0kqQ;_Une~y wSAEņd4f"OMD=ܵFzw^*zP`%Nj*oP[B9JXL5Mq*~piuًVf%npYٌPC2`=,rd6esks|2b=* ,1 &3W;-}ڶX8P!(œ+m8&(RΝR «kxr|=Rݵo房@v!fg%Pai_/+!4NQKbDUTW@Q(Ss& A]d7G.{`Ƿ]4ᢷSmzHP<hک9`e)!2C s|q&ݙH#Qj/! m2Ӏwv[O_@CAuiyX++ 4rݡ9c;H5K g 'UFΗ̌}|^7/4n}<$&) GtkN}knx}swIetbendstream endobj 375 0 obj << /Filter /FlateDecode /Length 5303 >> stream x\KGr>mlf`Ch 6.W3k핸aFX8aQӣ&{/QY=H2`,dEeFF㋈aѵl/v G>H:_^W؂YvzaiP绋evJֹf\t.{>r%ǛCA~uQ'h6ϊ'lW:봈n~QNZl~fEŒ~,*V&VDۿd@|P,XI+ [iyfQFj',h w;wTƥ/!72X]r N7J*텾~;ӫ3\cBGovyBłc\5D]s(^9M #v A|\x䳋f|yZrxk,A‘hNR/~ؑP)+xcYn"OJ}ثT;Yl;ԝUEpP#fRQB˱Ղ k(*%6U)1^fܝ w_CTڗ= Ehj&/~M#Nr00"8nn$kTCEU3  ȎXeI\*^sN8㛸ZG@2_GOu[gEMku偖 g^Z +b c5L @3i`ai:3S-'1-0S̩]1]A42>uhX{(vZ W@?&_zxPtй>n7/ӟd (o^wM˚OO!ݼ[lf0Vp[#% yZ𷦺Y|xƅX(~^~s %%aRg .`̜J(d~Fu=(:|(~Dۃ/`.5F,OѝnmJ~kB`v0OI.<.n"1H?OZ5N/$%0_MZdH6:0bXjA4gqt:8J 1QX5 aycY<A ϔq- ::*G0#B2h#+U ZI#'ghFD%E:E(< V e^9]rR L#a8aD5vA_-l+|%{!_g4qT#((r[:07Z`;Y&y0,ޗw R"J :H/98@RP{^a!y3Su6睢I[@mn!LͬM5FN2G @ qF2d#02R *75dTGa$(HPbx Hq2%:*Jn og~Ff43FEkBR3wAq#M( 4Łϐ(ne$ÀX,H@[`NAB]!E ,l}\tEgKO`fGyD~5DuHv %㣁F աcUTT$A<-J x?5]~ZRb$?"%gާ&5(+ʱN+Af,m):( ͨTm onϏʗRl ĞEIT UwSnA|xjojDb6T>/Oό-fIHl` +6>wE̵bbZ׈lh,ij37<$a );c!F53VtS~0׎o6+\zYMKWʞSꌙ9^Ewa P-D[رg FRY͜o+_Gqʷ;fԺ V47CâY z1wwOvX@cGrJPCc?Rvnb&44DjE5(cn 6UQaZǨ&g`ó|t 5/s0tIr}YKX_mQb)w^nբ-%; `7fmI%dy~}C!P':@ܻ`H ^Wx侶$CŪXWK8celW-L ءWk݌q_o#tl=s)qw.$!O¼a0ݹ¼ c »$XWAf|a^3^Μ<|CChEݸj.['t(>un*+YE(bh~aj:Gv;P@]Lz ~eHʈ7LPm|{0]]U7&ZUsk8}DP 6~꧍,IO餤Ex~|L ia ً= (>bId.wD̳B>kY2! QP` aCIE.٫^9E2}'І q֖%YD]ʚ1!H>VΈe݇I?TWk3Ex~(+χ,v术΅U)~x\^-<׶1 1zh(\T=HL̘!/\m#ctYM)'4-=sLTfjCp~ou~3AIMn@hAD^L'>Ka] T k bJ53fr;~!G0$}QJ}*m fe[M9k j!qQ'^RktEȡ$Q-:Lk4i"z4Ͻ #[a [=Fg^p)c-IhՌi?)jaєY^OT Mr*M* ]J,xX֡.Aw=iJu+3XzLTo%:}=j'i"oWR$ p7yKUo3Ɛ' kq'L{BG7+jnr αqB]4v,+_t>tcy>OnȪGZIU7Ɋv]Dݧ$4܅Uھn{7G:C۔Z6T%#&n+Pً-WI'\xrg0~n> stream xcd`ab`dd M34uI f!Cğ~<<,&={ #cxj^s~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡺ IMJId```df`b`bdd?jC匛f2(˔wO9 %;[~Wy/RՕ^Y]þgC݇7tpb6!?"Xcض=ѽni?|[0u.lr\,!<> stream xۏ_IO FAEitzN. -m@3 "gIΎ;#"2,ӜѴh4X8qKD^"#xHw}*)|x/U0WI·Q7__ϾVq>opz1_/3ų0ѮǗZJW~~_Q$%QJy8|y|SukstWS~oB|=e^'| |޿}=oWꛯTlz]Ώrup<➹Z<;,߳^Z*R͖Yɤ,# gݧU'ʬ k2_ٰF k^ڊȊEYks!]hi[uy9{uH?Yay*c?I틩GY?1M]eS<dkעv=|ZOwoe,K/};@Z;·f8qϜRVdVaUIt2 ?ʵv2Ӥ\oI I,B6Wȴb$%Hg@p5J<[!*ꢒB͹W1 ܧ1;`&)5c.WCO?pWb:22f5 ` efnCz䇬jOA@iHK}M.][w8+ٹ/+Gx@Y'hn!_zLZi(M+eS;xч8UjwZk[l=jrV+Uw98}ZveDsmp3 dwkKT7W?ۂ]m.j-zA;9$j42 >y_Ǿ(9R{2w"]QȐQ8[}fLˊ7gv-/Az3MqEHZq䷲ <-s7 qp$Du_~폟Mj*aî]v[O~^xSj1pO;焩ov͹{"c8 O[`5oviO vvii8OKc=C!i➖2u=m@֫=W{Ziqӊ 웫ղcՖAkE_;{ѵ9kYbHW['j;4Wїն\Cj9BZuF-T8D/JGKkqu*?Ѧ-O:OhIsnf?f}L7뀏z/@F, B/eCxERI:tQWpQd-dwO8ـ| ȟ l@dlqt' 'ӝ/w褓N{ǝl>:pp N6t7d%W۹S)R̎g4%.gw-{YM  +*?_dVJŒC d9"3ܩ4{Xt^ˡ (oAN^+ЬI\©"S>ul<ea_71kNѭ+:dzC:e%|ea96C D=xPGV P.r2lad2:=%@F-]Xs={` 5ABd(rPP2T]L9*rhB(\>@R]YFIP/P D$kՆM?[hCf++: 쩠qa3DR/.Ls.YXէB#V7ZjmNjJ׈F搷Z]~,foKETS@v-DKM5@\lǃsS+t8;,SFE#N rmhsZD[֏m5 Aˮ!(9Xjv-LueQ- &YV\hRǸQnhN;WΥ $](7frhv\tlIrs1V,jP.~`5n6%YªC(X]??)xu#E3RWR8rs{M9@iVɹuɹغdC()Pr (# ZjsuH@trs5;IkKe Qvn-jRB+mi6[Z--Y_ugs/sK!ؐrذr""®4+*?"~mV?gyȂ&xیV9)E# B2TknhsHփY#*( ߎc`:K ,&:(^BO w%DlmFj|8qLٹ6ة񹗽a}kkz;ǯ7y{+Cv%a5~0/#8~!FEpcvQab@ي9Bl,l-$ctNB0HiS(CqfeԞEbN`SY:v/Gb|]9uhXS𲏯q ?d2wkW B"ud;1k2[M5}j!D>\11`j]stlc, 6HC~1veݼ|e1`8 cE E$] hiEWt;R9;N8 [AAW$j΂]e.4>ߕfZ`/\(q7}fNe/.vpTkB|DnQ.J?;q(@;9S@#iv=\߶mQ݈ t;;D=n,nP2Rt(+r6-T2EJ6'*yS eE@ x|b9<8Pv-T9`k:WUIA5O7S:nV2$窽_AucQlBX^Ӯ[t~7_2 .tYa򚶚WM@&XM94EP,>@KÙڔbS2{RVS SFKIpਯΥX-"ǂ"Va"2rŬza k,kY̧|Zf>0!{F󤁹m="6vXdH ΙK;-HHPSV$‚ձ 6DX\I m'68< 1Zcr!ax|ENaϱXp`rZYc#ucq1p,N^- 7mmj(\^Q6KHX⧯k1kvoJ:DZM_{~5\wk`yH+*=qMH2k*=N-ƧlFwt -p3VXO9Xe'CW8X-rl8s8``j6qcs6*kk\ӡBҵڹ.akcշUvH^9ýŇ64zu[wP^y8ܫɛ{(ս1\{Ͱ^tHwNFk;1; ,iNV,i^W<"?ֽvpZޕCxכ?]WݷʎYV*[}8Z}L}V#Vŷ UFkoyn1~Uj®ѷ"ee *nqi>\}eU ݬ^v_ܹ ĪUmWi.\IwUt-XaxX׵X}bht+èP3aWxk7YYlO׀+fIz}$MVY[qtv~qk`e""®JvFVhbmEL~\ [Yz, BwA&ʨz.o*@bB,Z0ƚ>=ưENˮ!(6Y,AWBf6-K?7B,Rs]skP1R2UsI (UPmTj.Z@ a!!-fzkF4#jCD̦;r3E@e׌HF,B5 i7Z@@qe,q,ISVs7_{YH g`E&NCcp9n99Os{!0N9wAIaWu &y KW \ܠ(l/HZ`%gǯ7etB)@aA\f[Rc dKqc%HAXu]?S,Un24p,/ѫ<[\JƝ #i։e\ ] z7XNp`F l""Qm?uː+bUK,X`d/gIs$iŵ2N $M h&j.b}$9Řd^p1pn.\bPDRؕf€@4I+JwC8"#e׌EB3(T# O&?p,eO5LND(TF(2غb\ Z4f U%ЈA@`II:CЋN}NݬWAWv?wBB؅H]Rǀ+ͮp8p`W.4a}vˮ! Sj(cU5 5vkbsJͲx,72 &T0 &?t: q\-5#8& Sǰk1Al v-ڥC@{+[VrRUpےDY=uߙI!K)t9x)R:](7tQQ WE=阎 +ɂI!:] +T`kay5^ DWOlLmq[\|M@$N}-XOAVv%Ǻ\^ 6R>cb^?0.̱*N#YXs!A!A`Fqil[\_Lci`M i5Щť#:= wpiZvJ a7"v3rH"®5fah<oa x7.(" l:@6tvAO*/!&sA)N brڌC6:gn{@!&Us!A!A`BUQW%S𦁇2^1uNg,F#4 WtV WJW%BtFUI`wߞۻcp+d]r_P:%\JH*k+u8-GLeh*e;"5jJNіxZOFVԗnm洺W^Ъ\JdR!KrA#ym7QOw]_U_EiVwI4q*n1KZÁaVXb|A@RCU8M@c"YOtY E]BE5CakGH=9;W/8,SVvu ѬpÜl=Txs`wg>rpw]Ԃ%tנtnrmʒL E.te<Dn-Tv> @FJFbPZV Ʋ#AL r g]% iUgto$㎚O\$RFf[`5$^XycV8*b}$9 ]#lRV9魈r65- {D7B^9V΄H:,ulCNν1m%RIHUv`7\! (&;nHnGW켁s& y$ҝUp2w|OЩf /TeS= ݩSMf[VvzЁҥHvٝťvh.uv %RxR.Ukͧˮ,>tԆy|j%'|5wߜٺO9Uwp;UgNLET@Si(©_ej U3\ϙܯv5O~ղ/U{֌4Y3RgW\Ye"muzkr9\ZZ XwCw}Vɜvߚݷ&rߊgZߊ5uzzղ,zչqε7՚ﳜ+wptWw7w6v ?oݷ}Ͼ5|4'ӟ[Բb!֋oݷeDё[r2.[e'mVO5[V)Փo[EBbe[ :WЕ6j#?;ןsŅ @TSJ?.*e<[0خVVG1IbH("uu(A CǠȠgeUrmo-R}O,lfAec!_8DPeaae2werӳ ;{#D<(?Is᢬r^ZĨN QV~ۃl/,u;EYtz,@ՔU֫Ⅷt(+ND+qH ,+ 8d͑,,_PbԠif+c_e_1&{g_1,Q$NY0s!R] L"\,dmԸ.-{f +.Pdy٪ۿFsĞ5%p P+Vh*_AM~;e,|׍#L"(x9{ɚ (dʨRV HI Tn}yqϽr2W>$Wn&N, w,*7l$rCS+TbPDRؕfB,!䶉ߢYmv)xu#E'PRv=\8KlIB̊N.OaQ LBec_dbi䏟)RP.f2qhae:yfH2벛eRgtv\Qѭ'p sVD꿇u^Sh#-v=*XE`Yr2.,pE_*@/.O]Mc@NY*SMZ ( , 9N'ee4iHe ;׻ KʺtV];9S.:Csi}]::,/=)\h~mn: 'V! [wPA҂QqŁ< @Ąp6[ae Hv=\rb3?aY13Z%okhv)xsG`03t>wt)R®k:Af2rv˜ȓL}HbG@l0p>p)X>_ħB1Xw:F .g;5$\0Nl  -—.1\jPشfU`/i_rlfoHe^XVAl,|2eMUa}ɫqHXgNêv`9d7\crȂ5G֭YCƼMN}lEU$@rq%#`ÑۈZٰjxٰکiX,@6,}mdÂ> ֢6\)=O %==1.4uWOc];t̯ ˍȻ&c#哜ǖʟ[+ف)gM ;x%ɝ5M)ۋy $]UHU@4 h5B@'z̗1/|40v<΢2FIfҁ#TlM!ݾ*܋&9=N$~]"Lf=nʥZJՎtnAI}PadbCi؁Tm:$_p2Nc[Yj%w28ANr޴vH*aw^[KK 29c9IV6&&9]k %R$:\)r|m]7I[RǸ&3M.?Zgϭn'|5Q, 7ɏbJ]I&v\vx$mr{[̳w㙸Fi>MK^'N-{*%ɒeWl$ÔNM$kt'=4)l"Iu_o!©Z0Gt EKJKX1.WI#(қѫur2':U%?$Ur[@>:|ehfYa'8a- 1qcXv"a71#-5˵I(vƸ;o]Xj-26; ՆYG6`| `+)Vr[9=}qC=ltB,J[` ,f YO8K//mgX?_->(=dz2,[84 dsݝ,;r8Yq.NO.N/t{ cc;HJJNdJY\ ?نW6LIv<Ygb?~gm}[7H^伬CW^&zc k}첬=`Ý~(v5Q`lAV 6t{Tz]؀>V i>V2N1)k;XbU Ų>栛6zs< W&5*) ,!{!(!Q}*1\nPrMV#>lFj2͒F Xfsj*dF!R7-_G@`Y0\ i=/ !&hB#L $](תF[ni3bY;BO 0;KA JI Pn]ʮC(iss"tp+[F l 1bH }:cCH.7(z@9y3 mBѺ>ks *;!7u(j@.~N}5pAaW4G j^5sH쉹b=h1 &`U I yQ7 Av-%h_U#%Dɹel:8ƐrF w]7JSnΦ+bη3#1}]I5(v9^v "®7f1 'iB-\u-oB`4A˴s mKv=ܐe^UeZ>-\bȠ^g01p>'D$,|b|e'2Cn7מ[>NC&*)\z' `2*Op I ЬE^z1IvdfHm;P 85SL853L֝@H˞RY.8kFe+'r."%,le&NecWN}`e]]1\jصjM,j#%f@5A5_,Ia8/'CC^ +T bPJRrrw3жMc} u xSl,it ~NGa1 /ćJke]!5M6)Peakƥ~HLPR%S>Ul]!'kx"؍HA"8p.I2+v&ˡ.\6wyܹc]kvzY(+6_vE2Ly&<!D0Nƻi β߳}v ~)( *@fS8vΜ%z7Zb+%~j;sv 8[pAa \ hs%H>%P,s^1L DE &rTrfDdT. .ZG\5DP.A` 3ˡC)P9B Wrz6=~|,䙬J/{QI-X "Zgd@elCUPGʲ8,Me"m}F,YupJVJI;#aɛ3lԱٰ ÂHY$1);Stܟ^]ʄuX/ +u%*R6XcKzvBܹ\`>.P5ONێn d fr.vj,95zUͬ!Y l%V+_gI!\c>tOpNe'JHYq%|儸dwwl 4+ N~s!JeM/k+l^G.x_y_{ e)Uʦgu aW%SMRCP_KYWVI9t>˴A|tKǀG8xEM$^,$qrfqSd) AoC+GeL:gy8$5q ȠHKJ…lz$\[("!zsHT&}**`EUo]̙{^dn%T/2$6MI]%reU*zObX gK<5p[oouzg'|~g{dgMHy5cxVNù&s+?ֹ<9ݹn¹/st+sͅ Y:Wv _8WWp1/Di7ʔ\sٳ^xYf_6B2g,Y:yÊߊ@'&BGՑ@? @_ R9 U; 7NbrMjb-1жE,B/ A 6-ż(Ԍq]DX܅!cim+P%L҂pCή3&3bШ(P[IC#.M9ik(FYf.1\jPشfhC IWvxُURC #/`@$cHF ՅQy*~|WI :kklLj:̏X&s* -F2j2l^X}Z> :ܡcZM(.)BM 6U97 `ͩ .7ThB%#!FER`lL`ABbԠia%{34sEA>utQh&X(L`r9,\31U redr5|-m,&5s!R¦5`04:嶩y(99AeW(68^kzaYfZjXb%ݟrACeဘ jȃ }Ȁ)"?ߕfBv0 \)EI`H&d@[,(1\j64rOhFb}a.V/S@.dQbԬU h6!֗ SB{c9 oHAwr ۜ{ˀHw%L3jP/Xpf鲍bdBH-uWV!W̦4Ku`_Jf}{߱RQȲu${Wt "¦Ԓ,r|m+c\>!w`HP2.gv]RR®'q¡? ;.ز(_VCAY%H Y:wI]|=_ }+kAbP@RU^Uw :k7_1>ni/g=nɋ,w{Ie_ ٘YXhU2wJ@39*^8HںRMd&Y|>QBEd㬭Eft^=(C`z->w.RD v6R# CD~+a#gYZv`c {}d&q !2,VN-,\ǠԠiͪb(S*@z]Uι3(z9R&ЋB2IM~їA\7aY$L/H [IWThzs2tճIٶ#UYgC"T?p1cHlXHpd׊ȆgO}dÒt\ٰg72Aђ;h ^}m0Eii6GPN2qSWH#k1OVyUDtwT, *XrOެ@_0)f;#<2 :Sk5׸W'ņyIiu**4 2T岑\$S5g(Z~$.gftăUұROJUrYcjBBdZH$ưRֺnJD^jT Ec!#Y«d:5"117$ @XFbXȹWens-1`iFz+ʱpv_`&Uת@ CVrQN'F,AO9\ȆbOV FElDVt8*7wd}lgf,I,%FU4$p%hY#(&Hf,d>+ޱmf, kS+f51bFU(91yѤI$>s' "itBò'޵ګw= ZxWo|ҽ9pir{eZ.ܿV݅-'}'k/ `s͞u*)](s*#o޵U3 t) uc\+Yx[޵]00]-7]UݹҐs=>\\\&PsεMsE\8ù&Ztp {cݫſ&YBgkUrbe|:4N_ܿN0ܿ ܎ׄ.ٯW9a%4׃3>S 뻺™-klx{7V*!ޘM'_%ouku ݫm:{`^k,kG/,z@qwZ?۽rY+Ÿt/Z{J&\gpkA\-Cѧk,UVgFUUfeu~Ɲ_2s*\cCw|^c@*W]ݫ]SNW֚O{UͽfݽAWC^-u yפ7{e(pý+ý288+儻ףѽ0]k\9ù2ݝ+os&(i΋йJ홹sHm*`U*-O\~X\L*mQ\VtQs tэ\c*BU9:Wz\]^pws1ϦwiuzUƫ;WsѹUl?kD]75gԻ;W>p: j\*+[g_ʟt^}ȧ|k@[9?[e(~a׊H~W0! ʖ9[_/7P@'ɳ JA v=o~-6V +dB[ =T́xLG|E%/rhkSз*^ϔC)q\w(t}jLnN/&n!ͣka{8Gϳ4jAIN/+PIS,ǰ@NARu 9(ZxXA)Ia%ƍ~T++ncRo֝!~@HiET)2>U^jC9ؓT9%wΤICYݪ 'qP|\Zj]e!U">EΣI$NOZeKWƂgHŲ;D6˚ u-ZFՉ)®+c,*eYwat9nԕAYn7kJ;we'v[9`΃3W ;Ul[YXu,&NecNHe1\jPشfM8qhBZ-"Yq&Ӗ( ۹%82B ȥo9~sKe {v-ZGd1H68l˾"N=';]nAI`6\TsUhffsaxY:/jP2RfBf]ZeugqhZ&ҽ z&FG łC侻X@ e$] &g (ʸjx95QVQq$@  QVC4{F2OFHin0$ !X_Uހ:WjV݊K$$'5xp2jOe K PM=[!;?hDLyHeo6$ N lfRrt-k4~m˕xπ?.>]ǀ~Sj >MkDg^f&$En84N87z\bPFRصj}nB"8E$] hmoy~@H} rš… K PXfC!1eHC#h䜽Pc4;=h$A s4eM%ca31}Z~?n)N4&ufe e$] nd]dw!bv;qӶ͜>M֝&ç.1>ݿ^' s=!2uǭUҡ|Ǹt:YREUϠ>$ $]u6xaVŕ.M)(z'0R9OKj:Qu*1\jPشf͑#|!~=bGON~qIYiX3?gl4D4$pvר!FxΊW]MٚI!th?"+X<pF)v=L{`U :NKOz%; ;&r,{j@,)X8`*E.2U^ zɘx\ MI(S5}(L%Leu%oeԛ @ v)O+X⋷ϰ0Jevy 3`Yc}aFDh$ Χ/<.K =%eС,|kNj^Ne_Rm8©WM6 cPnPrح=qC-eX{>flpkB8ƱY] h֎5tߊvA*F:c_ݦmcXX|}˷e؅Ia!n  %aN;efϽ @)V%ΘVFĠ+$-t -<]gVQuJ[zΆJH9B $t]f:ysZ\h~ m+qի R1vo9/+ CN@^K +TbPFصjRCp%|b~׏̮C6Ðyُb^NbÏ\ bܠ$+/]?4i%Rp$% ) yxK P{FaF# |j•^9P9hEb6@sGFd:@fDZfh)tk" ןν\9nIӆѤ{6qųѮϾhϟq;\Nɾ7o5D|,jQ?^gR_ ʬU޿}Ur߿\JHZZIfk񍴮vkm07}nkw&!tug^[}oWFǭ'%ݿ:%/[|Wk=|72=WȐ bG?޼gM~ܪXbZ=}\zތxuͿ.f%]L޳jx볒4H"LϏ4VO*ӿ[X#A$!;]fUR]\FN!^MmFw|o>b5ƬԛΣ$xOSצD&l;˯vֿ]Vˤ}nkFNjnR|FmHIn6oWjmۥɋݺ?%MkEPy cXZ}oibuwļ\13|bH-}D:se>cESyS`N[^߮M)M,•ċTfQ!<#~8S>5l[HO`\mu]nJ|CC+g )D}T#;}9_Rn@gw_N {S۴m0ɒsdis\/ ݠt鰡OOSi͑#'Gjޟ#.#)I%|8 GauҘ~-Osf)F,˻. &gbɽ[>#9;DNC;\,m]@3?BG#t'|6̶LkiPc׶OW߮ev:jB>JY읛_lco&sȿzk˯L7hzN[77~iE$щ^PsL$5>yw[A4jgG/7;)sжIvW4Ӎqs=]?n%_n}W9%}Wuw߿Яe|2{?ii?/=A!PsyM!j^/߾|x#k/7XD^Cc8~KǴ9lfgVdwotğaNyLũF`}l`򁏦x$ +4ӶWٚ_{ c1s+JNw]M*~Tiü:vKu|Í!Z'Jxq*4ALhrSWibvtk-ͮKaMe/7$ɤ?BOLUk7|n&!&tJ^2p;io6}Xy%mkmE헽7ŌV9%‘BBׇNk+{y,hq7{RbJ6>M'e1>-N,:-8Yj)_}>=[-\ _}S.s^pc>LZשf{=*+i0}3=w/٭yi2+.1>itXڻOuv =Nzm~LosZz%}T]K {$y12OΒs72_m}/_ \>YT_d韰3'EUskjSr$%yp n΋KgSvY΅N\[= YǷAE/ݗt:dJ;RnnJbN:PZ#+Mi͂fا`2=QQ=󣻙ʬN,œyλKN4 7'2ɲ{LY޼w)YcI5S Շqmp.zǓ<ɥ1}s$€eI*U7'kXDtfa0{C,B8m-P]o}٪O۔}߉>\|ͯ K9{$O1ў~=yEa]L'OMurT;OmX]M7|UuӛOJ! X oS"dyb; Zendstream endobj 378 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 318 >> stream xcd`ab`dd M̳ JM/I, f!CGO]nnW}G1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000201012~_I؁{͏kN3~#XlMN ?/)KJ+b_}2?S:u2ض=tp-<{ p]b ^&N>óoֲz'Lav%endstream endobj 379 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 320 >> stream xcd`ab`dd M3 JM/I, f!CGO]nnW}G1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000201012~_)Y{ӏN3~_Gئvkb_ޝ+ڝ͑¾lzٳTR> 7s-<{ 6qb ^;wq {'Oۡvendstream endobj 380 0 obj << /Filter /FlateDecode /Length 3858 >> stream x[IoNJ.9=jW9I-$hpZ-v/r$N~{ޫ"ZIZ򽵪U%U/7G#bfӣq oJS2;8rSL4LN7G`- 8=?z^|4JpM)s)Rb5_&Zb,E嵝% ׺h2KoR 4k!7]7K? pRdJƯU#R9e +8â84߂uJ*%UžI?}tzőӞ(% jyiCqɊ?ݓa] {&x)&K\Nwr-crJ'᢬(- 'ܔ d]Z%)+-RA*D" xB-xpXJ1k7hE-\Gip pwI(vCۺqhMXK7LhR멷-n 60/kReQ>VDjHtU!F5׳a:dN]jJ67Πi!x~B |,+a$]0gn ƛVe"2pZ\s+@Y2I$v`Kz^|eS44 VN U4R0%)~7ZBGȘMMF@TJ+S<00>/)F%y8@fF*odo$cwthcLA ^4XBJy D+5l+5ʡ)gA)^ - %ѐUS.ސMD2&zo0ШǶ]UVRc҈n0!tzD)|l4/5Y`"tQ|gn!߀U@fq}mbSm%-]LYq?ɖIb\3\Vx|@( a3)1u)V$򲩷IN縄 !jQe4$ޕ~L0rq6/ ɐ:}ycx E~ jaGMqzя&~.8/Fjar=:%}sX9}ґWۉ=vz@؍tg k!6M1@}H{oK ;G  BPnU|oY)-ogU\A񗻋vup_.w7J:Gnٝ֟Xiw*ru=/Qgj{êߎѤ#:na`!1ݫr[oVYD6R=ee^H؇m=r{8T^⍈;^ii(dxz5;؂GAy'5*S͡q'Hx$LV m(\QdHǛUݮWu :(b!:ɐdֶ1wR ʉal|~B e6F+9FLҪd]?}(`}7$5e%\v3jE ^7r.zG&pM fa<}g7y8WS8+z _9E 9uij'=nWc}Wzϗ3IZ1L{'ƫ~*S݈^H;ߍt g|N"E'Z'w.S}1< TDN,mDJ6 ߏ1D#|g;0y9y5Vض"(M u o % ۉP]H8Ç<:. ЇjaT;_0%o lOg'"Ta`L[<)ׁ>f-l&K%_]]0ο1)aFZJZx.PWWaܵ KJ;?*wt|ʗ {-c̠d@yO ` KO g QbːBe>HnxW]9˰ꃮ1v9+96l)*C2߆F/UҠSi5.(PӔAC,=1kv0yu|E]ur2oL]PAd>q+o׮*=|Mձ?U-.0W..DQ[@t&Y74LS y<t/#b_ӡ9 Y' ,am7!P0Ni(}t?^D/<.zѻ^D0Es@5ʢ͢D' f@,#1 UBpޏ]KU\MIL QS QA9jF-AЎZPkC ֥wWH} DWb)<-_JJm2R2M`R7M-桲\g,Y(0giYaB k눼F(M#q~EYKVϣ,Ul}lsJ?&2$BE ƉɮD|мo6 3j6\wύoOϵʻ%8-> stream xm[HSqqG]vc QrH&8/VjK6tlM6yEs%T "BCtÇ"| z8AoA/߇>|_ pߛ/P:yդH6[$06\9J"~_'w#.D@;1W4rCRБGSS7Yk dUרk$'1YoJZE6(& Ȳ\i yVZXVTrHj-aX$,ƳVoº n Y/ѨG*RX$?A8JC(%ҕRsN*Q|qf 6+GI[lv ]GWyׅ .rgVf4;Gi)05 ,v-}".wYOsO vB/{N4b` n:!,#]`B A8͢|Nh?CB(ʘR * AfDPcbӲͅ:6|q> stream x]O1 yNQtЪjbLI:t컓ϲ=(ul"-~H0X4'0>UY!O |3Qul!􆖠DTZ b'Kv(DK&#qMkR1 >d/)S%endstream endobj 383 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 311 >> stream xcd`ab`dd74 JM/I, f!C?XyyX|_(=F{$0F ʢ#c]] iTध_^竧_TSHJHISOSIP v Vp Cw^XWRl} ߏ?˾K3<[{ukvwwuwvUu4TwWwmYp?MbF̦g,%0-ýq0"ϺzL=f*/RwBendstream endobj 384 0 obj << /Filter /FlateDecode /Length 21887 >> stream xݽ]]Ir8ʿ0p 2Z `CUqU/Y"* wgD"Z_F5oĉ;wfDGp}x|6}?wej9ݗ<&1~=gqz8:a˗Ͼpq8/0<~z.qyY||;}m[/ノ?eܿܿPIwqs|41._?B|liۦu~x/ٯ|۫:ژޭ~^njݸ=Oq9@۰-Nqq.^Xo`.9߽ۿ1;|:) obtvlwֆb^6XxLw?6}/m2]|=6̶_I76TtT1\ץRQMBb`}Vb^vmsc  sݦ> mسۻS"6@.@nO5? 9W_u3>}cL}">$vju./h:l "ޏ!^!QQ|9/>Xh#j s8c{bR~o\~Ϧyޯ۵i^6|Nm7xm?b=[hq[F.}H3ou1;94Iᨏ $~1z{xLD{&ds}uKjIVe.Gւݦ 8FD mpk |ш| خKbmYU6bށaRb/ZEBw7+ZW|mʮ=1oO#ܮ{!8\41NJ`k"}?7ŗ6$DMDm `D{I1 kALs1 rhdJ[ JA I ¯;b!LL[.9|{J`o؃QVqM :eBrq`i=ybG"?a3 þe6R4h އ9ė}< $~1?6}Ɩ_I&3"m'ȁp-iSCS(aHA 8|N6ƹ-MY}fiK[&TMOp/K[JGւԶ҅FO;Ed~؛ 6NJٯ䀽`_Fɵ`[ӦЦۼ>eRRC?XH[Z a^ZNtG $~1'ly>'9|9V}ɫ@-mc-\w i cz @LNؼA,mkvWl &l.=( ,)6--dQbb9xQg(a&){`UGU+&,Q $~+\QToS lx%{laͲi.#9biQ RPJYt8=џidМ ;m) CTcG@d d# 2J! R qZd$}jKԶt&Y¦Jqh.&0nT .tPM_6iegQ>VaR[z}.okpG[}*ۿ'> {րd>6!`O ($"8 kgjvΦgchzH$,LW } RRgKl*z1uS #CmLr}t1fwLRq@.RC?ܸF14Җë́cM#m_Omq۷`iBqj|6W zm Ӫ}* G; d NؼL2Ρ'f/ϱoޗmt 0o&hQ܀ ;Ϧ6.`kDAɡN+ӆ!r{c1v+rġ(d+GނWys#`t )$78〆5]af:#U{'NppR"}c]HeCӊhz4(̷]Πbu|g3b.Lږy$oRŒ€@Sw6oB{ `QI`k>0mjRrC?Փ+&Dz^ G >\5G_SۮQ(`߫g73Dq~-,˜$S8?_}qd~8(ޠPNbNۍf;vm ,</f%6&G5JA)ɡGim#8LF4`l0¦cvשR,#eC#CiQ RPJrǁs7Ҁe>_au A1f4҈E4Gi A@>C?5bl mbi_眫a] &=q ]@sq䇾aTHA I :;Xi- ϩ FvY./MZ Ĵ iS͏>@_b{cUllz,ZgM>b5|:lu ;tY <#8s,($~aL:f8m96:68j (4HA)BƁ$:Ffc~tYJalb 4i"iFiur>6τ};W+AۿS} #8>F)HA)ɡ|jy,65&>"&wTo ^p*0;CJ0RPJrK~13bjؚQ0q 3b#؅g5 dQ7H M/si::ôIm, V ܰf.Ϧ>*E,Zgn\gT]g:h%]guvˤ fքlWR@9q6\gqfYgqᬬ5rE3qg@H Rq֍C'!xB.8IxZHԿRPA1ЗBP nPBuF łN:kvX)ڼ0\gbs:A(k9xw*2"3_22s<W[ Lo A %2s̄%22FУLj@77Ψ14`IOz7&DTDP6I!qǻ}847"i)'lr*xO"ƻl q^ݍڪSh>Ɠ[Ց ~ =IaObB}%6fás-gCЏCz="863Cfμ6C%gc*5V3/x}w: )=bb:\pU]>EЏ# 6ޓ&LX`^ތ9NMm?F_L%93M0 FS `7 )$48P2iGa`h2k56n}b("DqE`XKf "Ԭya~XB2ޯ5l8{֣M Gu@9 b `Џ؁G%M>gG #qmZ i4͋E&Ӣ,/,$_+j 1hNa#* y4o""*Dh3|m\WKףtSNټAN0]wEŐRyZ8ȁ-/JA JI8("++e|[m_<A~xJam~Q %9r"cAf14-Bht%{XpeШFHRBrC?hŋ瘓Dȇ{KyPm ,RX\ha0z`gټZ:.ߥRHhp[ C'FCWYP+mׁvhN] ʳoy=E|j ga+cMy1lG\̕휱[㛲8z`۰փBrC?XӇXQFmF >KbS}Jm+Eba@D%FRd#&~ʕؖ.FE3xWAbQ!8(}EHQ"C?DD|k+6&?s1?hۙ0*<ǹ88aG`$( 8@oqLcAS$QU{,fO;s#G1RaAdDDAHdayl]w`j0"JO8>y`?s@}yqX}ezn< 6Yf}hH5[hdq}ЄcFrN'dc/RC?77M[DasqÀNq0;4'a,sb*nrÀC?|lt\gywyk&[jǾm 6E (C#*a&w'q7 r q &gm%g.MϬxQ(,]=!aτ;<})DA)֍ba\a $X6kS M.6EF(~|2`Ædb'9o#Wld'+b]pA<ΟTeb*?> RdP)TBY7xcSɀ`6|2Y,"J:bDX"q e0 />JFȜR)iu_f*JK}jDU*:!  m/}v?$~*4@ X\h0`1<5`qpi0`1HʀExyK"IAҲ.d,6kj@⬚hǵRmg?J" Y$ D!B@ q^11^;jMDV [jm*@{mӱ[[ڤ ir{C1~C [$X/N5(qZ//2+(0/2%5bfũ-JJآZڃ+GĜYE7quYg?vGYcƹ}v?|H! H)8.JYvue,v?SX2\8/ςgG(gL8R̈́V39LDLD т`)LGj&j&2+.nvX 'GKND*E0WD9bFf2KN*zqXsA72"nf}yIKZ%-ǡr BbӇr(\2) aT2Y6ap",ߪFTĈc)*0Y\񦘢ZF_Jl#"ż#FbhZ}D8)ɡ*0$d0̊dݚNv#2Sўp 3(=|A ipՙN>5jV-x2oaI(4ψQw } RԲwkb6gмB+_]H7^JE(&4Ј}d~bA QPJrǡX0*#Q2GHHTs飔*A)ٍod ÄjŎpb +(^~VN1L #L*Џ;TCT0U'c|GLGaN5!Ĩn8ǠYlq‚tVU Fu;p좺87 YC `YR6fn8lup`w {=Bÿ*aY&8p`,Ӓ5S#`Z+$~JX0Gӫ;^Qq ?IجZWQA Q@JqǁտU>ybnUZ[JѾ/'X^5`(9$~r\\\^`:]0/ BeG,q(}rzsuC?hQ|034)h3KsV`:W7&̉Qj_Z~7n,cnvBKuߖ !#P}u4bhe~JVU+kMcj*aRd ;laLj" PnƁ0pӾ),ycDaQ,`eyqKU.2w 2XL#Fe7#ZLn+%RY^Vf )ҐЏ۪ĨfW8۪U0C!X4a #zΛUA־G?˻\4a淏 3# 3d Ph iJ.dl5"c^0`vazL|]\pt :4b@#2 %q44w$ъьS;F|yR,) 3QD+Gw܌Ɓm,=xdžCdrϕXvŨ "iN"9B"i:#jq(C$3pSS&@1psT ܴ(O $\zsdڤBag퇋0`W,;`#-}f 9Z>n'z(73ơkڮۺo1g>4ޑWM QآKw#70NEЏ޳7G`Cv^C[+I8NˌE8pk g"m7H)\7*.GLY+ /S=lL8&PaWTڡhKuDCdZ<Tw1XDtƩte epbA4 "tc1,2I0H07+c\Jða%SPeB ʄtˌQ252Ttc2\.3e:2C2ret̺q@kP;:46\BÌ8Kꕇ\-ar0fՑfa:bz>;wPT̈+OD]1Q+j%wR]L:`lSr/2"L*ZcL;2%2&Ue%-L@uL@+#'% f˙#/ h8q-WٔaKU!kxH gٚ Bfg( toCPLyHq3* ٕ8; H0/Xy0>B&^ЍCi-111K` 2)gq@Z< 3`ƸB73M0cd3"CG f f fơ3Tb1m*? DY~F8k3f,eIY lFU^bc1Ǚ%6ĽJNp2- #־쀹DU]$edYRfSGqY7S?QmfJa f (9gr x^ >(j8Y$ gP)IgY ٺZeЏ6p剉=˖K]&q$P>ERc Èؠԁ0@1fΡg)W59ǐJy%c4y%Zs.W+ G7*Hy%@7^`\Q $!~w&`ӵR y %1(' =d=J@ *dLjQۉ;y;11F9T^1*v}V M5"zS+kD&1Ȍz _82 gPf`2(38(}԰LTuT\fHq8(W>xro}Co‚pr Cnp!7(ܐ; d=ǑJ6 ` n+WefAq +胃`lɁGl*ȣ7^y֍C}F 62JF$O 1u/&e ;T%e AdFM bX=r½5@6HDtg 6? F@FU , Tsƈ5eMIj߭hX5)L` K,:(X ; FJ:J@D|fP9y) m:9>#!'Eٖ5=RH`ЉkuXN lq`pV,_q9(lq; #FAGFQ U,XލCV07x#T"FymjĢ੨SCY$E$YЏ梮?@ՎȘGBmŽm%YUU@E) P!Z"lfW#Fyd ~/Q2JA JI8T=+Mċ~ަ1,P~<& nC!ɠᗭóA^vt %*ˑ԰3RYr]+n.Ւ2lwcD""';PgTm2ǀ12G1 El.dsupCGRgFЅ;8bp&\ÝA`fr8aߖӑj):l~3Յa|bЩҵpz-2L[zfNndN/Qb,EK JI8Y+-m1ahJ DNK@lmE-mP(JeCcj (A׍jժt-A_>ϮE TJqSJ"WT۸v;d2bLc1lDL"!d2bLJ&>j2َ) 8g#&=ccu׾-N[,sLq+tN |b0ҰŒ1ljܵ}\khO '#1s6߳VJ)š|м.2afp#Z\d+@1ϊN6r#C"|Sg|bX6͚q֢0;C5'°=$>b>ǯm{Q 1Jir,$.p̑bF4e CdlL.Q2Hn4VC?mk20W`e3jA]j>&#`\1dq` "j02bhUMiEPoJ,I pˀQ!8BiQ RPJƁC>V \CMNv]ҵW d P~2bb{ʆOFHs8ں1jVcЮpϸK4}̀;x`]@ / ^#m3J %~: oC֚$&kM.]ɩ֞ıV)D|$\kM]YkK՚5ٍCot9]F13aěZ%b"̐>MDS2]NW1ǁo:`t8t :q`U`A\*ND:y@HЛq@1 ܀7?t*Jn6bt{[0#6ȧۺfxl4ahawjFBaf&i C db[$~JތxYUQՏ>FJǂ ۳Z}}`CReN|[$Q0*D5,?VKRİT>9>ȸEJA Jɸ~ب3aj=rT#;W C9 sF)HA){ƁJW OiWAQuǁL)?M8F>A>Gz7Ru? wR60:nE6z4ік^^.u35c^~(Qj. Ù)8wj.""6}(IY`RGf*5A(\tOyLH-h>FЈCX8*/_d6fZ0T I "o( "癹۝[ucVKGGFnܕ8{ڦG>X۔>X4㳶))JR@87MKRჅMIA;ޢmu2Abp밵6T;&es@1b`LnF3w)"͹n ژI&L^VKwD*Qw)[5vWnd:0y#[yw[-AJa"ꕔhNJ,"nEVY\]( \m("&]d!]dGuYicqRЇ,+H1Y\63fq8,NC<YuSHnp>t2`*#q2\]*IMGP*\\eEptA \e p(pD1A{IoОq&؀h\] ܠ l0pP%(7hC RPJrǡz%\^ jw'p5K:5[%:Lc}pH 7 KƵp!38n0 {+W+wb\m1`hC1  +@'z(;>YFeYFOfoeDrXoe=-NJ56ig`+ #֏7*}thi-_Qd w\TϵPPJYc8gЊѭJAj>YR]SK X1m-5vft|w;Ad%{^E^߮(FWV : %!buu*wP_ӘaDuWJ+N^9{Ds*( j'*+ /{JXw؉%,mSZb+º3Y9VXFpd{w?8"C(% kXe8Tj&3F!lR:t~[Xgl i9m2dܩy^X6h-M6!ڙ6ن̖jU1aP17\Ezc7fGIGP14nCZdA1HX7tDb  I2ɐ6_!gVdD}3>V"1 =&4()(%9〺Gs 9.Cqrۚ0Jaq)s zf;?&5alzg"^"F+T~P(TvNU*Ru.T()$7USj?*{ʞyEYn*01 Fc "cl'ĹwCjFu=Z] MlAb7ղ#v1ȁVHRRC?9ٽ|RV'F7]od "*ŸT'A~q B)*SD] B6K9IaPNIG$ab$,' IF,'=r!(("ƠjN7a!vS'n#bPhQ&]㊄-p 0kᣏ=q(iɴNJI'T钘gerINCS"'D +ε20p,q'k _4]@Yq (281(ዐBRqh͟Ea; vLk^)PV>|tL<=dx Qau0K"0?/FfĀ Yq%\uL& bBdCBF{L땐 6mE.yfv‘!, \6H2 ZA RPJrǡ !|LD"vIV)l i0CpP"HKRVC M:iC;l˥tZuYfSnX ž!`FW,v!;2w !$AGi()}P$*bk HU@R:#((%9Pn#EZRܖP9 5Gn], ~cfM:\8SpQKgĈSPnrǡ-{8W{NcUXKFg ߏ*[ܺNqnW|2\e2+b8WHl.+m"RK&|e>q( 0(b7~l&+yk*ۃt7MƫTdK 3IrYD_\"V\鑡3wA AÞEy2@T&N `M 1F +(kĄ}=6>9W8Aqݠ"Z[#1J!{ R$Ɓ:*-Ltju- #yme'Xv14ȁVHRm]?4Q5\N6hzMy|,>T%ޜpȈQ֠^:Ol߿xs~6yCޓ;a;KlC͙3S2ZsSN;Yj 5}>6l:~f ?ZHowvߝ'm#vZlǨ275Hw0C&/Y,Xoh/Amy_`[և2BZe\" < ᷙ96FbڀLb0X$Ę=A ا66§Lun6le-֩gA#zEk (`"`BBC73nJh f ڳm7x8pk)\es8w66%뀍‘C/*rř[Lrm)\,oNp됢}-Z3i«#`kA)HA)ɡp=! W"4< P7}az.u{wCx[3e&05!D@ɠbfKs~\LPtKٓ_VR T٣0=)T7Vjhnĩnv`Ռֵ=z#/ݶˤf7erJ4NHuҟTSX ܞy,*`:*oS%:)DL*;g^6VwK?1LXhрr$Ж'^SzU?v'~wk Llb_~Wo~W}hY ~Jמ'7޾x}ӫ,o]/-Mzy^^5EcЏ"ls=4y^>Jtjl~zaJf;l_rm>l5 ֓hnϭc=Ve=Ɉ cJ+ǎBex1x@?P==F[t@}E$UꀢBUϟ/E=As(GeRmRLmqŗ*DŽJf+[ )4p +"j8鉈щ2A? ֵv R&kQy~a_/s'.nUGt,߽|4}]û/_?IE8r=qs;j_<^mnh2an\:[x7?ur{?~hⴷyw76oM=榽l.$nyy [DZ]L_9z5sz_?oswXUs y/?g /}kWsoScs%0KZ u톲|$/UYT;xV@W1mollp/,i-b,\CӍ^?~+ t?㟍ݫozû_sϿmۦF{moo^_?o_(/orUqxzfÀISM6K<ҔvbGúvP^{lX%A˙>ɂ|?mOi_.dl$ֱ5 =x`{m WWoSߌ2kd{5F.Vb˷9[4o?MJV{3>#\aChP[M{%(7NvR1dYyfo?jnگ-N;w|%Jt6Ӷ~`|2^/znZ{?_'Iݍf)IU5{1+OٌnT/y7֯J~Rwf Kif΍rۘy۲PGˍ:ķOw'ſoxrFmݔ a3~MT竅̣:Vf>0;h-NBv#k V ou/V϶2/R5}͉ cnuojSKi+y}?%%"u Ϲ)wX-UPUVVW]Ĵym#,3}|"mN stX]xR9i;1C01z̀6 v|Yūlrj륱;9.kH3Z,n_]y]vݟb|Ny30f4(Ԗ뱜_CWO6|g*-3F4woao:QNAٿ66et=\X_]wa)?.>L<SC65;|m2C ,;ԧ|Eg㫧۝.nln֡n#EYuz,>fqK圩UU[Xo|Ѿ?/ŝ~(&ʲ?a}XAcMEr/>7)7orr(~j0 ;ig7|g{u{zq_oJ_=̅Z |8ebF֨m,_3f{e`ISq?J۪ܭ>֜G[G\Ss͉2 9kVwWpt(qyR]׆~}Htn[gvQ=,Pr,l/fv]~t7F$;5]x  >o߿ח_ë_@'rl{RٳC/Hiޢw܌W響m֣?,p[>gtzw$z:"?z+BAm6 s|/릣g~xÇ&חw_}7vf?F)G:x{Sͤ# fiq]u|>G;6ZS?~辙ݾK/%ښ9SN?{x}wD|sm`N|&mP[וۧ5h*`?#s;t]wP[}SwVӉ?<{돀##Nۧ{q̀-E ?挖}!?G!d_?euFzI%<;ܶt;>:۴IpĽF~!/df٪Upқ)_~PW޶9hZ.||ښm!mzcz7O|p?QlS=.rL-s9kΟ>ʨգ i;)I~ʽ~}V/t>oNt{BXϜɱyǿXI,lKod?xwvm/_ZP#qB?}*%ʀKDOOR]jpdgNb[t[H:5[B>z_;Kտ{^P뼖W_,lm͍nz1!˧I>1,xvK]TG^έ5BHendstream endobj 385 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 369 >> stream xcd`ab`dd M3 JM/I, f!CǺ=<<<,_*=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ g```4b`f`bdd?SCϿ3> stream x}]$7~60QSw*ր0l;#c$(K\WvV>^˖z a= `tv7+~s}3|8i)|s/?D:o%fq7skH7_\ߜ\oyYv'^yo|yv:O).~]Oosݴn▼o?v_~t !4cK}wjwzV?ѝw?+g?/?_nܬ\Ỳw!u޿=?_:].oaNKsLOO$:?~yzw/pSyj^ˇۻy^هK.hEĂԻ}A)EIO[ ~1Us݀?^-ݗ=<^==1"2m:"0mvpw)G֥_~\&!O߿`Ucf~*;:pty/qS`j}SEcȝ^oNrػ ^)tayеjE-U+뭸y OY?xj%}N!y<]K/,ֿ)z,x-iRpLKЃaPXb OO//;|dfu?ѩ+Tj]wm7O^ۢ]@s4|9ؼ_n?| ȧ>0;&F2v##ل+0sJW2 Ig;}u*vzOx2?!5ؘkO-%Iy>&"0j6 /<._~[;!x>_YsYwnna3,=`>Fi\C=^"'y\Vǔ5B/IΜr9Hmq4 jE9rgCߓ1NrMSi:ǯ3lίɝEhpß>i]xpGաq9K-O<1_ b?__hdq9D /r?2OϷ{os7DOWIH֘E]yE48N#dH #O9g JK_CІNR:(}~9ޕ.nx Ş y4vIbzHHUoγoiN RSgCGЗCA`/_{ %-$yK]wwtw7FQtiH/֛f3K8}}u;X$}Eg}޷O5z1äJ,֎|,ϪC"fGۿޝ><_޿~ukCt]g~uG.+{ QGXq8_\FUx{=&[$6MKHg#L+~~sB( ьE[|IKZ?/7h70qGDQ3qX[و+l\ s>hf0 LC]D,^KAe(Z6RDUE+%U~*@h`tk*4C':G\>~';BUUuz뇖\̞ȥRgM1fG`lÛ(`) qبF.&9? Ret/IMڐ5i6z#K}(DQB.:\ő .W Õ^sAXY wq$!dGÚe (c]a21 WG]%%& 1nJ5 mO.y z ץhUYv*M"x# u a"&pEѐ*ɵbW$;NlL\Θd؂a| Km|-&2PxsH ꔱ*:ȒFaq?`l<935D8$h *jYQ4SSB=\\3aN"R ju)RǶWHIJhtH(*)౱>pF$u4 )+]5c0Ҥj2Mc)FleZGJބE2d٧<3A "-edHզEN`: ig#qۈ^zP.jg8ٵGEⴂxai |vCI"qZ2n)@ibBAw˓ܠ)p-qeu4#GPRCW|jĂ}HLB ZBƧNBh7\|B~ =U#Vd*$BbQt`1Sh I9ՑK 6ÒT❈ZS"_\݌[LK @Zx n(l8_6B31 4p5Xt{.hvf 'm yʄ !X[(TbJ3Uk1CX6 暽SZ5̝uX {ð8B`ES,BcB35%S[5D{|8Wꔳl"e3~h: aiŠ'i֘ <#3B1r,$VݘL/y2pFyev4#M:΃O8Cup2I/*l/4vY#MH\]J:'C)JCǠ9 €‰rA.-9@ p ,0,.a 릭+7~ذ&A}u}k 3KR<$S%I,<5 e0؜I!b]z֧yfEvq|RR`*U.rKxy';!$!It5M>sgֽڍ2jy F%!$:H[fE}R_Р*p>&0!UWFY@V= Y5UWFc_(6m%8nƵғ/l% Ha5C0ffVQ <& ^ jqg ]QY1 UZV ƴPC djazDzFz+q _1%^KQs cVLmP3UAeVlVmV#mr_,KEsu sfaq }|dO&D {+96GK9ML.med+ +BtD$̺Q;?٦Ѽ͈>N]ßa3DDRF9sLdB =rb cb1 Ʒ d^ޝc"/\Jw7XZye=t'ڗI%ŏ<;*DXS:(K"uSa[+.04؆N:-U[aM -bf /./˴ ! ;hsjOG!‰/g~$ _D0t]ddG?WL"Kb_f%e%2[bTQp!7}K.2@5.F1J/qMuXؤ!]A ӛvoj} L. m&}kj57_ЛrfFK= h(>r>DAh2 Cz|7 ̙?2F]ZD7XmjKˎ'7+c^YlF^\tZ Iv}NJ~zՖ]/:amR߫/zc%i 2YMYD Rl9FoA͠M^D-agW>}x# "<}u'P-U]?}wҒSܽ4)&4>/`ґck1dI0TYt ůp6*_F0AdRW'xF>kG ⱣxQ|"Mtᑄϰq" >1t1O@ l#zB6.JEBe]ϲ+H S[[)y&DZ;yB"Txq$ \ǩ"g/^ ebHkWLX8$ ~ [:gJ掣vh]%Xb U=HP%iE1R;B\Dg8aBHfa⃇F! >WChnX8fVҒcWNx%4HV8irVQ͠V[\V.,WN_ϫl6YDɼV*VAdaPYWT\HՠkA 6x;d+Ccz)Ď8бt=ܑt= &V'a$]Sг{J t}}4=^%#Jpm$]OO%Jlcgm$(KSѓJ LY$r#a"GΊuVN+β%ϲv5/\5+=ٗBewka>F r҇Fu}C+WuNvVNUC2Ҏ [5?yҭyFUoKw7ꨒjL?P+4wH? }Y?7F̾s"'?W[֎ɪ4ބP4˃6iZ*=NsYr==WK'IA~z|'Eg~~W'Zӵȅ?==?G& ~]el#Ϙ +n̔ڲW#v*%9{RS`,ƥr^ O~Ġoo,zDR  -2R`Eŭg7jnDdJ͍ s;fn娗̍@{KWHLDUM )gւB֢#ZB:} 鰓ȸs] -2[{{̆ HO`)~Vi:^nd^rˍN/}e ~,!V %ĬLȎBH4\"E!1:-7`;`}|R tY:y r8A#wX~$oUGBɍ,R۫(/%72 fFuJɍ925)ԍ0kȳV)2y$*ky*+ cb)\(6VkZ8x:B\ 3j\ 1r \De(DG"#QT:Eq5B۬-!t%"3W&+@ ! "D2}Hqrr>ɍ! `rHUԔ7RŽN RTƒlV6QGUt82̔JjRBVˈAOj,oPD" 9x9!RU$w69rUdVҊI/^WKch E:oH3nEYăml΁s78H86ذ Zl`s}Akv!*#.\)7lU9_\:Rnr]-eDr=렕D"V5Š<'V{AKg}s=RhH ՂbXZ(|IlȀ_hyԟ1 e*< PS6:V^%m̽ &t/B,^Cݔ#k*ƥC5N"ёoa$F;4;nmebTN)\xȕ(hK%7DODQr#DJɍ-)7NNo )v"kn_I1cm@YI[ւ=5Rn`R |?97ِ\ط"_*)7,a%F'$BʍrTɍtTi'2+hx V I6]+1"t+'a'GOucDʞ)ϊ5NndH+w̓HV *6 k\x]ZHpnT@F60UӁ*m7aMX%9U:Z5jmUZk@9 !^ KǿV\W{s899wY ͞'}q0ZBGh3-i`Q c|=z̢\G_9RoG1[53ATU>^>_ď' ov}i?/c:nYŃ!irOx؍K4CW| $ycG endstream endobj 387 0 obj << /Filter /FlateDecode /Length 27748 >> stream x˯_Ir&^/s!Y6zf`uf% (bkgD|_D揯JE#OfD>"#xHww>'Iwݿ͓sBJw~7xJp2qݿxΉwó^>WYwpR*8߮||C&/Q]<_}4 JN߽|4>6(JoE{eh=_mWv7OS{ZW~.s|]LFο;S|iӖ&,^e߾}Op:m?_^?~+\{nv:J _~go~ &My>N| Ηpv7r}IϤ=AK NF+j-kyrvkhn6֞Yx~C5 ߰}oNyw?E}7Ll̆i7~|r_ꕭv{C;Ҡ]V|Ԙt/߾{rނ7/Yk~ΗkcW u>4mdQ0K-*Qy>a_YݹVm3+/xyݿ^?ok)]F^"9jz*S_T\IͿkҼgo?GAO]--R~L$qw̹/W#VAwf 0fV 4H7-moGG)Zb^@/N/hƼqs${i_N:dU|P[H%t" O7k<ϞĬӀɩ^3Q&eNq(FwwJᬈ/WZ/W֢Y[WSiU!"ېݜ4Eנ<+_FǕ,g|ȣn1'`vH2]yHIsqll{cfefLFsCxwI \& \b_9RG݋7_|C It95bdxrdLw:e.fjͮvߟ~ղ#^_O݋}=<{ۿx?yK4;tBm/Zų7o^~}7_?_-a~Z+kKO}qZ5M_)Gf}Z XאhnJM,f7gng.Ƚ֪T1YueeSo@jǹe5uۍyֱ$n[aJ]d}b!Z8į7b_ɜ0y0#2ٸT\W^fl:%vۏyҝӟgi=6_)~gsq/,:&e"aQ;UwM|km]%aOm^mmm. \td;kX)_3mmNP۸k0EE?~}{+=_߄{\ȳ7/ߪUX.nHnic}W|M=J;;g`gJ?쫴c޸RWi+ugYVYOL[gowo^ Ϲ>|\5GXkԉZ6ky;-4>o?H,a5dfR&ZOwEʿw^|eɲ flA* -(wgפ޾x7۷T>+_<^|oH7kwɰ@3tdM[/_*:9UsP]sE \Ի7/wOè916[Q=Is pֻI=>ɩC^=2q :r+C~[`]ӜՍCVUhw!Ehb~Rr! !ǜ>\Pn~mvY>>[J hq7ۜ%,S3Y i}vuEϫLӂŜo@KC9~|120c4'5Uaj{l>SC0oվ Ӿ䥲Z7qM Եk4L˦t2 MV"*9|d`jg ڨS )&%dm>z$AL1sJ˸KRtYe1z&ϾAPCgN ;1r&kb*= )Yχ~2j2ßGS;cmu\e7zcf?9H: _RY + r26L#fWi.sdv&/Kkۜ 2 svx;Bk`}$\ƺ/tzW!gW`ړh-=U"~̐']k򬼯^Cֽf3Om9|HffaES5:jM/$hL z2[#Pz-j!6h\Fy>xS o8Yk˸{pOeim:U$ת S'jmɿ}t..]~O}'9Y3N?;?Z{mN6N+Z'X쭇5F5oVo]l˷>\a؂)cqcS,>zΧ}uZɖN֬;فο:Y3v?;ٟǝt4i]];ws] 1K'ps½oNVd;'+JԲ:YQ48dsb'+JK_:ٜ@d} 'ENVv%9Y^%t/+Z4^e^vv9/M^v6R۽l^m^vgeg8>ew/;=hڼ@lq/+&l^vBg^^]~kMHίȿbMZjĴ]w፬\F;-˓{QQ}~sEE]J\uuuzHAMr.}J2Ua:D%}WPU˖Pݻ"4u!$/Y;w( ! N,!zJ$q,,(1\Fصjúu2 IVŻ9!DN:㴱X6Z$ӥ ,<;WJ Pgyou;~5o`\fEG 1 c@Hصj8d˥jyL9: UnX(Y!R QVZ{AA:^[xXͧRRPNXeƢ,g*; mbEȤ1g \(xYh @]:Ch:&"BrO H1 H[˝"`RRc蜂3:C]TVvĠ k8賭iE48fM:=e'i4Ot] /+ Ȝ" S,M@I`ɂhos27c;,pŲ z$70<A*8$ 'Uh=.5(Z@z_!lK'Qn\>[տ)x?!luRW!n?i7ܥrnun΀^} zv q}e!5"!wN]@YФp v=\b(wx۪ ፹-2r q뀘u pKA v=ܙuboqɷZV$N]+ ߹ GtX6Z,((u~nlhQ*P" k.{ku3oXTmv^6Z${ZA@y`e4((a9P>Cp?ZK iѼ- Nķ\G kd+nBr JM.&)9E=2WRflz@:nC(ZK Cѱclmy9ts$#Je K L֯Hek3SlٹnTu,_ˮ[@L4ѝ+R](7-h6qѪmO} kU_Zq!bFbu B3m)ͪUsM7;h\ˡC )Pt(cPn6Ϧ{eS6*9qCں8%%b B] Sm̕! \s%|5YˡYS౟M\ bPjؔbզ"vcc` mEۈOw4o!!-j_,)XO4)Cɂ*Av-TZ{e2]A9)=+PsRP@H+X,5 cԠkfo?lrL/GC7/:#\78|q)r\j 7<4uJC#e,/bh:F~pdQ~l̫TR11g z^V Ę] X6Z,-{]xXfq' )$o ]s"g`n1b||0p j͕6 㜋,6yJ.{>d^NC,|l [ckS:ӰC:[^83b30r֙\ OmlEW9\">N Tt$:~.('?mKt ٲwA .5(Z@5@\u0.ɗzqO/kSqE1(1\nPrs۶C(Z@ A6lN+…M!(9XjlM U-'j1fy`١Q9uPV~@T2'`/P-d K [Y7ײڥ;MNps$"s茖sl[zi(^{$xoB*SnI$%o^X?IQFᯞܿ q Kj\A-gG rUNv!Ul!7^`QlCUPݛbnެݓ{'flt1i1r ܛu,isE2#G!l8CN6BlXsZ$6/r3;9Cz1vα:樋9z9',+V6?}Y5m/yͿlMq@rh*`2pO&BU%3#u.wo 2ĩcE.QyI]6x[Ȝ ]VY֍])`6G9q5MreSӉx~Xde>^h-SL7t$Ù]]5 @-_G;PvZA6?e]Snȡ$,$ L]ɗ] %0@#N.r$i|ID+\ɳ?>ѤmR ElT@kPlaB=[&s֣p"_!hYbmp=WݦmB$aZ@*!d N Z.$:>,̳HRۋւ1pXv {o J:-^sQDmt撮_?_,Es0 uv /ZEbt솫vGһx{=?Hvj'KcS6>t_֑u3FDol9[$)u) lRc>mu&_ U[ Of")loBsiab:m/J+K'K U*}d~ R:$>@Ԥ} )0Kʩ;Q΢T^6+pBMA`; "6of /PQ:B2^~Q̴9\#Enh*7:dm a\cyG31G䔌7ryⲭ[_V0XOgInϸW_^eͽήP^'̫{Xݫ UvgLXW8X1iڋ QV_*:'/&^u'Sݫl8ͽ>U|Ϳ._9>_ÛuO>_Yk=wJp`;Xlp5o颃`+Jtׯbrq6kΎVb~Ŋbm9)+LWy_g/UFX:kY 6:XɎakHwa`Wi`\CΆmܬ]\?\36+.fyTd2Zn$ǢP~.Nή 9ưP6Z"F RB8K v:t-0}U]x/wVT)/=Y6R! oɀrz>D jXߢ!6lWg9rSE/(-)4#EpHikvΚƂߓY Vk(OB3lW4;hjvXKn;X]a,bb a>zQМ"e6WM7}!l3<@qŚߑ9rnh#m}F hJ1i 8hk5e"t*Ne5)-iC@ Qy:]xiXsq.ҟx.î84 Ў~[z .5(lZ@3;_X2]2ճ29R!tA<] f+:!EcQ}6zl*\^RY"DźƇlkP:4ӆ#\U/WEkQT ]ȗ.&c\6W7wmk~ ȸ;!L2:y-w9aWC`FF S:̕ECNДV$̥ReT#Ne!5R%((>6yXR]('d%A>L%KQ fn2`h|gMp 6-Y1$f^LwO $q (f\ rŢf w-Yl8^U7y}>jdbq.8B'7*@yӋ)8vBn V}ժ*Usq c27 h[`ZiLǀu (Gt:x BԠilrl`;nL/W߭ʡ w` "ƱM xM]hj-Bs˕*~-P&B9!"EpJi4cXĆ2;( 88쒭Wg}X8mB/1\hPؕf9"2F+UV^UΡ=J;{Y?,5חVFөpAaSj2K"`|+:DŽn12&*;F0R)cA _Xhm2!UQ4˳h'bYXUFtϰC2Z @AV Ш+Ͳ5ZC0Jpgcv[~dLQedABFsd1\hPؕf%m&eZ4MDDI=#/r3~1,I @A#@a)B $n @j~H{2x/wf&D gd2w Lp7;t`g$f !0.~vQ{Wzv^ݨ[afq؝H5(H ,!åM h,腆啤;1ia^ewb@cևr\bȠ ZӒLy\ 9Vg9 C`@ BpAaW*`Ck5m5^vBͮ24M4etENn,OA+JoLT~-YfW u$ +.2⦂%1z[?CůeR`]z'Yf ]/ .2*^m r$<^mez.\au]\$@05B®j.rToni69z}*IoY$Aֵ"ȑL9$n%]eA9<.!*ԐJx_ #qêM7,@6>g!zLXlXbZ^5!f=_z=GOW ;zdt⎦F42ǹ)UkjѬkw4kay!V@g 5J(^o}BԊtY޲@ UYiUb*p*oTЗB,r !ruNByٚd\Tqdl-ĄȬ2& QKһ-AW&jNjr!Dsc-Ӌ9WډjF3rS˫!UVt|&Pe)7᯵fx"8= U%-C<5άJ~;eׁtBªC]9+ D8imsVAYDBQqNexeUR6Pdj専Q?_cdRnXu-wyÈgzEY_h]Ϯ,lXc=FEWى;W B#A_YR\aj\lx_OoWh׸4*Nbh5HFNi$]xK; ruXDvJ65*H}A^h pʪjtZ˃IsEp5uTʺDq%r6W*Gur|YBb]kk~>굺9BY 6qtr@Bz)՟>]oq xۥ=9K;Fa~"Sov2? kSLwuS34jq zZ[OtOִV ZBµ5jѷJ|t.քT$[]QtCgڜkv=&{W2]w;AxW:r:Woe ꐏրз}C>[uVз.9}k@[Bzo Vo-wgw_=9uZM!w>ܵknZV{Vhas)z/zhxV\c-ȹc3UTU.Hg=eps±N~!DtwCb7Zͯ&^Uo,w~FԯzGr@X_ U|ܯ:772L^~zk):hПNNշ ĩޝwQz1UXwyD*t/yj@WjСcfݱw:֐5gQNc7{Voԟ=럲gu*8~\!j+ a69GbkF`pQf%C]v=!ΧkHiD{X-%]9y;Br9}(b/$CTA++K H@ H #`yE]\اaQVA5cTe/OH~@-kaaem<A v-Lޫt=Uh޼,Srz 6N IP3 ^!f b|aE "4XƎ3]+Ɖ7e8q m, l9-7NHN or 1q @[{uNw ֜1~<.A;8j9|V"!Y&V ,AP n+T ǠܠA.?.=fz\!guE>xUm0Zb8v,*7~j``e7"®4øh f !7&ByZtSFE#Np!%)z@bYtȰcW{8b]c5, DRR{caem v-dFKL|/ímA'c9c8!e K P d$VT9/5}ZZ^NsA`e@ H Ь[6 Pr!UKכqJ* bgj l+EBu})J@3נtXnWVVIO&eCj8D_ U>ˆz*1\nPrfY1/4f`O_fO,6ژ:}6R" +.M4nM, 2r:u1lUP9F9!)D9٥ yh;.%(aʝs\`??#t*8rY14DȻ Do,xe P,i.M~5WllCpl~k OHՇQ_6s"Mwwd.3 j1/]ˆKeSUew%su \.9V3 f1':/s w m, l' vxzksN'B$} gSv_qrȂe+C+}+X?!F=&68姉QOiM,<,!+ǂEȆ%ʆȆUN+,@64ȆE/:R$3nxwnOsYy\{p\E xe!m}40~?bPwO)I)1Gď-"*qD|Ҽ";GdNۚdήq) x CbBr'yXNrgwz$A\Rn4xWqC90&q9IΫAl $ZL%:N$UIn%i?J;s. y*HZ$ c8.(MrQG\aQȩt~i)3Fq($8:@ 6@z:͇SVU~QgI4%l-:IX,vqs~&ʩyÜFDF8M~4&ُiRrDPHWe|4.5I~<֮$_JK !5qjCo(J:g1W>n.Ay/$?#ql0N˸@/EV%,Nr"o&r峕boxڛ,/ElϾ%F54p=K s=ث{.m`D,TzvdT=n0x<'d[Ͻ6;CԹf|9KGV%qԀW#Ou&+簈v`;xC/f3sZz>$vE~? =^b9?cXLR:ee!M$ JӴimkYklB qIpdW`4q̫RF"$EATnjO6V.}iwlYӵjt4N3ϖگq FI>Vci{,cm {̛šuY:>IZ$HIgڲ%VOUH$NVҫ)^ך8Np4#b=0Bÿf sW_h_$ YqIfu^W5]Pݫ䴹VZͷ8Vz\$q*auseqzب|kN[÷&AV,1ߊ%UiǷVkOր\=u` ?o(ŵ6{aqZ5d+r4sQY/zƾSmpn=\ b咦\sEK's݊^ AˮC )Pr(+OA`eM3U+D/)&BJOf&*]Ug"A"Ty#p؂1K!BT+LJ|5/@ml;0Z6G ^:)G|7JA ~U]/$ ERXn1 iz]_ ^vBm)ʀ)"J@wwM4,&[a]Vr}LpR]('erh FĪܩ c,F ѥp TN3.ӑdB/?jHﺸ K}9!s nS ϩgJڻPʲ֡QzS.!eakoư)S`xh BJJM7p*1\l#kպaf9W\7Nrm?INxp=m2Sb"drzLLX{WZ }c(^ÕT+\y5[ߣ,l$iA ~+TbVɻ;k";؊EӪDUL}l1a38xd `~tcAp%(= +Y c @Y弖Zz;Dz(nneFw6 LqCZtQ,\\S!!(z!0^,SK8*=T ǀNaI) 6-vJOclUС1ABj8D@9tv,S!AԲ9YĀPTbhc|蠬b>cW:/+AHo)t=vZDө "4+P.b< Iz5":n&IV1.5Nec5HsUaem<.5Z@5{e j·OBYʣ0+NsB+tDt.֫+K Pw4:M+;G,AY8 Dú|*1\nPrnrMjƶGzսl.fyM|4b^eRE<|*O}3m4$di,jޢ8 jҼ EmG(\dp:Ϊ]eCbFX]ٙ+J?6@a"0qcmyWU\ulj}ҹ J۵8n 8WйvUzGͷ6zғz[? ׊3 Lv*1(#)Z@5K1`uGN1zm=8/#coYeqzШ'[=$欷3$% b K,=t ڑEC v-L5yfbcںHƇo=kTp 1e~-՝|g`_owS[sA !W]h$wV:&e׈ F *5@# mhMxcc$·k9o`I5  ^^Xryt?KU^LЛ<$D kE˿Xw.XlX靧 Kӆ KK[ٰz׌  ^o8G{Β{;=|nx}yy/i~x=5dx٫W[u(uCSz"Wy,qx%tL, v(Tx*@t$SnYhSsi kd^Uy ITIc"q,mYF G$ ڔ[<,4 4_%k,s, J¼lf Q d +O{TM7쥡*GUH}7994{ ] :I,/(FUɢ5NS*o[הkaj|ZWfOUTm;o4WINqN$nf^?Ə[hv;U@/Nu&_ף* = "a.Zmgk3 %U c5 Fhg7:"t9큤*9ve;Qr(kԖxUv4]媒0rB!@. &NC*y,!$xԮ&CY{58$7y%IWwj><[qtq ;M?B#Cv' wcCZ{o*=W`gJ;W@R $kn0{IRRR®JjWn*c= lTϭ V2F}`v 3c]%44ۼ8"+ej>YU2o2E,}[8ɂeݙ v-ZvG,Cd$6eZ?:+$I g|4BB(1(%)z@~uU6 z5jPVQFb9=bX,&sh=v%ى[y#4#W'"fVVIS`xh B4P2ZO Pʷ&!0p2g qH^-dv@i!`bB@RF] SMkT@tB6XXR®TKuK@{*_ܱhe;}!/VXd<j VFAAaeT6"SZ>Te[,|NC>KJ_ 4*j7=x V֖IaWzYPdD熰\ ]_N + Dp .Fs@,@YZ0n8Wy`qE;FNeF/$`!1\jصj擋jj۬xԻҁXHǢ SjͦT;-8r2(.=A5Ul60*2"/ON=dd8VpAa]/GΓ}7hoe\M BUToB Hx]P +U `p)':;jѕVB\/LtI^R- _*j"0\FPصjjW!&Y P-˂[ETPCCc򔑍iD]S Ƹ~aZYI ;Jec59Abd-ʂRT+6WKWjB2u2UvzP'oE @v״'`ыUm"Ś^U q}rF :h"#d.4J@.YOβκ.n[XY8h&ƥf),-@K 1\jPشf+BuFryCڈl91܁`3{'ee5A0SS 3d]ue5q )ӧP]%1C$/xj_SNE d=};XY@bР+fs"+_kZ. zjVǸ,9, ~$dVev*1(#)Z@E V!ҼpAsbRDMB:BQS"P@U^7gF}⮊™@ZfR𲻳;rV"?s͟ZjDNCS1{,ud`X&c"#VS'Tg!vXYS^a&Wj@I@y`emvv1l s3Y IάeODpE, @97v9!?-s·Ӂ0e5ø/iY@),yiKA v=I H9FeO*FNeO 99Or)R] SL[D@lD%cmJ'RF/3\!vp `%\ bPJRrEa9MHy]uuE $e׍JF ,B5@HP"LD9e<`jvvLB^dD@,<"3`B Pm]!hQ.8p쟍:)xn1KzrMN]rh&zrM/m`l`rEu{ABbPDRؕfƒ, v]o,Inz~ Z"?TZ4Q߮q2O۝0ک(#ggf{@,Ijt~f$a 5CJΖ:W$o>QCX߸{`Aäi /S/zۉiDھlx-A1?(о6x[ADG4r|f>qK.gIѨmcULzG"QK#'5& ЍBv!z2mMEc"I3`O '=Se%Lߚ`>CB%p & >7=.)FFd!˻Et|P)mGf> stream x}]$uz,1/˙񕑄) 1c=3%vOz9\zsoDddޙ A;q8T/x1o^ _(?o.Ջryx 2^bq݋Ø._:<޽8Đ<>t~'8̇+ǜjG3~"SxwWk1=ӇexV9pr}ˏ9V+å<"YM.%7N?ϗ5qUd|1~]'^̦˪gG)axx9q*3Gmglqu(G<'|x# c:P Ώky,>eZ:/Q^S;2xGC:|{>ߕXmJ>s$ Euc=fwW/^7>b0NgzywrWo&w_ߝf]hՋBFxRk1qb1:ӹgjF.fKz;c+FoJ>BƯۛק|8}Uday,JD;aWЩqh3>}wz]ӇyY>ܜ~ą7|}<ǝë_~,ΛMJ>c'eӆ߿S8BS/pqaƣc#ps=189M0!G䌿9.G.aY 3nC/2nvX̘1'5sN<?ak9^Ѫ\ܡ%`"&(.nG-)BҒЂOR9I^xG4 ል4XE9Y|pzüq0.& 04!c֌X^rYɡk%z8IVf #. lˊqd'ϲd80XVi8ʥ~DZnH0jҒ&jC<0x$f5{ O³Zc492ET~ٮv˜Sv'Zt3"T|:s<&;y>3, 6a’et4ɠ yA-;GWNh2! xlFYu*-N/KΔTmE2mN$:Xsm109,ڎ c;mSg (ĒTCC3K4xPzQs+ۣ9>m(- r.6ߌqҡv0D뉢J#nnFZQE`1>1#Re4p71ruJ =Al.fEc<(?*"q豜V8[hvPIRL_ςWHޕlNrkfjSb{ N40J ǫ /Uxd/ޟKˋ>CBM ?8C?=ҟsuh##(j`f` 3Rm.OL4OtY"9H8SxWy,A @DFBMsi\7G Sk<-KbR,*-EI6 )JʠBԍg'T b&Ico(#(+JI4Of!'=!pM VpVUUÔàR.rیZbP(,F~;ѫճi5>3%ҐFdQghM3^Ƹgr۸(Nt(>@Tb)!4 bs=UFY l)g qf>Y{݇f ӀFCXa*^UQt飦pLܨYlt.M.JxNAzAF껦y%1{ѓ lf4ʙh/b&eb!o6'j5!‚C~kL'edNP.CA"PD7iryċsD=NPx,`p ]XxB &1H[y΁tմ,Ә g1pn8AvW;@ ˥\`98d@3;0.P%WA|;v`4:jt32ե`&P6vs3П|4Q icFpBo"]AUE[WŠ<9K0Zd3SKNOIa4$,i! ֩0T1(v) ~' ƬbBK!Tk:f!9do-hH X;XLhE$6Nxewl$TW6WnZګkn5H͑<؈hW4 lc.geV/p$ ?F72V(uEшD̢̤ǜJwki0R4q*_@xhC.)1ؒkʼ(`jۻsbbc/l/5 p۲U<\IiMFԻE(^:R]ZݜY p&@ajG4T@/"g /!%X:v`ǚXb;X,"3Ur7 9YYcTlTL!mfqfgz;?Sĝ*Y:!n g PX3X+ˎf~ ۆs8mUi ܨqI] 5ۧ1sGh/~ =6r$ `4cK:Nꉑ+q[6n䳦3X1<ĝO7>9bIJq}~r22"?H]?I<303jdfަl0זS .]QJzr kqoqf-}/;cN:Tv ޢ>Sr {**-^m]'mX)u*-^D^ ^)(&+34 Xo^ ޤ.<ƴ7<۞>PvŶRr9Ǭ]Wu`qٷN`1v8L6Bjq3\#Y?k7lJ4cąb2p;]=1rB®* VftacJ .XuRv2I(.G` Qv#ZErD JcUAx+F9ǂւŒL-j<ƈ Br".~jX[ $GԷQvsG] e׻q,[(LPvӴhzI}G Qv=Ǔ(~ ,]O/& Fk礬x7֮ҌmBH"FSmWu%w](vD%[uR}Ʉ-K=k_-wmK!Ie<4-EKLږ7xBB@~w!Yӈn旵\Gm&wjFݳ{ymk]E/5R"]orfrVWTT^p*OWZM {Ow; Vv4*U9)i.V4:$ҙSWHE}[ULIroԎ!1v&7 QuT] UבCӨpJiT]G Ů;*^xM[kC3W枧XU~m:[3󅦋A^iۉx\OD%NZmHj_NieTnmezOxq= W0Hmt\m::em^q+Lhm<--WTI=2m'\`6HۆqhQUPy:r*VU+t!mV Ck jRQ#%*K?wD՚V5F6M-<`2X b=,0b POSby0lMWX^%(j,]qZXYƎ W8EĞPMבu(_n4]G5Uk4]Gn K:~6e1k}ƍ c#kw=j*yf#帑wJl]FފFw^ Z4GyHWG؄T󣖁ϏJY_ruGh*Fp; ZFq}#3gߑwe9gE?ػb c,hYǞ-{˨(RJuq|2e=#/nf0J,b! ;{ 7m[aC1t_'Xxi:$nj1p 'FnZ`FPB~Pre{z"04Klш{2[Q3UʜTlV m5VmQ-7ͧuXsGZ+!21Npd(d@4wmBwZz2 c cU;87I*e3  EgaA nER3Tv-?3Yg!!,i8 5;5|XGîX3Hm`O6zp pS,߯ v% q=aخ/DCn{l6g ەnuԊ,yV;QՇ̥WiYs<+/wo^U,y'u5p[np­Sn_;;,D5 ‡n)`kfk~eE%&4Lp,Zwy=Pa?AH)u!bhcnBĴɾR`rXc^}_Lc1lQMtcԋ*Am +Hت[W_c]l |W!x-50=}[ye2i F]m>DZ!vXo_+"B,j+F(책.=F , e҂;k-8Ē7Zp /_c ݻтQF FK6Z0|j`soTZ0.u([ o7Nycxڝ 1,+XN|+Xw`4J.` ooղXL_8"/7/0 S`\!0u0YSdeBva-'~Ar=*#8%1%jӊ[{0ceK6nef(u07)% ~i`i({N%x;J}GUNp 2Ѝ+)mB)XZV/\;RvTk-3V]WRE)3(U SW=Ð,qDKMߘ=e-6ض A*-Y^@P=v_Ǝ|+)$vjS E^'T+R{W^M=,_Ϛ.+{$!WoM/F~{n&^Vz*7)BZjDZm\;?mZ7:p[S$I,6FXtMTF0}P#5)Ǝ:2y5B yP%!՟hġݘh6DV6 ^8Š-e)DV~!GT-o"dZ D*Y``o+u4KrBj ;10ʙQU]'w;P,{Bx2JQЁ:}pwdS8yw|`сaɏT:Fс=7Ņ,&,&kV:͞h{RV=_lj|`7㏶4_Ø\֍4o_؆:o7A ˥_oG;m{?"b#n}) (C  򚿅(ȅxLZ}]I//IƎ}#ӱ6ί% sSU[: ZD0W"fy17$5~ w ;1i7%V/, 7+_4U6>m J1Bߋ=5~Ȭ]oL=WaYD͢n;Ȝ g@Z$Ѣ4moa X8@iʭ! E{Mq{[`,G00|"BGPًlD :,d'QPd6c*rVYy{l>,XJ.]>z'B߾bݘ?M+ ]/U~`B@81*OP[U.!Zfo( cIK6ٛM `a1 {Xld?a,Rl G]A,J 6*`{1︽ۋOZ8Kڶp{ʓ`{x7SG'{<z$Vro@0f%%Bjaߌh^_ &Lw\ocر$ثdګm5֌XSQE c:z/Z+=w{wSEWnC,^,OFrvg])ES th轻H< $jPSh;Q~Ŵ{ɮPk—llΔlTmpST)WkL6bްLb#@ bOkof73V~I24s^4G ]޻o\#&uuVEjR~:^_I^a}?wE>q:S|In#mW_J6_ F~+/}%peÞ}%VOa@WiYڙ+7;:\{6Xzz/o[W^ͷ4i>:u4֫|[滳O!4f$WN#6%Wt{w/9|}z%kXa><\^Z2vyr߮?vΥ8]ץ3}gF؋)?>^K1K|7/  񴚪bp}ɇi>AF~{EX=9vmcȇO|(r^Rrw磼dnGJE||Ѱ89LJvO Kk>sBrr8^g"dNm?pB,~{/zA|uK_+x<1pwjۥFVZNoYNӏrp~ M9=!_?U>j'\Eȸ=ޯ^o܋yZ ΘZZ|Oma53Oyni1 eX"\?U kmSW $b0`cyDsty8F-t.퇜ZJϯ䞊>=Al} \P]Km"kʿ1_9vFjvGqpwG-Tre|\4zz-a&ծb~!o[ݮ[,}[quߕm9!gqUDuԱHG% a'Z\%rak X?y}8|,#.-[vqO"'뇛wwOn:\G㠗3VB˅ o,yꃻOx\~Dr _(e\)/Iү5uf54H\Ѵ+*3 Y*ty#Iyxx}hiO6߸1[I%/tpuu~,ϼ_aūW=A^W7!W=5]قpix}l K+Ƀo֗swT :][Gb ;rְ?D2[Oe+}gpԟ%|~kbBxlfU&ȵFO7".\'O UtoyFKtdqOA U 14S]9@4- SX%a_=y{7BzQ-I~e߭٠X)KhicB5y7&aeWc~(ODpV]dgϤq-X4pzMuh8W!""VZHQ HV;Mʯb ^d}? RNPL]ar?VeHtͪQp{^&̯XӵuCӈU;tscgrSYSI;Y-gFҘO)zb=lм?^+IW;>S8׹V݋6@ýĞM=b!>)BM+&#MEomO~rO恅ƹtwK/ Ncd)3.zd\wg݈0ךS~!@{~%e]2Gz{ҌH ͂̍V~KP0Wkx VG z]M 'Q?J-0nr_2E[_lR#d;EC*.w\9Z:W-Фkx6B&{=1=t&pqwU,Jo[, 6`K+Xk^<+GLB΂-Έ\&N0N+%+|&N?0I9)T&h܀Sٺ/a$POZY4G谩lF3_;"nZX6Tu¯6NOΚh%'kBibtvI(_3 Z?]-~Wo(4XMk\wnn-YL}tq5#8π̗oh|xY)PO:|8|}ZѸ"}6t{wo_ov "ZW80zIۺaxSB*v쨰iBendstream endobj 389 0 obj << /Filter /FlateDecode /Length 6132 >> stream x\K$qy>Zd+ߙxM$&Ǧ`{zջ̪ :}ȚV]V}V7?]0z ح~yٷ“u._^&lŬn;2ʴNYݺk;% \s ryЏǡ]o6.$\Uvplm|UD7_6IkzB=KY4^9G˲bmh\l4ך\t'y;!T$an}ŗwZJwҶZЦ@ܲVz61խLxNjmL5!Spky@{iWN3p|aL [œ% cFSP-va3^ߎ>-niyu SS;.QPevD'ۋ'̵B{)iW.dRH5JO2)l+U.LR5<}zIU+8IrC/A7`T7J /}H" n>|ѹba8m0 a[ɨ08|*j.gI.:v2 Or! Gи\(<Ʌ ΅“\Zr ':Z 'PXp&}7wh6?J؂g/=F2K|(@P=& L$!Vk}h{+pԬj/~RTJ9ⶖRY_LH.Q*/PweH&LtYD)V0 5!GcZ)]b@gͤ]k8@c^ 6H[S>hKG+37[ʙYN]ok[]x6wkϽiu&qmߠ\"ӓ5,x_eR$%:Xϥ'W9MO2) HczIk CÓSO"1AKOr _xǒT"$YJL2&KRʒTFeI*qYʸ,h:A*?3cgoͦ}:Mgzn W yvgI.ADdk((4xkub`ur>q&LG0+L*2y*AGe)w%lnB J7c3l&!䎝b,9Krq]$?ւTz2Vs$JO2)ozIt&rޚdRՊ5~}ɮCG A<_/BpKOrԞK @d_I*W+I%JR%_I*$+IeV4 zݙKXE_ߋÚesd5OO^!2 tK`_p袔\sn *TH 1’ \KwHL2Go@{')X*u&%҈ bcZ#KqB_Xt 7?@'zpf_)[R`m<\7HӶa`d5U^":͡ߍ7^ԩH:Άi7 &eeN8ߛ8lv{*\JIo4}1Ɲ([4Ib0Nj\ymCRX C2畛ŎuU!zSqQL%HLJ.tqϚ7b3!b_Z41a#r{;݄_LF)C'B}'5axhۅ`b۱]o.ۮnì.MoHjCMZ ּʁCpvPԇ55XA z`ϼ.kѡX(gr.Ö^[zlFkm.lydߴz 浄mŮ;o!53tp$,HU&W> ?c8d8B'4ͭk{ā Xa?0 =0a &~'D 1 ,gx? jbG!ἳF(}ń 9b Qź% qzRS0nG] 2@@a`?IJ9uXNw30mq8d4l c[Q4zR/9*cgig:; ht.z?ʱlf}^ xJeٸro $m vY46V9T3ROQ>ΥTOtgu+DgЅ]!*E PZa fΞ5-:Cbk{PQ:3^no=o%A7|ZkOQs͟wþ #oLQW%+) :癮8SH h&g}5\'U.ܩ#[u|9n !&юJP {^ ~` u[ ढJB!ln"ƧX_ou+`}i05=77,U{c}F'.(pТ\+`</sO:\VB@S9%`|gc EnW, 94LX#.10X@z#Xb) >d~h?YGPzp>VN"~wޟ-+|aWcRf+?0OUHe mY%O^`zG2/h40"y kܯ5 ޿ }Z䤛YމOu°uD7jxA%W[ `i;ZTCjZS-Y;P ]p s(m.N0B֮DIo;6?t,:SϦ,hB}[pΙ%m<[/q TP#gxy!3lgN< PД9ܲi~އMs֥ 1+֔9C)eL갥,P-,gr&B@-&GH+|9ҖUӂ)DXH?Z#IqzZFA9U0*@+n* (Y'=~t~<JRUGy|ÂM}9-A>d_Ye) EA |ECTϡ 0ƒ7?r-i ?Hǩ2Sӥ>q U=QAzjVc)BcI@0/֡吋 BK4IWEKjy@g]/|Ēp%v|炜imJkoRgi}G<{ew;#gxkBNM:x9Q7TS&m=CEqG[kSJBy:0"Ov,шhz|az9άZ̫Իm$ "' 4jihd8z5/V`/@(QO78֛3>pf8UMdϗ{xW&؟6y|%#b10)=OCxq&a_]mU aUwIFUg.xep/f65_X-gUDendstream endobj 390 0 obj << /Filter /FlateDecode /Length 5438 >> stream x\IHv6|}ePVҌ@ncư]Fh ,"rHj)ދ2^LUK C%3{KԻ :^U׏W}{{u盫NKt7Wq݈ԥSxUjw n67n~,Ueet#+N;jQ~LJF4)ݫq~|KoVJeq<;%?=Eq~E۳WGu`;>O:dSVʩb&ZJke]{vooxg/ᚔ0 \5-LsgCA),^v{]9 )?7@q]ɜb3vTب0C2&j?d7x >8;JX[|,w{[[`Oe0:[`>8`Ͷ ux:15DJbs|*YO[cI>ɸd/ x7mNӦ\{.C6#t J^ }4Io km|bct-H``@+7IL)am g*}:gߤ]X˂?ZEׂ@7~4ĀC7/A Qo; ЬF.° _ M{bD.FDCKcT0S Wbû׳fn8`c*dJ^ht_d8Ir{CMbzƐ)ĕ7ƶe?ESzJҙ⦆")o]O*l1 ~vU%?=ǗEY/@UEvKUDWWb:-k)_HLY+rE☊iQWHrh`0`SYd4n)Ѭy[-jtCҸhH;q6_>,qa~ Ϧ3Qy̼E43loc$L,6 os BbJ X+JH?{mн؉^ ˂LqJ!Pdr[JݴC񦯎vQ6%RccqxH~`@ȟu`/{6s­?60)+_&QfLBC>"!O,{﭅pK|/qB^SCn&@ n8zKOFK'Ep.gpP9mH3n7(4R4<1gÁ޻L@.:KTxjPrmVph:ybqiF06<{GCER D\w`K$1%@类5BK|| c}P>UڪaYs *OBt}h$p>`goEYDsD _ R1>>faJ]߶]d TlC(guT9Hdż{ tg cН`oSՁ[ C "25ov`>@Ba 'RY =!*]a#>CA1D"pʬ-8h i BK=O]j8uaqr@?/pͰwԘKdb99b'q0`lcϝ2h 9vȵZVySKP\T8H ߿[ @Ke2(VS_t#1uP^ky6鹑=!~tǾݷ|(bag(ER-r5 hE"fC.yY!, s>)VakY 8\NDi> $:!-ZeI@:*g5AhN#QGi2*/Ą!ǩ%e2G 56<$L4.Q# `UIvCp3=gr5H*e*ͪE g9?YW)) iΡSP>İw+9Ca7COMJw[pϘO,ga.h0xhӴ`40B #'6(TsQ=Jy*zr+@d\p,~o_jϱb,ӯ2(.)dKSaL/]>ֶ`W S6,X3]MXkGt=d/V.ft> @?\N kY\g sZ\د bLn|s) &(&]Xu*'9"5ny2#Oz9Qgl:o0DTǓ\94Xq,?Q&u$AhIGV?YɰhDzghh;ӵWHcFeGc7.VЈD.a)ȦmBp.?BG9W뤂xmxKs_7g0knq!o 'c<408Ns)1+—2ko)g)1ACLuP4pg%.Naو>LWrBm3NEfsDn᜾ZfVQ$%RUg Z,?מr(F ll}l\4k֪EҼP/d)kƑ| 7OT*~ th CjgEGkEpzlE3HGC|4~SlpwHoN ^O~<)HD:=0ҲEؕJRdک/3#q8Lg6 6O7qiwSK|YP— iqp?UD R4ڇ qy>yrY8"hT @ʫĴeNvX@ّB-FYBɺo:ΉD!{ixrdF!_cE[[qj+F3g}+yܖ$pJ[8=J*i/kMD؟ 2H")N݈mx31_jVQzLjEԪi7=; &cBCWk{k1ȩ%HJ[kSlOPg])hYH9MD>$e)6zui뾮(Uҹ:-;k|,Y ݂y2$t31FJ /+$I tcgpj.S"E'"|gv;S:OY\,%,#2zqϝ]GL@ M D0K[Kzӕ6}Nd/l@1d^|>+>R,Р'bOě\Ս'K O3z>0A*P+t dm`;tjS}ȴLRLߧ!q2+ =Zazgb_%vS+䓅> U'i:Y'Bb LM9|Fm{_V+r}&2IH>>GT;ao[={z*u]K~VLo/ڀFTg=*C4#FHCrO%4N/}aܝ~e<ŮC;`J1l0N Úb,5R8ٴU׷VM(,bT>?v'kDum6AlMf*_8kYgq7^pmY5ak5 U/d 79d-˶p~{ @ыEw`m | Hag]suQ*kKS݈vݭnہxw/|oڹ bd관?y f-O \f@_//ZЈ[y&È*+6MX& T[x7uf2TX Ԃ`7ͤA*DEwlTЦNYBG5de㮓63-aqh/|X Ҽp-:Jm8}LS*c:~}8G"=#1=F+'DzfTbG$ oeUNsdKvYIޜY #$i&W^纖y3&Tk&<$o&9l^n/ g4Mo$`ygZVTLt:J^60B|jk9]pw̬6CDsZ|Wim7ٲ6sB> )AxQ{xV]6W~q41 t[j.Z8S.|- UPmg.jϪXfـ0b$=VU\>"Q)RQ Y]d1&Yns߽qc^ni?x<.p>lrav& ~+*'lW~ۺ.Tj<\wе jr#㟴T~]lȸVl=m!$ U5Ot%YV "YzsxYTj˕`&|};@6}woSyB #aO1xV:*:!c$X`ni-RRj~Io?%])ABMm~ kRz ? /Æqv`1bS Ʒ_@񊢤eŶÜ[}Bc<;]x@endstream endobj 391 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 336 >> stream xcd`ab`dd N+ JM/I,f!CǗ^=<<<,o$ݟ3#cxZs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k9 e``` b`0f`bdd? ʾ?}17/w<~$.S@w_>.|ԧ+Mؾ>Z_7o}8,WG .d;[%$${쾞޾ S3flendstream endobj 392 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2078 >> stream xU{TB ~*klKjViO{uQ9R*pM[ry ! AnAVj):ٵUk9{6Y|}zjwN=)1uo+1/a eAr%b{d,K~Ƕa۱X<R2plf [fE7DG|ɰY7+^:k:op~m|^b@-i* yps*JX~ҏp9# 7PA%|i2q6\;,GRBK&3ϧвF[.C-y:LΫJgiO?DkE:r҈~9o҃y%rErueh)F/ۆ$;9xivcύg5mfzwĻCQC2.fR\Mfbch}`5A/tʠk]ݝ%uWޥhlx-נX&ʻ%BsN-D dȹܘWGUĄ< }xQVl&&L0J)oj&F/BRB.}bLVhd:0bh"S 69T025YNNT&؈Uu Yc;9 5龴/΢h UՏ'-[tcN]&vI^rxg#OLv&_YUqD`WvKgu9dLmzSk#aPUN#3rC<>:v@uCH}v8D:̟l7)r4 f< JFRj-vh[c%j)?Y!Kڑ OSFRy@IuF}Mq`Q\|+F\b[uEqEЬ 2AVIH[sskaX2MO(TD )5PR\Y\UVY+<;ؖFhd:%τLs_rr}IR65`s:=8 ~u{`p<\F"7g~3D<A^@:9(t@ޖsЁ.2Ү{OZ/ G=2Q QX:F饕A7,a: xrQ—9+gG6ė;`oV*A":,F4V*;*y8֢^(l2Q(h XƏ \q$f>5K-F./._r=lm`p?\i= ҟe*q!6?tBQbַe #9 \;@Io&ҦZH;K|fOC *CM4@%ݏ{{PєZ%eT𙭍zD1/<%9"{ШorZ"#G.`1"0_YTendstream endobj 393 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 420 >> stream xcd`ab`ddM,M)6 JM/I,If!C<<,~ }/=[1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5 U4$(8;(2Luo:cwCu';!]'uϗ\X1^諾3X̨mn[ɝ=-ݒuef_Z].Y:~Ƥޞ徫> stream xZo<F~s@\IܹO֡I5%D\}~uvEo~3fyFg9E>^|[f뢀/ ]^.tF j y3ϳ\rMsC6Ю ʶ|9!i8g*3vYf~9E}EA|xHj5g8%RQ: 7]3Ŕba׎sw TϯqP ?ߐpZds D ?j^&`$Y!Æ5į8e*d?蕊vѮ>?SrM9 r֖QQ3PO`I[;\+i!xL;U07~QYjI87wƑ#㘌QSqcMQ9i&=MP M:M4|nz׉ n`g06[PIa]- Tԅe!мs~[vG \3Bnf.&^a<*YW񬂋\#[~h*d*Ƥx W |M;$S ^+xa쒩   [;JK6;nPxgۥok~/wv-N!2B P9gj3J'+PX D]?\fU~|&ugݱmM \#h~`n~ݗ~KS&f!N~]|!х #oWo»$X `.rݦ\Ν%)Sjw7xVK{.qtܬ[ګ~0LN 0jZj}_ðׯ*S薤Mү"aSӺڵ~$4%[νR"2EVb6DTD<'`/(E߿ cl1+̰y,32d5:=4c]> i*9׃$X27bJ򱂝eX0K5SLPKiڛ뺶Xp#Ba%h>GUij䔥J6rPXƸMƕgH] c.6DT5Lvv*@شgHKNS|}"?`$2 %|m_SZ\T`=<+d0# ͏MOB8~ut^z೶G@ hMFr(O9\`kzhSIcU2́v( C!t5u]`(` lʥBG!Ip\~4gT.zZs2D&9Ƀc̦?M<@<Ԇq[?cΔC dE:g&ފ&7 0c6Mz2/ĔgӐl A}?A,b4En n 2Y{΃8ym_ߔ뫁W~10(ďCxG 'Y, E̻.o}Y_+uHp 0o/m_]_| Yrv<_+(fNl&4 ,bx^/ݠcj 4my DGNLj]bշ1ňκ"|5ҋD+8K2X3Dkc4I#xK D-8|-P`[8MID~?E{}ދܳ*kp<=+[Za~ZHNZᲦ!8Z;id> H͆$5m]&6})pޖ \c4Pu~4gge/U8,Vd~qtN$#!+rEB9 oqCY}Յ!m54ڷKJw-;y=,77I{mNՐJ73BnhAGP|*/`g}P1pEJ{­ 0Y9ޟSx.RI L&e Ge G e;A$ YVY&c 4i>I Aj}z3HBf h~ゼOG"Ϲ~iu.!rҁ P=pI_`8y/ K<}MTָp,X1}+:Y+ &O9Qd)eX1GWHG7T u^}LR "9U vرQ[Ci!3B\[A-Gt$lDӆSmGGH+Qb_rm79sMGA/8=<@+&Ezx"9!l)ISWpPX0L`G"wv^c2)+Gs{ m/"R[ i~%UeK$JNVNzM=Y7 i ӒX1~C/Γ}61^ NKՕEO: p7>^3WX! lkIONg+Ns .d柆bl8]JDm`OΙa>َy^Q_9'0;:Ju"9Qv #LCͱӗP51 d1+WuvwsAkuy^[/ܑOìn 6 5endstream endobj 395 0 obj << /Filter /FlateDecode /Length 17379 >> stream x}m$9r 7$˒%Ow#í`fgw[YA2VfeuNUwWFɈK03/W]5w_+W?nW鷭'vlFwWUW7~Ϥ< r#xoumb;q|4>;7_n޼7NfDa~sO6釛O?nϱu뻪:vO>ö c|a/7Km|v|_ۿ}o_Q5IЎۮj[ Wm^ݽoW$弋[_um{u;?n~7IBocZ"Zэ۱jK$V6Tmj U["Zco]ՖH֮ 43\;\u[cکܰu#;j7] }M7m;l۫N:  mGq;DvHzv!bCgfFH*h U$VoZVIU6Z{qI-%y<VS qwf΅ gA0n`SF_ Xr%8}: yɑ*XTڴTtai:utBrj:y=Ӄ st*yG){FCg*9ݽ@y<(G; )p.\(ᔛ}Mv! \x'O/?p|/r`x$Lh\ O>K,gb +t_>9K>6ݢ}|{ǭےqrWwm#Wڭ˷pG„%^k'tOte|ev;ZX叆X:JߧܪҎ6 a-1p M9vnyX~;Y 2TB2xHo--RzJCkda91 NFonpr'z 6۾|CF'ҷ,c5 EUZ#$<m3m+}wqz C{HYW'ޛr+ !&J c|ǔ/5֦xewx\A#4-_| >QZh{A(eX RZHBvZuեՂX\f;i4\hAʹ !g i;Ke!VF1RH~! }Z-->E OE2FWkmiAʹTHhI[i>rk!VJ ɷt&U*B RX%J9|_;IF"ħCqMI Oc9ϟqt?}NAŔh䉇qB! LW&:CĔ* .sni2!X" 㙛nHAJdɦޫ\g$X~ILiR`Ts|Y nkYVW89 "⦳@) ((P+P my PCgֆIE{l@)tJ'ENp8!pk+dU.ptS='H' +N((Rf(A sR, ~Trjd(Yj.WX yưTbX ؤ֠!Hd/**9-*"Xe6%əP~Tҁ+PՃ10sL.0sg"83g )ިO!TD7C"OҔo JlVT^/L?Ӻ!$p}kH׳y8.\ez>IDžJs #P-S-81Ղ܋fZ%\R <1*913cxgx<".Hgo_EmϓiHZ$\vA{䍒=ʻqW;1 ƒͷnH46 $hӖohXilZ26-mlw~_KcZI2dXuJKZ97>NBCpvD޲Pf;fC}- :Q ߤwn 4}ne/S\~GF_kNb R=2WDC,, Tkf{}R٦FM pZ/ú4Q"6z1) bai 95иB[#!* |8K[>rkK 7 adGE^ِAHː;_[t(lAڅ i\IwԮlr6dwDP |Zaj0A$bdnV$P\C$⛴P,G VX)-~$r[DR,kCuc3VtfqʊЎ2|X +ڏ[lFDR,|g^ɯi%BER,C r`hBGBlew׺LŎ6XDPLuҲ:$]&}U˫v& WG>1wO 17ٷZ"ZX%9lhj]Shjn~H֮noniV^y[?J$#[$9qsZtJuuЊޤ*JdX*JljI5*7Ly%Jm k4Y?n֭ҝ MHᷛqt 7!qݤ(wnvc{p[>wFed0 .tu;i~r%컜> DIE{$ɫniz{~nu0Nx<4vdEUuDSp-V!UO-V| AN`'m*|3]*X`E^p+ X+,iRGv)6<1m4`QÞ$`Qg< X:F׬VP됒B XdRØDg /UcXR/PAu :`."b LXz X (WlZKg L1c| :d VL+X0VS(Pkư@edJ% P"1 |57>c[@ o;VC|Bs^Aj+ClO.rE@~&B^(zūiq}d+'!yy“br20 <iqu` 㪳8g3 40%qWqB9$OBlvorY502^:h1']=r\@[[ % ɩٞM=4lO FP\g3){r k!ytf2;9=98 ~fӉ;ta 5x |C/Z¥Xq±glvS<)Η]}qNZ@l~$3L31 = L7/Cv*9?\q{>0>y$ϸyqO8t3ZRV8gطlƸ(_X=S>~+BrCNڢz/j5ETw}uIZ7 %f&]~"2##ϙg,iڬP=ont'{lID )C)O ! caL7C=.bV 8 څik~A rێЎ˗DAc=_φa,Zw|\44 XƘ%ͫ _4v|9MJcnϤ!۳ q9ULJty%M6 4-%D%;*rD&jսQѝӗPN] EraH}ˆǍΉ\fb4R]xA^uk$!gN>[T\93}8jTo4úI:+HR|`.gJeVECjKn&IF </Rz .4| H1u"R[LĄ s)N'[8S҄32wɓ1-fڀsF4:v@sYSkd#MDʅUդl!FOmi{kDS:me')>$Wm4b5 рݥڏ^gFҭf-.KbsKm*SI|L{HE&VsQ/Le &.-Ndh[+x障G(q䐮U S)i&QAR&=d>Ne & X=HNuc ׭ h0qXACʥ%JEn{NJ]rˤ IJkHm\FC{ ͰB4Ji#Ʃl!&Ik %JA[eS$rNOTZв*P }Z"bd6j'ޥ葂aQH}Rܟ"8{yl$.g44Lu)$3}2H&ȟaq^{pt#i/]&>;p@=R ,mʹ-HV aڂhu4B$FkWmAbFk$EB"lYR &Ѱ'Ѱ7stWtNy:##;>kVʰN%,9t`j;$,HXĩ;(Fdu"FԘԐ|,h8aódJgtM)O.]SxA+xKJIxw~5/RTx:K]={"|xr܁|E'I*DXUT#jm{ŠF~ Vɏ"aXGq /W4hN3XT8)w\?t NNJSUCJRr!VHEՍT~I)P@B,_cUGQE%J_#)(qBӔrW+[+Eb!xJn\.K4zơ"W%X̭mbFU2^d]0zL3Zo5IJ/Jk7קW%B~ қF`z3btNW˜W/y ʱ]r.8qTvm22D1p K1ʯ2~:+~1} 0zb ^WB]DaH]@o]Rؕ%ݰ+D]!J*bƃ\0G`UI! |Hٕ< bVv( \J.xaH5j8Ȁ]D]إ=9.$ Bg]蜜]ٕ Q`WTEPn z%&Vzm^S^ǯZ .WzOM8 ˂<08trL_a(G#W!eXf(s s"XZ"Xt@`,qFe|C`2;XlgKl+bA,˹ @,:O bqxbiLno` Cg`Du X4 6_˞7_eSZ[S BGtϯhO0)J-C@.D/\Eo3z U2^{7fdvq2-SvZE ;m-soY7o%\Y //c@ֲ_SZU|Y"Xf Yr2.Sslc.Q_(I9"sPJ9` eTn6_~~UG'llg2 RpJry?r^ w6م`Rz(XNN/F^2:;]} +:T.bpeWEgH@oQ9L!j:T@8gM8jW~2>m#+ BXvKu*O< .^=(r?2dA;u/`s?8_`y/N ΦA[/l )Żl.[hݐ2.8|c | 8Pq93ϸ/U%P|61 K.Iϒ`<% E@%K#X^Kϧ=SU-6(vrA)Hrjr,P>=L);#)|v,'=33\Y\X-P\A-P#R^t?|xQuJ`Kgs=\`y/Wtd>S~%v`ւ{'f\!Y`|+kMva> +kUif_w뵯x.;el>k~qx91.>=x5&JSsHal8v,P>u9R>~-PcP.%Ҏ|'(d<;ZgG/H^<峹f(_EycX8!# kJ t'X${2#vreƅN"\{>j=ǁly2h#?C9Lzrf4:7DkLe&%rl2Jiſ%%rF.].9C($& N\O%Xtzyf%n?3A/lq; ㎳ pʴϙ8X/SN8Ⲥ\dB(u$5^ėW@Ci/!M* m))bJ+g*TЙJ1K A#4-cЂST=QZ-\yGbP| FNGMZ$bH+A*}iK9Hʩ !a8sZ4}2+D) TN$3 $4m@3ԗ=͇>1rf&{N-H9j$][ Ci]zgB4`wi#W,I"Vh&rg*S4H*ՠ3 bJ|t\AL 1QZȎ /DkDű ]SVp bZc&VX)~$ߺC0pKu-o_)e4i8vșT#gPN]p {mUՇ}!VF1RH~0T$ٮS&{E]NV ;Gm]UAYF컠kIUd-S%mAXE )kZ(kǕUVF1Rx0};T 1Bp8t7,pI\[Ȅ e0B`ui"y(PN$UIˉ'/̧}NxH0AM R}p t(83}2+DCj?΋y _HcҢMTb t V 1Z26-HT+|#1 6j۔+hAbj G%EsɊ6jVdEfE) |#JAŗA+(/gT[FTR=IU*JةJ<ϸ:L6:' 6qmf; :0f'Oq8'))h]Nqӳ>}]èNq#T&"Fm15qGY or}9ǔÏ0 97K2ޫe$ݲfuYRZ:'w9;JIzH)pnN_5!pZ"-Nm}\L*)07IQN9IjnvP@z'=* N)'gH P@nPRk1 Щ$G ( @€h @C ;&V L@UI T*^T%:jk J(A0ab&JN\z RG HdHͥ{z )~N; R)ಀ::Š( 1Eg-5h PPU@@9 (80=-dm|2ۀo?h}TA%Jr OX9Mu}9Wd6~)n ?GtyYO9'y+q.rk!VJ 7G??"5ܟZq|q} <t|q8IZ؛1Bײ~*s B4`wi#曖?ۗJhJBL_)oPߕS\A$uGvt\C QZȞ G6BE?%2h&Kl |U6 E5䉢Dd !&vH a]VV2GY4-k# }Xe4Q.kJ ϼ*ˣ bP;k>| n$TSxA (5]5H RA`=% b"N$b30HY|T8H{F(q/LZ(KpLlQv";FWDFcv9ZYpĤTW-WÛұojSʊ}Wp'y W7p%0|+&>2ڄmMhuVquZ!ԽkC %n5POswjGmO?wCk}=ڡPSbTxhKܺmZ} \F3zʐF]]>'M胭_] h굼W9:SK;[w 5RJ8ԥ1y^z:!N鐊8!i}9& UkzLZ 90ǘ;:ԟD m}ԭg0SnDԧh,@h6=_nH?w=r@hټsKϹ~LPdvԏ>jzNP;|3g;:fډ;cASN1Z8;pfXZXR5cw>L#g(ZHxQCQ['~˧EoMcYOh5r?*c)GNT-_;-<>?+?5i_z~ϗu6hScBS?IZXg4S;}䜠ϝ>ºrEZ;gWgLvH6pc CkS!LTb1Oi4Ρ-MTwsMiuf(Ϋ1S5Xod:WY:c)+w9CoN=cNNIv--,#wiBp< -؎ {R1 Ju/лfܽEeIE+^ H4l?w14'ݗϥ&n>@W5}Q9dd7t_{K% O__,R{W \|ojUhMb6_vI su`;3ס}_WnŖ÷{r895}fr_N1v'o.|_ x@9g'' Ƣa,GۢEírJuͭݪM&X"S?͗swsճ"6h5ChbF[#k!#)xZɧ_/՟@L`fj޽ oh!6ӏNg]YGcm\hwRZtў=Ʈ5XLm9jNbn؊#4:tЕކzW@s_0hoiϪl_3O07zwgٖ ;cϮ+gAP "Y)o\#;v3HNSh|awelgECCnQS`tw{83`O39Al׻qZy%-4jSo"5iޙ01eRUM|έQ'`xz“F RkE~KGin vJ!݇;9kvF ǻ #uVb8z>IA1Ig6;cɶ;Lj6\n$i(ɮï+iOCKg~3>@)<5upj7 :h%40Z?}0qa_:c6Zwv Uplzx=2F|we?aKpu=j vеtwZ-|q=o9`]O̚W7[ kR^VΜa(cPw}sZ[:WƑ6?/Ӆ0mOcgom~w}'gܽU ~kY7O%Y60W߽[@3fB 6MW?_|'m5.͍] ,oԩ?!A$tgWi/H`懾?֦[,zS^bxڑx: F4㜝˻/7Kڝϱ\@ JCI@qPn'R!m&*)`hhb{-6m4< ccۢƟ4ͻ] k u.}F Q_i?b#paضu^䍀~*w7%: .ڭO[;oC><>XE,7UpWg@OjOԽcfēa&(w[B9b*]UR';-ú9i(T_n>o?}gwK0Xg7ӘDQdxOnĒ }iL_~^|^L^klV6{OXS`#G~cIyyZn}N6͊{hW !AڶyuʖUX)^}4"6CC/~գ?0YFߔ&kEOOWLL{ylnv׎g2y8"$WL+nO-]v\s66C{?}J|h/MO/&xñPӘU;Rƈ-ˇ!V [~a$L't7~Vտ9iuz+O]ƝUo߽wendstream endobj 396 0 obj << /Type /XRef /Length 287 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 397 /ID [<85fa8c73b0875e6b5de8ee1e7907e875><75e0a4b050501416bbc930df4cbbde0b>] >> stream xcb&F~0 $8J?u@6P6#Ϡp0ޯH"3xl?jJ@$'/dRSC) "y]A$ w̾ "΂Hn[D u1EApXenGtQ`)DʁeWH`B`Dqv+-`73HQF.K"c6jz&ȰS`OAs׃& RlrX*gvH%Y9 endstream endobj startxref 336573 %%EOF surveillance/inst/doc/twinstim.R0000644000176200001440000002633614615167576016525 0ustar liggesusers## ----include = FALSE--------------------------------------------------------------- ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("twinstim-cache.RData")) if (!COMPUTE) load("twinstim-cache.RData", verbose = TRUE) ## ----imdepi_components, echo=FALSE------------------------------------------------- ## extract components from imdepi to reconstruct data("imdepi") events <- SpatialPointsDataFrame( coords = coordinates(imdepi$events), data = marks(imdepi, coords=FALSE), proj4string = imdepi$events@proj4string # ETRS89 projection (+units=km) ) stgrid <- imdepi$stgrid[,-1] ## ----load_districtsD, echo=FALSE--------------------------------------------------- load(system.file("shapes", "districtsD.RData", package = "surveillance")) ## ----imdepi_construct, results="hide", eval=FALSE---------------------------------- # imdepi <- as.epidataCS(events = events, W = stateD, stgrid = stgrid, # qmatrix = diag(2), nCircle2Poly = 16) ## ----imdepi_events_echo, results="hide"-------------------------------------------- summary(events) ## ----imdepi_stgrid, echo=FALSE----------------------------------------------------- .stgrid.excerpt <- format(rbind(head(stgrid, 3), tail(stgrid, 3)), digits=3) rbind(.stgrid.excerpt[1:3,], "..."="...", .stgrid.excerpt[4:6,]) ## ----imdepi_print------------------------------------------------------------------ imdepi ## ----imdepi_summary, include = FALSE----------------------------------------------- (simdepi <- summary(imdepi)) ## ----imdepi_stepfun, echo=2, fig.cap="Time course of the number of infectives assuming infectious periods of 30 days."---- par(mar = c(5, 5, 1, 1), las = 1) plot(as.stepfun(imdepi), xlim = summary(imdepi)$timeRange, xaxs = "i", xlab = "Time [days]", ylab = "Current number of infectives", main = "") #axis(1, at = 2557, labels = "T", font = 2, tcl = -0.3, mgp = c(3, 0.3, 0)) ## ----imdepi_plot, fig.cap="Occurrence of the two finetypes viewed in the temporal and spatial dimensions.", fig.subcap=c("Temporal pattern.","Spatial pattern."), fig.width=5, fig.height=6, echo=c(2,4,5), out.width="0.5\\linewidth", fig.pos="!htb"---- par(las = 1) plot(imdepi, "time", col = c("indianred", "darkblue"), ylim = c(0, 20)) par(mar = c(0, 0, 0, 0)) plot(imdepi, "space", lwd = 2, points.args = list(pch = c(1, 19), col = c("indianred", "darkblue"))) layout.scalebar(imdepi$W, scale = 100, labels = c("0", "100 km"), plot = TRUE) ## ----imdepi_animate_saveHTML, eval=FALSE------------------------------------------- # animation::saveHTML( # animate(subset(imdepi, type == "B"), interval = c(0, 365), time.spacing = 7), # nmax = Inf, interval = 0.2, loop = FALSE, title = "First year of type B") ## ----imdepi_untied----------------------------------------------------------------- eventDists <- dist(coordinates(imdepi$events)) minsep <- min(eventDists[eventDists > 0]) set.seed(321) imdepi_untied <- untie(imdepi, amount = list(s = minsep / 2)) ## ----imdepi_untied_infeps---------------------------------------------------------- imdepi_untied_infeps <- update(imdepi_untied, eps.s = Inf) ## ----imdsts_plot, fig.cap="IMD cases (joint types) aggregated as an \\class{sts} object by month and district.", fig.subcap=c("Time series of monthly counts.", "Disease incidence (per 100\\,000 inhabitants)."), fig.width=5, fig.height=5, out.width="0.5\\linewidth", fig.pos="ht", echo=-2---- imdsts <- epidataCS2sts(imdepi, freq = 12, start = c(2002, 1), tiles = districtsD, neighbourhood = NULL) # skip adjacency matrix (needs spdep) par(las = 1, lab = c(7,7,7), mar = c(5,5,1,1)) plot(imdsts, type = observed ~ time) plot(imdsts, type = observed ~ unit, population = districtsD$POPULATION / 100000) ## ----endemic_formula--------------------------------------------------------------- (endemic <- addSeason2formula(~offset(log(popdensity)) + I(start / 365 - 3.5), period = 365, timevar = "start")) ## ----imdfit_endemic, results="hide"------------------------------------------------ imdfit_endemic <- twinstim(endemic = endemic, epidemic = ~0, data = imdepi_untied, subset = !is.na(agegrp)) ## ----strip.white.output=TRUE------------------------------------------------------- summary(imdfit_endemic) ## ----imdfit_Gaussian, results="hide", eval=COMPUTE--------------------------------- # imdfit_Gaussian <- update(imdfit_endemic, epidemic = ~type + agegrp, # siaf = siaf.gaussian(), cores = 2 * (.Platform$OS.type == "unix")) ## ----tab_imdfit_Gaussian, echo=FALSE, results="asis"------------------------------- print(xtable(imdfit_Gaussian, caption="Estimated rate ratios (RR) and associated Wald confidence intervals (CI) for endemic (\\code{h.}) and epidemic (\\code{e.}) terms. This table was generated by \\code{xtable(imdfit\\_Gaussian)}.", label="tab:imdfit_Gaussian"), sanitize.text.function=NULL, sanitize.colnames.function=NULL, sanitize.rownames.function=function(x) paste0("\\code{", x, "}")) ## ---------------------------------------------------------------------------------- R0_events <- R0(imdfit_Gaussian) tapply(R0_events, marks(imdepi_untied)[names(R0_events), "type"], mean) ## ----imdfit_exponential, results="hide", eval=COMPUTE, include=FALSE--------------- # imdfit_exponential <- update(imdfit_Gaussian, siaf = siaf.exponential()) ## ----imdfit_powerlaw, results="hide", eval=COMPUTE, include=FALSE------------------ # imdfit_powerlaw <- update(imdfit_Gaussian, siaf = siaf.powerlaw(), # data = imdepi_untied_infeps, # start = c("e.(Intercept)" = -6.2, "e.siaf.1" = 1.5, "e.siaf.2" = 0.9)) ## ----imdfit_step4, results="hide", eval=COMPUTE, include=FALSE--------------------- # imdfit_step4 <- update(imdfit_Gaussian, # siaf = siaf.step(exp(1:4 * log(100) / 5), maxRange = 100)) ## ----imdfit_siafs, fig.cap="Various estimates of spatial interaction (scaled by the epidemic intercept $\\gamma_0$).", fig.pos="!ht", echo=FALSE---- par(mar = c(5,5,1,1)) set.seed(2) # Monte-Carlo confidence intervals plot(imdfit_Gaussian, "siaf", xlim=c(0,42), ylim=c(0,5e-5), lty=c(1,3), xlab = expression("Distance " * x * " from host [km]")) plot(imdfit_exponential, "siaf", add=TRUE, col.estimate=5, lty = c(5,3)) plot(imdfit_powerlaw, "siaf", add=TRUE, col.estimate=4, lty=c(2,3)) plot(imdfit_step4, "siaf", add=TRUE, col.estimate=3, lty=c(4,3)) legend("topright", legend=c("Power law", "Exponential", "Gaussian", "Step (df=4)"), col=c(4,5,2,3), lty=c(2,5,1,4), lwd=3, bty="n") ## ---------------------------------------------------------------------------------- exp(cbind("Estimate" = coef(imdfit_Gaussian)["e.siaf.1"], confint(imdfit_Gaussian, parm = "e.siaf.1"))) ## ---------------------------------------------------------------------------------- exp(cbind("Estimate" = coef(imdfit_powerlaw)[c("e.siaf.1", "e.siaf.2")], confint(imdfit_powerlaw, parm = c("e.siaf.1", "e.siaf.2")))) ## ---------------------------------------------------------------------------------- quantile(getSourceDists(imdepi_untied_infeps, "space"), c(1,2,4,8)/100) ## ----imdfits_AIC------------------------------------------------------------------- AIC(imdfit_endemic, imdfit_Gaussian, imdfit_exponential, imdfit_powerlaw, imdfit_step4) ## ----imdfit_endemic_sel, results="hide", include=FALSE----------------------------- ## Example of AIC-based stepwise selection of the endemic model imdfit_endemic_sel <- stepComponent(imdfit_endemic, component = "endemic") ## -> none of the endemic predictors is removed from the model ## ----imdfit_powerlaw_model--------------------------------------------------------- imdfit_powerlaw <- update(imdfit_powerlaw, model = TRUE) ## ----imdfit_powerlaw_intensityplot_time, fig.cap="Fitted ``ground'' intensity process aggregated over space and both types.", fig.pos="ht", echo=FALSE---- par(mar = c(5,5,1,1), las = 1) intensity_endprop <- intensityplot(imdfit_powerlaw, aggregate="time", which="endemic proportion", plot=FALSE) intensity_total <- intensityplot(imdfit_powerlaw, aggregate="time", which="total", tgrid=501, lwd=2, xlab="Time [days]", ylab="Intensity") curve(intensity_endprop(x) * intensity_total(x), add=TRUE, col=2, lwd=2, n=501) #curve(intensity_endprop(x), add=TRUE, col=2, lty=2, n=501) text(2500, 0.36, labels="total", col=1, pos=2, font=2) text(2500, 0.08, labels="endemic", col=2, pos=2, font=2) ## ----echo=FALSE, eval=FALSE-------------------------------------------------------- # meanepiprop <- integrate(intensityplot(imdfit_powerlaw, which="epidemic proportion"), # 50, 2450, subdivisions=2000, rel.tol=1e-3)$value / 2400 ## ----imdfit_powerlaw_intensityplot_space, fig.cap="Epidemic proportion of the fitted intensity process accumulated over time by type.", fig.subcap=c("Type B.", "Type C."), fig.width=5, fig.height=5, out.width="0.47\\linewidth", fig.pos="p", echo=FALSE---- for (.type in 1:2) { print(intensityplot(imdfit_powerlaw, aggregate="space", which="epidemic proportion", types=.type, tiles=districtsD, sgrid=1000, # scales=list(draw=TRUE), # default (sp>=2 uses 'sf', with a fallback) xlab="x [km]", ylab="y [km]", at=seq(0,1,by=0.1), col.regions=rev(hcl.colors(10,"Reds")), colorkey=list(title="Epidemic proportion"))) } ## ----imdfit_checkResidualProcess, fig.cap="\\code{checkResidualProcess(imdfit\\_powerlaw)}. The left-hand plot shows the \\code{ecdf} of the transformed residuals with a 95\\% confidence band obtained by inverting the corresponding Kolmogorov-Smirnov test (no evidence for deviation from uniformity). The right-hand plot suggests absence of serial correlation.", results="hide", fig.pos="p", echo=FALSE---- par(mar = c(5, 5, 1, 1)) checkResidualProcess(imdfit_powerlaw) ## ----imdsim, results="hide"-------------------------------------------------------- imdsim <- simulate(imdfit_powerlaw, nsim = 1, seed = 1, t0 = 2191, T = 2555, data = imdepi_untied_infeps, tiles = districtsD) ## ----imdsim_plot, fig.cap = "Simulation-based forecast of the cumulative number of cases by finetype in the last two years. The black lines correspond to the observed numbers.", fig.pos="bht", echo=FALSE---- .t0 <- imdsim$timeRange[1] .cumoffset <- c(table(subset(imdepi, time < .t0)$events$type)) par(mar = c(5,5,1,1), las = 1) plot(imdepi, ylim = c(0, 20), col = c("indianred", "darkblue"), subset = time < .t0, cumulative = list(maxat = 336), xlab = "Time [days]") plot(imdsim, add = TRUE, legend.types = FALSE, col = adjustcolor(c("indianred", "darkblue"), alpha.f = 0.5), subset = !is.na(source), # exclude events of the prehistory cumulative = list(offset = .cumoffset, maxat = 336, axis = FALSE), border = NA, density = 0) # no histogram for simulations plot(imdepi, add = TRUE, legend.types = FALSE, col = 1, subset = time >= .t0, cumulative = list(offset = .cumoffset, maxat = 336, axis = FALSE), border = NA, density = 0) # no histogram for the last year's data abline(v = .t0, lty = 2, lwd = 2) ## ----strip.white.output=TRUE------------------------------------------------------- table(imdsim$events$source > 0, exclude = NULL) surveillance/inst/doc/surveillance.pdf0000644000176200001440000042213614615167604017701 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4698 /Filter /FlateDecode /N 78 /First 649 >> stream x7<叚;.W{urD^]h^.ϴT9]]+-K4j[Gy#DLY&F5L/ԢUo籧LyE^\X ]qJ7$Q~C?F?[M(%Q^GR}x 2=V,u:X-޺?\Cd;ձeqs/)Y|V/{ޟM:ay8,{o5vPP+Aߟ9Pr _V@!X@| ѓ0Zx>Mdkh/$Kpl]jT%x/8ZzW9rs@t5 o'Jy&i&R'\3^qm"^-kܰBx`؈dīxqd2o@CR!"oW~9Gǃpӽ처^zVLOAWPV z uP@ 0 $(pV\.v(({(qo``4x6PBᙂTzlxkH.>Wia^\]0x'9=o^&)9-)9]%]?WէQjеWRJ(@tXASosb|z =LpP92DtmjMӈe~IA~IjERH-M C#)6H %.O \'_C=!JQB|k Gl:oOڒ.fXTb|wVbSY[/Jw5.u`J!h MΞ5ngUN>}.ё٨D]DV#Ttj:KfVHưHw}ݫ$8Nwf]4vwjTMoӠ l3; :vm xM].4?R, mB%}5h#{~|`~M]CWڔZ:(saZ@9fZ:[3H cI$[O,K ^ !RW1ƿDZCr/ꦘIǎ(MSNWb6O{G!vst6H=iW1DewP)7"f0-V4sb^OC4QVu| jv,0HDw`p+^BmX$tlOi;)BVT PwZvO^7)rN?-r؈`dxsq97+7p;.x!mI`J5i[-DcXXv\JHw2, ?ϱPzo#AQSdz9ڈ oLo(z#ıI1k{SRL lAnۦz_۝0Z *p[lS}sϺPOlo-DjCLRTs,v֏IQ1nƓ[r*lڋ>RNOX| p4ݪB+DN;yٻ";5٦ԦfKWK_W^IA2o۩)h6$zC1ZtL޳)!=6+1xn-Kjlk gfIiY8n+{Kf?/r&EK~3XixhRʸ1@Ec %0+:0edI *9 -# w}go/d5gVFuAƏ9k1⾨tIV8dB٪LTᬂw:e74}ͶIdVP_`Gj:/"[:`)&uS<:,ԝj- ʤx8#L} }~܅yz ?T 1peڣ܏r5K{!='n:CW;;BTsFX4N)aEVDa+6v߸of1CSiUU_`? R>S- $+3_Ovhc%Hgf  He @VM PFʻ4@!Z1e5'yN 0x]1¯GO?(],@y_2?h;Rx}F.X~ ZE? ;A1 >Ъ-l[B1ppLvq?Q5w>1ɸ @͂ q(Da}"1, *G VŭCAj~`|,"=gK6LO 0VcA8^GԣKv7ܦendstream endobj 80 0 obj << /Subtype /XML /Type /Metadata /Length 1511 >> stream GPL Ghostscript 9.55.0 2024-05-03T16:07:00+02:00 2024-05-03T16:07:00+02:00 LaTeX with hyperref Getting started with outbreak detectionMichael Höhle and Andrea Riebler and Michaela PaulR package 'surveillance' endstream endobj 81 0 obj << /Type /ObjStm /Length 3211 /Filter /FlateDecode /N 77 /First 692 >> stream x[r8}߯NM ek*Uq2dN2'Td%$g= ER6Eĥ}8 @A1fE 1`ǼœgYR12 &,J&S,*& e@h-SJB3ecH*12cR"*B2-GB1m$}L{K Ì4) ᙉBTBDfEZE ɬw,zP\jD@WaNiJX洡̎9)WM͐J0!T X@I,K7DAe5RRA/Q=DK]FCRCB4QjtQ4"uiF}zHJPj&2"zck3:IƠJh%IlCkɐF*K]U@ k$YH@RHgP d-Iu+Wi^3^Yw?OEMj9&1Ȳ7A;e|7s,|>-9"n!"\]KߐMS={}>LsJݖwW}y=w`]{1,Н9\ٿ|4ܛ~A{TFQ]0c~\=Y>g$>jK*u3=;Iٻ#zכ̫Nm/-pԮ!o(Ke}sulgۥg+=os앋gYϦC ä#]2\ϱ#Թ)feng{7]p]%NKQ_&@鞗B7Ҹ2A =2>.f%xZ r$qn4vs2t}0|l@P%;Lg KTep옦=W'i{ RLq񻈤`#ʦH"˺T P'I;?#W2!;"B㘚x pM-h ,6H1'%SHԦHIv!L!Fh ImpFR>܃aC9-נ}%4eh:)^j#淳pgF<~Hf˺t"Q`>>,I=G@6iT–̍|3TA`Wl* *VijJC+L;l\ U?/3`SPltRؘr LKU?WDe&D!xGS]]ۿhL[Q$[e]%R/W5~\-g/7UeS{<^daSvegavEv1XovO8Mn$fId7DŢHͨlͳK6"[\r3n4?) 4/`ɘ{'O" FG㜖'JH {Gg'4 -I"~jXlAj ''=07M< B]͒DE sv(%V o s]&wF~f{pMNYp}Uzi ys>وucIJfuB7FX_P(,eO-)~䗷cm{ßajzdzsh~DOC|q ?5 Mn `:*Mޣ;Uߎ^z8&eaа;1SPS]-s8f4[sK8rSLm2QfMi$o_~mB-HњKDOxfݿu:[A5ך}ly(f[9=m}NDi-4ZK߾dX fRB#hӆ^8  1p %U"m>D" Av]Zyb8lJ l  yh=C;m(޽m _>s&ӊînd*)4;fm3{i>T\F%J !ZiaP^ΆfJ &gEǙ"=] qx:1Y%&;X -BT$î|_#u1_Xʿ!-ljTyi{lїo޾}]q- I5( UЮSB[tK4M| j)oyAԮH777ȤdJ$8E$F@Vs᳂Vla)$4NconIi _%!ởT$8:ͨU!r gZK=$3<ĸ ѵۉ4㏮1#c,L[S:ڷ|J Nj"vpdlmu%zum.Hmq)݊ie .b{Z(Vĸ IK\M^>4p͠? vj_MoU8cv(x|#'^^ wl@(!(hΦ?/}#zYNfe譼ZcuO뛖Vť?#Žn?uc׈ti;7 '9ܡMG"0NG&)N,E"mFw#֝rŚKxaֻR;?g憂1apDp~H?ٷHJ& 6l#Fȴ̾0NE +"sœ^r{Rh8}kz%l)l>\Q;EE鯴\נ/>BZ%#Fֶ_vm%]s㊭5zuͦ}P\mmjcWڲU+֖endstream endobj 159 0 obj << /Filter /FlateDecode /Length 4665 >> stream x[Ks8sW̉*xpGGgfg;"C%خŲZ'dJnL $D>zU.lߔWo~}Sӫߗ߼dYhR]UUhTsUfQiwu}sQU좬.Wl+xU:~n +-|+` כ8ئn6c~͕1@a.mS,7E銥ׯ]۷yS5)ArE 3.͔u45&Y.]hkbk[,^>H!f+?Z,:AN[>cirmW^t2ek ()TQ5M7`*=9dI׵E(D{T Z^ҵA%Adb{3Us:>"DZKډpj02>L xLB6j˹~E}y6zSOL7 7 h }յ!r1[{XŇChVb?uR 1i&Noa]DCcޒOZ☎2L i/УOV^[S F^AhX$Ju*m/8Jىmixl 8xaێ~{?wT<`\'ZC%Iΰ(Pmu~>c.u<5O~yjtmLw`15k X:T<=ze?O#o9bw@y* eDG?W.SE>jU"DDQ|eKD[=5T3bAfaN]l&-cdo 1h8ۓp З(h0h,!qOTcPtP +uzZVnVߟALG;EB;K !pkB@LBjl?fPDVB<5EDtֆA; Iҧ=H;fzjgDl,k SL$IǕV,X'T-%Eh%qqGTɨK( FM\.-!L׹4 ү4 ib&\G.7^9bKm-R$+[et-SUNR ˊBe~>~`Ǥ| g=cIʼ>YpJ*]`Z ŭi5= JUiJ.Ri^WAj,fErK#)jb~*r㔩k8&FPB@DAl /R l #z)Q7R|d9x_w'L42uL ϡm#/=ϗ0'8rC-L0& &˅ħp6jGȕl29}Ӷ?fҜ 0Tyj١4$Pg&ci wc\ EZ2:kS{KTQMk-[Ȭyxj=@CIx2%2C8ݐYb{PSv{l7xǧ^!w7'SP" N7Gm#OM#$S -O*"gx&t8 {ǽːEaO;҈0+rA7/Ӛ^J+13@+F5afv醼iOz*1ˇu'U0"%)-Q쫸E-&gN粭;Z58@ʜ~DțEcHu8)W6Gǰ EU8lNP5 [!*L-qN x]؏GPzUK'pys<)l|T^4ϙWVPpɘɁyL`z˓- Gr{||y n%,,[i8&Ɂy@y6Ӌ`r@mL91FjK` ̹~E&p6BZW5l+jT>#IA|/U7xZY~IΙuz: ̩1̵rj|^LU6)S1N~^B?O UmE{+d8Itc1T^Ɔ6@!JYm>W6e=q)V6/[ w9@M ʏFPF!Fuz wy775'h,eN("%T]EDhŠ#s0Q1޼ w|!K MF.s6`İ'$+oi]gNhmљV\9H|>h>1TµP8f'㜪 vjH`'~ <5 椩OrvMMG]a/DH hGhSI^p>dr%=}-M@&$$:d LOb{CnAO?v8C"Cb!Fn StB#!,'9Ƭ#[\ƥQH( Br@06\!C o7 yL:KsVV.B|~'IHr^sn|ys+ŀJF]% r-T<q ͊oLPYS?Ahn.0 ZRkYg+G{: O1qt֞Tv|:հ·L H]7|-gVL%9XIIZȂO iS*odN! ^|P7x4:ͩ0TtJ )ACWFi}N9 t=(c<~`[758ٷ<(~iL!0||J:8U8..sV C?rz/I< dYL[5r|a.%*qz{I{R?{y FUzL|A2&4jb}(O. qx/]++9V\ɷ^D*Ԑ8M_E*-US14?4 s+zk (/f(67bh;G3^@lD,g#{Mko.S:$.b>ceoiW\htOS>aėb>ĈxPM%=U[ 6ݩRk)~(ޑF&'J" U-TQȺ߽CmbXt_]N5eH|ѺZfCF$,ዮDl%!w斘?`fRƵQo]:$~IKj\^'ќg˟d^^?[4|wv wi7 hjSendstream endobj 160 0 obj << /Filter /FlateDecode /Length 3649 >> stream xZIwܸt :#+a-Z6ۊsN-4[~󒧃$W_iI~:DrssYKyzq}¯S)]?uɤ.N/6'<ˍK^t3lVʍW3ZZ,0V2b]-TdWvY^(5wķڇz B[~(K'.^NT]lCڊ,t_}P榴_ZM]NmË5`ih!seO'Rgxz⏿JRS~w~oq:9rAaRÐnRY1֦ ᪟o풖+`9񢭻>DCAK_0mf.U,ƽSvNu! Ql}sQ;Ù8VEaG&E`s($8 M`"m A+r|jʜmE–z]m#\ss)hom[ج7Lngf0:P0rh>aP+B;2V0`-(9ﻻ$X9 4 m> ;!q)|܊!IDỌ e^.w=V(ە%FGA&fLvch3;&BQ"9-y6_QČM P;3=Bg \p~ǯ ǽ4T^jf܉wۉ^Vw.r\3 >=ɯY4=*'?8)hRY$+|~8.Y1ClXRy*{8wJ*1?-’9ת0䉳kl$Qg@E?HrW漮Ϡ1QVz0MD1_W AMR5嚼9'JKG /ٮDVQ`hX0h1tx8e&CcHu{c۬(*5 pi%^(.\ƞ5$%@KtRaAX!BXXu Ѕ3b JK _txP"O|0WQ$P1F4<:7Îݡ3*D)_^;`{e r MF5)aP'^ı0:&ET0dBz|+w/e7"GdwHJeJG"6藕0̘$e6 ~#3k Yng C2*!$p q1gꎁ9#// =^sCy~wD YFe`((8'B{_WمjY+oGx>@E^T xN4rsXIs5|p%%R\&xݛP"Isĉ<2E>ߤV0 NǼ-[>ED2/aK?z S7>i<VJi򙎧Kڑj5tҬrDiCI䙂]$~WrФuVG";eֱ֧+Iw12gD 69'CB>lN,(g,AIbUtSax<m.w㨯,K.%9.EĻobtPQ˅'つ#,?/2fsH)* .0V!C7AwLT ,y- Iv`Ɔ*'.f$ޡ2U zsS- = ^z#(9: ێ)xUrb9O1h`TIgZ'Z0c%1ڤ0::JNy4+Of r(4A0]8Nɇ%AByJRiI1⠠8+X=^С'`  ίYUt-z;57l31>c`+>3ѥfE1?qyFzUch# 4Y,vےrnrZ8\d1pwhȌcSx R F^:6|I2}, I-z _z9H}3ਾȬ.RG=#D_t?)B/Aҧ/| }3l{M]ng |3 ~մJX(: Fm13}:*aߟvbs@jNB?hr}fA| imNrE˓.x{;=7:B\#|O 8f㨺?J lN`_%Aw thfp< GM]c8XOeut`U襁;Mbn<"I<^}O< Y`n lN)i3LvɡV.V M(ᙺ$V> stream xZK۸7$U86\Tt n9IHn\~k]9o&8Si]ݞ&6.z<ԑM4XW$Uo{E˚>> Օ3nRi}sZAzvX>Ӱ$T7M@ @$NSgY!$i?r}9:r!q3"17Pf-H:xsǔ t "+ pb.`)0ũ {@#E7Q6u- g&)9FI4"шep;~'e2Ʈ[V2=9d"iwKՔDSeB|/se?@3N:=n뻦Z m ($Eij2ظm؟<i\-g>]sW;={Ba+!M8f ܙq9ݰHߗ] Ӑk{.oLMq)tp1?QL]Q_+ \?t©<\8;>X;>Kϧ, ԍRИ-DaBD_b!c9!tQad Y6]@4rʂf™]}kp;ϸ㦧BO{feG?b"4<3kj +#ˠHKnYh͸px4{ PKs AG&\ϥ;-r+hqmlR{_UG506 ˭ŷ*VX+dA%r_{X^RR9#AR-`̄0ܐ0& *LfRe$<,3!xTZ" Tƥ6 !V& A9Fa9 ۞H 5~Dpƍ<Tbzž=kb9Gړl0Rrv7|E1SUݡr䮇PHx`'~j>>_ @pxP8 {6=%09FA/N}Wnă@-$`vo9-j2ԁq: Y@/|6xd#tZ06K@NȢVE ʊn HPXAŊ9]8(,'ھL0pbk E@q^0ڦyfku)N?ֳ}^ڐvTk )̍䜢͂\}/x1ZlP%&nPsL)>hViMxD(WI b-$PQlPC^RmdwBcI[*5J|cBp[*UIG煙@Sj!/n5:xi?sA=ETΆzt^(n @ߵ)1eІhG|3L~?Lp+;%s MϑEGE%'"ڽȐ#G2f!YQヒݣka^W /ܐ iNBӈ-TKNzhTA@|`OA0 Ly|vvp~lڮj݌Y. 1_0@|=q@a)YZ@^lCDm>MOQzX#O!f) th~\K7]'7 ۉxrM׷%a]NUtQǥ}l/ ks@1 /-/\_;>`E zVuaS7+ğvl }C 8R.aY ݷ熒}jZg^, {1f>AF+g~Ÿx*)H8+4OJz+-0R5|LRDazbƺEaӝJC -d`ޓ=QgUi} QЫq0TX͐X)"%Q˫B,BRct S? 4XtӋ י{Ϣ)}v&B5[0B/zuwX갨o>Ӌd2 38"0MPHzwB@R.ZO{Fk=E5I†Ć'ff|\Sܩ(fXmg[Ч"?S}ɍ˫sJPSΧl6Bu ӃEm긭^8G7jkTi[N\q>J&ڴpnHtsHj"ܨk=4spMҙ2.UMG|o_}u#T ;:{kuP31@v[/'PPΠn8A1%Խc ؂#eC7.TDendstream endobj 162 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2217 >> stream x}U PW~0ݭAPFܞRDnEPTptCPqp#gPpV[4ޮ1[krFSZ<(7Q#1VW>qC b N^\|>@?MYW%oXw;( RV'N;V~3 IcnN݂ y1I7"٨MHYJJ ](ldE#3S7l̈v$BdNH8 KRI2,#3IEd%^rąъţ>>w6.TgLņ_q\W_Olr{LXO@D?QZ8%=mu9 4ɰ+wg>1m1NnV8GP-*;Uhg.S?=b} ahTLPz: tG{4(FK-j%gOؼ8'G?}fg#rl+|K$n͛!-\g"EKP70i,_D~Sn!s11&/#FCrs{ԩ#ÑE|xJ*ۜR+cnŒgvWkc@I֮|ȌR[Gz\p-Եt+q!)7;r< \ҵTfŽB./ hcV.O _DoglCZbZ-`WazوfnZnn f:oitZa_` c?\<\{VGleu7<ߞrԕݤr4\TIR4D-ƂT \ZQ+NuVd3e*UgC9h*au'S\Qd NMQ[h!pP CzN0=]Av&,,f6 ڡ2ؤ:/c1S٢_bQ`]Cp/CTG;ϹBKFc{6mM-Ur|K,{I[a҇*]璯tԼNąplG=x8S5lXV94g~MGR]Ȭ?ho?Yi.(nw3M4S9~hu;X{O_ ++dA@V7_q*_ːU<0?܉pH_d̡ 0V[9=[.6o߮KW|&M0h 7#ζX Ỏ*Kkv jdf@"QYqY rɽ!eٌ΀Sӛ_/=45j>Ãi`i;">}*;_錸#_<@zzS⍱+ n"qp5uY(*E=o& Am^eiLߐwafVȷZK+5$%3#]\ UXeZk~5Xmɽͣ=Vq7PJžꊭ= ?;OH<3RH-^vTZ> ;^Vj 5e [-PH-N?w0!kK/l/fU>פnuG#::11:ڑptoɓti(Ǘe}<Ǽ~Ο&6dž.Z"d<gM0s:wWTeL}zS=*ncK}>smҢ\i[ʈH\?jZ-"v䲫X^^\jSTXjuOwendstream endobj 163 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7688 >> stream xzTTrԜ{n+ bW 3;3^+FX"jbM,هl}{@Mr{ :9g<{+(Hd|Ck^~!#A"aQ'X@O14?5xKaZ?TKEuB{yL4i,(ylFnq ftŠ 6+#6l<]y%G1lȈU2^%a6xt@\DGR.L"PTmlXl,Xc{< O.MǶh%#1^ˣq1Z ۬ؾB1"v l>9NQqdo g`W*AjM!3FI .?eT>~}C+F~Zy^]b8dfYD>5Aۥ4:8&2]bcn-G^0zGH~Σ#fbMb%V_5hP3:z9<~>ci(]ŽJEO FB̑4 +XAnGŽX3Q/r}jef:,΃sL}eCdf 9AZ.JNXNOP=`)MoŎޅUjcAu/zgx}SiRぉ(9;!)'M-)t:p=)#A .}G1~gO$nEگ~Wxʗ KNPw'xd)$[tjJ<OƮMSÍr4nJMP50#Q"GZxTp /+=\ O8ģa<f!,*&fF|pz+5.hOO8]&T t.WKvA>s[UН({~Is2M'8zTN? Gywoi$1!ݏG& 驛͛:|c{4۠,c0 ;sR gKn?`#9wJSdGUwo"S+>MCwެXv01b!MN zݨ R)Ǚ2ljy `]AHZ}Ry~h8F]r;R-*/Ekzk* ޲/Cb xۘ+U mCc3=qZEua]X(goq`w7ᴙ=n·\׀$^Tn'nw 5L6h QJHIdP*W4&(%SC@WP1 'ơ\ԷL N\u/?b􉦌G pct:,uC_ʊy$KD2ve-~iX!L#:DQLfZɫq[ӆMZy-ZyUќZ`6YIW^?w{:pfXB._9p sOr=:BFc:DUk.kV2J+S3 PT( urٳZ ̩|\[$AVS{*xPNTpyv~4 ͸r2ƫ^VC,\Y]YZ9M~1/FE=MMſm*jTP"gK4IQ8 g j5N <$Q7BFcFki%v\mFgd.4ߠ4LQOlM,Ipg]xgVN'%BoHxQCI#2# E"14[99o *i4$ƭy26)Cfw;H:wmgUjϲlal?#`NѵSVM&;o}NdpԺVGd tɻ ¯ĸ?=o8SJne`cCoM,9 򂹂|b*J"ם <{R>RD>5Q#i ;L;H1ԡP R1)!f('i4C!ib誈 _/ NWHtmB&)'I̢E2.93/oѕg:^^1 Mb!2&!L?+Wt[CZ!zNSL@p^ϳߍjݸ/iyRs=v>AHC4#uUgg7- 2 etC wzY`&.L T9?yNev03svs `1;x d*A=nfDv9dIH \,ҶFp]b59RLG;Ζ5銯`|չBt-yc?= XNhQI`bWh.Hb{v';}Q}nseTwb h\dᆏ֬kLaԡ@KLNrKFLl4G Vv5{SΌ1~aG _j9vq+y 4KY,ߴ]IԄ$A&I"{F ]'48Of Ouf p֓MHaIbztڴ/tlC%SM2͎0 2~[d'ݾ_ x)VKZf+2{> m0 OVG^D<IYo^bjK,S,K\{NK( +Y1r1Uf;l\Wqٽ!1ZQӧr9`ܒUFT7؇n B ;wF +2VT4x'meiW sbXmO-[#ǁR5'ŋX[C`6wәR!Yic錸QrR3!#)4(z(^GO䳓F~`7!Je3bܹ:`#b'dmm}ʶV"-oϕuHvs͚6R۹9gvm/lָהǨ/˓dQȀ&Յs sbs˹rΗƱöȬ)C £->I|JgnCL"F8&:\Xulo^=uۋ2,C.2͜|_5BoiMhE@@hh@@EhMMEE oZ__wTPppQPC^ \6GAevIYLR*-wý=Do-tϾ|mV8P`A~Q!!eaU|C ZWTS" FnCЃ.o#+N'WӒf]7i_kusV"~)zqN$)gEE4o/~y&0 ^o,{pKIOgtM߂R@ {gڧ(U*RJGS:Ǔ2kTUz{;r3]^a@ ~d#"*5h^q!.9O<o«?FOfrg=2I%HM5BǓq@hrDh&zfX91v y HIkaN]Vm 7[bo':ue<{݉{:ruu T1+#oG,ꨁ8]A&eAH⹿?diNYSc&/YX /t@|t@޿DRb[&DkR4DhR ƴ,$lNj.n+RTƖ>n8,XĿ [h2}(#MC "tVA ӳs8G+7+ :"D., o'Trt־n=1Cq?-wJ)}- :!AHiڎ\D!sT,F5^z ;LfJ p-v?iO%Vb=@Qǫ9KdR*EVBN~jvCe^1`6[4Iኸi#mC4:330Sh9|Ϸp\4Zi2JmHU `oG{-o bDe%mꡉ]0_t(.޵t0q7KhI$B$F'3x 4˯W'Vq "nݯປYܳaL C_جOץԞ(endstream endobj 164 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4856 >> stream xX T׶DT,U8lШT" Ҍ 4 E&yyG5U4D<1|Try؝߰`ݮg}v24D"WWYlC}7' Eo}X! 7f9L)H [.ۣF̝={̙"?YldHo.[W[7Y,y3f,owocfVoYv om )Z(۳"Bعm@ !a̝7w&.ZtӶn;RoR$ʝ@M<&jIm-rʋZAfQN*jrQ.|jr(3ʜbG,(KʊSxFPHj 5ZFLw!D=yq/~◆k ?621G%9Rfs`Ę#5v5><ل75mTY/?ΦW6]3_brlxEcq]ܫqsDžk;ChW2Q j PƵQ/O.YdzTw(4 KO^ MMI֟=\DZ$5feQ[5$&w9zsq͍SP/yC+#PXh#6(͡(0P:Np~!h:|ڵn>Yf nsPb!B90} Tlg|NE޼y < *[CR 9 5fOolVݿCn"G=ځ=RqW\'aͯ^x ~R%zjr 0 [o8z~@[`l` Gc4`+HuǺW!0# %Kt  D=~Mf`~7 n:T'!^D9VKW4z8k"OVq2g^0S b5ڂ-$#6X3؀~KܻXrBaJbo}wFV6"YK`ͯ&O% \d0el` `@#Q} \2H'Ky8}_s Ub8OՅ* _U1M?.sǷ#FQZR")ӳy:G~7jQWϔ/&?x %|fX4IWv[v<>-H\r`Ux>}ob RH;cGڪr# ΢ zhiM`v[ 6Q(n"G ̿ ힳ89d ;Ⱦ't춐:T=lD=q4DHyL JpNh`!%Gi"U*Qly[BZh,Av$DjiAբ:dUNwmCM@ ΫD;* I\[$RXB+"ICFMor}MIgO(g)Y;1/ɡ=Q7]@! I?^G\QyǑqW\j|[W]xD~Zi|5*E](2[ A9X;*Ԑ@t,N$D߽yi*aʼ Տ XqP"=*άIKt?h; {QBVI3lzG@vb ˤ}Zγ'+"|4XKaHG!mSCdX2fǦIqpoϵ_w Jsk ij{ycx.< t; U"4(տtY. k+sU[iQP(}v ƪ=.-t>zTG%|yuOx9} #e_&g6+`"kF<ɋb ̈LQw,\⮽]}>iNAFiY᧨WH _&%sb tQaz5dp9iM;o@ֿN:m%kpk޵kWjXOkJ %w(}cWNv5Jk~Ꭺ8)+RRìQ`8J^ W_ R|9ȷ~bVi( OD(a'#k<`^ѨnzM 6Tar=EKW[>2㊙|^tIFՁ吭ˌKl,&%_pǑR1b+Z2ηܱn+y'ۼÜꜪÖ?JAf sI}~F~BOK% EPzu=K\쐐$Bn0`@mc@btD{ExZv(ijbYcڲ陿6\7<LQ}!6qFj~-nAozg)niHig 2EC2?տ;- Qȡ;ۮ:|r]b9~%dVFe&ay<ƾ(;,1pO4$B/pFI |q~z kf\Vr6BZPPTjZyTtb[|칶Q(7^%`Kݙ~ ё(3'),SP6ey(F5+Pӎ FC`JD 9'lǃ;=!R\#QW]]>#("GlI KeJ0OA<` 4ϝþ= g=xzywè2 2mjj4x/:٧ +0!`r]ݪX~oT^//v?#\QN/Z WÏJJCLj*;5Ax*i fjm$O*N|Vl\ut7uӞ30Gs><6-齿{%*%ӱ8nd3``u5얇EtmloU?9GEB`'v(0J7GQ2ɵ.˻5MHWbӯCQ%E9Yw`K\Gsd tTP{`0j1۟~Ͼ'1شĒ,)aQ^@\,g'MDLZalc+ `HXJ.ΕW(eiQYaQN.ߔ j*F(85u[BYLgU//K$~ tsƿ3#zH%Au WXAdN 9Y)*k* yxSQe.BFK`iI~ 2V =d&#ȣWAm~ɑE5/u4EQs(endstream endobj 165 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2252 >> stream xV PgaUuP{UQF+k6xE@c$ 2ǛcfAѸ"(ei4]W1ꮚk7$Ĥ6JU]{{k!!8<"R*3oȄ^4npk}Fn,֏!| RefoR"Cܹg柋r44DZT''Ie{⥫C"Bkj~3I#'(d)]MҘQҕkcEY\/7G7}eFZ&OHT$%ZbEDD DKerb6XMb1!$}h.L~DA"#i4j{?$Í;OP|_©{0Edox5q񉈾GSL1*~hn叮9Vmem.TZ7)hB-CR[ƅ<,aH@b&!xڴ 3@g>9^uݽ m R>y; "R=K'$-EcD݂_xz ް4h{v@f*>Z':Z GμJqcGZRw6#޴V]._^ R'ߔLO63bT)X\,t@g43z]a^G;L9of`/j5uHc,HxG>z0i'BѨfRc2L&MjҎ QߙQ\_F\7#> OeCQCb sImޟȮ"_2 ⏾D~f`f0NE0"f-v, &gb9Yx6ZvFV%oVڀϭ$eZlKӅ>1_>g5Q䊴=q5gPzEB#2LQGEـl?wܨNw dѷ$~G6&}kQџN3nhSIxb=ʊFU ڮ:j)SOBj# b!LVK{Ph(~twX'xcDn_.d@IItpȺvŖ%FdĪ] %9bQ^8>ԩ ٝ:2mTjB%2{[1q=@U`S;7w8Tw0szL ɽDNMC2ijS~v{0-bT${M\iv,=~rMbLh ;ʓ3)7X*k>Uu>cy+!t5lХ84Rb5Z<Z*l fiu\vt^[]ˑ++,Չ=N7goN[v#u6bŁ8>h$ !Uh{jRRq=BQh=':UlEACDYDKb~0p i],p?5|]k :&setFϱ i=)0S蘈Z`.cX+)> D c]({.t圏rU5ݺ .)έIf@T6%%[zd[bYK6*@^<Te YqZpiG$ K: C)Ŗ Gsrqmwj+|hY=XlzP(ZWZXЎ-U /"01> ܹÿo^P3O_jsTj,Ko!/EX:\a:(n|^5!u&7~Dcov3'[#%D$}^c p {"ivedgW6C)z Q/*RJ;KS{E%`';l'U9HEV˴ Ə#F~4> O5e@^Fzu -GJGSŌF+G*d3%Rb.V/iendstream endobj 166 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3729 >> stream xWiTTWEAݫ"QR^C ES1ΊAʌU*a.y 85!//>L\rxhz1[݋q9s(k+J$ٻ{*vʝgN |( c?oycbcaN E1oC(H!$|",.bGpH3\M#99.vrtߥPF+pturwrP((~!A Gys\u~_>P5n\4"rE_8BJ֟&7p< !ճ.m`qO]8J+Eu]K,lC;eH69fԱv ϾF\{歱>%amO0mG4B3 nĐbzM/F?\F%]#C,*Ci_ct5{&q>3nzwƈրK gH-^ФdʠA~4@_H՝4} le ^- (YȐ7,~./\H zk uV)G%Ohܹ:N\w`ޖld7paA}}!j[ :thiӻwC? RY]Xi%RzC{kgjJ<-MUJ5Mr<m&7 9%7'ϥcL#*6P\@R޹?97>̰`aqcˏ}DP=KɆ `!@!+)%6:9 5^!Bǒ$}Ѡ`GlvYзlQdDPqx ,}qɡ-ݤ1bb1<E +G*Okn L jKx ԌG?^VA]Ldq(4&)ݴ@qf*ī vƾ]󥃜qW`rP¡%tsf%D&x䦴~9!}^o xTʢ4c~!)3ԌKfTņ ~̣cvRἒ^; l/9)|D>V$Njg^3WRȧJžw #j7!MjQ7iEJI 4+>Kߟ:x.Pd!ngexk_H7`i"@s ^dĂJHZ,C(;Úݐ*aw֨QUY},OGh6@L> yh!+^*l0Kpt!%KSŠ Sw!]e?egў)Q̒iߧh0ܼ]xseiiek0̇O[9I3Os=F8i[ +ݒY|dtygiMZs&WФg- Ў.օ-Eז,AK}'tesБK0?Z !qOG .#K*'{1]rt n[#j.oA&7LHҎ 8A:QUZAFJHt(`:!GU&Z9l =} 5qxOL<`P֓9Hxq F8!.sO,LFdN֪lRx@S/[O:/%_dJ|y{ YS2c*JK=oz\pb2"zW[*P&LK@Ԥ2ʹ09L礀&7A!/^LNWi?aiV=I')FH S ̴b 6|(_`|'֢E ғz0}xv~2Am*ܑ 'Krc-xG"j5a^pY`>/_al֖x8KNPP2`Vw0S8;TE`e~f‹#U(ͲLg5s5-?_M#*zMY 4a. 3UVZC \#:݉Vw~)⑛ G5aZ>ًxvO u:||aU6"S6n;54&_kL9_v<1_:=&vm{um6' UzKo m8q Yq6ȋGǙk^ۆ71 9Il#i8u޴5ZV;O@Hn4[V&Ĩ,"Th7VȨNA-csƽfo@m _e;ײ1=.C8/tCTw-kab%o/"ڿіNŋXedT\SZQ΢YhВ21ڐ. 3Egg، EW_m+j Qern")#E^Nxy;Ka;ltzHo))2LC`^endstream endobj 167 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 479 >> stream xcd`ab`dd M̳ JM/I, f!CG4nn? ~)__PYQ`d`` $-*ˋ3R|ˁ y I9i i ! A Az讂KR2sK2Y~_IXHr# 'Hn*ڽ,zz销e &sO6aڄc$M6{)ǬyUurg~3{٥5]rU}US$~3^\7[`w&cڦModoohkh ((hHh.䨙Q1g}g^[UxAkWkTrgN!=cvl7Ϩ-9gƼY|e ~8?u5\׹XBy8y =,o⤾ &20Qüendstream endobj 168 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 324 >> stream xcd`ab`dd N+64 JM/I, f!Cß^=<<<,*=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ g``` b`0f`bdd ?SUe/>0oaWw[V}GoG~zw#/ KUؾs p+]#`-ýyVT#3z@| НVendstream endobj 169 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 447 >> stream xcd`ab`dd M3 JM/I, f!Ci<<,~( }=R1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5]'eg&d0000j10v1012?S ÑN?f7^g7ޞI=l?JT^E9\endstream endobj 170 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4302 >> stream x T',"(CjZZF.  a I@@`TDEkKV[ZU+j[Z[띠z{oww9L3>=Wa`up9A1b?;Ylľb ܮL53c039zK7X1c`KY"MG͟;w9ݮv~a;vK!v%vāv@M^v+=\7xypF0~yDJYKtLluC<kpF8Y'}Xm%Z_14Bx"BSr`YqNGdA-,A lx{VER3C-'w8VR??0AuhP_$- [tvϭ1s8n8ߥL_z8 ol 4}9˂|ۣȆjIqrmk&?hF`MN}d<;Gyܻ0!^͖uxJ-GStFO`ʦ[\cń;Tm4ہePτ߫)rgn1_[ ZX"5z4[zkCxaH2Hgn)>C%ⅴUI S3(G.& ɣ z Ύ %(tu7欃!zW #|v7֤;^o]4~*$pSDT}٥H^q eq'f⇊4$ԸJQ62EPuHCu(1+DV"8S/(yYdR8CwEXlJ@A~5=^ ) $S*UZZB\' 14P M?DډJe]bQ.>JYKb/'Мi%yMu+.uTb}SA0(a_eg.CY(KJ9lݰsq+~?'%^slHvzQ'jE}7{N(CT@n-GNTeR^̽-|8_{y}{WOWJ;( -js/4$ɠq?H|CEg$rqPjB-ȞZ ^L%!+f!gr=".D(bMqc<^![W~UPΧ8C$77) V˾*U>y F3YU"!UʒOrm8!jT ߶)UEwB0D@mjy rM^R ;Ԟh/iˋC#Q* tˤLek\j+9Lv#[GfX 5⽅RP*8q1Qif9mӁmre(<$V(R MnJNj9X[ۧMrE<萶V3[]\; ҡ:swDK6r*(m9o{V {O\T] tSf N X@➪ea1[ Nn?/~Aݓuʿ'En;vghN84F$wYr.@rzS[rjeʹް|$f ]p~3 +g,knߴ&ʑZ)ŐB @p&<mcRoT;6TJh0n#s 2H,Uf}AۤhYBԧ+nƪCm,_n^v o.EcE%r^IE=<~_zJ%cBYX[ɜ]g5ˎg;݊RX"%]s'2OP.J3ba,d@F=|ކfkREv{ŧ4+W2?{8DFri%`[ B3dfQ_-?/<sJ0d]bN](MצCֻI\sS|"?D{' NMx^9][E1dm K9>bxɾ٭Z'`]!`lS@I!o ن7%#VDyyUyiʌ,5b?_î^u?th.j)fsr9럦!sdvAD\9V4i8+CjgMxfz hXFC6QG8M9|`')EP*̏GYknw> =Uhl~?jm[VNUe#|Anw]{UU*I0q!AM +?pǤw#+dSC(0^gG7)-/,%1{x#z%me(2] Ů jmޮ< D'g9Q9EɈ̓'^)juJPT%f9@arEsٞR}!l[6w #)V%?u;nKC⛛kk)=DѝY!1c>E`1Y *%xÕpvySPAUe}m=8i5_ F-EODr4gMxuttvg=WRuVoo_7.B9mGyk{HHt]k2~gynYsY**甜{v_$?.+P(881F"O_;DI({S$ma:$^k8PKi6,P|G2 aofq7AWLq_4Gg3y䶃LX ςKr67DMRiLTZT[DUpb'3F٢O#;wKji8-u/~~ËqcXJQW'd Ƙlڴ%0۠?Z >GWS晍ð9Eendstream endobj 171 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1599 >> stream xTP厽"lV^JGF`D ;o{?w AM'ڪ4D IkiNߝ{iٝyyy)mEӴYY]JKZQ\nTh(Q;6~4h F|DS1?3_2_,Ul))II7PTaH6da YɆlɭnZ $\h3$aU y+Xix~EN^ʧPKvt-ICRkB}r>jew|V_J`bO6FoQ/691x[ޱYN@Yok^>t ??9qxL AhD<ju]B"v SuߙHRo2egUA5l-a|/BcFST3WYlB lk|?8 n98#`LP'O>zZ7v[ #SȟХ+m <a&Kts'!Yֳ]4{LiH#3i]8u < I:R<8arʒWagBnQߏ}WbB?irTkSYyˆo/|`.h;꼻[,-m::|fB>YMRI엳0>5(9X@Gqtj7vVGHv7:~[Uf| 佺 }YG?^8RX_)2u?Q֍˪ rX"? '$vL21 ‡FŅSgx2vo:;6]td5cq[Gz }v~K*6(xD&A;.ȴQr;$锤."Kf(V2ۨO4S_t"ششDC& 4_"Kȣ$ RBFo;*栃_PWxzx;%E284Ѹ9 ޸|VSj) fEK'& @mF}11}] ۼMAcPԿ_endstream endobj 172 0 obj << /Filter /FlateDecode /Length 1180 >> stream xV=s6ջKr a|Px|;;.8O-ƒ(SeJqɄ,] $vx^2JXF/V#=^F̿l]MGbeqBXXI 7YI%aBgo?7 i`PeU>/RR9/6xX8Li6/Z }I䅢_ImBMXUK3hd=wy>KЬݳz0)M9P|Ysy GS4A4`G4YQҘlZ#̿C tOX8DP8TGc n݆: ڮkR0"YhEIRJ4|մE*;B(of;[̷aj We^ -Q2lüFSv⎥/S" [s  B Ήbk߶IWL+8f,vd82V=l gL`rl1t ` SIܔBHlhi!UrED#(k)_y! $TjOnyP惀|e$Qr&=raҋācƾHT̒y)aVs*:, -=F^ Xpq!x!)K .˸swG}=ßendstream endobj 173 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3524 >> stream xW XW FqndLhP&* 6KAEAI mrCyjF/_>Ct 1om0e_u{\(2DO87&rHS!r+r{g%8;4`+^èxT(7Eώٚ]7gرw.$Q;N^DLB\DQpܒq1 enTL.dS!r.fnպUsWX?q?1 #Ί}ǂxMCVDDFN8i 3Y3Ùf$Yżx3jƗey|f3YLf3KTƕ [G&R,U\ˎjPJeV=UoVq}S4e7ssn7MQ.rHŋ67i KJ^āG,$G1L19D/`:jLMS_ KA;iJ} Nhx&\l ٭>آryRpN7+!Kf ftPKg"(lO[0?Gۯ!q4&QhSԣ3R zB&)71'OU %@8!n}lO#hz P(B]Z~))p |ь4O`/tO?ԸGa"Ay }v ep[Do,x5r- ]]q5'su մva7R S;V &Be+IG؝fLD.ĖT[k;"P\kbVԵ*_5ј~HW[-&DQEuL@Qg /\UtY)>yU,kRBpU_#~VBѮ,drrӌٹ1 C"@܆b]-3cWtYyICvN0YpTy82^[{`J VwN8@ndDEG.Ok<$2  yTШQ »^uo'/(̳l[ӷ +0g(;K̩ Z孿MgG~pWRS^n(jD)%64 P GNg-Oؓۙx[R,6t!%DT$v\ Ѱe8۵x%<*`NßE{=1Ƥ2c ڔDJ϶r!daI3S&.{R 2J ;'U;,' VGm7ͣ" JXZQb%֓D~f]hSWjb)kClLw{9ͽQD9i:)0:, ғlsǜ^tɔ f,Xp,iߙ{-\ERbɠq$NGgN6\eV C%2gwTnQCFL":2ɟ™J 1g-5N $k kN&6XFs κ#:ÝBAY ͹)Y¶ ⃨f(y5CM!5 >#Z->N\{O=? G P[ZNT5V6|P-PL'f/%)P9%uQn"0|6y<=uVj1 ]IϽאxЫ&$'vicV̮V/<}fhHv44i i s՞I++)-͔av1DPz7NLK u'_U7^Aj [QV #>Z~fQ&@>-=xό3`?1=vL^ "K M: G{_guCםrxoZtl Nm! ?7Imz2U؞n+Lʷk-բ Zm(Ly[ { *1Q~-:h)o|jwJ)'re| B(J^ؼ&w-W G華+e Fh xLtEbG_T6t7yWUSXu5*@h>^P\ə;;D/(&HH6SO[]Ϡq@=u%&< |?/×ܝWHDkҏ+Z[C!p/**'8"DʹɔjN0瘲r9\R!Ϊ//?$Jpkq!:0*z_?*6g/eQAo8n7;%oy[k.M4Ttv/S8QPn<OB(P#M.-n[lG[W+21kA]> ʌ ;2ܓW2mӖsh1Rif i+ t%ג \*'$坴C%BƓ_0طgPi\-L㶺Q[Mr xL.e1n8TRPWpr\Z,y{J8;.c).ʷ8ceendstream endobj 174 0 obj << /Filter /FlateDecode /Length 217 >> stream x]n @|&t*_Km?@8 uvxHlc;OW۽%~jS.sroD\;/~~U@ipAܖn5Dj\)2{z'Rp7iT ::> VQR^t x/ N|t$-YmFe d\wue ZPm;endstream endobj 175 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1067 >> stream xlev=:"\ԡȖ D8)vmv?ڮ3ttm?fQALt1!!^w zn,5o/a8kMΖFy`qq}{@E*#P>Sx&Vljjm/)F'l)]?ls0fZo=NWVm9hYFCbmF>T~j+}nh[,Y:0\a5۬Xq&LFsÞX*vpC8=r̈- >W7M#ћEb@rv.tZB< P@7,/|whXL? :8$ZjM3$ vEG/qԧx?xBOy/`-mQy {nV;.Ly%A*}|8!>ݼuNVƚxl#1 4 gxߍ+n {FJ2d9t0v OK!'xD"1>~'P\f V}<[!puÑNH$ana5 {yO87h ĔʍIC < HaH;/KrR0tR(y ޘ;~7F<%%b~qZ,@.͗i!,*g'ą "k@?'|Uxiʏ^K6PƭL/*p.oߞ}7j_?[Y:o֑o"#Z3S#G(%Ҧ:J$S(bTWz*3+)E SHukvV0EbE8JA,ݭO2Yendstream endobj 176 0 obj << /Filter /FlateDecode /Length 348 >> stream x]An@ E0`'RMɢU0Em.#=2[^s-Ʃ_>?֤yq*Ǵ.Yq~mEs[{ ʽ)ͽޗ6NWN!i$ө{G7 )J\@sֆq&{z }djZ@BVdS'Onl U\@2G`n 6 6l0 Ȇ-  v˴yIcK3N˼XWe?8endstream endobj 177 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4686 >> stream xWpSwy)(y$K–K`؄B/{Ŗ-[,YV/O\$˖mi)!$nvdCȖIemhF3z}>xiSp8(g J*_={[4-HAN, _ߏsQ,$xy(n>3u,Ac4Xs_[VGbYe&kSqa&Wj*z+7)u ]]=Wo&rηٜ?)2TZ Yc@'fTFMU[de@jN{7$W4\03BoHt?z=AssW^h^t69ZeK1w4{IS~'fvِҎtFz"[S7z08v9;ێ֠PU "[+l}0=z=q\ѭs T>D=]qzf.*3KsơC/r)K2~z]ީNO`)K{FԠ!dKZTZ}`۹OЏųEE%BV !Z4'iQk&G7 >0JnuI%n$ 0M8S9_MNG 6Ʌ}`4ӬQk0 T0h3ʈf޽mQgSVͭm{E8ZnЬ(3H*rҐ[E[ wTŕ!mq\m{2اZ"[ϥҵ 2@bGf*Btp)+9ď3))ücHt%v][?[XRJ]GgP$f;C]ªS4Ej94c- tDs1|ߣ&3xA6\÷aԷ^: y{Kbm ]]k(A[bJV噯сc{o l޸owa\pB-9 |RCbro.QQp?VV6~j|~M@&uu. zK4f۫4>~Tvz븐 OK(x3VEK>m Fo؎''o.z]d)fԕ|dt+I/ݡO˖*zE k^(זŴLr#P2e n=ڻzSGcGD"?T ./d-]-]N?l:׋swqZ.C] 8*4ZWmTZTPMwy+Z; SHɇkEEn{e]SJF_}/>M?hP<FAeɩ FڷMt|wd6.7_4g`sK%ѼV{AYlܴIb00ѸSnt-:y֫uAyq5w1vQ-$[! 5VKť@mK{{[;ŽC.sY}iK݅m]T± g 4wfԼovr.'}lP+9U'?s$N*ox|v;+[J3^ FY /v4;;{m{gOVdT:YlطyUtv8;&fK(;``ěܫll5VD˺G!S^F;a_-TD=>XՂ Vs˅i<0c:C4#~p3ޫ>;^0:|{ hmRѷf4#f ^:ӷC+|{Kec/~u zJFmC/rsm~> 2 C?͇xE^F?do+xc!f8^^85u;B.| !ꔆ˻ҁK#E"n.Ek3:({eUԞҸXU8O%U鹅y58d}ڀ;2t7MA/t5rVwZ IJZF1H\b{%@&0`*A_$bsG(ڣp֒ ~詶+BT'$7B g Jbc=x e0$\x'ib#f>&+cS{R}~?HTZ ^#kERN]A! nE!=8 niXPv Ixt`O\Z59~w-H}o䎽-vo8"-x:Zдk.7nt@Lu ܒ/_+]j"*`[D]v4}=aY%r|nLkR-,BD=pZ}qńز7=;fzQBW5j MME%PJQ[C洿³\d[W2Px,5 wSBl=L׏58ڬXC0 ,ce1賷Ul}]gȅBMtAʻ/] \B.4SpRx,j;2g@ʲnkCRoINXzaMM̻endstream endobj 178 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2093 >> stream x{PSgOYEm n:nۙ]uYou$"!! ${\%Bj) xEeN[N[;vgv0=^6f{= KJh4ڢ;wE[EJnɯWdpŕl??{-!z<^4=45 !9k7/#KH*`hJi#Z*WXZw5Xڰ]r_[sbWܹί.e*V1]Y◱rrXY32Y[2ve\Kveu#bc6JT[,Mư]XmrwmvlD,K%ۓI:?k=>:!AӏB12D-H ڪQ5*Q]^ [:])4ᷳ7Tc9PBQ}eM*ojַx̶f=vqnP,թydMYm}Vz(fh鵷H'>Y0ѱSoeuZP#!@S>ӿ #Jɢm44DmMKhzțhhcz d*z?Zb^q5De|P'a!}W\6Uk{Qz8{ ܛh $qZ/fR U_y/?nyϑ!t UPVh+Me>T1AgV[K Ƃnk+ˊiV;VP_?VHid[}P/pue]QCdz.┃Aaf|}rmfQyB\[JQDdF LܣmҪJ"5@|;(ĺAYv //uGɎ6}E@nI;o%/ ExfG_Gc< hƟ ¨k*I Ek6+E*N@>Ho{gJ9yAȀc نwJ=q,7{h^!( (-vljkc (m>f4}3LfQ"%+6O܍m #py/mvrB_}U&Y~V0VoftJ'| J3I _!a45|A3&ImiE=i;_<2[}Dxj|4n9OnbfNCzt`Chl=lUBep%?]Qg)DR=^ i{o4u{& -, Q%*>߿'0#ؓ!l|{#y:)_2sU*2J񾓧g@|W˓|}'^#/!]- a_lɠ zL9h:N" A}7t@?Cvg7Q9r|{.F>0zQAQ³ii. (iKc.nܘKIO $X$'GΠb[f{< ^endstream endobj 179 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2260 >> stream x}U TT><E9sZ\4,_)(ѐ (^(80(eR){W]KKoqMڇ~ruWku>wGABЭ 6DϚmpG|#JQq4vt4v>,࠰5!p3'f~fm\;}EQkPʟ VQdJGGM)jS8ʓ)5e(jcpNDuSt͈֢=BO鯘vy!R4.Caf;Ω.uȀ p\Ƥވ22wiv8-Vv[T[XEy:eqcv]Q9uԛc8) v%un Lw[eTVl|Ŏ:`.ܦRRxkx$4e ş3l]M-r;0۠,it.UUT˛A_>nt\`oQT<ʓC/eL[< u+~GFO%<> óIGVc$Ɖ'v68N9'fid|Ƃͦh%h1oŊ"9¶e MM̲~+dʱ\O8v?j+3p#ZxƛmEri!ARGDV7e;hW)vCwفimn_V[JɘL |T!P%b_-!mXg)CV6E~Œ g#/h X㗼d<+_|kwa9 nqoc>-+'+n<{ۥ{p͛Y å\$(r{^Qː-(@;rg!?4BEE4K<;=w ˠ;O[ ix.@JY,PDkUl㟹'ApV((XƀgYpX^ǡ_vN+rGZJzҎ3.a/t؞Mn|;&rzS&Ep8~-Bmښ447uuOW[փBմc)@ֹ5o4[.m56kއֈZsCm3n ʌ!'vrQ,jlmimMO(isB52.{Hr^ת;|\5^fǤ␝}Vƭ`[hI=Z':MВh桡ȣC8NY~i <7>%($ VCP;p2:o]m8.~o̯6A C%/#%55335%'?H`?,(;`NKOoL+րP֎)*"2nz9ܤqiG&Q@ Bi~Qy QP)>[\Ǯkd=vZckv unwNs~3)nPWld2q-Lq)N"SS*o_I5:, *xՑ xyN`+ŚEǭ2a9` ‰sOb+ ߏ @^g$VpWI*w bgL̓x҉]`7`"]toÖ& ;\d;eZWк ǩCC#==sVaUlǞbZŪJ _a9endstream endobj 180 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 775 >> stream xemHSq;ZۘQݥ,P)Il++nӼ޲3*Peln+ ZX@%AE ︅}s<;HPsM-FG-e.s ~qeޤ6hhX8HnqmF-iֶlsٚ,[QPY\ialjn`Xcخ7{ =FQE @JBA4 :& =%^Ʊ4U rF(1<3$Os]Qj\ciwTĦgG Ӂ;_=_ Ucp.-s[eq0 ~w `ؠ%P.b#=Hސ3KiQikUp?"'m3f+5읆[bᮿ엘rls,@ru3:s-pdBsq@fl{^3WJunkTa.?td뗕nBFP 9^O't-5Tr9LzL0I>S=,VqDB(#> stream x\K7ry~E^\mx?vC>h+ɶXiCCrFp[Cq}@$WqDf"H$ݱ7|bWW0y o/ؼk[[YgVȁeSWX3rH^p=@OIog0zyFVJƬzvW%%qH~R!7<<&f#,a)IGK3d|Vd\p%P7=VŬy( Ǩh'4u'Apq~qN +·DA*h:'L/~G8 ; bn!<~7oWՉc( wR;3QݛͥB&%ۑ;ױ?"hwwov_JVvre ڏZsj8-xaz^D"$%; AV͂a WGHz4㋛Z9NFw;p4`,xg(wc T+)bZ!@+ttr~jC}.=:t*ah,+Na2F]g. x&נg2PR+/(RF$AtUav굴Zo'h#š 9c-$XAt^\T*@mx/ ڸ_R8ho7T =э6u˩H^'Յ'+mg`n\0dvrv  ,!GZ`s85RYT2*sAkQ9?DUԌ :X+#i܏ND1@뱅Ȃ' jD0Xf"ANr+#tze=W’<3Ț֕0(HڠG2VDgε`]I1DTqHZzTti-6pފшLV/N.7)=@FXYUzBH$wl"Qz-5Hՠ}2_d+G_J+:)UoRTuhR&e*a͟ c55$o"o _ `0NEHQl 7!Qn*6[4z ?4[1U9^{%F6(F{ڔ,+}?S+7_y,2RPjW⣺9l6[^t]a6;aZoE'Su}Ƚ.a#`NQ $딴'߬Ƿl$Ҽq=r-%VXU"cKoV=Mp8U`g/, 3Ju/ HZjrJP&4o3./Q$)gV`|>`#1:3p]|gCFtT,ӖvGNo7dܟ[0tV׆őb Pek(Þ N?+ ŝ$ٓ`ozxQ`Go '?CI%1}[e(UT%>=յmwT$ E{oˊ\D˜ښ?r/fp8bSdKBj uLj@뒴Ӌ= aT0fH ^ëUoME]#׵R@=|CqVkPZEczC}zjL*mޔ_hRXM5SQVT_R=F7Cf2jTIfM3=.W7#`w[/KzSWUep{P kh靪ΰEKj.Y;2V{ 喘yn9us{ψ(G"/)#U :dCJ5T!??U$ 9U%sA fCCM WN[CH:&M/! Eem2-c e? nGo1Ԕ3( ƩB. :!2D#aCɈyciTci)%&vCClJl,#9k(CӏϱTjn>\5vFz#e3if@dV/6"Zie*-.lb9[9!FCa̠g8<1eeVƊIX/ ?{QF)KѮb$i4r ε1Y2Sy27NkcXwú q$ZH5dA 4gb7С_,l8&%$ g "[]k`6g ZGQɹ^"}rs2TŜ9ϩ-9DfYYԺgg1Daʶ.iQ~'\vb×$꾠 E[%H^Om*:)rURBڼHyj}) 5xex*>O"HQALXPWn<FwMg3cա09ux _df= R)R̈ql8C~рn< a!.. jd!-JXI ݐЁ/eXfYpS"zZ_ m!kEC %ͦBX؅0EA@HtݳEښ臰N7?ᦅJi؛4gx_:DLNC!b8r_59OHC ZF{?(1zAA烠:AAAR/*AP+zL6]9`Hc<$;I< !^c_uѰb$Ł9kAqQhZ$|;ń39lP BK<6 K͇Hѯ]-^=%in?%%H,d&_o cJ%` U/@T( [cD`N^X{Te-=L3]I|;\"=Ug:-1CC3EW΁2+|[&"̴2gXs{9*]:_N;d[&l41Bok6V=`P5fH_U9%+!{|uNV˂ToOT<ʖ-D.^VQ4W-Y|.?ZU+f=^xERc&Ds3VGoKCt.1>ܝk10K UJ>K@>n*3_>?:Y!R~nYE'^~KW*n!l$Cp_^gP'C˞wpzS8cm/ [:a=;)E9#iendstream endobj 182 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6650 >> stream xYxSGrC7W1 N @h!`c`:pEe[%U[W)it@DH@$ɂ dQ6mnv{ol &/.͜9?ϵտ4rOtTMY'̌ݜQpo~`gԨ1Fahp) "蘔! ӧM1e wwϩށã{{O-%{'DG vv~ݲW]oSW R$3q IwwJٽ7hu_Hua#"5]>cs^7f --&o2uEFP~Xj :ZGS T&Sw)fj)zZNMVPoQ+)/ʛIKfS>/5Am\(NH+QKTʍQW @jL SCa Yqt|D{DTBfsc fpC|54aOEkFq%]v(yeH\S\dֿtrӎZ7/xWּR?F껯FZچ`ƿ*ujE@y]PWUD^# @WqrH6CMWGC0ˡ)846 )#$Z(֔A=YQhs4.6s6˯vowef%"Y٣/Jظ71afcn7O: |Hs} qfvhmzXz S`\ܞޯ586kLuI6^d;l$F~{*.V:֛D!ԑ:(X.y0#\* D];&3އ-Ø|PyL3K@I" = l+(B\F,~qG$a/Q?>?T!fEX6c ,K| M6SS^ 'AqhHVJ0505~gJa3lآ$d+uݥJ69-sgIj D?qeK*H5I9rNnv& <(:ҷDEzcMnh$Pd gC~)z0n d&Gn\ u\wHtT z}< Ixvo!RɷĸzKpe}RtF|ֈ}|bcJcU@&VqORzȤ0rkN߲~\pbG5g ouh˲fx(|{ ij_~k O,36pS+ѬYdz[dhvItN>TEK>S9lOo ;YcO:h6.T#oYO:ͺ {aOZOBx v&<`GGiط(by;xX~R+\%RlVO@辝m݂|O҇{]{肌􇮬[_{FמU!h昰S!bs前8u_vX /?^VQ\E# h #tʞƢq=]p]cwtwz`~OMh$m2(a6eIn.Rs߾hpyR6?[Wv K=ڂǽ_CyNW3hz Cb&nxjBvytO>~wߢṕ4IqPj2熦>j1 fk"6T['$ !Lؑd׎*< d4'd?@]~!Hw+Ѱ3F,r|DsLi&I9rXT'ghqeI=挕NHؙ'k_\yC<:ao4{*$Hz{)\زc]%ǎvT,璟BIYr6QRh'hf(ʮuHOߣnWGڿ%:t^6E]Y a}UC4l0.{EO#mq.|+E{(n/)z1r|-|%2=@h&p9^ sKŮ;HC, EDoGЄZ4 px<^v >N)Nhoni@8SurjtUSpXFh-=|VI-{ShdAi{da ICQdMaXayfp}?tEDg\CU2"LBmQvnGZ>&طf(f)UjEwqz6?!VNF35}iG)R[S e*Dgq|3rrN =^'-_t`;nn,YK,9 b7|n'E|.â-aJ̍|AHvudRhdbpl6D&GBf5+WMQrbγVVGjPL.~k %(27A:: HѤ XTy$4.UqtV#U)[D`JHVb.G'Z8F?EnkYJ+Hh}Pخܞ؊rH{j: ;pIIh% `6[Z?(?7S-_0RM}?so&#,+˄TS{"#,'Z/&$E"Sv@"m ZV%zb(ŜH,| T|x[DXgc6UP~KL_"ğ!&\{њȆIVr}¯ *B@e4މW-1)V k'(07Dy^>[Sn0 tĉOϋC2D(rv$VI"y2RcΡ__ .D!dAsxH2N'z>.;y8@s O aN_g>-;7C{#򼍊le&]P O諝W0oISqXKr30DaT:a1jLIeR6#Z vnrC.w ?y'~||Ǯ⬍[Qw>}{F_ĵ=ޫ.=w%f42&M++L-jt/lK+y8yq*-3VHL5i&]ZoTɲ5tªD'pWeY Vj>tw!h ^hE&9O&En|@ڵ0;+Egņ"UAV.> H4HI$d+Q>%액$eaҗXy ->ņ)&Ihwy&C>OG/ pvbjyaaSJ}c[dĸJ4(N]W;II͔겵2ҬASNff2]AZL$ĽL_dz &6)Z}bO[|1x+-5VM݀GY 07魖0ma,uT6ψw$2-E#$ 8蕁(?JeNC0WҐ?xEOcendstream endobj 183 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4364 >> stream xX XSg>!jbӒ9jkUkmZeXEva_!HBN%! I!ID*Eqiv֥vtN;xz[νOx$]7u-Q) [$\>c{gp %0Ɲr >25-/ChK_.*F)Gq\|Q?;5?:.1*)?5?$nhp`[C̿Y') Z6g]nԆgϙ7 fL"Ln1COL1凇a*߹G 6aGcB pm.v{.!{MB 0ڬ"SgHZZ&QHF_bocfL +A(y!-,TƮF>Hjin*rq ][p{ڔ*mR dlmq0H^ qn[fREBfɒ1m`&r͐1R^תuւzGBG/STq5{*?ȃ;P̔@5םh ?ws?߽ C+>s<;/)0Vs@>Zޯ17ˡFhO'[%|P,2@ $z3ٗgr^ Ѧ7ӗQ7Z.;;ǠE^25#K/psBn7s3T@"ldlfo?Aw nHΠroѲg-G#")T`#**$%`֨L̷V:I3曣[l3[˪}h%)ƃ&hM2"ը7[h앓 mDqSӓpyhk:!.q?lzK(Oo0%#.–R2Sw)!<[F)75fc5PP؏P/OT0(% ˥͵P^go_E/` ?|@ pTsƆW[cDLbRaoivYD? V5uBIIOeo6QGMp/"'+5?b`{n47ؚȅr1G;kESRyo,d4U[Jo j% _te`!TQ0[D~F#(#Q?B~* rkY`V95C]ePE3K@1HuBi}/ ;{C^ݵ~5yZu:ge)ytth}k0M`ٕUɪz/mIHȈC_4] J#v"'rգ,5TQVW7@LzfqMLt4De P^@¢?`^(d6r C|$[J**1()+Ƈ*:oOUAҒ@N.8rrW35uf;/|]^rQ+1ۍn!;jU#˷@4$6){ :Xvv65V0A'b/4a,k?}HKCne#&d@~>^1;ml5)4̚-TS$F|Pq5RgzP¹i 3ShmG3p=h>'^QOC(iZcMr p#i?*Z*TJ6. rtۀ  ֨), t*pc>˞!GSc*J(#I,Ng{m6jy Dlg`fy1Ald$z 8z5! #E9rD;Wv1#fK+*8n銝@)6`.=f*UO~wk$?ڝE䳉 MJR+i < {:Uj%e[G"mf^z߫pʼ+|<#l`@}=|/: "NK#yp\QVTJ̌.ܺiݰG;T"zA U`sY5~zw|PULqes~W!nl]lP"]UFd/5Hau:,)t )lPyؠ*f97@BY#T&mzbݺT̖R`t#dEBT %1 R,E>b[*ѪJkx֨uzܣqSr SLs~-&B$÷Mzm%pC7!vȯ)=itkHD/c ._f:{=ݶ~K #hw뮴{f^(O#U$vQ9>w$N{QtUVBe@gq7=M;zNXEp^k=XBVgm,V爔°(QQflzҙged&Ft}ߋYˈ&UA;Zb"+4h+dɥL%kRft/mX=2I!F /zȇ^"܂9q;cåxel2TphzO< ń BcוU,(ɂ,eIkǍfsO.ykGz:ŢpuNX=p!$Ah.=/IӕwQ%Ca8&6~ 4E78؏tE%Ƚ͑I'5IԟQJ=|K)Gu 5v#ՇVssK:ą>D\lu~شwWB\X+-bd Vm2ll46ݦlE3]&vJq5 ib%9;{~P7"Vʙy0خֻbHrFVj./f~hhrJxj g ]6bY PoaޘF So|l+Roiϣl{ x#qMܜ G4+S/ϖiHEnwg˨i-l,$Isکsl{A+yDދJG՛ޞ*2mK v%}ۭWTlJ',nהQPLoTSPb k|48U#rcV&.gCg-_ݦPi=qqZڤ1[;m] G#_0qLjv nqc R52*#?@ +8[Js@ƾ-MT`q_xfkt;w&SKauvwa@% ւ4U^U~]./<FN%2-&\44;Pde^hj7~7&q!AjÛmYVf|֗ syFqѨ4bRnzxNE:01OЌ[Bk]((Sdc)4N(#=&-h R  nm䨊F<>8'tR%w7w:ڨNveS BBvNIF,SSf4m1T6mA7Yendstream endobj 184 0 obj << /Filter /FlateDecode /Length 5233 >> stream x\[Gvg%-Dv&$=JZ\u$>zɮ˹|ZYת/WϺg?=SYru7ᵃ_lkgo?WԙR};l?{z1sk;qiaT.4˻zqnzۆ7/n֛v7˩hC.ae ٛ{8n|̿bzh'L熆\Oau^7Wq;'7㖷qA ~hqm;3ʿ6{eyƉy_nٸ&%FH;*z5i,tpelo\z}Zm?w=جfx;<0z֗w d2ÐzQ><& Ͻ؄k> wV8#Țf/qPA/wc.\W(]/\wrޝ=,<z\/Xw}ɿA?wC XqQSA3!0Nd(@lӭu84"4g3 `' 4*81t'[Pz! x.=? d8SDz3E@YC|wַh:nqbFvTk# Vt?z>9H%u8@TUg CP /4`ũLAq^Vx=n h﬜+r+h @lZ m)R. $4YN\u.XEʚ(vHwRJ\=Yo ;7~|MIPhYA8KDߤ|"[mm٦@+]j-Gᔒ:˃.ҩ]3ڀtvȘqCbg=Dlq57;xInTCؑo_&j'5jxX = D'm C0`NB.$ZD/;&LqEJ?f/7Wu3 c01#ir_e2 ߬W<q 5X#՚|ZsM'>,R&Xϓ;O%gcAEqL5#Nj2bhɸ#oɤ5v/P0ajaaW欎(l ڦU,>ؕ,`5QgpG t|59[6027L}*ys[5LJ.}m Yo@pцVuӨͨ֒_nS sc}AEKUeP64,:=,Ը@FԞ!쌅)=MSlXx~ű\gU:>^aG..onRmҳB$80I)IM"DqqU2Owz @cA5?Uߌ71UW: 8#]|0e9C#;~gtEqrwƁZ{+S"4c3_;ܖ#řCc:N OrQR ӒGl@2$ !69W/ۺ~r*W;5& 4r`7ۑf1 xͻJ'RGQ -ѣW?ܮYYPXӃiT˟ցYmv ?f6jPPӳɰpv6( ;-`a%V :Zb *" h]|l]d`OےDE= .`G *Tŷ{2630$eK4/ew"3un!dR?@ا/ vECa`Bi[P2P.2 NUh2[1YOT0쉦%iYv41{&c=h-bptw`eI`;~%S'j{`2'Ymv+4de=[4iU:!L=), )}]Ⱦ_w. ՐhA!υ戴~8ZMsZʰ֓,*b8>FGPK 2]K֦pLAGԟk^Ta`-鋕p~s4/o?DZu0cY'NۀWC}Q׭YM%m2XWB5z|@t (Gp_>o~7rg\CMDq|n @2ӃL9pb?+*RWn44耬@.nr6e^"leE#2l!8AC-E d,,ԙI}cܣ|\^]{պO)|`}8~a*IB?UU0 uje R$xΞ>-69}~3Ja>#D#:2xq 8ɩ0j0[cZ9D7iT(P(if]y(fQ @_vǠt^|UQ dsDfduGSS#zYQvO\:c'{`u>(2LDҐXPMil)[U-|2YsD9O#ojcCu,&iB's8v0y k狂 HSENo|Ro fל3^;ZKR2M#{% iҭ iZl5}ݯS˲Cy`S* >?aUno?SnԾa5ӾC}SnmpaY 4pIכjyoI٩sr^ 3w?(~叿 .U8?vת .o`v{h8ӢaͼS4΀lAԥpa݂&]`s_ʦ:: ۭ?9t|8̛kx=k*q}U?^H:VL T۱hHuR_1VBjh}6}RZ_4;M>锔O!uBSlY#i͐.榁?֨ա]`ڻ1%jLphƇ8_=Vf!ޏFJ-T,4;).<׉Uc[E Y S)fsz_ޗ>^^+,Bp4Vhr(UUG\ vR*rh5bOְy@1Wv]YZ?E=+4f%?4s-uwU=//h<3HWՌ޹\;@B Ȱ8Oo?2 endstream endobj 185 0 obj << /Filter /FlateDecode /Length 2527 >> stream xYߏ~µTb?Iu:i!+`%)Bo92Krϲ$RGR$E!]l>cWv*?/8bu/LǶo7?-P&v|17R'Z*{~NL0tvJwX˸ݔ5(2aAGx۝]_owj O Z6 o_ UMfۣdj܄#7 'S,j1?4嚦ܯ{\re݌ˮL.i,uy8ԟ{iW-"EMF:Oqjry:fzfF],ʍS})kdl5Q6UW,ձ56L0tbƛJ!S7\"t۠]misUgt !+ ɬ"+2Ő[E:NMf#csrXP6cP %(2L$4xIK{)ȂGqF&z &X 8qErD6XeXXmvHIEd2DX%hcK N 7{58lBnal։RIMԯ[c<Cc)q;ú)Hzu0PwXU[h.(j7G;եQ_h3u9WxJ*n:DUDyX6ARA>M B*L{3 0/jBacݲFKK-O]';? W?z|rPu#]HSE(9M]{UWy!W,bLk qHVc1TZTA{Ie/{lQ`7ms>.6o*R 8$R I9%!D*NHujI[x^DõN2BwB߂Ѩ*U)pD3Sh+1Ʊ7X[:ϟ7B>xK)oJxc3 js@v0}[Cq/ ݁է50欤hc2fuE|kTnXMM^2<**mKűZVz҇mv}4 sz0;>`CZ 85Dkt0Үbp0a)nW\@5ǐv%˻򪦝uIM+Wfv[5sv+ES(rmP.Ą+Imr{~"9 ) ?n[ _+ħc^Tƶ"dT],۪&RS^5=1mp(Ά o05:AӖ-*^5vZAhMc;ctb@]i)@:28 @kk9Tk7SOeB;#̰6ݧ|-Á2u|)ikB /pVPR l&pObZ!WXLݰ_K%69k`I^3y[@"&ͽo+Q"+NrR ^)w#ꌟf#E.i_]~}6SS4n.Di2=Pa-h m=NqawJ0}Lx1pkIo|7g?NU)=Ӎ6>]e R}Q??iTD&?t%UiN d/$!u)(=)\6T#4WEo6{bh2'> /'eϩd~ x?Ap'9Lq:qT`*AnPszY+1a8X0; MH>)#!z5PkW=#8 ]{=+KZƜ#Q/ !!y?=jwy. Y $^XK> stream xgXw-A8YsJh"`4QlEDM`pE *D%DR41H&!,܏>;oYѢh6ILIMNEsZ-V6r h#L[c8jc)vYg:n- qӝ\_1) qIJkޢIJ]LKQD$(k4EQ%yoINIM̈K؜}r:\{vNN c¼ŜaA,bOHn7U&mzzPi84 cqЊmpdC*aq*m@W?C=c(҈1%TvK'{|ӊMK17~71Qrt6*c``T6p|~55ם:1WZyS>.%_ [[x XWV:(0N,6V6p~2 S5ī 3o?"fhĿЅ@$0k$d+Ofj^øg`n]T^3A!I +xS [|&ۆxy{Kmbތm(Ff*O8ʇ ["IܮhZ#=xAPlO--l$sE-a}M,ow$$]Q8r& _MoŪ?*Ȑo;Ȟd5n9{jQCUC݊?y {] *+4m7ϤϑA|J?-[ob%~۱:SUف}g!>6HZlRhĽiuX?N#pK"WnW6 _ﴕ_o.q҈."&V%xXH)UN΁+[/r0g}܇q۶e+D;+`xeFp o>XYv0'jgh҉skCuy4 FwFNPqјtIhJSO8Yۚ^sIwY۾z A A A!`KKF?ֶ_xtb.^ eܗu?g`96tM`XWJЁ[vTD`~YX%qwޗc 6OiXu=}{@q~|Gh%~؜%yTV4"JUőnwG)Ki>*ragaoAv"%qM ؟bpeiu°lX [XSU҄Mkg\Pyu$\<y/.^`w#e`9|+BD!̴ e屗*#g8:3;s† jW7. =L ~l*:sC"0'J.Wxy[([7o@a?hC: F&Aa#Z1+MM50NH>-6B0Cq̒P8h &cކ}#`mMf&bɜVϵTl|^ 9Zo?P5i0kӼI`Mw?nc.G"^\}ajXw|70V10E endstream endobj 187 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2413 >> stream x{Twg *0QL -E|U< PyD@ DV>ʠn"UA|VXԮl*XV- 99I~3{>C&$'(3Dj`E ֓k9o*MM*'X@9 I첏Zzy}s rS2'"YR;2?e^zjWff稔YtU<٪ĬmBa,+;7O101)9%T.-=2#3Z%_xm!~#‰UD$EDK ‘XN ""DJo,1$Hb&1F&'d y|BNtR=Q袉dIIɿsTqxI^BJZGfzGhy9)dA6ہů)^%F:2:![ Ѱh+Tl&4rN>8k\h*XCE\0mlo,EdmP{1xZ'՝NZ ZYdlBg s~ ,ţh>W7zhz•ss3~,bsrV,’Sbo>VX*OXE3q}ojaV$ flѨh*O#ܯt|~ݬ> #'vhjKik8:̪vQuV~W -^;n?dTTuJ&dߎ-<?ޢc}{`Kf?CpCul%0車`/qyg)מm}$8/_W/EW TxPAI^‘^U-볽4%Cuݘ*٩l5GǥJv QRZ`o ?=9MϣNoY>pK:=3XRoS]5x(=zmT,B4]nq굖Lm,xLHԆ~ݐnAx/y8sS88+;T@hJie7Liw:|ۛؽ츰ljmY챍 5(0ꀷJ8WjD?v`y[c$OkO{P5TZê*iH<1[?-B";x}d1Og'`f(5ӯ ՉqPge0vc*͸w.PY{=v -CmL{[%ǥ|}zi6.=HyiH( ,R"mF6Z3uM\ף a RwpMA!w0 `8r3(`Va<.=.:J6Q;¿+i%7lxOD/-U KO [,A"V 玣>7l8n^yW/DފC;|:f5!XF ROAjģZ?AeEF7[D0opS ODx! B͠l ZB=Gi0z] 8,]W~6Lt@ysƽ5sn"Ju"(JYCN!DM[u˜_h>(hYß/}uIq;<{y/>/2RBr;>o@gKOV^>&8sBK"YBN \>hɴgS5O$##q0#JG3ji#v:,n9y|B]lсh>*~WӚq^dlvf -Nj.q"_҃$ðFP],ʥ +a h Jߎ6 wCy]ǢK#J+6|}f7m58lO:&y*X1ܚh4kK.{-06D^BٙG<2;}mť`5 ކY+-K>m' pi}6xx' \QcY.C!/{9Fa2lˏaƢf0h%3"X | K@#ʴx)3ꑔ9qez3ܯHDQVl²knݺ1讉^KJⰦzMj_`k5e*`eiƗԓCS4LM{KL0"endstream endobj 188 0 obj << /Filter /FlateDecode /Length 170 >> stream x]A Eh Mɢ"*,zI|y68({D/LX#~t:ҴT[H*?idF%נr3s# :jd*83[!~ODň.U VxmҢY 5Vkendstream endobj 189 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 720 >> stream xmOqwi1jQbcu&@5 hTb@Q|D-/(-@KRZ[ݥ>[II(hix`<`".&^a8uVTmM4`9vZNj⑲Q@{b9HE (QBc"3drXL~tmm]MPɎ!QM6vBldZ&o]h!OmdIɶ-䕖mZOo_0Q ](L&Zm. a/ydKc 25/G\v=[L -{{(F0p&zhUOF|ހ?7*Ρ$Do&1&$1 Tc t4CX/Bdl B2o]MC{ S^.K+䉗zH2QT~"&?cG t+}d4#ʩUKR|:4QKtޥsbtx*71'|/C)ٷK Iek/ RτZ:OKa,T* cpᦣATjiieu#D l_DH^sfm6f:sl6GMx(Tbt/H+lafe&"to}Vendstream endobj 190 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 597 >> stream xcd`ab`dd M3 JM/I, f!CǴ:<<,~!=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k; g```642f`bf{ac5|, X{r +>]{ؗuyt%usHg_}r?سRپBMzO}}u߽D3:J[k9~}yn]W]8;"M#M]b-V]:pW7V&n[756uwvK0`Ww˿:g|c1hM}ٸZ [~3f6 \XrEW/[´ ;N$gwFvuvvuqt7v6N#Piӎ%ꝶ{E9UI~_γM2m=-n9.|n=}z'^ó|bI'&Xendstream endobj 191 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 444 >> stream xcd`ab`ddM,,IL6 JM/I,ɨf!C_nn?4' ~-S_PYQ`d`` $-*ˋ3R|ˁ y I9i i ! A AzX]"rL _rUjߕEguwv6˕X'$%ws\hŒ;䧯09aɹr-&u'tԕuqӷlܬclX:)@0H{]kQwdsgϘ2An”ɫ',XTb‰ ',w-7hODoD*Yo.7K|S/϶2KH>g7򞾞=fL8gmo ;9"endstream endobj 192 0 obj << /Filter /FlateDecode /Length 7112 >> stream x=]#GR3A݃xn:0A\6ڝhx1̬J׆G쬬lWp3loQ݌{ۛJӐ7Q*QMl߼=| `] Qu/E}dНudyw|+9[Ru{oB@ؾ7͝q3ퟚ >MeFmt][w}&^|J/>ΧݻC=j]qw~>n|5 d}Y7xAl݇;Jv쉑luiYC"ZCt"wQ jzgc|[QLY;8~P?3>bE;]EBݖ&^w=C'$[ka^Ndʪ\O.D]f J}&.zlwQ4Cz1뭳&^PU9}ՉFRGzx5LR# *3 9GsQf3H@f̴nHJM% JO/n(7DwŸ*wiw,GT7h^sPܬ2\w︑m#I.4c!cøx _OK(T$;4 *7c}5  6β6rW2R v J(5pR9Ї)fv"'{(w9nIgIl#\}uXHs㕧kޔ%D7{&xɕykv+wD\FyƁk 1}p^U/DW]ʔ}PݓJfBs11;7J3J F1M̸f&ZnөQ8vLfoL#XyN=[M}媗oJ|;OP#ǟv|qں7d3hneQcmK QB{nߝ䒿'ƶ\V{5*(n90]c9= 0Lu>.ۭ;둒xt۞vP,ؙ3“ujgcΙ0A^B8ZX;X@.f.X=d}*UuMD9܇lEw߳#X3ޣIG|fx'pAJQq#eH]X5|z⃸X[Fi$E<bI3ρq]V"IfhX;N:fS#}"btv1hHprB=q9f0Wrײ/[0yQǂ:o.Bcߡɍp<܃Cp}i0b ,Y {_ }Ofi=对}+2Q*5;Ǭvhr|/Bu?$RPG+)iu.?7aJXObޤuN z7d+wlj2O oh@.T.I#Kny8[˸H 7OI.ciYʋl4)=B2Œb1GO<*R1!zFqkڜ)ێ ImIɝ"+8|W_NܫGGMJY<'EIU X}mYH WVeF0'lfbx< q$y: %Naũ>O)юZɥL׶^:c(=‡ 1anVȧyS5*sD}Q])bQ|tLk5RОM1ΩD MŭȐ#DCdLcɮFM{LuZ"Y+bJqf{T\ M.7)i{YKij0w^^Obb+>LǫAͮtR]3שݱh=ʔ 82[Ќh'FP pt<ˮ.N=9F;9-]BV|=LUp)am1+D1 {(m3n0RF{.|+`ɔsin!HcL@^,s6¯ 9F G [kx揀A@Uo)hx 1( *(z9muJP3,W!}iJrTC R>Aa],WQyh*Tf9,p `D)/gO(Oڛ[v୼A#Lqzb@T%@lZE \Dy1A )Ht[- ą4*eX VLtj f;!%p7JX¤e"l)CUЉjApCLR\ gڞwMPէ)riN[. KH~E$Ɣ J YA/paz5sr \3B&}j`)ެ^ %p(f0nEOĖ%&K@J\LBԄ!hOB؞.IW!ODC'=^^pzp2t@8Mѧզ )8.K!/Vb>+ ĕ@+28 Ep[i!MN~+<f;# _Avi~@ UEa߼uա@nB$Ezh `b("S dtT&OXz$8%XɲgܓJueF{h (kՐ,) *^B/JQE{h WqA|2R$PYVfU.Fm AVFRTZTX4V6VDeccs2 J:^7\^0Hy?9p9z ɬs U:\vґ_ő cp+dsq˙PfrV5\NB H+W5LYd6ocFUYL,1[J6l\LBB;HB{*\\2kq9Ĥ/>C[Qe}oҤbk.Q/pvWㄪ2E˅$ԋ%_k\T&sCB lL 6=•P8%d@=zk\ZìRE{xi"9UrWHVHpiJ3Q )JI/M$Iʜ[+,$BH+JFW5I\c &P%݂gbk^#%Η ^jWejwI)JvS|)CՈT9q!eri6VqԔ/ѸՖֈ-y~|5GONjWHAK]'x/_zԖ7Y-WKӐ_T+AS6-$sšrSK@Źg4Rx++`+ηW Im[@ ķx$67|s8zapU*r5<;!% 4*dbX&5 N JD) .!xl4ﺖӼQCB2^sѸZN+:ͻ2SAм !SA/0$dZVO+C+BBKa {o!O'@2-=O✭ ɴ8T)rAplJ6Д.*ljJ8]UЧ՛ Cs&UN ɬsA~2iEZ23p*ӽVW‚Z⡈ۨJp X҅% ʨ`{\ P# (ja֐,LC$ _8),PDKIeQT0ov&_RDWfD,4a,bqX)Jk!biuu%^ysFW bK#m)QQ`_:&V*hqlZ}ҬJkiVxeVҬô:pQ!-pԐ=BbKL+`84+,d`hVx%4+-Nxtq jUy ]NT — /7c,N wGp{GdL+q5ςDd儥59Un'*$p;Q-bi@wsbiz jiAܵW, 2 4B *β4ۦXls4+L2q]IZ muע9 w%Rèx#Uu]baUYݕY]F _M׳RsQݕ<ҨnYא=Bh!OV=R%U#UBmiwJ4ӻf8Իv`q5kn9i~BR=z%qw?7Q`_} [#FDo<6od@ƞ V)b2$dǐšW@G J# ͂T꣮IErI*CRqBa")=̔fHI |[!aD4դA3R# p&Vo,,MU2TfHA*sel#5Adze9 )頞{N NVP ( ѓ,P}EZ3J#$eGB=ń\L#d!u( foҀEAiX-!Ќ)Iq4f!@tE 5"#5BԳ|끥RfB**,E\ !BcĢO@Fg,> 5C,aZ MkX4KR`э2Ú!8H+FiX-@,mT ̀{E!Mkzt!HE f)R` % kX)@ ,GgfȂei6T Pм`)p (pec}eIm-X?7+GGG#GX+ӟf13>F)ۧ?f11Ǵ^i B4| )hHa͐+(.$ 3 )`! V-RR cs2A%KX6-K!I@%`_44͡D îTS|koD4ԛ~mEm|$)S`喿w=! qcgPn43^B  *c I_!W 5HF/@9&;#jt1Z|9k/G? OonVHe@Il0Rnnendstream endobj 193 0 obj << /Filter /FlateDecode /Length 183 >> stream x]O  $EU%]:!t`$cjMzAh-(ƒڨEzƛ 5!4^*@ `k`yJ a{<'ʓ«3M j_c(HX*s[cww>hk^_endstream endobj 194 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1098 >> stream xuR{L[U-P\j`^nt2 2- ":dx(tm)Q^Jo(bCX"dq1&.KDI<23_s}Q*ra!<2j-vۮ"sEwf!QYJ`pR}.JЪt}T*BGW~owJd^S99rܾ\P[mx;[˽bo-cvg4Wr^̥\IbՒ;rںcx MZw[l.s޽QNd9[Y*l躇];j.6t9(Kx]/QH@(((BmTXԈ>Wd)Oɴx $z3?@r.j#[ X}ώb:ZEAg@+,3Ox txS{踚lS) 1] B/4B8ZJxC7@f{?d{5 % F1>nJo*sus%3w lo;aQ>\Crl$=@W8OI簫RYz?4-){KC*_S8xش5Ց,1)6%%eb:IԜ<[ qō5$ā'ciFz (~_7e1F:C' ,^Mәg|xrpi#=+OHo@+g4@7mPuC6tԐ$9H2I7]=}04@ fpY "&I0V݌DLNX (qƖް7 f[:=dӕMn5cz"ǟå%YL'/V,_ R= uA]/oN4D"qb%i8|/ =~b]$; 2> stream xcd`ab`ddM,M) JM/I,If!CW<<,~^-{+#cxnuSs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+kawhjNjnj^If^Zf^fI%3!2.n/Xt&1|_*{NƟ%DvV[]R{l3v/t${Nb/ o|kr+I~{] B=oZe~v;¢иFc,gU=G;w*^rsn7ol33{W?Uqh3 ߹{D͌og5p@YƣKD-E~3~ON[f}*8uB7-dɵ[9\Ğ{y_={&LY3gɽ=< 2uendstream endobj 196 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 397 >> stream xcd`ab`dd M3 JM/I, f!CǮ<<,~0}G1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000X102HgX} d)?V3+_}ߝݿ:9w^{gtfv{wU8eu'v/W}ms7f\u;ϖ.m1Cwys|a]tMek,[Fi 1?g}ϟ:y&{r\,!<<ܫ{z{zz'N>ówsO)Syx Yendstream endobj 197 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1699 >> stream x]T PTP؛'uL5`HbSaYvVX]eY.XJ5 &NhbKԪjrΤ1Igz̙9;"D~{bm3Ku c1D?/J(C~^_L,~]}07;eΤ1z̙觧,CUUB$d..͓x oB5s&e ah'ȵHhԉRpRto;hoE~'c#2$v#B۟d8`+%&%),!*/>{&xvS |< =p L;=jC{4z ? _&$jW){*:{~J Ž^s$a\޻ڔ\J/p8u.lW(cUo+OA 'N@ UK2< ?x`He>֍("O֩>Z-: P]J6)bM38@!r@E2k|ZӖd eCn{-oW9^lz@jvZ-q Ȫw^EeZ#+>_ɾ I, 8+rAw J9zBP6-Am}Iß d j0vQ,? P!o)a h3@jjn~Ub+U*SϚZB{3Cͬ1Pϰ(݉DguV"A\Ye5P 9/_p@cF^H__r#"|MG 9(iB|码_i,"5ha~IJQw!xEnj]1uap2_Mf۟iZRUA+,{ g U"@V ~d{ܰ e cZ/`~%K1ŏ+ ˜bQP P)Dw'Yi ڡ&`X[=|v {iĮk48FuBQ!弐$Lϲ5"%9x! #TZ! )xڌgu!TBr|F7cgec'wGxI5myTLW@|9㧫#e4/{V] 8ZCWB)ðGII_+Grl͵]\f6AT4y5.吰nzS<@2.-h:5#̶>slXc2endstream endobj 198 0 obj << /Filter /FlateDecode /Length 6383 >> stream x]ݏ7rs@ ^7Î@`pp[{I+X;ʲק_^M,bU;1ʝ3{sLٿ|'# cQ>UNJ?v^Qj{z<{6|8Wa¸Bk3 c7PZ'P` 2ףpn6 T\C 72N _+Z}n臇T?B腎 CE=}u6r(ΏыTЎawrtF OsI뺒n~I,,PJU=Zk~( -(Z+hdk%t c>ŏ>CϦ;h) 0:"\pfqr?}U }|A})RciGSjt`U FÂftP`Qܕ-H TؔW>?0F{Uv 'MľIhG9:{&uXOةlHQڙnb`z",{48PDj/T/ϕGe/ʄaqp ?ׇ̼}rLY$x/)oOI`;wk/7Tax[|Rps;`Nad=wz&tiXYe-{[5D]D9:)6手 $V↗}U&P@6GpeؗCՇ|C""hf_H x~gO_렖H?ޑ_~_J:9|{w+ <9e3eXA5X!kVAV"G"!*7 |}+he1BoQ㾎%DЛ+^s )rv>Lrv+A}?y72XC4Ć[ ]:Oe(j7Xz|? { Ow%53=*3T/v!oUIm[F &KR"zlrnSlBm&_o#I"vǍF' ~D{ Sv\ x PFCVcuYMܙLp @"w7tz#8b|\pL6 TX!ځe#SD1UoJ9#Z֩Jfa1S\;j>]mWȍ{&9r|py$ VW{ʓL{۾"Q[lͿخlNİ?L+`cJtI/l:M(a2G2S{.$4C>0c,4AW.F[4k#t\ĥOX ¨;i-fİD:1UܯYL.9g~GSz7], V,N=`I,Oр} ؐxy\rO^pߓ&( 5IM.uN9 !h:َgC:O5Ke: T5nsL-1g_ʀGYbGDA His騾r'e@+].LSVXT~E.(;- hȺo\>ϐ|߳>?vَ|P!RQ }<~O0Kb믞VxJ_$4C /d6o`kaq95tbJ_0B XG,ϔH/9u}O범d;Ht,žV2ۿWY\ .L' " lVG0JRH8Bgg |ܘR]Ve-Ot NdQX@ n9sO k@ 6[, f\Xo UQ&2ѥ]`b||)h?k8J10$Z4*IlQ8sM_kH svr/)i3L%r5dΔcg=sn _Ygx_*On >^4˙,bnci U 3V9 KA\&l@'p|Ψq-|=~3>w ,iW )Q!\aHa==)|>8N'aFbEX)6rK YinBId:Ri>TP%D7v!zˮqpovj_\H*Çx~aUfU|2S.٩ VS5`MMξ>.t+<,{nY4#7 eoVԗr|ᜨ?=07 ϡD?=E藷7wדϧfχ $>{=(`Aqsl#un=7 :v^o XL&rW@ rx̒7j_6AH H"Mr0^Gj'`;M K!%xZq7!;@`S- ^hL>"Ŧ,R׬9YG$DxD).25"GX6:# 1*XH7{O6{^x"4ێx\&YzD11[$7H!F@șxIxA<$7Eڴ*ցtX$ &B\|G<'4&Hc#V?cd}@_^Aj9ZC^p-R!F@ ؐNU`KD 1y@E7,2Ղ(a=Z٥vHN>MeQm VS?!mHQBu 2}>>$ Dx0h|6,pߕ(f}ʰ~?n_͛݋9Asd H'(44w.k{.ү%2H# x&]=JI9Ңf|pj,>`ȉ]E<NZIYZZ*b*iT)_|mTQF e*&RTe7XKJE` _UT*b/gS4nC.bNdUp:xΠjE`Js)> .bug&R)Ȉ:3Ɉ@$'s j!e*1SFe$f<+u9X6X6‰Hes#$P xip#-芠r*iQ@OY,Ye:WfcyOFU=$u(xUc rʉ!+EcHV1$Ug tB[EYY7E!rH2q(+3ZI)3(K@yso!ӡJ7Yϩk=GA<< St|'Z5DZrS<2q$9K+RU<!V % ! :'EZR[1+r#Hcѧ1-\L-7Fp)66Bp)4Nt TF֩@O.i(_ АS2$rfe*HzaB\P!OS*e:U2OCTpe& e8L%L3\I@.i)Vtlbՙ=$)ܸzq mUFbs`.WI \r.Y\ʄ.Yz^Y:t9c:U] j]tjɪ\mӇ=Sd}xU6w rg|k[(߅L /Y Yo11ĹTxENcWƦ1kr*sOcP獗4>Ҍ=>j IT+bRC\gԄG_S##6!I-ϸB9=ҊQSeAY.^Y*?K>U) 9ހ`;\E@RZAI\w#\PC>26e$ԿTz/3,1N';Ocٴ^ .HRTm/H`%)ԐVH-VhBB_ȳ}LrݤPCZ!e MTBIL<$OM  h6d*4~[TwFMb^t?>Ix{W*_n[jl龙)+uRW.ÛӵԘ05[mCI+ى7iyҜZ %L%ށx-K=|X@4[c/Z& Ȫ?-lih:iS3ɪH_j&k+^M!ZhXk eL}0QJ&꼕)d FL~&E@2 [N,.c;Mxɥ̯w ?xC$v?|W Ҷ4_ B:=qe ,dojW*BayY,8PAVH1`uCGX} \*U⌙, $^)6 C~g@Ib_W+~? O.n_l/.o3ރ?Όcj ǰϪ}|IO2z'r8 K^|szO6} ˰{ 'd>nV2GVH՗zX`O* {n_(몔1g}#(s\޶db n;I-gl78C&]T%OoJ_8?+r?n.ޞbu7KB]Mg%ݝN>MNdj|LU/|1DB.^;RU )+2O.ۍUŤcj,E=a7jc |PY]-endstream endobj 199 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 553 >> stream xcd`ab`ddM,,IL6 JM/I,ɨf!Cw:<<,~L*={3#cxNs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+kau Sf73? , տϸw&C⫿k*g.qcu~.]RWW4f%+ȭS"5U:"?igX%V)HM=pHըmM3gM'́E˻9O+)ol-RY)YV]3Ї%?nB7 30|YDWO.).]d%+~7{&޿Y]KW7Ϝ?s܊3X9C^gC@D`dG~O|_fwϒ\]8 4-Tsy6~Y)WiӾ,`[͵[%${eoOoO߬9S{&lg)< -endstream endobj 200 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 990 >> stream x]mL[eRh/P0 - ,s`lشBx)Ja0 WʹuE!"`%2f?A8tķ,sY2圜rߟB~]*]8P7PBHs')"݅™O#EꔺҲz.qqy+j\Bg(.=>3;3rn+Җ+K8] rPeqGU'r7B(@Qn"T$5AE%R~%~7ljvVDzv8W7ޑ}$ͤN;%5[b!D҈%J*"e~_KOB ,9$i1#p(O{QMU. bd1',KYѧXzGw%0|bn1i'x#ŪW &ΟB*}wFb; t#3I x~dpbp >{KЯ8,x®;oo.Z-fmI;h4peE/$Ì{t|rcκ`oWIr%ѢЧg1Z֖POYYJ}~nO#ؖ19yK׮^mцHg#a [[2x%JЃɼfV0;$& vuu1>ìWbXj2V:*)aheS#檓e_|g-v-c|Ol:j[`4endstream endobj 201 0 obj << /Filter /FlateDecode /Length 14251 >> stream x}Y${ϛ1k;rʹch{3rU}XYEeU~ R\ь]pp8a:Äɿ7ӛq?? ȩN|Y|*O.̇7_7bi7S?P"0rt~rzm~t??79gqe.Ǘ_|5_ۛw X_. 뇞] ;{fw*E<^ܷU?FQ/R^rwDO5&f? K9PYכwap<~pk Q=}^tY}<ܩ̰bJTb,ؼT]S= ~Gnlɐ;#XKuy>~1M EC oJM= .q;_度U>/sIV T,drCu ʎo}'*k*RSK2˙F[cxR<rVSyߺ(aG9lPçXg8RP?ȟ0ptSR}~ZZ &P7:Tp~a(=ױ2bFے,ہMCCSMOJSSf0C1~? `_; SKgtuD[h/rߛODO=1"_J>Ï㤍q*f?e{$,T,O?~Y9D )h`\cu`Yd,WBK)D+,{ ]'gk_z] xxR_t?${-]j_,!"nV"pO {637X%EG+?=̍t ,gv-On5SԆ_upܙ:Wn'tXpCLUaf $#ɣ}ק6rn63W/OwX,:32\v\z| 5& 4J\XO+GJ? 0֬ڵel5jKA"mEx_ %ϫr6X˳z+K_V#$з.!UM%FTHkU#8efw~|$0a,3LlJ+Z k'{~<Nе+_S kl1!m#4SyqM  &&hEe[Hq.5CghHː`ԥ-$'iDz@ K`8-[Y3xBm"HQEFM`ۮ8E1xl5&jmHNF, mNi8A#Gm"cM#RX`{>A]#ɳF :TvO [wJuWH\l,~K[w0:Fx"9j'HPg' )8j̞}3%%DBG r.I`=Jy9sd(kl x'<-ѨBđFW#gH%g\A<%B}0X^#`7?fridY欜X#P0 6=4RnSM@6M>1cTRJx'ꩀg&UŶ@ot=;yKP0D`&hh!{'3u& g] Դ䥚x\dz>uqă;+zޙ"'oWFC`uGc8")9y)rJ3eϊgH ʐF:Hq鐎ʐ*U62Zhبvc]$bܸ{$Dڿ9i1 |2YH`ippȓq<<' C3AA1ZA0׍~I۪+%VT L4E'9#nR d7UwD ;":"gX 5撦㲕„ YZ9[ԭt#ZjWJI`ik)E4a-eBhSԃ$)6E%+t^;HM%ED%ɯiM#tn. p!V?P/{}&3/V?s8h`*A8GrWD P)è2!ndze76OT XŹ馛"*rPɵJaڋaԃuKOZ74D:nbcG6Q[ǴJ|Xz"ҙv4)DA TD?zn0 p߭Zwy^4u w ,mz)"r)[h (GXBS^:nuX'pN &IJSR;Kso2Qq& NSJR*Q ?>BG.hVĴ;4J k6S1 0bP2(#xHG|heHꏥP R9,{4'^zfMHê ӕfU$ ,YL]~K;iC2ͺ`*NR+JjQ[:wIK̰B `$Mbf<|(aGhK}ӐvS4U*r` ^M=e'iy IcFXsP ʡQ¡oHː4UKa&p`ݠ*:2n\1.3֓z&DX.=RQ-+Ir o hXiZfBETLi,54w!IcLq;j@\훆R9@K͡+,Pqq.C MUQ0l8MbRQ i.s(x8O9U28M'R(JF=X7 6U8_:DZvHҷu+EC\z+nh7wepOP R8,`*WqlH3v>$ vt_C,0['$t٤ I'L=HP'K4A\[he;q%ircJCA\P\[Ia4UH*r``FtHrظ1-'$MVH)MsCX{8Bni?B)TJ0=߇La՝jeLNI%G(&g=œƟTu"iQ*rTOɂv ;I,Wb]nM3{̠D`,VuI#4 ?"yƳ#r: ͅoda BI|;$i.s(95wepNP R9zn0:G͔Z7k4݌"j앃r+ÌI*r``:$@ #~󚒼Ùt #][K :d EzNR+JJW[0}=c GutQhi57l&QmǨ)VaVu/s J3\IJQ8h$!T ISFar Q oa,rkS-B;+i,76AKV\A\P0]+T"RaԃuΛxBr[HW\j0RXZW҆J8Jʰ "T`7ƓQ3E#p *=cǦ%MbҭF#{AR0έNRͱ̹GX-8F3gڎ0$-". <.젷T\h䎢=A\$vXҷ28MU'R(JF=X<{馈Ju|>ӭҍF=:AM7ET2堒kM7´)èV<߹5/!*bzsBpWL ~“I: aq0'DPQ|LWU/ IP=b0J iP;20"qgy]leH]d0z!hԆpIxoQv"~4,YpMktZA5)B4L x|fR1\I| b@u`Й^@x^LtôijeA)TBe0z""Ŗ"^(8\/ 4SDR*4S!LwQ9Zf0+!_iw!ww"i7 (}yi.sB'/鈟i>B)Ln0LҴqL;7sAxMoHuG(7o4ePA@ Z)BTt(u7&uH\xt]ց-[:!ڝv7-uHA TBe0z^(ť"mACZv<&Iqix7"0h E[!„̋QJnZgtF(\xACp zrvnC ( 4; heB TFe0jqLУ Mp٩ϑx+KjdA%2j*)/R*Q֭h"V'bPfd6=>,T:# Cle&Raԃu˼馈JVUgqfHfTr-R"6q׵_m:Ls,mƱ!lڔX>+FAmI-qV/C[KLx1-/{Q('.=jGbӉS`ƷijeB)TH0hqh<' e [oSc 9Mr֍Mso2;ƍ̷ NSJR*Q[]- dE(.n{BsGu4mpC$n8PxB)TJ0E ׽<g{e*yY(Мu 4)[]VX;eJk"(F%X1ۦu.);qx% ۴x*vl蕃eO!8Цt+B6 򻊨G%X'GVL|[+6] )IJ Mr AG|S+Tq"jQV+.83_abPH"/'z0Z 'oe3~NrfK2w"=Ҥ|PBVn*2,S zyxWJ ز[ D8i4-ԲRlI>kYb!*;6& ); |;?t4SDSaHF=X7\A7E#yMr~ʦ sGqtML9ZFM0EJkA wtnX5&9زh:l biv[ hF%X1<]my^_C Ǻ$is&(QqS(ʛUʐ452Ka,1`Ym!bfcFO9j6`͢ZEE(j~yVYE@)T@0jr[F K\\}9A<  0DP Q :Z0 W\HKTޒ>Ɨ 1)IQtX0r̡݅Ң%_|E$51`*0XhUcgX^#g ,; fv͕G9'4'g>SM 0)B-ѻlndʛ|Ӎ?(۬M7Qݔe4T ^TLt.mKDVyk$?K rDsɍrǞ"RZ V1v<I#]?xԎbMՀƁ/2AB)DHe0(znYKVhfOkkv1#wY֖h5c vϊ0hB( -X7cً-7qa.oq ~/|yDzk ;0J4U*r` S _/vų>*#i[nKiyƁsKzۊ_U:=:rO;gmÞ;Oqq(Rqܝt;gSz:NhT PB֭򵘮qky N)X0ݍ[)"nU k6BMV t[!:\c'L {ZR HBss,økÊU:=:yObf[^g`GIcE6ߧ̡`*\+Ծ"R`PqSD劎ǃ-OSv#wM7Qʭe4T ]T[1vChfGjEMg\gE;r-!E,pV]}4)BTva!| v_D"lo1<8֫B% Em~7%]Υ2D<"|c<&}T34BW|S".q0ʤP R9zn/t)UoM7+xNQW3c/c g¬;4fB( ) F-X۝f\;aoxBh@*ojJ QV+mN-Ck^{VkQ=Kb`@"f*.B Q[y. ?gC} uj.SH#} bIbOm!4@$L )| %3G7DR~-.\Z7~|eW?V@}| Y#0!3tV6|8c^GX#by O|&__!s|_Z"3'|E/qq1KczelX.|/Mu KM߅B Tyf+y ?U4o"!''6_ۢ'wHGiAM$ET\^SRD,%*[n)'CA7.,< B"< gt\MdъlxƘ&R7A$89Ff7CiDY DR-k&DuQ z&P8O6XDR_šF^GBֈG0MQ5" 9%⬏]$:TjAxCXPGXIAj o p!3W #DS VԤ1ިJi J !%{VHw.`J$"o!sID`:2!xl"$D?Fp& Uy{s~ZS4|.ǡ7VNuPuz&wӸSܳ$ZC kl-#V@p[F#+Ē xw;7MHg&BDq6}\ݙv m1"kPX#x$]#99~CtԾg-$vCKcn m#f[gdl7G5q56(JX*WħTF4 X;eW sBah`  vZG#40PD*h#itF}EX.˦v@ Uq]4O$}$Ib H[A+ A=- .X| xI{ӽ"v b|&^#~c+c\R؜,c-3[lcBYxc5Q]6qZ#jȮn]khdW$ Htd4 $նGZ] ]d~@uZ'9b)iHeriLeh \~e*aR$=-aMG>"c_fQvjtnhCYiQe.[ߦU3-gG^y35 >] _t2,c X2Ag99]N7eΨ#r49=sBQ/.q}!|'(6z^/z^tp4J|#iEƈ=?WQHWo?tH;ORk[6^ yUuz^<ጼ8%>s۳Ri ýn_/iL'ݒFy ,|R?[6j5Ukχeʐ ?3 iTː RsOeHGШױQӻpw my:awJ0g}+///{p& x3k(Le$ mՅO72v!x:02gǫL:Κ}& :*e@ߠ7*A*m*A* xJ ?^TQu%cǛ7VwM=&% ~KwI%Ӹ- ,b <Ɍw hDyp|wEE-R S*O703L0޼ t<1??< ~/p|<+s9^?=Cj;a2etp+er~fWO}A#(JL~uto{LQ9Tұc @L~>O_jۈ sAQ/K_nNe9Zs?< q۠N>=]UXPw0VyRI>}jLrs?u$BM4x|h;&b+gQ*=BpB9щq~9` B@^74;oZև|>պ`=a?sڐcZVţs jX]_  0QuGj w]kF4,Ɏ/鈄Kӣ _>{KQwiқЍǻ}3qHRkkÆD.:?Gk=CgcYfdkɯ`7ر=8.Moe\ʡC d"SKf6}>܉S8~+ i^Ȩ_ف%a}dp?=~;RiifY8#4,^\ȡ9g4?ސ fwWB "+~zIMƓзXj2?}:i|//T8tn5Qw_.:I7IܰD&=q#b} ?HLNV ,:/uô^u-ZI/%wvc?Gwg8禠nz٧~9?ܿuB}5|Ϯxh֋X[N(̝ORmV\-go> stream xn#5g圛 EGԾ N!ȇRᢡA=ェj6%T}z7ᕘpK.]z:I?sT1\-b"u%̷ٗәBz\zWf<\zc-^MʄL;&%@ *x^LgP^~ zwaәqr}um7hH_; 2cLw3{>8g3. ͓(D!V2`6kOq+؂l/;oJ`dM\ЎKXs ,[^ol ҁ%L;\clDkb:>u1 MXvZ5c+j}z_Yi-6:N/Z\Qi%ԳleM^G_Bhϖ>SIT}&?aa!жrF@p֞H{te~3WJCBJvO6FiǢ4,DKR1CWR "94'hR$_%%5tV 8$T6X'J9+d[lT"wȂ=a`as J{ 7PS=ŘϤ%ge) -;F ]f.4eX A/o 1%ܩYo!"wmiKQ$h? 2 y_x%]yꬔp5% ֋)H0*Į)d2f,:Vǐo t< $z1EFyk1VU] t0Uwd'tZOХ0g3\6Xi$m}N[!3'hZlЎmDKF5}Zo2BMdE?A]tdnPXqb~j}_H{$ȥ&Ddj"HjP|R-*2zMJ׬M2v[H@EB[l4B2G`JM-0,|rhđ."rN-`>a^y[h hD88c[`MY(W(HS1BQ ; ~7}^Zj֏`XdQ^xvY-z2E݁t-ށ[aw`}7ߏHdRҰf9N^6QXk 7t b37$yy^ t !4&\Kiw@MFK9ՋB *, ?bEAM]hTSnf<69e^}MaSɱʜCܐ<:(M0^}fb_.CE%M7SYo36-V`Y7u`q)ro.@?κ$SA}01E7Bv->^f$:2}8z D="y>0/O/=6w 􂏀ySݪZB&m8U^Jm:Wa;?O.ޭ;t(S9xnm?ou`dLrҕt3mڞ<9a|UHC ԲxPX aLƸ9eh-c2Wْ&c2{*n B#-b_Mظ%f8> H~~`~ 5}Vz8h6s?- Wnl0?6ţˡ?fcȳt`-m fSWGf^YSfЙsUDdM_g"3%B9pHF\iiTLb% >ԱstTEzv߱C5J0*p=C[АOqf*}tG=D$sDZA46tf}X pǻ3hM[`7`Mc1*GWN}(:M`nrө80θ-@CWHRbμ7 H ʙpwNQyA=xy$wB U.c%P}'z1#q BRx;hъ+صhEVѺ[h\zh+S"֗R>b_b ag1v=Q+a?!-b$G]J9s1J4r'“4 \ZiNs)Z`X.gr< @ƁWLeyWxǹ/ ܟdCdo/ƹJendstream endobj 203 0 obj << /Filter /FlateDecode /Length 2539 >> stream xَ}!>''c`c'k8GCe=S`M}uUͧM،_ogf?yu-+MRЂV7W͘IYFeD:[ޓgL|Ir99C!*O(H{R!3np#B E)}eded3<# TJK%EoD`YU[u񔑛i9|1Tr`̗L˺x }s79|,KE(C!-I:FՒ9f%y>[m9 5%SI*<ORH,a=Cǝ2vV[F;?Ȝ*EWibQ" dT\ ,s Es.ˆE D <8)JE x"<w5}6I{գUwlƝ"' =S?K>a =~YHD w i}6Շ #7pI{mp{ S ,>4XhB0[o.lȭJw?`pC X 7$}&e!g% vSG? (Xtj431lZB4ӮĔkbkS\ r].R\cHӏLbP+ZQFY"܄eEI.7ȕw.@PKN}S}up96ܭ {|u{XE@Z 2 RSOm}ߵnS1 .'OȠgSJ:)20RCSv'.`V WYBT1 Jokoinӹ:lxzX7~_^M(Kp!@Phs N_VU˚u(hkycR`1t%_}݇ \Br=qJD;iyڙ4Kp2M>-HC h\d35ZhA<`_ܲڅ8f0kBڬ8ƕβ)%&Ry@v(wpDu\J'GGhG-~U=Rvi̓ROY>R®RCfm˾|pkCj^=ͯRƱnG\-c/50@ wo\w])т|2%|V)9GwL|=Vר|T90&H>!đ꠽,>K3[ūb/rWF&so~iurcEVî<@M&8ytXI2>LbJ֘J9?.2JFkЫbZ]< }у/*Ux ]n2K+͸ӝwn{hnFn21KIBf/ P/o,牘{`uȦDza7w1%I}Gf"1OnYGc{}?F~ujSdm^4<wHCUxsguSݝ7{85&ypֿa3֧_v ;b4XN08G:| rWSﵬ;aaDZϣ +4N(I húXm/endstream endobj 204 0 obj << /Type /XRef /Length 206 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 205 /ID [] >> stream xcb&F~0 $8J?@6%(~{p!3d 7┿D\, R>D EjހH&K09LJHAM> D>| Q ,f/DrtIF.}9DJR R(D`΃`s>ui`7H!,F]LU`9m@$`X` 慘o!= endstream endobj startxref 139901 %%EOF surveillance/inst/doc/twinstim.Rnw0000644000176200001440000016164414615162374017063 0ustar liggesusers%\VignetteIndexEntry{twinstim: An endemic-epidemic modeling framework for spatio-temporal point patterns} %\VignetteEngine{knitr::knitr} %% additional dependencies beyond what is required for surveillance anyway: %\VignetteDepends{surveillance, grid, sf, polyclip, memoise, colorspace} <>= ## purl=FALSE => not included in the tangle'd R script knitr::opts_chunk$set(echo = TRUE, tidy = FALSE, results = 'markup', fig.path='plots/twinstim-', fig.width = 8, fig.height = 4, fig.align = "center", fig.scap = NA, out.width = NULL, cache = FALSE, error = FALSE, warning = FALSE, message = FALSE) knitr::render_sweave() # use Sweave environments knitr::set_header(highlight = '') # no \usepackage{Sweave} (part of jss class) ## add a chunk option "strip.white.output" to remove leading and trailing white ## space (empty lines) from output chunks ('strip.white' has no effect) local({ default_output_hook <- knitr::knit_hooks$get("output") knitr::knit_hooks$set(output = function (x, options) { if (isTRUE(options[["strip.white.output"]])) { x <- sub("[[:space:]]+$", "\n", # set a single trailing \n sub("^[[:space:]]+", "", x)) # remove leading space } default_output_hook(x, options) }) }) ## R settings options(prompt = "R> ", continue = "+ ", useFancyQuotes = FALSE) # JSS options(width = 85, digits = 4) options(scipen = 1) # so that 1e-4 gets printed as 0.0001 ## xtable settings options(xtable.booktabs = TRUE, xtable.size = "small", xtable.sanitize.text.function = identity, xtable.comment = FALSE) @ \documentclass[nojss,nofooter,article]{jss} \usepackage[utf8]{inputenc} % Rnw is ASCII, but auto-generated bib file isn't % (specification is redundant in LaTeX >= 2018-04-01) \title{% \vspace{-1.5cm} \fbox{\vbox{\normalfont\footnotesize This introduction to the \code{twinstim} modeling framework of the \proglang{R}~package \pkg{surveillance} is based on a publication in the \textit{Journal of Statistical Software} -- \citet[Section~3]{meyer.etal2014} -- which is the suggested reference if you use the \code{twinstim} implementation in your own work.}}\\[1cm] \code{twinstim}: An endemic-epidemic modeling framework for spatio-temporal point patterns} \Plaintitle{twinstim: An endemic-epidemic modeling framework for spatio-temporal point patterns} \Shorttitle{Endemic-epidemic modeling of spatio-temporal point patterns} \author{Sebastian Meyer\thanks{Author of correspondence: \email{seb.meyer@fau.de}}\\Friedrich-Alexander-Universit{\"a}t\\Erlangen-N{\"u}rnberg \And Leonhard Held\\University of Zurich \And Michael H\"ohle\\Stockholm University} \Plainauthor{Sebastian Meyer, Leonhard Held, Michael H\"ohle} %% Basic packages \usepackage{lmodern} % successor of CM -> searchable Umlauts (1 char) \usepackage[english]{babel} % language of the manuscript is American English %% Math packages \usepackage{amsmath,amsfonts} % amsfonts defines \mathbb \usepackage{bm} % \bm: alternative to \boldsymbol from amsfonts %% Packages for figures and tables \usepackage{booktabs} % make tables look nicer \usepackage{subcaption} % successor of subfig, which supersedes subfigure %% knitr uses \subfloat, which subcaption only provides since v1.3 (2019/08/31) \providecommand{\subfloat}[2][need a sub-caption]{\subcaptionbox{#1}{#2}} %% Handy math commands \newcommand{\abs}[1]{\lvert#1\rvert} \newcommand{\norm}[1]{\lVert#1\rVert} \newcommand{\given}{\,\vert\,} \newcommand{\dif}{\,\mathrm{d}} \newcommand{\IR}{\mathbb{R}} \newcommand{\IN}{\mathbb{N}} \newcommand{\ind}{\mathbb{I}} \DeclareMathOperator{\Po}{Po} \DeclareMathOperator{\NegBin}{NegBin} \DeclareMathOperator{\N}{N} %% Additional commands \newcommand{\class}[1]{\code{#1}} % could use quotes (JSS does not like them) \newcommand{\CRANpkg}[1]{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}} %% Reduce the font size of code input and output \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl, fontsize=\small} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\small} %% Abstract \Abstract{ The availability of geocoded health data and the inherent temporal structure of communicable diseases have led to an increased interest in statistical models and software for spatio-temporal data with epidemic features. The \proglang{R}~package \pkg{surveillance} can handle various levels of aggregation at which infective events have been recorded. This vignette illustrates the analysis of \emph{point-referenced} surveillance data using the endemic-epidemic point process model ``\code{twinstim}'' proposed by \citet{meyer.etal2011} and extended in \citet{meyer.held2013}. %% (For other types of surveillance data, see %% \code{vignette("twinSIR")} and \code{vignette("hhh4\_spacetime")}.) We first describe the general modeling approach and then exemplify data handling, model fitting, visualization, and simulation methods for time-stamped geo-referenced case reports of invasive meningococcal disease (IMD) caused by the two most common bacterial finetypes of meningococci in Germany, 2002--2008. } \Keywords{% spatio-temporal point pattern, endemic-epidemic modeling, infectious disease epidemiology, self-exciting point process, spatial interaction function, branching process with immigration} \begin{document} <>= ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("twinstim-cache.RData")) if (!COMPUTE) load("twinstim-cache.RData", verbose = TRUE) @ \section[Model class]{Model class: \code{twinstim}} \label{sec:twinstim:methods} Infective events occur at specific points in continuous space and time, which gives rise to a spatio-temporal point pattern $\{(\bm{s}_i,t_i): i = 1,\dotsc,n\}$ from a region~$\bm{W}$ observed during a period~$(0,T]$. The locations~$\bm{s}_i$ and time points~$t_i$ of the $n$~events can be regarded as a realization of a self-exciting spatio-temporal point process, which can be characterized by its conditional intensity function (CIF, also termed intensity process) $\lambda(\bm{s},t)$. It represents the instantaneous event rate at location~$\bm{s}$ at time point~$t$ given all past events, and is often more verbosely denoted by~$\lambda^*$ or by explicit conditioning on the ``history''~$\mathcal{H}_t$ of the process. \citet[Chapter~7]{Daley.Vere-Jones2003} provide a rigorous mathematical definition of this concept, which is key to likelihood analysis and simulation of ``evolutionary'' point processes. \citet{meyer.etal2011} formulated the model class ``\code{twinstim}'' -- a \emph{two}-component \emph{s}patio-\emph{t}emporal \emph{i}ntensity \emph{m}odel -- by a superposition of an endemic and an epidemic component: \begin{equation} \label{eqn:twinstim} \lambda(\bm{s},t) = \nu_{[\bm{s}][t]} + \sum_{j \in I(\bm{s},t)} \eta_j \, f(\norm{\bm{s}-\bm{s}_j}) \, g(t-t_j) \:. \end{equation} This model constitutes a branching process with immigration. Part of the event rate is due to the first, endemic component, which reflects sporadic events caused by unobserved sources of infection. This background rate of new events is modeled by a log-linear predictor $\nu_{[\bm{s}][t]}$ incorporating regional and/or time-varying characteristics. Here, the space-time index $[\bm{s}][t]$ refers to the region covering $\bm{s}$ during the period containing $t$ and thus spans a whole spatio-temporal grid on which the involved covariates are measured, e.g., district $\times$ month. We will later see that the endemic component therefore simply equals an inhomogeneous Poisson process for the event counts by cell of that grid. The second, observation-driven epidemic component adds ``infection pressure'' from the set \begin{equation*} I(\bm{s},t) = \big\{ j : t_j < t \:\wedge\: t-t_j \le \tau_j \:\wedge\: \norm{\bm{s}-\bm{s}_j} \le \delta_j \big\} \end{equation*} of past events and hence makes the process ``self-exciting''. During its infectious period of length~$\tau_j$ and within its spatial interaction radius~$\delta_j$, the model assumes each event~$j$ to trigger further events, which are called offspring, secondary cases, or aftershocks, depending on the application. The triggering rate (or force of infection) is proportional to a log-linear predictor~$\eta_j$ associated with event-specific characteristics (``marks'') $\bm{m}_j$, which are usually attached to the point pattern of events. The decay of infection pressure with increasing spatial and temporal distance from the infective event is modeled by parametric interaction functions~$f$ and~$g$, respectively. A simple assumption for the time course of infectivity is $g(t) = 1$. Alternatives include exponential decay, a step function, or empirically derived functions such as Omori's law for aftershock intervals. With regard to spatial interaction, a Gaussian kernel $f(x) = \exp\left\{-x^2/(2 \sigma^2)\right\}$ could be chosen. However, in modeling the spread of human infectious diseases on larger scales, a heavy-tailed power-law kernel $f(x) = (x+\sigma)^{-d}$ was found to perform better \citep{meyer.held2013}. The (possibly infinite) upper bounds~$\tau_j$ and~$\delta_j$ provide a way of modeling event-specific interaction ranges. However, since these need to be pre-specified, a common assumption is $\tau_j \equiv \tau$ and $\delta_j \equiv \delta$, where the infectious period~$\tau$ and the spatial interaction radius~$\delta$ are determined by subject-matter considerations. \subsection{Model-based effective reproduction numbers} Similar to the simple SIR model \citep[see, e.g.,][Section 2.1]{Keeling.Rohani2008}, the above point process model~\eqref{eqn:twinstim} features a reproduction number derived from its branching process interpretation. As soon as an event occurs (individual becomes infected), it triggers offspring (secondary cases) around its origin $(\bm{s}_j, t_j)$ according to an inhomogeneous Poisson process with rate $\eta_j \, f(\norm{\bm{s}-\bm{s}_j}) \, g(t-t_j)$. Since this triggering process is independent of the event's parentage and of other events, the expected number $\mu_j$ of events triggered by event $j$ can be obtained by integrating the triggering rate over the observed interaction domain: \begin{equation} \label{eqn:R0:twinstim} \mu_j = \eta_j \cdot \left[ \int_0^{\min(T-t_j,\tau_j)} g(t) \,dt \right] \cdot \left[ \int_{\bm{R}_j} f(\norm{\bm{s}}) \,d\bm{s} \right] \:, \end{equation} where \begin{equation} \label{eqn:twinstim:IR} \bm{R}_j = (b(\bm{s}_j,\delta_j) \cap \bm{W}) - \bm{s}_j \end{equation} is event $j$'s influence region centered at $\bm{s}_j$, and $b(\bm{s}_j, \delta_j)$ denotes the disc centered at $\bm{s}_j$ with radius $\delta_j$. Note that the above model-based reproduction number $\mu_j$ is event-specific since it depends on event marks through $\eta_j$, on the interaction ranges $\delta_j$ and $\tau_j$, as well as on the event location $\bm{s}_j$ and time point $t_j$. If the model assumes unique interaction ranges $\delta$ and $\tau$, a single reference number of secondary cases can be extrapolated from Equation~\ref{eqn:R0:twinstim} by imputing an unbounded domain $\bm{W} = \IR^2$ and $T = \infty$ \citep{meyer.etal2015}. Equation~\ref{eqn:R0:twinstim} can also be motivated by looking at a spatio-temporal version of the simple SIR model wrapped into the \class{twinstim} class~\eqref{eqn:twinstim}. This means: no endemic component, homogeneous force of infection ($\eta_j \equiv \beta$), homogeneous mixing in space ($f(x) = 1$, $\delta_j \equiv \infty$), and exponential decay of infectivity over time ($g(t) = e^{-\alpha t}$, $\tau_j \equiv \infty$). Then, for $T \rightarrow \infty$, \begin{equation*} \mu = \beta \cdot \left[ \int_0^\infty e^{-\alpha t} \,dt \right] \cdot \left[ \int_{\bm{W}-\bm{s}_j} 1 \,d\bm{s} \right] = \beta \cdot \abs{\bm{W}} / \alpha \:, \end{equation*} which corresponds to the basic reproduction number known from the simple SIR model by interpreting $\abs{\bm{W}}$ as the population size, $\beta$ as the transmission rate and $\alpha$ as the removal rate. If $\mu < 1$, the process is sub-critical, i.e., its eventual extinction is almost sure. However, it is crucial to understand that in a full model with an endemic component, new infections may always occur via ``immigration''. Hence, reproduction numbers in \class{twinstim} are adjusted for infections occurring independently of previous infections. This also means that a misspecified endemic component may distort model-based reproduction numbers \citep{meyer.etal2015}. Furthermore, under-reporting and implemented control measures imply that the estimates are to be thought of as \emph{effective} reproduction numbers. \subsection{Likelihood inference} The log-likelihood of the point process model~\eqref{eqn:twinstim} is a function of all parameters in the log-linear predictors $\nu_{[\bm{s}][t]}$ and $\eta_j$ and in the interaction functions $f$ and $g$. It has the form %% \begin{equation} \label{eqn:twinstim:marked:loglik} %% l(\bm{\theta}) = \left[ \sum_{i=1}^{n} \log\lambda(\bm{s}_i,t_i,k_i) \right] - %% \sum_{k\in\mathcal{K}} \int_0^T \int_{\bm{W}} \lambda(\bm{s},t,k) \dif\bm{s} %% \dif t \:, %% \end{equation} \begin{equation} \label{eqn:twinstim:loglik} \left[ \sum_{i=1}^{n} \log\lambda(\bm{s}_i,t_i) \right] - \int_0^T \int_{\bm{W}} \lambda(\bm{s},t) \dif\bm{s} \dif t \:. \end{equation} %\citep[Proposition~7.3.III]{Daley.Vere-Jones2003} To estimate the model parameters, we maximize the above log-likelihood numerically using the quasi-Newton algorithm available through the \proglang{R}~function \code{nlminb}. We thereby employ the analytical score function and an approximation of the expected Fisher information worked out by \citet[Web Appendices A and B]{meyer.etal2011}. The space-time integral in the log-likelihood \eqref{eqn:twinstim:loglik} poses no difficulties for the endemic component of $\lambda(\bm{s},t)$, since $\nu_{[\bm{s}][t]}$ is defined on a spatio-temporal grid. However, integration of the epidemic component involves two-dimensional integrals $\int_{\bm{R}_i} f(\norm{\bm{s}}) \dif\bm{s}$ over the influence regions~$\bm{R}_i$, which are represented by polygons (as is~$\bm{W}$). Similar integrals appear in the score function, where $f(\norm{\bm{s}})$ is replaced by partial derivatives with respect to kernel parameters. Calculation of these integrals is trivial for (piecewise) constant~$f$, but otherwise requires numerical integration. The \proglang{R}~package \CRANpkg{polyCub} \citep{meyer2019} offers various cubature methods for polygonal domains. % For Gaussian~$f$, we apply a midpoint rule with $\sigma$-adaptive bandwidth % %% combined with an analytical formula via the $\chi^2$ distribution % %% if the $6\sigma$-circle around $\bm{s}_i$ is contained in $\bm{R}_i$. % and use product Gauss cubature \citep{sommariva.vianello2007} % to approximate the integrals in the score function. % For the recently implemented power-law kernels, Of particular relevance for \code{twinstim} is the \code{polyCub.iso} method, which takes advantage of the assumed isotropy of spatial interaction such that numerical integration remains in only one dimension \citep[Supplement~B, Section~2]{meyer.held2013}. We \CRANpkg{memoise} \citep{R:memoise} the cubature function during log-likelihood maximization to avoid integration for unchanged parameters of~$f$. \subsection{Special cases: Single-component models} If the \emph{epidemic} component is omitted in Equation~\ref{eqn:twinstim}, the point process model becomes equivalent to a Poisson regression model for aggregated counts. This provides a link to ecological regression approaches in general and to the count data model \code{hhh4} illustrated in \code{vignette("hhh4")} and \code{vignette("hhh4\_spacetime")}. To see this, recall that the endemic component $\nu_{[\bm{s}][t]}$ is piecewise constant on the spatio-temporal grid with cells $([\bm{s}],[t])$. Hence the log-likelihood~\eqref{eqn:twinstim:loglik} of an endemic-only \code{twinstim} simplifies to a sum over all these cells, \begin{equation*} \sum_{[\bm{s}],[t]} \left\{ Y_{[\bm{s}][t]} \log\nu_{[\bm{s}][t]} - \abs{[\bm{s}]} \, \abs{[t]} \, \nu_{[\bm{s}][t]} \right\} \:, \end{equation*} where $Y_{[\bm{s}][t]}$ is the aggregated number of events observed in cell $([\bm{s}],[t])$, and $\abs{[\bm{s}]}$ and $\abs{[t]}$ denote cell area and length, respectively. Except for an additive constant, the above log-likelihood is equivalently obtained from the Poisson model $Y_{[\bm{s}][t]} \sim \Po( \abs{[\bm{s}]} \, \abs{[t]} \, \nu_{[\bm{s}][t]})$. This relation offers a means of code validation using the established \code{glm} function to fit an endemic-only \code{twinstim} model -- see the examples in \code{help("glm_epidataCS")}. %% The \code{help("glm_epidataCS")} also shows how to fit %% an equivalent endemic-only \code{hhh4} model. If, in contrast, the \emph{endemic} component is omitted, all events are necessarily triggered by other observed events. For such a model to be identifiable, a prehistory of events must exist to trigger the first event, and interaction typically needs to be unbounded such that each event can actually be linked to potential source events. \subsection[Extension: Event types]{Extension: \code{twinstim} with event types} To model the example data on invasive meningococcal disease in the remainder of this section, we actually need to use an extended version $\lambda(\bm{s},t,k)$ of Equation~\ref{eqn:twinstim}, which accounts for different event types~$k$ with own transmission dynamics. This introduces a further dimension in the point process, and the second log-likelihood component in Equation~\ref{eqn:twinstim:loglik} accordingly splits into a sum over all event types. We refer to \citet[Sections~2.4 and~3]{meyer.etal2011} for the technical details of this type-specific \code{twinstim} class. The basic idea is that the meningococcal finetypes share the same endemic pattern (e.g., seasonality), while infections of different finetypes are not associated via transmission. This means that the force of infection is restricted to previously infected individuals with the same bacterial finetype~$k$, i.e., the epidemic sum in Equation~\ref{eqn:twinstim} is over the set $I(\bm{s},t,k) = I(\bm{s},t) \cap \{j: k_j = k\}$. The implementation has limited support for type-dependent interaction functions $f_{k_j}$ and $g_{k_j}$ (not further considered here). \section[Data structure]{Data structure: \class{epidataCS}} \label{sec:twinstim:data} <>= ## extract components from imdepi to reconstruct data("imdepi") events <- SpatialPointsDataFrame( coords = coordinates(imdepi$events), data = marks(imdepi, coords=FALSE), proj4string = imdepi$events@proj4string # ETRS89 projection (+units=km) ) stgrid <- imdepi$stgrid[,-1] @ <>= load(system.file("shapes", "districtsD.RData", package = "surveillance")) @ The first step toward fitting a \code{twinstim} is to turn the relevant data into an object of the dedicated class \class{epidataCS}.\footnote{ The suffix ``CS'' indicates that the data-generating point process is indexed in continuous space. } The primary ingredients of this class are a spatio-temporal point pattern (\code{events}) and its underlying observation region (\code{W}). An additional spatio-temporal grid (\code{stgrid}) holds (time-varying) area-level covariates for the endemic regression part. We exemplify this data class by the \class{epidataCS} object for the \Sexpr{nobs(imdepi)} cases of invasive meningococcal disease in Germany originally analyzed by \citet{meyer.etal2011}. It is already contained in the \pkg{surveillance} package as \code{data("imdepi")} and has been constructed as follows: <>= imdepi <- as.epidataCS(events = events, W = stateD, stgrid = stgrid, qmatrix = diag(2), nCircle2Poly = 16) @ The function \code{as.epidataCS} checks the consistency of the three data ingredients described in detail below. It also pre-computes auxiliary variables for model fitting, e.g., the individual influence regions~\eqref{eqn:twinstim:IR}, which are intersections of the observation region with discs %of radius \code{eps.s} centered at the event location approximated by polygons with \code{nCircle2Poly = 16} edges. The intersections are computed using functionality of the package \CRANpkg{polyclip} \citep{R:polyclip}. For multitype epidemics as in our example, the additional indicator matrix \code{qmatrix} specifies transmissibility across event types. An identity matrix corresponds to an independent spread of the event types, i.e., cases of one type can not produce cases of another type. \subsection{Data ingredients} The core \code{events} data must be provided in the form of a \class{SpatialPointsDataFrame} as defined by the package \CRANpkg{sp} \citep{R:sp}: <>= summary(events) @ <>= oopt <- options(width=100) ## hack to reduce the 'print.gap' in the data summary but not for the bbox ## Note: sp >= 2.0-0 loads 'sf' for summary(events), but has a fallback, ## see https://github.com/r-spatial/evolution/issues/10 local({ print.summary.Spatial <- sp:::print.summary.Spatial environment(print.summary.Spatial) <- environment() print.table <- function (x, ..., print.gap = 0) { base::print.table(x, ..., print.gap = print.gap) } print.summary.Spatial(summary(events)) }) options(oopt) @ The associated event coordinates are residence postcode centroids, projected in the \emph{European Terrestrial Reference System 1989} (in kilometer units) to enable Euclidean geometry. See the \code{spTransform}-methods for how to project latitude and longitude coordinates into a planar coordinate reference system (CRS). The data frame associated with these spatial coordinates ($\bm{s}_i$) contains a number of required variables and additional event marks (in the notation of Section~\ref{sec:twinstim:methods}: $\{(t_i,[\bm{s}_i],k_i,\tau_i,\delta_i,\bm{m}_i): i = 1,\dotsc,n\}$). For the IMD data, the event \code{time} is measured in days since the beginning of the observation period 2002--2008 and is subject to a tie-breaking procedure (described later). The \code{tile} column refers to the region of the spatio-temporal grid where the event occurred and here contains the official key of the administrative district of the patient's residence. There are two \code{type}s of events labeled as \code{"B"} and \code{"C"}, which refer to the serogroups of the two meningococcal finetypes \emph{B:P1.7-2,4:F1-5} and \emph{C:P1.5,2:F3-3} contained in the data. The \code{eps.t} and \code{eps.s} columns specify upper limits for temporal and spatial interaction, respectively. Here, the infectious period is assumed to last a maximum of 30 days and spatial interaction is limited to a 200 km radius for all cases. The latter has numerical advantages for a Gaussian interaction function $f$ with a relatively small standard deviation. For a power-law kernel, however, this restriction will be dropped to enable occasional long-range transmission. The last two data attributes displayed in the above \code{event} summary are covariates from the case reports: the gender and age group of the patient. For the observation region \code{W}, we use a polygon representation of Germany's boundary. Since the observation region defines the integration domain in the point process log-likelihood~\eqref{eqn:twinstim:loglik}, the more detailed the polygons of \code{W} are the longer it will take to fit a \code{twinstim}. It is thus advisable to sacrifice some shape details for speed by reducing the polygon complexity. In \proglang{R} this can be achieved via, e.g., \code{ms_simplify} from the \CRANpkg{rmapshaper} package \citep{R:rmapshaper}, or \code{simplify.owin} from \CRANpkg{spatstat.geom} \citep{R:spatstat}. % \code{thinnedSpatialPoly} in package \CRANpkg{maptools}, % will retire % which implements the Douglas-Peucker reduction method. The \pkg{surveillance} package already contains a simplified representation of Germany's boundaries: <>= <> @ This file contains both the \class{SpatialPolygonsDataFrame} \code{districtsD} of Germany's \Sexpr{length(districtsD)} administrative districts as at January 1, 2009, as well as their union \code{stateD}. %obtained by the call \code{rgeos::gUnaryUnion(districtsD)} \citep{R:rgeos}. These boundaries are projected in the same CRS as the \code{events} data. The \code{stgrid} input for the endemic model component is a data frame with (time-varying) area-level covariates, e.g., socio-economic or ecological characteristics. In our example: <>= .stgrid.excerpt <- format(rbind(head(stgrid, 3), tail(stgrid, 3)), digits=3) rbind(.stgrid.excerpt[1:3,], "..."="...", .stgrid.excerpt[4:6,]) @ Numeric (\code{start},\code{stop}] columns index the time periods and the factor variable \code{tile} identifies the regions of the grid. Note that the given time intervals (here: months) also define the resolution of possible time trends and seasonality of the piecewise constant endemic intensity. We choose monthly intervals to reduce package size and computational cost compared to the weekly resolution originally used by \citet{meyer.etal2011} and \citet{meyer.held2013}. The above \code{stgrid} data frame thus consists of 7 (years) times 12 (months) blocks of \Sexpr{nlevels(stgrid[["tile"]])} (districts) rows each. The \code{area} column gives the area of the respective \code{tile} in square kilometers (compatible with the CRS used for \code{events} and \code{W}). A geographic representation of the regions in \code{stgrid} is not required for model estimation, and is thus not part of the \class{epidataCS} class. %It is, however, necessary for plots of the fitted intensity and for %simulation from the estimated model. In our example, the area-level data only consists of the population density \code{popdensity}, whereas \citet{meyer.etal2011} additionally incorporated (lagged) weekly influenza counts by district as a time-dependent covariate. %% In another application, \citet{meyer.etal2015} used a large number of socio-economic %% characteristics to model psychiatric hospital admissions. \pagebreak \subsection{Data handling and visualization} The generated \class{epidataCS} object \code{imdepi} is a simple list of the checked ingredients <>= cat(paste0('\\code{', names(imdepi), '}', collapse = ", "), ".", sep = "") @ Several methods for data handling and visualization are available for such objects as listed in Table~\ref{tab:methods:epidataCS} and briefly presented in the remainder of this section. <>= print(xtable( surveillance:::functionTable( class = "epidataCS", functions = list( Convert = c("epidataCS2sts"), Extract = c("getSourceDists"))), caption="Generic and \\textit{non-generic} functions applicable to \\class{epidataCS} objects.", label="tab:methods:epidataCS" ), include.rownames = FALSE) @ Printing an \class{epidataCS} object presents some metadata and the first \Sexpr{formals(surveillance:::print.epidataCS)[["n"]]} events by default: <>= imdepi @ During conversion to \class{epidataCS}, the last three columns \code{BLOCK} (time interval index), \code{start} and \code{popdensity} have been merged from the checked \code{stgrid} to the \code{events} data frame. The event marks including time and location can be extracted in a standard data frame by \code{marks(imdepi)} -- inspired by package \CRANpkg{spatstat} -- and this is summarized by \code{summary(imdepi)}. <>= (simdepi <- summary(imdepi)) @ The number of potential sources of infection per event (denoted \texttt{|.sources|} in the above output) is additionally summarized. It is determined by the events' maximum ranges of interaction \code{eps.t} and \code{eps.s}. The event-specific set of potential sources is stored in the (hidden) list \code{imdepi$events$.sources} (events are referenced by row index), and the event-specific numbers of potential sources are stored in the summarized object as \code{simdepi$nSources}. A simple plot of the number of infectives as a function of time (Figure~\ref{fig:imdepi_stepfun}) %determined by the event times and infectious periods can be obtained by the step function converter: <>= par(mar = c(5, 5, 1, 1), las = 1) plot(as.stepfun(imdepi), xlim = summary(imdepi)$timeRange, xaxs = "i", xlab = "Time [days]", ylab = "Current number of infectives", main = "") #axis(1, at = 2557, labels = "T", font = 2, tcl = -0.3, mgp = c(3, 0.3, 0)) @ \pagebreak[1] The \code{plot}-method for \class{epidataCS} offers aggregation of the events over time or space: <>= par(las = 1) plot(imdepi, "time", col = c("indianred", "darkblue"), ylim = c(0, 20)) par(mar = c(0, 0, 0, 0)) plot(imdepi, "space", lwd = 2, points.args = list(pch = c(1, 19), col = c("indianred", "darkblue"))) layout.scalebar(imdepi$W, scale = 100, labels = c("0", "100 km"), plot = TRUE) @ \pagebreak[1] The time-series plot (Figure~\ref{fig:imdepi_plot-1}) shows the monthly aggregated number of cases by finetype in a stacked histogram as well as each type's cumulative number over time. The spatial plot (Figure~\ref{fig:imdepi_plot-2}) shows the observation window \code{W} with the locations of all cases (by type), where the areas of the points are proportional to the number of cases at the respective location. Additional shading by the population is possible and exemplified in \code{help("plot.epidataCS")}. %The above static plots do not capture the space-time dynamics of epidemic spread. An animation may provide additional insight and can be produced by the corresponding \code{animate}-method. For instance, to look at the first year of the B-type in a weekly sequence of snapshots in a web browser (using facilities of the \CRANpkg{animation} package of \citealp{R:animation}): <>= animation::saveHTML( animate(subset(imdepi, type == "B"), interval = c(0, 365), time.spacing = 7), nmax = Inf, interval = 0.2, loop = FALSE, title = "First year of type B") @ Selecting events from \class{epidataCS} as for the animation above is enabled by the \code{[}- and \code{subset}-methods, which return a new \class{epidataCS} object containing only the selected \code{events}. A limited data sampling resolution may lead to tied event times or locations, which are in conflict with a continuous spatio-temporal point process model. For instance, a temporal residual analysis would suggest model deficiencies \citep[Figure 4]{meyer.etal2011}, and a power-law kernel for spatial interaction may diverge if there are events with zero distance to potential source events \citep{meyer.held2013}. The function \code{untie} breaks ties by random shifts. This has already been applied to the event \emph{times} in the provided \code{imdepi} data by subtracting a U$(0,1)$-distributed random number from the original dates. The event \emph{coordinates} in the IMD data are subject to interval censoring at the level of Germany's postcode regions. A possible replacement for the given centroids would thus be a random location within the corresponding postcode area. Lacking a suitable shapefile, \citet{meyer.held2013} shifted all locations by a random vector with length up to half the observed minimum spatial separation: <>= eventDists <- dist(coordinates(imdepi$events)) minsep <- min(eventDists[eventDists > 0]) set.seed(321) imdepi_untied <- untie(imdepi, amount = list(s = minsep / 2)) @ Note that random tie-breaking requires sensitivity analyses as discussed by \citet{meyer.held2013}, but these are skipped here for the sake of brevity. The \code{update}-method is useful to change the values of the maximum interaction ranges \code{eps.t} and \code{eps.s}, since it takes care of the necessary updates of the hidden auxiliary variables in an \class{epidataCS} object. For unbounded spatial interaction: <>= imdepi_untied_infeps <- update(imdepi_untied, eps.s = Inf) @ Last but not least, \class{epidataCS} can be aggregated to \class{epidata} (from \code{vignette("twinSIR")}) or \class{sts} (from \code{vignette("hhh4_spacetime")}). The method \code{as.epidata.epidataCS} aggregates events by region (\code{tile}), and the function \code{epidataCS2sts} yields counts by region and time interval. The latter could be analyzed by an areal time-series model such as \code{hhh4} (see \code{vignette("hhh4\_spacetime")}). We can also use \class{sts} visualizations, e.g.\ (Figure~\ref{fig:imdsts_plot}): <>= imdsts <- epidataCS2sts(imdepi, freq = 12, start = c(2002, 1), tiles = districtsD, neighbourhood = NULL) # skip adjacency matrix (needs spdep) par(las = 1, lab = c(7,7,7), mar = c(5,5,1,1)) plot(imdsts, type = observed ~ time) plot(imdsts, type = observed ~ unit, population = districtsD$POPULATION / 100000) @ \section{Modeling and inference} \label{sec:twinstim:fit} Having prepared the data as an object of class \class{epidataCS}, the function \code{twinstim} can be used to perform likelihood inference for conditional intensity models of the form~\eqref{eqn:twinstim}. The main arguments for \code{twinstim} are the formulae of the \code{endemic} and \code{epidemic} linear predictors ($\nu_{[\bm{s}][t]} = \exp$(\code{endemic}) and $\eta_j = \exp$(\code{epidemic})), and the spatial and temporal interaction functions \code{siaf} ($f$) and \code{tiaf} ($g$), respectively. Both formulae are parsed internally using the standard \code{model.frame} toolbox from package \pkg{stats} and thus can handle factor variables and interaction terms. While the \code{endemic} linear predictor incorporates %time-dependent and/or area-level covariates from \code{stgrid}, %% and in the disease mapping context usually contains at least the population density as a multiplicative offset, i.e., %% \code{endemic = ~offset(log(popdensity))}. There can be additional effects of time, %% which are functions of the variable \code{start} from \code{stgrid}, %% or effects of, e.g., socio-demographic and ecological variables. the \code{epidemic} formula may use both \code{stgrid} variables and event marks to be associated with the force of infection. %% For instance, \code{epidemic = ~log(popdensity) + type} corresponds to %% $\eta_j = \rho_{[\bm{s}_j]}^{\gamma_{\rho}} \exp(\gamma_0 + \gamma_C \ind(k_j=C))$, %% which models different infectivity of the event types, and scales %% with population density (a grid-based covariate) to reflect higher %% contact rates and thus infectivity in more densely populated regions. For the interaction functions, several alternatives are predefined as listed in Table~\ref{tab:iafs}. They are applicable out-of-the-box and illustrated as part of the following modeling exercise for the IMD data. Own interaction functions can also be implemented following the structure described in \code{help("siaf")} and \code{help("tiaf")}, respectively. <>= twinstim_iafs <- suppressWarnings( cbind("Spatial (\\code{siaf.*})" = ls(pattern="^siaf\\.", pos="package:surveillance"), "Temporal (\\code{tiaf.*})" = ls(pattern="^tiaf\\.", pos="package:surveillance")) ) twinstim_iafs <- apply(twinstim_iafs, 2, function (x) { is.na(x) <- duplicated(x) x }) print(xtable(substring(twinstim_iafs, 6), label="tab:iafs", caption="Predefined spatial and temporal interaction functions."), include.rownames=FALSE, sanitize.text.function=function(x) paste0("\\code{", x, "}"), sanitize.colnames.function=identity, sanitize.rownames.function=identity) @ \subsection{Basic example} To illustrate statistical inference with \code{twinstim}, we will estimate several models for the simplified and ``untied'' IMD data presented in Section~\ref{sec:twinstim:data}. In the endemic component, we include the district-specific population density as a multiplicative offset, a (centered) time trend, and a sinusoidal wave of frequency $2\pi/365$ to capture seasonality, where the \code{start} variable from \code{stgrid} measures time: <>= (endemic <- addSeason2formula(~offset(log(popdensity)) + I(start / 365 - 3.5), period = 365, timevar = "start")) @ See \citet[Section~2.2]{held.paul2012} for how such sine/cosine terms reflect seasonality. Because of the aforementioned integrations in the log-likelihood~\eqref{eqn:twinstim:loglik}, it is advisable to first fit an endemic-only model to obtain reasonable start values for more complex epidemic models: <>= imdfit_endemic <- twinstim(endemic = endemic, epidemic = ~0, data = imdepi_untied, subset = !is.na(agegrp)) @ We exclude the single case with unknown age group from this analysis since we will later estimate an effect of the age group on the force of infection. Many of the standard functions to access model fits in \proglang{R} are also implemented for \class{twinstim} fits (see Table~\ref{tab:methods:twinstim}). For example, we can produce the usual model summary: <>= summary(imdfit_endemic) @ Because of the aforementioned equivalence of the endemic component with a Poisson regression model, the coefficients can be interpreted as log rate ratios in the usual way. For instance, the endemic rate is estimated to decrease by \code{1 - exp(coef(imdfit_endemic)[2])} $=$ \Sexpr{round(100*(1-exp(coef(imdfit_endemic)[2])),1)}\% per year. Coefficient correlations can be retrieved via the argument \code{correlation = TRUE} in the \code{summary} call just like for \code{summary.glm}, or via \code{cov2cor(vcov(imdfit_endemic))}. <>= print(xtable( surveillance:::functionTable( class = "twinstim", functions = list( Display = c("iafplot", "checkResidualProcess"), Extract = c("intensity.twinstim", "simpleR0"), Modify = c("stepComponent"), Other = c("epitest"))), caption="Generic and \\textit{non-generic} functions applicable to \\class{twinstim} objects. Note that there is no need for specific \\code{coef}, \\code{confint}, \\code{AIC} or \\code{BIC} methods, since the respective default methods from package \\pkg{stats} apply outright.", label="tab:methods:twinstim" ), include.rownames = FALSE) @ We now update the endemic model to take additional spatio-temporal dependence between events into account. Infectivity shall depend on the meningococcal finetype and the age group of the patient, and is assumed to be constant over time (default), $g(t)=\ind_{(0,30]}(t)$, with a Gaussian distance-decay $f(x) = \exp\left\{-x^2/(2 \sigma^2)\right\}$. This model was originally selected by \citet{meyer.etal2011} and can be fitted as follows: <>= imdfit_Gaussian <- update(imdfit_endemic, epidemic = ~type + agegrp, siaf = siaf.gaussian(), cores = 2 * (.Platform$OS.type == "unix")) @ On Unix-alikes, the numerical integrations of $f(\norm{\bm{s}})$ in the log-likelihood and $\frac{\partial f(\norm{\bm{s}})}{\partial \log\sigma}$ in the score function (note that $\sigma$ is estimated on the log-scale) can be performed in parallel via %the ``multicore'' functions \code{mclapply} \textit{et al.}\ from the base package \pkg{parallel}, here with \code{cores = 2} processes. Table~\ref{tab:imdfit_Gaussian} shows the output of \code{twinstim}'s \code{xtable} method \citep{R:xtable} applied to the above model fit, providing a table of estimated rate ratios for the endemic and epidemic effects. The alternative \code{toLatex} method simply translates the \code{summary} table of coefficients to \LaTeX\ without \code{exp}-transformation. On the subject-matter level, we can conclude from Table~\ref{tab:imdfit_Gaussian} that the meningococcal finetype of serogroup~C is less than half as infectious as the B-type, and that patients in the age group 3 to 18 years are estimated to cause twice as many secondary infections as infants aged 0 to 2 years. <>= print(xtable(imdfit_Gaussian, caption="Estimated rate ratios (RR) and associated Wald confidence intervals (CI) for endemic (\\code{h.}) and epidemic (\\code{e.}) terms. This table was generated by \\code{xtable(imdfit\\_Gaussian)}.", label="tab:imdfit_Gaussian"), sanitize.text.function=NULL, sanitize.colnames.function=NULL, sanitize.rownames.function=function(x) paste0("\\code{", x, "}")) @ \subsection{Model-based effective reproduction numbers} The event-specific reproduction numbers~\eqref{eqn:R0:twinstim} can be extracted from fitted \class{twinstim} objects via the \code{R0} method. For the above IMD model, we obtain the following mean numbers of secondary infections by finetype: <<>>= R0_events <- R0(imdfit_Gaussian) tapply(R0_events, marks(imdepi_untied)[names(R0_events), "type"], mean) @ Confidence intervals %for the estimated reproduction numbers $\hat\mu_j$ can be obtained via Monte Carlo simulation, where Equation~\ref{eqn:R0:twinstim} is repeatedly evaluated with parameters sampled from the asymptotic multivariate normal distribution of the maximum likelihood estimate. For this purpose, the \code{R0}-method takes an argument \code{newcoef}, which is exemplified in \code{help("R0")}. %% Note that except for (piecewise) constant $f$, computing confidence intervals for %% $\hat\mu_j$ takes a considerable amount of time since the integrals over the %% polygons $\bm{R}_j$ have to be solved numerically for each new set of parameters. \subsection{Interaction functions} <>= imdfit_exponential <- update(imdfit_Gaussian, siaf = siaf.exponential()) @ <>= imdfit_powerlaw <- update(imdfit_Gaussian, siaf = siaf.powerlaw(), data = imdepi_untied_infeps, start = c("e.(Intercept)" = -6.2, "e.siaf.1" = 1.5, "e.siaf.2" = 0.9)) @ <>= imdfit_step4 <- update(imdfit_Gaussian, siaf = siaf.step(exp(1:4 * log(100) / 5), maxRange = 100)) @ <>= save(imdfit_Gaussian, imdfit_exponential, imdfit_powerlaw, imdfit_step4, file = "twinstim-cache.RData", compress = "xz") @ Figure~\ref{fig:imdfit_siafs} shows several estimated spatial interaction functions, which can be plotted by, e.g., \code{plot(imdfit_Gaussian, "siaf")}. <>= par(mar = c(5,5,1,1)) set.seed(2) # Monte-Carlo confidence intervals plot(imdfit_Gaussian, "siaf", xlim=c(0,42), ylim=c(0,5e-5), lty=c(1,3), xlab = expression("Distance " * x * " from host [km]")) plot(imdfit_exponential, "siaf", add=TRUE, col.estimate=5, lty = c(5,3)) plot(imdfit_powerlaw, "siaf", add=TRUE, col.estimate=4, lty=c(2,3)) plot(imdfit_step4, "siaf", add=TRUE, col.estimate=3, lty=c(4,3)) legend("topright", legend=c("Power law", "Exponential", "Gaussian", "Step (df=4)"), col=c(4,5,2,3), lty=c(2,5,1,4), lwd=3, bty="n") @ The estimated standard deviation $\hat\sigma$ of the Gaussian kernel is: <<>>= exp(cbind("Estimate" = coef(imdfit_Gaussian)["e.siaf.1"], confint(imdfit_Gaussian, parm = "e.siaf.1"))) @ \citet{meyer.held2013} found that a power-law decay of spatial interaction more appropriately describes the spread of human infectious diseases. A power-law kernel concentrates on short-range interaction, but also exhibits a heavier tail reflecting occasional transmission over large distances. %This result is supported by the power-law distribution of short-time human %travel \citep{brockmann.etal2006}, which is an important driver of epidemic spread. To estimate the power law $f(x) = (x+\sigma)^{-d}$, we use the prepared \code{eps.s = Inf} version of the \class{epidataCS} object, and update the model as follows: <>= <> @ To reduce the runtime of this example, we specified convenient \code{start} values for some parameters. The estimated parameters $(\hat\sigma, \hat d)$ are: <<>>= exp(cbind("Estimate" = coef(imdfit_powerlaw)[c("e.siaf.1", "e.siaf.2")], confint(imdfit_powerlaw, parm = c("e.siaf.1", "e.siaf.2")))) @ Sometimes $\sigma$ is difficult to estimate, and also in this example, its confidence interval is relatively large. The one-parameter version \code{siaf.powerlaw1} can be used to estimate a power-law decay with fixed $\sigma = 1$. A more common option is the exponential kernel $f(x) = \exp(-x/\sigma)$: <>= <> @ Table~\ref{tab:iafs} also lists the step function kernel as an alternative, which is particularly useful for two reasons. First, it is a more flexible approach since it estimates interaction between the given knots without assuming an overall functional form. Second, the spatial integrals in the log-likelihood can be computed analytically for the step function kernel, which therefore offers a quick estimate of spatial interaction. We update the Gaussian model to use four steps at log-equidistant knots up to an interaction range of 100 km: <>= <> @ Figure~\ref{fig:imdfit_siafs} suggests that the estimated step function is in line with the power law. Note that suitable knots for the step function could also be derived from quantiles of the observed distances between events and their potential source events, e.g.: <<>>= quantile(getSourceDists(imdepi_untied_infeps, "space"), c(1,2,4,8)/100) @ For the temporal interaction function $g(t)$, model updates and plots are similarly possible, e.g., using \code{update(imdfit_Gaussian, tiaf = tiaf.exponential())}. However, the events in the IMD data are too rare to infer the time-course of infectivity with confidence. <>= local({ nSources <- sapply(levels(imdepi$events$type), function (.type) { mean(summary(subset(imdepi_untied_infeps, type==.type))$nSources) }) structure( paste("Specifically, there are only", paste0(round(nSources,1), " (", names(nSources), ")", collapse=" and "), "cases on average within the preceding 30 days", "(potential sources of infection)."), class="Latex") }) @ \subsection{Model selection} <>= AIC(imdfit_endemic, imdfit_Gaussian, imdfit_exponential, imdfit_powerlaw, imdfit_step4) @ Akaike's Information Criterion (AIC) suggests superiority of the power-law vs.\ the exponential, Gaussian, and endemic-only models. The more flexible step function yields the best AIC value, but its shape strongly depends on the chosen knots and is not guaranteed to be monotonically decreasing. The function \code{stepComponent} -- a wrapper around the \code{step} function from \pkg{stats} -- can be used to perform AIC-based stepwise selection within a given model component. <>= ## Example of AIC-based stepwise selection of the endemic model imdfit_endemic_sel <- stepComponent(imdfit_endemic, component = "endemic") ## -> none of the endemic predictors is removed from the model @ \subsection{Model diagnostics} The element \code{"fittedComponents"} of a \class{twinstim} object contains the endemic and epidemic values of the estimated intensity at each event occurrence. However, plots of the conditional intensity (and its components) as a function of location or time provide more insight into the fitted process. Evaluation of \code{intensity.twinstim} requires the model environment to be stored with the fit. By default, \code{model = FALSE} in \code{twinstim}, but if the data are still available, the model environment can also be added afterwards using the convenient \code{update} method: <>= imdfit_powerlaw <- update(imdfit_powerlaw, model = TRUE) @ Figure~\ref{fig:imdfit_powerlaw_intensityplot_time} shows an \code{intensityplot} of the fitted ``ground'' intensity $\sum_{k=1}^2 \int_{\bm{W}} \hat\lambda(\bm{s},t,k) \dif \bm{s}$: %aggregated over both event types: <>= intensityplot(imdfit_powerlaw, which = "total", aggregate = "time", types = 1:2) @ <>= par(mar = c(5,5,1,1), las = 1) intensity_endprop <- intensityplot(imdfit_powerlaw, aggregate="time", which="endemic proportion", plot=FALSE) intensity_total <- intensityplot(imdfit_powerlaw, aggregate="time", which="total", tgrid=501, lwd=2, xlab="Time [days]", ylab="Intensity") curve(intensity_endprop(x) * intensity_total(x), add=TRUE, col=2, lwd=2, n=501) #curve(intensity_endprop(x), add=TRUE, col=2, lty=2, n=501) text(2500, 0.36, labels="total", col=1, pos=2, font=2) text(2500, 0.08, labels="endemic", col=2, pos=2, font=2) @ %% Note that this represents a realization of a stochastic process, since it %% depends on the occurred events. The estimated endemic intensity component has also been added to the plot. It exhibits strong seasonality and a slow negative trend. The proportion of the endemic intensity is rather constant along time since no major outbreaks occurred. This proportion can be visualized separately by specifying \code{which = "endemic proportion"} in the above call. <>= meanepiprop <- integrate(intensityplot(imdfit_powerlaw, which="epidemic proportion"), 50, 2450, subdivisions=2000, rel.tol=1e-3)$value / 2400 @ Spatial \code{intensityplot}s as in Figure~\ref{fig:imdfit_powerlaw_intensityplot_space} can be produced via \code{aggregate = "space"} and require a geographic representation of \code{stgrid}. The epidemic proportion is naturally high around clusters of cases and even more so if the population density is low. %% The function \code{epitest} offers a model-based global test for epidemicity, %% while \code{knox} and \code{stKtest} implement related classical approaches %% \citep{meyer.etal2015}. <>= for (.type in 1:2) { print(intensityplot(imdfit_powerlaw, aggregate="space", which="epidemic proportion", types=.type, tiles=districtsD, sgrid=1000, # scales=list(draw=TRUE), # default (sp>=2 uses 'sf', with a fallback) xlab="x [km]", ylab="y [km]", at=seq(0,1,by=0.1), col.regions=rev(hcl.colors(10,"Reds")), colorkey=list(title="Epidemic proportion"))) } @ Another diagnostic tool is the function \code{checkResidualProcess} (Figure~\ref{fig:imdfit_checkResidualProcess}), which transforms the temporal ``residual process'' in such a way that it exhibits a uniform distribution and lacks serial correlation if the fitted model describes the true CIF well \citep[see][Section~3.3]{ogata1988}. % more recent work: \citet{clements.etal2011} <>= par(mar = c(5, 5, 1, 1)) checkResidualProcess(imdfit_powerlaw) @ \section{Simulation} \label{sec:twinstim:simulation} %% Simulations from the fitted model are also useful to investigate the %% goodness of fit. To identify regions with unexpected IMD dynamics, \citet{meyer.etal2011} compared the observed numbers of cases by district to the respective 2.5\% and 97.5\% quantiles of 100 simulations from the selected model. Furthermore, simulations allow us to investigate the stochastic volatility of the endemic-epidemic process, to obtain probabilistic forecasts, and to perform parametric bootstrap of the spatio-temporal point pattern. The simulation algorithm we apply is described in \citet[Section 4]{meyer.etal2011}. It requires a geographic representation of the \code{stgrid}, as well as functionality for sampling locations from the spatial kernel $f_2(\bm{s}) := f(\norm{\bm{s}})$. This is implemented for all predefined spatial interaction functions listed in Table~\ref{tab:iafs}. %For instance for the %power-law kernel, we pass via polar coordinates (with density then proportional %to $rf(r)$) %, a function also involved in the efficient cubature of % %$f_2(\bm{s})$ via Green's theorem) %and the inverse transformation method with numerical root finding for the %quantiles. Event marks are by default sampled from their respective empirical distribution in the original data. %but a customized generator can be supplied as argument \code{rmarks}. The following code runs \emph{a single} simulation over the last year based on the estimated power-law model: <>= imdsim <- simulate(imdfit_powerlaw, nsim = 1, seed = 1, t0 = 2191, T = 2555, data = imdepi_untied_infeps, tiles = districtsD) @ This yields an object of the class \class{simEpidataCS}, which extends \class{epidataCS}. It carries additional components from the generating model to enable an \code{R0}-method and \code{intensityplot}s for simulated data. %All methods for \class{epidataCS} are applicable. %% The result is simplified in that only the \code{events} instead of a full %% \class{epidataCS} object are retained from every run to save memory and %% computation time. All other components, which do not vary between simulations, %% e.g., the \code{stgrid}, are only stored from the first run. %% There is a \code{[[}-method for such \class{simEpidataCSlist}s in order to %% extract single simulations as full \class{simEpidataCS} objects from the %% simplified structure. %Extracting a single simulation (e.g., \code{imdsims[[1]]}) Figure~\ref{fig:imdsim_plot} shows the cumulative number of cases from the simulation appended to the first six years of data. <>= .t0 <- imdsim$timeRange[1] .cumoffset <- c(table(subset(imdepi, time < .t0)$events$type)) par(mar = c(5,5,1,1), las = 1) plot(imdepi, ylim = c(0, 20), col = c("indianred", "darkblue"), subset = time < .t0, cumulative = list(maxat = 336), xlab = "Time [days]") plot(imdsim, add = TRUE, legend.types = FALSE, col = adjustcolor(c("indianred", "darkblue"), alpha.f = 0.5), subset = !is.na(source), # exclude events of the prehistory cumulative = list(offset = .cumoffset, maxat = 336, axis = FALSE), border = NA, density = 0) # no histogram for simulations plot(imdepi, add = TRUE, legend.types = FALSE, col = 1, subset = time >= .t0, cumulative = list(offset = .cumoffset, maxat = 336, axis = FALSE), border = NA, density = 0) # no histogram for the last year's data abline(v = .t0, lty = 2, lwd = 2) @ %% Because we have started simulation at time \code{t0 = 0}, %% no events from \code{data} have been used as the prehistory, i.e., %% the first simulated event is necessarily driven by the endemic model component. A special feature of such simulated epidemics is that the source of each event is known: <>= table(imdsim$events$source > 0, exclude = NULL) @ The stored \code{source} value is 0 for endemic events, \code{NA} for events of the prehistory but still infective at \code{t0}, and otherwise corresponds to the row index of the infective source. %% Averaged over all 30 simulations, the proportion of events triggered by %% previous events is %% Sexpr{mean(sapply(imdsims$eventsList, function(x) mean(x$source > 0, na.rm = TRUE)))}. %-------------- % BIBLIOGRAPHY %-------------- <>= ## create automatic references for R packages knitr::write_bib( # produces UTF-8 c("memoise", "sp", "polyclip", "xtable"), file = "twinstim-R.bib", tweak = FALSE, prefix = "R:") @ \bibliography{references,twinstim-R} \end{document} surveillance/inst/doc/twinSIR.R0000644000176200001440000000741314615167565016177 0ustar liggesusers## ----include = FALSE--------------------------------------------------------------- ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("twinSIR-cache.RData")) if (!COMPUTE) load("twinSIR-cache.RData", verbose = TRUE) ## ----hagelloch.df------------------------------------------------------------------ data("hagelloch") head(hagelloch.df, n = 5) ## ----hagelloch--------------------------------------------------------------------- hagelloch <- as.epidata(hagelloch.df, t0 = 0, tI.col = "tI", tR.col = "tR", id.col = "PN", coords.cols = c("x.loc", "y.loc"), f = list(household = function(u) u == 0, nothousehold = function(u) u > 0), w = list(c1 = function (CL.i, CL.j) CL.i == "1st class" & CL.j == CL.i, c2 = function (CL.i, CL.j) CL.i == "2nd class" & CL.j == CL.i), keep.cols = c("SEX", "AGE", "CL")) ## ----hagelloch_show, warning=FALSE------------------------------------------------- head(hagelloch, n = 5) ## ----hagelloch_plot, echo=2, fig.cap="Evolution of the 1861 Hagelloch measles epidemic in terms of the numbers of susceptible, infectious, and recovered children. The bottom \\code{rug} marks the infection times \\code{tI}.", fig.pos="!h"---- par(mar = c(5, 5, 1, 1)) plot(hagelloch, xlab = "Time [days]") ## ----hagelloch_households, fig.cap="Spatial locations of the Hagelloch households. The size of each dot is proportional to the number of children in the household.", fig.pos="ht", echo=-1---- par(mar = c(5, 5, 1, 1)) hagelloch_coords <- summary(hagelloch)$coordinates plot(hagelloch_coords, xlab = "x [m]", ylab = "y [m]", pch = 15, asp = 1, cex = sqrt(multiplicity(hagelloch_coords))) legend(x = "topleft", pch = 15, legend = c(1, 4, 8), pt.cex = sqrt(c(1, 4, 8)), title = "Household size") ## ----hagellochFit, results='hide'-------------------------------------------------- hagellochFit <- twinSIR(~household + c1 + c2 + nothousehold, data = hagelloch) ## ----hagellochFit_summary_echo, eval=FALSE----------------------------------------- # set.seed(1) # summary(hagellochFit) ## ----hagellochFit_confint---------------------------------------------------------- exp(confint(hagellochFit, parm = "cox(logbaseline)")) ## ----hagellochFit_profile, results='hide', eval=COMPUTE---------------------------- # prof <- profile(hagellochFit, # list(c(match("c1", names(coef(hagellochFit))), NA, NA, 25), # c(match("c2", names(coef(hagellochFit))), NA, NA, 25))) ## ---------------------------------------------------------------------------------- prof$ci.hl ## ----hagellochFit_profile_plot, fig.cap="Normalized log-likelihood for $\\alpha_{c1}$ and $\\alpha_{c2}$ when fitting the \\code{twinSIR} model formulated in Equation~\\eqref{eqn:twinSIR:hagelloch} to the Hagelloch data.", fig.pos="ht", fig.height=4.4---- plot(prof) ## ----hagellochFit_plot, echo=2, fig.width=4.5, fig.height=4.5, out.width="0.49\\linewidth", fig.subcap=c("Epidemic proportion.","Transformed residuals."), fig.cap="Diagnostic plots for the \\code{twinSIR} model formulated in Equation~\\ref{eqn:twinSIR:hagelloch}.", fig.pos="htb"---- par(mar = c(5, 5, 1, 1)) plot(hagellochFit, which = "epidemic proportion", xlab = "time [days]") checkResidualProcess(hagellochFit, plot = 1) ## ----hagellochFit_fstep, results='hide'-------------------------------------------- knots <- c(100, 200) fstep <- list( B1 = function(D) D > 0 & D < knots[1], B2 = function(D) D >= knots[1] & D < knots[2], B3 = function(D) D >= knots[2]) hagellochFit_fstep <- twinSIR( ~household + c1 + c2 + B1 + B2 + B3, data = update(hagelloch, f = fstep)) ## ----hagellochFit_AIC-------------------------------------------------------------- set.seed(1) AIC(hagellochFit, hagellochFit_fstep) surveillance/inst/doc/hhh4.Rnw0000644000176200001440000010307114516236515016025 0ustar liggesusers%\VignetteIndexEntry{hhh4: An endemic-epidemic modelling framework for infectious disease counts} %\VignetteDepends{surveillance, Matrix} \documentclass[a4paper,11pt]{article} \usepackage[T1]{fontenc} \usepackage[english]{babel} \usepackage{graphicx} \usepackage{color} \usepackage{natbib} \usepackage{lmodern} \usepackage{bm} \usepackage{amsmath} \usepackage{amsfonts,amssymb} \setlength{\parindent}{0pt} \setcounter{secnumdepth}{1} \newcommand{\Po}{\operatorname{Po}} \newcommand{\NegBin}{\operatorname{NegBin}} \newcommand{\N}{\mathcal{N}} \newcommand{\pkg}[1]{{\fontseries{b}\selectfont #1}} \newcommand{\surveillance}{\pkg{surveillance}} \newcommand{\code}[1]{\texttt{#1}} \newcommand{\hhh}{\texttt{hhh4}} \newcommand{\R}{\textsf{R}} \newcommand{\sts}{\texttt{sts}} \newcommand{\example}[1]{\subsubsection*{Example: #1}} %%% Meta data \usepackage{hyperref} \hypersetup{ pdfauthor = {Michaela Paul and Sebastian Meyer}, pdftitle = {'hhh4': An endemic-epidemic modelling framework for infectious disease counts}, pdfsubject = {R package 'surveillance'} } \newcommand{\email}[1]{\href{mailto:#1}{\normalfont\texttt{#1}}} \title{\code{hhh4}: An endemic-epidemic modelling framework for infectious disease counts} \author{ Michaela Paul and Sebastian Meyer\thanks{Author of correspondence: \email{seb.meyer@fau.de} (new affiliation)}\\ Epidemiology, Biostatistics and Prevention Institute\\ University of Zurich, Zurich, Switzerland } \date{8 February 2016} %%% Sweave \usepackage{Sweave} \SweaveOpts{prefix.string=plots/hhh4, keep.source=T, strip.white=true} \definecolor{Sinput}{rgb}{0,0,0.56} \DefineVerbatimEnvironment{Sinput}{Verbatim}{formatcom={\color{Sinput}},fontshape=sl,fontsize=\footnotesize} \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontshape=sl,fontsize=\footnotesize} %%% Initial R code <>= library("surveillance") options(width=75) ## create directory for plots dir.create("plots", showWarnings=FALSE) ###################################################### ## Do we need to compute or can we just fetch results? ###################################################### compute <- !file.exists("hhh4-cache.RData") message("Doing computations: ", compute) if(!compute) load("hhh4-cache.RData") @ \begin{document} \maketitle \begin{abstract} \noindent The \R\ package \surveillance\ provides tools for the visualization, modelling and monitoring of epidemic phenomena. This vignette is concerned with the \hhh\ modelling framework for univariate and multivariate time series of infectious disease counts proposed by \citet{held-etal-2005}, and further extended by \citet{paul-etal-2008}, \citet{paul-held-2011}, \citet{held.paul2012}, and \citet{meyer.held2013}. The implementation is illustrated using several built-in surveillance data sets. The special case of \emph{spatio-temporal} \hhh\ models is also covered in \citet[Section~5]{meyer.etal2014}, which is available as the extra \verb+vignette("hhh4_spacetime")+. \end{abstract} \section{Introduction}\label{sec:intro} To meet the threats of infectious diseases, many countries have established surveillance systems for the reporting of various infectious diseases. The systematic and standardized reporting at a national and regional level aims to recognize all outbreaks quickly, even when aberrant cases are dispersed in space. Traditionally, notification data, i.e.\ counts of cases confirmed according to a specific definition and reported daily, weekly or monthly on a regional or national level, are used for surveillance purposes. The \R-package \surveillance\ provides functionality for the retrospective modelling and prospective aberration detection in the resulting surveillance time series. Overviews of the outbreak detection functionality of \surveillance\ are given by \citet{hoehle-mazick-2010} and \citet{salmon.etal2014}. This document illustrates the functionality of the function \hhh\ for the modelling of univariate and multivariate time series of infectious disease counts. It is part of the \surveillance\ package as of version 1.3. The remainder of this vignette unfolds as follows: Section~\ref{sec:data} introduces the S4 class data structure used to store surveillance time series data within the package. Access and visualization methods are outlined by means of built-in data sets. In Section~\ref{sec:model}, the statistical modelling approach by \citet{held-etal-2005} and further model extensions are described. After the general function call and arguments are shown, the detailed usage of \hhh\ is demonstrated in Section~\ref{sec:hhh} using data introduced in Section~\ref{sec:data}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Surveillance data}\label{sec:data} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Denote by $\{y_{it}; i=1,\ldots,I,t=1,\ldots,T\}$ the multivariate time series of disease counts for a specific partition of gender, age and location. Here, $T$ denotes the length of the time series and $I$ denotes the number of units (e.g\ geographical regions or age groups) being monitored. Such data are represented using objects of the S4 class \sts\ (surveillance time series). \subsection[The sts data class]{The \sts\ data class} The \sts\ class contains the $T\times I$ matrix of counts $y_{it}$ in a slot \code{observed}. An integer slot \code{epoch} denotes the time index $1\leq t \leq T$ of each row in \code{observed}. The number of observations per year, e.g.\ 52 for weekly or 12 for monthly data, is denoted by \code{freq}. Furthermore, \code{start} denotes a vector of length two containing the start of the time series as \code{c(year, epoch)}. For spatially stratified time series, the slot \code{neighbourhood} denotes an $I \times I$ adjacency matrix with elements 1 if two regions are neighbors and 0 otherwise. For map visualizations, the slot \code{map} links the multivariate time series to geographical regions stored in a \code{"SpatialPolygons"} object (package \pkg{sp}). Additionally, the slot \code{populationFrac} contains a $T\times I$ matrix representing population fractions in unit $i$ at time $t$. The \sts\ data class is also described in \citet[Section~2.1]{hoehle-mazick-2010}, \citet[Section~1.1]{salmon.etal2014}, \citet[Section~5.2]{meyer.etal2014}, and on the associated help page \code{help("sts")}. \subsection{Some example data sets} The package \surveillance\ contains a number of time series in the \code{data} directory. Most data sets originate from the SurvStat@RKI database\footnote{\url{https://survstat.rki.de}}, maintained by the Robert Koch Institute (RKI) in Germany. Selected data sets will be analyzed in Section~\ref{sec:hhh} and are introduced in the following. Note that many of the built-in datasets are stored in the S3 class data structure \mbox{\code{disProg}} used in ancient versions of the \surveillance\ package (until 2006). They can be easily converted into the new S4 \sts\ data structure using the function \code{disProg2sts}. The resulting \sts\ object can be accessed similar as standard \code{matrix} objects and allows easy temporal and spatial aggregation as will be shown in the remainder of this section. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \example{Influenza and meningococcal disease, Germany, 2001--2006} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% As a first example, the weekly number of influenza and meningococcal disease cases in Germany is considered. <>= # load data data("influMen") # convert to sts class and print basic information about the time series print(fluMen <- disProg2sts(influMen)) @ The univariate time series of meningococcal disease counts can be obtained with <>= meningo <- fluMen[, "meningococcus"] dim(meningo) @ The \code{plot} function provides ways to visualize the multivariate time series in time, space and space-time, as controlled by the \code{type} argument: \setkeys{Gin}{width=1\textwidth} <>= plot(fluMen, type = observed ~ time | unit, # type of plot (default) same.scale = FALSE, # unit-specific ylim? col = "grey") # color of bars @ See \code{help("stsplot")} for a detailed description of the plot routines. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \example{Influenza, Southern Germany, 2001--2008} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The spatio-temporal spread of influenza in the 140 Kreise (districts) of Bavaria and Baden-W\"urttemberg is analyzed using the weekly number of cases reported to the RKI~\citep{survstat-fluByBw} in the years 2001--2008. An \sts\ object containing the data is created as follows: <>= # read in observed number of cases flu.counts <- as.matrix(read.table(system.file("extdata/counts_flu_BYBW.txt", package = "surveillance"), check.names = FALSE)) @ \begin{center} \setkeys{Gin}{width=.5\textwidth} <>= # read in 0/1 adjacency matrix (1 if regions share a common border) nhood <- as.matrix(read.table(system.file("extdata/neighbourhood_BYBW.txt", package = "surveillance"), check.names = FALSE)) library("Matrix") print(image(Matrix(nhood))) @ \end{center} <>= # read in population fractions popfracs <- read.table(system.file("extdata/population_2001-12-31_BYBW.txt", package = "surveillance"), header = TRUE)$popFrac # create sts object flu <- sts(flu.counts, start = c(2001, 1), frequency = 52, population = popfracs, neighbourhood = nhood) @ These data are already included as \code{data("fluBYBW")} in \surveillance. In addition to the \sts\ object created above, \code{fluBYBW} contains a map of the administrative districts of Bavaria and Baden-W\"urttemberg. This works by specifying a \code{"SpatialPolygons"} representation of the districts as an extra argument \code{map} in the above \sts\ call. Such a \code{"SpatialPolygons"} object can be obtained from, e.g, an external shapefile using the \pkg{sf} functions \code{st\_read} followed by \code{as\_Spatial}. A map enables plots and animations of the cumulative number of cases by region. For instance, a disease incidence map of the year 2001 can be obtained as follows: \setkeys{Gin}{width=.5\textwidth} \begin{center} <>= data("fluBYBW") plot(fluBYBW[year(fluBYBW) == 2001, ], # select year 2001 type = observed ~ unit, # total counts by region population = fluBYBW@map$X31_12_01 / 100000, # per 100000 inhabitants colorkey = list(title = "Incidence [per 100'000 inhabitants]")) @ \end{center} <>= # consistency check local({ fluBYBW@map <- flu@map stopifnot(all.equal(fluBYBW, flu)) }) @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \example{Measles, Germany, 2005--2007} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The following data set contains the weekly number of measles cases in the 16 German federal states, in the years 2005--2007. These data have been analyzed by \citet{herzog-etal-2010} after aggregation into bi-weekly periods. <>= data("measlesDE") measles2w <- aggregate(measlesDE, nfreq = 26) @ \setkeys{Gin}{width=.75\textwidth} \begin{center} <>= plot(measles2w, type = observed ~ time, # aggregate counts over all units main = "Bi-weekly number of measles cases in Germany") @ \end{center} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Model formulation}\label{sec:model} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Retrospective surveillance aims to identify outbreaks and (spatio-)temporal patterns through statistical modelling. Motivated by a branching process with immigration, \citet{held-etal-2005} suggest the following model for the analysis of univariate time series of infectious disease counts $\{y_{t}; t=1,\ldots,T\}$. The counts are assumed to be Poisson distributed with conditional mean \begin{align*} \mu_{t} = \lambda y_{t-1}+ \nu_{t}, \quad(\lambda,\nu_{t}>0) \end{align*} where $\lambda$ and $\nu_t$ are unknown quantities. The mean incidence is decomposed additively into two components: an epidemic or \emph{autoregressive} component $\lambda y_{t-1}$, and an \emph{endemic} component $\nu_t$. The former should be able to capture occasional outbreaks whereas the latter explains a baseline rate of cases with stable temporal pattern. \citet{held-etal-2005} suggest the following parametric model for the endemic component: \begin{align}\label{eq:nu_t} \log(\nu_t) =\alpha + \beta t + \left\{\sum_{s=1}^S \gamma_s \sin(\omega_s t) + \delta_s \cos(\omega_s t)\right\}, \end{align} where $\alpha$ is an intercept, $\beta$ is a trend parameter, and the terms in curly brackets are used to model seasonal variation. Here, $\gamma_s$ and $\delta_s$ are unknown parameters, $S$ denotes the number of harmonics to include, and $\omega_s=2\pi s/$\code{freq} are Fourier frequencies (e.g.\ \code{freq = 52} for weekly data). For ease of interpretation, the seasonal terms in \eqref{eq:nu_t} can be written equivalently as \begin{align*} \gamma_s \sin(\omega_s t) + \delta_s \cos(\omega_s t)= A_s \sin(\omega_s t +\varphi_s) \end{align*} with amplitude $A_s=\sqrt{\gamma_s^2+\delta_s^2}$ describing the magnitude, and phase difference $\tan(\varphi_s)=\delta_s/\gamma_s$ describing the onset of the sine wave. To account for overdispersion, the Poisson model may be replaced by a negative binomial model. Then, the conditional mean $\mu_t$ remains the same but the conditional variance increases to $\mu_t (1+\mu_t \psi)$ with additional unknown overdispersion parameter $\psi>0$. The model is extended to multivariate time series $\{y_{it}\}$ in \citet{held-etal-2005} and \citet{paul-etal-2008} by including an additional \emph{neighbor-driven} component, where past cases in other (neighboring) units also enter as explanatory covariates. The conditional mean $\mu_{it}$ is then given by \begin{align} \label{eq:mu_it} \mu_{it} = \lambda y_{i,t-1} + \phi \sum_{j\neq i} w_{ji} y_{j,t-1} +e_{it} \nu_{t}, \end{align} where the unknown parameter $\phi$ quantifies the influence of other units $j$ on unit $i$, $w_{ji}$ are weights reflecting between-unit transmission and $e_{it}$ corresponds to an offset (such as population fractions at time $t$ in region $i$). A simple choice for the weights is $w_{ji}=1$ if units $j$ and $i$ are adjacent and 0 otherwise. See \citet{paul-etal-2008} for a discussion of alternative weights, and \citet{meyer.held2013} for how to estimate these weights in the spatial setting using a parametric power-law formulation based on the order of adjacency. When analyzing a specific disease observed in, say, multiple regions or several pathogens (such as influenza and meningococcal disease), the assumption of equal incidence levels or disease transmission across units is questionable. To address such heterogeneity, the unknown quantities $\lambda$, $\phi$, and $\nu_t$ in \eqref{eq:mu_it} may also depend on unit $i$. This can be done via \begin{itemize} \item unit-specific fixed parameters, e.g.\ $\log(\lambda_i)=\alpha_i$ \citep{paul-etal-2008}; \item unit-specific random effects, e.g\ $\log(\lambda_i)=\alpha_0 +a_i$, $a_i \stackrel{\text{iid}}{\sim} \N(0,\sigma^2_\lambda)$ \citep{paul-held-2011}; \item linking parameters with known (possibly time-varying) explanatory variables, e.g.\ $\log(\lambda_i)=\alpha_0 +x_i\alpha_1$ with region-specific vaccination coverage $x_i$ \citep{herzog-etal-2010}. \end{itemize} In general, the parameters of all three model components may depend on both time and unit. A call to \hhh\ fits a Poisson or negative binomial model with conditional mean \begin{align*} \mu_{it} = \lambda_{it} y_{i,t-1} + \phi_{it} \sum_{j\neq i} w_{ji} y_{j,t-1} +e_{it} \nu_{it} \end{align*} to a (multivariate) time series of counts. Here, the three unknown quantities are modelled as log-linear predictors \begin{align} \log(\lambda_{it}) &= \alpha_0 + a_i +\bm{u}_{it}^\top \bm{\alpha} \tag{\code{ar}}\\ \log(\phi_{it}) &= \beta_0 + b_i +\bm{x}_{it}^\top \bm{\beta} \tag{\code{ne}}\\ \log(\nu_{it}) &= \gamma_0 + c_i +\bm{z}_{it}^\top \bm{\gamma}\tag{\code{end}} \end{align} where $\alpha_0,\beta_0,\gamma_0$ are intercepts, $\bm{\alpha},\bm{\beta},\bm{\gamma}$ are vectors of unknown parameters corresponding to covariate vectors $\bm{u}_{it},\bm{x}_{it},\bm{z}_{it}$, and $a_i,b_i,c_i$ are random effects. For instance, model~\eqref{eq:nu_t} with $S=1$ seasonal terms may be represented as $\bm{z}_{it}=(t,\sin(2\pi/\code{freq}\;t),\cos(2\pi/\code{freq}\;t))^\top$. The stacked vector of all random effects is assumed to follow a normal distribution with mean $\bm{0}$ and covariance matrix $\bm{\Sigma}$. In applications, each of the components \code{ar}, \code{ne}, and \code{end} may be omitted in parts or as a whole. If the model does not contain random effects, standard likelihood inference can be performed. Otherwise, inference is based on penalized quasi-likelihood as described in detail in \citet{paul-held-2011}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Function call and control settings}\label{sec:hhh} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The estimation procedure is called with <>= hhh4(sts, control) @ where \code{sts} denotes a (multivariate) surveillance time series and the model is specified in the argument \code{control} in consistency with other algorithms in \surveillance. The \code{control} setting is a list of the following arguments (here with default values): <>= control = list( ar = list(f = ~ -1, # formula for log(lambda_it) offset = 1), # optional multiplicative offset ne = list(f = ~ -1, # formula for log(phi_it) offset = 1, # optional multiplicative offset weights = neighbourhood(stsObj) == 1), # (w_ji) matrix end = list(f = ~ 1, # formula for log(nu_it) offset = 1), # optional multiplicative offset e_it family = "Poisson", # Poisson or NegBin model subset = 2:nrow(stsObj), # subset of observations to be used optimizer = list(stop = list(tol = 1e-5, niter = 100), # stop rules regression = list(method = "nlminb"), # for penLogLik variance = list(method = "nlminb")), # for marLogLik verbose = FALSE, # level of progress reporting start = list(fixed = NULL, # list with initial values for fixed, random = NULL, # random, and sd.corr = NULL), # variance parameters data = list(t = epoch(stsObj)-1),# named list of covariates keep.terms = FALSE # whether to keep the model terms ) @ The first three arguments \code{ar}, \code{ne}, and \code{end} specify the model components using \code{formula} objects. By default, the counts $y_{it}$ are assumed to be Poisson distributed, but a negative binomial model can be chosen by setting \mbox{\code{family = "NegBin1"}}. By default, both the penalized and marginal log-likelihoods are maximized using the quasi-Newton algorithm available via the \R\ function \code{nlminb}. The methods from \code{optim} may also be used, e.g., \mbox{\code{optimizer = list(variance = list(method="Nelder-Mead")}} is a useful alternative for maximization of the marginal log-likelihood with respect to the variance parameters. Initial values for the fixed, random, and variance parameters can be specified in the \code{start} argument. If the model contains covariates, these have to be provided in the \code{data} argument. If a covariate does not vary across units, it may be given as a vector of length $T$. Otherwise, covariate values must be given in a matrix of size $T \times I$. In the following, the functionality of \hhh\ is demonstrated using the data sets introduced in Section~\ref{sec:data} and previously analyzed in \citet{paul-etal-2008}, \citet{paul-held-2011} and \citet{herzog-etal-2010}. Selected results are reproduced. For a thorough discussion we refer to these papers. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Univariate modelling} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% As a first example, consider the univariate time series of meningococcal infections in Germany, 01/2001--52/2006 \citep[cf.][Table~1]{paul-etal-2008}. A Poisson model without autoregression and $S=1$ seasonal term is specified as follows: <>= # specify a formula object for the endemic component ( f_S1 <- addSeason2formula(f = ~ 1, S = 1, period = 52) ) # fit the Poisson model result0 <- hhh4(meningo, control = list(end = list(f = f_S1), family = "Poisson")) summary(result0) @ To fit the corresponding negative binomial model, we can use the convenient \code{update} method: <>= result1 <- update(result0, family = "NegBin1") @ Note that the \code{update} method by default uses the parameter estimates from the original model as start values when fitting the updated model; see \code{help("update.hhh4")} for details. We can calculate Akaike's Information Criterion for the two models to check whether accounting for overdispersion is useful for these data: <<>>= AIC(result0, result1) @ Due to the default control settings with \verb|ar = list(f = ~ -1)|, the autoregressive component has been omitted in the above models. It can be included by the following model update: <>= # fit an autoregressive model result2 <- update(result1, ar = list(f = ~ 1)) @ To extract only the ML estimates and standard errors instead of a full model \code{summary}, the \code{coef} method can be used: <<>>= coef(result2, se = TRUE, # also return standard errors amplitudeShift = TRUE, # transform sine/cosine coefficients # to amplitude/shift parameters idx2Exp = TRUE) # exponentiate remaining parameters @ Here, \code{exp(ar.1)} is the autoregressive coefficient $\lambda$ and can be interpreted as the epidemic proportion of disease incidence \citep{held.paul2012}. Note that the above transformation arguments \code{amplitudeShift} and \code{idx2Exp} can also be used in the \code{summary} method. Many other standard methods are implemented for \code{"hhh4"} fits, see, e.g., \code{help("confint.hhh4")}. A plot of the fitted model components can be easily obtained: \begin{center} <>= plot(result2) @ \end{center} See the comprehensive \code{help("plot.hhh4")} for further options. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Bivariate modelling} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Now, the weekly numbers of both meningococcal disease (\textsc{MEN}) and influenza (\textsc{FLU}) cases are analyzed to investigate whether influenza infections predispose meningococcal disease \citep[cf.][Table~2]{paul-etal-2008}. This requires disease-specific parameters which are specified in the formula object with \code{fe(\ldots)}. In the following, a negative binomial model with mean \begin{align*} \binom{\mu_{\text{men},t}} {\mu_{\text{flu},t}}= \begin{pmatrix} \lambda_\text{men} & \phi \\ 0 & \lambda_\text{flu} \\ \end{pmatrix} \binom{\text{\sc men}_{t-1}}{\text{\sc flu}_{t-1}} + \binom{\nu_{\text{men},t}}{\nu_{\text{flu},t}}\,, \end{align*} where the endemic component includes $S=3$ seasonal terms for the \textsc{FLU} data and $S=1$ seasonal terms for the \textsc{MEN} data is considered. Here, $\phi$ quantifies the influence of past influenza cases on the meningococcal disease incidence. This model corresponds to the second model of Table~2 in \citet{paul-etal-2008} and is fitted as follows: <>= # no "transmission" from meningococcus to influenza neighbourhood(fluMen)["meningococcus","influenza"] <- 0 neighbourhood(fluMen) @ <>= # create formula for endemic component f.end <- addSeason2formula(f = ~ -1 + fe(1, unitSpecific = TRUE), # disease-specific intercepts S = c(3, 1), # S = 3 for flu, S = 1 for men period = 52) # specify model m <- list(ar = list(f = ~ -1 + fe(1, unitSpecific = TRUE)), ne = list(f = ~ 1, # phi, only relevant for meningococcus due to weights = neighbourhood(fluMen)), # the weight matrix end = list(f = f.end), family = "NegBinM") # disease-specific overdispersion # fit model result <- hhh4(fluMen, control = m) summary(result, idx2Exp=1:3) @ A plot of the estimated mean components can be obtained as follows: \setkeys{Gin}{width=1\textwidth} \begin{center} <>= plot(result, units = NULL, pch = 20, legend = 2, legend.args = list( legend = c("influenza-driven", "autoregressive", "endemic"))) @ \end{center} Alternatively, use the \code{decompose} argument to show the unit-specific contributions to the fitted mean: \begin{center} <>= plot(result, units = NULL, pch = 20, legend = 2, decompose = TRUE, col = c(7, 4)) @ \end{center} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Multivariate modelling} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% For disease counts observed in a large number of regions, say, (i.e.\ highly multivariate time series of counts) the use of region-specific parameters to account for regional heterogeneity is no longer feasible as estimation and identifiability problems may occur. Here we illustrate two approaches: region-specific random effects and region-specific covariates. For a more detailed illustration of areal \code{hhh4} models, see \verb+vignette("hhh4_spacetime")+, which uses \verb+data("measlesWeserEms")+ as an example. \subsubsection*{Influenza, Southern Germany, 2001--2008} \citet{paul-held-2011} propose a random effects formulation to analyze the weekly number of influenza cases in \Sexpr{ncol(fluBYBW)} districts of Southern Germany. For example, consider a model with random intercepts in the endemic component: $c_i \stackrel{iid}{\sim} \N(0,\sigma^2_\nu), i=1,\ldots,I$. Such effects are specified as: <>= f.end <- ~ -1 + ri(type = "iid", corr = "all") @ The alternative \code{type = "car"} would assume spatially correlated random effects; see \citet{paul-held-2011} for details. The argument \code{corr = "all"} allows for correlation between region-specific random effects in different components, e.g., random incidence levels $c_i$ in the endemic component and random effects $b_i$ in the neighbor-driven component. The following call to \hhh\ fits such a random effects model with linear trend and $S=3$ seasonal terms in the endemic component, a fixed autoregressive parameter $\lambda$, and first-order transmission weights $w_{ji}=\mathbb{I}(j\sim i)$ -- normalized such that $\sum_i w_{ji} = 1$ for all rows $j$ -- to the influenza data \citep[cf.][Table~3, model~B2]{paul-held-2011}. <>= # endemic component: iid random effects, linear trend, S=3 seasonal terms f.end <- addSeason2formula(f = ~ -1 + ri(type="iid", corr="all") + I((t-208)/100), S = 3, period = 52) # model specification model.B2 <- list(ar = list(f = ~ 1), ne = list(f = ~ -1 + ri(type="iid", corr="all"), weights = neighbourhood(fluBYBW), normalize = TRUE), # all(rowSums(weights) == 1) end = list(f = f.end, offset = population(fluBYBW)), family = "NegBin1", verbose = TRUE, optimizer = list(variance = list(method = "Nelder-Mead"))) # default start values for random effects are sampled from a normal set.seed(42) @ <>= if(compute){ result.B2 <- hhh4(fluBYBW, model.B2) s.B2 <- summary(result.B2, maxEV = TRUE, idx2Exp = 1:3) #pred.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52) predfinal.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52, type = "final") meanSc.B2 <- colMeans(scores(predfinal.B2)) save(s.B2, meanSc.B2, file="hhh4-cache.RData") } @ <>= # fit the model (takes about 35 seconds) result.B2 <- hhh4(fluBYBW, model.B2) summary(result.B2, maxEV = TRUE, idx2Exp = 1:3) @ <>= s.B2 @ Model choice based on information criteria such as AIC or BIC is well explored and understood for models that correspond to fixed-effects likelihoods. However, in the presence of random effects their use can be problematic. For model selection in time series models, the comparison of successive one-step-ahead forecasts with the actually observed data provides a natural alternative. In this context, \citet{gneiting-raftery-2007} recommend the use of strictly proper scoring rules, such as the logarithmic score (logs) or the ranked probability score (rps). See \citet{czado-etal-2009} and \citet{paul-held-2011} for further details. One-step-ahead predictions for the last 2 years for model B2 could be obtained as follows: <>= pred.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52) @ However, computing ``rolling'' one-step-ahead predictions from a random effects model is computationally expensive, since the model needs to be refitted at every time point. The above call would take approximately 45 minutes! So for the purpose of this vignette, we use the fitted model based on the whole time series to compute all (fake) predictions during the last two years: <>= predfinal.B2 <- oneStepAhead(result.B2, tp = nrow(fluBYBW) - 2*52, type = "final") @ The mean scores (logs and rps) corresponding to this set of predictions can then be computed as follows: <>= colMeans(scores(predfinal.B2, which = c("logs", "rps"))) @ <>= meanSc.B2[c("logs", "rps")] @ Using predictive model assessments, \citet{meyer.held2013} found that power-law transmission weights more appropriately reflect the spread of influenza than the previously used first-order weights (which actually allow the epidemic to spread only to directly adjacent districts within one week). These power-law weights can be constructed by the function \code{W\_powerlaw} and require the \code{neighbourhood} of the \sts\ object to contain adjacency orders. The latter can be easily obtained from the binary adjacency matrix using the function \code{nbOrder}. See the corresponding help pages or \citet[Section~5]{meyer.etal2014} for illustrations. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection*{Measles, German federal states, 2005--2007} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <>= data(MMRcoverageDE) cardVac1 <- MMRcoverageDE[1:16,3:4] adjustVac <- function(cardVac, p=0.5,nrow=1){ card <- cardVac[,1] vac <- cardVac[,2] vacAdj <- vac*card + p*vac*(1-card) return(matrix(vacAdj,nrow=nrow, ncol=length(vacAdj), byrow=TRUE)) } vac0 <- 1-adjustVac(cardVac1,p=0.5,nrow=measles2w@freq*3) colnames(vac0) <- colnames(measles2w) @ As a last example, consider the number of measles cases in the 16 federal states of Germany, in the years 2005--2007. There is considerable regional variation in the incidence pattern which is most likely due to differences in vaccination coverage. In the following, information about vaccination coverage in each state, namely the log proportion of unvaccinated school starters, is included as explanatory variable in a model for the bi-weekly aggregated measles data. See \citet{herzog-etal-2010} for further details. Vaccination coverage levels for the year 2006 are available in the dataset \code{data(MMRcoverageDE)}. This dataset can be used to compute the $\Sexpr{nrow(vac0)}\times \Sexpr{ncol(vac0)}$ matrix \code{vac0} with adjusted proportions of unvaccinated school starters in each state $i$ used by \citet{herzog-etal-2010}. The first few entries of this matrix are shown below: <<>>= vac0[1:2, 1:6] @ We fit a Poisson model, which links the autoregressive parameter with this covariate and contains $S=1$ seasonal term in the endemic component \citep[cf.][Table~3, model~A0]{herzog-etal-2010}: <>= # endemic component: Intercept + sine/cosine terms f.end <- addSeason2formula(f = ~ 1, S = 1, period = 26) # autoregressive component: Intercept + vaccination coverage information model.A0 <- list(ar = list(f = ~ 1 + logVac0), end = list(f = f.end, offset = population(measles2w)), data = list(t = epoch(measles2w), logVac0 = log(vac0))) # fit the model result.A0 <- hhh4(measles2w, model.A0) summary(result.A0, amplitudeShift = TRUE) @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Conclusion} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% As part of the \R~package \surveillance, the function \hhh\ provides a flexible tool for the modelling of multivariate time series of infectious disease counts. The presented count data model is able to account for serial and spatio-temporal correlation, as well as heterogeneity in incidence levels and disease transmission. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \bibliographystyle{apalike} \renewcommand{\bibfont}{\small} \bibliography{references} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \end{document} surveillance/inst/doc/hhh4_spacetime.R0000644000176200001440000003610214615167550017514 0ustar liggesusers## ----include = FALSE--------------------------------------------------------------- ## load the "cool" package library("surveillance") ## Compute everything or fetch cached results? message("Doing computations: ", COMPUTE <- !file.exists("hhh4_spacetime-cache.RData")) if (!COMPUTE) load("hhh4_spacetime-cache.RData", verbose = TRUE) ## ----measlesWeserEms_components, echo=FALSE---------------------------------------- ## extract components from measlesWeserEms to reconstruct data("measlesWeserEms") counts <- observed(measlesWeserEms) map <- measlesWeserEms@map populationFrac <- measlesWeserEms@populationFrac ## ----measlesWeserEms_neighbourhood, eval=FALSE------------------------------------- # weserems_adjmat <- poly2adjmat(map) # weserems_nbOrder <- nbOrder(weserems_adjmat) ## ----echo=FALSE-------------------------------------------------------------------- weserems_nbOrder <- measlesWeserEms@neighbourhood ## ----measlesWeserEms_construct----------------------------------------------------- measlesWeserEms <- sts(counts, start = c(2001, 1), frequency = 52, population = populationFrac, neighbourhood = weserems_nbOrder, map = map) ## ----measlesWeserEms, fig.cap="Measles infections in the Weser-Ems region, 2001--2002.", fig.subcap=c("Time series of weekly counts.","Disease incidence (per 100\\,000 inhabitants)."), fig.width=5, fig.height=5, out.width="0.5\\linewidth", fig.pos="htb", echo=-1---- par(mar = c(5,5,1,1)) plot(measlesWeserEms, type = observed ~ time) plot(measlesWeserEms, type = observed ~ unit, population = measlesWeserEms@map$POPULATION / 100000, labels = list(font = 2), colorkey = list(space = "right"), sp.layout = layout.scalebar(measlesWeserEms@map, corner = c(0.05, 0.05), scale = 50, labels = c("0", "50 km"), height = 0.03)) ## ----measlesWeserEms15, fig.cap=paste("Count time series of the", sum(colSums(observed(measlesWeserEms))>0), "affected districts."), out.width="\\linewidth", fig.width=10, fig.height=6, fig.pos="htb"---- if (require("ggplot2")) { autoplot(measlesWeserEms, units = which(colSums(observed(measlesWeserEms)) > 0)) } else plot(measlesWeserEms, units = which(colSums(observed(measlesWeserEms)) > 0)) ## ----measlesWeserEms_animation, eval=FALSE----------------------------------------- # animation::saveHTML( # animate(measlesWeserEms, tps = 1:52, total.args = list()), # title = "Evolution of the measles epidemic in the Weser-Ems region, 2001", # ani.width = 500, ani.height = 600) ## ----echo=FALSE, eval=FALSE-------------------------------------------------------- # ## to perform the following analysis using biweekly aggregated measles counts: # measlesWeserEms <- aggregate(measlesWeserEms, by = "time", nfreq = 26) ## ----measlesModel_basic------------------------------------------------------------ measlesModel_basic <- list( end = list(f = addSeason2formula(~1 + t, period = measlesWeserEms@freq), offset = population(measlesWeserEms)), ar = list(f = ~1), ne = list(f = ~1, weights = neighbourhood(measlesWeserEms) == 1), family = "NegBin1") ## ----measlesFit_basic-------------------------------------------------------------- measlesFit_basic <- hhh4(stsObj = measlesWeserEms, control = measlesModel_basic) ## ----measlesFit_basic_summary------------------------------------------------------ summary(measlesFit_basic, idx2Exp = TRUE, amplitudeShift = TRUE, maxEV = TRUE) ## ----measlesFit_basic_endseason, fig.width=6, fig.height=2.5, out.width=".5\\linewidth", fig.cap="Estimated multiplicative effect of seasonality on the endemic mean.", fig.pos="ht"---- plot(measlesFit_basic, type = "season", components = "end", main = "") ## ----measlesFitted_basic, fig.cap="Fitted components in the initial model \\code{measlesFit\\_basic} for the five districts with more than 50 cases as well as summed over all districts (bottom right). Dots are only drawn for positive weekly counts.", out.width="\\linewidth", fig.pos="htb"---- districts2plot <- which(colSums(observed(measlesWeserEms)) > 50) par(mfrow = c(2,3), mar = c(3, 5, 2, 1), las = 1) plot(measlesFit_basic, type = "fitted", units = districts2plot, hide0s = TRUE, par.settings = NULL, legend = 1) plot(measlesFit_basic, type = "fitted", total = TRUE, hide0s = TRUE, par.settings = NULL, legend = FALSE) -> fitted_components ## ---------------------------------------------------------------------------------- fitted_components$Overall[20:22,] ## ---------------------------------------------------------------------------------- colSums(fitted_components$Overall)[3:5] / sum(fitted_components$Overall[,1]) ## ---------------------------------------------------------------------------------- confint(measlesFit_basic, parm = "overdisp") ## ----measlesFit_basic_Poisson------------------------------------------------------ AIC(measlesFit_basic, update(measlesFit_basic, family = "Poisson")) ## ----Sprop------------------------------------------------------------------------- Sprop <- matrix(1 - measlesWeserEms@map@data$vacc1.2004, nrow = nrow(measlesWeserEms), ncol = ncol(measlesWeserEms), byrow = TRUE) summary(Sprop[1, ]) ## ----SmodelGrid-------------------------------------------------------------------- Soptions <- c("unchanged", "Soffset", "Scovar") SmodelGrid <- expand.grid(end = Soptions, ar = Soptions) row.names(SmodelGrid) <- do.call("paste", c(SmodelGrid, list(sep = "|"))) ## ----measlesFits_vacc, eval=COMPUTE------------------------------------------------ # measlesFits_vacc <- apply(X = SmodelGrid, MARGIN = 1, FUN = function (options) { # updatecomp <- function (comp, option) switch(option, "unchanged" = list(), # "Soffset" = list(offset = comp$offset * Sprop), # "Scovar" = list(f = update(comp$f, ~. + log(Sprop)))) # update(measlesFit_basic, # end = updatecomp(measlesFit_basic$control$end, options[1]), # ar = updatecomp(measlesFit_basic$control$ar, options[2]), # data = list(Sprop = Sprop)) # }) ## ----aics_vacc, eval=COMPUTE------------------------------------------------------- # aics_vacc <- do.call(AIC, lapply(names(measlesFits_vacc), as.name), # envir = as.environment(measlesFits_vacc)) ## ---------------------------------------------------------------------------------- aics_vacc[order(aics_vacc[, "AIC"]), ] ## ----measlesFit_vacc--------------------------------------------------------------- measlesFit_vacc <- update(measlesFit_basic, end = list(f = update(formula(measlesFit_basic)$end, ~. + log(Sprop))), data = list(Sprop = Sprop)) coef(measlesFit_vacc, se = TRUE)["end.log(Sprop)", ] ## ---------------------------------------------------------------------------------- 2^cbind("Estimate" = coef(measlesFit_vacc), confint(measlesFit_vacc))["end.log(Sprop)",] ## ----measlesFit_nepop-------------------------------------------------------------- measlesFit_nepop <- update(measlesFit_vacc, ne = list(f = ~log(pop)), data = list(pop = population(measlesWeserEms))) ## ---------------------------------------------------------------------------------- cbind("Estimate" = coef(measlesFit_nepop), confint(measlesFit_nepop))["ne.log(pop)",] ## ----measlesFit_powerlaw----------------------------------------------------------- measlesFit_powerlaw <- update(measlesFit_nepop, ne = list(weights = W_powerlaw(maxlag = 5))) ## ---------------------------------------------------------------------------------- cbind("Estimate" = coef(measlesFit_powerlaw), confint(measlesFit_powerlaw))["neweights.d",] ## ----measlesFit_np----------------------------------------------------------------- measlesFit_np2 <- update(measlesFit_nepop, ne = list(weights = W_np(maxlag = 2))) ## ----measlesFit_neweights, fig.width=5, fig.height=3.5, fig.cap="Estimated weights as a function of adjacency order.", out.width="0.47\\linewidth", fig.subcap=c("Normalized power-law weights.", "Non-normalized weights with 95\\% CIs."), echo=c(1,5)---- library("lattice") trellis.par.set("reference.line", list(lwd=3, col="gray")) trellis.par.set("fontsize", list(text=14)) set.seed(20200303) plot(measlesFit_powerlaw, type = "neweights", plotter = stripplot, panel = function (...) {panel.stripplot(...); panel.average(...)}, jitter.data = TRUE, xlab = expression(o[ji]), ylab = expression(w[ji])) ## non-normalized weights (power law and unconstrained second-order weight) local({ colPL <- "#0080ff" ogrid <- 1:5 par(mar=c(3.6,4,2.2,2), mgp=c(2.1,0.8,0)) plot(ogrid, ogrid^-coef(measlesFit_powerlaw)["neweights.d"], col=colPL, xlab="Adjacency order", ylab="Non-normalized weight", type="b", lwd=2) matlines(t(sapply(ogrid, function (x) x^-confint(measlesFit_powerlaw, parm="neweights.d"))), type="l", lty=2, col=colPL) w2 <- exp(c(coef(measlesFit_np2)["neweights.d"], confint(measlesFit_np2, parm="neweights.d"))) lines(ogrid, c(1,w2[1],0,0,0), type="b", pch=19, lwd=2) arrows(x0=2, y0=w2[2], y1=w2[3], length=0.1, angle=90, code=3, lty=2) legend("topright", col=c(colPL, 1), pch=c(1,19), lwd=2, bty="n", inset=0.1, y.intersp=1.5, legend=c("Power-law model", "Second-order model")) }) ## ---------------------------------------------------------------------------------- AIC(measlesFit_nepop, measlesFit_powerlaw, measlesFit_np2) ## ----measlesFit_ri, results="hide"------------------------------------------------- measlesFit_ri <- update(measlesFit_powerlaw, end = list(f = update(formula(measlesFit_powerlaw)$end, ~. + ri() - 1)), ar = list(f = update(formula(measlesFit_powerlaw)$ar, ~. + ri() - 1)), ne = list(f = update(formula(measlesFit_powerlaw)$ne, ~. + ri() - 1))) ## ----measlesFit_ri_summary_echo, eval=FALSE---------------------------------------- # summary(measlesFit_ri, amplitudeShift = TRUE, maxEV = TRUE) ## ---------------------------------------------------------------------------------- head(ranef(measlesFit_ri, tomatrix = TRUE), n = 3) ## ----measlesFit_ri_map, out.width="0.31\\linewidth", fig.width=3.5, fig.height=3.7, fig.pos="htb", fig.cap="Estimated multiplicative effects on the three components.", fig.subcap=c("Autoregressive", "Spatio-temporal", "Endemic")---- for (comp in c("ar", "ne", "end")) { print(plot(measlesFit_ri, type = "ri", component = comp, exp = TRUE, labels = list(cex = 0.6))) } ## ---------------------------------------------------------------------------------- exp(ranef(measlesFit_ri, intercept = TRUE)["03403", "ar.ri(iid)"]) ## ----measlesFitted_ri, out.width="\\linewidth", fig.pos="htb", fig.cap="Fitted components in the random effects model \\code{measlesFit\\_ri} for the five districts with more than 50 cases as well as summed over all districts. Compare to Figure~\\ref{fig:measlesFitted_basic}."---- par(mfrow = c(2,3), mar = c(3, 5, 2, 1), las = 1) plot(measlesFit_ri, type = "fitted", units = districts2plot, hide0s = TRUE, par.settings = NULL, legend = 1) plot(measlesFit_ri, type = "fitted", total = TRUE, hide0s = TRUE, par.settings = NULL, legend = FALSE) ## ----measlesFitted_maps, fig.cap="Maps of the fitted component proportions averaged over all weeks.", fig.pos="hbt", fig.width=10, fig.height=3.7, out.width="0.93\\linewidth"---- plot(measlesFit_ri, type = "maps", which = c("epi.own", "epi.neighbours", "endemic"), prop = TRUE, labels = list(cex = 0.6)) ## ----measlesPreds1, results="hide"------------------------------------------------- tp <- c(65, 77) models2compare <- paste0("measlesFit_", c("basic", "powerlaw", "ri")) measlesPreds1 <- lapply(mget(models2compare), oneStepAhead, tp = tp, type = "final") ## ----echo=FALSE-------------------------------------------------------------------- stopifnot(all.equal(measlesPreds1$measlesFit_powerlaw$pred, fitted(measlesFit_powerlaw)[tp[1]:tp[2],], check.attributes = FALSE)) ## ----include=FALSE----------------------------------------------------------------- stopifnot(all.equal( measlesFit_powerlaw$loglikelihood, -sum(scores(oneStepAhead(measlesFit_powerlaw, tp = 1, type = "final"), which = "logs", individual = TRUE)))) ## ----measlesScores1---------------------------------------------------------------- SCORES <- c("logs", "rps", "dss", "ses") measlesScores1 <- lapply(measlesPreds1, scores, which = SCORES, individual = TRUE) t(sapply(measlesScores1, colMeans, dims = 2)) ## ----measlesPreds2, eval=COMPUTE, results="hide"----------------------------------- # measlesPreds2 <- lapply(mget(models2compare), oneStepAhead, # tp = tp, type = "rolling", which.start = "final") ## ----measlesPreds2_plot, fig.cap = "Fan charts of rolling one-week-ahead forecasts during the second quarter of 2002, as produced by the random effects model \\code{measlesFit\\_ri}, for the five most affected districts.", out.width="\\linewidth", echo=-1---- par(mfrow = sort(n2mfrow(length(districts2plot))), mar = c(4.5,4.5,2,1)) for (unit in names(districts2plot)) plot(measlesPreds2[["measlesFit_ri"]], unit = unit, main = unit, key.args = if (unit == tail(names(districts2plot),1)) list()) ## ----measlesScores2---------------------------------------------------------------- measlesScores2 <- lapply(measlesPreds2, scores, which = SCORES, individual = TRUE) t(sapply(measlesScores2, colMeans, dims = 2)) ## ----measlesScores_test------------------------------------------------------------ set.seed(321) sapply(SCORES, function (score) permutationTest( measlesScores2$measlesFit_ri[, , score], measlesScores2$measlesFit_basic[, , score], nPermutation = 999)) ## ----measlesPreds2_calibrationTest_echo, eval=FALSE-------------------------------- # calibrationTest(measlesPreds2[["measlesFit_ri"]], which = "rps") ## ----measlesPreds2_pit, fig.width=8, fig.height=2.5, out.width="0.93\\linewidth", fig.cap="PIT histograms of competing models to check calibration of the one-week-ahead predictions during the second quarter of 2002.", echo=-1, fig.pos="hbt"---- par(mfrow = sort(n2mfrow(length(measlesPreds2))), mar = c(4.5,4.5,2,1), las = 1) for (m in models2compare) pit(measlesPreds2[[m]], plot = list(ylim = c(0, 1.25), main = m)) ## ----measlesFit_powerlaw2, include = FALSE----------------------------------------- ## a simplified model which includes the autoregression in the power law measlesFit_powerlaw2 <- update(measlesFit_powerlaw, ar = list(f = ~ -1), ne = list(weights = W_powerlaw(maxlag = 5, from0 = TRUE))) AIC(measlesFit_powerlaw, measlesFit_powerlaw2) ## simpler is really worse; probably needs random effects ## ----measlesFit_ri_simulate-------------------------------------------------------- (y.start <- observed(measlesWeserEms)[52, ]) measlesSim <- simulate(measlesFit_ri, nsim = 100, seed = 1, subset = 53:104, y.start = y.start) ## ---------------------------------------------------------------------------------- summary(colSums(measlesSim, dims = 2)) ## ----measlesSim_plot_time, fig.cap="Simulation-based long-term forecast starting from the last week in 2001 (left-hand dot). The plot shows the weekly counts aggregated over all districts. The fan chart represents the 1\\% to 99\\% quantiles of the simulations in each week; their mean is displayed as a white line. The circles correspond to the observed counts.", fig.pos="htb"---- plot(measlesSim, "fan", means.args = list(), key.args = list()) surveillance/inst/doc/twinSIR.pdf0000644000176200001440000045323514615167605016551 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 5131 /Filter /FlateDecode /N 85 /First 724 >> stream x\Y6~oT$e*Um;޻t'<VI;;HqdvGOݛL )2Le\Ike2qkUf3$\ƽgggB[E&G)L9gѪ@L+˴wgF3  2!2k42^ Шיh\9ĸ+23ODK9iJJP=r)(Ɖ% <Z.F*BR -K0P#ƸI](ME#`'WʁhYѲr/iՙF`pNвA`Nh(t ڸ1mcp٠e+0[lf8L2Z-E'\2hqaвSegXϝCE˘@\I_1rLвנCނ1g38@AS8=9fw:L*Ę`Lv'GjLpe|MVdeγf>[k@;_ޡb?ߗYϗ{B'כ*fZNiʌ3fQ;lJP$g}:qjc7.EmtKӵq]jSnTf\<mÿ$f1}7ه2OVrɺEѹ5V'ڈIEKAo_O]-OM;=|˛lE7x%`[{T6ǍqF_յ&iLAesia'<jMc.7hgY08;̏l[{v- \&oM L.'rr=.ǯ^d/zd>:gxͼMU4ҸH5董$kGQ0Iϰ$u0Y_* y\MOS}z%M^X,r#3( -¿\W},EXp+y_,f-K -Kgr=E5,`ԧ+G "Րƞ?{Obs,V/FA+r1/IEf@gwh_kKq{0/x6VZ妜B7)iuy5t?@zXω^HWrl)J.EyWX ׇ U~ 6X[o}W#R[,ֳ텭T4W+M)Mm+wΚ.Ui@:i} QJ)Yؐh#*mⵡsֳw†~:]ԡA=ś4Xуg?~@tX$UL &1LurcX4wkX D;5_/aòˬ)~"f|R72/Ueb"Zrpm ףypɺD2obzݲ3ab:v,&j=^CCJezZ-m`y[^!,¯D_ICZ \S@fR6Y .pXˢ*<9Ngm8saѦ#j;f{NWA5^?OWoR 5/6P aTniA=Ƙ1ˢep2TS:A3y/;BVh컗$Eekw RA@Qv 8|HN!ђoȸuZuJ?vXv)IJLiAOt.1 i .tϝ!L;wͨF4dT,+ OރrXCRT\ ֜I&  k9 *zmM{gOΦ.x냧T;y T>ve:wuS1NZw2nVHmikvJ>i# C ̚^:yg~X s̮<>:ޥv G -PR)XY'Q:ѷaE]+!$څmlѺ iu~|c/nDܣXd;V$˺s3r7}hoocqqr/6PU-PKٻXpJ Íb]].Ukm#7Gn/lʏ~ gKs/7i ثA{8ǩϋ?.ݰV]X-3aڳ;9BO?n^|tXNVQپ(_Q*%-`cBdЂDR={13TOI,Wrv[)m ە-eĕVik \(siBⷊ㥷F E mJ;FcQڹvG6{|¡}0wuBOGZvCk֪ޕj[fUo۩(Ҍu;mFEB2rƖu>r'{h(^3X6ۏ~铳/7\UXUDZڿ]ѺJZ~KlཟgUM_]={Qfoh =ZLgo[\o>dol-b [>o4 ^9 m!nҤM}net|rZJhCs+DirDZJ::z2WV/C>צAi߄_dOƔm\n6/'g%/W7+x< QqN9'9v)J[3#{C & *Mʹiei*IOANoBS=>ɫ?l/!GoptE\@pDgx3RW9~ǙͽS_&g.W4Ivifޘּ.TOT:}8V*=UL$uɨW炾M&gK/׽jAw@}\0<}MEcѴ2D紖?2"9Tp"+.p;٩F]7p9-ݘ-Qt#G],ZM[wW5JEx,]Kx#=&)IhW`yƘf7 Q(iqnrm@tsS\0IL1]y(e N*3R\\ˁK V{%yKb1t Z1QJvT{+W2I߄GXҏ7t!L41{c T~Y73A}.!~[ i_jnr KPGϩ-:~jYr⳪/h3[#[:IS72-pt^P皾S hܖFw@< rxu)) ߯G\QAO)Nʘz+ipnp6rA=vƍxlV "l}-zY{lo˜z;l{'` DzN¬HCbK`*BT4cz89?ltQLt>:5^?Mbng[ C>LG9j']ܳw,zL7`fBendstream endobj 87 0 obj << /Subtype /XML /Type /Metadata /Length 1679 >> stream GPL Ghostscript 9.55.0 individual-level surveillance data, endemic-epidemic modeling, infectious disease epidemiology, self-exciting point process, branching process with immigration 2024-05-03T16:07:00+02:00 2024-05-03T16:07:00+02:00 LaTeX with hyperref twinSIR: Individual-level epidemic modeling for a fixed population with known distancesSebastian Meyer, Leonhard Held, Michael Höhle endstream endobj 88 0 obj << /Type /ObjStm /Length 3697 /Filter /FlateDecode /N 84 /First 773 >> stream x[[s6~_vvw'iS;(tȴ,6"l*V;L\RR&fA0< aYPY]w,&Rs˄dpLj.6>2 z'D*Rn)1-zJ B3iz8=h`N3Ra2|`U!@iAbV*ͬƳV Xf99A~4 N HpyLGjX0/M^Yz1o=w)X'xI JcP[\(FʀDAFRO z' Uv4*z+>zpD?:/мb[-)T^S2+5n2^mP^aZYr[T"—bF.-g`>_+B @=(<ˣ)Q.$Q $?'L#.nTzuoձxfZ6GNSm1NTGUтvIz3 ]9W5c;jgXjbdKE2'I2Ys''Id<9MNaU<&Yr̓Egl5]%y\&o4/Ζ4br-dU9'yH?/_r}TH= M'3h?8q<]Q4\ygcзvl{E mAik[@@[ <=Ϊm|nf\ 7@nѬK2n8p &@Sg*Xrn@l܇"EX1ܞ>+ b<_ 7/;jf5Ap;BCZlB5DVr 4TYvK -m( Ǐ~2)T;?˶#]F”Ppi8:z)t#GsUX_Mc8 Һ3h].ktNv:nz$=–ma_/Ͷ5{_=^bwG#0ҫеhu G?^zu1K>*kPnbcEl0ym4ϳ2oBT$GPqPT(d5""3;9z'yp#`k}7>|8ޣcׇM|8)nbII;mAU0!'q~lD[}k0a>Ox5یn[?o宑nLYvWt:_8ϧ,_\6c\j)Fӱm ġ&aճo!AF_WUJ"03>Iu6 ㇇_.zx m͚[ӡev"7B8iLeTm.c<<'|(䯦R6{8u\e|q507_?40Xe?y ю*PUW# m7k-Щ^&,'ٲ$-Ć(eY 2Q!q:3I|HNٌӞkI9-"Wg AM*4Qd* He K#T Ms,iVK996O)6Ӫr) F[ϝ#š"NStBtS`kWqZ7R,4;_OO9J,M4JFx5S8T(P<L>J"J ɍۑd%FLb^\b<VG~}ɖ>_}JbD SS@u\HxQ,7WKVUGRǭe]e#nY(*Щ^dl\C +ڥHv#}AtU!YDowwR)ڴ+9!M{s+O&IQvNlаPIHL ZŷJ=47Zr.t)"o.鈔/6eǍ-@ 餝)ƸP6 Sq3I 'dW8ǽ'o]՛G߯i_Y etTBzn}jgdgWbXV!ʤ^Go[^A|%iKѐbRwfTMՑe>lI"%#+TDir-kHCT, %2(Q# pTDU7 'G2HCRDHA}{Qrġ"8iGwô;)54oʝa!qY$kwIS Rя0j`oB֫9QP6F tmR00%l1XQ[~Hdl6v_񚭿ue6b ͞)\oŌA_U9B'Pe(vʸ+`|PSѾ}ӤjHO@%ָRh5 Rfeধ tiHWfēV*.8tn*_iyճ@d4!6in !nXs/\\o#Q{AhORJsU镾*>8|endstream endobj 173 0 obj << /Filter /FlateDecode /Length 5604 >> stream x\͓u?ֹW.{PD%#6eW6w;UTRɁRkCIm==7CN9(;^'5(}XU%[U/sV?\1z Vp}3Zo ְѼԕZ]~”U涬НR1SlotpϺtÇ?*]J# ,}* U:`ɏ{[UY8a /9㒦j?N(M{@q8u6Lq*咧\2Vr\>9]]}&)>L$KcSɵ5m[ol)tfpDzx_m).?΋msS> J ްt@gKu*uߜc4"hozX300=47kŐ5m7o`T"`\u>7~^h\,FjF2`\Ŋ] !}U|kl*0ׇsy!#H)%s&#e/hF.-u3H/>!s4ޛ4Z7]?Buۡ`lc` OMqߏ/F*KrҰ9DvFݑy uJ$g o!]xld#8⁞V`+'S@a+JqkJ' eJa$3GO2ZU>¤sp%b,Ns+RrAiCT4Hc 1~ 2<-^ͧ!-w0}nݧ@a`25 0Ŕsu蝺K ) iW=N+oR931\a_o"?": &o6[y-NaxʠfK$ T#Nu)mF68BrI4 P9Ӂ*!`@WiT0peL:O6mil7 w;, ;}L@gK"'? ʶ`L,ʁiL}ӸI7oe2mfS4LH~ CN"k xr[|Z+勎i~iq(J f7LN`-Hbv3j}&䳙hϸ}|LR`+I/k<5wD5-!xB:c6I`R5t*{F] 6lC${؄N")tX M<&rRcЕf|GL'NKi4;gU`)FEv!t8NV̆tfAMsF##jjXRsaMGfև!\TTted X3ˍbO.[4Q5z!eӜ6_4^i ?{G@LH\|{BE!x++sHxeqs1؝&S%ֻ/DT4ҭ,06dcCb;.}~Cc"$MtP;cЁV{8 iNа@h*ga2 \sJ}}Ty1o;Mp!`ǘЯ,@n'z8K׽QI2râ2bԽ"F43"20T07bmy |(@&%+1KJyjiQԄ^c3iIK0)'90 \WXǤ<ymn8Z4) 7MqJ7V&b3DVͤq3 ҞyE>~q-F.㯒!繍k*o. l)V_ǬE:g:C<ᔐi ,&/tɳ>kq[Q:=߰C6F gFzW|DIcj1.>))r'`:,)́!O$ A) #bA=G3A ,`_Е^(J# vpy.|ZI%%'ay_kc)emPYYI직K̷ڑ 壐|%!2pla/*0}V2LWzaY]BVr O-P~sۂz.mj3 D̹Ӑ(Ht}ߊd,vҌGHS~]޽fpfdUцJ < ! pcjg B9/b -votSuw!THO?S *1Oلv?r2t6`Y~iS^ FLșKu -"-ty( yf3Eydeu:hDzBc"Y<}NPQڢs*+JR>ڱ,x0&ndt?V Hyyefwq9wP|J-]^%гa?>T~f&N6(hke.ԣ~bV@LjL2a*I4(>/?}Ci n5MA7ke Wͮ2wv= (Efģ-fGbp1ffq(/YTҦ,}s4w \3}B0. 2hSԃY@mdMA%>IfXL7@+ 7JqL@*V|րkwޛ%?GWAiTٹdOhGHL]pҤ_㟩#RVZ^[ӣHq7R@ >H: 4=JԶ!NquF%Mv:`Es84n=2?@J3BƯOBY }v J I( TmU-DV#-8 m=݌6D6`{Z t!I<E{F) X7Xr4ECtQ>WÈ񍕔3iʄ]fnf>C\D'D;iZ$㚗"ޘ$ACsX4\ڷX述UpoDVR]E&Ut5Bh&2h#Su~lI$3Ήv^(v@W6Ӥ˩xAf`lE36Kʥ ^0?zx*Z$ԀgxM2[sJuAOD~:G.4B?EHy=l H9ej E*^X}eY̓& ~ؑ v$%r$&o!Qn lc'9#y>k僚~rL>XjF.EqOP秹ϠX:ǎ.y \̽bl pYqy&s*]ٵ!71WLlv: $_($Cji[J`ҨR?vD6ѥO4=d_2V?%:ߑ{ӥN ?G?M5hR/1 tIM!Teo[Vt_XJmF%7*HrJPi.pNh{LY_ *ϒ)6ot0+Eg?,Tt/ Q:{Q4 i^Rqu!ǂwU$&*g%FO |u* y'm7^J k] ?}z)l-0DŽo]0CWЕqJ8{?/~- h%ચmDV:Hwq72 \_-hdݜZٴ9 jK$-|pߒݠtkY*a8u]i^Z1Z6_*n ?:[p-T2"x_MAPQ}\V /R+DER15rvY>xfE?,jqdnhJxxXТ+B@[h/XBɆ^42PbK E e[t60Ia1p7ߋ6 JXWpb%Gkenٝeлu76T$8q1\MlI$Jg] mv7k Ut&sI?Q:ǒ9wBN?YۼlO8~x  %Iz&EAZb.d/wž^{aRs? M _o;ȽЅb7z<ؘJRozIsxHXf`(7:\qe` f|NJLv1'.T=H)iC>#u3T'Yf?cQNKE|=Q)VP"(V!ޗWÀeendstream endobj 174 0 obj << /Filter /FlateDecode /Length 6270 >> stream x]ͳ#qyCrH`W勇r2%WY\Rl9eRo=jɥDr9 ``HS:,ƯY׊Y_mug?>,j3ٿ4|]/fWoG̋3학]m5r~=uӭCg/m'o]D7 o}^~/RmW!kkzO^B{%~mM󋬧XxBĭh0gj^ads:ܦ|6vN"Qz@1e@JǧlVaL kޠ2s*cؿ. Di$Wa_{nc++ÂdkkvB^hH-nx>_جE- C1֜:HG |QV|b?kMT8EZcko2ǖ/\P02&,fݸS囩_ v 3&Fu.h@`2~,q$1ɰnи,6{ $тLexp;Elv펍9"hLƈQ+a G߃i=>VYAs:Py--$0a(YaqLr/{W82J/]! | o2`XKOAς; A/‚w"_x b'cK$Op2sc*9iH]U* t1o1{"i v_$A'zfZ#aa aG`Ɔ/_z JW]誻JݘrB%r/Īnz{c"iq%^xuDa4RY`3LoQUwb- XR9j ^&>wQC0yQ￸zg!igf{' 0;3lR{q\e WstI,+r{i7/R6V^z@(R8N\: ]|l4& c)7|-'2|5 ǻbp`> hFqI|AnbX/&b zCaC3kŸdQ:0O/s90l5p68U𐮰uS!rb '`:yÿ>~5 a=AuEyLSlԁ3z9= _>[{t'[X_PF{N]Knu ,I=1& vE(l7LH1 ߂*Ĺr Kf$?X "JM^. SCZxJ`*fe(LEDT ǰ'L g#is}jL_2[5+Zb?vŸnC+ ̀E$[]l+Ő84OvV/ ꛭqRh4鱭ށ@o5m5%a#] G5)k57ǵ2gP|aZ|R2gHᰎ|xl".iDS*.7:IndZPmog>XPǻ5_6ǃ5yRʆtH i UnS߲}^ ĥ\JQ}}߭x>Hf\L\=eJ>Ioð'[6Qʇm =͇z:T ~5NVXϑR֏쯱Ȭ ;r?oQ$a]I@Úv~ĭp`eCS`nRR)('/3U)j@guV#W8J,'WIIyvܤ+'ԠC%)8)(Gi#BW Βh}H `7!,E@ ဩנex!.8#I7! l ="Xiѡcx\RhjvUk+b)GÊ30_-"l<%g)!E9 X2u**Og> nB 氼Iu^Q%!"drY@> 'EVj?d쵒\K3f1<lPHa~|_w)HcՐ??W}U<! ~$֨2a"RzQa'g8Jã|F-CqrmROJ4paju&Z`Rd[ )!lEՎ$fbBuP'PVtƏxw(#\z)S=4!C]N -}dž*.;L]gsI/;ŗ\$M =4eX ? jʞXƿWĭC@M]h!: qYcܚ'a\@,LiQ[JYW1+cYpg$evµ>mڄ ʶ")=V3L8%AſǗ_= VFRv$4ebQn fglۯMՊ!r45霮eV* $874>K |'D-&BFFM!-9ԭ;Jv&80@_^<ÁXQdM@x`$ [ `g}dQ s}dFY7P(| DC7\zG8Ɏ1 `_nw T? ׹pIk۠Õ/j{˔) 鼄Y#4pCYe'^B5d$;tp (繜چG/<-k;-5tn  k X I J|ӎ_ )Up&lk).$qO6 NiܑnT%;&ꋫ RI ΝEwtCHѴsDNti(@RD-PP?ܥ"oW\e"HGMH ap+LmeWixYfՋh3cbή Q}Ql TQh脐m~7Y<9Cxu0rҽ/Q;z_^QF'.HT;]x0<3;,s 0;" kk1BY Xy +xcKO[wt]^t:4 l% :.5`m)K"nn[wh)<[%}udT YwƘm Yؾz{?qq#YSUR'u]QHIys* 4ml]XA_!$HȿuR/Ixס* v9X((L%5X]c?3ZcFRunKwAifBfqq^OI.\oC'" 9ZϏjt]f5~@G5KExq:ev۸xVvWU_*xjE,͂%ʉ'/Tz>"a n{7dipn[Kϗ'k\ᄌ>FBmW-PY`Z>58Npq:?at"*xΔ0A^E|/<咟5]  g=a?9[ dr~w`X= Hʣ(MnN~HWEvMLҮw%`CqJG?Зi"谾8[7o2@ n 97$S1q6 {6ֳ~%0r02\hA(Q h2q%9CȽ#&fţx ,& B.͢'xV,QaepUctS9b7}ȩyr_;KiVsZye\\'BlbEβ hó CؖD&l~y Jy()\U}~ Oo㏆wx9v({]g*kendstream endobj 175 0 obj << /Filter /FlateDecode /Length 21002 >> stream xo$IvpW6@, h-{ Vd@cfap{f(1MΎp=;"%/ 2+r;\]NoN9 5:]9=.pp5eږW/eچq~{}S~ݻio翇z{ۂyr?y|g־7";1uGy#O翿}=Yg ^A&e:lj븮Wnc΋՛y~ϧynrkIN1.e϶[f̍z_S=/%:TY_?a>~oKjno!qw-4_/v%t>=-˩_s PtѼR \i鑗ekX{633*2ӱxK^m1<дY~:MS֨q. re>FZTv=j{S0,ͯ=WƼf|{b;?ߧ)+ɇT9:r3̃]82+JUeYn}U Sx}xZ7Ʋy0t;scN篯=/X+yWaS3886i^r35qoA?͟q. \Woy۟,='p٫?o~|ϾNP11ᯖRૼ.0iz꟮ޝ,vږ_|soJCm>]nqk3^yJ<3ۭ%lmq}oö8oմ$R~ϤɺON59Lۙ.%LIh9'Ķ1gāwi\.eⴌ=:>{%pݽ䇗͒7&򞽴llemllCIð\mX%mW1NImc2)>W}~ޯּLh냟 m}3!-;]R)ok=zE7_6oӼ/yKxɯ%\`Jϼvݎr5o>DU]4ا_)hWYY2ۉ[}W__ݿ{s7烒[høc0e.ǦfcIi}yw}:Gm|]k}|*O.kvEziKUhy~?ybơHO4gl҄Zoj+oJB-<Y|Pu-ZcYIjI̷y+QZ[9ЄZ嵈İ% 0+ki߯|lz~vDjaV[yZQwPvK!sN-=$gMK~eԄ[]xcPKy%?祜?pme:cqԄZ;Sp?>k *sk"p-f팥`'/ &l-d_gЄ[]hZL9W5jaƭ՗J׏N2>*I׏ ;* {1pʹ6V>XZB%ɆM&ܑ"sr'Ԓq6VnQv)!;6*^]H׭r-%ܒleD[&_d?gе$f^`HGh=6's'۪ImiWyW:ZwV^6nq3õ&l(Gk[4dcAnqW6iZN%Eq^jaV[clc *g^}rOS_7PFq#YvB.qZyMnAVZyԗ \bjg)ЮYm=rׂ#` ښݵ$V[;^nq?* -rk-z]ZHtҀJPdBnAƭw-V4u-gיYMYnmS>t.Wׂ&hAƭiyzRp 2nOkly^N%ܒl5b{]ƭݗJ>OQq%gإ̚h,_&Œ[[&Gt-.,Ӝl&2ٷJ[BKZ&@;-Z.c\>IehNYm.@ :u-ȸ5-..3]jI6N.Dp?s.S& 8˟9~ֹ\9[ql]e#;yYPO/,&ڪY3Σ&ܒ"KD)G3Ka[˕>I%Y:jw $d=fjOPJ_l(U?up5|d\v PGi+T.M&ڢRT}NYm[Vӵ8+WڞyMZ꺏-:Kt/ǖ&܂gةUv$d!hׄ[qk}dKYn4]sB-1t t?nIv啓%ڪYzɯ8{mp|Kbז$d}D z-Q6rXxNn<MEYy`=;'ld˳&2Ymի!]%1;p 2n0עl,gUKŒ[e[&c] ڪϟt-jk4؂z-Jk5ZflAV[[=?d׽5 /{JkYm]wׂ3Z[ْu-jkWYm=ildp\lmYm  V9[&>UЂUׂ[ ښ-jeb ڪkA-?5z.M=4بvz qg_]Fe;W֙{JIieڢ;0؂z5[Vw-Jkϒ` 3nӾe2n-cV[3m gRס|Xz[Vyڣ+٨t1֏~cV[s+-j>ص |bdUw-J~A`V[mWQDAT:C?MP cdӤ6leՠY^OpFC4c#stNϮ4MD3i;mFܩ촨vTLRYzبvv?{7|v NZqg ;؎jg`۱QLB 7O-\بvxc;6"vlT:BQ7D HБbs;S-f:bn-1*8S5{ѧCŒ[K?fEg؂Uׂ:d2SyʰsR[ CcՄ[@gВlg]r;J.و;kPZV>dڵ0+R7LY}IYi=B¬lРQy. +^'f5c)lAV[C [/ $[YNLA pB-rk=GhuYi{Yi彺kaVZ;=-J(b "AiVӱYnMZa[]VZ券.+ru-JkHgfפt0hYi-؏Y:ӆ3ȁre;zY\r ;ͱ8tp)8jKNQ \r 8tp)8jKNQ \r Z޼E2\r 8o".9-pp)\r [μE2\r Zyd3o-qSp9%ਅ.9-pp)8jKNq \r N[%e\r [Sp2.9G-tp)8nE-q%.9G-tp)8m8KNQ \r [Sp:B7/"e\d޼ ͛qy2.2o^ƅ˸yћqy2.4o^y`\d޼ ͛q9Qɸ5qy2.Poȼy7e\`޼ z `8%՛H98tpWpT:\mu.9G-tp)8nKNQ \r ZSp88o".9G-ppWp3o-q0ΛH9ɸE2\r [SpGoVd"כHƁKNq7o[$yd\d"g\: [ydqp+8nK^q+2oRSpNӖqp+8j-qyd8tydqp+8m-qҩWpNV`".z-o"כHƁK^q \: Z0ΛHƁK^q \: [ҩWp2.z-pp+8mu-qҩWpNӖqp+8nK^i7oNVd"g\:}yZҩWpNup+8*K^q˛HƁKNi'c\: NKyd7o-qydZFQ \:u KS.zǭȼE28tK^i8tSd\: JҩWpBNVN8tSd\: [޼E2ΛHƁK^Vd".9-o".9-pp)8nE-q%ਅ.9-pp)8m8"ɸ//7/e\d޼yd8%e\r [SpB8%՛HƁKNq+2o3.9-o".9G-ppWpVo"$>b".9G-tp)8nKNQ \r [Sp:K1o^ƅ˸y7/Be\`޼{s,\r [Sp^iCos-qz.:yd8+8KR[%.}̼yћq6o [$zɸȼE2nw-'8o"[$yd\`"[$yd7o[$:ɸE2[$yd8ɸȼE27o-qyd\o"[$yd\d"[$ K0.@ok.9WJ/H-q޼E2ΛH9ɸмE2ΛH-q?ݼE8o"[$zмE27o-q޼E2ΛH9ɸE2Ρ-qyd88+>b"H-qଌ z `\ף98Do-q? 0Co՛wq0Go[z `ws-q0Ϋ7)`Cos-q=z `Go`\`޼yd88+>l"H-q޼E2ΛHƁ͛q1oCge'H98o"gHy8[$8o"7s Zଌyd\`"[$yd7o [$zɸE2ΛHy8o"H9ɸ޼E2\BWIKqyRs/_Wg'eWg? ((-kÁ48llXt,q0fm,q8d9g7D@hf"cqbcIbci Q686] `Z&A-L"cic|hL"cqD̢DLGbCI֦ALUdj&j\P@=4e3G-SAper"+ΞLMׯZ$%5'c847` g-hdFYK;Dr+!Lo0'vp.D3812{ n1i&wX;Z 6RppN#UniA"#8Ѩޮd75[&> R6*#8٪ޒe7n[&wM`V138vf7%k.Zg75 f~?S8x0@3}|)DAH` vh0D4GI'-W#.2 XDp,XDp,a&qHffJ⺱8kE$K68K6]p8k41ǞZ&G1G4XC[.0FqXa2Fqșf8xM3}Q<0YP%Y.Bq8]HPbS<'(>2T Q&Rq0Mcs `mY`͒̌/׬M8.tI,J#14k#á$kcR8ksx[Tر8ӱٱ4%/(.yt (nZ&Aqv[Ӳ61K6~ű$kctqfPƪ*ȌD(G,yBq9wQP}5kc1$k(K2383kd0ᦋ3383386-,/X`,Xp,`}cլ#8GXp,t⨍(FM8ñ83SNfgw@LPݕibcIbci&{XAqv>/(>RAq hf"cqf-#řnXX&Př`,ΔNe0Yaq~hf"cqf"cqck<2yԬEWp,XϏ}`ŷa,t1钬#8Gty1Yx%YY[':!hN9Zb"gXfbr-%ruiր{Q(Q@Y!9'骑CmWFY'YI\&!sv8ǵ4ґǙ4k##qdFb#qFbgGH84k##qFb#iv(f#g٥f7Y⩙BPqj&T\qÁ("A,L8j%S{+&\H[Xّ4, ΢a LY3wHQp8K[&Z8eؚ! gFf$#qF" #qdF" #qF{C ęDĉ}apL"@"Vpkñ$kcñ$ӱXɷ 3ߔ~ 8 W3_22Ap+#4ӯgBbL'&Ύđ(ęw ]XX-ÙZ&烊R19lkg-3gpd|B)Z2\h\QfŴLIkDb%"jR8serJ)reap"FrmN)62Χ\k\3T gl9d gL+3[&™{ &J}=p文FrD,y/T gnlc gcEǒEǢL Q g iEf΁EΛPy3h8o" \Ἑ47sf.pEΛHy3j8o" \Ἑ57sf.pEΛ9Ἑ8#sf.pΛ@y3i8oB ͜pEΛHy3q8G \Ἑ 8#sf.pΛHy39#sf.pΑ92h8o" \Ἑ 57sf.p̅Λ@y3i8o \Ἑ 47sf.pΛHy3p8G" \8#sf.p̅Λ@y3i8o" \Ἑ47sf.pEΛ@y3k8o \Ἑ47sf.pEΛHy3i8o" \ 57sfs8G\Ἑ 47sf.pEΛPy3p8G" \Ἑ 47sf.pEΛHy3j8o" \Ἑ47sf.pΑHy3i8o" \Ἑ47sf.pEΛHy3i8o" \Ἑ47sf.pEΛ92i8o" \Ἑ 57sf.pEΛHy3j8o \Ἑ47sf.pEΛHy3i8o" \Ἑ 47sf.pEΛPy3i8o" \Ἑ47sf.pEΛHy3j8o" \Ἑ 47sf.pΛHy3i8o\Ἑ 57sf.pEΛ92i8o\Ἑ 8#sf.pEΛ92j8o \Ἑ47ssd.pEΑ@y3h8o\Ἑ 9#sf.pΑPy3h8o\Ἑ 8#sf.pEΛ9z1j8o" \Ἑ47sf.pΑHy3j8o \Ἑ57sf.pEΛPy3h8o" ͜q47sf.pEΛHy3i8o"\Ἑ47ssd.pEΛPy3i8o \Ἑ47sf.pEΛPy3h8o" \Ἑ 47sf.p̅Λ9Ἑ 57sf.pEΛ92j8o \47ssd.pΛ92i8oB ͜p̅ΛPy39#sf.pEΛHy3i8o" \Ἑ 47ssd.pΛHy3i8oB ͜p̅ΛPy39#sf.p̅Λ@y3i8oB \Ἑ 8#ssd.pEΛHy357sf.pEΛHy3j8o \Ἑ 57sf.pEΛPy39#sf.py \Ἑ47sf.pΑPy3h8o" \Ἑ 57sf.pEΛHy3i8oB \Ἑ 8#sf.pΛ92i8o漇\ἙΛ92@\\Ἑ8#s92i8oB \ 47sf.py\Ἑ47s\Ἑ47sfk8oB \Ἑ 57sfq47s]-g|o>)?3'\jU>̵9,2g[%CL1:Az 5eɐ9,Dg[%ClK3|,,2gZ5 9B29fΨ3&s@0Ka\pNw;M]1s֦ILȜi] d Kf2fDdɠ5շ[Y2lk8l d$;wQ2nvl31siQ2vv*^v JAFI\Wb+g+&3tKtlR3rбQjB:6JD8茝Oeuvě@2qбQj":6JÙFi8ۑHi.k8w1J A J%pرQjJcp,5 -RpL`8K,5 -Rp}k"Z,Q--β.KA (0KVF᠅Yj[F᠅YjZFYj[F%rpk&\$q%pbTlDY.Ru6pֳK$R]5.r Tg9f"ſ͎Qj :6J;AFI雭p&^]|ÖdBY`yowYj [)ff Y2,L7𻬶r`3e,"-jkDYQ|dZfZAK2 o4ӯfh˸U[*Yo[e;ٷ(#fj +-) - /@2no~MB[ ٯ6"-J8/@f&A3oklAV[߰e"-ȸWLA.-ښa 2n[.}dE [qk} T.-2b3 !mk*c- o,h [7lAVZ ߠYm|Ödr/o ([uKյj_@%/f˸U1\, L7 %kU5*YJKmaV[ ߠYm1|d Z5+]j ֲj - ]VZ ߠYi1|fO[/cV[߰Yi1|fܚFߚpaFgmL@7F,5S,. Ka3%,T0K a \:!8lAg^YQj/,5-Rp} )P gn᠅Yjo,5 -Rp,5-RpZ?+ oLQ8K,5-]gs%gAqAwYR%RcqX,5׷V8ˮ,5-L Rcq,5-Rq,5-RqWd-R#o}k~J` K a ` K a `0Kl㰲Z>/0".K a ` K VeYԮ(sqK\X]ÖdYQj,KY`H֘8ްgvg0Ka3(VHq 8 45h(8g찉G#?LI 8FIbgݒD 71B)q$Ssκ,gfJʄYx&4pFIԘ[< gafY'Y|@˰@p5Sb  d+2ԈYj$Z5 $d [2MFq;%kQPQ(eT3ũ‰J֠+8ఒ54,hd 2ٮ2ydljjV $d1V"jJ%C $u q-ΎU8TRY' $45Dk5 ' $o;a8IU9Ii@;5_mNnI[},N.QR8ID١WJ-szE[-a]p<%u\޼ | ppDžнyq{:.to^yp\޼ܛq|s87"u\ ܛq{:.oDžy7Bu\޼ܛq{:.to^}нE:.po[\ $"8cᬎ ݛq{:.po^DžHE-q`@}ؽE:Z8"u\޼ ݛqoƁ:.ro^Ey7"u܇[{tZ8q޽y7Bu\޼ q{:.to^Ƚy7u\޼ܛq{:Eh\gbߜ׵LK۫zwyorק-8ƫWwz?<߿z*;y:}|S_oϑoߴNsNnK>1Ӻ-&N_u~eچˑ_,y7|2翬y+H|/nwCyki=?kjo)<:p+/?+=`??<<^ԗpqs_2!LJyQ[~E@}W1[e;<ڰRK5vpB|G}AYu9y]z޼MOym^'(1ZYCۿp Sl~!my^ro_ ŔS9ݽ'^4V14uZ+}>6 ixhn^;Tg ŖkiP9ɻy͇ uN뛥l܎moo'p_7}ʋǯZV[ͻpW+Z?/~ʫӟde~.??;?#?op)[w7<-{..뷿 :7<{}__]ɳ7o߽,=?~g] 8G4j{:-k3wϷC߾{ּz]O /?=5L~rm?K=ۮq׃WuǛ7Oe>q Oδܿ|Xwd{*"o~4nC&N|T6%߷u|\eͫ{ɧr>1[ųr0_s//޺y,o9i=O/a]{Μնf>)}gxp{M[/K \D= >??Ht~9]򇲲zO#8~% la_=V^(_؜gk?n/YW?i;^Op\{pUiWGަ0x.=\2~ۓc4(q}HYyQ_,:]/wj}rz}-_gWɺ7oHY!__'/n65w}3u#oںgzCPZT3;h/Vaًݗ43$Cȑ s21S._M9\:aw+챧uwco`IcK*.{Acqwy S|PvHe1 >p\Ie /wlG.i6Pa̗ב:_8:x## [!~rP/-^5_c͇>: / n$p7[C?k ߖ9 hᵮMCyhSPnۡnboꅝ}e yD[E0[-OW?"hse_;\w۸~\W^6ˠ|Î\[H'+Z4q0.k\0}0ιf-iӣ¿GyS8A2OFvyf|y P9@F8vzk/W;%l߼)rWL^8cJJ=?zNXQ(g/>k<gd=0se):' |m.NA偋rb\Ϟ^<R~_:c۱m)< %.'O| Nt~|Gz./3 ^ TN's}Zy聆9oKOv9}Z _mF}uK|uQ]KߡO=\+? S0 o1Tlrm|ir1%Ln}h|/ԷdƋa%qu[TGI4qmm]U8Usn2n"+N|߶e2Oݺzgsc}myS@BO{xM}O_VS~|g>:oŹ_]>GH7Xc^j-ɱ+GHt7ifե͘}<b8^endstream endobj 176 0 obj << /Filter /FlateDecode /Length 13414 >> stream xˏ%Ǖ/fgY2XWYƣ4an%wuSUωsNĉG[@W_FfFǟn9߯_7߼+S Ǜ}'Mȵ|+ܘGI!] 7?zQ.onG]|ps̗O_nm'xGzw*o}^M|M(>׷G CW'1oQeoIm6_Aܹ! !>Rn?o0❉1B5ݫw~#| HM,]Sy\[ ^|qGz/jÖxuH&!GpaKJ#\k!8x7DPF#"JqĻ%%k{HvW'qF7"ݎ9]Ěks kc>] ([`_r1 jʎ`LЗ~ 0s;r.^S&R6?D%wLe{BrD+-~f3cH{-nԋVPħ=WCb=Z&vObo%6&Pn3r$!>r;\Gޓ@))j!Q o$[@&g"C;'$KC<'򄙿D#$3 5=RuKCʍPڲ%PnFH?D?'pJ*iݞ2ǘ.gRP[wFNʖ@s ݖ؈*UB| ypgDJp䚂-$pʅBI[ҿLJX@ kJ'،4gԦrJ8&sF8 `{3bgd8#2AɞGfW~pPrFEcY]aH;c[Ha3"W9jm y)L:534RoNm['S%' aƟL۟rG(N[Hܺܐ Og$6 D2ro)dKZځDsFQt 8@)϶p@o;H8%u_$*yϕpJ2-M8J86PC#`:! yC-N1=POaK$H= ii;Sjo%ݘz^\U+(Sy;!0᫨|B*jvU g5pRMyB*۞p%rmoH>%cdž^U~yNmcaO)POsKDf,s{™XI@\}9*DLKP*!&vՔgC#[1)i_H#|;wHlzrpW:)^ 7fpB*3±=Έ\y\wGb%_u i9[DoY_ w ? 91Bl<#s: q'Sw1V)/N ܿ@/J83Zŝ~c+i5{HM%@ ؒHg$qȶ]!9!˨ߎԯWI>67N ۓ ]G'FLlzGWysGixl%oDd%^o#Qq%USO(sc6H\aVi'3Up6~EҮZǘ C1*HqN mP1TuܠbUzM 8%DUBU]6(bSF mP1*Z˦UBZ 8QVJ42ZADh5V * s{]5H zkP1Tum֠b2(R1gҒh 2sە+ "& $ "fYTy-F#j0TuvP1*ZUB^Ƞ Ti:B&|ǵeklUلUvH#*YHV TcI5iTfNB]nNmFZ *<<_o1LFU^+o+/q׸UZ%dRMiBȠ2SAeݪ/7_v *U0~y.yWWZwh*!*L-FU\Ši#/a%cP1Q*^aT 0Ƞ߱I5aE5yĠb2&<}<}Y*kXu!15qmBrjNaP5Nià뷦jAyTLαeزsIfaPMX$a4uM b2WidP~q_SȠSOAU>[#ZE+ JȠ  6a9 `P1T̪ǫ JȠ2SϮAe; Tnq62{;h%*!-*U;UuEb2V^âYZ%dPyV |2AoPyIW dPqdAs'ZeNi?Z%DhV Tnc;Tu̠bUu14qk@kҬIfGdPDęF7!t-a8CiЉIj3me uy|GUZwBM֗LJx/hR=wR1]?UW?r8Kav ^TYz*0VU'ws뤫|M`'JqJΩ(Ua꤫7 8τE0Cby?}xkp|x[Mr77?< /o Ε8Yf?([-Uy2LoE>0c,Ar%<iPI' &dCi ZHP t>FK"KnB6LwȨ¥.'FSz&"ꐣiW_m+4pR_mqHNcRupp =PϨw; pKNhQmEz+4A*" Hu6{`I<$;H)C=oi%uO%@] a 8[뀀OԘ "64c9M)mn?0dNefwŀb;@2F` y3JpKG" MANJsXޓdy\DH `X1"M8`ބ-}nX <˚7! ͘p8urLx]D^g̢o~` 왢t˘R kɰM a j\D=yM #nYi1=P=NL͞5G['& nGNr](qt.fO3[×)=SL7Yٳq5SY[{3wy8{\)zk׭!s,4:L#_m2vO6uHDe:CS.}:Vǃeus c`2:rHԎ"&JNhv:EvQ5(:Ѣi$%r~ddE'Q~v2ۅved!]HG:Q0MDp(EqD g N.DLQ0(N,4 DhawE7݉cG;Ѣ{ bEq4m;Ѣ4:(5 Ѣ0ΎD %A#ZF%|;!Zҩ%:""ӴN(B'JT5Eawd!58hQ'uD9Q blDB.O%\Ɖs?eFsp:Q0MdDp(Diη(QNDvEa;Ѣ,*?lNhr;Q";'FH)6E2(AvD8Em(A&-֎uEea:Q"Gb IA_`Hsč;Q"Hq'ZTq4mtۉiܺ%2f(D8%ӴNȎ-*NM:"3)(/HiA'Z4ΰn@Ip?A@KjWv0Q"ht +:Q"\2hQwE;AaF%rhv2"ʳ aJun ( -,pV1n ahfL+\v&K5qVMrfgHIB> 3!,fLA5@B*asR sKlЄrЄJM4!+oƀ5p6:hBX,.E*alфTUc&ŮR4!bfLNR 3l ḁ6{iBX '՘g3M42RQ~B*a8i HPV iBX wh V1u_ӄJk5$b ae6[jBH%uOMm-TR{c* a3\m5!j,S-V1ÓM7քJwTf&Up%H֚V +ޚR ý-XU5!b&oƀ4vkBH%Tz&E2 !Dj&E(&T¬[6!U՘;"R5Md*fKM !0(1 MCJoqل4UekU `!Ye bo)F1I׉T !UcJnڄJ3&Tp@U&sJnqۄJ?nVHimBX i*fP-VR5V^_tMѺf 'P&EǪbMHUufM%pc@As͆V1'$M՝&DB=7!bK]j&K( !0\wz]7i]7!FK5M@1eFInBXČƛR y*aKlބJaؽ7!曐j 7r2IS+uo Xèn7l !0\E7!V l !Ucl߄.JET&BZpHW*ق"f9ypBX%,sy&R ۑWԍӺƠjuoBHd a3ZfN5[pBH%݃*bدM8!j,s.V13[&nO?IRԫ^pBH" ׇtiz&Bᄐe5qBX qNj jT㜭8! !UcKk6㄰.ftL5qBHE,]ߵ'Tn !UckㄐJCy6䄐JuGNHU5}ؒB*a {rBHXM9!'tSi9(SN:ÂUn*aJl儐JGrBXE WVy>K/Zn3'U|iRY>Tj7'T sBX{*ŝ*f57WM3'*35OL1 @Ӧmo#=.~Fqۚ=zp;wmvdmܵՃ۹kqVn뮭][=zp;wmvmݵՃ[łksVn箭^[,zpwmܵՃۺkqVnc-][=zpwmvܵՃ۹kuVnqVnﮭ][=zpwmvܵՃ۹kuVn㮭imc-j-][=zp;wmvmݵՃ۸ksVnc-][=zpwmvmܵՃۺkuVn㮭][=zp;{m6ܵՃ۹k n뮭][=zp[wmvmݵՃ۸ksVn箭][=zp;wm6bܵՃkkuVn箭][=zpwmvܵՃkqVnc-^[,zp{wm6ܵՃ۹ksVn5&n n箭][=zpwmvbmݵՃۺkqVnc-][=XpwmvܵՃ۹k n㮭j-][=zp[wm6ܵՃ۹kuVn nc-][=zp[wmVwmvbmł۹kuVn㮭bM^[,zpwmvܵՃ۸kwVn㮭bM][=Xp[wm6ܵՃ۹kuVn㮭^[,][=zp[wm6ܵՃ۹ksVn뮭][=Xp;wmmܵՃ۸kuVn箭][=zp;wmvdmܵՃ۹kݵcql?7qeHdq<6G'ub[TVXԦGۺ9;!xx[7_ۺC;5̙n.i7ydٸHm\i#*uc޷9by 6B}yNmxm66B}f޺7BOLn[͜yfyfSuP[7d [7umlNmfkjmfm[7[x,CB6zmlefKjffμw6(޺!8C!ͮ۩y#dٹD훶s3ti$=5>Yvnefx#d޺`Ynhfμu3gO ͪusA1FȲu3oi#dٺl݌6B# l݌6BO!⍐eD{xn6m,7wF Gh+g޸aflT.Ȳos*l}XYmƆ9,6gx*91=J ˾hg.ȼo3H ˾&Ȳo3pO/PPKCN/ȖM Av|`eO#$jjp5XR F U zbV`>eOeOASZ%=$t%];[%wt.neϙ #{}G=~zcڠ5/ONv^3VFHwuvBzC-C;?.9?gyU\@b~nS>g-5 "/.oz>W/:z~o.80zşrS5At~zBe1f8ؿ:\߼y@WM%(?(/˷߼yW'o߯?ëɤ?1Zޡ^t'4(4o/Oq%/$q%E緯t<(rF"QxNqȓpqĠ KZ</~;ү.TWP:g'Rv)hQ~÷~w϶\=G>z9r}w53CHc5lܿ&4/vn)3dƧΞ|VY@a+pVý~WtyJpbmKNPsTptQIz-(TvC%4<* xzB ]a7 ҙ`Wȋ?{x@>p,[HxxPE`Ie"(Շ.aBm9iqb.u3?b[BW>Y z35}hUp%TlkPWMLscqz:߾M[W3d#Z:\ʏitcXgͧJ*XhM~q лzw;spZB@W4KgrpJ980i3])-"v6oӽ,Qn|䏭Ҥm}ᄌ|+?iSZnU$DA,xguz|hBӛw_yd__f{M8fc9ԟfjh7 iRu60ן࿱/i_^>D_v7Kvs~V ^:Wu1-,h Lo Rvq <ӧ[?:O@{a G &>Lq=OoqAA\_ibIU5MKzt0Ǹ?4q=+_;ݿgF.򝻋9Ϊ籚ĊꅪrQ\ k47&(AUk?#H DOhXCwols_+rGr躔.O_g_jPZ'~NO4|Zݿ+ӥ܁|ףՠ>> ͠qTmLo>5;S]΀ݧ0 nB J|<|/!40ˠHByj/#mªc0vPmy8ݵA5^Yes?zlc(Wc $H:\_)zOa7zzBݻw3(weZjCIm[//Pmˊ;kQSg/'.z1Ay$1}[uO>;\T)/.<&B *W> stream xWiTTWEA݋"7(8^;tD Ed&62 2 DMhˋt~ иz;011㭳֭Ssηs3F&9"?|ܙ#B)L`&N艗X{c8\oe2=+"'D q>oLI|:7C"CzD veVUVo޸{_o_ L _eTt̚ص8x͆7= 6gO9a62/fx3[tf0rf;ɼdf1f5Yc1 ':cKqd>c˜8f:1gb^r%fG7?0(lU֗Ͻ}jQnnjNr:<}c=[Z>;~㿳ƱO,u6S(]( >[j&f+< z4S#KX!@E>PՆpOZ), 2^*/]M2tq%N?EO%|&S.uw=2_\sV \tTd!~\X d:VZOKN + )в0Tce67Io_6 KJ.ag@'[b;~@X)ሒZ>TUM./8|m&t5)Ŧ—Vv9F+Q q yS}䵟,趰g N|9NQ+[wZ]u!T|6=^ĞKk%ER0 /N`lLJJԒ8x F[-8BOE&d+X s;97_g|5oQ8ɮ%Kq%f$.Ye)?{+do)qC =|\ӌ8-i :n&݈/7Ć x\*%\4ƕk/X @%VE(rU_(]̬䴌7 :1CUaLυ(^uҾ!>pZȊQ(=)Uq.2_oYXz2NiZî U ،.&~ߴiY>IA;gޡGGTJ3aP˟<59}&6\{isp /7<C==rRH]%)Y4hS,o$ӗ]%2k=~N(qo+Ɗ F8D5sJ-sW7i {|#H`)Պn&誔f@fWuUi$EDWL* "k?`qMa!JPx?O|HYIDM@D[-5)u^t 6ԜhL_J6+Q1tTA}S3'UC1i, O*/>,'=iwfB3a8hSObsNlRVaaC6B5l7)"@`, ntYz%sɼD\O<{RBT-3$1+2c@9[*,A5rP|sp0u᠆1HTO1`tŢ;Lujᴴ@PO~JG=`/P=B G Վc*r]jK4,g>$ׄpx}^_ɖUUv%J0RI 6GH xp'iӗ;V*5"4-9V+<R`D`Ro] D}F0M*G|FgYY,GK 9A5Dk,zf$Hr Xyhѕag' \bU*Y+xq\ .Iz}Rl*΀3d2@UYY o>P[zm%hAdɄogTӈ\>+4OyZ4"_$B*jIi{&N<ւ H}X>23AO.F6P5lưA9l+,>>ReWtgK+ L[?,s(JI$dZ'~Љ,oz0d[ރB2iStQ$4505B_G"lyuUh3Xu >!: ekp.ݯ7G~5aDnV'RA+>Q|bU8!O? oI*R՗22! 7ϟ_};USm"2z8BⓏ}TFtc4o內2L2>+~ş~ /NxdԚ[L6CKtCg;*ˎ$BPmw![2hSP(3?T1bh"!Ц KU?<<"M,|GXb VE^Y8]_ Qdk_awɫ=PGyM"o]#q&d_9&PLԄ>.{!z=|({p!ՒӪnqbW)hA_1bkeSRQܨL^:ִ8~XuTẓ]Xb}rj퟈#3xiwQ|+-,M }&75VCIh3DAd@U~2&@[#p tc);5 hmmt}!Juv+"[$wxj q3#‚"70Ԥ ZIe V%qL^wTQ{q 5)ցuxʮPf1)2S\T y+ƕu\%ݳٟPM* qɢiF ̷DXY윜lCvA~]+%G 9\1 ߶g1endstream endobj 178 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7902 >> stream xzwXTWrĜލ5{/(]"#"0a{"{=Qc%b |%11_hL{3g]~׻V@P|r;?'_\CWV k fU]MOozU=)@#`xvw`qcǎ=jn=g'/ N۬Y>z_zju:>Ozw}0/`~B. sZyYVںtn{ڱ6Ok)S}4= om7ͣc>(jeK VRUG`ʎBSC0ʁNFPk:j5ZOͥFSyj#5Z@R6"j15ZBMRe$j95ZAMzQKT*$%՗Q".P۩NTg!uQTwʏAttVtQT8Z'xbpp.fJ4g 43|ɩsκ.JjtfY= =4Y 6Ir" H$|.%MALOԕkT*0C :GrHΛ\(CCD1LFj(fz\C,*^ {޻.x́M[3?5_fM_O %,"oAfdj\"e4[Ӎ3/e9q8򽻌>@ލjQIѹgs^Z RT gE.>\wZ.m-ݓdsA|?,K{&c!#FvC=EgHpxک8K))FJ5}4f;ZAe3,佐wýF`?DP#.wpq cpN8td![˷*peH7P!zh+0E3!-J%ZO`Vu{qts Z!Ru$(rM&KL8nluF%xI@#)b9khG__ClOy;6]gx17Vw2 ߲:ΠS"u9KOZE DW:nuxlf\K? x?Ł8,1/'Ԝ"%,4|9qE2b!_)6VV/%YLwG qDQ/E3<&"4qhZ)p0UCN~/ƣp-+3& c6{`O3ʿ&qJulTHr#p\o_k+/$(*0sV uŽ kU7*:GIZkEp cYG~?eyMPah{g;XFC|,et"?bz>% +HԿW_?`y%:}H@Wr ðOag'eI45(՜B _.m.#=G*kqiCul= QܶC^Uij@U#|u FIv V319s$7PtI@@ɴ"y|$;b8;:۳z[S}֢8Ԗ7>B&)6jNLIh۠ I)cbΰ"{|iu@HM1:>)r1DA|KRqj5 8T}@s aDTPܦ+Z @X+\`k,'t)M1om5-A_N #^'q ; xيl/dDj⌈SSr@uq}x24F:$9%F;(ymr&ej0BDLL\r$]AX_ɰ R3)M4(w'YU M-rk"wq3Rvû E3n uݺIK:b^p/GS-wK0p/ 'vM rTY gNA (s-w؁3`F udTGxf`lVA"3Y!mW' dpSH?&)Q)YIOBJC7F|FB| `t|o`dK2;:b"fd^Ns&UO"n2H4,RѣӄbI-jeok%GhMm-w0zp,aHtjt1THl $ɰ }l".Ш8 P>_uDB.dULhJ~j%w2+/mI|~lRw(yRJ ;֢NIP)gh2 \H+G 8{G048uBl<.d1\vPǠjV%/}|8/t?ERcDh`^ebmv)7Lm+=x$x4Ǣh ƣ-ܠ\1.Lp$5Ehg͏y8ø| ]+@W>"ޭfIks}q'_9r@y\tbx2aUyeܻgo97}4+ )/?5ïME3hQ_ ϱCQs\,/EP]j"e2>&.(wvX,qr҄XYcG.T+<;Ufk+0s_FQ矎ߩ<[S VQ *P=TUZPר(knGJԥݶF)KLA43':?(0%׮`?`& UuN^eVz CȤaC?yho 2w#!ˎdppg B{*۹O3C=:E'S $Eũ%x%' xQ$7Ԭ.zVvaǢx(?} [>in܍-RM/U};x"X. {ܽ|՝R/qdLu&>|nBFM81A i,6bt%CNM.~M-&QZra~Wܐno_Уi3?]h^.?Km;E.Ai-JmnkxΧʹq6s_x<Ίn%[?w̔kUu8PS7i*uVI9~ٽTN#iT5,&|֋yG!a5%v҄` s)/  X{쭋ކqh^PC-(]'4׉w'Hm&ՠP吙T2fSC[Ԩ+h$fkz_ 4ݾzE_>}=[ؙk3UP"f/S[^ߕ ]/i<`G6:dWF䩈~-pbȀ} I*'hz"$##,s_ãMH 5L"a۶\$bӱhO(K Sȓxikjyn[Zut+5cx#tEZHv(r))((ɭء g;a&&G QwF>W_(2 YېIV- Se'i8ԈVg G)RI!ЈTw씳P,m'2_|$'dM&VNKAS ֚~Ѳ*NA³3!ZD+hhFB~+){ <|'9c$̀`VMnSeɁ絛܁̔l1B]|6X ^v'p*B]ne ˴fM*>(F׈ԓ$Y}1bq7o9o vY pdz\)E㨁WtPWB"|b-:IgyI?|*}ii,d/10jc{sj^a*+yU5{-xZVUAeAAeAUUeeUck?ijB?XC/5E.MNO#gq{ka-hFXk~O:4"Y'N|Yx9~"90VQG{ɸ[7϶ \8zBzXB| *lb%ANJxA@es+I ?vLL7ңQɓS3|O$ Oхhf݉Rgx@Ùk&ãJ[};inDg{ft"^ ՟<^RgOc.˳_Gp1h.w9A**d+> Wфh(]+>8Hk[C婽su1NڷBvĘ뜄(H0{FlVnrfCz3'%R87Yiz<دttML|S''|b#GW#aр\XXf0#3+G+w^Êا5ZA[?{lަc6#۹ k3w"?@w|`%ޖaQ>FV/7|RVWus oVV| tjǮkJm,DijB׮FM:UѤ&wFQZ endstream endobj 179 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1659 >> stream xU{PSgOsTnsN*ErQjc1 &ܓ\ oAn*HRj+Vw]-eNUuoq|θaw3;; AI$ 'iVFfͯK$b'TݞK'x{MCrôŸ՗Hvn rdV\&2=TeUqQ\07GfFJUNؗ9_ۯJٗJMOJVmIږ=yY{GQƂ"MFżAQPT JQ͔  *qg"Ar#;5^K ^xˣ@0AH/ Ɛ9i 8 :8V}H,d:bDM `7>RItc0afɷxTI 4xN*{!?C PV@E(z)/ C)!6ɍw ʭpnᵸ ڌA}sAsA]0kP1#L@nmm[[A`o<{ڔFrRc{nh6Cߖݔ !$0'0?=liW PrXW^e'U]z8iӝ_@(0m7(0Y/ i @SQ4fKnnp d5S;"psӪ߽ 'v#~\YH*>eo9sh^sGoeIDvlMn~ᬡ\ϝiC0Vd)\?'^8)6=&Ǔ=(Ge:Ƒ헬n)Sw~i@E@E 3YV_C/Sfh .1<5gi3TBoDGA7T炔d/]$U&mm MC[mXl(1/'^ lhM00i h|/ߖ0%$n=۔TqsEB>~t.fzldRiĵ?DN3J؝%Tڬ!cȏ2p狔1I˒>> stream xYXڞvvDl#dcEPQP6TP{]z?{ F؂&MLQir$<vXRnK̜=;WD%&m}{g`Cʋ"5-u.JΥצ &A6v pwu 2Yhђ Jp&V{z9bbz6Prd!/_;=&;m7ؚlپs l𘢨f>{}1"pS`ːC[œ8yW7w[;ϝ^ދގZ$z﬘rՌ׬}/XEMS+j5zIP([j6eG͡vRoRnjeNͧR=ZH6RoQ"j6PVRj J-m$J:@dʑ)eHQڔ15S4:SRj KVSz8j<52&R?M J׵nij_1IKAgtd C}SX۱gt]?c|̈́)B'# 6M6J3cdyS~Z ^y /79RYdtj'F  ۵V$$e( Նd^ExgB!.nQ{"gm{yB˔7riӠo84koC7i90f~Qk!pGv,1 !ӬP. ^LZ`s$~3@oAZY?x͛wްZ,0L!GXp*XWcT_Qy9OHFXA^405kJcB\t\}d0Xu '* 1s' \RiVDfd+b:QMŗ{9rlcly)|9L![rS 0!^2`MX½yeKZx}d|;b@7J-hqs= wW͗j~Jrpe0ix2i,X3"˃S0eda<=<.U E8~-N61'~=n骫bOQ>{WXد\ifuۊO^k>QU  ܀DUH(o! $N((_ ݋t8l7PQ/ RmIMRʼ58R+h*D@ Hr1'VՎ?*aVZҌTS&2f|-3+BS[]4G^#$nI;eP^ȭQ@]9TʵGġ0W㙳'{S1iloRo,>#"3m(tL%5(ݠo\&I$b\\<-z'W#F.\I$ h-(*{\/5h^9u9)>Vec5`c]Y( >ϣAfF41gCcݣxez3Tl`u` VKIoHy">_L \%qHӭm]lB<@Wf nx49x"^&>L #a:BK0'}EeܗX."lKROZOt( !+HI=\IT•IW9rM2t \4#A@&ra\͏-chD/t:*&j!$6}0 R2B(MsMJgPNA5m ٓ~yu O:)q>()2.-4OooudԚP4íJV{ӑ6ݎ_[ =}P4C\JOz5f $B'/$ʄd)%̛"ߌ c\}|Hǝ]iqH[RRd;?(x*Q?VX lT✓PXJPi~~iV[|K#xAԣnUdrƵ =5Yh0 #!Cz@2"!So➐Ta^xa]Q3\n)Cz4DkHDYL{8$l,GԡDSK3nsEev:Xaoo߼}N/z!ѬNBjLGT24N92e_ 4lL-q+OoDFYǤBnDdڿd>' ԰D>xx_dLG~ u{<7O]xó 0Ut齾o#Ү`F^4UN4cklO5~` [koQ!k!vgbĜQ?Ut1z:˶1aHت`)\殽"]{`)kFgz Eς~?*ǟ}Z#uCgRU.%H0^=7 foJt20 nAy I]~ ̮|x ]r5La ))!W0vڧY](ҭL( "*62>Đ3m5^6 gLPW=MyjFF:E(bJvZlliz-2FٙمYiǂz)ƷD4gd%"E7cmqCg/͜+N]|b.(9GӃgCj":^p&;OHsEg.]Gu|LKPaJmX7HV˰ՆC yWyVx7GE;_wivF*WʜXIk Z+(zA1TwQ SbRMW/|@)HlYsgKwܱ>0)DzezEzPC UUmni{[yhӁ!&Oƹ0|!8r:@H5x2Fً>I8"1A!A><{ 3<;9CoARɷoD޲`5-OTZޗ~kPxF,"Mglw]ieBaYil> Qr඙`lգm?bW` VEXa5k@,ngx9A2Ykr ZzaI11ɼݱai!iȗ L.=v\HN#(Bmm8NR:ܐ[ :I rDC0 pW78$|yO.|q}q̍OAo<^ܥ98$>/;sC<~x`F,oOHJF2#eó9fa+`/?5}dt >Bs>}mg VnXTŷQλ:xGK=\lRa—6vkKsr*dê<@/P!X<<26)9)9 8$!Ƞ(`DE͍奨IILItuQԄ*ZjQ吘Ľ{L}j|wޗDѡ8 fP(QCGfM[hyhjlL.ztO^`{ă $zTK{${Jq$WfMݕW7O[a;[?%ZC㏬|#@[M6:ѿtgÿ!߻G zڽ;Ɂ/7~E9+XP]zy.c<;81ɳ@G2KVGz|\}f=*eק6)/ EWT*nHgpw&=4Tʫybdȣρ.XLPTY=qϬ擦= x#<뽳z͙;![v}&+8gchγ֧{/+vKK Ya٫_+[S8+ .{~4 C>Y%0#*+5ʌ O\3gG!99@!ɞI`ϯyYj{9($<~ l2,K$0I :\wsK6% eC=/&H:R%$ǠhP~SM}qCXR /;KVu b V{18JTu!701́)V\] L,T)m?&UD ;8] ܹ 4[b|}QCj?LudE,\gl\eTEh`b))qi((<>(_7ef 6x왷;#1:_u${]L{U*XT}?KEQ$PI.(!M@*&<}2,3yL]DdVTB`Ԏ$j|0n%1G%F^R}PSd&GLuIe\+N',k(u:[-ܸ> stream x XSgoKbo5]eԶتұv*պ""jb ,BH YN@ؗaIAԵEj[y3t77ϙ{xp=w1~p]~SrRhoG& >~~jinR Yg@ 9:Y ;t؁L-@j;pz:9\RJ_7C |P^^L-&fWѣb8ќQj>-KСm-Y@@LfXNEB`hBK#ƽqA_iƸt+KGQ%Ӂ4Dࠉ(f)jJȍF`eֶ3WOd02(ZL`fVz*k(4?͞PLNF(YEA ZܶM+#_r}8 }ݢ;idwďC2qԽ-Z &FOJ F,eͩہdCWz;MLR=d&Щ<j7B+ӊ+5Df9:L)7Z;o>^^]urDbZ3p%苫8ϳorR3$XL[,V}U&hZi\#B2Xvw{\?-N4,zܩ^ht y9gAP(Թ pYgz83U&&XˊPTE&Ź)9j ^VS7akL &M<&^)IճwZ[GR|y'G#֤3:jv>Ò54o0]iKV#놮5vhZܜS_(~z!&??BIaʫ26H#&؏PWs`o]hFDaYnNq{LeVۣm2*-Piib.>xUXDE`1g.Y˹Wx+Z-)?5S{Z'{2T4DNd*45q|"+I)Rh7lɢ]@,z!Zg*ngļ6@5ʡ:?ͦIݓ"aRSCz:OUPP*=㇃o Fe]w0}YC* k=Xl =_W2"PH D1Qatɶf$Z >5ܫ]X Ȗ[/L/izxKX.?|?ݓvSgQt}Qa*?:x6U+0`9=o=mϰ-ur|,UFx 蝰È$Zƪ\P{%㦋m QР5 `*뫎GՕ/ u'Z,~Wؼ;, NuY hጜ0a;@Kzm}5F)S05X2Yy'.ˎ;.;ӖӃ+} R!Vc+_S.h/k9Rד}-mFy_>)RP}JOcݡƶ3ĔBurCX$Z0t3.']t^f9iO:4woлV}HڤL@:FnU:S+-)dJفW%j=mJ26J1L4DcFoםktW`cfL YZlLL;lX9cuyBRG:l[߫%&RQ5fTbB}kuMN2\baFɏXKV}#_w:дc;2ceVD )I6ۻEtz{3؍?U;Ǩ|q=h,Q+|paxy6!A] {{lT+۩+l3ji3{1+Ue&`sQ%⻛y5䀲e`mn_j?ۉb0oG$~Y * z@7yΔHՙI|3ϻ ~>k*42ݼx ΃^;,ߏ:Y_/n:ׇ|k,gosϒ {ivSh3`H6gs2^E,5,wa2 \GʑE49voɥ o*:eWs-v9i7lhzR}Q{f t&;m/DY8ޛþQLB 6+ZLPKڳK$iiY ;2;Eq(u^UKy.i;|+i$I=EfTW64Զ{QȀˁ3+rFNHl˙H~C~?#_fQ#Ycw%Ą0~!8vwHڑs ֩v ocxZG!{MQnVE#JiisJS~xvjUW2/U~h Rl:X jR1ѝ7jh }lRh#[wi8oTK F#Er4nss;QBJU)tz`xr`OK%0 9ۭ:Z\7^ t;#ճyFR]^M%FYٚ~.4׷N\^a'2dxG&.OׁTt! Ff.NHHJ?DlmV'ǗʋskʪlF-w ծZWًT"ÎQ=fGG~lib*OWEk4tNH0$Ma7:^~ VCCGi P`)K|G>;*Y!HC姅go`(P煆&W,ei, }sb$A?;yĴ?͐(!T(k-dΡ7J x# qsrq둾\G.R%qX5~L};"z;˵' ŒfG'tN&>vRlG4+{S]iNqNؔX\hT丠4ZS3hQ=:({E:J}n$SXf2˜5vUt\*&e@<9s -nhvV*065ؕLjEo(ҶR3\Q pGkP8w)u,*(ʴ@qd2>:[Xatml(ρsSc32<v%ъ a5;!:<Һ})JYÖ;7rzP2&qg[(,e% w'Nq9[[ߡOdzj Q^t9e(~PR0:-A$ܛ_W[i+2ѹ-ԤƨT)X}'z{@A'9"3v`6ۡh6=:O*{'@Vf^ `G\JNΰWCgD7 &ڍi]Ud4 n1M5I{Wendstream endobj 182 0 obj << /Filter /FlateDecode /Length 262 >> stream x];n0D{7 8A PaJ"2Nx%-?y7#%UMk%gϯ~`oG۔:}OWNi45$\ TBCH.f D) !'XFhߒbm/H :R d ӱ'ZБ(QG]@=!4$^:ԉHgҕ,GΜv^_޶n2Aчendstream endobj 183 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2787 >> stream xmV p^a[,9 U*P`#)&M 6lɲdɲuouYC0Wb ĀI%i;%aJ M!i*3t:;3_}@p8l$殗 -]=piP}=!:'  )/NSQ4b"\c1늊ùR%KL`b#E#y(KałErv0OH$r;v=M}έi, >?*,(ff_, kJK˲r__Bo&A%^'vb/Jl ^%6S8 N`!~hB8Ή'^rym}Cؔ'|!Qg|;*'.-3-xHZ'QL rB:A%mzҕͲW|F\ %įtEx s?B8 |~Ѹ5N÷y -ĉͭ+-caodUhA6qc|9cr" S84>*SJfUO@A<7_ ~5X(<"M }rG:FSC>XL6JYgh4݁~nI ' d`W2vKɮxc]]|?'ɛMhQ~-kh.ϧfјsw)VkW9[lnC,o-(dڧruT^•kL :kVٗ}E4C*M sq?ՁEk3WXTӸO7}_x^IlSʵ߭-7@+!rHE9xN1Zy_oZۑȨs6>r ɅўpnDj;z@:{F7< TaNWYdo)M4`q ʧ= e&Zu4~I.Ǣ]| F3h%PLbWcȣh냸(.QJ$Jѫf1 yW{Ļrs^~hU3H@\a_/1 @Y 8 6Z XtWaA+V] JAh {_wt?P)2( kղné+-#]w:,8˂8a{Hx:iݏ V*_Zޞή;?Ew91໠ +Lr pg[yrwIՔdtO'qؽvhsnݶ9X@of nv(ZQJGs;@NO^D)(gf\Z[3,4<% J"UImFTj/ԜEkǓ4+ j؜9C_D;м{a}t4̼w )̢-q4e%JrW? Kv (?@ QĢJ|WOu^LK+(_slV%gc; 4Z 0ksAEJաpk=g糑#qw8YF @1:'u%8U:V.>yK 'ɯOE_ԫV )lqa4ĸ)ɰU7lNe`!.0um+.l6[hZk1}GA>]B+J HkkK+%XfyQؽwgpy&䡚/< d,Z4f%dRٛnOck@mia V*d rs>C;xm%M"QIHTl^-C;sp`x|A|,P(ΰV&wK~>aE2M1xoEb1X(žl`FVJlDb'|VGG98/-yѕO"@U:V0Pp-SyxCs-Wϵ =/X36IH521 Wdz4fΈ6Arj{ 0 :4mpq>p,sl N;nu8m]p9~ٞCzO4=+7;?,u7k; S'~wъZWPCUiR"AgЙ 6+XJCwsLUk}UW}2T2 L T&J{5jXX HIxdl1Emf267'6ܪVPWյ^C!#=YR+ז00nV׬ҾSNpXEzj#E8ss3kZU̚6+?An(6c@Ϲ w,8~V4pt_ p TbI 0cw8 S$%53]݌='M&αendstream endobj 184 0 obj << /Filter /FlateDecode /Length 233 >> stream x]1n0 EwB7t \%Cd 4XgC2I owTjﶄ_Zm%6,NtsX3̾߭g~6RX"]|9;Po[1*dQaE'TX'ш kd-*dTXAc@@E94$84$yءOAo}TjƆkkTVSrRe2fx;endstream endobj 185 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2186 >> stream xUyp^YXФZ) dhg`mcm|ȇlKeYJ]Yuۖmٲ@%P@Lh20d2iUifٙ}a lYYvQA+K2r*ǟ<{)_>|HN<3gƢ"hRX!-U$˗.}idBBiuEa$ddmJj$MZ-HKK${sK%[%6(y+#}Wla,5rR(,~6a Vl1&a4l6c%bj6!1 ̤_$}& Ʀ]Ly>L=EyzVcV@TfUZ4h|u4 腠_5RAWU)0%Ir >h" Y.SgvA](ol2!XJy*' AY9Kc (V+!Y*!8Ԯ>u-_%t.ע5Zm:_e#SNIbvA?D"tC+R@U|ӱxLr&{sLWYJ%j:QOB%0j f%ɊuycQQ rS}eHgOB8; 6W/D˜l\2C3#hWѲ&d+eeji"o=^@ih:.PBA Cm} fPhMJ6X-euŪ7(l6Q)Mt}hRM( ֨%=-p&lD1d^F?G%ЁZ`u0C@Q>Nm4 F5]:HQF6ox'O;|p.kA5^C/Hg籜UY_!>ZWX LU2! @:>+hy좹}F|+?;*W[FUa!7!@&xkG;@9whqdSҵ~qb/ Du1hG h@wht/u2 Av ?ϫ^ b @=vV+KKd]}WBI} Zi\f7<i`<Fʧ7Y*8d궃t#}ݫk|44(lS6J*+."6bQ{sjf_7}+&ޭ Y_<<mj]1Yt }ؤ2q.Ʒ;Q$|x?M@R=D~l) VIy{W8&a4@#NCNi[j%k@Uw oWJJ"J88 @ŚsoQa&4Ye/3uh=D\{x&4lRuv۶a bCFyeY+vKk.,2bҢB]0Q`1qIbV;Pk`O!=qe5~ JdQ+Է?s;42U棯]Ǽux%;7p 5;A4 7XZ׼vB2s,ȇ򪚂,Va'=|aGy$ ^.4\ɂz_su6GC5g->l ܎vأÃўp!xK vY&M5b0FO֪lv|+ 3NJj/<Pz m󫥥Ҡ=TLY,4 Fӛh:15VAdLbFb4y:$ 3 x$'w!6?mOaendstream endobj 186 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1811 >> stream xeT PT~)5 `ޛJ\ד&zAP\]DDnEFfg!Ȩ8㱬+nV$$jL 1b&~lJE͡(5UN j&AyR2J[|w2cB-Wx(b";\!ʜc~JofPhB ̫gw ܫtzOldh(7] O&HɅ{_[=Z*")>ǖu W{{޽B؉0.ph| f?Aqʭ!>}` W@3٦|Ȇr3E+5](,o U~S C[[(m.P"mγgѷl5ITQ`X" |bBVz*31JHşsFג|‰]鐜êjKmQ_mdC%삤d#`Cdć0?'ڀ,B=/{URaŅ]3 L<CcJ퐜1~?OiO(6~axv^罷ŸGU*>(]aS7Q1 OF:MN]mʧ otJ0xT0<<'-?|n(e]#~`6F'pqjSM5&d*xpfB2w}Nk]8s 2}>JɓoY'Q:.P+kwB&Qh;XK p%ï2Yf`gpA<`cK?WzKE 43ϊn/.{{k}?,zrUXW[⇴jzpSΠ PkV}ҍJ]|]P %uP`lKgoԵZECTAbArj~S7v: 6;IRYL=/åf* C[]1FtT2EV+ 'Ud $KJ[rH!G(ka cySKS)Re/2ՄNhgNsdL̕)JZ9aB:woT+BI x >蛉рK#b$zmEir+&RX-du"&^65cKD ȫ`gmGyzM%0::ł_ )@RZM| <;T`QC [pGgv=Ebo(tu`NաpͼΔmߞ1<fb17X,MoXy?bEQ;endstream endobj 187 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1141 >> stream x]Q{LSw].0ڮoof؆nN@6`< EVQky (ʫuP70YP$h%nf>!ş+QINrΗ;ߡ(JQ|2'蝐ܲŒ}q%{+i BBPРPa^^ |>7  [rP..#7蹌OP.7z./22 s8>e⶧lMNb?ޞ6^!Yغ [ BJBj:G,B5H6"2je*z1GKl;}{ sPw]ZW5WͥF뀨`wH9v6!צ'4ܱNqp.1]Huê|CtafY?|6esN}a]:98QE#Mh1ϙ' n:Jb63kGI00R;̳NiN)˗ wwMTM?L~^)4SMGB0$ZW`^)goϲ 7o%N$ai_챍XǴ`b_<-0Oo|{H"#Z"~Kmh޷\J^5L;0 êϥ͙gmsKվH<#5orn3WsI9C#}OSS7cU7l-ʨ),mNhRLUe'$&ViQ~C7~94ԪFK YXݿyNAdlLSXq8]kNb^o/s;X.lo/ 6 I驇[8d>tD./ڰ(Jo/Ie UX`@K<RRitc:*GH=D'NGZd%qc9^qm64Vgr$HdڻKA%g4cTp&7,hacYڽr`j64BsI9l|$DNwnYtA8;q1KSEa_qŊv)!ge:^ üpBvM8l*ë(endstream endobj 188 0 obj << /Filter /FlateDecode /Length 170 >> stream x]1 EwN  KdhU;bA }$:|Ko=0^GrG#a[4'1rL:\fсzlK}{x kX4GT ڽ0ᑔ9Y^TRUaPg\*L'7[@W~ >b_W7endstream endobj 189 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1190 >> stream xuS{LSW-WLLҫ3qn2M8 ()Θ(ZR yY(½mˣ lSfs\6眒l#]G݁ɲq}T %99gei֘m5Z1eN!/U] ǁF .NEgЍE.}>뛿lfS_njoK)6C>[}>3oRrRz4/ج|`m|q'_oQ*F묁fSMmUINOPn[ "mtZ3'ə/8(MYiQH-^GnGޘRQM=Fft<qju=~O ѧ6V ܝNPp+ { 5xq ]ź<셾@?>@t-E*zt0q]`ӭ3kJ`c2ZoE#eA )cPKcENc"Fv(@gҁ %Gqc MїDe[j\@3r|v'@'&$1h iodڞD/Dq.e ]b|d216 T"^Fu\BBmI#y"J$HpnXGgxsMҺ3uhBk厭+ xE X;Д;ݬ\W$`EeTa)K6ۋŭ,PT59VKޖQ&hķ5llvÎţ#ugq`%iX7tnfNC@ɒ ++"su#oޭ% tN5"j 0Ť,hڎ.Zջ ]Bdc/<3NYWı'"]cQnsvplO=1{|sS  ȹh1 -(G zE7XMoD'NC<`ksʔnrtI];(uAĄ__<_U`͂Ao#}M%+  1eendstream endobj 190 0 obj << /Filter /FlateDecode /Length 198 >> stream x]M0=EohB Q/PʔtAXx{#Ƹ7y-|J6n^"p҆0GW‘|9*뫘kR!iG\腙e[8A3<0gL94A'*H)1z }I"ϧr͚BP16g]:bendstream endobj 191 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 724 >> stream xuKSa׳Φe@KNQPH%1,@)M?p;6u37휙S_-J;ytUABAЕDНg;K;j|/y aP3`s]+ژaչ.g\#HeҁcHO }:TN .Z-o"*49x}=CtUeeuYzhQN7[;]tsyK9T`ikwӎnGwo[mw:/'fuvT"8dv 0଱ i/ Zu`,¯ qgEܨLVD^jFEe(R35$ZQGk}ȣ$e؃߁v܎c5We].MR5B~*_A>*AF-!$oZ62ބOJx[#2M !>GfZAifݧ0{g)&;,u*tB0N-5G0Rz-x}Ţљ0B@`|,>0iWH !4Z<>(>Gɛ89'4_ԨTV"}R{9WSR/-!7PIF>m q KJ-(R\\kW>'$!]*)ITa9uMl,czj,h4}]?.]endstream endobj 192 0 obj << /Filter /FlateDecode /Length 2152 >> stream xXw6rAGG!IMM#6JtHڭ= J,&8 79؜w_b=~>;9~ul~~1 KܲQrB3hqM&l\e%ouWV)KQGVE/YmIlOE)%u"UnuQK` 5>YEM4ZF!a5#]jMcM[(N~oƫI%viȜ c.G\kn_ X9ZPN : Z$O3$dTchҐOE0Q%>3{)*D, S2}RNZ0찜 apWBΐ˾P'0xe^ܰ\#&M.~nM_0\ pm$5QV(%hMfՕX_k%5~A"S$fOZej;Y&|jwaEC[_+WMy9I5+6pPxfOH6W*tFU0y|s8"6׫oCh9)k#>B5 nc?&Ràl(VDSX3ٻq ! %smx%Uˮy |жRHHC`)J6JVP ľxj.ް` ^_^qi=ë%~EґgJD D,KP1GR9e솃֮"uGwC3D3!ۻ |݃D 8 G Bp-ߺQD(zr >Ü80 k6K(PEAb ޖZhDxfS7izXVpcioF_[_u7=Y lS<$Ou:l$d K~ CbR 9 _1_"R_ \Xp\ `V s 6eE>CuKPo"`<[Z5G[Ư dkTo2򕭤ooTAC?'xk(!1A~Ֆ.QЇϏS*XN=Zߝ0!Irffd[;}MVd~Sr6ht:]ܰ(iCoc:I0iE6>a= 6,` Sbf6zt+afGl$1k`t oEXA˰:q!=x ~ K@3,i;=u &[zȐ'ZW|kȞSCπ柑jC𠡎i cf /0,q[xO l.V}޳,CQ:ŋ@p\ȉ%&3E;>mB3%0W,@ B٪+ $T(^_Y<%'x!i?{97{wOyۚ߸6AS&> e}%@-87xW+ߞT(80Pn]!Oo՜RVrj) ҊJCf A3!˴L~8p< 'ùr!6RUxW'4y !@0_Jp;D{Wm9,<0#C-24I#g(l-QZfYf.>3ȶ.-[B? ˜7Gpn+rzn68p9Locq>և ]bPiKAuWHZ>"Lq8}:\!"ZU_\ p ft R̊^߻|7endstream endobj 193 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3630 >> stream xW PTgMUqI$h,w#3* Ⱦ۬ t+K, Nq1c,oqd˼y .z{UV׽|G@kȔ idJI#3\^ 7">gp<>0s':6 LAS @#9oMjZNFb|By.Ynd}{}"Sb|95L)I'8hm`-As|~y )i2eّ6DoOH +Mi\ [ bL!;.b BCku?xxHl"6$8C;'Iܮ y8ѫkqҗt?*nܑ/!7_EETYX1G5xNB/˘,15jiFtC0Adru&6RapEK'v{&@{N}~JMC%eg3 +:bKJV_tw H"+@l3XX/QH&FA>!Ŀ0HP kMoQ]?`|'_S32z K]TS92\ flwy\Wh#WʯEZhc'z)ɋC? 1WM?Tc94zYsĿ,/5Kvְ2K-p9yu9<ќ!/J9EOQI*+c>X`ba$1ŷŽ>^0Ҩ(VO?C[ЅH?Q8zBPSCzԓTkAYRvrs+_֖Y$EC_>^)LZyh.0tk7iDy'pT9<a?/*a͒2mNI{tu SC[3͌r& d.='TiK ʒl{jz'c+0=]ϻ703`eK2?+ ziP4*tn>U٭']duO=4N=$);RT5]izs' KZzSIջa UlP'6C+י йGg?T`ײ듙;$Xz໌ރppIZE!}J17Ebw$t){]s%ųӏh8=f&Wb&%r f"?yfgϱztTɰPl|괖m'/PV7?,.PUSV'2YGBu6/ m` 5@$Ū͆}30BXeTWLΏ?*mQaiGtZ1=/E(EE ++9g  N$>q"s'P`D'KF$Cmqb6kPmsp:kb뢔(\"lnC PKpX qi;@.9ĵ.ى 9QHQȸ$])jţ/΅;<_p=*L\$,_q*s5hdזL.7;6F4SVi34"H"PjȄSPmnέ΄lWN){6}|y۴j\"{:%:ry=dzYy=@clшQpO!V^8P݀AYVحa;n!ѭ~ݸlFy "Dg\Q K$ exul}V~$UZZۚ17:BEtdo4{_姖nu_h+Ieҭf lz)aЛL uu]GX|_mq9e GZ씌:RQ*r6*r/16vhT{3 iX[PwSIXsT^zj2S#%Ev́W ,U%';YKÁOΌ1-k|Iz(?˧#5bk $F(yhnPՄXsI/s?3RUq۟)4vCKP'SKNs2$BF&CfKo.hj55\@kmeZ*kA%5euPri6=:ݜJRi"Hɐk}y1Q#ȇQ  CEnO0NJA5EJq@)gzAc0ݹTQz=C' pՈmR@'/R \& Z_|3a9۠Uꯣb=u9DOBkƆ_gX_Xd ;n HWOt}/I-%156d&&7{ >{fRGPݳup3.E ~3*V=j+c2}pQӋtZi |w 0 3Tm* \mn/?}g/ϋbjgbJMݞf}`.PF ϤP.DzZ<Cf&]^UPe,/ݼ#T@U5fo?qd[SR1ahܷm ح 2GSU36Fl1yL" !0endstream endobj 194 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6498 >> stream xx \S׶AQдVSV\J(**N 2ʔ!2dA BAQ{k[r;H}mt}ko}kQGQnnn&%&IL{~ޜ͑{R'8(q#@1cS/yr>Ps"J̔1i>[0ggo\=⒤q|$ 8gC 𙑔72fO|OROHV-7ݼqKPsW\)}9q_+W%NY6m]tOo | 86$.>a估pSO/bgg9gnE=EmPS ij FSөjz fR[)?j 5N©sj-<P ԫBj=Hm&QK=BEPBj2MSq! j 5K-G L!0ۥ Eyj4HAM85jh&s*"E 6 ?(*ڄ!AE k0+hy *yh]sh6Zg1KE^kq6㰎<;P/ \O~G^NۚL\Ť3Q  tsWǃt6z6a& Cȟvos[ ?]7f!1*{tNǫq fe갰$h PL?8.={þxW KQpLɅ;;0XB˝5A0-r6l[t\޻&0OӝhM+_Bi69_ozGDQ_BjoƆ>qhh?n3$xF_(u/̃7M~惞KddmzS]#"2V y.Y){Gp@~?&b^78ņM6CE[-VM E݅v9oH]=b5Y?jlij .>Yv]NR_ًp/!!@]蜰$X{O A K#/ӂm3xYt'|Otbo)f9c;؛:5WCg$F݄ gPOD Ĩ帰XKȗ褹kD 8]h^ :`+2{E B4ۣ ewwu$C}ÿ Gj5w0hG/\7NhӾºLNko7xG>wnpe,N3a.\ XenqZ{fB l-geq\?54ox6! MoBs~4 Y? Ɂ=={bq7AO!1u.1 aW Ӏ/ك!.y 5D K`=cjbǐR ‹iH C:%2,_"xa jߦblօ}nYR$f1;ۋLm&׽G:>w p ΠDw })yKL^rdq4u=O9Z %dk NgĞhۈzvE}SQg/΍/sۨqK4{7f}Jy,9JF\~=ԈU1)Sݹ!=)K5y;v>:LzN s׸gQSIYeCt&S6=hh֞W]4@I@yV?2ZN N 4t2&/JcV[n+:?)TYj RU܀/jz'ajdws|8xmf5/* 4g OP+;DzZ]X\PPWXQPNrc]Whl*(,Eg7ᨸ)EK˗$8b:-[OFϘ؞x2n&f^as= -DS 1" Zji{͎u'vA{gYx`vy ]4AtOHrM47lH@iU؟O ]tߢKui3\fYC}i`Dv8י*T'+Ɓ^\}5ۻ(rPd-,'pL5)bm OViw ~Rd\fÙQYH@3ܚbE^!U2,W*->كBbYA" Xm>̔] X) h znQDr\Xrޥt#EFN+0-KǂRU2tDeY i?TԠeyk4\M-:cP_y6L %Y%GVoF)MI:㉒3BOKa.fыB+Xxx_%x=XE^wA< &z$™8x׎zeS.IP@߻+24w-GɱEM. >ȃde$l V&/AzfKw-#Ι.~1 H!azJk߽g|!$I$CY5__{{eeheh-͚y;mDa:ZϦ3[x}Gx̭NېTOrªAGBWSvoI/yʻT!kf!?t}26{ xV?nC4z7%UN$45۷w!~TWS<^/R.-ȑk41%)EKv)m@yBŗn;;ZEYM ԅ$y coQ&Sa}tδS;5AùeL%P Me p8v']YXDl=ֳ ~t '=Pdtk,zXSUZedSjt?)G9-R;oKrTGO_ErvLE}l$$ӯ D`P) OTbmpF}nö_cG_R|t%nI䧫M) q "I)]+:LGUC6Ǜh+t‡2OhɋsdSd,~jD m(~xDB-\ԚِD|MIoVhn? gT;-\J|CYs,ȷfEh_Y\Wq{' 9Mk@"g 2RaEu]"ͧR/aAˉ!ᦘl1QXSX]Xұ1] eko1D J?Ȼ?=b/ .B^ zj+sYȸxD-2,S`,(,(6Z"f ip3Ћ;]?ކK=ѫ̣;TܰE[R=e^R$ 飫/&hpDp$ƩDžB]6JiD|ص.V<p%EfE5զ2}wA|Co)TNGw *;܃jؿjмsho%KlW6%ڭ.]־3JbT;s^zcҡtt-z/4I Dl2DA uYKW뉊WK,4wq<+#a57Kz> stream xUiTWD; (d]P%e tD5.ƨ,.1 W2"-FMnu^33!L9}W{ޏ (2rrҖ%wv-ZUhc Kaq<1m#!~%Y^m"Nb"3/+-%5G1q"1Oۉ');-ELI+2I4elUPE٪VxgfeMX,yHRrJjZdzrN.3ScQT(FM©T$ERŔMySK)*OP DS!+eJQ<519ES㨣\ʃI)Cry7?D|apA/Y'yhhijXh\:Z.=2i$Fp\װQ҇45R0 'LZT,F45ztNsdX"J.`rE/C~lq#ar!<.\lv7ol]v+k7lB10uKjبwxy (mwkrQy'-͕پh خm\>,w;UpӪB iN "\`+:/=PrYB%BP>qxD *Fph6A=4G0Zbװ|bs@ٻ2uٰ >h}KO 4T8D:6:wt% c+}^ {;%7m[fĩn}~5XYf!g`\,}8s'gY,Qd'\%zU ʖY:ld /˽d-1&oH:iq,0E{ |uek֦qk'y;yؗ_9Vk2zsq̓kvj}CaUA&)5j5-E}ᅴW`y'l:,Z$?Wu EUL+/I.I6®5Ԋ}Fr$\ g`ASa~Kt 0Qw :GHeIBG6)+BܐOhOYTYlW\I]wՕt2kpUaH/Z 6uφO,{ uG!|q ?dH Y7vI\5$yx9w`]xT ?跷O/o 󨫶 aKeu ;ؕqY_}rj׌`RjxT$ di@Rė0W (צ(T4nAsxk;:H]6bYrM1Ĺdĸ)b_A \1T8h$G#h)l|[q *gJjA77Wuc~!zne%I\|MG o#؞Ce~q?J;Dam3ƉCsNԴ}X =nyy%12.‹WO'N6&6GdDžaw2cEkxMyȕWkt]X/GM 0gvgf(噇fV ɟ9/ZêӨ11*SX:,9Nƿ,m<@* ƶ/9Z.{-StEο7 5g9E8yCoCO A+  >V>ABLVS0디TB~!o*'O[ZV o2dDIyb7mqg5"endstream endobj 196 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 521 >> stream xcd`ab`ddH)K-LNuI if!CŸ?xyyX'N{9"FFsIA:E% F& I P<5 ,5' 75/37X!81Xd3ayF3000Z0021H=ʰ*Jqw)/!j핝Ra[l㵡[/}jc]XC6XtsfeY߽|Nvݚ- yՉ%i׮lVڶjn3~oYVOwzN 9!N^wV~s|H+ CLtiM]lζߙ-m}yL9OqaR>}w,w -TԐ?nxJ^Sﵢ:ǹ'xy|%~lcz,\广N.?endstream endobj 197 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 360 >> stream xcd`ab`ddd v541H3a!#kc7s7ˊﷄ ~ Ș_Z_PYQ`hii`d``ZXX('gT*hdX뗗%i(gd(((%*@\KsR=Yt^:^cS]}S͚=gnMwulݕUsgkPW]U9{ulsguϝS>yoݢݳ6T]]񧗽tJ%of)sv+q웹6sq\7yendstream endobj 198 0 obj << /Filter /FlateDecode /Length 4155 >> stream x[KܸyCHu2M*HlY O(=/eգV9UERMR걽6|HV}UvwVg?q mw?_{Kݰ.n|̬u#bwLKYS]7⠝Ў_oUOkaY?fUd w<8}tFV0^u۵GQdfof1⯰w2;)u(ؾʮ/sQ6__O˶ j§F \Qh JnxB( am ˦c{(']ZR:DfZkj6o Z~pԐ13YUm`r4|]]qfc|c !LvMmϖfwrEZiKHP۸DgP6~cH}B\͝덒`U_9ԧGPhtWI{TEjYݽFH]rS*lk/.S =Z,SY۵kCڞvv#2w GP˗x"֌c *.?Ö#Y v" uc9841f(ծ`#,|Vueq3?Azs`6h˸ݚE#`􈪪zX79i<i7T5gH'⛳߼XJXChDJ\l`oH t `DܦF9Ǜe2njv"K&7aI6%k+l&Nd \ 2| ~-)Ts'Pf" ЂZ7B,~F ˸ꮽa{Uw8Lw%(xb;`}w}~q( lM$,7(a`^o lW;Z09Op^b `oo9ari#<7&k0JDQr(;XcuWc|r=Ec&[LikRhN$!Ҏ?de- rʀz"BZp3Dᄬy37l/`<Д|z7iڪ~Z;$@<ν6K6{DEL4M2L҈5զc+K}Z5);twh{> pcg<χ=-IK_HwB`egvUa* %cmjFF(&l9%K77 2FNIMȓ݀ `'t*Rn?C7p[ b2'zsi9x|ςjܜR+3 a㪷 ԉ3S#)2"Qg0 ̬ lrnAG,HaVEA7_Jg(=_HM[ @!poL `5"KS#PDT- H8#Dy8DN"Ք7qa1͗ )U]e};~vqKw86y/9EH1Rԫ}:<7<lV@h?LQr.WlSHs|"ĸc3 # /\U $eeq~-(³6R4C=SQE=ECs)`v=(Čծ=l.!/c'{Y#Ɣ7^cK@o8?ً0:5[Y8UB6i!ݸ(P轀f#s6\!&Tɿp8V싐Kǩe65&)-uç0L?vr$4HdN<($Di-h6Zs{q}b} 0}5|(yȟŅ* W" tNi- \-ٗ. 9(ðQh<$_ l&$UNb<ouq{)Q )i68̈́[enಞs2 bU::@H-L%K'^_sl's}~{kOa$>|å)%G!R(1WDr8\،x/ 8jrqݙPЫX&J҄$W2ʀ(\mFIvjS?Vl8&hl$)URgR2ELA#rKi %n˄n$ UV^[R\.x4zG]&T¸;to5$~.pt=%Hm̷j &47QA`6 {r7L}U4vfy)ju"Ɓ`udKq1& 6eU7;抮d3Q׵/6 gp|Mo;jߒ6f!eTHVFy`E3=L S3Oh[t9`qڦ8ݫ!$olqll:X s@ۉcx=f閜~XN~84C1]RX--钗Ŭ5X0^jSy/ + &7TQQt7j, yp]}Q\BavWLhu?$AR}fd\v^5ف]zh\p=m6.i Z$<]g`[s-q'a0(E=l關(/WApNRtU[ X㇑I]mcXB.HY%ʚ߱fo}陝A=-"!*npGl(eg􌖈e-PI;9oGW_,X:Q̟G:lE ]ھ[kq"hT'G ȓ'h^Ȏ7׶@ͧ,';[<qcMk1kߊYJo:X"dHf?q`ĥ@VMǗ|a&jȢi0 Ox ]K͟^lT8oR=!o*Tz0Ⲙ&%ä!KH2/}f?߁e`&8Y SWQLTKk`BޫF5ҫj@p1ԳM`}0Q#,#s;Ox,ls:kCՆ=oÉ"nI+OEY382>5rdGE۷H`Ɗ 6ρQAՄD-R"jlU}} ̊0CǓE V . (OMC&~P$PK+-~E}:^ܻX̳8[1GҰuL F?@P)1 Ô7;x0+ߕ,,dRW)|Cqfw_u̘ /Dm"T&$qP({Y/xwǻԴ&UaأyH xñTU!~}>|.Sh;?fendstream endobj 199 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4023 >> stream xW TT?#:C&%Ӻ(j&{`x?$`x 378b HE- Joefysڶ{Z:f֜ٳ>~D"Ukq^քGC,7' DV“bۀ`JsD"QP[>g칳fw/-=}Cbɱ[}=WyH'7ݧ*ݷG#KY?߷;EQ+Sn [5<"2*? V79͛o괙ROH)* Qk`j1M^<%RʇZF-|穕*5ʉrXJJRʖzRPrZ5/r%[' NrI6%%!&0YvOݴ_$:z;6pN9:u<rElS !]42FeyӮj,MQQ57&%j{ Fktxhr}0*I?aөA>h8Rd8'M"*y $ SPN1WOؼ4[hoI존 p#Q : #p5 O/W!?:6nzX_DSJ0$긆\ (Z\1;Nw"G޾˥'mRlܘ ԔVb8yn8ey=p 6F!!h 07.k.TaKm-S-7TZYv?ϋnKdE.c!mFCh=>9,ddr{yy{_~atg\gU)'>✏uGtz[+$ᴴF LBӶNQE4! 5bAI`z{jKȲE5%&^Hs\(d;l}58Z=8$Uk!hx8a䗺6ܒ`[Zϰۻo˨KIJ8~;'Z9\x~ލ{DhXxIVf[?1^T4nYZqz63mmM;읋pNXzwVrz=!^X~UG$IB()]qpQO7E2"T K݅M4;B.֐ 7ְ9D1#lfkMIռ ;p};ǡWe2]DʹՊ<(s#JԅZ.cM[SbA{%%7z.C߽z\%FNPgYj-XG|I6Cpx݅$X ;H 3/{Ma%eq7r T*$6dڸ[ʁ+ݹd򥜓K]']qP,L6da!(.ykM(03}^ {S(GEg2ର7k8ghw3GB>4y]Imy)DoΟܧʩs@.PA&,hh/)0YwZ307`z 35 Bfqrڢ'*>&R9j54JKl1Nl`}ܟѢo%lO"۟6ѓ=|QMlǷ- Sxe"B37@!ja]諾ɭqqqqɝM5+xƌ2`F^fS?9. %TUR8v sJڹM/6&lߑ،5!Cz`d(nZmn!YQ1YJ#+'?\DI$6 f4[إ.u{.ds!(C0Ŀ-![F5G,L<a:qp&5ڶ$FH˅-hQB9cֱ5-joXXn؞y"JhW+cD'o>QuotwM}P IqΪE}WZ_JKUO}_>:EsϗgK?+URXҰdQ^āwM{Tt.Wh>X{a 2^t"~I,:=UMZ}j3$,gO:דp:' 3G'ܽËE_-hT!d/%॒|^@;ny4x˳gU7wLkԠ-Zwsg̥ ^$+z% &GB*K{2r|?Fڞ'V.RÇ$yKS酖zs^K1Hi§Wv}I)vb;Z($18زduUYe!.x<`B\ hJ3bGߵ$妇((`_05X[w$Ƚ-k%2fv73rYڞ֔МΡH3~JqJԆ2,E[2@ހD~)Ѩ7@ S2>E܆ɓہw9bǯ /+1(~\d~04j^]V({'Y't"ހ=TZ_PQu<sGm(xa $` _MАT[Gz&WbUiaYKv TfP!&ũLj_D(2Yށ+K% ;: `ke$mr;fi{h0?FQLj^endstream endobj 200 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2183 >> stream x}U{TW2MR'iݺXv+ >AH$H77J@QEmT(T#e벻uk;{v̙s7>q8EJ%R ԘLǷe'yˉY)\+:ޚԾ݋0._U$]r%bRL, |}AR%1YT"MHI "ބa!a}~0R)+v)cbsDai>a{pl`[Cvl[`k ml!:ǘ3pNQNm܍ϝ.A.pw3R#^Y a!vw957""sS(r\\Km@ ^dYf)qϱ΁ZYdb^3;&˨o<~臲T;J36̬`^ka!,$y8)(\xMf  vKjڝ` qg4Ĕ]ę'd*J@.lTh ǠtYE 0,I9*VSU'b}+*oPKq̢ GQgfu 9qFm7',S̠ʒ `"^2wR=sF?|W%F BzϝcIi[5pY#_F߾7teTyA0Os>}ǸL7AlfUeˠ ΙhN?~ҧ7acgXH)>*JTgàX%Z=ApvBs(sΰB6 pC+CP d0>Z-wS6.A AL-Nϛzh|viwȑg;7&6LtyUGCΚ.ȆZCeL,oJrYn677 ݮQw2I;B刚ʬ-#5@/1p3dRiu c|( 4iTxw>gk-ꣂQmsOȱ +WUNEuōI't[/Lc;90`1 @UTQiv8]RKX-Z%L:KRLd!G> stream xcd`ab`dd N+ JM/I,f!CǗ^=<<<,o$ݟ3#cxZs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k9 e``` b`0f`bdd? ʾ?}17/w<~$.S@w_>.|ԧ+Mؾ>Z_7o}8,WG .d;[%$${쾞޾ S3flendstream endobj 202 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1958 >> stream x}UyPwanAiFPܞT+Y5*)AC1  p\5PQAA:jibFRƭ[ni\ekgUGj*O{]}{Pd0ӖX ݖ[Sbӝ0EȦ/*WمIi%HRrM9IDzy~s?98)+Ð5ƫ|}kLYczɨcSԦ:]:"< ,\2,$"4}o)o4gfI)[(* RaT8"(j9 O *ZCy)H%..'FY|@qUl+$K r ī@ V(h8r8H [nBiC`#!) hRdQ~ -Bjx+AQI f=$@n:[}_^8:C]2lM  "(b ęYLvcwf'V ePY̫ߠ fG":*rΣЬgWS>J}MnJ;T#- D1} M<]zmv -M&CQ.0Q_.׈e$A'_W.Rw͋  2嗡7f|dN[[Ҩ";6ٞ$χ UJҵ)[_Gffy뽪U\y^E~`AAXr wrM:`ҧl8ָSe3( LhL^˕Xɀ"HlRS-\U垺*tLݼAJȁӲp7YEbG7:b[1rhñ<(+a459 ԝ̫u^FSd۱|v{@~@lYvU-s+HFw31=fB2% b{9kNZJ Th_ĽȬreUP ۡ' fk+4A)e_dU6sO.[qڊ vl\dz)Sn j2!w\H* >tAƎ tΈq#㥂Ry%%R[Neq[J]̼iڲ?zXL7 e p%nv\Kw$lE`c/hRB52fb279R'۟7'b|ؾ/\7ut@#rpu7.{B1dCqnYb.c8 p%Z5Gq(fpҩTsp(sV<2ͬ/(d9OI?~<:%R"R/օrDIKt+?CƆָN*%4 b}aPۊ֙&m8p7C7ЗLpkii9X}~w=}5|\jOArO }9Zq$r2{q9qsO^U'GO;}z$)nȍqn1{.rxy |↔ێ-`a&^$˝]z{ܬrODg..G>^ xLԋ_鲈7'Ưk?{9e[l5?Dk!??7uVߠG1h:(pm,,iW4U舘*otKQSendstream endobj 203 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2078 >> stream xU{TB ~*klKjViO{uQ9R*pM[ry ! AnAVj):ٵUk9{6Y|}zjwN=)1uo+1/a eAr%b{d,K~Ƕa۱X<R2plf [fE7DG|ɰY7+^:k:op~m|^b@-i* yps*JX~ҏp9# 7PA%|i2q6\;,GRBK&3ϧвF[.C-y:LΫJgiO?DkE:r҈~9o҃y%rErueh)F/ۆ$;9xivcύg5mfzwĻCQC2.fR\Mfbch}`5A/tʠk]ݝ%uWޥhlx-נX&ʻ%BsN-D dȹܘWGUĄ< }xQVl&&L0J)oj&F/BRB.}bLVhd:0bh"S 69T025YNNT&؈Uu Yc;9 5龴/΢h UՏ'-[tcN]&vI^rxg#OLv&_YUqD`WvKgu9dLmzSk#aPUN#3rC<>:v@uCH}v8D:̟l7)r4 f< JFRj-vh[c%j)?Y!Kڑ OSFRy@IuF}Mq`Q\|+F\b[uEqEЬ 2AVIH[sskaX2MO(TD )5PR\Y\UVY+<;ؖFhd:%τLs_rr}IR65`s:=8 ~u{`p<\F"7g~3D<A^@:9(t@ޖsЁ.2Ү{OZ/ G=2Q QX:F饕A7,a: xrQ—9+gG6ė;`oV*A":,F4V*;*y8֢^(l2Q(h XƏ \q$f>5K-F./._r=lm`p?\i= ҟe*q!6?tBQbַe #9 \;@Io&ҦZH;K|fOC *CM4@%ݏ{{PєZ%eT𙭍zD1/<%9"{ШorZ"#G.`1"0_YTendstream endobj 204 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1425 >> stream xu}Pew9XVE.MlF|K|AISDE|IFCoDy!(qp(ɡhƄ vΑ5jVZlҡ3~88>fYx8ag͞HHب ,8?K[p=3H"Z&Ul%'&gϜ7}x 䁾0e\ OKI+50p_rV/.&'*!Iq _Z2:X-QDhCEr4E`QJl* Ă%<0W,x%#i4׫nn 8Vqv>:ZSa ByØ! 45qt(%4a:j M"jZu$BqV+ha}.84C ! ǧ2wco6}jYۡ_ń1-$d 7kg엹Y_4F^zM#?_dfS #.Pt73 =RԐEoj%T_%_m#| <,Xfy`,ý=97HbG֪$5VFlo˲T!C 5%Yd qn]D> B3sN[TWo.s}0V z0Ύs޸f ]Ebxh#:9hTFooTXmȱTLG4Tj&h ,h"Kk&BIm]|!nCij]zػY$ e*IٲAwdl[OtINlVP*@>NվȷgL U(xݚ~숥A+!33͕Q蘀EAQWw8.ٻ"Wh^Eޜρ.n.,l4Ѻ~GDct1;ILA^Hu E/4{nڻ/c q1p[vo6mm*MVXgPos[yU$}3 ayV ‡kb@KR [2!=v<!.%]lt \!(xZf)J&Jd2D7S!CGS3oYfNzlm8yy^ǡy2:xɎNqZA8A8=tH53q YẒSLp_"樲/b+7cXrelA?oj7h͐Ѵh5_ $rm3Fkʍ7>麂Z&Xn4Wxxؚ[#1}ba4 endstream endobj 205 0 obj << /Filter /FlateDecode /Length 183 >> stream x]1 EwN $R;D,钡UL@ }i:txHl/w{ ZM5lI`vpAՋ W_4M-9c& QiH@7_nJD~oD*DDW%HDcLSR,]:cE Z]endstream endobj 206 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 728 >> stream xm_HSQ_nMFZd\dCb.nilsY "!ė,^ {Hz y5"|~@ G+LeofmNcOPHNPb?Z.E* $/L?}q6{slirtvffNFx.HZ.gCrcvXll&bm]V[p&'g`mvmf1 `8qLc*;! }@*~?؆^. giL'D_OlR`UK iS87};̢$r9C4}+1+@IZl%[rQn=@'by}Q̝S:1ʫ&P~6kȭ%2zˍ V6B=gl- E2RLNdr\⋋uHRoς\#;ӏm,ӟ-K+ז !|z \H, }Nϣo_XkR KeWaiɛX)ZlvqKuI"k|"Q,`z4Y,}l9ܝBhRvu(4${6M< cXHR)#þ #JG̸?U OWLendstream endobj 207 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 324 >> stream xcd`ab`dd N+64 JM/I, f!Cß^=<<<,*=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ g``` b`0f`bdd ?SUe/>0oaWw[V}GoG~zw#/ KUؾs p+]#`-ýyVT#3z@| НVendstream endobj 208 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1358 >> stream xmkLSgO[VFpx%M ]4H ^RZ r BUYV"n3nn3Kƒl,fɒMO GJ'JTrvO2iZ=#͌oc]]-N6 Idy:mFiH`մrIXۛoW Ԋ: OPԉP!kU 'R⏋yxg7Hł*RaXBmdc+ʰ +u%$˨fK$J}8e2L1&T?n\ ]b'SJ Q=q^xӐ~xt&t=VP#>MTHZ AlX{A5}0am r"O@EL{0S D(+N4_ gR 0 Z8OgkdCmn qIՂ ]RC֥y&wWrwA_p˰Ed0tY 0dAc :qKcAᇰ<4;p  ~"2:[ |b =^hVmRnr4y9X#%WUm\~8 W8~N~z ѠNoJmz dY@ j? N>Kbřς>bLYCiS;[03b5#~:0B{7Ѯ1ɏi)x UoЮS'k hU@PAJ[K\ ;J!m>+iCge~QAJ;`y\usq1m4AF(_CX% =qB0J^|Mڣ#|zݺt|D,s*f{i||m~J4 ;=7ĥ h+ˍǚt+/;5X~/tg@ObGͨBQ )g[2?s1Y%DovN\3pm~r+L&Gj#'H>Л^OYtəVs).s؝_!Wf|= ߒ˗b.TX\wʐ>;Kr #bY6N=q!lQvS\:P Vc w݈D|ӄ;w]^f+ԙ\9jʢN4@v?a`O KmHNR /66z`o6["]669uNބayendstream endobj 209 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 420 >> stream xcd`ab`ddM,M)6 JM/I,If!C<<,~ }/=[1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5 U4$(8;(2Luo:cwCu';!]'uϗ\X1^諾3X̨mn[ɝ=-ݒuef_Z].Y:~Ƥޞ徫> stream x\sݶr{U:7ޛ'qwb'Vw&ɑrH;q>ww Rt:~0 .b7~s9cgGzi$ܩۦegWGv̬}l[n^mQ°.7[aaOtw޴l uk NQ7Ξo<0VZ[.6Q@YT G~Ie3RDvnZsgPu+A|gG؜#ds-R4FZqwշ/6[޴0V/<*ꆉx-W/agMSzVr7W}O|(g_m-"ucnbn}l$,KgynwyD]Ieze;W7J ț\Jg=0w0'*9*K#_w~+8V8q7_>`v~mxwwί] òjp6ل6l߃NL Ob"rpRv)~{ ؆F蒊#W8l$OHoW%FXQkvY\ҷ/?{_<˧xz?z~Y/[v_^/*s}\nןwvp) kR8O1HYַy;D&Muه졿K֓pתv0k67jh)f@p5RW?_@)/XB2|Un =b ]gXD`> NW(hvk 3v0 (MTiؔȀ2+̂ I_^W]B֪ku+]KsJ$h񺕬JuNd.$9K*!P聕z9-DŽ4!xy*BO\V|Hzb#@/pIi`qurzU+@S!6RTE-j"O XE1arh =I!פ_ouу:!d`Gkminn^9lFl2en~N! 0UBs l;u&M~{&)˟\5K^C*m4MY 1J4މ2V}9qwZ]{)"z\4[4,MZ}qOVbDknd&hnnb1"j_q  ^h8Dʮ_ݹ< TC2Ou.yL@~prEF,bfdLn6,0&*Yě@H>N=Zy4"DF{B ȌPB jvd1It%RH.;IQ,| }AgXLF,nÐNst2׼fL΀yXiLȞsFptf#޹:UEX{5&J߃u޳IP_SjQrfGJ /zai܀RA!iͩg sbxS@0|/gD;!< ՛Hݹ CF?AL6ʥPM=\h)7an ơ%+6%1Ә& VwoA ҁ |qvA^@&w .^(xl>F]m:o=x8]f {c:YoJ BuDa V8.srY2I` yf{sMY bDs/SF.`v='g`ڙRۍ %g|Oˡ%ӡ0'pN'R]Knt ˣ@S%RTwa.rl4F.]7幟q>)G V H<% SH~]YC`88&4dP(#)}%0C@8w6ӳ]u|X?]ɢX*1`kp^A!8|a ql ekۈ.K(?mjY.IW^ \Y  3czDoNL?&MKS̬q jN󈰙qnX6%. h7W{-fƘւ׾̀wn"ZPbjш s([[wH )H4,jFVFWɀ1yUȗٲե?MI| /2Nʜ)VKzI?Z%Z[;ƾe:RǑ F<9Z0Կ}4B M8]Pj= @ɯdɼ; ]pNv-&a9o㈿%v6tX4ݏ|>nOe]ņaXBXxu7~&T"'FH#/H2I0?wAI1_//&Ewƞ0ߜ;'O|z0rנJTאkJ*+->`|L{̴ح 3\Qe5,`$uFI祠ESav惾,τ.<{d uк\gv:W$?F\< yKKIJa\QM'a gQЯ4 F2BD\-B/b+0OsEt*.U^{Ń"VST_v#+,$|Ե,~J_a$U~Ve\5-C*Yupv 8ZI]1?Au CVqxQ|\FiN2!-f-UU%B8OU Y0iuo (bˇ'Em7^ 5}E5YV̧RΦ_B%=#QS!= X xxkӎP))nz9( `oe~CyZųP-!gq*|u]8~c]8[iݧ_/9`J+ᇕl*NURV"فpX<¯sg@Ui lFЇ)P;wLn& 'pɍAB'+eΡP"1vn8 Ԃѐ^_5ƶtdq؉t?|XV8NjyoZmLh,> stream xr{**ovlljwuHjì4ק kKqF/jjj_rw֬n~:cvܭ>8s!MVg~ [Y2N?Z5ZXqu|m0en0q|Xf6|-骻dMk^zvZT|䵳$s*,R^sf>E>y6vPzh#[Io?'4(nuI7+i57u.6c:ra-Tm|pDhu{WkD~GQpppxu6`'[/#nLxQX۷ KI^eRm~9n}}}o~T߀! tɎYYHIQ{f?70bYwRM$}%~ Lz$gv̫p\ne '-l+UԵ:XYE&pXfvL/A%7QJL6*_W9n;l`=u],b,JQd ]1t,ೊ^=!OٞL ~zE-e>L AB2\E ҦI%{ (p -=1z< &CL^L]y͇:i q!Sx?Irz1.h}LJ>=2T/5D(*r؜!Rǜrct-.DY] ˫ЅlE2]!U+1EH > lZ0sG޾?-18-VD!nFf.-QHbFBwgMpX~v?!LT2A=Diu.SDmB4fJh"_&#!S@-, re*>W(YKU쏥‮V (K'(ࠬu(zP 8T1jѭOp9_.'IrSz#AorBCe A_|UdAN"fſ)9t-9 c_6V҅y2оX8@:1*//IGYeR)Xug`ٰN/uʹ\ L &K$5~SY#bAY܍k7h,Į‰fuP~Xb-rRͭփL>3l>67?EvG6ȫ}Q],}SgUkXVXvPeV'&7_M`s| &EL~sF7 0"PhnZ&E[K n]KisdI1.`0FLY @SJbae(KJ)!'23*FRҘ+Go&4vSl$Yųt4fynsBq QCx?0. = }MMuR)Kim[k#2ʃ֕t .tj"5b@"9HN?4jxqݾ0:Y'J46:FZp[[7[6)wp\\BO [^iZgxd0ԕ= w8/%}᫆5>JXB|pv2a&3;!W~> stream xU{PwYWV张F<^UPQP E#!$$!/^!_B3 <PT (4ķuƩ:sw\g[ڹ$3~?gYbGDoo&NJ^ŢWk|a_wy+7ar̗:[ 22wlٺy3sOw'9Y)s3AOILM 11чb#cT;b  ŒiY9EaX vŎ`,ۃ°~,8 _̏9]VxNY>rg />j.aAAQ)r1 YF᧿sq3x`Ꙧh˼r'?@dvL%@|%O`8.᪗%[nIHNbxWrMoɅt̂\ɕ*J+dr$-{O [yOJ@PcamWbI`|JZܵ{7ِT42Y_39J-B|f ԩe0GMU -YC4n<x(ЩͶgmGW-97\!ӵ„D&☵J,0ޝyYStͻJ?PRr<_-Qlk56Ʃs5MgV7&7(|}ƜycR+0ќ[*9SPD*%]$jˍ {܍_f}TR@VԜWhy rYIf;-5ܳĻ\wX/i6LLzk :70쿰8endstream endobj 213 0 obj << /Filter /FlateDecode /Length 3374 >> stream x[[~o+,BEM|oEdpTL!LG҇q ^=u4]*r'w zS.иXhq`]`,I K6P?VhT/йʣG>tM&5j&Q,hF2[   -["^K}#(sEV)s>1%FQafA]!mvx%qtҀUkQ2pQisJ{QUVDJrZ"PY-h\x;(M!E]tp0Pt2T% ' kmԱtMT%P%#3X4C#5vP'LI$yCP`ʾh!2O*-{aLqHg*g|$J$jG]omAx[䷂J:Ɔt4E=>PJ@ŀHtΟ[[)1R8vcJ)[%R5 Sr)٬Ex>ݬ}`'ɧAj8wbYge4 AHʴ'P<qbz;.L߅)m(jJ2n|uz3͌W KKhϬg/'P'6°cC gFm՟PzO8B gє>?3BhkOGH<e{F"otR XѿnzrEI*o `=gΌQ݃՝PK՞Pց~3*: \nёhvIP=) BJFzQ<B;gPH/O Wi`XЦvOQq%O(JUZD0wj4yZ%c8&O"4QlwMc)K0#q!ݠAϠOVt{_nW~WP-)iǀRS5`yq5c )'3AǏbU fb- +0|^k8x9¤=ÒlqX--²ua#`vƳbo^(`"KXBN٧|Id䈧#қݦ;Jscc}F(.4bmыx.n +Q,cYpDם1\z;v}d{tc٪+mE;˶^*,Bބbt򙋧amq#o KUvv_;ic}:b.6] ۭJZ"Nxա{*d+?kh]u~czYP^ip=~yhk&Zz3.m |O:xLͧY?/HG{׽#!)y>6YJk.W氧zjj[}a9U30x:_ZIiv#ei%38C?B@u.RݢYtiӧOimY(&;f#X؇,"]21]*~bRTG>NŽc^Bˁia ᄚմ5~^m0_oiN< "4Z)j6}0+wtY]EruY]7۫%< g Y!(f;\ٓ6jHL266br2N*HI ]):J9fRW4 3E ! ,W20jN"[mneZ-Ԕr~2ɪ@pь aU(]l?'jm^v2MuUi^^R׹72}Ͳޯ]9A|Bjd-SԿF'K՟Zo~~~׫oUωV>-[glIaѭDKqѝDG &֚s?BcvJCKsK!*jADFhsǞu|;٬FT&<hH:ښm4O7GpǮ%˶V},F]s)jy4/ ;zJ샂ԯV?dg3OL_k B$aޖa| ZٕTEt ־V-z[|8xI[<˾~gB di]K<2N.S\קrLY]Xk$&% NyDZ25vamӠ8"LNطh|_^1$Y1@ jSE{ t.kc>A*ߴl 8d݊*qG]SBv Q*(NAqbL|ϔ@{&!MUҞƟ%lbi3=E&٥iEYo*"$boBzD:x} h5dTɺ"}@?V]pJ=r Wqn&/o%6g?QӋQ!༱endstream endobj 214 0 obj << /Filter /FlateDecode /Length 162 >> stream x]O10 X @p' aKtp'w'ezv =(ul"-~H0XT5 㬃]'l3g]]ʪC -A#EFO:=-Pj?%Λkĩ4-Mr{&SA|.dS1endstream endobj 215 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 335 >> stream xcd`ab`dd74 JM/I, f!CL<<,o$={ #cxz~s~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ /,/I-KI+)6d```Tg`b`bdd ˾*p?nv.WVUUY!> stream x[[s#u~gRC ~K/3Zg߿ -gί+|j{gwg9ȟ_]t/׮ii9j;fRl,Yn}Y\A³7[ң'UO?7]]%!m0B`wZyURBH7?Rm!%RCJg#Hr )¶ࡁF ő(s/(Awך g^{(@ZF^5ͥ7{$/g2xYHRz[7{]fDf~?GϹ2Vsѧ\ͫ9O=XXXx9y+9yD. Q1AKDw)$7iHE1!9]9D ^F&Zu&H zYQvT=VnyX]{vs;a妪bUߖx8 klFeěsKR"0!6!5Ai XiASZk> )6 Cv2f UoGKЂyL "Қ\HJB_cZkJj*Toń)iDh!.^TqڴVN9i(%P[cf10*h7xU & (P 4 #d xڀ2_ie#~r@jTp]ghS-dBA4EK D: Lb<:s/(zᣠx(Qz9AAw=]i~J 1kFJy₵Tji ZIZj Y^"xE -GZvCC"@[rIdDs"ʢE1 @4 OG36 ľ`ǨbMJl uUc)ly| BER<`K<~kRPk! X$TBhq(0e ̛X {<" wd @ZҎFo 2OSԇq˫(s /..ե؃?p2mq1'Rע &bΏ\\ƪ?389k\99ͪrrl~g/ .z~G Q25V`(2RƇ"h`2?omj,&;B3~.ð%Ӯ[5TauتK^IGP' >|wBSޅ:bW 8 OS>e"( ƮxhmJnk c)uim,>nO'k·Ѕs|H ߜ*M5۬^Li` M.#W)hb3v㪎E.8͊X :r9&t@vP}(P(u/@p=VCAEQ{}I"THUErNZ\tm>3G^zv^޴>TӓD#}ò,C B)( izeTiyb'-Q ~ǣDTo(Qn6Qmw8<@le 3 %xfZ2ڶqzov{()|]n{QNѡ֭B;'l}x$J߿l_k}w_o0~>E4CYVၚsy|b__=,7^oM I!⡫]ޯ#,_zڣss{kQ0c玎閯ba Qdwjk ȾvG'}2Ċs9QؓȘs_ܬWD5m=xR?=)Nyt(A|?D+ϳ} G/"koxOwR騹 d>8LjX]]nWSsN`9aVFҩk)s [ Tb$e&tS&4τ0R'1cޞ6n%3?8]6WDyi1+A3M$wS\YFTx| :݇ayOU`|Fv#ă قczۖxS0ۆ@`~E?Oˮ !h4* U}\Oˉjcnܭ>AQZ&^cE *nQG;1Þ\)d Ux].%6O>`+CLmOb&soȜ9 50 qZO췩[(DRpTCag2 eԶߍ<_T=#U}Ezpٽ-+ujj :v$k#&t7a>7mceUf\)ƒT2nNB>="3;tQ[.ہJt?>^ȣmfFaOA¢B<Bv]Tyrj;?/Fn1(:$@'3˫C{\~$pk5-͝z7iv% dHN1<##ИZ7g؞\L80VJF:RdHrԝc'\a}C9b::` =ʺ#`Xߨk }ii)U_<;Ի}=q&\p͓Z o7+D7|[y9v ZCq.z>.FܵeGW%`b{LXHO gIDwk˽NA0Zi{mhO@]lֈٜ0ѭ4vePJ06XeXx]mAEҲ[Sl:EaE|Vo %iS8epou0֫Rڵ<'@W庢Ka^SpewkJJX ݅uK`$J "g(J'sCJۜ;d}JRQ+\L[1C& ʇfRcUu]YRU-m =+/^Sڄj7fqt*$|WWenW#n0cAW'g^)@!̔z+:QtֵS4Õ;Ѕ2ҤN OYa͓OD Յ]"8ֺQ&f2X3pD~COXMl-qtt>^ijN /2^.U+~ShDۂiOPfc\Lr^vIbR4-r=қi:%j_%cqFq[&ftw8RB\۪gLl"-URUCIrJj~6mީ/'΄]Hy >> *N3i&FTS ыx7(3#nYf "2 iU΂C:tS? g='ZVp=զ.P9M&#q06N O8sK):ip[\{ioi&/stu0gRT/( GU5S.s@9 wMRoIɎ/]˖e\,ljMu΋1Јj s/ ^o˗MK1:;!y3 ]样~7 FepIVhW j vc _ì/N*#LI*%RթX?'~]ެkZxW#26O;ov Κ]VC 6^Z9|z9̻dmn?Q^Γ)=nendstream endobj 217 0 obj << /Type /XRef /Length 204 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 218 /ID [<7a9e94d72045635d1e1453cfd69951dd><9446efdd77d52d2ea2284e21b8b60386>] >> stream xcb&F~0 $8J8?H !(%<6FAZ [L'@dP(4"ā$%~ DJفHS DrE@$S<z3fHf]@$_'̽`s`@`+ B``8*A$z^m\ f_\ *DVugx0" endstream endobj startxref 152766 %%EOF surveillance/inst/doc/monitoringCounts-cache/0000755000176200001440000000000014615104657021123 5ustar liggesuserssurveillance/inst/doc/monitoringCounts-cache/fPlot2.pdf0000644000176200001440000000343413752253562022771 0ustar liggesusers%PDF-1.4 %ρ\r 1 0 obj << /CreationDate (D:20201109152824) /ModDate (D:20201109152824) /Title (R Graphics Output) /Producer (R 4.0.3) /Creator (R) >> endobj 2 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 5 0 obj << /Type /Page /Parent 3 0 R /Contents 6 0 R /Resources 4 0 R >> endobj 6 0 obj << /Length 571 /Filter /FlateDecode >> stream xVnA +XJE. wQa@>5={!]3]ryb83a$"bJ_XäՈ`fȘ2?θ(8;Lfa\H8b l`Î0  #lSB3` ;ۃq|?@w0wA' B. ma0[J (ҌIUIbcyB [1zBJ zj_&[P_em !ۂ^}cv*ɖD\QV#!߃EB$nmD\/{*Ayy̱$hѰZhx6/́Y"Ç5δ,I}FN4Kzܬi#exV,vrendstream endobj 3 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 /MediaBox [0 0 504 216] >> endobj 4 0 obj << /ProcSet [/PDF /Text] /Font <> /ExtGState << >> >> endobj 7 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 45/minus 96/quoteleft 144/dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron /space] >> endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F7 /BaseFont /Times-Roman /Encoding 7 0 R >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F11 /BaseFont /Symbol >> endobj xref 0 10 0000000000 65535 f 0000000021 00000 n 0000000163 00000 n 0000000934 00000 n 0000001017 00000 n 0000000212 00000 n 0000000292 00000 n 0000001109 00000 n 0000001366 00000 n 0000001464 00000 n trailer << /Size 10 /Info 1 0 R /Root 2 0 R >> startxref 1542 %%EOF surveillance/inst/doc/monitoringCounts-cache/pMC.RData0000644000176200001440000000025414330454336022514 0ustar liggesusers r0b```f`abb`f2XCCt-"@# 'HA3baC&8vuᩃ[7$^r.ۂ׹߷Nqs76՗okfeR}H}=YuK (?jf QUxsurveillance/inst/doc/monitoringCounts-cache/pMarkovChain.RData0000644000176200001440000000035714330454336024423 0ustar liggesusers r0b```f`abb`f2XCCt-"@# ')M,/sHXxc}{T-=گ?Ree?M_ RӼio_f,SxR}]|~cyrL߶Qsx'fPna+Twa}@uIo ;ho-el4?ސy[͍jsurveillance/inst/doc/monitoringCounts-cache/boda.covars.RData0000644000176200001440000002104014615104657024236 0ustar liggesusersTTޙa( (HޥQ"^
(M]vEPE^H,c5boh}s&/{[k}3g==g;ݵue2\PJ)SֻLq 2=hИjQx me|:.VtN$#Vh>_1 ":!ͪG%F&DDDE#wSïϧ|>x Y8[> 2Y}|>>X[@]Zo@' Ƃd0Y`)ip;W d Հ )h AW CA4HT0 `X^p΂&LP3P8: 4 ہa`8$h8$T0d% .p A9x>d0=p>>hZLF]@o&q` @XV`Pn1xdYcdo\ ' qst@(`4R,+ZPv}(8 ΃ <OkQ& 8J` `+@h ڃΠ  0de`AP ~u xwR&  S`  A3| A}b(0LAXrAv"pA nLh|xܨpbQ^a9W&rsJRs[1r)(<1J8+J# vRaU7|A0OtJ|A#vJ7%O+16J8(p_J9sW ܛ/菈9"1r}1E_D K 61rO#甘JS~o >OWt: T5t9%sDX|RW{%bYX+v1OX rp%l/_"b "E9 %}h#6+.kVotT:G*u<'t0:y9^P٠Blց ^+aO%qQ1Q )grG8\_+|y5qN(9N7rW9bPS?:hP5|^RUﺈQ PaLT q@ATbL9ĜV9@SxA+;9'"{R֌g5sNyh#"6o4?41R;<' E3Mc.CMg..TqU%בb]X3H!.- m9b9bwQ*fGDi2Q2i&p DN0"3S=m׼O+-iI$+p… .\H]lju'QGj .vCG?166<.4&1zv3DK?_1@4茇Lә`W1ib734:sFgitBXibv].oFgL?cgXY?Z3]g-F/eF/9ˮ0ٸd>Jk;f76> YͬvYhi֟Of̐YicNkLO_Yi> "֏x9jr\6oޣ++u}'0ifQf-cZλx_#vb?Hv?leb㒩2ٸ,d3GY_gtfKyL3e˶`3vl.b/v2vVvylbﯩ/c3#'X;ϕ+`[Ǽbf:Gk'vv/e2ڧ'3Vt6>ileifl^e2e^_OB[R柹!L̻4*6.ktqFnƎ3}TsYY?K.=6i,cbcn&{ ;vl^.`󂍳Γ- v_ }eqfaρum4ϟϧQQ>uFgo#]5{fڠgX{M] fijnu/_U^Weg6α8i)=ﲙeͲy,n׼ZT: Ka115"W sſڿ ؘHuBDLt8uvu޹kkՑ ` 0MD0 $>A` _R@*ofG s<0tLA>T,؏ r䂕 ` (o z`?(H_R f`)l2͗쿅}K88 >aL(7 ?_ONpp\%2] Rpܔ}Pn;pC+xSPx ^ x ރ|BP ’( }/J_z \xMvʣGòSkm'˺_|e\ܐoe.[E&]zlqnQmI~Vwze yl~277]D^d7ٌuuRP_;D|?-9oW[wyznP񢰀<#KyѯX-(]J&sv+B/h׿`!H> ƇQb\M(7 2?Ϗ KzdAӌ_#Z;4.";6qT&ȿ[wTc{^Opz|eO9 & ʣ>jtx=y2V!Cn::,'T3H3n~^ul)q$E}K6-"{YKN}޳IrQ<1llQԠ̧>o}Y)n8V̂"^PgC ` Cfd1IwCW}ҲdaӐ -ّeHH9:酖R6:QSuL&6 vXpSd̄^\يl> /RכKΰ/td3MKx^u rie62/Uw=)KɱGd׬c}i/. A{doBcG͘rs6y,-6jT}ss7os;PLt#O(g&ʤ;a*3ma&C~Ok_"s{Fہct&7Ujc/G='"4!dp䚷޵QlrS>Pۋ=2&al=kJ6GwkN6߮P,jG9Q="}ʳҮj_enьl{*bMWגmRZ%djݸ͆dSqd^gF232YexC1kti; wٯ]=2fms<~yYwt!ύ ny/$SUBw]q*y\y\,j:֮&9o}W?c.5~J.7FS}"ǩ3w#^ί<^B2n{d;HPa]2~l4Y'EN=2s|tT㤟s=-T+pБ?n×b˩ar̎ `Y6Yzod:fԤ ͨ搷f=gN&?VWRM2kYm593xnde̋ORgΠxzx@rzzqCr2qZݗgE4;{ hMMK'NOGC4'#1Zu"S m&+M#t$X7kv%SSRS*'߂V]˧>ms|\y}PۺuxnJk|4|yA‰wƒϚ!?G_F;u!ʐz?}Wgǡd߯ {2itHYM r1?<;9Ş߿9:fxbo3]}CV~fY96%~j͛f6~m3x{0i$(@xd7Yǽdת|W軗dߩ< =Ykh: Ֆn DM&'[^[A+I=J..|M C'u&^w O nd7uǡǒaS¢'f?$_ǖ!Ɔ5F8E]'qfi9cܰ>̤S{'j<oz(*m 1ξ{xy44{/y^ B>^q#qƐ%ײ%jݲIFSNQŏvuw#? LUU,Uj9KXx>rWQ"7lk< >}W9\GP%N煼!Ǻ@οŎVx?I"^9: 3$i;" Lh;٘5X?,?orQv?w>hӃLs."%-$to{UQ?OϿA^ ESw~ ^^#{ƪ(39Fo\ {9Pz/btoE y9ϙM#l0ƣ rݶr2rBHrPE(zcltZ$;JߐO6sHΎػWū9VOɷi3gƐ`Ucʰ,ЯFs_pRɑӹљvIJc*0zrK$Ӌ<;LJaS Zؑ-'GL3{C}޹? 6i/(\MֱdoZd<=2;wu^ȰRe%Ǿ~$ w}VwWT3dqC{dc TV~ږdQtfbdrs\[9aid4VdA~/ o=hoI)9Y͚HwVvqm\S^ITwqη6#Y=,m" =ZIu:,s9U[}pTmn->U[}pTm \p… *)¿H, VSu"}%FqQ/H7:|pu\B`ذ(N~b""ښz_NP C.73GlS4 T1A@*AHɥ"T¾ J^RIR@* t]T J=A/ R@0 ߁A@ BAJKE@*@*A #TnQF@*U?T{"@2 @*MRt }u&JR `@: T> d <_%@* ,+@.X @>Jk@J l`3vn> 2?C@*QqP ?$JŸ?3,8΃ "2J_@)J7-Pn; !<Tj7g9x^W5x{TLSyEGʁBKMR$/5O&EkFҷ"_)W+E"_/E"_/E"_/E"_/E"_/E،@i]Zi߬R{V JNVkXa:*62"zha1LTG'DDjTx\hLOK-,OBFGDF)d~X(u\uGg>Xo?Z?Zyg+EW_)RJ"+EW_)RJ < < < < < < < U$wy________^řx~x~x~x~x~x~x~xg.pTmSۧj p;UmSۧ \On->U[}poSn->U[}*\p…T*T-N34:ͼ$/&ɋI:UN)jeV1surveillance/inst/doc/monitoringCounts-cache/boda.RData0000644000176200001440000000617214615104657022753 0ustar liggesusersw|Nv{F D% bEvd u7AdSl˳aWXy{^ܙs~wNc'gR0,ö~ظ 6Qm`)ҐwRd?Y~w791>Eڪ{m7L356TfOTV+VDbH(zء+5̽wxKS~4a\< ua#]a pp2$a:̄0A+tUp=C<!,N5a=a8cGd(T™p\ihv 7p< OK&Wa#0ց asv@ X( q̀ R+a! wÃ8<[|φQH5(- [ Ip@…P 05p# G)xހwc7 \`t`6l3a#G8dc` D p>\ p\]W`17aD: aKB82qTRp:s 2p5"xux>/`,7Ek)l;D/:B@Nab&Z/""hI`SR0lfXlr¿9i1'OLYwbELYyX6gp#q'_%\'r!OB1ߴs7tuvC~䦍l6}WM+Wqfl6so1EX$ModC _XğX\ ]|  \r%'JHKEO]4scqZxrU;hM<;hm}<_)4B"OLD[MtDKMmboҶ{sWݻi#vF/,_K?Ysڶ:mxyq4}6--sZd~څb5bi_ߗK?ԶJS-ּmRyŖ8N LҶEmd\]3_Abn+e3ҿr>#~tH9*q"Bbe~e\LMZ/ Zo~|/+L'zs;FVϓd\xj.:ኻ\XoL C-VnсN|6Y=Wdm}hyi~׋nՊfTgܷk$nkiozQuXmqŴV=O[' ҮA(k|/y!~}EطŎ؁fy:r~WY,ϯ,Vxbm[DW}6&A U+Ymo^:?EjNO+קe>}WK|%r}gN z뜿..=ݻH~g投gvi@ƹ@P@].I] { ! 5P ԍjCP+f(S} C;t@'tA7d`\:Oy] Bn&n[NnJu "x~0\(p)P7iV_| ,~)P˵ JdZ@nz4QoHIJ[C"{ُG7ef9bzQFbh*9~[gxoHF6_50vr0!z|pTvp(9SC )U;*ODYPƇ+?2D=ӼH}^eJUJ*Yt#h(V^"O!JP_ +_ +J _ TdWVDi3/yU< > endobj 2 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 5 0 obj << /Type /Page /Parent 3 0 R /Contents 6 0 R /Resources 4 0 R >> endobj 6 0 obj << /Length 532 /Filter /FlateDecode >> stream xVnA +XJE.c w†|j~'{hW!* -gKrpgx1HD8?|5'I̐1 2?θ(8;Lz0.D$Q1w&[AvaGUlCl-FS#|~T6b`2ڠےZ8tTf\9_uϾՔ۪9)9cLUsQR|kyڲ6Y׀7I9`>ƭ„C5b}#M77r{NtM ]j;p?;]N,\R%%sl1+5JTM/CwlSp*U6!7_m )5ԧ/3~]OM-52[P_Sr !;ǂscv:ɖ }W\Fa_lh`-DB6I&M%׺aCZeI$t> endobj 4 0 obj << /ProcSet [/PDF /Text] /Font <> /ExtGState << >> >> endobj 7 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 45/minus 96/quoteleft 144/dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron /space] >> endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F7 /BaseFont /Times-Roman /Encoding 7 0 R >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F11 /BaseFont /Symbol >> endobj xref 0 10 0000000000 65535 f 0000000021 00000 n 0000000163 00000 n 0000000895 00000 n 0000000978 00000 n 0000000212 00000 n 0000000292 00000 n 0000001070 00000 n 0000001327 00000 n 0000001425 00000 n trailer << /Size 10 /Info 1 0 R /Root 2 0 R >> startxref 1503 %%EOF surveillance/inst/doc/hhh4.pdf0000644000176200001440000104766014615167601016043 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4834 /Filter /FlateDecode /N 79 /First 661 >> stream x\s۶ v:!;yi.v<mT\Nxd:QOq$X,DD226RQ2+"qIF\Cq+_񌋈H$)GHI]#WgI7cnp?x/TADi%nic4E:h+)H,7h*"F6Kp΢ThLBGij02RFVY$U,Q* m,KH&_Ddy$Ŕ$'`9qa"* Y2!T 堒4 4")aA4 +HNt:BxZcfIAJ@)hatL#Lpd'NbnJPͭ4&"8ֆIap{UxBX*@NM9Mx'^YiZ@D"i?g,%q~)2߀;] /?_;@"߁xpS^яyy ā C8"I4ݵ Eh }dxOh[`ύ~6 gqYYfe}" Jn%ɿw询.1:?_MGm^W8\6l]\Qk'rrs(@> ψ (fdg-  J,E^FPܚC*O-[tuzֺI7' ,r3`[FG*\}[osټC0 +&?X,KҮ ;T8IDj g~[_4<^RW"+DKJtV\JM*"m8i@4K™sVP,,Yù`,%yrϋ'Mwtc5U<VhkP)|Ya4ǀ"h$/x?p~XԀQ7e'gZdvB o>7eXl]&,o 9[PQ7U;bˉFdK`BzI#I?3WF W~Oy(aMÒ Âvi!y`-dM @#=#n{|ƣm<&AT kc4TbiM^gG/QݣLrZ͇ZX7g$g*үe7`}=b? {ʞ_!;bٯ;f'%{^7-{flvx3[٬d쌝%9˙lsOg;g`ǜ/9]K2_-&D5_bVh_kRWk7)Vs'fUӅP5|kahozS|b[rknM=G>z(e xU=U " 3Э糫|z8{ᎊJ)sRW6vQK T_c̖Q ]|͍FW"0ZWSUQCųYqkj~Y'PvOHz8)pW*?+ޙp=sN5U.rNtg<*rYE~蜤sΙAm@@k'7c[( +EoUCM+/nrO]]eu0CtK/0j*K5\嬿L\e-tNUݩǎnϪw\w fs/v hFM hq`5۶ {G6rsVeϛقl3X՝7lk9>[] 1긠SF8B+>UȒ[ Q@ȞzO-釛(dJ| d|IvXGYv*R`hG2h#BS$i̪]/(q ht_;w] &q&!q))Xjw칔?qh`+nv$KnaDocRP=dCǦYMd'ۗ/qŽ|*fC.Ǧ\$SMcW0)m ų'aTf.`[jg)jv(. Ԗa(:My&?EUOtN:zo#UEO{m٧.~ =DG9wt LRybj.]a*]V5H3|!천YkMb,1fNbphebt Eƴuũ U^7~,ˬ<|uZ,6d*'꽥^/oTIXQYKsv#qW#Y䛍lneqM iJ#6*('Fn=: #z\\ >zW`szlC bhr8a.ҍ&g0_{vsgK M|15[5mߌs|Sp\^oPMKO;ySY,n6[mzG}ĥޮ Zp48T{8 hWD"}ZfpkۄùULt1Ms'! I[M)AUOIb B8+CXSRf!(8 +Eu!Sy,jSBRɀYIXiBQCl)@V})wAJq[&,d|"TkcI嵩fHfo,H쳌%1/0:Ln<<XiC~#L@BJp e~Gj7?;F)lYcIr4Wжar;d=ޭ{SrwUǶ~!_q:[yY{pݹ|5 #\U<(QS:m9v nY֭0dg`{|#*owDG N8z|1/Y;v0̝AZ!z/+ķd1|l'OH>lף$͵+ :׵j5VTWUPQGsw,׬P*ʋTB&i!.[}펿$MƲfp3ǠXcȟ;#3Լӣ7cz݂0,RA!e>K߯ VɄl\ƠfTɗs6J4 RϪ,o[swҊ'0O\U(Qgk:ݪyg(<;({OSWfSnxeVӤT81mm>~Tܞha}Bww6 y > stream GPL Ghostscript 9.55.0 2024-05-03T16:06:56+02:00 2024-05-03T16:06:56+02:00 LaTeX with hyperref 'hhh4': An endemic-epidemic modelling framework for infectious disease countsMichaela Paul and Sebastian MeyerR package 'surveillance' endstream endobj 82 0 obj << /Type /ObjStm /Length 3001 /Filter /FlateDecode /N 79 /First 710 >> stream x[Yo9~_Y,Ҽ`;3 $+A۶YJl2~b_Rڑon6.V`0$ c6 ȤEdNLyY`eZZɢcZ;=V}`9bd:HIIT$WeFyhftT<Fci0`c1V[tYK |g,j)-s 8%sFQϜ34N`G<2 ^.ټ2\)5FiW0hRe4)1PųXP ,;Z-] Qi}4,1>ͅ!0z4421x1+* }`5 mHȅop!:I,7;Z@+ Ax(#D5*I+~8~Kč4M%+7`@Fi%yk@PQMǯ23͋%+GQNYU2%&*KY*: *WxwW6ڌxhdo |J|/痋|FKN.Gyg{˿PqP9 ZU*[{J+We:h% @y^|_x&œ糣dv27Y,g c9|y\i\!/ij k'z\៖{gm\$%فX-TiHSSeO}wnl2<2C4F–G$[ :=0MК C>_?O3{~><3ώ3~O&r~2O,||g|9 ^o/w2N'TO qOZ;].M96SW-=z=>%e1Nvf_r Ll1?,ɬ؊lO '{^ì<>姗Sol9i r[MVJEmPzK+6]KeW`L Y1$IJI>O ~ ^|1r8%y- 5U'bU-=ڠ57$[A{OլE^%yu+zp'z]Z f%/Vjvm"c :Cv1D-3~ c͛?O` acߖ qk`y"mTbmw(袥vZeSh}|\V)LD#Q+QvwSSr}fA=AlGV6Zh` ;f8kὮ̇Kw8ȶ0|q/*P29ݩA9\dYٜO 0##.S8ʏ *]Ey BZ-\Ed{¤MU;TSh!!L@(JBt`+-2J!$)V0aմNg ty&dBzŔ A̤2D[I!G/Gd>+rVs\|["[|d9/WpJ R%dPD@Qg+p)I3!~DP-Sux~RC|]uҲS[1CJQB aoF73ZSЭU/3Q ׂyolmky|_kbQ'2Ji <s&o3&mCFySY(_ Ӻ m\ͥZkΒk&⌼~?+p:g˭C}GDvD&Od~69P`sN(✤fr^!LXMJ7' q:NJշNʕ6 䩤}e؅"%Wo@)cش\‹;YmkDRfCl@%|c9n6$Ѐ *KɺGTŝ3mU~SL&F+Hء]U:ab,o$Z٧]& %Vv+vg _FIb}wvNZhd]E[<<ZAendstream endobj 162 0 obj << /Type /ObjStm /Length 2972 /Filter /FlateDecode /N 77 /First 709 >> stream x[r7}߯cR`pl\+ۑ]qqC e%RERq 9L%Y* .n ,fIgekYKg^YI!(JңJ; ~(dG#EC*S˔ǔϴ}i+rda<Ӂ^Ɍ0h3*8C 3Qa`!R3 fVYx6H"Jf#9)O) sFh39/g.Xy!yd^Z 5QB2oLDF1d@F3#e 1U (<2y+XpB&eoPPBf%%QcH-jOAXX=Y V!Iqԣ$J&!0$/HjR" * ҄R#$I])HDjM-04ЖRCB'Vc iq4PCc(CLC9ГTiBS 4PѸ=zĊي}X\o,קx˯`sp>fWWSWTUu*-Tz3Z.-??NWW%{4)'[pȻ8 W⧫w&@ܧ1{8Mhx&[O##[HeZ|4F،Mq)b{w\$1Q% %ߑC.2",?<"cfnw/csqč4ې+.O7Y1->Wu1+M(Ū->6h-CLK/˧[dm S`G[.޻Wkdos!nS枉ICҜ)mm20fcrbfeju`75NJbT'=k$H"H9QQxYoWpQbmjVqI; X|***m.ۻ; !kqٵE}dl1J`购\5[bp=Z`9:i0(k }=EA];C{ڂǮ;_~Z{ڂעGpg!X׷~l| -_2:=R=ZmӘ~#:Xjx"MKwx4ʍ᪜"~!*w>, bcmlXEkVa4H!UZKnxNqi mx:sV y5lz0PrOk *zPRin VRT\!8,(︍j*n=Xژ#P4 ݸΣyݚu ]Γ?TK?(P7ߜ=9b7;>9:nGrTi=;PfzV}e*U9959)C7ַA7nu|QD:)N<@h "6"M M#Ψ kg:SO0ӽ [!S7P`SX ܸt2*y("=|/: w`0B~h󡝰8aF10{A) /lql0PCۧ#F~T8d9W5ZU{`v>xvAE*ͻλλ6=R'e7qk ƍPԦTe}>It?(BbU!<$(܇n:mlv{=jcM]i 5>cYi|/P-3ŵ` 58a{6LJ$@;("4j[1LPo?d~endstream endobj 240 0 obj << /Filter /FlateDecode /Length 3541 >> stream xZݏF^JgU&H=4m_+ ]'Ysg,^nM7?eY|Yw_/ NOff񇟄^r[n%(K4,~vZ G %Q7Z(e_VkY_ޖN-5(VjjPl}M]i&VJ?e+ v,:'{v* Вu5O+aq:Ύ݇07//Q| t&pӘ4S#.7Ro< 7V삢7²ʛq8l > .gx/9,BC0`\VI \f^y궂PxV[|:l-{WVqmLGtK[ƜBpTB`_H4^ i_+7BW"={u}O}7e޸6~GZssJ8,E ?5-C@Yxo&%NMB>_%Ðݛ^~׀Yp0TqGO+qgmw0%ȥ1_@D- !KM#?LZ w\nvuSq;'ºNr(CAx8PGQӻ44akV7-r3~]'uѪAH"Jk#`.ĂFY`4 IK/dQZWGKQu5Зs6(.9V6+ʚ_s! JIel4ֶS))T1Z@ء]#~Bc{aF,>2]rf VY2/l Hx拟Ľd!kD(`f;lAE6!>p\"<`,!&)8ַ!U,}JwZSI J6UhxvF4҄4]S6$a6CO޿f FªMLJ"h EKSВ!wU52aZy5KzQ`lL;٘DC$$^37S=Xy8wm*ïG],b.,St?Ɣt]?sln!&yXYdTo.Ճ%_hN2dJ z|wc l<(C5e ~H>p?āeNs`#^yFex$e(zbS&xz߼ @ER {[K!h!6طɰ[?o_ǵ,1+$ xއ0!ЩY~u>GN*x(C9C"I]6|wofҎi?63Qn۬2@çHL'E-+ÕSXε` SrʽWp~Ut^7w|Ѿ$R]ţkHKoj~j 'TDɖ5W_."0@˃þ=Ev:yrItì/d,~\c(^pn %N/ a(Ix.!N5,â Ư_BC k~++\Gvw-Qr$l/5M;-vo}\w~`.g)ۃ](6D9; t0^`0S;~\ߐ{Oendstream endobj 241 0 obj << /Filter /FlateDecode /Length 4497 >> stream x[Ks8rQgP1Cx3qtk꒪8]U(pXȒԽ"$_WuW5js_W߇?o.Yj竛 _qn+'֪Ҭnju_^I Ƴh/kؾiӁ>N%uذm[[;6).eۭ3kX3GR8X<٭4+emb:E6K+ |z6-,[?0FX͜2BloJ+V7zHd+ ҉:[,{a? gw@-ȍv# .MlD<49yv!l2;ϝMҷ9;vqS 2x3@+VcDc֩.,0G|^s]6V虔Ʋpu_9Ἒ] 8vczEzEEY)iA-Yӧ-a vq:@&2i*oAbݔOӛv7\6u iQ☔w!o m) 0>Tpm6_T;H\ߤ'ET^öNq]j|x9PG,!!}|{)| !~: S21 l0el*%}mVӑ?,*IUۥkB 15h$7fSr_^48 Pxo_.8 xJO9l($7 Ac"?7KV.Q.-lRGܷ(mcx6YqhPcb%3T Gv%R PI+])Ǡl̺>>ۄKd~ؑDUmH6)vl~Q5@Y]5ܕ⺀vsp9-]S< osg.QG;=⭘M`R϶@RVߑ6j9 7ݕ@ /K詓A~2j>+0#h—Èvc.`닽Ij=aA0j|j! Mn"71r97s+.ʤf>.Y)ΐKN")L3ڐ uMKz)O*e i1N ч[dܨ ~ "%ΝȜ"())$G0D.j _s8暥SzfAZI]dhF I` P: Wr)f{=ۮ[$_8f2l iSq+s@Z{kAHԘZpY[>9pE9 1&gbL ,⼀ Ϙ:&W 4F .r7\ܦzz= Y(^GUųj9| P_4#K\: v-E oS-V%.qIi}8o2YH3;#;;Fv'5'[Bj[e) *BiIBa}e[BחaT-M(;"$jo8okfdpxnjm($"G;@nR֧1$㒧B$ftc? aAC"+#6cOR0Z0ӎT=ph) *9)剆I~M!(RRjHƿl3v&&Ie@YbZuAo'i{:֏( M~xk_I28fxk'%mV/ cS :,3ev~G)hֽXpCL'861TFh8Ǭ"p„^K8PkӵAFQ@[̺_|r`}s)vt.?5Cֆ1]_‚ԀDo/-Sp`s[u6;nb 0(pGF@0CGxߔ@\|ѱ?\@1G2\a ٯ!OW"#9C8VS2 ư|bj&m\%* vǓ9.ya}J D zij"4[ĺu Fu é쏻;1-v;B<ؾ5TjgH85oou"XWY] )'N/7݀n$}@Ax/[#Tls.0r$R"'Z&F iyO}Ȫ)2_ZA]zNM~ѻ]qa+2HڙrIt&^/I8c )~ G cܩ,?(0yvw*)X/ !P:J@{(R&WGإiY\fgCڎ} 'F_1PP3$_LFb~ ֯uʝA)3-LOfE##2J`jqN.~ &(6 [4_7F5, lw=>Ϗc[蕹X]rJz_H.N[ endstream endobj 242 0 obj << /Filter /FlateDecode /Length 5356 >> stream x\K#GrXB.Zb)A x{ kxW iN-6[so(fd[+Mʊ2^Y5-^,?}I_vw7"771zq&].BKp͛˕vnY?6Ο6KW =nNowso0̀\~Yߟ6sp~̐Aw7-׻]n 7g˕faF[7ݧ2OwNg)%PrСKInNӯ.fx{{Z+mo>@0B,N,XgVR뵓Rb\-Z+R-ⰄU8~XY-d"P[};n2D"qR^ i"Մ5baI;.5.]}X*⃑ 06 xoB*nsBb1MÅG,XZOFňRқ񦗪xi|Y#X8](k2&股}1A6L0 B2`tHvޔKYjTFo{-%z[I#uә^2+&sE-mf!B뉅qs1C1n:k̨Hd?gqtj~NU-;g07a*]vpgVs$nfG]4vZ"bvqf2.ZnWNހ3'irށ]h0CN %nFGO2; o̝UB [@%!^ɂSqf/LiSԁƘV0FØljb& `0KҚ;J9"ȸ˽miLL4XtOs7{hM6W9_TG~1425mqپJb>승RbAE`lCW&Ih똪%BbKLLrCK4**1F]W, u~vZ"TeZ^ۖij ;y@8L 8ͱzZNnXSNfr-@~;!0%* IZX`s뫈+91>,up7%QC DPYR%z]PEPQp*Kj$Ŵ/rl"a()"O@IPcU۾ CWI6T0ce C!yFi♮QEPpZ5*K%A1p[^$ Ea_0\a+e=TB0k\$5 -d"a(82,Q$ W&%Fy83ô/R-$c`0T}V,QARF Ci_Jq-B)xO"`py0u-Ce C!!F @\>JJ5l% (Ce Ccf"QR5G Cip1T03oSFe/R G C7*KʛؿPYR46,`py0\.AF1HJȩPYPHӽHj4c^$ +3݉>ap!3O(;A s:1Z}+:r#Uw\p6;|qÒC鎧j[C>ECyOC'O,72 Χc`}@VRcKokC(Cz_EwJmw}-zo[thDwۻ4 >0yS»T]q~wb}w[*]?{˧@^]HlA` OKZA[ѱ0Cm}:ԿRf#37SWrY;b{:.^q¶;L>4Zٽ[evݧk߱ޝT#%`oߺgkCGZ+cKY:} qKF*޺SMi?">R 3K0] 0k?C1 ][ {_*+ >wc2 1#2Y[l]ҎS+H]ևnLv#~!N%:I4i/opϟYm /⢁1#v{'( lnJSzOk,9 o;E<e( m3SP;!#HVTУLDe,MnPM)S!c9d+:B0Jz$Byl8%Lei{ h_^9 *:ZtIQɀt =AVP/LF~9zT9^ZhETذn gLk^.6 {^{ڷ}O3.lF=qRm{#-ϧ;.+י8ZKGEM)D\|n<1cpX):Ųn{Ta;_e(X^cd~vc8!]d<*|aR:L77jgǏywCs#r2ŷݼY3*P]ͯ2.L_jh9 (S *uUֶtnF#Bi[,dU_ƗC遜W.y"TSQMv^CEMmHN>2^ګSp{PZQF\~zN>q'~桶wMp778tKDoHqW:NKrnںwR~=cqʫ1<   h / K+[c|Qǵq$~Cc=$icحcV@CE4J8>GlU^Kre[*x6j!pC髱x6nbACg{dnob]CM] avhL9mh541zV)A aεG3{EoD,UDeOBS6ڗb˲w͉#ͼUv~jG#DR3Uܲ/5TAlFnޔ[8I *:N" UdG^𒯈Z@XmEk,l3AHl|ej@Cxvwx+#ɕFU6kUis愝k]FODIۄu~O4QVIEhZ{fjEtN6ʈv=9%m5"=/X!{{W zn<Ti 6W3 5WPGZeX[8 |Ĭ$M|^sP!FoOn/m󅼜f51\C묿 լ:mmawx[BlxJ`~vO͕ƜF*nvӃ}|iʝs Uͳk\#]_fTH{by>!%T^GmU*Kv1T=~FXWN".Jl^I6Jtӷ %zsT=I+Jt! +uxwh5P==4M1֙O;\D&/[Lr |=wC?+K86Z+oC˲ˉSUvyULcaD}>Iv%2}Fqt{0At8"!..0Tw>.vgCMfgA][JdzkݝRG)nOS}[9iQ:+|E)'WN?j Fem#<0c4+:jW?ug]W팙Oc~Lsj];vP +2^] D4ݭggynkRJ3y kzijzd1qp7\m8x`Fs 7Y)GIO/ :|vpۣ7iU0"$-匁VW&wj1Ʀ9U8iߔS-x\|RMSi?G;F}{{f0}~7eN0v&MR鉆_dD,aGeӎ_kF*.^Z+++}γ9c}?zGw0|0ԏgls~z\.Yx-61 UPP+9l9 "{vYendstream endobj 243 0 obj << /Filter /FlateDecode /Length 3912 >> stream xZKoAX_abF,TN4Ñv}oO&{f43lvW㫯9*92 ߝ>sf{~)5̽1"\"Vb*/g/ q%.jk*zMa%.KOLI/g/._Lٹ,DvOR.ّȍLbh⋋0V'Nt~Ka'ίdZHK|!դDhv&fHC٢%} #ҒRh"ݾ*V!_x[ӰRi'idɅhBkFY`7rcR5=\4DZt3a!Wj_ۏ;;jD"vGόWXRipZr&Jw2{c da4ɣ;UR+3r5KYaAy6jX=4:a%F!?t-dDñr$J8\N~7e2s=mY}Roe8˦ C,*El.Ao'O Df@KNu ^"8=R7f6RR0ur+ˢv>4<ە1,)>A;m&E&1b=Kpb&  v))RMS]2,c2&|$N,rmRk[]̠*ŮM>DABƩRxp(--c*0O25eZǪFaaKD8ɶ2dhW`;Ҁ4f)Cma Y[PY8-PQ.{}JmW~ 0I_N`b40px"XLAST4a{?&u[ԩGas\Xhj Y6': ,htPկܼI\ʜM6sAeFEmD]=__*;` Ikw# xa3,d3Xsyә;Fq&gs@SG]Wyl6vU쇽EcflcLeH$ć^0EK!^ #H|*PSLpػaD3[U棉Ӑٺ4f*E3d(tΝlk9񔴰alx'/7m[-fvOtjf#q;\`ۭE㰄 D:颴a.?$\q\r$g\K*/G j/{`taR`*Ns)lPЃQJI蕱su'Ҵ:EB&u=fztNDCB0i{Sou'U硲n*c\,0* $$?l=j˻Fʧc0G;6pDip-=%#uf΂_ d^w(T1`apJC&,0>B3 yzϲ@*vveU|8:A?vZdEZ ^~}X,|$D3DXlqI[>0bI6wS*@!gsuwWE[mկSJ*n]8!RZ:jTP14o類~GZe27iREx $<֖pPQ_N0Zhxe3F[oM}&S4>K8]S M6>+5}{wQtwnvۭvp<+绾{4a>Aw;V>MCۍu=}>B>m[=ړ,f?t?Rq% i *5IC[-`uYBm=lv]?P*"z{޼Z`7uV!ǃ8(fBl~)C_wQ_^u;Y vv]oۇ42@͛z5~t\dY· (MﷅɘCĨ0}u)d8>qDCuIpVC&F͡A8cU{T.bϏ.R"oٓj4oNtd=WGrWc5+œ*m'̮,Tb'qGʠw˧ZM~m6gۨ}v{hpҊ3.ߙƜdD6{ڋ=3g6iz`=)\Fo{d|2CeHl Gpђh|O7^H`jv vLt=N[ɛ:lNo?{*BΐeuMͮ6] SkhvO {|а;X3iBOm O\Y3WT-Ñ`h)?CD] I(`*{}blqi{.OAe؞T!#0\4w7|ѽd\ *QA)8&]/ |oL=urܠs.]mCp6 f}2`oǐzEմu6lJ⡩r i6 W~>B8$or8At>z c+TLМ؛G.n1y: rJl#^b$xV0 7pN#cզ8oÞ[rv$ߕZIs1C„a f+#%? aendstream endobj 244 0 obj << /Filter /FlateDecode /Length 3697 >> stream xZKscxJfS!yct -"bC񐊔]jXm~`1X,-.A_৫W%O^o/^{%MSWןxWea8HGi~qh(KmŢYpbRU&'cU%,p\lFFp'kb\)ꍗFv_s3*R)/=5 Y *H].J|~YĨʫ"X}u-uaMU6!avEP srP] D|N:Q%JV3XXqꚟgB6ulKӕ9Jo+&=|f`U}ଘ7{&ë&'sIrPM.\jV[M*lHF.S–L4h<@&O]! fy&tgTZhע8jWBaY+e6> $QgSx\֛Df;Y &Urw[mU;#uVuq0d@&T*~9Le×٨|6 b=m:^ d$ٙ+efir1|饬aįu,6z3L:]y'w4a-U~by,@R*zoA:[A* -۲E18=J xPu6o5a!(A(a` 'cij34a( ;%o(lY mP KAeo tlX>|d(; D-: eQ`!mJYfJI=(VcNTf^tm qC9$.Z g?a(K^vۓ_IɓX_!݃Քf+ÀӬJĹ ⻁ƒ'$7]P+sޑ/6w sɩXx;C.mȥ=Tm#M3T#^jޞ0& |Uiu-| yg ##?J}okM73쿀vn- P͏3bh%#TW~~) XiG# ^sWUEoӨc |>5,JG y܋r f}ԣԤ<"+i`E*Xn~cFSΗe&fM jn\r'hr&L¹VA$<9u<aɰUc1#ZL,d~+ȼ*Rv-vHdɏO-@`gB3>[PxA`R^BҞ(K$cߎ50K{9ކ\5pqpgA11C%c۳Q>#jẘ vO^{4+i7;Cy\͠_Pǧ-Ą81[dBZ:~GxNf'ZJkh >ˮHte3J=f$@l'ˊrd8^K}eO7xڐ)U ;r%N:r%~;hURgЊHpS<%㍲.'KI.+-TK Ll8[ZS}:$uP HKdP=X~a|RaH>w*vbai O-:!>K~ M/aCda73~>hCPTy(S(e ҃ Ely C}:#Xem,z2/mBHazyfl4݁ * y:D@ӨW̎`*}0h?7|b"nV&Ԯ7QÉ8D/]I7?i*ٓmݲ?ZP2txo#+(Ј`0M $VP/wV`$7lOhC#ax1q!M'U$Z|<ɖHN=(+(%Li,^3qR|&n tGwO?'.endstream endobj 245 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 8162 >> stream xzXT2 j`T){0ì:0D^X"&F4Mn>cY͙?츅C'7I2yS6\jIm>FQhʎCSc)jOm6Sj 5J-&Sۨ)2j*VP+*jIfQk:j52@JB "( JJP`j5GCzP=a#ʏCS}_SЋ@ERQA B!!55YExKC.% ,!O_|Pi/bp, xCSp#24B31, cgfak#"'hD1`*jJǿĦ]"VIh:d+tzL^?~$9pf/rs/;ƖB=^{rӱA4B<*,r^Krjrd3-v؋8 Df{DsȂ֢,5$YFC9˹ȫWTW" W(}j [<YNX4Xi5"vh`FwGw ;0fKoQomEE7\%(F;FOq 3|<exo5E%zl~ˌdT,)Z$/2 @afS񝶽汅؊:ZŞ+cYdtLGa?pzQjn Mc_}U#! (߭/1ձ䠚KA C&?nV$BcŶ!Aԏos1;{;e㺠-B`WYV:뵥ܰRcX1 ԁJߞ<ﺝY.Yv+Pu12Iղ\`!T}gB|R&$*U5 ;0Y]PXF|[|df/=?dU` 9Jt4$k4V ڒC.$#B(kFuʬ6a{J!,}O"uSCƦX om-~~fǔ/>ug ó4] <޾_uq,?l[.0ِU(CI _Qr %њo&=B%E~+Y1hk܌`z8%Fp:VͭklWabD{y1gWI7jsﰕFj)Zto%OWY5>#%j| GkBt =]"+ˍnjѷ X>J<.Cc~MemV=Ŋ{G@oj T4ܡ+5MP5 mǃA~Qĩ.%vٗ=^(7cUSuNaC%nc/yzh^X?*Q]MZujJhb!+sRHU5A?)1r/4C ^fl5X蘿$Ę"*(4",ϱWh)IMǃRlmz.䦣^PuRW{qA4~r:ڳARATQSUVS0/Cs6M*TX" 狂Q8q*rK<)Qс}$ozP92QC#1IK']VZ.Rj:n&Z7h5?97zQȆD: w q=E$bmbgӜCi2!^A$u} )$ ֐nś*܃װ=Pֱo<&oԅ F LGNOѨĎx:,qj8}G0r LͰ$mJb")i 6Ƞ:^/^c$iiF#N9oܸ\!kۘ^BtB :\"x&:?(4K1%@7`fjM]A&&˪? !^[ƍ^v}MtEcd 3eJݹRlpd{^ ҿ,ɣT 58~%ɀ89$&YR` I'c/޾Ep1,o ˇFݭN٭C"v_X;#>ybϐjd8.Y>˒' rPSdģ|ɥmA7~~(o2Y iylcq(Mt АWm)sKCvEV[Vc`bCh_#8woКkBNI@tm3Sy]q`5 PvhGgV'^~iΞ>lweʓ7$xx7t˒ ҏod7Q]S7s@c1fj,.q56RzȺN`ܞy%Ei9yR].! @rR~GFEˮx?L\6 ӷKV*m Oَo ,r,e>| Ӭ,8p(?Mݍp'!\._{#o9\kp=L)yzT;Xk6Ĺx-B?r}hkUn@W6]z:\yϩ*;ޚ}O~t4țO,Ŀph1q)~N V` ћh*b/WHd}fL;↼UQU^IVi̳ϕ?̳_T[E{ۉ*lo_5JcmČD?×:vM[Ćr{8) (*Rq=:ϊLЊEGԄu'^z$m ;$WɢM)W' An>P'=( +E5b1U&^SU #(H*2ܢ3_)0Ȋ*$ lB\Bvz yo{:"#^Pөs*+ ޱ^;dr)b~ Fܣ7Fȕ{,r+*0(8 'lVCXO5ke$*&9]ɢ:W>o0oy= xj! q opml%M|QƓ-]zv8VntlF,!f2Y$H*H`lAJ(: [iXkdK<`3lh;u+K mڥᾐ,eEؕk]Q̌O,ix7(pS*9+1D'$U2˝7\ »#1K.撱a;u㎠@p`G77l./ycSy6wOk^Цa:LzV?#$(.0`+;$m&3'ř/69%o/;4qSGwq3h+/!K"9;IUtgDlBSS R 2?zE繎LIKY{T:l(%yk ew!z%ķkd6h>Cߣ)czv36Bb >g%`2t߽Ő׷ Q{df8RPAji컱tn- ]~l"M$ȞD&yH.=h5?g@ 7ood]wnwG$(/@x&^x^X!~Zf5*n"&'bDQ ?Sr2ؘUxFˑF9=`Ŕd2q#/8Y(C B eɳj"sM;9q26L~}XmYΦS2@" Nk6+"Yb ubebJ oxNr=8 y֓?5S%Ll&Ǔ4$nk?aQׁt>g;g]1jT姛L$xx= ek"b視Ҋ=[Mƽ6cE uHkpMdƹp$夑\ 96A 2rrYuN Yww,%Q/XP/~sО % RkSJjf8؍zwfB G>c;j1 QYެuA.*Zd#K6DQ^dI01w9BٴKrʄ)qBB%N-Hѱ,Nχt,nQ^t$p]δ4z[LaMx)m$tacGJbTpA NTA"3ƻAk"Mˋΰ?ÿ!N.Zv/I:mwRIa%6C$;SC bJR<' Iʆjo[Rs3"c؞N{@^z/DZrކ mNKH݇H,endstream endobj 246 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 324 >> stream xcd`ab`dd N+64 JM/I, f!Cß^=<<<,*=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ g``` b`0f`bdd ?SUe/>0oaWw[V}GoG~zw#/ KUؾs p+]#`-ýyVT#3z@| НVendstream endobj 247 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1395 >> stream xmT[PSWEPi*C;9ebVS'RnEdE`xhdXě. jgde ɩJ""DMl%D D yH$vavF@+>vbdi vF]h2n`P {,"%5QDg#8jhK{E'%ba#]$\E\d`,Qh =P;2Ub#~i;Փ_8$X'.X76'Vv<9qIMu ]ptøPuX׾1ݍ7GYʗ!Gj}3tw; K#NZ|<8)yеނC}5qztQ2~[v*8ڑ :-+)*9kkHlٴB9eB" 9ao3eM:c.drLRDk52UMuUFv5-r=%iIav]WN9MA9GP j@$埴3xԗ -(zcԚo]F(9ƈOU,e2JQ 5%J3]Beq:0bTFriU[WǑO[c{B{byFڏJ#jDHf\N[ol^sǰ91$(Or-0ej|FQaq{:#A m e 7tl>_}rNV\ 8?5GteLINVRO F [M-̉⢏Qo>vx{> stream xX XWfnѨP:UĈkFQ`e_i-K7" Fh*I&&gSL2_WUν?9?-l(HdK+]'$,):Hf9_-X >BϞh5bsq~i=I_ea.ܖ/^Lq lru :%MIp =-M!7#\Jc]CƒC].~!gW}sc_S2vto-2Ĥ䔠`!!;C_ tYƊsnX ]PN/ԫZ5jCͧ|M^6Q{)j3JPK(ʍJ-Q۩'AyQjʞr*b55I 5FSөUZʆʠWjQSGlvٌn=Mϡψ_]դ{L431i>FkS8.3v32g\cmml3W=S1NLtHCz?? gpd;.RpN"RS9Ѝjqh EǴjM<htu+4 ;9rXlZf\ش7×H73m Xdw}m5wАd>p2G1-oUMWM3`{uC~)Q۟瞅{"y-~? 3 |ֹ)E`-A4 q]1 `V| G)qG_^~5O7䀠ԋ ~Lv%BAu#Zfꔡt~q3CKB|"?"[X%zaYМt٧-󸣠:Wm dw# 0E[XI Ii$4bg,gF_D7 ]D8J :[}{3xσՍs}MZGOp.LYïn>^@Mw4iO0EP#bV)n$p#Eo5pƞ)94TӋ$:HS督 O3V'J˻ ) `m@92nB6f^+~\g,\A5]cb>3bvLhW:2By\ܧM0jFҵQщnĿ]QN/2$ oQ-=L׶.Cuɂ^ {^k!_x֜*x4Xwm-a$+ c~t Ə*#97&TqSZs¾aP,c;bZ@iB _UG[3eϯGGHܲU0w4E!k&WHQba)| [h u ]O*ʩLGˆS [z *Iq :R\A֮OM1ZEsM{yCeMjM*Gމ-x^HdycPiyqֽ>9koQaJ @9{=c6~|G枠"%w3`%:o{nOI-8l[Ǜ6sʋhJsСNFJP# #' KiJ~4.#;k/ZDz<it[G;x!)nbW+~q[#޼~ڀE<AkA5.l!V˨TMB~8BіQr5&H54ͯ U"“P" ]*;0q1sSU\뻲\hmL <k#vᇏHe}cgn_{^sաr ^LmJڕ寎81vT"śWIN«e噤LfZf'CqF' R$B s,j 37+ZCPѱ'#<ufwk+4%qMHRTmؚ ܳ+E^ٳ\:7l Ϝ/nZj0-Z97k9үI3Ǚn24N@YD`Ũ4):w}Tev$j>> Jկ2DR .%B(!.]у$7$/?57eM3#_}uw{~9%i\czTs'0g&- y tl{N*MJJuI:ܦ$ux级xCuG&Z,v:*T\NA![fqt WT8&ɬbr]$Z_Ox25Em:u}Ԙ,N&]+.NHK~0 L}-514ii 0eZbGU[xb&f*'L)d6,e,HAQkx<$K3[H4O+ũpW`9 z X +`#H8nSFOH:ڣ{m?KQ6)IbIN l똢Ir8f_3$̣]hLOv׬ mϪ6յWUer5w$X~<9yHlc+O'|֦*rrU\4^$)Ϩ̨JF8$U$&!DQ().):[kqR 22{PjmkСfL? Xm' UY'P:#_3PJD8(Ɣׄ/>ydSe4G[SK+PDËa@UR0>0HUvr]_T|kL{s;*}])_\\V%1هWlC6>"#2UX4k$x5F5|(ذ}1Q!-]]b{SyHHP"McZOJ~+O^`29 Ic<3H ۾E5"y%pF`? <ⲼX|;r<޽Mw}ɜZXf275<+,{}0Id)9|VcQ ^IނPnGrP$$sf,8̷-cB:d'JJ5JṭGy15iu?^+prppl[teYdAy :VПu)I\?*gyMZO~( T<5Bx6TUz;dO:e2dmWXT2eJXQAs҉Saendstream endobj 249 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3812 >> stream xX xSe>ih8,\:Tp@x;@- m6I4m&i$_fik螴tY+ *#:r:>:Ο}:> w}O{z;~CL 8ΜmwIr+W,\#L _\||0"+n>PR$)gwv.ꝃPl$dJ7H%̬VXldtJIˣ$$"at8-zˣwHEab8:%=+9'#Z'}ot]7߹{ ׋lmm)NN)Iݞ%ܝ2X@ DM!Dx@'^ 1o&b3xN  h 1h̹qRIDEx]SL#'?~3GYxYQgKg5_MEQ#'965=ZP$06}F ͱ'=TeP%$cpvZCF&Zo4jwHsOE*`@?uz mnhP%Mz$5\k ~ZЕJK—6G tfMQ=O+/t']I Ņ\yj\ VR WOlZȫ:AoFv5vj=nٚ>;k[FQslAv2.2 #vd-Rӟ}ˇrCO" >tlC j|w%Cx 5v(ePBv#F><MESs-g(v>"ڡh:scǾ_B6bgrbY&}DulGG~pZqr6l.`=lǧCRâX񞽉L{ q}w yN#.Y"hNM&T`tj@ j+qu@"Uk0PJ ]ٺ'VC .Q}/}.O ?b9nhK ]aRY[U@Qwt ꈼŻlWHu2Q9沘Hu**F/ȋ)dttMa!5) `H kM fAL^J4 mU?s xM`2ٽ!|قK qS>Ћ{7 m">֘O0So"2 ФR3"$km ځ0S2H³o*;Q͈I釋⬧)+Ņ7{d(Xm&b̒\46KTKv):;;țzf[(y}hqu-*h.j52liռN=_&iG9npdz"=-&2k'~ m&+X.8W'ّ0T qA +v_2hB#y2۟<]蜹rۿb 4ReGůjͭ^CY4fy-h仵P.{B[4;X@ I 1Dj(724ؐ6B  (Q #`ҎUMG&QZq7 VŅvMGYD%jvjdhVK rVr%cۨAwPDhFofg2 6&yq %2)ժ2`V1;ٍ^k_h4-c;F@uv'G9w7o<<%R^rbHu>P=NY$F:g͋1նQFµ}@ B a!=]<zZg;ܷA'ezD:aDjtQvc1z6]dJUvmjwi G NК FAb#45$3JDB*tpP*r : (ZN tǕyC)K(9b {~lj&E/h Eֶ@+q*e}^;<9IZs EnɢM]kka<#r .p6>T{UP+Ҏ$v*}h+ri}zD(H='G9p7C=h+QoH)Pkq ﻎwiͯЭ|ZQF[7wlrsߡx`T[5e͞zF'^!~?Z­/{Ͻry?\,}WU<ݞ>ziƪMoX&dTj۾7X'sd,VWaZRNݍVSۃY2_H#*u55jEt >*Щ UG;֜J[!>uyF]UeTFu':R'0Ax4;LXX{qTJ[uB9t/q)]EIX֭³ Uz! In*dv:(-_*; $~4mG8_= m*J_#O2vb(؛qC+OF;]Ct fJBc"lNyrx `oT'6T[X>$D 7&S4KDٹy m=.MjNa(0A6.K|û|x ^1:iW˕(8-ɨ"_p |> stream xW XS׶>!$瀈cJ='8u֊HEQI`@ Lb 2VQ[SPz[h/[JMv{~;ɗ}Y`B1hiЊX}ܔlv5JU9C@?.~7%9_|nClyR-5!*"2Q;ud LmxvDbQZ}fA'?c["1[[+Ѯ "D`ŲU!c'~0_m ;)6o"*d媘)S0˘L03Y΄0*f53 e2kyDf>,`2f13yy b^c<hOf $1]NNv%lwV:orT)T9j:}圸M..]7Jr{m@^sOv1ȌvG*NjDn@_$w{JX~&q %IޫұW `H Ա8@KXd>~r+)Po3tϷX-)p$/9$ 73nE8}8uMLfzt5μ[O57j\rZ8Y5Yoa]fLv]рnXnJ5;{2L6x 8=zĭX3G4YxYj;}Dy a``%NLWOt(ebpeWf&d,<фN$ZdK%@+wd5Jkql5% sB-y|^2$[I80YtGWHVK8.sR|GE1ݼC7xMr&wWE\&Jp8OqH<Ȁ5Kt1s';[}߽Liz3 _Ya/EwS(m2_sk{PCwY~E؝aLT.ܞV[k?.P/Opbs8ѿ4գ`MfPt6+$`[">h~[q؁zܽ +цsEŹN&ێw-p-<E nO>xIɲ8ǽ*Q??*X:઄j  ve k/7Ø_5?X20Ԑ#سC[V[蹗'ax!ْrE²)`,+BQXȋp|.3v2${wˮ8Xөe,6=k6fL.-{Aw?O]Pɶos`;_(6vOְlxm}eyofoT!ܓ,<$6Dnth1"m>:BC*w2yo#5U&:*` )&lR]ԉ `9l>kN5C(ğ ^>o=l4pG*MeZ9a^%~!5g1VRa:Fe2ƎG hȱtwXLVPAht_6&zÁkAU$*N]cI˰:]ΥjVP\J9>sid4scʶ#~ϟbA/*bdssNߔV[r}"󩒲o&hҀ\y0)3F{>=%?W"Q @}'Q>E0P~S If}ds*p:uO'nȋo@'_XӁs`#'oSuhh q )w0bů  %ؤ@a Et*kD %U-b+R4T,5!6|Q]$'ܗ=ŋ atf,E5cu>?+;B.'8xq[Z++OTI7Z>+P9sn%4 DF.'?/xG\n~ DT?xoOAK*Qϋuw?ljI$yɿ8vpc[,EBIIwh&PouWTL; K5ɴoy:d:E(Gw+2^X+ƚT/ K/N/"NuŴ>HvF#/jOlHVPցjrm,fHaQˉ+ ؇Ͼ#3z%6ΤZ+zĻ8z v<*#֣#쇕J* Il<$_ľC;Oy[u7~so=_/]/QDv~l Cr8BŽ NV%鯯cBh ܍*L;=fh%DIˁKUO@g~A:W[UOW+^G2`0QVչcٰ̽$5Ep*?uAWMT.- 6a D8[Kzyh~iEOd8TwKWZTJHw2O5Q8{*OMî9h~I|fin{7T ${ sۋȠנ/Ma{ueygfoSJn7T\8MP)7:w=#w;lZsK4qj).J5^ d֥ގy-yJ;u[cH]78@spb,EhqZrEye Y,VKaA]7gJX E2`>endstream endobj 251 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1041 >> stream xu{L[u^%>y">) HA`Y+[jwl6%VR[kجv+bSJqP+0  y&"yxȿ%h\!<>XCߙn8%<8m.8^q\pJ~NQ.ZL`2*ng!2X&'&$ -Yv)w7U:3*j[)zD ԎOCr}g ^/>P_*-ԅtIֽ }A=%8.GM>@Zendstream endobj 252 0 obj << /Filter /FlateDecode /Length 352 >> stream x]Mn0`c)MɢUؘEސtgüUez_r~ͷ\=N~LtLn)k|,y>JsoKM߹8#a"O)Hk@XS{qQ@m+ 4R(ĖDlO=b\2T7EU{fkl`@@TTrP2Ę:Q^JX!4o(+NcZmDr9YϬE25O>6}L|C2/LXendstream endobj 253 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4535 >> stream xuWitS絽Bع3dPcr儒u1$i)d0,AeɃl㑮6e˒()I4%-6i~"Yﭾ3ɏǩLjV3_5ֳL\].*(hђ ii+,W Ks-ܸ0mS<PVW(,O+Oۑ+-}[۶޶9}y DX\(Γ saIXX+"qawqieYI^BTP"(* Z*:'OhDzGSOӘ=J^vQ+*j3:zUj4j&c;qr\7RT,7i2BRmҝD?M2Tz֩G)˧͙<ؼ= L@ěrD^SCFpuMIk_ F^79krLJ; h 1L@;Xu ;}oM#{MijAM4 Wa&M~ p:2pu2ڍ>J 痣*=2] OUp`z 9oq+9.l/`( >9~8Ko^kIZtt!UsGmdӘg_4/87Zqa<9v5|O4w] pvFyV|E,o1d3Chإn:~)ǹh`"kqU<}`R Ev]F֋wC A1љyNfT =-h={l9ʒXKcXm;#뀏)-H&Zio@x,;-@m˜k,F2*l[b x|K.1h+-(-mhkHJ2$ W9+>A Qlwwz'8 L&,k1] +ztbCal!o:coR)ZXcNcnH[̳迋oS.RwbCk*ǃwP0e*Fq:A<_Π _XŠ&N^9Tҿ䠵a.ʲ!I?`xf`ԽYH"jN9߇FSqSA2Qi<*Τ71_o4ԃԚ p:A\zV3tD䑦p_pMmASX*-G'.o^| d=uQW*%#WN#_i&FsO[m5 ~o0:hEKzbr<6a6 !VȻMu 5>;;F'l~,RuTCS`~Fgpnt2dY=Mmz,=ͧO:x}yEUY@>F[#Ѝxh{!V((ZsFWW\it-uT@A'+C_$bD[瘟Wfς2Cވ y TP V;!#~D&sRB6ſF?΍:=hi07hˆ6|#:Yx>s`-m-,!+:mNpB@g=Boh@cZL c^Rh”0k}lMdѶzYrKspno^WūZYbdCIW{a:fNFw(( W!34JNCob!d(㡱pcl58z77TD¿9q*w.-,Xz2hT-j#׼7+P'( h fxJES7%,)[rΣ?jc7hw;wxfwnf0~nBMT羴ʯʙ X~eK賕ȊEy,.KhZWe{[ > stream xmkLSgϡ@P/[iVE'n2b:ut 8"[K)Ӗ^8^(۰0'*hK0yuF-F4پrL%˛y vfg5Yytze g%F'I 0ҲD7z!X%xa2oUjEEFafGtKT&/V65T+2,#;Cl ZeR^sD<"-(/ߖ/ݑgW~zϰF^[R&k0l^L_Y =6LmNX"\D0$xx. =3tH_&jZRb$ø17GuK;%/vor%֨n* s )Gw/\ÝzLf3ŷ) .Q|,sЋ#^b<,Oˮ8 \ u&UV> stream xe TW'2"*q;nR֪hyU  `D𒇂 PTTԊlڮ+w}ծz9۝ֳ{9sνww9p7K%od6Սccgn\<h?0gr3⧡Z-K.Y} ~ $<=)A(J))H*g'a8^+ C°C6xx_]'Sd/>ZdrwHl&B0XCbL J& 1L8X=$q9rns{؋qp0Βj2FuO>Iڜ~#lu0+ nG\-V,3diP c`NȫK?% Z @a'H|H\p=0^Fx|qf1M^@~9_UZ\3Z-h{E'4 @!l'&L& arY(J"u 27M[x_CEe|]):5_bl1r̨)&AAeD)]q;nwMՅm;GOWY:}aBA,PI2A")r+}' /[e4 D93|4϶&Q!ꃦЕ{AHUPĤxnPq-sM\ Z] =TaysS}]+>3g(9Vf[:e< ZM$ey]AAl%ؓ\#6s Zc(rBjof>nXB 8d,Pƺ.1G##7;wwʌ(AQ rjr#`TMRl"C{xr$)+n`^MLlx{mپO;{uEEC_zqrpa  zUi%F,,ڡf65>$IKeƴ֣&7q+p'ĭ^ܗg] QTBnpvW;֊ Ң=.e؊KoO;H-+N1`IͦK. W є !6Q<:CrJk]<˜Dz:ALFH*gu>k&qj7k݃nJ7>jv>hP77zd??b. و};aU. 9cMM@fW:zp|m}?4DW <[vCM~<YVv4t͆;Gds~+W$Z3!1عLoEQPZ@-A-פ~MRrczyw:y9kS"V] )ՑZh= ~b^dqAɹ>Zu_z߅?VE#ǘ.6|i$QS``rc "1PzR%x&v4NZH?}\4l9q $ epeyrXOlۢeia7x J+U<E5*=%%hOW{JMuy-al - BD_dI8;W1Pb<89rCA KL3 g-iPd5}g0L=\xkUڈLSf JYܟ#Ff֠h޹-0OUuW{ڲiU+.ZeIM[ޜuR~E!^ @\ju[SRSR[Z[%Z NMKK(S^\(),߸*?{T~mDs']"n9?;.FO,c&@.![!= Z.3-/A1mw+8E|tͩ3s ߧMC3jlr`:̄c;bX^ @Wf{[J459iwmJU"} XN{/*~dW *]h 9Vn[W9` j\Y yyG숗Y?Ƞ6d!_eiC)Ueyf}hh$pb(kZ阮L[JJĿendstream endobj 256 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7908 >> stream xZ\SWۿj6r)m]^(**.! !d@{oC Q[oXR;{}熈}Js=yωT~^^vDľ2mڀ=qa;|?hG?V`# Iwxa譡h3oX{źM6mƔ)s7n+v ƄbTURr1m|d΀ann>֯[v۲{0?fw(#6zDnzc%Kc.Hw\+qՁ{ ]!w+g̜5{ܑF/>oSLQ#(|1`L[ꭷMXef5y펼V_C3{l"bb鉨 MB*ضu`,<=\V 0 | -LaYdNbrt5} %TGIcVg 4 mXGxUB_uoIh顥4زx=>-[?|RՉy mZf3J=fntdvbMm"4f/ ^f//N߼{&y2KCzf} eTfف&D^r/$t2J,'Ouw^7W*X+b+h!48 @4d3zmFgE!$5;|cAZyZ(6ƀ$ʈ cv4X[-X&[0:DV6 AWF#8]6@Rj2 31:aGFbp"مC186蒐g-і,J˯5P|C=~| /awÎ PcG f $\srlqP.J2KԤ+ ۹G q0ټ'λ^AyqN9 z4,,C`Oo24mvb> ֢!Q1p6"6\ v M* 1n'J37'^ hm11.V]9ow޲|F hyMi83xb%7wʉ4u)+HRʼn3ܩIj6WKqrIʝ v&/B4{XA.U@3y4&ˏ[d20(ͱ ٗx0?HP ayJcZ G>R>n*'QHV-=zUS(% []bY"P:ɇ3{̫׺wh&Ziwao!}3>}P=W꭮X]|,Xn>7dFfG> U< gA~}]Gw/0k2` ˶&} dJSIz.ّ) !` OdeGA7:&r&0AIVY{Nd6+H73f٩˂,;x)ņn!: _ė5EjєI=Ŕ6QZ’R. o ,x0`'=[ pdL ݕe}̰šZK$ġo14ANb]2B@-$ʽb502H!Bsz4N C%rY6O4 vݦwbMҤs{uvq]1$?1;ۙ-MB L}YKm"D)d}|Î$lJr%7ٕ]2ImPPRD`Vn|IVh3/jB@6eˡ=8XľJPׅ`l5s_foǦIo6Q e'Ow!!)KՇCf_K JM&G?q{'5xnDr31* o^>3; }R <˪ˁ9JDZAzYZ2Z:ݱdc*  &sËnr,:÷ N7%At$ 1k"wߊ+f'v;_)`@PD;@aPBa\]_Ѱ@:yd r4QWjC<3*!C*Ś6wq q {dcQU-pWB (r*V/Xg|E붶`}lN^OW@!鍈EM<~K$oE$9(;cWr5Y:]-cPBҷrx R P6j5DUp@Pڨ%!㜮Z~&O+e_ƿ+e{ƀ4=a$\;p}K#zQeOϝLxI3} Ek2^pYW-tW}-,#MNP\PgG|г 'Bq"̯t$n6v#G< qTyZ dYfy. L x_skөs߫>Zp n@ߒ._64KeׯYٝ|=R0{lb7[f B2fcivqtNx͎=\x". vCͶf1;XX Gxwq=;)p!)t3Z)6{oY:I@AFKzТ?p*>sВd@T;8"9c=sb}y=a7a/Ηouse BSR᪠y2Y߭Bςz\ї[yWYBC ( ҊE* r"cúi2bޅ/iN64e46T苲V)j ab?Hf__XM'gN{IhBvzcq0󎮬ȢT.R6!y- Vp::3fo rX}埞9ښY@e`=Ć(M8 צ+!r܁ٹ會E_y Ɩ@-M`>\Az"JB^ʰ j\CG9qgqf5ӀyzU m~=zYR8~{x٫#$zBGyvzJoH$ˈTG5@Uu矕~>Xe5h8B!EaЁW˸]MNh hdiT qF6Sƒ} Hv g˗{~rO_|7x/$2^w(,4,֐a֑3 LEE-g.'v_0"Uc.%,//}{]*{eFu18f{H$''FܷD&XwӶfΪ 5py?߭@CϠz;a=Gxx/ t|7[G>Vh#XI ?rqBɶծ-t.\M喷G>IR(/ifMD3{/{ Rs kC8lO ڭh. !8Tǰ7餐j"nM:[vOaلqѮ⣇VC~|n,{PE3/}y B3VAiBqV%#] m:Hr%Kp!\#zlSnkAk9sX%U:s(NW!+7`!]sDL2*Tes.2k N9r9GYJ^L8ѣd/$܇^BԭErZV1:b_u)ޓv'U &݉l֢o ?fVkY>CS^ ɓg ן4_$!24\h]9#xo)Sf@ɂTO͕1}m:p0H1ʊ/1F]QDCl"xBc̊O 7΅b? oCMln1>u`J͹^F|9,82O+:BXv1nEOw%K("4Ain  [EzKy[={ԁyoŊ[;ng9 RM,IjF&>?=O'/cT`KFlij )gbO]\jp:^]'~_ rԿ@)ggjID`n;6IW7p] 0u`ʵV9! '|Ǝ!OKSNZ\S5yƦ#9'h UeDŤJӕ̔$FC=\w᱖ChӻYӻ魽mqVvg;!R3MML6) 4;YVx4:3Y-qo#S13j"Nu~ys)i "IN %LBDՠhĤ WiΊ"(|~~Xe r;i}#kn o2/N:.IoݳYw^BĺR)3+ԫ5 <ʳ]d78c]G,5D@[VȞp*D2'%h5y}oNQT6CqW9VJTGhVȭY&CcGuw$eC.%esᆞ7F%BO[̟or0}ZIҴʺvf |fHej(;JGiOb>={\u+<-+}}r6^@s?Ɖue} -9=њ?riIZЦk + s 5,J@y>F>z5_OZ8O0xоcP7ܙUwX7i?eendstream endobj 257 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2875 >> stream xV}XM߻{KBۖ9MEL }>ATRNR _sɸL)AK)2*HJ*Qt1:s{<iSm-ԛZ7TF|M(t jpEJ`hYr-Y=ey+G ox4;fv #o@7qS|F܈l0vmmn֮pxW=C ^SD ?oyaR޶-ihq/"bKm=RΖ#`"\WݻW̎wk1Tj\qtÒĠ}28,Z6;%7 &œ\(ĺcGX~g[Vb(P->úN\boƊsq%˗+]<#/ޗ\kWwiE'+9'\}P >)|2BX ` V5R"%⍱0}pjh%|Rk>hZ:hJ_VNCcn q_>!l{%}7DR+.庘N!ɥu lVlVXos[}'#wΪ›oODG}9lZryŜURsH"Hn!>mH UDxa7 -Ybub z@ N8#;/K)q;8?*wݜ!Y 7x*Q NءG0i 9 l*qA-0 nt56j iOZ'(gpF_Ptlm,<GH WT\\U'4ǮݘG'f,# ?GZ>0gEkD-Ԓ$ь{柔jQ͈#4jGfqZilP/wWM!ǛO/1 lNu @!(hՍ>UkBZiA$I3&qa9({Y#)w[6 3]ݛ4abJ[8 Fk/xyo5'$,?2X/-X\"^|GW$+))|k jE|p 8GPW.Ƙ_nVh 0Iw'7C7u4 ꫓xOdnΗHFk!'W{ߚ("urfkA|t!B߮<4i!WYdKg+Px eD. ,x<hg2ڂP`=hX5ȧ, Ks5 n@;Ǵ\BC9?4$ψ?{`Onmw>C?i_hwK=Cq"\552,&q+ [қ{c.U;RW^}:]hO#IXWbv` [QbX.C$@}  H]B}ބ)\c""\6"l+%&O`<ACb^Ε#l/> stream xUkXUUξ(xpܠ!SI ƢEk;P 1g5 rAPQi4=Ԉ~晵.~oַ~-Q1,:EeM+LIbJUd7Vl'4h-d#C퉣j{*`=cՅy+ 3$133r 4XeZS83;yM!:)'ߠ rBLƼ5'gd^:Y?ü 3yD31'˼1!L<"*cd1aL8D2(f1hgFH 2n~f eQE,ư9۽iwf?*ZU9s3|,OQX ?/kWc1Y-1>cvhll:.h_:2x u (8E RP[ h {a:4WMMz,]I4l Q+z OSy-qD/yB6SlL)ThY<ؓ'^i"ಆ 5l?Jt\o_trz<GtZ~Cо|᛻۱VO [Jd!I  j`tC \&Iہ=s>"vv}M"xnbF|=u]dݪBƊ[jtb$_--NruQcZy'+l1w|jNm- 02&G(ed Mޜ&7cEtE{{pkcŠ40HWT|a.?]n٫3ͫᛂ.{kxR0LGNs&}RFݐi[;^RqBǩ;0rl ڣ W$rIFQ@K ~xC[HE[Klu\zРDJ4oi7MÍT5~9'/r]_G{=GDn|yoA"_QXqc~fBŠ7O4.!^ץ4>Iۛ6k0y)ˍ 9 G?ԝe)z$ e 8 0`6(# ;AJ4ܘfy?sC^B5[%  Wϻ8Agk>8OYph ' y"T 0OJݡOy. 5& <U*4:򪣺Gdw}xXnW--.){HPrG i# }X]YG)q!pG TNs|" ; _jZMDcRiWl gFQ-oQ^19(ьrr4p_=00RG]pzuV*$#̖og !K1<*\/ܛ3aЕGzEyq$Yw _m?%ݕvj@.DxZ2_TXUca!,t-}^[1K9- r-Es{0 &j'MKܖWScM[y"ǭ}ݺ!rk .44iw%se_5"¬{_FOgd!O=8q`OjhE*)J Jo*j< ~%>e2%SѠh B a <ÿ`$r8m 5?NL8W<QO*:MڊEyhDΏQzAf 0U ]6R^]P/[vAD< z*A_8aO.endstream endobj 259 0 obj << /Filter /FlateDecode /Length 176 >> stream x]OA  ~5.҃ƨpoLfXןz2eZM) 8:OAauSGºWD<]E?$U LڏHZUk"I|EZyP\c*лq%0>5g<~. o#Yendstream endobj 260 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 418 >> stream xcd`ab`ddM,M) JM/I,If!Cw?YyyXP"{+#cxnu$ʢ#c]] iTध_^竧_TSHJHISOSIP v Vp :TѼĒ⌜ĒԒf3;.e ,,&1iCtZں?wwwH6L9ҌIr?4O?U?K.*sdaLf.^$QNR;!f QW??jK-^8SǏ!nShl;vrq1pvp/0gbτi<> stream x]mHSqͻ9m(kTs}ДDKYLsoלmZ &Gǜ8 ה-jAb aa ("︅m_:8sI Ii`l<ՙ/5n6`';xbdx@gb`&\2MmVj4Ux?D״jX[8Vx.Q3nZLL4c u 1.֝(SƌkG )!J*Z$tM'#U\xY:_?2's\Н pܳg׭30+'Ǘ=BC9dE6BѰ#9_awcp.h aFvEWӂPwO= 6A³ve),6r³e跈t&ZVk[d!".7ngWzW\!WD ,? m}>7? 8u[NsTF{}6].WcAe*ʃvhWI!2~eLBG ,3$d3F,ƙ` ћTo`R=z{z(*<}>OG!tendstream endobj 262 0 obj << /Filter /FlateDecode /Length 171 >> stream x]1 EwN H*RĒ.ZUm/@1!Co_ I[1\/Wgᅉu&GcB]0p siw=x>[ %h݄o)ViOʜ,:mC#X.#T+X >b_WCendstream endobj 263 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1208 >> stream xulSU=J¨m} [- l$tF׭ݏc?趶זn00bF@!!4`#"Y8-?79{ssͥ)iz⪂jyl[j/̘^l6N%V!e)eՠSNuUgX)JKl>RYfΘ1ktyϕ99cҴu[M}3Y˹yy\aM|hrj\T]TpkҒ%܊%y/f3[-eujsœߒ~vCN0793[,ELVQ4O-"tbR**D/W+~SڕACean`G5[J_IIOfe8mff`v_ sL8K NΞ"qH!5$m $ztOQ%Tx|q\FxBo)cW"mhL,Xx3QHؕ{-~GWNƴAA~f>pٲBbS`),XK˶Xwyh,1s׃ژd$|Ja"f@ M/CWkqw@&$p)xCu,r&)EI>gj ѓQmHu\1W[u2eӢX21oaCN~|ȣc. vCf!NXga$#H?g0"jBJ"Nhi'tUa>Q#gI;&̅xb<&7/i7I/=rTx w%:MKhuub'SIkr("! ^芐KRqiPy14sU<|A<gkRRl{U=A˟Ń/eɓV ݹdlxG#~ e`&;{q1 N;"k͗7p}ٚ#ji. M.LVe$:ڠ /VOoa6ܑVD9b:s]8Mw ˔XUC(*? fjGlP2͠Z(Ѝ#]B= ᐼz{#x_7<{endstream endobj 264 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1325 >> stream xm]LW߶GeuV/f1uY\bt* 8J b?h ZPW S7up]1ۅٜX4ي3K,'9?<0$&`0V()RI[Ȥ:F<_zp RY4 +b}Ha0k4-F^YV.+۲oݚwZ,~VVJJ~NVn?ONfY=_X%HE|_XU?Ra~_# d%A,V)Ղ:A)*M8J1 `ĒS$C\˜fM: ̱xzY f_&,vzJuu=gy?RgzoKEzn>iW۴ZE!wg< 73-c֬'@Ufm 6j )7ߊ|:+> B'bt`Oa6~٬[@og҆}3ݓ( |BF'ᔮڨz噢h^\+jEE~?rTH[i)4U$z]^u2,u MhKfs7&? Cp=b`c a,T͈79&hk3kʹ˜~f8|->Igc;W!(pTAePDo(rāNIObNWyn8+jCw$=7ve 0QՐv*A)_9|/a-,B-p[HnL dpE5v+TI[Gfgr<vLz͡=:75 ΉO\Ѻh OP*Ϗ1k&oU4ӵNe.8/cXK;>Y*)+.t ‰>QufhB%OW „q1\-4Π_$ ]n@})t]_b*=R6[wk5 D3)cݱJ> f1]hQc\-uI v+XfNё8VjjBYl*\QUuptv-[B+Ɉy11zqv|@c[ylx u*xs NB=)Map7O?yF~87xuۗ)7^BbyIĖ=_]T.1I:]Θ"SS/G.Ez6endstream endobj 265 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 475 >> stream xcd`ab`dd M34uI f!C礟N<<, }_1<59(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5Pg&2000102v1032d?ןZϸ"?~,{߭]45z~Woo-z> 4}r?8uq-u+v[rgc>.ƟɻN>C4췣zon پo>m℉HvOlZ l5,mͱ-{+_aΩ 7{ֶֶ&9ݳ~ 5L0{܂vq}gb ^3i<<&n1qZi}< \[endstream endobj 266 0 obj << /Filter /FlateDecode /Length 2810 >> stream xZKܸr{n> òwgd"%ш 'qf& дrUǞHJZ=0 >Z,]_Q2 eu}^n/~Yחo/^CrxPͅx"LB(/~a/EVB:> U塿cYWfͺp$$uEߋ,~Zo ND\B mյHd&# ECDhId I&)gmg@:F y{+uN-LִY{OE9h_49CH|fXg&T"oA,τ{CGl%Sr"JQ'Ɣ~'e'ց9;Yׯn?Idq"( %Tr PwBBXy1uMew+% A~ ,xge3)*7"–sMK#"-+铔'Y2Ҥ.3 cm 9=wP wPD7ϟ{!>l MIA|/+;6%`^t zt!@ NeE@GI% =`d`5 GK]kc- 78Ce8)ưNЀ±fKu}1lP3&ڏ3E$I o7Q$^iI@Ș(] !@4:6[ gB`eK3?d(\Tɮ2 ސh9^T|s:kz&Xg}W~d<1P*NSw o*|YdFݒ p6TO/`|# # N04A[  lMM W'a1 Yb$%PHM! N\h`~e=<]ϻ@"3TlDvřޏF6`;)^2| 8hi;Rj}| ?rfm%LVaad!J UX65~E]{= #}$ե"؟W)H:mcr]{,!M/S&19Ƈ> a+13ClْzGO1Eii 0V+J ߂Paź<[۴]}P{;Nܶ;Ih.u[ۦhzS Mb"n9k"@<)C+Hw6>q2ž65))j X}xadn⩲Cn oǥ}9_Ldxݨĺ=LqZfT=w '(.cՇcO QDmEѶ ϙDjT4.VxzY# T&qqsLñu3DdU>8Pݡ?xU<.O̚:V)Ϟ=iNJ7mٔ aHb(6ο=#C)`,[o$5a L"I HY'|!qW` Cs\xW-b~ (|j,r׶KE4.'Ø &1\*<|<9~d9fTؔ@#j䒧ž-)l$(LiBTSJ2oKBZbv c>X$49|y955ʦçpa+> stream xͳg9n%umo4o t={y?xg,/!QX5Jꬬec:v9૬ք+:?\ aWj=|8ε=a;tѮu},W_^m˶>-qoݿy~}ZoA޿'tlturU,B V[Eg?*!oHR^J]ڡ`-w~7o~^GE&#HO7n@21t>:t[63L&)ϤoԷ910ڟ΀\TF3: v eti ʽ=NO{StoGOj]vg^9d]=bc?9]3|=6\fPnk[MT HNƤkQn Рuc_Qq?Cv55ʹ: s5YNI_:wcԬzhp-S3֫ǿVmmM52+Zt>c6Nƚ$8vnoTYy`;F: q>]SîiO^նck1ddqvz1ӽ;c {}C=SsHc6NƆT8mA6cTKe]~ Zk PMTO=FCh=TjG tɰ]]mx5WqmBNΊVa^بĻ 4 /5 =Th7ܵ ʩaeixVc7Ik vN!6R/f'pCE3}9v{L'{ܮ9f-s؂jw;q9_Zm\s f|HzX,b|@2t~Wt-t׀jh }t_&@4a3֠vfǘX̹\ãs ya4W &0 mPw7jAǾ_a`Ok95;lCE]sXM*tϣ!Fӕl FsG6nM.\07u:]^5wb6&1=fS)}"m}\}BWN m69PSi|eY-Lms8M%f C33 a7WkcL LOjjMі=knM~f_XM5QAh43K=ibi(u cbSۖ;?<} =a4} knhJ7mq0:u6r"Aa6$ Bp7=4y.GͶ:cܢCyO4ub~k}-3]d6zgTm{̥msX/a3}yn%ޱӍ`-@c&hNC9yL{XH[[mnJ|bi&Šnn08ci;z -س)0fبX1Dm 9+ a3W[0lۀ@ia2Webo2Lj:G3IBc\Q6*yǺw41r޴fz]1=l&M[-ca &ӗ1v3i4׾~0 #}9>|8 a2}tܣ#Lmb=E]&3s77ckb`Lm6jƐ1aP l]8D6]l Nl)F1GMglڱ00hOj0 l#PYd `Y jr6$hrUk; kjhR9mDcYo1rl84kmjV|yWLf~Z+lc1lheԜi5fQh cZfǵb7vB^fƌ-ͼpeΆ1|a3}6=l~XhYc"5c;YֲlEƊ]=OѠëiN1(Ec_%ff_jj“jBŻ}_ ¦(gc ciFC/ :^cu~X$&a5s1 V 3,^h뽅Ԓ a5}8ļ}7|֐Gbܾ%|7ɴ}dJ5oӥHY-<w4rXcJ3; 06fڲ1Q{ Y` {59ve06 {)?оj%<9ȄjdK5<9S/p9˜ii-/wL).a0}97uAfxW_=ZLOO?4J vmlvgcL3KT5Â1tC${K[0\ڂ8ij߼WN7y +\rN\w; ^xrmS =[֍\# Or}\JW{JWm"\nbOHWfϮܝ;rMÿ OCScNO:]zr帀'7 >yr}ܭ O/@O!]('wp' 8,*'wU\*'“@gғ.O&O+tcJ{_~D^P:r+0m J9r5ftʿ%Guk0uL8`N<2KGo:~\2G,ء+ѓAWn&]pJ3Mͤ+I?njZҏjI?n%tZґjIGn%rJ/ȥ^ҏ)?~TLqS1MŤ75S~\i&J1Ǖfʏ+ͤW)?S~\)RLqJ1Ǖfʏ+͔W)?4S~\ܸRMqrJ3Ǖfʏ+ͤ75~\)&bҏI?.Rn\%ݸt^ҏzI?n%RLqS1ƅb҇In&}n҇In&}n‡)TS>\\RMptf҅Inj&]rJ3•jʅ+Ք W)TS.\\pJ1•bʅ+Ŕ W).\\R/Ӈ L.2}TtR1ӉKŔW)'3R3ŕfʋ+L/.T3TMyqťfʋ+͔W)/.5SN\iJ3fWj)R\\&}j҇).US.\\Mptn҅ItMzptߦn҃In'=v҃Inj']vʇ+)S.\i']tz҇In|ROpJ=Õvʇ+W)'SN\ig8qrJ5ӉKՔW)'TSN\RM9qJ5Õjʉ+ݔW)'tNM9qtn҉I'nꦜMpJ7Mդ7U>TMptj҅ դ6UTMoS5Mդ6uM8pS5Mդ7US\&\LypJ3Mͤ75.TLpS1•bʅKL.3]tR3ӇKL7.53ݸtR9ӍKn\fqƥnʍKL7.T3TR5ӋKՔ^\jfB3ŕfҋ+ŔW)/3PtR1ӉK9';pFsq:N?qrQ~m a?+G @boe\\,r-J sܮV"9Fy O לPPy_2RQ YgCpt2۞+dx|) du{N( Ӡ0 Aɮ0bN&qtdH#({ŶF+9Nʣ +V2:f9 ܘmEB=0֟f4OwFy0yzʭ|bPwtZU|}䣌GfuX8Jkghk=!S onF<80ڳ _|⛲1- X7#28͕?_֓BQຂuʃ\\r1dHayV׮wX8, - #<'!و^c݅KȰE/#H(Vc#7BOAAQmђB$udQ .A.Ia!\/J:(zPD0 1$0>nܴYCGS"Ed\S KmUC=t;+NHdE+]ա Yg3\(T@Y|CT E9bTBu#됺 bKRpƳUC9B+0C鑜W([,PBCI 0CR\\,b='} %΃%|D8𹑀8BnAoA= m>22/^ox_>PD B^<{_ .YHemuM>A=ӇFmF]~ѥxT6-!lTibbf! I{;w_a?E{L(VϱL;\r1 dO$jQF )|rPqSW[y?rm\ok+ڂkzת_sOEA8<*XC\ۓcQI"414(B@2+ MX#iƤ2qFbX][rEA0Icuh, boPp[!kHS,E]*F&UUwMj" upB3A.oFCٛ׺_nP5^W$$>`9A~2NmJ E/xcnWH ,k'؈6*C[qA G\UH+yAN-ZׂЖ{m#A?; g恦TF8X7ԅGy,aKTz4eR r!`f! qe$&[oۣpGia븻RPuBbLƪCӵt-.1]rpb>Q挖ƥNiʔ:H [ ()MGJuhF 0Dozy!w.s!LHE>F!/ YӤ-}혂cJM9iw+~;YqI;!1dաI[\C|,>%$m\3ݟq 0zMG *pMT1%)rPY aw>DMК}9lkeS0"eU=&{|2HM/߀P"uuߠT [ i'Xw!/.!Aa~ak`1DzGx3wqЏ#ޒTfF'v n# *%8h1;:qqI *aGm@wÎ\\,[7iC,/T&nIh֑lrA rI /Όw{.D!y#Hq &$UX D DI5(I,CL,$[׸P\+-AN5&\xY[ۢFZi%$IuJK\C|,W-GYpj JŰa!k RZC/h5B.L$3#3̔LvדP]WEw!-膟ThhIq>RDYY6\@K؁vA 蒖ďG&NXPPYYP%miI0(rP{̙Z' \N\G ㈔QPt,Ubd&) ~VsĊMƚzdGKÓ *‰uPKA,8XV$f) ځz&FW*8O 2O}@zPб YgVzi2Ӆ9]-n>ׅ`r|rm`f"\!6 2  OKxˁa)_Wž|Z (c:ߠ0᮸]&| 72k]a#_ȪU{ |b&d{邾N|Y?>dP_"!K=R9:P-J}rEA0H5P$ Ӡ0 A"XA~d} ~V0%rI!˴ ֑\C\‚r@;pPHO[ $c3@K8% (.$>p!ܸm# [Dߌ֊PN#փ!D,š V:剤7,;sꖊa˸RP fEӰD-.A.Ia­TDXk`= o[9H^Sẽj Ӡ0 ɶȨOsO̵:54 |AŴ &à|rq|= @">-GB,S1 : TñGʿ,! )p2AjaZ~KZb׶uPP :IRZh bKPp+^Ҥ&%oLMZz1_7pFej II0iMkbbf!(ٍr *) :m"_XVAB"t@Z*x  A`mQ)2?0 fbK#Y߲[G?%ҹQQ=1mD-$M]-yNGuv/#Ee%$DdC'if9 ?}հNAy푈ϨM>ēq8)0Teu&$2Iaz]"17(rPOkyul=R 쵞#_{gA~ 9>%(f=$:"EB4"_#oX<#_prEA0H#uX$ߠ0ȢEHBMŘUNebQ1.ZU(h' !RpE_L>! |*mlxu XN/L6)Ф4f9 5OfW |Wۋ;ɅmVG1e""s2 Hds ֋ j_ *q|2md N *kH׋"" $Y xٙ1úK싗4;[=nߪ9!crǜ{I=ggVO q<$#eGbkaViQ}m(FRr_2I 8: F^yae 0ǫ1>DaeZ1W&DacCef9(HWݶ+dv؇xr< ~al/ */dx=)x>o+uD=}T 0I˧߼$!#|4 ^m ~awě ʒꎸbG,YHE⼂\!*}{ r-a ^) "aQ r 0IZ$Z1!-RSZ{ c""`ϱTZ/aERdȚ !<9I@j? LABb/ 9#R@}Ǜt~{9̷3 ˰~FZ>gY^W rbiPdG|8egZAXz3 půȧX_ro/T:_&6B03y^ &6o+N,kbKHLK"iK5hb 4&Y̛Ռ$$o {2#` B%j} *4# 0ͮ#Guik-EeC. QCu!".!AamK}B"l[Ȩ>a/R1{BbV9bZT^ȁͼ"PxuHA0ZkG+zF$!O:rD bKI;^Apݐv1w)V qAd@12=X,#]t l#N !|:>v(}ˆ~QPY]F!z^]F.A.YG$3>{U3ie&$KEQSU?|b5z>Gd34>#'?'9γb\/ ,+x"! P  0 ȗ/BȸO#'vE~b*z Q #E#|q&9(sF#զ zqAݷ#XMGuF.!Aa];ׅ ~6OqC0,q~~  ׸\u_8 XY#m>rAHe@`}s 3Җ%rA&Hq"#ȃRPńp:9Y7xV*j)=+T88YHuY h+/+V[Ű9 UʘkQR*|\p>#f9pzIHlFF_1>kemY>@N$ N%k^&Y YHF@ϽvJn3KV-rEAeu!6R`6r! pY:A1W'$h#Ov?!4W˜ݹ'of:e_kR9gi17(r@9&{^sf%7_PPY&+#\\,y<^50{0ۺD>1Qq#(d{ O:(..IEsH]Y ٟ+A 4HHh#,E-6bX m| nkWU չR`A2‚EaêC"17(rPȖWH`> fEX}alx(`DGRp#1%)r@5S}YO[KS-EN(,D '֑G..Eam:/Hk[y̲p}]> >CQs0OzLZD %7ny۴\ Y_Ae-"K@QQuh).!AaYZ'1nsrkVO շBAe&$NiBf'v"?Y Ύy hcڙ }o%wc[ݘ~ژ%$UmоL<A\,D#U> 4G˴GL57+ O 4#? YwD AKlsX1.Dff#@0@wq_@3rs+o[&4TT|Z*2҂`#, (mŅ0%)rPp+$,ǖOy6A#_Xz.9 dA`Qf! m6"^?'@'Q9 0@#:Ҍ boPpGpfYR_]br+D PZuHRf9(\2gmA0Z+uN6r4k7[ßrnyb)sNH̹9uM.!.1kr@8IMH]9yR]Fj?~)tXPIl\aH꣉m<\ox4H'FEOH'f:\\,1cN&§gzFk[d c;5LKI )4BRf9 Ii[.oDӶHFk,kӖrdC6qA n$<,LHX{,#_Ti 8 bKRp#>80AyUz-WŃ6bGgY\Bbz"^AY 93%!bk#>]!2VuF<Q` ;B|PIAɅ07(rPHOϏ pݴ!{xv<WOWDZ,OBo#y~14(B@2Ӆ dw9lr,~g&B,KP0 ۨu#2"@;3B޾cZ_\73۲u0XLHBo !=9_RE|* bjC yr)պA5I" !TQ"CIꞶ I[ͥ?|Nݳ *i2$$ T1qA q nE޼` so, \[Eb??GQ|bίy-Y?0Twh,!ߚ.lsPLmJO0 AC,CL,$BB.d}Kd7˻^ԗɭWpBb%+ X17(r@8\pex+HͣF|!TaBg):B..Ea| sB8#[=ߏ2ү/QHQG" HDBXSř F29̎&{R?˶N`ȁH.!9xL>\$$,tuJ0^1lvU *s),RX\\,;#]? Z9W/_`5#Ec|AHQo(ߠ0A"i>inq2NvXyG^(i(Lu"`a沣R{2AAU*D!@K ֐@2' )25!*{}LHOHy&DeCif9(܍RV8Ә%ܧk t6@SYV2!aD6u$߰ΧYX+?|Mv,/Mڪt-!)MRk䂺&k!V)*^nNGӼDJǕݱ`{-awe 爢J 0K/uD+`)=LHHJxT]-GZ"_Tf HR%[ bKRpIuN3sX󧕏iG}a}bDei I0cif9 ٘*!,FszEb>ʃH?`sF+YEWנ0IZSl=_VO!;"Iem@;HQUh*@A`E¼p UHUJ?Y2@ 9\U(}\LL$$#[>; 4{NAg 8#_XN/>)}qA |5)QuE/ ,K5U bkPdp YZ7ǵ>ic 6{L&TC?== Eˋ>]]l!wr%dw}30 '%:Xy>9l[rMw IAenARTڂ bKRpwѓpfKKWl[b*(,C4@7HGYgydhC؎HnU>g,HUfD56*" 'n\ T*եz.gys{\eiZBBODzR5MLCf!BsYsd޾c^EZ ib1+)HAe& 2Q@ƙPNR{)CcB01lKs *Ɔ~RPY(QSf9 ܊y[e\̂)(Te{cQYuhw-.!AaY KK`B"=O {qY0s=)d :J0 H rI L$KOw#ԟVW+2L5ԄD\ TU(2UL\RP+҂p-sO+eA5F^? $!{XV BhAqXYZd --'_U&=֑/k-SJ&@( L C ,=%CSxBIrFX# :R8r! r֙p| I}+5 E[Ma-cX,CQCP]c _?y4V< E7U719x.[nc"+#R‰uʊ\\,kBuro**|\H,r LV \{Jd.AG: ]Rq!]AA:JwvrSu%HQBuY6m\.[.DT:)N#N ֑F.Ա;"_FA`٬rK6[#EAeFA`Hum$0ApxP]gϟUs͟j|Pe&$DCf9 1J0^rn^q>}a5( "9֑\L$3}ȄDbu]Sշ`/7yxCIAeFFR`#Hr! p) ζ p*K)\#mvf,}by,R"; XJp XAa]qS8B:sL_ ytB)!d:('5_e-$Q2Juh%.!AaYd Eod kճRnݵ͐2Aآ( Qu(Q\\, 6.r 6S}~z^͏"5>5'ٴOlC"L%ÚtSy#nL"G_fsU/^P9H*R1$)LR@2k-QApO]M鷂 )Fey(YwEv|p ]_Av%y0J6r99h"6֐Ñ,L,%} ݹG=Rs/۽9s{H#5yBhm'em*ߓßj> e+M #< YwGj| g-*\ߧp )\ǣ"!(H8ԑ‘ ao6$cnT\*MG-Ne~ո3*)2RQ"SUT1:(Rd2 8!I$ӨʽZ{}!l/* -AF_,,$2_ [G=Z"C?1"_T!6h"XGr!`R&!(2fA%־jvUjۆGa^Ƭr 3R陸 Yg-qhѷ:!cZu`uj c $IA'8 &_^2zzpA q ڬOS k*/+mKԭ|,,kNH̳"yhD 0@ѴzxU6q\xrX(F)p Ȓ̈́D7p|O+O-XkbʌLաMqA rI @|FB4v"_D?~Y(F pdbf! ٹTsЛv6XuVw\+2IEӏ Hc|/dW>W['i}?,g Σ"xHѮB f-v&vV$^I6^k.ɾ*+v3!y) Tߠ0laO׆Bzd' N%ܽJVCGX#:R8r!7gu<-A)ԽM}Uzj_#jJCF *QРCeX aד)e Vjq}'Lb/5RAa[¸g i?XDbVmKH '+6ݟW.>z!^{/X`)1B 2 Y wGLo-G=y^ʛoVGŰ fH *VڄĽI!:xmrA rI n=cj+!aF+#}DCyn!F~Q`i˭f9 ܖ,Fh[Y5}s7#63VaotHi+$F#|*Wf F0"VPTWxd1U2qq|= ZD@0V֪cB}:ܽCqD(ӺYdBe<L.!.Aa!_!C1Ď/c<}a/ ,0C8XGDrA c _Uާ;#Q_g$8AnAoA1{HAѮkҴPOε*ֵzA]P,&H "T4po|HxԬ\SwFđY,\2L_Y oZo*;. XYȵ-1=j6$&#oٻf@{5m|2XlDsl&&AAaEZN d&!(Gǽ}ώck[)C ApJ$ 8DR:f0ZW>WLr/oӫ:[%l# ۈ:6 !Ghb ~k_8&qDn>?zDns$ @|NxvLnۙyJteYd[I|+R1#bIAe jlPPg["3]pZcԢ1!-W~r{# 92 %(`I:h0ε5\!*>\j\ lLjvKTQ8E^FA/crA rI ."&o--^ke^.(QytEFF dlvP{&ALL㎼}QPi i!YG bKRm~fe]W>?ĭ7l#I"߿+7FCE*D)_~i_Ͽ~ؗߪ9=~{~zv?}+A8l|Wo߽y?_ ,o+wyC_Go_?po? Wy/?<}7xi, Ac?nZw|Y?~[~xk0iuz633d~óωw٭ز=>mgǯ޾Q,љwq47~3|YΟB}?2'nc{7^rߣk `rЏs5m|>`Z7`tO/ߣ=~?VlwSMu~?z{#Zf] ?|j1lh~w ?|݇F-n_)V/l`cV?R3F3"M˟oQ oQ?KAv1acF̈́rM +c5»׮V}q ?|SM߬WIlgǰۘx~x2csr7Տb_0_՟fM6˞kcO'ڻkt5e\E}=)~KgE;܍ON,[w/xWX}J koQ\Vj=PT6`8iG_{o]l%%ZlݽVgPݺCKԞ؆$~ݗ'`lGqdY4O^y&.f=Ї  %?/5K6i.j>Qmm#9LxtMV5f^Sox|zzrƟ5ر??`rr%߿y6:~oIc=m22S DkY c!ϿHDːyټ骝~"ciy7֣f<--eri):/[kh59x0.e|76N oe.?|F:,F_VUua~ʀ풖[207Oz >ϵ[ϼSW=""r]}us hk]_D[{S^mI?Q5Sn{Wۖ6u6u:7fd^Gw{1LvambB|8_ X( FZ#>Te3:3TWݏow~9nzH_6׿<yJG>R}s V#F*9v#'%;LKeٻXS /?L֒1R dO-/쓾Y}J?t?^rǯ~ o4GoζG/0Gۢ}ڵ`&J㼏s!ٶXz[j ǮnV<_޵ѡwS-qpݴT pmom鎸2;~3tXW~/=ۢ;!>_y?&T/?lIr|55/} /X?bW7>[ o3cXۋ֯_RuؓC/;ye#lg?k_ƞm~~Z xĎu8fx-WV'gk1+f>܁s~ڷ`M ĨǤoxKM-O(&' ϧ0+G6Sg8fGM'Fv/=,Nי0>_?M]6>.ōޓk{_c?]=F<5mj<ݽCObwܵ936ۏles>;sI-`}c ƪl:Q+i[8 |O燏{[w_~߿W9㳗10l7?~O1tH݇?7:(\|x}W_<7/^ݯ~_ޯ_ۘ_? ozMMˇa&N—kKe.yWgbTsan_?j{<_.wo޵T 5:=?/J k _~o~0ع|1Q柟-Yw?۷o}- ׿2Z[[%hLEϾ/1}wo~)%Zh6i|~J:mi,?u+B1Y6/5} #:q߾ǯrv 8WzS=u_<~]RD$s͋s\W8hYÿ?gboyWz޾_4vIZ}ıO2c> stream x[fGn%cj:/qch0 [~#ey_?ArňOrp 2qksG~~xt: x>ǿ?s}v}\wx?su|ÏN:8?Ͽ3Z}}}^9>Z_B~ +|mϿ,gR4G}?w7?|?/?|?Zs~?ִi珵?Sޟ64~S8-mݢoaLlqno|㟿w]]g-߯b?~7`ߞyy2F?֞غK7wuhF/Qib6e?o~&Ğyi_pOSum3.>m?_֏t7֫zӗ~_qbdqKO_YOĨuY~ MS}WnåK,CՕEb?}UK]bw7ٺ5>g 1ow͖k3Zۏ~>xٴ޷>9Co{˧*9rV_R,RLWj9T̙UU|V)rVlEkyַVgxF^q~3lfu\N)aԽV6nmg,)ze N;M]+Rw{8T9uRlRmPs^٤U UjSC/+sz9Dq?osT#~kۈ#~<;۹uBKDhg[{ޯ{կ? a'59FyD8OsUy?7c| mV6-:U|~^SjvT>MUWf_Ma- k<'y̦9=3*~W;i]՗3TNOfPNḼd}g_ӊ3N[;sV|Xf ͊FyʋJj(yjvkXfׅ|y-8 ̈;lF} G)q5&0unmPʛ8X .$J%A)̷g]q?[]|G'jf{L;Pu9U(5;u(ou3^뚝&<`4[)R>2]ڣCϾAS}Y ͮy)4f>w,t gϠ~^¼3̎aON  GK1QcώR3cVTs/uy =+uuzRWCӆ F{/>gt0z_P/dqjfX?,)W((^Bgs͡bzm'ksEg8ݳj3f V=SP=":e\h:Үnؓsf\i[-g4/d5 =Vp{r(5/nŗ/}22&'1;j;TrRORy,#:KnpJ,w_XYTlvN9}9ϟ(T"'ei "'̎2xo8j,li,g1ֵ籎M3G xhəq{ىT8WX&v2"f/d8r3m` /tˀ [fӣЍMrFU895 ͳc|;=(Ue55Ŋ̙N#iGE=Ef'8νF]\saϺ]qȉ3ԯeɊ}.G}>*׺}P#5.fQױxώ7OVN5my=9fjƈ}|UAj{!bDB6;^Opʩn&zf|nNRںVupϙ U9b-J%T,<5NU*Z1jTW }67TU1k*!hQT(&:Ų>h˼v~?"5ZC GE{pm9tŹN/糪(yٶn Ly*[Q^Rz&|l.Kssbo_Fl^ e𤏫Ć8؏36" =w u Pr~\߿*_ߟ=|c?%8϶vF-f/E0 "ρ=LFKdo'}vU7n?u.^}v K3E[+8]b0KPyGu5fV 9ץNpwnpbtq 7xb؏zFr̺BUE6xO H[#p-6ׄkBk,Rz%^k[t6qSB'Z+^{]xq,% `dG4ZCx-'-൶)"+Vh@g<.-ֹ%Α-ْ֑T &9k)A,V@Ȗ(PBymJ [NV ] ["N_l&%dK\hlcNV"l-C ![ J%R-lo d{CȖ1![IAlsH ըdQ)VR0[LB90 $dcmMB9<$f@Wd;fpK̖)V"lf+ŵ$69ْ3^jf+c̖fK0ۨ- Qa f+m l%#Vz& ̖k\1rp \a {8Mmsh $n)V#SF&q[Lm50j\ ͍>q[K`"6QP n{ }T*6p ,[MN"м $rKZjAnyAnÞ#,-?EBni[nxj,V0[L_Cn 9 [r(r˧Dn%"Vjrl&r˱IqTȭPb"n5:jt I6'nsx $tmOB9@= L^B r,,+薱B$݊s;YJt{%g]DVJU m t YЭ~Tn `[[@n%zЭdcW/-GdB rD Ո$v)VmH`9x$vmGb9j8H6G#ns@I6[5[o )V%۔xRjނ׺ʞi-9?x+Pɍo9rx&x2C[AJFL3[ί rx LSƧ[Oo5@r 6(DosI6'lv9<j8U eD&~"CdpJ[qo*~ s~KNh%lxWZm~+j/ѯJzxIH#4[ɴC[o9Br:~km|)`8DXc̵iin <ʙpjL"+ Y*0i,UUIFjؼ\=[ZۮxNso^GśYQ)SKl3l7ؖ:F'аAwQcMlpbHC@"Bj ux ri&51:FGаf5c8\s&J~;C|Ĵr+d5\A_~F"U{.D{V-h8=a/]VPVR3 wʱ`o^>7^J3<9lUvC'o˫bL Qv/ȵ9MDz-N{,h8 ? -?>XYɥ=XQGYơn>|Tȹ}8ÿXGPFZ}ܱ'diѮ sb*S1P@:൏pn}ԟNAG 9L''%itp  l؀Xtp 6~ >:c{WcDav|anӧ] pG4wQKdFSSJin(w:K.ͥ6P@FG8+/q0Q?H@½Z$v<̈́O<Ӑ􉭟81Rf/U8;LT zVЯKr<R$x< =@>?Bc'r<ۖin(z v,/xpe5u$_94y9Xluk n#V;}b ɧ|4jҏߊy⭉e;C~]:/-r!ew)N:Gn5͈m!= &ʳ xVn-by_i2wެ g.*g}]Ԑ)-gYn9=ˏ,+[̱n5,'TN :/x2AϾAl'"/Ql@.[Fjؼk5a$- @lՓh"9 f!&P&+hV0qk_Ӯ%,\T"P\/qDdam\X?%dVЋ0q9Qy0{tV1a䰹@Ή4A0Q]9Ak(Cӎ-mhS(:={P3 @ɱҪX|vw?:-~7IM`I(ϙ/|Zj?Cgko]ѷ|FU$@GAhjgZZmPC|(*DsT{ƩNkв[7"}{.\>h-ȑo PG:G+$q*C 8XdZ h?6Ş^/u)AX|7>=z |'c&Џ 1Ȓs(9UXm VЇzxOC^ ZvK7ԨА4'֑ϴBϻtnk<OSu&ua1?D)xR z |ts"OZs]yot\$.XX2 {[_\_^Y-r/kNx=ϱGhE8Fj`E#X:n v =&N.#u gvR]4.MO>K 65`$N߳eu+CdBl$~ȁvldS#vR>^'G^-={^ɉݑ0'G7۫~w=ՄE H_ l'Vݕlm f06XX L-E+A8Qud<ˆxܽk]TXxbί@K[Oy.u@9[[=V JJhszh)e6[:{t,F; 8XC6 k!w'YC_39(_}vg^2$:-ʋgrQ `z P kq0)乮~>O(a h`Ƭ#kZ!c_w?ݽhX U $ Dsk#*7틑аyAϞK{pCq{nh`)3ɢ􉕚h ?~~)@ŋp,fn gNosSJ\gR.: /AN S iTG톆:cr`ԏIt#vST @tL5Q>88a~(N^?J { RW<ϱ(M19JP)V!Q6P@6B\3Ls{'|n>>E.1%8|hL#$`5t%&'ƘeeM͗0UJDj؝g''ۜEGT^贱eZؑ #:uز$XEml\z}) ׏  m{y[su>86T4X5/T@#"'[k|Y[h#}{.aiB(6?lx=yF|< v;9xG { _QDT?xYG^~{KsNEF=ǵΉQ91iv8hn)P=s",Hd/.Я:'-^!>'>G[Dfۜ(ՠ ұωᙵ1z,9/]cn]UEa<]^8@:9>RsV=]qEs/vRݻjPR:ϗ19,9uF|sq_䨿mFT c4A6#8AkC:]WQt:@DyZM_}D(Dl.ώHC9oqum~rhMpN!'X@H *~1r\B:C쾖gImY\9!TrIDj؝g#Ie]%'rSϬxޯ* ͤD J5(J6PB6B\/A&N9H 8ihzh/$7h 9X \iݚ^vhr⢵ň X\h$`4lNгiL :2tY89l٫, Dk1҄oG&AF^ v/ڰ/N#~*SJ>ʸ[rهKG>{mOfe4@]Nk[3 3qι,ױh=cS"N ^\h$n͌aיQmt.S_^f^יq:͌53É 9QΌ44 vWq8w ` f\!YZ0z F s4bGPټ/A  DM`rEX^q[W/xM%'NB&Gs$󾢊&43Lg:ogR×5(Z6H6J]s=pL|F}%nt T7)Ux r"xl$v ]iP{AJ2p 8fěo.R )niGr%:Bnn%d74~9C/-nqĸc.#9'Yi v#`LӠ`_(w-nv$C{O珅cc3N/ng )֢tT%&SCe*!8ծ wmO\8EB 57(mq)$N45 Ǐ1H nu85:,zd ȱ5oc FF5ni\~ObfS4PП*@IFiؽkcW&>5i[7^hSi8sg εV&ih l.ЯjVp|wLW.p&np%\ L;m fpfrZjU}(nysKzgdh#^е`X~pDi`}A@%S=dIY:b*а ޏ:߷mWTݟRF  2AmyAzq[X˅Údc}r̐C3zg dh\_\X9wp^&ZMRn!AԧW_F`h<[U}Jȡ[f75@|R AF~CƊw/ `ߋ ka(N6% 90-ȑ_cC֐ {.Я^9km:fo.97kL,-0d}K/Эаs C.} C׳ӷ0ȯzn~o+}u.c=:sI8Is=Ļ̬o;I D_w'Y Dq͗@{cڗ߇]IAKzD5,}HNE,ZVXٹOb1i9F;/d$-_\_%`k,gY2lXV,XDjP,JDEse,Z{84zV˫b%v>nE/.Z#ƚ85g4AboNгYQ,yƭ"lkN;pLKo\wYHj=ge]b}-EWZĸb`"h?_f?}jCZ-vEeʖAʪP @ "pΰ 8 Zа{>@7oy#^o A0ZSA,E!W? Sv(X}_5.x-z qebq<L,"-ŒEFa%*p( 4ew~,.x(FҔ58-Oq2gV;JjhؽkXn5kI#זzibGz7)R5ͦL9J.Я*8)ސc_U~cu_tJ<dYtT%M qW8e1-C,=mGriQ$ ^&!a[M or0i WՑxiEJ0^| Ϟ~`ąni;6ܤ!i 'yWV7?݋,ƌX8I#lR{f>FCKqQ7RpƦYUUgқtno?]xWw?vST}F0OEyP`#tc#@]2 iNRg%_mqxeC0htE`N޼T ` ǯ ׋f AIF*ؼkR)]F~u h73PiIXP_>\\~hj,{ןaЭaSf /9o^ K/G*SXK s\ h@   c4 8C(&m{[&o3q-(kn$h#^еf Nn=bWIn%%1z(Mrs|z&1?:Sqř Sq}J jBrYW,5tcu.v?\)%3'֣cbI粣@cbuBK+'m ֛4Nђh4!-qb*hNY|w5ڮJKF^3.kLj{wz,P|>BBZ63:phJXь)1.E[ӉIHjXgՖX9Nޖ 4DfrrX xM@ tQkRb储Ik07 ~{,E5Kr=4=JTw,?>=[Rni3 >us}sKGҚ[-)[/ՠb2A0v'@/2m 9wvę6`/j ʹq_:6 +(A+a=R&۽.wOrXŁXo[WIAK{$sX~qK/ӧ >5O9z4H3,+xҗLoUޫHDhxq"<؅YrhzewNmn@ q9QM[kg2A04lNг*X.rv-']3lC/+˭8x*H( 7RƱn>}zԅRgwqenwA&qZ]hN`KաCVPVR3rEqKm y B{(V(@kP ({(Nг \BgD]m (h"9%*`] 4N<~%/k>Cju{ٷ}jq[3-ȡYT xSx:Vp@5qѯ(d{{1׀˱2( Hcȱ"űGQDy9 />V;zor h-pa^ *0N7SE9is1e3N xE:fQf c"~@ʁѢPLfBbI4ͅ|_$5i9Q}N_O6V\`t?:0X8ͅu;?t5Р֐&P&R={ЋaM^(~ˎ+Qt8lp*`첪݉=nTMNv/ĵX2:u'lb}_QvlhBl\-eIWȭ'NX|{çnIleEn]saͅ-ȡYT ǺBmEj4/remc{Zg[\lO{^-+5pK:rK+(A+a2%'#ߺ_]ߜ89NY<1JwN=oC ΅Ч΅x ǽͅ^j EWu fűͅ4P~_ #W&Ζʬu;7 P==C9A4V& T6YA Y pΠ48;|Lj )=͌9PҙU$nM0tk#1yo=,3snfS4@QP8b #83;`h#^5'7P*9(Oy_g/[Yk9uXœ8D 8XC3 ȁ;A(={qZ~b9c&ŤӭMq[u/>rIq7?|*GSrmb9mVLZn#mVT L&H&J=BɉoqSC9ns(v`_%ڻฺҜ<_0;v?ܣ+pt/3v嬚|[^@EiLON+YRzU3|NYY/lY&OвR닥UE.zъ^1"3^ 9*m*(/a󂞍C'' };ޢ[A-+\ )DIi׋yi zUzـi"N3&PbNZ;9{0i)=qQ xJ2X^Q.D z֣Wr :#x$#ب@4'nM ñ7U$8h#^5(zsF_rbn`D<ؤta%RC\kuv+$AaՈn7VZ)I DvYܾU vx8$d"4,[1ĹyI; mm} ̚-̢S9!,nyR%;)`N?FH;bl&v: H4 H{ ^ ?>\~}V4x, 6(㖗iiѕ{1q?PT7l4w'Ynl42o~br DH/7UJJMYSb?@]_w?W}?[w`nV$- s*ͣc'ʓih"o>б =2\13,vqF}2 .nfGSd 2/@  u~x.ʉ}}3_2*- d:%܀E\]gA JJhs͊*0x~uðim>gl(a_E 19xҢ{x:FOU6B]K+g_0[PC^W + U^}SB&B<ǝᏕZ ÈIYq=X#83lK& Xinw59d<.\f-JݮiIt5*HoRFUVN\O5דy89+%. H0g1"}^ő tLM z?VNI`Ę?+^}@Qi>%'A v/Z_3(98dMI7y[ 1硴hqYEAiG@0 vW3f Ar" ^eӌ*ou>I2 @*WevZyígɜvΒ"G=kރ_4@0P 6WUү0d/Pύ0*SKScMqHǚ*}vL\|q=Ko]k[k'y68./~{[qUZVu轭8genX>Vƿ]ԒyGZk- G/-Z9(Ϲs( GW@z_C }='y/-kq$_RA8e%h"5NziVg+'^mնsMF졸hu9lq*`ol;M\:}qX=[,%[]c=Ec}EԿHWX25Z,f>Ty`H5*༇ rb8qw~Z5nBOsY柺6t).*ݬa}ӳ/һP=A,$P%ݎ\CQBF0XC"Mı=+8yF=kE$b1E:VngG[`\_CE LH55Gt -G5|O(Aaw ?m.ej:zUFH<7DL>5>uO5OPAN cDR2r3/{v HhI}3&=8Iw#Bgs =9DXohǹώ(؎> LҜDApIՐM,B5XnKN6:w)͛6tK5rkЀ>a4 ظt]+/urbcƤǾV^vV,(-_`HjPT@^ ;Y ,+GNr 7C؎87\ܟp13vUP Srb=T_6H6B]cov"}èt㤇5좀t:Fk+ug0BD Yּ\C .V}hv ;lQ@YbDJ#^()_&H&B=k501sFvDpKRK۹A8&a:r JJhsͶZ1|3hL/#$r"ԢH&'rc[AUZ }WT j\vpDD)QߟEI#:ޥ4 Y@ Y tAjCL Y3hCYuA+(!+uyY'(wn6`sTiwYZО'94 b Z @Xl?ĩj0VH8%/  nX&V+@ H ~,9`-'#-K= = f(|_\c`mvNk@uDkv.a ̢$/#Pq\ tLĩ "q}t;xqۻҢ]˓sYH8-ػs"h FHFB]ڱ=<_揸5+Ao@ګdN*h~6wV4ٍpLX9_b g 5AXSG$UdRדe AIF)ؼk{ҾӬŹÈf7?XRil.u 46*}qIN4#i|P:xu2gz6$5&ǿ'&XT[h4ht&ӏ^N .\Iti"oNг=iyg'<)ZkF X_HG^+4 n$h74~йa+;X8GĬ8&7D#~51?/ @G^g(5c* v/b= UX8vo/&4hg!q.HG^z|C:FODM tc?VO7<~-A.,>WJUD qN֡;|d%d%4~&!}$ Րjg~T$*䴈0(OQjM+%@`5J\rpoo8}<>w`Ҡ%]"4.ϓsABeAcDߝghTbql-WGp#`$$[uj Tx&RJ%PyAJ,HN7A,vB#CFQhWRha:@6P@6B]{+''ka^M[OD4.򍜀{p`,+(!+a>VN<3X#/+Ozw+[%)J4Rd$`%5~йd2Er"¿^ζZgc-M8@@24 vA;[Lk`^^=^m6"{~^\4_ÑCxǩT&H&R=k04=#oX~OyVU%sKNN޾쎣8{JUY,%W(.4B5> C{[zQyy, ( WQ_T PXX 0\_CH- C8%; m-߻[zgtK}zPkyuPS`|u=cY\Ru+ h /r8PË5d$.ao.Я2&~=_t8MWߧCXߦC)ݬa &ȳ͇/N3+@hW[ }@Ki D0F,0 D/sUĉGqs.@CAhbI JF*ؽknkв Hq'2{F9~ Z#Ɩ:9Z! X) t 9rٟguYA7uOF7Z0hWsUYuf!~׈{DkӷgIj#rn1dSkL$Ǥh9GM97^cVHcruu'Hqbn&~K!֊{gEs/R-j&_&P&R<3rIqe_c{LkI6rNamBtƤ8tn1טleְ98r1:Rε_I-Aծ-&[}ɹ|19W-&E+&aDQ#5dLkI( ǯĤ[8-nfj97Iq@:;ZHfa%d74~йGHNejޤ7\}V$֞t[N@ j g6O鴷hx+ 3|ɴ??فo|?~:ӧoJWKI|Rn&UU c?BRRσ/$E"U4UJѬ*E*;o>?Ͽ洷sIm}q]<>߾8sYhը˩ThčiT+Q7̀/ۯ$ӎOEʞM&eljKIIQV)pV)ZR]j vŦϞ?|qفЖ8{||Oxr^3",O?m^[f}} <19257f{vS"oڶ~~??ƃ4(Zfi3;r.(5l~_Eޛc³z2}>omt+;ȸA;l`;v3ة*8Ƕԓ12gjc WG=,1\WbxG16[p5^נƱw6H;]|NQaQeƩQteBx/tNRqdq#Yu'l`>vM{)3*#O;Zع&_Ne) "mB2QKn#۪8Sc`S{j+v4)6ءQQezTd9i=<*aiFӣhm? ~3l_ n+Wb׸9O҂sM8솲`ĵ%2տrm'0pv2 N`j1'X 쬭洸qdk%Wa{`|)6څ1fshʞah;G0C ?s!̱Oq y+T=9qqN1ϠKYBvbL6 5? :{玫` y6FG,) JB'8'.(1hj\dv{cCCgpn{>WRu3s:1%<(U0Mر%u= ˦ɱti/U}s2RZiat'ڬ1xM%9n+5~*]{rkb:X<Su/9~Ҟe"^hAC\b)_ ;Oco1.E)qe/0ٛ:ᴽ4~T/dIѾi=d^qX!2j^aG:>R([UZR}ڰ< 0Qb2c9:tD]5$Bߡ;F~bI=3qtjNSlڂ /9Kٵ#<}9"$lh14c~s)~309ojnӟ{r }+ Ή|s랹|~wΆvفT'Ogz⢇zS#63c;FT{P`z,}%q"݇V"?9]_f<"[4}Ϯ?z#''rZ;0"V _B?rNwGRw}Jp>h.QU1{L'ij(G9Gu"DL앭3}+0g1[l~Fy=v49{~&Gl(Q[~ۚ(ĖoU3ya>F'#vs;;rmA )P󫽜;~ml;v,pFU;\w?(5#=Q{n"wl<;Kq+ZB\,=ԱB^68['/iVVcoϦWXcoK2 FE'vToh0)C.~-׃ lo2{DJ4pL~v XG?Gܿ[<1ܾ~zK){\"خF%62C^:($؊ ;B+ŎBN~d'!;ɛҞ a*'> ,T>w@)~jJEKqkذVqZ6Ć5"~BI6<']Sx·L; hovm/5P&psq̵͗Lp^Ds ͵U`nC,`ݣ=A0(Dڕ%'k16(FUs[ 0bM0מR,r+A*, k\.rhAc!4< -qX¹!/8xJ8΂s Bs j-(6܊9.\!_s[E%\{ĭ@op)\<!<qP_aغ0\{kWp Wp0'}Y0\{xnJ,O6<;kH9npkµ-$ \C V߰!\ 6F" 6q0ؗq5$z{?'pp<Jap5"S@\`b)WP\-BqK`cpT&Q) $1\BjX bX հ$kò.( b)x#%ܫK'`!9~%8%IYi dⴖ㴱Ypڣ%N{u@/PkH<\=I, ԞxOBjxR{ \H-=^Z"%+R+R{'x!R{쉷zZA+R{H-@W R{H\Hm@{_Ej P{^ZR3mtjxЊβJ;&JDDi-ABrd&JˑI6GPZ MBi54jlLI6&`ish $L)V#S0F`Z LBi50Lrj.@mqr`@ So'ZͯcDf"[tj_`HM6W V{`+V_b_jch.X :6Zjj_`10U3ZK9.j\հdaI6% lsXaI6%!ls\ d-fBkGc` [/gxfe9;޼9\|&`4.n89F0Eⰹ7׵p}Fq`: v氊[f:Z"BaAw 9{0F:+{0 `"N ⳚIp `HBH kն>4fwP< 㣚"DYr66@2Aׂ-Q =6 0pj[B{j[[r (g2P4N{\Q0;"w$޺`'т=%OwW\a80jY]RUͤ8Ȁp4Oo$"giA ?Kd^w gp&Dj6b%?;Q\R<' r+߱A R|sCa?D}Lkltv(8 0l@D 8G]u1x?T1%o=k@o'vHa?.0H7X&ƾwHc!Jbx3w*P/ x@h_] R%9 ODq 8N@6ˀr)Y_uCLLؑn5D\!zX-e1Ąi M %5CSzydQKԮ5*_'b19f\QP\/)H!)A6Ʉf_a .'t \ XN2rY&8$~Uh5-1^+D݉B]J?G2 H #7/ `еjg6b}}>>/br ̝Xbb#%h m$)$%8t=WF0 ^AzQDUu^k}1~T0mV0dw- h s0; s''f_]@ THzCEPqbgWT9\BEa*nBsBP.Wrۉ`Y[8%Yʞm`?1]mK RHJpz@9Zvsִ7sě穛U:Us,s$E76!syU^G,pu'&RkIeuۗMR a&AZ"& "41aÏHː-z0cյnkd X#F  0"l@F ;x7 < ҽ|}]R)X>GMFi_9|-;jWq`Wy9R <ǁ @Q %eΡ.:P1TB$&ȼ9/g.bŇA0+!u :JIA I ](AVYYw䳖o '_OO/1QG[舄v}7OL>U{Tv< ~ Na@xR lc%"[zT ] fiʽ& %S1CbK`& D#)6rBrG&LT꛸J%GKrqܺA0s (HF2QRE|(dɾ ut_BOFxB|}!.` h!} qWzy& N)O: ێ5 :KLiCy I.xWjP\Tſ<߅w&zoRRCӃʭprG{$p|xS"8S`pq] |YtwRtI~8 €05C‚"̢#@] 6ϱ)"Zވ2ڗ[W/8`%&%r( b.>ucS"} ; CemgT Bd !Pr831 up6)<nH7pnDFDŠiA6D ,"NsRlEK[4;yU[\U[(F-GP5#%$=fI(#~=1p" )>c(Y$ *!  $ tӀZwqcb";,ZF}\q~8Uc2 ̰Q}dQ`( ;]5l%&&eI+v%b\ƆvV9֚& $r6rQrébDj p[IUqQr2baP+ %`*6 "dеj{.N)˧gya-]F:)AL3&v%6Hrμq1< 3թ U <_C%Q}<&zt>B2Aׂ1E5bZ|=%uWEU'v&nH7pR+uRRJf̎0bCܕuM-x11!ZPH 3EMhuߡ"r>( N 2- Yq"6r\)#WU|?T1}vzk]_q("p/'%QF{NK`.LY'o e91W=OX%f12@P$e]*vPv1]}=|n;.nT(.3€7Os%P6 ʟ% *@/b3vK%=`m6SЄofIy1[K 1/J ^Sx@ĬzILԬXn^4U/`U# 2̢D E-E2B2A~TDg[F^a9=90@0D' ՆF !HM Oɜ1,gQ9s?cL3g3l#sBPrK$&vz%|R˹]C@0S ? 1 dдjf&&cĺ ܧAV3a+ ¿#np1sNGrx: .7d@X~:0`r#S@>U^OL$2ԙ 9UπǤ/  q@Cm(")D)ɡA~?V$E*=,bYrNӍ-9&0T8XԀ\$)$"8 /! ;g5Dxݚ!^a2,C$046 C}U^`V%&w}D9W!y21BD8LML2@2A:6d°Ǘ4"= ٠Fe e$Te;}O %gWZ#gؗԾ,Ոd z =6ȨiZPÇ2a({yz.ƝIq`$&Q,jC'1PβtS$լt;rӋbȁr8DMM0-';M j^A& w$3t͍9`0#lB#DOw0{m{ܷ{={,H 9 Go=v%v,I;EᒵG",jAR^*kQk9pbQ QPJpzP3R0:zuT%=eI28Oa(30B PmL}n:ɜŹ`~bɁm!ɠ)A2f.\'9hv"8p3a@#]:h,e~,LL]2,t^WdEqͱ` :>q@P% d$U{Oy oӽ{[p,H ۵6xMw2wHȧrgSEֻW~u)eėY> ߂"`2@ZPde$U[gU$&9/FSD T`#9DGj jhZPSCe Ļ܍25.gs+#ަA0&Abb$FYJF)5SwvHb<}|ecg܀˔Ȑ"V7>O銂񄆞|G6H ]*v Yб`<pKlqU%&a6Q"g ȧ kGz+p| pVϲ`&86xRRC׃>$&!W AqQ8[[>`|'"OI D]5ɨ`<^2 ^2?.Us?m@0ւq"USPF2hZP-J1ȂttҊ#9f חZܝMh(BsțTwv{:U=I{`jy onjb ىm1l))(#t-讫BR0X[ r=mk,9խM kE#+9pECQ@F2ZPӇR1V DZnPkc L䭓rkKd 1Rr*`RBRCYBj~D5nX#/]klKd X~D0` G(((#t-hx c.Htapd 29RMp22AYJ3_{J *qV\rsV!bx8XG6(,kSG 0Dc {AFv69p0v R.zP+ AHkKd<R̐XDd-dHLH ,5! &^ `d8Zi[ c{l#^o/2Aׂ>$hw4xYty_nn!`` f  y$($78t=費QerE#Ɜ?= ָ n' a "{صjJ?Kޣ2Ĉ."K- N kF Ym.(7|,y5<yˣ.><3C#|a!;G&>u|UcP0^!E',156"cLq_0^ @M e dT$f}q`%혯]гi- =ub#&F!(#4-C0ԯ#,v鶅CŒA. FB~׃ʝv,Z݇01?Z>.Q>Z'aa![pzMȬuJ$[3)Ɔ *ILDbCM( "`ub:M Wi<߭8:M8*K\FӔBPK5bח:li=Aڶ+'& sH? zt,W"DZ8@p @/Gǣ\=`A$ "?4e󉉁Gz={8'.S A|"16%(n'AVܛ%&vVƽ!X{Ɋ6+f&5+2K-hg&HAɠkA.gcS=<bXp`ZWNd v~%~|Fo§*|!:FZCv$ucuMh! "5;ptjF nػf{=ӒrT )S5 (ҫ9#gutbtn#^-Ԣ7xK Ƌ(~X- D@yO-gqbiy;pY ZzFY!($78t=e-0NSbf_)x 8nzZc/mfƓ|~j0DH LM*6BZ+Q0i.oIKwޝ`9Eb^-'RLtWz]>|ϧ {\wxw|=9|EMp =loдfdSŜ0-ܗtʹ_5njb D: Q HQPF0ZPGF %kץ x))GtIn0 CRT.\)2RTOً뼙ݘ>gc:PK>rGb"}!Ho %@$((%8t=\Q*zs[ UXN݈n[d E5 (#UkZ@s 璫0Zθ[k \+$| EM,I%+(kdHJMM PP_DJ$MX%uRnp X>1 Ɂ<`RRC׃]^Rxk_cv%_2b0]Ib yk PmK}ճ`m5jmyoap`0ba׊ޫ$1G P@F]uF b"1[ʳԊY(ukr9@@) 1@CM( "!Ht-B5뭫'ԮKp\8OSi(X(LԂQ22Aׂw֘լq;knÙ4k,k$Hanl( 3-[^_/kgyfz`q#xF|M0)ͬ%ߐ0#caۊCjdw%h_9Ќɻ >bF:@ruGw74=.oD'?-vH!+,9s3bxe[_mGێlK_`p%f.fl?QX>ׄF^<庞>_X.yQlmOM8ÏD@.FB T oSġZg+(py@fS/qб L-[bWsv/GKp+ W$~Ђ"%K]uH&ꗝh.3lѵ}sSpa`CL#4)OuᡑnpD~S*{&lmrHc%ބ?@fߎN_Mu!DAiA}|` cF ;w*TQ@0am~ ק-RϹ~k6B*/=-X0X}Ȁ[ ASzĨ)1f;&Uİ|F~:)Xy0'Y#f dTM^:({ym5Un`)an6V T kJRPF2Z@5K_w~7`v4Ԣ8pd on۝loKPF0ZPUk[;inLuRw<å;=$+C!K\mrĽ&A{:NO`i- )& &H0A eA`еj;d =]Qv}=8lS k) =$]& dT֭՞&-u?풶,:_cI fDPR1 HM jER2`x !|5%]&$D0& hI ;]u0*# r1WjT͵Kyx *$sȀ6 A I ] 6&᭽Cl;Dےu[nl` !bϡǹ'akصt%ىCM3ab,v]e.i+_9aγ4!"y&8$#Y"T;%kb 52;&嫀4)(Eěb/ h&;] jvܙcbhMW3eqDPW:A $؛ڐEJ RHJEZ-$1 .h;0*FՀ/cO$aN bpNv6cej\kq5 -dw%e,[_xӭ:/ +t„u5!/!DAɡiA{cik׽1.s3e(XH i1ם1Rvc*P o5 )-.-qwrt[&lQlr4[D 2EJ@Se7EbhI[m.C;Mq)K3EiȀ&)(n] v8%Qqw,t;nIDԦyHRHD0h:@]G{K$1Q`5Dvku[Jf%Ab@P(&TI D@kAv2!4"[$ːmNݍMs̄@MQ +W-/[Y>1*) *P+V2`d5vE*jRԈ%N6CF!4d:Ǽh,ٷ1°vQVcΤc ^UЮ62 Kd*bܬw\oHE;yu wLL87rc!wZj]KHbT$>dDŽ kQ 52քy.( ~jCBTn7L ]2-rںENGHHbh&hSDtSMS$*db F-_p\m+9kQ̓m@0_/0^pTzB2AӂmH C 7-'v\=:/C5O>(#4=JRHdp*P/&zCz9ŀtgYW{n+B0eiR1 (3k:@Ԏߪ^Ws oNň\d ͮo2gTʹ$&NSLzvnjp z+<"R8ZԀNc$)$"8t%%1ϺhE'\l1iK`Pಠ -h=C e= IAkA,ILrXoY1zm%A5Iq`$&j9jC  Pmt e 0|q]#ghzJa&s93!8d7%#YM_cE>ڶdka X&  8$l!nj2hT)czy98Oh=m.9kQ7{0V|E #r`62"bдj~RX +]ҹ@QP11Q((aT*rrg8tw[; Og&aya- `еjr"d$2c.X@f0,Ʉ&rQ,Ev-C&&i]KI~zD:)08r&&):C%)$%8t=5I $bqqo筙9w,48&ID1uZPݎ;~FlGDەs*t; d Xb!nWDng( (#t-e5k>zԀvIV^S X+1t@6rr1TwJ "=]<\F8ug EJ2JU|0RZo{<;xt]+`.KH\\F.BK@׃1J Oڵ)uẀO_aa BmșH :JIgF-11]E>|ntJ400.&4$ #t-y}V c3cllRvIuBqɉRړ쥉1.)($t-7ljuwv?65tAtr\ 8`aVZ%((%94=voТn$祛u,$E84&IH@e3&i Vڙ(̴>PqxvnR,778qDa8pSmSRBRCY04|p(`00)rɱ4JJ!e׃ʝ>&r[IoRr.j-gyr $`ubܛbPݒ^ޕf\fP$duU,"ؼ-bH1pbтMLqݛⶴmc ) K"ZHS $̴S}N\n_8 ~ө]RI€>| ϧЕflԉ%nmq_7-Ck"1RxW~y9>s`|ֺʏ؎]/[KO%%eHa@E0R[5RH@0(C}*[5:\@ M5kjYbN2툋l[)6c> ,4KLԆ ((#4-oh)pƉKm*$yb8#<2rl(霻=qxl8HGG!`Nx)(nkAvUG$e̮^8nvGa0}2f!DPmlǜj`\3=9׮ɰ]WX8\S8F5JA I ](g̳V Pm׻4^/=-@቉n>oWa wSI[ >m5kogFi c"()d||neV11aLmmߎ;s܇ILGKf5DŽi cڐ9J QPJpzPDwN˻N4ݹ}Z{ܧDŽލG@ MeJ0-8ѹ٧m`,Q=g@m`1DMh#!DAɡiAV|iOq ߉HF[3c7cJ͍ [3^Ȁ/Ű|mBBRCׂ]TeO4fSmm\nmɀf0'`irQRHFNզT=e5SŜr#}ZEھ_NfF.1OԆ2rBTԢ&/KK\5kTtYԖHW'UMj|в&H!k,OgEֿ: ^o8M:)9i08+% 6I Q@JrzPCC2qt.sG'R72[u%3t0z- |u_+6KO[ˋ'@tl#ŭ]*PQ#&{.o<͖ͭRlnod@0M:pTDRj|ӂJPHbnSbCnG*WK+C CFBRHj0Z@5KeDpg9kڷ&!]ҹ!3혘jCyGI! J ]*7췕$&RQ{e;W.kq8afA2JRJgI RPJrz@g[{)1U{wOJK&q "ɑ`d" x-I! *^%j*ƈZ?m\p96};Hqb}JU`W> L%o^ynh9m>mWbۇi>|hv]ko9=ɡ7ӹ~iևo#~mA? { |xDҾm}hw>~/ ô??}mݎaH0۵|צ?;@aAôX[{8/[C?lXy>oyyW_=EK<7=m}楏 ӟ69L^3Ja~MN~Pz1[~h߉7߷_~ >0~}ݎ!Ŀk#< qև"h޽?y;poEO>kx= yʘ|~<;?˵̦<'PnOW>>fNf v(u?O~z yEXבͺ3UXmxx5+,Ï? 5w2?4ojHNklPu^#}lOm-jÓkv6_~1_U} e4~&gX̼= Fya CXo->7 ݝ۫Z#l\i̾jϷl k m܆}C2x5i Ymجo>}z2a~|5ַg$-/>ېhocmc9})\/C=?fӯ_}z5txzwo~<%%{!ei6oֻz#ԥ~9y¦9-GwޣS"uz͇G}`l 7T\yzCcc:yGW=,*妹!0wm,exck4YcV2A}1a4Bя~t[-cߏm>|:9}ݠv/;%w>=|#D9]< Gջ?SoͧP͝>Vuۀ-7 p'mOgx߅#^;cx"JWjz /^+?5Mnޢ9xZoj-o?'{HƎ7-fW 31>ܾO$-;66*cQ<9m~x`ͣo۞1m!9Na9 U|id? m؆`ce-m/mw{]RK-.FPcCW~ֲr<bGy@{Uڿ-@~ UoNm_nXe/%omɰoa@1gcoZΒ뗥߰ z_G/sZ֢4= XN: UiL/ /AŴ |[^Cc>Bگ֎zFطv+z_gӇ}?Ɵi=:ڜ>7?bv236?kKF|]qx3|yu1=繽m/>~9g3Υ_t"m/* &?8&)[?O 1YE=jL_؋G645WYW4wὖ]tpF7 gyl_c{.sk,MݲzJN._=kvԾʨ-۹"|g3-+l{/߶o4sfQk0Ǿ{z =&GO(k%1{g vvMP\/l?lETq{02`FOvxyϠe[m;{Ml] :Ow#^8ݺE,skIbz=kp/",`{!cBsG=V{asYV8>5i_*?)iem>OΚs1Kg-)߾^}ls-=:ߧp^>1&~1F+$-{aG3/վLtŽ}3o3} G.Դ6XsFs|N E ol_q&3۽cn{CɜUy GBg}>/&FH! t݃f!s!->;i}G[ݦM-KZN<~zUZx`?.=瑯߃v_E}xieKw_Nzb̸n|Kloz@I7sySYM+!~q^}CçY>>ayn6KSw|.o{,~-Ouw ^";uZ??XcBc?fXal]0?'ޯ){'z u{rY>jӟg̋_?~y쇿xnbՈfk#yiXZ.<[{>?4ˀhu=l/_,Fxz )^/EzlbdW-? GvC/#1Eç{/;ƟczQӹnO#;qv<Ƿ]㋩+?<:2^AϞ2څ9O<rYJ|i4Ws=y vSdsw/ e}aG%Li19QvNendstream endobj 269 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4028 >> stream xW TWR٤l1(̀(j+4o-4v7" ("( RDcL苙<cv9>/}_)~Bp ~CDGYo‚ :qkb"֯u_tM{P@EAL}P~1 1#.>?)yNJ 6FY.p'M}cڛo{f"f1`h&YƌeLf%30lf3yLa0 A#0Cgƅqe;&gWIP)vTXϞ'*/-{|nC'ױ@M2XdUe_my$mZÑuZd2D۸:<- N7_.C\ɌN_4>USuJС|[g}F~͹L{U#N5bI#)xUʞC$wHCX-e~=z]^Po }8c>&uc MP J: !'k4iH(rja9Iۏ jNZ:%E|^)=Dőw15@raVlуq˖i] Xbg |L<7fDCj͏)Kp2~d*2-` .}AGhL42oE\z=+=u;w'[q1_haibT\dhn,Cԙy,kkN9"0$7%Eˁ4G,` M@X% O I 3 \h7W4@;?i]|\FTy g+ט/+EaC! 8rWdf]1PLLyO!T a.Ә7%.nl(ԓ93h)Pr$2瑹?}ϭUPZ :On"3U[bI[ FsM:Qvd_m$+)ܬB@'?| ?sB,Vt,/3Ljd8q G|iwf%'Fأˉ\F.3Re+؆8:6?Lٛ=G3 7 3bZH@;utTBlW5"g[Q 4/=+f/Y*]Vxdu*|_ZDo)#,Ǝ!ٓ?3?͙؛U#uwL{xxLLxx{Lww{{ r-s݊KJ ik޾]GF<{/գudXX Ɨ?xEEsUaKzUPZ'^3Ǎ?>Us|T$ߦԐ=k7m8O>kvBiKw2;(: e]}[PH2yִb-7NtKy26}3D2QŸGjڷ! gO!!Z) z*|Զ;+ teԅծ Wiҥtn<(y׸L5BA^H:G|vzM}5D厘=Y~Hr:bf鎢P+`eZCzz_ȤJ_to(rʄvXVS[gÉS;JĖCUof,;HD&:N(gbup;tlK! ¡wppFݻdt2CVDnoamQXP[r5+φL 9 dks ;0?$KFhs▦÷'g-[ƍ7;q:6w8CZ]n5{\#v0760‡M 'wCcJt.6;:]8 #oM%V5[|LLjȰbXб#_lkAg{i 2MރhpR}&l 쒴 c%ecH9U/KnB-=a:KHӥ#63ѼPC*1rڻp"ub_abGA Z@otAoMVftgHeDsug _gɶ]fOUnjWT<- [#}V`%[@nV&BՏ" |ftxFqU@M?dzbÞB(07m*IۑSNNXaQ|JjKߕh>J^\+Xi6KmfT\b*/?pV*;\]VeJacsendstream endobj 270 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1991 >> stream x}U PSW!*(X꽩UAh[*W V!`HBʪxC@ B%Q>F ޱښumgk3u;' [M2w9|}GBɂ(D2ry|N:m)+%Ƿ6QocfY\0 P!`k2z:%'c[Q9=:zԩL(OSƥ4:ALnUM\3 $VVʵiW&Yzrꕉ k&OWFs FSnJek:=C}Vw(jZK%R|jZD-PK8j9ަFP#)MɨC < R]IOȒeY.gR]EpqQ+x}C.A !=|m:xtRͥ uHي獛o>]Bn=!n~r1 }yO[\zz/_Y.GБ2L!bȰ~z!1k+wdpXF[?c4umXGBh{@qjW!8x[R^0 a_ p@ոXԝn>ΩjOٿu1G:\}WaqeVT 9 WܱVqG%{4F[wpp,׵_G.B,mz US+iSC|܊*W5w!j$ jd?Ab0AyD`lT\`.JT C`xځjNqÏ3yej|Vz_ݻ8+}{,P뻅 7iڃ]jZ=sGsP[;WwTSf 伋?Bx 2rh6NԄF;qm}_Qv &RRXf;5UqM~k-4j--sT2Wxv)OFEkRIF#\-XXdD*3poHHu~r F"@ %*fd"j~a 6 JvP>i:Zо,%xJff]f}[b7\ Evd. nYnC Ҋ"D>VI-)rv Fgӫڷ\^U U.B [z|+@D/D-69Tu5^QG<Ӈ'd?rLVNpV/pF  $VMSa2 b hxg:dSU,bfA 8RSd3k;܆@=žC[ C9G߸l;ʕ 8R6ϗhT3x٘Mi,dlGΐaF7e?%]`›bB &p0TT gE B@I[ cQx\0{CلH7#Mߑ6ryܥfw%" f3GnpA?}r  ;x0MHnR+Ugi&{e h&ə޿T4=EE-_%?vgܚ,x赘 ?+ B<x1^+ڜI͝3RMB,O/^L6>k0K.QRQl<̳[ ;vUF[W#=V\P +Po7TV:?`UUv9++m5BQΌendstream endobj 271 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 498 >> stream xcd`ab`dd)14uIf!CGҏ=<<<,~}_1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5М20000005|?^>Z5 ׾_]LoEYJN,ֽCXaѪt,+)+ͱg" :g675%I۾4]KZ-823 ,"^*k]6=#X^'o9kfӹG{!nqw]н81\+4ã{uY!Be]K9۱Ww/+wx.0Ŵ]-ýkQL?boO$ o)< ysuendstream endobj 272 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1019 >> stream xLg^K542sn,"Ana+P\H7GaZxJ-AV0Zԙ?9 Y,nY{&ef\r} DQT\NVe'xi-%SHih{8W 44h_SNk%Ĺ [Q[YamJr:)|t`?X2>;%7ϳ5ȓ-C弭/0gLÞo'?BH-ԗ+^^T2. (Jݣ,w7AbSE^QB-~0X͆kDfgqKIɵbeVFzr)qnLzS9LՋ[6Nws8g'oqkZp@g~G IZɤ夥&/rDžpoӓD&R𫿜<fԎbc^fIK0l$,)T0 :Z(0*s6 Q\Ԭd+X[ aXxk՞ᱩ%#ErB7Pil:YurFwvHLu;UiQO;ahvc&n"Df?xtz0(8J6x"b7 A#?ƴv*\ɩ}rlo\/!-#/FROȩO<ʌ{~胯aԭf o:fHjP͙'Oq1O%nfyer+z8Gs4 dC"jVnؾqT_2lZq۴J0IOS͕ I2~ W'LۙY }XWnF-@a:eyIOS =}S& D'HxeO,8'kSAtÔ[Swwq~AhhWǼ7(c[oJYE+ l(,x"辢~ogԬ@/:endstream endobj 273 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 320 >> stream xcd`ab`dd M3 JM/I, f!CGO]nnW}G1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000201012~_)Y{ӏN3~_Gئvkb_ޝ+ڝ͑¾lzٳTR> 7s-<{ 6qb ^;wq {'Oۡvendstream endobj 274 0 obj << /Filter /FlateDecode /Length 1875 >> stream xXKo6キXRWEQ">i"؛Jp$E{gD} Ê"97 vt*ZWoWT]ۿ^]}&lkJPbEIHY֫ r6Q%\d^"lS`8 iJ`CÈ4#})/6+&C%'tT VdWt>>ؾ92/C)el_0$2Wlo9VSP;#]17ӳP eN锥!UUb1TiM,P;3P,7! )BR;#CxPn eVCW;n&C:_iɥv3$&.#J 1` FoY}kԊi;UehhLUC +u(BQU&cL{c,ܗU#Kz"yiƊuKw4]$WJdgšc'͇)f0c^vPPjyaF3vpJnEqAve3LsW/iڴCÝ%ԍ0ۢSՉʺ,Svc/վj30.se`bHy(0٩ϛ鹽zSQ9-|:7GyǡP$G35UO>]Y_NԻbw{0tK&šqA_OES'Gfl(N] ДIjoyU;RaF}d`vD];0\^F A ̢TٝU9byj]d6J Í#[*<ɰK  70YWpy6yͼ[YsbvRfu[km'ݦ[-n=j'ѩp"CV7:nSc3: S'nG`ʓ:n? c"óݻ`#JrԒis [abIs84p>Mζx[% rRO_Ln{؟? P% }UPM[uGPc2;(og' /;n+Oe&fIÔ1Mل!_W0wendstream endobj 275 0 obj << /Filter /FlateDecode /Length 10682 >> stream x}[%{qmu`YˋYQ655%թUWff&Lƌb# ƅnԤoo՟^idҍ6L9dotvw7wH[~}zWZkcH7o}5cTLVśWx߿ABmC NJY$=beU*^޿}xӫ_}?h ~2Ƨon F[4A{&n|z M:n, 䯠ޘ(y |LV0C2hY=) W~r; #tW<K7BKm)]m:I҄#Wd}àRSr)໐juAM'4ȏ=+Dyrf9 Ý*RӾE@Uݾond&cvHhFek*2 ߞK˿+]:ڽ»Sܳ\MeWJ~5+0ゞq`~d:"7ŽQ{;hmQk6z堝<`Ay'x5ٽF >̏b90wMU*^;f*qrӒtc*NÖVu͔PPX14*=Ffm?%@TULT`.AZ,SX(0Db=foGށt7u `j5 :3QUrO.TQTGtqZ\%ʓ710g6{VW4@ A GW`&̣gܑc^qauDZs:7yv}Ņ(qd<;gd6r6hف-l$7}\i2vz;G;TzUBg\xvt&0g)Vp n7yȲ o:v}u`+y*BEJ/*6. W2c+KߪUd]lTC[OK˧%s`fc5ćq;FZzT#X㽙d91f*5{Si:]=J>X`7 F{4񳉓ӵS`iM$`d'wZ2 sx]]P`;/б;\uZ ,gjuuW%n:-8#u?0S mԝ̍"Wgllԕ˭vV&^.w`dGo@9AgIK`R>-9JK*̽\ ,.1s:2`duQb_DXVU4n]5Y"yFD[jXGy@+QbNk6)ݎ+/S0^KfIf24{#+YĺO'!֎PƓ4sI'9j,AW­s ~aT XڈUɂ c-,ۯ"O.  zZ3k̆U+ b4`ed0wH4J@aٟ֕܀!։THK %s[S2vuD] %\ή>sT`@kKRɸ3)4 1} jx)nuG~~wGeV"7-; -J ~bCLX0:٤`n־M`o;v,-X\Ʊ_},F ƎQ{`qz/,-[iUBXu_k˸`pj%2sѩ@9wѤ@ԇCLq`sw1tyg{"sהõ-*z2\Uy8A-cI1pq`Wѕx,QR['e\4FB= q80Hہ}܏hTn&s">U>g$XmW$J$"Wq 9^#P9ΫQa==9<+t=Ot1.,7&΃S&G bLZI<P}uyg+QfWiF]I1sx|@UA]MAɵ/:7N:8;tmSAT|y+ gs-*xA{ѥK2jGصv+{3%Bg@[%!*Jpݕ̏`dYA:~V]U59|9QqʵuWliyZzeLJf,Zz;yW`EsrvlE& \ܮܯK031jbn{9ޔSx,3(A^ bW%zmwD` s>0zN{xW溊3 }Ԭ_㕓; 5Zue",%~| Q-))Tj-!TxPx!ĴTkIK`jh֒* R% Qxm}-!TpZJZ*+mkIKep]c-!TRRY\i1%-0PWE*l9_KZhX+K "biC3.ni`S(oQJ-9~;.^] Ҡ=F ̬?Ӡ?vt?s??+=s'=U-:/:/$*iV4TF)2A֒.iZRu=jضkWmZEW 5Ek7`bhBB9P-% CDBjZ/kH\FzrR~St@}Ѫ|//Т8jfg3́TZ iiۇwb-0b<4뻥nUWswKۋZu3xn#G+ {6dY[iw`m_w`>@,*5L9@UAkDm-!ǬcKyr}l3MW/?9oѴs̚ePd6@֓:@{Ua؂]MOW:?M|%ʦ[{ō4;8)^m$g 91h@$$ު .].gwotIگtY?1;3 P9vh}Vڜ7iBƞu ok;!s/n QT;nјaOe?f8v)8 ꀍ^nb{ݴ6FFkf%€b6(` <جhKGN0T`~\ۉ@ ܶCG4_8heVp(#} I{86K36rl۬ V`|2|\ s-[^A=i=0q:YٴVq|~.+Iܾʀ !! `#3VGXo4llQsv0*U0\rs< `g(lub-lgɜEv:FbNWV.lbWVD,iQ r<-:fiўEZ m Ekӡ?7XLv:$8OGJEMŜF!Ca K5ε6b\-ov>dbkQ=mS h-Dpa-h2muo$-$Oq94Ҝ= mi^w"!=L Z}ڄisDh#Mƌ$L5еjۢb%[ 1tcMqMVJmI-B0J&L5R JVhfˎBf+[bmfླྀQRk2$e-mu4}W SjF3j1v5I}ZEskeǚdleGg̥5X (ۣ!c"-FגA2eʴo`>H8Z>1EaBn2.3XD9G1(Dȩ7n> hs#RMs ~h(-B^pv͸[MN>/QNCt }@Yw5o@Y6W3@8gk͝4wJ  @,טTIir0]Co̺Ӫ4ZFҘ ZD=OK81䈍dfƼRLJ6?0].Ԇy3ڍGk:I}ɝNYGofpbZX]SR#~[Ǜȑty:<V q2mzoXp\x$YڢvdpKIٮO̴3r>cI]#ٷxJm:<$:@QsyN)&m:_ւROR2lMg¼@x:9ZT8<W0s: HTHLTK0uն#0?!M.QYQ0>e" 1Hkft\I ע|HÌ̝{j Fjaacf2ƄܩfQ Ӣ/Z@Gs i,iU-J^<3Q"?VfʌMir-dH(`3 ip@2x#(du>L>dbZQ1“ܽs2^S) â&`"fڮLMt>fx(c̽|)xƽ ĒG0FQ"â1~,(G-Q-inXgZBbwjIKP-iب֒ N-i. 7ЄziCT9wjIC0m{XKUR4TKIKUZR9F4!LSKUo6TKIKg4ZRajGz*"uQ*ߎo};j_[VY0*Ki4,щhW9=|ŧO?<|5oHq3ew?{a:|)Au߿?=.?-'w!\̞l0u\x^ E 1̝Ћd~ W^zrжr]~ xJ?=_o_M9\~| fF_owIk2N60S.P>߼F]k@|zz}X`TdaB@c@n?,? [:6'@KY T"0R}= m=iֲw(UTx<i|! 0U,Fc2ցA#k4:Jg`<e5 ԑ>tCX[3EzX]j6>sdB0 }v!˟_L~V|qc#AAs|-wg: 8 ۹y|0 _,8?P:/ ?|7_-Tʁ}͆G[R~tMRRh|Hzr΢_,i* eֹ6y\tפO¬61G79 8_tV9Qq^g39&Y栭8t.AZTD sj|nkQCv~iVpQ6O+rT]p3_m~&xA⩨x`*ƗUopӊ/Q|58Y/Z0J 3g>rUlZ}< T忾 n?M[?+^ny{w㧗=~_@w/_jr_]}F[}?<>\ ?f ߽ɇ?ŕQkw]pK2LƇ?ܾ{|Zd.3s6X<}ԧӟ>>߭bf^7o?=/9ǏOOwyxGh +LRzE˞d||r&5d}8#@~F8\ ΐ ̆r| hC WbƠbX満|W-08av t_A"ȫ'g\e[mւfІlTnT[IChCUKE@ZP-PՒ >ޢEO s0/{(%|  &,RużY7F̱G&O%g%jN%sg%jN%ZJ͜d9 M;q*Q8+Q3o*Q7+Q3ml5oߚ&+vLE154b՗6GTba^0Ը~pQ\c$DjMP!* ~T$?Zk-5A1y?x72bX/QuΉ,LX΄pged)R,=+ %?r/cTx$+YLj Nh3:ָRr7QGT.4%]ybɚu TyBZ$^vtCFqy1Ѽ7˔GP߾QQӝǷeXU/B'[O\C([5s>iiB!0ib`qq(7 UDxފB93:pi*1|xC,aO 7x(Qt奘|Le;ܨxخKGDQ% zL믩f%oW(Y6f EB.SXN1:s3gG4k ( צr9#*rP)qjkBӥ0K06 76 (|l> vıJkr,B0T4 3ـo+ϕ폠YAL{qVs}eX.ʠnQ} W"(/:wA$s(su[D JD $\ |V+oXc99MA.;/CB5@-'Al@/˼GP"ھ`ɂGYdKBIW"cfC*} XxU%1eX`ΊʳG#,a 9!0N7%$a KddPB2޵vѕX.8*G9NSPX‰}40:_ZX2!r </XXPx"n{`W Y`q/|%c K¬ 1kQ.3IZUlnX4r…YEpŒ\=rv>eR8aG0uԬ\6AE+R4kMY1$bgT. -wg9,)żZ&#A鈏,b,њ K^kNsb- @"˹Q!dJ%[hhro%v{zJ k#6,-klXY;m3P ^Z*Yd@Aj|hq JÞC^@[oT{j Y2,Q)tO;ɛokK $n JVFB,JʠDN JS,KElɢ|DʻFa~r ;ǫtXblB,0ʺ(ePB9DzbYV@ڠXD1!;Ws9^9T(e;MuNxGgڜykvX"1aEU ІO6R;|;bm~'׮هa\ej8Y7nmPGqX"#}|bnoS2dW<Š%a-YN $0O#(LRV,mm%1R,PaYNg?FdV$I3r 9aIB )lJ(  _x8YްDG%>"($`%_6LҬ0Pmz[?=Yq `DC(l5[^ b,Ibqb&]B9m $K6\yi%rMX/bV(!Sϱ ΊA'|PSPƟcͯ /* %qtePB> 2|kn4w|S1B`-g Ȟdn!bAwUUD@kqsܚ>&jsY\$R5gx*k\ mcNH2@OSlu(I42TI)u*Vly4D:9/V.?@>LMČC 6,Y+Y:5??wԬJ4P'y 2(A| LfPĹUZ[dM?Gr]a}]C9ޖ2ibfjln+"!HX`n&wc=DDIxeCd!:>1d]p@%Jb7$NHB&J9h^(|<KRÈ&”vP}خKXXCK9,0:Je^%~Œq]=&\ GX/|Pαl#l6waY|X$1=t^dbz4vWVPP"^ɠ$\!岹+FqŒX !T'|x, %2Qf QV,Y6vL K6@X?YwqW;~#&3v~5?#nendstream endobj 276 0 obj << /Filter /FlateDecode /Length 25338 >> stream xݽYeIzCITeݝRC (@3BKj4'nfuft lߛgJYs[>w˃[.ϔݧ_#ѝ7o_C9޽9Wwe.价WO$??==~CkOϏ/?~O oCKy+?7ȇo痧wǯG/{7{x˯Z^>{ն,?>o_}ӿ<~~W_jF?|$?^>oׯmܿnrgx?={˶5ǟ>|JE'mȯAqxa矞>YEQK}tr(OV'Zo?|O?|^ׯQ}&Cô-~v ,KLTwDG! _)}'.Q~[+?gҶwg>zܾ'K~ho_c WvL_ɌX[r^&x7h}? 蟳v>,QzÇoJHN^7{\ݛ )WdtGe h)EyCڱ1ao01i77>.'e_xhWϏ>XiӅ QKb|H%zc /Y5+si?~V̴ۘ7>~ɴ5>Z~._>u/^GogYG?> J5&(ócc~Wwo~}ݺB>WŅ?/ Y +Rc}a5xwֆL)x%~Oy$t"'7Ak45ӵn; ?g{ܵ8]ť=D__ӏ}?m_ֳ[CqTΎ~}<XO|Sᘏth#jKؿXPtfNG.f:\w.5*j.w z^-{?O?^{|e K׬7>~ƙ@_@G]]ϸIaxЏMnHe.{cYI׽fY>^a>'}O?Ȫ;bۛ-%⻟ {>{x\9QI}-l Hnum}v>>?}3A1~MnRbצ%ꃇIkeU*_<ʜ|σMPxPlZ_ƟޜA?<2-+({Xz~;3%4j'~fsSr`%Ȋ~(=|tPaϟƳ"9$y}O'8?ÏeъXjާ ҁ}8qu8{ow?=݀0Hx-h\C'K3'_*w&itCx~A?/;5aXQ"Gt1 XɈkȊiwǧY_7>ӈ?s}O޿Jp^>PFnѶ;42P}_ OoJl"9I7v~ln?f̞Yt}x׷w*}ș|,=5ERqn}ynCG~̢1LJ;\i{OOwp3]y(݄lCN. ]Ckwwzz׺Bwֿ'wǻ$[5 u')UHC%A_%.Ib ޮk7vE xxÂ1 iI<3Z0q>J\~vGvƍS~>}CKCLIҧF,;!,ȣm2"|M%/t $vrE-.AQ,ַ7*:y}p Fw~$ه[i<G)_٭e-tgnZ"5'^ [3*}XƍzM߷Līx SAx,.ѡh}-Z7 *}"2l7ͫG REF|*cEC[0;VC~hY/dI -h[1HMoM$}}_&CJc==/rERy}W#|1^pɘbH^| q۾qy>w_]eZabW"v\^Ttg.XJW$ΐtE#q>G c~0"?}M[In\xB0'Xs \Xt/1}?)U|9Z[A =@';IjACUZႪڕ;Q%8b^`Iu$OO_YI_~J^K j_ 5IVn?ġ<$qU"eEe&=fzeYHB߃JɄ#g5A\ r5MĿ|pMRhN;)$,I1+= P=(6 __]ReĠq-}Xdե{Hxӹa8c7δ LR> -(Jl#R]M5>Yx}g- =uXE+ fk`7,e"hǺC'PWc|/ʫa$&9WX|$K1R}tc}D<\mƱ<ƴ 9S]#7 Z>H5d@А1p<4F?-x Osp<.Y'FM$?e/_tsƱ5VX3QH#^Vv|ɻ-c-tM">)VNBϯ=H/gC) [:/$XΉ}Aiܺa`&5rNvIF_aqAU#GZ$3蚅q֥I<1nU~ 5XI4Į C$N 1 u&AObA $YqJtQ^'ʣ_,=WRe% yhyEBHr _(qd=gK"K`gгt1\<80^&dsb!\t]W8AB~[ZkJ`W)sR>,8^xoBb1f3TϐLƮe_dRuIa%W#cA? DdbuG%7#:]f`MbU$|ugYۀi3Ap%dj-Vs^߳S% /ԗGt}ys"oo[yT?اnzWJ(% W%(8Ed^ΘSOaOtdpR 0ϯxlC7y_4M#"d*ʠpp+ۃ0tS/EPMo$x)ds ]i8 g!?/E+ zǾYH}# IPl_R/? ~Z/RVk%0uLsk6rݪ ˑH(K !e1Sp;'\˿?6Ck"` ,حJ1HV ~n 7\dYaWmoa2$<u-Xx+cJrrէ:ZΈ90CR]TY+M䃯]$+k$6nSyke|Bu*XӃ)VLRZeL8IxwD$v)X/mue(K\n}7|ǓMϟZU%+&1쓼D C}\/:]x z%ޔea@%Xj$,B{1wzt#b9N9PbJaXcJ$2FZFgkq"[px^n45*r[\N}h(ɤO^W&iվQFqҰ1ac,&J9q9Ea.vIObl#_I˜c k QkG{Cj w&'5|>`@Z6ۃH91sfΈ6y-'Ӌpgg,sHU0' r+^i%Fm&p"lʁ c?K0J|\SPN3L*AAb.ptc̼q.,fěIU``hYIzKN!A (:l.XNH!OR\A2 Aáؿ08HolSu\Vuml)m1^h ~U jI$3p6)I~D#%\r"a}p9"7\ `$dV GT%^I.q>,#g8d(;vWEZD8j(8b>PൖQ|9'<7z ?7@b3q:q萦Mr'N7 vJR@DXYܝ_p?oFOj!_ mGh``0 `t׎̫e!eؐ! v\o׷J# &-de9WS1H\gt~]CHE`q i"lr t-HmXi5-GA02e Xl.0e':xxZH\6,2/XؖBq̴XOy댓ԑ~ ]DiM2H}t}.̙$6&^@WI^3~{USWhgn%ЉDJ]e- Z$j%$wSt6v3]|M޻;o Qt;pv<4$K9t!cVN3(xŠ[,fH38LA+QT;L!ruЪ.DkPcpMIb#486Y]q Jjv}VB_-q]?`Tpj*HŅ W06HU"2hbdK 2!B@Q,ZW .#R`"pp(pze p>@\Ŝ I</E.T ƁC,|ЈjI,ΠP͆ ' ;P拀N}fXS (\8g;ȨFtZ*ro VW20U}>a!c'4C6ϒE `vw,|HpK s%׃GBw\'l N%ZbaE|#kV(x|@SRx>R5+S뚁 'Y5rڷ 6,Z4qhPḌoa%+D`FeP|_?RE<<%j2+E &GUaEFͥ0|AL 0!5qZp3 .Q39}b/ihжж8WVdqZof[tRھ0 cb/xW l D<<'n"@[Ĉ8PiN"EAx ~[y#Kf0[xqa!ȱ}&}fj1F[KE*k6`~j&Hf5ڧ3SPw+YcVElVAA8*S DxEfHgR IS ^%ʈuIRIS©I)л.\F[WabHrہ[#0,{&$O?6Xs̚l֬:9(~4/Zf9ShM$ҖMJS}ydĔh)H^2an k+2V=ӢE#xEi؃*̺b]q_U2rd! 2Z@D̯`4҂#W1w.:Ay@x8ydbNL{*x+"ԝ';)d `v aAtQV#Xq>Ƹ)6X VZat5@$;'$X_9:amʁ8_dQs?2mP|fHrSqSfnj&>d7Bli|V~*)L1n^HyAQb4 K8"O"=~6hIDJ*)A.0ݸ1ф*m1t]٠fS_'&N]O20zUy/4W}6&m0~Mff^PjDﴫ"t`Bdi JpӂKࡤP/(jkU5٥s)D=^b%ioB/'<LZ`o 5S2zPJ*yJ7kײ*05:.S׎L5>TINLi);=S7+r`^*G$q<0/;aREy|@n0 k>@%H,IBL mͩ$NudHחcxe7(cpR+Hj4NS2s@K|GVI=Ѓ TJքMfyMU#^.i$Ɂ2]]Ϝ@ tBam= hQ6#>Se%ء3DZ3ԣ@/%R t+@HN(( a2l'e@5(ɉ}T8bf+FpLNu8dsIf#,T `aw.hZ)~ʊ+ ,8RlA_MU`<-cUW]1T Я`[K!gA/ᡉμ#;һNB[E炘Yc$}%]AFƂ2úY F`Edgb7M>{W%}L$\RoHk(ˣ} S]#΁.5ƻLsC1Ba~c1 ;kP {IyJt0DQ%BG`2{J+M$擊t[~ h-aDާ迹AH{ۖxߔJ, SF.< 9 c_Rxd,`e[`"R`ԥZK F*˃<(ڊ/pɆ:%(Ip6e.MpF_>R9\,\ }b|JYxD5W}?P Fb$J( Hvp+E7o.DxHz\7;_%-\VJXBŠ&20&})5B8xzUPDp$3I'{t&Md]/c+! C9IM`4Ѣ)-Cu(GI4-OAQ-9%$ޒ՟-}o rV#-3~ X;6h|R¸`[H4,bU2 7؞7%kzg9IKZ\$lj:ڒ ⽂w˧XvF0!S\ň$qq2mDI V$7:̎Ql n 8l`&pFV("mXjU!jDQl؃*C@sa)H#⶜ȂFx8 Qu#jJ"HPA;$;hu ^c$ EL$HU~o|m5n}[~o-X<얪ݲyYï v\)&:Vؿ%5SW 9rgZ^ 15[aDPH$e‎. rZ78 *) ) "aATLn@X)eҙ[rD$( VY2(^i(ba%mIܤdi\Hd{Dng4Df4iw:3 GV9΋_C E0k:UA~;u[nmmSm&m;=~0 rt0uJD Fm`c~'6;/jpz& ^A:N@!)˪vyp1J*4 TὩ֟ `, 043*92y ,N%Rk?F(qT4KL7'VD H.+(,2 Eϗx-Фh&>ɱ(rLOFBuS  H"ԮJ=DjUIyKIE.ߧTID,`${߱Gh ቩcPf%+S8|T_+5 &MTUhH~/a"ۯuJe1EUmFgt3`m?JUMgDe1Ip6 wEYdiDjF"[7t-K‰(3<ؔ3B)HM[ %m6N&$7R}mE1P|I)r@goKXI`TkItr W kc(P Q#4K$o=ᜰIFlf"6- <p0zG m& hܸVI`@,gsE>'u$ (g"i*^nFw@qل]ad(j;Bޒ D[c'?s:Գڔq qZy9RV }Ѝ$PQ߸pi4h:66M\{h\3r,2}o0-TZm\"AM#5P~ ;ShJNG/О;?E" txTY@rHt1I@-gu4I0 v+npK8l*B+ ;kOnzGX2tv!F~ wr}%xQ.^DE+Asi7(mW_k AFy3 ٗKiIROhbɴ,M-kD*?fOC!fZp~MU9jPU@81K,AVy[kx>AۥS2]pm\Mtܵ]y'{mw3L<8(j!WIa4H;,4D_35 w 0/IދPBWDG J^*@~gԠAZE(5#X#LE"~O ^Do%i-5BWk#ꈬSSܞrR}iI (K!6]Qm@Ob.fI X0e.RhZ;2f~@􊰒3/7331=b3(6b06Ws&\q@:L3-*UXVTii,QC. >]@0i4O *IZg}+S׏5FtTTEvEҨh6[6)'R&9伉u\UJHMGUQ'u`+!r,1"(i2* W$Qw&ZY4 ]A&M$A̍Ϩ}EI:' K!R?þ.<<ۀ nVճ8.%/PC0F;3@r\ ػ={'R]s5u{44C }otI1®PNÓ0~2icD]QC-(w.ȃ& 5c#џNOl"Iq*'kբ]-QG-A2\_wk{˚EtkᚆgzT<@&UO@+(l{%48YAtLTUyi{j\'*X8N)켩;.Gp慱,yd&2S]7mca?'bEýh STNV(7ql<*^xQbSFzAew[hԅAL.|PLP`]!td45^4WؓrYy Po"ܯiF3SeaCC@D5'u\7͠C˴әVQWH35[ wMvt\1?h?`It*dN61eWgR^53,"ԛ%ΑZduO<eEfY|k䨾|sr^B5oȍ%EgxD;[z m_L)(B*WFS.eSGB,ut rSVYr!3TmZh%QJq>HJ"5^ D,f`- 5v!SD[hm%I[nJŏӊsS~\ס>J7hi12s 6$X;`7j0; l>xdg]r Xsę[b*Yl)1533 8fh3V2/.]EWh"EP#KNgmCQgXۀQhWԜeMwxйVZT<$Ӝ3}Ϝ,wm}U=eRa[xz@ H SPFy&azMW?5M3G^/' v%gUrʑyOD'iY lJ[-&mLk jascQy23>g?WJd ƃs *ZiR9Η8Ɇi90&P֞#\RF#s/x5cMoY~ֶ=E524_ ЅYJSӁҟ. DneUȮJ¶|.`h_9)(.)SFnEvA0A;!'YT%r{Q Ls'$<_}AҖ =h/A&c$rg-%FV2?4U沝dRЗV,)--O_k/HQ I_b$6 d!ԳN/> NBIн q[%a4̦F`(MH0o<$U. ,%0`Ԗ9ő2TћZ3h@ g:Ry)*l͸'^e&bq'Y5I`IL#q9"pAhd[_SZeX1}&[ Zvϙi}s8c$}B$UV3##Z$&5"!<+ POFM0['!Ycs&CM64{1qcXëQ((H|rʢD,r&܈4ԢZ_4zEp AY*$#31o2d$`61agR{Rmm:DMvkNQ D, +ɉ\6'Kq%)Uj[˞Rc=j mvr8E>CV_.P:b|+j^JgQe@YI JܦHc>O*a?T "e{g99iY9VwOW:~gn6t0 q 4iBS- erײVbLϡeLjDA:hVݦ, RMAM W$>P9J{$]r@H>Vd6̥:h\ ^?pBOM;muɉM~1H%ER[Lt}KI-hMh|/; ׏q.\Aٌi PE]x8b| _*zG5 n4Ñ<̔Biit4iug{t ّ2O4zWi|[~oIw/n#>-tI]]a$A(7h@Kȥ 7%tHC׎2Ak/dIܙ2+sq"" 62>gBPwp4])RļY_qvH/3DƆR$[Lx!^ U:*4vʬ^3A4 >.Z!y?I$JFrQx mPف;QLٮ^̚:իv]MI//=SM_U{նgrGxSZn:a pSRz<-IɊVV&xEsG&;&}4t&iKBmiyZ!kj/2?5X"SP.+SP#0%eW_Hj*3?Z0T&E5t[J;H |jLEyKRݜH bV޸:z Q{1}3>PC]ژSI|A]gs7P DPgno"?]e-X]S5PkOZy*hMU9 l<^@*[f%CHL7hs )1џdSa2-_ $ZuaA*S$6@jN,tʝ &x?OgBUnMRoAcⷓzN:94%]89_@Z[0*:O t?MOغc@ziRf.:-9x(Lr|cLTr,O6R rqU.IT` $1 fZ )IXOzI̴a\atexP}w<^`k[B+ +:ғg`,b1Bca6c:3 Yv0 fY,)CΆNQXByp@~B,F 3cܶ< hy:%IVfj0"Db-R}ݤWg{پ|uigg: ..Y]obK-<,޵xvkz.qa͛3&gd]PA׆Ö́&g`f7!Hh+jSf`ƴY'lgR];'0`rOYg֦f,v-yj=Q-4ne Z檝Ei6y"JU!N'z|o!o8"/&8hJP+iaԺunE.wZIJ|Qʗ1TV#LʝF TNҷ\ҪFT]a@Cl$ٿMN}L" %t ! 9遶:-3F9#2MsfWȸ6&6qKT\R (!^g𦃼2o;nG.tE )!3r6HXWVI?q!"F !dZZKh;!=AK~EN! 2H70ۙ$&ԍpޘRw6BH@'tZ^S jkHT~yw[dݢ*vT&WEaUX6 QL4H?Z4'b%<\EpPpN؞+}Z3;9^+5^sc iMa:!M}Z[:6QHv~0 ܧ1()R+͑8Hܩ==C~P/c-.ae W! )if.l":#=NPC1慃{eY/wfs/:u'vKovғ}l bT,\BZ°.hH'u[Yܑ.a)yޠԑ,҅CT}D5ô_0*F_FMZ Ҵ=EQƒBg)sa=yFs4H,Y9 ÂTL%/6"YchЗ.M AdPTyd꺃,TW#hu뙲CShfM@;-n6˶n\f@7+:PbntKH여g=L?DGy7"opsʔ@LFʹ%e%_o{it_XC[Zr3q]oy$&E,)[}4U( 5̂&LuVk*\_VG 4hEd'&=MT"pS9voPXY&q8#(RhѦ#Wh%\_Ҩ8\Oc< 7h3:놿uE tA:5 Q@$(LB6KIҬZyҠh&9652]L_$:i^؂L&J_+ׄDSl'x0jq[VWR7IxEj\tqBZZԺtMVƩMDstArMʉ:, R9DYI2p&IKa[RN ,p7eY,Q ;Ѧ64Ml#/G';j0N.cee!9j^# h^MKi2Eɥ$3~]R7~ŊQuph 3p.r$tuT7wXdG.Nl( 3.JBQPE B `&kR@9<5T-<rbutiN1A$evwoT]"D=Q S5RVsڊO[j GMm)?V):UhTE#J䬔MV4YkmӰn3Gةi$ڹaT| e; @ M6LpCMX3iݤbbh=zO.Hx W&q;h &lG`<8X @($e]6"v&v$HA-:l5gKr$ +g.zv2Sv P(Y3=y)mP 1ę^gd e~fsp t+jj$D>$}|ظ _WN$]`;5Zp[|@*̇uEv(cD`hYEÊՎ!Đm%rPȂ&Mmx6UF1|*LKh3? T|kB. .Ti池ց簣l Nܞi?zY={*k=n(3&|M(\̲TD;Esg,%ٳD|G@#Tѫd[K+_W$LZoTtGIxM­o3g)CSZ YaƑʐ475D2!athF!V{鳠= hӁd?7c m.HxVW}>GlfJ{B,&s*`_o`7q^C.VK 7#{@VLG0|Q)a<2PiXXĭG}й?}2yGH VH~iL$ ~LuРCYUyݖL bd*UnM)a_M nBʇ\1A8~E$!Wq PG 2Ҫm) A' vKJt(VXd~|\vG2 M@K +'1kPֶHtb"? ;r65ARMeWT oڸG/!14nBDIiNꊄ6ۡl=%We+ǹr{~M(p H*FmZoR9F,&yVľQ&}7deӻ~"Tb~bKQ} 9Uq)VBjHdHTu0~Cͦ[8&w =F5uPt-*2RWtBa4Y.7UY]HN1 HpB9$% IG韃{ gKT1s\@Jas iI q "3Şg[g,)V7Ny"{Q!֭,.H =99=h*]5e);GKoxpW^%dlᄂ? 5CV[QP\-"giOW7c^}cLM+C' LIgRPnRQۑy5RC䜥(cFJ=G^ܤ+΃"iQGASY{H.zw:NH 'v"w\1O8FI̫(w`q}xqnBLA\1H /s5&Z(?6Vic*#%Y$ u#G]^ƣ"L} >OOw/݂rwߟ^-ww$aq 7rT=+0`C)Mݕ|j_Kr@n% >P_XO)*!bhd{^0X}i˲Q䲚_N:pCKΣ J%]9- vC}~V_Nc]EIΆ&%Qvx*/{ZDS,·q=.ήqJS%}]k-U"]5Jt8kv-5ʾX|a]VƺU]tY%۫[JWel:l*^uXU/dsq9_VڽUzY%۫U]ջWr~Rw]wh=;nݖ{yni/8.>_~}Ӵz RQv̔p|L%n7 FA@ۿ=)ܷ`~Wo>{Ow.nY~x㇗xO~|psLOm͠ \T_޽ ߾~yvW81ˏ x&Qp??=~{,O#PP5ϯ1 %HAbۼ18Z?Уb'~|~cj^~݊_?eNj,m?Y-pŽY+_~EKJ\_B?`??/.vg?]J,T7w|gy?7]ZmԯU7M_dr?|&DwZKЂy%v/~>__$U͋/3i\ؿrMr~xDZpv]l;I[Z+>,}unO<>aZ|ON.g?~wm@f5?Hu=~?m6~>KOrX1Gj{.߼v~ZC=Ou~y;4I;?Hfճ[u}*3ԕ1i|} t#Is|_@ǘo䟽k˧=_}z߬f"8CԪZendstream endobj 277 0 obj << /Filter /FlateDecode /Length 162 >> stream x]O10 UB,tahU@p' aKtp'w'e?\v #z|QDZ`ɱj01Y!O dgҔUZF'R]km'͟tF{8+Pj?%Λkĩ4-Mr{&SA|4S;endstream endobj 278 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 328 >> stream xcd`ab`ddI+14 JM/I,ɨf!CO&nnw }/=[1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5: E4$83/='UؐQ ,Ə ktstW4ty5{w7m^=y]߂ީL?4@侩=9pvZ4\XBy8y7ΞO9;g'.lendstream endobj 279 0 obj << /Filter /FlateDecode /Length 4834 >> stream x[[uįN:[WAX6` qH)-hD-q8/9}IJ^~]+__uW]^/~}?+ߴ bq*N !\_NBՋzUu6J݆rյ 3I^x=iv)]g6xӼ쀣}h>,onnko֏ |بn7!r:pm?p M.E3jwq{ols+澧uyf#fxǛ4IiX֗b~Ymh5w^˕P/_4aH0^0ydzv78RÆ"D(i.WZy 9Zb+H?0ݓۨK0Q:) #67Mj6@D␕0] {r5.TGjp;`'n1G Ј4,:qsj88% :cH7m:ܛrKU[ W-ׂ%B) dδ 3s:k]aϵ ]Ժz2l] e9)u.X@HpRZ%'Y0Zq~H%gg=@B)؃Plӿ#ZbKF3V*bFpf= p19])hd0 u@0SF?,Hx1I<|]Q+ W[NP`d?](ն~#|Lt<د4'zf&%‰QӰN 00d]l6CFA(s|\;4p7W3@&`uB';k?;Ks`X;s%f`+JrP &i.rQbOχ N`QXB|,ˮ1ς(gv"9K؊ng1ws̡UYmB뵸.MqMK9s4QjMԲrʬ5$E1:}%@3= t1{H`R%5FmZnaFL{C>S^ 2e 3öl X W, hI ‹E5wɶJƉ= 6\ #23w[@c4aR_6D|j\v'vBX|;84KbШf)87G71sR0sNԽQ@ecҜ)F)hቷoe=UZ tAs9'4tat:K , vfWMuU~:0,Ndp&FߔQRoPi\X MQ=d[Q:/"'tVXY0bf`EҙFW~cg8%+u\*d'@cO$ sӷG "SX{ʵC X&hAYL8FE{t:/ðM9{m^(а&I"Jq HWiaw}nL?/=Iڐo>t*A1Uݥ&p(lYh$aMWs IGZr ?K5A8,J=l 8(OQ{ulRrgҹݕTbs#Ф4tLL@ʹ'NX,_n.,H$5tx!hr'Gk:ϸW#$!2SAk%f NTM9qKJ934ƁϠ*_DH `ꗅ|zcLAEC#G1+mU : O~Q(>D@ ,`QQ 76 '] W`}sXz\/ʝ=R{*ai!`/Ḧ́VH}Xuڕ}XRJ%1q;*whNʗTDSFT0MZIfhd)e&{)cw2lCJ̘ey䧩P]DY]c*y|XyO[/4*B0UF+|_8x%|ivh;j)*/Y˘g>mX.-bŵ׼SySKmfC%Vɻ0w5x TMuJO{YLrǜ@og)6x>#Ra2+( q^"_J bJ.F sh:'i gYxIg>BW;|eCX3s։Pvi'׮f3bVJgè8ܗxuRtp iM*JЛ,CSZ\++-d0k5+ޑԂT7漿:B/x[F4F 溅5Rs6𦙺tgtZ T7Dzv Qb.tE + >y\5 #E+QL|UچWmCW6P{]Yp^Y U+v(VM c y. V7j ttHaJ{)*͇}eY짎Ib"Af6Q-\tnTF7ePxcތ!:˻fx zߓc*ﶃ @'IpM]rl2v'!~KK YY7&ͱF_޾}k. v ['YqqK<^D WmzGIQ`X?‚\ SCWxڨ=Kqi3+#vcfh}؞җ\Rj9׼lk/#Vsɀ)~>gw&1,Y{})'_笆ps@l󅹗fۜȳirInW`C5>تB>2HŽMM=IO)F`RλqDn0T@/ٳ(V qg[""t$`OX*n+ۑ`ҷ-y7D2JR<` ڬ+@(5ߞ4sxS6ЅV:QRsq<9]M:_Nvg'ѐ"5$h'h̦B9T7 ]~Uoa*2㟦{j8dkF-cW|\ ٹ8UQ~s?=))|:/O| ^HQRJUҺ˸LJ˗p.Ou)}9)=!ƢhqŢ+DSf_% Uo'/54- \(_YUurKjfO5Q -@s@*1(%hj%-z)ˆY! *d2plT?\_'h0endstream endobj 280 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 283 >> stream xcd`ab`dd M34 JM/I,f!Cܬ<<,7 }_1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C50\``````(a`bdd?3qG߷0~բxy؜u̙[r| 87mBU\XBBy8yL;ódKމ}}}&201g>endstream endobj 281 0 obj << /Filter /FlateDecode /Length 2525 >> stream xYK*Œ:"y$Qgmr-%"p%]fpU{Xb0ӏigx?ȗخ.ϛ(L/7;L90qv5q jg9J*n&ZgZћ} +d8f)d&Rv]y[&Q ưc2ӊ 5B;,,`9G69w #yq^]Z(rF )XA7s#w+ #Xj8N<"%Gh%02\gTӌHN9 pBFuSޗpyK@A%Pz{mrVN()=s{DϺ.m{!u mB#cW!1Iۛ~n2>XEoy;mNQ^&H{_NT}ZO\A24„%x4[{x 7.{棨O;c֟΀=l:4ɮ 2 ($EJ;!PʐCW"ʄRUANX:z@x,3"Gc=o~HL<.q# "!Ee>l,o~ l"8WÛjk8ͮ4![pYn?f;Cs5!*.ݏr 8:bB} DP[v/j/ܝv@ 6O^A4n횄LDn>@}5XoH,w +mq4=fpB'K*M'Qn0 vfo,ٌʈp[ ) ͩIL4 wPF4-ip)1"&99M`νEQ2f-w/9g3Jy"1'LFLg~"/UL<)P#m6 >ngjNTV |}\U_G$q2`GuCq&VƁ,-dendstream endobj 282 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1444 >> stream xTmLSWmJ{Y@&n2Dd(DR[J .0*i{ʥ ш  %ƪc.n3FLpdSn[ -YqnyyU0BPNNI7rKsKV *\4/LOŠq *!F _z{@>-x*\5WK#9i@)^ QM%EpkVN*U #[fq:T By6(//> stream x]&7rx߿B  {#,± y6,q_P&vH%_d9Ӝ4 'D&> ǧ9=yy];ק{_|6=RW߾)T˫˔~Oo}tOo>~ׯ}ïzwS߼5"?F_wꯇO_ͫqסoX:O ~qTLMyQl~˻'Wow/~nC߼?߾}wowǯ}>~ ݏǗ߼}E |߽qZĿ7Mf~I?~Oex𻗗߿Fua}_oS %Wmd6[z{__|n e͂3= /?vD?_WVӗ#ߍ<}m&y=_}]?Y?ׯ9=0 ~2+q>U~Ndzp?>S>|7o~ikweWZ?\ᇷ  :hrޛ)>|5ʜe86B}l9vYPJVw~d~L߾]cag/VsRMjZUװ!i|jG%cK;j|O}ZR{z#:O8i<z*}8?ZjKKtY*OUH=eh[k7w~(83nc/3Ff|ߏQ+T!Zw^7hzM|߷g/Sk/`r7q _~?'݇w6}ϟs U֘~Oh>Z\)g{Os$bPňV[zK^^u]c]uOsuA1לG'(7_ig5]Xd z+ 1 l k*?Tj#9~{+V^߿vLO[SS,zGE޶=p̘.~r7 E<~9~'3KCSrĢl$_hp~~7Z/Cۗwo~aO0vDVtuә3=]w+ezI+ߟ>M=˰FP˫t0?_@Sx%zw^s}i!g|ne"g:S rV|39T]9lE~G+Ҷ=kt3}F6Rt. Fݛd~35‹}T*I&S{y 8yEMls:W)p6)XH-Aj8gp(e)RӣnNk!3lׂ3ff8E3FT8E;NLB6lxS+GrZ8Ek`oO/ۆ yqj#*Q(ck㷶$D1IL`|kkAIȐ~Aas[dG3F6Be4-RQ~T:1`qxlf䩯]heq@Gу3q)op JqT# ږݢw=!PHFքtiu1GBcFDH; >bb<^Ȳ9MGoAVF5Vc8#GJ^2w tgQ<=Ԏ(4+[pUdIУЈWT'`0n4P w1kF2wR6cXs4CM9[eyZuA/qp u31rsR#,*B1BϽ6|ȤaS &Ӟ|uz&{!r_爊R#,VM!CM r'ר Z{ =#0V֦YJsjpJzBbSRn!8=ĊG`z_ |*ZrWM1x'F[;=IE"}NwX:ղ Đt19]z4n*Ye˱rh]s=pa_B$͕}̨%ae_byԖT,ŹsUNƓc(fU*]U*JB*UC*EV3^7ի}M?#?#?#gDψψψOwY7P#6l'v0jpD 96O@ t@ֻӆ38=>b)UCX1ʀ,@>m(@x& +F +%}Z!X%}t`/J4XB> XI⯌)U"}_9O`,LW+ MN諺Wv;|=y_g#:;|_g:{ gsaL}aJ|KUXB+N5hba0 1Wџ\ޚWvs>\ 8WqMyu[iZPk jU#ԪGUݏHzV>A}Zg#:;Vu>"{BZbPx!uZ"U&`i \A˶f YEZ'jVq>1V'Ү]Mp]i  xHت$RU\*'* "RB`o7aU=7 V+\PzpU@V]삄Ug$: aV0`U@ꁂUϺ=MXoH{LkQ%YD5)mԽL@U*Oy 1Y&? M9(5}]L%+,=jbdJυ9sDDy"uHTh8*z݄Q0T:auP鄡 CU>Gu9BB].].0ԥC=qPg#:; Tu:AjnAwA%)U=BO'`O``܏; C/NŸg r48SgpSt6VA 5e'j8AS4a2 K? N]PxRAꃄKg$\:;! NHtBDKg'$Z:;!>Ht68RvA|aJ1a@i9 }=zI`L4CI$Dʮ2!!F5!R1ʾ4),iVx(:G%obbH[ UsFܕ~M씖H#&g_:85ZoUӢAa%ı nXE^͋7bccN3W,X `\x HG^ -XY՞SP{A׺jFNߘW.+ͬ ?qO`q^65JYA^ϲw{IS5<9P]2I|ne<-T\Wh.*5 ԰;AϚGF 1E[ԑZ0xMsDXM /ANa:F Jnhs9 3YN39%Vbl1czVFx r\n~LP|ngt2qj`B}-l~v;;MD{^1LKA#n%d%4~9C}ה/+g/ KREH¶ߋ^x{Z*Qv$AG,qϘ?b83=*-{r¦ϲnnkXS=F1qX6Ga{9> LJc5:8|x IXdeЈ?SVJ+9 jem|> TnA TE} ݫtV XI tqV@6,W3 I|oY0ISwN!9{)⨜?[m7D?bt|'dBN[rEbxVӢ@ȸ p*b6H&B5/_dg*|y#(u5*%8i7 HHhؼg F+CqX*xo&fp'hJcUι# ˝ݺDog[g<H(KVs0 Ӗec͙PR7nx>i.q0Lw6{ؾ[]D$Zh581`{RGЈqVC(aeDIS(invxƜk/> !eQv:R=:ͱH{i4XY=Wl3mL݇pK\a/+#^Zk5{uII{\"!AUȀ#T/UEЈoV ɦXgqgdЮCRnmmnu'B-2OX|yi>}Y7-^zds9b98J) XREo^h"l>Яrt4:#jmY 9lOeSCV/k7S>QDFCӧ0$Nh -Ƞ[P@YF3IV/Y>c-Ę, :M[N;m#@uF# )A# zV]NzFFe7a7Tyv?WPv}-0p~s'TO vwYNlw'[PXRW-4 6/b0ꞈeD,מAlKDLD1`'0XLDA IOO1^38⸃9AiҖCqњIS)!P|nFĘͽQkHh̀?4B4!_g!Š]Ǟڽ?=+{*־hyT*g4B=7/rm?ġ0:39~uxih DoK/_lбY<*-645LΓϽR}Τgܥ b7Ĉ(۫(c~4zT=„D`_i뾬m`6c&H'R Dz&2l.KA{[p[*%5~й< ԔaiZ0F74(㠋f71v30{MLdW{6d:-yFbIChe8MT Gl 8l}cy']:FoQ4#&U̐4o=KɉUo.K]U+ⱙ vDzjrbQ$ X4 dd#^5*lto/og6AxFFq"@AǽFذDy:VG>FON]b>F\k?*߫|x<*=L JJhs|@G-Z]>x-YE P;]FHG zVK>rN9+#*Q@4:'k }:N@ws8:WhPwӵK\-Zs8i3\M+$qsci$Ya~ja @-%q@%@z878}ux|1w'YXV_q,vDc3i<6DS^D(7qqbA5`P ^(Sv֓k鑊dd߫f_[؈G̃NӔD{^b'(5T?wk9Wi VH" :㑵9Ss7ƶm S6) }b8Ǽ i|Ӭ·*((A`U|+b_T[߭YGm%<)O&'ǡMN:' v/Z3R+Fq+\RA;J=%( 5<#*~AKe(HM/+'͎'8vG :xjķҐKU85.Q|wq&Eq8k\ZķNǧ)Ў#L( P/ XCЈ ^еlggqn%[`×ʃvCݷO/ѓ4:F6/5k0c{,ܲSםZS@=]j*N:*vT`P祆1 Sk؝g5ƕ䧈,3F"kat||nj)*tTɾ Rlԟ꙰ v/ZŽɒb}`19aRLШJ_QӞDh5l^еC9k>u]5jlg^בɾqA4W`' Xe%h%5~90ҿ|Y8xhیq^NP5BEi}89ĿRC ZMt-G088JOxWng\7>3ȈSurKM"=9Ӟ خv훽;H[h-+(!+aI0&'@ {ykAZ6~1ṲL?<0yA wXH n@ @yfGU5(Mqr.P:hLLp,A ?V3OS.1[o ON Xu#P{A׊ӵVX*c^ٹi(8Dd T^ JHhؼgH*h6[CЯ0ΐ3[ֈdŬmO+F ]gw3fɩ!a3hBA =ši \{>^еb 壎T>ݖb *f>%lq~O-^VFl+U}:Z}lL46& 9RGB{d$`$5l^гz/+5Vv`X;sf+-ǪNǠf/ `Z}_-4 j;!cQ0+ïLcA0q~eei;Uְ[Ӵk.&zh%d$4l^3|;#FlV׀Lu~[&N N j L\B>}_c5bb6&a6&#ocɈ?A4qF|@Ø(l;~mLGI+`mPPH>&n^g\yk2fA+bXt̀zN+3 4690% xRzP{AתEw{]"z&>M|`r)`a@FPBF Bɮ&:˷V6u94AUib<+&H&RF10AF>頡hChd#j##MMTOFV``20ȹNҺBSi;rhht 9ybOETUɌFHFR=ˈ:8"r֥ F'+B]4(>&NtWFƢ6>1 6xB*2 yyq+tV@{}7k M!>r!TTp*]z&.Q/4d&"j\:lF+$A+aՇqQ kqÞnpѸXm\mEs\Zq"MLUC2\yOZ_6z[f2\ZH$d|_e1z3^6> $h 'I+{PF(ekWp%99qƱpYy/Pz8Es8w\׾i C#w(\_9h^9 7\K^o LZw*9Xp&.w] P{A׺DZ$?e}d]=kSK_QHCTG[A pPڞGbrX8M֮+,ǥSSM18 ګ4?9W .80FGWHp旕GJvIO: [hmSi?M v᎝gL (sZ#79q7mEo#m&GbJ$?vj ux rnۈ55$?t֑pBv?\MgC)s8GO-&lI>.rmjcT^8~P[3qv+(!+az9 :8ta/K -5{L1xt D1 Ï( .>./&H&Rm"Qmi>{;yF?H~M"q{IKm;/pgA#eP{A׺ egt/R#+Sb4y/HGVBn w:F Jnhsbb9r;1[WH>I `/;F~j;f Nc?d]_ ahGtqancw&]ӀsCGQ58\P@B2 /ːɉE7n]eyGHsp|15"ceȴBv?\b BXո\QUA s'xrn}*hQCӴI( `оI1q|\+1hk?!q'@ D{VB/5UGsYh#l^еG35|w{Qf0fe}Yh1(ζroc>k.@t K f U s~մ2h/ټl:օ>t4"MzE $A aun*th^&ڊ iEj+=+X &xOxP[,4lmO~i(~Aڞb:$pi@}o~1{KC]o-5Ґܺ4diӐHx[! ŠUiOC]=ݪ[h4uKCV0 i΅qq?ILU㜌ґͶfaҘ,+sVwI\ zVQk"[dw$Uō+0il2ťQK2r1\ ڕ\˳np,gK&H"m@ʞLj[.;앋)KAvj\$H4U\I.Zs|ݼmzg:R D32Y[7*g4B0RV/YVYV.:p|fExv^ϛ\t/:v+,&PB&~u 1"ĻЙ.v~] tf] ؅Pc42t~bU ǷGy8Tc6ĕz O?5i$h%4~йb N5׮K%*[2^mOFLF1K(Tc3iҵɸg w4hA@)я3j uX q ~4{NL+(!ad'^KZ ǵvSkPg{ɉגRזB/6e$h54^еg Ls~A^DdIq8ZxJCDZ~}*{/ cH#8h3xiH#O6hW'N u֡WB;4@AHKb<_m).'`RG^{F;n0bNχUqC7h3 )qGQKOpp!vF z#;Y9 h;fu툴F +@QCϥ!hmm f)Vľ1gt5.­͟ hKqҮ No )Ti/oӧ1r6n 9h7P$c4,q 3K!Y,YA ZI p 9) TDe(@ C&HYxI` 'D׬sDcqz :9N ~UQn>|JTְWWM[iUuCb#L+q2"}[ıNY|sŠ^VNw;Bkml)PcP 'Y Ne7L(!`uDoY&' %Po̪ws?f(.oY&'^H^A*A"[J]4"J EW"ylU?Ullfa}* ؽe, ǚ5ea8vo;UgUY^+<Y/^[9,33oĬ3S~Tpo|">zoڜ%E㠋]"-YT@YXc_0Q~>|p,#Y>.X NB{$90@VVƝ\bk?:3Թs Ѕf纷3;vV1; zDyF^ng]H<* U̐E&2bkQ1{zn+u'xFc}WpI\Jݪ(:D D}j~y,NZ^AV|T=e}`9I\R.C)~tnJ Erj,cye"e~O^qd5 syZpU5 Z^qd.iY\ JJhsK{'ݾ+L|XEKE u}lIEs.OR> V/CXӃ~ ŠOu 8k m:W>Rfcu e"? kWgʬqyiWJ̀ڮV.%kMmr+`iCh8g48ǻcՈnsO՗ӯh(.'A(́ʵYKE~:E ˸Яٍ, $2 Hk8.9r F(ؽkLd +Qm>m &^6IU^F#$A#6/YyŠgWaH̜ [u4,'T/>$nOH~|yEyѷ11[bЭBIHjXg7"qcr[z`` ƍDy&DsRAUh`&k]CbW]N>I<4$zqY?9.J\U*|Nb۶zqZVvz>ۙgy8s]Ջ+N쌗8*fNQ|w6ON/֍L,xMy& O8/ <:^VPVR; ֻ4&2n4iWaZ].q~/H1{tpb/Υ- Z F-roܸ->rZsGO5ҋDKq^YġT$4 v!ިf}5kf?g8KMqYEЈm v{l99Ύpvnj;%'4:9پÜץ '5^ hߝgWe)ļK{ly1k/ġd][`ruJU:/z<9~kpřƪ4B 6/Zvv[_V Hm-d4WySb<- HIݫҵ'A_a$da(]_=|h8qd_k\_ h3p)E5أ]_Qv+(!+aε+.ekqz_@Rƣ/[.JE>8хkqa T_i s[hb}c50eĽqàXv#MK¾*dwva0b.VY+A{O D3|q \kx1Q}p[wHܣ,$_I!V1i$hchx\/=`˵5?O] q㶶lpiI2(W!0U74L._\u"0/ ؅d]"WZ܋ ]x@OCwZt6_N96 ÌuN֍o 9#؄Fxs]$d44NгQ eKw aĒvn)PiJG&V29ڗ bc Pn7٧q˄/ Wi`;m|^ęs$n˫46Hm`w~5xʉW'֬ɓܬ Y׾8u)Sx*yՠ  v/yb(.ɈMB־s ڋ4$KC+M F HUhmLU;/s{XvېEIl(Jc;k,,eX庹c2hեiސvuĝ_bбnsP/ HF| ׶[yGH12`nVxVs3 zExzsvz+[4}Ĩ^N/j''޳JêаrF(9zΟ C>sh[^A;?sl`s T@ F//&v;V 8cnlUw226/G>ZZm/u͐Fv϶[KЧ>X\,EXs[.ů"M_\,ah[x7c3FPi>0n>Яa~ngy(<:FZvųL }޼gTn(nqX3ޏXu!a' (H3 ib"ı=s$u zEY_Vn繮O;*M#ZA@fem D@rGk5,{κܱG{1Ds5p4gsb>gTh_<'vowjVA"aP'ZeC(mZQ^ۙF VH b{ϼQ41jGo:&B2r_1늱ׇѕ/qn+Is89ޓY\1 I}ŸA=M mwDֻh硵e3i !b #cHo=2y}ə\=8)!ݠ@&ִHiV  z2ة&Я0י^mMIyyк"=#Bi;4QBvd%d%4~bc䟜ܛݹ.pfd?9>nK{jи/$pirNO>бvf+LZ*+8fT. HOȁ[eEg/ *p<Gqyk{nt}^NJ/Ґ+I~/FWqW}/$Aaw:8"t]|RӒbjN&5 h%d%4~f6Z1bXqdUb&rqZ4N,U B_S2/N&y2Ή]nI9vf #^8z e1Эj? 9Yq4y-Dk}Dds']V2&ʸKW_ږ>|,OSH`cuOUF͈)AaebM)'|KA M=WLQ '.ϐ;>S7 Inhs~^V΅~%d gD~A[T@ګMijYE^6P6R\3O/+>0;M U|&O)IW } @П45ث4"C4%`%5~йُb~Y9E{#vnz РT/H4L LN :t187ڬyY9WkjKS;2!VNln*pO8wjLTEA v/Z`'űûcOAJJCH ㋒KYEЈs,"!!aG1,ZԾ#^c>&b?DC$i>&"-Ĺ'/oiY ̪`ayW%kyY LTiỦFPBFB:iDl2aV1C$D|_C"Aꖈ8Ff~-EQ* ( i"rZ#&U73u7~!ы@cјrU&eI&rR|ڑB5 i-޶-ҹmtl)#i9֕tk ZCڶGuLh$h%5l~йl9{_+Hk t ۪ؕ`wP&θ'nj=#s~\DSR)I 4uLhk{N~|=8-v:ܚ80\{IZ!k:WN,'#}Y·Cmw:WfWN ȟXKB|A  ='a='s{NVAS:fh$Ҟt<8t9YcNd) 99r\su,ε='e%+?rpI1Qs܏9Yڞ59)9)2 q~I!c zK[Z3w֎]/wd5'[Jc%аv?\Α3+Cm]~ܞjH8* ͝[ѥA@ .,}p۫|>Ӷ2laoӇWvC9zzR;aVٶ!v1޿OeOv?M"BR"gHE*)OJ}"gڝOYcOyy^ߦt?>XkiO_};e3R;zy?^Ǒҗ6tj<q᧚ʛMbTo٨_W#z QgD?dU㥥YdԜ9lXMv]mЬ}__|qz#@O_}u򟎍wrCSFZloFMѱ^crAL@G$ig۴gۍ/:R^??cA?2~Ƿx*4fz5Gy/a_L6=v\θbLSP|gql<ŷW:#ޫmqNB͑\g03Z~ql..} {m=dv^_+&+d{s;lWsr*~vs|*Iɶ!ΩQ9wj/u& (N {prKIcۛוثBf׽Th ?D!cQߣтs۾dFRc' ~aYxeKdخ>{"z~fn(t9ι&#2Q&ۼTç#̳41z\Ro M녊1 ?^8# l'y NbIjp H;.g4N Ug.?u9qǭ=ф㥰0Q*FFjyXXX˘YQDӮn2FK y ǣ`7z'i~\eʁDU`Pـጸ_~qk~13gn)UAaJ>3jc'R?gPqH;#Zg6jψzs[Qo1JlΩQ>@(E>FP/um/eF#΃7.x|aL*%Z(ei(6Xf˿^(\sB^W QŶE}g51^IHEvNIZ+ ߙgM }?6nP(c;Co$BZj۩c q [9(T؜\cG0Fd/" Ԩ#z:K$26DuϺ wd^_æ`nO[H~6`xat}AR3SPэ@[۫a9El|x́(Lѳ Rv*ZKjp'*sgcR*|{BxPdbh->O ( p5.2uFBnK;ziKݯ=Jtakx0ӓ?̩99p1Qa pv>[E coVC7#|+;igCoӷ=eT,UJ`GPy8]Wĭؔbs*h2>-6[Sۻa|ص=!'6tbLJ<3F\Pα,ddz1gBͿpv3F\PZ)%^ht3_Cړ+ 'Ω0!-2GhFB=Sh k`86`05e gsFłf?so>Z,m(cv_" ~P||ˤ6:FMhX7X3 ~,>nXo2]̯Q]eNCqCX_X k~ӱqb;DN9gϱčM#&4. 9z=Ʀ+ 0+(SX'aoM5lԏ-U#$+})W+}{kt> 83V62u+}{pw^ҷ>W,`y(Scgs|AB8?O;c="gLYO9uXÇ윂ujT%"[S%{ߖúޱP^꺐wh"/5&+8R'!2^*6gJfWdS ۃ|[s:vI3Z+F0Wf_]b ~4sXS|kK{ɅP@ٽ(Duck\1u˜V"84/ n00c_}nO,c4Nmxu]+, 1@gDё3(Z׳78K[b94~Þ_Ubk6{F Q^x9>/'˜lRvZ{ 7eyJٟ-ePSBZ0bo3Z +}[40bߣsm%f=\鄈#%-=8}̷B?k+86nE3|{9>?clpF#M˜ }{#Y0P0- f v,cgHt/B<0#$iSm+{N;8SǍYC8rᴚ.4 p CzJ65t r\ژ&R^V @Hma~?RW X5` X^@bl9Z4wY9b=ڌ| e`m?o&Xˎ9Z&ZłCވڂPM]sM׎R@U p צp-DkZy'1&%lh-'̉&LeDkm%hml!tl\!VblO def< %ƿBZ TWm= [> %&GU$b{f|Bldko M [uJ@C1/٦ް#ہَH_u8 :I#g6!lk-zV{¶P[>),-&BBm9g.m")6 j| j96Y6E?MfAm#H~m_/mp~o+l mL6c$% ik¶jˮ9Q[͉rj[IyAm&r¶|0a!l쟰-P^7AVsp3ųnS8V]B\M=i|Kw 6wm3_Lؖmo ųm-'l{Jln9a[<-6 j zAm#H@ EmgQv+j9Զ*n[}}Kn9nݼ~ŝ;OCڏi @Ir:Ď >""U9 H$[RޖAJySmy]g7i-H۞Mۮ3&m'!L^R ;ƍ6.֖A("s_GK> ClonvQq7Wi]y 3m;Xًk2i뎬#{Y["6l>R6.@lq$qGvj g2=7Ztl "akz{Uvg/q௙_]}ݐdL(SxEĩSk9evLT1_;YB|1|Ev-Q|m"_e3|γ km,?h'k#Md6]tI&l'O2_>ɄI&l'MD6} Il'K*g{H%G*a+d6= [8$J!C*]+Tld|RZ9tJjJ+S*W+TV^\tJ%kH֦O2Y>d|ZrI%kL#Md6=tH&k!MDV\m#G$kMd6tH&k!MTVd-L#K*U+d6]Z$J'O*Q+T><|yZtIiJ#G*M+dViZ:rHiJ?2MKTV,YtHfi!C2K,mzHei%K*KKTV>,|RYZ9rJei+S*KKTV^$RIZ9rJ%i铙Of>$3t%#3Cyg吙Cfz,1ӳ?fvYc&g鐙CfrYzd&g%9K-K*7K,=2spIf鑙Gfn,RY9rYU1L;frY#Φ7*;+oDv6tFfgHΦ329+gdn6F&gModr6ݑtG%gJΞH"5+TjVԬtHf˦G*/+T^V\yYzҲHeL#GfVɬRYY9rHfe?2)+TRV,Q9Y9rrHdɦG*'+dN6=9tIdJ%O*)+TRV>ItJ&e)MDR6IY9%s)MdJ6YIfe'MdVV.\RiuG*'+TNVl:$spH%dL?*!+TB|RX9Hc#K*+T>V.||2SXұrJcJ)3KT6VNtRX9%ұLǖ[c'K*+T>V.ɄJ@kA⊯Erx_~?σ]҉)6096|*FFiP[X+g^3mqvI%@f=DO60څe$Uk$_Ú]RW ##*"9<2<荫RHF0Z@7|`#Bވ -kd((G an?9f0Fڥ&,e;C9b3 d?` yyl ){ b|.=CRRC׃3%P0di`ƒb&&'3H@h"C e Te7afqO%X*G a#9v66 ((794=\lQV`{xk`T1UsF, B61E21\Wl!Ȕ TK5aW8'Z\–[^|M ЕD:d $6O[HBs8[O' Pp ;$į ¨[hDmLj(0`-{h:@1[0{?#🬚'yHaYA72uGP?r60 >RE D_֮DP`RFaUR86 3lDqR0n@HD(f01nFֿ Ul%3[p_0AabŠ{JQl ?tbIwY'&V\.x:<=$fru~bb.Xū %)$%8t=\Lo#*@~KobsxIR@K lvGLLl!6l{MI?K@xȢb,9K%\oу#! P ;ϛ̿)o#͞Dգ#գ#9@r6=-@ AI ] : ֹ#O$fP3rcLyB8_? PH Q~6atm)]s(yvou9`@8Jt5p$Be`RUg4B6xAz)|w4BaIaF$& jCPnZ {G妪rkvYjzD8OmORb? tlV(_%/];v!-5]5Zw'\?u炒>Ƽ+!#&&&dat 񡐥'4,̌.n0n(i>4,@01EkNd0ާ.?7T,1qey Tl.FoA0Ƅ8KmhLRRCK 04RǣHHvu^8. B390t BTn *myto D7[ODAkA0O~JnM=\ a#N4F4j:>>G9$#Snu(כ9hߪ3疘HRjjCI7I! J ]*wb5 E( &?cNAua2B2A~^ ʽIܵ0ym[ xA ȉ (ID%TqwpwD]NOG/y6s >(DhfuC)|˔7(s;<Lmh;&)DA)ɡAƇE&u7ĽP"[>E EC$EJPFEڹc+/>vsk$~+.g<ao9 %0 M0Еfmw`#l=춀.N:>}NL;eAJ%0($R|YtB[2JD!8HoQI2@RAGLwZl (\l]s~O~NV[Œ8`16ܒrpkY$&VxAt\IsB~|/&IL(+5 ;00 Jkj]3a& uMjA T_n!RE%b 0 DDr`Ы-% Tͯ(;a.~J -5͐bk XVjC{IA ](g̬1,*l0/N,˒L5)l~ ZE9p6rYB)DA)A=\JAV!Q $BF@ H] f!jW65{xU=B NF  !D0zZPLJ2 BA9uS y o\U1~UU(P, ϻgYȸL}!xO! k.p>f 9cSQPF0ZP;`Gax\ \\ȋEq5 0 aDr``F  $5t-ڻPfKys 3'F ")(%94= O ZF v00d(2P8ҵլxb@xf"o {{Z b Eq F5 G?S@@( FֹO~_ gҽIR D)1Q`$(@R*Q`TZ11.֎P%׎~ג38կ p( ~5օb #.?ZƽeATe-3,%5,Z=%%Xa11QM(*JPj0ZPM9`o]x}fRZcyaeq@b@m(s )H!=,:Qo5ZR}5c\=;-@H m }##.?|3HBYΒF%@0X$8 I&Œ $`еj%x FpPivGЀ{Zل|eȋTk|-vr@RCq~!d X#& : 8l!G2hH)cyт1:yJLW ONɓ]:F%xĀ0O8`MI22A3Rk`I4&Œgj(y&E1\TWUlC*I! HI]*w`NH}ʄw@rJ[VOpY9)MHKCkNrNe*QZ'MTz`֪41\ޘ0k6 ] W=7Q|Wey?V|KԵ(n3  YIzrx0Fڥ t[Oք=s33'kvI2bg9Ĺ8LmdMRrCӃMRڙ(̴^3)qNYٙ uN @ 8~|OK+?}!2aLXqʍO!k CBBBTdf7FbdJquiэ 1 S"Hc81v= -I(b* kkHZ9p&rEBH k,y/ b3M DLW Vn?eUb+Cp$XEH\'St#C RH9JIPJR,߸^ x諬$߷$L+Ia$.D$) 4-4N`}V{xٶ-iH sNL̸Ym !8eKFL] PRՈSՎu ./S GRPMw a0h#`oRBRÇc ͳ֞%&Ǭg֖;rYzfofeGlҏLԍ(+#{՝y@<+@G;8Њ ^-<.妔~Osc\60F- P|+ƾX?vAh᯻$6g2-9-'`&v ((#8t-50 źxo:ay<+k"2 D E-F2BRA{-! @㲂+eo6R`  @1PMhID@>e 1, ZnZdl_WiA0`/ $)(%9t=6BߺZ_25G~AbbO e$((54-ڈwoOJOY&nbtVpz6tK!D@kAjD^-b9neМȁ6 )L6EW%%7ϺY[-Yo⣪Y{fI0(1 ZbbE؈m$((5t-/Aab:>aHc]@&&jB'Pmu3?1XxE+z]e{ZH{8=vfZ1޷WUlf&P rc,6KLKD֚QHF0Z@alc& Ͽ瘡| _$AK  8&l"GB2?s,ԚUaPqj]kV-ʷE0@JV5dj "ǯ?T^䥮"1﷔禳VxZZ*AQ~ WUC)맧$ƕe()I~Zwad jşK+4PԂ|ꗦZےyȺ*IwǫjrwV9%&!q<64I RHJpz@9Kh;G<`9=2 ;Wzf\2RAׂ]ץN[-=hutvtߕE!V]b NP%6TGG!H k,JsuUy+LfS\#ꑃ`fɈ8Y(ERPJrhzPEYbb6&U=GQg<[{^{̈́H 0WMf T썡FFlC(C.p~ci5@acq.EmhC!H k,.xLuo]FG]H.xuc4adA{2\KK9M |ldེJp7)ZW,xMLu/ b790  Prd>1lg,R^еvηy`& $#7v](#iAnr># W;z^6Ku@8_ H RHnpz@9kD:2 gzw+%uʼn`AMSJI Q@JqhzPYV¸f.RӹF]V.r{_ ".s.@."! (t4{|&›@k|g|G H!Dصjk^hOpRYMZW˴v8i=#քDFNkBTMb|:$ngvpaq e$T"~"xE~>75פXM`~aɁmd`Дbd3aK?~>3v @0n?# EԲdfVWL[(UڑBTuF ثXSEB$1QڋXmY!2ls4c @ UPTWKȻ"1 ][TY)S0w)bl? #9dt&)MW{l>%HgxM"Öo!X0 dE\1L`َl鐔A TFkƂpzԅqkX%&|Xf\3JP:2CAԡnwnyAww}?=zMM`H69đmCݔBTa`|fd[ճIp`.1I L@ H] vxmg.Y3 J}kgXh€0ת]5p JMM 6# ~2(g$˨h|̲텃` 1urਰ7J{ccQxxMw{#RV/L-/@0* k Jք `еjuI`V:pZէeGpքFDjA TV`}Eѹ~g\ZN p 0fy,.RRHSe̷bF1"%]S1 " b0D "A Tg{̍(YHt<~d ‚cr}3e dT\f~>]0Q]E eÖȀ0K ƋC5f,{"dдj32GMvpPwIZbIraN]7H9E*`Ҙl큊\ 6ԣacښp.ʖE4 $`еjϬsa |cqn f'ɀpaVmd$Ej0ZPLJRVώ,*NmI8Mt;9pXDeW] vD5aft]bO<^vkk[[KhF 7[97cl wkw}%#.?TB?1ODBޫP8/ B790BTn0ޠ`Z;_׋j%XdYn#"MQ P0^, (&`6 "`еjͬ ȯ?-;}{ &;1"l#7B TmP_,Ļ2ؾW/I0(P OLŁz~J! Ju׃=kfF%() IIAD1C$cR%5kRb-}tCExb`Cq2Cmh!B!D@kA:11Vy^1Y(6Y'ZL
Xmhrֹg7bJu 6nUma4F D@s؋TT{xpV/)"3:uRD  `P=9x{6:w?K@,Bcb؎+0콜x<=4yAh$>()D1ڪ%&6Z%X[<˖{3 sgajA5@ ] 扵<&,;.cJDŽ sBv`/!`6cB@I](vXr:K_UkQa\3b8@NhATkԩ16K{WWG7XNZ#z"RNJ5 R3(y޽U=LC)%,h./yNQmhZBRAׂ,- Yz&.賴^8,M Xr6rr\ion1n ?'N6sv7ovQ=i-5aoD%@ bдj25. qmapk+q<{\DAX#=a"@Aׁ>(1j'J= g>ā0)'9'>>Jw w%23]0X%ÿ65rz51 Ob"?CHߨ%x$((5t-#YUFV| z,= jPDvZTiV]UwD"cg&$:V TZbǦA0S!L9062B)RC׃]>U9b\<5ΒYN݈nuBU-dH(#UkZ@-ϣMl`ZzOHyګ3jo{ ׈DDNkAQ TmP0X[4?Xr%uR\np X}a\'.F.))$%8t=%a$xzg|kb|4r!X$1Ӣ;?$e T[zЂw]п5-RgX:V?Io]k.?zb3B 2Ƕ qlTȱ] X^9V.$1:Ԇ!ɍlH#.{ۡ0ʂ}oƸ 1 D05 c `еj1&fFWc<ٍq1 1Ccak/c$th]u W>3=;n-Kž0tC\'&VbUкXB2CׂMXD!^?;7q/,9<M% e["|5 N?&0дf5uN؄$(54-ڰ`S!5qɟ%VKg(f\'E0XCjC AH] DP1Zb̺xSD>Zh HU)ވ|@hc0q19 \fł<*gM%8 Pp$?g @g]~*u0?#n2pz@.:l\DM؅3a&@7bh P͒+'}KX[`s9Eq<~9 цL99X[ 1.N5l$ˋ'K KF//ïf`~xw.RHyjY2󪳙2UMElfHIqfh@0'3!0*6dE$>e]4xw?]kvA=i](86\~&WFbT]]vJr+L sۙ4jAN@ ] v OL|`{$/з sIqf&~'4<B TAU'Qے5+Gw$/Mf'1?gLg))$48t%2lUx%EdT\KZ'ZU0 & < Hl!]2RAׂ]HUjI EV.,sA#g{2 Oao$+FMqMp00$r4EJ!b׃qȭaPb/xxֽÓI𸹉a$&V Z^$.L$1Q!p sD6ZZŹ}Yb V,1 I@kA|<Sz,A#2#]lF:).6q c& z0(lBF8Cޔflcg}f|ZyyA0.8\BmBRRCӃ ˬ LL3HayyJ:O[ἕ``V >q@PUd e$U{c0U* LgkQyݞI7M P51Qg*CU*T$`еjӬ7 'R&.<%d-i+aaAqmH)RC׃1ݥ oςrn^SCg!:Ho $dеj/MjP2!%tU*fG@T#T+2oT4IahPO7g4IKw=~D1{Z -p&rGZ`ubd3`J?5 H䠽w$h@1ae-X99pLFШQf^}%=ZXP$aKLh޺vծ9ؘ2D>.1rl9ȱ=-F&) B8  H I#nILY?˳ #- #<4LLՆN %((%8t=u$j,9Og7n&)P&) L `pjB&)!H!iM }K +&v>1g}#- {. sǎ‏!Ն>"dдj"FIavxxD8{<&P11p9PЕfoy^4F}:O87d@8U=eR5 (5UkZ@chGS|Vޚ rA ZpkKՈd ޚ8J@7M FX?@tkǏrLfQS!E?)D 4S`Z:M[S9kpk׈BNkA T,# ú8{^b&p)s؅6kKU0ԃ PHj0Z@a8.~ʝcD:ֆհ݅bOy& N'gjCgkBRTn`q#FkXf'^nZ 4ss܄AG-Q ,΁/Z@Epɥ0X(ke5ΕD.f'Zi u9p6r!D@ɠiAlJdbq$ۃ.$u셃`A& ujBB2t-]Fb--Z hcT3  l!?e TI ]^A.Fkv=Fާ[2 & \Jh"}21kAJ]BBԺ)k%aOxA0/!MQ5KH%)$ԺOc$dOQstc$( l hjl!2bصjkc~ 0؏\+^68.5w\@64`?BܯPHF0Z@gW~aGY.*w G:+ M l##?$̦1T/R-"M]{=3 NN݈d`@BQoZZӂ6~UZR >bZ:^/<(GdXSq@y*Pd TlFwFpbd_smŌ"q؟62S QPn}0K(&"ڛ+ 4uƒ]`ݻp XP6L$D0zrs;<¤%&z໬*}m0-1.wb7 ] v`Ejr+?>6s]no9av/IQh0E E$4fNYLs?sE}Lۛ8ĝw-)DAɡAE CEۇEg5`""A MERHFAm:Mc3Q9xP<+=Q(-erJD8SmSRBRCY%12~eJR$iȁ&6()(n]*p*) ҉˳yKzby>arbXD:QndJGJHj0Z@5r;Id h aqd@8U6nN7M ZzoK<줸X) 5ssU|JRP>r@-Kqq3]$u*"YZ"FZ*R@N Tj~!1>p{+6d@8PX9F! 1åwX}a'^ gP+2Ȼ€>9#:ȘOH!+, 3Û%5dВsZH[|5ZO<|[qZy\$^Q#we@&&VMV\?K@Vw=6ެ8v{ʊs@((("8t%Ø ֺwiOVZkܖ)KU%U̕DƯ ku̫+&*Ƭ,(w<$%g~[Q|32̒D9mdHHM 6}01qgeaGލ⒎V&iW-%a >qiy $fGbhNī= `H8QX؀[Ǯ>eЄ.#e^J>Qwa XcF {ej# B2Aoq,& ٬O8f+1$ԆR\PΪ QGAuy:?>||rgX~/$&>|ZD%+)???ocj7DMyp'ןO";W8Gi7O??hbkut~_?>9\ﶝ H?~??/Ϡ~q/?YWw[["ݐv 䵕y؏?O(endstream endobj 284 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 429 >> stream xcd`ab`dd74 JM/I, f!CGOVnn? ~#_PYQ`d`` $-*ˋ3R|ˁ y I9i i ! A Az莂2L<DAԿ?T߯q!g]Q]+mNKԊ*AZfyv-)Os]m I=ޜv IV3\a#!6;|Ŷer\ [qw[W}?Muݝݕ3ڗ}d nL v_!;{O|8On3(n9.|nS̟óf9wZ^OĐendstream endobj 285 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2450 >> stream x TW'$dFf@q'qVVԭ][׺[ (bC$WAH$7!A(hVG֞n+m-m_s;m={9'/w~#~sSw/Y0>#('5߷z7pTfC3'P+B{nq&6yLYw?p!~TKMϖ+ wHEFJ˕b4B[!K)&f<-MJX ߐ@t}@"n;3sr/$_8b#@$I&ibXKDO"XOl.zB@y<_ɿ&) "oR33$olM-͒@~?EV5+ *54$)} (2B3t (L6kAԙz 5 _+`]X^ 0 |SOp!r^ѧ}S dI JNL2 Ap8`E28)/ွ rnV &3tUќv? ǧEMH]^S[I[NfB.u:ϣ|jKfE~y9¢ } 1610l*ߖRɐ~p ~4{3phvYw2<9tx3v]}%A!tWrHyJ3W8o7]G<@}>9Hb,\|.npPh vh^ZNU\w_aD^ gkC?z\VOHwa'~EoZ]%Q#^[k2PU4W45Jhj/)Bt p^![VjKlXc)>2Ul3cj Hzhڧ3BgMᘟq]$ԭUcykdRI\P1]&M8-J GLd2;b®{^Lq0,U>\qD/qϨȵyRwƠ>$eŒL%4̓-Cү{%={FB ݢʚ5>eϮzQ 4~AS:IxRXyCqޅ˶).N4/z=˝}1K*%f>w*Ҡ];BC'CfCdBC*pV (}3`hY[B#QZZ֗X·"Ȃb߅7C-j jb6}FBGeC-٠҈Pؠtj|yޤţxr}F4 p8u`gOJ}P+cyPf;QTWe4%-^ted MBnL dP+?( wieⱿ)/ݞ̎=g1';G,>9S8 PW\(ryBygXjXL*z2%Ld6M>jԋ+.y0a_|F~m2ُ>v 9ys ނo!~MҎ; V:k@␏}ЅZdIYU*)67+$|oPzQ ~Ef>ʢ2ZqEQ^1o$sݏƳ?^% }R :(*1k3UJ{P0:& M2D֢yop"ڄ>hQ/W>”X\f[zcs[x*Ot幆,]GOkliX ­6 8Q+}Drg+ NSԍmk;=61vr-2w6CψKY\ۙYH|Of}nȕAZս-ެNKgoX>:#`%C?RiPeʱPͭe=@yY`n#m` U3V`E u mdoX(V&zvs &%N\i>CingWCBKΎz>ELuLw\E?g\ˇOLW?5v8m8 JK K[ڝͭy*}^F5>䜃d[;E(6h^=sʚCܧ7dQ!gSvcL)K 0Utϝ{~s ?:Lҗm|i#ŷSǔ?? _ rk~yaT;80*y[1 \ ֗Sq5μK> stream xWiT׶T$e DM:E (3(43 (2 4f@2Fc")1W{; j^zoݻQ>{}{K(c#J"m wUN1uwkqDc$)L`j|z {L Go (D'. 02'j̩SVnVVk\BZ*=XrPV(<}\=Z9mZqʍ4Oy~@Qxm@!aUn<5DC9RNfjJRv3S˩Jj:ZMfQsu5S,eNYRC Z1 72'*hi|dgJz}qdT94cЍfffoD;lŰSwI>5m [Pu_6g?KG 6:jC)[vd$𜗠bROX%Iv3+iXX)j@1#s/nup_4/r A{w,+Gkp6RmK^1Y9+dZ+%ΎS)ES+R<{3K-F֠:!il' S,pxo"Gvx$'.%yC*I]둊RL 3tX,#NF24H-Q }g'xK3=c8pFh#5;RzY@B^eTcOة?`)T7TZf.oZi[40~)%#񐕳) t*.b2ȍ3N]m1ykͻ) 3bTlG%0Y"> /oYIbq^L9$,YoMBR+8YF.-i[@ s9V/%CM2?%8L6;o2gR^g)C@"<˂PI_k TW!RNu9;"s"rH*c s픮+a X%"RzOIaT4W^nx#"2 ʄN4;+9.˖O:~C_O$ցwݞʠIA(n`$cׅL&JѵB4%0/҇sopzA 3 B4RO]ra& 7P/x h )Cb8A!Ju4|>C,īb< l SP tz dsƿZh5I4ݶїfxn& $f iHsvu~ D@Br4\dj"wi ݲ0j7Ptf(PߓS,&r6òtm#Y~Hۋ$<m)jx)9`YyFw,4% :$G麪U>En{YD巊sa! ўpCv4]->\ w3iR]QYRR #'J[s:N)Kb]zBDZ;2꽏.*㹧mvvk:,&M?ieȷU^=HKTwՖ:vg42 {.Wx9M\CU~~ |jC4]+l:&tS";kÛ{ =JA7P sVVBAqւ`!!XՍPF` R;CL2| >#]cA_D)ИXQɳEQqJ^ϵuvW=qq͕i:$ZF3zIcr''!DHOMI–9;4|v~ > BJ*+t•'Ao\Y!Ҹ97|HAEފ׹2OAjjBV++TK<сcJ&>Z |t ţi4:`Bք\6%YݐR m6^ԈFRMdO-ˢ!9!A"y+=g|;$<n{$RzݒM"':MnW&Be8v7:h;>z+h6D1lOr L[ |Y}kI.@ k4w@dJh^'H32&qRsAsW:Pv5{Ų0l|!*! eKk័ǦM!芃T Iwq\q[ؾ|xZkV| FmE\rjp<(}ŕH%L歎hC$œIh?`I.APZD3z+`aU ##%v-GNg.GryM*tuzwd NRFlػ?)$j⍍^<86fclh Ny`7laV<ڈ@C~<}*m0 "uq:(̒~̃+ܬIh{oi=Z"6WͰ%'Ŏ΍).9)_ܢ#q̄gVR넺r`0!GT`KvLlQ5`!o$}M^M2Z<D~ɒns $Iֶ1~4\9Hw wA|@eI| хêtwzHt]_tIhp!=%#Zl-p9 k线@xLNɹ/'1?$ÁDnw.1~{ɮ|Gc g wM湬;m8|=!5;xḁLgq ܻ}&d|12zIƣ_jzR,XXRdǰ#?jnEv8֒g>9Ǟ2zkhq1o!ИhF_I~ !?F٫ vr: ޏϧ{|yDtq?]@xJփz>S;=nΰ)ǭL,ۦe-K"SBW ,',uF>הF Iy!w>/ʇG]WUD6T)3S!^+ MŅn RL_)3Sj4O|)^y磛=s6QG D%8KH(u +OAVN8 67Vͬ|wc^^]t6BNə|ujٴ9m\KMBD =89W>*]7"h}wٱwfY(zc bu kLxBlXQDuUIpYd k麯8R$y瓉m+Dxor'kNjY˷+myhRHfm-Ü#-PsE'N|_2=?E6\ށk $mlG}9>[~V. {1c6qu+/m}b-Xۋr.K{xi8rz"AveR%Yq1C +frt&:im];T5$3I$mNE"]._ 6v 0CtiefiZLM5LmFa: zendstream endobj 287 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 479 >> stream xcd`ab`dd M̳ JM/I, f!CG4nn? ~)__PYQ`d`` $-*ˋ3R|ˁ y I9i i ! A Az讂KR2sK2Y~_IXHr# 'Hn*ڽ,zz销e &sO6aڄc$M6{)ǬyUurg~3{٥5]rU}US$~3^\7[`w&cڦModoohkh ((hHh.䨙Q1g}g^[UxAkWkTrgN!=cvl7Ϩ-9gƼY|e ~8?u5\׹XBy8y =,o⤾ &20Qüendstream endobj 288 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 447 >> stream xcd`ab`dd M3 JM/I, f!Ci<<,~( }=R1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5]'eg&d0000j10v1012?S ÑN?f7^g7ޞI=l?JT^E9\endstream endobj 289 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2390 >> stream xU TTuw^@@ڝPJSdf@s`x:!2|03A1]cZl۶ۮwٿ{ڋ:ngΙ}~My(Sl6@ɝ9 xHro𓃟׉Osjٔ7مi)>b2;BX W$e yijMu0MR'jS5d>YWŬ^a}\tu7EQʧٹyR4cayZOES/R1T,GDS3JYjZGͧfQ>/5ONyQt'e:]l{^{C Ŋo#s ebr@[qΟ'1*&i&hyj2kKS:fޖ`PU$@3Σ  QVesHf :8c胟xg@_J܁5ɓAQ|cp 6X>nm&ϖYW ,2z3*l5sRU4Ƭ~yR|ۻ(cMW]Ġ{…\2J 7?RB2MuA@-c`{wͦWa2Z5Ua%%wV;pjqabk Q˟b)6liZ/`:sO(AŪ%h;[Yf8Ox<TbDEyN}Eʃ 5u튂sǪF9&R?%P=އ Xmťf7uɔэ 7v{T.*p Rjޛlq`"RVU`jv/6.3UjBnj-/7umMGgi/P+FG[ڊw] %ryjJ-=*2)򆚪$% ?x_%Q'I.%1ORRVxEY# X\3ң ^9;+}= ˯|Uy !KJfQOo*59cxH{[BUTN֊ dB:hҸfʬ&K]F=Sf%QsdAb/qb. cI#5hAhKt=c$=ZPI;KeMzGݷs9M:G$яrVݚ9q; XRR>i4m֢ή':z׮P3q֧̫3R 6B#~{y.RI>DWr%Oen7O ̈w{s ;U6bk6&'ص1 D kjg؜Cgg~ݕ+ܥj2(,,Oup3BpztBr%> 烸l_9wOEJ>ߙDV ps/{ZWYV)P.\:Z7xmoհ9UQ xg H="uߍ5R9k*D9Í39s޷ފt 'upr1޼̼̎ގ{=4}{λYs~U"Hџ#%xeuJ=<ȫ'-fDɮ.6ߜ㗤\ NTKWF>Ћx7pT֚E:߲4o!_rI6 "ZVX*EE^(ƀ%/-6,2,"J0=u >@rw~jy|Mι㦧b#>2+/Ym!VUZLqC탦<7ҤR6{<룋7ޤh`CɬػU' ꍇ5UfW&P Ů]{X;2Q\dǖ%mb~̪iS>|ym~ϷZ8}Y_Jaw8k7Zkendstream endobj 290 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 360 >> stream xcd`ab`ddd v541H3a!#kc7s7ˊﷄ ~ Ș_Z_PYQ`hii`d``ZXX('gT*hdX뗗%i(gd(((%*@\KsR=Yt^:^cS]}S͚=gnMwulݕUsgkPW]U9{ulsguϝS>yoݢݳ6T]]񧗽tJ%of)sv+q웹6sq\7yendstream endobj 291 0 obj << /Filter /FlateDecode /Length 1654 >> stream xXs4#3;E[bW%YPJ,e.g-'nXlo'!9q }O5w_z׊دg_ϷG/H$*T6[,dMHJ*1!d|-WfbCcbqȉXVmB@Pae yH49Q[*"W&2Ą??$d(ZϘo(@dE\]Kmbe, -J^b`T1j sлr(;0|PNXw6phW"LPWGu7z9ʫNah%B °@i%dY88*)Gd%U: 0S^V!S ~@h f"I;b%W>8#Pt:<>à_Qsۄւ .0SO$l$CG$^ 9)zu2ߏ塮t՝o \(ˁ,=E[yQt h9u#'I[WI;ݔ$ Jy}8s u5} G$M/HMy,^ul1 w{ЏOSw n3Z!l,DHя;H.X6ƻ錈@t{EΦn:uzdfNujzg>r0Ke ϩ uM&7?'#$X8q*_ׅ@M.[u ?_SA^&EAE0}ۅa9m{twDzݍ)84 OtU#֚Wu[$=(8Ww0vdIety 7M<nψ;fn_t' S%b:m%MmRu0#M!4QIy(tNg6AKCVke605B'XIF0CPg)w}]`GB[@xW}~ussæĜ~jrle4wNT ^t&K$Ooa1Y4F{=lOWMnVA۵^^kv MꚺX4t*2Nj=\LJ-륙%$z +&t?)Y]gо|iXyft[-37,yu-42fvst٥q\׷3VCPic@(@&Mj#38*9BA%39 56P%BccH0Y,gQ`0|drW]q(!64S$35b5QG3o% 5Uμ^Tcu4RaY\?X3ed-%2#gl(csXTC5cPaHw %!^K"yT{?YL&teԡSAEnͳ(xP" %iE뾔 b0IGLIX^inWg.8*7}1`͕0`ǧ$@蓇:~G{nqs'gG?GWiendstream endobj 292 0 obj << /Filter /FlateDecode /Length 3759 >> stream xZݏOqOTj\.?@qi+". IwGw>vIΒR"(kv>3?,ZW?\)u-^^_mujq}wKBl'"Ztq.Y|+G*^Y-}B0R/W:Ene0ahD$㠥!^L0.(@Gdޕze A++߳eJծ^C<4;_g3# "N5"` * nS0n{pJ9g3  #ge:uhƌuS"R\wr:1#}< 8Z@zYĠ&)-j/ѩ E.xYGHzW4A!IOca/cNfA9L8#ˑVigŘ͉S<>LXϴZ !kGqq$(_ePԘYuW!Jk BwQt6ND?e:\1XNv.cu~RȦlߴaFsQ*.DpkddwV{;D[{si3w6m{齂X?q^#|>:*tGŋ ur#\)9!7` ؙNyՙ^ mS-74 [7L7bl>o稀It }QBNBd3&z!!x*Y,70g48H=J-\օwA%,{̥ 2C!5)\l$I+2V]/f ]Xr~)<-=H A 9{  # yw xX:nTHF-dog]%CtkHɶj^=M\ќ&H/jBMuS+U/`>I#PY Zi2j"&pnOm&7 *Cq':[=ݸg,ev C{mS>D- Nף!dw 0=KqTRqYܻ &Η+@;0HAIѴKN5`k\h6vUJ ?%Ksn=﯍j?=W3u:cg90;S?9?E.A׋ꊥ}@/6Šb0a<ύ9,L]D:Nึ<BF}`m[ܰWm!T)%HAHRgǩs$g:ܑ߂nS49Pح#օgiue9b2To/4: yʵIku(nJCO |ʵr82.ՠ>RCU>,bePKIJT]?\N &cEŠl/"v4Xm@]pUi4܀k˛!mԾ<2~ȷqa~WC}?8nlJ).\hld~%f0suUٶs%"- "W %ӆIhFf#\gj.1Tm}F彈@GO{h|5/"n ubdB;@O-qJs˕A_ܢnXծRק ҄ 5X 疯3i)+*zLTm#v--hNY z{^3૙DRj> C5ɞ15{_F-F_Ыi=&%R}>d!'_s0q'OiAa|I_RaIFeސUXUKi2HGR %8ʅlK!IxZN!!AN?]G %z][5"f{w1?E#~^ʛml_.=|~asc"LPiϷ2+Y2 ~6شqB6覧@$4q ?ަ6[ЮT^ٜ$Y4&Ty?ښԊJzyL⧲:6U:endstream endobj 293 0 obj << /Filter /FlateDecode /Length 2467 >> stream xXKrߐwsvzDI)QKQ3۷$[Y#@0]_=*2I:I_+jW'r7y9zKXI4ʉ :1Lt*d#~:J'T$M)%r:KqҐ !i*r%Ȅ֔VIR!I$\OyOR eHoܳJ$ә2 #oqJMuUy)#~s=->P%TfFփ+ ES ^]mL+*r W'R3w5 wg"mpw%)`h}!,6ipd뷃ж6o#T;(#|>cYTgVIɡ+3R7G- ug&ZЗ/L[9Yn׹0)za?âic0^aqF: _sc5G[xϯAV0^n>y1ȯMWEF -Ƀ!;2RUs*̊vG3侜=Z34C|X .7&B}^t86|vqxGwG6aWy' wfYZ7 /I6p/=Z ْWWJ d1`04^csiPׂP|Aknt45 +Q 08}]AY*D6*A" +p<*e!tE|rj n *.a59 ?- kw9#|$1KlD%Sk읠oBeX׭|eP f{ 1%Ӧ&p++̷mաXH(:FJ40rs*܁XˇUipD>evÊuj /؝Dp2vmG3M#p;b-pm0B'Zɬf @S~ќSe:0V4%^^pbjчaU-@zq*xQ ihQ+#cڈgFH"IuPstϺ~9zŚ3].Lu6ȟu 6ޒ)+E1ptphDcӑ }|EfKcHsf\cY`!a2.$?We䏃|۝o*N}֤Qi1UzæiFY(&~GG)y bȷCgԝE{7ڣAU{ՏWnz j4ON4&&ɔcx;:&7hvv7}$\ɉkp|SѴm/(B=` R eTHh_6OV RM+ᙑ7n^c,k2sNR{*Y#oKB<VRhLlˈ d2ZlpsXqA 2mg۩J v ?m1.g)7^vF7q{ǨXFLlT1|< {mgi!i)7a@ LrGۙPzue{efGkb6Cݎ:)C=>CӮEy;Ψ+S8a{>?!Xٯ"N#A$:aNzzń }YAjF!0g]ƛ&3{7n°c6i|Gjڳ|jbJ[v>?;Cy.s"KYKX'=1}{!om,Cۗ? r_<[Ͽ8RVIhܟVE~ ?*ց4F8?OzwW=_1^QOXCWIJ gKفjzUTɋ[va'r /^GA\7?Ac^xeBw6LWz},ѭ -*q1 6 -Q<N/M_6RzFenaF4ѵ.X1iSz }݊]E˸Mn7CUUq-m1  yW 2hb}&=/sy{z}; g SaWu^x3 Q4tQc[lAmAoU릩a0/%iP'Jm؁*F XTé39fTh-UttϜF_Ƿ=ԇr̖nI`Kt4>I !`4ͬ*?UM/3Z_}5G2¥R˳ K p oX۝%L^9Ex!bDj'3- ~_l7]⋲endstream endobj 294 0 obj << /Type /XRef /Length 248 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 295 /ID [<6c6c4d23f77f1c38058ffd69dfe1b9d9>] >> stream xcb&F~0 $8J+?p& -p$3mK;\ [l>yP bf  "lA$<zD ڃC`ɸld $AlyJi kXO@$d`qS.xdڮd[@Dr(H0i@$\ R N.K.Q?H 8;X-lXIIF;e?Ozy.F endstream endobj startxref 282021 %%EOF surveillance/inst/doc/monitoringCounts.pdf0000644000176200001440000130201614615167604020561 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4956 /Filter /FlateDecode /N 92 /First 784 >> stream x\YwF~o9B[&s'o$ Ip(R!!ɯ&ɄB: bkTWWuu*+t!)0; _'T %BzPBB9U#"Lgy+ ėSSXH|s$Ff٘\>,'.r]Ʈ'er>yd[,rjQ!gѧDr6]+˧œ鼙gESҘjwpnՊc;tm.ZȲ5Wњ%:fn,5EZ=T32KV;fZ~іnkbB;&V`&騞X5D-yp{0X; gDAH%MX-'QsFhI? ٸhpG,9xIRtWPDoMgT`,)!lЕFX ¥geiTjAaM ;+Dlb^q] s&D1t`"9TK{=mD'v)$sWC:܋=na}=dc};aa߲{^;vȎ+={~`o[#fռ9|0c6dx:XŪ+y`d4vBkɘ5SvBϪ ; s6a8o6eӎ삼˸:i,V]/W%\=0M5:w$=ټ:S{p4?oXs6*|Kvٱ}`ow{5~MI<#zmkǻ!z\*lp༺}L=79EdBu0:*\9j4\veK^pý~ѽo?|+d^/.,,^67\V^Ѐ{mP (157;64hVq(YI2 ؒ>^7PBU*祻JԺ]۪ר{6tO &+#MȾ}zM!MjV:T/wRgt=a eV;0BO^ke?`аտ|~7[l߮V-XJgE tw;R~rtUEEmWhoWqu_A5FL# k<M7:6?An#wɝP$^ m@RL[ı]8jӁf&2f]uoVÖ1>9\^B:bS}SqS/J3(׫{),o]dǩ̒ h5/L" S1Cd)!s!`GA iOylK>4S kM|61 °רT R̎} =\ dWq5u"m m:n_EdHmZ Xmii{=y5?NHt| F1{~y>j]low*͖s+~ Iu%~d&a]7xTA{<l0jUdW:[ r0fO)MzTM#WPs s}ů;ձ@nگab.`~>voHCtY\̿d蝺NV9n>/sK/bt6fG L!%7K>Ue R.ǂ;xZO~阢d'4yq<źD6Mms(`\.eA|p-;%WiO`W%(l\ oK4'Z3/n^7+XvcO}h<4fWDURoUoV UkWrKk^bn^M#mZy;S;ݔH0G(]BtLY骅< ؈5LSXK <ֹo_} Wd<_(K0fDwV'(ǃ{ÃٔV\Dq88=jɰ= 4a0x{UXoK`o=*ڴ duܹڑ;9Jr oN)ȃ!]*m; u @[! @SI{q m6P?н6dW c0Cx`L.ގq==fBJB/Ɲ.5$7J#:[mJ 2[keq)1BE{L/g{t5-ꛏ=KL+;(1RhZIb^lJ)`F W!Br4YE`1Rtv ػR-ORX(?)HC9l^-ȦE,vq3-/pe-z Ei4-sHC_BمTdc?|Pt>=i0M@U n|*uk|_zKiJl7@R;aUCKC0 b~ L/\E4yZbFN^b& Ou*IzU,v>%kLid)I3;)@ncxz:}àc3M(E 2 .Es.c*. ?:`h1`.UrWDZ"©8_k&s&6 b]QY^~|1GcYaB i?т^E)%}g=k +`JJķ(:ʔ/+P9>MIs,F;>zl A .3`לxAX"OY[P \pWJ5ӝy=*PBR|e×_p.4`W4N3VIs?JD2eL4ץCh灞6؍MЃ =ۭam<~cU\xV ~y5{B #p?Jc_r!2,wgL1%ƊˠRpAS͛l"[y;Y> stream GPL Ghostscript 9.55.0 R, surveillance, outbreak detection, statistical process control 2024-05-03T16:06:58+02:00 2024-05-03T16:06:58+02:00 LaTeX with hyperref Monitoring Count Time Series in R: Aberration Detection in Public Health SurveillanceMaëlle Salmon, Dirk Schumacher, Michael Höhle endstream endobj 95 0 obj << /Type /ObjStm /Length 4273 /Filter /FlateDecode /N 92 /First 866 >> stream x\is_IT{X#ޤDB"ּ#׿O@ R*LOOOw8؄'%R$D yQ$%~N<ԞDxI&U~,5>9:ۑXV=!,١SzV֣Sa,|1 hm+ +-WmՈ*EsT[8\ 3R5Tm&*fC6l^U8[H57t`_"ȶyԢ*fuRK{.//~~{vCߩ<򈞮FlYʣؽn/f1OuK<ZvJYјfkMy6C} {;ԗ_:5丒%P< PE![>]ogg"_]MMLc[4CK4{B!Fؘ"t26EGΫ'L߫6>W|{:ov q$7m y;:0d٢E5LVr-/-C~k}WtaB)[r|r݇7 &%tYloZh! )$7' wbnv3^Q!mc))ǚ3̃sӚ'g?Նj6^i_xl*w6\vqӱ w^hw-SBcJF޲l O<+c ϕ8_.˳I1E,4YW|t^ENr}Wv3 ŽԍOCit62t=ڴ~6lD3}!Q}#z.^n!}[v =0@D錢)z.e1w{vc#{稯8Wfa2ax! |@٭:) -UK޼>FܦCJ!ȯ;~pxɩPT%wi!&RTM2 ,&S,hr)(7R<4eC2S9Q3D)㘛$I+#Sh'\z\6]*>Q:o-󿿮p8:}@^8{׿u]q7m8޶ҊJo߫ rG l`̦C-E*Vt)_mn|0 e*hȆ1j q 83zAM^te>*bTN:i\oAʣxob^)TeYۀ _(ݔ--d@]5z9yYml.T %aiRT(o+*ԻPr@TyQտEU2U5VJ?ZT=: Im8%xOd:hҩѾ x>+Q@}4m\9JZMx-HSIWA@ɒ$-6R:>) CPkh^JpKu|*y}@}M#*ˬqᚬǭ?UNzLn.quՇ;K\2uػe}%?k,tݚOh;w^m> ICD }r}:c tG%K5+Y:@k![{' [^n&_ dm3Sxs6TJ_Ӵil.|W&5C7Oh\JUܚ(-A|,0qrup@Ծw%8lDwWڔ8(j2=W'Ӕp-ħV0UrQ֔> ,,0-ޗ6RN?*mզ7h HiB9R]9e1Zb? 2O8J;Q;MB/+V*vk+EZ%!(N3uu; );tmA+Y5Х'-kD CzVVT70,?QywT`q#+DۉonN2¤IQQ,I/KcJ\!J*WcHoyr"Fo<QULAkjNi@HYPe,5_ӟ(e& =Q]SPw$pis[ʆn@W&+3p*Z 7a$LŖhLs ó |3%yM)#Q5g}"^ Jlrr9KN+;Rendstream endobj 188 0 obj << /Type /ObjStm /Length 3659 /Filter /FlateDecode /N 92 /First 859 >> stream x[r7}߯S)ָzxJ8RK@S#L*$;{!)Rr)nz!8nt0&eZq5…9w&x.8a(xaM4(aQX2 I`M Mj-H SXAT јvZ  Y?EhU'bD: --x-: Ol q‡u  gϕZD"8l1=zFtB\ uPH\"B (h1fÎHFNbd3HΰDH);AE5ȆEYd$";4+ ;93f1Qb@m(cXftcA:ixYgk=4ad ôFb(q }1XИ"b62>,KBƖm }BDز'Ŕkn^Mzzu5kmLmlm϶*h8m@s{OlgOajH(ī:i&~3k׶_j{j{j{ߢt-p?M:|7?~˓ѻ؃g3GgEdztVq3ѸR^W ZS_OKߌt@ڎM/B,XEŇ@JgVЍ!9cRb!D.rD**(GjpX\AZW@9w/PZ>SBK*݇~I' Qfpq}?Q:RkB}^+uNՏ'SU_GW:Skd0Q|7sL]Kue3TV]wjFj4{f4lԵnƃљiHWC3x0Ub]nb|ӯW B@ʭz;gij?^\5xBL&eNͻ0qFf\}RAsT `?S? *#GpIzD+y&$jtRL(9,ky* vJlz0(D`T&0;PVrH97˨"yPd;P8-C(٧1θ9Ѩkk5`m X[kk5P m{7o Eaݶj%a3j@7RQ2w˄ CFr_T ~.+YsTRQ-`B'd¹Hkc2rΎg8" $2Vf⫽pit#l@6!ej+^q3H6 _:=z$aQޣ8xLJ]d01'H|&$$mGHlpOǚ\-qCR/$bI_z{{w^|[^E">H8S.wőB`Vs 8XoUs>cnPRn~{߻b2xp7^)U:[!wࣚ\]npDc;{[ 1! 8b\户' DD*{N\6u`Mdn%xXxAi-y,Ǹl6V}9G|6xj[uI2z_LjD<䜤@ҫLn%]m /_Y/3ķ^0%-˲3>ԁ[A6yѸbb^(-ِl'+!$^Af'Ny P\+.]{<(0#zPlr>SϢ-gc6X^[yr @yNw1[nn$H\(7Iz~ ѰZPXX:InQ8TlFz]<Ff*a Qʮq PN^^Wl+ۋ7!`$os{7scDTo܁/ 3Lƴq3[ hEL`Fgixb#$:b[G2(ά@T$E])D1ua&%7C6bCu]߅)39c"7>}}L̺:97gx4$+sO"sPPv6 3QgL% )efoQ'da*I ;@uyu؇҉ʵ s %ӮMP+y  EjZW fG4S/ޔcW~Ũi`mLsM9`.0 ;G\Jrjn+ vGd*9y,P+109qw[1y|'nr :s7k1f*\SԒ0!u >(n_y)2 m  \9ʻOL@<mgmr& 0mW*Cg;2ւ0juE!hWv$T/Tq:@{fߠ:QPQfHkNC*BtbV?'Rg/ :&gݣ47TI'd+Hh"Bg׃;\v`Ā `5#CI-{F^`tW Қ9F'g=J#6~#a{xm9\7cR3 ӿ潠S4xػ|hf& $),+G|Ю}xo]G'ɓ z/.L" rZ`RQ7>ÿ]>|t 荐%a\.쭙:,"2.^e'OV$ç@- $5Fi7~3QǧGTQ6 l$|Bjuy <,G$;L3:x"v#lu Zʛ@6H7Ў-!0=OhSw~8lop'!f,PeRɚ#$͛^Ȗ2*uՇe} ۊJ`W!ڕ-kSl4i=Ap o|Y\w~T"ij(v#L`%o~lO9i\9Efo72BYh'X.жFyYՠ-,aPa.gGZR}%BjwjUj z#)Pq.3=5j(1]Ud8f/OL_fzj3`2xa~+?ۃ6R̊7S{RSgUgeqrGp\'Jb$W>Bc%|#=FBzendstream endobj 281 0 obj << /Type /ObjStm /Length 3476 /Filter /FlateDecode /N 92 /First 859 >> stream x[m۶_tLbN&3N=c'9NtA褫ěς %QҙhntH``wŋ JH01iO'HJ)GHAFs" r Q_ZPB9I|?TU Is mky7A@\= # ^K)" cjH%'P0’2VX:Z:a q kAXO\8 l)wM$YN(* g,49fxpG /9f Ctu_](x͢լCr6UU/YZU}ʻa(cL ylrS/Z]H<7|:0yI%W?LO E=Mof tH!2ySWw?eߔĆ\wח}ܳ?``VŜAܪZ {<2-@?Z9o_c? l΃3i_2?]+yp{Cl}+Xf{\b;}TvRoz]Li+{Z۹l*\O&3.z~69[_ts?>=;сX^W<_4 5T; ߄Յg\Na6゗ *G\06"8x1^N翷Вr"Dp sE`61QkPhֱ0=LlR`b1bC*6c#>A}NYS."T(,X"P!jO ggggg\[lg3=Lfz6ӳ\2=Lez.s>?8;_cD>r[I"gyY@WQWrȈ\ zY9/USiyɡ`-GvBxU_`By3:S9.L ֱQڲvBųyslն_s9 {!'Vxr߼ǷQYAe`ַ|Fbu8Ys.i_;P'tDXi$̈Z+/kùol'7ZP4> *P m| Jo]e'y,< ?w yLn.°; |FO8k"*xK,ekנ< PÅG6|Žd S1y>I G]ŕׂqN#ii˟ޓqJsX!%9GdT֘`7#`i3E{F ge޸/QGa Cbko!& H{F{d"gukD.:'H1Q}ya xe|LJ0v#|$">;1J64""PiSpv|P{\GJ|U'pPFBњQ& Svŗt(:OX߀Ј nݨ|8(5wP{ ۠ic (a=y| qLW럃J)LEbZTODBz{/ TvA16O=mNT`7jb)ᅪ } > stream x[]#|ϯcd0 پ;18͞|'d-:ɯOő+ZΌf8fgBNFģ&:A[Lrm5%$3od@Wy%qPO5 oHz#E+p9>߮+\KW2&3QGt}YT0:\͡ X3:5JF}A6wh,_,oMyմqJoCoco?gr:Gɯ|=}3x r⣷"UϓWӛ! n}s|=]70o-çL)No+쀸VÓ@.Y{[z#}0##c F6j#]mNNB\ ] C30 C| C\ }p.>b_c +b/b/JK(*OJ7c:81 oAÉN>ް#MoA V}7^stŒU(0 0-fTL9T[`w0%aA| L3\"~i78[9~Q!c7|8 1y- ] $uҼU{[zo3i$%k<%p6hՓfA& u R7q B%ܲ؂w0($>% VI6> (+P5 ANJz+.*W<7*b+B Ct&PY%P1":&PxkPAmzPPTx 88 ctgBDU6*cP8r#vGֽsH3RTH1_b<89A AJb tQMz ,>2sZDPL0LMf; MEp2JkP% Tp;3DI#@aK# ( t?RnS{P kB\3G,>sq3mt{}3b~x3m&g.:zrq6M_]lYKW/nfEmy!⸹dl_r:{n8E 8ty!ɋ7&>~W]M`.}bryq5|6{5g77JCߖdn0rWf xl  bAw6ensļMܨoEVY L.3[29 j8sr.P19PU毎j7`8E̦ng1Hmc0wZĹb_Yxʔ ⨩# Eט-|T%!)n|p6!PȐ`8Q|8Pʼkms'wi%I}0lb1@P"AdD{,"ER5*D3 B~_H5+:``KiΠ(+k- ˇӶxh(Qlcpn`]\AsͶQ`KP Ŕ):򡻠`!3XJ*(ﬠ˟@q@-"eǚ'ˊI7w **l0s 0Ep޼:HrC7q:T$IA@)+%.caЉz`񬜵 ~RηF(Rɜ<p]t:o/xӫ_V}ll~3\cMk:̻jZ(N&zoLO_|:Yg1z筫|Bnf*cnzV3`R'Ϻ~aWw˜MQJxz)}ȑ#ئ !a2bo&lܐk_+ȴ,d=BlEgDx(KDŽr|2:GVv)O^ec}aÇW'wܢ¿[\qjF@si; ?X # rOUC> *?~x])v}T|#c}X֍0;1Qޙ]3U[F`?^-":Зh糟~BozNt1endstream endobj 467 0 obj << /Type /ObjStm /Length 4040 /Filter /FlateDecode /N 92 /First 874 >> stream x\[s6~_tB~t&IޒnID]GHr_)[Jz<2A;72b2LTʲ#83E Yq5SW]q \bk+!BU(+n9VI-)'*1r)|JSgK$sW->.Xvٵ͛x61B4aLq,ٵ=G}<ekt zK Z T2..(1HZHB5%ϜΞ# ?J 枙p<~7\0de$G _4l1r=I=6p/{iw{I 'LvsJKʱ6&3HNCȸ6Vzapf{#TRi2=AVq|͠ gjTu,|;X&#eaM{]gn7qoS?BeBWM&xjB$,0A× ?B>nVj5Ȗf+ML^/[ Cb6&̌+=2}hM*c$'ىl'1wk癩%fmYz{*rQzKI:ԑޖ>'Ӣ#I@xT=pA,g30=*dYB_~ʥJv͟|(BwV>NvQ$qA˒t|M6܂MeDtG\CݬnֳvSLg-,uFɭf/ZAWg5B- -Eka5ӳ[5}Mx.e~%l/aaNSYBQsƉϝt] s'D`}c|a'A$[i ć@t^j kn~h#"i 8Ҍq[[*4FՁq3ȯ|E@xZbԭ:1:QG+8Ԧ/uS4 r0LTBX40ŋMDE.ZL s@!l_FKF}?d;#ĝ1닋决c|x˖GN2y 35 r`Zj@dv^)ٝvE6DZU6FW-LLm-ڴ/iW]j;  ]Gai8I_4g+lZ֖ЍBau mpTvW(XS:Cų?Ir7Bh_eQH@4qjlOq5m=sJx&Ϗ32xFJys)DM9C:yFUi\E>AU?*=L=d:4F2ף]ԴY;RnN)u8Qyn@'i\(A d%MR:,V-%\h@nLU" 5X=Fi{?-.e]r7Amƞ ?|o?xnʜ6k(JSQ֓f+ cX,Np 1O+iVՅK8byi !5Q!-DE"FXz2UaK#abd̸T PxtWWݽx]8jf :O$` =U3REQuEK—U}TBxBʆ T!_{?9AcyOP S]345E'm!g2L#$h}% 00T A;PԀtU'p9}{H=a%}J{bTq.@ <}yv%-JM> VM,Ɛ7ÜOSL_xSvFTkk`ypGcEm>N4 Dyh2sBfYq/1(?% BD:(@p쉂fCD>1" Nu$B6'I ##E42@4q &eMm(83595}uw4\U 4G,1AӔ> stream x\KsƑ>7a4ֲذ5t CrFw*&GZY_~Y"s^. AOww4; !vrWY]..oqPZ兰S{|"U? 7 묿kw 5G5^u4*{x|ߵ5?{km6Oh,m.dUV{ S876LmwS3#L/U6za_EFZ:ML,wA+YV\8Enں&fv*sl?(d8Fnle^jWU"ee}9(Qo2O5md^pe {10VU:/tQJ[U9?.A ԷUPh~@5%uA#+hP=Y-Ꝩr)Hʘ]%Ea7P䅩8y;C{4`N&|^ffifhoF,``҂ƭv3x#ms?a`SX ~1jwjay/H< UO7W,#m^9uǛn7PVg7m5WޡPKraas-U,2klRUN7C/p:7F x䱾A VUQl=R jc$ĒB*[Jg_ݣKUIGlrXp6%`J~wN<#wWlBU m)Sa -ۛa[zZ`n+/=YvֻY2©U*ĎiOe95Co mt7c+=9Ѯ$h%l l.& fӰ-!z?F;@kt g NKl% ^xhۇf'I})T`n3izeV#h"pn+ Ȇ _Hطqe XpO U3Y 70I(aeOLA@W˿\\7#} ";!B;> 4ʬ xTjɏQ:h~Yӭ/(m 7R@\$>@2f(QL]:etƦCY!G;co86S-R  ~x(45*Km೴!En\6n_Sy8c!&voK<0`Y'Z Gk rZ@j"4O yA)d"#Vv~YHxnvIc='8 M Z oPi$|XQm%>7ㄨpZ=|ˮ(M+ G7t!׆MKyj#($3#s'BH'Wt*=& `od8b̨MIDC&Ġ$Z:["IfݯLlgC[כ3%ZƎJHJnXyO^YNl)G "QKJ,pfA6~Ie6st})NuEGU [iD=asnH )rdǨ p;~Lmy9;4bpW c iz@(6/g ~zF8q…;MnZQ Ҙ)jS%$AI?dhpsE}^QJMpT*4 l]@^N$BF<"܁ n+@(2e+VRd$EXPvj:Ӄy({IȀӖ/n)kK/ ' %^:geWFFSYdf:y3pϸ|5"(ĹyLoiXwfq($vG4tmt'gpb%RM[A"<830LWЬЩ#U?~pp1x*m{ƇS.Tu30Ɋ&X6.gl8q*92!Z?:my"]Q<e}Lql`;+4Kl#2qTx4LT1.x3TQ4DOHrᾭugp+}_é(K%8{] ٳ]#:4L 9^bݍS]?,޷.RM ވ(nɻ4ƥgwZg [>Jy*r>ܛܹL-sug$?pM"4X!2r1%Z6M]s;Ўqn6I|u9xP|!lGNwgZC:ErS{&卦DP6sY|׸T=bܧ%~帝+ 8Qۘvb썿AJl/m=7~N˧h>zZsUڏT@7?č [QwWWZla_4&ycGB#Yt<) kI7Sy)~Pkzg|7AwI,f.^-[#D3hNENʽ4ץ'!onꏩaR) |eKEFUϸq\6G{> XNϮAat/*>¿g0̕LgaKU}ʅG@˭2J5%3/{T.,As%n’"ja iRRbl_U.+,+s[J?6~dTTS+ fa3m`o*611ƮxD5y p T9<͵B>T7(V3* sP,ZEK$cЕiO2o<{3|ƨCq\zGzM#tl s9BҗsUFF\Peaw\+0, ,Ɦ1CM>\g*s)}ò-1.qYegvt u> p܁ ;p} D-$.}v|:k5\=n6R-Cg,iQ@Z:Rő|+iK%QP~m dw#urcz'Ʌc)Df Oܺw"jMEZ;'J X$hɂ_s7'9iY+ CuK 2J@ڽZ ~0;Dmxo yۮ_J o:8hFHΎl5n"߉WxHUzbKN])Q(p}m8C5S\l{!r.Z_E ^ kgVˎՍԮ"]<N&Yqj'ǥ'~X&IR?II}~329c{p/Z1CE9'︺S?@+藻DԋVzdwmcF lD,}'+FƦ`9x8L̚`5hL.P9xޞ(p~g)#ڤs j|d;g)R@>gͰab))"ڮ _xZ]p,e!0p5-SWx^ZRkF/&$5b:"nU{[m \_1s I?UB˨c4;a~6ɋ1`< 0;fMCOxj|3b̢:CƆCu@8v#!;R XVy}.WNߖlMlBTtF<-Nm¤7GGE5~9T% p\@%"ü_#k%TyI> r+7"q96O >-KUD">e 8@E}At)H2lktO0\F3`q !#5/>+0nM2ʂ}|B$"65r%,?Yj0 V\<Cf>P'ߕ~z+ 441  5 u<߬-f剡H׹/ee,糆@ho7M-X_réLч:R:69jE#3 [%6A˝F񥞢^sz9^QOeAQU!]Nw'w]ƎNJ%l0WLK蹻݌ )oBUjR)ቓTv aFHDžݞ] D~*ڃ0nXͩ"!86nrӍwsUk,/6&$l0)!h_Zuxnr.w叉E/xendstream endobj 561 0 obj << /Filter /FlateDecode /Length 6123 >> stream x\KFr/1G +yZ/E g8=m8{v>3abЅzdee~]T_Yuqo_|W/}oʶjūwuѨekūBo^m+].._7UY9S-6)+䷷-Z4_vӮ+[ߪכ*Sxj5 8Sl1e2R<]/ժ~HE9QJҷ5ϱxKָ^6 j{[\Y ~|;W/OoRzSt>Ò/NBZ R V7vꢋuv6Ӗ|81$qb.i8 ~U:Ӕm ϡZCoW>u0Sw)Cķʔζ>{/.0gm3 2N ZԎy:wۉ O5Ԝط>7f̈lTqv0PBs0A K㗦xn Y6ץXv~vcJnwm+:aUxYעy QC71|pZ[ KZNe](XYx]HXƑʰUiz)?G=i~Qe;MW u HjexFԠuiRw]*[wqSة@8Z3#8}otA)XF*;;{]Ā~F>J߻0CUJ]lIX[dvő 紘 o[Wqu`gB?߾| ɆDݫg}V`qԋEg]^O_}#/%\0/WoOx- ?J&U3AP7ܭhsLdUe!"~ "IԖ4.}`l֩p22F#nl霯`R.l PuÊ{gefCXdV<؋aF UzIKTRl$h@' 4~J:S/t?*8*&pq͍^KdyW- ?9?%JSHs{O!_)J.Mjf͜x8㞲ШSJ-H3~aɀE8U~ZV$u/=LYg DN''-H{1L*a566:њQ3H(́ΌEuhʔɶ/IcMDy06 hp@hTFuCCH>l_H-SaGdиSq/l~x/e0,`$|Y- , ?!m4y)۷q `Mf١1wƣ|aȆ^eƛ,m6coLF!/a>r >R;FIaa\dv\,֮vך:.WΡeejXH@ |:Uv pI'lM[Z@icgwUF4$\N̤/A ?ӷ϶Cw9a\&{vvN;a  wI*Vxɮcw<ƚ Gv)^F]8Ə꜒[NN8/n!{*A=% (hZ_˱jPXO`IciȒh<)t{kN`VC@UA9`/h}lwSs.SǰťboLf(/"xjƻ=9@/K_x˴t\e U݁tBLϘ&.WdK4C{M fU&a o   -8|e|}cfi,}AC I0`wr5kd4ȃ;I!T[=Su{Ucd %S.O'vX;ţeibinMb 3̯23^d67^ys^`̝6cdtK}iiJmCX)29 @!@t3"CulIA=oOB4Lr $U-,,#ǐ~XeЅrѻ05#YU^f-@z{]wW t!Q2 RT{@i& mB?O4!h.PhB)p%fjOXu/a-fv?1g5u@Ӂ9okTg 8Λ CvF+9C,zSj=5=Pk\?%f4lzv!Na(6 Fbf&1L 6mI*Lp#$H .>]Gc#`93[ fx4:cNVg{94L K{لޓ/f! '$y5b()HsXS_Qqܰ1OE 8& {gvPf,A#z&3灑 fs7%ul 3\|_[D]vt+ۛc&aD9fvJ4{ԋ!ӣ>vD$SM̴.?7S%Jp8I$x,ccT'Nvl 3 6lkhVnÔO͑QO_ SwDt0snJO̤>~9M'u ~yHWFn2ˋF`r䈄3qTdH5̹t17z\X f^fQoq)˾|NB& څ.Ucn&5ZNAUw)VyW|n8sKmӒ!$; ]nd\9ܪN3qU5 ~4d:[ކq- S~[}3Hj0E2 Lf8S)OHK)Ro4j027䧗9€]:nPcmVÞy=DȕOJ5oL&; 6j| 6{e#rq3HN\\'H.)'V1lGV7Q!22l2Kx~9yI' [GtUїb6Dk6$F\4aL[S@W7ֲYO(GCs{^?Y$ǤhvA./n5(0nu);$LcNT.zt 'fܙx P){~b{0 @8Qw,sP@ywiK p ᬆ' Y_W͗nm4zPpL2Dy!a!g%XYc0ȵE`;V !(@;94( ;Lu}? .{r_U-ӫKxNomb)cHF X*K j!DL;f]EkQ0sR$,>4+< hb_bt$܆Ggk~mg%wE8hP@5^ (]zXZt/V|iyڴj}M9%ĕx_6N-m$2s4ԧyOQT5_x0Ƨ+FMP=%!J[w%&sY_nr֐/{%ů k8/jUwTtۖn$1Ok~ð~Z|0O!}Ei ؃iҜ-~3¯"##r̵Qe[2.77 M|P 2>T clEJFp" Nޥ;0jV8uR]i2%pma]B2 3}B}#Z3{+h>SƛUR+ 38Vd%o"AMz麆g9_V XNںW\g t`f+2mE@k!fiuU4X$c^ %Nr֒ -g?/qCRmbZJe[+ZYCVD䲅n'0_1dWXaȭ -&z)pAA>&5OU1^&:USz,l*8a! #ذ/qL5\seęӸvܘTH? ݥk *L7AH;uVIZ d*k ΏcSgvz2XȰ5Ox^Eg~3J ocjN 0Զ;voF~QTiF=Q-Fƕ}ۮrnGjdR`Tۅ63sՅY3_)â OS{K#Hr| 竰d\tnk\vUpMSmWBQiⱱB.%ά7GXA)J7®L\ YC`l-bףo%?aefZ;K'B~0uͷM~{jCh E;W7f%&܉Dٹ[rX'?tt߰#-Qk3|wF=sѡZ[RǑF,A5hZ݋V׼yr 3wi ĜWʆc-)/2Bp5YHYLn? .n}0endstream endobj 562 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 8652 >> stream xzXTrԜ{/QE]QH"W fP{X"jbI1@cnxx9s^k]Z{DI7J$Xi3e`/H~ҍGu)Lz2?2EkQbh_nAS'O6a;)rDeΞ;,}[.r*Prqh_K'wG/WK_W˵.,l?\lcmv?[lqߦ, \$xiȲPaN+WFl_bm[v^Oqigoaב;uܐLN~`Qlj8zA>ޥl-5ZK1:j,GmS㩍jZHM6SSEdj15ZBMRӨetj95ZAGfRYTeFJJ B)sJFYPbj5BݦhvP)KuDޔՇRQD=D= $ Nu[xdI SG;et8Ӈq.꾽c{\^ǪW}go\g/nII0;eV KAVŃ :址w.qKCt=71"Ǝ cU@̫> žh6,u$7!NAUQ EKIFÐ M$], &8AuA3vi5͐}29{MK_bqΓ⫗ Iw@WV&o/ݒq^ ,~/=M3"V~C$'uﭓGpdKrzU4kyy^0E{")0%"K6uGzXnV.x[6J Pp|C{a? pp5¼@f)5^j?4q0TPF')x6.K,BE!gH0w 2 _BRNo$1H(Gv4C6\8RgQƶ F.q%͂h(c\<n9Y7Fq~$jGȵQtrKB") b⹍V lgi; |䈑w^gD1`**h1gEKرϰm}GIq=]M&:d{R|Hgҩv_z)g Ľ?iREJHU>6ƅiT؉ v'5b *H.Kl |+5Uϣ>nAܝt;s?SSbp9sZ-h;P<~9!B*(ȿ+﵊Q"A!C{FN Pp/ f|MuQ%_g«{x*vĎh:lnܩ8[9LȗtcJ'$o)}hE߮" GgV.KQ!h*z$&fq.z\hD;0H$/7r]eEJ wUNwG($u/H_BQ(odz3z5":G><4YDO߼x̤C9OMr<.VsShC^QܐV1z0O^},ص>찬Lv}nw횐XV?(*|*?'(GӅؠ0KNJR3d(s!Hq"8kD\e,-J ̔,dn2 ]KLI15!'B,yꌥ*G.Svo'm]DZÔ29*}K|Q,X]nƵ/9M)~5ݔK 󍢢6+qm`(Zև(!91z2ΔF5I9jAT6B t|: mTewz (JsȊ)%^HX> 9OdFhR~BqCBd :Kײ:%FTެ&rz$O4*=`K P*<rh ְqcf`f/ڲԻ$"'vF^Yw$#gOTVx1'{c;T:\z!k9Ռ_~SS-hvq7D`m!)q$N ǾNDAD'+ ]L4bP7eFCv{K6Q0hkYK̮pmP5d9R^ao?$ndo?x:ml,MΈD6\9G68AY@~~fasI)Ul !gX*b [l6YMZ~Pu @_]{F2uqq; "5UBzW+VЌk3)K[hC]m3,%nxi4+Tɜe1@36ȼv;VUlnG$L~xjP,!2ʲ WدſR?:!aoL^E,s^K![Fu8T)54Rnѩ٠HF2MuɫDk}| Be,?e|w1.&=Bad{efw^nV)` ̰W(}4'`٣qmXfKˬMbdqL>,91x9=f_n&YnWMn`P.1ROА8CG+aIե'k] JLfƨOWsbZOl4?TУ㝀6oi⽅ E}}G~yS'.-G,Gq70} i "۱ ` ,&=tJk»UrO. |H̑@uYj(!2I;۫^}yKR弘f`KGd* ?_MWuɻl-2{Go_%U36g؈/Uӗ?V\Ih/;0Vo?Ik'/B,4NevWv4 juLn]4x洡N̿'N:s-2aWBkx0 7.37:nIeu:+T-vFRjOw\vk%L)pc.%n \r3S%m7cybs)%yPT?{ˋq쀶a&osWWuFQe ͊ H1C3k8( J.M1); j%i  h"8qAnAU`dk+D"{eBּFb] A rhLML#1Kǚ|QE/Q+Q|.Vg) Bb {{^tzA_>ush-[E$qDCS٭/vh46[pM㡈䭈~rȄ AZ-j>4 -Ӿ #&8*PG6hAW-R&+ʼ> :ЋVA׺RUP<ߗ5TV&b+8 #m'#\ʶ$LyJ?5fE~Svx;K $O%JU3P 9neXng 0[o>%$渢-m2].6@f2~{ZEΫ ; j$ ַ" )Ig85w(q|R4#p*C[p#%\Xs=lՆ1p%d1ejJx,[ +?H$Ow$;^JCJ*E2-k1 ˡ"9IOQe7t9h˧&3W0$,1S8OA}{7*OnEd4;_9o$;a[΄D'L`SISm."=>*쓓 gyr`kWC@%BhmDEM|LBBzh5nk$w7r\}XD_}t Gt*xJLmr;Txu`rī(ҡ/۰x güsD0~%>Q&PG~*d䃉[O\fKĉiq*atϷ0B-lŅ8QptoF)VIna+t\ ڨG-? B͎> i}ocjC,S,M^{JM) 5Q)t {(gؚ4^$=c!>Rեp '`ؚ^Nց]Z9qaStG{V9[*qu,2A?"ȋRV<98՗e=jV@䙰`JyL IHMJn кc䇕4g f#/vݰ9+lWYCt{]%Y=?|d))ln[X1j?,8+\+lMBj}p`e!mxL$$&3D RnNz-%YM)xû` pJw*dJYރ`d#fLm} 棥GꨐJ^q942k+g&zjb־y `X3F3C^ 2Wnllݑmݕ 4_qy]*~[\C}TU&<ůAumSڒPP=Y@&?Wv!tQ?'=wHϦn99<v 2|qk"촻ՅHKN:GR AIv%-"ץ8 B58TPytOnl; rlC}E {0eJCM&vxvܾ\:}@2Jr{<<ֵjnhO: Fޚ0r zr'[,_tF.DSz^"PVDTF*:9Y- 9/&K9BĔDŬu : qxo;CEΊ= %M6Gfh AQ_?=I:eŘ]mb9ٸ)lz}, ]Ъ$-˟CСG}7;妗6 D'P4SYx V.^ƱC(*NN8BgDw!)KTyѢ8Қ7ϴp AW+"t0AIKZp Aqh(O Pҧ$(P-DwZ/|{j?1+46T IeN(aL%l{/ *ᜒxTD:j"8,UC۱h*}0=IЭQ0Dh)am&W i?]mRVCRܾhM fai7e5IZ <'P3 lv?S~{WP UqqI; aYQ6*jd-=(C/>I:eHI"Y$O5hZBP9kTDiQxQNB^xBa8dgdCyvi\[H2QI*ѐHУȌKqB*t|+mqלEHGWmL[_in\9T?`cf=e\Ŵ63tC>1HU0MRj*T1 dJ?ɑ0ޘq q^ԁ4+n;FlW ˼f3 s,ܝ$Fmۓ Ή,Jd@oϕ%Vr}B䓝{\0Yv[Ы^{VЫIMti)zSl .'endstream endobj 563 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2286 >> stream xUyPw{n#"L"(=c5FPCa# x ( ĨI<65Z&kh6ɒI}m~ֺ M֯W{}=4R(SB KޥKZec!_iB1AQS<uJth'T:#zr H&$1-y#\kCvb1~|MҚo2rҰ*]4v8TGq""i|[ ʠXLdN}vv>d*Uu{[N`V,+n \7anv5ن ϝ7?owdLw?RE?![h4%iUPBkP䚤kipmnq1e6iqok<72LkCgs*v{ ؑ3!AkBWAtyP z/K+1X}]cwQ ARPy%ao^Nzm+;SN]W&t -k3Rsyt/YέPNӨ9Z\ꖊOT> ,wHŧD.]i( ~z8*DiLJ!DTsL9'_ <{8iۉQ<:W mЭK/E'7(#/i)Q+4XImI}·&3+Pel6n@ܜZ]h1ͅl5` wbUpP }XJM\B+/e[yG{r[zg1ʡ|P \#J< L| [g?\fY0@h~u^;Q²Qa%D|-N48۩ QIdiMpsltd?;lN؇wn'Lxk\E+`Gmy^ףϘO^ě?nz.d0pCNž,Rg9ciq!Rq a@|~CSg-{n= {+`#$Q skRR>[ks3Krs“) (ɇb/}cACke*A{@eXkAmg$<)e"L:aWY'?vqNWZ˖Y\&S✓endstream endobj 564 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 324 >> stream xcd`ab`dd N+64 JM/I, f!Cß^=<<<,*=3#cxzs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ g``` b`0f`bdd ?SUe/>0oaWw[V}GoG~zw#/ KUؾs p+]#`-ýyVT#3z@| НVendstream endobj 565 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3985 >> stream xW TgYT#.8*dLFA4.!n,͎(bIӷipAVPfM41 1Y_nIo,9sީssoU0vB:/p~݌uM]&vg쩐QYЧw `wfb(e T'MK?7kΚx}FJ|]ל3藱^c:5 kkD-  X5kAO_2 3fO8#) 9eVj5En :fqlВuƛYd2Ehf13 b0c`f)3Y1+ƗLdBYf&3yLf0/0/2@f>81>y|+g)_P`RZUl-|o:A~:x8|?xq)hȀ!/ 93Ɛ>luu$ EoW$rs̙ M"1}ܷd:cFQ*dׂF@*ԳTMѲVp FH&ٻKE]["/!&/rfZ;D<|N4} wɴ(P[ ֵ߳|N6CJJJpnY@bGAQdƒ#Z*rP ِP,Nu!?~I譕^ZO^M'TGa[=+) HxP  &iBv;^b@L+V:V62MX(o.l Y&4thO}J)qFEUݰ~.%c>ߔXA뻮.%F 7UǵFko̻(^, k a7lӗG?9yʽIU5-v] ЬPpɲ(HrkʊF,-^QjJN߻F;tNl/LFo7aFo 5.[k* f8t '{ev.dʮk!bE8t\:}Ve'܀֓x2J-@\I*IG%\u;4/&;42)/aP-dҗ ?g> 7Bn[pDc3'B>&{YL+G2-ڭ$inq63]#3PI}03{ây`SQ@ol*H\q"k"DӮ>嬖p^wmcvˣ%\,H$Laśtn2h^ Ѣ:'H,*%G ܖTY<rN?oizwۘ֌VEUʩ{PSl0k-P u<&p_O8mn;ڒZb]Iy/4Dsd7?^GڎՉx=2YstGtj*H-U Cmեe2a]Qo4 > qZ1 +#MrO{̅76qRҲ8ȢzbEgYI9YcEHdVb#owBOН&P#64VfEeƥS*6:}{+X@JUTUA=ڌ Yo˔ gm,$〟-wScÍc!Jb,Ol`Ij&#۵ǡJy2To9Yͅb~F cp8nMeqgߙ qq"c{^ތv9 I)f*&T !F#k:+*35i|#ņFH$πlW eP*45 <)]6W׊S4}5|&$ϡY[6mٴEL(=vpy Z2hD%&SEtaǾLajb0[k #S5l6>E_elJ9d4&kDClQdi1U$i?i҈ X!GJx|@}[?8$98oV<\%Uʊd+Nm>܄QET 9:rCV[xV16J "V=_;b&!¸ Pl,Xxb>ū8xElRqR=*@OW[3{[]Hl˩TWl/1@+i="Y:AϜ N¹ioūW!pxo:2nH/{ ߖg1y ?D_Λ V ?K^APl67pxO@+0I, HS?bi] ?45qWE#d/6F'U),mTT{O el -VFO5C@VI9∌Ј5R 爟>G*15mѝRljnt*\ajx5"+Z/-7VwbϹkSKFDR:e>(+Libbbd]L&v i:By_5liZt2m Wf̚:8G|TiOXa67^~;_G{#:lHD-TR4]Pˬe 'naZG8ME oʦTЎ~u6Le6Ldlm0&=iEjXTW6WSADl[|cAAICy~G\f&BZ%qT$͋MO@}ӯm/xz=9SgrznvHCvAC3B"%x<\-Bp"0AE%()~~R3{\NR\IJ\wCӶzuLm1mmR^Xu*YvKaP\\b.+Aj>Ru{ya01p]endstream endobj 566 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7436 >> stream xz xSa#FĽe8 2@t':i2O9h(X(8!r{xwD<ozÇgM[C^X0o]zhBlf0n kqxh.73!XpSV'FǤOY`y˦Ly}YiSB"iY)EƄ&DMIsm>[M>փꪤ'NY'42gnۘ)7bs_'H \EK_5{<|JˈbNl%fۈD1N&vb':1"V]b>!DA, |BbXOHl ^"6Mb3G'&Oib$81H&ÉΛ¸ù{ /s?rdcF7z苏KDߍslBA|>_)D)ٓMr>O>@Ng˦ |N;:tmOM5i p].fOq{m9H@VCyZ Tr;UFj] ԍ@!VVv F<WV8D"lq!j ͅPNkFf>¥sr gss| SQ[Ԗkt4zɛ]veS㱍! YR;t:*Zqd-$Il^ɞ(JP $ּ2K:^49U&>8s^v(ΏU@&>7-hX79.]娐S(t-A~ڶ&Cg('mr"9Q IT,DT4IlZm6h djIN&;}u[Uʊ6Е9zyd"Xx4gŧ +FRm8`t*^2@Ղ ЌKW |Љe[zn/XN9@ yR$ƒNtqO^64Cˡ>POl WAd /mPJxh*F|O';ůNgyͻ hzw@oa??9v>KlUV1!|aWQU.cF.}}S.n =[gR>1-/)`g. #\zj4vXA Dg 2\y.z}½3`$Ak$U!n) Ƴ]iBw)r\rz'a)KAS/Ԡ>A+_!?>efXrkNrp(4 ͦٱZ85g'[Ao-֖ .vTz[5ϸRf==Y>^zT-hEv>'~gں&t9[E-ӏى&! 2_2!Z&B08\MWKca_n Y.;zG[m]=BYHB Z24nƜiL" e GvDžFkwtk˓B{dZ(H ?܅8ܯqݫbPcP[X*f=jCqX)rm,L0ˍ[(e(B1Adg ˼HkmCDMM:*&0zj?1* Ѽ\)[d2UNouݘ4^%t/QNoGArj]=}q [\FČ\{#:(CHINET/%`SPЅP)AI۲k]=$ u{Ҽd q#á8DwQuBLR`-2XB_D&xly)*!>0VYP^1+L:F pUתsTa*>Tx:#yt&VZυ-۟Wz0A2ϠpgEy-mN'umsj ;cG |^AvIa;|Z !uGp*2ӓs7FoGcws6">$6TķL jB ,$("(iV-@P#ILG9we$F>EjPJ_Y4h[3Л chy~"@wl& "w!s"mr+)PSjRK=+s |9 2*$MfbK.Z˽OOxCZJ"APs<@\G-`5Pid^A ,B"C!b"BI7/w)sV` A7E x1Buul{L]Η2f((Ѷ썱@<_Cz3Ad%ʓduK|AvrR^ 4o mƧs̏ag)C_l?pISD>} |7j|{ڠU^xnP!6Ew+2e0m&]`@T!C?:ҀZd@ĢxtN!(O}k(K A#2Rf4UJJOMOϷrz![=]te*5sԐōV[ ̸ǚ˨ʭ%@~wM| (0x`wGfRWQ}ۊIjjjLh![ #1\VOk0,9>FO~ڀx% [ځ|4,m}0gHǶR-֪TdxC|2ak5?}aJ@G ob 5? &JIs k`Ch'Czp78[fҙGI~ mݮ"*]joE&-:e*RJȡ&mo} V5821M2LJeԪy U@nO=UcK=]X[4%aA :몝C6hg]z򳿕x5T?uo,D riI^A~{ӫqj0@f' E"L =-pɱu`rD-VJfc)0: /A,f3/_0va9e|<^ Y d,P ZMGy=vl$s^+R{v4w?U! ,kN_hΆ6rSڜ+HBv){[UCKmx7RUu]<4$'D&p/h^Pbs̕G6?ϕRkH]bmI7>!֐rkF1eRTZJu7L7giAG!Ma{14HCls)N.R6K;nyXMp ,dw Sf>/[A +YvQN;<Ԓz]DF{i u70|tx6 gl;4AQ()Ň(X._ m7Ѩb4*Cw;@~t͏BG*>a]hGUNN-t ΰaS٧bT&;k'Y)%#śaL,6?0m4t؅Y1mwUX2H56ǩ BHAQ.-l.kE\wĿ;<?fG:/';I/CVȽ1A~yWPs6 lpdzﱍ|aK28-q,IERgGg~\"Rd& c ⨴VaWTTP/'Aޖs7.ߨ(+0kn85UGGpHlKdZ5vǽjX'/׽A˷(M F!P>AQ i%h58KZ[*JIPՋ(!ձ/M4)>X d@B\4߄kW\G#s(⧉%X%p@#}2keCn}6&&1zu=ʱh5Z ~ĖWQUT0Ph.v@/olx?Gd81TO9Ix&qZ85ߢ1kb5-1 [Pm MG Yr'?~]vŖ&0~oV>{J;|RZ.m%{T"&'t:VVj.jIA@,VE/蛠Ⱦ!(?GO9 [PR\!HWW[\F zȚylϖ\̀%RItҨYHADu{y#5aJïs&'gf645˟ {A=b*>4;5Ć٦R[}w>\AiE^?o~N6?JVR@oxg. w,ћBNEdU]92 \b•+|Tgp`(@II kxPTfNoR&{Q@bIhr͓[('iotc) &vn)?.ϩg 0A\ȱ:tpKVRnL с޽~=3`eXvlWgNgAEyY)rY_oܰU+$`0`z^{=[_@J.RS ]zpU p> ')y ".Q}T"Q GZ2, h45ߘlʞ,2@*`G&`?QwaI0~"~2`ps+TS\d*;Je v:^YWSD=Ȑ6ӽg(=f/A㐤!J)JEUKjxTɗd,LW)xpTG!BU] R~}NY ewZmx& 熖7j#VR'hDJn`E07\}aUCOg@vμy^~Er~q?8Pp! c5`d˴- l5Gyg0/eK:ڊ&+"E{@5퇍<=S6@D*m;:Zq-@KW&k gٯecX`/Gq[.T3uF؇sN7v#Х \&-w|ӎ§!%z^Q懰a!,&]ׁ_g d|HG7c망-@vHܰʇ=2w+jlys(d|2 VJަ3zt_ B扩WȓJr=wƒ֣X,^&]٠*)VF3:8eh=)DKlX!*4F[#l |~Ϳs >F8 ^e0^^КPbNC|IQnKM#4hRvKfS)i>K$k8Pc3g/?MPU[8{n~ Ntux kNqs%L:ˇ ~{n_1uqLER[[wkO%PXEyIYXjg D.& et=WrN@?:9`F6(!K%;5~9nc_0hu}F{l ۞oWϖtq:%%z/ }a3͌.NSfNξJl&\X$gTv4`SHP-|mV?_h6{=J|&c6  Bdę86Jw ֶOGdjlB|BziV}5as2⠹=\Tʱ(Qn~Sv|(XÂnQ x"c%0m˃jvn)ýh'2 >-ӓNHKJEJ^f] >NH5)74S4u.$LEG͢ԘҪRDaOT xe9|\lwf䀣bҀ*_Pf{PN^6]!AV'&C|I ͙;8ʌp2(M_9;3zlx@#a(ash= ٢/֙*яFaendstream endobj 567 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6426 >> stream xYXWGfXb`( ";J0v,K4Z1D/?c..e%_q;ssy{3jQڔ֤ ; ;zyxHg Sik:pp2A禽P7 *&DJGK[$8Zfhff N~]hq5V\5-v_6EM6Q˩7( MCjHͤY35LmP.VʚFOͧ\5j-6eC-QP)[j1eG-6PK2ʞr̩I!bɔ;QS(#ʘ2t(Sj*GM^xJLש8j5@MHX(]*j_vBR笮nH/LF!.1fƘi_ߤrl؟ W3ǻ4aDIJI֓ S&rAnpʦ))ύ5YmRnʙzޛM4m=y"_{ſЀʅ#Za3ؤ#up<$!?-7!(@A(%{q22ҒP<؂_&ō2 =H؄jĿ-CWVӟz_,7Q #PuJQ,q[Xų.TcdT!>GG +ZmqsM<#RkUΛ'V,䆭`ȿ{SH%68>ƯC A^]\\AIQ`@#j3WLF!U !ZPMp^8dž u6W2T-ďa96S rp~8v"=)_p,gn::-PO,\́m';-*Ĺ19FubPs`tzRj:eKvmE ȱM`rC,rBc 0#Q2Κ׷E ?xؓ>q4 1m]kvSMkxOo]^2 !獆,Y s =W7 GGdy0zf,|'dh#e4uKFpE >(Ƌnlq$ѝ1x9ʼnz1wՈ{Eur+k_Sܻ}|.w)+v.dD""y\`$DPC-d^'fC: Pƒx3ė3Q?b_X% "ֈ]( c#[7Dot;(B# L7^zf4UmEqux!6xҨe~[0 }ibሑ1) 1f1$h>=KEq= ::U l6;GnpVOE͗f{߱H_w(bz"%m=(@11<#u7E2Y Uˏ0%~lrB&PnqavEnM1y)e15 ܪ0`Q? r %t%Tȑ呔Cof ئʶlegTdb|y6` h/='y2TmEoH= [R{A&T\3#_Ո3"Svx2,R+a3\f[V3W2\`Ղ x60F ~=ɰjt7/}r AZ&3"J2.rp$ c`|{ Gxb٣5B"HZp: }'/uGQwrsb3L^0Fŏy{(U;[fϟqLB4ZfB?H'黟~_ƪ!Q*"$G ,'VaM7G l$r ڲf.:dF?;jEї'aˆ XOE#v"%\cTD,ߝB кDӥ/`2L~-Z[[ =AZ:ţ8*vzbbEV2Ey9y%z1u$Ǵ՗5g7 ]ces<{5±cgٱ cr׬YGwuU&b@-/ޙ8spCh;*<u >H?GY`7FN%7 aR}YO>j&(‘џHDu. =L l=O>;H7B}A}}>za/ O@4PxJ-؅x7H$ICx[[C ܪ$5<{NqRbU#6@ ]>Py(peEGW7:ɜ=u+iu:X-cSxenu,W,[P1ʶ#`5u7ѺHVMVuV*aPPU ^!p` VzXK's G2 ΧQ (%dTȴUGla\³u?W<&tt~j*헒'tDdPџZi4VD-{RsXaݩITb@` L^^Bh ӃjsF+AUy\݂m3G9a H$'N᧴yCeٟf=~0#;є:DUbO!1-->5b{r!H8zq$5~BH=_mh=HECPe։ށ'7VX&&Sv|# KaI2,%FDYN];~%!*0p*Hn CɤDIفw}jSϻfqZubq6}cN߄ʦ:TR[x$<,Bҙ4Bqi.ҕ|L,3kcYT`#` vM)ga+@fL[7g x9ԂtP մ)ye.QYHHk+k<Z,iH!^nZ|QwЮ@"!Z_DIxL/yv!}i߉+L`m<Xlo[bu}cu[Yzyr!_yd'g⵮:qvHNIKG2P͇4 +D9\W᱁MMLCw\:ܲ6~Ͳ:i%|gueoio8p4;q_BA24[6.ܽd8?1MQuҰ8E?~HO;**61-=-R#}Q0ĆDh&2 hk@%'E@ i/J.F{خJxIO-%t(JϊQwx"N1eQ-׏C;9,A })r "x GU?a}pO!U%J헚/ƵhU_RķvHy5ޕl(DBWTHV ?um~'MkB"zRЋK_?@U'83&;xvIkgO߀QKm߷+䓚rP_[oܿ$B(:CmNF)EQbSC5F_6#C~ե|>|_!; !U; R7mKVZ ewXl ³-#6|`i:bț!ݚg[;w_w/lwW9['su4S/~ TY.oQ~!Q@5׍ؗ$8W9H:yXg9q;ph=[}8'=wvDU^~~fB15kT6&3 \w8͎[>G"I3]{֘*Of$-t஠{Ivtl%ݿ\#O^rкlWsWhe`hӲI) (! _U^"a5B x6ĝ)+)BL[hudWU\35cɖtԡV qhێ >?ꆶ2g]^!_IO/+*.%-CbʘgAWEI>s6([c E֤1,69#+YxwrZ| 2AdfI*<^ɹYjU8rv#r{INl/ُ;]u9e_(bi)qb0Zx)fb~Gl¾tRQ'06qFqendstream endobj 568 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3783 >> stream xWyXW,E)Zy5gFͨDAwhOwC7&yƸ&f4~3&F8c̼w\ɻd{Q}s~Q0cB19pƄ;vǼ4o6.fONd䭐~MX;'pq~gꤟ<$w'bk\BbfRLGF,Y#"6!=96F#>Rj afVBF۹#.J٤{S9h Mu̻͞Ca4K-OJHIMۑ X[scLЦظsfl`f03 f3la2KƏYe3+yL y2k;3qfr/(L#:wʙcs/{?4A9eK^X'&j'Z1Nz<# (\.+XW}+jؠ\ǛǬ,)* 0D$WѢl88nԱB:5~*}{s_NVɧ&XKSDW,zBT/K.{7غG\Yw]2!7~ ̬]Vš/ܻ_?pGDj!dG6I. И&>i< iN (d*$cq$(2LPi JмLf$/DP?|z5<*E!E[c#);[']bΆcŖ* .ӖxыҏYJs t`ɂ<(cV*QaHtjݗUs Hfl4@Xem=Td_0 +"[&eSGҢH2*n\ȣW# [D#)~KQt%&Jb}}L!rw;TtBc4AIh4߇!cDڎے{Any99hnapn lTwC4._a3[,G-"}^|< 9bp:G¶p_1,o)/rbG.>lR&f1X >q"SB ,f:ZFf:Npn?):/W2 ӎ ^!9++ a{򮕔u_BYLmTSʵc+xܪ>}oԬC04i+=Lqt>TNVV^ӑ_صQZt- ػڔfα4JQY\CvrܤiEZT=Ztb~MP!M,T HsqIJ&QFZuv[wqt3VߢWuJEi<̮*#>CTo6Kk1SY.F!يBT8Y3^ȋ/j^k4|{ /LwF2/8 'OmT՛YB&HJIC5ķs[Mt@-Xklu ST `t43q_Tͩ;UCmةBWr«D,!܌hp=.$̟ӮO({v}=&v;0O}YbXX9?tjP,/[V8H{%!8}p /1 i Q!]$I0k'&= Dڄ6<-3{34ξTVWUV~d~9UjXQ8@EЪl5Sq]@T aͥvod:8'2݇N | q OX*sH-d18ʏL9\.;m烡8=k쎏R0֤5gz:*@=FdطumUүqZ2!@[XAZqĪ/W?Bĝ.e~+ysF!qF㲸k')[D͉L<}*P$?2Qߡ*~{WlLHes}[׶xM}$6u%u]AiK%刲˴.}7,E27LҌ95΢Σ?i3:^E8"/+0v'9I8Niͅȁsq>=v}_~d+84R3fOCmSyԫȬ{d gZŻ 0Q$JgQI[z }qqr _ Xɥȡ!P df{nĹ.9ɨ40x ztCW:'ĥA`ItDecSV(̳Y󛽛^{cɜF$,|}ނS# I=X~##dP @E9IONp 2hUB_tP#ݎ-G[NiԽ!^`. ó5f^ޢܘk"fTqG Cu(4W48|_/)J~| 9:dBA_1Xz+Yd%W#ّ$' pы)aȂ?k Pj7dgchv,W *U@X 6EDIĻ+x>š3r3<wFt (ߢ;p3F?/efB@ve̗wl ~pFwoil4=YzlC?wSqocvhŖ$Kl QQp_QZHiR"98!, ސLrXyOن/y Q/+\&/Ny쉿Й"u@^GԎaKӏĞU,lNt*/(I8]~-L3,9G"߁G҈ԸDULWx `+Ĺ`}mX{-{{ LoU-ndzX-e l7Y5*b9uHu&캡p2 7#t4t`pB$?qkH1+rpL=4է,BsYDy^4yLᄕ)5V0G> stream xViPgaUD3;dS㺘(Wx_hC9pawfa`P@dd8l@oC<B<*ٍ Hb*kbʄ|M=Qd+Z{nTyyH$[:$9)Z*VdL:%$6^)NsME =/<35CcPXB,mJڽ$9E#C6}S6lq;w&Ȣ1WW$g dl[hy,9N!5YX貐PيaB'6_%YH^޶}uL쎄Н4 kuP"Dl$KD XN$^%^&V5uŸM“"[dNOo6+S//\jkG|6rۣjG5 6s,@VN"BnY0ƒݰZ7LkQ9aFgAmLdd0&QB!pt:j&* J{d!%\??o 6AbPm\Z+W8CXT?25N~J4[H0B 䈴 1 jbUtv 氂a ޠvS"%JkSs Ke 㔂KhрF~[hj]/SD&ElQl(^de[kI{oЮ_m["NE+Q "4MXԠKjɏ6^T=AWBZGi Vؒ~"Pp0ؚ0fKW=eu0ϡs?Z/IMQ`eT5``_+K# 1g`/Q8{%'/pZP Sž?C l4yT}'r[vYC|тk9nҋ4>[!oQ\lP  /C3uYޠd># ˜ZGo8¡M3x5QnC[| XX 쎇RplGB0E{V!>{-ؘ'QΑBォ%v78t2Дv $ۄIRs^^b1ES資A7hșΦ /˙&  Wr1*pfs7t 듖vb Bקj&B)3%m튶aW%UeA֙ˡyYGt٘6naaEII=_ ֟ PŒRZ=9g^Bqf[( w(E5b¥HRGa#^W37,ײmjGȣ v֪kp?߂1`[iSДZ{`&DmTo|Eo<`yq枨C3ЬSn3ruY P(U!LO8e8%hz_ݳGxfj<2/1Xi `3{R 'o#-Ž3zoH_=,2`Pl9Џa6>b :Ɲz +v2ly^?:F>R=\xA[gR DBm9Ԥ^ 'J *cQn6E%^ݢre:Vr䘭RzD8 GsFسȠz$eR ZǀxHBέPq4ȇͰ6n=P XjVA4 ᙾ BbK5X;פ[y&eC<מ4gAZeÔ2}GuF32՚MT/]d(`5rj*+ FA 3lcfEƕv| η!P}wn?c@ hѬ,,\*8{\c?ɐ k{Lj]]ڝWf >'|XZuy9Ԡb T]YX> 7̱crc7 ޤm Ѫ Oviz%ti;Fo|њ;=wa::@~iqm2MԧUeNWA -gC~o7켏ژU.NN)t鍀56Ra͡C}1 ~KHon/,Da")F&+v)T}jyJ+T@moY+k6kF#4VȋQ:%UH9IndߨFzn=G՘Lfl*5[.{{*,6bڊG?+endstream endobj 570 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 346 >> stream xcd`ab`dd N+64O,,M f!CgO/nnC }_1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000103012_*ÂO|qwaW[ߙV޽4w~+wsne׋!۹Y}} 5.v*T];G҅?|_8{! 'r\,!!<<܇zl^}?20lendstream endobj 571 0 obj << /Filter /FlateDecode /Length 4620 >> stream x[Ms6=>]L"WAZ_YɻUhi,3*ȱy f|0G~nIYI˽rrrl8xS٧ЅOXm /lǤKWZBXw=-gשx6j|;96ُ8Iֺ~әR(K?Ng$SC_qgkj]7LJQxm~FH YG]B[D(bUB "; LpVNfRΘeX3ŕ8Ͼ;MX/9h:iW%;|+ثmo=;j5> K 38P8%ŔKDgf3&W^Aah3 |9lf^v\wdU7<#eamEὸ0}E}SW,mHv!) |e(Jɚ.JD+̸Y(+g S )U pqnYlBfb  +Of vQש6 eUk9v>=;eoAeIKݲ}kfY?fST@/XM饓W|4^~5K۫ԛ]]-ұ7{C{AuZr 8׷ZUa̰]jzy,7̨Pz|c+Q.r@UlfY`ڈ73FEA1{uG[23%eiسUa8_.K'X;E%aMuN*}=`릗DMBT 6uW )Wޕ~/ #)5z,;JeglhF)p!ʹ:3q逷eRJi7&K (l)zRշSF`˷J|H.Hc)v%#-@V*6A2S4kSD:fByku3{ f>a:pf˴ N6_y٦]w<||nfg*[u d] E"V|xZ+ww# ]cʝ`T0I[Kfy4: gYä ٞ4> L ~GLr-!M {2 5Դ>x^f5fXa'S,<3e%w)TWhh3(4#nh.,# b.Jm)$H~ Bw^agVv]Cy=qg4"$#ܗ0FJJɁ>{ AǸDWl%*LQxœ q Z8L!c JU8.6TZ&@{>Id:R| $c<+}|ʰ&uj!DnӐ^]n:zUx6f^\*m ^/K 8qdϮۯ;R.TF먵a_E6Il 3]<f>rGsD0Mۧ{ {A4gT?W݋ß>c,ji/g8 !|{< RG41?PF TO톳 9ԍYR>ӂ#.Ha 3 M`0uO]ToeTa߁h:^.CP3#B/D0u~Fv.,Ĺ2m~`yoGW+U[ըVBC)fxWB$.ˍ%;T$%NЁeH.ן#m0uwWђ  q:pl#`Qn7C ~dL) &=?Vb( "L6\6xMؼ%P)pshK"貖]su30![—b bVJ@ӑ*MbSW$[n*:8˔ri7u=X:i qx 8f6^g.;x$C=OJ'QNb؅woc, @"ԉf_y47K5 wyrQ \C:Eod>B6sQQ 1F}΅c_fUT +c*M$Z.(Pƞ=G b%HzS%`^sMiE7l;V ew'|q=ǩ~ GM~}BBcY|Ƨ]9ѐx\rtgVˆK,&w]o .‚tcb_'o%B rỹ/~/yzOؑNV}z&A٩ϡpck"FNBB{u(pG *_#]?s&cV|oICer=8 L ,{G0MUi.ݗExkFcRX( XbVލD( :)c}gUp(Y{u `WA4pޅ,p eUwv'kX؄sdW:9 n %L1a[5c9_''I@sYendstream endobj 572 0 obj << /Filter /FlateDecode /Length 4662 >> stream x[sw-*s4 8*[qV^Yξ*%"E/9s9 ` 6RR&55@_ 6+>]v鯣bKkG q*gj[yGxRWPDJYZcxg|\Yٓ;^VױSNgcSi%XVܰ/E- ,khwƱM%`*͎gaHiTѡ)zj${<43a5lqVIi+.pNOh"u?g'22 O薽%+_yaW&[W FHAG)`0'}`|W Fe.+lՒľMۭذ },a=knb_"<[>e68Th\MtGZ pmlmkM ᜝2~4ppt+lpijCn]ex]LmX[t\k/k:iI~ˎqp;9˽vWg4{xœß-XWc.e5a JM3 o@@{5ݸMlfBլ[pmj }i3Is.,r Vp6ь,{>rna s?A߆&2Ц Xi'?;LrXzQ~8=堮4!j7`[7B>_ΞBS;Tqe<_Vkf*_[շl{…] _YE(' Gň B1 %'E#wUr0 q b[8Nu*8-Y}k@ا*]gOYzq^"4قpvM׃ᨔRq1U\(C -N-WY{o6Kr7RyuWk︫ۯ;NE>qնONTD?gm\]~n-*k~ T`.H S):ڛ-(H_І_4^Og@EqZ *uկiΎh^Cxb`bL$HHBuJsB<ְ46@70~E\ۊcb;*Eˏ]ނ(Wx}BaS+dG"e3+k!!UH uN Di5Zq5gbpǮr܋' 2M%4( ?1c\`޵jaj{ȵS۵ꇷZh }d]}?Qj@I80 BF])R1]0&়Bۀ/8$mCB[?Q@^W=\} gJ;Ktb]3{ZbmkF_rפ.G8-t țdXo YƺvS_@\6>6 /f.c%8)=^Qus@cMgŴEd@,hxSډ}hBLo>0CYyKxksȟ;+ jH#vz+ȝ!T"k8YS8[|BQoҴ@B3T 9xl˗#_6qj[SX8jgL%o^+FWEpwp͒|d7!D4>Ho$L엜5Y2CO#F}eFj)XÞר IY.\pHM1IOj=evy]3;J s݄ Ruq_;%`U ;AڀP@, ذt 8w*K/cXC ]a;=Bfʥ1ȹ-f/n׎42_ Sam:6"E AnBᤰcbc`Z֋ٺ^a30`M7(4H}ri| o 0޵*|J?ώ; 0Ɩ(FlUkQĨY B#zg*]R18⥎PF"l0hoVBTm#WNL! +3Ҏ+S:X]5я#ҿ!G#kG骙$E"ԡVU +Ċ(y-Оulqk+*M `^N/|3O`XX;dEޅ61P`BfRuq 9{7iv\aԧ|e(n(KfB(0UXݼ`ֆ2I9.4q$li%:XTeGr:4@vکH;"\\X֩}~6Ө?i?Q 3jP4/Wg'&!.Qogls{uuK8HlB,p~Pe%*`Jz\-FZ&CO˯( /%PI\"zH?F)oӢ֊\" r0Uַnb;Ŏސ*aBgEK ^)ɠ  Ԫ S#~,c6`oA)EQ-LY}xaj ]iC3 u\^ȉ>VС /La7, D>b@+V恂{(Bs-X%v"AWHq0-޾HsV+y|(ƝCWn¤C-Ml6۱YkGIy|W9u_Smgz .Y{ía3\RN?߰E~x @͞_hpB\`f(֟ UeLtpӴvi+Ÿp /sn.XQwٽ cendstream endobj 573 0 obj << /Filter /FlateDecode /Length 4482 >> stream x[KsG9"f׻J;啥 eDZk͡ BdK73 Jhwe~ꊏj?;]գ˽?8󳽃SMkGgB>r|dԣj|;U4g{v\okOc_lum:sl6kCk]y}xZDʔЗrYx"6z#eˢ4Kh+X-9.<*!+mX"; TDr[Y1H]9c^1)'glFrf?PqϞK gًI܍c;h`p~keaf'}M7qcݸ7^=95דJh|%\]3 q"-Y(L^]j Q^H ޺Nd/eHuZy6o%_"ZkNlw$)G.+EJXvr.>vYQ'7oQm!־v"za]|uN8r)je DhI"뢺2^m"]ǫ 1nRa7JW~٫+Mb$\zdkWiA0sѵϠ%=˙94 t5&JZ|?]p{>iK%W5d˵k>_a.rIR.YkjyCX;v7Y,k=e ~`yN և|Ǹ ;rp ˫iLEmKnya1ٛhKڇN)vQbotQGM|g)Q7yw-n;0\vClWdpS8a\0D<6 +#eNKӌ: 6|@[1@!+0kkApHɼʭE&ׂ(+65-DTk#ي{UJ-Ň ܏߁'ht>Q@<})!%UFڃ̃*m</^G_h{mؾD>,Q+H6ߣiO%nvGiȗdiDSѰd&HPI#FvI 8dqړo5h؈6AOaABl Ţ \ӼGڏ/_?h+C.I$K+ t=(x|?E6"ջhyB+`v+ֲӀHĸfa35pnӀ#}!|!z7 rPe5bqYp Tz{Ox  ,mUzc~~Ɍix^nQhJ=e#RDE 3)" v}p/QoJ8Ml@I>]LOy`Vdj@K;?5XL6ƅ[\ޟ0 kTMQLrzkb <ӆ ?66@1%*p l۴XaӬ_"X5&5T.H%Ͱ <|D'm1[~ntsӏ59Ƴ^WPxY`&@bkqN% Gq=H[8_d\^0!dT[[{xx핶j5Df84X[6p@wC>%j=WvQiN H\6Lғa a98~@x{mC*uݗ"%)kŰ76r[.S'w*sҡɃ=9܈oZdGw+g*jJ dKA$r{`w.4!`Gu<I coT0IN6'Lxخ֦қs#rɤ0%A6hA/J+4KGp#袶z;MBO)(#xm̊HkdIt;fIt(υHTI MCwSDї~&}n튓22VhG80[cĢD Dqv6>GSYkBU ͛^: + IoF]" ^%|Su?XzKhAg릪{nJ,8 ɛQ*~X@Y|j5l*Ou_P<;I4Io*(?N1ddXvwfe{&'ͿRBO_6pM*B"t&UK"Wj˺ oUa[axA%g _:'i!+zZjg{5!+NJmBrQ ^;.RiW$e~ٸ-* (<:1Hµ,f1^ *=`,Yj"F fLZ+B cgЅgi[c ؾ}0PMǿhG) f 3]A8/ |i>P-澘!\mM_ u=-T.'ݼ/t 艳}xa'}`'K!%>g'IL!Aof`įbOVâ_qFKH°rXWx"scT?C *Ot<s$0J*~zES=o;`wV^Ium ?Dx)z_GcH ܚ܂:oJ5$\XCЗI [&ʄ@q1tjWLuo'0[h[.`߬vX'r0!: wyխJ.fY?oc\0?ήo/ۆ:,ˬ% tc'̔f z=]Y샅ir.զ.#%dSVjka޼>$6۲+2dR^9l&Q(l0'#%K/yeӴ@~-r9ڟ)]zaRI[r(mI^ Q6Y{yA,6|4˄QBN|yUi3w MɣqADcږ7b.5j?Zk+fC<1fa@ OGFQ@9?-I|ާ펍59!!Yᙲ9a(Y J\k(u'4V}ەS *v-R/Ύ6] xs{8V 2jZ}1b$+謓_W+cXuUcʣW!Βl1AlO3&2PURfm7˷~^9'jӋG[E['I 5BDc9_(Uӵ7vba TQ87\ܕ[W?[` Cnή\޳@jpdpOSHa`d@Ui:]_`ܨRXR5b,!ed%gU,bAyalgJ]3'ְ<(ym4gUwTBkI\r]u',)%+!Ef|H;X4X~Z\eR 0B@͖C*Ud@?o/Zh\_eQP4mlMb0+XVz[L <]\eW0<5+ 'Nj{*Y|Ł>bz#?Tڃ-wh!#`-9(cIKe; CP%vvYe#q6IȰsFP<>a֔ Â>CA%wh0oHCux' !xj]>~ս?> stream x\KsGrgĞZD$Z8@=CR̪ܿꮬ:x`Y?^ _pqH]_|ſ}-|Ӈ!^Gą.\8v_sy5Ծo/R`d%`C}_7/%,e^_JZm#,lF|K[2^x뻉)쁑=ϻQìV~G %rH7/:u/cCWZm'{_^fdå=l?>HI _OyN?^ǂG[2nPy!` ,ɣޠ펷<@r74*~VCɉaTw s1Hп+'xU|%Mn爟 @`XXsCzn f捍@;>4A+ek~wI˼rCIHꁙ|L{%qĸWWHx.Ǩ z0y ([8S״Va.~~Ȼm<ΖXN'JX*Wt{cm2~~XM[mA|μĝ=wޅY\gkG~5Oep..]c@ay1\n0Aqn nǰ1/&p ӸI '7nM+q71 Vn57xKr!@,{2k_t#^榸iVӺ_< Gi/Jn"1r@ U pMvtdN{|o:1F }v'h/DqO 4\A!J 7#ڕgΓYd#B))&/"rC ˮwkei"1vo7z0tg=ƺBѱW6S'Ǵ%#a5h`$Qa0nDŽz7c bAn-,}%OmP;@'͛F|:asWq&N>_45y{wUw̶/;BL:֤}F t*#Hx+ZA$45ēE:#MBX`f{ϴMMǛc>Y C0qf\.d~S Z2O`a9;;uPgfHdlQ8/<4Ӵc:z?"x)VAuXDv4{k F{HWUZ͈(Y 70xɑ'!n#t8L[7wpta1ev獝3 ~4t k}5󌮜чڧ"Wy49eED{'J#b)y% id E rq:~8 X k>3%ctQYsULr8'DG4 LUN*ЃP>SJLpD}vnCs34mDhsb (-H!6:Թ,SX}NY%1=$% [LFCP%q|7V̴E@(_Γh3.&5Қ^:7ӊ̙`[0G0d4$A}lց'"Duve\lQj 4ڟ{KGJ1[1g(@/x;iM$K y~ȇ?%R:"[k)K(<I:FKOe4rZE^3J7U;ڑ/t<}vٲR%toׯ[Tv:Q7t7A?G(k*@գ%6cQV& b=O)1Wire0 \Z{=ύ}CkkXY-y6sp{ $~L>k+Ya?{3};wD2j23b*!Md.}c'4x u!E<[ 9\Fbꗽݺ/Tm׉:b(L-dz\[h<% ^mx:d[5Qb4B=,#,)iٲMp&30$^;BѭJΣX R WLM=)8T@fI- 11L&fb\AlA6$M肀JϹނ.FsjC|gr$Jkę#$>/,"BU? i/i ,v\U̗NB30.x)\lS'ƼpâV'ЛeP/k; y+6Ȍ3 *h`Be :9FE_{ Zk(`=Ny`7"_ƩL%KɁX.)F3-<ۦI'Jivhdxy)YT'qu/\Dy٪䪊1ᢺ|)ޘRra>]@9e3cJUmƞ8)y 1#7P)nP/Lh\R|DH@\GYrJͧ'$pur*qS Vdc=]ӝg+H>a@4JŒʕ+tEt0]M ^zQK"/r:68dG6ȞPor[ꌞjo#~IV.ix@oU0L+1@ܽA*oݺ$|H;n>)/Tʍ`ԍAn} Po\*Ґd?7C zSwhwd+ $}+p"Whol]fTpjq]r[doȧeǓV3nX sW>U߽N;' /FmKNZ\|dg}ۈvKwӣqMVgݴa͜"y50z;<`xpD1+cS7/_El6vw5Sj:`BoR9 x-:ypQ""|r5FC,PNg`&ȀlF#pŌF_FYL:P1D&mHY2aWL݁gX*W;MҕˆE)w}uGőwS? 8*b f "(ʎBo@QI$b[ux, c;jp&јVl;L*0b5f"v7iN z&[0w?d7b3sZG9#a>Lj0B>b3M(H}~f/V;3M>CKu]7uiW%>Sǜ0#17NE! <$[)Ѝ86^&,& oH|(uwWSB]mxF9Aއ4(T6s=)w+Ʀ 29]Tt6V`*L&X xwf:أKX^wLbF(2ż(.a+N v?GHpUg|&.jHF*TgNm{*QSQshܲP%TKPq%҉dR%Թ><[a[&0H.ֱzoo'PMW/*]WUqj"XluruV&:!.7[z%xH?~.Ryq g4W"B8Z^L8[Zby4Q狷 f,K^ҹ|KFՋjK&]2RdTO>[j,O6aC<K#IxFB)̿6S+=̠XRրM0Bݞ_Z ڜbu`V+P0l3UI mޫRlw:pD0=NE7? X4;rN⛛2;7qZ7oZi.+xn:"zt U^ԁ]63Th򧪏,O Wڸ Er%cZ>3lՉ/$K~w3OکA{niϤξVddbV@^NDC1"+O;"0ȿITab>1 eU F/̤UT4nJEURO1jn!rLrçzZ&G?~W rCFrͣo!CDME::@OXVkaY+ۘޥĘ|AǼGYWSwj`慿6hD~ @VŦca> stream x]mq!`6v更8'؁rciӌV3g =UlvOUfzϗ ObXd7s=WLE^ホ\|{5bN! Ņy-pg\gP _fsf76esm?konG(>5i! %3[0nşnn-4;ւ1oLJ7ιyCd\)ޚ] isk#uC,ijkЯ^^ |Rv,צd?맻?^#ƃ`#4\{@c<_m>ݽ?"śnncp-\>׏o1j䡦k7t `ܩ]yOࡊK4[r믮Li  A."W~k|̅18 k7tŇXn˕1UG θk $c!?ZhkazU1 5,Zg&.w28 ˚!v  @P<L4qxH" {Y l*9 U5(^$~贘wdq띔 ZȲ\\-+!XA!"3UѢ1\k CC xo0SkICLF:dz(`R$Pif3v Or{X*fz ^yaU/ ǣl ,C/.Qa'{&jdrodY vU\L5Z𥳐)ᚪ .%3U8{_.`#' vE=#5 >SiUu jJ̪JhpZ3*L@sܛ&xLE /,0NY?Xq0x? X0- s/SQ m/ҐdjGp~J+S]).h:`sbAw3;Ͻ] 'Na[%vi-c2Codԇ#c`苿N>|+be6k&q-V^<š5h ][>z*IqWe>^ֲր wkX0bW 玕b2( 8S@w8صW@,4vFaԗ\Ua(% Ls\2 Ԣk65<^\R`] T! wXqڸ6Lڂ%Ί6Fe5 DlN< 8MeW|<penש\%$+jVUVF75 ;0iV)33.zV733!TOK^+P\>.4hmF7Y)$j%T)0& RBEf75=njrn6 FZ z+pZը;T,.UUPU\b' `qY:GSg̼qOVO"j. ֹB#:FaԲIf#%T6X5)8U wjH?l扃2X|41!BG\ (F?'rG#j?Fl,˪ON?5/1Q׉Fq1Ħ6l#8phFF'SN噠FS|r{yI̵P5jKՐ#Sl dH ogd8%%Y<"UC̦$p<%|$h&HCCr\=m%{ԐV!Ѵ8|f&;q#Ljʚ\Mbj9e0^!X׉bw|B&UjQQ>PRz-̓lje*ռ>9j>;5Q*Y^&JUaPTKϔ9{2S%U2x[/Y#xX/3xOC$y*F19cR!upUQ>"Yfvv 9D5|Ë 뉶 +e9,U}u@ kR%d6-`jP>@$,w9^&cs /< 6kHg,N#lwh>;dH۷4zq|c8!``m6,keG ߏZc)w66dV24M *L]13snL"yxQ =#yFC~b+kI9YV<)w$ ʙ1eIB\D& X+,\o#B[#2j9|duQMtߧlTX2eQgnTVY:Ք&ɔGxՙ,ѪLFk5ݱTގ2y,0ω IX0kg6 h6ыߪY: cugL;C$}er c^58oM4!saI&XTɡZk &(ZZXdZURj\KGKӴhv0KI|eܷ M6 ܂M[+k{$+amj7 EW(\AOp"Ҥ3%5k-YYfՇ2kUԬuǒYkQZ Zk[gd"k-""G#05k-[dZmWֲ,o`k[y7Ye`rtߑ4rxߚ9 N:}LR[I'YEfm.NưV1\e,+̚ , Nf5Nf5Ceey6 ^h#/`?H{H[#!sa ޫgqVCτA>G_dz&SAƭoH,WRRFw> Eid&]mW3!̤k?5. I.(ˊ23M;: |P6 |PNl'll 3tܗIר{d*JgT";S( Ϙ)[eY2k@֊!>cPrN(:;9I:;SB,/J%≣ Gm/;+WEU3C-ny$]Gm,-v"%mgfN~G9Sw V߾tU6lt70';Qeߑ|t@J(12x.w$TC[a2e38dzarI洵 sɬ|2x՗].l j X#|*~k !saQʭfu+#VFc%W"H8~i3qNv~I+f4U3.xqW6Fb1Xj]kIF$^X'\zUY&ȕ\ͥ>fu Ǥ>VѶE#omFu#[VPkJC墶EQ6 |j.XIُۢQ-|EQ>oٮ(30c"-vPRS߲{ڪ$y& S]y3R'{d.,퍱[x=~omZ!f[8G73;tr& {Fp #XXb/"J?M6|G 6#FGZ8|abVl7YUI>)*Nk HSX|! ;zhIZh쑹05.҂'ʁU,B;*;6-x6mǦwc[pWʎMY+eǦdbߥ 'd16:ɋz$-x^lJ[DGZ+G`R`9=fGZÊ]"_RہSr,73Vy^VhԬ:u2\ kw_?O;Vުߤl !oEQt MjH+g4ՁRv*'L⛭z_;pVKYd%^D~G(8olCeEQ,@i*mBeQVMX_־׌i'y+uI 넸q6}JIYd,eX3BYc5#k!,\@8p L BYԅšl1oׂP2R(p+2֌&+kA( [XY BY˚E&bkfIJ`:!iX3BY򌆱f0ZkF` IAVւPf3.eY3caY&%ZʲAkA( (] BYpxƚ¸2y-eܛ AC5#? BY88wae-eጀkA( tkA( Y֏ BX ׂPl] BYf@VDZXY BY Wx\Js ~3/eZJ",йkF+C۵ mMz֌PVuDX3BYs|<.a9Jr~` QjA(+NX3rbqWOBYq@9o11ҌPV U šʂYdeaZ1֌P[5#U|]$!,pLuZʂ@XXҌ5B]+#,жaA( ->\x,>P Or>asBYwFj ڳ 秈xtT+vzd3JgӰyR-̭oϴAgG;$ %1PzBpsSopݫwO{js]y-/~mI:mVSq ,9 pPЊemU£)T}'8UJm2($TI+H9>Cn: