## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(message = FALSE, tidy = FALSE)
library(BiocStyle)

## ----packages-----------------------------------------------------------------
library(bHIVE)

## ----module-overview, eval=FALSE----------------------------------------------
# model <- AINet$new(
#   nAntibodies = 20,
#   shm            = SHMEngine$new(method = "adaptive"),
#   idiotypic      = IdiotypicNetwork$new(),
#   germinalCenter = GerminalCenter$new(),
#   microenvironment = Microenvironment$new(),
#   init           = VDJLibrary$new(method = "pca"),
#   activation     = ActivationGate$new(),
#   memory         = MemoryPool$new()
# )

## ----shm-comparison, fig.width=8, fig.height=4--------------------------------
data(iris)
X <- as.matrix(iris[, 1:4])
y <- iris$Species

set.seed(3)
methods <- c("uniform", "airs", "adaptive")
results <- lapply(methods, function(m) {
  shm <- SHMEngine$new(method = m)
  model <- AINet$new(nAntibodies = 15, 
                     maxIter = 15, 
                     shm = shm,
                     verbose = FALSE)
  model$fit(X, y, task = "classification")
  data.frame(
    method   = m,
    accuracy = mean(model$result$assignments == as.character(y)),
    n_ab     = nrow(model$repertoire$as_matrix())
  )
})
do.call(rbind, results)

## ----idiotypic-small----------------------------------------------------------
a <- sqrt(log(4) / 2)
A <- rbind(cbind(diag(4) * a, 0), c(0, 0, 0, 0, 10))
rep <- ImmuneRepertoire$new(A)
idi <- IdiotypicNetwork$new(theta_low = 0.01, theta_high = 0.5)
idi$regulate(rep, "gaussian", list(alpha = 1))
idi
round(as.vector(idi$get_population()), 2)

## ----idiotypic-full, message = TRUE-------------------------------------------
set.seed(1)
model_idi <- AINet$new(nAntibodies = 25, maxIter = 15,
                       idiotypic = IdiotypicNetwork$new(),
                       verbose = FALSE)
model_idi$fit(X, task = "clustering")
model_idi$repertoire$size()

## ----gc-demo------------------------------------------------------------------
gc <- GerminalCenter$new(
  nTfh = 20,                 # number of Tfh selectors
  selectionPressure = 0.2,   # 0 = no selection, 1 = very strict
  rounds = 1
)

set.seed(4)
model_gc <- AINet$new(
  nAntibodies = 30, 
  maxIter = 15,
  germinalCenter = gc,
  verbose = FALSE
)
model_gc$fit(X, y, task = "classification")
c(antibodies = model_gc$repertoire$size(),
  accuracy = mean(model_gc$predict(X) == y))

## ----microenv-demo------------------------------------------------------------
me <- Microenvironment$new(
  high_density_threshold = 0.75,
  low_density_threshold = 0.25,
  stabilization_factor = 0.3,   # reduce mutation to 30% in stable zones
  exploration_factor = 2.0      # double mutation in exploration zones
)

rep <- ImmuneRepertoire$new(X[sample(150, 15), ])
env <- me$assess(rep, X)
table(env$zones)

## ----vdj-demo-----------------------------------------------------------------
vdj <- VDJLibrary$new(nV = 5, 
                      nD = 3, 
                      nJ = 3, 
                      method = "pca")
A <- vdj$generate(20, X)
dim(A)  # 20 antibodies x 4 features
print(vdj)

## ----activation-demo----------------------------------------------------------
gate <- ActivationGate$new(
  signal2_type = "density",
  threshold1 = 0.1,    # minimum affinity (Signal 1)
  threshold2 = 0.3     # density percentile (Signal 2)
)

A <- X[sample(150, 10), ]
rep <- ImmuneRepertoire$new(A)
aff <- rep$affinity_matrix(X, "gaussian")
activated <- gate$evaluate(aff, X, A)
c(activated = sum(activated), total = length(activated))

## ----memory-demo--------------------------------------------------------------
mp <- MemoryPool$new(
  archive_threshold = 0.01,  # minimum average affinity to archive
  max_memory = 50,
  recall_threshold = 0.01
)

rep <- ImmuneRepertoire$new(X[sample(150, 10), ])
mp$archive(rep, X)
mp

# Recall memories relevant to a subset
recalled <- mp$recall(X[1:30, ])
nrow(recalled)

## ----classswitcher-demo-------------------------------------------------------
cs <- ClassSwitcher$new(alpha_IgM = 0.1, alpha_IgG = 5.0, alpha_IgA = 1.0)

rep <- ImmuneRepertoire$new(X[sample(150, 10), ])
zones <- sample(c("stable", "explore", "boundary"), 10, replace = TRUE)
alphas <- cs$switch_isotypes(rep, zones)
data.frame(zone = zones, isotype = rep$metadata$isotype, alpha = alphas)

## ----convergent-demo----------------------------------------------------------
# Run 3 independent bHIVE analyses
set.seed(42)
results <- lapply(1:3, function(i) {
  m <- AINet$new(nAntibodies = 15, maxIter = 10, verbose = FALSE)
  m$fit(X, task = "clustering")
  m$result
})

conv <- ConvergentSelector$new(tolerance = 1.0, min_appearances = 2)
public <- conv$from_results(results)
nrow(public)

## ----full-example-------------------------------------------------------------
set.seed(2)
model <- AINet$new(
  nAntibodies = 25,
  maxIter = 20,
  k = 3,
  beta = 5,
  shm = SHMEngine$new(method = "adaptive", base_rate = 0.1),
  germinalCenter = GerminalCenter$new(nTfh = 8, selectionPressure = 0.4),
  microenvironment = Microenvironment$new(),
  classSwitcher = ClassSwitcher$new(),
  verbose = FALSE
)

model$fit(X, y, task = "classification")
model
mean(model$predict(X) == y)

## ----session------------------------------------------------------------------
sessionInfo()

