##############################################################################
##############################################################################
##                                                                         ###
## link to biomaRt and get gene info for cdf file annotation to            ###
## match AffyBatch                                                         ###
##                                                                         ###
##############################################################################
##############################################################################

Annotate <- function(AffyBatch, chip.type, filters=NULL, attributes=NULL,species="rnorvegicus_gene_ensembl", write2file=F, file.name="gene_list.html"){

  ## #################################################################
  ## PARAMETERS:
  ##
  ## Affybatch = define probe set ids to annotate
  ## chip.type = "affy_rn_u34", "affy_rat230_2" or other as required by biomaRt
  ## filters = can specify input id, ex: "ensembl_gene_id" if alternative CDF
  ##           file is used , default will be set to affy chip.type if left empty        ## Attributes= output to ann-table, possible to add to default values manually       
  ## species= data set for biomart to connect to
  ## output.biomart="list" or "data.frame"
  ##
  ## NOTE: Ensembl Gene and Transcript URL so far only for Rattus_Norvegicus
  ##       Must be adjusted to work for other organisms...
  ## #################################################################

  require(biomaRt)
  require(affy)
  require(annotate)
  
  ## ##################################################################
  ## define gene identifiers for the ensmebl database search
   
  gene.ids <- featureNames(AffyBatch)
  feature.names <- gene.ids
  
  ## if no filter entry then chip.type is used as filter and
  ## affy id asumed..
  if(is.null(filters)){ affy.id <- TRUE
                      }else{affy.id <- FALSE}
  if(affy.id) filters <- chip.type
 
  ## if its alternative cdf file rm _at extension to make names
  ## match ensembl intries for data base query.
  ## manintain original feature names for later comparison with CDF featureNames 
  if(!affy.id){
    get.list <- function(x) unlist(strsplit(x,"_"))[1]
    gene.ids <- unlist(lapply(gene.ids,get.list))
  }
  
  print(paste("Filter used for biomaRt query : ", filters))
  
  ## ##################################################################
  ## connecting to ENSEMBL and extracting gene info:
  
  att <- c(chip.type,"uniprot_swissprot_accession","entrezgene","ensembl_gene_id","ensembl_transcript_id", "external_gene_id","description","chromosome_name","go_biological_process_id","go_cellular_component_id","go_molecular_function_id", attributes)

  IDs <- c("Affy ID","UniProt ID","Entrez Gene ID","Ensembl Gene ID","Ensembl Transcript ID","Gene Symbol","Description","Chromosome name", "GO BP", "GO CC", "GO MF", attributes) 
  
  print("Attributes extracted to Annotation List : ")
  print(cbind("biomart"=att, "re-named"=IDs))

  mart <- useMart("ensembl" ,dataset=species)
  gene.annotations <- getBM(attributes=att, filters=filters, values=gene.ids, mart=mart)
  
  ## ##################################################################
  ## Defaut biomart ouput is data.frame, that must be reorganized into a list of
  ## each attribute, if output is list then each attribute list name must still
  ## be specified (IDs)
  
  ##if(output.biomart=="data.frame"){
    
    print("Exit biomaRt, re-organzing data...")

    n.genes <- length(gene.ids)
    n.att <- dim(gene.annotations)[2]
    gene.list <- vector(length=n.att,mode="list")
    names(gene.list) <- IDs
    gene.list.items <- vector(mode="list", length=n.genes)
    names(gene.list.items) <- feature.names
    gene.list <- lapply(gene.list,function(x) x<-gene.list.items)
   
      for(i in 1:n.genes){
        o <- which(gene.ids[i]==gene.annotations[,filters])
        for(j in 1:n.att){
          ids <- unique(gene.annotations[o,j])
          ids <- ids[!is.na(ids)]
          if(all(ids=="")) ids <- "&nbsp;"
          gene.list[[j]][[i]] <- ids
        }
      }
    
    o <- which(filters==colnames(gene.annotations))
    filters <- IDs[o]
    ## print(filters)
 
  ## #####################################################################
  ## Ensembl urls for each ensembl Gene and Transcript IDs

  print("Extracting Ensembl URLs")
  
  o <- which("&nbsp;"==paste(gene.list[["Ensembl Gene ID"]]))
  ensembl.gene.url <- sapply(gene.list[["Ensembl Gene ID"]],function(x){paste("<A HREF=http://www.ensembl.org/Rattus_norvegicus/geneview?gene=",x,">", x,"</A>",sep="")})
  if(any(o>0)) ensembl.gene.url[o] <- "&nbsp;"
  names(ensembl.gene.url) <- feature.names
  

   o <- which("&nbsp;"==paste(gene.list[["Ensembl Transcript ID"]]))
  ensembl.transcript.url <- sapply(gene.list[["Ensembl Transcript ID"]],function(x){paste("<A HREF=http://www.ensembl.org/Rattus_norvegicus/Transcript/Summary?t=",x,">", x,"</A>",sep="")})
  if(any(o>0)) ensembl.transcript.url[o] <- "&nbsp;"
  names(ensembl.transcript.url) <- feature.names
  
  ## #####################################################################
  ## calculate nr of probes pr probe set for alternative cdf files

  ## if(affy.id)  n.probes <- rep(length(probeNames(AffyBatch,gene.ids[100])),n.genes)
    
  if(!affy.id){
    print("Calculating probe numbers pr transcript...")
    n.probes <- lapply(paste(gene.ids, "_at",sep=""),function(x){length(probeNames(AffyBatch,x))})
    n.probes[n.probes==1] <-  "&nbsp;"
    names(n.probes) <- feature.names
  }
  
  ## ######################################################################
  ## re-order list as follows: 
  ## affy id, uniprot id, entrez id,ensembl id,ensembl gene url,ensembl transcript,
  ## ensembl transcript url, Ensembl Exon ID, gene symbol, gene description,chromosome,
  ## n.probes(if !affy.id),go BP, go mf, go cc + attach Annotation Type ("Affy ID",
  ## "Ensembl Gene ID", "Ensembl Transcript ID" or "Ensembl Exon ID"). 
  
  if(!affy.id){
  gene.list <- c(gene.list[1:4], "Ensembl Gene URL"=list(ensembl.gene.url), gene.list[5], "Ensembl Transcript URL"=list(ensembl.transcript.url), gene.list[6:7],n.probes=list(n.probes),gene.list[8:length(att)],"Annotation Type"=filters)}else{
    gene.list <- c(gene.list[1:4], "Ensembl Gene URL"=list(ensembl.gene.url), gene.list[5], "Ensembl Transcript URL"=list(ensembl.transcript.url), gene.list[6:length(att)],"Annotation Type"=filters)
  }
  
  return(gene.list)

}


## ###################################################################### 
##                                                                     ##
## Extract sequences from biomaRt given sequence IDs                   ##
##                                                                     ##
## NOTE: if affy ids used the filtering might give more/less hits      ##
## as there can be several transcripts for one gene                    ##
## ######################################################################

extract.biomart.sequences <- function(gene.ids, ann.obj, biomart="ensembl", filter=NULL, seqType=NULL, downstream=NULL, upstream=NULL, species="rnorvegicus_gene_ensembl", export.fasta=T,file.name="sequences.fasta", affy.id=T,data=F, filter.genes=T, filter.ID="Ensembl Gene ID",cluster=NULL){

  ## gene.ids = gene identifiers, so far ensembl ids used, set by filters
  ## chip.type = affy_rn_u34, affy_rat230_2 or other as required by biomaRt
  ## filter = specify input id, ex: "ensembl_gene_id"
  ## type = The type of identifier used. Supported types are hugo, ensembl, embl,
  ##             entrezgene, refseq, ensemblTrans and unigene. Alternatively one can
  ##             also use a filter to specify the type. Possible filters are given by the
  ##             listFilters function
  ## filter.ID= "Entrez Gene ID", "Ensembl ID" possible identifyers in ann.object
  ## seqType: sequence type, ex coding_transcript_flank                
  ## species= data set for biomart to connect to
  ## Attributes= output to ann table, possible to add to default values manually
  ## NOTE: seems like getSequences() filters gene ID so that it doesnt return reoccuring
  ##            gene ID (i.e. automatically prevent multiple copies of the same sequence!!!)
  
  require(biomaRt)
  require(affy)
  require(annotate)
   
   if(is.null(biomart)){
    biomart <- listMarts(mysql=F)[,1]
     print(biomart)
     biomart.nr <- readline(paste("Choose one of the above biomart database [option 1-",length(biomart),"] : ",sep=""))
     biomart <- biomart[biomart.nr]
  }

  mart <- useMart(biomart, dataset=species)

  if(class(gene.ids)=="matrix") gene.ids <- rownames(gene.ids)

  if(class(gene.ids)== "ClustreLustre.obj"){
  ##  cluster <- as.numeric(readline(paste("choose cluster to extract [option 1-",max(gene.ids[,"Cluster ID"]),"] : ",sep="")))
    o <- which(gene.ids[,"Cluster ID"]==cluster)
    gene.ids <- rownames(gene.ids[o,])
    print(paste("number of probe sets in cluster", cluster,":", length(gene.ids)))
    file.name <- unlist(strsplit(file.name,"\\."))
    file.name <- paste(file.name[1],"_Cluster-",cluster,".",file.name[2],sep="")
    print(paste("file name:", file.name))
    ## print(gene.ids)
  }
 
  ## mapping gene.ids (e.g affy) to entrez or ensembl and extract unique IDs
  ## reset filter so getSequences() use correct input gene ID 

  if(filter.genes){
    gene.ids <- lapply(ann.obj[filter.ID],function(x) x[gene.ids])
    ## print(gene.ids)
    gene.ids <- unlist(gene.ids) ##[[filter.ID]])
    gene.ids <- unique(gene.ids)
    ## print(gene.ids)
    gene.ids <- gene.ids[gene.ids!="&nbsp;"]
    print(paste(length(gene.ids), "gene specific ids after filtering"))

    if(filter.ID=="Ensembl Gene ID") filter <- "ensembl_gene_id"
    if(filter.ID=="Entrez Gene ID") filter <- "entrezgene"
  }

  ## if filter is undefines a list of options is created for the user to specify choice
  if(is.null(filter)){
    filter <- listFilters(mart)[,1]
    print(filter)
    filter.nr <- as.integer(readline(paste("Choose input ID filter:[option 1-",length(filter),"] : ",sep="")))
    filter <- filter[filter.nr]
  }
  
  ## if "type" of sequence to extract is not specified at list of optiens is created for
  ## user to choose from
  
  if(is.null(seqType)){
    seqType <- c("cdna", "protein","3utr", "5utr", "gene_exon", "transcript_exon","gene_exon_intron","transcript_exon_intron","coding","coding_gene_flank","coding_transcript_flank","gene_flank","transcript_flank")
    print(seqType)
    seqType.nr <-as.integer(readline(paste("Choose one of the above sequence types [option 1-",length(seqType),"] : ",sep="")))
    seqType <- seqType[seqType.nr]
  }

  ## mart <- useMart("ensembl", dataset=species,mysql=F)
 
  print(paste("Getting sequences with", filter, "IDs and",seqType, "sequence type..."))

  ## extract sequences, upstream only, downstream only
  ## or a combination thats is merged into one sequence
 ## print(gene.ids)
  if(!is.null(upstream) & is.null(downstream)) sequences <- getSequence(id=gene.ids,type=filter, seqType=seqType, upstream=upstream, mart=mart)

  if(!is.null(downstream) & is.null(upstream)) sequences <- getSequence(id=gene.ids,type=filter, seqType=seqType, downstream=downstream, mart=mart)

  if(!is.null(downstream) & !is.null(upstream)){
    sequences.up <- getSequence(id=gene.ids,type=filter, seqType=seqType, upstream=upstream, mart=mart)
    ## print(sequences.up)
    sequences.down <- getSequence(id=gene.ids,type=filter, seqType=seqType, downstream=downstream, mart=mart)
    ## print(sequences.down)
    ## neet to mact the two outputs as they do not come out the same way, NEEDS FIX!!!!:
    ## print("NEEDS FIX: two put doesnt match... edit scipt to use this function...")
    sequences <- data.frame(cbind(V1=cbind(paste(sequences.up[,1], sequences.down[,1],sep="")),V2=sequences.up[,2]))
    
  }
  ## martDisconnect(mart)
  ## print("Disconnecting Ensembl")
  print(paste("file name:", file.name))

  if(!is.null(cluster)) file.name <- paste("cl-",cluster,"_" ,file.name, sep="")

  if(export.fasta) exportFASTA(sequences,file=file.name)
  
  if(data & !is.null(downstream) & !is.null(upstream)){
    return(list(up=sequences.up, down=sequences.down))
  }else{if(data) return(sequences)}
  
  
}

## ###########################################################################
##                                                                          ##
##      Make html Annotations file from list of gene IDs                    ##
##                                                                          ##
## ###########################################################################

gene.html.export <- function(gene.ids,ann.obj, data=F, file.name="gene-list", extract.1.cluster=F){

  require(annotate)
  ## file.name <- "gene-list.html"

  if(class(gene.ids)=="matrix") gene.ids <- rownames(gene.ids)
  
  if(class(gene.ids)== "ClustreLustre.obj"){

    if(extract.1.cluster){
    cluster <- as.numeric(readline(paste("choose cluster to extract [option 1-",max(gene.ids[,"Cluster ID"]),"] : ",sep="")))
    o <- which(gene.ids[,"Cluster ID"]==cluster)
    gene.ids <- rownames(gene.ids[o,])
   
  }else{
    n.clust <- max(gene.ids[,"Cluster ID"])
    gene.cl.ids <- character(0)
    cluster.ids <- numeric(0)
    for(i in 1:n.clust){
      o <- which(gene.ids[,"Cluster ID"]==i)
      ids <- rownames(gene.ids[o,])
      gene.cl.ids <- c(gene.cl.ids,ids)
      cluster.ids <- c(cluster.ids, rep(as.character(i),length(ids)))
    }
    gene.ids <- gene.cl.ids
  }
  }
  
  ## print(gene.ids)
  id.tag <- length(names(ann.obj))
  ann.table <- lapply(ann.obj[-id.tag],function(x) x[gene.ids])
  ## ann.table["Ensembl  URL"] <- lapply(ann.table[5],function(x) paste(x,collapse=","))
  if(extract.1.cluster){
    colNames <- names(ann.table)[c(1:3,5,7:9)]
    htmlpage(ann.table[1:3],paste(file.name,".html", sep=""),"Gene List",ann.table[c(5,7:9)],table.head=colNames,repository=list("affy","sp","en"))}
  else{
    colNames <- c(names(ann.table)[c(1:3,5,7:9)], "Cluster ID")
    ## print(colNames)
    ## print(length(cluster.ids))
    ## print(length(gene.ids))
    htmlpage(ann.table[1:3],paste(file.name,".html", sep=""),"Gene List",c(ann.table[c(5,7:9)], "Cluster ID"=list(cluster.ids)),table.head=colNames,repository=list("affy","sp","en"))
  }
  
  if(data) return(ann.table)
}


##############################################################################
##############################################################################
##                                                                         ###
## Exports expression data for ClustreLutre clustering                     ###
## Can extract the whole expressionSet or only the DE genes                ###
##                                                                         ###
##############################################################################
##############################################################################

Clustre.Lustre.Export <- function(expr.export.matrix, class.names=NULL, class.labels=Null, gene.filter=NULL, order.chips=F, file.title="ClustreLustre-exprSet.txt", data=F, write=T){

  ## create tab delimited file for ClustreLustre with Header and gene IDs
  ## ordered into classes in the order they appear in class.names
  
  require(affy)
  
  if(class(expr.export.matrix)=="ExpressionSet") expr.export.matrix <- exprs(expr.export.matrix)

    if(order.chips){
      chip.order <- numeric(0)
      for(i in 1:length(class.names)){
        o <- which(class.names[i]==class.labels[,2])
        chip.order <- c(chip.order,o)
      }
      expr.export.matrix <- expr.export.matrix[,chip.order]
      ## print(cbind(class.labels[chip.order,],colnames(x)))
    }

  if(!is.null(gene.filter)) expr.export.matrix <- expr.export.matrix[gene.filter,]

  print(dim(expr.export.matrix))

  if(data) export <- expr.export.matrix
  
  col.names <- c("Gene ID",colnames(expr.export.matrix))
  row.names <-rownames(expr.export.matrix) 
  expr.export.matrix <- cbind(row.names,expr.export.matrix)
  expr.export.matrix <- rbind(col.names,expr.export.matrix)
  
  if(write) write.table(expr.export.matrix,file=file.title, col.names=F,row.names=F,quote=F,sep="\t")
  
 if(data) return(export) 
}


CL.import <- function(file=NULL){

  ## file can be specified, if not user is used to choose from files in working directory
  
  if(is.null(file)){
    print(paste("files in directory :", list.files()))
    file.nr <- as.numeric(readline(paste("choose file containing clustreLustre data [option 1-",length(list.files()),"] : ",sep="")))
    print(file.nr)
    file <- list.files()[file.nr]
    print(file)
  }
  CL.data <- read.table(file,header=F, sep="\t",skip=1)
  rownames(CL.data) <- CL.data[,1]
  n.col <- ncol(CL.data)
  CL.data <- CL.data[,-c(1,n.col)] ## rm gene ID coloumn and last empty
                                                    ## coloumn of NAs
  n.col <- ncol(CL.data)
  group.names <- paste("Exp. group", 1:(n.col-1))
  colnames(CL.data) <-  c( "Cluster ID", group.names)
  o <- order(CL.data[,"Cluster ID"])
  CL.data <- as.matrix(CL.data[o,])
  print(paste("Data contains",max(CL.data[,"Cluster ID"]),"clusters"))
  print("The data returned are sorted ascending according to clusters" )
  class(CL.data) <- "ClustreLustre.obj"
  return(CL.data)
  
}


CL.geneID <- function(gene.ids,ClustreLustre.obj,ann.obj){

  if(class(gene.ids)=="list"){
    gene.ids <-unlist(gene.ids[["Transcript ID"]])
  }
   if(class(gene.ids)=="matrix"){
     gene.ids <- rownames(gene.ids)
  }
  
  o <- numeric(0)
  for(i in 1:length(gene.ids)){
    o <- c(o,which(rownames(ClustreLustre.obj)==gene.ids[i]))
  }
  
  gene.symbols <- ann.obj[["Gene Symbol"]][gene.ids]
  for(i in 1:length(gene.symbols)) gene.symbols[i] <- paste(unlist(gene.symbols[i]),collapse=" ; ")
  
  CL.IDs <- cbind(unlist(gene.ids), unlist(gene.symbols),unlist(ClustreLustre.obj[o,1]))
  o <- order(as.numeric(CL.IDs[,3]))
  CL.IDs <- CL.IDs[o,]
  
  return(CL.IDs)
}

extract.eset <- function(exprSet, cl.obj, cl.cluster=1){

  print(paste("Extracting expression summaris for cluster", cl.cluster))
  chip.order <- numeric(0)
  for(i in 1:length(class.names)){
    o <- which(class.names[i]==class.labels[,2])
    chip.order <- c(chip.order,o)
  }

  o <- which(cl.obj[,"Cluster ID"]==cl.cluster)
  gene.ids <- rownames(cl.obj[o,])
  eset <- exprs(exprSet)[gene.ids,chip.order]
 
  print(paste("Exported eset has",dim(eset)[1], "genes and", dim(eset)[2], "chips"))

  return(eset)
}

#########################################################
#########################################################
##                                                     ##
## produce cluster plots of your choise on exprSet     ##
##                                                     ##
#########################################################
#########################################################


plot.cluster <- function(exprSet, class.labels,class.names=NULL, top.genes=NULL, pam=F,h.clust=T,heatmap=F,div.clust=F,pca.clust=T,scale=T, center=T,method.linkage="complete",method.dist="correlation",group.subset=F,gene.subset=F, clusterOn="samples",eset.is.log=F,ClustreLustre=F,cl.obj=NULL, cl.cluster=NULL, cex.scale=1,rowv=NULL,colv=NA, save.plot=F, scaleH="row",col.heatmap=rgcolors.func(51), pc.ids="character"){

  require(cluster)
  require(pls)
  require(amap)
  require(affy)
 
 ## Ex:  plot.cluster(eset.liwong,class.labels,class.names,group.subset=T,gene.subset=T,topTable=toptable.limma,heatmap=T)


  
  ##  ARGUMENTS:
  ## Class.labels: VECTOR of labels for each chip!
  ##  pam : perform pam clustering
  ##  n.classes : for pam only, will be overwritten if subclass true
  ##  h.clust : hierachical cluster
  ##  heatmap: produce heatmap based oh hclust and method.dist
  ##  div.clust : divisive clustering 
  ##  pca.clust :principal component 
  ##  method.linkage= linkage method for for hclust
  ##  method.dist=distance measure option;'"euclidean"', '"maximum"',
  ##  '"manhattan"', '"canberra"','"binary"', '"pearson"', '"correlation"' or '"spearman"'
  ##  gene.sample.clust=cluster "sample"s or "gene"s
  ##  subset:only use subset of chipset
  ##  class.names: if sunset=T -> define class/group names for chip subset
  ##  e.g v=c("a","b")
  ##  class.labels: if subset=T-> character sequence with class.names positions
  ##  e.g v=c("a","b","b","b","a","b","a","a","a","b","a","a","a")
  ## rowv, colv : heatmap paramater, NULL givens dendrogram and NA not for row or col

#####################################################
   
 

  if(class(exprSet)=="ExpressionSet"){

    ## if all classes to be displayed, class.names need not be defined
    if(class(class.labels)=="matrix") stop("Class.labels object is a matrix,  MUST be a vector of chip ID's")
    
    if(!group.subset){
      if(is.null(class.names)){
        class.names <- unique(class.labels)
        chip.set <- 1:length(class.labels)
      }else{  ## order chip.labels according to chip.names
        chip.set <- numeric(0)
        for(i in 1:length(class.names)){
          o <- which(class.names[i]==class.labels)
          chip.set <- c(chip.set,o)
        }
        class.labels <- class.labels[chip.set]
      }
      n.classes <- length(class.names)
    }
    ## subset chip set extraction if wanted, define class.names to extract
    
    if(group.subset){
      n.classes <- length(class.names)
      chip.set <- c(which(class.names[1]==class.labels),which(class.names[2]==class.labels))
      if(n.classes>2){
        for(i in 3:n.classes) chip.set <- c(chip.set,which(class.names[i]==class.labels))
      }
      class.labels <- class.labels[chip.set] 
    }
    
############################################
    ## calculate expression values from affybatch
    print(class.labels)
    print(chip.set)
    
    if(ClustreLustre){
      o <- which(cl.obj[,"Cluster ID"]==cl.cluster)
      gene.ids <- rownames(cl.obj[o,])
      eset <- exprs(exprSet)[gene.ids,chip.set]
    }else{
      eset <- exprs(exprSet)[,chip.set]
    }
    
    if(eset.is.log) eset <- 2^(eset)
    if(gene.subset){
      deg <- top.genes
      eset <- eset[deg,]
    }

    if(clusterOn=="samples" ) eset <- t(eset)
    
    ## expression set values for chip clustering
  }else{
        eset <- t(as.matrix(exprSet))
        class.names <- unique(rownames(eset))
        class.labels <- rownames(eset)
        n.classes <- length(class.names)
      }

  ## #####################################
  ## distance matrix
  
  ## dist.clust <- as.dist(1-abs(cor(eset[,chip.set])))
  dist.clust <- Dist(eset,method=method.dist)
  hclust.func <- function(x){ hclust(x,method=method.linkage)}
  dist <- function(x){Dist(x,method=method.dist)}
  x11()
  
#######################################
  ## pam classify clusters, #clusters must be specified!

  if(pam){
    pam.dist <- pam(dist.clust,k=n.classes,diss=T)
    clusplot(pam.dist,cex.axis=cex.scale,cex.lab=cex.scale) #note this is PCA plot with pam cluster drawn
    print(cbind(pam.dist$clustering, class.labels[chip.set]))
  }

#######################################
  ## bottom up/agglomerative  hierachical clustering

  if(h.clust){
    if(pam) x11()
    ## hclust.dist <- hclust(dist.clust,method=method.linkage)
    hclust.dist <-  hclust(dist.clust,method=method.linkage)
    plot(hclust.dist,axes=F,ann=F,cex.axis=cex.scale,cex.lab=cex.scale,cex=cex.scale)
    title(main=paste("linkage:",method.linkage,", distance:",method.dist),cex.main=cex.scale)
  }

########################################
  ##  heatmap

  if(heatmap){
    require(sma)
    if(pam || h.clust) x11()
    if(clusterOn=="samples"){
      ## rc <- rainbow(nrow(t(eset)), start=0, end=.3)
      ##cc <- rainbow(ncol(t(eset)), start=0, end=.3)
      heatmap(t(eset),distfun=dist,hclustfun=hclust.func, Rowv=rowv,Colv=colv, scale=scaleH, col=col.heatmap, cexRow =cex.scale, cexCol =cex.scale) #,RowSideColors = rc, ColSideColors = cc,col = cm.colors(256))
      if(class(exprSet)=="ExpressionSet") title(main=paste("Cluster",cl.cluster))
      if(save.plot) dev.print(device=pdf, file=paste("heatmap_cluster",cl.cluster,".pdf", sep=""))
    }else{
      heatmap(eset,distfun=dist,Rowv=rowv,Colv=colv)

      if(save.plot) dev.print(device=pdf, file="heatmap.pdf")

    }
    
  }
  
#######################################
## divisive clustering

  if(div.clust){
    if(pam | h.clust) x11()
    diana.dist <- diana(dist.clust,diss=T)
    plot(diana.dist,main=paste("divisive cluster,",method.dist),cex.axis=cex.scale,cex.lab=cex.scale)
  }

#######################################
## principal component analysis
  
  if(pca.clust){
    ## pc.clust <- prcomp(dist.clust,scale=F,center=T)
    if(pc.ids=="character") cluster.id <- letters[1:n.classes]
    if(pc.ids=="numeric") cluster.id <- as.character(1:n.classes)
    pc.clust <- prcomp(eset,scale=scale,center=center)
    if(pam | h.clust | div.clust | heatmap) x11()
    plot(pc.clust,cex.axis=cex.scale,cex.lab=cex.scale)
    x11()
    ## if(!subset) plot(pc.clust$x[,1],pc.clust$x[,2])
    print("PCA plot characters are as follows:")
    print(paste(class.names[1], "=",  cluster.id[1]))
    plot(pc.clust$x[class.labels==class.names[1],1],pc.clust$x[class.labels==class.names[1],2],xlim=c(min(pc.clust$x[,1]),max(pc.clust$x[,1])),ylim=c(min(pc.clust$x[,2]),max(pc.clust$x[,2])),pch=cluster.id[1],xlab="2nd pc",ylab="1st pc",cex.axis=cex.scale,cex.lab=cex.scale,cex=cex.scale)
    title(main="Principal components: \n",cex.main=cex.scale)
    mtext(paste(class.names,"=",cluster.id, collapse=" , "),cex=cex.scale)
    for(i in 2:n.classes){
      text(pc.clust$x[class.labels==class.names[i],1],pc.clust$x[class.labels==class.names[i],2],cluster.id[i],col=i,cex=cex.scale)
      print(paste(class.names[i],"=", cluster.id[i]))
    }
  }
  
}
