{
"contents" : "#Copyright 2012 The Board of Regents of the University of Wisconsin System.\n#Contributors: Jason Shao, James McCurdy, Enhai Xie, Adam G.W. Halstead, \n#Michael H. Whitney, Nathan DiPiazza, Trey K. Sato and Yury V. Bukhman\n#\n#This file is part of GCAT.\n#\n#GCAT is free software: you can redistribute it and/or modify\n#it under the terms of the GNU Lesser General Public License as published by\n#the Free Software Foundation, either version 3 of the License, or\n#(at your option) any later version.\n#\n#GCAT is distributed in the hope that it will be useful,\n#but WITHOUT ANY WARRANTY; without even the implied warranty of\n#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n#GNU Lesser General Public License for more details.\n#\n#You should have received a copy of the GNU Lesser General Public License \n#along with GCAT. If not, see .\n\n########################################################################\n# #\n# Normalize OD readings for an entire array of well objects #\n# #\n########################################################################\n#\n# Note: This function does not write any new OD values to the well objects in the array - it only \n# fills the \"norm\" slot of each well object in the array with a value that will be subtracted \n# from all OD measurements when returning data from the wells using the function (see well.class.R) \n#\n# These functions make use of which simply returns the raw time and OD of a well (also see well.class.R)\n#\n# well.array: an array of well objects. note this is the only normalization function that acts on an entire array instead of an individual well.\n# normalize.method: \n# - (default): subtracts the blank OD (either specified by or taken from the first timepoint as default) of each well from all timepoints in that well\n# - average.blank: subtracts the mean of all first OD timepoints on a plate from all timepoints in all wells on that plate\n# - average.first: takes the mean of the difference between the OD of the specified timepoint and the first timepoint of all wells on a plate\n# and subtracts this value from all timepoints in all wells on that plate\n# - anything else: do nothing\n# blank.value - user can enter a blank OD measurement for uninoculated wells. if NULL, defaults to the value of the first OD measurement of each well. \n# start.index - which timepoint should be used as the first one after inoculation (defaults to the 2th one)\n# add.constant: add a numeric constant to all timepoints in all wells. \nnormalize.ODs = function(well.array, normalize.method = \"default\", blank.value = NULL, start.index = 2, add.constant = 1){\n \n if (normalize.method == \"default\"){\n well.array = aapply(well.array, function(well, blank.value){\n # Use the blank OD value if specified; otherwise, get it from the first OD timepoint. \n if(is.null(blank.value)) blank.value = raw.data(well)[1,2]\n # Set the blank OD (minus the constant to be added) to the \"norm\" slot of each well.\n \twell@norm = blank.value - add.constant\n \treturn(well)}, blank.value)\n }\n else if (normalize.method == \"average.blank\"){ \n # Use the blank OD value if specified; otherwise, get it from the first OD timepoint.\n\t\tblank.ODs = unlist(aapply(well.array, function(well, blank.value){\n if(is.null(blank.value)) blank.value = raw.data(well)[1,2]\n return(blank.value)}, blank.value))\n\t\tplate.IDs = unlist(aapply(well.array, plate.name))\n\t\tblank.averages = tapply(blank.ODs, plate.IDs, mean)\n\t # Set this value (minus the constant to be added) to the \"norm\" slot of each well. \n\t\twell.array = aapply(well.array, function(well){\n\t\t\twell@norm = blank.averages[plate.name(well)] - add.constant\n\t\t\treturn(well)})\n\t\t}\n\telse if (normalize.method == \"average.first\"){\n\t # Find the mean difference between starting OD (timepoint specified by ) and blank OD (first timepoint) for each plate\n # Use the blank OD value if specified; otherwise, get it from the first OD timepoint.\n blank.ODs = unlist(aapply(well.array, function(well, blank.value){\n if(is.null(blank.value)) blank.value = raw.data(well)[1,2]\n return(blank.value)}, blank.value))\n\t\tfirst.ODs = unlist(aapply(well.array, function(well) raw.data(well)[start.index,2]))\n\t\tplate.IDs = unlist(aapply(well.array, plate.name))\n\t blank.averages = tapply(first.ODs-blank.ODs,plate.IDs,mean)\n\t # Set this value (minus the constant to be added) to the \"norm\" slot of each well.\n\t\twell.array = aapply(well.array, function(well){\n\t\t\twell@norm = raw.data(well)[start,2] - blank.averages[plate.name(well)] - add.constant \n\t\t\treturn(well)})\n\t\t}\t\n\telse{\n # Simply set the negative constant to be added to the \"norm\" slot of each well. \n\t\twell.array = aapply(well.array, function(well){\n\t\t\twell@norm = - add.constant\n \t\t\treturn(well)})\n\t\t}\n if(is.null(blank.value))\n well.array = aapply(well.array, remove.points, 1)\n return(well.array)\n\t}\n\n########################################################################\n# #\n# Log-transform OD readings for a single well object #\n# #\n########################################################################\n\n# Must include this so that the checking process will not complain about\n# inconsistency S3 generic/method. Though I don't know why.\ntransform <- function(input.well, ...) {\n UseMethod(\"transform\")\n}\n\n#' Transform.Ods \n#' \n#' This function adds a \"log.OD\" column to the \"screen.data\" slot of a well object with log-transformed data. \n#' The raw data is kept intact. \n#' It also checks to see if any of the raw OD values (before a certain timepoint) is below the blank OD. \n#' This can be disastrous for the log(OD) transform. \n#' @param input.well an object of class well \n#' @param use.log gets added to the \"use.log\" slot of the well object. this will determine whether the log-transformed data \n#' or raw normalized data is returned using the function \\code{data.from}. \n#' @param blank.value user can enter a blank OD measurement for uninoculated wells. if NULL, defaults to the value of the first OD measurement of each well. \n#' @param start.index which timepoint should be used as the first one after inoculation (defaults to the 2th one) \n#' @param negative.OD.cutoff if any ODs below the specified blank value are detected before this index timepoint, the entire well is discarded. \ntransform.ODs = function(input.well, use.log = T, blank.value = NULL, start.index = 2, negative.OD.cutoff = 10, constant.added = 1.0, ...){\n \n # The default value for the log-transformed ODs will be NA. Valid values will be filled in. \n\tlog.OD = rep(NA, length(input.well))\n OD = raw.data(input.well)[,2]\n \n\t # Use the blank OD value if specified; otherwise, get it from the first OD timepoint.\n if(is.null(blank.value))\n blank.value = OD[1]\n\n # Remove any points from the analysis that weren't already removed and fall below the blank value (using below)\n OD[input.well@screen.data$Remove] = NA\n \n negative.points = which(OD + 0.2 * constant.added < blank.value)\n if(length(negative.points) > 0)\n\t input.well = remove.points(input.well, negative.points)\n \n # If any points fall below the blank value by more than 0.2 * and before the cutoff index , remove the well from analysis. \n # First adjust the cutoff to compensate for curves that don't start at timepoint 1\n negative.OD.cutoff = negative.OD.cutoff + start.index - 1\n \n if(any(negative.points <= negative.OD.cutoff)){\n input.well = remove.points(input.well, rep(T,length(input.well)))\n input.well@add.info = paste(\"ODs at timepoint(s)\", paste(negative.points[negative.points <= negative.OD.cutoff],collapse=\" \"), \"were below blank OD; well discarded\")\n }\n\n # Take the natural log of the rest of the OD values (after subtracting the normalization value)\n log.OD[which(OD > input.well@norm)] = log(OD[which(OD > input.well@norm)] - input.well@norm)\n\t\n\t# Add a column to the \"screen.data\" slot of the well\n\tinput.well@screen.data$log.OD = log.OD\t\n\t# Update the \"use.log\" slot of the well \n\tinput.well@use.log = use.log\t\n\n\treturn(input.well)\n\t}\n\n########################################################################\n# #\n# Remove timepoints from the analysis but not from the raw data #\n# #\n########################################################################\n# \n# Removes timepoints from further analysis. Does not remove them from the raw data;\n# instead, this function creates or updates the Remove column in slot \"screen.data\" of the well which dictates whether \n# individual timepoints are returned using the function. \n#\n# can be a vector containing:\n# - any combination of positive and negative integers \n# the timepoints at indices corresponding to positive integers will be set to be removed.\n# the timepoints at indices corresponding to negative integers will be be re-added if they were previously set to be removed.\n# - a single zero, which resets all timepoints (nothing will be removed)\n# - a logical vector to replace the Remove column and which will be cycled along the length of the timepoints. \n\nremove.points = function(input.well, points){\n # Copy the Remove column or create a new one if it doesn't yet exist\n\tif (is.null(input.well@screen.data$Remove))\n\t\tRemove = rep(F, length(input.well))\n\telse\n\t\tRemove = input.well@screen.data$Remove\n\n # If is a logical vector, recycle it along the length of Remove \n\tif (length(points[!is.na(points)]) != 0){\n\t# Separate positive and negative integers\n \tif (is.logical(points) & !any(is.na(points)))\n \t\tRemove = rep(points,length.out=nrow(input.well@screen.data))\t\n \t\telse{\n \tpos = points[points > 0]\n \tneg = -points[points < 0]\n \tRemove[pos] = T\n \tRemove[neg] = F \n \t\t \t\n # If contains only zeros, reset the Remove vector to all F \t\n \tif (all(points == 0))\n \t\tRemove[1:length(Remove)] = F\n \t\t}\n }\n # replace the Remove column\n\tinput.well@screen.data$Remove = Remove\n\tinput.well\n\t}\n\n\n\n\n\n",
"created" : 1425413265888.000,
"dirty" : false,
"encoding" : "UTF-8",
"folds" : "",
"hash" : "3349576883",
"id" : "74C1CB00",
"lastKnownWriteTime" : 1428436335,
"path" : "~/Documents/GCAT4/trunk/R/GCAT/R/normalize.and.transform.R",
"project_path" : "R/normalize.and.transform.R",
"properties" : {
},
"source_on_save" : false,
"type" : "r_source"
}