PlateReaderCurves

Purpose

This package is for working with the output from optical platereaders.

Status

This is very early development.

Plans

  • [X] Data structure to hold reader curve
  • [X] Plots recipe to plot a reader curve
  • [X] Functions to fit a model to the reader curve and extract the maximal slope
  • [X] Data structure to hold a fit to the reader curve
  • [X] Plots recipe to plot a creader curve together with the fit and derived slope
  • [X] Data structure to hold a plate of reader curves, fits and slopes
  • [X] Plots Recipe to plot a plate of reader curves (and fits and slopes)
  • [ ] Data structure to hold relative activity of 2 wells
  • [ ] Plots recipe to plot relative activity of 2 wells
  • [ ] Parsers for output files from readers I use
  • [ ] Fit functions:
    • [X] Trimed linear regression
    • [X] Splite fit
    • [ ] B-spline fit
    • [ ] Exponential asymptote
    • [ ] 5 parameter logistic

Tutorial

Create a reader curve and plot it:

using PlateReaderCurves, Plots
s1 = collect(0:10:100)
y1 = PlateReaderCurves.rc_exp(s1, 4, 100, 0.05)
A01 = ReaderCurve(well_name = "A01",
                      kinetic_time = s1,
                      reader_value = y1,
                      time_unit = "sec",
                      value_unit = "OD405nm",
                      )
plot(A01)

Fitting a readercurve

Fitting a reader curve returns a ReaderCurveFit. This contains the original reader curve, and the fitted function, which can be used for prediction. It also contains the "slope" and "intercept" of the maximal slope of he fitted function in the observed x-range.

A01_fit = PlateReaderCurves.rc_fit(A01,"linreg_trim")

collect(A01_fit.predict.(1:10))

plot(A01_fit)

Fitting methods

We implement different fitting methods:

  • max_slope: maximal observed slope between adjacent measurements
  • linreg_trim: linear regression. Optionally trimmed on fraction of y-range
  • smooth_spline: smoothing spline fit
using SmoothingSplines
A01_fit = rc_fit(A01,"linreg_trim");
A01_fit2 = rc_fit(A01,"max_slope");
A01_fit3 = rc_fit(A01,"smooth_spline"; lambda = 250);

plot(plot(A01), plot(A01_fit), plot(A01_fit2), plot(A01_fit3))

Missing values

For some types of experiments, the reader can not report a value, but only that the value is OVERFLOW or UNDERFLOW. There are represented as Inf and -Inf respectively. Values missing for other reasons are encoded as NaN. In this way, we stay within the floating point types.

Non-finite values are ignored in fitting and plotted at the max (Inf) or min (-Inf) of the other values or 0 for NaN. All Inf curves are plotted at 1 and all -Inf curves are plotted at 0.

using PlateReaderCurves, Plots
s1 = collect(0:.1:2)
A02 = ReaderCurve(well_name = "A02",
	kinetic_time = s1,
	reader_value = replace( 2 .* s1, .6 => NaN, 1.2 => Inf, 1.4=> -Inf),
	time_unit = "sec",
	value_unit = "OD405nm",
)
A02_fit1 = rc_fit(A02, "linreg_trim")
plot(plot(A02), plot(A02_fit1))
using PlateReaderCurves, Plots
s1 = collect(0:.1:2)
A03 = ReaderCurve(well_name = "A03",
	kinetic_time = s1,
	reader_value = repeat([NaN], length(s1)),
	time_unit = "sec",
	value_unit = "OD405nm",
)
A04 = ReaderCurve(well_name = "A04",
	kinetic_time = s1,
	reader_value = repeat([Inf], length(s1)),
	time_unit = "sec",
	value_unit = "OD405nm",
)
A05 = ReaderCurve(well_name = "A05",
	kinetic_time = s1,
	reader_value = repeat([-Inf], length(s1)),
	time_unit = "sec",
	value_unit = "OD405nm",
)
plot(plot(A03), plot(A04), plot(A05))

Plotting plates

API

PlateReaderCurves.ReaderCurveType
ReaderCurve: Datastructure for holding reader curves
Fields:
well_name::String = "well"
kinetic_time::Array
reader_value::Array{Union{Missing, Real}}
reader_temperature::Array{Union{Missing, Real}} = [missing]
time_unit::String
value_unit::String
temperature_unit::String = "C"
source
PlateReaderCurves.ReaderCurveFitType
ReaderCurveFit: Datastructure for holding reader curves and corresponding fits
Fields:
readercurve::ReaderCurve the input readercurve
fit_method::String name of method to fit (linreg_trim, )
fit_input_parameters::NamedTuple parameters given to fit method
predict::Function fitted function. Can be used to predict new fitted values
slope::Real max slope
intercept::Real intercept of max slope curve
fit_mean_residual::Real average absolute residuals of fit and read
source
PlateReaderCurves.ReaderPlateType
ReaderPlate: Structure representing a readerplate
readerplate_id::String  globally unique eg from UUIDs.uuid4()
readerplate_barcode::String  can be ""
readerfile_name::String
readerplate_number::Int  number in readerfile
readerplate_geometry::Int  96, 384
readercurves::Array{ReaderCurve} array of reader curves
source
PlateReaderCurves.ReaderPlateFitType
ReaderPlateFit: Structure representing a fit of curves on a readerplate
    Very similar to ReaderPlate
readerplate_id::String   globally unique eg from UUIDs.uuid4()
readerplate_barcode::String   can be ""
readerfile_name::String
readerplate_number::Int   number in readerfile
readerplate_geometry::Int  96, 384
readercurves::Array{ReaderCurveFit}
source
PlateReaderCurves.linreg_trimMethod
linreg_trim(ReaderCurve; y_low_pct=0, y_high_pct): trimmed linear regression
linreg_trim(x,y; y_low_pct=0, y_high_pct)
Skip the y_low_pct %, and y_high_pct % of the y-range.
Eg linreg_trim(x,y; 5,95) will use the central 90% of the y-range.
Note it is using the range of the y-values. Not the number of values, as a quantile would do.
Output: (intercept, slope) or ReaderCurveFit object
source
PlateReaderCurves.rc_fitMethod
rc_fit(::ReaderCurve, method::String)
Fit a readercurve.
Returns a ReaderCurveFit containing the original readercurve and a predict function that can be used to predict new values. It also contains Slope, intercept and mean residual.
See @ref ReaderCurveFit
Methods:
- linreg_trim: linear regression omitting y_low_pct and y_high_pct of y range.
- max_slope:
source