This document explains how to use the functions provided by the rfret package to analyze FRET binding data from titration experiments, and determine the binding constant (Kd) of a macromolecular interaction. An example using a real-life dataset is presented and discussed.

Overview

FRET data analysis workflow

Analysis of FRET data can be broken down into the following steps, each of which rfret provides functions for:

  1. inspect raw data to detect possible outliers (function inspect_raw_data());
  2. average fluorescence intensities across technical replicates, if such replicates were measured (function fret_average_replicates());
  3. correct FRET signal of the titration experiment, using signal from blank experiments which contain no donor or no acceptor fluorophores (function fret_correct_signal());
  4. fit a binding model equation to the experimental data, to determine the binding constant Kd (function fit_binding_model()).

The fit_binding_model() function is independent of the others. It can accept any data from other types of experiments, as long as this data comes as two columns called concentration and signal.

On the other hand, all the FRET data processing functions (named with a common fret_ prefix) are designed to work together: each function produces an output that can be directly used as input for the next one, making the whole analysis free of any need for more data reformatting as long as input files are properly formatted in the first place. These functions work ideally with the pipe operator (%>%) from the magrittr package.

Raw data format

rfret is designed such that the user doesn't have to manually do any calculation or any edit to the numbers obtained from a plate reader instrument: such manipulations in spreadsheet programs are time-consuming and error-prone, and doing calculations in a spreadsheet can accidentally alter the raw data.

The raw data must be formatted like the following example. This first table shows the first 6 rows of a real-life dataset:

knitr::kable(head(rfret::fret_binding_data))

And this second table shows the last 6 rows of the same dataset:

knitr::kable(tail(rfret::fret_binding_data))

Most (if not all) plate reader instruments have an "export to CSV" feature, which is best suited to save raw data in a format usable by rfret. If offered a choice between "plate layout" and "table view", choose "table view": this will export the data in a format similar to the previous table.

The Well Row and Well Col columns present in this example dataset were created by the plate reader software used to produce this dataset, but rfret will simply ignore them and any other column except the following ones:

Your own datasets don't have to use the same column names, because rfret uses a mechanism to map the names found in the actual data files to the names it uses internally. This is achieved by providing a file in the JSON format indicating these mappings. Note that the names mapped by this file are case-sensitive.

Using this method, you won't ever need to edit column names manually in each file when you save your data (which is tedious and error-prone). However, you might need to add the concentration column manually if your plate reader software is not aware of your titration series, and to fill the content column manually as well if your plate reader software doesn't allow you to describe the contents of your plate before performing the measurements. The content column should contain, for each row, a name indicating what part of the experiment and what replicate this row belongs to, with the format type.replicate where type can be any word, and replicate must be a number. They must be separated by a dot, and there can be only one dot in the entire resulting character string. The example dataset contains the following contents:

levels(as.factor(rfret::fret_binding_data$Content))

Here is an example of a JSON file mapping column names and contents description to rfret's internal names. In such a file, you would simply have to indicate the names found in your data files in the rigth-hand side of the key-value pairs (the left-hand side being the name used internally by rfret):

{
// Only change the right-hand side of the pairs delimited by ':'.

// Map internal column names to the corresponding column names in data files.

"content": "Content",
"concentration": "concentration",
"fret_channel": "Raw Data (488-20/680-50 1)",
"acceptor_channel": "Raw Data (620-30/680-50 2)",
"donor_channel": "Raw Data (488-20/535-30 3)",

// Map internal sample types to the corresponding factors in data files.

"titration": "my_titration",
"acceptor_only": "my_acceptor_only_series",
"donor_only": "my_donor_only_series",
"buffer_only": "my_buffer_only_series"
}

This data preparation step is the only one for which you will need to use a spreadsheet program (you can also edit the CSV files in a simple text editor, but a spreadsheet displays this sort of data in a way that is much easier to navigate). This step can probably be automated in most plate reader softwares as well.

Analyzing a dataset

We first need to load the rfret and magrittr packages:

library(magrittr)
library(rfret)

Data preparation for processing

All fret_ functions in this package work by first concatenating together any number of datasets, to perform all subsequent data processing and analysis steps on a single, large internal dataframe. Any analysis must start by using the format_data() function to prepare the raw data.

The function format_data() takes either:

It also needs a parameter data_type = "fret" to indicate that we want to pre-process FRET data (because rfret can also handle FP data, and can be extended to support more data types).

It will format the data properly for subsequent processing by the other functions.

Raw data inspection

A FRET experiment provides built-in controls for the correct preparation of the titration samples. In a typical experiment, the donor-labeled molecule is kept constant at a low concentration, and the acceptor-labeled molecule is titrated across a wide concentration series prepared by serial dilutions. Fluorescence detection is sensitive enough to detect very small pipetting errors, therefore, inspecting the fluorescence intensities in the donor and acceptor channels provides an easy way to check for outliers in the series.

The function inspect_raw_data() takes the output of format_data() and outputs, for each experiment, plots of the fluorescence intensity across the titration series for the donor, acceptor and FRET channels.

Let's look at an example:

fret_binding_data %>%
    format_data(data_type = "fret") %>%
    inspect_raw_data(data_type = "fret")

In the donor channel plot, all fluorescence intensities should be equal, since the donor-labeled molecule is present at the same concentration in all samples. In the titration experiment, it is expected that the fluorescence intensity of the donor channel will decrease at high concentration of acceptor if FRET happens (because part of the donor fluorescence is transferred to the acceptor instead of being emitted).

In the acceptor channel plot, the fluorescence intensity should increase linearly with the acceptor-labeled molecule concentration across the titrations series. If the serial dilution was performed with good precision, all data points should cluster around a straight line, as in this example.

The FRET channel plot quickly tells if the data contains useful signal: the titration and acceptor_only experiments should have visible differences in fluorescence intensity at some point in the titration series. If their data points perfectly overlap, it means the data doesn't contain any useful signal.

Data processing

Automatic processing of any number of data files can be achieved using the pipe operator %>% from the magrittr package, and the three functions fret_format_data(), fret_average_replicates() and fret_correct_signal():

library(magrittr)
library(rfret)
fret_binding_data %>%
    format_data(data_type = "fret") %>%
    fret_average_replicates() %>%
    fret_correct_signal(output_directory = "./my_results")

The pipe operator allows to write this code in a natural way, one step after the other in the order of execution.

Average technical replicates

The function fret_average_replicates() takes the output of fret_format_data() and returns a dataset where the fluorescence intensity values have been averaged over the technical replicates.

Correct FRET signal

The function fret_correct_signal() applies the correction described in the following references:

It takes a reduced dataset from fret_average_replicates(), or the output of format_data() in case there are no replicates, and outputs the corrected FRET signal. Given a directory name, it will write out the corrected datasets to CSV files. These output files will have the same names as the input files, appended with _corrected. These files can be used to plot the corrected data using a different software, for example.

Curve fitting

The last step involves the function fit_binding_model(). It takes a corrected dataset (output of fret_correct_signal()) and a binding model. Currently available binding models are: "hyperbolic", "hill" and "quadratic". To use the quadratic model, the function also needs the fixed concentration of probe molecule. It returns an nls object that can be further examined with standard functions (like summary()) or used as input for make_figure().

Fitting the example dataset with the quadratic model can be achieved as follows:

fret_binding_data %>%
    format_data(data_type = "fret") %>%
    fret_average_replicates() %>%
    fret_correct_signal() %>%
    fit_binding_model(binding_model = "quadratic",
                      probe_concentration = 5)

Given a directory name, fit_binding_model() will write its results to CSV files.

Final figure

The function make_figure() takes the output of fit_binding_model() and returns figures with a plot of the binding curve and a residual plot. Given a directory name, it will write the figures in files named like the original input files. Figure are written as PNG files by default, but the function can also write PDF and SVG files.

fret_binding_data %>%
    format_data(data_type = "fret") %>%
    fret_average_replicates() %>%
    fret_correct_signal() %>%
    fit_binding_model(binding_model = "quadratic",
                      probe_concentration = 5) %>%
    make_figure(probe_concentration = 5)

Automated processing and analysis

The entire data inspection, processing and analysis can be performed by a single script run from the directory containing raw data files in CSV format. Here is an example script:

# Load required packages
library(magrittr)
library(rfret)

# List data files
my_files <- list.files(path = ".", pattern = ".csv")

# Generate raw data plots and save them in a directory called 'data_inspection'
my_files %>%
    format_data(data_type = "fret",
                skip_lines = 4, 
                metadata_json = "column_names.json") %>%
    inspect_raw_data(data_type = "fret",
                     output_directory = "./data_inspection",
                     plot_format = "png")

# The following commands will:
# 1. process raw data and save corrected data in CSV files in a
# directory 'corrected_data'
# 2. fit each dataset with a quadratic model equation, and save fit results
# in CSV files in a directory 'fit_results'
# 3. generate binding curve figures and save them as PNG files in a
# directory 'final_figures'
my_files %>%
    format_data(data_type = "fret",
                skip_lines = 4,
                metadata_json = "column_names.json") %>%
    fret_average_replicates() %>%
    fret_correct_signal(output_directory = "./corrected_data") %>%
    fit_binding_model(binding_model = "quadratic",
                      probe_concentration = 5,
                      output_directory = "./fit_results") %>%
    make_figure(probe_concentration = 5,
                output_directory = "./final_figures",
                plot_format = "png")

Automated report generation

Used in combination with R Markdown, rfret can make the process of data analysis fully integrated with lab notebook record keeping.



Guillawme/rfret documentation built on Dec. 17, 2021, 10:24 p.m.