Summary

This vignette provides an introduction to the eposmol library. The eposmol library is a library for the scoring of lipid species identified in mass spectrometry experiments, based on their eposmol class and using their molecular properties and fragments. The library is used in the EPos-MoL R-Shiny web application where users can upload identification tables created with their software, where individual lipid species and their identified features are listed in.

Installation

In order to use the eposmol library, please install the package from an active R session first:

devtools::install_github("lifs-tools/empirical-lipid-ms-score")

For the examples in this vignette, we will use the following libraries:

Scoring and Mapping Tables

The main scoring table is located in the file Table_1.xlsx (below inst/extdata). This table contains the scoring scheme for the identification of lipid species based on their eposmol class, using their molecular properties and fragments.

scoringScheme <- read_excel(
  path = here("inst","extdata","Table_1.xlsx"),
  sheet = "Scoring scheme", 
  range = "A1:X30"
)
scoringScheme
#> # A tibble: 29 × 24
#>    Primary Secondary  Fragment Evidence ID    Unknown    FA `FA mod`    MG    DG
#>    <chr>   <chr>      <chr>    <chr>    <chr>   <dbl> <dbl>    <dbl> <dbl> <dbl>
#>  1 MS1     Molecular… NA       Nominal… L1.1       10    10       10     8    10
#>  2 MS1     Molecular… NA       Mass 5p… L1.2       30    30       30    24    30
#>  3 MS1     Molecular… NA       Mass 1p… L1.3       40    40       40    32    40
#>  4 MS1     Molecular… NA       Chromat… L1.4       10    10       10    10    10
#>  5 MS1     Molecular… NA       Ion mob… L1.5       10    10       10    10    10
#>  6 MS2     CID fragm… NA       Fragmen… L2.1       15    15       15    15    15
#>  7 MS2     CID fragm… LCF      Headgro… L2.2       12    12       12     0     0
#>  8 MS2     CID fragm… LCF      Headgro… L2.3        8     8        8     0     0
#>  9 MS2     CID fragm… LCF      Headgro… L2.4        4     4        4     0     0
#> 10 MS2     CID fragm… LCF      Headgro… L2.5        4     4        4     0     0
#> # ℹ 19 more rows
#> # ℹ 14 more variables: TG <dbl>, PL <dbl>, PIP <dbl>, CL <dbl>, LPL <dbl>,
#> #   `N-mod PL` <dbl>, oxPL <dbl>, SPB <dbl>, SP <dbl>, LSM <dbl>, CerIP <dbl>,
#> #   Gan <dbl>, `Cer OH` <dbl>, ST <dbl>

The mapping of LIPID MAPS categories and classes is in the class_map.xlsx table (below inst/extdata). This table can be used to map the lipid names from LIPID MAPS or as parsed by the Goslin library to the eposmol categories and classes. If you do not use the Goslin library to parse lipid names, or you are using currently unsupported lipid classes or categories, you will need to manually assign the correct eposmol class to your lipid scoring input before supplying it to the scoring function.

classMap <- read_excel(
  path = here("inst","extdata","class_map.xlsx"),
  sheet = "class_map", 
  range = "A1:B88"
)
classMap
#> # A tibble: 87 × 2
#>    LipidMapsCategoryOrClass EposmolCategoryOrClass
#>    <chr>                    <chr>                 
#>  1 BA                       BA                    
#>  2 BMP                      PL                    
#>  3 CAR                      FA mod                
#>  4 CL                       CL                    
#>  5 CoA                      FA mod                
#>  6 DG                       DG                    
#>  7 DLCL                     CL                    
#>  8 Docosanoids              FA mod                
#>  9 Eicosanoids              FA mod                
#> 10 EPC                      CerIP                 
#> # ℹ 77 more rows

We will transform the scoring scheme table into a long format table for easier access to the scoring values.

scoringSchemeLong <- scoringScheme %>% 
  pivot_longer(
    cols=!Primary:ID, 
    names_to = "EposmolCategoryOrClass"
  )
scoringSchemeLong
#> # A tibble: 551 × 7
#>    Primary Secondary        Fragment Evidence ID    EposmolCategoryOrClass value
#>    <chr>   <chr>            <chr>    <chr>    <chr> <chr>                  <dbl>
#>  1 MS1     Molecular prope… NA       Nominal… L1.1  Unknown                   10
#>  2 MS1     Molecular prope… NA       Nominal… L1.1  FA                        10
#>  3 MS1     Molecular prope… NA       Nominal… L1.1  FA mod                    10
#>  4 MS1     Molecular prope… NA       Nominal… L1.1  MG                         8
#>  5 MS1     Molecular prope… NA       Nominal… L1.1  DG                        10
#>  6 MS1     Molecular prope… NA       Nominal… L1.1  TG                        10
#>  7 MS1     Molecular prope… NA       Nominal… L1.1  PL                         8
#>  8 MS1     Molecular prope… NA       Nominal… L1.1  PIP                       10
#>  9 MS1     Molecular prope… NA       Nominal… L1.1  CL                        20
#> 10 MS1     Molecular prope… NA       Nominal… L1.1  LPL                       10
#> # ℹ 541 more rows

The following examples are also contained in the Table_5.xlsx file in the inst/extdata folder. The examples use the same scoring scheme as the main scoring table.

Example a

This example assigns points for identification of a Ceramide with one long chain base with 18 carbon atoms, one double bond and a fatty acyl with 16 carbon atoms and no double bond. Identification was performed in positive mode on a triple quadrupole instrument with UHPLC separation. We here assign points for nominal mass accuracy, chromatography and the primary head group CID fragment.

You can use the mapCategoryOrClass function to map the LIPID MAPS category or class to the eposmol category or class.

Platform TQ EVOQ Elite
Separation UHPLC
MS Mode MRM
Ion Mode (+)
ex_a <- "Cer 18:1;O2/16:0"
# parse name with Goslin and add eposmol class based on mapCategoryOrClass, using the default classMap
ex_a_norm <- rgoslin::parseLipidNames(ex_a)
ex_a_norm <- ex_a_norm |> mutate(eposmolCategoryOrClass = mapCategoryOrClass(ex_a_norm$Lipid.Maps.Category, classMap))
ex_a_norm
#>    Normalized.Name    Original.Name       Grammar Message Adduct Adduct.Charge
#> 1 Cer 18:1;O2/16:0 Cer 18:1;O2/16:0 Shorthand2020      NA     NA             0
#>   Lipid.Maps.Category Lipid.Maps.Main.Class Species.Name Extended.Species.Name
#> 1                  SP                   Cer  Cer 34:1;O2                   Cer
#>   Molecular.Species.Name Sn.Position.Name Structure.Defined.Name
#> 1       Cer 18:1;O2/16:0 Cer 18:1;O2/16:0                     NA
#>   Full.Structure.Name Functional.Class.Abbr Functional.Class.Synonyms
#> 1                  NA                 [Cer]           [Cer, Ceramide]
#>         Level Total.C Total.OH Total.O Total.DB     Mass Sum.Formula
#> 1 SN_POSITION      34        0       2        1 537.5121   C34H67NO3
#>   FA1.Position FA1.C FA1.OH FA1.O FA1.DB FA1.Bond.Type FA1.DB.Positions
#> 1            2    16      0     0      0         ESTER               []
#>   FA2.Position FA2.C FA2.OH FA2.O FA2.DB FA2.Bond.Type FA2.DB.Positions
#> 1           NA    NA     NA    NA     NA          <NA>             <NA>
#>   LCB.Position LCB.C LCB.OH LCB.O LCB.DB LCB.Bond.Type LCB.DB.Positions
#> 1            1    18      0     2      1           LCB               []
#>   FA3.Position FA3.C FA3.OH FA3.O FA3.DB FA3.Bond.Type FA3.DB.Positions
#> 1           NA    NA     NA    NA     NA          <NA>             <NA>
#>   FA4.Position FA4.C FA4.OH FA4.O FA4.DB FA4.Bond.Type FA4.DB.Positions
#> 1           NA    NA     NA    NA     NA          <NA>             <NA>
#>   eposmolCategoryOrClass
#> 1                     SP
ex_a_lipidCategoryOrClass <- ex_a_norm[1, "eposmolCategoryOrClass"]
nominalMassPos <- scoringSchemeLong |> 
  filter(
    Primary=="MS1" & 
    Secondary=="Molecular properties" &
    Evidence=="Nominal mass" &  
    EposmolCategoryOrClass==ex_a_lipidCategoryOrClass
  )|> 
  select(value)
separation <- scoringSchemeLong |> 
  filter(
    Primary=="MS1" &
    Secondary=="Molecular properties" &  
    Evidence=="Chromatography (RT)" &  
    EposmolCategoryOrClass==ex_a_lipidCategoryOrClass
  ) |> 
  select(value)
headGroup <- scoringSchemeLong |> 
  filter(
    Primary=="MS2" &
    Secondary=="CID fragments" &  
    Fragment=="LCF" &  
    Evidence=="Headgroup 1" &  
    EposmolCategoryOrClass==ex_a_lipidCategoryOrClass
  ) |> 
  select(value)
score <- sum(  
  nominalMassPos,
  separation,
  headGroup
)                                                                        
score
#> [1] 35

Example b

Example b assigns points for identification of a Ceramide with one long chain base and a fatty acyl, both with 18 carbon atoms and one double bond each. Identification was performed in positive and negative mode on a low resolution QTrap instrument, without prior separation. We thus assign points for nominal mass accuracy in positive and negative mode, additional CID fragments for MS2 in both modes and the primary fatty acyl fragment for negative mode.

Platform QTrap 6500
Separation NA
MS Mode Precursor Ion Scan
Ion Mode (+) & (-)
ex_b <- "Cer 18:1;O2/18:1"
ex_b_norm <- rgoslin::parseLipidNames(ex_b)
ex_b_norm <- ex_b_norm |> mutate(eposmolCategoryOrClass = mapCategoryOrClass(ex_b_norm$Lipid.Maps.Category, classMap))
ex_b_norm
#>    Normalized.Name    Original.Name       Grammar Message Adduct Adduct.Charge
#> 1 Cer 18:1;O2/18:1 Cer 18:1;O2/18:1 Shorthand2020      NA     NA             0
#>   Lipid.Maps.Category Lipid.Maps.Main.Class Species.Name Extended.Species.Name
#> 1                  SP                   Cer  Cer 36:2;O2                   Cer
#>   Molecular.Species.Name Sn.Position.Name Structure.Defined.Name
#> 1       Cer 18:1;O2/18:1 Cer 18:1;O2/18:1                     NA
#>   Full.Structure.Name Functional.Class.Abbr Functional.Class.Synonyms
#> 1                  NA                 [Cer]           [Cer, Ceramide]
#>         Level Total.C Total.OH Total.O Total.DB     Mass Sum.Formula
#> 1 SN_POSITION      36        0       2        2 563.5277   C36H69NO3
#>   FA1.Position FA1.C FA1.OH FA1.O FA1.DB FA1.Bond.Type FA1.DB.Positions
#> 1            2    18      0     0      1         ESTER               []
#>   FA2.Position FA2.C FA2.OH FA2.O FA2.DB FA2.Bond.Type FA2.DB.Positions
#> 1           NA    NA     NA    NA     NA          <NA>             <NA>
#>   LCB.Position LCB.C LCB.OH LCB.O LCB.DB LCB.Bond.Type LCB.DB.Positions
#> 1            1    18      0     2      1           LCB               []
#>   FA3.Position FA3.C FA3.OH FA3.O FA3.DB FA3.Bond.Type FA3.DB.Positions
#> 1           NA    NA     NA    NA     NA          <NA>             <NA>
#>   FA4.Position FA4.C FA4.OH FA4.O FA4.DB FA4.Bond.Type FA4.DB.Positions
#> 1           NA    NA     NA    NA     NA          <NA>             <NA>
#>   eposmolCategoryOrClass
#> 1                     SP
ex_b_lipidCategoryOrClass <- ex_b_norm[1, "eposmolCategoryOrClass"]
nominalMassPos <- scoringSchemeLong |> 
  filter(
    Primary=="MS1" & 
    Secondary=="Molecular properties" &
    Evidence=="Nominal mass" &  
    EposmolCategoryOrClass==ex_b_lipidCategoryOrClass
  ) |> 
  select(value)
headGroup1Pos <- scoringSchemeLong |> 
  filter(
    Primary=="MS2" &
    Secondary=="CID fragments" &  
    Fragment=="LCF" &  
    Evidence=="Headgroup 1" &  
    EposmolCategoryOrClass==ex_b_lipidCategoryOrClass
  ) |> 
  select(value)
nominalMassNeg <- scoringSchemeLong |> 
  filter(
    Primary=="MS1" & 
    Secondary=="Molecular properties" &
    Evidence=="Nominal mass" &  
    EposmolCategoryOrClass==ex_b_lipidCategoryOrClass
  ) |> 
  select(value)
headGroup1Neg <- scoringSchemeLong |> 
  filter(
    Primary=="MS2" &
    Secondary=="CID fragments" &  
    Fragment=="LCF" &  
    Evidence=="Headgroup 2" &  
    EposmolCategoryOrClass==ex_b_lipidCategoryOrClass
  ) |>
  select(value)
fa1Neg <- scoringSchemeLong |> 
  filter(
    Primary=="MS2" &
    Secondary=="CID fragments" &  
    Fragment=="MLF" &  
    Evidence=="Fatty acyl 1-1" &  
    EposmolCategoryOrClass==ex_b_lipidCategoryOrClass
  ) |>
  select(value)
score <- sum(  
  nominalMassPos,
  headGroup1Pos,
  nominalMassNeg,
  headGroup1Neg,
  fa1Neg
)                                                                        
score
#> [1] 60

Running the R-Shiny Webapplication

The eposmol library is used in the EPos-MoL R-Shiny web application. Once you have installed the eposmol library, the web application can be started from an R session with the following command:

eposmol::run_eposmol_app()

The web application contains additional documentation detailing the input and output formats, as well as the scoring scheme used in the library. It further provides a user interface to upload identification tables and download the scored tables. The Shiny web application expects the eposmol category or class to be provided as a string in the LipidCategoryOrClass column.

A live version of the web application is available at https://apps.lifs-tools.org/p/app/eposmol.

Please note that the web application is launched individually and exclusively for every user to provide isolation and data protection from other users. After your session ends, any uploaded data will be deleted automatically.