From 461d93babfe1b4848ddcd813b844b77b66f0cced Mon Sep 17 00:00:00 2001 From: tonywu1999 Date: Thu, 16 Apr 2026 15:36:36 -0400 Subject: [PATCH 1/8] fix(vignette): Turn off nM to M conversion in vignette --- vignettes/MSstatsResponse.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/MSstatsResponse.Rmd b/vignettes/MSstatsResponse.Rmd index 0e1a3c6..e6041e6 100644 --- a/vignettes/MSstatsResponse.Rmd +++ b/vignettes/MSstatsResponse.Rmd @@ -162,7 +162,7 @@ dia_prepared <- MSstatsPrepareDoseResponseFit( drug_column = "drug", protein_column = "Protein", log_abundance_column = "LogIntensities", - transform_nM_to_M = TRUE + transform_nM_to_M = FALSE ) # Examine prepared data structure From 3130791a2ed3b19dc6e146205afb540f3194cd4d Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Fri, 17 Apr 2026 11:24:46 -0400 Subject: [PATCH 2/8] update manuals devtools document --- NAMESPACE | 5 ++- man/calculatePeptideWeights.Rd | 73 ++++++++++++++++++++++++++++++++++ man/doseResponseFit.Rd | 1 - man/selectTopNPeptides.Rd | 27 ------------- 4 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 man/calculatePeptideWeights.Rd delete mode 100644 man/selectTopNPeptides.Rd diff --git a/NAMESPACE b/NAMESPACE index 8b0e171..086b554 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand export(MSstatsPrepareDoseResponseFit) +export(calculatePeptideWeights) export(calculateTurnoverRatios) export(convertGroupToNumericDose) export(doseResponseFit) @@ -8,13 +9,14 @@ export(futureExperimentSimulation) export(plot_tpr_power_curve) export(predictIC50) export(predictIC50Parallel) -export(selectTopNPeptides) export(run_tpr_simulation) export(visualizeResponseProtein) import(dplyr) importFrom(BiocParallel,bplapply) importFrom(BiocParallel,bpparam) importFrom(data.table,rbindlist) +importFrom(dplyr,across) +importFrom(dplyr,all_of) importFrom(dplyr,arrange) importFrom(dplyr,distinct) importFrom(dplyr,filter) @@ -55,6 +57,7 @@ importFrom(parallel,stopCluster) importFrom(plotly,ggplotly) importFrom(plotly,layout) importFrom(stats,approx) +importFrom(stats,cor) importFrom(stats,p.adjust) importFrom(stats,pf) importFrom(stats,quantile) diff --git a/man/calculatePeptideWeights.Rd b/man/calculatePeptideWeights.Rd new file mode 100644 index 0000000..57a8aa0 --- /dev/null +++ b/man/calculatePeptideWeights.Rd @@ -0,0 +1,73 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/protein_turnover_ratio_helper.R +\name{calculatePeptideWeights} +\alias{calculatePeptideWeights} +\title{Calculate quality-based weights for peptide measurements} +\usage{ +calculatePeptideWeights( + data, + protein_col = "Protein", + peptide_col = "BaseSequence", + time_col = "TimeVal", + response_col = "H_frac", + light_intensity_col = "Light", + validity_threshold = 1.3, + top_n_peptides = NULL +) +} +\arguments{ +\item{data}{Data frame with peptide-level measurements (output from calculateTurnoverRatios)} + +\item{protein_col}{Character. Column containing protein identifiers. Default = "Protein"} + +\item{peptide_col}{Character. Column containing peptide identifiers. Default = "BaseSequence"} + +\item{time_col}{Character. Column containing timepoint values. Default = "TimeVal"} + +\item{response_col}{Character. Column containing response values (e.g., H_frac). Default = "H_frac"} + +\item{light_intensity_col}{Character. Column containing light channel intensity. Default = "Light"} + +\item{validity_threshold}{Numeric. Maximum allowed response value. Default = 1.3} + +\item{top_n_peptides}{Numeric. Top n peptides based on median light channel intensity. If NULL, no filtering (all get weight 1).} +} +\value{ +Input data frame with added columns: +\itemize{ +\item n_obs: Number of observations for this peptide +\item coverage_score: Proportion of timepoints observed +\item light_intensity_score: Normalized median light intensity (per protein) +\item monotonicity_score: Kendall correlation (time vs response), 0 if decreasing +\item validity_flag: 0 if any invalid values, 1 otherwise +\item weight: Combined quality weight (product of all components) +} +} +\description{ +Calculates weights based on coverage, signal intensity, monotonicity, and data validity. +Designed for protein turnover data but applicable to any dose/time-response data. +} +\examples{ +# Calculate ratios first +ratios <- calculateTurnoverRatios(feature_data) + +# Add quality weights +ratios_weighted <- calculatePeptideWeights(ratios) + +# Inspect weights +ratios_weighted \%>\% + group_by(Protein, BaseSequence) \%>\% + slice(1) \%>\% + select(Protein, BaseSequence, coverage_score, monotonicity_score, weight) + +# Use with doseResponseFit +result <- doseResponseFit( + data = ratios_weighted, + weights = ratios_weighted$weight, + increasing = TRUE +) + +# Use stricter validity threshold +ratios_weighted_strict <- calculatePeptideWeights(ratios, validity_threshold = 1.0) + +} diff --git a/man/doseResponseFit.Rd b/man/doseResponseFit.Rd index c5db8a8..f426c61 100644 --- a/man/doseResponseFit.Rd +++ b/man/doseResponseFit.Rd @@ -94,7 +94,6 @@ interaction_results_precalc <- doseResponseFit( precalculated_ratios = TRUE ) - \dontrun{ # Example 4: Full dataset analysis full_results <- doseResponseFit( diff --git a/man/selectTopNPeptides.Rd b/man/selectTopNPeptides.Rd deleted file mode 100644 index 6e3bbb4..0000000 --- a/man/selectTopNPeptides.Rd +++ /dev/null @@ -1,27 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/protein_turnover_ratio_helper.R -\name{selectTopNPeptides} -\alias{selectTopNPeptides} -\title{Example peptide selector: Top N by total signal} -\usage{ -selectTopNPeptides(df, n = 10) -} -\arguments{ -\item{df}{Data frame with BaseSequence and Intensity columns (for one protein)} - -\item{n}{Number of top peptides to select} -} -\value{ -Filtered data frame -} -\description{ -Example peptide selector: Top N by total signal -} -\examples{ -# Use as peptide_selector -ratios <- calculateTurnoverRatios( - feature_data = quant_data$FeatureLevelData, - peptide_selector = function(df) selectTopNPeptides(df, n = 10) -) - -} From 1875459d88963578226955f6f4dc0c7db40ab1b2 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 20 Apr 2026 12:39:00 -0400 Subject: [PATCH 3/8] fix unit tests by adding precaclualted ratios = false --- tests/testthat/test-IC50_prediction.R | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/testthat/test-IC50_prediction.R b/tests/testthat/test-IC50_prediction.R index 39bd6d0..132aefd 100644 --- a/tests/testthat/test-IC50_prediction.R +++ b/tests/testthat/test-IC50_prediction.R @@ -191,7 +191,8 @@ test_that(".calcSingleIC50 handles single protein-drug pair", { bootstrap = FALSE, prot = "TestProtein", drug_type = "TestDrug", - target_response = 0.5 + target_response = 0.5, + precalculated_ratios = FALSE ) expect_s3_class(result, "data.frame") @@ -217,7 +218,8 @@ test_that(".calcSingleIC50 handles bootstrap option", { bootstrap = FALSE, prot = "P1", drug_type = "D1", - target_response = 0.5 + target_response = 0.5, + precalculated_ratios = FALSE ) expect_true(is.na(result_no_boot$IC50_lower_bound)) @@ -234,7 +236,8 @@ test_that(".calcSingleIC50 handles bootstrap option", { bootstrap = TRUE, prot = "P1", drug_type = "D1", - target_response = 0.5 + target_response = 0.5, + precalculated_ratios = FALSE ) expect_false(is.na(result_boot$IC50_lower_bound)) @@ -257,7 +260,8 @@ test_that(".calcSingleIC50 handles ratio vs log scale", { bootstrap = FALSE, prot = "P1", drug_type = "D1", - target_response = 0.5 + target_response = 0.5, + precalculated_ratios = FALSE ) result_log <- .calcSingleIC50( @@ -270,7 +274,8 @@ test_that(".calcSingleIC50 handles ratio vs log scale", { bootstrap = FALSE, prot = "P1", drug_type = "D1", - target_response = 0.5 + target_response = 0.5, + precalculated_ratios = FALSE ) # Results should be different @@ -295,7 +300,8 @@ test_that(".calcSingleIC50 handles failed fits", { bootstrap = FALSE, prot = "P1", drug_type = "D1", - target_response = 0.5 + target_response = 0.5, + precalculated_ratios = FALSE ) }) From 2961aebbca52df7f8cf9329d93ace8a11ce6a32d Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 20 Apr 2026 12:39:59 -0400 Subject: [PATCH 4/8] add direction as a column in unit tests --- tests/testthat/test-IC50_prediction.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-IC50_prediction.R b/tests/testthat/test-IC50_prediction.R index 132aefd..59a49b4 100644 --- a/tests/testthat/test-IC50_prediction.R +++ b/tests/testthat/test-IC50_prediction.R @@ -196,7 +196,7 @@ test_that(".calcSingleIC50 handles single protein-drug pair", { ) expect_s3_class(result, "data.frame") - expect_named(result, c("protein", "drug", "IC50", "IC50_lower_bound", "IC50_upper_bound")) + expect_named(result, c("protein", "drug", "IC50", "IC50_lower_bound", "IC50_upper_bound", "direction")) expect_equal(result$protein, "TestProtein") expect_equal(result$drug, "TestDrug") }) From 7aee9bd3da82de3eace229ef7e6dfe6d39529079 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 20 Apr 2026 12:41:30 -0400 Subject: [PATCH 5/8] fix tets --- tests/testthat/test-PredictIC50.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-PredictIC50.R b/tests/testthat/test-PredictIC50.R index 0a20790..7f24abd 100644 --- a/tests/testthat/test-PredictIC50.R +++ b/tests/testthat/test-PredictIC50.R @@ -34,7 +34,7 @@ test_that("predictIC50 returns correct structure", { }) expect_s3_class(results, "data.frame") - expect_named(results, c("protein", "drug", "IC50", "IC50_lower_bound", "IC50_upper_bound")) + expect_named(results, c("protein", "drug", "IC50", "IC50_lower_bound", "IC50_upper_bound", "direction")) expect_equal(nrow(results), 3) # 3 proteins }) From a468b81b9f39e5a46a74c34f7bda017994909a28 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 20 Apr 2026 13:19:01 -0400 Subject: [PATCH 6/8] dont run examples for turnover yet --- R/protein_turnover_ratio_helper.R | 4 ++++ man/calculatePeptideWeights.Rd | 2 ++ man/calculateTurnoverRatios.Rd | 2 ++ 3 files changed, 8 insertions(+) diff --git a/R/protein_turnover_ratio_helper.R b/R/protein_turnover_ratio_helper.R index 5829249..23cd28e 100644 --- a/R/protein_turnover_ratio_helper.R +++ b/R/protein_turnover_ratio_helper.R @@ -21,6 +21,7 @@ #' @return Data frame with columns: Protein, BaseSequence, TimeVal, Run, Heavy, Light, Total, H_frac, L_frac #' #' @examples +#' \dontrun{ #' # Basic usage - all proteins, all peptides #' ratios <- calculateTurnoverRatios( #' feature_data = quant_data$FeatureLevelData @@ -59,6 +60,7 @@ #' #' # Filter for specific protein after calculation #' protein_ratios <- ratios %>% filter(Protein == "A0A2K5TXF6") +#' } #' #' @export #' @importFrom dplyr filter mutate group_by summarise arrange slice_head pull ungroup select rename @@ -205,6 +207,7 @@ parse_timepoint <- function(time_strings) { #' - weight: Combined quality weight (product of all components) #' #' @examples +#' \dontrun{ #' # Calculate ratios first #' ratios <- calculateTurnoverRatios(feature_data) #' @@ -226,6 +229,7 @@ parse_timepoint <- function(time_strings) { #' #' # Use stricter validity threshold #' ratios_weighted_strict <- calculatePeptideWeights(ratios, validity_threshold = 1.0) +#' } #' #' @export #' @importFrom dplyr group_by mutate ungroup across all_of diff --git a/man/calculatePeptideWeights.Rd b/man/calculatePeptideWeights.Rd index 57a8aa0..f0c8f67 100644 --- a/man/calculatePeptideWeights.Rd +++ b/man/calculatePeptideWeights.Rd @@ -48,6 +48,7 @@ Calculates weights based on coverage, signal intensity, monotonicity, and data v Designed for protein turnover data but applicable to any dose/time-response data. } \examples{ +\dontrun{ # Calculate ratios first ratios <- calculateTurnoverRatios(feature_data) @@ -69,5 +70,6 @@ result <- doseResponseFit( # Use stricter validity threshold ratios_weighted_strict <- calculatePeptideWeights(ratios, validity_threshold = 1.0) +} } diff --git a/man/calculateTurnoverRatios.Rd b/man/calculateTurnoverRatios.Rd index 67e47a3..15ece21 100644 --- a/man/calculateTurnoverRatios.Rd +++ b/man/calculateTurnoverRatios.Rd @@ -58,6 +58,7 @@ Data frame with columns: Protein, BaseSequence, TimeVal, Run, Heavy, Light, Tota Calculate turnover ratios from MSstats FeatureLevelData } \examples{ +\dontrun{ # Basic usage - all proteins, all peptides ratios <- calculateTurnoverRatios( feature_data = quant_data$FeatureLevelData @@ -96,5 +97,6 @@ ratios_norm <- calculateTurnoverRatios( # Filter for specific protein after calculation protein_ratios <- ratios \%>\% filter(Protein == "A0A2K5TXF6") +} } From 47bc565c3eeb6d670db8a926f1927450a706da5d Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 20 Apr 2026 13:36:40 -0400 Subject: [PATCH 7/8] fix docs for parsing timepoints --- R/protein_turnover_ratio_helper.R | 2 +- man/parse_timepoint.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/protein_turnover_ratio_helper.R b/R/protein_turnover_ratio_helper.R index 23cd28e..2be9f0c 100644 --- a/R/protein_turnover_ratio_helper.R +++ b/R/protein_turnover_ratio_helper.R @@ -165,7 +165,7 @@ calculateTurnoverRatios <- function( #' @return Numeric vector of hours #' #' @examples -#' parse_timepoint(c("0hr", "1hr", "12hrs", "168hrs")) +#' MSstatsResponse:::parse_timepoint(c("0hr", "1hr", "12hrs", "168hrs")) #' # Returns: 0 1 12 168 #' #' @keywords internal diff --git a/man/parse_timepoint.Rd b/man/parse_timepoint.Rd index aa73b64..f24f5a8 100644 --- a/man/parse_timepoint.Rd +++ b/man/parse_timepoint.Rd @@ -16,7 +16,7 @@ Numeric vector of hours Parse timepoint strings to numeric hours } \examples{ -parse_timepoint(c("0hr", "1hr", "12hrs", "168hrs")) +MSstatsResponse:::parse_timepoint(c("0hr", "1hr", "12hrs", "168hrs")) # Returns: 0 1 12 168 } From 2831320d0641c836abd53f8d61fab98e0d2c74cf Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Mon, 20 Apr 2026 13:45:56 -0400 Subject: [PATCH 8/8] dont run visualize proteins for the turnover cas --- R/Visualize_Isotonic_Fit.R | 2 ++ man/visualizeResponseProtein.Rd | 2 ++ 2 files changed, 4 insertions(+) diff --git a/R/Visualize_Isotonic_Fit.R b/R/Visualize_Isotonic_Fit.R index d0376e6..a6e7639 100644 --- a/R/Visualize_Isotonic_Fit.R +++ b/R/Visualize_Isotonic_Fit.R @@ -65,6 +65,7 @@ #' print(plot2) #' #' # Example 3: Color points by replicate +#' \dontrun{ #' plot3 <- visualizeResponseProtein( #' data = prepared_data, #' protein_name = "PROTEIN_A", @@ -74,6 +75,7 @@ #' color_by = "replicate" #' ) #' print(plot3) +#' } #' #' @export visualizeResponseProtein = function(data, diff --git a/man/visualizeResponseProtein.Rd b/man/visualizeResponseProtein.Rd index c0e6dd3..9095e67 100644 --- a/man/visualizeResponseProtein.Rd +++ b/man/visualizeResponseProtein.Rd @@ -108,6 +108,7 @@ plot2 <- visualizeResponseProtein( print(plot2) # Example 3: Color points by replicate +\dontrun{ plot3 <- visualizeResponseProtein( data = prepared_data, protein_name = "PROTEIN_A", @@ -117,5 +118,6 @@ plot3 <- visualizeResponseProtein( color_by = "replicate" ) print(plot3) +} }