Contents

!!!Caution work in progress!!!

1 Introduction

Function optimizes Extraction windows so we have the same number of precursor per window. To do it uses spectral library or nonredundant blib.

2 Prerequisites

specL contains a function specL::cdsw.

## Loading required package: DBI
## Loading required package: protViz
## Loading required package: RSQLite
## Loading required package: seqinr
## 
## Attaching package: 'specL'
## The following objects are masked from 'package:protViz':
## 
##     plot.psm, plot.psmSet, summary.psmSet

3 Classical Method based on quantile

# moves the windows start and end to regions where no peaks are observed
.makenewfromto <- function( windfrom, empty , isfrom=TRUE){
  newfrom <- NULL
  for(from in windfrom){
    idx <- which.min(abs(from - empty))
    startmass <- 0
    if(isfrom){
      if(empty[idx] < from) {
        startmass <- empty[idx]
      } else {
        startmass <- empty[idx-1]
      }
    }else{
      if(empty[idx] > from) {
        startmass <- empty[idx]
      } else {
        startmass <- empty[idx+1]
      }
    }
    newfrom <- c(newfrom, round(startmass,digits=1))
  }
  return(newfrom)
}

.cdsw_compute_breaks <- 
  function(xx, nbins){
    q <- quantile(xx, seq(0, 1, length = nbins + 1))
    q[1] <- q[1] - 0.5
    q[length(q)] <- q[length(q)] + 0.5
    q <- round(q)
  }


cdsw <-
  function(x, massrange = c(300,1250), n = 20, overlap = 1.0, FUN, ...) {
    if (class(x) == "psmSet") {
      x <- unlist(lapply(x, function(x) {
        x$pepmass
      }))
    } else if (class(x) == 'specLSet') {
      x <- unlist(lapply(x@ionlibrary, function(xx) {
        xx@q1
      }))
    }
    # x should be numeric
    if (class(x) != "numeric") {
      warning("can not compute quantils. 'x' is not numeric.")
      return (NULL)
    }
    
    x <- x[x > massrange[1] & x < massrange[2]]
    
    q <- FUN(xx=x, nbins=n)
    
    idx <- 1:n
    from <- q[idx] - overlap * 0.5
    to <- q[idx + 1] + overlap * 0.5
    width <- 0.5 * (to - from)
    mid <- from + width
    h <- hist(x, breaks = q, ...)
    data.frame(from, to, mid, width, counts = h$counts)
    
    
  }
cdsw(exampledata, 
     freq=TRUE, 
     overlap = 0, 
     main = "peptideStd", xlab='pepmass', FUN=.cdsw_compute_breaks)

##     from   to    mid width counts
## 0%   301  384  342.5  41.5    586
## 5%   384  420  402.0  18.0    591
## 10%  420  449  434.5  14.5    583
## 15%  449  476  462.5  13.5    599
## 20%  476  500  488.0  12.0    565
## 25%  500  524  512.0  12.0    604
## 30%  524  547  535.5  11.5    566
## 35%  547  572  559.5  12.5    598
## 40%  572  598  585.0  13.0    591
## 45%  598  625  611.5  13.5    577
## 50%  625  651  638.0  13.0    603
## 55%  651  682  666.5  15.5    575
## 60%  682  713  697.5  15.5    594
## 65%  713  745  729.0  16.0    574
## 70%  745  783  764.0  19.0    595
## 75%  783  825  804.0  21.0    572
## 80%  825  881  853.0  28.0    592
## 85%  881  948  914.5  33.5    583
## 90%  948 1045  996.5  48.5    592
## 95% 1045 1250 1147.5 102.5    586

4 Iterative Distribution Mixing based cdsw

4.1 Requirements

  • Mass range can be specified (mass_range)
  • Maximal window size can be specified (max_window_size). This is because windows should not be to large because of optimal collision energy (personal communication by Bernd R.).
  • Minimal window size can be specified (min_window_size).
  • target number of windows can be specified (nr_windows).
  • boundaries between windows are placed in regions were no precursors are observed.

4.2 Contrains and Objective Function

.cdsw_objective <- function(splits, data){
  counts <- hist(data, breaks=splits,plot=FALSE)$counts
  nbins<-length(splits)-1
  optimumN <- length(data)/(length(splits)-1)
  optimumN<-rep(optimumN,nbins)
  
  score2 <-sqrt(sum((counts - optimumN)^2))
  score1 <- sum(abs(counts - round(optimumN)))
  return(list(score1=score1,score2 = score2, counts=counts, optimumN=round(optimumN)))
}

.cdsw_hardconstrain <- function(splits, minwindow = 5, maxwindow=50){
  
  difsp<-diff(splits)
  return(sum(difsp >= minwindow) == length(difsp) & sum(difsp <= maxwindow) == length(difsp))
}

4.3 Construction Heuristic

.cdsw_compute_sampling_breaks <- function(xx, nbins=35, maxwindow=150, minwindow = 5, plot=TRUE){
  breaks <- nbins+1
  #xx <- x
  
  #xx<-xx[xx >=310 & xx<1250]
  # TODO(wew): there is something insconsitent with the nbins parameter
  qqs <- quantile(xx,probs = seq(0,1,by=1/(nbins)))
  
  plot(1:breaks, qqs, type="b" , 
       sub=".cdsw_compute_sampling_breaks")
  legend("topleft", legend = c(paste("maxwindow = ", maxwindow),
                               paste("nbins = ", breaks) ))
  
  
  # equidistant spaced bins
  unif <- seq(min(xx),max(xx),length=(breaks))
  lines(1:breaks,unif,col=2,type="b")
  
  if(!.cdsw_hardconstrain(unif,minwindow = 5, maxwindow)){
    warning("there is no way to generate bins given minwindow " , minwindow, "maxwindow", maxwindow, " breaks" , breaks, "\n")
  }else{
    .cdsw_hardconstrain(qqs,minwindow = 5, maxwindow)
  }
  
  mixeddata <- xx
  it_count <- 0
  error <- 0
  
  while(!.cdsw_hardconstrain(qqs,minwindow = 5, maxwindow)){
    it_count <- it_count + 1
    uniformdata<-runif(round(length(xx)/20), min=min(xx), max=max(xx))
    mixeddata<-c(mixeddata,uniformdata)
    
    qqs <- quantile(mixeddata,probs = seq(0,1,by=1/(nbins)))
    lines(1:breaks,qqs,type="l", col="#00DD00AA")
    error[it_count] <-.cdsw_objective(qqs, xx)$score1
    
  }
  
  lines(1:breaks,qqs,type="b", col="#FF1111AA")
  plot(error, xlab="number of iteration", sub=".cdsw_compute_sampling_breaks")
  
  
  qqs <- as.numeric(sort(round(qqs)))
  qqs[1]  <- qqs[1] - 0.5
  qqs[length(qqs)]  <- qqs[length(qqs)] + 0.5
  
  round(qqs, 1)
}

4.4 Evaluation

4.4.1 Comparizon to Classical Approach

op <- par(mfrow=c(2,2))
par(mfrow=c(3,1))
wind <- cdsw(exampledata, 
             freq=TRUE,
             plot=TRUE,
             overlap = 0, 
             n=35,
             massrange = c(350,1250),
             sub='sampling based',
             main = "peptideStd", xlab='pepmass', FUN=function(...){.cdsw_compute_sampling_breaks(...,maxwindow = 50)})
## Warning in plot.histogram(r, freq = freq1, col = col, border = border, angle
## = angle, : the AREAS in the plot are wrong -- rather use 'freq = FALSE'

readjustWindows <- function(wind ,ms1data, breaks=10000, maxbin = 5){
  res <- hist(ms1data, breaks=breaks)
  abline(v=wind$from,col=2,lty=2)
  abline(v=wind$to,col=3,lty=2)
  
  empty <- res$mids[which(res$counts < maxbin )]
  newfrom <- .makenewfromto(wind$from , empty)
  newto <- .makenewfromto(wind$to , empty , isfrom=FALSE )
  
  plot(res,xlim=c(1060,1065))
  abline(v = newfrom,lwd=0.5,col="red")
  abline(v = newto , lwd=0.5,col="green")
  plot(res,xlim=c(520,550))
  abline(v = newfrom,lwd=0.5,col="red")
  abline(v = newto , lwd=0.5,col="green")
  
  width <- (newto - newfrom) * 0.5
  mid <- (newfrom + newto)*0.5
  newCounts <- NULL
  for(i in 1:length(newfrom))
  {
    newCounts <- c(newCounts,sum(ms1data >= newfrom[i] & ms1data <= newto[i]))
  }
  data.frame(newfrom, newto, mid, width, counts =newCounts)

}
readjustWindows(wind,exampledata)

##    newfrom  newto     mid width counts
## 1    349.5  379.1  364.30 14.80    305
## 2    379.0  403.1  391.05 12.05    355
## 3    403.0  424.1  413.55 10.55    366
## 4    424.0  444.1  434.05 10.05    418
## 5    444.0  463.1  453.55  9.55    391
## 6    463.0  481.1  472.05  9.05    433
## 7    481.0  498.1  489.55  8.55    404
## 8    498.0  514.0  506.00  8.00    411
## 9    514.0  531.0  522.50  8.50    408
## 10   530.9  548.0  539.45  8.55    428
## 11   547.9  565.0  556.45  8.55    412
## 12   565.0  582.0  573.50  8.50    397
## 13   582.0  600.0  591.00  9.00    405
## 14   600.0  618.0  609.00  9.00    394
## 15   618.0  636.0  627.00  9.00    403
## 16   636.0  654.0  645.00  9.00    407
## 17   654.0  676.0  665.00 11.00    386
## 18   676.0  694.0  685.00  9.00    371
## 19   694.0  714.0  704.00 10.00    369
## 20   714.0  736.0  725.00 11.00    387
## 21   736.0  757.0  746.50 10.50    387
## 22   757.0  782.0  769.50 12.50    351
## 23   782.0  805.0  793.50 11.50    325
## 24   805.0  832.0  818.50 13.50    354
## 25   832.0  861.0  846.50 14.50    302
## 26   861.0  891.0  876.00 15.00    281
## 27   891.0  921.1  906.05 15.05    287
## 28   920.9  952.1  936.50 15.60    257
## 29   952.0  987.1  969.55 17.55    242
## 30   987.0 1025.0 1006.00 19.00    209
## 31  1025.0 1064.0 1044.50 19.50    198
## 32  1064.0 1105.0 1084.50 20.50    194
## 33  1105.0 1150.0 1127.50 22.50    124
## 34  1150.0 1200.0 1175.00 25.00    104
## 35  1200.0 1249.5 1224.75 24.75     71
cdsw(exampledata, 
     freq=TRUE,
     plot=TRUE,
     n=35,
     overlap = 0, 
     sub='quantile based',
     main = "peptideStd", xlab='pepmass', FUN=.cdsw_compute_breaks)
## Warning in plot.histogram(r, freq = freq1, col = col, border = border, angle
## = angle, : the AREAS in the plot are wrong -- rather use 'freq = FALSE'

##           from   to    mid width counts
## 0%         301  363  332.0  31.0    332
## 2.857143%  363  390  376.5  13.5    343
## 5.714286%  390  410  400.0  10.0    328
## 8.571429%  410  429  419.5   9.5    331
## 11.42857%  429  445  437.0   8.0    339
## 14.28571%  445  462  453.5   8.5    347
## 17.14286%  462  476  469.0   7.0    339
## 20%        476  489  482.5   6.5    315
## 22.85714%  489  503  496.0   7.0    333
## 25.71429%  503  517  510.0   7.0    353
## 28.57143%  517  531  524.0   7.0    338
## 31.42857%  531  544  537.5   6.5    316
## 34.28571%  544  557  550.5   6.5    337
## 37.14286%  557  572  564.5   7.5    341
## 40%        572  586  579.0   7.0    337
## 42.85714%  586  601  593.5   7.5    324
## 45.71429%  601  617  609.0   8.0    350
## 48.57143%  617  632  624.5   7.5    332
## 51.42857%  632  646  639.0   7.0    321
## 54.28571%  646  663  654.5   8.5    342
## 57.14286%  663  682  672.5   9.5    340
## 60%        682  698  690.0   8.0    336
## 62.85714%  698  716  707.0   9.0    323
## 65.71429%  716  736  726.0  10.0    350
## 68.57143%  736  754  745.0   9.0    328
## 71.42857%  754  776  765.0  11.0    335
## 74.28571%  776  800  788.0  12.0    336
## 77.14286%  800  825  812.5  12.5    327
## 80%        825  855  840.0  15.0    344
## 82.85714%  855  891  873.0  18.0    330
## 85.71429%  891  928  909.5  18.5    334
## 88.57143%  928  969  948.5  20.5    340
## 91.42857%  969 1029  999.0  30.0    337
## 94.28571% 1029 1097 1063.0  34.0    332
## 97.14286% 1097 1250 1173.5  76.5    336

4.4.2 Comparizon using different MaxWindowSize

op <-par(mfrow=c(4,3))
res <- lapply(c(75,150,300, 800), function(mws){
  cdsw(exampledata, 
       freq=TRUE,
       plot=TRUE,
       overlap = 0, 
       main = paste("max window size", mws), xlab='pepmass', 
       FUN=function(...){
         .cdsw_compute_sampling_breaks(...,maxwindow = mws)
       })
})

5 Chaning nr bins

op <-par(mfrow=c(4,3))
res <- lapply(c(20,25,30, 40), function(nbins){
  cdsw(exampledata, 
       freq=TRUE,
       plot=TRUE,
       n=nbins,
       overlap = 0, 
       main = paste("nr bins", nbins), xlab='pepmass', 
       FUN=function(...){
         .cdsw_compute_sampling_breaks(...,maxwindow = 100)
       })
})

6 Session info

Here is the output of sessionInfo() on the system on which this document was compiled:

## R version 3.5.2 (2018-12-20)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.5 LTS
## 
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.8-bioc/R/lib/libRblas.so
## LAPACK: /home/biocbuild/bbs-3.8-bioc/R/lib/libRlapack.so
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=C              
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] specL_1.16.1     seqinr_3.4-5     RSQLite_2.1.1    protViz_0.4.0   
## [5] DBI_1.0.0        BiocStyle_2.10.0
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_1.0.0         bookdown_0.9       codetools_0.2-16  
##  [4] digest_0.6.18      MASS_7.3-51.1      magrittr_1.5      
##  [7] evaluate_0.12      stringi_1.2.4      blob_1.1.1        
## [10] rmarkdown_1.11     tools_3.5.2        ade4_1.7-13       
## [13] bit64_0.9-7        stringr_1.3.1      bit_1.1-14        
## [16] xfun_0.4           yaml_2.2.0         compiler_3.5.2    
## [19] BiocManager_1.30.4 memoise_1.1.0      htmltools_0.3.6   
## [22] knitr_1.21