Mercurial > repos > galaxyp > pmd_fdr
view PMD_FDR_package_for_Galaxy.R @ 1:460edeedeb7d draft default tip
"planemo upload for repository https://github.com/galaxyproteomics/tools-galaxyp/tree/master/tools/pmd_fdr commit d87c44ec8fd5bc03d7bb06f65a1a6ec247daee36"
author | galaxyp |
---|---|
date | Thu, 10 Oct 2019 17:29:37 -0400 |
parents | 5cc0c32d05a2 |
children |
line wrap: on
line source
############################################################################### # PMD_FDR_package_for_Galaxy.R # # # # Project 021 - PMD-FDR for Galaxy-P # # # # Description: Computes iFDR and gFDR on PSMs as a script designed for Galaxy # # Note that plotting code has been left in that is not used # # in this file; this is the code I used to create figures for # # publication. I left it in for potential development of views. # # # # This file was created by concatenating the following files: # # # # A - 005 - Parser - ArgParser.R # # B - 019 - PMD-FDR - functions.R # # C - 021 - PMD-FDR Wrapper - functions.R # # D - 021 - PMD-FDR Main.R # # # # Required packages: argparser # # stringr # # RUnit # # # # Release date: 2019-10-05 # # Version: 1.4 # # # ############################################################################### # Package currently supports the following parameters: # # --psm_report full name and path to the PSM report # --psm_report_1_percent full name and path to the PSM report for 1% FDR # --output_i_fdr full name and path to the i-FDR output file # --output_g_fdr full name and path to the g-FDR output file # --output_densities full name and path to the densities output file # ############################################################################### # A - 005 - Parser - ArgParser.R # # # # Description: Wrapper for argparser package, using RefClass # # # ############################################################################### #install.packages("argparser") library(argparser) # Class definition ArgParser <- setRefClass("ArgParser", fields = c("parser")) ArgParser$methods( initialize = function(...){ parser <<- arg_parser(...) }, local_add_argument = function(...){ parser <<- add_argument(parser, ...) }, parse_arguments = function(...){ result = parse_args(parser, ...) return(result) } ) ############################################################################### # B - 019 - PMD-FDR - functions.R # # # # Primary work-horse for PMD-FDR # # # ############################################################################### ############################################################################### ####### Load libraries etc. ############################################################################### library(stringr) library(RUnit) ############################################################# ####### Global values (should be parameters to module but aren't yet) ############################################################# MIN_GOOD_PEPTIDE_LENGTH <- 11 MIN_ACCEPTABLE_POINTS_IN_DENSITY <- 10 ############################################################# ####### General purpose functions ############################################################# # Creates a more useful error report when file is not reasonable safe_file_exists <- function(file_path){ # Still not particularly useful in cases where it is a valid directory tryCatch( return(file_test(op = "-f", x=file_path)), error=function(e) {simpleError(sprintf("file path is not valid: '%s'", file_path))} ) } # My standard way of loading data into data.frames load_standard_df <- function(file_path=NULL){ clean_field_names = function(field_names){ result <- field_names idx_blank <- which(result == "") result[idx_blank] <- sprintf("<Field %d>", idx_blank) return(result) } if (safe_file_exists(file_path)){ field_names <- read_field_names(file_path, sep = "\t") field_names <- clean_field_names(field_names) if (length(field_names) == 0){ return(data.frame()) } data <- read.table(file = file_path, header = TRUE, sep = "\t", stringsAsFactors = FALSE, blank.lines.skip = TRUE)#, check.names = FALSE) colnames(data) = field_names } else { stop(sprintf("File path does not exist: '%s'", file_path)) } return(data) } save_standard_df <- function(x=NULL, file_path=NULL){ if (file_path != ""){ write.table(x = x, file = file_path, quote = FALSE, sep = "\t", row.names = FALSE, col.names = TRUE) } } rename_column <- function(df=NULL, name_before=NULL, name_after=NULL, suppressWarnings=FALSE){ if (is.null(df)){ stop("Dataframe (df) does not exist - unable to rename column") } if (name_before %in% colnames(df)){ df[,name_after] <- df[,name_before] df[,name_before] <- NULL } else if (!suppressWarnings){ warning(sprintf("'%s' is not a field in the data frame and so has not been renamed", name_before)) } return(df) } rename_columns <- function(df=NULL, names_before=NULL, names_after=NULL){ for (i in safe_iterator(length(names_before))){ df <- rename_column(df, names_before[i], names_after[i]) } return(df) } round_to_tolerance <- function(x=NULL, tolerance=NULL, ...){ return(function_to_tolerance(x=x, tolerance=tolerance, FUN=round, ...)) } function_to_tolerance <- function(x=NULL, tolerance=NULL, FUN=NULL, ...){ return(FUN(x/tolerance, ...) * tolerance) } safe_median <- function(x) median(x, na.rm=TRUE) normalize_density <- function(d){ # Normalizes y-values in density function # so that the integral under the curve is 1 # (uses rectangles to approximate area) delta_x <- diff(range(d$x)) / length(d$x) unnormalized_integral <- delta_x * sum(d$y) new_d <- d new_d$y <- with(new_d, y ) return(new_d) } if_null <- function(cond=NULL, null_result=NULL, not_null_result=NULL){ return(switch(1+is.null(cond), not_null_result, null_result)) } rainbow_with_fixed_intensity <- function(n=NULL, goal_intensity_0_1=NULL, alpha=NULL){ goal_intensity <- 255*goal_intensity_0_1 hex_colors <- rainbow(n) rgb_colors <- col2rgb(hex_colors) df_colors <- data.frame(t(rgb_colors)) df_colors$intensity <- with(df_colors, 0.2989*red + 0.5870*green + 0.1140*blue) df_colors$white_black <- with(df_colors, ifelse(intensity < goal_intensity, 255, 0)) df_colors$mix_level <- with(df_colors, (white_black - goal_intensity) / (white_black - intensity ) ) df_colors$new_red <- with(df_colors, mix_level*red + (1-mix_level)*white_black) df_colors$new_green <- with(df_colors, mix_level*green + (1-mix_level)*white_black) df_colors$new_blue <- with(df_colors, mix_level*blue + (1-mix_level)*white_black) names_pref_new <- c("new_red", "new_green", "new_blue") names_no_pref <- c("red", "green", "blue") df_colors <- df_colors[,names_pref_new] df_colors <- rename_columns(df_colors, names_before = names_pref_new, names_after = names_no_pref) rgb_colors <-as.matrix(df_colors/255 ) return(rgb(rgb_colors, alpha=alpha)) } safe_iterator <- function(n_steps = NULL){ if (n_steps < 1){ result = numeric(0) } else { result = 1:n_steps } return(result) } col2hex <- function(cols=NULL, col_alpha=255){ if (all(col_alpha<=1)){ col_alpha <- round(col_alpha*255) } col_matrix <- t(col2rgb(cols)) results <- rgb(col_matrix, alpha=col_alpha, maxColorValue = 255) return(results) } credible_interval <- function(x=NULL, N=NULL, precision=0.001, alpha=0.05){ # Approximates "highest posterior density interval" # Uses exact binomial but with a finite list of potential values (1/precision) p <- seq(from=0, to=1, by=precision) d <- dbinom(x = x, size = N, prob = p) d <- d / sum(d) df <- data.frame(p=p, d=d) df <- df[order(-df$d),] df$cumsum <- cumsum(df$d) max_idx <- sum(df$cumsum < (1-alpha)) + 1 max_idx <- min(max_idx, nrow(df)) lower <- min(df$p[1:max_idx]) upper <- max(df$p[1:max_idx]) return(c(lower,upper)) } verified_element_of_list <- function(parent_list=NULL, element_name=NULL, object_name=NULL){ if (is.null(parent_list[[element_name]])){ if (is.null(object_name)){ object_name = "the list" } stop(sprintf("Element '%s' does not yet exist in %s", element_name, object_name)) } return(parent_list[[element_name]]) } read_field_names = function(file_path=NULL, sep = "\t"){ con = file(file_path,"r") fields = readLines(con, n=1) close(con) if (length(fields) == 0){ return(c()) } fields = strsplit(x = fields, split = sep)[[1]] return(fields) } check_field_name = function(input_df = NULL, name_of_input_df=NULL, field_name=NULL){ test_succeeded <- field_name %in% colnames(input_df) current_columns <- paste0(colnames(input_df), collapse=", ") checkTrue(test_succeeded, msg = sprintf("Expected fieldname '%s' in %s (but did not find it among %s)", field_name, name_of_input_df, current_columns)) } ############################################################# ####### Classes for Data ############################################################# ############################################################################### # Class: Data_Object ############################################################################### Data_Object <- setRefClass("Data_Object", fields =list(m_is_dirty = "logical", parents = "list", children = "list", class_name = "character")) Data_Object$methods( initialize = function(){ m_is_dirty <<- TRUE class_name <<- "Data_Object <abstract class - class_name needs to be set in subclass>" }, load_data = function(){ #print(sprintf("Calling %s$load_data()", class_name)) # Useful for debugging ensure_parents() verify() m_load_data() set_dirty(new_value = FALSE) }, ensure = function(){ if (m_is_dirty){ load_data() } }, set_dirty = function(new_value){ if (new_value != m_is_dirty){ m_is_dirty <<- new_value set_children_dirty() } }, verify = function(){ stop(sprintf("verify() is an abstract method - define it in %s before calling load_data()", class_name)) }, m_load_data = function(){ stop(sprintf("m_load_data() is an abstract method - define it in %s before calling load_data()", class_name)) }, append_parent = function(parent=NULL){ parents <<- append(parents, parent) }, append_child = function(child=NULL){ children <<- append(children, child) }, ensure_parents = function(){ for (parent in parents){ # print(sprintf("Calling %s$ensure()", parent$class_name)) # Useful for debugging parent$ensure() } }, set_children_dirty = function(){ for (child in children){ child$set_dirty(TRUE) } } ) ############################################################################### # Class: Data_Object_Info ############################################################################### Data_Object_Info <- setRefClass("Data_Object_Info", contains = "Data_Object", fields =list( data_file_name_1_percent_FDR = "character", data_file_name = "character", data_path_name = "character", experiment_name = "character", designation = "character", input_file_type = "character" #score_field_name = "character" #collection_name="character", #dir_results="character", #dir_dataset="character", #dataset_designation="character", #file_name_dataset="character", #file_name_dataset_1_percent="character", #experiment_name="character" ) ) Data_Object_Info$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Info - <Abstract class - class_name needs to be set in subclass>" }, verify = function(){ checkFieldExists = function(field_name=NULL){ field_value <- .self[[field_name]] checkTrue(length(field_value) > 0, sprintf("Field %s$%s has not been set (and should have been)", class_name, field_name)) checkTrue(length(field_value) == 1, sprintf("Field %s$%s has been set to multiple values (and should be a single value)", class_name, field_name)) checkTrue(field_value != "", sprintf("Field %s$%s has been set to an empty string (and should not have been)", class_name, field_name)) } checkFieldExists("data_file_name") checkFieldExists("data_path_name") checkFieldExists("experiment_name") checkFieldExists("designation") checkFieldExists("input_file_type") #checkFieldExists("score_field_name") }, m_load_data = function(){ # Nothing to do - this is really a data class }, file_path = function(){ result <- file.path(data_path_name, data_file_name) if (length(result) == 0){ stop("Unable to validate file path - one or both of path name and file name are missing") } return(result) }, file_path_1_percent_FDR = function(){ local_file_name <- get_data_file_name_1_percent_FDR() if (length(local_file_name) == 0){ result <- "" } else { result <- file.path(data_path_name, local_file_name) } # Continue even if file name is missing - not all analyses have a 1 percent FDR file; this is managed downstream # if (length(result) == 0){ # stop("Unable to validate file path - one or both of path name and file name (of 1 percent FDR file) are missing") # } return(result) }, get_data_file_name_1_percent_FDR = function(){ return(data_file_name_1_percent_FDR) }, collection_name = function(){ result <- sprintf("%s_%s", experiment_name, designation) return(result) } ) ############################################################################### # Class: Data_Object_Info_737_two_step ############################################################################### Data_Object_Info_737_two_step <- setRefClass("Data_Object_Info_737_two_step", contains = "Data_Object_Info", fields =list()) Data_Object_Info_737_two_step$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Info_737_two_step" #score_field_name <<- "Confidence [%]" data_file_name_1_percent_FDR <<- "737_NS_Peptide_Shaker_PSM_Report_Multi_Stage_Two_Step.tabular" data_file_name <<- "737_NS_Peptide_Shaker_Extended_PSM_Report_Multi_Stage_Two_Step.tabular.tabular" data_path_name <<- file.path(".", "Data") experiment_name <<- "Oral_737_NS" designation <<- "two_step" input_file_type <<- "PSM_Report" #data_collection_oral_737_NS_combined$file_name_dataset_1_percent = "737_NS_Peptide_Shaker_PSM_Report_CombinedDB.tabular" #data_collection_oral_737_NS_two_step$file_name_dataset_1_percent = "737_NS_Peptide_Shaker_PSM_Report_Multi_Stage_Two_Step.tabular" } ) ############################################################################### # Class: Data_Object_Info_737_combined ############################################################################### Data_Object_Info_737_combined <- setRefClass("Data_Object_Info_737_combined", contains = "Data_Object_Info", fields =list()) Data_Object_Info_737_combined$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Info_737_combined" #score_field_name <<- "Confidence [%]" data_file_name_1_percent_FDR <<- "737_NS_Peptide_Shaker_PSM_Report_CombinedDB.tabular" data_file_name <<- "737_NS_Peptide_Shaker_Extended_PSM_Report_CombinedDB.tabular" data_path_name <<- file.path(".", "Data") experiment_name <<- "Oral_737_NS" designation <<- "two_step" input_file_type <<- "PSM_Report" #data_collection_oral_737_NS_combined$file_name_dataset_1_percent = "737_NS_Peptide_Shaker_PSM_Report_CombinedDB.tabular" #data_collection_oral_737_NS_two_step$file_name_dataset_1_percent = "737_NS_Peptide_Shaker_PSM_Report_Multi_Stage_Two_Step.tabular" } ) ############################################################################### # Class: Data_Object_Pyrococcus_tr ############################################################################### Data_Object_Pyrococcus_tr <- setRefClass("Data_Object_Pyrococcus_tr", contains = "Data_Object_Info", fields =list()) Data_Object_Pyrococcus_tr$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Pyrococcus_tr" #score_field_name <<- "Confidence [%]" data_file_name_1_percent_FDR <<- "" data_file_name <<- "Pfu_traditional_Extended_PSM_Report.tabular" data_path_name <<- file.path(".", "Data") experiment_name <<- "Pyrococcus" designation <<- "tr" input_file_type <<- "PSM_Report" } ) ############################################################################### # Class: Data_Object_Mouse_Mutations ############################################################################### Data_Object_Mouse_Mutations <- setRefClass("Data_Object_Mouse_Mutations", contains = "Data_Object_Info", fields =list()) Data_Object_Mouse_Mutations$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Mouse_Mutations" #score_field_name <<- "Confidence [%]" data_file_name_1_percent_FDR <<- "" data_file_name <<- "Combined_DB_Mouse_5PTM.tabular" data_path_name <<- file.path(".", "Data") experiment_name <<- "Mouse Mutations" designation <<- "combined_05" input_file_type <<- "PSM_Report" } ) ############################################################################### # Class: Data_Object_Raw_Data ############################################################################### Data_Object_Raw_Data <- setRefClass("Data_Object_Raw_Data", contains = "Data_Object", fields =list(df = "data.frame")) Data_Object_Raw_Data$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Raw_Data" }, verify = function(){ # Check that file exists before using it file_path <- get_info()$file_path() if (! safe_file_exists(file_path)){ stop(sprintf("Raw data file does not exist (%s)", file_path)) } # BUGBUG: Needs to also check the following: # - file is tab-delimited # - first row is a list of column names }, set_info = function(info){ parents[["info"]] <<- info }, get_info = function(){ return(verified_element_of_list(parents, "info", "Data_Object_Raw_Data$parents")) }, m_load_data = function(){ info <- get_info() df <<- load_standard_df(info$file_path()) } ) ############################################################################### # Class: Data_Object_Raw_1_Percent ############################################################################### Data_Object_Raw_1_Percent <- setRefClass("Data_Object_Raw_1_Percent", contains = "Data_Object", fields =list(df = "data.frame")) Data_Object_Raw_1_Percent$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Raw_1_Percent" }, set_info = function(info){ parents[["info"]] <<- info }, verify = function(){ # Do nothing - a missing file name is acceptable for this module and is dealt with in load() }, get_info = function(){ return(verified_element_of_list(parents, "info", "Data_Object_Raw_1_Percent$parents")) }, m_load_data = function(){ info <- get_info() file_path <- info$file_path_1_percent_FDR() if (exists()){ df <<- load_standard_df(info$file_path_1_percent_FDR()) } # Note that failing to load is a valid state for this file, leading to not is_dirty. BUGBUG: this could lead to problems if a good file appears later }, exists = function(){ info <- get_info() local_file_name <- info$get_data_file_name_1_percent_FDR() # Check file name not file path if (length(local_file_name) == 0 ){ # variable not set result = FALSE } else if (local_file_name == ""){ # variable set to empty string result = FALSE } else { result = safe_file_exists(info$file_path_1_percent_FDR()) } return(result) } ) ############################################################################### # Class: Data_Converter ############################################################################### Data_Converter <- setRefClass("Data_Converter", fields =list(class_name = "character", file_type = "character" ) ) Data_Converter$methods( initialize = function(){ class_name <<- "Data_Converter <abstract class - class_name needs to be set in subclass>" file_type <<- "file_type has not been set before being used <needs to be set in initialize() of subclass>" }, check_raw_fields = function(info=NULL, raw_data=NULL){ stop(sprintf("check_raw_fields() is an abstract method - define it in %s before calling Data_Object_Data_Converter$load_data()", class_name)) }, convert_data = function(){ stop(sprintf("convert_data() is an abstract method - define it in %s before calling Data_Object_Data_Converter$load_data()", class_name)) } ) ############################################################################### # Class: Data_Converter_PMD_FDR_input_file ############################################################################### Data_Converter_PMD_FDR_input_file <- setRefClass("Data_Converter_PMD_FDR_input_file", contains = "Data_Converter", fields =list( ) ) Data_Converter_PMD_FDR_input_file$methods( initialize = function(){ callSuper() class_name <<- "Data_Converter_PMD_FDR_input_file" file_type <<- "PMD_FDR_file_type" }, check_raw_fields = function(info=NULL, raw_data=NULL){ data_original <- raw_data$df check_field_name(data_original, "raw_data", "PMD_FDR_input_score") check_field_name(data_original, "raw_data", "PMD_FDR_pmd") check_field_name(data_original, "raw_data", "PMD_FDR_spectrum_file") check_field_name(data_original, "raw_data", "PMD_FDR_proteins") check_field_name(data_original, "raw_data", "PMD_FDR_spectrum_title") check_field_name(data_original, "raw_data", "PMD_FDR_sequence") check_field_name(data_original, "raw_data", "PMD_FDR_decoy") }, convert_data = function(info=NULL, raw_data=NULL){ data_new <- raw_data$df return(data_new) # Pass through - everything should be in order } ) ############################################################################### # Class: Data_Converter_PSM_Report ############################################################################### Data_Converter_PSM_Report <- setRefClass("Data_Converter_PSM_Report", contains = "Data_Converter", fields =list( ) ) Data_Converter_PSM_Report$methods( initialize = function(){ callSuper() class_name <<- "Data_Converter_PSM_Report" file_type <<- "PSM_Report" }, check_raw_fields = function(info=NULL, raw_data=NULL){ data_original <- raw_data$df check_field_name(data_original, "raw_data", "Confidence [%]") check_field_name(data_original, "raw_data", "Precursor m/z Error [ppm]") check_field_name(data_original, "raw_data", "Spectrum File") check_field_name(data_original, "raw_data", "Protein(s)") check_field_name(data_original, "raw_data", "Spectrum Title") check_field_name(data_original, "raw_data", "Decoy") check_field_name(data_original, "raw_data", "Sequence") }, convert_data = function(info=NULL, raw_data=NULL){ data_new <- raw_data$df data_new$PMD_FDR_input_score <- data_new[, "Confidence [%]" ] data_new$PMD_FDR_pmd <- data_new[, "Precursor m/z Error [ppm]"] data_new$PMD_FDR_spectrum_file <- data_new[, "Spectrum File" ] data_new$PMD_FDR_proteins <- data_new[, "Protein(s)" ] data_new$PMD_FDR_spectrum_title <- data_new[, "Spectrum Title" ] data_new$PMD_FDR_sequence <- data_new[, "Sequence" ] data_new$PMD_FDR_decoy <- data_new[, "Decoy" ] return(data_new) } ) ############################################################################### # Class: Data_Converter_MaxQuant_Evidence ############################################################################### Data_Converter_MaxQuant_Evidence <- setRefClass("Data_Converter_MaxQuant_Evidence", contains = "Data_Converter", fields =list( ) ) Data_Converter_MaxQuant_Evidence$methods( initialize = function(){ callSuper() class_name <<- "Data_Converter_MaxQuant_Evidence" file_type <<- "MaxQuant_Evidence" }, check_raw_fields = function(info=NULL, raw_data=NULL){ data_original <- raw_data$df check_field_name(data_original, "raw_data", "PEP") check_field_name(data_original, "raw_data", "Mass error [ppm]") check_field_name(data_original, "raw_data", "Proteins") check_field_name(data_original, "raw_data", "Retention time") check_field_name(data_original, "raw_data", "Sequence") check_field_name(data_original, "raw_data", "Reverse") }, convert_data = function(info=NULL, raw_data=NULL){ data_new <- raw_data$df data_new$PMD_FDR_input_score <- 100 * (1 - data_new[, "PEP" ]) data_new$PMD_FDR_pmd <- data_new[, "Mass error [ppm]"] data_new$PMD_FDR_spectrum_file <- "<place_holder - assumes a single spectra file>" data_new$PMD_FDR_proteins <- data_new[, "Proteins" ] data_new$PMD_FDR_spectrum_title <- data_new[, "Retention time" ] # Used for ordering peptides - not important in MaxQuant since PMD has already been normalized effectively data_new$PMD_FDR_sequence <- data_new[, "Sequence" ] data_new$PMD_FDR_decoy <- ifelse( data_new[, "Reverse" ] == "+", 1, 0) return(data_new) } ) ############################################################################### # Class: Data_Object_Data_Converter ############################################################################### Data_Object_Data_Converter <- setRefClass("Data_Object_Data_Converter", contains = "Data_Object", fields =list(df = "data.frame", data_converter = "Data_Converter")) Data_Object_Data_Converter$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Data_Converter" }, currently_supported_file_types = function(){ return(c("PSM_Report", "PMD_FDR_input_file")) }, verify = function(){ info <- get_info() raw_data <- get_raw_data() file_type <- get_info()$input_file_type set_file_type(file_type) data_converter$check_raw_fields(info=info, raw_data=raw_data) }, m_load_data = function(){ info <- get_info() raw_data <- get_raw_data() file_type <- get_info()$input_file_type df <<- data_converter$convert_data(info=info, raw_data=raw_data) }, set_file_type = function(file_type = NULL){ if (file_type == "PSM_Report" ){ data_converter <<- Data_Converter_PSM_Report $new() } else if (file_type == "PMD_FDR_input_file"){ data_converter <<- Data_Converter_PMD_FDR_input_file$new() } else if (file_type == "MaxQuant_Evidence"){ data_converter <<- Data_Converter_MaxQuant_Evidence $new() } else { stop(sprintf("File type '%s' is not currently supported by PMD-FDR module", file_type)) } }, set_info = function(info){ parents[["info"]] <<- info }, get_info = function(){ return(verified_element_of_list(parents, "info", "Data_Object_Data_Converter$parents")) }, set_raw_data = function(raw_data){ parents[["raw_data"]] <<- raw_data }, get_raw_data = function(){ return(verified_element_of_list(parents, "raw_data", "Data_Object_Data_Converter$parents")) } ) ############################################################################### # Class: Data_Object_Groupings ############################################################################### Data_Object_Groupings <- setRefClass("Data_Object_Groupings", contains = "Data_Object", fields =list(df = "data.frame")) Data_Object_Groupings$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Groupings" }, simplify_field_name = function(x=NULL){ result <- gsub(pattern = "PMD_FDR_", replacement = "", x = x) return(result) }, verify = function(){ data_original <- get_data_converter()$df check_field_name(data_original, "data_converter", "PMD_FDR_input_score") check_field_name(data_original, "data_converter", "PMD_FDR_pmd") check_field_name(data_original, "data_converter", "PMD_FDR_spectrum_file") check_field_name(data_original, "data_converter", "PMD_FDR_proteins") check_field_name(data_original, "data_converter", "PMD_FDR_spectrum_title") check_field_name(data_original, "data_converter", "PMD_FDR_sequence") check_field_name(data_original, "data_converter", "PMD_FDR_decoy") }, m_load_data = function(){ make_data_groups <- function(data_original=NULL){ # Functions supporting make_data_groups() standardize_fields <- function(data=NULL){ data_new <- data info <- get_info() info$ensure() #field_name_of_score <- info$get_field_name_of_score() # #data_new <- rename_column(data_new, "Variable Modifications" , "ptm_list") # data_new <- rename_column(data_new, field_name_of_score , "PMD_FDR_input_score") # data_new <- rename_column(data_new, "Precursor m/z Error [ppm]", "PMD_FDR_pmd") # #data_new <- rename_column(data_new, "Isotope Number" , "isotope_number") # #data_new <- rename_column(data_new, "m/z" , "m_z") # #data_new <- rename_column(data_new, "Measured Charge" , "charge") # data_new <- rename_column(data_new, "Spectrum File" , "PMD_FDR_spectrum_file") # data_new <- rename_column(data_new, "Protein(s)" , "PMD_FDR_proteins") # data_new <- rename_column(data_new, "Spectrum Title" , "PMD_FDR_spectrum_title") # data_new <- manage_decoy_column(data_new) # Now managed in Data_Converter # data_new$PMD_FDR_input_score <- data_new[, field_name_of_score ] # data_new$PMD_FDR_pmd <- data_new[, "Precursor m/z Error [ppm]"] # data_new$PMD_FDR_spectrum_file <- data_new[, "Spectrum File" ] # data_new$PMD_FDR_proteins <- data_new[, "Protein(s)" ] # data_new$PMD_FDR_spectrum_title <- data_new[, "Spectrum Title" ] data_new$value <- data_new$PMD_FDR_pmd data_new$PMD_FDR_peptide_length <- str_length(data_new$PMD_FDR_sequence) #data_new$charge_value <- with(data_new, as.numeric(substr(charge, start=1, stop=str_length(charge)-1))) #data_new$measured_mass <- with(data_new, m_z*charge_value) data_new$PMD_FDR_spectrum_index <- NA data_new$PMD_FDR_spectrum_index[order(data_new$PMD_FDR_spectrum_title, na.last = TRUE)] <- 1:nrow(data_new) return(data_new) } add_grouped_variable <- function(data_groups = data_groups, field_name_to_group = NULL, vec.length.out = NULL, vec.tolerance = NULL, value_format = NULL){ # Support functions for add_grouped_variable() find_interval_vec <- function(x=NULL, length.out = NULL, tolerance = NULL){ q <- quantile(x = x, probs = seq(from=0, to=1, length.out = length.out), na.rm=TRUE) q <- round_to_tolerance(q, tolerance = tolerance) return(q) } get_group_data_frame <- function(vec=NULL, value_format = NULL){ n <- length(vec) a <- vec[-n] b <- vec[-1] lower <- ifelse(a == b , "eq", NA) lower <- ifelse(is.na(lower ), "ge", lower) upper <- ifelse(a == b , "eq", NA) upper[n-1] <- ifelse(is.na(upper[n-1]), "le", "eq") upper <- ifelse(is.na(upper ), "lt", upper) group <- data.frame(list(idx=1:(n-1), a=a, b=b, lower=lower, upper=upper)) name_format <- sprintf("%%%s_%%%s_%%s_%%s", value_format, value_format) group$new_var <- with(group, sprintf(name_format, a, b, lower, upper)) return(group) } merge_group_with_data <- function(data_groups = NULL, group = NULL, vec = NULL, field_name_to_group = NULL){ field_name_new <- sprintf("group_%s", simplify_field_name(field_name_to_group)) group_idx <- findInterval(x = data_groups[,field_name_to_group], vec = vec, all.inside=TRUE) data_groups$new_var <- group$new_var[group_idx] data_groups <- rename_column(data_groups, "new_var", field_name_new) } # Body of add_grouped_variable() vec <- find_interval_vec(x = data_groups[[field_name_to_group]], length.out = vec.length.out, tolerance = vec.tolerance ) group <- get_group_data_frame(vec = vec, value_format = value_format) df_new <- merge_group_with_data(data_groups = data_groups, group = group, vec = vec, field_name_to_group = field_name_to_group) df_new <- add_group_decoy(df_new, field_name_to_group) return(df_new) } add_already_grouped_variable <- function(field_name_to_group = NULL, data_groups = NULL ){ old_name <- field_name_to_group new_name <- sprintf("group_%s", simplify_field_name(old_name)) df_new <- data_groups df_new[[new_name]] <- data_groups[[old_name]] df_new <- add_group_decoy(data_groups = df_new, field_name_to_group = field_name_to_group) return(df_new) } add_value_norm <- function(data_groups = NULL){ df_new <- data_groups df_new$value_norm <- with(df_new, value - median_of_group_index) return(df_new) } add_protein_group <-function(data_groups = NULL){ data_new <- data_groups df_group_def <- data.frame(stringsAsFactors = FALSE, list(pattern = c("" , "pfu_" , "cRAP"), group_name = c("human", "pyrococcus", "contaminant"))) for (i in 1:nrow(df_group_def)){ idx <- grepl(pattern = df_group_def$pattern[i], x = data_new$PMD_FDR_proteins) data_new$group_proteins[idx] <- df_group_def$group_name[i] } data_new <- add_group_decoy(data_groups = data_new, field_name_to_group = "PMD_FDR_proteins") return(data_new) } add_group_decoy <- function(data_groups=NULL, field_name_to_group=NULL){ simple_field_name <- simplify_field_name(field_name_to_group) field_name_decoy <- sprintf("group_decoy_%s", simple_field_name) field_name_group <- sprintf("group_%s", simple_field_name) data_groups[[field_name_decoy]] <- with(data_groups, ifelse(PMD_FDR_decoy, "decoy", data_groups[[field_name_group]])) return(data_groups) } add_group_training_class <- function(data_groups = NULL){ df_new <- data_groups lowest_confidence_group <- min(data_groups$group_input_score) is_long_enough <- with(df_new, (PMD_FDR_peptide_length >= MIN_GOOD_PEPTIDE_LENGTH) ) is_good <- with(df_new, (PMD_FDR_decoy == 0) & (PMD_FDR_input_score == 100) ) is_bad <- with(df_new, (PMD_FDR_decoy == 1) ) #is_used_to_train <- with(df_new, used_to_find_middle) # BUGBUG: circular definition idx_good <- which(is_good ) # & is_long_enough) n_good <- length(idx_good) idx_testing <- idx_good[c(TRUE,FALSE)] # Selects every other item idx_training <- setdiff(idx_good, idx_testing) #is_good_short <- with(df_new, is_good & !is_long_enough ) #is_good_long <- with(df_new, is_good & is_long_enough ) is_bad_short <- with(df_new, is_bad & !is_long_enough ) is_bad_long <- with(df_new, is_bad & is_long_enough ) #is_good_training <- with(df_new, is_good_long & (used_to_find_middle == TRUE ) ) #is_good_testing <- with(df_new, is_good_long & (used_to_find_middle == FALSE) ) df_new$group_training_class <- "other_short" # Default df_new$group_training_class[is_long_enough ] <- "other_long" # Default (if long enough) df_new$group_training_class[idx_training ] <- "good_training" # Length does not matter (anymore) df_new$group_training_class[idx_testing ] <- "good_testing" # Ditto #df_new$group_training_class[is_good_short ] <- "good_short" df_new$group_training_class[is_bad_long ] <- "bad_long" # ...except for "bad" df_new$group_training_class[is_bad_short ] <- "bad_short" df_new <- add_used_to_find_middle( data_groups = df_new ) # Guarantees consistency between duplicated definitions return(df_new) } add_used_to_find_middle <- function(data_groups = NULL){ df_new <- data_groups idx_used <- which(data_groups$group_training_class == "good_training") df_new$used_to_find_middle <- FALSE df_new$used_to_find_middle[idx_used] <- TRUE return(df_new) } add_group_spectrum_index <- function(data_groups = NULL){ # Supporting functions for add_group_spectrum_index() get_breaks_all <- function(df_new){ # Supporting function(s) for get_breaks_all() get_cut_points <- function(data_subset){ # Supporting function(s) for get_cut_points() cut_values <- function(data=NULL, minimum_segment_length=NULL){ # using cpt.mean -- Appears to have a memory leak #results_cpt <- cpt.mean(data=data, method="PELT", minimum_segment_length=minimum_segment_length) #results <- results_cpt@cpts # Just look at the end #results <- c(length(data)) # regularly spaced, slightly larger than minimum_segment_length n_points <- length(data) n_regions <- floor(n_points / minimum_segment_length) n_regions <- ifelse(n_regions == 0, 1, n_regions) results <- round(seq(1, n_points, length.out = n_regions + 1)) results <- results[-1] return(results) } remove_last <- function(x){ return(x[-length(x)] ) } # Main code of for get_cut_points() max_idx = max(data_subset$PMD_FDR_spectrum_index) data_sub_sub <- subset(data_subset, group_training_class == "good_training") #(PMD_FDR_input_score==100) & (PMD_FDR_decoy==0)) minimum_segment_length = 50 values <- data_sub_sub$value n_values <- length(values) local_to_global_idx <- data_sub_sub$PMD_FDR_spectrum_index if (n_values <= minimum_segment_length){ result <- c() } else { local_idx <- cut_values(data=values, minimum_segment_length=minimum_segment_length) result <- local_to_global_idx[local_idx] result <- remove_last(result) } result <- c(result, max_idx) return(result) } remove_last <- function(vec) { return(vec[-length(vec)]) } # Main code of get_breaks_all() breaks <- 1 files <- unique(df_new$PMD_FDR_spectrum_file) for (local_file in files){ data_subset <- subset(df_new, (PMD_FDR_spectrum_file==local_file)) if (nrow(data_subset) > 0){ breaks <- c(breaks, get_cut_points(data_subset)) } } breaks <- sort(unique(breaks)) breaks <- remove_last(breaks) breaks <- c(breaks, max(df_new$PMD_FDR_spectrum_index + 1)) return(breaks) } # Main code of add_group_spectrum_index() field_name_to_group <- "PMD_FDR_spectrum_index" df_new <- data_groups[order(data_groups[[field_name_to_group]]),] breaks <- get_breaks_all(df_new) df_new$group_spectrum_index <- cut(x = df_new[[field_name_to_group]], breaks = breaks, right = FALSE, dig.lab = 6) df_new <- add_group_decoy(data_groups = df_new, field_name_to_group = field_name_to_group) return(df_new) } add_median_of_group_index <-function(data_groups = NULL){ field_median <- "median_of_group_index" data_good <- subset(data_groups, used_to_find_middle ) med <- aggregate(value~group_spectrum_index, data=data_good, FUN=safe_median) med <- rename_column(med, "value", field_median) data_groups[[field_median]] <- NULL df_new <- merge(data_groups, med) return(df_new) } add_1_percent_to_data_groups <- function(data_groups=NULL){ data_new <- data_groups if (get_raw_1_percent()$exists()){ # Load 1 percent file df_1_percent <- get_raw_1_percent()$df # Get relevant fields df_1_percent$is_in_1percent <- TRUE df_1_percent <- rename_column(df_1_percent, "Spectrum Title", "PMD_FDR_spectrum_title") df_1_percent <- df_1_percent[,c("PMD_FDR_spectrum_title", "is_in_1percent")] # Merge with data_groups data_new <- merge(data_new, df_1_percent, all.x=TRUE) data_new$is_in_1percent[is.na(data_new$is_in_1percent)] <- FALSE } # Save results return(data_new) } # Main code of make_data_groups() data_groups <- standardize_fields(data_original) data_groups <- add_grouped_variable(field_name_to_group = "PMD_FDR_input_score", data_groups = data_groups, vec.length.out = 14, vec.tolerance = 1, value_format = "03d") data_groups <- add_grouped_variable(field_name_to_group = "PMD_FDR_pmd", data_groups = data_groups, vec.length.out = 21, vec.tolerance = 0.1, value_format = "+05.1f") data_groups <- add_grouped_variable(field_name_to_group = "PMD_FDR_peptide_length", data_groups = data_groups, vec.length.out = 11, vec.tolerance = 1, value_format = "02d") # data_groups <- add_grouped_variable(field_name_to_group = "m_z", # data_groups = data_groups, # vec.length.out = 11, # vec.tolerance = 10, # value_format = "04.0f") # # data_groups <- add_grouped_variable(field_name_to_group = "measured_mass", # data_groups = data_groups, # vec.length.out = 11, # vec.tolerance = 1, # value_format = "04.0f") # # data_groups <- add_already_grouped_variable(field_name_to_group = "isotope_number", # data_groups = data_groups ) # # data_groups <- add_already_grouped_variable(field_name_to_group = "charge", # data_groups = data_groups ) # data_groups <- add_already_grouped_variable(field_name_to_group = "PMD_FDR_spectrum_file", data_groups = data_groups ) data_groups <- add_protein_group(data_groups = data_groups) data_groups <- add_group_training_class( data_groups = data_groups) data_groups <- add_group_spectrum_index( data_groups = data_groups) data_groups <- add_median_of_group_index( data_groups = data_groups) data_groups <- add_value_norm( data_groups = data_groups) # fields_of_interest <- c("PMD_FDR_input_score", "PMD_FDR_pmd", "m_z", "PMD_FDR_peptide_length", "isotope_number", "charge", "PMD_FDR_spectrum_file", "measured_mass", "PMD_FDR_spectrum_index", "PMD_FDR_proteins") # fields_of_interest <- c("value", # "PMD_FDR_decoy", # "PMD_FDR_spectrum_title", # "median_of_group_index", # "value_norm", # "used_to_find_middle", # "group_training_class", # fields_of_interest, # sprintf("group_%s" , fields_of_interest), # sprintf("group_decoy_%s", fields_of_interest)) fields_of_interest <- c("PMD_FDR_input_score", "PMD_FDR_pmd", "PMD_FDR_peptide_length", "PMD_FDR_spectrum_file", "PMD_FDR_spectrum_index", "PMD_FDR_proteins") fields_of_interest <- c("value", "PMD_FDR_decoy", "PMD_FDR_spectrum_title", "median_of_group_index", "value_norm", "used_to_find_middle", "group_training_class", fields_of_interest, sprintf("group_%s" , simplify_field_name(fields_of_interest)), sprintf("group_decoy_%s", simplify_field_name(fields_of_interest))) data_groups <- data_groups[,fields_of_interest] data_groups <- add_1_percent_to_data_groups(data_groups) return(data_groups) } data_original <- get_data_converter()$df #parents[[INDEX_OF_ORIGINAL_DATA]]$df df <<- make_data_groups(data_original) }, set_info = function(info){ parents[["info"]] <<- info }, get_info = function(){ return(verified_element_of_list(parents, "info", "Data_Object_Groupings$parents")) }, set_data_converter = function(data_converter){ parents[["data_converter"]] <<- data_converter }, get_data_converter = function(){ return(verified_element_of_list(parents, "data_converter", "Data_Object_Groupings$parents")) }, set_raw_1_percent = function(raw_1_percent){ ############## BUGBUG: the 1% file should be using the same file type format as the standard data (but isn't) parents[["raw_1_percent"]] <<- raw_1_percent }, get_raw_1_percent = function(){ return(verified_element_of_list(parents, "raw_1_percent", "Data_Object_Groupings$parents")) } ) ############################################################################### # Class: Data_Object_Individual_FDR ############################################################################### Data_Object_Individual_FDR <- setRefClass("Data_Object_Individual_FDR", contains = "Data_Object", fields =list(df = "data.frame")) Data_Object_Individual_FDR$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Individual_FDR" }, verify = function(){ data_groups = get_data_groups()$df densities = get_densities()$df alpha = get_alpha()$df check_field_name(data_groups, "data_groups", "value_norm") check_field_name(data_groups, "data_groups", "group_decoy_input_score") check_field_name(data_groups, "data_groups", "PMD_FDR_peptide_length") check_field_name(data_groups, "data_groups", "PMD_FDR_input_score") check_field_name(alpha, "alpha", "alpha") # BUGBUG: I'm missing a field here... check_field_name(densities, "densities", "x") check_field_name(densities, "densities", "t") check_field_name(densities, "densities", "f") }, set_data_groups = function(parent){ parents[["data_groups"]] <<- parent }, get_data_groups = function(){ return(verified_element_of_list(parents, "data_groups", "Data_Object_Individual_FDR$parents")) }, set_densities = function(parent){ parents[["densities"]] <<- parent }, get_densities = function(){ return(verified_element_of_list(parents, "densities", "Data_Object_Individual_FDR$parents")) }, set_alpha = function(parent){ parents[["alpha"]] <<- parent }, get_alpha = function(){ return(verified_element_of_list(parents, "alpha", "Data_Object_Individual_FDR$parents")) }, m_load_data = function(){ add_FDR_to_data_groups <- function(data_groups=NULL, densities=NULL, alpha=NULL, field_value=NULL, field_decoy_group=NULL, set_decoy_to_1=FALSE){ # Support functions for add_FDR_to_data_groups() get_group_fdr <- function(group_stats = NULL, data_groups = NULL, densities=NULL){ group_fdr <- apply(X = densities, MARGIN = 2, FUN = max) df_group_fdr <- data.frame(group_fdr) df_group_fdr <- rename_column(df_group_fdr, "group_fdr", "v") df_group_fdr$group_of_interest <- names(group_fdr) t <- df_group_fdr[df_group_fdr$group_of_interest == "t", "v"] f <- df_group_fdr[df_group_fdr$group_of_interest == "f", "v"] df_group_fdr <- subset(df_group_fdr, !(group_of_interest %in% c("x", "t", "f"))) df_group_fdr$group_fdr <-(df_group_fdr$v - t) / (f - t) return(df_group_fdr) } get_mode <- function(x){ d <- density(x) return(d$x[which.max(d$y)]) } # Main code for add_FDR_to_data_groups() # Set up analysis data_new <- data_groups data_new$value_of_interest <- data_new[,field_value] data_new$group_of_interest <- data_new[,field_decoy_group] data_subset <- subset(data_new, PMD_FDR_peptide_length >= 11) # Identify mean PMD_FDR_input_score per group group_input_score <- aggregate(PMD_FDR_input_score~group_of_interest, data=data_subset, FUN=mean) group_input_score <- rename_column(group_input_score, "PMD_FDR_input_score", "group_input_score") #group_fdr <- get_group_fdr(data_groups = data_subset, densities=densities) group_stats <- merge(alpha, group_input_score) group_stats <- subset(group_stats, group_of_interest != "PMD_FDR_decoy") x=c(0,group_stats$group_input_score) y=c(1,group_stats$alpha) FUN_interp <- approxfun(x=x,y=y) data_new$interpolated_groupwise_FDR <- FUN_interp(data_new$PMD_FDR_input_score) if (set_decoy_to_1){ data_new$interpolated_groupwise_FDR[data_new$PMD_FDR_decoy == 1] <- 1 } return(data_new) } data_groups = get_data_groups()$df densities = get_densities()$df alpha = get_alpha()$df d_true <- densities[,c("x", "t")] d_false <- densities[,c("x", "f")] i_fdr <- add_FDR_to_data_groups(data_groups = data_groups, densities = densities, alpha = alpha, field_value ="value_norm", field_decoy_group = "group_decoy_input_score") # Derive local t interp_t <- splinefun(x=d_true$x, y=d_true$t) #approxfun(x=d_true$x, y=d_true$y) # Derive local f interp_f <- splinefun(x=d_false$x, y=d_false$f) #approxfun(x=d_true$x, y=d_true$y) # Derive local FDR i_fdr$t <- interp_t(i_fdr$value_of_interest) i_fdr$f <- interp_f(i_fdr$value_of_interest) i_fdr$alpha <- i_fdr$interpolated_groupwise_FDR i_fdr$i_fdr <- with(i_fdr, (alpha*f) / (alpha*f + (1-alpha)*t)) df <<- i_fdr } ) ############################################################################### # Class: Data_Object_Densities ############################################################################### Data_Object_Densities <- setRefClass("Data_Object_Densities", contains = "Data_Object", fields =list(df = "data.frame")) Data_Object_Densities$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Densities" }, verify = function(){ df_data_groups <- get_data_groups()$df checkTrue(nrow(df_data_groups) > 0, msg = "data_groups data frame was empty (and should not have been)") check_field_name(df_data_groups, "data_groups", "value_norm") check_field_name(df_data_groups, "data_groups", "group_decoy_input_score") check_field_name(df_data_groups, "data_groups", "group_training_class") }, set_data_groups = function(parent=NULL){ parents[["data_groups"]] <<- parent }, get_data_groups = function(){ return(verified_element_of_list(parent_list = parents, element_name = "data_groups", object_name = "Data_Object_Densities$parents")) }, m_load_data = function(){ # Support functions for make_densities() set_values_of_interest <- function(df_data_groups=NULL, field_group = NULL){ field_value = "value_norm" new_data_groups <- get_data_groups()$df new_data_groups$value_of_interest <- new_data_groups[,field_value] new_data_groups$group_of_interest <- new_data_groups[,field_group] #groups <- sort(unique(new_data_groups$group_of_interest)) return(new_data_groups) } get_ylim <- function(data_groups=NULL){ ylim <- range(data_groups$value_of_interest, na.rm = TRUE) return(ylim) } make_hit_density <- function(data_subset=NULL, descr_of_df=NULL, ylim=NULL){ #stop("Data_Object_Densities$make_hit_density() is untested beyond here") verify_density = function(data_subset=NULL, value_field=NULL, descr_of_df=NULL, ylim=NULL){ values <- data_subset[value_field] values <- values[! is.na(values)] if (length(values) < MIN_ACCEPTABLE_POINTS_IN_DENSITY){ stop (sprintf("There are too few valid %s (%d < %d) in %s to be used for calculating a density function", value_field, length(values), MIN_ACCEPTABLE_POINTS_IN_DENSITY, descr_of_df)) } d <- density(values, from = ylim[1], to = ylim[2]) return(d) } uniformalize_density <- function(d){ # Reorganizes y-values of density function so that # function is monotone increasing to mode # and monotone decreasing afterwards idx_mode <- which.max(d$y) idx_lower <- 1:(idx_mode-1) idx_upper <- idx_mode:length(d$y) values_lower <- d$y[idx_lower] values_upper <- d$y[idx_upper] new_d <- d new_d$y <- c(sort(values_lower, decreasing = FALSE), sort(values_upper, decreasing = TRUE)) return(new_d) } local_df <- subset(data_subset, (PMD_FDR_peptide_length >= MIN_GOOD_PEPTIDE_LENGTH) & (used_to_find_middle == FALSE)) d <- verify_density (data_subset=local_df, value_field = "value_of_interest", descr_of_df = descr_of_df, ylim=ylim) d <- normalize_density (d) d <- uniformalize_density(d) return(d) } make_true_hit_density <- function(data_groups=NULL){ d_true <- make_hit_density(data_subset = subset(data_groups, (group_training_class == "good_testing") ), descr_of_df = "Good-testing dataset", ylim = get_ylim(data_groups)) return(d_true) } make_false_hit_density <- function(data_groups=NULL){ d_false <- make_hit_density(data_subset = subset(data_groups, (group_training_class == "bad_long") ), descr_of_df = "Bad-long dataset", ylim = get_ylim(data_groups)) return(d_false) } add_v_densities <- function(data_groups=NULL, densities=NULL, field_group = NULL){ groups <- sort(unique(data_groups$group_of_interest)) new_densities <- densities for (local_group in groups){ d_v <- make_hit_density(data_subset = subset(data_groups, (group_of_interest == local_group)), descr_of_df = sprintf("subset of data (where %s is '%s')", field_group, local_group), ylim = get_ylim(data_groups)) new_densities[local_group] <- d_v$y } return(new_densities) } # Main section of make_densities() df_data_groups <- get_data_groups()$df new_data_groups <- set_values_of_interest(df_data_groups, field_group = "group_decoy_input_score") d_true <- make_true_hit_density( new_data_groups) d_false <- make_false_hit_density(new_data_groups) densities <- data.frame(x=d_true$x, t=d_true$y, f=d_false$y) densities <- add_v_densities(data_groups=new_data_groups, densities=densities, field_group = "group_decoy_input_score") df <<- densities } ) ############################################################################### # Class: Data_Object_Alpha ############################################################################### Data_Object_Alpha <- setRefClass("Data_Object_Alpha", contains = "Data_Object", fields =list(df = "data.frame")) Data_Object_Alpha$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Alpha" }, verify = function(){ densities <- get_densities()$df checkTrue(nrow(densities) > 0, msg = "Densities data.frame was empty (and should not have been)") }, set_densities = function(parent=NULL){ parents[["densities"]] <<- parent }, get_densities = function(){ return(verified_element_of_list(parent_list = parents, element_name = "densities", object_name = "Data_Object_Alpha")) }, m_load_data = function(){ densities <- get_densities()$df max_of_density = apply(X = densities, MARGIN = 2, FUN = max) df_alpha <- data.frame(stringsAsFactors = FALSE, list(v = max_of_density, group_of_interest = names(max_of_density))) df_alpha <- subset(df_alpha, group_of_interest != "x") t <- with(subset(df_alpha, group_of_interest=="t"), v) f <- with(subset(df_alpha, group_of_interest=="f"), v) df_alpha$alpha <- with(df_alpha, (t-v)/(t-f)) alpha <- df_alpha[,c("group_of_interest", "alpha")] alpha <- subset(alpha, (group_of_interest != "t") & (group_of_interest != "f")) df <<- alpha } ) ############################################################################### # Class: Data_Processor ############################################################################### Data_Processor <- setRefClass("Data_Processor", fields =list(info = "Data_Object_Info", raw_data = "Data_Object_Raw_Data", raw_1_percent = "Data_Object_Raw_1_Percent", data_converter = "Data_Object_Data_Converter", data_groups = "Data_Object_Groupings", densities = "Data_Object_Densities", alpha = "Data_Object_Alpha", i_fdr = "Data_Object_Individual_FDR")) Data_Processor$methods( initialize = function(p_info=NULL){ if (! is.null(p_info)){ set_info(p_info) } }, set_info = function(p_info=NULL){ # This initialization defines all of the dependencies between the various components info <<- p_info # raw_data raw_data$set_info(info) info$append_child(raw_data) # raw_1_percent raw_1_percent$set_info(info) info$append_child(raw_1_percent) # data_converter data_converter$set_info (info) data_converter$set_raw_data(raw_data) info $append_child (data_converter) raw_data $append_child (data_converter) # data_groups data_groups$set_info (info) data_groups$set_data_converter(data_converter) data_groups$set_raw_1_percent (raw_1_percent) info $append_child (data_groups) data_converter$append_child (data_groups) raw_1_percent $append_child (data_groups) # densities densities $set_data_groups(data_groups) data_groups$append_child (densities) # alpha alpha $set_densities(densities) densities$append_child (alpha) # i_fdr i_fdr$set_data_groups(data_groups) i_fdr$set_densities (densities) i_fdr$set_alpha (alpha) data_groups $append_child(i_fdr) densities $append_child(i_fdr) alpha $append_child(i_fdr) } ) ############################################################# ####### Classes for Plotting ############################################################# ############################################################################### # Class: Plot_Image ############################################################################### Plot_Image = setRefClass("Plot_Image", fields = list(data_processors = "list", plot_title = "character", include_text = "logical", include_main = "logical", x.intersp = "numeric", y.intersp = "numeric", scale = "numeric", main = "character", is_image_container = "logical")) Plot_Image$methods( initialize = function(p_data_processors = list(), p_include_main = TRUE, p_include_text = TRUE, p_is_image_container = FALSE){ include_main <<- p_include_main include_text <<- p_include_text data_processors <<- p_data_processors is_image_container <<- p_is_image_container }, plot_image = function(){ plot(main="Define plot_image() for subclass") # Abstract function }, get_n = function(){ stop("Need to define function get_n() for subclass") #Abstract function }, create_standard_main = function(){ needs_main <- function(){ return(include_text & include_main & !is_image_container) } if (needs_main()){ collection_name <- data_processors[[1]]$info$collection_name() main <<- sprintf("%s\n(Dataset: %s; n=%s)", plot_title, collection_name, format(get_n(), big.mark = ",")) } }, plot_image_in_window = function(p_scale=NULL, window_height=NULL, window_width=NULL){ scale <<- p_scale SIZE_AXIS <- 2.5 * scale # in the units used by mar SIZE_MAIN <- 2.5 * scale SIZE_NO_MARGIN <- 0.1 * scale FONT_SIZE <- 8 * scale WINDOW_WIDTH <- window_width * scale WINDOW_HEIGHT <- window_height * scale X_INTERSP <- 0.5 * scale + 0.4 # manages legend text spacing Y_INTERSP <- 0.5 * scale + 0.4 # manages if (include_main){ mar = c(SIZE_AXIS, SIZE_AXIS, SIZE_MAIN , SIZE_NO_MARGIN) } else { mar = c(SIZE_AXIS, SIZE_AXIS, SIZE_NO_MARGIN, SIZE_NO_MARGIN) } mgp = c(SIZE_AXIS/2, SIZE_AXIS/4, 0) # Margin line (mex units) for axis title, axis labels, axis lines ps = FONT_SIZE x.intersp <<- X_INTERSP y.intersp <<- Y_INTERSP windows(width = WINDOW_WIDTH, height=WINDOW_HEIGHT) old_par <- par(mar=mar, ps=ps, mgp=mgp) create_standard_main() plot_image() if (!is_image_container){ axis(side=1, labels=include_text, tcl=-0.5, lwd=scale) axis(side=2, labels=include_text, tcl=-0.5, lwd=scale) box(lwd=scale) } par(old_par) }, plot_image_in_small_window = function(p_scale=1){ plot_image_in_window(p_scale=p_scale, window_height=2, window_width=3.25) }, plot_image_in_large_window = function(p_scale=1, window_height=NULL){ plot_image_in_window(p_scale=p_scale, window_height=window_height, window_width=7) } ) ############################################################################### # Class: Legend_Object ############################################################################### Legend_Object = setRefClass("Legend_Object", contains = "Plot_Image", fields = list(user_params = "list", scale = "numeric")) Legend_Object$methods( initialize = function(p_user_params = NULL, p_scale = NULL){ if (is.null(p_user_params)){ user_params <<- list() } else { user_params <<- p_user_params } if (is.null(p_scale)){ stop("Legend_Object must have a valid scale") } else { scale <<- p_scale } user_params$x <<- if_null(user_params$x , "topleft", user_params$x) user_params$y <<- if_null(user_params$y , NULL, user_params$y) user_params$bty <<- if_null(user_params$bty , "o", user_params$bty) user_params$lwd <<- if_null(user_params$lwd , NULL, user_params$lwd * scale) # Because we allow NULL, scale must be inside parens user_params$seg.len <<- if_null(user_params$seg.len , 3, user_params$seg.len ) * scale user_params$box.lwd <<- if_null(user_params$box.lwd , 1, user_params$box.lwd ) * scale user_params$x.intersp <<- if_null(user_params$x.intersp, 0.6, user_params$x.intersp) * scale user_params$y.intersp <<- if_null(user_params$y.intersp, 0.4, user_params$y.intersp) * scale + 0.2 }, show = function(){ first_legend = legend(x = user_params$x, y = user_params$y, title = "", legend = user_params$leg, col = user_params$col, bty = user_params$bty, lty = user_params$lty, lwd = user_params$lwd, seg.len = user_params$seg.len, box.lwd = user_params$box.lwd, x.intersp = user_params$x.intersp, y.intersp = user_params$y.intersp) new_x = first_legend$rect$left new_y = first_legend$rect$top + first_legend$rect$h * ifelse(scale==1, 0.07, 0.03 - (scale * 0.02)) #switch(scale, 0.01, -0.01, -0.03, -0.05)# (0.07 - 0.09 * ((scale-1)^2))#(0.15 - 0.08*scale)#.07 * (2 - scale) legend(x=new_x, y=new_y, title = user_params$title, legend = "", cex=1.15, bty="n") } ) ############################################################################### # Class: Plot_Multiple_Images ############################################################################### Plot_Multiple_Images = setRefClass("Plot_Multiple_Images", contains = "Plot_Image", fields = list(n_images_wide = "numeric", n_images_tall = "numeric", image_list = "list")) Plot_Multiple_Images$methods( initialize = function(p_n_images_wide=1, p_n_images_tall=2, p_image_list=NULL, ...){ n_images_wide <<- p_n_images_wide n_images_tall <<- p_n_images_tall image_list <<- p_image_list #plot_title <<- "True Hit and False Hit Distributions" callSuper(p_is_image_container=TRUE, ...) }, plot_image = function(){ # Support functions apply_mtext <- function(letter=NULL){ line=1.3*scale mtext(letter, side=1, line=line, adj=0) } # main code old_par <- par(mfrow=c(n_images_tall, n_images_wide)) i=0 n_images <- length(image_list) for (i in 1:n_images){ image <- image_list[[i]] image$create_standard_main() image$scale <- scale image$plot_image() axis(side=1, labels=include_text, tcl=-0.5, lwd=scale) axis(side=2, labels=include_text, tcl=-0.5, lwd=scale) box(lwd=scale) apply_mtext(letter=sprintf("(%s)", letters[i])) } par(old_par) } ) ############################################################################### # Class: Plot_Compare_PMD_and_Norm_Density ############################################################################### Plot_Compare_PMD_and_Norm_Density = setRefClass("Plot_Compare_PMD_and_Norm_Density", contains = "Plot_Image", fields = list(show_norm = "logical", display_n_psms = "logical")) Plot_Compare_PMD_and_Norm_Density$methods( initialize = function(p_show_norm=TRUE, p_display_n_psms=TRUE, ...){ show_norm <<- p_show_norm display_n_psms <<- p_display_n_psms plot_title <<- "True Hit and False Hit Distributions" callSuper(...) }, plot_image = function(){ # Support functions for plot_compare_PMD_and_norm_density() get_densities <- function(data_subset = NULL, var_value = NULL){ data_subset$value_of_interest <- data_subset[,var_value] from <- min(data_subset$value_of_interest, na.rm = TRUE) to <- max(data_subset$value_of_interest, na.rm = TRUE) xlim = range(data_subset$value_of_interest) data_true <- subset(data_subset, (PMD_FDR_decoy==0) & (PMD_FDR_input_score==100)) data_false <- subset(data_subset, (PMD_FDR_decoy==1)) d_true <- with(data_true , density(value_of_interest, from = from, to = to, na.rm = TRUE)) d_false <- with(data_false, density(value_of_interest, from = from, to = to, na.rm = TRUE)) d_true <- normalize_density(d_true) d_false <- normalize_density(d_false) densities <- list(d_true=d_true, d_false=d_false, var_value = var_value, n_true = nrow(data_true), n_false = nrow(data_false)) return(densities) } get_xlim <- function(densities_a = NULL, densities_b = NULL, show_norm=NULL){ xlim <- range(c( densities_a$d_true$x, densities_a$d_false$y)) if (show_norm){ xlim <- range(c(xlim, densities_b$d_true$x, densities_b$d_false$y)) } return(xlim) } get_ylim <- function(densities_a = NULL, densities_b = NULL, show_norm=NULL){ ylim <- range(c( densities_a$d_true$y, densities_a$d_false$y)) if (show_norm){ ylim <- range(c(ylim, densities_b$d_true$y, densities_b$d_false$y)) } return(ylim) } plot_distributions <- function(densities = NULL, var_value= NULL, dataset_name = NULL, ...){ leg = list() leg$leg = c("Good", "Bad") if (display_n_psms){ leg$leg = sprintf("%s (%d PSMs)", leg$leg, c(densities$n_true, densities$n_false)) } leg$col = c("black", "red") leg$lwd = c(3 , 3) leg$lty = c(1 , 2) leg$title = "Hit Category" xlab = ifelse(var_value == "value", "PMD (ppm)", "PMD - normalized (ppm)") ylab = "Density" if (!include_text){ xlab = "" ylab = "" } plot( densities$d_true , col=leg$col[1], lwd=leg$lwd[1] * scale, lty=leg$lty[1], xaxt = "n", yaxt = "n", main=main, xlab = xlab, ylab=ylab, ...) lines(densities$d_false, col=leg$col[2], lwd=leg$lwd[2] * scale, lty=leg$lty[2]) abline(v=0, h=0, col="gray", lwd=1*scale) if (include_text){ legend_object <- Legend_Object$new(leg, scale) legend_object$show() #legend("topleft", legend=leg.leg, col=leg.col, lwd=leg.lwd, lty=leg.lty, x.intersp = x.intersp, y.intersp = y.intersp) } } # Main code block for plot_compare_PMD_and_norm_density data_processor <- data_processors[[1]] data_processor$data_groups$ensure() data_groups <- data_processor$data_groups$df data_subset_a <- subset(data_groups , used_to_find_middle == FALSE) data_subset_b <- subset(data_subset_a, PMD_FDR_peptide_length > 11) densities_a <- get_densities(data_subset = data_subset_a, var_value = "value") densities_b <- get_densities(data_subset = data_subset_b, var_value = "value_norm") xlim=get_xlim(densities_a, densities_b, show_norm = show_norm) ylim=get_ylim(densities_a, densities_b, show_norm = show_norm) dataset_name <- data_processor$info$collection_name plot_distributions( densities=densities_a, var_value = "value" , dataset_name = dataset_name, xlim=xlim, ylim=ylim) if (show_norm){ plot_distributions(densities=densities_b, var_value = "value_norm", dataset_name = dataset_name, xlim=xlim, ylim=ylim) } }, get_n = function(){ data_processor <- data_processors[[1]] data_processor$data_groups$ensure() data_subset_a <- subset(data_processor$data_groups$df , used_to_find_middle == FALSE) data_subset_b <- subset(data_subset_a, PMD_FDR_peptide_length > 11) if (show_norm){ data_subset <- data_subset_a } else { data_subset <- data_subset_b } data_true <- subset(data_subset, (PMD_FDR_decoy==0) & (PMD_FDR_input_score==100)) data_false <- subset(data_subset, (PMD_FDR_decoy==1)) return(nrow(data_true) + nrow(data_false)) } ) ############################################################################### # Class: Plot_Time_Invariance_Alt ############################################################################### Plot_Time_Invariance_Alt = setRefClass("Plot_Time_Invariance_Alt", contains = "Plot_Image", fields = list(show_norm = "logical", display_n_psms = "logical", training_class = "character", ylim = "numeric", field_of_interest = "character")) Plot_Time_Invariance_Alt$methods( initialize = function(p_ylim=NULL, p_training_class=NULL, p_field_of_interest="value_norm", ...){ get_subset_title <- function(training_class=NULL){ if (training_class == "bad_long"){ subset_title="bad only" } else if (training_class == "good_testing"){ subset_title="good-testing only" } else if (training_class == "good_training"){ subset_title="good-training only" } else if (training_class == "other"){ subset_title="other only" } else { stop("Unexpected training_class in plot_time_invariance") } return(subset_title) } ylim <<- p_ylim training_class <<- p_training_class field_of_interest <<- p_field_of_interest subset_title <- get_subset_title(training_class=training_class) backup_title <- sprintf("Middle 25%% PMD for spectra sorted by index%s", ifelse(is.null(subset_title), "", sprintf(" - %s", subset_title))) #plot_title <<- get_main(main_title=main, backup_title=backup_title, data_collection = data_collection) plot_title <<- backup_title callSuper(...) }, plot_image = function(){ # Support functions for plot_time_invariance() # Main code of plot_time_invariance() data_subset = get_data_subset() plot_group_spectrum_index_from_subset_boxes(data_subset = data_subset) abline(h=0, col="blue", lwd=scale) }, get_data_subset = function(){ data_processor <- data_processors[[1]] data_processor$data_groups$ensure() return(subset(data_processor$data_groups$df, (group_training_class==training_class))) }, get_n = function(){ return(nrow(get_data_subset())) }, plot_group_spectrum_index_from_subset_boxes = function(data_subset = NULL){ n_plot_groups <- 100 field_name_text <- ifelse(field_of_interest=="value", "PMD", "Translated PMD") new_subset <- data_subset new_subset$value_of_interest <- new_subset[,field_of_interest] new_subset <- new_subset[order(new_subset$PMD_FDR_spectrum_index),] idxs <- round_to_tolerance(seq(from=1, to=nrow(new_subset), length.out = n_plot_groups+1), 1) idxs_left <- idxs[-(n_plot_groups+1)] idxs_right <- idxs[-1] - 1 idxs_right[n_plot_groups] <- idxs_right[n_plot_groups] + 1 new_subset$plot_group <- NA for (i in 1:n_plot_groups){ new_subset$plot_group[idxs_left[i]:idxs_right[i]] <- i } xleft <- aggregate(PMD_FDR_spectrum_index ~plot_group, data=new_subset, FUN=min) xright <- aggregate(PMD_FDR_spectrum_index ~plot_group, data=new_subset, FUN=max) ybottom <- aggregate(value_of_interest~plot_group, data=new_subset, FUN=function(x){quantile(x, probs = 0.5 - (0.25/2))}) ytop <- aggregate(value_of_interest~plot_group, data=new_subset, FUN=function(x){quantile(x, probs = 0.5 + (0.25/2))}) boxes <- merge( rename_column(xleft , "PMD_FDR_spectrum_index" , "xleft"), merge( rename_column(xright , "PMD_FDR_spectrum_index" , "xright"), merge(rename_column(ybottom, "value_of_interest", "ybottom"), rename_column(ytop , "value_of_interest", "ytop")))) xlab <- "Spectrum Index" ylab <- sprintf("%s (ppm)", field_name_text ) if (is.null(ylim)){ ylim <<- range(new_subset$value_of_interest) } if (!include_text){ xlab="" ylab="" } plot(value_of_interest~PMD_FDR_spectrum_index, data=new_subset, type="n", ylim=ylim, xlab = xlab, ylab=ylab, main=main, xaxt="n", yaxt="n") with(boxes, rect(xleft = xleft, ybottom = ybottom, xright = xright, ytop = ytop, lwd=scale)) #points(median_of_group_index~PMD_FDR_spectrum_index, data=data_subset, cex=.5, pch=15) axis(1, labels=include_text, lwd=scale) axis(2, labels=include_text, lwd=scale) box(lwd=scale) #box around plot area } ) ############################################################################### # Class: Plot_Time_Invariance_Alt_Before_and_After ############################################################################### Plot_Time_Invariance_Alt_Before_and_After = setRefClass("Plot_Time_Invariance_Alt_Before_and_After", contains = "Plot_Multiple_Images", fields = list()) Plot_Time_Invariance_Alt_Before_and_After$methods( initialize = function(p_data_processors = NULL, p_include_text=TRUE, p_include_main=FALSE, p_ylim = c(-4,4), ...){ plot_object1 <- Plot_Time_Invariance_Alt$new(p_data_processors = p_data_processors, p_include_text=p_include_text, p_include_main=p_include_main, p_training_class = "good_testing", p_field_of_interest = "value", p_ylim = p_ylim) plot_object2 <- Plot_Time_Invariance_Alt$new(p_data_processors = p_data_processors, p_include_text=p_include_text, p_include_main=p_include_main, p_training_class = "good_testing", p_field_of_interest = "value_norm", p_ylim = p_ylim) callSuper(p_n_images_wide=1, p_n_images_tall=2, p_include_text=p_include_text, p_include_main=p_include_main, p_image_list = list(plot_object1, plot_object2), ...) } ) ############################################################################### # Class: Plot_Density_PMD_and_Norm_Decoy_by_AA_Length ############################################################################### Plot_Density_PMD_and_Norm_Decoy_by_AA_Length = setRefClass("Plot_Density_PMD_and_Norm_Decoy_by_AA_Length", contains = "Plot_Image", fields = list(show_norm = "logical")) Plot_Density_PMD_and_Norm_Decoy_by_AA_Length$methods( initialize = function(p_show_norm=FALSE, ...){ plot_title <<- "The Decoy Bump: PMD Distribution of Decoy matches by peptide length" show_norm <<- p_show_norm callSuper(...) }, get_n = function(){ data_processor <- data_processors[[1]] data_processor$data_groups$ensure() data_subset <- subset(data_processor$data_groups$df, (PMD_FDR_decoy == 1)) return(nrow(data_subset)) }, plot_image = function(){ # Support functions for plot_density_PMD_and_norm_decoy_by_aa_length() add_group_peptide_length_special <- function(){ data_processor <- data_processors[[1]] data_processor$data_groups$ensure() data_groups <- data_processor$data_groups$df # the name data_groups is a data.frame instead of a Data_Object data_groups <- subset(data_groups, used_to_find_middle == FALSE) df_group_definition <- data.frame(stringsAsFactors = FALSE, list(group_peptide_length_special = c("06-08", "09-10", "11-12", "13-15", "16-20", "21-50"), min = c( 6 , 9 , 11 , 13 , 16 , 21 ), max = c( 8 , 10 , 12 , 15 , 20 , 50 ) )) group_peptide_length_special <- data.frame(list(PMD_FDR_peptide_length = 6:50)) group_peptide_length_special$min <- with(group_peptide_length_special, sapply(PMD_FDR_peptide_length, FUN = function(i) max(df_group_definition$min[df_group_definition$min <= i]))) group_peptide_length_special <- merge(group_peptide_length_special, df_group_definition) data_groups$group_peptide_length_special <- NULL new_data_groups <- (merge(data_groups, group_peptide_length_special[,c("PMD_FDR_peptide_length", "group_peptide_length_special")])) return(new_data_groups) } get_densities <- function(data_subset = NULL, field_value = NULL, field_group=NULL){ get_density_from_subset <- function(data_subset=NULL, xlim=NULL){ d_group <- with(data_subset , density(value_of_interest, from = xlim[1], to = xlim[2], na.rm=TRUE)) d_group <- normalize_density(d_group) return(d_group) } data_temp <- data_subset data_temp$value_of_interest <- data_temp[[field_value]] data_temp$group_of_interest <- data_temp[[field_group]] xlim = range(data_temp$value_of_interest, na.rm=TRUE) groups <- sort(unique(data_temp$group_of_interest)) n_groups <- length(groups) d_group <- get_density_from_subset( data_subset=data_temp, xlim = xlim ) densities <- list("All decoys" = d_group) for (i in 1:n_groups){ group <- groups[i] d_group <- get_density_from_subset( data_subset=subset(data_temp, (group_of_interest == group)), xlim = xlim ) densities[[group]] <- d_group } return(densities) } get_limits <- function(densities_a = NULL, densities_b = NULL){ xlim = c() ylim = c(0) for (single_density in densities_a){ xlim=range(c(xlim, single_density$x)) ylim=range(c(ylim, single_density$y)) } for (single_density in densities_b){ xlim=range(c(xlim, single_density$x)) ylim=range(c(ylim, single_density$y)) } return(list(xlim=xlim, ylim=ylim)) } plot_distributions <- function(data_groups = NULL, xlim=NULL, ylim=NULL, densities = NULL, field_group= NULL, field_value = "value", xlab_modifier = "", var_value= NULL, include_peak_dots=TRUE, dataset_name = NULL, ...){ data_groups$group_of_interest <- data_groups[[field_group]] data_groups$value_of_interest <- data_groups[[field_value]] # Main body of plot_decoy_distribution_by_field_of_interest() FIXED_LWD=3 groups <- sort(unique(data_groups$group_of_interest)) n <- length(groups) df_leg <- data.frame(stringsAsFactors = FALSE, list(leg = groups, col = rainbow_with_fixed_intensity(n = n, goal_intensity_0_1 = 0.4), lty = rep(1:6, length.out=n), lwd = rep(FIXED_LWD , n)) ) d <- densities[["All decoys"]] xlab = sprintf("Precursor Mass Discrepancy%s (ppm)", xlab_modifier) ylab = "Density" if (!include_text){ xlab="" ylab="" } plot(d, lwd=FIXED_LWD * scale, main=main, xlab=xlab, ylab=ylab, xlim=xlim, ylim=ylim, xaxt="n", yaxt="n") ave_peak <- max(d$y) max_peak <- 0 for (local_group in groups){ data_subset <- subset(data_groups, group_of_interest == local_group) data_info <- subset(df_leg , leg == local_group) col <- data_info$col[1] lty <- data_info$lty[1] lwd <- data_info$lwd[1] if (nrow(data_subset) > 100){ d <- densities[[local_group]] #density(data_subset[[field_value]]) lines(d, col=col, lty=lty, lwd=lwd * scale) peak <- max(d$y) max_peak <- max(max_peak, peak) } } abline(v=0, h=0, lwd=scale) leg <- list(title = "Peptide length (aa)", leg = c("All decoys" , df_leg$leg), col = c(col2hex("black") , df_leg$col), lty = c(1 , df_leg$lty), lwd = c(FIXED_LWD , df_leg$lwd) ) if (include_text){ legend_object = Legend_Object$new(leg, scale) legend_object$show() #first_legend = legend(x="topleft", title = "", legend = leg$leg, col = leg$col, lty = leg$lty, lwd = leg$lwd, seg.len=leg$seg.len, box.lwd=leg$box.lwd, x.intersp = leg$x.intersp, y.intersp = leg$y.intersp) #new_x = first_legend$rect$left #new_y = first_legend$rect$top + first_legend$rect$h * .07 * (2 - scale) #legend(x=new_x, y=new_y, title = leg$title, legend = "", cex=1.15, bty="n") } box(lwd=scale) #box around plot area } # Main body for plot_density_PMD_and_norm_decoy_by_aa_length() data_mod <- add_group_peptide_length_special() data_mod <- subset(data_mod, PMD_FDR_decoy==1) densities_a <- get_densities(data_subset = data_mod, field_value = "value" , field_group = "group_peptide_length_special") densities_b <- get_densities(data_subset = data_mod, field_value = "value_norm", field_group = "group_peptide_length_special") data_processor <- data_processors[[1]] dataset_name <- data_processor$info$collection_name() limits <- get_limits(densities_a, densities_b) xlim <- limits$xlim ylim <- limits$ylim if (show_norm){ plot_distributions(data_groups = data_mod, densities=densities_b, field_value = "value_norm", xlab_modifier = " - normalized", field_group = "group_peptide_length_special", dataset_name=dataset_name, xlim=xlim, ylim=ylim) } else { plot_distributions(data_groups = data_mod, densities=densities_a, field_value = "value" , xlab_modifier = "" , field_group = "group_peptide_length_special", dataset_name=dataset_name, xlim=xlim, ylim=ylim) } } ) ############################################################################### # Class: Plot_Bad_CI ############################################################################### Plot_Bad_CI = setRefClass("Plot_Bad_CI", contains = "Plot_Image", fields = list(breaks = "numeric", ylim = "numeric")) Plot_Bad_CI$methods( initialize = function(p_breaks=20, p_ylim=NULL, ...){ if (is.null(p_ylim)){ ylim <<- numeric(0) } else { ylim <<- p_ylim } breaks <<- p_breaks plot_title <<- "Credible Intervals for proportion within range - bad" callSuper(...) }, data_processor = function(){ return(data_processors[[1]]) }, get_n = function(){ data_processor()$data_groups$ensure() return(nrow(subset(data_processor()$data_groups$df, (PMD_FDR_decoy == 1)))) }, plot_image = function(){ data_processor()$data_groups$ensure() data_groups <- data_processor()$data_groups$df data_decoy <- subset(data_groups, data_groups$group_training_class == "bad_long") data_decoy$region <- cut(x = data_decoy$value, breaks = breaks) table(data_decoy$region) regions <- unique(data_decoy$region) N = nrow(data_decoy) find_lower_ci_bound <- function(x){ ci <- credible_interval(length(x), N, precision = 0.001, alpha=0.05) return(ci[1]) } find_upper_ci_bound <- function(x){ ci <- credible_interval(length(x), N, precision = 0.001, alpha=0.05) return(ci[2]) } xleft <- aggregate(value~region, data=data_decoy, FUN=min) xright <- aggregate(value~region, data=data_decoy, FUN=max) ytop <- aggregate(value~region, data=data_decoy, FUN=find_upper_ci_bound) ybottom <- aggregate(value~region, data=data_decoy, FUN=find_lower_ci_bound) xleft <- rename_column(xleft , "value", "xleft" ) xright <- rename_column(xright , "value", "xright" ) ytop <- rename_column(ytop , "value", "ytop" ) ybottom <- rename_column(ybottom, "value", "ybottom") boxes <- merge(merge(xleft, xright), merge(ytop, ybottom)) xlab <- "Precursor Mass Discrepancy (ppm)" ylab <- "Proportion of PSMs\nin subgroup" xlim=range(data_decoy$value, na.rm = TRUE) get_ylim(boxes=boxes) if (!include_text){ xlab="" ylab="" } plot(x=c(-10,10), y=c(0,1), type="n", ylim=ylim, xlim=xlim, xlab=xlab, ylab=ylab, main=main, xaxt="n", yaxt="n") with(boxes, rect(xleft=xleft, xright=xright, ytop=ytop, ybottom=ybottom, lwd=scale)) abline(h=1/breaks, col="blue", lwd=scale) }, get_ylim = function(boxes=NULL){ is_valid_range <- function(r=NULL){ return(length(r) == 2) } if (! is_valid_range(ylim)){ ylim <<- range(c(0,boxes$ytop, boxes$ybottom)) } } ) ############################################################################### # Class: Plot_Selective_Loss ############################################################################### Plot_Selective_Loss = setRefClass("Plot_Selective_Loss", contains = "Plot_Image", fields = list()) Plot_Selective_Loss$methods( initialize = function( ...){ plot_title <<- "PMD-FDR Selectively removes Bad Hits" callSuper(...) }, data_processor = function(){ return(data_processors[[1]]) }, get_n = function(){ data_processor()$i_fdr$ensure() data_subset <- data_processor()$i_fdr$df return(nrow(data_subset)) }, plot_image = function(){ # Support functions for plot_selective_loss() samples_lost_by_threshold <- function(updated_i_fdr=NULL, score_threshold=NULL){ data_subset <- subset(updated_i_fdr, PMD_FDR_input_score >= score_threshold) tbl <- with(updated_i_fdr, table(PMD_FDR_input_score >= score_threshold, new_confidence < score_threshold, group_decoy_proteins)) df <- data.frame(tbl) df_n <- aggregate(Freq~group_decoy_proteins+Var1, data=df, FUN=sum) df_n <- rename_column(df_n, name_before = "Freq", "n") df <- merge(df, df_n) df$rate_of_loss <- with(df, Freq/n) df <- subset(df, (Var1==TRUE) & (Var2==TRUE)) df <- df[,c("group_decoy_proteins", "rate_of_loss", "n", "Freq")] if (nrow(df) > 0){ df$score_threshold <- score_threshold } return(df) } get_loss_record <- function(updated_i_fdr=NULL, score_thresholds=NULL){ df=data.frame() for (score_threshold in score_thresholds){ df_new_loss <- samples_lost_by_threshold(updated_i_fdr, score_threshold) df <- rbind(df, df_new_loss) } return(df) } # Main code for plot_selective_loss() updated_i_fdr <- data_processor()$i_fdr$df updated_i_fdr$new_confidence <- with(updated_i_fdr, 100 * (1-i_fdr)) #ifelse((1-i_fdr) < (PMD_FDR_input_score / 100), (1-i_fdr), (PMD_FDR_input_score/100))) loss_record <- get_loss_record(updated_i_fdr=updated_i_fdr, score_thresholds = 1:100) xlim <- with(loss_record, range(score_threshold)) ylim <- c(0,1) xlab <- "Fixed Confidence threshold (PeptideShaker score)" ylab <- "Rate of PSM disqualification from PMD-FDR" lwd <- 4 plot(x=xlim, y=ylim, type="n", main=main, xlab=xlab, ylab=ylab) groups <- sort(unique(loss_record$group_decoy_proteins)) n_g <- length(groups) cols <- rainbow_with_fixed_intensity(n=n_g, goal_intensity_0_1 = 0.5, alpha = 1) ltys <- rep(1:6, length.out=n_g) leg <- list(leg=groups, col=cols, lty=ltys, lwd=lwd, title="Species/Category") for (i in 1:n_g){ lines(rate_of_loss~score_threshold, data=subset(loss_record, group_decoy_proteins==leg$leg[i]), col=leg$col[i], lwd=leg$lwd * scale, lty=leg$lty[i]) } abline(h=0, v=100, lwd=scale) abline(h=c(0.1, 0.8), col="gray", lwd=scale) #leg = list(leg=group, col=col, lty=lty, lwd=lwd) #with(leg, legend(x = "topleft", legend = group, col = col, lty = lty, lwd = lwd, seg.len = seg.len)) legend_object <- Legend_Object$new(leg, scale) legend_object$show() } ) ############################################################################### # Class: Plot_Selective_Loss_for_TOC ############################################################################### Plot_Selective_Loss_for_TOC = setRefClass("Plot_Selective_Loss_for_TOC", contains = "Plot_Image", fields = list(xlab="character", ylab="character", title_x="numeric", title_y="numeric", legend_border="logical", legend_x = "numeric", legend_y = "numeric", legend_title="character", legend_location = "character", name_contaminant = "character", name_decoy = "character", name_human = "character", name_pyro = "character")) Plot_Selective_Loss_for_TOC$methods( initialize = function( ...){ plot_title <<- "PMD-FDR selectively removes bad hits" callSuper(...) xlab <<- "Confidence threshold (PeptideShaker)" ylab <<- "PMD Disqualifiction Rate" legend_border <<- FALSE #legend_title <<- "Species/Category" title_x <<- 50 title_y <<- 0.9 legend_x <<- 10 legend_y <<- 0.75 name_contaminant <<- "signal - contaminant" name_decoy <<- "decoy - reversed" name_human <<- "decoy - human" name_pyro <<- "signal - pyrococcus" }, data_processor = function(){ return(data_processors[[1]]) }, get_n = function(){ data_processor()$i_fdr$ensure() data_subset <- data_processor()$i_fdr$df return(nrow(data_subset)) }, plot_image = function(){ # Support functions for plot_selective_loss() samples_lost_by_threshold <- function(updated_i_fdr=NULL, score_threshold=NULL){ data_subset <- subset(updated_i_fdr, PMD_FDR_input_score >= score_threshold) tbl <- with(updated_i_fdr, table(PMD_FDR_input_score >= score_threshold, new_confidence < score_threshold, group_decoy_proteins)) df <- data.frame(tbl) df_n <- aggregate(Freq~group_decoy_proteins+Var1, data=df, FUN=sum) df_n <- rename_column(df_n, name_before = "Freq", "n") df <- merge(df, df_n) df$rate_of_loss <- with(df, Freq/n) df <- subset(df, (Var1==TRUE) & (Var2==TRUE)) df <- df[,c("group_decoy_proteins", "rate_of_loss", "n", "Freq")] if (nrow(df) > 0){ df$score_threshold <- score_threshold } return(df) } get_loss_record <- function(updated_i_fdr=NULL, score_thresholds=NULL){ df=data.frame() for (score_threshold in score_thresholds){ df_new_loss <- samples_lost_by_threshold(updated_i_fdr, score_threshold) df <- rbind(df, df_new_loss) } return(df) } convert_groups <- function(groups=NULL){ new_groups <- groups new_groups <- gsub(pattern = "contaminant", replacement = name_contaminant, x = new_groups) new_groups <- gsub(pattern = "decoy" , replacement = name_decoy , x = new_groups) new_groups <- gsub(pattern = "human" , replacement = name_human , x = new_groups) new_groups <- gsub(pattern = "pyrococcus" , replacement = name_pyro , x = new_groups) return(new_groups) } # Main code for plot_selective_loss() updated_i_fdr <- data_processor()$i_fdr$df updated_i_fdr$new_confidence <- with(updated_i_fdr, 100 * (1-i_fdr)) #ifelse((1-i_fdr) < (PMD_FDR_input_score / 100), (1-i_fdr), (PMD_FDR_input_score/100))) loss_record <- get_loss_record(updated_i_fdr=updated_i_fdr, score_thresholds = 1:100) xlim <- with(loss_record, range(score_threshold)) ylim <- c(0,1) #xlab <- "Fixed Confidence threshold (PeptideShaker score)" #ylab <- "Rate of PSM disqualification from PMD-FDR" lwd <- 4 plot(x=xlim, y=ylim, type="n", main=main, xlab=xlab, ylab=ylab) groups <- sort(unique(loss_record$group_decoy_proteins)) n_g <- length(groups) cols <- rainbow_with_fixed_intensity(n=n_g, goal_intensity_0_1 = 0.5, alpha = 1) ltys <- rep(1:6, length.out=n_g) bty <- ifelse(legend_border, "o", "n") leg <- list(leg=convert_groups(groups), var_name=groups, col=cols, lty=ltys, lwd=lwd, bty=bty, x=legend_x, y=legend_y) #leg <- list(leg=groups, col=cols, lty=ltys, lwd=lwd, bty=bty, x=legend_x, y=legend_y) for (i in 1:n_g){ lines(rate_of_loss~score_threshold, data=subset(loss_record, group_decoy_proteins==leg$var_name[i]), col=leg$col[i], lwd=leg$lwd * scale, lty=leg$lty[i]) } abline(h=0, v=100, lwd=scale) abline(h=c(0.1, 0.8), col="gray", lwd=scale) #leg = list(leg=group, col=col, lty=lty, lwd=lwd) #with(leg, legend(x = "topleft", legend = group, col = col, lty = lty, lwd = lwd, seg.len = seg.len)) legend_object <- Legend_Object$new(leg, scale) legend_object$show() text(x=title_x, y=title_y, labels = plot_title) } ) ############################################################################### # Class: Plot_Compare_iFDR_Confidence_1_Percent_TD_FDR ############################################################################### Plot_Compare_iFDR_Confidence_1_Percent_TD_FDR = setRefClass("Plot_Compare_iFDR_Confidence_1_Percent_TD_FDR", contains = "Plot_Image", fields = list()) Plot_Compare_iFDR_Confidence_1_Percent_TD_FDR$methods( initialize = function( ...){ plot_title <<- "Precursor Mass Discrepance i-FDR for 1% Target-Decoy FDR PSMs" callSuper(...) }, data_processor = function(){ return(data_processors[[1]]) }, get_n = function(){ data_processor()$i_fdr$ensure() if (one_percent_calculation_exists()){ i_fdr <- data_processor()$i_fdr$df data_subset <- subset(i_fdr, is_in_1percent==TRUE) n <- nrow(data_subset) } else { n <- 0 } return (n) }, plot_image = function(){ if (one_percent_calculation_exists()){ i_fdr <- get_modified_fdr() report_good_discrepancies(i_fdr) data_TD_good <- get_data_TD_good(i_fdr) mean_results <- get_mean_results(data_TD_good) boxes <- mean_results boxes <- rename_columns(df = boxes, names_before = c("min_conf", "max_conf", "lower" , "upper"), names_after = c("xleft" , "xright" , "ybottom", "ytop" )) xlim <- range(boxes[,c("xleft", "xright")]) ylim <- range(boxes[,c("ybottom", "ytop")]) #head(mean_results) xlab = "Confidence Score (Peptide Shaker)" ylab = "Mean PMD i-FDR" if (!include_text){ xlab="" ylab="" } plot(mean_i_fdr~mean_conf, data=mean_results, xlim=xlim, ylim=ylim, xlab=xlab, ylab=ylab, main=main, xaxt="n", yaxt="n", cex=scale, lwd=scale) with(boxes, rect(xleft = xleft, ybottom = ybottom, xright = xright, ytop = ytop, lwd=scale)) abline(b=-1, a=100, lwd=4*scale, col="dark gray") abline(h=0, v=100, lwd=1*scale) } else { stop(sprintf("Dataset '%s' does not include 1%% FDR data", data_processor()$info$collection_name())) } }, get_mean_results = function(data_TD_good = NULL){ mean_i_fdr <- aggregate(i_fdr~conf_group, data=data_TD_good, FUN=mean) mean_i_fdr <- rename_column(mean_i_fdr, "i_fdr", "mean_i_fdr") sd_i_fdr <- aggregate(i_fdr~conf_group, data=data_TD_good, FUN=sd) sd_i_fdr <- rename_column(sd_i_fdr, "i_fdr", "sd_i_fdr") n_i_fdr <- aggregate(i_fdr~conf_group, data=data_TD_good, FUN=length) n_i_fdr <- rename_column(n_i_fdr, "i_fdr", "n") mean_conf <- aggregate(PMD_FDR_input_score~conf_group, data=data_TD_good, FUN=mean) mean_conf <- rename_column(mean_conf, "PMD_FDR_input_score", "mean_conf") min_conf <- aggregate(PMD_FDR_input_score~conf_group, data=data_TD_good, FUN=min) min_conf <- rename_column(min_conf, "PMD_FDR_input_score", "min_conf") max_conf <- aggregate(PMD_FDR_input_score~conf_group, data=data_TD_good, FUN=max) max_conf <- rename_column(max_conf, "PMD_FDR_input_score", "max_conf") mean_results <- mean_i_fdr mean_results <- merge(mean_results, sd_i_fdr) mean_results <- merge(mean_results, n_i_fdr) mean_results <- merge(mean_results, mean_conf) mean_results <- merge(mean_results, min_conf) mean_results <- merge(mean_results, max_conf) mean_results$se <- with(mean_results, sd_i_fdr / sqrt(n - 1)) mean_results$lower <- with(mean_results, mean_i_fdr - 2*se) mean_results$upper <- with(mean_results, mean_i_fdr + 2*se) return(mean_results) }, get_data_TD_good = function(i_fdr=NULL){ data_TD_good <- subset(i_fdr, TD_good==TRUE) data_TD_good <- data_TD_good[order(data_TD_good$PMD_FDR_input_score),] n <- nrow(data_TD_good) data_TD_good$conf_group <- cut(1:n, breaks=floor(n/100)) data_TD_good$i_fdr <- 100 * data_TD_good$i_fdr return(data_TD_good) }, get_modified_fdr = function(){ i_fdr <- data_processor()$i_fdr$df i_fdr$PMD_good <- i_fdr$i_fdr < 0.01 i_fdr$TD_good <- i_fdr$is_in_1percent == TRUE i_fdr$conf_good <- i_fdr$PMD_FDR_input_score == 100 return(i_fdr) }, one_percent_calculation_exists = function(){ data_processor()$raw_1_percent$ensure() return(data_processor()$raw_1_percent$exists())# "is_in_1percent" %in% colnames(data_processor()$i_fdr)) }, report_good_discrepancies = function(i_fdr=NULL){ with(subset(i_fdr, (PMD_FDR_decoy == 0)), print(table(TD_good, PMD_good))) with(subset(i_fdr, (PMD_FDR_input_score==100) & (PMD_FDR_decoy == 0)), print(table(TD_good, PMD_good))) with(subset(i_fdr, (PMD_FDR_input_score>= 99) & (PMD_FDR_input_score<100) & (PMD_FDR_decoy == 0)), print(table(TD_good, PMD_good))) with(subset(i_fdr, (PMD_FDR_input_score>= 99) & (PMD_FDR_input_score<100) & (PMD_FDR_decoy == 0)), print(table(TD_good, PMD_good))) with(subset(i_fdr, (PMD_FDR_input_score>= 90) & (PMD_FDR_input_score< 99) & (PMD_FDR_decoy == 0)), print(table(TD_good, PMD_good))) } ) ############################################################################### # Class: Plot_Density_PMD_by_Score ############################################################################### Plot_Density_PMD_by_Score = setRefClass("Plot_Density_PMD_by_Score", contains = "Plot_Image", fields = list(show_norm = "logical")) Plot_Density_PMD_by_Score$methods( initialize = function(p_show_norm=FALSE, ...){ show_norm <<- p_show_norm plot_title <<- "PMD distribution, by Confidence ranges" callSuper(...) }, data_processor = function(){ return(data_processors[[1]]) }, get_n = function(){ return(nrow(data_processor()$data_groups$df)) #data_subset <- data_collection$i_fdr #return(nrow(data_subset)) }, get_modified_data_groups = function(var_value = NULL){ # Note: Filters out used_to_find_middle # Note: Creates "value_of_interest" field # Note: Remakes "group_decoy_input_score" field data_new <- data_processor()$data_groups$df data_new <- subset(data_new, !used_to_find_middle ) data_new$value_of_interest <- data_new[, var_value] cutoff_points <- c(100, 100, 95, 80, 50, 0, 0) n <- length(cutoff_points) uppers <- cutoff_points[-n] lowers <- cutoff_points[-1] for (i in 1:(n-1)){ upper <- uppers[i] lower <- lowers[i] if (lower==upper){ idx <- with(data_new, which( (PMD_FDR_input_score == upper) & (PMD_FDR_decoy == 0))) cat_name <- sprintf("%d", upper) } else { idx <- with(data_new, which((PMD_FDR_input_score >= lower) & (PMD_FDR_input_score < upper) & (PMD_FDR_decoy == 0))) cat_name <- sprintf("%02d - %2d", lower, upper) } data_new$group_decoy_input_score[idx] <- cat_name } return(data_new) }, plot_image = function(){ # Support functions for plot_density_PMD_by_score() get_densities <- function(data_subset = NULL, var_value = NULL){ # Support functions for get_densities() # New version # Main body of get_densities() data_subset <- get_modified_data_groups(var_value=var_value) #data_subset$value_of_interest <- data_subset[,var_value] from <- min(data_subset$value_of_interest, na.rm=TRUE) to <- max(data_subset$value_of_interest, na.rm=TRUE) xlim = range(data_subset$value_of_interest, na.rm=TRUE) groups <- sort(unique(data_subset$group_decoy_input_score), decreasing = TRUE) n_groups <- length(groups) densities <- list(var_value = var_value, groups=groups) for (i in 1:n_groups){ group <- groups[i] data_group_single <- subset(data_subset, (group_decoy_input_score == group)) d_group <- with(data_group_single , density(value_of_interest, from = from, to = to, na.rm = TRUE)) d_group <- normalize_density(d_group) densities[[group]] <- d_group } return(densities) } get_xlim <- function(densities_a = NULL, densities_b = NULL){ groups <- densities_a$groups xlim <- 0 for (group in groups){ xlim <- range(xlim, densities_a[[group]]$x, densities_b[[group]]$x) } return(xlim) } get_ylim <- function(densities_a = NULL, densities_b = NULL){ groups <- densities_a$groups ylim <- 0 for (group in groups){ ylim <- range(ylim, densities_a[[group]]$y, densities_b[[group]]$y) } return(ylim) } plot_distributions <- function(densities = NULL, var_value= NULL,include_peak_dots=TRUE, xlab_modifier="", xlim=NULL, ylim=NULL, ...){ data_groups <- get_modified_data_groups(var_value=var_value) groups <- sort(unique(data_groups$group_decoy_input_score)) n_groups <- length(groups) groups_std <- setdiff(groups, c("100", "decoy", "0") ) groups_std <- sort(groups_std, decreasing = TRUE) groups_std <- c(groups_std, "0") n_std <- length(groups_std) cols <- rainbow_with_fixed_intensity(n = n_std, goal_intensity_0_1 = 0.5, alpha=0.5) leg <- list(group = c("100" , groups_std , "decoy" ), leg = c("100" , groups_std , "All Decoys" ), col = c(col2hex("black") , cols , col2hex("purple", col_alpha = 0.5)), lwd = c(4 , rep(2, n_std), 4 ), title = "Confidence Score") xlab = sprintf("Precursor Mass Discrepancy%s (ppm)", xlab_modifier) ylab = "Density" if (!include_text){ xlab="" ylab="" } plot( x=xlim, y=ylim, col=leg$col[1], lwd=leg$lwd[1] * scale, main=main, xlab=xlab, ylab=ylab, xaxt="n", yaxt="n", cex=scale, type="n")#, lty=leg.lty[1], ...) include_peak_dots = FALSE # BUGBUG: Disabling this for now. Need to move this to class parameter for (i in 1:length(leg$group)){ group <- leg$group[i] d <- densities[[group]] lines(d, col=leg$col[i], lwd=leg$lwd[i] * scale) if (include_peak_dots){ x=d$x[which.max(d$y)] y=max(d$y) points(x=c(x,x), y=c(0,y), pch=19, col=leg$col[i], cex=scale) } } abline(v=0, lwd=scale) if (include_text){ legend_object = Legend_Object$new(leg, scale) legend_object$show() } } # Main body for plot_density_PMD_by_score() data_groups <- data_processor()$data_groups$df data_subset_a <- subset(data_groups , used_to_find_middle == FALSE) data_subset_b <- subset(data_subset_a, PMD_FDR_peptide_length > 11) densities_a <- get_densities(data_subset = data_subset_a, var_value = "value") densities_b <- get_densities(data_subset = data_subset_b, var_value = "value_norm") xlim=get_xlim(densities_a, densities_b) ylim=get_ylim(densities_a, densities_b) dataset_name <- data_processor()$info$collection_name() if (show_norm){ plot_distributions(densities=densities_b, var_value = "value_norm", xlab_modifier = " - normalized", xlim=xlim, ylim=ylim) } else { plot_distributions(densities=densities_a, var_value = "value" , xlab_modifier = "" , xlim=xlim, ylim=ylim) } } ) ############################################################################### # Class: Plot_Dataset_Description ############################################################################### Plot_Dataset_Description = setRefClass("Plot_Dataset_Description", contains = "Plot_Multiple_Images", fields = list(ylim_time_invariance = "numeric")) Plot_Dataset_Description$methods( initialize = function(p_data_processors = NULL, p_include_text=TRUE, p_include_main=FALSE, p_ylim_time_invariance = c(-4,4), ...){ plot_object_r1_c1 <- Plot_Time_Invariance_Alt$new(p_data_processors=p_data_processors, p_include_text=p_include_text, p_include_main=p_include_main, p_training_class = "good_testing", p_field_of_interest = "value", p_ylim = p_ylim_time_invariance) plot_object_r1_c2 <- Plot_Time_Invariance_Alt$new(p_data_processors=p_data_processors, p_include_text=p_include_text, p_include_main=p_include_main, p_training_class = "good_testing", p_field_of_interest = "value_norm", p_ylim = p_ylim_time_invariance) plot_object_r2_c1 <- Plot_Density_PMD_by_Score$new(p_data_processors=p_data_processors, p_show_norm=FALSE, p_include_text=p_include_text, p_include_main=p_include_main) plot_object_r2_c2 <- Plot_Density_PMD_and_Norm_Decoy_by_AA_Length$new(p_data_processors=p_data_processors, p_show_norm=FALSE, p_include_text=p_include_text, p_include_main=p_include_main) plot_object_r3_c1 <- Plot_Density_PMD_by_Score$new(p_data_processors=p_data_processors, p_show_norm=TRUE, p_include_text=p_include_text, p_include_main=p_include_main) plot_object_r3_c2 <- Plot_Density_PMD_and_Norm_Decoy_by_AA_Length$new(p_data_processors=p_data_processors, p_show_norm=TRUE, p_include_text=p_include_text, p_include_main=p_include_main) callSuper(p_n_images_wide=2, p_n_images_tall=3, p_include_text=p_include_text, p_include_main=p_include_main, p_image_list = list(plot_object_r1_c1, plot_object_r1_c2, plot_object_r2_c1, plot_object_r2_c2, plot_object_r3_c1, plot_object_r3_c2), ...) } ) ############################################################################### # Class: Plots_for_Paper ############################################################################### Plots_for_Paper <- setRefClass("Plots_for_Paper", fields =list(data_processor_a = "Data_Processor", data_processor_b = "Data_Processor", data_processor_c = "Data_Processor", data_processor_d = "Data_Processor", include_text = "logical", include_main = "logical", mai = "numeric")) Plots_for_Paper$methods( initialize = function(){ data_processor_a <<- Data_Processor$new(p_info = Data_Object_Info_737_two_step$new()) data_processor_b <<- Data_Processor$new(p_info = Data_Object_Info_737_combined$new()) data_processor_c <<- Data_Processor$new(p_info = Data_Object_Pyrococcus_tr $new()) data_processor_d <<- Data_Processor$new(p_info = Data_Object_Mouse_Mutations $new()) }, create_plots_for_paper = function(include_main=TRUE, finalize=TRUE){ print_table_4_data() print_figure_2_data() plot_figure_D(p_scale=ifelse(finalize, 2, 1), p_include_main = include_main) plot_figure_C(p_scale=ifelse(finalize, 2, 1), p_include_main = include_main) plot_figure_B(p_scale=ifelse(finalize, 2, 1), p_include_main = include_main) plot_figure_A(p_scale=ifelse(finalize, 2, 1), p_include_main = include_main) plot_figure_8(p_scale=ifelse(finalize, 2, 1), p_include_main = include_main) plot_figure_7(p_scale=ifelse(finalize, 2, 1), p_include_main = include_main) plot_figure_6(p_scale=ifelse(finalize, 4, 1), p_include_main = include_main) plot_figure_5(p_scale=ifelse(finalize, 2, 1), p_include_main = include_main) plot_figure_4(p_scale=ifelse(finalize, 2, 1), p_include_main = include_main) plot_figure_3(p_scale=ifelse(finalize, 4, 1), p_include_main = include_main) }, print_figure_2_data = function(){ print(create_stats_for_grouping_figure(list(data_processor_a))) }, print_table_4_data = function(){ report_ranges_of_comparisons(processors = list(data_processor_a)) report_ranges_of_comparisons(processors = list(data_processor_c)) }, plot_figure_3 = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Compare_PMD_and_Norm_Density$new(p_data_processor = list(data_processor_a), p_show_norm = FALSE, p_include_text = TRUE, p_include_main = p_include_main, p_display_n_psms = FALSE) plot_object$plot_image_in_small_window(p_scale=p_scale) }, plot_figure_4 = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Time_Invariance_Alt_Before_and_After$new(p_data_processors = list(data_processor_a), p_include_text=TRUE, p_include_main=p_include_main, p_ylim = c(-4,4)) plot_object$plot_image_in_large_window(window_height=4, p_scale=p_scale) }, plot_figure_5 = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Density_PMD_and_Norm_Decoy_by_AA_Length$new(p_data_processors = list(data_processor_a), p_include_text=TRUE, p_include_main=p_include_main) plot_object$plot_image_in_large_window(window_height=4, p_scale=p_scale) }, plot_figure_6 = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Bad_CI$new(p_data_processors = list(data_processor_a), p_include_text=TRUE, p_include_main=p_include_main) plot_object$plot_image_in_small_window(p_scale=p_scale) }, plot_figure_7 = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Compare_iFDR_Confidence_1_Percent_TD_FDR$new(p_data_processors = list(data_processor_a), p_include_text=TRUE, p_include_main=p_include_main) plot_object$plot_image_in_large_window(window_height=4, p_scale=p_scale) }, plot_figure_8 = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Selective_Loss$new(p_data_processors = list(data_processor_c), p_include_text=TRUE, p_include_main=p_include_main) plot_object$plot_image_in_large_window(window_height=4, p_scale=p_scale) }, plot_figure_A = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Dataset_Description$new(p_data_processors=list(data_processor_a), p_include_text=TRUE, p_include_main=p_include_main, p_ylim_time_invariance=c(-4,4) ) plot_object$plot_image_in_large_window(window_height=4, p_scale=p_scale) }, plot_figure_B = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Dataset_Description$new(p_data_processors=list(data_processor_b), p_include_text=TRUE, p_include_main=p_include_main, p_ylim_time_invariance=c(-4,4) ) plot_object$plot_image_in_large_window(window_height=4, p_scale=p_scale) }, plot_figure_C = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Dataset_Description$new(p_data_processors=list(data_processor_c), p_include_text=TRUE, p_include_main=p_include_main, p_ylim_time_invariance=c(-4,4) ) plot_object$plot_image_in_large_window(window_height=4, p_scale=p_scale) }, plot_figure_D = function(p_scale=NULL, p_include_main=NULL){ plot_object <- Plot_Dataset_Description$new(p_data_processors=list(data_processor_d), p_include_text=TRUE, p_include_main=p_include_main, p_ylim_time_invariance=c(-4,4) ) plot_object$plot_image_in_large_window(window_height=4, p_scale=p_scale) }, create_stats_for_grouping_figure = function(processors=NULL){ processor <- processors[[1]] processor$i_fdr$ensure() aug_i_fdr <- processor$i_fdr$df aug_i_fdr$group_good_bad_other <- gsub("_.*", "", aug_i_fdr$group_training_class) aug_i_fdr$group_null <- "all" table(aug_i_fdr$group_training_class) table(aug_i_fdr$group_good_bad_other) table(aug_i_fdr$group_null) create_agg_fdr_stats <- function(i_fdr=NULL, grouping_var_name = NULL){ formula_fdr <- as.formula(sprintf("%s~%s", "i_fdr", grouping_var_name)) formula_len <- as.formula(sprintf("%s~%s", "PMD_FDR_peptide_length", grouping_var_name)) agg_fdr <- aggregate(formula=formula_fdr, data=i_fdr, FUN=mean) agg_n <- aggregate(formula=formula_fdr, data=i_fdr, FUN=length) agg_len <- aggregate(formula=formula_len, data=i_fdr, FUN=mean) agg_fdr <- rename_columns(df = agg_fdr, names_before = c(grouping_var_name, "i_fdr"), names_after = c("group" , "fdr")) agg_n <- rename_columns(df = agg_n, names_before = c(grouping_var_name, "i_fdr"), names_after = c("group" , "n")) agg_len <- rename_columns(df = agg_len, names_before = c(grouping_var_name), names_after = c("group" )) agg <- merge(agg_fdr, agg_n) agg <- merge(agg , agg_len) return(agg) } agg_detail <- create_agg_fdr_stats(i_fdr = aug_i_fdr, grouping_var_name = "group_training_class") agg_grouped <- create_agg_fdr_stats(i_fdr = aug_i_fdr, grouping_var_name = "group_good_bad_other") agg_all <- create_agg_fdr_stats(i_fdr = aug_i_fdr, grouping_var_name = "group_null") agg <- rbind(agg_detail, agg_grouped) agg <- rbind(agg, agg_all) agg$fdr <- ifelse(agg$fdr < 1, agg$fdr, 1) linear_combo <- function(x=NULL, a0=NULL, a1=NULL){ result <- (a0 * (1-x) + a1 * x) return(result) } agg$r <- linear_combo(agg$fdr, a0=197, a1= 47) agg$g <- linear_combo(agg$fdr, a0= 90, a1= 85) agg$b <- linear_combo(agg$fdr, a0= 17, a1=151) return(agg) }, report_ranges_of_comparisons = function(processors=NULL){ report_comparison_of_Confidence_and_PMD = function (i_fdr = NULL, min_conf=NULL, max_conf=NULL, include_max=FALSE){ report_PMD_confidence_comparison_from_subset = function(data_subset=NULL, group_name=NULL){ print(group_name) print(sprintf(" Number of PSMs: %d", nrow(data_subset))) mean_confidence <- mean(data_subset$PMD_FDR_input_score) print(sprintf(" Mean Confidence Score: %3.1f", mean_confidence)) print(sprintf(" PeptideShaker g-FDR: %3.1f", 100-mean_confidence)) mean_PMD_FDR = mean(data_subset$i_fdr) print(sprintf(" PMD g-FDR: %3.1f", 100*mean_PMD_FDR)) #col <- col2hex("black", 0.2) #plot(data_subset$i_fdr, pch=".", cex=2, col=col) #abline(h=0) } if (is.null(max_conf)) { data_subset <- subset(i_fdr, PMD_FDR_input_score == min_conf) group_name <- sprintf("Group %d", min_conf) } else if (include_max){ data_subset <- subset(i_fdr, (PMD_FDR_input_score >= min_conf) & (PMD_FDR_input_score <= max_conf)) group_name <- sprintf("Group %d through %d", min_conf, max_conf) } else { data_subset <- subset(i_fdr, (PMD_FDR_input_score >= min_conf) & (PMD_FDR_input_score < max_conf)) group_name <- sprintf("Group %d to %d", min_conf, max_conf) } report_PMD_confidence_comparison_from_subset(data_subset=data_subset, group_name=group_name) } processor <- processors[[1]] processor$i_fdr$ensure() i_fdr <- processor$i_fdr$df info <- processor$info print(sprintf("PMD and Confidence comparison for -- %s", info$collection_name())) report_comparison_of_Confidence_and_PMD(i_fdr = i_fdr, min_conf=100, max_conf=NULL, include_max=TRUE) report_comparison_of_Confidence_and_PMD(i_fdr = i_fdr, min_conf= 99, max_conf=100 , include_max=FALSE) report_comparison_of_Confidence_and_PMD(i_fdr = i_fdr, min_conf= 90, max_conf= 99 , include_max=FALSE) report_comparison_of_Confidence_and_PMD(i_fdr = i_fdr, min_conf= 0, max_conf=100 , include_max=TRUE) } ) ############################################################################### # C - 021 - PMD-FDR Wrapper - functions.R # # # # Creates the necessary structure to convert the PMD-FDR code into one that # # can run as a batch file # # # ############################################################################### ############################################################################### # Class: ModuleArgParser_PMD_FDR ############################################################################### ModuleArgParser_PMD_FDR <- setRefClass("ModuleArgParser_PMD_FDR", contains = c("ArgParser"), fields =list(args = "character") ) ModuleArgParser_PMD_FDR$methods( initialize = function(description = "Computes individual and global FDR using Precursor Mass Discrepancy (PMD-FDR)", ...){ callSuper(description=description, ...) local_add_argument("--psm_report" , help="full name and path to the PSM report") local_add_argument("--psm_report_1_percent", default = "" , help="full name and path to the PSM report for 1% FDR") local_add_argument("--output_i_fdr" , default = "" , help="full name and path to the i-FDR output file ") local_add_argument("--output_g_fdr" , default = "" , help="full name and path to the g-FDR output file ") local_add_argument("--output_densities" , default = "" , help="full name and path to the densities output file ") #local_add_argument("--score_field_name" , default = "" , help="name of score field (in R format)") local_add_argument("--input_file_type" , default = "PMD_FDR_input_file", help="type of input file (currently supports: PMD_FDR_file_type, PSM_Report, MaxQuant_Evidence)") } )############################################################################### # Class: Data_Object_Parser ############################################################################### Data_Object_Parser <- setRefClass("Data_Object_Parser", contains = c("Data_Object"), fields =list(parser = "ModuleArgParser_PMD_FDR", args = "character", parsing_results = "list") ) Data_Object_Parser$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Parser" }, verify = function(){ # Nothing to do here - parser handles verification during load }, m_load_data = function(){ if (length(args) == 0){ parsing_results <<- parser$parse_arguments(NULL) } else { parsing_results <<- parser$parse_arguments(args) } }, set_args = function(p_args=NULL){ # This is primarily used for testing. In operation arguments will be passed automatically (through use of commandArgs) args <<- p_args set_dirty(TRUE) } ) ############################################################################### # Class: Data_Object_Info_Parser ############################################################################### Data_Object_Info_Parser <- setRefClass("Data_Object_Info_Parser", contains = c("Data_Object_Info"), fields =list( output_i_fdr = "character", output_g_fdr = "character", output_densities = "character" ) ) Data_Object_Info_Parser$methods( initialize = function(){ callSuper() class_name <<- "Data_Object_Info_Parser" }, verify = function(){ check_field_exists = function(field_name=NULL, check_empty = TRUE){ field_value <- get_parser()$parsing_results[field_name] checkTrue(! is.null(field_value), msg = sprintf("Parameter %s was not passed to PMD_FDR", field_value)) if (check_empty){ checkTrue(! is.null(field_value), msg = sprintf("Parameter %s was not passed to PMD_FDR", field_value)) } } # Check parameters passed in check_field_exists("junk") check_field_exists("psm_report") check_field_exists("psm_report_1_percent", check_empty = FALSE) check_field_exists("output_i_fdr" , check_empty = FALSE) check_field_exists("output_g_fdr" , check_empty = FALSE) check_field_exists("output_densities" , check_empty = FALSE) #check_field_exists("score_field_name") check_field_exists("input_file_type") }, m_load_data = function(){ parsing_results <- get_parser()$parsing_results data_file_name <<- as.character(parsing_results["psm_report"]) data_file_name_1_percent_FDR <<- as.character(parsing_results["psm_report_1_percent"]) data_path_name <<- as.character(parsing_results[""]) #experiment_name <<- data_file_name #designation <<- "" output_i_fdr <<- as.character(parsing_results["output_i_fdr"]) output_g_fdr <<- as.character(parsing_results["output_g_fdr"]) output_densities <<- as.character(parsing_results["output_densities"]) input_file_type <<- as.character(parsing_results["input_file_type"]) #score_field_name <<- as.character(parsing_results["score_field_name"]) }, set_parser = function(parser){ parents[["parser"]] <<- parser }, get_parser = function(){ return(verified_element_of_list(parents, "parser", "Data_Object_Info_Parser$parents")) }, file_path = function(){ result <- data_file_name # Now assumes that full path is provided if (length(result) == 0){ stop("Unable to validate file path - file name is missing") } return(result) }, file_path_1_percent_FDR = function(){ local_file_name <- get_data_file_name_1_percent_FDR() if (length(local_file_name) == 0){ result <- "" } else { result <- local_file_name # path name is no longer relevant } # Continue even if file name is missing - not all analyses have a 1 percent FDR file; this is managed downstream # if (length(result) == 0){ # stop("Unable to validate file path - one or both of path name and file name (of 1 percent FDR file) are missing") # } return(result) }, get_data_file_name_1_percent_FDR = function(){ return(data_file_name_1_percent_FDR) }, collection_name = function(){ result <- "" return(result) } ) ############################################################################### # Class: Processor_PMD_FDR_for_Galaxy # Purpose: Wrapper on tools from Project 019 to enable a Galaxy-based interface ############################################################################### Processor_PMD_FDR_for_Galaxy <- setRefClass("Processor_PMD_FDR_for_Galaxy", fields = list( parser = "Data_Object_Parser", info = "Data_Object_Info_Parser", raw_data = "Data_Object_Raw_Data", raw_1_percent = "Data_Object_Raw_1_Percent", data_converter = "Data_Object_Data_Converter", data_groups = "Data_Object_Groupings", densities = "Data_Object_Densities", alpha = "Data_Object_Alpha", i_fdr = "Data_Object_Individual_FDR" )) Processor_PMD_FDR_for_Galaxy$methods( initialize = function(){ # This initialization defines all of the dependencies between the various components # (Unfortunately, inheriting from Data_Processor leads to issues - I had to reimplement it here with a change to "info") # info info$set_parser(parser) parser$append_child(info) # raw_data raw_data$set_info(info) info$append_child(raw_data) # raw_1_percent raw_1_percent$set_info(info) info$append_child(raw_1_percent) # data_converter data_converter$set_info (info) data_converter$set_raw_data(raw_data) info $append_child (data_converter) raw_data $append_child (data_converter) # data_groups data_groups$set_info (info) data_groups$set_data_converter(data_converter) data_groups$set_raw_1_percent (raw_1_percent) info $append_child (data_groups) data_converter$append_child (data_groups) raw_1_percent $append_child (data_groups) # densities densities $set_data_groups(data_groups) data_groups$append_child (densities) # alpha alpha $set_densities(densities) densities$append_child (alpha) # i_fdr i_fdr$set_data_groups(data_groups) i_fdr$set_densities (densities) i_fdr$set_alpha (alpha) data_groups $append_child(i_fdr) densities $append_child(i_fdr) alpha $append_child(i_fdr) }, compute = function(){ #i_fdr is currently the lowest level object - it ultimately depends on everything else. i_fdr$ensure() # All pieces on which i_fdr depends are automatically verified and computed (through their verify() and ensure()) save_standard_df(x = densities$df, file_path = info$output_densities) save_standard_df(x = alpha$df, file_path = info$output_g_fdr) save_standard_df(x = i_fdr$df, file_path = info$output_i_fdr) } ) ############################################################################### # D - 021 - PMD-FDR Main.R # # # # File Description: Contains the base code that interprets the parameters # # and computes i-FDR and g-FDR for a mass spec project # # # ############################################################################### argv <- commandArgs(TRUE) # Saves the parameters (command code) processor <- Processor_PMD_FDR_for_Galaxy$new() processor$parser$set_args(argv) processor$compute()