## The the module detection tool uses 3 arguments: 
## 1) One named vector of weights, representing e.g. differentially expressed genes, 
##    where the names are gene identifiers.
## 2) One n * 2 matrix representing a biological network (e.g. a protein-protein interaction)
##    network. Each row in the matrix represents one interaction between two
genes. The
##    elements in the network should have the same annotation source as the
names in the vector
##    (e.g. gene symbols, entrez gene IDs, etc)
## 3) The number of iterations to use for the enrichment test.
## 4) The p-value required of each clique to be included in final disease module.
## The tool uses the following libraries: igraph, 


module.detector = function(GeneVec, BioNetwork, Niter, cutoff){
  GeneVec2 = GeneVec[intersect(names(GeneVec), as.vector(BioNetwork))]
  library(igraph)
  print('Initiating clique identification.')
  Cv = maximal.cliques(simplify(graph.data.frame(unique(BioNetwork),
directed=F)))
  print(paste(c(length(Cv), 'cliques found.'), collapse=' '))
  
  print('Determining clique size.')
  f = function(v){
    length(which(v%in%names(GeneVec)))
  }
  len1 = unlist(lapply(FUN=f, X=Cv))
  Cv2 = Cv[which(len1>2)]
  len2 = len1[which(len1>2)]
  
  print('Calculating unpermuted clique scores.')
  f = function(v){return(sum(GeneVec[as.character(v)]))}
  TrueScoreVec = unlist(lapply(FUN=f, X=Cv2))
  
  print('Initiating permutation test.')
  len3 = sort(unique(len2))
  
  f1 = function(n){
    return(sum(GeneVec2[sample(length(GeneVec2), size=n, replace=F)]))
  }
  
  f2 = function(c, v){
    return(length(which(v>c))/Niter)
  }
  
  Pvec = vector(length=length(TrueScoreVec)); Pvec[] = 1
  
  for(i in 1:length(len3)){
    rv = replicate(n=Niter, expr=f1(len3[i]))
    Pvec[len2==len3[i]] = sapply(FUN=f2, X=TrueScoreVec[len2==len3[i]],
v=rv)
    print(paste(c('Determined p-value of cliqes with size ', len3[i], '.'),
collapse=''))
  }
  
  if(all(Pvec>cutoff)){print("No enriched cliques sounds found.")}
  
  Cv3 = Cv2[which(Pvec<cutoff)]
  
  DisMod = t(combn(as.character(Cv3[[1]]), 2))
  
  for(i in 2:length(Cv3)){
    DisMod = rbind(DisMod, t(combn(as.character(Cv3[[i]]), 2)))
  }
  return(DisMod)
}

