From 4c4f703c574bf3f689eff427b1aeac76bf51adb4 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Fri, 21 Nov 2025 10:04:23 -0500 Subject: [PATCH 1/6] feature(response-curve): Enable configuration for response curve analysis --- R/constants.R | 8 +- R/module-statmodel-server.R | 38 +++++++++ R/statmodel-ui-comparisons.R | 18 +++- R/statmodel-ui-headers.R | 4 +- .../test-statmodel-ui-options-contrasts.R | 16 ++++ tests/testthat/test-utils-statmodel-server.R | 84 +++++++++++++++++++ 6 files changed, 162 insertions(+), 6 deletions(-) diff --git a/R/constants.R b/R/constants.R index cf9224f..d4b8c45 100644 --- a/R/constants.R +++ b/R/constants.R @@ -8,12 +8,16 @@ NAMESPACE_STATMODEL = list( comparisons_custom_pairwise_choice2 = "comparisons_custom_pairwise_choice2", comparisons_all_vs_one_choice = "comparisons_all_vs_one_choice", comparisons_custom_nonpairwise_name = "comparisons_custom_nonpairwise_name", - comparisons_custom_nonpairwise_weights = "comparisons_custom_nonpairwise_weights" + comparisons_custom_nonpairwise_weights = "comparisons_custom_nonpairwise_weights", + comparisons_response_curve_choice = "comparisons_response_curve_choice", + comparisons_response_curve_xaxis = "comparisons_response_curve_xaxis", + comparisons_response_curve_amount = "comparisons_response_curve_amount" ) CONSTANTS_STATMODEL = list( comparison_mode_all_pairwise = "comparison_mode_all_pairwise", comparison_mode_all_vs_one = "comparison_mode_all_vs_one", comparison_mode_custom_pairwise = "comparison_mode_custom_pairwise", - comparison_mode_custom_nonpairwise = "comparison_mode_custom_nonpairwise" + comparison_mode_custom_nonpairwise = "comparison_mode_custom_nonpairwise", + comparison_mode_response_curve = "comparison_mode_response_curve" ) \ No newline at end of file diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index a1643e2..a2b33f4 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -32,6 +32,8 @@ get_contrast_panel_ui <- function(mode, ns) { build_all_pairwise_panel(ns) } else if (mode == CONSTANTS_STATMODEL$comparison_mode_custom_nonpairwise) { build_custom_nonpairwise_panel(ns) + } else if (mode == CONSTANTS_STATMODEL$comparison_mode_response_curve) { + build_response_curve_panel(ns) } else { NULL } @@ -69,6 +71,17 @@ render_custom_non_pairwise_inputs = function(output, session, condition_list) { }) } +render_response_curve_inputs = function(output, session, condition_list) { + ns = session$ns + + output[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] = renderUI({ + selectInput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_choice), + "Condition:", + condition_list() + ) + }) +} + # Todo: Add helper function to render dose response curve inputs validate_contrast_inputs = function(input, contrast_mode, condition_list) { @@ -202,6 +215,27 @@ build_all_pair_contrast = function(input, condition_list, contrast, comp_list, r return(contrast$matrix) } +build_response_curve_matrix = function(input, contrast) { + if (is.null(contrast$matrix)) { + contrast$matrix = data.frame( + Condition = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], + X_axis = input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]], + Amount = input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]], + stringsAsFactors = FALSE + ) + } else { + contrast$matrix = rbind(contrast$matrix, data.frame( + Condition = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], + X_axis = input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]], + Amount = input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]], + stringsAsFactors = FALSE + )) + contrast$matrix = rbind(contrast$matrix[!duplicated(contrast$matrix$Condition),]) + } + + return(contrast$matrix) +} + # Todo: Add helper function to build dose response curve mapper matrix # ============================================================================ @@ -467,6 +501,7 @@ statmodelServer = function(id, parent_session, loadpage_input, qc_input, render_all_against_one_inputs(output, session, condition_list) render_custom_pairwise_inputs(output, session, condition_list) render_custom_non_pairwise_inputs(output, session, condition_list) + render_response_curve_inputs(output, session, condition_list) Rownames = eventReactive(input[[NAMESPACE_STATMODEL$comparisons_submit]], { req(input[[NAMESPACE_STATMODEL$comparison_mode]]) @@ -509,6 +544,9 @@ statmodelServer = function(id, parent_session, loadpage_input, qc_input, } else if (input[[NAMESPACE_STATMODEL$comparison_mode]] == CONSTANTS_STATMODEL$comparison_mode_all_pairwise) { contrast$matrix = build_all_pair_contrast( input, condition_list(), contrast, comp_list, row(), loadpage_input()) + } else if (input[[NAMESPACE_STATMODEL$comparison_mode]] == CONSTANTS_STATMODEL$comparison_mode_response_curve) { + contrast$matrix = build_response_curve_matrix( + input, contrast) } enable("calculate") diff --git a/R/statmodel-ui-comparisons.R b/R/statmodel-ui-comparisons.R index d2278cf..d4ba098 100644 --- a/R/statmodel-ui-comparisons.R +++ b/R/statmodel-ui-comparisons.R @@ -23,13 +23,14 @@ create_contrast_radio_buttons <- function(ns) { "1. Define comparisons - contrast matrix", class = "icon-wrapper", icon("question-circle", lib = "font-awesome"), - div("Define what conditions you want to compare here.", class = "icon-tooltip") + div("Define what conditions you want to compare here", class = "icon-tooltip") ), c( "All possible pairwise comparisons" = CONSTANTS_STATMODEL$comparison_mode_all_pairwise, "Compare all against one" = CONSTANTS_STATMODEL$comparison_mode_all_vs_one, "Create custom pairwise comparisons" = CONSTANTS_STATMODEL$comparison_mode_custom_pairwise, - "Create custom non-pairwise comparisons" = CONSTANTS_STATMODEL$comparison_mode_custom_nonpairwise + "Create custom non-pairwise comparisons" = CONSTANTS_STATMODEL$comparison_mode_custom_nonpairwise, + "Create response curves" = CONSTANTS_STATMODEL$comparison_mode_response_curve ), selected = character(0) ) @@ -78,4 +79,17 @@ build_custom_nonpairwise_panel <- function(ns) { actionButton(ns(NAMESPACE_STATMODEL$comparisons_submit), "Add"), actionButton(ns(NAMESPACE_STATMODEL$comparisons_clear), "Clear matrix") ) +} + +#' Create panel for configuring response curve metadata +#' @noRd +build_response_curve_panel <- function(ns) { + tagList( + h5("Set up response curve configuration:"), + uiOutput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_choice)), + textInput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_xaxis), "X-Axis Label:", placeholder = "e.g., Dosage, Time"), + numericInput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_amount), "Response:", value = NULL, step = 0.1), + actionButton(ns(NAMESPACE_STATMODEL$comparisons_submit), "Add Entry"), + actionButton(ns(NAMESPACE_STATMODEL$comparisons_clear), "Clear All Data") + ) } \ No newline at end of file diff --git a/R/statmodel-ui-headers.R b/R/statmodel-ui-headers.R index c3db71c..d948937 100644 --- a/R/statmodel-ui-headers.R +++ b/R/statmodel-ui-headers.R @@ -28,8 +28,8 @@ create_custom_styles <- function() { create_header_section <- function() { tagList( headerPanel("Statistical modeling and inference"), - p("In this tab a statistical model is built in three steps:"), - p("(i) Create a contrast matrix with the correct Group comparisons,"), + p("In this tab, build your statistical model in three steps:"), + p("(i) Create a contrast matrix for a group comparison or set up a configuration for a response curve analysis,"), p("(ii) generate the model and "), p("(iii) view result plots."), p("More info ", a("here", href="https://www.rdocumentation.org/packages/MSstats/versions/3.4.0/topics/groupComparisonPlots")) diff --git a/tests/testthat/test-statmodel-ui-options-contrasts.R b/tests/testthat/test-statmodel-ui-options-contrasts.R index 08e497b..ee93e24 100644 --- a/tests/testthat/test-statmodel-ui-options-contrasts.R +++ b/tests/testthat/test-statmodel-ui-options-contrasts.R @@ -52,4 +52,20 @@ test_that("build_custom_nonpairwise_panel creates correct UI structure", { expect_true(grepl(">Clear matrix<", html, fixed = TRUE)) expect_s3_class(ui, "shiny.tag.list") expect_length(ui, 5) +}) + +test_that("build_response_curve_panel creates correct UI structure", { + ns <- function(id) paste0("statmodel-", id) + ui <- build_response_curve_panel(ns) + html <- as.character(ui) + expect_true(grepl("
Set up response curve configuration:
", html, fixed = TRUE)) + expect_true(grepl(NAMESPACE_STATMODEL$comparisons_response_curve_choice, html, fixed = TRUE)) + expect_true(grepl(NAMESPACE_STATMODEL$comparisons_response_curve_xaxis, html, fixed = TRUE)) + expect_true(grepl(NAMESPACE_STATMODEL$comparisons_response_curve_amount, html, fixed = TRUE)) + expect_true(grepl(NAMESPACE_STATMODEL$comparisons_submit, html, fixed = TRUE)) + expect_true(grepl(NAMESPACE_STATMODEL$comparisons_clear, html, fixed = TRUE)) + expect_true(grepl(">Add Entry<", html, fixed = TRUE)) + expect_true(grepl(">Clear All Data<", html, fixed = TRUE)) + expect_s3_class(ui, "shiny.tag.list") + expect_length(ui, 6) }) \ No newline at end of file diff --git a/tests/testthat/test-utils-statmodel-server.R b/tests/testthat/test-utils-statmodel-server.R index 3b53ac8..e5d0284 100644 --- a/tests/testthat/test-utils-statmodel-server.R +++ b/tests/testthat/test-utils-statmodel-server.R @@ -374,4 +374,88 @@ test_that("get_contrast_panel_ui returns correct UI for each mode", { expect_null(get_contrast_panel_ui(NULL, ns)) expect_null(get_contrast_panel_ui(character(0), ns)) expect_null(get_contrast_panel_ui("invalid", ns)) +}) + + +test_that("build_response_curve_matrix when contrast$matrix is NULL", { + input <- list() + input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] <- "Control" + input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] <- "Dose" + input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] <- 0 + + contrast <- list(matrix = NULL) + result <- build_response_curve_matrix(input, contrast) + + expect_equal(nrow(result), 1) + expect_equal(ncol(result), 3) + expect_equal(result$Condition, "Control") + expect_equal(result$X_axis, "Dose") + expect_equal(result$Amount, 0) +}) + +test_that("build_response_curve_matrix appends row to existing response matrix", { + input <- list() + input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] <- "T5" + input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] <- "Time" + input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] <- 5 + + contrast <- list( + matrix = data.frame( + Condition = "Control", + X_axis = "Time", + Amount = 0, + stringsAsFactors = FALSE + ) + ) + + result <- build_response_curve_matrix(input, contrast) + + expect_equal(nrow(result), 2) + expect_equal(result$Condition[2], "T5") + expect_equal(result$X_axis[2], "Time") + expect_equal(result$Amount[2], 5) +}) + +test_that("build_response_curve_matrix removes duplicate conditions in response matrix, keep first occurrence", { + input <- list() + input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] <- "Control" + input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] <- "Time" + input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] <- 1 + + contrast <- list( + matrix = data.frame( + Condition = c("Control", "T15"), + X_axis = c("Time", "Time"), + Amount = c(0, 15), + stringsAsFactors = FALSE + ) + ) + + result <- build_response_curve_matrix(input, contrast) + + expect_equal(nrow(result), 2) + control_row <- result[result$Condition == "Control", ] + expect_equal(control_row$X_axis, "Time") + expect_equal(control_row$Amount, 0) +}) + +test_that("build_response_curve_matrix handles multiple unique x-axes correctly", { + input <- list() + input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] <- "Group_C" + input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] <- "pH" + input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] <- 7.5 + + contrast <- list( + matrix = data.frame( + Condition = c("Group_A", "Group_B"), + X_axis = c("Temperature", "Pressure"), + Amount = c(25, 100), + stringsAsFactors = FALSE + ) + ) + + result <- build_response_curve_matrix(input, contrast) + + expect_equal(nrow(result), 3) + expect_true(all(c("Group_A", "Group_B", "Group_C") %in% result$Condition)) }) \ No newline at end of file From 3e45d0e1f39acc9b660900bb558b0779d6b4b755 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Fri, 21 Nov 2025 10:25:35 -0500 Subject: [PATCH 2/6] address coderabbit validation comments --- R/module-statmodel-server.R | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index a2b33f4..843e0ac 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -97,6 +97,16 @@ validate_contrast_inputs = function(input, contrast_mode, condition_list) { validate( need(wt_sum == 0, "The contrast weights should sum up to 0") ) + } else if (contrast_mode == CONSTANTS_STATMODEL$comparison_mode_response_curve) { + x_axis <- input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] + amount <- input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] + + validate( + need(!is.null(x_axis) && trimws(x_axis) != "", + "Please define an X-axis variable"), + need(!is.null(amount) && !is.na(amount), + "Please provide a valid amount") + ) } } @@ -216,18 +226,29 @@ build_all_pair_contrast = function(input, condition_list, contrast, comp_list, r } build_response_curve_matrix = function(input, contrast) { + x_axis <- input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] + amount <- input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] + + if (is.null(x_axis) || trimws(x_axis) == "") { + return(contrast$matrix) + } + + if (is.null(amount) || is.na(amount)) { + return(contrast$matrix) + } + if (is.null(contrast$matrix)) { contrast$matrix = data.frame( Condition = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], - X_axis = input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]], - Amount = input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]], + X_axis = x_axis, + Amount = amount, stringsAsFactors = FALSE ) } else { contrast$matrix = rbind(contrast$matrix, data.frame( Condition = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], - X_axis = input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]], - Amount = input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]], + X_axis = x_axis, + Amount = amount, stringsAsFactors = FALSE )) contrast$matrix = rbind(contrast$matrix[!duplicated(contrast$matrix$Condition),]) From 0ccbcabc988e3a5dab1c676f4971cc1273be1077 Mon Sep 17 00:00:00 2001 From: tonywu1999 Date: Fri, 21 Nov 2025 15:08:38 -0500 Subject: [PATCH 3/6] change condition to group in tables --- R/module-statmodel-server.R | 8 ++++---- tests/testthat/test-utils-statmodel-server.R | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index 843e0ac..4674512 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -76,7 +76,7 @@ render_response_curve_inputs = function(output, session, condition_list) { output[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] = renderUI({ selectInput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_choice), - "Condition:", + "Group:", condition_list() ) }) @@ -239,19 +239,19 @@ build_response_curve_matrix = function(input, contrast) { if (is.null(contrast$matrix)) { contrast$matrix = data.frame( - Condition = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], + GROUP = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], X_axis = x_axis, Amount = amount, stringsAsFactors = FALSE ) } else { contrast$matrix = rbind(contrast$matrix, data.frame( - Condition = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], + GROUP = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], X_axis = x_axis, Amount = amount, stringsAsFactors = FALSE )) - contrast$matrix = rbind(contrast$matrix[!duplicated(contrast$matrix$Condition),]) + contrast$matrix = rbind(contrast$matrix[!duplicated(contrast$matrix$GROUP),]) } return(contrast$matrix) diff --git a/tests/testthat/test-utils-statmodel-server.R b/tests/testthat/test-utils-statmodel-server.R index e5d0284..fa97240 100644 --- a/tests/testthat/test-utils-statmodel-server.R +++ b/tests/testthat/test-utils-statmodel-server.R @@ -388,7 +388,7 @@ test_that("build_response_curve_matrix when contrast$matrix is NULL", { expect_equal(nrow(result), 1) expect_equal(ncol(result), 3) - expect_equal(result$Condition, "Control") + expect_equal(result$GROUP, "Control") expect_equal(result$X_axis, "Dose") expect_equal(result$Amount, 0) }) @@ -401,7 +401,7 @@ test_that("build_response_curve_matrix appends row to existing response matrix", contrast <- list( matrix = data.frame( - Condition = "Control", + GROUP = "Control", X_axis = "Time", Amount = 0, stringsAsFactors = FALSE @@ -411,7 +411,7 @@ test_that("build_response_curve_matrix appends row to existing response matrix", result <- build_response_curve_matrix(input, contrast) expect_equal(nrow(result), 2) - expect_equal(result$Condition[2], "T5") + expect_equal(result$GROUP[2], "T5") expect_equal(result$X_axis[2], "Time") expect_equal(result$Amount[2], 5) }) @@ -424,7 +424,7 @@ test_that("build_response_curve_matrix removes duplicate conditions in response contrast <- list( matrix = data.frame( - Condition = c("Control", "T15"), + GROUP = c("Control", "T15"), X_axis = c("Time", "Time"), Amount = c(0, 15), stringsAsFactors = FALSE @@ -434,7 +434,7 @@ test_that("build_response_curve_matrix removes duplicate conditions in response result <- build_response_curve_matrix(input, contrast) expect_equal(nrow(result), 2) - control_row <- result[result$Condition == "Control", ] + control_row <- result[result$GROUP == "Control", ] expect_equal(control_row$X_axis, "Time") expect_equal(control_row$Amount, 0) }) @@ -447,7 +447,7 @@ test_that("build_response_curve_matrix handles multiple unique x-axes correctly" contrast <- list( matrix = data.frame( - Condition = c("Group_A", "Group_B"), + GROUP = c("Group_A", "Group_B"), X_axis = c("Temperature", "Pressure"), Amount = c(25, 100), stringsAsFactors = FALSE @@ -457,5 +457,5 @@ test_that("build_response_curve_matrix handles multiple unique x-axes correctly" result <- build_response_curve_matrix(input, contrast) expect_equal(nrow(result), 3) - expect_true(all(c("Group_A", "Group_B", "Group_C") %in% result$Condition)) + expect_true(all(c("Group_A", "Group_B", "Group_C") %in% result$GROUP)) }) \ No newline at end of file From 0dc9021132c90f6beb4e0854bf5be52ed8f0eb43 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 1 Dec 2025 18:43:10 -0500 Subject: [PATCH 4/6] set up default parsing from MSstatsResponse --- NAMESPACE | 1 + R/module-statmodel-server.R | 36 ++------ R/statmodel-ui-comparisons.R | 7 +- .../test-statmodel-ui-options-contrasts.R | 7 +- tests/testthat/test-utils-statmodel-server.R | 84 ++----------------- 5 files changed, 16 insertions(+), 119 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 9e72d74..f61c14a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -48,6 +48,7 @@ importFrom(MSstatsPTM,SkylinetoMSstatsPTMFormat) importFrom(MSstatsPTM,SpectronauttoMSstatsPTMFormat) importFrom(MSstatsPTM,dataProcessPlotsPTM) importFrom(MSstatsPTM,groupComparisonPlotsPTM) +importFrom(MSstatsResponse,convertGroupToNumericDose) importFrom(arrow,read_parquet) importFrom(data.table,copy) importFrom(dplyr,`%>%`) diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index 4674512..1b35263 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -225,35 +225,10 @@ build_all_pair_contrast = function(input, condition_list, contrast, comp_list, r return(contrast$matrix) } -build_response_curve_matrix = function(input, contrast) { - x_axis <- input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] - amount <- input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] - - if (is.null(x_axis) || trimws(x_axis) == "") { - return(contrast$matrix) - } - - if (is.null(amount) || is.na(amount)) { - return(contrast$matrix) - } - - if (is.null(contrast$matrix)) { - contrast$matrix = data.frame( - GROUP = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], - X_axis = x_axis, - Amount = amount, - stringsAsFactors = FALSE - ) - } else { - contrast$matrix = rbind(contrast$matrix, data.frame( - GROUP = input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]], - X_axis = x_axis, - Amount = amount, - stringsAsFactors = FALSE - )) - contrast$matrix = rbind(contrast$matrix[!duplicated(contrast$matrix$GROUP),]) - } - +#' @importFrom MSstatsResponse convertGroupToNumericDose +build_response_curve_matrix = function(contrast, condition_list) { + condition_to_metadata_table = convertGroupToNumericDose(condition_list) + contrast$matrix = data.frame(GROUP = condition_list, condition_to_metadata_table) return(contrast$matrix) } @@ -522,7 +497,6 @@ statmodelServer = function(id, parent_session, loadpage_input, qc_input, render_all_against_one_inputs(output, session, condition_list) render_custom_pairwise_inputs(output, session, condition_list) render_custom_non_pairwise_inputs(output, session, condition_list) - render_response_curve_inputs(output, session, condition_list) Rownames = eventReactive(input[[NAMESPACE_STATMODEL$comparisons_submit]], { req(input[[NAMESPACE_STATMODEL$comparison_mode]]) @@ -567,7 +541,7 @@ statmodelServer = function(id, parent_session, loadpage_input, qc_input, input, condition_list(), contrast, comp_list, row(), loadpage_input()) } else if (input[[NAMESPACE_STATMODEL$comparison_mode]] == CONSTANTS_STATMODEL$comparison_mode_response_curve) { contrast$matrix = build_response_curve_matrix( - input, contrast) + contrast, condition_list()) } enable("calculate") diff --git a/R/statmodel-ui-comparisons.R b/R/statmodel-ui-comparisons.R index d4ba098..9df89b7 100644 --- a/R/statmodel-ui-comparisons.R +++ b/R/statmodel-ui-comparisons.R @@ -86,10 +86,7 @@ build_custom_nonpairwise_panel <- function(ns) { build_response_curve_panel <- function(ns) { tagList( h5("Set up response curve configuration:"), - uiOutput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_choice)), - textInput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_xaxis), "X-Axis Label:", placeholder = "e.g., Dosage, Time"), - numericInput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_amount), "Response:", value = NULL, step = 0.1), - actionButton(ns(NAMESPACE_STATMODEL$comparisons_submit), "Add Entry"), - actionButton(ns(NAMESPACE_STATMODEL$comparisons_clear), "Clear All Data") + actionButton(ns(NAMESPACE_STATMODEL$comparisons_submit), "Setup Metadata"), + actionButton(ns(NAMESPACE_STATMODEL$comparisons_clear), "Reset") ) } \ No newline at end of file diff --git a/tests/testthat/test-statmodel-ui-options-contrasts.R b/tests/testthat/test-statmodel-ui-options-contrasts.R index ee93e24..4f870fb 100644 --- a/tests/testthat/test-statmodel-ui-options-contrasts.R +++ b/tests/testthat/test-statmodel-ui-options-contrasts.R @@ -59,13 +59,8 @@ test_that("build_response_curve_panel creates correct UI structure", { ui <- build_response_curve_panel(ns) html <- as.character(ui) expect_true(grepl("
Set up response curve configuration:
", html, fixed = TRUE)) - expect_true(grepl(NAMESPACE_STATMODEL$comparisons_response_curve_choice, html, fixed = TRUE)) - expect_true(grepl(NAMESPACE_STATMODEL$comparisons_response_curve_xaxis, html, fixed = TRUE)) - expect_true(grepl(NAMESPACE_STATMODEL$comparisons_response_curve_amount, html, fixed = TRUE)) expect_true(grepl(NAMESPACE_STATMODEL$comparisons_submit, html, fixed = TRUE)) expect_true(grepl(NAMESPACE_STATMODEL$comparisons_clear, html, fixed = TRUE)) - expect_true(grepl(">Add Entry<", html, fixed = TRUE)) - expect_true(grepl(">Clear All Data<", html, fixed = TRUE)) expect_s3_class(ui, "shiny.tag.list") - expect_length(ui, 6) + expect_length(ui, 3) }) \ No newline at end of file diff --git a/tests/testthat/test-utils-statmodel-server.R b/tests/testthat/test-utils-statmodel-server.R index fa97240..86a34cd 100644 --- a/tests/testthat/test-utils-statmodel-server.R +++ b/tests/testthat/test-utils-statmodel-server.R @@ -377,85 +377,15 @@ test_that("get_contrast_panel_ui returns correct UI for each mode", { }) -test_that("build_response_curve_matrix when contrast$matrix is NULL", { - input <- list() - input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] <- "Control" - input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] <- "Dose" - input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] <- 0 +test_that("build_response_curve_matrix returns correct columns", { + condition_list = c("Dasatinib_001nM", "Dasatinib_001uM", "DMSO") contrast <- list(matrix = NULL) - result <- build_response_curve_matrix(input, contrast) - - expect_equal(nrow(result), 1) - expect_equal(ncol(result), 3) - expect_equal(result$GROUP, "Control") - expect_equal(result$X_axis, "Dose") - expect_equal(result$Amount, 0) -}) - -test_that("build_response_curve_matrix appends row to existing response matrix", { - input <- list() - input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] <- "T5" - input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] <- "Time" - input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] <- 5 - - contrast <- list( - matrix = data.frame( - GROUP = "Control", - X_axis = "Time", - Amount = 0, - stringsAsFactors = FALSE - ) - ) - - result <- build_response_curve_matrix(input, contrast) - - expect_equal(nrow(result), 2) - expect_equal(result$GROUP[2], "T5") - expect_equal(result$X_axis[2], "Time") - expect_equal(result$Amount[2], 5) -}) - -test_that("build_response_curve_matrix removes duplicate conditions in response matrix, keep first occurrence", { - input <- list() - input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] <- "Control" - input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] <- "Time" - input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] <- 1 - - contrast <- list( - matrix = data.frame( - GROUP = c("Control", "T15"), - X_axis = c("Time", "Time"), - Amount = c(0, 15), - stringsAsFactors = FALSE - ) - ) - - result <- build_response_curve_matrix(input, contrast) - - expect_equal(nrow(result), 2) - control_row <- result[result$GROUP == "Control", ] - expect_equal(control_row$X_axis, "Time") - expect_equal(control_row$Amount, 0) -}) - -test_that("build_response_curve_matrix handles multiple unique x-axes correctly", { - input <- list() - input[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] <- "Group_C" - input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] <- "pH" - input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] <- 7.5 - - contrast <- list( - matrix = data.frame( - GROUP = c("Group_A", "Group_B"), - X_axis = c("Temperature", "Pressure"), - Amount = c(25, 100), - stringsAsFactors = FALSE - ) - ) - - result <- build_response_curve_matrix(input, contrast) + result <- build_response_curve_matrix(contrast, condition_list) expect_equal(nrow(result), 3) - expect_true(all(c("Group_A", "Group_B", "Group_C") %in% result$GROUP)) + expect_equal(ncol(result), 3) + expect_true("GROUP" %in% colnames(result)) + expect_true("drug" %in% colnames(result)) + expect_true("dose_nM" %in% colnames(result)) }) \ No newline at end of file From 732e5f497ce2cfe0dae89067445752803cb86322 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 1 Dec 2025 19:00:26 -0500 Subject: [PATCH 5/6] add description file --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 88e82c2..abdfb0d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -27,7 +27,7 @@ Depends: R (>= 4.2) Imports: shiny, shinyBS, shinyjs, shinybusy, dplyr, ggplot2, plotly, data.table, Hmisc, MSstats, MSstatsTMT, MSstatsPTM, MSstatsConvert, gplots, marray, DT, readxl, ggrepel, uuid, utils, stats, htmltools, methods, tidyr, grDevices, graphics, mockery, MSstatsBioNet, - shinydashboard, arrow, tools + shinydashboard, arrow, tools, MSstatsResponse Suggests: rmarkdown, tinytest, From 4ce844f6594adc1a9cbba4cfb32b14f43b538d15 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 1 Dec 2025 19:03:36 -0500 Subject: [PATCH 6/6] remove dead code --- R/constants.R | 5 +---- R/module-statmodel-server.R | 21 --------------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/R/constants.R b/R/constants.R index d4b8c45..3385c1c 100644 --- a/R/constants.R +++ b/R/constants.R @@ -8,10 +8,7 @@ NAMESPACE_STATMODEL = list( comparisons_custom_pairwise_choice2 = "comparisons_custom_pairwise_choice2", comparisons_all_vs_one_choice = "comparisons_all_vs_one_choice", comparisons_custom_nonpairwise_name = "comparisons_custom_nonpairwise_name", - comparisons_custom_nonpairwise_weights = "comparisons_custom_nonpairwise_weights", - comparisons_response_curve_choice = "comparisons_response_curve_choice", - comparisons_response_curve_xaxis = "comparisons_response_curve_xaxis", - comparisons_response_curve_amount = "comparisons_response_curve_amount" + comparisons_custom_nonpairwise_weights = "comparisons_custom_nonpairwise_weights" ) CONSTANTS_STATMODEL = list( diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index 1b35263..5dd9b57 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -71,17 +71,6 @@ render_custom_non_pairwise_inputs = function(output, session, condition_list) { }) } -render_response_curve_inputs = function(output, session, condition_list) { - ns = session$ns - - output[[NAMESPACE_STATMODEL$comparisons_response_curve_choice]] = renderUI({ - selectInput(ns(NAMESPACE_STATMODEL$comparisons_response_curve_choice), - "Group:", - condition_list() - ) - }) -} - # Todo: Add helper function to render dose response curve inputs validate_contrast_inputs = function(input, contrast_mode, condition_list) { @@ -97,16 +86,6 @@ validate_contrast_inputs = function(input, contrast_mode, condition_list) { validate( need(wt_sum == 0, "The contrast weights should sum up to 0") ) - } else if (contrast_mode == CONSTANTS_STATMODEL$comparison_mode_response_curve) { - x_axis <- input[[NAMESPACE_STATMODEL$comparisons_response_curve_xaxis]] - amount <- input[[NAMESPACE_STATMODEL$comparisons_response_curve_amount]] - - validate( - need(!is.null(x_axis) && trimws(x_axis) != "", - "Please define an X-axis variable"), - need(!is.null(amount) && !is.na(amount), - "Please provide a valid amount") - ) } }