├── .Rbuildignore
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── DESCRIPTION
├── LICENSE
├── NAMESPACE
├── R
├── biotekCytationFunctions.R
├── biotekNeo2Functions.R
├── flowCoreMisc.R
├── flowCytometryFunctions.R
├── plateReaderFunctions.R
├── tecanInfiniteFunctions.R
└── tecanSparkFunctions.R
├── README.Rmd
├── README.md
├── examples
├── csv_save.png
├── flow_cytometry
│ └── DATA
│ │ ├── 20191121
│ │ ├── 20191121_beads.fcs
│ │ ├── 20191121_plate_layout.csv
│ │ ├── pMed_None_0_1.fcs
│ │ ├── pMed_None_0_10.fcs
│ │ ├── pMed_None_0_2.fcs
│ │ ├── pMed_None_0_3.fcs
│ │ ├── pMed_None_0_4.fcs
│ │ ├── pMed_None_0_5.fcs
│ │ ├── pMed_None_0_6.fcs
│ │ ├── pMed_None_0_7.fcs
│ │ ├── pMed_None_0_8.fcs
│ │ ├── pMed_None_0_9.fcs
│ │ ├── pNeg_None_0_1.fcs
│ │ ├── pNeg_None_0_2.fcs
│ │ ├── pNeg_None_0_3.fcs
│ │ ├── pNeg_None_0_4.fcs
│ │ ├── pNeg_None_0_5.fcs
│ │ ├── pNeg_None_0_6.fcs
│ │ ├── pNeg_None_0_7.fcs
│ │ ├── pNeg_None_0_8.fcs
│ │ ├── pStrong_None_0_1.fcs
│ │ ├── pStrong_None_0_10.fcs
│ │ ├── pStrong_None_0_11.fcs
│ │ ├── pStrong_None_0_12.fcs
│ │ ├── pStrong_None_0_2.fcs
│ │ ├── pStrong_None_0_3.fcs
│ │ ├── pStrong_None_0_4.fcs
│ │ ├── pStrong_None_0_5.fcs
│ │ ├── pStrong_None_0_6.fcs
│ │ ├── pStrong_None_0_7.fcs
│ │ ├── pStrong_None_0_8.fcs
│ │ ├── pStrong_None_0_9.fcs
│ │ ├── pWeak_None_0_1.fcs
│ │ ├── pWeak_None_0_10.fcs
│ │ ├── pWeak_None_0_11.fcs
│ │ ├── pWeak_None_0_12.fcs
│ │ ├── pWeak_None_0_1_processed.fcs
│ │ ├── pWeak_None_0_1_processed.pdf
│ │ ├── pWeak_None_0_2.fcs
│ │ ├── pWeak_None_0_3.fcs
│ │ ├── pWeak_None_0_4.fcs
│ │ ├── pWeak_None_0_5.fcs
│ │ ├── pWeak_None_0_7.fcs
│ │ ├── pWeak_None_0_8.fcs
│ │ └── pWeak_None_0_9.fcs
│ │ └── 20191121_processed
│ │ ├── 20191121_beads_BL1-H_calibration.pdf
│ │ ├── 20191121_beads_singlet_beads.pdf
│ │ ├── data_summary.csv
│ │ ├── pMed_None_0_1.fcs
│ │ ├── pMed_None_0_10.fcs
│ │ ├── pMed_None_0_10_processed.pdf
│ │ ├── pMed_None_0_1_processed.pdf
│ │ ├── pMed_None_0_2.fcs
│ │ ├── pMed_None_0_2_processed.pdf
│ │ ├── pMed_None_0_3.fcs
│ │ ├── pMed_None_0_3_processed.pdf
│ │ ├── pMed_None_0_4.fcs
│ │ ├── pMed_None_0_4_processed.pdf
│ │ ├── pMed_None_0_5.fcs
│ │ ├── pMed_None_0_5_processed.pdf
│ │ ├── pMed_None_0_6.fcs
│ │ ├── pMed_None_0_6_processed.pdf
│ │ ├── pMed_None_0_7.fcs
│ │ ├── pMed_None_0_7_processed.pdf
│ │ ├── pMed_None_0_8.fcs
│ │ ├── pMed_None_0_8_processed.pdf
│ │ ├── pMed_None_0_9.fcs
│ │ └── pMed_None_0_9_processed.pdf
└── plate_reader
│ ├── biotek_cytation
│ ├── 231031_pr_calibration_lid.xlsx
│ ├── 231031_pr_calibration_lid_parsed.csv
│ ├── 231031_pr_calibration_lid_parsed_absorbance_cfs.pdf
│ ├── 231031_pr_calibration_lid_parsed_cfs.csv
│ ├── 231031_pr_calibration_lid_parsed_fluorescence_cfs.pdf
│ ├── 231031_pr_calibration_membrane.xlsx
│ ├── 231031_pr_calibration_membrane_parsed.csv
│ ├── 231031_pr_calibration_membrane_parsed_absorbance_cfs.pdf
│ ├── 231031_pr_calibration_membrane_parsed_cfs.csv
│ ├── 231031_pr_calibration_membrane_parsed_fluorescence_cfs.pdf
│ ├── 231031_pr_calibration_nolid.xlsx
│ └── plate_layout.csv
│ ├── biotek_neo2
│ ├── biotek-neo2_example_data.xlsx
│ └── biotek-neo2_example_data_parsed.csv
│ └── tecan_spark
│ ├── 191219_calibration_membrane.csv
│ ├── 191219_calibration_membrane_parsed.csv
│ ├── 191219_calibration_membrane_parsed_absorbance_cfs.pdf
│ ├── 191219_calibration_membrane_parsed_cfs.csv
│ ├── 191219_calibration_membrane_parsed_fluorescence_cfs.pdf
│ ├── 200228_example_data.csv
│ ├── 200228_example_data_parsed.csv
│ ├── 200228_example_data_parsed_GFP.pdf
│ ├── 200228_example_data_parsed_OD.pdf
│ ├── 200228_example_data_parsed_mCherry.pdf
│ ├── 200228_example_data_parsed_norm-curve_GFP.pdf
│ ├── 200228_example_data_parsed_norm-curve_mCherry.pdf
│ ├── 200228_example_data_parsed_processed.csv
│ ├── 200228_example_layout.csv
│ └── calibration_plate_layout.csv
├── flopr.Rproj
└── man
├── biotek_parse.Rd
├── calibrate_flu.Rd
├── calibrate_od.Rd
├── cytation_parse.Rd
├── ff_append_cols.Rd
├── flu_norm.Rd
├── generate_cfs.Rd
├── get_bacteria.Rd
├── get_calibration.Rd
├── get_singlets.Rd
├── infinite_parse.Rd
├── next_blank.Rd
├── next_blank_cell.Rd
├── next_blank_row.Rd
├── next_filled.Rd
├── next_filled_cell.Rd
├── next_filled_row.Rd
├── od_norm.Rd
├── plot_trimming.Rd
├── prep_flow_frame.Rd
├── process_fcs.Rd
├── process_fcs_dir.Rd
├── process_plate.Rd
├── sparkParse.Rd
├── spark_parse.Rd
├── summarise_data.Rd
└── to_mef.Rd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 |
32 | **Additional context**
33 | Add any other context about the problem here.
34 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | .DS_Store
6 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: flopr
2 | Type: Package
3 | Title: A package for the normalisation and calibration of flow cytometry and plate reader spectrophotometry data
4 | Version: 0.4.03
5 | Authors@R: c(
6 | person("Fedorec", "Alex J H", email = "alexander.fedorec.13@ucl.ac.uk", role = c("aut", "cre")),
7 | person("Robinson", "Clare", role = c("aut")))
8 | Description: something
9 | URL: https://github.com/ucl-cssb/flopr
10 | BugReports: https://github.com/ucl-cssb/flopr/issues
11 | License: GPL-3
12 | Encoding: UTF-8
13 | LazyData: true
14 | Imports:
15 | ggplot2,
16 | gridExtra,
17 | grid,
18 | gtable,
19 | stats,
20 | utils,
21 | dplyr,
22 | rlang,
23 | tidyr,
24 | broom,
25 | mgcv,
26 | tidyselect,
27 | checkmate,
28 | readxl
29 | Suggests:
30 | flowCore,
31 | flowClust,
32 | flowStats
33 | RoxygenNote: 7.2.3
34 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(biotek_parse)
4 | export(cytation_parse)
5 | export(generate_cfs)
6 | export(infinite_parse)
7 | export(process_fcs)
8 | export(process_fcs_dir)
9 | export(process_plate)
10 | export(sparkParse)
11 | export(spark_parse)
12 | importFrom(dplyr,"%>%")
13 | importFrom(rlang,":=")
14 | importFrom(rlang,.data)
15 |
--------------------------------------------------------------------------------
/R/biotekCytationFunctions.R:
--------------------------------------------------------------------------------
1 | #' Parser for Biotek Cytation plate reader data
2 | #'
3 | #' @param data_xl path to xls or xlsx file from Biotek Cytation plate reader
4 | #' @param layout_csv path to csv file containing plate layout information
5 | #' @param timeseries Boolean flag indicating whether the data is a timeseries or
6 | #' single recording. Currently only works for timeseries=T.
7 | #'
8 | #' @return a data.frame containing the parsed plate reader data
9 | #' @export
10 | #' @importFrom rlang .data
11 | #' @importFrom dplyr %>%
12 | #'
13 | cytation_parse <- function(data_csv, layout_csv, timeseries=T) {
14 | if(stringr::str_ends(data_csv, ".xlsx") | stringr::str_ends(data_csv, ".xls")){
15 | data <- as.data.frame(readxl::read_excel(path = data_csv,
16 | col_names = F,
17 | col_types = "text"))
18 | } else if(stringr::str_ends(data_csv, ".csv")){
19 | data <- utils::read.table(data_csv, sep = ",",
20 | na.strings = c(""),
21 | header = F,
22 | stringsAsFactors = F)
23 | } else {
24 | stop("data_csv is must be a .csv, .xls or .xlsx file.")
25 | }
26 |
27 | plate_layout <- utils::read.csv(layout_csv)
28 |
29 | if(timeseries == TRUE){
30 |
31 | # find start of data blocks
32 | end_kinetic_idx <- which(data[, 1] == "End Kinetic")
33 |
34 | # find where the next block starts
35 | next_blank_idx <- next_blank_cell(end_kinetic_idx, data, col=1)
36 | next_block_start_idx <- next_filled_cell(next_blank_idx, data, col=1)
37 |
38 | end_of_file <- F
39 | all_data <- c()
40 | while (!end_of_file) {
41 | # find what is being measured
42 | block_name <- data[next_block_start_idx, 1]
43 |
44 | # start of data
45 | next_block_start_idx <- next_filled_cell(next_block_start_idx, data, col=2)
46 |
47 | # find where the end of the current measurement block is
48 | block_end_idx <- next_blank_row(next_block_start_idx, data)
49 | if(is.na(block_end_idx)){ # if we're on the last block, there is no blank row at the end, so the last row is the end of the block
50 | block_end_idx <- nrow(data)
51 | end_of_file <- T
52 | }
53 |
54 | # grab the data only for that measurement
55 | new_block <- data[(next_block_start_idx):(block_end_idx - 1), ]
56 |
57 | # manipulate the data
58 | wells <- new_block[1, -c(1,3)]
59 | new_block <- new_block[-1,-c(1,3)]
60 | names(new_block) <- wells
61 | names(new_block)[1] <- "time"
62 | new_block <- new_block %>%
63 | tidyr::pivot_longer(cols = 2:ncol(new_block),
64 | names_to = "well",
65 | values_to = "value",
66 | values_transform = list(value = as.numeric)) %>%
67 | dplyr::mutate(time = as.numeric(time),
68 | time = time*24*60*60,
69 | time = round(time/600)*600) # round to nearest 10 minute
70 |
71 | # add info for each well
72 | joined_block <- dplyr::full_join(plate_layout, new_block)
73 | joined_block$measure <- block_name
74 |
75 | #
76 | all_data <- rbind(all_data, joined_block)
77 |
78 | #
79 | next_block_start_idx <- next_filled_cell(block_end_idx + 1, data, col=1)
80 |
81 | # if we're at the end
82 | if(is.na(next_block_start_idx)){
83 | end_of_file <- T
84 | }
85 | }
86 |
87 | # rearrange data ----------------------------------------------------------
88 | out_data <- all_data %>%
89 | tidyr::pivot_wider(names_from = .data$measure, values_from = .data$value) %>% # reshape so we have a column for each measurement type
90 | dplyr::mutate(row = substr(x = .data$well, start = 1, stop = 1)) %>% # make a "row" column from the "well" column
91 | dplyr::mutate(column = as.numeric(substr(x = .data$well, start = 2, # and make a "column" column
92 | stop = nchar(.data$well)))) %>%
93 | dplyr::arrange_at(dplyr::vars(.data$time, # order the rows
94 | .data$row,
95 | .data$column))
96 |
97 | # write parsed data to csv ------------------------------------------------
98 | if(stringr::str_ends(data_csv, ".xlsx")){
99 | out_name <- gsub(".xlsx", "_parsed.csv", data_csv)
100 | } else if(stringr::str_ends(data_csv, ".xls")){
101 | out_name <- gsub(".xls", "_parsed.csv", data_csv)
102 | } else if(stringr::str_ends(data_csv, ".csv")){
103 | out_name <- gsub(".xls", "_parsed.csv", data_csv)
104 | }
105 | utils::write.csv(x = out_data, file = out_name, row.names = FALSE)
106 |
107 | return(out_data)
108 | }
109 | else if (timeseries == FALSE){
110 | # get start and end block idxs
111 | start_block_idx <- which(data[, 2] == "Well")
112 | end_block_idx <- next_blank_row(start_idx = start_block_idx, data = data)
113 | if(is.na(end_block_idx)){
114 | end_block_idx <- nrow(data)
115 | }
116 |
117 | # grab the data
118 | all_data <- data[start_block_idx:end_block_idx, 2:ncol(data)]
119 |
120 | # simplify names
121 | all_data <- all_data %>%
122 | dplyr::rowwise() %>%
123 | dplyr::mutate(...2 = unlist(strsplit(.data$...2, split = ':'))[1]) %>% # take first section of name
124 | dplyr::ungroup()
125 |
126 | # transpose the data
127 | all_data <- as.data.frame(t(as.matrix(all_data)))
128 |
129 | # 1st row contains column names
130 | names(all_data) <- all_data[1,]
131 | all_data <- all_data[-1,]
132 | all_data <- all_data[, -length(all_data)]
133 |
134 | # convert to numeric
135 | all_data <- all_data %>%
136 | dplyr::mutate(dplyr::across(!Well, as.numeric)) %>%
137 | dplyr::rename(well = Well)
138 |
139 | # join to plate layout csv
140 | joined_block <- dplyr::full_join(plate_layout, all_data, by = 'well')
141 |
142 | # split row and column from well
143 | joined_block$row <- substr(x = joined_block$well, start = 1, stop = 1)
144 | joined_block$column <- as.numeric(substr(x = joined_block$well, start = 2,
145 | stop = nchar(joined_block$well)))
146 | joined_block <- dplyr::arrange_at(joined_block, dplyr::vars(.data$row,
147 | .data$column))
148 |
149 | # write parsed data to csv ------------------------------------------------
150 |
151 | if(stringr::str_ends(data_csv, ".xlsx")){
152 | out_name <- gsub(".xlsx", "_parsed.csv", data_csv)
153 | } else if(stringr::str_ends(data_csv, ".xls")){
154 | out_name <- gsub(".xls", "_parsed.csv", data_csv)
155 | } else if(stringr::str_ends(data_csv, ".csv")){
156 | out_name <- gsub(".xls", "_parsed.csv", data_csv)
157 | }
158 | utils::write.csv(x = joined_block, file = out_name, row.names = FALSE)
159 |
160 | return(joined_block)
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/R/biotekNeo2Functions.R:
--------------------------------------------------------------------------------
1 | #' Parser for Biotek Neo 2 plate reader data
2 | #'
3 | #' @param data_xl path to xls or xlsx file from Biotek Neo 2 plate reader
4 | #' @param layout_csv path to csv file containing plate layout information
5 | #' @param timeseries Boolean flag indicating whether the data is a timeseries or
6 | #' single recording. Currently only works for timeseries=T.
7 | #'
8 | #' @return a data.frame containing the parsed plate reader data
9 | #' @export
10 | #' @importFrom rlang .data
11 | #' @importFrom dplyr %>%
12 | #'
13 | biotek_parse <- function(data_xl, layout_csv, timeseries=T) {
14 | data <- readxl::read_excel(path = data_xl,
15 | col_names = F,
16 | trim_ws = T)
17 |
18 | plate_layout <- utils::read.csv(layout_csv)
19 |
20 | if(timeseries == TRUE){
21 | start_time_idx <- which(data[, 1] == "End Kinetic")
22 |
23 | next_block_start_idx <- start_time_idx + 2
24 |
25 | end_of_file <- F
26 | all_data <- c()
27 | measure_times <- c()
28 | while (!end_of_file) {
29 | # find what is being measured
30 | block_name <- unlist(data[next_block_start_idx, 1])
31 |
32 | # check if we are at the end of the file
33 | if (block_name == "Results") {
34 | end_of_file <- T
35 | break
36 | }
37 |
38 | # find where the end of the current measurement block is
39 | block_start_idx <- next_block_start_idx + 2
40 | block_end_idx <- block_start_idx + 1
41 | while (!is.na(data[block_end_idx, 2])) {
42 | block_end_idx <- block_end_idx + 1
43 | }
44 |
45 | # grab the data only for that measurement
46 | new_block <- data[(block_start_idx):(block_end_idx - 1), -1]
47 |
48 | # trim unnecessary readings i.e. temp
49 | # and rename columns
50 | wells <- new_block[1, -2]
51 | trimmed_new_block <- new_block[-1, -2]
52 | names(trimmed_new_block) <- wells
53 | names(trimmed_new_block)[1] <- "time"
54 |
55 | # hack to unify times of readings across different measurements
56 | if(length(measure_times) == 0){
57 | measure_times <- trimmed_new_block[1]
58 | }
59 | trimmed_new_block[1] <- measure_times
60 |
61 | long_trimmed_new_block <- tidyr::pivot_longer(data = trimmed_new_block,
62 | cols = 2:ncol(trimmed_new_block),
63 | names_to = "well")
64 |
65 | # add metadata for each well
66 | joined_block <- dplyr::full_join(plate_layout, long_trimmed_new_block, by="well")
67 | joined_block$measure <- block_name
68 |
69 | #
70 | all_data <- rbind(all_data, joined_block)
71 |
72 | #
73 | next_block_start_idx <- block_end_idx + 1
74 | }
75 |
76 | all_data$value <- as.numeric(all_data$value)
77 | all_data$time <- as.numeric(all_data$time) * 86400 # conversion to seconds - coefficient calculated empirically
78 |
79 | # rearrange data ----------------------------------------------------------
80 | # includes a bit of a hack to get around duplicate rows (there seems to be
81 | # lots of empty rows with time = 0)
82 | out_data <- all_data %>%
83 | dplyr::group_by(.data$measure) %>%
84 | dplyr::mutate(id = dplyr::row_number()) %>%
85 | tidyr::pivot_wider(names_from = .data$measure,
86 | values_from = .data$value) %>%
87 | dplyr::select(-.data$id)
88 |
89 | # get split row and column names for convenience
90 | out_data$row <- substr(x = out_data$well, start = 1, stop = 1)
91 | out_data$column <- as.numeric(substr(x = out_data$well, start = 2,
92 | stop = nchar(out_data$well)))
93 |
94 | # write parsed data to csv ------------------------------------------------
95 | out_name <- paste(tools::file_path_sans_ext(data_xl), "_parsed.csv", sep="")
96 | utils::write.csv(x = out_data, file = out_name, row.names = FALSE)
97 |
98 | return(out_data)
99 | }
100 | else if (timeseries == FALSE){
101 | stop("We can currently only parse timeseries from Biotek Neo 2 plate
102 | readers. Please send me some single timepoint data so I can update the
103 | parser.")
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/R/flowCoreMisc.R:
--------------------------------------------------------------------------------
1 | ### FUNCTIONS FOR APPENDING COLUMNS TO FLOW FRAME
2 | ### from updated version of flowCore not available to R < 4.0
3 |
4 | #' Append data columns to a flowFrame
5 | #'
6 | #' Append data columns to a flowFrame
7 | #'
8 | #' It is used to add extra data columns to the existing flowFrame. It handles
9 | #' keywords and parameters properly to ensure the new flowFrame can be written
10 | #' as a valid FCS through the function \code{write.FCS} .
11 | #'
12 | #' @param fr A \code{\link[flowCore:flowFrame-class]{flowFrame}}.
13 | #' @param cols A numeric matrix containing the new data columns to be added.
14 | #' Must has column names to be used as new channel names.
15 | #'
16 | #' @name ff_append_cols
17 | #' @aliases ff_append_cols
18 | #' @usage
19 | #' ff_append_cols(fr, cols)
20 | #' @return
21 | #'
22 | #' A \code{\linkS4class{flowFrame}}
23 | #' @author Mike Jiang
24 | #' @keywords IO
25 | ff_append_cols <- function(fr, cols){
26 | new_pd <- cols_to_pd(fr, cols)
27 | pd <- flowCore::pData(flowCore::parameters(fr))
28 | pd <- rbind(pd, new_pd)
29 | #add to exprs
30 | fr@exprs <- cbind(flowCore::exprs(fr), cols)
31 | flowCore::pData(flowCore::parameters(fr)) <- pd
32 |
33 | update_kw_from_pd(fr, new_pd)
34 | }
35 |
36 | update_kw_from_pd <- function(fr, new_pd)
37 | {
38 | new_pid <- rownames(new_pd)
39 | #take care of flowCore_$PnRmax
40 | trans <- flowCore::keyword(fr)[["transformation"]]
41 | if(!is.null(trans) && trans == "custom"){
42 | flowCore::keyword(fr)[paste0("flowCore_", new_pid, "Rmax")] <- new_pd[new_pid, "maxRange"]
43 | flowCore::keyword(fr)[paste0("flowCore_", new_pid, "Rmin")] <- new_pd[new_pid, "minRange"]
44 | }
45 | fr
46 | }
47 | #' generate new pData of flowFrame based on the new cols added
48 | #' @param fr A \code{\link[flowCore:flowFrame-class]{flowFrame}}.
49 | #' @param cols A numeric matrix containing the new data columns to be added.
50 | #' Must has column names to be used as new channel names.
51 | #' @noRd
52 | cols_to_pd <- function(fr, cols){
53 | checkmate::checkClass(cols, "matrix")
54 | ncol <- ncol(cols)
55 | cn <- colnames(cols)
56 | if(length(cn) != ncol)
57 | stop("All columns in 'cols' must have colnames!")
58 | #add to pdata
59 | pd <- flowCore::pData(flowCore::parameters(fr))
60 | ncol_old <- ncol(fr)
61 | new_pid <- max(as.integer(gsub("\\$P", "", rownames(pd)))) + 1
62 | new_pid <- seq(new_pid, length.out = ncol)
63 | new_pid <- paste0("$P", new_pid)
64 |
65 | new_pd <- do.call(rbind, lapply(cn, function(i){
66 | vec <- cols[,i]
67 | rg <- range(vec)
68 | data.frame(name = i, desc = NA, range = diff(rg) + 1, minRange = rg[1], maxRange = rg[2])
69 | }))
70 | rownames(new_pd) <- new_pid
71 | new_pd
72 | }
73 |
--------------------------------------------------------------------------------
/R/plateReaderFunctions.R:
--------------------------------------------------------------------------------
1 | #' Plate reader normalisation and calibration
2 | #'
3 | #' @param data_csv path to a .csv file containing parsed plate reader data
4 | #' @param blank_well the well coordinates of one or more media blanks
5 | #' @param neg_well the well coordinates of a non-fluorescent control
6 | #' @param od_name the column name for the optical density data
7 | #' @param flu_names the column names for the fluorescence data
8 | #' @param af_model model used to fit negative control autofluorescence.
9 | #' For now these include "polynomial", "invers_poly", "exponential", "spline" and "loess".
10 | #' @param to_MEFL a Boolean to determine whether to attempt to convert OD and
11 | #' GFP reading to calibrated units
12 | #' @param flu_gains if to_MEFL=T, the gain values at which the fluorophores
13 | #' specified in flu_names was recorded. If there isn't calibration data for a
14 | #' fluorophore, do not speficy a gain value
15 | #' @param conversion_factors_csv if to_MEFL=T, path of the csv file containing
16 | #' conversion factors from plate reader calibration
17 | #'
18 | #' @return a data.frame with columns for raw plate reader data, normalised data
19 | #' and, if to_MEFL = T, calibrated OD and GFP data
20 | #' @export
21 | #' @importFrom rlang .data
22 | #'
23 | #' @examples
24 | process_plate <- function(data_csv, blank_well = "A1", neg_well = "A2",
25 | od_name = "OD", flu_names = c("GFP"),
26 | af_model = "spline", to_MEFL = F,
27 | flu_gains, conversion_factors_csv) {
28 |
29 | pr_data <- utils::read.csv(data_csv, check.names = F)
30 |
31 | od_norm_pr_data <- od_norm(pr_data, blank_well, od_name)
32 |
33 | plt_od <- ggplot2::ggplot(od_norm_pr_data) +
34 | ggplot2::geom_line(ggplot2::aes(x = .data$time, y = .data[[od_name]],
35 | colour = "raw"), size = 0.2) +
36 | ggplot2::geom_line(ggplot2::aes(x = .data$time, y = .data$normalised_OD,
37 | colour = "normalised"), size = 0.2) +
38 | ggplot2::scale_x_continuous("time") +
39 | ggplot2::scale_colour_discrete("") +
40 | ggplot2::facet_grid(row~column) +
41 | ggplot2::theme_bw(base_size = 8)
42 | ggplot2::ggsave(filename = gsub(".csv", "_OD.pdf", data_csv),
43 | plot = plt_od, height = 160,
44 | width = 240, units = "mm")
45 |
46 | flu_norm_pr_data <- od_norm_pr_data
47 | if(!is.na(flu_names)){
48 | if(length(flu_names) >= 1){
49 | for (flu_idx in seq_len(length(flu_names))) {
50 | flu_norm_pr_data <- flu_norm(flu_norm_pr_data, neg_well, blank_well,
51 | flu_names[flu_idx], af_model, data_csv)
52 |
53 | plt_flu <- ggplot2::ggplot(flu_norm_pr_data) +
54 | ggplot2::geom_line(ggplot2::aes(x = .data$time, y = .data[[flu_names[flu_idx]]],
55 | colour = "raw"), size = 0.2) +
56 | ggplot2::geom_line(ggplot2::aes(x = .data$time,
57 | y = .data[[paste("normalised_",
58 | flu_names[flu_idx],
59 | sep = "")]],
60 | colour = "normalised"),
61 | size = 0.2) +
62 | ggplot2::scale_x_continuous("time") +
63 | ggplot2::scale_colour_discrete("") +
64 | ggplot2::facet_grid(row~column) +
65 | ggplot2::theme_bw(base_size = 8)
66 | ggplot2::ggsave(filename = gsub(".csv",
67 | paste("_", flu_names[flu_idx], ".pdf", sep = ""),
68 | data_csv),
69 | plot = plt_flu, height = 160,
70 | width = 240, units = "mm")
71 | }
72 | }
73 | }
74 |
75 | out_data <- flu_norm_pr_data
76 |
77 | if (to_MEFL) {
78 | out_data <- calibrate_od(out_data, od_name,
79 | conversion_factors_csv)
80 |
81 | if(!is.na(flu_names)){
82 | for (flu_idx in seq_len(length(flu_names))) {
83 | if(length(flu_gains) >= flu_idx){
84 | out_data <- calibrate_flu(out_data, flu_names[flu_idx],
85 | flu_gains[flu_idx], od_name,
86 | conversion_factors_csv)
87 | }
88 | else {break}
89 | }
90 | }
91 | }
92 |
93 | utils::write.csv(x = out_data,
94 | file = gsub(".csv", "_processed.csv", data_csv),
95 | row.names = FALSE)
96 | return(out_data)
97 | }
98 |
99 |
100 | #' Normalisation absorbance against blank well
101 | #'
102 | #' @param pr_data a long data.frame containing you plate reader data
103 | #' @param blank_well the well coordinates of one or more media blanks
104 | #' @param od_name the column name for the optical density data
105 | #'
106 | #' @return an updated data.frame with an additional column "normalised_OD"
107 | #'
108 | #' @importFrom dplyr %>%
109 | #' @importFrom rlang .data
110 | od_norm <- function(pr_data, blank_well, od_name) {
111 | pr_data$normalised_OD <- pr_data[, od_name]
112 |
113 | # remove background absorbance signal -------------------------------------
114 |
115 | pr_data <- pr_data %>%
116 | dplyr::group_by(.data$time) %>%
117 | dplyr::mutate(normalised_OD = .data$normalised_OD -
118 | mean(.data$normalised_OD[.data$well %in% blank_well]))
119 |
120 | return(as.data.frame(pr_data))
121 | }
122 |
123 |
124 | #' Normalise fluorescence against negative well
125 | #'
126 | #' @param pr_data a long data.frame containing you plate reader data with OD
127 | #' normalised
128 | #' @param neg_well the well coordinates of a non-fluorescent control
129 | #' @param blank_well the well coordinates of a media blank
130 | #' @param flu_name the column name of the fluorescence chanel to normalise
131 | #' @param af_model model used to fit negative control autofluorescence.
132 | #' For now these include "polynomial", "invers_poly", "exponential", "spline" or "loess".
133 | #' @param data_csv path to the original data. Used for saving normalisation curve plots.
134 | #'
135 | #' @return
136 | #'
137 | #' @importFrom dplyr %>%
138 | #' @importFrom rlang .data
139 | flu_norm <- function(pr_data, neg_well, blank_well, flu_name, af_model, data_csv) {
140 | pr_data$v1 <- pr_data[, flu_name]
141 |
142 | # fit autofluorescence model to negative control --------------------------
143 |
144 | negative_data <- pr_data %>% dplyr::filter(.data$well %in% neg_well)
145 |
146 | if (af_model == "polynomial") {
147 | model <- stats::nls(v1 ~ (a * normalised_OD + b * normalised_OD ^ 2 + c),
148 | start = c(a = 1, b = 1, c = 1), data = negative_data)
149 |
150 | } else if (af_model == "inverse_poly") {
151 | model <- stats::nls(normalised_OD ~ (a * v1 + b * v1 ^ 2 + c),
152 | start = c(a = 1, b = 1, c = 1), data = negative_data)
153 |
154 | } else if (af_model == "exponential") {
155 | ## ae^(bx) + c
156 | ## intial parameter estimation
157 | model_0 <- stats::lm(log(v1) ~ normalised_OD, data = negative_data)
158 | start <- list(a = exp(stats::coef(model_0)[1]),
159 | b = stats::coef(model_0)[2],
160 | c = -1)
161 |
162 | model <- stats::nls(v1 ~ (a * exp(b * normalised_OD) + c),
163 | start = start, data = negative_data)
164 |
165 | } else if (af_model == "bi_exponential") {
166 | ## a exp(bx) + c exp(dx) + e
167 |
168 | model_0 <- stats::lm(log(v1) ~ normalised_OD, data = negative_data)
169 | start <- list(a = exp(stats::coef(model_0)[1]*0.2),
170 | b = stats::coef(model_0)[2]*0.2,
171 | c = exp(stats::coef(model_0)[1])*0.8,
172 | d = stats::coef(model_0)[2]*0.8,
173 | e = 1)
174 |
175 | model <- stats::nls(v1 ~ (a * exp(b * normalised_OD) +
176 | c * exp(d * normalised_OD) + e),
177 | start = start,
178 | data = negative_data)
179 |
180 | } else if (af_model == "linear_exponential") {
181 | ## ax + be^cx + d
182 |
183 | model_01 <- stats::lm(v1 ~ normalised_OD, data = negative_data)
184 | model_02 <- stats::lm(log(v1) ~ normalised_OD, data = negative_data)
185 | start <- list(a = stats::coef(model_01)[2],
186 | b = exp(stats::coef(model_02)[1]),
187 | c = stats::coef(model_02)[2],
188 | d = 1)
189 |
190 | model <- stats::nls(v1 ~ (a * normalised_OD +
191 | b * exp(c * normalised_OD) + d),
192 | start = start,
193 | data = negative_data)
194 |
195 | } else if (af_model == "power") {
196 | ## ax^b + c
197 | model_0 <- stats::lm(log(v1) ~ log(normalised_OD), data = negative_data)
198 | start <- list(a = exp(stats::coef(model_0)[1]),
199 | b = stats::coef(model_0)[2],
200 | c = 1)
201 |
202 | model <- stats::nls(v1 ~ (a * normalised_OD ^ b + c),
203 | start = start, data = negative_data)
204 |
205 | } else if (af_model == "linear_power") {
206 | ## ax + bx^c + d
207 | model_01 <- stats::lm(v1 ~ normalised_OD, data = negative_data)
208 | model_02 <- stats::lm(log(v1) ~ log(normalised_OD), data = negative_data)
209 | start <- list(a = stats::coef(model_01)[2],
210 | b = exp(stats::coef(model_02)[1]),
211 | c = stats::coef(model_02)[2],
212 | d = 1)
213 |
214 | model <- stats::nls(v1 ~ (a * normalised_OD + b * normalised_OD ^ c + d),
215 | start = start,
216 | data = negative_data)
217 | } else if (af_model == "loess") {
218 | model <- stats::loess(v1 ~ normalised_OD,
219 | data = negative_data,
220 | span = 0.5)
221 | } else if (af_model == "spline") {
222 | model <- mgcv::gam(v1 ~ s(normalised_OD), data = negative_data)
223 | }
224 |
225 | # plot model fit curves ---------------------------------------------------
226 |
227 | if (af_model == "polynomial" | af_model == "power" |
228 | af_model == "exponential" | af_model == "bi_exponential" |
229 | af_model == "linear_exponential" | af_model == "linear_power" |
230 | af_model == "loess") {
231 | plt <- ggplot2::ggplot() +
232 | ggplot2::geom_line(ggplot2::aes(x = negative_data$normalised_OD,
233 | y = stats::predict(model,
234 | negative_data))) +
235 | ggplot2::geom_point(ggplot2::aes(x = negative_data$normalised_OD,
236 | y = negative_data$v1)) +
237 | ggplot2::scale_x_continuous("normalised_OD") +
238 | ggplot2::scale_y_continuous(flu_name) +
239 | ggplot2::theme_bw()
240 | } else if (af_model == "spline") {
241 | plt <- ggplot2::ggplot() +
242 | ggplot2::geom_line(ggplot2::aes(x = negative_data$normalised_OD,
243 | y = mgcv::predict.gam(model, negative_data))) +
244 | ggplot2::geom_point(ggplot2::aes(x = negative_data$normalised_OD,
245 | y = negative_data$v1)) +
246 | ggplot2::scale_x_continuous("normalised_OD") +
247 | ggplot2::scale_y_continuous(flu_name) +
248 | ggplot2::theme_bw()
249 | }
250 | else if (af_model == "inverse_poly") {
251 | plt <- ggplot2::ggplot() +
252 | ggplot2::geom_line(ggplot2::aes(x = negative_data$normalised_OD,
253 | y = ((- (stats::coef(model)[1]) +
254 | sqrt((stats::coef(model)[1]) ^ 2 -
255 | 4 *
256 | (stats::coef(model)[2]) *
257 | (stats::coef(model)[3]) +
258 | 4 *
259 | (stats::coef(model)[2]) *
260 | negative_data$normalised_OD)) /
261 | (2 * (stats::coef(model)[2]))))) +
262 | ggplot2::geom_point(ggplot2::aes(y = negative_data$v1,
263 | x = negative_data$normalised_OD)) +
264 | ggplot2::scale_x_continuous("normalised_OD") +
265 | ggplot2::scale_y_continuous(flu_name) +
266 | ggplot2::theme_bw()
267 | }
268 | ggplot2::ggsave(filename = gsub(".csv",
269 | paste("_norm-curve_", flu_name, ".pdf", sep = ""),
270 | data_csv),
271 | plot = plt)
272 |
273 | # normalise fluorescence data ---------------------------------------------
274 |
275 | if (af_model == "polynomial" | af_model == "power" |
276 | af_model == "exponential" | af_model == "bi_exponential" |
277 | af_model == "linear_exponential" | af_model == "linear_power" |
278 | af_model == "loess") {
279 | pr_data$v1 <- pr_data$v1 - stats::predict(model, pr_data)
280 | } else if (af_model == "spline") {
281 | pr_data$v1 <- pr_data$v1 - mgcv::predict.gam(model, pr_data)
282 | }
283 | else if (af_model == "inverse_poly") {
284 | pr_data$v1 <- pr_data$v1 - ((- (stats::coef(model)[1]) +
285 | sqrt((stats::coef(model)[1]) ^ 2 - 4 *
286 | (stats::coef(model)[2]) *
287 | (stats::coef(model)[3]) +
288 | 4 * (stats::coef(model)[2]) *
289 | pr_data$normalised_OD)) /
290 | (2 * (stats::coef(model)[2])))
291 | }
292 |
293 | # rename normalised fluorescence column
294 | names(pr_data)[ncol(pr_data)] <- paste("normalised_", flu_name, sep = "")
295 |
296 | return(pr_data)
297 | }
298 |
299 | #' Convert arbitrary absorbance units to calibrated units
300 | #'
301 | #' @param pr_data a data.frame of parsed plate reader data
302 | #' @param od_name the column name for the optical density data
303 | #' @param conversion_factors_csv if to_MEFL=T, path of the csv file containing
304 | #' conversion factors from plate reader calibration
305 | #'
306 | #' @importFrom dplyr %>%
307 | #' @importFrom rlang .data
308 | #'
309 | #' @return
310 | calibrate_od <- function(pr_data, od_name, conversion_factors_csv) {
311 | conversion_factors <- utils::read.csv(conversion_factors_csv)
312 |
313 | # Get conversion factor for OD --------------------------------------------
314 |
315 | od_cf <- unlist(conversion_factors %>%
316 | dplyr::filter(.data$measure == od_name) %>%
317 | dplyr::select(.data$cf))
318 |
319 | pr_data$calibrated_OD <- pr_data$normalised_OD / od_cf
320 |
321 | return(pr_data)
322 | }
323 |
324 |
325 | #' Convert arbitrary fluorescence units to calibrated units
326 | #'
327 | #' @param pr_data a data.frame of parsed plate reader data
328 | #' @param flu_name name of fluorophore to be calibrated
329 | #' @param flu_gain gain at which the fluorophore was measured
330 | #' @param od_name the column name for the optical density data
331 | #' @param conversion_factors_csv if to_MEFL=T, path of the csv file containing
332 | #' conversion factors from plate reader calibration
333 | #'
334 | #' @importFrom dplyr %>%
335 | #' @importFrom rlang .data
336 | #'
337 | #' @return
338 | calibrate_flu <- function(pr_data, flu_name, flu_gain, od_name, conversion_factors_csv) {
339 | conversion_factors <- utils::read.csv(conversion_factors_csv)
340 |
341 |
342 | # Get conversion factor for fluorophore ------------------------------------
343 | flu_cfs <- conversion_factors %>%
344 | dplyr::filter(.data$fluorophore == flu_name)
345 |
346 | # if there is no calibration for the fluorophore
347 | if(nrow(flu_cfs) == 0) {
348 | return(pr_data)
349 | }
350 |
351 | tryCatch(this_cf <- flu_cfs[which(flu_cfs$measure == paste(flu_name, flu_gain)),]$cf,
352 | finally = this_cf <- NA)
353 |
354 |
355 | # if a conversion factor doesn't exist at the measured gain, try a --------
356 | if(is.na(this_cf)){
357 | flu_cfs$gain <- as.numeric(gsub(paste(flu_name, " ", sep=""), "", flu_cfs$measure))
358 |
359 | # Fit cf to Gain relation to get cf for specific gain ---------------------
360 | model <- stats::lm(log10(cf) ~ poly(gain, 2), data = flu_cfs)
361 | this_cf <- 10 ^ stats::predict(model, data.frame(gain = flu_gain))
362 | ggplot2::ggplot() +
363 | ggplot2::geom_line(ggplot2::aes(x = flu_cfs$gain,
364 | y = 10^stats::predict(model, flu_cfs))) +
365 | ggplot2::geom_point(ggplot2::aes(x = flu_cfs$gain,
366 | y = flu_cfs$cf)) +
367 | ggplot2::geom_vline(xintercept = flu_gain, linetype = 2) +
368 | ggplot2::geom_hline(yintercept = 10 ^ stats::predict(model, data.frame(gain = flu_gain)),
369 | linetype = 2) +
370 | ggplot2::geom_point(ggplot2::aes(x = flu_gain,
371 | y = 10 ^ stats::predict(model, data.frame(gain = flu_gain))),
372 | colour = "red", shape = 1, size = 2) +
373 | ggplot2::scale_x_continuous("Gain") +
374 | ggplot2::scale_y_continuous("Conversion factor (MEFL/a.u.)",
375 | trans = "log10") +
376 | ggplot2::theme_bw()
377 | }
378 |
379 | pr_data[,paste("calibrated_", flu_name, sep="")] <-
380 | (pr_data[,paste("normalised_", flu_name, sep="")] / this_cf)
381 |
382 | return(pr_data)
383 | }
384 |
385 |
386 | #' Generate Conversion Factors
387 | #'
388 | #' @param calibration_csv path of a .csv file of your calibration data
389 | #'
390 | #' @export
391 | #' @importFrom dplyr %>%
392 | #' @importFrom rlang .data :=
393 | generate_cfs <- function(calibration_csv) {
394 | calibration_data <- utils::read.csv(calibration_csv, header = T, check.names = F)
395 |
396 |
397 | # get types of measure ----------------------------------------------------
398 | well_idx <- which(names(calibration_data) == "well")
399 | row_idx <- which(names(calibration_data) == "row")
400 | measures <- names(calibration_data)[(well_idx+1):(row_idx-1)]
401 |
402 |
403 | # remove saturated values -------------------------------------------------
404 | # using similar approach to Beal et al. 2019 bioRxiv to assess validitiy of measurements
405 |
406 | non_sat_values <- c()
407 | for(calib in unique(calibration_data$calibrant)){
408 | # get values only for this calibrant
409 | temp_calib_values <- calibration_data %>%
410 | dplyr::filter(.data$calibrant == calib) %>%
411 | dplyr::arrange(desc(concentration))
412 |
413 | # get concentrations at which we have measurements
414 | concentrations <- sort(unique(temp_calib_values$concentration), decreasing = T)
415 |
416 | # calculate fold dilution used
417 | fold_dilution <- concentrations[2] / concentrations[3]
418 |
419 | # points are considered saturated if they have less than 75% measurement change relative to the fold_dilution
420 | high_saturation_threshold <- fold_dilution * 0.75
421 |
422 | # work out dilution order from concentrations
423 | temp_calib_values$dilution_ratio <- 1 / fold_dilution
424 | temp_calib_values$max_concentration <- max(concentrations)
425 | temp_calib_values$dilution_idx <- - log(temp_calib_values$max_concentration / temp_calib_values$concentration) / log(temp_calib_values$dilution_ratio)
426 |
427 | for(meas in measures){
428 | blank_mean <- mean(temp_calib_values[temp_calib_values$concentration == 0,][[meas]], na.rm = T)
429 | blank_sd <- stats::sd(temp_calib_values[temp_calib_values$concentration == 0,][[meas]], na.rm = T)
430 |
431 | for(rplct in unique(temp_calib_values$replicate)){
432 |
433 | values <- temp_calib_values[temp_calib_values$replicate == rplct, meas]
434 | saturated_1 <- values[1:(length(values)-1)] <= values[2:(length(values))] * high_saturation_threshold
435 | saturated_2 <- values[2:(length(values))] >= values[1:(length(values)-1)] / high_saturation_threshold
436 | saturated_3 <- values[1:(length(values)-1)] <= blank_mean + 2 * blank_sd
437 | saturated_4 <- is.na(values[1:(length(values)-1)])
438 | saturated <- saturated_1 | saturated_2 | saturated_3 | saturated_4
439 |
440 | temp_calib_values[temp_calib_values$concentration %in% concentrations[1:(length(concentrations)-1)][saturated] & temp_calib_values$replicate == rplct, meas] <- NA
441 | }
442 | }
443 | non_sat_values <- rbind(non_sat_values, temp_calib_values)
444 | }
445 |
446 |
447 | # calculate mean of 4 replicates -------------
448 |
449 | summ_values <- non_sat_values %>%
450 | dplyr::group_by(.data$calibrant, .data$fluorophore, .data$media,
451 | .data$concentration, .data$dilution_ratio,
452 | .data$max_concentration, .data$dilution_idx, .drop = F) %>%
453 | dplyr::summarise_at(measures, mean, na.rm = TRUE) %>%
454 | dplyr::filter(!is.na(.data$concentration))
455 |
456 |
457 | # normalise data ----------------------------------------------------------
458 |
459 | norm_values <- summ_values
460 | for(meas in measures){
461 | norm_values <- norm_values %>%
462 | dplyr::group_by(.data$calibrant) %>%
463 | dplyr::mutate({{meas}} := .data[[meas]] -
464 | .data[[meas]][.data$concentration == 0])
465 | }
466 | norm_values <- norm_values %>% dplyr::filter(.data$concentration != 0)
467 |
468 |
469 | # fit pipetting error model for conversion factors ------------------------
470 | # error model from Beal et al. 2019 bioRxiv
471 |
472 | long_values <- stats::na.omit(norm_values %>%
473 | tidyr::pivot_longer(tidyselect::all_of(measures),
474 | names_to = "measure",
475 | values_to = "normalised_value"))
476 |
477 | fit_values <- c()
478 | for(calib in unique(long_values$calibrant)){
479 | temp_calib_values <- long_values %>% dplyr::filter(.data$calibrant == calib)
480 | for(meas in unique(temp_calib_values$measure)){
481 | temp_meas_calib_values <- temp_calib_values %>%
482 | dplyr::filter(.data$measure == meas)
483 |
484 | if(nrow(temp_meas_calib_values) < 3){
485 | next
486 | }
487 |
488 | model <- 0
489 |
490 | error_func <- function(x){
491 | data <- temp_meas_calib_values
492 |
493 | cf <- x[1]
494 | beta <- x[2]
495 | error <- 0
496 |
497 | for(i in data$dilution_idx){
498 | data_i <- data[data$dilution_idx == i,]
499 |
500 | b_i <- data_i$max_concentration * (1 - data_i$dilution_ratio - beta) *
501 | (data_i$dilution_ratio + beta) ^ (data_i$dilution_idx - 1)
502 |
503 | e_i <- abs(log10(cf * b_i / data_i$normalised_value))^2
504 |
505 | error <- error + e_i
506 | }
507 |
508 | return(error)
509 | }
510 |
511 |
512 | for(init_cf in c(1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14)){
513 | res <- stats::optim(c(init_cf, 0), error_func)
514 |
515 | if(res$convergence == 0){
516 | new_fit <- data.frame(cf = res$par[1], beta = res$par[2],
517 | calibrant = calib,
518 | fluorophore = temp_meas_calib_values$fluorophore[1],
519 | measure = meas)
520 | fit_values <- rbind(fit_values, new_fit)
521 | break
522 | }
523 | }
524 | }
525 | }
526 |
527 | long_values <- dplyr::full_join(long_values, fit_values)
528 |
529 |
530 | # plot the mean normalized values -----------------------------------------
531 |
532 | abs_plt <-
533 | ggplot2::ggplot(data = long_values %>%
534 | dplyr::filter(.data$calibrant == "microspheres")) +
535 | ggplot2::geom_point(ggplot2::aes(x = dilution_idx,
536 | y = normalised_value)) +
537 | ggplot2::geom_line(ggplot2::aes(x = dilution_idx,
538 | y = cf * max_concentration *
539 | (1 - dilution_ratio - beta) *
540 | (dilution_ratio + beta) ^ (dilution_idx - 1))) +
541 | ggplot2::scale_y_continuous("Normalised Absorbance", trans = "log10") +
542 | ggplot2::scale_x_continuous("Microspheres dilution") +
543 | ggplot2::facet_wrap(~measure) +
544 | ggplot2::theme_bw(base_size = 12)
545 |
546 | ggplot2::ggsave(gsub(".csv", "_absorbance_cfs.pdf", calibration_csv),
547 | plot = abs_plt)
548 |
549 | flu_plt <-
550 | ggplot2::ggplot(data = long_values %>%
551 | dplyr::filter(.data$calibrant %in% c("fluorescein", 'FITC'))) +
552 | ggplot2::geom_point(ggplot2::aes(x = dilution_idx,
553 | y = normalised_value)) +
554 | ggplot2::geom_line(ggplot2::aes(x = dilution_idx,
555 | y = cf * max_concentration *
556 | (1 - dilution_ratio - beta) *
557 | (dilution_ratio + beta) ^ (dilution_idx - 1))) +
558 | ggplot2::scale_y_continuous("Normalised Fluorescence", trans = "log10") +
559 | ggplot2::scale_x_continuous("Fluorescein dilution") +
560 | ggplot2::facet_wrap(~measure) +
561 | ggplot2::theme_bw(base_size = 12)
562 |
563 | ggplot2::ggsave(gsub(".csv", "_fluorescence_cfs.pdf", calibration_csv),
564 | plot = flu_plt)
565 |
566 |
567 | # save conversion factors to a csv ----------------------------------------
568 |
569 | utils::write.csv(fit_values, gsub(".csv", "_cfs.csv", calibration_csv), row.names = FALSE)
570 | }
571 |
--------------------------------------------------------------------------------
/R/tecanInfiniteFunctions.R:
--------------------------------------------------------------------------------
1 | #' Find next blank line
2 | #'
3 | #' @param start_idx
4 | #' @param data
5 | #'
6 | #' @return row index of next blank line
7 | next_blank <- function(start_idx, data){
8 | next_start_idx <- start_idx
9 | while (!is.na(data[next_start_idx, 1])) {
10 | next_start_idx <- next_start_idx + 1
11 | }
12 | return(next_start_idx)
13 | }
14 |
15 | #' Find next non-blank line
16 | #'
17 | #' @param start_idx
18 | #' @param data
19 | #'
20 | #' @return row index of next non-blank line
21 | next_filled <- function(start_idx, data){
22 | next_start_idx <- start_idx
23 | while (is.na(data[next_start_idx, 1])) {
24 | next_start_idx <- next_start_idx + 1
25 | }
26 | return(next_start_idx)
27 | }
28 |
29 | #' Parser for Tecan Infinite plate reader data
30 | #'
31 | #' @param data_csv path to .csv, .xls or .xlsx file from Tecan Infinit plate reader
32 | #' @param layout_csv path to csv file containing plate layout information
33 | #' @param timeseries Boolean flag indicating whether the data is a timeseries or
34 | #' single recording. The Tecan software outputs the two scenarios differently.
35 | #'
36 | #' @return a data.frame containing the parsed plate reader data
37 | #' @export
38 | #' @importFrom rlang .data
39 | #'
40 | infinite_parse <- function(data_csv, layout_csv, timeseries=F) {
41 |
42 | if(stringr::str_ends(data_csv, ".xlsx") | stringr::str_ends(data_csv, ".xls")){
43 | data <- as.data.frame(readxl::read_excel(path = data_csv,
44 | col_names = F,
45 | col_types = "text"))
46 | } else if(stringr::str_ends(data_csv, ".csv")){
47 | data <- utils::read.table(data_csv, sep = ",",
48 | na.strings = c(""),
49 | header = F,
50 | stringsAsFactors = F)
51 | } else {
52 | stop("data_csv is must be a .csv, .xls or .xlsx file.")
53 | }
54 |
55 | plate_layout <- utils::read.csv(layout_csv)
56 |
57 | if(timeseries == TRUE){
58 | start_time_idx <- which(data[, 1] == "Start Time:")
59 | if (length(start_time_idx) > 1) {
60 | start_time_idx <- start_time_idx[length(start_time_idx)]
61 | }
62 |
63 | # find where the next block starts
64 | next_block_start_idx <- next_filled(start_time_idx + 1, data)
65 |
66 | end_of_file <- F
67 | all_data <- c()
68 | while (!end_of_file) {
69 | # find what is being measured
70 | block_name <- data[next_block_start_idx, 1]
71 |
72 | # check if we are at the end of the file
73 | if (block_name == "End Time:") {
74 | end_of_file <- T
75 | break
76 | }
77 |
78 | # find where the end of the current measurement block is
79 | block_end_idx <- next_blank(next_block_start_idx, data)
80 |
81 | # grab the data only for that measurement
82 | new_block <- data[(next_block_start_idx + 1):(block_end_idx - 1), ]
83 | # new_block <- new_block[-c(1,3), ] # remove cycle no. and temp.
84 |
85 | # trim unnecessary readings i.e. temp and cycle number
86 | # and rename columns
87 | times <- as.character(new_block[2,])
88 | new_block <- new_block[-c(1:3), ]
89 | names(new_block) <- times
90 | names(new_block)[1] <- "well"
91 | new_block <- new_block[,names(new_block) != "NA"] # remove erroneous NA columns
92 |
93 | # reshape time into long data
94 | new_block <- new_block %>%
95 | tidyr::pivot_longer(cols = 2:ncol(new_block),
96 | names_to = "time", names_transform = as.numeric,
97 | values_to = "value", values_transform = as.numeric)
98 |
99 | # add info for each well
100 | joined_block <- dplyr::full_join(plate_layout, new_block)
101 | joined_block$measure <- block_name
102 |
103 | #
104 | all_data <- rbind(all_data, joined_block)
105 |
106 | #
107 | next_block_start_idx <- next_filled(block_end_idx + 1, data)
108 | }
109 |
110 | # rearrange data ----------------------------------------------------------
111 | layout_cols <- ncol(plate_layout)
112 | out_data <- all_data %>%
113 | tidyr::pivot_wider(names_from = .data$measure, values_from = .data$value) %>% # reshape so we have a column for each measurement type
114 | dplyr::mutate(row = substr(x = .data$well, start = 1, stop = 1)) %>% # make a "row" column from the "well" column
115 | dplyr::mutate(column = as.numeric(substr(x = .data$well, start = 2, # and make a "column" column
116 | stop = nchar(.data$well)))) %>%
117 | dplyr::arrange_at(dplyr::vars(.data$time, # order the rows
118 | .data$row,
119 | .data$column))
120 |
121 | # write parsed data to csv ------------------------------------------------
122 | out_name <- gsub(".csv", "_parsed.csv", data_csv)
123 | out_name <- gsub(".xlsx", "_parsed.csv", out_name)
124 | utils::write.csv(x = out_data, file = out_name, row.names = FALSE)
125 |
126 | return(out_data)
127 | }
128 | # else if (timeseries == FALSE){
129 | # start_time_idx <- which(data[, 1] == "Start Time") # get start and end time ids
130 | # end_idx <- which(data[, 1] == "End Time")
131 | # names_idx <- which(data[, 1] == "Name")
132 | # names_idx <- names_idx[2:length(names_idx)] # remove the first start time entry which just details plate type
133 | #
134 | # all_data <- c()
135 | # for (i in seq_len(length(start_time_idx))) {
136 | # block_name <- data[names_idx[i], 2] # record name of what is being measured
137 | #
138 | # block_start <- start_time_idx[i] + 4 # find start and end of measurement block
139 | # block_end_idx <- end_idx[i] - 3
140 | #
141 | # new_block <- data[(block_start):(block_end_idx), 1:2] # grab and name the data
142 | # names(new_block)[1] <- "well"
143 | # names(new_block)[2] <- "value"
144 | #
145 | # new_block$value <- as.numeric(new_block$value)
146 | #
147 | # joined_block <- dplyr::full_join(plate_layout, new_block) # join to plate layout csv, add measurement category
148 | # joined_block$measure <- block_name
149 | #
150 | # all_data <- rbind(all_data, joined_block) # add to all data
151 | # }
152 | #
153 | # # rearrange data ----------------------------------------------------------
154 | # spread_data <- tidyr::pivot_wider(all_data, names_from = .data$measure,
155 | # values_from = .data$value)
156 | # spread_data$row <- substr(x = spread_data$well, start = 1, stop = 1)
157 | # spread_data$column <- as.numeric(substr(x = spread_data$well, start = 2,
158 | # stop = nchar(spread_data$well)))
159 | # spread_data <- dplyr::arrange_at(spread_data, dplyr::vars(.data$row,
160 | # .data$column))
161 | #
162 | # # write parsed data to csv ------------------------------------------------
163 | # out_name <- gsub(".csv", "_parsed.csv", data_csv)
164 | # utils::write.csv(x = spread_data, file = out_name, row.names = FALSE)
165 | #
166 | # return(spread_data)
167 | # }
168 | }
169 |
--------------------------------------------------------------------------------
/R/tecanSparkFunctions.R:
--------------------------------------------------------------------------------
1 | #' Find next blank line
2 | #'
3 | #' @param start_idx
4 | #' @param data
5 | #'
6 | #' @return row index of next blank line
7 | next_blank_row <- function(start_idx, data){
8 | next_start_idx <- start_idx
9 | while (any(!is.na(data[next_start_idx, ]))) {
10 | next_start_idx <- next_start_idx + 1
11 | if(next_start_idx >= nrow(data)){
12 | return(NA)
13 | }
14 | }
15 | return(next_start_idx)
16 | }
17 |
18 | #' Find next blank line
19 | #'
20 | #' @param start_idx
21 | #' @param data
22 | #'
23 | #' @return row index of next blank line
24 | next_blank_cell <- function(start_idx, data, col){
25 | next_start_idx <- start_idx
26 | while (!is.na(data[next_start_idx, col])) {
27 | next_start_idx <- next_start_idx + 1
28 | if(next_start_idx >= nrow(data)){
29 | return(NA)
30 | }
31 | }
32 | return(next_start_idx)
33 | }
34 |
35 | #' Find next non-blank line
36 | #'
37 | #' @param start_idx
38 | #' @param data
39 | #'
40 | #' @return row index of next non-blank line
41 | next_filled_row <- function(start_idx, data){
42 | next_start_idx <- start_idx
43 | while (any(is.na(data[next_start_idx, ]))) {
44 | next_start_idx <- next_start_idx + 1
45 | if(next_start_idx >= nrow(data)){
46 | return(NA)
47 | }
48 | }
49 | return(next_start_idx)
50 | }
51 |
52 | #' Find next non-blank line
53 | #'
54 | #' @param start_idx
55 | #' @param data
56 | #'
57 | #' @return row index of next non-blank line
58 | next_filled_cell <- function(start_idx, data, col){
59 | next_start_idx <- start_idx
60 | while (is.na(data[next_start_idx, col])) {
61 | next_start_idx <- next_start_idx + 1
62 | if(next_start_idx >= nrow(data)){
63 | return(NA)
64 | }
65 | }
66 | return(next_start_idx)
67 | }
68 |
69 | #' Parser for Tecan Spark plate reader data
70 | #'
71 | #' @param data_csv path to .csv, .xls or .xlsx file from Tecan Spark plate reader
72 | #' @param layout_csv path to csv file containing plate layout information
73 | #' @param timeseries Boolean flag indicating whether the data is a timeseries or
74 | #' single recording. The Tecan software outputs the two scenarios differently.
75 | #' @param wells_as_columns Boolean flag indicating whether blocks of data are
76 | #' oriented with wells as columns or rows
77 | #'
78 | #' @return a data.frame containing the parsed plate reader data
79 | #' @export
80 | #' @importFrom rlang .data
81 | #'
82 | spark_parse <- function(data_csv, layout_csv, timeseries=F, wells_as_columns=F) {
83 |
84 | if(stringr::str_ends(data_csv, ".xlsx") | stringr::str_ends(data_csv, ".xls")){
85 | data <- as.data.frame(readxl::read_excel(path = data_csv,
86 | col_names = F,
87 | col_types = "text"))
88 | } else if(stringr::str_ends(data_csv, ".csv")){
89 | data <- utils::read.table(data_csv, sep = ",",
90 | na.strings = c(""),
91 | header = F,
92 | stringsAsFactors = F)
93 | } else {
94 | stop("data_csv is must be a .csv, .xls or .xlsx file.")
95 | }
96 |
97 | plate_layout <- utils::read.csv(layout_csv)
98 |
99 | if(timeseries == TRUE){
100 | start_time_idx <- which(data[, 1] == "Start Time")
101 | if (length(start_time_idx) > 1) {
102 | start_time_idx <- start_time_idx[length(start_time_idx)]
103 | }
104 |
105 | # find where the next block starts
106 | next_block_start_idx <- next_filled_cell(start_time_idx + 1, data, col=1)
107 |
108 | end_of_file <- F
109 | all_data <- c()
110 | while (!end_of_file) {
111 | # find what is being measured
112 | block_name <- data[next_block_start_idx, 1]
113 |
114 | # check if we are at the end of the file
115 | if (block_name == "End Time") {
116 | end_of_file <- T
117 | break
118 | }
119 |
120 | # find where the end of the current measurement block is
121 | block_end_idx <- next_blank_cell(next_block_start_idx, data, col=1)
122 |
123 | # grab the data only for that measurement
124 | new_block <- data[(next_block_start_idx + 1):(block_end_idx - 1), ]
125 | # new_block <- new_block[-c(1,3), ] # remove cycle no. and temp.
126 |
127 | if(!wells_as_columns){
128 | # trim unnecessary readings i.e. temp and cycle number
129 | # and rename columns
130 | times <- as.character(new_block[2,])
131 | new_block <- new_block[-c(1:3), ]
132 | names(new_block) <- times
133 | names(new_block)[1] <- "well"
134 | new_block <- new_block %>%
135 | tidyr::pivot_longer(cols = 2:ncol(new_block),
136 | names_to = "time",
137 | values_to = "value",
138 | values_transform = list(value = as.numeric)) %>%
139 | dplyr::mutate(time = as.numeric(time))
140 | } else if(wells_as_columns){
141 | wells <- new_block[1, -c(1,3)]
142 | new_block <- new_block[-1,-c(1,3)]
143 | names(new_block) <- wells
144 | names(new_block)[1] <- "time"
145 | new_block <- new_block %>%
146 | tidyr::pivot_longer(cols = 2:ncol(new_block),
147 | names_to = "well",
148 | values_to = "value",
149 | values_transform = list(value = as.numeric)) %>%
150 | dplyr::mutate(time = as.numeric(time))
151 | }
152 |
153 | # add info for each well
154 | joined_block <- dplyr::full_join(plate_layout, new_block)
155 | joined_block$measure <- block_name
156 |
157 | #
158 | all_data <- rbind(all_data, joined_block)
159 |
160 | #
161 | next_block_start_idx <- next_filled(block_end_idx + 1, data)
162 | }
163 |
164 | # rearrange data ----------------------------------------------------------
165 | out_data <- all_data %>%
166 | tidyr::pivot_wider(names_from = .data$measure, values_from = .data$value) %>% # reshape so we have a column for each measurement type
167 | dplyr::mutate(row = substr(x = .data$well, start = 1, stop = 1)) %>% # make a "row" column from the "well" column
168 | dplyr::mutate(column = as.numeric(substr(x = .data$well, start = 2, # and make a "column" column
169 | stop = nchar(.data$well)))) %>%
170 | dplyr::arrange_at(dplyr::vars(.data$time, # order the rows
171 | .data$row,
172 | .data$column))
173 |
174 | # write parsed data to csv ------------------------------------------------
175 | out_name <- gsub(".csv", "_parsed.csv", data_csv)
176 | out_name <- gsub(".xlsx", "_parsed.csv", out_name)
177 | utils::write.csv(x = out_data, file = out_name, row.names = FALSE)
178 |
179 | return(out_data)
180 | }
181 | else if (timeseries == FALSE){
182 | start_time_idx <- which(data[, 1] == "Start Time") # get start and end time ids
183 | end_idx <- which(data[, 1] == "End Time")
184 | names_idx <- which(data[, 1] == "Name")
185 | names_idx <- names_idx[2:length(names_idx)] # remove the first start time entry which just details plate type
186 |
187 | all_data <- c()
188 | for (i in seq_len(length(start_time_idx))) {
189 | block_name <- data[names_idx[i], 2] # record name of what is being measured
190 |
191 | block_start <- start_time_idx[i] + 4 # find start and end of measurement block
192 | block_end_idx <- end_idx[i] - 3
193 |
194 | new_block <- data[(block_start):(block_end_idx), 1:2] # grab and name the data
195 | names(new_block)[1] <- "well"
196 | names(new_block)[2] <- "value"
197 |
198 | new_block$value <- as.numeric(new_block$value)
199 |
200 | joined_block <- dplyr::full_join(plate_layout, new_block) # join to plate layout csv, add measurement category
201 | joined_block$measure <- block_name
202 |
203 | all_data <- rbind(all_data, joined_block) # add to all data
204 | }
205 |
206 | # rearrange data ----------------------------------------------------------
207 | spread_data <- tidyr::pivot_wider(all_data, names_from = .data$measure,
208 | values_from = .data$value)
209 | spread_data$row <- substr(x = spread_data$well, start = 1, stop = 1)
210 | spread_data$column <- as.numeric(substr(x = spread_data$well, start = 2,
211 | stop = nchar(spread_data$well)))
212 | spread_data <- dplyr::arrange_at(spread_data, dplyr::vars(.data$row,
213 | .data$column))
214 |
215 | # write parsed data to csv ------------------------------------------------
216 | out_name <- gsub(".csv", "_parsed.csv", data_csv)
217 | utils::write.csv(x = spread_data, file = out_name, row.names = FALSE)
218 |
219 | return(spread_data)
220 | }
221 | }
222 |
223 | #' Parser for Tecan Spark plate reader data
224 | #'
225 | #' @param data_csv path to csv file from Tecan Spark plate reader
226 | #' @param layout_csv path to csv file containing plate layout information
227 | #'
228 | #' @return a data.frame containing the parsed plate reader data
229 | #' @export
230 | #'
231 | sparkParse <- function(data_csv, layout_csv) {
232 | return(spark_parse(data_csv, layout_csv))
233 | }
234 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Using FlopR"
3 | author: "Alex J H Fedorec"
4 | date: "02/06/2021"
5 | output:
6 | github_document:
7 | html_preview: false
8 | toc: true
9 | df_print: kable
10 | ---
11 |
12 | ```{r setup, include=FALSE}
13 | knitr::opts_chunk$set(echo = TRUE)
14 | ```
15 |
16 |
17 | ## Prerequisite Knowledge
18 |
19 | We have attempted to make our software usable with minimal prior knowledge of the R programming language or programming in general. You will need to be familiar with the idea of running commands from a console or writing basic scripts. For R beginners, [this](https://moderndive.netlify.app/1-getting-started.html) is a great starting point, there are some good resources [here](https://education.rstudio.com/learn/beginner/) and we suggest using the [RStudio application](https://rstudio.com/products/rstudio/). It provides an environment for writing and running R code.
20 |
21 | ## Installation
22 |
23 | FlopR relies on several other R packages. Most of them are available through the "Comprehensive R Archive Network (CRAN)" which just means that they can be automatically installed. There are, however, a couple that need to be manually installed if you are using the flow cytometry processing functions. To do this use the following commands:
24 |
25 | ```{r eval=FALSE, message=FALSE, warning=FALSE, results='hide'}
26 | install.packages("devtools", repos = "https://cloud.r-project.org/")
27 |
28 | if (!requireNamespace("BiocManager", quietly = TRUE))
29 | install.packages("BiocManager")
30 |
31 | BiocManager::install(c("flowCore", "flowClust", "flowStats"))
32 | ```
33 |
34 | Once those packages have been installed we are ready to install FlopR.
35 |
36 | ```{r eval=FALSE, message=FALSE, warning=FALSE, results='hide'}
37 | devtools::install_github("ucl-cssb/flopr")
38 | ```
39 |
40 | This grabs the latest version of FlopR from GitHub and builds it on your computer. If it installed successfully we should now be able to load the FlopR package in R.
41 |
42 | ```{r eval=FALSE, message=FALSE, warning=FALSE, results='hide'}
43 | library(flopr)
44 | ```
45 |
46 | The examples in this document can be run using the data in the "example" folder. Download the whole folder and make sure that you have set your current working directory (you can use the `setwd()` command in R) to the location where you saved it on your computer
47 |
48 | ## A Quick Note on .csv Files
49 | This package makes extensive use of .csv (comma separated variables) files for data and meta-data. Unfortunately, not all .csv are created equal.
50 |
51 | - When using a Windows OS computer we recommend that you save your .csv files explicitly with a UTF-8 file encoding (as shown below). This means that your files can be used by someone running a different operating system without error.
52 | - Some parts of the world use decimal commas instead of decimal points. In these places, .csv files use ";" as a separator instead of ",". Unfortunately, we are unable to automatically detect which format your .csv files are in. As such, you will have to ensure that your files are saved using "," as the separator and decimal points for the decimal mark. [This article](https://support.collaborativedrug.com/hc/en-us/articles/115004985746-CSV-files-comma-separator-and-decimal-number-format) has some help for doing so.
53 |
54 | 
55 |
56 | ## Plate Reader Calibration
57 |
58 | The experimental protocols for producing absorbance and fluorescence calibration data can be found [here](https://www.protocols.io/workspaces/igem-measurement) and [here](https://pubs.acs.org/doi/full/10.1021/acssynbio.0c00296).
59 |
60 | The data produced by plate readers from different manufacturers comes in different formats. The first step we need to do is to "parse" the data from the plate reader into a standard format. We have written an example parsers for use with data from Tecan plate readers and the Biotek Neo 2. If you need help writing a parser for your plate reader, please contact us and we'll see what we can do.
61 |
62 | For a Tecan plate reader, the data is saved as an Excel .xls file. As of flopR version 0.4.02, the spark_parse function accepts Excel files (.xls and .xlsx). If you are using an earlier version, the data first needs to be saved as a .csv file (open in Excel and "Save As" .csv) that can be read by R. We also need a .csv file telling us what is in each well of our microtitre plate. An example can be found in the "examples/plate_reader/tecan_spark" folder, but the first few rows looks like this:
63 |
64 | ```{r echo=FALSE}
65 | head(read.csv("examples/plate_reader/tecan_spark/calibration_plate_layout.csv"))
66 | ```
67 |
68 | Once we have the calibration data and layout .csv files we can parse the data.
69 |
70 | ```{r eval=FALSE}
71 | flopr::spark_parse(data_csv = "examples/plate_reader/tecan_spark/191219_calibration_membrane.csv",
72 | layout_csv = "examples/plate_reader/tecan_spark/calibration_plate_layout.csv",
73 | timeseries = FALSE)
74 | ```
75 |
76 | The `data_csv` argument takes the path to the calibration data. `layout_csv` is the path to the plate layout .csv file. Finally, the Tecan plate readers save timeseries data differently from single timepoint data, so we have a Boolean flag, `timeseries`, that lets the parser know that this is not a timeseries.
77 |
78 | The `spark_parse()` function saves the parsed calibration data in a new .csv file, in the same location as the calibration data, with "_parsed" appended to the filename. The first few rows look like this:
79 |
80 | ```{r echo=FALSE}
81 | head(read.csv("examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed.csv", check.names = FALSE))
82 | ```
83 |
84 | The parser has extracted the information we need from the calibration data and merged it with the plate layout information so that we now have columns containing each of the measurements for each well.
85 |
86 | Now we can actually calculate our calibration coefficients. To do this we just need to use one function and give it our parsed data.
87 |
88 | ```{r eval=FALSE}
89 | flopr::generate_cfs(calibration_csv = "examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed.csv")
90 | ```
91 |
92 | For details about how this process works, you can read our paper [here](https://pubs.acs.org/doi/full/10.1021/acssynbio.0c00296). At the end, there should be two .pdf images showing the calibration curves for absorbance and fluorescence, along with a new .csv file, appended with "_cfs", containing the parameters for use in the future, the first few rows of which look like this:
93 |
94 | ```{r echo=FALSE}
95 | head(read.csv("examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_cfs.csv", check.names = FALSE))
96 | ```
97 |
98 | The "cf" column contains the calibration coefficients that will be used to calibrate our data in later experiments.
99 |
100 | Before we get too excited we need to check the images to make sure that the calibration curves look sensible. The software attempts to remove data points which it deems are invalid, but this process isn't perfect and occasionally may need you to remove data points from the "*_parsed.csv" file. Using the example data, you can see ([here](examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_absorbance_cfs.pdf)) that some of the fluorescein wells are considered valid absorbance measurements. In this case, it isn't the end of the world since we would never use the parameters produced from those two curves.
101 |
102 | n.b. Currently the software is setup to work with "microspheres" for calibrating cell number and "fluorescein" for calibrating GFP fluorescence. We hope to extend it in the near future to work with other calibrants.
103 |
104 |
105 | ## Processing Plate Reader Data
106 |
107 | As mentioned above, because plate readers from different manufacturers save the data in different formats, the first step we need to do is parse our raw data. The parser that we provide takes Tecan plate reader data in the form of a .csv file. We also need a .csv file telling us what is in each well of you microtitre plate. This can include any information that you wish; we include as much meta-data as possible as it makes our data analysis later much smoother. (Before version 0.4.01: The only requirement is that **the last column must be named "well"** and include an identifier (usually the well id i.e. B2) that can be matched to the same identifier in the plate reader data.) Here's an example where we include information about the strains, plasmids, media, inducers, etc.:
108 |
109 | ```{r echo=FALSE}
110 | head(read.csv("examples/plate_reader/tecan_spark/200228_example_layout.csv", check.names = FALSE), n = 2)
111 | ```
112 |
113 | Now we can use our parsing function.
114 |
115 | ```{r eval=FALSE}
116 | flopr::spark_parse(data_csv = "examples/plate_reader/tecan_spark/200228_example_data.csv",
117 | layout_csv = "examples/plate_reader/tecan_spark/200228_example_layout.csv",
118 | timeseries = TRUE)
119 | ```
120 |
121 | The data is extracted and the meta-data from the layout is attached. Note that this time the data a timeseries so we set the `timeseries` flag to `TRUE`. A new .csv file is produced containing the parsed data with "_parsed" appended to the filename.
122 |
123 | Now we can start processing our data. There is one function that does all the work for: `process_plate()`. There are a few arguments that we need to give the function which will control what happens.
124 |
125 | ```{r eval=FALSE}
126 | flopr::process_plate(data_csv = "examples/plate_reader/tecan_spark/200228_example_data_parsed.csv",
127 | blank_well = c("C12", "D12"),
128 | neg_well = c("C6", "D6", "E6"),
129 | od_name = "OD700",
130 | flu_names = c("GFP", "mCherry"),
131 | af_model = "spline",
132 | to_MEFL = TRUE,
133 | flu_gains = 135,
134 | conversion_factors_csv = "examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_cfs.csv")
135 | ```
136 |
137 | Let's walk through what each of the arguments do:
138 |
139 | - `data_csv` is the path to our parsed data.
140 | - `blank_well` are the well identifiers of wells containing media blanks. These are used for normalising absorbance. If you only have one blank well you can specify it using `blank_well = "C12"` for example.
141 | - `neg_well` are the well identifiers of wells containing negative controls. These are used for normalising fluorescence. As above, if you only have one negative control well you can specify it using `neg_well = "C6"` for example.
142 | - `od_name` is the name of the column containing our absorbance values in the parsed data .csv file. Currently we can only use one absorbance column, so if you record absorbance at multiple wavelengths (like I do), you will have to pick one.
143 | - `flu_names` are the names of the columns containing our fluorescence values. You can include as many or as few of you fluorescence columns as you like. Whichever columns are named in here, we will attempt to normalise.
144 | - `af_model` allows you to choose the type of model that we are going to use for fluorescence normalisation. We'll discuss the available choices below.
145 | - `to_MEFL` is a Boolean flag that lets you tell the function if you want to convert the fluorescence data into calibrated units. You can only do this if you have carried out the calibration as detailed above.
146 | - `flu_gains` is where you specify the gain at which your fluorescence data was recorded for each fluorescence channel. Here we only have calibration parameters for "GFP" so we only specify one gain value.
147 | - `conversion_factors_csv` is the path to the calibration parameters that you generated using the protocol detailed above.
148 |
149 | When we run this function the absorbance is normalised, then the fluorescence and finally (if desired) the absorbance and fluorescence values are calibrated. Finally, the processed data is saved in a new .csv file with "_processed" appended to the filename and with additional columns for each of the processed values.
150 |
151 | We also save some .pdf images comparing the raw and normalised data, and images showing the fluorescence normalisation curves. Using these plots, there are a few checks that we should make before celebrating.
152 |
153 | - Check that none of the blank wells you used showed any contamination (it happens to the best of us). If there is growth in a blank well it will throw off the absorbance normalisation.
154 | - Check that the fluorescence normalisation curves fit the data. Read below for more detail on possible issues.
155 |
156 | ### Autofluorescence normalisation details
157 |
158 | Autofluorescence is the fluorescence produced by anything other than the fluorophores that we are interested in measuring. A small amount usually comes from growth media and can be minimised by choosing certain medias. A large contribution comes from molecules produced and secreted by our cells. Some of these molecules show particularly strong emission at similar wavelengths to GFP. We observe that the level of autofluorescence is not simply proportional to the number of cells or optical density of our culture. As cells enter stationary phase, autofluorescence increases, perhaps due increased production of the autofluorescent molecules and changes in cell size.
159 |
160 | In order to remove this autofluorescence from our sample data we fit a curve to our negative control data. We provide four different models that the user can choose to fit their data (and if desired more models can be added). There are two smoothing models: "loess" and "spline". The primary difference to the user between these two models is that the "spline" is able to extrapolate beyond the negative control data provided. This means that if the range of absorbance values at which you have measurements of your negative control is smaller than the range of your samples, we can still make an attempt at normalisation. However, this extrapolation is very crude (linear from the last data point) and can produce poor normalisation in the extrapolated range. Fortunately, negative controls tend to grow better than fluorescent samples, so extrapolation is often not an issue. We also provide a second-order polynomial and an exponential model, specified by "polynomial" and "exponential" repsectively. These are inherently able to make predictions beyond the range of normalised data and therefore may be good starting points.
161 |
162 | Prolonged periods in stationary phase can cause autofluorescence to increase while absorbance remains stable and in some cases absorbance can start decreasing while autofluorescence does not. In these circumstances, none of the models perform particularly well. The performance of each of them should be checked and if none of them perform satisfactorily it may be necessary to trim the data to remove confounding timepoints.
163 |
164 | ## Flow Cytometry Processing
165 |
166 | We have two functions for processing flow cytometry data:
167 |
168 | - `process_fcs` takes a single .fcs file, removes debris and doublets and saves the trimmed data in a new .fcs file.
169 | - `process_fcs_dir` takes a folder of .fcs files and performs the same trimming on each. It can also perform fluorescence normalisation if you have a negative control and fluorescence calibration if you have measured a calibrant.
170 |
171 | ### Process a single .fcs file
172 | To process a single .fcs file we can run the following command:
173 |
174 | ```{r eval=FALSE}
175 | flopr::process_fcs(fcs_file = "examples/flow_cytometry/DATA/20191121/pWeak_None_0_1.fcs",
176 | flu_channels = "BL1-H",
177 | pre_cleaned = TRUE,
178 | do_plot = TRUE)
179 | ```
180 |
181 | We need to give the function four bits of information
182 |
183 | - `fcs_file` is the path to the .fcs file that we want to process.
184 | - `flu_channels` are the names of the fluorescence channels that we recorded. When processing a single .fcs file like this we don't actually do anything with the fluorescence data. However, if you include the channel names you can see the data in a plot that is saved. If you have more than one fluorescence channel, the argument needs to be a vector, which will look something like this: `flu_channels = c("BL1-H", "BL2-H", YL2-H")`
185 | - `pre_cleaned` lets the function know if you have gated out debris on the flow cytometer. Most people do this when running their experiments by setting a threshold on forward-scatter and side-scatter. But some people like to record everything and process the data later.
186 | - `do_plot` lets the function know if you want a plot to be saved of the trimming process.
187 |
188 | In the end we have a new .fcs file with "_processed" appended to the filename, and if you asked the function to save a plot we will have a .pdf that looks something like [this](examples/flow_cytometry/DATA/20191121/pWeak_None_0_1_processed.pdf).
189 |
190 | ### Process a folder of .fcs files
191 | It's much more likely that we have more than one sample that we want to process. This is where the other function comes in handy.
192 |
193 | ```{r eval=FALSE}
194 | flopr::process_fcs_dir(dir_path = "examples/flow_cytometry/DATA/20191121",
195 | pattern = "*Med*.fcs",
196 | flu_channels = "BL1-H",
197 | pre_cleaned = TRUE,
198 | do_plot = TRUE,
199 | neg_fcs = "pNeg_None_0_1.fcs",
200 | calibrate = TRUE,
201 | mef_peaks = list(list(channel = "BL1-H",
202 | peaks = c(0, 822, 2114, 5911, 17013, 41837, 145365, 287558))))
203 | ```
204 |
205 | There are a few more arguments to this function and some of them look a bit complicated so let's go through them.
206 |
207 | - `dir_path` is the path to the folder with your .fcs files in.
208 | - `pattern` allows us to just process a subset of the .fcs files in the folder. Here we are just going to process files with "Med" in the filename. Without going into too much detail, this uses a simplified version of "regular expressions" called ["globbing patterns"](https://en.wikipedia.org/wiki/Glob_%28programming%29). We can use "wildcard" symbols to represent any character (? is a place holder for an single character and * is a place holder for 0 to any number of characters). In this example all we know is that "Med" appears somewhere in the filenames and they all end with ".fcs". So we use the * character to show that there are some unknown characters before "Med" and between "Med" and ".fcs". If you want to process all .fcs files in your folder, the pattern would be "*.fcs".
209 | - `flu_channels` is as above.
210 | - `pre_cleaned` is as above.
211 | - `do_plot` is as above.
212 | - `neg_fcs` is the filename of your negative control sample. It must be in the folder with the other .fcs files. This is used to normalise autofluorescence. If you don't specify a filename here, the processing will be carried out without any normalisation steps.
213 | - `calibrate` tells the function whether you want to calibrate the fluorescence measurements. To be able to calibrate you must have an .fcs file with data from calibration beads and it must have "beads" somewhere in the filename. For discussion about calibration beads, read our paper or check out [TASBE](https://tasbe.github.io/) and [FlowCal](https://taborlab.github.io/FlowCal/).
214 | - `mef_peaks` is where we tell the function what the true fluorophore values are for our beads. These will be available from the bead manufacturer. We need to specify peaks for each of the channels that we want to calibrate and the channel name needs to correspond to one given in `flu_channels`. Here we are just calibrating the "BL1-H" channel which corresponds to GFP on our flow cytometer. If you wanted to calibrate two channels it would look something like this:
215 | ```{r eval=FALSE}
216 | mef_peaks = list(list(channel = "BL1-H",
217 | peaks = c(0, 822, 2114, 5911, 17013, 41837, 145365, 287558)),
218 | list(channel = "YL2-H",
219 | peaks = c(0, 218, 581, 1963, 6236, 15267, 68766, 181945)))
220 | ```
221 |
222 | The function carries out the trimming as described above. Then, if a negative control file is given, it performs fluorescence normalisation by negating the geometric mean of the negative control's fluorescence in each channel from each of the other samples. Finally, if the files are going to be calibrated, a calibration curve is fit to the bead peaks in each of the fluorescence channels in `mef_peaks`. We use a model developed for FlowCal for our calibration curve. We then calibrate both the raw and normalised data since normalisation can produce fluorescence values less than or equal to 0, which get removed during calibration due to working with logged data (the output will contain a both sets of calibration). The new data, any plots produced, and a data_summary.csv file (containing geometric statistics for each .fcs file) will be saved to a new folder with the same name as the original but with "_processed" appended.
223 |
224 | There are a few checks that should be made to reassure yourself that everything has worked.
225 |
226 | - To confirm correct trimming, we recommend setting `do_plot = TRUE` so that you can see which events have been removed during processing. Check that the debris, if there is any, and doublets have been correctly identified and removed.
227 | - For each fluorescence calibration channel, a plot will be saved showing the bead peaks that have been identified and the calibration curve that we have fit to them. Sometime the bead peaks aren't identified correctly. In this case, there is another argument that the function can take `beads_dens_bw`, which has a default value of `0.025`. To identify the beads we use something called a Gaussian kernel to smooth the fluorescence data and pick the highest points. Sometimes this smoothing isn't quite right; we might not smooth enough and one peak is identified as two, or we smooth too much and lose peaks. In the former case we need to increase `beads_dens_bw` and in the latter we decrease it. If tweaking this value doesn't work, we also provide a way to manually specify identify the peaks using the `manual_peaks` argument. For this data, a manually specified set of peaks would look like this:
228 |
229 | ```{r eval=FALSE}
230 | manual_peaks = list(list(channel = "BL1-H",
231 | peaks = c(1.9, 2.5, 2.9, 3.3, 3.7, 4.2, 4.6, 4.95)))
232 | ```
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Using FlopR
2 | ================
3 | Alex J H Fedorec
4 | 02/06/2021
5 |
6 | - [Prerequisite Knowledge](#prerequisite-knowledge)
7 | - [Installation](#installation)
8 | - [A Quick Note on .csv Files](#a-quick-note-on-csv-files)
9 | - [Plate Reader Calibration](#plate-reader-calibration)
10 | - [Processing Plate Reader Data](#processing-plate-reader-data)
11 | - [Autofluorescence normalisation
12 | details](#autofluorescence-normalisation-details)
13 | - [Flow Cytometry Processing](#flow-cytometry-processing)
14 | - [Process a single .fcs file](#process-a-single-fcs-file)
15 | - [Process a folder of .fcs files](#process-a-folder-of-fcs-files)
16 |
17 | ## Prerequisite Knowledge
18 |
19 | We have attempted to make our software usable with minimal prior
20 | knowledge of the R programming language or programming in general. You
21 | will need to be familiar with the idea of running commands from a
22 | console or writing basic scripts. For R beginners,
23 | [this](https://moderndive.netlify.app/1-getting-started.html) is a great
24 | starting point, there are some good resources
25 | [here](https://education.rstudio.com/learn/beginner/) and we suggest
26 | using the [RStudio application](https://rstudio.com/products/rstudio/).
27 | It provides an environment for writing and running R code.
28 |
29 | ## Installation
30 |
31 | FlopR relies on several other R packages. Most of them are available
32 | through the “Comprehensive R Archive Network (CRAN)” which just means
33 | that they can be automatically installed. There are, however, a couple
34 | that need to be manually installed if you are using the flow cytometry
35 | processing functions. To do this use the following commands:
36 |
37 | ``` r
38 | install.packages("devtools", repos = "https://cloud.r-project.org/")
39 |
40 | if (!requireNamespace("BiocManager", quietly = TRUE))
41 | install.packages("BiocManager")
42 |
43 | BiocManager::install(c("flowCore", "flowClust", "flowStats"))
44 | ```
45 |
46 | Once those packages have been installed we are ready to install FlopR.
47 |
48 | ``` r
49 | devtools::install_github("ucl-cssb/flopr")
50 | ```
51 |
52 | This grabs the latest version of FlopR from GitHub and builds it on your
53 | computer. If it installed successfully we should now be able to load the
54 | FlopR package in R.
55 |
56 | ``` r
57 | library(flopr)
58 | ```
59 |
60 | The examples in this document can be run using the data in the “example”
61 | folder. Download the whole folder and make sure that you have set your
62 | current working directory (you can use the `setwd()` command in R) to
63 | the location where you saved it on your computer
64 |
65 | ## A Quick Note on .csv Files
66 |
67 | This package makes extensive use of .csv (comma separated variables)
68 | files for data and meta-data. Unfortunately, not all .csv are created
69 | equal.
70 |
71 | - When using a Windows OS computer we recommend that you save your
72 | .csv files explicitly with a UTF-8 file encoding (as shown below).
73 | This means that your files can be used by someone running a
74 | different operating system without error.
75 | - Some parts of the world use decimal commas instead of decimal
76 | points. In these places, .csv files use “;” as a separator instead
77 | of “,”. Unfortunately, we are unable to automatically detect which
78 | format your .csv files are in. As such, you will have to ensure that
79 | your files are saved using “,” as the separator and decimal points
80 | for the decimal mark. [This
81 | article](https://support.collaborativedrug.com/hc/en-us/articles/115004985746-CSV-files-comma-separator-and-decimal-number-format)
82 | has some help for doing so.
83 |
84 | 
86 |
87 | ## Plate Reader Calibration
88 |
89 | The experimental protocols for producing absorbance and fluorescence
90 | calibration data can be found
91 | [here](https://www.protocols.io/workspaces/igem-measurement) and
92 | [here](https://pubs.acs.org/doi/full/10.1021/acssynbio.0c00296).
93 |
94 | The data produced by plate readers from different manufacturers comes in
95 | different formats. The first step we need to do is to “parse” the data
96 | from the plate reader into a standard format. We have written an example
97 | parsers for use with data from Tecan plate readers and the Biotek Neo 2.
98 | If you need help writing a parser for your plate reader, please contact
99 | us and we’ll see what we can do.
100 |
101 | For a Tecan plate reader, the data is saved as an Excel .xls file. As of
102 | flopR version 0.4.02, the spark\_parse function accepts Excel files
103 | (.xls and .xlsx). If you are using an earlier version, the data first
104 | needs to be saved as a .csv file (open in Excel and “Save As” .csv) that
105 | can be read by R. We also need a .csv file telling us what is in each
106 | well of our microtitre plate. An example can be found in the
107 | “examples/plate\_reader/tecan\_spark” folder, but the first few rows
108 | looks like this:
109 |
110 |
111 |
112 | | calibrant | fluorophore | media | concentration | replicate | well |
113 | |:------------|:------------|:------|--------------:|----------:|:-----|
114 | | fluorescein | GFP | PBS | 7.53000e+14 | 1 | A1 |
115 | | fluorescein | GFP | PBS | 3.76500e+14 | 1 | A2 |
116 | | fluorescein | GFP | PBS | 1.88250e+14 | 1 | A3 |
117 | | fluorescein | GFP | PBS | 9.41250e+13 | 1 | A4 |
118 | | fluorescein | GFP | PBS | 4.70625e+13 | 1 | A5 |
119 | | fluorescein | GFP | PBS | 2.35313e+13 | 1 | A6 |
120 |
121 |
122 |
123 | Once we have the calibration data and layout .csv files we can parse the
124 | data.
125 |
126 | ``` r
127 | flopr::spark_parse(data_csv = "examples/plate_reader/tecan_spark/191219_calibration_membrane.csv",
128 | layout_csv = "examples/plate_reader/tecan_spark/calibration_plate_layout.csv",
129 | timeseries = FALSE)
130 | ```
131 |
132 | The `data_csv` argument takes the path to the calibration data.
133 | `layout_csv` is the path to the plate layout .csv file. Finally, the
134 | Tecan plate readers save timeseries data differently from single
135 | timepoint data, so we have a Boolean flag, `timeseries`, that lets the
136 | parser know that this is not a timeseries.
137 |
138 | The `spark_parse()` function saves the parsed calibration data in a new
139 | .csv file, in the same location as the calibration data, with "\_parsed"
140 | appended to the filename. The first few rows look like this:
141 |
142 |
143 |
144 | | calibrant | fluorophore | media | concentration | replicate | well | OD600 | OD700 | GFP 40 | GFP 50 | GFP 60 | GFP 70 | GFP 80 | GFP 90 | GFP 100 | GFP 110 | GFP 120 | row | column |
145 | |:------------|:------------|:------|--------------:|----------:|:-----|-------:|-------:|-------:|-------:|-------:|-------:|-------:|-------:|--------:|--------:|--------:|:----|-------:|
146 | | fluorescein | GFP | PBS | 10.0000 | 1 | A1 | 0.0921 | 0.0831 | 1830 | 9811 | 36911 | NA | NA | NA | NA | NA | NA | A | 1 |
147 | | fluorescein | GFP | PBS | 5.0000 | 1 | A2 | 0.0942 | 0.0852 | 932 | 4993 | 19221 | 54510 | NA | NA | NA | NA | NA | A | 2 |
148 | | fluorescein | GFP | PBS | 2.5000 | 1 | A3 | 0.1015 | 0.0928 | 453 | 2434 | 9448 | 27864 | NA | NA | NA | NA | NA | A | 3 |
149 | | fluorescein | GFP | PBS | 1.2500 | 1 | A4 | 0.0985 | 0.0899 | 232 | 1253 | 4853 | 14513 | 36349 | NA | NA | NA | NA | A | 4 |
150 | | fluorescein | GFP | PBS | 0.6250 | 1 | A5 | 0.0957 | 0.0905 | 114 | 617 | 2404 | 7128 | 18282 | 41812 | NA | NA | NA | A | 5 |
151 | | fluorescein | GFP | PBS | 0.3125 | 1 | A6 | 0.1027 | 0.0965 | 54 | 294 | 1137 | 3388 | 8672 | 20095 | 42244 | NA | NA | A | 6 |
152 |
153 |
154 |
155 | The parser has extracted the information we need from the calibration
156 | data and merged it with the plate layout information so that we now have
157 | columns containing each of the measurements for each well.
158 |
159 | Now we can actually calculate our calibration coefficients. To do this
160 | we just need to use one function and give it our parsed data.
161 |
162 | ``` r
163 | flopr::generate_cfs(calibration_csv = "examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed.csv")
164 | ```
165 |
166 | For details about how this process works, you can read our paper
167 | [here](https://pubs.acs.org/doi/full/10.1021/acssynbio.0c00296). At the
168 | end, there should be two .pdf images showing the calibration curves for
169 | absorbance and fluorescence, along with a new .csv file, appended with
170 | "\_cfs", containing the parameters for use in the future, the first few
171 | rows of which look like this:
172 |
173 |
174 |
175 | | cf | beta | calibrant | fluorophore | measure |
176 | |-----------:|-----------:|:------------|:------------|:--------|
177 | | 184.7274 | 0.0057476 | fluorescein | GFP | GFP 40 |
178 | | 996.4472 | -0.0035424 | fluorescein | GFP | GFP 50 |
179 | | 3821.0497 | -0.0004737 | fluorescein | GFP | GFP 60 |
180 | | 11298.9531 | 0.0002015 | fluorescein | GFP | GFP 70 |
181 | | 29128.3783 | -0.0007481 | fluorescein | GFP | GFP 80 |
182 | | 65834.9342 | 0.0012751 | fluorescein | GFP | GFP 90 |
183 |
184 |
185 |
186 | The “cf” column contains the calibration coefficients that will be used
187 | to calibrate our data in later experiments.
188 |
189 | Before we get too excited we need to check the images to make sure that
190 | the calibration curves look sensible. The software attempts to remove
191 | data points which it deems are invalid, but this process isn’t perfect
192 | and occasionally may need you to remove data points from the
193 | "\*\_parsed.csv" file. Using the example data, you can see
194 | ([here](examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_absorbance_cfs.pdf))
195 | that some of the fluorescein wells are considered valid absorbance
196 | measurements. In this case, it isn’t the end of the world since we would
197 | never use the parameters produced from those two curves.
198 |
199 | n.b. Currently the software is setup to work with “microspheres” for
200 | calibrating cell number and “fluorescein” for calibrating GFP
201 | fluorescence. We hope to extend it in the near future to work with other
202 | calibrants.
203 |
204 | ## Processing Plate Reader Data
205 |
206 | As mentioned above, because plate readers from different manufacturers
207 | save the data in different formats, the first step we need to do is
208 | parse our raw data. The parser that we provide takes Tecan plate reader
209 | data in the form of a .csv file. We also need a .csv file telling us
210 | what is in each well of you microtitre plate. This can include any
211 | information that you wish; we include as much meta-data as possible as
212 | it makes our data analysis later much smoother. (Before version 0.4.01:
213 | The only requirement is that **the last column must be named “well”**
214 | and include an identifier (usually the well id i.e. B2) that can be
215 | matched to the same identifier in the plate reader data.) Here’s an
216 | example where we include information about the strains, plasmids, media,
217 | inducers, etc.:
218 |
219 |
220 |
221 | | strain | host | plasmid | plasmid\_2 | strain\_2 | media | sugar | amino\_acids | inducer | concentration | init\_ratio | init\_dilution | well |
222 | |:-------|:-----|:--------|:-----------|:----------|:------|:------|:-------------|:--------|--------------:|------------:|---------------:|:-----|
223 | | | | | | | | | | | NA | NA | NA | A1 |
224 | | | | | | | | | | | NA | NA | NA | A2 |
225 |
226 |
227 |
228 | Now we can use our parsing function.
229 |
230 | ``` r
231 | flopr::spark_parse(data_csv = "examples/plate_reader/tecan_spark/200228_example_data.csv",
232 | layout_csv = "examples/plate_reader/tecan_spark/200228_example_layout.csv",
233 | timeseries = TRUE)
234 | ```
235 |
236 | The data is extracted and the meta-data from the layout is attached.
237 | Note that this time the data a timeseries so we set the `timeseries`
238 | flag to `TRUE`. A new .csv file is produced containing the parsed data
239 | with "\_parsed" appended to the filename.
240 |
241 | Now we can start processing our data. There is one function that does
242 | all the work for: `process_plate()`. There are a few arguments that we
243 | need to give the function which will control what happens.
244 |
245 | ``` r
246 | flopr::process_plate(data_csv = "examples/plate_reader/tecan_spark/200228_example_data_parsed.csv",
247 | blank_well = c("C12", "D12"),
248 | neg_well = c("C6", "D6", "E6"),
249 | od_name = "OD700",
250 | flu_names = c("GFP", "mCherry"),
251 | af_model = "spline",
252 | to_MEFL = TRUE,
253 | flu_gains = 135,
254 | conversion_factors_csv = "examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_cfs.csv")
255 | ```
256 |
257 | Let’s walk through what each of the arguments do:
258 |
259 | - `data_csv` is the path to our parsed data.
260 | - `blank_well` are the well identifiers of wells containing media
261 | blanks. These are used for normalising absorbance. If you only have
262 | one blank well you can specify it using `blank_well = "C12"` for
263 | example.
264 | - `neg_well` are the well identifiers of wells containing negative
265 | controls. These are used for normalising fluorescence. As above, if
266 | you only have one negative control well you can specify it using
267 | `neg_well = "C6"` for example.
268 | - `od_name` is the name of the column containing our absorbance values
269 | in the parsed data .csv file. Currently we can only use one
270 | absorbance column, so if you record absorbance at multiple
271 | wavelengths (like I do), you will have to pick one.
272 | - `flu_names` are the names of the columns containing our fluorescence
273 | values. You can include as many or as few of you fluorescence
274 | columns as you like. Whichever columns are named in here, we will
275 | attempt to normalise.
276 | - `af_model` allows you to choose the type of model that we are going
277 | to use for fluorescence normalisation. We’ll discuss the available
278 | choices below.
279 | - `to_MEFL` is a Boolean flag that lets you tell the function if you
280 | want to convert the fluorescence data into calibrated units. You can
281 | only do this if you have carried out the calibration as detailed
282 | above.
283 | - `flu_gains` is where you specify the gain at which your fluorescence
284 | data was recorded for each fluorescence channel. Here we only have
285 | calibration parameters for “GFP” so we only specify one gain value.
286 | - `conversion_factors_csv` is the path to the calibration parameters
287 | that you generated using the protocol detailed above.
288 |
289 | When we run this function the absorbance is normalised, then the
290 | fluorescence and finally (if desired) the absorbance and fluorescence
291 | values are calibrated. Finally, the processed data is saved in a new
292 | .csv file with "\_processed" appended to the filename and with
293 | additional columns for each of the processed values.
294 |
295 | We also save some .pdf images comparing the raw and normalised data, and
296 | images showing the fluorescence normalisation curves. Using these plots,
297 | there are a few checks that we should make before celebrating.
298 |
299 | - Check that none of the blank wells you used showed any contamination
300 | (it happens to the best of us). If there is growth in a blank well
301 | it will throw off the absorbance normalisation.
302 | - Check that the fluorescence normalisation curves fit the data. Read
303 | below for more detail on possible issues.
304 |
305 | ### Autofluorescence normalisation details
306 |
307 | Autofluorescence is the fluorescence produced by anything other than the
308 | fluorophores that we are interested in measuring. A small amount usually
309 | comes from growth media and can be minimised by choosing certain medias.
310 | A large contribution comes from molecules produced and secreted by our
311 | cells. Some of these molecules show particularly strong emission at
312 | similar wavelengths to GFP. We observe that the level of
313 | autofluorescence is not simply proportional to the number of cells or
314 | optical density of our culture. As cells enter stationary phase,
315 | autofluorescence increases, perhaps due increased production of the
316 | autofluorescent molecules and changes in cell size.
317 |
318 | In order to remove this autofluorescence from our sample data we fit a
319 | curve to our negative control data. We provide four different models
320 | that the user can choose to fit their data (and if desired more models
321 | can be added). There are two smoothing models: “loess” and “spline”. The
322 | primary difference to the user between these two models is that the
323 | “spline” is able to extrapolate beyond the negative control data
324 | provided. This means that if the range of absorbance values at which you
325 | have measurements of your negative control is smaller than the range of
326 | your samples, we can still make an attempt at normalisation. However,
327 | this extrapolation is very crude (linear from the last data point) and
328 | can produce poor normalisation in the extrapolated range. Fortunately,
329 | negative controls tend to grow better than fluorescent samples, so
330 | extrapolation is often not an issue. We also provide a second-order
331 | polynomial and an exponential model, specified by “polynomial” and
332 | “exponential” repsectively. These are inherently able to make
333 | predictions beyond the range of normalised data and therefore may be
334 | good starting points.
335 |
336 | Prolonged periods in stationary phase can cause autofluorescence to
337 | increase while absorbance remains stable and in some cases absorbance
338 | can start decreasing while autofluorescence does not. In these
339 | circumstances, none of the models perform particularly well. The
340 | performance of each of them should be checked and if none of them
341 | perform satisfactorily it may be necessary to trim the data to remove
342 | confounding timepoints.
343 |
344 | ## Flow Cytometry Processing
345 |
346 | We have two functions for processing flow cytometry data:
347 |
348 | - `process_fcs` takes a single .fcs file, removes debris and doublets
349 | and saves the trimmed data in a new .fcs file.
350 | - `process_fcs_dir` takes a folder of .fcs files and performs the same
351 | trimming on each. It can also perform fluorescence normalisation if
352 | you have a negative control and fluorescence calibration if you have
353 | measured a calibrant.
354 |
355 | ### Process a single .fcs file
356 |
357 | To process a single .fcs file we can run the following command:
358 |
359 | ``` r
360 | flopr::process_fcs(fcs_file = "examples/flow_cytometry/DATA/20191121/pWeak_None_0_1.fcs",
361 | flu_channels = "BL1-H",
362 | pre_cleaned = TRUE,
363 | do_plot = TRUE)
364 | ```
365 |
366 | We need to give the function four bits of information
367 |
368 | - `fcs_file` is the path to the .fcs file that we want to process.
369 | - `flu_channels` are the names of the fluorescence channels that we
370 | recorded. When processing a single .fcs file like this we don’t
371 | actually do anything with the fluorescence data. However, if you
372 | include the channel names you can see the data in a plot that is
373 | saved. If you have more than one fluorescence channel, the argument
374 | needs to be a vector, which will look something like this:
375 | `flu_channels = c("BL1-H", "BL2-H", YL2-H")`
376 | - `pre_cleaned` lets the function know if you have gated out debris on
377 | the flow cytometer. Most people do this when running their
378 | experiments by setting a threshold on forward-scatter and
379 | side-scatter. But some people like to record everything and process
380 | the data later.
381 | - `do_plot` lets the function know if you want a plot to be saved of
382 | the trimming process.
383 |
384 | In the end we have a new .fcs file with "\_processed" appended to the
385 | filename, and if you asked the function to save a plot we will have a
386 | .pdf that looks something like
387 | [this](examples/flow_cytometry/DATA/20191121/pWeak_None_0_1_processed.pdf).
388 |
389 | ### Process a folder of .fcs files
390 |
391 | It’s much more likely that we have more than one sample that we want to
392 | process. This is where the other function comes in handy.
393 |
394 | ``` r
395 | flopr::process_fcs_dir(dir_path = "examples/flow_cytometry/DATA/20191121",
396 | pattern = "*Med*.fcs",
397 | flu_channels = "BL1-H",
398 | pre_cleaned = TRUE,
399 | do_plot = TRUE,
400 | neg_fcs = "pNeg_None_0_1.fcs",
401 | calibrate = TRUE,
402 | mef_peaks = list(list(channel = "BL1-H",
403 | peaks = c(0, 822, 2114, 5911, 17013, 41837, 145365, 287558))))
404 | ```
405 |
406 | There are a few more arguments to this function and some of them look a
407 | bit complicated so let’s go through them.
408 |
409 | - `dir_path` is the path to the folder with your .fcs files in.
410 | - `pattern` allows us to just process a subset of the .fcs files in
411 | the folder. Here we are just going to process files with “Med” in
412 | the filename. Without going into too much detail, this uses a
413 | simplified version of “regular expressions” called [“globbing
414 | patterns”](https://en.wikipedia.org/wiki/Glob_%28programming%29). We
415 | can use “wildcard” symbols to represent any character (? is a place
416 | holder for an single character and \* is a place holder for 0 to any
417 | number of characters). In this example all we know is that “Med”
418 | appears somewhere in the filenames and they all end with “.fcs”. So
419 | we use the \* character to show that there are some unknown
420 | characters before “Med” and between “Med” and “.fcs”. If you want to
421 | process all .fcs files in your folder, the pattern would be
422 | "\*.fcs".
423 | - `flu_channels` is as above.
424 | - `pre_cleaned` is as above.
425 | - `do_plot` is as above.
426 | - `neg_fcs` is the filename of your negative control sample. It must
427 | be in the folder with the other .fcs files. This is used to
428 | normalise autofluorescence. If you don’t specify a filename here,
429 | the processing will be carried out without any normalisation steps.
430 | - `calibrate` tells the function whether you want to calibrate the
431 | fluorescence measurements. To be able to calibrate you must have an
432 | .fcs file with data from calibration beads and it must have “beads”
433 | somewhere in the filename. For discussion about calibration beads,
434 | read our paper or check out [TASBE](https://tasbe.github.io/) and
435 | [FlowCal](https://taborlab.github.io/FlowCal/).
436 | - `mef_peaks` is where we tell the function what the true fluorophore
437 | values are for our beads. These will be available from the bead
438 | manufacturer. We need to specify peaks for each of the channels that
439 | we want to calibrate and the channel name needs to correspond to one
440 | given in `flu_channels`. Here we are just calibrating the “BL1-H”
441 | channel which corresponds to GFP on our flow cytometer. If you
442 | wanted to calibrate two channels it would look something like this:
443 |
444 | ``` r
445 | mef_peaks = list(list(channel = "BL1-H",
446 | peaks = c(0, 822, 2114, 5911, 17013, 41837, 145365, 287558)),
447 | list(channel = "YL2-H",
448 | peaks = c(0, 218, 581, 1963, 6236, 15267, 68766, 181945)))
449 | ```
450 |
451 | The function carries out the trimming as described above. Then, if a
452 | negative control file is given, it performs fluorescence normalisation
453 | by negating the geometric mean of the negative control’s fluorescence in
454 | each channel from each of the other samples. Finally, if the files are
455 | going to be calibrated, a calibration curve is fit to the bead peaks in
456 | each of the fluorescence channels in `mef_peaks`. We use a model
457 | developed for FlowCal for our calibration curve. We then calibrate both
458 | the raw and normalised data since normalisation can produce fluorescence
459 | values less than or equal to 0, which get removed during calibration due
460 | to working with logged data (the output will contain a both sets of
461 | calibration). The new data, any plots produced, and a data\_summary.csv
462 | file (containing geometric statistics for each .fcs file) will be saved
463 | to a new folder with the same name as the original but with
464 | "\_processed" appended.
465 |
466 | There are a few checks that should be made to reassure yourself that
467 | everything has worked.
468 |
469 | - To confirm correct trimming, we recommend setting `do_plot = TRUE`
470 | so that you can see which events have been removed during
471 | processing. Check that the debris, if there is any, and doublets
472 | have been correctly identified and removed.
473 | - For each fluorescence calibration channel, a plot will be saved
474 | showing the bead peaks that have been identified and the calibration
475 | curve that we have fit to them. Sometime the bead peaks aren’t
476 | identified correctly. In this case, there is another argument that
477 | the function can take `beads_dens_bw`, which has a default value of
478 | `0.025`. To identify the beads we use something called a Gaussian
479 | kernel to smooth the fluorescence data and pick the highest points.
480 | Sometimes this smoothing isn’t quite right; we might not smooth
481 | enough and one peak is identified as two, or we smooth too much and
482 | lose peaks. In the former case we need to increase `beads_dens_bw`
483 | and in the latter we decrease it. If tweaking this value doesn’t
484 | work, we also provide a way to manually specify identify the peaks
485 | using the `manual_peaks` argument. For this data, a manually
486 | specified set of peaks would look like this:
487 |
488 | ``` r
489 | manual_peaks = list(list(channel = "BL1-H",
490 | peaks = c(1.9, 2.5, 2.9, 3.3, 3.7, 4.2, 4.6, 4.95)))
491 | ```
492 |
--------------------------------------------------------------------------------
/examples/csv_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/csv_save.png
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/20191121_beads.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/20191121_beads.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/20191121_plate_layout.csv:
--------------------------------------------------------------------------------
1 | strain,plasmid,name,media,replicate,well,row,col
2 | ,,,,,A1,A,1
3 | DH5alpha,Bba_I20270,Pos,LB,1,A2,A,2
4 | DH5alpha,Bba_J364000,J23101,LB,1,A3,A,3
5 | DH5alpha,Bba_J364001,J23106,LB,1,A4,A,4
6 | DH5alpha,Bba_J364002,J23117,LB,1,A5,A,5
7 | DH5alpha,Bba_R0040,Neg,LB,1,A6,A,6
8 | DH5alpha,Bba_I20270,Pos,LB,1,A7,A,7
9 | DH5alpha,Bba_J364000,J23101,LB,1,A8,A,8
10 | DH5alpha,Bba_J364001,J23106,LB,1,A9,A,9
11 | DH5alpha,Bba_J364002,J23117,LB,1,A10,A,10
12 | ,,,,,A11,A,11
13 | ,,,,,A12,A,12
14 | ,,,,,B1,B,1
15 | DH5alpha,Bba_I20270,Pos,LB,2,B2,B,2
16 | DH5alpha,Bba_J364000,J23101,LB,2,B3,B,3
17 | DH5alpha,Bba_J364001,J23106,LB,2,B4,B,4
18 | DH5alpha,Bba_J364002,J23117,LB,2,B5,B,5
19 | DH5alpha,Bba_R0040,Neg,LB,2,B6,B,6
20 | DH5alpha,Bba_I20270,Pos,LB,2,B7,B,7
21 | DH5alpha,Bba_J364000,J23101,LB,2,B8,B,8
22 | DH5alpha,Bba_J364001,J23106,LB,2,B9,B,9
23 | DH5alpha,Bba_J364002,J23117,LB,2,B10,B,10
24 | ,,,,,B11,B,11
25 | ,,,,,B12,B,12
26 | ,,,,,C1,C,1
27 | DH5alpha,Bba_I20270,Pos,LB,3,C2,C,2
28 | DH5alpha,Bba_J364000,J23101,LB,3,C3,C,3
29 | DH5alpha,Bba_J364001,J23106,LB,3,C4,C,4
30 | DH5alpha,Bba_J364002,J23117,LB,3,C5,C,5
31 | DH5alpha,Bba_R0040,Neg,LB,3,C6,C,6
32 | DH5alpha,Bba_I20270,Pos,LB,3,C7,C,7
33 | DH5alpha,Bba_J364000,J23101,LB,3,C8,C,8
34 | DH5alpha,Bba_J364001,J23106,LB,3,C9,C,9
35 | DH5alpha,Bba_J364002,J23117,LB,3,C10,C,10
36 | ,,,,,C11,C,11
37 | ,,,,,C12,C,12
38 | ,,,,,D1,D,1
39 | DH5alpha,Bba_I20270,Pos,LB,4,D2,D,2
40 | DH5alpha,Bba_J364000,J23101,LB,4,D3,D,3
41 | DH5alpha,Bba_J364001,J23106,LB,4,D4,D,4
42 | DH5alpha,Bba_J364002,J23117,LB,4,D5,D,5
43 | DH5alpha,Bba_R0040,Neg,LB,4,D6,D,6
44 | DH5alpha,Bba_I20270,Pos,LB,4,D7,D,7
45 | DH5alpha,Bba_J364000,J23101,LB,4,D8,D,8
46 | DH5alpha,Bba_J364001,J23106,LB,4,D9,D,9
47 | DH5alpha,Bba_J364002,J23117,LB,4,D10,D,10
48 | ,,,,,D11,D,11
49 | ,,,,,D12,D,12
50 | ,,,,,E1,E,1
51 | ,,,,,E2,E,2
52 | blank,blank,,LB,1,E3,E,3
53 | ,,,,,E4,E,4
54 | ,,,,,E5,E,5
55 | ,,,,,E6,E,6
56 | ,,,,,E7,E,7
57 | ,,,,,E8,E,8
58 | ,,,,,E9,E,9
59 | ,,,,,E10,E,10
60 | ,,,,,E11,E,11
61 | ,,,,,E12,E,12
62 | ,,,,,F1,F,1
63 | ,,,,,F2,F,2
64 | blank,blank,,LB,2,F3,F,3
65 | ,,,,,F4,F,4
66 | ,,,,,F5,F,5
67 | ,,,,,F6,F,6
68 | ,,,,,F7,F,7
69 | ,,,,,F8,F,8
70 | ,,,,,F9,F,9
71 | ,,,,,F10,F,10
72 | ,,,,,F11,F,11
73 | ,,,,,F12,F,12
74 | ,,,,,G1,G,1
75 | ,,,,,G2,G,2
76 | blank,blank,,LB,3,G3,G,3
77 | ,,,,,G4,G,4
78 | ,,,,,G5,G,5
79 | ,,,,,G6,G,6
80 | ,,,,,G7,G,7
81 | ,,,,,G8,G,8
82 | ,,,,,G9,G,9
83 | ,,,,,G10,G,10
84 | ,,,,,G11,G,11
85 | ,,,,,G12,G,12
86 | ,,,,,H1,H,1
87 | ,,,,,H2,H,2
88 | ,,,,,H3,H,3
89 | ,,,,,H4,H,4
90 | ,,,,,H5,H,5
91 | ,,,,,H6,H,6
92 | ,,,,,H7,H,7
93 | ,,,,,H8,H,8
94 | ,,,,,H9,H,9
95 | ,,,,,H10,H,10
96 | ,,,,,H11,H,11
97 | ,,,,,H12,H,12
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_1.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_1.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_10.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_10.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_2.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_2.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_3.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_3.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_4.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_4.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_5.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_5.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_6.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_6.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_7.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_7.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_8.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_8.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pMed_None_0_9.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pMed_None_0_9.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pNeg_None_0_1.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pNeg_None_0_1.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pNeg_None_0_2.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pNeg_None_0_2.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pNeg_None_0_3.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pNeg_None_0_3.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pNeg_None_0_4.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pNeg_None_0_4.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pNeg_None_0_5.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pNeg_None_0_5.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pNeg_None_0_6.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pNeg_None_0_6.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pNeg_None_0_7.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pNeg_None_0_7.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pNeg_None_0_8.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pNeg_None_0_8.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_1.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_1.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_10.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_10.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_11.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_11.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_12.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_12.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_2.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_2.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_3.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_3.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_4.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_4.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_5.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_5.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_6.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_6.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_7.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_7.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_8.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_8.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pStrong_None_0_9.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pStrong_None_0_9.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_1.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_1.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_10.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_10.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_11.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_11.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_12.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_12.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_1_processed.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_1_processed.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_1_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_1_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_2.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_2.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_3.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_3.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_4.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_4.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_5.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_5.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_7.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_7.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_8.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_8.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121/pWeak_None_0_9.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121/pWeak_None_0_9.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/20191121_beads_BL1-H_calibration.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/20191121_beads_BL1-H_calibration.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/20191121_beads_singlet_beads.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/20191121_beads_singlet_beads.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/data_summary.csv:
--------------------------------------------------------------------------------
1 | "","file","channel","mean","sd"
2 | "1","pMed_None_0_1.fcs","BL1-H",14065.6856135571,3.69713174089346
3 | "2","pMed_None_0_1.fcs","normalised_BL1-H",17772.439416889,1.75375962404867
4 | "3","pMed_None_0_1.fcs","calibrated_BL1-H",42704.351632172,3.81842449628054
5 | "4","pMed_None_0_1.fcs","calibrated_normalised_BL1-H",54270.7967240767,1.77825127253438
6 | "5","pMed_None_0_10.fcs","BL1-H",4105.50782199545,12.8683957548119
7 | "6","pMed_None_0_10.fcs","normalised_BL1-H",14082.2843664163,2.99120031272887
8 | "7","pMed_None_0_10.fcs","calibrated_BL1-H",12091.3633934326,13.7061670007658
9 | "8","pMed_None_0_10.fcs","calibrated_normalised_BL1-H",42755.9914300549,3.0732156097424
10 | "9","pMed_None_0_2.fcs","BL1-H",13353.1050496398,2.02389307488439
11 | "10","pMed_None_0_2.fcs","normalised_BL1-H",13756.8784235517,1.70349519617632
12 | "11","pMed_None_0_2.fcs","calibrated_BL1-H",40488.9092430635,2.05942809142663
13 | "12","pMed_None_0_2.fcs","calibrated_normalised_BL1-H",41743.9086372191,1.72604529864676
14 | "13","pMed_None_0_3.fcs","BL1-H",16272.0637294663,2.32711470166975
15 | "14","pMed_None_0_3.fcs","normalised_BL1-H",17485.7527168965,1.65530050403779
16 | "15","pMed_None_0_3.fcs","calibrated_BL1-H",49581.0983720343,2.37614904749194
17 | "16","pMed_None_0_3.fcs","calibrated_normalised_BL1-H",53373.9230353711,1.67602469808081
18 | "17","pMed_None_0_4.fcs","BL1-H",12240.7466324196,2.5952189354505
19 | "18","pMed_None_0_4.fcs","normalised_BL1-H",13504.2071564739,1.78026888040504
20 | "19","pMed_None_0_4.fcs","calibrated_BL1-H",37036.4334453882,2.6570455920304
21 | "20","pMed_None_0_4.fcs","calibrated_normalised_BL1-H",40958.4532405383,1.80579944296022
22 | "21","pMed_None_0_5.fcs","BL1-H",15218.8311348887,3.2821869492828
23 | "22","pMed_None_0_5.fcs","normalised_BL1-H",18258.5901578027,1.73399025156251
24 | "23","pMed_None_0_5.fcs","calibrated_BL1-H",46295.3474101075,3.3799182917839
25 | "24","pMed_None_0_5.fcs","calibrated_normalised_BL1-H",55792.4894437666,1.75771380866814
26 | "25","pMed_None_0_6.fcs","BL1-H",10666.7346454101,3.99955747104834
27 | "26","pMed_None_0_6.fcs","normalised_BL1-H",13918.1751456708,1.92363380923118
28 | "27","pMed_None_0_6.fcs","calibrated_BL1-H",32164.5143385943,4.1387980369343
29 | "28","pMed_None_0_6.fcs","calibrated_normalised_BL1-H",42245.503281852,1.95495484799477
30 | "29","pMed_None_0_7.fcs","BL1-H",16428.9312607474,2.28010775306535
31 | "30","pMed_None_0_7.fcs","normalised_BL1-H",17539.5653717219,1.67265273778469
32 | "31","pMed_None_0_7.fcs","calibrated_BL1-H",50070.9331424297,2.32697901959676
33 | "32","pMed_None_0_7.fcs","calibrated_normalised_BL1-H",53542.2436147167,1.69403025189602
34 | "33","pMed_None_0_8.fcs","BL1-H",12138.5174725072,2.90883258339255
35 | "34","pMed_None_0_8.fcs","normalised_BL1-H",13768.1973610868,1.89005342936667
36 | "35","pMed_None_0_8.fcs","calibrated_BL1-H",36719.5185366871,2.98652996859113
37 | "36","pMed_None_0_8.fcs","calibrated_normalised_BL1-H",41779.1031380375,1.91999276253171
38 | "37","pMed_None_0_9.fcs","BL1-H",11660.9843416416,4.39079813506934
39 | "38","pMed_None_0_9.fcs","normalised_BL1-H",15800.9312060012,1.98836217924825
40 | "39","pMed_None_0_9.fcs","calibrated_BL1-H",35240.0263994794,4.55414017787882
41 | "40","pMed_None_0_9.fcs","calibrated_normalised_BL1-H",48110.6445470602,2.02238885015184
42 |
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_1.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_1.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_10.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_10.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_10_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_10_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_1_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_1_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_2.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_2.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_2_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_2_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_3.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_3.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_3_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_3_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_4.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_4.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_4_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_4_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_5.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_5.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_5_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_5_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_6.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_6.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_6_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_6_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_7.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_7.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_7_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_7_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_8.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_8.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_8_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_8_processed.pdf
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_9.fcs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_9.fcs
--------------------------------------------------------------------------------
/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_9_processed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/flow_cytometry/DATA/20191121_processed/pMed_None_0_9_processed.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_lid.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_cytation/231031_pr_calibration_lid.xlsx
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_lid_parsed.csv:
--------------------------------------------------------------------------------
1 | "calibrant","fluorophore","media","volume_uL","concentration","concentration_M","replicate","well","OD600","OD700","GFP 30","GFP 40","GFP 50","GFP 60","GFP 70","GFP 80","GFP 90","GFP 100","GFP 110","GFP 120","GFP 130","GFP 140","GFP 150","GFP 30 TOP","GFP 40 TOP","GFP 50 TOP","GFP 60 TOP","GFP 70 TOP","GFP 80 TOP","GFP 90 TOP","GFP 100 TOP","GFP 110 TOP","GFP 120 TOP","GFP 130 TOP","GFP 140 TOP","GFP 150 TOP","row","column"
2 | "FITC","GFP","ddH20",125,7.5e+17,0.00997,1,"A1",NA,NA,845,8126,44144,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,989,9452,51005,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"A",1
3 | "FITC","GFP","ddH20",125,3.75e+17,0.00498,1,"A2",NA,NA,505,4873,26791,97416,NA,NA,NA,NA,NA,NA,NA,NA,NA,587,5613,30815,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"A",2
4 | "FITC","GFP","ddH20",125,1.88e+17,0.00249,1,"A3",NA,NA,281,2734,15135,56530,NA,NA,NA,NA,NA,NA,NA,NA,NA,325,3170,17523,65176,NA,NA,NA,NA,NA,NA,NA,NA,NA,"A",3
5 | "FITC","GFP","ddH20",125,9.38e+16,0.00125,1,"A4",NA,NA,151,1473,8208,31150,90859,NA,NA,NA,NA,NA,NA,NA,NA,178,1715,9550,36030,NA,NA,NA,NA,NA,NA,NA,NA,NA,"A",4
6 | "FITC","GFP","ddH20",125,4.69e+16,0.000623,1,"A5",NA,NA,79,754,4215,16074,47547,NA,NA,NA,NA,NA,NA,NA,NA,90,875,4866,18551,54952,NA,NA,NA,NA,NA,NA,NA,NA,"A",5
7 | "FITC","GFP","ddH20",125,2.34e+16,0.000311,1,"A6",NA,NA,42,386,2166,8294,24696,62644,NA,NA,NA,NA,NA,NA,NA,47,450,2516,9554,28481,72428,NA,NA,NA,NA,NA,NA,NA,"A",6
8 | "FITC","GFP","ddH20",125,1.17e+16,0.000156,1,"A7",NA,NA,23,193,1094,4165,12479,31892,72830,NA,NA,NA,NA,NA,NA,25,228,1276,4872,14564,37141,85171,NA,NA,NA,NA,NA,NA,"A",7
9 | "FITC","GFP","ddH20",125,5.86e+15,7.79e-05,1,"A8",NA,NA,9,100,547,2078,6218,15954,36522,78495,NA,NA,NA,NA,NA,11,114,633,2410,7246,18449,42574,91706,NA,NA,NA,NA,NA,"A",8
10 | "FITC","GFP","ddH20",125,2.93e+15,3.89e-05,1,"A9",NA,NA,5,50,280,1070,3195,8225,18818,40613,82648,NA,NA,NA,NA,5,60,331,1261,3775,9681,22378,48380,NA,NA,NA,NA,NA,"A",9
11 | "FITC","GFP","ddH20",125,1.47e+15,1.95e-05,1,"A10",NA,NA,1,24,144,543,1631,4155,9568,20705,42595,81977,NA,NA,NA,3,29,167,649,1936,4951,11490,24912,50847,NA,NA,NA,NA,"A",10
12 | "FITC","GFP","ddH20",125,7.33e+14,9.73e-06,1,"A11",NA,NA,0,16,74,296,881,2262,5204,11198,22864,44816,83711,NA,NA,0,15,91,351,1037,2685,6152,13368,27210,53606,NA,NA,NA,"A",11
13 | "FITC","GFP","ddH20",125,0,0,1,"A12",NA,NA,0,0,3,14,36,91,204,465,922,1793,3373,5814,10778,0,0,3,15,34,91,221,458,956,1761,3509,6035,10594,"A",12
14 | "FITC","GFP","ddH20",125,7.5e+17,0.00997,2,"B1",NA,NA,859,8254,44347,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,1032,9824,52473,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"B",1
15 | "FITC","GFP","ddH20",125,3.75e+17,0.00498,2,"B2",NA,NA,500,4799,26294,95675,NA,NA,NA,NA,NA,NA,NA,NA,NA,582,5549,30277,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"B",2
16 | "FITC","GFP","ddH20",125,1.88e+17,0.00249,2,"B3",NA,NA,278,2670,14760,55078,NA,NA,NA,NA,NA,NA,NA,NA,NA,342,3262,17990,66722,NA,NA,NA,NA,NA,NA,NA,NA,NA,"B",3
17 | "FITC","GFP","ddH20",125,9.38e+16,0.00125,2,"B4",NA,NA,151,1456,8082,30645,89602,NA,NA,NA,NA,NA,NA,NA,NA,176,1724,9570,36188,NA,NA,NA,NA,NA,NA,NA,NA,NA,"B",4
18 | "FITC","GFP","ddH20",125,4.69e+16,0.000623,2,"B5",NA,NA,76,750,4173,15954,47321,NA,NA,NA,NA,NA,NA,NA,NA,93,890,4964,18862,55496,NA,NA,NA,NA,NA,NA,NA,NA,"B",5
19 | "FITC","GFP","ddH20",125,2.34e+16,0.000311,2,"B6",NA,NA,38,384,2138,8172,24347,61822,NA,NA,NA,NA,NA,NA,NA,47,452,2524,9628,28820,73063,NA,NA,NA,NA,NA,NA,NA,"B",6
20 | "FITC","GFP","ddH20",125,1.17e+16,0.000156,2,"B7",NA,NA,18,195,1091,4145,12387,31811,72572,NA,NA,NA,NA,NA,NA,27,229,1284,4869,14622,37274,85415,NA,NA,NA,NA,NA,NA,"B",7
21 | "FITC","GFP","ddH20",125,5.86e+15,7.79e-05,2,"B8",NA,NA,10,98,555,2119,6352,16318,37329,80508,NA,NA,NA,NA,NA,12,123,666,2532,7625,19483,44845,NA,NA,NA,NA,NA,NA,"B",8
22 | "FITC","GFP","ddH20",125,2.93e+15,3.89e-05,2,"B9",NA,NA,7,50,284,1077,3217,8278,19006,40904,83268,NA,NA,NA,NA,5,61,339,1287,3855,9901,22891,49412,NA,NA,NA,NA,NA,"B",9
23 | "FITC","GFP","ddH20",125,1.47e+15,1.95e-05,2,"B10",NA,NA,0,26,144,550,1648,4234,9616,21007,43179,84327,NA,NA,NA,6,31,174,670,1997,5116,11840,25645,52251,NA,NA,NA,NA,"B",10
24 | "FITC","GFP","ddH20",125,7.33e+14,9.73e-06,2,"B11",NA,NA,4,15,79,300,901,2347,5335,11503,23498,46042,86074,NA,NA,3,17,93,360,1070,2752,6404,13716,28248,55672,NA,NA,NA,"B",11
25 | "FITC","GFP","ddH20",125,0,0,2,"B12",NA,NA,1,0,1,11,39,89,207,437,874,1759,3251,5753,10370,0,3,4,12,34,89,216,436,890,1847,3275,5698,10281,"B",12
26 | "FITC","GFP","ddH20",125,7.5e+17,0.00997,3,"C1",NA,NA,853,8228,44293,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,1024,9720,51852,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"C",1
27 | "FITC","GFP","ddH20",125,3.75e+17,0.00498,3,"C2",NA,NA,503,4857,26522,96524,NA,NA,NA,NA,NA,NA,NA,NA,NA,592,5685,31068,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"C",2
28 | "FITC","GFP","ddH20",125,1.88e+17,0.00249,3,"C3",NA,NA,278,2688,14770,55104,NA,NA,NA,NA,NA,NA,NA,NA,NA,325,3150,17250,64285,NA,NA,NA,NA,NA,NA,NA,NA,NA,"C",3
29 | "FITC","GFP","ddH20",125,9.38e+16,0.00125,3,"C4",NA,NA,145,1423,7859,29872,87104,NA,NA,NA,NA,NA,NA,NA,NA,176,1695,9336,35481,NA,NA,NA,NA,NA,NA,NA,NA,NA,"C",4
30 | "FITC","GFP","ddH20",125,4.69e+16,0.000623,3,"C5",NA,NA,78,736,4102,15558,46146,NA,NA,NA,NA,NA,NA,NA,NA,91,869,4828,18329,54184,NA,NA,NA,NA,NA,NA,NA,NA,"C",5
31 | "FITC","GFP","ddH20",125,2.34e+16,0.000311,3,"C6",NA,NA,39,377,2079,7922,23646,60323,NA,NA,NA,NA,NA,NA,NA,48,442,2455,9318,27867,71272,NA,NA,NA,NA,NA,NA,NA,"C",6
32 | "FITC","GFP","ddH20",125,1.17e+16,0.000156,3,"C7",NA,NA,19,191,1063,4082,12141,31032,71140,NA,NA,NA,NA,NA,NA,24,230,1265,4832,14346,36791,84311,NA,NA,NA,NA,NA,NA,"C",7
33 | "FITC","GFP","ddH20",125,5.86e+15,7.79e-05,3,"C8",NA,NA,10,95,532,2020,6038,15414,35501,76114,NA,NA,NA,NA,NA,10,111,622,2389,7114,18274,41755,90684,NA,NA,NA,NA,NA,"C",8
34 | "FITC","GFP","ddH20",125,2.93e+15,3.89e-05,3,"C9",NA,NA,8,50,272,1029,3094,7860,18220,39579,80097,NA,NA,NA,NA,6,58,321,1227,3702,9458,21733,46817,95663,NA,NA,NA,NA,"C",9
35 | "FITC","GFP","ddH20",125,1.47e+15,1.95e-05,3,"C10",NA,NA,3,26,139,530,1602,4087,9366,20289,41328,80389,NA,NA,NA,5,33,167,631,1904,4858,11116,24328,49494,NA,NA,NA,NA,"C",10
36 | "FITC","GFP","ddH20",125,7.33e+14,9.73e-06,3,"C11",NA,NA,2,13,74,276,835,2122,4938,10689,21711,42498,79231,NA,NA,5,15,89,333,984,2550,5871,12706,25674,50206,NA,NA,NA,"C",11
37 | "FITC","GFP","ddH20",125,0,0,3,"C12",NA,NA,0,2,5,10,34,89,197,434,940,1736,3187,5659,9772,0,1,3,13,34,78,192,430,850,1763,3146,5739,9343,"C",12
38 | "FITC","GFP","ddH20",125,7.5e+17,0.00997,4,"D1",NA,NA,900,8616,46251,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,1107,10540,55639,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"D",1
39 | "FITC","GFP","ddH20",125,3.75e+17,0.00498,4,"D2",NA,NA,540,5198,28238,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,649,6168,33327,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"D",2
40 | "FITC","GFP","ddH20",125,1.88e+17,0.00249,4,"D3",NA,NA,306,2932,16154,60444,NA,NA,NA,NA,NA,NA,NA,NA,NA,364,3487,19076,71156,NA,NA,NA,NA,NA,NA,NA,NA,NA,"D",3
41 | "FITC","GFP","ddH20",125,9.38e+16,0.00125,4,"D4",NA,NA,165,1594,8781,33285,96845,NA,NA,NA,NA,NA,NA,NA,NA,196,1895,10472,39451,NA,NA,NA,NA,NA,NA,NA,NA,NA,"D",4
42 | "FITC","GFP","ddH20",125,4.69e+16,0.000623,4,"D5",NA,NA,87,809,4467,17044,50369,NA,NA,NA,NA,NA,NA,NA,NA,101,965,5330,20279,59993,NA,NA,NA,NA,NA,NA,NA,NA,"D",5
43 | "FITC","GFP","ddH20",125,2.34e+16,0.000311,4,"D6",NA,NA,43,416,2305,8746,26093,66402,NA,NA,NA,NA,NA,NA,NA,51,492,2751,10435,31064,78753,NA,NA,NA,NA,NA,NA,NA,"D",6
44 | "FITC","GFP","ddH20",125,1.17e+16,0.000156,4,"D7",NA,NA,23,205,1157,4410,13139,33836,77513,NA,NA,NA,NA,NA,NA,27,247,1378,5293,15739,40295,91768,NA,NA,NA,NA,NA,NA,"D",7
45 | "FITC","GFP","ddH20",125,5.86e+15,7.79e-05,4,"D8",NA,NA,10,105,585,2227,6674,17038,39092,84282,NA,NA,NA,NA,NA,12,129,694,2657,7889,20312,46830,NA,NA,NA,NA,NA,NA,"D",8
46 | "FITC","GFP","ddH20",125,2.93e+15,3.89e-05,4,"D9",NA,NA,9,53,291,1111,3342,8605,19819,42658,86306,NA,NA,NA,NA,6,61,349,1337,4024,10342,23640,51478,NA,NA,NA,NA,NA,"D",9
47 | "FITC","GFP","ddH20",125,1.47e+15,1.95e-05,4,"D10",NA,NA,2,27,152,580,1731,4462,10223,22188,45503,87988,NA,NA,NA,2,35,177,692,2064,5330,12319,26647,53898,NA,NA,NA,NA,"D",10
48 | "FITC","GFP","ddH20",125,7.33e+14,9.73e-06,4,"D11",NA,NA,2,15,82,301,929,2371,5363,11776,23971,46800,87237,NA,NA,1,17,94,366,1078,2782,6521,13997,28983,55496,NA,NA,NA,"D",11
49 | "FITC","GFP","ddH20",125,0,0,4,"D12",NA,NA,2,0,2,10,37,84,205,454,897,1726,3064,5683,10033,0,0,3,10,34,91,200,441,906,1903,3414,5779,10426,"D",12
50 | "microspheres","","ddH20",125,891346154,1.18e-11,1,"E1",1.47,1.238,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",1
51 | "microspheres","","ddH20",125,534807692,7.1e-12,1,"E2",1.054,0.846,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",2
52 | "microspheres","","ddH20",125,320884615,4.26e-12,1,"E3",0.718,0.567,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",3
53 | "microspheres","","ddH20",125,192530769,2.56e-12,1,"E4",0.495,0.393,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",4
54 | "microspheres","","ddH20",125,115518461,1.53e-12,1,"E5",0.359,0.289,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",5
55 | "microspheres","","ddH20",125,69311077,9.21e-13,1,"E6",0.253,0.21,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",6
56 | "microspheres","","ddH20",125,41586646,5.52e-13,1,"E7",0.186,0.158,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",7
57 | "microspheres","","ddH20",125,24951988,3.31e-13,1,"E8",0.153,0.131,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",8
58 | "microspheres","","ddH20",125,14971193,1.99e-13,1,"E9",0.128,0.113,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",9
59 | "microspheres","","ddH20",125,8982716,1.19e-13,1,"E10",0.113,0.1,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",10
60 | "microspheres","","ddH20",125,5389630,7.16e-14,1,"E11",0.102,0.087,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",11
61 | "microspheres","","ddH20",125,0,0,1,"E12",0.081,0.078,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",12
62 | "microspheres","","ddH20",125,891346154,1.18e-11,2,"F1",1.497,1.274,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",1
63 | "microspheres","","ddH20",125,534807692,7.1e-12,2,"F2",1.062,0.855,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",2
64 | "microspheres","","ddH20",125,320884615,4.26e-12,2,"F3",0.725,0.572,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",3
65 | "microspheres","","ddH20",125,192530769,2.56e-12,2,"F4",0.497,0.395,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",4
66 | "microspheres","","ddH20",125,115518461,1.53e-12,2,"F5",0.357,0.29,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",5
67 | "microspheres","","ddH20",125,69311077,9.21e-13,2,"F6",0.254,0.209,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",6
68 | "microspheres","","ddH20",125,41586646,5.52e-13,2,"F7",0.189,0.161,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",7
69 | "microspheres","","ddH20",125,24951988,3.31e-13,2,"F8",0.154,0.132,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",8
70 | "microspheres","","ddH20",125,14971193,1.99e-13,2,"F9",0.134,0.118,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",9
71 | "microspheres","","ddH20",125,8982716,1.19e-13,2,"F10",0.113,0.101,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",10
72 | "microspheres","","ddH20",125,5389630,7.16e-14,2,"F11",0.106,0.089,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",11
73 | "microspheres","","ddH20",125,0,0,2,"F12",0.086,0.083,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",12
74 | "microspheres","","ddH20",125,891346154,1.18e-11,3,"G1",1.435,1.198,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",1
75 | "microspheres","","ddH20",125,534807692,7.1e-12,3,"G2",1.04,0.83,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",2
76 | "microspheres","","ddH20",125,320884615,4.26e-12,3,"G3",0.716,0.565,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",3
77 | "microspheres","","ddH20",125,192530769,2.56e-12,3,"G4",0.499,0.401,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",4
78 | "microspheres","","ddH20",125,115518461,1.53e-12,3,"G5",0.348,0.277,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",5
79 | "microspheres","","ddH20",125,69311077,9.21e-13,3,"G6",0.262,0.213,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",6
80 | "microspheres","","ddH20",125,41586646,5.52e-13,3,"G7",0.19,0.16,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",7
81 | "microspheres","","ddH20",125,24951988,3.31e-13,3,"G8",0.154,0.129,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",8
82 | "microspheres","","ddH20",125,14971193,1.99e-13,3,"G9",0.127,0.109,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",9
83 | "microspheres","","ddH20",125,8982716,1.19e-13,3,"G10",0.109,0.094,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",10
84 | "microspheres","","ddH20",125,5389630,7.16e-14,3,"G11",0.117,0.14,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",11
85 | "microspheres","","ddH20",125,0,0,3,"G12",0.08,0.077,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",12
86 | "microspheres","","ddH20",125,891346154,1.18e-11,4,"H1",1.458,1.229,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",1
87 | "microspheres","","ddH20",125,534807692,7.1e-12,4,"H2",1.056,0.846,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",2
88 | "microspheres","","ddH20",125,320884615,4.26e-12,4,"H3",0.706,0.556,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",3
89 | "microspheres","","ddH20",125,192530769,2.56e-12,4,"H4",0.485,0.387,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",4
90 | "microspheres","","ddH20",125,115518461,1.53e-12,4,"H5",0.345,0.281,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",5
91 | "microspheres","","ddH20",125,69311077,9.21e-13,4,"H6",0.24,0.201,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",6
92 | "microspheres","","ddH20",125,41586646,5.52e-13,4,"H7",0.17,0.148,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",7
93 | "microspheres","","ddH20",125,24951988,3.31e-13,4,"H8",0.136,0.12,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",8
94 | "microspheres","","ddH20",125,14971193,1.99e-13,4,"H9",0.115,0.105,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",9
95 | "microspheres","","ddH20",125,8982716,1.19e-13,4,"H10",0.102,0.094,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",10
96 | "microspheres","","ddH20",125,5389630,7.16e-14,4,"H11",0.098,0.092,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",11
97 | "microspheres","","ddH20",125,0,0,4,"H12",0.093,0.089,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",12
98 |
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_lid_parsed_absorbance_cfs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_cytation/231031_pr_calibration_lid_parsed_absorbance_cfs.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_lid_parsed_cfs.csv:
--------------------------------------------------------------------------------
1 | "cf","beta","calibrant","fluorophore","measure"
2 | 1.73411407582599e-15,2.46476510092312e-10,"FITC","GFP","GFP 30"
3 | 1.58206584654132e-14,2.28051952205029e-10,"FITC","GFP","GFP 40"
4 | 8.72349620423461e-14,2.09924902425371e-10,"FITC","GFP","GFP 50"
5 | 3.4171812813719e-13,2.04751511913593e-10,"FITC","GFP","GFP 60"
6 | 1.07314591295955e-12,1.87544535531197e-10,"FITC","GFP","GFP 70"
7 | 2.80481604754579e-12,1.90037751716375e-10,"FITC","GFP","GFP 80"
8 | 6.48422213271198e-12,1.74671525158919e-10,"FITC","GFP","GFP 90"
9 | 1.41135422745713e-11,2.29248723370256e-10,"FITC","GFP","GFP 100"
10 | 2.91248205816367e-11,1.95386169356061e-10,"FITC","GFP","GFP 110"
11 | 2.05528760803502e-15,2.43219430207211e-10,"FITC","GFP","GFP 30 TOP"
12 | 1.85869508571003e-14,2.26649190451653e-10,"FITC","GFP","GFP 40 TOP"
13 | 1.02974795089581e-13,2.23479764191819e-10,"FITC","GFP","GFP 50 TOP"
14 | 4.17851686710777e-13,2.0422505265513e-10,"FITC","GFP","GFP 60 TOP"
15 | 1.28605365753111e-12,1.89214569330215e-10,"FITC","GFP","GFP 70 TOP"
16 | 3.33242845217621e-12,2.24208990515285e-10,"FITC","GFP","GFP 80 TOP"
17 | 7.75059228617403e-12,1.98039381867784e-10,"FITC","GFP","GFP 90 TOP"
18 | 1.67632544878864e-11,1.93897487700451e-10,"FITC","GFP","GFP 100 TOP"
19 | 3.45350759103888e-11,1.70041463384405e-10,"FITC","GFP","GFP 110 TOP"
20 | 3.38335914611817e-09,4.27744674682617e-10,"microspheres","","OD600"
21 | 3.08515658620745e-09,5.50387836806476e-10,"microspheres","","OD700"
22 |
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_lid_parsed_fluorescence_cfs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_cytation/231031_pr_calibration_lid_parsed_fluorescence_cfs.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_membrane.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_cytation/231031_pr_calibration_membrane.xlsx
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_membrane_parsed.csv:
--------------------------------------------------------------------------------
1 | "calibrant","fluorophore","media","volume_uL","concentration","concentration_M","replicate","well","OD600","OD700","GFP 30","GFP 40","GFP 50","GFP 60","GFP 70","GFP 80","GFP 90","GFP 100","GFP 110","GFP 120","GFP 130","GFP 140","GFP 150","GFP 30 TOP","GFP 40 TOP","GFP 50 TOP","GFP 60 TOP","GFP 70 TOP","GFP 80 TOP","GFP 90 TOP","GFP 100 TOP","GFP 110 TOP","GFP 120 TOP","GFP 130 TOP","GFP 140 TOP","GFP 150 TOP","row","column"
2 | "FITC","GFP","ddH20",125,7.5e+17,0.00997,1,"A1",NA,NA,791,7649,41529,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,375,3659,20287,75143,NA,NA,NA,NA,NA,NA,NA,NA,NA,"A",1
3 | "FITC","GFP","ddH20",125,3.75e+17,0.00498,1,"A2",NA,NA,480,4635,25309,92305,NA,NA,NA,NA,NA,NA,NA,NA,NA,229,2198,12273,46427,NA,NA,NA,NA,NA,NA,NA,NA,NA,"A",2
4 | "FITC","GFP","ddH20",125,1.88e+17,0.00249,1,"A3",NA,NA,273,2662,14652,54956,NA,NA,NA,NA,NA,NA,NA,NA,NA,127,1229,6840,26058,76632,NA,NA,NA,NA,NA,NA,NA,NA,"A",3
5 | "FITC","GFP","ddH20",125,9.38e+16,0.00125,1,"A4",NA,NA,150,1466,8094,30754,90276,NA,NA,NA,NA,NA,NA,NA,NA,74,685,3850,14733,43709,NA,NA,NA,NA,NA,NA,NA,NA,"A",4
6 | "FITC","GFP","ddH20",125,4.69e+16,0.000623,1,"A5",NA,NA,80,760,4216,16127,47910,NA,NA,NA,NA,NA,NA,NA,NA,40,374,2058,7908,23580,59895,NA,NA,NA,NA,NA,NA,NA,"A",5
7 | "FITC","GFP","ddH20",125,2.34e+16,0.000311,1,"A6",NA,NA,40,388,2166,8314,24806,62827,NA,NA,NA,NA,NA,NA,NA,17,179,1008,3867,11572,29755,68013,NA,NA,NA,NA,NA,NA,"A",6
8 | "FITC","GFP","ddH20",125,1.17e+16,0.000156,1,"A7",NA,NA,21,202,1116,4272,12850,32745,75024,NA,NA,NA,NA,NA,NA,11,94,526,2005,5966,15243,35092,75787,NA,NA,NA,NA,NA,"A",7
9 | "FITC","GFP","ddH20",125,5.86e+15,7.79e-05,1,"A8",NA,NA,12,96,551,2109,6324,16253,37323,80018,NA,NA,NA,NA,NA,6,49,264,1012,3007,7696,17711,38499,78752,NA,NA,NA,NA,"A",8
10 | "FITC","GFP","ddH20",125,2.93e+15,3.89e-05,1,"A9",NA,NA,3,52,281,1075,3211,8192,19011,40782,83143,NA,NA,NA,NA,2,25,138,527,1581,4008,9278,20086,41130,79934,NA,NA,NA,"A",9
11 | "FITC","GFP","ddH20",125,1.47e+15,1.95e-05,1,"A10",NA,NA,5,25,145,548,1633,4210,9594,20937,42735,83170,NA,NA,NA,0,12,73,280,842,2156,4982,10643,22060,42533,80674,NA,NA,"A",10
12 | "FITC","GFP","ddH20",125,7.33e+14,9.73e-06,1,"A11",NA,NA,4,14,78,297,881,2249,5243,11279,22849,44954,84041,NA,NA,2,5,44,153,452,1193,2732,5807,11734,23058,43489,77073,NA,"A",11
13 | "FITC","GFP","ddH20",125,0,0,1,"A12",NA,NA,0,4,2,10,39,106,224,486,1014,1931,3693,6495,11769,0,0,3,6,27,68,160,343,677,1323,2576,4510,7419,"A",12
14 | "FITC","GFP","ddH20",125,7.5e+17,0.00997,2,"B1",NA,NA,808,7716,41416,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,382,3677,20230,75028,NA,NA,NA,NA,NA,NA,NA,NA,NA,"B",1
15 | "FITC","GFP","ddH20",125,3.75e+17,0.00498,2,"B2",NA,NA,458,4404,24176,88778,NA,NA,NA,NA,NA,NA,NA,NA,NA,206,1979,11027,41661,NA,NA,NA,NA,NA,NA,NA,NA,NA,"B",2
16 | "FITC","GFP","ddH20",125,1.88e+17,0.00249,2,"B3",NA,NA,262,2515,14007,52413,NA,NA,NA,NA,NA,NA,NA,NA,NA,121,1164,6433,24542,72213,NA,NA,NA,NA,NA,NA,NA,NA,"B",3
17 | "FITC","GFP","ddH20",125,9.38e+16,0.00125,2,"B4",NA,NA,149,1434,7941,30094,88672,NA,NA,NA,NA,NA,NA,NA,NA,70,669,3758,14380,42468,NA,NA,NA,NA,NA,NA,NA,NA,"B",4
18 | "FITC","GFP","ddH20",125,4.69e+16,0.000623,2,"B5",NA,NA,78,753,4209,15925,47403,NA,NA,NA,NA,NA,NA,NA,NA,39,371,2068,7872,23501,59846,NA,NA,NA,NA,NA,NA,NA,"B",5
19 | "FITC","GFP","ddH20",125,2.34e+16,0.000311,2,"B6",NA,NA,39,390,2171,8304,24740,63016,NA,NA,NA,NA,NA,NA,NA,21,182,1008,3865,11533,29509,67746,NA,NA,NA,NA,NA,NA,"B",6
20 | "FITC","GFP","ddH20",125,1.17e+16,0.000156,2,"B7",NA,NA,20,200,1121,4282,12790,32779,75004,NA,NA,NA,NA,NA,NA,10,92,507,1940,5809,14967,34242,73675,NA,NA,NA,NA,NA,"B",7
21 | "FITC","GFP","ddH20",125,5.86e+15,7.79e-05,2,"B8",NA,NA,10,103,573,2176,6517,16628,38194,82236,NA,NA,NA,NA,NA,6,53,268,1032,3096,7944,18390,39413,80718,NA,NA,NA,NA,"B",8
22 | "FITC","GFP","ddH20",125,2.93e+15,3.89e-05,2,"B9",NA,NA,3,50,280,1077,3202,8303,18978,40950,83629,NA,NA,NA,NA,2,23,142,545,1623,4168,9616,20802,42515,82838,NA,NA,NA,"B",9
23 | "FITC","GFP","ddH20",125,1.47e+15,1.95e-05,2,"B10",NA,NA,2,27,145,551,1669,4247,9870,21111,43306,84285,NA,NA,NA,2,17,72,275,819,2107,4874,10517,21690,41882,78744,NA,NA,"B",10
24 | "FITC","GFP","ddH20",125,7.33e+14,9.73e-06,2,"B11",NA,NA,2,15,77,295,884,2266,5223,11274,23218,45335,85040,NA,NA,1,7,42,157,469,1181,2770,5912,12243,23991,44474,79251,NA,"B",11
25 | "FITC","GFP","ddH20",125,0,0,2,"B12",NA,NA,0,0,3,14,37,94,215,487,961,1947,3669,6457,11088,0,1,4,9,23,70,155,343,651,1309,2483,4540,7822,"B",12
26 | "FITC","GFP","ddH20",125,7.5e+17,0.00997,3,"C1",NA,NA,793,7577,40883,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,382,3670,20306,75463,NA,NA,NA,NA,NA,NA,NA,NA,NA,"C",1
27 | "FITC","GFP","ddH20",125,3.75e+17,0.00498,3,"C2",NA,NA,464,4437,24354,89579,NA,NA,NA,NA,NA,NA,NA,NA,NA,224,2143,11929,44860,NA,NA,NA,NA,NA,NA,NA,NA,NA,"C",2
28 | "FITC","GFP","ddH20",125,1.88e+17,0.00249,3,"C3",NA,NA,261,2524,13944,51970,NA,NA,NA,NA,NA,NA,NA,NA,NA,122,1182,6594,24900,73079,NA,NA,NA,NA,NA,NA,NA,NA,"C",3
29 | "FITC","GFP","ddH20",125,9.38e+16,0.00125,3,"C4",NA,NA,144,1372,7613,28815,84592,NA,NA,NA,NA,NA,NA,NA,NA,66,636,3579,13616,40180,NA,NA,NA,NA,NA,NA,NA,NA,"C",4
30 | "FITC","GFP","ddH20",125,4.69e+16,0.000623,3,"C5",NA,NA,77,737,4103,15619,46358,NA,NA,NA,NA,NA,NA,NA,NA,37,352,1967,7486,22284,56880,NA,NA,NA,NA,NA,NA,NA,"C",5
31 | "FITC","GFP","ddH20",125,2.34e+16,0.000311,3,"C6",NA,NA,39,381,2105,8055,24002,61479,NA,NA,NA,NA,NA,NA,NA,16,171,971,3701,11033,28277,65110,NA,NA,NA,NA,NA,NA,"C",6
32 | "FITC","GFP","ddH20",125,1.17e+16,0.000156,3,"C7",NA,NA,20,197,1090,4155,12391,31927,72940,NA,NA,NA,NA,NA,NA,10,91,509,1950,5787,14901,34185,73669,NA,NA,NA,NA,NA,"C",7
33 | "FITC","GFP","ddH20",125,5.86e+15,7.79e-05,3,"C8",NA,NA,10,99,540,2056,6173,15748,36108,77909,NA,NA,NA,NA,NA,2,48,259,1008,2981,7668,17670,38017,77752,NA,NA,NA,NA,"C",8
34 | "FITC","GFP","ddH20",125,2.93e+15,3.89e-05,3,"C9",NA,NA,4,50,273,1047,3111,7992,18516,39797,80937,NA,NA,NA,NA,2,27,137,523,1568,4020,9261,20072,40703,80253,NA,NA,NA,"C",9
35 | "FITC","GFP","ddH20",125,1.47e+15,1.95e-05,3,"C10",NA,NA,2,23,138,530,1584,4048,9382,20310,41438,80601,NA,NA,NA,0,13,66,259,766,1999,4532,9805,20061,38990,73807,NA,NA,"C",10
36 | "FITC","GFP","ddH20",125,7.33e+14,9.73e-06,3,"C11",NA,NA,1,13,75,282,832,2151,5006,10691,21914,42676,80009,NA,NA,0,7,39,143,432,1109,2575,5510,11377,22128,41352,72439,NA,"C",11
37 | "FITC","GFP","ddH20",125,0,0,3,"C12",NA,NA,0,0,5,11,38,104,230,487,1005,1889,3535,6477,11296,0,2,0,10,25,72,159,316,694,1329,2635,4472,7449,"C",12
38 | "FITC","GFP","ddH20",125,7.5e+17,0.00997,4,"D1",NA,NA,832,7887,42286,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,429,4051,22455,82613,NA,NA,NA,NA,NA,NA,NA,NA,NA,"D",1
39 | "FITC","GFP","ddH20",125,3.75e+17,0.00498,4,"D2",NA,NA,481,4586,25054,92019,NA,NA,NA,NA,NA,NA,NA,NA,NA,229,2218,12244,46248,NA,NA,NA,NA,NA,NA,NA,NA,NA,"D",2
40 | "FITC","GFP","ddH20",125,1.88e+17,0.00249,4,"D3",NA,NA,281,2698,14878,55801,NA,NA,NA,NA,NA,NA,NA,NA,NA,134,1286,7153,27168,80093,NA,NA,NA,NA,NA,NA,NA,NA,"D",3
41 | "FITC","GFP","ddH20",125,9.38e+16,0.00125,4,"D4",NA,NA,158,1507,8309,31510,92237,NA,NA,NA,NA,NA,NA,NA,NA,76,716,4020,15332,45530,NA,NA,NA,NA,NA,NA,NA,NA,"D",4
42 | "FITC","GFP","ddH20",125,4.69e+16,0.000623,4,"D5",NA,NA,83,790,4318,16475,48706,NA,NA,NA,NA,NA,NA,NA,NA,41,374,2088,7935,23707,60428,NA,NA,NA,NA,NA,NA,NA,"D",5
43 | "FITC","GFP","ddH20",125,2.34e+16,0.000311,4,"D6",NA,NA,43,415,2287,8752,26172,66265,NA,NA,NA,NA,NA,NA,NA,18,190,1065,4051,12076,31022,70957,NA,NA,NA,NA,NA,NA,"D",6
44 | "FITC","GFP","ddH20",125,1.17e+16,0.000156,4,"D7",NA,NA,24,211,1166,4460,13314,34066,77991,NA,NA,NA,NA,NA,NA,10,98,555,2113,6333,16217,37375,79851,NA,NA,NA,NA,NA,"D",7
45 | "FITC","GFP","ddH20",125,5.86e+15,7.79e-05,4,"D8",NA,NA,12,107,585,2241,6719,17181,39548,84764,NA,NA,NA,NA,NA,9,52,285,1089,3271,8415,19197,41479,84934,NA,NA,NA,NA,"D",8
46 | "FITC","GFP","ddH20",125,2.93e+15,3.89e-05,4,"D9",NA,NA,5,51,290,1098,3271,8435,19444,41987,85603,NA,NA,NA,NA,2,28,147,561,1674,4289,9857,21524,43692,84923,NA,NA,NA,"D",9
47 | "FITC","GFP","ddH20",125,1.47e+15,1.95e-05,4,"D10",NA,NA,3,26,148,574,1716,4425,10160,21877,44788,86917,NA,NA,NA,2,14,72,286,858,2223,5138,11121,22791,44249,82461,NA,NA,"D",10
48 | "FITC","GFP","ddH20",125,7.33e+14,9.73e-06,4,"D11",NA,NA,2,17,79,302,918,2352,5415,11632,23899,46717,86934,NA,NA,1,8,42,158,469,1215,2798,6114,12435,24034,45118,80748,NA,"D",11
49 | "FITC","GFP","ddH20",125,0,0,4,"D12",NA,NA,0,0,5,11,38,101,229,482,1029,1963,3691,6503,10751,0,0,4,8,30,66,151,349,665,1398,2321,4457,7820,"D",12
50 | "microspheres","","ddH20",125,891346154,1.18e-11,1,"E1",1.388,1.221,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",1
51 | "microspheres","","ddH20",125,534807692,7.1e-12,1,"E2",1.024,0.864,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",2
52 | "microspheres","","ddH20",125,320884615,4.26e-12,1,"E3",0.716,0.595,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",3
53 | "microspheres","","ddH20",125,192530769,2.56e-12,1,"E4",0.551,0.435,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",4
54 | "microspheres","","ddH20",125,115518461,1.53e-12,1,"E5",0.393,0.335,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",5
55 | "microspheres","","ddH20",125,69311077,9.21e-13,1,"E6",0.294,0.257,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",6
56 | "microspheres","","ddH20",125,41586646,5.52e-13,1,"E7",0.244,0.22,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",7
57 | "microspheres","","ddH20",125,24951988,3.31e-13,1,"E8",0.214,0.196,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",8
58 | "microspheres","","ddH20",125,14971193,1.99e-13,1,"E9",0.17,0.156,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",9
59 | "microspheres","","ddH20",125,8982716,1.19e-13,1,"E10",0.182,0.172,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",10
60 | "microspheres","","ddH20",125,5389630,7.16e-14,1,"E11",0.177,0.169,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",11
61 | "microspheres","","ddH20",125,0,0,1,"E12",0.147,0.14,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"E",12
62 | "microspheres","","ddH20",125,891346154,1.18e-11,2,"F1",1.427,1.267,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",1
63 | "microspheres","","ddH20",125,534807692,7.1e-12,2,"F2",1.05,0.892,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",2
64 | "microspheres","","ddH20",125,320884615,4.26e-12,2,"F3",0.722,0.599,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",3
65 | "microspheres","","ddH20",125,192530769,2.56e-12,2,"F4",0.517,0.427,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",4
66 | "microspheres","","ddH20",125,115518461,1.53e-12,2,"F5",0.405,0.344,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",5
67 | "microspheres","","ddH20",125,69311077,9.21e-13,2,"F6",0.303,0.269,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",6
68 | "microspheres","","ddH20",125,41586646,5.52e-13,2,"F7",0.236,0.212,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",7
69 | "microspheres","","ddH20",125,24951988,3.31e-13,2,"F8",0.196,0.179,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",8
70 | "microspheres","","ddH20",125,14971193,1.99e-13,2,"F9",0.178,0.165,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",9
71 | "microspheres","","ddH20",125,8982716,1.19e-13,2,"F10",0.159,0.149,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",10
72 | "microspheres","","ddH20",125,5389630,7.16e-14,2,"F11",0.164,0.157,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",11
73 | "microspheres","","ddH20",125,0,0,2,"F12",0.141,0.135,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"F",12
74 | "microspheres","","ddH20",125,891346154,1.18e-11,3,"G1",1.362,1.194,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",1
75 | "microspheres","","ddH20",125,534807692,7.1e-12,3,"G2",1.018,0.86,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",2
76 | "microspheres","","ddH20",125,320884615,4.26e-12,3,"G3",0.721,0.605,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",3
77 | "microspheres","","ddH20",125,192530769,2.56e-12,3,"G4",0.518,0.433,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",4
78 | "microspheres","","ddH20",125,115518461,1.53e-12,3,"G5",0.414,0.359,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",5
79 | "microspheres","","ddH20",125,69311077,9.21e-13,3,"G6",0.298,0.26,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",6
80 | "microspheres","","ddH20",125,41586646,5.52e-13,3,"G7",0.235,0.21,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",7
81 | "microspheres","","ddH20",125,24951988,3.31e-13,3,"G8",0.2,0.182,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",8
82 | "microspheres","","ddH20",125,14971193,1.99e-13,3,"G9",0.178,0.166,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",9
83 | "microspheres","","ddH20",125,8982716,1.19e-13,3,"G10",0.18,0.169,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",10
84 | "microspheres","","ddH20",125,5389630,7.16e-14,3,"G11",0.186,0.166,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",11
85 | "microspheres","","ddH20",125,0,0,3,"G12",0.149,0.142,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"G",12
86 | "microspheres","","ddH20",125,891346154,1.18e-11,4,"H1",1.421,1.26,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",1
87 | "microspheres","","ddH20",125,534807692,7.1e-12,4,"H2",1.05,0.891,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",2
88 | "microspheres","","ddH20",125,320884615,4.26e-12,4,"H3",0.719,0.606,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",3
89 | "microspheres","","ddH20",125,192530769,2.56e-12,4,"H4",0.514,0.433,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",4
90 | "microspheres","","ddH20",125,115518461,1.53e-12,4,"H5",0.379,0.323,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",5
91 | "microspheres","","ddH20",125,69311077,9.21e-13,4,"H6",0.296,0.257,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",6
92 | "microspheres","","ddH20",125,41586646,5.52e-13,4,"H7",0.24,0.216,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",7
93 | "microspheres","","ddH20",125,24951988,3.31e-13,4,"H8",0.208,0.192,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",8
94 | "microspheres","","ddH20",125,14971193,1.99e-13,4,"H9",0.191,0.178,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",9
95 | "microspheres","","ddH20",125,8982716,1.19e-13,4,"H10",0.171,0.16,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",10
96 | "microspheres","","ddH20",125,5389630,7.16e-14,4,"H11",0.151,0.142,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",11
97 | "microspheres","","ddH20",125,0,0,4,"H12",0.15,0.143,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"H",12
98 |
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_membrane_parsed_absorbance_cfs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_cytation/231031_pr_calibration_membrane_parsed_absorbance_cfs.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_membrane_parsed_cfs.csv:
--------------------------------------------------------------------------------
1 | "cf","beta","calibrant","fluorophore","measure"
2 | 1.64032913776628e-15,2.43505349358509e-10,"FITC","GFP","GFP 30"
3 | 1.54149836181872e-14,2.23647775549191e-10,"FITC","GFP","GFP 40"
4 | 8.53241735961217e-14,2.09524794743675e-10,"FITC","GFP","GFP 50"
5 | 3.38099989260685e-13,2.03482049982522e-10,"FITC","GFP","GFP 60"
6 | 1.07103257669161e-12,1.88314181870328e-10,"FITC","GFP","GFP 70"
7 | 2.81891594477139e-12,1.94261699870685e-10,"FITC","GFP","GFP 80"
8 | 6.53563566229361e-12,1.6520988310458e-10,"FITC","GFP","GFP 90"
9 | 1.41256719827646e-11,2.29518724232912e-10,"FITC","GFP","GFP 100"
10 | 2.90396267315367e-11,2.00431090424536e-10,"FITC","GFP","GFP 110"
11 | 8.61358795753689e-16,2.40623076743591e-10,"FITC","GFP","GFP 30 TOP"
12 | 7.4202969911514e-15,2.24451790754604e-10,"FITC","GFP","GFP 40 TOP"
13 | 4.13200631656152e-14,2.19057472855282e-10,"FITC","GFP","GFP 50 TOP"
14 | 1.5724138549382e-13,2.00583524389911e-10,"FITC","GFP","GFP 60 TOP"
15 | 5.04982958084896e-13,1.84873346850286e-10,"FITC","GFP","GFP 70 TOP"
16 | 1.35686301800826e-12,2.05906767202396e-10,"FITC","GFP","GFP 80 TOP"
17 | 3.15825842699207e-12,1.98941823623681e-10,"FITC","GFP","GFP 90 TOP"
18 | 6.91681598072984e-12,1.77886026754186e-10,"FITC","GFP","GFP 100 TOP"
19 | 1.44093716080527e-11,2.17673925977579e-10,"FITC","GFP","GFP 110 TOP"
20 | 2.8493703237836e-11,2.0345069856221e-10,"FITC","GFP","GFP 120 TOP"
21 | 2.92192580957781e-09,4.01769679511199e-10,"microspheres","","OD600"
22 | 2.40078125e-09,5.46484375e-10,"microspheres","","OD700"
23 |
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_membrane_parsed_fluorescence_cfs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_cytation/231031_pr_calibration_membrane_parsed_fluorescence_cfs.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/231031_pr_calibration_nolid.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_cytation/231031_pr_calibration_nolid.xlsx
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_cytation/plate_layout.csv:
--------------------------------------------------------------------------------
1 | calibrant,fluorophore,media,volume_uL,concentration,concentration_M,replicate,well
2 | FITC,GFP,ddH20,125,7.50E+14,9.97E-03,1,A1
3 | FITC,GFP,ddH20,125,3.75E+14,4.98E-03,1,A2
4 | FITC,GFP,ddH20,125,1.88E+14,2.49E-03,1,A3
5 | FITC,GFP,ddH20,125,9.38E+13,1.25E-03,1,A4
6 | FITC,GFP,ddH20,125,4.69E+13,6.23E-04,1,A5
7 | FITC,GFP,ddH20,125,2.34E+13,3.11E-04,1,A6
8 | FITC,GFP,ddH20,125,1.17E+13,1.56E-04,1,A7
9 | FITC,GFP,ddH20,125,5.86E+12,7.79E-05,1,A8
10 | FITC,GFP,ddH20,125,2.93E+12,3.89E-05,1,A9
11 | FITC,GFP,ddH20,125,1.46E+12,1.95E-05,1,A10
12 | FITC,GFP,ddH20,125,7.32E+11,9.73E-06,1,A11
13 | FITC,GFP,ddH20,125,0.00E+00,0.00E+00,1,A12
14 | FITC,GFP,ddH20,125,7.50E+14,9.97E-03,2,B1
15 | FITC,GFP,ddH20,125,3.75E+14,4.98E-03,2,B2
16 | FITC,GFP,ddH20,125,1.88E+14,2.49E-03,2,B3
17 | FITC,GFP,ddH20,125,9.38E+13,1.25E-03,2,B4
18 | FITC,GFP,ddH20,125,4.69E+13,6.23E-04,2,B5
19 | FITC,GFP,ddH20,125,2.34E+13,3.11E-04,2,B6
20 | FITC,GFP,ddH20,125,1.17E+13,1.56E-04,2,B7
21 | FITC,GFP,ddH20,125,5.86E+12,7.79E-05,2,B8
22 | FITC,GFP,ddH20,125,2.93E+12,3.89E-05,2,B9
23 | FITC,GFP,ddH20,125,1.46E+12,1.95E-05,2,B10
24 | FITC,GFP,ddH20,125,7.32E+11,9.73E-06,2,B11
25 | FITC,GFP,ddH20,125,0.00E+00,0.00E+00,2,B12
26 | FITC,GFP,ddH20,125,7.50E+14,9.97E-03,3,C1
27 | FITC,GFP,ddH20,125,3.75E+14,4.98E-03,3,C2
28 | FITC,GFP,ddH20,125,1.88E+14,2.49E-03,3,C3
29 | FITC,GFP,ddH20,125,9.38E+13,1.25E-03,3,C4
30 | FITC,GFP,ddH20,125,4.69E+13,6.23E-04,3,C5
31 | FITC,GFP,ddH20,125,2.34E+13,3.11E-04,3,C6
32 | FITC,GFP,ddH20,125,1.17E+13,1.56E-04,3,C7
33 | FITC,GFP,ddH20,125,5.86E+12,7.79E-05,3,C8
34 | FITC,GFP,ddH20,125,2.93E+12,3.89E-05,3,C9
35 | FITC,GFP,ddH20,125,1.46E+12,1.95E-05,3,C10
36 | FITC,GFP,ddH20,125,7.32E+11,9.73E-06,3,C11
37 | FITC,GFP,ddH20,125,0.00E+00,0.00E+00,3,C12
38 | FITC,GFP,ddH20,125,7.50E+14,9.97E-03,4,D1
39 | FITC,GFP,ddH20,125,3.75E+14,4.98E-03,4,D2
40 | FITC,GFP,ddH20,125,1.88E+14,2.49E-03,4,D3
41 | FITC,GFP,ddH20,125,9.38E+13,1.25E-03,4,D4
42 | FITC,GFP,ddH20,125,4.69E+13,6.23E-04,4,D5
43 | FITC,GFP,ddH20,125,2.34E+13,3.11E-04,4,D6
44 | FITC,GFP,ddH20,125,1.17E+13,1.56E-04,4,D7
45 | FITC,GFP,ddH20,125,5.86E+12,7.79E-05,4,D8
46 | FITC,GFP,ddH20,125,2.93E+12,3.89E-05,4,D9
47 | FITC,GFP,ddH20,125,1.46E+12,1.95E-05,4,D10
48 | FITC,GFP,ddH20,125,7.32E+11,9.73E-06,4,D11
49 | FITC,GFP,ddH20,125,0.00E+00,0.00E+00,4,D12
50 | microspheres,,ddH20,125,8.91E+08,1.18E-11,1,E1
51 | microspheres,,ddH20,125,5.35E+08,7.10E-12,1,E2
52 | microspheres,,ddH20,125,3.21E+08,4.26E-12,1,E3
53 | microspheres,,ddH20,125,1.93E+08,2.56E-12,1,E4
54 | microspheres,,ddH20,125,1.16E+08,1.53E-12,1,E5
55 | microspheres,,ddH20,125,6.93E+07,9.21E-13,1,E6
56 | microspheres,,ddH20,125,4.16E+07,5.52E-13,1,E7
57 | microspheres,,ddH20,125,2.50E+07,3.31E-13,1,E8
58 | microspheres,,ddH20,125,1.50E+07,1.99E-13,1,E9
59 | microspheres,,ddH20,125,8.98E+06,1.19E-13,1,E10
60 | microspheres,,ddH20,125,5.39E+06,7.16E-14,1,E11
61 | microspheres,,ddH20,125,0.00E+00,0.00E+00,1,E12
62 | microspheres,,ddH20,125,8.91E+08,1.18E-11,2,F1
63 | microspheres,,ddH20,125,5.35E+08,7.10E-12,2,F2
64 | microspheres,,ddH20,125,3.21E+08,4.26E-12,2,F3
65 | microspheres,,ddH20,125,1.93E+08,2.56E-12,2,F4
66 | microspheres,,ddH20,125,1.16E+08,1.53E-12,2,F5
67 | microspheres,,ddH20,125,6.93E+07,9.21E-13,2,F6
68 | microspheres,,ddH20,125,4.16E+07,5.52E-13,2,F7
69 | microspheres,,ddH20,125,2.50E+07,3.31E-13,2,F8
70 | microspheres,,ddH20,125,1.50E+07,1.99E-13,2,F9
71 | microspheres,,ddH20,125,8.98E+06,1.19E-13,2,F10
72 | microspheres,,ddH20,125,5.39E+06,7.16E-14,2,F11
73 | microspheres,,ddH20,125,0.00E+00,0.00E+00,2,F12
74 | microspheres,,ddH20,125,8.91E+08,1.18E-11,3,G1
75 | microspheres,,ddH20,125,5.35E+08,7.10E-12,3,G2
76 | microspheres,,ddH20,125,3.21E+08,4.26E-12,3,G3
77 | microspheres,,ddH20,125,1.93E+08,2.56E-12,3,G4
78 | microspheres,,ddH20,125,1.16E+08,1.53E-12,3,G5
79 | microspheres,,ddH20,125,6.93E+07,9.21E-13,3,G6
80 | microspheres,,ddH20,125,4.16E+07,5.52E-13,3,G7
81 | microspheres,,ddH20,125,2.50E+07,3.31E-13,3,G8
82 | microspheres,,ddH20,125,1.50E+07,1.99E-13,3,G9
83 | microspheres,,ddH20,125,8.98E+06,1.19E-13,3,G10
84 | microspheres,,ddH20,125,5.39E+06,7.16E-14,3,G11
85 | microspheres,,ddH20,125,0.00E+00,0.00E+00,3,G12
86 | microspheres,,ddH20,125,8.91E+08,1.18E-11,4,H1
87 | microspheres,,ddH20,125,5.35E+08,7.10E-12,4,H2
88 | microspheres,,ddH20,125,3.21E+08,4.26E-12,4,H3
89 | microspheres,,ddH20,125,1.93E+08,2.56E-12,4,H4
90 | microspheres,,ddH20,125,1.16E+08,1.53E-12,4,H5
91 | microspheres,,ddH20,125,6.93E+07,9.21E-13,4,H6
92 | microspheres,,ddH20,125,4.16E+07,5.52E-13,4,H7
93 | microspheres,,ddH20,125,2.50E+07,3.31E-13,4,H8
94 | microspheres,,ddH20,125,1.50E+07,1.99E-13,4,H9
95 | microspheres,,ddH20,125,8.98E+06,1.19E-13,4,H10
96 | microspheres,,ddH20,125,5.39E+06,7.16E-14,4,H11
97 | microspheres,,ddH20,125,0.00E+00,0.00E+00,4,H12
98 |
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_neo2/biotek-neo2_example_data.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_neo2/biotek-neo2_example_data.xlsx
--------------------------------------------------------------------------------
/examples/plate_reader/biotek_neo2/biotek-neo2_example_data_parsed.csv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/biotek_neo2/biotek-neo2_example_data_parsed.csv
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed.csv:
--------------------------------------------------------------------------------
1 | "calibrant","fluorophore","media","concentration","replicate","well","OD600","OD700","GFP 40","GFP 50","GFP 60","GFP 70","GFP 80","GFP 90","GFP 100","GFP 110","GFP 120","row","column"
2 | "fluorescein","GFP","PBS",10,1,"A1",0.0921,0.0831,1830,9811,36911,NA,NA,NA,NA,NA,NA,"A",1
3 | "fluorescein","GFP","PBS",5,1,"A2",0.0942,0.0852,932,4993,19221,54510,NA,NA,NA,NA,NA,"A",2
4 | "fluorescein","GFP","PBS",2.5,1,"A3",0.1015,0.0928,453,2434,9448,27864,NA,NA,NA,NA,NA,"A",3
5 | "fluorescein","GFP","PBS",1.25,1,"A4",0.0985,0.0899,232,1253,4853,14513,36349,NA,NA,NA,NA,"A",4
6 | "fluorescein","GFP","PBS",0.625,1,"A5",0.0957,0.0905,114,617,2404,7128,18282,41812,NA,NA,NA,"A",5
7 | "fluorescein","GFP","PBS",0.3125,1,"A6",0.1027,0.0965,54,294,1137,3388,8672,20095,42244,NA,NA,"A",6
8 | "fluorescein","GFP","PBS",0.15625,1,"A7",0.0984,0.0918,27,149,581,1733,4464,10204,21665,43374,NA,"A",7
9 | "fluorescein","GFP","PBS",0.078125,1,"A8",0.0966,0.0949,14,76,296,883,2255,5224,11013,22278,42802,"A",8
10 | "fluorescein","GFP","PBS",0.0390625,1,"A9",0.1007,0.0955,7,39,153,454,1160,2681,5671,11383,22231,"A",9
11 | "fluorescein","GFP","PBS",0.01953125,1,"A10",0.0998,0.0953,3,19,76,227,578,1330,2842,5695,11008,"A",10
12 | "fluorescein","GFP","PBS",0.009765625,1,"A11",0.1058,0.1008,2,11,42,124,316,729,1562,3143,6020,"A",11
13 | "fluorescein","GFP","PBS",0,1,"A12",0.1086,0.102,0,2,7,20,52,119,246,491,969,"A",12
14 | "fluorescein","GFP","PBS",10,2,"B1",0.0905,0.084,2170,11542,42376,NA,NA,NA,NA,NA,NA,"B",1
15 | "fluorescein","GFP","PBS",5,2,"B2",0.0911,0.0854,928,4936,18887,53645,NA,NA,NA,NA,NA,"B",2
16 | "fluorescein","GFP","PBS",2.5,2,"B3",0.09,0.0838,468,2522,9739,28562,NA,NA,NA,NA,NA,"B",3
17 | "fluorescein","GFP","PBS",1.25,2,"B4",0.0932,0.0889,231,1247,4823,14304,35869,NA,NA,NA,NA,"B",4
18 | "fluorescein","GFP","PBS",0.625,2,"B5",0.0923,0.0874,112,597,2314,6901,17604,40521,NA,NA,NA,"B",5
19 | "fluorescein","GFP","PBS",0.3125,2,"B6",0.0939,0.0892,56,299,1158,3443,8880,20403,42963,NA,NA,"B",6
20 | "fluorescein","GFP","PBS",0.15625,2,"B7",0.1007,0.0946,27,150,578,1722,4417,10297,21574,43215,NA,"B",7
21 | "fluorescein","GFP","PBS",0.078125,2,"B8",0.0957,0.0908,13,73,286,857,2162,5080,10684,21470,41483,"B",8
22 | "fluorescein","GFP","PBS",0.0390625,2,"B9",0.0957,0.0952,7,38,148,445,1127,2627,5554,11165,21597,"B",9
23 | "fluorescein","GFP","PBS",0.01953125,2,"B10",0.1103,0.1055,4,19,74,223,563,1308,2794,5592,10697,"B",10
24 | "fluorescein","GFP","PBS",0.009765625,2,"B11",0.1093,0.1044,2,10,41,121,312,726,1534,3068,5909,"B",11
25 | "fluorescein","GFP","PBS",0,2,"B12",0.1027,0.0982,0,2,7,20,52,122,252,513,956,"B",12
26 | "fluorescein","GFP","PBS",10,3,"C1",0.1468,0.1185,1671,8769,33015,NA,NA,NA,NA,NA,NA,"C",1
27 | "fluorescein","GFP","PBS",5,3,"C2",0.1016,0.1176,936,4985,19136,54613,NA,NA,NA,NA,NA,"C",2
28 | "fluorescein","GFP","PBS",2.5,3,"C3",0.0897,0.0877,487,2619,10078,29570,NA,NA,NA,NA,NA,"C",3
29 | "fluorescein","GFP","PBS",1.25,3,"C4",0.0966,0.089,250,1330,5127,15429,38751,NA,NA,NA,NA,"C",4
30 | "fluorescein","GFP","PBS",0.625,3,"C5",0.1054,0.0991,124,664,2559,7651,19627,44688,NA,NA,NA,"C",5
31 | "fluorescein","GFP","PBS",0.3125,3,"C6",0.0995,0.0941,61,333,1280,3853,9783,22754,47388,NA,NA,"C",6
32 | "fluorescein","GFP","PBS",0.15625,3,"C7",0.0997,0.0959,32,174,670,2011,5184,11869,24938,50197,NA,"C",7
33 | "fluorescein","GFP","PBS",0.078125,3,"C8",0.1003,0.0948,16,87,338,1018,2588,6013,12642,25441,49472,"C",8
34 | "fluorescein","GFP","PBS",0.0390625,3,"C9",0.097,0.0913,9,47,182,545,1390,3230,6844,13771,26431,"C",9
35 | "fluorescein","GFP","PBS",0.01953125,3,"C10",0.0995,0.0942,5,24,95,282,724,1680,3530,7183,13821,"C",10
36 | "fluorescein","GFP","PBS",0.009765625,3,"C11",0.1004,0.096,2,13,51,152,390,906,1913,3850,7460,"C",11
37 | "fluorescein","GFP","PBS",0,3,"C12",0.1063,0.1,0,2,7,20,52,117,244,498,978,"C",12
38 | "fluorescein","GFP","PBS",10,4,"D1",0.0883,0.0834,1901,9994,37406,NA,NA,NA,NA,NA,NA,"D",1
39 | "fluorescein","GFP","PBS",5,4,"D2",0.0919,0.0871,944,4965,19101,54386,NA,NA,NA,NA,NA,"D",2
40 | "fluorescein","GFP","PBS",2.5,4,"D3",0.0928,0.0866,470,2486,9732,28393,NA,NA,NA,NA,NA,"D",3
41 | "fluorescein","GFP","PBS",1.25,4,"D4",0.0968,0.0925,219,1156,4510,13505,33991,NA,NA,NA,NA,"D",4
42 | "fluorescein","GFP","PBS",0.625,4,"D5",0.1003,0.0947,115,614,2392,7088,18110,41487,NA,NA,NA,"D",5
43 | "fluorescein","GFP","PBS",0.3125,4,"D6",0.0963,0.091,56,298,1172,3468,8910,20564,43074,NA,NA,"D",6
44 | "fluorescein","GFP","PBS",0.15625,4,"D7",0.0949,0.0898,27,146,576,1684,4333,9989,21188,42712,NA,"D",7
45 | "fluorescein","GFP","PBS",0.078125,4,"D8",0.0963,0.0912,14,74,291,863,2223,5099,10898,21882,42137,"D",8
46 | "fluorescein","GFP","PBS",0.0390625,4,"D9",0.0984,0.0927,7,37,147,437,1121,2581,5476,11030,21377,"D",9
47 | "fluorescein","GFP","PBS",0.01953125,4,"D10",0.0992,0.0936,3,19,77,225,577,1326,2807,5709,11010,"D",10
48 | "fluorescein","GFP","PBS",0.009765625,4,"D11",0.1098,0.1048,2,10,40,118,307,702,1494,2994,5801,"D",11
49 | "fluorescein","GFP","PBS",0,4,"D12",0.1049,0.0997,0,2,6,19,50,115,243,491,946,"D",12
50 | "microspheres","","ddH20",807692307.7,1,"E1",0.9082,0.772,0,2,7,23,56,135,277,570,1102,"E",1
51 | "microspheres","","ddH20",484615384.6,1,"E2",0.5497,0.4572,0,2,8,23,60,141,305,597,1176,"E",2
52 | "microspheres","","ddH20",290769230.8,1,"E3",0.445,0.3738,0,2,8,23,60,139,293,589,1150,"E",3
53 | "microspheres","","ddH20",174461538.5,1,"E4",0.2943,0.2496,0,2,8,22,59,135,284,576,1107,"E",4
54 | "microspheres","","ddH20",104676923.1,1,"E5",0.1999,0.1722,0,2,7,22,57,131,277,565,1090,"E",5
55 | "microspheres","","ddH20",62806153.85,1,"E6",0.161,0.1421,0,2,7,22,56,131,268,547,1078,"E",6
56 | "microspheres","","ddH20",37683692.31,1,"E7",0.1362,0.1224,1,2,8,22,55,131,273,552,1022,"E",7
57 | "microspheres","","ddH20",22610215.38,1,"E8",0.1239,0.1139,0,2,7,23,56,132,288,538,1096,"E",8
58 | "microspheres","","ddH20",13566129.23,1,"E9",0.1167,0.1084,0,2,7,21,55,128,269,528,1011,"E",9
59 | "microspheres","","ddH20",8139677.538,1,"E10",0.1052,0.0983,0,2,7,22,57,134,277,542,1076,"E",10
60 | "microspheres","","ddH20",4883806.523,1,"E11",0.1017,0.0957,0,2,7,21,56,128,267,535,1050,"E",11
61 | "microspheres","","ddH20",0,1,"E12",0.1007,0.0959,0,2,7,21,54,123,265,528,1001,"E",12
62 | "microspheres","","ddH20",807692307.7,2,"F1",0.8487,0.7162,0,2,8,21,56,129,273,547,1073,"F",1
63 | "microspheres","","ddH20",484615384.6,2,"F2",0.5781,0.4821,1,2,8,23,60,136,288,582,1130,"F",2
64 | "microspheres","","ddH20",290769230.8,2,"F3",0.3934,0.3286,0,2,8,24,61,142,298,598,1142,"F",3
65 | "microspheres","","ddH20",174461538.5,2,"F4",0.2767,0.2339,0,2,7,23,58,135,284,571,1133,"F",4
66 | "microspheres","","ddH20",104676923.1,2,"F5",0.2097,0.1817,0,2,8,23,58,136,292,566,1109,"F",5
67 | "microspheres","","ddH20",62806153.85,2,"F6",0.1654,0.1462,0,2,7,22,57,129,279,553,1079,"F",6
68 | "microspheres","","ddH20",37683692.31,2,"F7",0.1362,0.1241,0,2,7,22,56,127,268,536,1055,"F",7
69 | "microspheres","","ddH20",22610215.38,2,"F8",0.1315,0.1214,0,2,7,21,54,130,269,536,1066,"F",8
70 | "microspheres","","ddH20",13566129.23,2,"F9",0.1113,0.1027,0,2,7,22,55,130,264,561,1088,"F",9
71 | "microspheres","","ddH20",8139677.538,2,"F10",0.1076,0.1001,0,2,7,22,57,131,277,559,1082,"F",10
72 | "microspheres","","ddH20",4883806.523,2,"F11",0.0997,0.0934,0,2,7,20,52,124,261,502,991,"F",11
73 | "microspheres","","ddH20",0,2,"F12",0.1036,0.0994,0,2,7,20,54,124,260,522,999,"F",12
74 | "microspheres","","ddH20",807692307.7,3,"G1",0.8686,0.7304,0,2,7,22,56,131,281,553,1096,"G",1
75 | "microspheres","","ddH20",484615384.6,3,"G2",0.5947,0.4927,0,2,7,23,58,135,283,578,1112,"G",2
76 | "microspheres","","ddH20",290769230.8,3,"G3",0.3973,0.3322,0,2,8,23,60,137,299,576,1121,"G",3
77 | "microspheres","","ddH20",174461538.5,3,"G4",0.2801,0.2385,0,2,8,24,62,142,308,596,1171,"G",4
78 | "microspheres","","ddH20",104676923.1,3,"G5",0.2072,0.1792,0,2,8,24,59,145,299,593,1192,"G",5
79 | "microspheres","","ddH20",62806153.85,3,"G6",0.1572,0.1383,0,1,8,23,59,138,283,575,1088,"G",6
80 | "microspheres","","ddH20",37683692.31,3,"G7",0.1364,0.123,0,2,8,22,57,132,280,562,1080,"G",7
81 | "microspheres","","ddH20",22610215.38,3,"G8",0.1215,0.1119,0,1,7,22,58,136,286,557,1090,"G",8
82 | "microspheres","","ddH20",13566129.23,3,"G9",0.1137,0.1059,0,2,7,22,56,132,277,559,1082,"G",9
83 | "microspheres","","ddH20",8139677.538,3,"G10",0.1002,0.0939,1,2,7,21,52,119,260,504,990,"G",10
84 | "microspheres","","ddH20",4883806.523,3,"G11",0.1013,0.0953,0,2,7,21,54,123,259,516,1026,"G",11
85 | "microspheres","","ddH20",0,3,"G12",0.0994,0.0942,0,2,6,20,51,121,258,508,977,"G",12
86 | "microspheres","","ddH20",807692307.7,4,"H1",0.8752,0.7372,0,2,7,22,55,133,277,557,1106,"H",1
87 | "microspheres","","ddH20",484615384.6,4,"H2",0.5622,0.4682,0,2,7,23,58,135,290,579,1107,"H",2
88 | "microspheres","","ddH20",290769230.8,4,"H3",0.3919,0.3268,1,2,7,22,58,135,285,562,1101,"H",3
89 | "microspheres","","ddH20",174461538.5,4,"H4",0.2847,0.2423,0,2,7,23,57,133,292,567,1098,"H",4
90 | "microspheres","","ddH20",104676923.1,4,"H5",0.2058,0.1776,0,2,8,23,60,140,294,595,1130,"H",5
91 | "microspheres","","ddH20",62806153.85,4,"H6",0.1632,0.1441,0,2,7,22,56,134,276,545,1054,"H",6
92 | "microspheres","","ddH20",37683692.31,4,"H7",0.1349,0.1214,0,2,9,27,68,166,335,670,1321,"H",7
93 | "microspheres","","ddH20",22610215.38,4,"H8",0.1323,0.1216,0,2,10,28,73,169,354,706,1391,"H",8
94 | "microspheres","","ddH20",13566129.23,4,"H9",0.12,0.1121,1,2,8,24,65,146,313,626,1215,"H",9
95 | "microspheres","","ddH20",8139677.538,4,"H10",0.1097,0.1031,0,2,7,22,57,133,279,561,1059,"H",10
96 | "microspheres","","ddH20",4883806.523,4,"H11",0.105,0.0985,0,2,7,22,57,132,276,550,1073,"H",11
97 | "microspheres","","ddH20",0,4,"H12",0.1005,0.0953,0,2,7,22,55,128,275,541,1064,"H",12
98 |
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_absorbance_cfs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_absorbance_cfs.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_cfs.csv:
--------------------------------------------------------------------------------
1 | "cf","beta","calibrant","fluorophore","measure"
2 | 184.727423380549,0.00574759624626908,"fluorescein","GFP","GFP 40"
3 | 996.447161301119,-0.00354235187381888,"fluorescein","GFP","GFP 50"
4 | 3821.04972156311,-0.000473714337673158,"fluorescein","GFP","GFP 60"
5 | 11298.953070981,0.000201527635187288,"fluorescein","GFP","GFP 70"
6 | 29128.3782889558,-0.000748121513265721,"fluorescein","GFP","GFP 80"
7 | 65834.9342365029,0.00127508170363757,"fluorescein","GFP","GFP 90"
8 | 139940.146694077,0.000982238741907277,"fluorescein","GFP","GFP 100"
9 | 288001.553550677,-0.000879790172713573,"fluorescein","GFP","GFP 110"
10 | 567984.42938174,-0.00242703741977703,"fluorescein","GFP","GFP 120"
11 | 2.64499346746598e-08,4.77318409341387e-09,"microspheres","","GFP 40"
12 | 1.5168920457363e-09,8.13779775053263e-09,"microspheres","","OD600"
13 | 1.21544813615036e-09,7.88761279867322e-09,"microspheres","","OD700"
14 |
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_fluorescence_cfs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/tecan_spark/191219_calibration_membrane_parsed_fluorescence_cfs.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/200228_example_data_parsed_GFP.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/tecan_spark/200228_example_data_parsed_GFP.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/200228_example_data_parsed_OD.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/tecan_spark/200228_example_data_parsed_OD.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/200228_example_data_parsed_mCherry.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/tecan_spark/200228_example_data_parsed_mCherry.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/200228_example_data_parsed_norm-curve_GFP.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/tecan_spark/200228_example_data_parsed_norm-curve_GFP.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/200228_example_data_parsed_norm-curve_mCherry.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ucl-cssb/flopr/94a5eefef52c6d4aed8fd9ce4608a26004cb73c7/examples/plate_reader/tecan_spark/200228_example_data_parsed_norm-curve_mCherry.pdf
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/200228_example_layout.csv:
--------------------------------------------------------------------------------
1 | strain,host,plasmid,plasmid_2,strain_2,media,sugar,amino_acids,inducer,concentration,init_ratio,init_dilution,well
2 | ,,,,,,,,,,,,A1
3 | ,,,,,,,,,,,,A2
4 | ,,,,,,,,,,,,A3
5 | ,,,,,,,,,,,,A4
6 | ,,,,,,,,,,,,A5
7 | ,,,,,,,,,,,,A6
8 | ,,,,,,,,,,,,A7
9 | ,,,,,,,,,,,,A8
10 | ,,,,,,,,,,,,A9
11 | ,,,,,,,,,,,,A10
12 | ,,,,,,,,,,,,A11
13 | ,,,,,,,,,,,,A12
14 | ,,,,,,,,,,,,B1
15 | ,,,,,,,,,,,,B2
16 | ,,,,,,,,,,,,B3
17 | ,,,,,,,,,,,,B4
18 | ,,,,,,,,,,,,B5
19 | ,,,,,,,,,,,,B6
20 | ,,,,,,,,,,,,B7
21 | ,,,,,,,,,,,,B8
22 | ,,,,,,,,,,,,B9
23 | ,,,,,,,,,,,,B10
24 | ,,,,,,,,,,,,B11
25 | ,,,,,,,,,,,,B12
26 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,1,0.140625,C1
27 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.8,0.140625,C2
28 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.6,0.140625,C3
29 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.4,0.140625,C4
30 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.2,0.140625,C5
31 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0,0.140625,C6
32 | ,,,,,,,,,,,,C7
33 | ,,,,,,,,,,,,C8
34 | ,,,,,,,,,,,,C9
35 | ,,,,,,,,,,,,C10
36 | ,,,,,,,,,,,,C11
37 | ,,,,,M9,0.4% glycerol,casamino acids,AHL,0,,,C12
38 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,1,0.052734375,D1
39 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.8,0.052734375,D2
40 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.6,0.052734375,D3
41 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.4,0.052734375,D4
42 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.2,0.052734375,D5
43 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0,0.052734375,D6
44 | ,,,,,,,,,,,,D7
45 | ,,,,,,,,,,,,D8
46 | ,,,,,,,,,,,,D9
47 | ,,,,,,,,,,,,D10
48 | ,,,,,,,,,,,,D11
49 | ,,,,,M9,0.4% glycerol,casamino acids,AHL,0,,,D12
50 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,1,0.019775391,E1
51 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.8,0.019775391,E2
52 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.6,0.019775391,E3
53 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.4,0.019775391,E4
54 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0.2,0.019775391,E5
55 | JW_SPoCK634301,JW3910,p63_AF043,pMPES_AF01,MG-Gm-CFP,M9,0.4% glycerol,casamino acids,AHL,0,0,0.019775391,E6
56 | ,,,,,,,,,,,,E7
57 | ,,,,,,,,,,,,E8
58 | ,,,,,,,,,,,,E9
59 | ,,,,,,,,,,,,E10
60 | ,,,,,,,,,,,,E11
61 | ,,,,,M9,0.4% glycerol,casamino acids,AHL,0,,,E12
62 | ,,,,,,,,,,,,F1
63 | ,,,,,,,,,,,,F2
64 | ,,,,,,,,,,,,F3
65 | ,,,,,,,,,,,,F4
66 | ,,,,,,,,,,,,F5
67 | ,,,,,,,,,,,,F6
68 | ,,,,,,,,,,,,F7
69 | ,,,,,,,,,,,,F8
70 | ,,,,,,,,,,,,F9
71 | ,,,,,,,,,,,,F10
72 | ,,,,,,,,,,,,F11
73 | ,,,,,,,,,,,,F12
74 | ,,,,,,,,,,,,G1
75 | ,,,,,,,,,,,,G2
76 | ,,,,,,,,,,,,G3
77 | ,,,,,,,,,,,,G4
78 | ,,,,,,,,,,,,G5
79 | ,,,,,,,,,,,,G6
80 | ,,,,,,,,,,,,G7
81 | ,,,,,,,,,,,,G8
82 | ,,,,,,,,,,,,G9
83 | ,,,,,,,,,,,,G10
84 | ,,,,,,,,,,,,G11
85 | ,,,,,,,,,,,,G12
86 | ,,,,,,,,,,,,H1
87 | ,,,,,,,,,,,,H2
88 | ,,,,,,,,,,,,H3
89 | ,,,,,,,,,,,,H4
90 | ,,,,,,,,,,,,H5
91 | ,,,,,,,,,,,,H6
92 | ,,,,,,,,,,,,H7
93 | ,,,,,,,,,,,,H8
94 | ,,,,,,,,,,,,H9
95 | ,,,,,,,,,,,,H10
96 | ,,,,,,,,,,,,H11
97 | ,,,,,,,,,,,,H12
98 |
--------------------------------------------------------------------------------
/examples/plate_reader/tecan_spark/calibration_plate_layout.csv:
--------------------------------------------------------------------------------
1 | calibrant,fluorophore,media,concentration,replicate,well
2 | fluorescein,GFP,PBS,7.53E+14,1,A1
3 | fluorescein,GFP,PBS,3.765E+14,1,A2
4 | fluorescein,GFP,PBS,1.8825E+14,1,A3
5 | fluorescein,GFP,PBS,9.4125E+13,1,A4
6 | fluorescein,GFP,PBS,4.70625E+13,1,A5
7 | fluorescein,GFP,PBS,2.35313E+13,1,A6
8 | fluorescein,GFP,PBS,1.17656E+13,1,A7
9 | fluorescein,GFP,PBS,5.88281E+12,1,A8
10 | fluorescein,GFP,PBS,2.94141E+12,1,A9
11 | fluorescein,GFP,PBS,1.4707E+12,1,A10
12 | fluorescein,GFP,PBS,7.35352E+11,1,A11
13 | fluorescein,GFP,PBS,0,1,A12
14 | fluorescein,GFP,PBS,7.53E+14,2,B1
15 | fluorescein,GFP,PBS,3.765E+14,2,B2
16 | fluorescein,GFP,PBS,1.8825E+14,2,B3
17 | fluorescein,GFP,PBS,9.4125E+13,2,B4
18 | fluorescein,GFP,PBS,4.70625E+13,2,B5
19 | fluorescein,GFP,PBS,2.35313E+13,2,B6
20 | fluorescein,GFP,PBS,1.17656E+13,2,B7
21 | fluorescein,GFP,PBS,5.88281E+12,2,B8
22 | fluorescein,GFP,PBS,2.94141E+12,2,B9
23 | fluorescein,GFP,PBS,1.4707E+12,2,B10
24 | fluorescein,GFP,PBS,7.35352E+11,2,B11
25 | fluorescein,GFP,PBS,0,2,B12
26 | fluorescein,GFP,PBS,7.53E+14,3,C1
27 | fluorescein,GFP,PBS,3.765E+14,3,C2
28 | fluorescein,GFP,PBS,1.8825E+14,3,C3
29 | fluorescein,GFP,PBS,9.4125E+13,3,C4
30 | fluorescein,GFP,PBS,4.70625E+13,3,C5
31 | fluorescein,GFP,PBS,2.35313E+13,3,C6
32 | fluorescein,GFP,PBS,1.17656E+13,3,C7
33 | fluorescein,GFP,PBS,5.88281E+12,3,C8
34 | fluorescein,GFP,PBS,2.94141E+12,3,C9
35 | fluorescein,GFP,PBS,1.4707E+12,3,C10
36 | fluorescein,GFP,PBS,7.35352E+11,3,C11
37 | fluorescein,GFP,PBS,0,3,C12
38 | fluorescein,GFP,PBS,7.53E+14,4,D1
39 | fluorescein,GFP,PBS,3.765E+14,4,D2
40 | fluorescein,GFP,PBS,1.8825E+14,4,D3
41 | fluorescein,GFP,PBS,9.4125E+13,4,D4
42 | fluorescein,GFP,PBS,4.70625E+13,4,D5
43 | fluorescein,GFP,PBS,2.35313E+13,4,D6
44 | fluorescein,GFP,PBS,1.17656E+13,4,D7
45 | fluorescein,GFP,PBS,5.88281E+12,4,D8
46 | fluorescein,GFP,PBS,2.94141E+12,4,D9
47 | fluorescein,GFP,PBS,1.4707E+12,4,D10
48 | fluorescein,GFP,PBS,7.35352E+11,4,D11
49 | fluorescein,GFP,PBS,0,4,D12
50 | microspheres,,ddH20,807692307.7,1,E1
51 | microspheres,,ddH20,484615384.6,1,E2
52 | microspheres,,ddH20,290769230.8,1,E3
53 | microspheres,,ddH20,174461538.5,1,E4
54 | microspheres,,ddH20,104676923.1,1,E5
55 | microspheres,,ddH20,62806153.85,1,E6
56 | microspheres,,ddH20,37683692.31,1,E7
57 | microspheres,,ddH20,22610215.38,1,E8
58 | microspheres,,ddH20,13566129.23,1,E9
59 | microspheres,,ddH20,8139677.538,1,E10
60 | microspheres,,ddH20,4883806.523,1,E11
61 | microspheres,,ddH20,0,1,E12
62 | microspheres,,ddH20,807692307.7,2,F1
63 | microspheres,,ddH20,484615384.6,2,F2
64 | microspheres,,ddH20,290769230.8,2,F3
65 | microspheres,,ddH20,174461538.5,2,F4
66 | microspheres,,ddH20,104676923.1,2,F5
67 | microspheres,,ddH20,62806153.85,2,F6
68 | microspheres,,ddH20,37683692.31,2,F7
69 | microspheres,,ddH20,22610215.38,2,F8
70 | microspheres,,ddH20,13566129.23,2,F9
71 | microspheres,,ddH20,8139677.538,2,F10
72 | microspheres,,ddH20,4883806.523,2,F11
73 | microspheres,,ddH20,0,2,F12
74 | microspheres,,ddH20,807692307.7,3,G1
75 | microspheres,,ddH20,484615384.6,3,G2
76 | microspheres,,ddH20,290769230.8,3,G3
77 | microspheres,,ddH20,174461538.5,3,G4
78 | microspheres,,ddH20,104676923.1,3,G5
79 | microspheres,,ddH20,62806153.85,3,G6
80 | microspheres,,ddH20,37683692.31,3,G7
81 | microspheres,,ddH20,22610215.38,3,G8
82 | microspheres,,ddH20,13566129.23,3,G9
83 | microspheres,,ddH20,8139677.538,3,G10
84 | microspheres,,ddH20,4883806.523,3,G11
85 | microspheres,,ddH20,0,3,G12
86 | microspheres,,ddH20,807692307.7,4,H1
87 | microspheres,,ddH20,484615384.6,4,H2
88 | microspheres,,ddH20,290769230.8,4,H3
89 | microspheres,,ddH20,174461538.5,4,H4
90 | microspheres,,ddH20,104676923.1,4,H5
91 | microspheres,,ddH20,62806153.85,4,H6
92 | microspheres,,ddH20,37683692.31,4,H7
93 | microspheres,,ddH20,22610215.38,4,H8
94 | microspheres,,ddH20,13566129.23,4,H9
95 | microspheres,,ddH20,8139677.538,4,H10
96 | microspheres,,ddH20,4883806.523,4,H11
97 | microspheres,,ddH20,0,4,H12
98 |
--------------------------------------------------------------------------------
/flopr.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | StripTrailingWhitespace: Yes
16 |
17 | BuildType: Package
18 | PackageUseDevtools: Yes
19 | PackageInstallArgs: --no-multiarch --with-keep.source
20 | PackageRoxygenize: rd,collate,namespace,vignette
21 |
--------------------------------------------------------------------------------
/man/biotek_parse.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/biotekNeo2Functions.R
3 | \name{biotek_parse}
4 | \alias{biotek_parse}
5 | \title{Parser for Biotek Neo 2 plate reader data}
6 | \usage{
7 | biotek_parse(data_xl, layout_csv, timeseries = T)
8 | }
9 | \arguments{
10 | \item{data_xl}{path to xls or xlsx file from Biotek Neo 2 plate reader}
11 |
12 | \item{layout_csv}{path to csv file containing plate layout information}
13 |
14 | \item{timeseries}{Boolean flag indicating whether the data is a timeseries or
15 | single recording. Currently only works for timeseries=T.}
16 | }
17 | \value{
18 | a data.frame containing the parsed plate reader data
19 | }
20 | \description{
21 | Parser for Biotek Neo 2 plate reader data
22 | }
23 |
--------------------------------------------------------------------------------
/man/calibrate_flu.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plateReaderFunctions.R
3 | \name{calibrate_flu}
4 | \alias{calibrate_flu}
5 | \title{Convert arbitrary fluorescence units to calibrated units}
6 | \usage{
7 | calibrate_flu(pr_data, flu_name, flu_gain, od_name, conversion_factors_csv)
8 | }
9 | \arguments{
10 | \item{pr_data}{a data.frame of parsed plate reader data}
11 |
12 | \item{flu_name}{name of fluorophore to be calibrated}
13 |
14 | \item{flu_gain}{gain at which the fluorophore was measured}
15 |
16 | \item{od_name}{the column name for the optical density data}
17 |
18 | \item{conversion_factors_csv}{if to_MEFL=T, path of the csv file containing
19 | conversion factors from plate reader calibration}
20 | }
21 | \description{
22 | Convert arbitrary fluorescence units to calibrated units
23 | }
24 |
--------------------------------------------------------------------------------
/man/calibrate_od.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plateReaderFunctions.R
3 | \name{calibrate_od}
4 | \alias{calibrate_od}
5 | \title{Convert arbitrary absorbance units to calibrated units}
6 | \usage{
7 | calibrate_od(pr_data, od_name, conversion_factors_csv)
8 | }
9 | \arguments{
10 | \item{pr_data}{a data.frame of parsed plate reader data}
11 |
12 | \item{od_name}{the column name for the optical density data}
13 |
14 | \item{conversion_factors_csv}{if to_MEFL=T, path of the csv file containing
15 | conversion factors from plate reader calibration}
16 | }
17 | \description{
18 | Convert arbitrary absorbance units to calibrated units
19 | }
20 |
--------------------------------------------------------------------------------
/man/cytation_parse.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/biotekCytationFunctions.R
3 | \name{cytation_parse}
4 | \alias{cytation_parse}
5 | \title{Parser for Biotek Cytation plate reader data}
6 | \usage{
7 | cytation_parse(data_csv, layout_csv, timeseries = T)
8 | }
9 | \arguments{
10 | \item{layout_csv}{path to csv file containing plate layout information}
11 |
12 | \item{timeseries}{Boolean flag indicating whether the data is a timeseries or
13 | single recording. Currently only works for timeseries=T.}
14 |
15 | \item{data_xl}{path to xls or xlsx file from Biotek Cytation plate reader}
16 | }
17 | \value{
18 | a data.frame containing the parsed plate reader data
19 | }
20 | \description{
21 | Parser for Biotek Cytation plate reader data
22 | }
23 |
--------------------------------------------------------------------------------
/man/ff_append_cols.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCoreMisc.R
3 | \name{ff_append_cols}
4 | \alias{ff_append_cols}
5 | \title{Append data columns to a flowFrame}
6 | \usage{
7 | ff_append_cols(fr, cols)
8 | }
9 | \arguments{
10 | \item{fr}{A \code{\link[flowCore:flowFrame-class]{flowFrame}}.}
11 |
12 | \item{cols}{A numeric matrix containing the new data columns to be added.
13 | Must has column names to be used as new channel names.}
14 | }
15 | \value{
16 | A \code{\linkS4class{flowFrame}}
17 | }
18 | \description{
19 | Append data columns to a flowFrame
20 | }
21 | \details{
22 | It is used to add extra data columns to the existing flowFrame. It handles
23 | keywords and parameters properly to ensure the new flowFrame can be written
24 | as a valid FCS through the function \code{write.FCS} .
25 | }
26 | \author{
27 | Mike Jiang
28 | }
29 | \keyword{IO}
30 |
--------------------------------------------------------------------------------
/man/flu_norm.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plateReaderFunctions.R
3 | \name{flu_norm}
4 | \alias{flu_norm}
5 | \title{Normalise fluorescence against negative well}
6 | \usage{
7 | flu_norm(pr_data, neg_well, blank_well, flu_name, af_model, data_csv)
8 | }
9 | \arguments{
10 | \item{pr_data}{a long data.frame containing you plate reader data with OD
11 | normalised}
12 |
13 | \item{neg_well}{the well coordinates of a non-fluorescent control}
14 |
15 | \item{blank_well}{the well coordinates of a media blank}
16 |
17 | \item{flu_name}{the column name of the fluorescence chanel to normalise}
18 |
19 | \item{af_model}{model used to fit negative control autofluorescence.
20 | For now these include "polynomial", "invers_poly", "exponential", "spline" or "loess".}
21 |
22 | \item{data_csv}{path to the original data. Used for saving normalisation curve plots.}
23 | }
24 | \description{
25 | Normalise fluorescence against negative well
26 | }
27 |
--------------------------------------------------------------------------------
/man/generate_cfs.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plateReaderFunctions.R
3 | \name{generate_cfs}
4 | \alias{generate_cfs}
5 | \title{Generate Conversion Factors}
6 | \usage{
7 | generate_cfs(calibration_csv)
8 | }
9 | \arguments{
10 | \item{calibration_csv}{path of a .csv file of your calibration data}
11 | }
12 | \description{
13 | Generate Conversion Factors
14 | }
15 |
--------------------------------------------------------------------------------
/man/get_bacteria.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{get_bacteria}
4 | \alias{get_bacteria}
5 | \title{Remove background debris events}
6 | \usage{
7 | get_bacteria(flow_frame, pre_cleaned)
8 | }
9 | \arguments{
10 | \item{flow_frame}{a \code{flowFrame} for processing}
11 |
12 | \item{pre_cleaned}{a flag to identify if debris has already been manually
13 | gated}
14 | }
15 | \description{
16 | Remove background debris events
17 | }
18 |
--------------------------------------------------------------------------------
/man/get_calibration.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{get_calibration}
4 | \alias{get_calibration}
5 | \title{Get fluorescence calibration curve parameters}
6 | \usage{
7 | get_calibration(bead_file, flu_channels, mef_peaks, manual_peaks, bead_dens_bw)
8 | }
9 | \arguments{
10 | \item{bead_file}{path to beads .fcs file.}
11 |
12 | \item{flu_channels}{a vector of strings of the fluorescence channels to keep
13 | in the processed data and plotting. Defaults to \code{"BL1-H"}.}
14 |
15 | \item{mef_peaks}{a list of lists in the form \code{list(list(channel="BL1-H",
16 | peaks=c(0, 200, ...)} of MEF fluorescence values for the calibration beads.
17 | Default values for BL1-H and YL2-H.}
18 |
19 | \item{manual_peaks}{if bead peaks are not being found by the EM algorithm,
20 | one can manually specify the positions of the bead peaks (on a log10 scale).
21 | A list of lists in the form
22 | \code{list(list(channel="BL1-H", peaks=c(2.1, 2.8, ...)} of log10
23 | fluorescence values for the calibration beads.}
24 |
25 | \item{bead_dens_bw}{the bandwidth for the kernel density of the bead peak
26 | data. Default = 0.025. Increase if erroneous peaks are being found, decrease
27 | if not enough peaks are found.}
28 | }
29 | \description{
30 | Get fluorescence calibration curve parameters
31 | }
32 |
--------------------------------------------------------------------------------
/man/get_singlets.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{get_singlets}
4 | \alias{get_singlets}
5 | \title{Remove doublet events}
6 | \usage{
7 | get_singlets(flow_frame)
8 | }
9 | \arguments{
10 | \item{flow_frame}{a \code{flowFrame} for processing}
11 | }
12 | \description{
13 | Remove doublet events
14 | }
15 |
--------------------------------------------------------------------------------
/man/infinite_parse.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanInfiniteFunctions.R
3 | \name{infinite_parse}
4 | \alias{infinite_parse}
5 | \title{Parser for Tecan Infinite plate reader data}
6 | \usage{
7 | infinite_parse(data_csv, layout_csv, timeseries = F)
8 | }
9 | \arguments{
10 | \item{data_csv}{path to .csv, .xls or .xlsx file from Tecan Infinit plate reader}
11 |
12 | \item{layout_csv}{path to csv file containing plate layout information}
13 |
14 | \item{timeseries}{Boolean flag indicating whether the data is a timeseries or
15 | single recording. The Tecan software outputs the two scenarios differently.}
16 | }
17 | \value{
18 | a data.frame containing the parsed plate reader data
19 | }
20 | \description{
21 | Parser for Tecan Infinite plate reader data
22 | }
23 |
--------------------------------------------------------------------------------
/man/next_blank.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanInfiniteFunctions.R
3 | \name{next_blank}
4 | \alias{next_blank}
5 | \title{Find next blank line}
6 | \usage{
7 | next_blank(start_idx, data)
8 | }
9 | \arguments{
10 | \item{data}{}
11 | }
12 | \value{
13 | row index of next blank line
14 | }
15 | \description{
16 | Find next blank line
17 | }
18 |
--------------------------------------------------------------------------------
/man/next_blank_cell.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanSparkFunctions.R
3 | \name{next_blank_cell}
4 | \alias{next_blank_cell}
5 | \title{Find next blank line}
6 | \usage{
7 | next_blank_cell(start_idx, data, col)
8 | }
9 | \arguments{
10 | \item{data}{}
11 | }
12 | \value{
13 | row index of next blank line
14 | }
15 | \description{
16 | Find next blank line
17 | }
18 |
--------------------------------------------------------------------------------
/man/next_blank_row.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanSparkFunctions.R
3 | \name{next_blank_row}
4 | \alias{next_blank_row}
5 | \title{Find next blank line}
6 | \usage{
7 | next_blank_row(start_idx, data)
8 | }
9 | \arguments{
10 | \item{data}{}
11 | }
12 | \value{
13 | row index of next blank line
14 | }
15 | \description{
16 | Find next blank line
17 | }
18 |
--------------------------------------------------------------------------------
/man/next_filled.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanInfiniteFunctions.R
3 | \name{next_filled}
4 | \alias{next_filled}
5 | \title{Find next non-blank line}
6 | \usage{
7 | next_filled(start_idx, data)
8 | }
9 | \arguments{
10 | \item{data}{}
11 | }
12 | \value{
13 | row index of next non-blank line
14 | }
15 | \description{
16 | Find next non-blank line
17 | }
18 |
--------------------------------------------------------------------------------
/man/next_filled_cell.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanSparkFunctions.R
3 | \name{next_filled_cell}
4 | \alias{next_filled_cell}
5 | \title{Find next non-blank line}
6 | \usage{
7 | next_filled_cell(start_idx, data, col)
8 | }
9 | \arguments{
10 | \item{data}{}
11 | }
12 | \value{
13 | row index of next non-blank line
14 | }
15 | \description{
16 | Find next non-blank line
17 | }
18 |
--------------------------------------------------------------------------------
/man/next_filled_row.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanSparkFunctions.R
3 | \name{next_filled_row}
4 | \alias{next_filled_row}
5 | \title{Find next non-blank line}
6 | \usage{
7 | next_filled_row(start_idx, data)
8 | }
9 | \arguments{
10 | \item{data}{}
11 | }
12 | \value{
13 | row index of next non-blank line
14 | }
15 | \description{
16 | Find next non-blank line
17 | }
18 |
--------------------------------------------------------------------------------
/man/od_norm.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plateReaderFunctions.R
3 | \name{od_norm}
4 | \alias{od_norm}
5 | \title{Normalisation absorbance against blank well}
6 | \usage{
7 | od_norm(pr_data, blank_well, od_name)
8 | }
9 | \arguments{
10 | \item{pr_data}{a long data.frame containing you plate reader data}
11 |
12 | \item{blank_well}{the well coordinates of one or more media blanks}
13 |
14 | \item{od_name}{the column name for the optical density data}
15 | }
16 | \value{
17 | an updated data.frame with an additional column "normalised_OD"
18 | }
19 | \description{
20 | Normalisation absorbance against blank well
21 | }
22 |
--------------------------------------------------------------------------------
/man/plot_trimming.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{plot_trimming}
4 | \alias{plot_trimming}
5 | \title{Plot trimming process}
6 | \usage{
7 | plot_trimming(
8 | flow_frame,
9 | bacteria_flow_frame,
10 | singlet_flow_frame,
11 | normalised_flow_frame,
12 | calibrated_flow_frame,
13 | flu_channels,
14 | out_name,
15 | normalised,
16 | calibrate
17 | )
18 | }
19 | \arguments{
20 | \item{flow_frame}{the original \code{flowFrame}}
21 |
22 | \item{bacteria_flow_frame}{the \code{flowFrame} with debris removed}
23 |
24 | \item{singlet_flow_frame}{the \code{flowFrame} with debris and doublets removed}
25 |
26 | \item{normalised_flow_frame}{the normalised \code{flowFrame}}
27 |
28 | \item{calibrated_flow_frame}{the calibrated \code{flowFrame} with debris and doublets
29 | removed}
30 |
31 | \item{flu_channels}{a vector of strings of the fluorescence channels to keep
32 | in the processed data and plotting. Defaults to "BL1-H".}
33 |
34 | \item{out_name}{the filename for the outputted \code{flowFrame}}
35 |
36 | \item{normalised}{a Boolean flag to determine whether to normalise}
37 |
38 | \item{calibrate}{a Boolean flag to determine whether to convert fluorescence
39 | to MEF values. Requires an .fcs file with named \code{"*beads*.fcs"}.
40 | Defaults to \code{FALSE}.}
41 | }
42 | \description{
43 | Plot trimming process
44 | }
45 |
--------------------------------------------------------------------------------
/man/prep_flow_frame.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{prep_flow_frame}
4 | \alias{prep_flow_frame}
5 | \title{Log10 transform and remove -Inf values from \code{flowFrame}}
6 | \usage{
7 | prep_flow_frame(flow_frame, flu_channels)
8 | }
9 | \arguments{
10 | \item{flow_frame}{a \code{flowFrame} for processing}
11 |
12 | \item{flu_channels}{a vector of strings of the fluorescence channels to keep
13 | in the processed data and plotting. Defaults to \code{"BL1-H"}.}
14 | }
15 | \description{
16 | Log10 transform and remove -Inf values from \code{flowFrame}
17 | }
18 |
--------------------------------------------------------------------------------
/man/process_fcs.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{process_fcs}
4 | \alias{process_fcs}
5 | \title{Process an .fcs files to remove debris and doublets}
6 | \usage{
7 | process_fcs(fcs_file, flu_channels = c("BL1-H"), do_plot = F, pre_cleaned = F)
8 | }
9 | \arguments{
10 | \item{fcs_file}{path of an .fcs files to be processed.}
11 |
12 | \item{flu_channels}{a vector of strings of the fluorescence channels to keep
13 | in the processed data and plotting. Defaults to "BL1-H".}
14 |
15 | \item{do_plot}{a Boolean flag to determine whether to produce plots showing
16 | the trimming of each \code{flowFrame} Defaults to \code{FALSE}.}
17 |
18 | \item{pre_cleaned}{have you pre removed background debris.}
19 | }
20 | \value{
21 | nothing is returned. A processed .fcs file is produced and a plot if
22 | \code{do_plot = TRUE}.
23 | }
24 | \description{
25 | \code{process_fcs} uses mixture models to cluster bacteria from background
26 | debris and fits a linear model to SSC-H vs SSC-A to remove doublets.
27 | }
28 |
--------------------------------------------------------------------------------
/man/process_fcs_dir.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{process_fcs_dir}
4 | \alias{process_fcs_dir}
5 | \title{Process .fcs files within a directory to remove debris and doublets, and
6 | optionally calibrate}
7 | \usage{
8 | process_fcs_dir(
9 | dir_path,
10 | pattern = "*.fcs",
11 | flu_channels = c("BL1-H"),
12 | do_plot = F,
13 | pre_cleaned = F,
14 | neg_fcs = NA,
15 | calibrate = F,
16 | mef_peaks = NA,
17 | bead_dens_bw = 0.025,
18 | manual_peaks = NA
19 | )
20 | }
21 | \arguments{
22 | \item{dir_path}{a directory path containing the .fcs files to be parsed or
23 | folders to be recursed through.}
24 |
25 | \item{pattern}{a regex pattern to match particular .fcs files. Default is
26 | \code{"*.fcs"} matching all .fcs files.}
27 |
28 | \item{flu_channels}{a vector of strings of the fluorescence channels to keep
29 | in the processed data and plotting. Defaults to "BL1-H".}
30 |
31 | \item{do_plot}{a Boolean flag to determine whether to produce plots showing
32 | the trimming of each \code{flowFrame}. Defaults to \code{FALSE}.}
33 |
34 | \item{pre_cleaned}{have you pre removed background debris}
35 |
36 | \item{neg_fcs}{filename of .fcs file for a negative control used for
37 | fluorescence normalisation.}
38 |
39 | \item{calibrate}{a Boolean flag to determine whether to convert fluorescence
40 | to MEF values. Requires an .fcs file with named \code{"*beads*.fcs"}.
41 | Defaults to \code{FALSE}.}
42 |
43 | \item{mef_peaks}{a list of lists in the form \code{list(list(channel="BL1-H",
44 | peaks=c(0, 200, ...)} of MEF fluorescence values for the calibration beads.
45 | Default values for BL1-H and YL2-H.}
46 |
47 | \item{bead_dens_bw}{the bandwidth for the kernel density of the bead peak
48 | data. Default = 0.025. Increase if erroneous peaks are being found, decrease
49 | if not enough peaks are found.}
50 |
51 | \item{manual_peaks}{if bead peaks are not being found by the EM algorithm,
52 | one can manually specify the positions of the bead peaks (on a log10 scale).
53 | A list of lists in the form
54 | \code{list(list(channel="BL1-H", peaks=c(2.1, 2.8, ...)} of log10
55 | fluorescence values for the calibration beads.}
56 | }
57 | \value{
58 | nothing is returned. A new folder is created with the processed .fcs
59 | files and plot if \code{do_plot = TRUE}.
60 | }
61 | \description{
62 | \code{process_fcs_dir} uses mixture models to cluster bacteria from
63 | background debris and fits a linear model to SSC-H vs SSC-A to remove doublets.
64 | }
65 |
--------------------------------------------------------------------------------
/man/process_plate.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plateReaderFunctions.R
3 | \name{process_plate}
4 | \alias{process_plate}
5 | \title{Plate reader normalisation and calibration}
6 | \usage{
7 | process_plate(
8 | data_csv,
9 | blank_well = "A1",
10 | neg_well = "A2",
11 | od_name = "OD",
12 | flu_names = c("GFP"),
13 | af_model = "spline",
14 | to_MEFL = F,
15 | flu_gains,
16 | conversion_factors_csv
17 | )
18 | }
19 | \arguments{
20 | \item{data_csv}{path to a .csv file containing parsed plate reader data}
21 |
22 | \item{blank_well}{the well coordinates of one or more media blanks}
23 |
24 | \item{neg_well}{the well coordinates of a non-fluorescent control}
25 |
26 | \item{od_name}{the column name for the optical density data}
27 |
28 | \item{flu_names}{the column names for the fluorescence data}
29 |
30 | \item{af_model}{model used to fit negative control autofluorescence.
31 | For now these include "polynomial", "invers_poly", "exponential", "spline" and "loess".}
32 |
33 | \item{to_MEFL}{a Boolean to determine whether to attempt to convert OD and
34 | GFP reading to calibrated units}
35 |
36 | \item{flu_gains}{if to_MEFL=T, the gain values at which the fluorophores
37 | specified in flu_names was recorded. If there isn't calibration data for a
38 | fluorophore, do not speficy a gain value}
39 |
40 | \item{conversion_factors_csv}{if to_MEFL=T, path of the csv file containing
41 | conversion factors from plate reader calibration}
42 | }
43 | \value{
44 | a data.frame with columns for raw plate reader data, normalised data
45 | and, if to_MEFL = T, calibrated OD and GFP data
46 | }
47 | \description{
48 | Plate reader normalisation and calibration
49 | }
50 |
--------------------------------------------------------------------------------
/man/sparkParse.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanSparkFunctions.R
3 | \name{sparkParse}
4 | \alias{sparkParse}
5 | \title{Parser for Tecan Spark plate reader data}
6 | \usage{
7 | sparkParse(data_csv, layout_csv)
8 | }
9 | \arguments{
10 | \item{data_csv}{path to csv file from Tecan Spark plate reader}
11 |
12 | \item{layout_csv}{path to csv file containing plate layout information}
13 | }
14 | \value{
15 | a data.frame containing the parsed plate reader data
16 | }
17 | \description{
18 | Parser for Tecan Spark plate reader data
19 | }
20 |
--------------------------------------------------------------------------------
/man/spark_parse.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tecanSparkFunctions.R
3 | \name{spark_parse}
4 | \alias{spark_parse}
5 | \title{Parser for Tecan Spark plate reader data}
6 | \usage{
7 | spark_parse(data_csv, layout_csv, timeseries = F, wells_as_columns = F)
8 | }
9 | \arguments{
10 | \item{data_csv}{path to .csv, .xls or .xlsx file from Tecan Spark plate reader}
11 |
12 | \item{layout_csv}{path to csv file containing plate layout information}
13 |
14 | \item{timeseries}{Boolean flag indicating whether the data is a timeseries or
15 | single recording. The Tecan software outputs the two scenarios differently.}
16 |
17 | \item{wells_as_columns}{Boolean flag indicating whether blocks of data are
18 | oriented with wells as columns or rows}
19 | }
20 | \value{
21 | a data.frame containing the parsed plate reader data
22 | }
23 | \description{
24 | Parser for Tecan Spark plate reader data
25 | }
26 |
--------------------------------------------------------------------------------
/man/summarise_data.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{summarise_data}
4 | \alias{summarise_data}
5 | \title{Get geometric mean and standard deviation of fluorescence channels of a flow frame}
6 | \usage{
7 | summarise_data(flow_frame, flu_channels)
8 | }
9 | \arguments{
10 | \item{flow_frame}{a flow frame to be summarised}
11 |
12 | \item{flu_channels}{channels to summarise}
13 | }
14 | \description{
15 | Get geometric mean and standard deviation of fluorescence channels of a flow frame
16 | }
17 |
--------------------------------------------------------------------------------
/man/to_mef.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/flowCytometryFunctions.R
3 | \name{to_mef}
4 | \alias{to_mef}
5 | \title{Calibrate fluorescence measurements}
6 | \usage{
7 | to_mef(flow_frame, flu_channels, calibration_parameters, normalise)
8 | }
9 | \arguments{
10 | \item{flow_frame}{a \code{flowFrame} for processing}
11 |
12 | \item{flu_channels}{a vector of strings of the fluorescence channels to keep
13 | in the processed data and plotting. Defaults to "BL1-H".}
14 |
15 | \item{calibration_parameters}{parameters of a model returned by
16 | get_calibration(...)}
17 |
18 | \item{normalise}{Boolean flag to indicate if data has been normalised}
19 | }
20 | \description{
21 | Calibrate fluorescence measurements
22 | }
23 |
--------------------------------------------------------------------------------