1library(shiny) 2 3source("../../analysis/R/read_input.R") 4source("../../analysis/R/decode.R") 5 6# Random number associated with the session used in exported file names. 7seed <- sample(10^6, 1) 8 9PlotCohorts <- function(x, highlighted, color = "grey") { 10 n <- nrow(x) 11 k <- ncol(x) 12 if (n < 16) { 13 par(mfrow = c(n, 1), mai = c(0, .5, .5, 0)) 14 } else if (n < 64) { 15 par(mfrow = c(n / 2, 2), mai = c(0, .5, .5, 0)) 16 } else { 17 par(mfrow = c(n / 4, 4), mai = c(0, .5, .5, 0)) 18 } 19 for (i in 1:n) { 20 cc <- rep(color, k) 21 if (!is.null(highlighted)) { 22 ind <- highlighted[which(ceiling(highlighted / k) == i)] %% k 23 cc[ind] <- "greenyellow" 24 } 25 barplot(x[i, ], main = paste0("Cohort ", i), col = cc, border = cc, 26 names.arg = "") 27 } 28} 29 30shinyServer(function(input, output, session) { 31 Params <- reactive({ 32 param_file <- input$params 33 if (!is.null(param_file)) { 34 params <- ReadParameterFile(param_file$datapath) 35 updateSelectInput(session, "size", selected = params$k) 36 updateSelectInput(session, "hashes", selected = params$h) 37 updateSelectInput(session, "instances", selected = params$m) 38 updateSliderInput(session, "p", value = params$p) 39 updateSliderInput(session, "q", value = params$q) 40 updateSliderInput(session, "f", value = params$f) 41 } else { 42 params <- list(k = as.numeric(input$size), 43 h = as.numeric(input$hashes), 44 m = as.numeric(input$instances), 45 p = as.numeric(input$p), 46 q = as.numeric(input$q), 47 f = as.numeric(input$f)) 48 } 49 params 50 }) 51 52 Counts <- reactive({ 53 params <- Params() 54 counts_file <- input$counts 55 if (is.null(counts_file)) { 56 return(NULL) 57 } 58 59 counts <- ReadCountsFile(counts_file$datapath, params) 60 updateNumericInput(session, "N", value = sum(counts[, 1])) 61 counts 62 }) 63 64 output$countsUploaded <- reactive({ 65 ifelse(is.null(input$counts), FALSE, TRUE) 66 }) 67 outputOptions(output, 'countsUploaded', suspendWhenHidden=FALSE) 68 69 Map <- reactive({ 70 params <- Params() 71 map_file <- input$map 72 if (is.null(map_file)) { 73 return(NULL) 74 } 75 76 map <- ReadMapFile(map_file$datapath, params) 77 updateSelectInput(session, "selected_string", choices = map$strs, selected = map$strs[1]) 78 map 79 }) 80 81 output$mapUploaded <- reactive({ 82 ifelse(is.null(input$map), FALSE, TRUE) 83 }) 84 outputOptions(output, 'mapUploaded', suspendWhenHidden=FALSE) 85 86 DecodingParams <- reactive({ 87 list(alpha = as.numeric(input$alpha), 88 correction = input$correction) 89 }) 90 91 Analyze <- reactive({ 92 if (is.null(input$map) || is.null(input$counts)) { 93 return() 94 } 95 params <- Params() 96 map <- Map() 97 counts <- Counts() 98 decoding_params <- DecodingParams() 99 100 fit <- Decode(counts, map$map, params, 101 alpha = decoding_params$alpha, 102 correction = decoding_params$correction) 103 fit 104 }) 105 106 # Results summary. 107 output$pr <- renderTable({ 108 Analyze()$summary 109 }, 110 include.rownames = FALSE, include.colnames = FALSE) 111 112 # Results table. 113 output$tab <- renderDataTable({ 114 Analyze()$fit 115 }, 116 options = list(iDisplayLength = 100)) 117 118 # Results barplot. 119 output$res_barplot <- renderPlot({ 120 fit <- Analyze()$fit 121 122 par(mai = c(2, 1, 1, .5)) 123 124 bp <- barplot(fit$proportion, col = "palegreen", 125 main = "Discovered String Distribution") 126 abline(h = Analyze()$privacy[7, 2], col = "darkred", lty = 2, lwd = 2) 127 text(bp[, 1], 0, paste(fit$strings, " "), srt = 45, adj = c(1, 1), xpd = NA) 128 legend("topright", legend = "Detection Frequency", lty = 2, lwd = 2, col = "darkred", 129 bty = "n") 130 }) 131 132 # Epsilon. 133 output$epsilon <- renderTable({ 134 Analyze()$privacy 135 }, 136 include.rownames = FALSE, include.colnames = FALSE, digits = 4) 137 138 output$map <- renderPlot({ 139 image(as.matrix(Map()$map), col = c("white", "darkred"), xaxt = "n", yaxt = "n", bty = "n") 140 }) 141 142 # Estimated bits patterns. 143 output$ests <- renderPlot({ 144 ests <- Analyze()$ests 145 ind <- which(input$selected_string == Map()$strs) 146 high <- unlist(Map()$map_pos[ind, -1]) 147 PlotCohorts(ests, high, color = "darkred") 148 }) 149 150 # Collisions. 151 output$collisions <- renderPlot({ 152 params <- Params() 153 map <- Map() 154 tab <- table(unlist(map$map_pos[, -1])) 155 tab <- tab[as.character(1:(params$k * params$m))] 156 tab[is.na(tab)] <- 0 157 tab <- matrix(tab, nrow = params$m, byrow = TRUE) 158 159 ind <- which(input$selected_string == map$strs) 160 high <- unlist(map$map_pos[ind, -1]) 161 162 PlotCohorts(tab, high, color = "navajowhite") 163 }) 164 165 # Observed counts. 166 output$counts <- renderPlot({ 167 counts <- as.matrix(Analyze()$counts) 168 ind <- which(input$selected_string == Map()$strs) 169 high <- unlist(Map()$map_pos[ind, -1]) 170 PlotCohorts(counts, high, color = "darkblue") 171 }) 172 173 # Downloadable datasets. 174 output$download_fit <- downloadHandler( 175 filename = function() { paste("results_", seed, "_", date(), '.csv', sep='') }, 176 content = function(file) { 177 write.csv(Analyze()$fit, file, row.names = FALSE) 178 } 179 ) 180 181 output$download_summary <- downloadHandler( 182 filename = function() { paste("summary_", seed, "_", date(), '.csv', sep='') }, 183 content = function(file) { 184 write.csv(rbind(Analyze()$summary, Analyze()$privacy, Analyze()$params), 185 file, row.names = FALSE) 186 } 187 ) 188 189 output$example_params <- renderTable({ 190 as.data.frame(ReadParameterFile("params.csv")) 191 }, 192 include.rownames = FALSE) 193 194 output$example_counts <- renderTable({ 195 counts <- ReadCountsFile("counts.csv")[, 1:15] 196 cbind(counts, rep("...", nrow(counts))) 197 }, 198 include.rownames = FALSE, include.colnames = FALSE) 199 200 output$example_map <- renderTable({ 201 map <- ReadMapFile("map.csv", ReadParameterFile("params.csv")) 202 map$map_pos[1:10, ] 203 }, 204 include.rownames = FALSE, include.colnames = FALSE) 205 206}) 207