Skip to contents




Introduction

This document demonstrates the quantification of the intact monoclonal antibody Bevacizumab using Liquid Chromatography with Diode Array Detection (LC-DAD). The files include a blank, a calibration set with 10 points from 0.5 to 5 mg/L, a QC triplicate with 2.5 mg/L, and a sample in triplicate to be quantified. The data was acquired with an Agilent 1260 Infinity II system coupled to a DAD detecter. The raw data files are in Agilent’s .d format.

basename(files)
 [1] "0.5.d"                    "1.5.d"                   
 [3] "1.d"                      "2.5.d"                   
 [5] "2.d"                      "20240815_67_BVCZ_1.d"    
 [7] "20240815_67_BVCZ_2.d"     "20240815_67_BVCZ_3.d"    
 [9] "3.5.d"                    "3.d"                     
[11] "4.5.d"                    "4.d"                     
[13] "5.d"                      "Blank.d"                 
[15] "QC_BVCZ_1608_2_5mgmL_1.d" "QC_BVCZ_1608_2_5mgmL_2.d"
[17] "QC_BVCZ_1608_2_5mgmL_3.d"

Processing Engine

The StreamFind package provides a flexible and powerful framework for processing mass spectrometry data. In this example, we will use the MassSpecEngine class to handle the LC-DAD data. The engine will be initialized with the raw files, and we will specify that the data should be centroided and processed at level 1. Note that The msconvert from ProteoWizard was used in the background to convert the files to the open format mzML.

# Starts engine for quantification
ms <- StreamFind::MassSpecEngine$new(
  metadata = list(name = "Quantification of Bevacizumab"),
  analyses = files,
  centroid = TRUE,
  levels = 1
)

# Edit to assign analysis replicate groups
ms$Analyses <- set_replicate_names(
  ms$Analyses,
  c(
    "cal_0.5",
    "cal_1",
    "cal_1.5",
    "cal_2",
    "cal_2.5",
    rep("Sample", 3),
    "cal_3",
    "cal_3.5",
    "cal_4",
    "cal_4.5",
    "cal_5",
    "Blank",
    rep("QC_2.5", 3)
  )
)

# Concentration was obtained by attempting to convert the file names to numeric
# Alternatively, you can use the setter method ms$Analyses$concentrations to manually add the
# concentration values with NA_Real_ when the concentration is to be calculated
DT::datatable(
  info(ms$Analyses)
)

Available Chromatograms

chroms = data.frame(
  "name" = unique(ms$Analyses$analyses[[1]]$chromatograms_headers$id)
)

DT::datatable(chroms)

The chromatogram of interest is the DAD1 A: Sig=214,4 Ref=off, which is the second, and we know that our analyte elutes between 250 and 400 seconds.

Workflow

ms$run(
  MassSpecMethod_LoadChromatograms_native(
    chromatograms = chroms$name[2],
    rtmin = 250,
    rtmax = 400
  )
)
plot_chromatograms(
  ms$Results$MassSpecResults_Chromatograms,
  colorBy = "replicates",
  normalized = FALSE
)
ms$run(
  MassSpecMethod_SmoothChromatograms_movingaverage(
    windowSize = 3
  )
)

ms$run(
  MassSpecMethod_CorrectChromatogramsBaseline_airpls(
    lambda = 25,
    differences = 1,
    itermax = 20
  )
)
plot_chromatograms(
  ms$Results$MassSpecResults_Chromatograms,
  colorBy = "replicates",
  normalized = FALSE
)
ms$run(
  MassSpecMethod_IntegrateChromatograms_pracma(
    merge = TRUE,
    closeByThreshold = 5,
    minPeakHeight = 10,
    minPeakDistance = 3,
    minPeakWidth = 5,
    maxPeakWidth = 50,
    minSN = 1
  )
)
plot_chromatograms_peaks(
  ms$Results$MassSpecResults_Chromatograms,
  colorBy = "replicates+targets"
)
# Note that concentration values of the calibration curve
# were automatically obtained by the file name
ms$run(
  MassSpecMethod_QuantifyChromatographicPeaks_native(
    calibration = NA_real_,
    value = "area",
    model = "linear"
  )
)
model <- ms$Results$MassSpecResults_Chromatograms$calibration_model

fitted_values <- stats::predict(model)
r_squared <- summary(model)$r.squared

dt_cal <- data.table::data.table(
  fitted_values = fitted_values,
  calibration_values = model$model$calibration,
  values = model$model$values
)

fig <- plotly::plot_ly(
  model$model,
  x = ~calibration_values,
  y = ~values,
  type = 'scatter',
  mode = 'markers',
  name = "Data"
) %>%
  add_lines(x = ~fitted_values, y = ~values, name = "Fitted Line") %>%
  layout(
    title = paste("Linear Regression (R² =", round(r_squared, 4), ")"),
    xaxis = list(title = "mg/L"),
    yaxis = list(title = "Intensity / counts"),
    showlegend = TRUE
  )

fig
peaks <- get_chromatograms_peaks(ms$Results$MassSpecResults_Chromatograms)
DT::datatable(peaks)