1 Description

This R notebook contains data and analysis regarding physiological measurements obtained from chemostat cultivations of Ralstonia eutropha (a.k.a. Cupriavidus necator).

2 Libraries

suppressPackageStartupMessages({
  library(lattice)
  library(latticeExtra)
  library(latticetools)
  library(tidyverse)
})

3 Chemostat cultivation, biomass and growth rate

3.1 Import and reshape cultivation data

First we load the three cultivation data tables. These contain all four limiting conditions. We are thinning out the OD measurement data by 75% so that file sizes become smaller and more plottable.

# load chemostat measurements
df_chem <- read.csv("../data/input/20180921_chemostat_OD.csv") %>%
  
  # remove outlier data points originating from sampling
  filter(!od_value > 0.6) %>%
  
  # thinning data to reduce file size
  slice_sample(n = 4000)

3.2 OD and growth rate

The next step is to plot the OD720 and growth rate for all cultivations.

plot_OD <- xyplot(od_value ~ batchtime_h | condition, 
  arrange(df_chem, batchtime_h),
  groups = replicate, par.settings = custom.colorblind(),
  layout = c(1,4), as.table = TRUE,
  type = "l", xlim = c(0, 335),
  cols = custom.colorblind()$superpose.polygon$col[1:4],
  between = list(x = 0.5, y = 0.5), lwd = 2,
  ylim = c(-0.06, 0.86), ylab = expression("OD"[720*nm]),
  panel = function(x, y, cols, ...) {
    panel.xyplot(x, y, col = cols[panel.number()], ...)
  }
)

plot_dil <- xyplot(dilution_rate ~ batchtime_h | condition, 
  filter(df_chem, replicate == 1), 
  par.settings = custom.colorblind(), type = "l",
  between = list(x = 0.5, y = 0.5), ylim = c(-0.03, 0.43),
  xlab = "time [h]", ylab = expression("µ [h"^-1*"]"),
  panel = function(x, y, ...){
    panel.grid(h = -1, v = -1, col = grey(0.9))
    panel.horizonplot(c(x, 335), c(y, max(y)), col.regions = grey(0.7, alpha = 0.5))
    arrow_x <- c(sort(x)[which(diff(sort(y)) != 0)], max(x)-1)
    panel.arrows(x0 = arrow_x, y0 = 0.4, x1 = arrow_x, y1 = 0.32,
      type = "closed", col = grey(0.5), lwd = 2, fill = grey(0.5), 
      length = 0.05, unit = "npc")
  }
)

print(doubleYScale(plot_OD, plot_dil, use.style = FALSE, add.ylab2 = TRUE, under = TRUE))

3.3 Residual substrate concentration

The residual substrate (carbon sources only) was determined using HPLC measurement. In order to merge cultivation and residual substrate measurements, we summarize average OD and growth rate for all cultivations leaving out the first 25 h batch growth phase.

df_summary <- filter(df_chem, batchtime_h > 25) %>%
  
  # summarize average OD
  group_by(condition, dilution_rate, replicate) %>%
  summarize(OD720 = mean(od_value, na.rm = TRUE)) %>%
  
  # then we need medium substrate concentration for FA, FRC, NH4CL, SUC
  mutate(c_substrate = case_when(
    condition == "ammonium" ~ 0.025,
    condition == "formate" ~ 1.0,
    condition == "fructose" ~ 0.5,
    condition == "succinate" ~ 0.5
  ))
`summarise()` has grouped output by 'condition', 'dilution_rate'. You can override using the `.groups` argument.

The residual substrate measurement is imported, and merged with the cultivation summary table. For concnetration of substrate that is really taken up is calculated by subtracting the residual substrate (mg) from feed substrate concentration (g).

df_residual <- read_csv("../data/input/20181116_chemostat_residual_substrate.csv", col_types = cols()) %>%
  rename(condition = limitation) %>%
  mutate(condition = recode(condition, `formic acid` = "formate", `Nlim - fructose` = "ammonium")) %>%
  mutate(c_residual_g_L = mean_concentration_mg.L/1000 %>% replace(., . < 0, 0))
Warning: Missing column names filled in: 'X1' [1]
# join the summary df with residual substrate data
df_summary <- left_join(df_summary, df_residual %>%
    select(condition, dilution_rate, c_residual_g_L) %>%
    filter(!duplicated(c_residual_g_L), condition != "ammonium")) %>%
  mutate(c_residual_g_L = c_residual_g_L %>% replace_na(0))
Joining, by = c("condition", "dilution_rate")
print(head(df_summary))
plot_residual <- xyplot(concentration_mg.L ~ factor(dilution_rate) | condition,
  df_residual,
  par.settings = custom.colorblind(), as.table = TRUE,
  pch = 19, ylim = c(-50, 1450), layout = c(4, 1),
  between = list(x = 0.5, y = 0.5),
  scales = list(alternating = FALSE, x = list(at = c(1,3,5))),
  xlab = expression("µ [h"^-1*"]"), ylab = "concentration [mg/L]",
  panel = function(x, y, ...) {
    panel.grid(h = -1, v = -1, col = grey(0.9))
    panel.barplot(x, y, ewidth = 0.3, lwd = 2, fill = "white", fill_alpha = 1, ...)
    panel.xyplot(x, y, alpha = 0.3, ...)
  }
)

print(plot_residual)