Description and usage of MsBackendTimsTof

Introduction

The Spectra package provides a central infrastructure for Mass Spectrometry (MS) data in R. The package supports interchangeable use of different backends to represent or import MS data from a variety of formats and sources (such as mzML files). The MsBackendTimsTof” package adds support for MS data from Bruker TimsTOF raw data files. This vignette shows how, and which data can be retrieved from such files.

Installation

The package depends on the OpenTIMS C++ library to access data in timsTOF Pro data format (TDF). This support is provided by the opentimsr R package, which gets installed as a dependency when installing MsBackendTimsTof:

BiocManager::install("MsBackendTimsTof")

Some variables in the data files can only be accessed after setting up a converter library. Two options are available. The first is to use the open-source library built into opentimsr:

library(MsBackendTimsTof)

setup_converter_library()

The setup_converter_library() function is also run on package startup hence, to use the default, no manual call to setup_converter_library() is needed.

Alternatively it is possible to use the proprietary Bruker converter library, which can be downloaded and cached through BiocFileCache or downloaded to a personal folder. Note that this library is currently only available for Windows and Linux (no macOS support).

setup_converter_library(opensource = FALSE)

Accessing data from Bruker TimsTOF files

The MsBackendTimsTof package adds support for Bruker TimsTOF files to Spectra-based analysis workflows. Below we load the package which will also automatically setup the use of the open-source converter library.

library(MsBackendTimsTof)

We next load the TDF test file which is bundled within this package using the Spectra() constructor function specifying to use a MsBackendTimsTof as data backend with parameter source.

## Get the path/file name of the example file
fl <- system.file("ddaPASEF.d", package = "MsBackendTimsTof")

sps <- Spectra(fl, source = MsBackendTimsTof())
sps
## MSn data (Spectra) with 9120 spectra in a MsBackendTimsTof backend:
##        msLevel precursorMz  polarity
##      <integer>   <numeric> <integer>
## 1            1          NA         1
## 2            1          NA         1
## 3            1          NA         1
## 4            1          NA         1
## 5            1          NA         1
## ...        ...         ...       ...
## 9116         1          NA         1
## 9117         1          NA         1
## 9118         1          NA         1
## 9119         1          NA         1
## 9120         1          NA         1
##  ... 35 more variables/columns.
##  Use  'spectraVariables' to list all of them.

We thus have access to all spectra variables within the file:

spectraVariables(sps)
##  [1] "msLevel"                 "rtime"                  
##  [3] "acquisitionNum"          "scanIndex"              
##  [5] "dataStorage"             "dataOrigin"             
##  [7] "centroided"              "smoothed"               
##  [9] "polarity"                "precScanNum"            
## [11] "precursorMz"             "precursorIntensity"     
## [13] "precursorCharge"         "collisionEnergy"        
## [15] "isolationWindowLowerMz"  "isolationWindowTargetMz"
## [17] "isolationWindowUpperMz"  "frameId"                
## [19] "ScanMode"                "MsMsType"               
## [21] "TimsId"                  "MaxIntensity"           
## [23] "SummedIntensities"       "NumScans"               
## [25] "NumPeaks"                "MzCalibration"          
## [27] "T1"                      "T2"                     
## [29] "TimsCalibration"         "PropertyGroup"          
## [31] "AccumulationTime"        "RampTime"               
## [33] "Pressure"                "file"

And the full data for spectra variables can be retrieved with spectraData:

all <- spectraData(sps)
all
## DataFrame with 9120 rows and 34 columns
##        msLevel     rtime acquisitionNum scanIndex            dataStorage
##      <integer> <numeric>      <integer> <integer>            <character>
## 1            1  0.218626             NA       218 /tmp/Rtmp9lF9e5/Rins..
## 2            1  0.218626             NA       220 /tmp/Rtmp9lF9e5/Rins..
## 3            1  0.218626             NA       221 /tmp/Rtmp9lF9e5/Rins..
## 4            1  0.218626             NA       222 /tmp/Rtmp9lF9e5/Rins..
## 5            1  0.218626             NA       223 /tmp/Rtmp9lF9e5/Rins..
## ...        ...       ...            ...       ...                    ...
## 9116         1    6.7812             NA       719 /tmp/Rtmp9lF9e5/Rins..
## 9117         1    6.7812             NA       723 /tmp/Rtmp9lF9e5/Rins..
## 9118         1    6.7812             NA       726 /tmp/Rtmp9lF9e5/Rins..
## 9119         1    6.7812             NA       727 /tmp/Rtmp9lF9e5/Rins..
## 9120         1    6.7812             NA       730 /tmp/Rtmp9lF9e5/Rins..
##                  dataOrigin centroided  smoothed  polarity precScanNum
##                 <character>  <logical> <logical> <integer>   <integer>
## 1    /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 2    /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 3    /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 4    /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 5    /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## ...                     ...        ...       ...       ...         ...
## 9116 /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 9117 /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 9118 /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 9119 /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 9120 /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
##      precursorMz precursorIntensity precursorCharge collisionEnergy
##        <numeric>          <numeric>       <integer>       <numeric>
## 1             NA                 NA              NA              NA
## 2             NA                 NA              NA              NA
## 3             NA                 NA              NA              NA
## 4             NA                 NA              NA              NA
## 5             NA                 NA              NA              NA
## ...          ...                ...             ...             ...
## 9116          NA                 NA              NA              NA
## 9117          NA                 NA              NA              NA
## 9118          NA                 NA              NA              NA
## 9119          NA                 NA              NA              NA
## 9120          NA                 NA              NA              NA
##      isolationWindowLowerMz isolationWindowTargetMz isolationWindowUpperMz
##                   <numeric>               <numeric>              <numeric>
## 1                        NA                      NA                     NA
## 2                        NA                      NA                     NA
## 3                        NA                      NA                     NA
## 4                        NA                      NA                     NA
## 5                        NA                      NA                     NA
## ...                     ...                     ...                    ...
## 9116                     NA                      NA                     NA
## 9117                     NA                      NA                     NA
## 9118                     NA                      NA                     NA
## 9119                     NA                      NA                     NA
## 9120                     NA                      NA                     NA
##        frameId  ScanMode  MsMsType    TimsId MaxIntensity SummedIntensities
##      <integer> <integer> <integer> <integer>    <integer>         <integer>
## 1            1         8         0         0          734             44601
## 2            1         8         0         0          734             44601
## 3            1         8         0         0          734             44601
## 4            1         8         0         0          734             44601
## 5            1         8         0         0          734             44601
## ...        ...       ...       ...       ...          ...               ...
## 9116        52         8         0    208896          742             42368
## 9117        52         8         0    208896          742             42368
## 9118        52         8         0    208896          742             42368
## 9119        52         8         0    208896          742             42368
## 9120        52         8         0    208896          742             42368
##       NumScans  NumPeaks MzCalibration        T1        T2 TimsCalibration
##      <integer> <integer>     <integer> <numeric> <numeric>       <integer>
## 1          927       348             1    25.143   23.9875               1
## 2          927       348             1    25.143   23.9875               1
## 3          927       348             1    25.143   23.9875               1
## 4          927       348             1    25.143   23.9875               1
## 5          927       348             1    25.143   23.9875               1
## ...        ...       ...           ...       ...       ...             ...
## 9116       927       304             1    25.143   23.9898               1
## 9117       927       304             1    25.143   23.9898               1
## 9118       927       304             1    25.143   23.9898               1
## 9119       927       304             1    25.143   23.9898               1
## 9120       927       304             1    25.143   23.9898               1
##      PropertyGroup AccumulationTime  RampTime  Pressure      file
##          <integer>        <numeric> <numeric> <numeric> <integer>
## 1                1          100.008   100.008   2.57282         1
## 2                1          100.008   100.008   2.57282         1
## 3                1          100.008   100.008   2.57282         1
## 4                1          100.008   100.008   2.57282         1
## 5                1          100.008   100.008   2.57282         1
## ...            ...              ...       ...       ...       ...
## 9116             1          100.008   100.008   2.57283         1
## 9117             1          100.008   100.008   2.57283         1
## 9118             1          100.008   100.008   2.57283         1
## 9119             1          100.008   100.008   2.57283         1
## 9120             1          100.008   100.008   2.57283         1

The data is organized by individual spectra, all spectra measured within the same frame have the same value in the spectra variable "frameId". This also means that the scanIndex is not unique within a file, only within one frame:

sps$scanIndex |> anyDuplicated()
## [1] 182

The combination of frameId and scanIndex identifies each spectrum uniquely within the same file:

spectraData(sps, c("frameId", "scanIndex", "file"))
## DataFrame with 9120 rows and 3 columns
##        frameId scanIndex      file
##      <integer> <integer> <integer>
## 1            1       218         1
## 2            1       220         1
## 3            1       221         1
## 4            1       222         1
## 5            1       223         1
## ...        ...       ...       ...
## 9116        52       719         1
## 9117        52       723         1
## 9118        52       726         1
## 9119        52       727         1
## 9120        52       730         1

The inverse ion mobility data is provided by the "inv_ion_mobility" variable. This information can be extracted as a spectra variable (i.e., one value per spectrum):

## Get the ion mobility information
sps$inv_ion_mobility |> head()
## [1] 1.364833 1.362675 1.361597 1.360518 1.359439 1.358360

But can also be requested to be added to the peaksData(). Below we extract the full peaks data (i.e., all peaks variables for all spectra) and show the information of one selected spectrum:

## Request all supported peaks variables
pd <- peaksData(sps, peaksVariables(sps))
## Show the data for the spectrum number 10
pd[[10L]]
##      frame scan    tof intensity       mz inv_ion_mobility retention_time
## [1,]     1  228 315083        36 1221.931         1.354045       0.218626
## [2,]     1  228 315091       321 1221.975         1.354045       0.218626
## [3,]     1  228 315095       116 1221.997         1.354045       0.218626
## [4,]     1  228 315270        50 1222.967         1.354045       0.218626
## [5,]     1  228 315277        65 1223.005         1.354045       0.218626
## [6,]     1  228 315453        59 1223.981         1.354045       0.218626

In addition to the default "mz" and "intensity" columns with the individual peaks’ m/z and intensity values many more columns are reported.

Note however that "inv_ion_mobility" and "retention_time" have the same value for all peaks in each spectrum. Thus, these variables should be accessed not through peaksData(), but through spectraData() or using the $ operator or the dedicated rtime() function.

Each of the Spectra object represents the signal from a single scan within a TimsTOF frame. Thus, in TimsTOF data we have multiple spectra for the same retention time (frame). Below we plot the first 4 spectra from the first frame.

plotSpectra(sps[1:4])

The first 3 spectra contain only a single peak, the spectrum number 4 2 peaks. All of them are recorded in the same frame, with the same retention time, but a different inverse ion mobility time:

spectraData(sps[1:4], columns = c("frameId", "scanIndex",
                                  "rtime", "inv_ion_mobility"))
## DataFrame with 4 rows and 4 columns
##     frameId scanIndex     rtime inv_ion_mobility
##   <integer> <integer> <numeric>        <numeric>
## 1         1       218  0.218626          1.36483
## 2         1       220  0.218626          1.36268
## 3         1       221  0.218626          1.36160
## 4         1       222  0.218626          1.36052

This first frame has 180 spectra, all with the same retention time, but different inverse ion mobility time.

We can also collapse the ion mobility time dimension of the Spectra object to simulate and generate a classical LC-MS data with one spectrum per retention time. This can be done using the combineSpectra() from the Spectra package. Below we first define a factor to assign all spectra from the same frame (and original data file) to one spectra group that should be combined into a single spectrum.

## Define a factor assigning all spectra from the same frame to one group
f <- paste0(sps$frameId, sps$dataOrigin)

We can now combine the spectra within each such defined group using combineSpectra(). With parameter peaks = "union" we merge all mass (or fragment) peaks of all spectra per group into the representative spectrum. Peaks with a difference in their m/z smaller than 10 ppm (parameter ppm = 10) are reported as a single peak, with the median m/z reported as its m/z (mzFun = median) and the largest intensity as the peak’s intensity (intensityFun = max; see also the help pages for combineSpectra() and combinePeaksData() for other options and parameters).

## Combine all spectra per frame into a single spectrum
sps_merged <- combineSpectra(sps, f = f, peaks = "union", ppm = 10,
                             mzFun = median, intensityFun = max)
sps_merged
## MSn data (Spectra) with 52 spectra in a MsBackendMemory backend:
##       msLevel     rtime scanIndex
##     <integer> <numeric> <integer>
## 1           1  0.218626       218
## 2           1  0.344953       215
## 3           1  0.473940       220
## 4           1  0.614673       216
## 5           1  0.750315       218
## ...       ...       ...       ...
## 48          1   6.26716       217
## 49          1   6.39452       220
## 50          1   6.51963       220
## 51          1   6.65089       222
## 52          1   6.78120       211
##  ... 35 more variables/columns.
## Processing:
##  Switch backend from MsBackendTimsTof to MsBackendMemory [Mon Oct 26 19:33:31 2026]

There is now one spectrum per frame. Below we plot the (MS1) spectrum from the first frame.

plotSpectra(sps_merged[1L])
grid()

Importantly, for each such combined spectrum the metadata of its first spectrum is reported (in this case the first spectrum per frame).

spectraData(sps_merged)
## DataFrame with 52 rows and 36 columns
##       msLevel     rtime acquisitionNum scanIndex dataStorage
##     <integer> <numeric>      <integer> <integer> <character>
## 1           1  0.218626             NA       218    <memory>
## 2           1  0.344953             NA       215    <memory>
## 3           1  0.473940             NA       220    <memory>
## 4           1  0.614673             NA       216    <memory>
## 5           1  0.750315             NA       218    <memory>
## ...       ...       ...            ...       ...         ...
## 48          1   6.26716             NA       217    <memory>
## 49          1   6.39452             NA       220    <memory>
## 50          1   6.51963             NA       220    <memory>
## 51          1   6.65089             NA       222    <memory>
## 52          1   6.78120             NA       211    <memory>
##                 dataOrigin centroided  smoothed  polarity precScanNum
##                <character>  <logical> <logical> <integer>   <integer>
## 1   /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 2   /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 3   /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 4   /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 5   /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## ...                    ...        ...       ...       ...         ...
## 48  /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 49  /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 50  /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 51  /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
## 52  /tmp/Rtmp9lF9e5/Rins..         NA        NA         1          NA
##     precursorMz precursorIntensity precursorCharge collisionEnergy
##       <numeric>          <numeric>       <integer>       <numeric>
## 1            NA                 NA              NA              NA
## 2            NA                 NA              NA              NA
## 3            NA                 NA              NA              NA
## 4            NA                 NA              NA              NA
## 5            NA                 NA              NA              NA
## ...         ...                ...             ...             ...
## 48           NA                 NA              NA              NA
## 49           NA                 NA              NA              NA
## 50           NA                 NA              NA              NA
## 51           NA                 NA              NA              NA
## 52           NA                 NA              NA              NA
##     isolationWindowLowerMz isolationWindowTargetMz isolationWindowUpperMz
##                  <numeric>               <numeric>              <numeric>
## 1                       NA                      NA                     NA
## 2                       NA                      NA                     NA
## 3                       NA                      NA                     NA
## 4                       NA                      NA                     NA
## 5                       NA                      NA                     NA
## ...                    ...                     ...                    ...
## 48                      NA                      NA                     NA
## 49                      NA                      NA                     NA
## 50                      NA                      NA                     NA
## 51                      NA                      NA                     NA
## 52                      NA                      NA                     NA
##               tof inv_ion_mobility   frameId  ScanMode  MsMsType    TimsId
##            <list>        <numeric> <integer> <integer> <integer> <integer>
## 1          315091          1.36483         1         8         0         0
## 2          315091          1.36807         2         8         0      4096
## 3          315095          1.36268         3         8         0      8192
## 4          315091          1.36699         4         8         0     12288
## 5          315275          1.36483         5         8         0     16384
## ...           ...              ...       ...       ...       ...       ...
## 48         315091          1.36591        48         8         0    192512
## 49         315093          1.36268        49         8         0    196608
## 50         315096          1.36268        50         8         0    200704
## 51  315094,315272          1.36052        51         8         0    204800
## 52         315273          1.37238        52         8         0    208896
##     MaxIntensity SummedIntensities  NumScans  NumPeaks MzCalibration        T1
##        <integer>         <integer> <integer> <integer>     <integer> <numeric>
## 1            734             44601       927       348             1    25.143
## 2            751             45260       927       323             1    25.143
## 3            931             45496       927       335             1    25.143
## 4            965             42886       927       332             1    25.143
## 5           1114             43828       927       335             1    25.143
## ...          ...               ...       ...       ...           ...       ...
## 48           757             45204       927       344             1   25.1431
## 49          1187             43818       927       304             1   25.1431
## 50           796             40630       927       296             1   25.1431
## 51           920             42973       927       309             1   25.1431
## 52           742             42368       927       304             1   25.1430
##            T2 TimsCalibration PropertyGroup AccumulationTime  RampTime
##     <numeric>       <integer>     <integer>        <numeric> <numeric>
## 1     23.9875               1             1          100.008   100.008
## 2     23.9875               1             1          100.008   100.008
## 3     23.9875               1             1          100.008   100.008
## 4     23.9878               1             1          100.008   100.008
## 5     23.9878               1             1          100.008   100.008
## ...       ...             ...           ...              ...       ...
## 48    23.9895               1             1          100.008   100.008
## 49    23.9895               1             1          100.008   100.008
## 50    23.9895               1             1          100.008   100.008
## 51    23.9895               1             1          100.008   100.008
## 52    23.9898               1             1          100.008   100.008
##      Pressure      file
##     <numeric> <integer>
## 1     2.57282         1
## 2     2.57282         1
## 3     2.57282         1
## 4     2.57282         1
## 5     2.57282         1
## ...       ...       ...
## 48    2.57283         1
## 49    2.57283         1
## 50    2.57283         1
## 51    2.57283         1
## 52    2.57283         1

Also, combineSpectra returns a Spectra object with an in-memory backend, hence all data is loaded into memory. The original MsBackendTimsTof however is an on-disk backend, which reads peaks and spectra variables from the original data file(s) upon request. Modifying spectra variables within the raw data files is not possible (and also not desired), but, by directly extending the MsBackendCached backend from the Spectra package MsBackendTimsTof supports changing or adding spectra variables by caching them locally within the object. Below we add a new spectra variable to the object.

## Add a new spectra variable
sps$new_variable <- seq_along(sps)

This new variable is now available within the object and can be extract like any other spectra variable.

spectraVariables(sps)
##  [1] "msLevel"                 "rtime"                  
##  [3] "acquisitionNum"          "scanIndex"              
##  [5] "dataStorage"             "dataOrigin"             
##  [7] "centroided"              "smoothed"               
##  [9] "polarity"                "precScanNum"            
## [11] "precursorMz"             "precursorIntensity"     
## [13] "precursorCharge"         "collisionEnergy"        
## [15] "isolationWindowLowerMz"  "isolationWindowTargetMz"
## [17] "isolationWindowUpperMz"  "new_variable"           
## [19] "frameId"                 "ScanMode"               
## [21] "MsMsType"                "TimsId"                 
## [23] "MaxIntensity"            "SummedIntensities"      
## [25] "NumScans"                "NumPeaks"               
## [27] "MzCalibration"           "T1"                     
## [29] "T2"                      "TimsCalibration"        
## [31] "PropertyGroup"           "AccumulationTime"       
## [33] "RampTime"                "Pressure"               
## [35] "file"
sps$new_variable |> head()
## [1] 1 2 3 4 5 6

Analogously it is also possible to change existing spectra variables. Below we shift each retention time by 10 seconds.

rtime(sps) |> head()
## [1] 0.218626 0.218626 0.218626 0.218626 0.218626 0.218626
sps$rtime <- rtime(sps) + 10
rtime(sps) |> head()
## [1] 10.21863 10.21863 10.21863 10.21863 10.21863 10.21863

Session information

sessionInfo()
## R version 4.6.1 (2026-06-24)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 26.04.1 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so;  LAPACK version 3.12.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [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       
## 
## time zone: Etc/UTC
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats4    stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
## [1] MsBackendTimsTof_0.99.0 Spectra_1.23.6          BiocParallel_1.47.0    
## [4] S4Vectors_0.51.10       BiocGenerics_0.59.12    generics_0.1.4         
## [7] BiocStyle_2.41.0       
## 
## loaded via a namespace (and not attached):
##  [1] sass_0.4.10            MsCoreUtils_1.25.4     RSQLite_3.53.3        
##  [4] digest_0.6.39          magrittr_2.0.5         evaluate_1.0.5        
##  [7] fastmap_1.2.0          blob_1.3.0             jsonlite_2.0.0        
## [10] ProtGenerics_1.45.0    DBI_1.3.0              BiocManager_1.30.27   
## [13] codetools_0.2-20       jquerylib_0.1.4        cli_3.6.6             
## [16] rlang_1.3.0            opentimsr_1.2.0        bit64_4.8.6           
## [19] cachem_1.1.0           yaml_2.3.12            otel_0.2.0            
## [22] tools_4.6.1            parallel_4.6.1         memoise_2.0.1         
## [25] dplyr_1.2.1            buildtools_1.0.0       vctrs_0.7.3           
## [28] R6_2.6.1               lifecycle_1.0.5        fs_2.1.0              
## [31] IRanges_2.47.5         bit_4.6.0              clue_0.3-68           
## [34] MASS_7.3-66            cluster_2.1.8.3        pkgconfig_2.0.3       
## [37] bslib_0.12.0           pillar_1.11.1          Rcpp_1.1.2            
## [40] data.table_1.18.6.1    glue_1.8.1             xfun_0.62             
## [43] tibble_3.3.1           tidyselect_1.2.1       sys_3.4.3             
## [46] knitr_1.52             htmltools_0.5.9        rmarkdown_2.32        
## [49] maketools_1.3.2        compiler_4.6.1         MetaboCoreUtils_1.21.2