norm.counts <-
function(names, data, mz, rt, std.outliers, zero.missing, min.corr, max.rt, mode = "", mz.tol = 1e-3, adducts = c(), fplot){
###################
## NORMALIZATION ##
###################
cat("NORMALIZATION BY FEATURE MEDIAN...\n",sep="")
data_N     <- data;
j          <- which(apply(data,1,median)!=0)
data_N[j,] <- data_N[j,]/t(kronecker(matrix(1,ncol(data),1), matrix(apply(data_N[j,],1,median),1,length(j)))) 
j          <- which(apply(data,1,median)==0)
if (length(j)>0){
    for (i in 1:length(j)){
        data_N[j[i],] <- data[j[i],] /median(data[j[i],which(data[j[i],]!=0)])
    }
}
####################
## OUTLIER SCORES ##
####################
cat("OUTLIER DETECTION...\n")
breaks     <- c(seq(0,10,by=0.025),max(max(data_N)))
a          <- matrix(0,dim(data)[2],length(breaks)-1)
for (i in 1:dim(data)[2]) a[i,] <- hist(data_N[,i],breaks=breaks,plot=FALSE)$counts
b          <- as.matrix(hist(data_N[,1],breaks=breaks,plot=FALSE)$mids)
minhist    <- min(which(b > 0.5))
maxhist    <- max(which(b <= 2))
int_0      <- (a[,1]-median(a[,1]))/sqrt(var(a[,1]))
quants     <- matrix(0,5,dim(a)[1])
for (i in 1:dim(a)[1]) quants[,i] <- quantile(data_N[,i],c(.1,.2,.3,.4,.5))
for (i in 1:5) quants[i,] <- (quants[i,]-mean(quants[i,]))/sqrt(var(quants[i,]))
int_1      <- apply(quants,2,max)
int_2      <- apply(quants,2,min)
jj         <- which(abs(int_2)>abs(int_1))
int_1[jj]  <- int_2[jj]
int_1      <- (int_1-median(int_1))/sqrt(var(int_1))
if (std.outliers <= 0){
   cat("\t- DEACTIVATED...\n")
   inp <- 1:length(int_0)
   out <- c()
} else {
    out        <- which( (abs(int_0) > std.outliers) | (abs(int_1) > std.outliers))
    inp        <- which( (abs(int_0) <= std.outliers) & (abs(int_1) <= std.outliers))
    if (length(out) > 0){
       data_N     <- data[,inp];
       j          <- which(apply(data[,inp],1,median)!=0)
       data_N[j,] <- data_N[j,]/t(kronecker(matrix(1,ncol(data[,inp]),1), matrix(apply(data_N[j,],1,median),1,length(j)))) 
       cat("\t- Max Dev allowed=",std.outliers,"\n",sep="")
       for (i in 1:length(out)){
          cat("\t- SAMPLE #",out[i]," (",names[out[i]],") excluded: [",int_0[out[i]],",",int_1[out[i]],"]\n",sep="")
       }
    }else {
       cat("\t- Max Dev allowed=",std.outliers,"\n",sep="")
       cat("\t- NO OUTLIERS\n")
    }
}

#################
## CORRELATION ##
#################
if (mode!=""){
  if (length(adducts)==0) adducts <- adduct.list(mode)
  if (mode=="+"){
    i <- which(adducts$labels=="[M+H]")
  } else {
    i <- which(adducts$labels=="[M-H]")
  }
  diffs <- adducts$masses-adducts$masses[i]
  diffs <- sort(abs(c(diffs[setdiff(1:length(diffs),i)],1.00335,2.00670)))
}
cat("COMPUTING CORRELATION MATRIX...\n\t")
tot   <- round((dim(data_N)[1]-1)*dim(data_N)[1]/20)
corrM <- matrix(0,tot,6)
L     <- length(inp)
## WITH M/Z FILTER
if (mode!=""){
  if (!zero.missing){
    cat("- Zeros=NotMissing\n\t")
    k   <- 0
    ind <- 1
    for(i in 1:(dim(data_N)[1]-1)) {
      for(j in (i+1):dim(data_N)[1]) {
        cc5 <- abs(rt[i]-rt[j])
        if (cc5<max.rt){
          cct <- abs(mz[j]-mz[i])
          if (any(abs(diffs-cct)<mz.tol)){
            cc3 <- cor(data_N[i,],data_N[j,])
            if (cc3>=min.corr){
              corrM[ind,] <- c(i,j,cc3,0,cc5,cct)
              ind      <- ind + 1
            }
          }
        }
        if (k %% tot == 0) cat(10*k/tot,"% ",sep="")
        k = k+1
      }
    }
    cat("\n",sep="")
  } else {
    cat("- Zeros = Missing\n\t")
    data_N[which(data_N==0)] <- NA
    k   <- 0
    ind <- 1
    for(i in 1:(dim(data_N)[1]-1)) {
      for(j in (i+1):dim(data_N)[1]) {
        cc4 <- length(which(is.na(data_N[i,])|is.na(data_N[j,])))
        if (cc4 < L-1){
          cc5 <- abs(rt[i]-rt[j])
          if (cc5<max.rt){
            cct <- abs(mz[j]-mz[i])
            if (any(abs(diffs-cct)<mz.tol)){
              cc3 <- cor(data_N[i,],data_N[j,],use="pairwise.complete.obs")
              if (cc3>=min.corr){
                corrM[ind,] <- c(i,j,cc3,100*(L-cc4)/L,cc5,cct)
                ind         <- ind + 1
                if (ind>dim(corrM)[1]) corrM <- rbind(corrM,matrix(0,tot,6))
              }
            }
          }
        }
        if (k %% tot == 0) cat(10*k/tot,"% ",sep="")
        k = k+1
      }
    }
    cat("100%\n",sep="")
  }
} else {
## WITHOUT M/Z FILTER
  if (!zero.missing){
      cat("- Zeros=NotMissing\n\t")
      k   <- 0
      ind <- 1
      for(i in 1:(dim(data_N)[1]-1)) {
         for(j in (i+1):dim(data_N)[1]) {
               cc3 <- cor(data_N[i,],data_N[j,])
               cc5 <- abs(rt[i]-rt[j])
               if ( cc3>min.corr && cc5<max.rt ){
                   corrM[ind,] <- c(i,j,cc3,0,cc5,abs(mz[i]-mz[j]))
                   ind      <- ind + 1
               }
               if (k %% tot == 0) cat(10*k/tot,"% ",sep="")
               k = k+1
         }
      }
      cat("\n",sep="")
  } else {
      cat("- Zeros = Missing\n\t")
      data_N[which(data_N==0)] <- NA
      k   <- 0
      ind <- 1
      for(i in 1:(dim(data_N)[1]-1)) {
         for(j in (i+1):dim(data_N)[1]) {
               cc4 <- length(which(is.na(data_N[i,])|is.na(data_N[j,])))
               if (cc4 < L-1){
                   cc5 <- abs(rt[i]-rt[j])
                   if (cc5<max.rt){
                       cc3 <- cor(data_N[i,],data_N[j,],use="pairwise.complete.obs")
                       if (is.na(cc3)==F){
                         if (cc3>=min.corr){
                             corrM[ind,] <- c(i,j,cc3,100*(L-cc4)/L,cc5,abs(mz[i]-mz[j]))
                             ind         <- ind + 1
                             if (ind>dim(corrM)[1]) corrM <- rbind(corrM,matrix(0,tot,6))
                         }
                       }
                   }
               }
               if (k %% tot == 0) cat(10*k/tot,"% ",sep="")
               k = k+1
         }
      }
      cat("100%\n",sep="")
  }
}
corrM <- corrM[1:(ind-1),]

##############
## FIGURES  ##
##############
if (fplot){
  par(mfrow=c(2,3))
  cols <- c("black","red","blue","yellow","azure","brown","blueviolet","cyan","magenta","orange","purple")
  ## 1
  plot(int_0[1],int_1[1],pch=20, xlim=c(min(int_0),max(int_0)),ylim=c(min(int_1),max(int_1)),col="black",type="p",cex=1.5,main="(a) Outlier scores",xlab="Zero-intensity",ylab="Quantiles")
  for (i in 2:length(int_0)){
    points(int_0[i], int_1[i], col=cols[i%%11+1], pch=20,cex=1.5)
  }
  abline(h=std.outliers)
  abline(v=std.outliers)
  abline(h=-std.outliers)
  abline(v=-std.outliers)
  grid()
  ## 2
  plot(c(.1,.2,.3,.4,.5),quants[,1],type="p",col="black",cex=1.2,main="(b) Quantiles",ylab="Standardized quantiles",xlab="Probs",ylim=c(-7,7))
  lines(c(.1,.2,.3,.4,.5), quants[,1],col="black")
  for (i in 2:dim(quants)[2]){
    lines(c(.1,.2,.3,.4,.5), quants[,i],col=cols[i%%11+1])
    points(c(.1,.2,.3,.4,.5), quants[,i],col=cols[i%%11+1])
  }
  ## 3
  plot(b, a[1,],col="black", type="l", cex = 1.2, main = "(c) Intensity histograms", ylim=c(0,max(max(a))),  xlab = "Intensity", ylab = "Counts", xlim = c(0,1.5),font=2)
  for (i in 2:dim(a)[1]){
    lines(b, a[i,],col=cols[i%%11+1])
  }
  grid()
  ## 4
  hist(corrM[,3], col=heat.colors(40)[seq(40,1,-1)], breaks=30,main="(d) Correlation Histogram",xlab="Correlation",ylab="#Feature pairs")
  ## 6
  hist(corrM[,5], col=heat.colors(40), breaks=30,main="(e) RT differences histogram",xlab="RT diff (s)",ylab="#feature pairs")
  ## 5
  v   <- c()
  mzs <- seq(0.5,80,0.1)
  for (i in mzs) v<-c(v,length(which(abs(corrM[,6]-i)<0.05)))
  i <- which(v>0)
  par(cex.lab=.1)
  temp <- getOption("warn")
  options(warn=-1)
  polar.plot(log10(1+v[i])+0.001,mzs[i]*360/80,labels=seq(0,77.5,by=2.5),label.pos=seq(0,77.5,by=2.5)*360/80,rp.type="r",main="(f) M/Z differences",lwd=2,line.col=4)
  options(warn=temp)
  par(cex.lab=1)
  par(mfrow=c(1,1))
}
scores <- list(int_0 = int_0,int_1 = int_1)
return(list(corrM = corrM, out = out, inp = inp, scores = scores))
}
