Calculate the half maximal inhibitory concentration (IC50) for each compound used in a SARS-CoV-2 study

public public 1yr ago Version: Version 1 1 bookmark

This notebook demonstrates how to retrieve metadata associated to the paper A SARS-CoV-2 cytopathicity dataset generated by high-content screening of a large drug repurposing collection and available in IDR at idr0094-ellinger-sarscov2 . Over 300 compounds were used in this investigation. This notebook allows the user to calculate the half maximal inhibitory concentration (IC50) for each compound. IC50 is a measure of the potency of a substance in inhibiting a specific biological or biochemical function. IC50 is a quantitative measure that indicates how much of a particular inhibitory substance (e.g. drug) is needed to inhibit, in vitro, a given biological process or biological component by 50%. User can download the IC50 for each compound used in that study

A shiny app is also available for dynamic plotting of the IC50 curve for each compound. This R shiny app can be launched in My Binder

Inputs

Parameters needed to configure the workflow:

screenId : Identifier of a screen in IDR.

Ouputs

Output file generated:

ic50.csv : Comma separate value file containing the IC50 for each compound.

Code Snippets

2
3
# Parameters:
screenId = 2603
 7
 8
 9
10
# Load the libraries
suppressPackageStartupMessages(library(romero.gateway))
suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(drc))
14
15
16
server <- OMEROServer(host = 'wss://idr.openmicroscopy.org/omero-ws', port = 443L, username='public', password='public')
server <- connect(server)
paste('Successfully logged in as', server@user$getUserName())
20
tableName <- 'bulk_annotations'
24
25
26
27
28
29
30
screen <- loadObject(server, "ScreenData", screenId)

annos <- getAnnotations(server, 'ScreenData', getOMEROID(screen), nameFilter = tableName)
annotationFileID = as.integer(annos$FileID)

df <- loadDataframe(screen, annotationFileID)
df
34
35
36
37
names(df)[names(df) == 'Compound Name'] <- "CompoundName"
names(df)[names(df) == 'Compound InChIKey'] <- 'InChIKey'
names(df)[names(df) == 'Compound Concentration (microMolar)'] <- "Concentration"
names(df)[names(df) == 'Percentage Inhibition (DPC)'] <- "Inhibition"
41
42
compoundName <- "Remdesivir"
inChIKey <- "RWWYLEGWBNMMLJ-YSOARWBDSA-N"
46
47
48
49
50
51
52
53
54
55
56
57
58
59
get_id <- function(x) {
    value <- unlist(strsplit(x, split="="))[2]
    id <- unlist(strsplit(value, split=")"))[1]
}

filter_data <- function(df, value) {
    dfcopy <- cbind(df)
    dfcopy <- filter(dfcopy, CompoundName == value)
    df1 <- subset(dfcopy, select=c("Concentration", "Inhibition", "Well"))
    df1 <- cbind(df1[c("Concentration", "Inhibition")], apply(df1[c("Well")], 1, get_id))
    names(df1)[3] <- "Well"
    data <- mutate_all(df1, function(x) as.numeric(as.character(x)))
    data <- data[order(data$Concentration),]
}
63
64
data <- filter_data(df, compoundName)
nrow(data)
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
cols <- 2
n <- nrow(data)
m <- 4

values <- vector()
par(mfrow = c(m, cols))
par(mar=c(0,0,2,0))
par(oma=c(0,0,10,5))
for(i in 1:n) {
    row <- data[i,]
    if (!is.element(row$Concentration, values)) {
        values <- c(values, row$Concentration)
        well <- loadObject(server, "WellData", row$Well)
        image <- getImages(well, 0)
        thumb <- getThumbnail(image)
        plot(0:1, 0:1, type="n", ann=FALSE, axes=FALSE)
        rasterImage(thumb, 0, 0, 1, 1)
        title(main=paste(row$Concentration, 'uM '), font.main=2, cex.main=2)
    }     
}
mtext(paste("Compound:", compoundName), outer = TRUE, font=2, cex=2, side=3, line=1)
92
disconnect(server)
 96
 97
 98
 99
100
101
102
103
104
105
calculate_IC50 <- function(data){
  IC50 <- NA
  data.LL.4 <- NULL
  ctest <- filter(data, Inhibition != "NaN")
  data.LL.4 <- drm(Inhibition ~ Concentration, data = ctest, fct = LL.4(), control = drmc(errorm=FALSE))
  if (is.null(data.LL.4$convergence)) {
      IC50 <- ED(data.LL.4, 50, interval = "delta")[1]
  }
  returned_values <- list("ic50" = IC50, "data" = data.LL.4)
}
109
110
111
values <- calculate_IC50(data)
IC50 <- values$ic50
IC50
115
116
117
118
119
120
121
options(repr.plot.width=6, repr.plot.height=5.8)
plot(values$data, broken = TRUE, type = "all",
     main = "Dose Response Curve (DRC)", xlim = c(0, 100),
     xlab = "Log Concentration (uM)",
     ylab = "Percent Inhibition (percent)")
abline(h = 50, col = "cyan")
abline(v = IC50, col = "green")
125
compounds <- unique(as.vector(df["CompoundName"]))
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
ic <- vector()
cn <- vector()
for(i in 1:nrow(compounds)) {
    c <- compounds[i,]
    if (c != "") {
      d <- filter_data(df, c) 
      results <- calculate_IC50(d)
      ic <- c(ic, results$ic50)
      cn <- c(cn, c)
    }
}

result <- data.frame(cn, ic)
x <- c("Compound Name", "IC50 (uM)")
colnames(result) <- x
147
148
setwd(path.expand('~'))
write.csv(result, "ic50.csv")
ShowHide 14 more snippets with no or duplicated tags.

Login to post a comment if you would like to share your experience with this workflow.

Do you know this workflow well? If so, you can request seller status , and start supporting this workflow.

Free

Created: 1yr ago
Updated: 1yr ago
Maitainers: public
URL: https://github.com/IDR/idr0094-ellinger-sarscov2
Name: calculate-the-half-maximal-inhibitory-concentratio
Version: Version 1
Badge:
workflow icon

Insert copied code into your website to add a link to this workflow.

Downloaded: 0
Bookmarked: 1
Copyright: Public Domain
License: BSD 2-Clause "Simplified" License
  • Future updates

Related Workflows

cellranger-snakemake-gke
snakemake workflow to run cellranger on a given bucket using gke.
A Snakemake workflow for running cellranger on a given bucket using Google Kubernetes Engine. The usage of this workflow ...