def test_calc_ratio_mean_sd_num():
    numer_mean = 1
    denom_mean = 4
    numer_sd =0.25
    denom_sd = 0.8
    result = ep.calc_ratio_mean_sd(numer_mean, numer_sd, denom_mean, denom_sd)
    # Check that return value is an iterable (should be a tuple) with two
    # entries, each a number
    ok_(isinstance(result, tuple))
    ok_(len(result) == 2)
def test_calc_ratio_mean_sd_array():
    numer_mean = np.array([1, 2, 3])
    denom_mean = np.array([2, 4, 6])
    numer_sd = np.array([0.25, 0.3, 0.35])
    denom_sd = np.array([0.5, 0.6, 0.7])
    result = ep.calc_ratio_mean_sd(numer_mean, numer_sd, denom_mean, denom_sd)
    # Check that return value is an iterable (should be a tuple) with two
    # entries, each a number
    ok_(isinstance(result, tuple))
    (ratio_mean, ratio_sd) = result
    ok_(isinstance(ratio_mean, np.ndarray))
    ok_(isinstance(ratio_sd, np.ndarray))
    ok_(len(ratio_mean.shape) == 1)
    ok_(len(ratio_sd.shape) == 1)
    ok_(len(ratio_mean) == len(ratio_sd))
    ok_(len(ratio_mean) == len(numer_mean))
示例#3
0
def calculate_fret_from_endpoints(wells, fda, fd, fa, bg, num_pts=20,
                                  plot=True):
    """Calculate FRET using the endpoints of the FDA and FD conditions.

    For the donor + acceptor, subtracts the acceptor-only background average;
    for the donor-only, subtracts the no donor/no acceptor background average.
    Then takes the average of the last num_pts of the background-subtracted traces
    to get the fluorescence value for that condition/replicate.

    To get an estimate of error across replicates, the values for the FDA and
    FA wells are then averaged across replicates, yielding a mean fluorescence
    for each with an associated standard error. The FRET is then calculated by
    taking the ratio, and the standard error of the FRET value is calculated by
    sampling the standard deviation of the ratio of two normal distributions
    with means and standard deviations matching those of the mean and standard
    errors of the FDA and FD conditions.

    Note that this approach accounts for error across replicates, but not for
    error in determining the mean fluorescence of each individual replicate.
    However, it appears that the variability between replicates is
    substantially greater than the variability within a single fluorescence
    timecourse, and the standard error of the mean could be further reduced by
    averaging across more points.

    Parameters
    ----------
    wells : collections.OrderedDict
        Dict containing the timecourses for each well in the plate.
    fda, fd, fa, bg : collections.OrderedDict
        Dicts mapping the concentration conditions to the well names of the
        replicates.
    num_pts : int
        The number of final points to average across.
    plot : boolean
        Whether to plot the FRET results (defaults to True)

    Returns
    -------
    tuple : (bid_concs, fret_means, fret_ses)
        Tuple containing the concentrations of the unlabeled Bid used in each
        conditions; the mean FRET values calculated for each unabeled Bid
        concentration; and the standard error of the mean calculated by
        sampling.
    """

    # Get the background averages
    bg_avg = get_average_bg(wells, bg, plot=False)
    fa_avg = get_average_fa(wells, fa, plot=False)
    # Initialize a few variables
    num_concs = len(fda.keys())
    num_reps = 3
    bid568_conc = 10. # Concentration of Bid-568, in nM
    fda_endpoints = np.zeros((num_concs, num_reps))
    fd_endpoints = np.zeros((num_concs, num_reps))
    bid_concs = np.zeros(num_concs)
    # Iterate over the conditions
    for conc_ix, conc_name in enumerate(fda.keys()):
        bid_concs[conc_ix] = float(conc_name.split(' ')[1])
        # FDA
        for rep_ix, well_name in enumerate(fda[conc_name]):
            fda_value = np.array(wells[well_name][VALUE])
            # Subtract the FA background:
            fda_value = fda_value - fa_avg
            # Calculate endpoint value over last num_pts
            endpt = np.mean(fda_value[-num_pts:])
            fda_endpoints[conc_ix, rep_ix] = endpt
        # FD
        for rep_ix, well_name in enumerate(fd[conc_name]):
            fd_value = np.array(wells[well_name][VALUE])
            # Subtract the BG background:
            fd_value = fd_value - bg_avg
            # Calculate endpoint value over last num_pts
            endpt = np.mean(fd_value[-num_pts:])
            fd_endpoints[conc_ix, rep_ix] = endpt

    # Now, calculate the means of the endpts across replicates
    fda_means = np.mean(fda_endpoints, axis=1)
    fd_means = np.mean(fd_endpoints, axis=1)
    fda_ses = np.std(fda_endpoints, axis=1, ddof=1) / np.sqrt(float(num_reps))
    fd_ses = np.std(fd_endpoints, axis=1, ddof=1) / np.sqrt(float(num_reps))
    # Calculate the mean and SEM of the FDA/FD ratio distributions
    fret_tuples = [calc_ratio_mean_sd(fda_means[i], fda_ses[i],
                                      fd_means[i], fd_ses[i])
                   for i in range(len(fda_means))]
    # Convert the list of tuples into two separate lists
    (fret_means, fret_ses) = zip(*fret_tuples)
    # Now convert to numpy arrays. We take 1 - the FRET values so that we get
    # FRET in terms of FRET efficiency instead of % quenching:
    fret_means = 1 - np.array(fret_means)
    fret_ses = np.array(fret_ses)

    if plot:
        plt.figure('FDA and FD, mean/SEM over reps')
        plt.errorbar(np.log10(bid_concs), fda_means, yerr=fda_ses)
        plt.errorbar(np.log10(bid_concs), fd_means, yerr=fd_ses)
        plt.xlabel('log10([WT Bid]) (nM)')
        plt.ylabel('RFU')
        plt.xlim([-0.5, 3.1])
        plt.title('FDA and FD, mean/SEM over reps')

        plt.figure('FRET')
        plt.errorbar(np.log10(bid_concs), fret_means, yerr=fret_ses)
        plt.xlabel('log10([WT Bid]) (nM)')
        plt.ylabel('FRET (%)')
        plt.xlim([-0.5, 3.1])
        plt.title('FRET')

    return (bid_concs, fret_means, fret_ses)
示例#4
0
def quenching_std_curve(dpx_std_file_list, dpx_std_wells, dpx_concs,
                        bg_avgs=None):
    """Calculates and plots the quenching std curve from the raw ANTS data.

    Parameters
    ----------
    dpx_std_file_list : list of strings
        Names of the text files (exported from the FlexStation plate reader)
        containing the raw fluorescence data at each quenching step.
    dpx_std_wells : list of strings
        Names of the replicate wells measured in the quenching assay,
        e.g., ['A1', 'A2', 'A3'] etc.
    dpx_concs : numpy.array
        The concentrations of DPX at each quenching step.

    Returns
    -------
    tuple : (i_avgs, i_sds, fmax_avg)
        A tuple; the first element in the tuple is the array of mean quenching
        values, given as I / I_0, that is, the ratio of the fluorescence at a
        given amount of DPX to the unquenched fluorescence. The second element
        contains the standard deviations of this ratio at each concentration.
        The third element is the average fluorescence intensity of the lysed,
        unquenched liposomes (liposomes after Triton but before DPX addition.
    """
    num_dilutions = len(dpx_concs)

    # We'll store the means and SDs for the fluorescence intensities at
    # each DPX concentration in here:
    dpx_intensity_avgs = np.zeros(num_dilutions)
    dpx_intensity_sds = np.zeros(num_dilutions)

    # Iterate over the files containing the intensity data
    for dilution_index, std_file in enumerate(dpx_std_file_list):
        well_vals = np.array([])
        timecourse_wells = read_flexstation_kinetics(std_file)
        # Iterate over all the wells used in the standard curve, calculate
        # the read average for each one and add it to a list
        for well_name in dpx_std_wells:
            well_vals = np.concatenate((well_vals,
                                        timecourse_wells[well_name][VALUE]))
            #well_avgs.append(np.mean(timecourse_wells[well_name][VALUE]))
        # Now take the average and SD over all of the replicate wells
        dpx_intensity_avgs[dilution_index] = np.mean(well_vals)
        dpx_intensity_sds[dilution_index] = np.std(well_vals)

    # Plot the intensity values at each DPX concentration
    plt.figure()
    plt.errorbar(dpx_concs, dpx_intensity_avgs, yerr=dpx_intensity_sds,
                 color='k', linewidth=2)
    plt.xlabel('[DPX] (M)')
    plt.ylabel('ANTS Fluorescence (RFU)')
    plt.title('ANTS Fluorescence vs. [DPX]')

    # If we have background values, subtract them here
    if bg_avgs is not None:
        if not len(bg_avgs) == num_dilutions:
            return ValueError("The background array must have as many entries "
                              "as there are DPX concentraitons.")
        dpx_intensity_avgs = dpx_intensity_avgs - bg_avgs

    # Now calculate the intensity ratios, I / I_0
    # To get the standard error of the ratio, we have to account for the
    # error in both the numerator and the denominator:
    i_vals = np.zeros(num_dilutions)
    i_sds = np.zeros(num_dilutions)
    for i in range(num_dilutions):
        (i_vals[i], i_sds[i]) = calc_ratio_mean_sd(
                                              dpx_intensity_avgs[i],
                                              dpx_intensity_sds[i],
                                              dpx_intensity_avgs[0],
                                              dpx_intensity_sds[0])
    return (i_vals, i_sds, dpx_intensity_avgs[0], dpx_intensity_sds[0])
示例#5
0
def requenching_analysis(requench_file_list, requench_wells,
                         requench_dpx_concs, q_outs, fmax_avg, fmax_sd,
                         ka, kd, dpx_0, bg_avgs=None, do_plot=True):
    """Calculates and plots the quenching std curve from the raw ANTS data.

    Parameters
    ----------
    requench_file_list : list of strings
        Names of the text files (exported from the FlexStation plate reader)
        containing the raw fluorescence data at each quenching step.
    requench_wells : list of strings
        Names of the replicate wells measured in the quenching assay,
        e.g., ['A1', 'A2', 'A3'] etc.
    requench_dpx_concs : numpy.array
        The concentrations of DPX at each quenching step.
    """
    # FIXME add other comments to docstring

    # We know how much of the stock DPX we added at each quenching step, but we
    # have to calculate the actual concentrations:
    num_dilutions = len(requench_dpx_concs)
    num_wells = len(requench_wells)

    # We'll store the means and SDs for the fluorescence intensities at
    # each DPX concentration in here:
    requench_well_avgs = np.zeros((num_dilutions, num_wells))
    requench_well_sds = np.zeros((num_dilutions, num_wells))

    # Iterate over the files containing the intensity data
    for dilution_index, requench_file in enumerate(requench_file_list):
        timecourse_wells = read_flexstation_kinetics(requench_file)
        # Iterate over all the wells, calculate the read average for each one
        # and add it to a list
        for well_index, well_name in enumerate(requench_wells):
            if bg_avgs is not None:
                well_values = (timecourse_wells[well_name][VALUE] -
                               bg_avgs[dilution_index])
            else:
                well_values = timecourse_wells[well_name][VALUE]

            requench_well_avgs[dilution_index, well_index] = \
                            np.mean(well_values)
            requench_well_sds[dilution_index, well_index] = \
                            np.std(well_values)

    # Plot the intensity values at each DPX concentration
    if do_plot:
        plt.figure()
        for well_index in range(num_wells):
            plt.errorbar(requench_dpx_concs, requench_well_avgs[:, well_index],
                         yerr=requench_well_sds[:, well_index])
        plt.xlabel('[DPX] (M)')
        plt.ylabel('ANTS Fluorescence (RFU)')
        plt.title('ANTS Fluorescence vs. [DPX]')

    # Now calculate the total quenching, I / F_max, for each well
    q_tot_by_well_avgs = np.zeros((num_dilutions, num_wells))
    q_tot_by_well_sds = np.zeros((num_dilutions, num_wells))
    for well_index, well_name in enumerate(requench_wells):
        # If we've been given a list of fmax avgs/sds for each well, use the
        # one for this well; otherwise, assume we've been given a single value
        # for all wells and use that
        try:
            cur_fmax_avg = fmax_avg[well_index]
            cur_fmax_sd = fmax_sd[well_index]
        except IndexError:
            cur_fmax_avg = fmax_avg
            cur_fmax_sd = fmax_sd

        # The error associated with the total quenching depends on the
        # error of the reads for this well/dilution, and the error of the
        # maximum fluorescence
        for dilution_index in range(num_dilutions):
            (q_tot_avg, q_tot_sd) = calc_ratio_mean_sd(
                        requench_well_avgs[dilution_index, well_index],
                        requench_well_sds[dilution_index, well_index],
                        cur_fmax_avg, cur_fmax_sd)
            q_tot_by_well_avgs[dilution_index, well_index] = q_tot_avg
            q_tot_by_well_sds[dilution_index, well_index] = q_tot_sd

    # Calculate the (predicted) Q_out for each of the DPX concentrations used
    #q_outs = np.array([1. / quenching_func(ka, kd, dpx_conc)
    #          for dpx_conc in requench_dpx_concs])
    # FIXME have q_out get associated error by sampling from ka/kd dists

    # Plot the Q_total / Q_out curves (should be straight lines)
    q_ins = np.zeros(num_wells)
    q_in_errs = np.zeros(num_wells)
    f_outs = np.zeros(num_wells)
    f_out_errs = np.zeros(num_wells)
    #plt.figure()
    for well_index, well_name in enumerate(requench_wells):
        #if well_index < 30:
        #    continue
        if do_plot:
            plt.figure()
            #plt.subplot(6, 6, well_index+1)
            plt.errorbar(q_outs, q_tot_by_well_avgs[:, well_index],
                         q_tot_by_well_sds[:, well_index],
                         linestyle='', color='k', linewidth=2)
            plt.title('$Q_{total}$ vs. $Q_{out}$ for well %s' % well_name)
            plt.xlim((0, 1))
            plt.ylim((0, 1))
            plt.xlabel('$Q_{out}$')
            plt.ylabel('$Q_{total}$')
            # Add tickmarks only to the plots on the edges
            #if well_index + 1 > 30 
            #    plt.xticks([0, 0.5, 1.0])
            #    plt.xlabel('$Q_{out}$')
            #else:
            #    plt.xticks([])
            #if well_index % 6 == 0:
            #    plt.yticks([0, 0.5, 1.0])
            #    plt.ylabel('$Q_{total}$')
            #else:
            #    plt.yticks([])

        linfit = scipy.stats.linregress(q_outs,
                                        q_tot_by_well_avgs[:, well_index])
        f_out = linfit[0]
        intercept = linfit[1]
        #std_err = linfit[4]
        n = float(len(q_outs))
        sd_slope = linfit[4]
        sd_intercept = np.sqrt((sd_slope ** 2) * np.sum(q_outs ** 2) / n)

        # Calculate the internal quenching
        (q_in_avg, q_in_sd) = calc_ratio_mean_sd(intercept, sd_intercept,
                                                 1 - f_out, sd_slope)

        # THIS IS ALL WRONG!
        #mean_x = np.mean(q_outs)
        #sx2 =  np.sum((q_outs - mean_x)**2)
        #sd_intercept = std_err * np.sqrt(1. / len(q_outs) + mean_x*mean_x/sx2)
        #sd_slope = std_err * np.sqrt(1./sx2)
        if do_plot:
            plt.plot(q_outs, (q_outs * f_out) + intercept, color='r',
                     linewidth=1)
            plt.text(0.05, 0.9, '$F_{out}\ \mathrm{(slope)}\ = %f$' % f_out)
            plt.text(0.05, 0.8, '$Q_{in}(1 - F_{out})\ \mathrm{(intercept)}\ = %f$'
                                % intercept)
            plt.text(0.05, 0.7, '$Q_{in} = %f$' % q_in_avg)
            plt.text(0.05, 0.6, '$R^2 = %f$' % linfit[2])

        # Save the results for this well
        f_outs[well_index] = f_out
        f_out_errs[well_index] = sd_slope
        q_ins[well_index] = q_in_avg
        q_in_errs[well_index] = q_in_sd
    #plt.tight_layout()

    # This error is not meaningful because it doesn't account for errorbars!
    # FIXME FIXME FIXME
    linfit = scipy.stats.linregress(f_outs, q_ins)
    f_out_pred = np.linspace(0, 1, 100)

    if do_plot:
        plt.figure()
        plt.errorbar(f_outs, q_ins, xerr=f_out_errs, yerr=q_in_errs,
                     marker='o', color='k', linestyle='')
        #plt.plot(f_outs[0:12], q_ins[0:12], marker='o', color='r',
        #         linestyle='')
        #plt.plot(f_outs[12:24], q_ins[12:24], marker='o', color='g',
        #         linestyle='')
        #plt.plot(f_outs[24:36], q_ins[24:36], marker='o', color='b',
        #         linestyle='')
        plt.xlabel('$F_{out}$')
        plt.ylabel('$Q_{in}$')
        plt.xlim([-0.2, 1.1])
        plt.ylim([-0.2, 1.1])
        plt.title('$Q_{in}$ vs. $F_{out}$')

        plt.plot(f_out_pred, (f_out_pred * linfit[0]) + linfit[1], color='r')
        plt.text(0.1, 0.9, 'Slope = %f' % linfit[0])
        plt.text(0.1, 0.85, 'Intercept = %f' % linfit[1])
        plt.text(0.1, 0.8, '$R^2 = %f$' % linfit[2])
        plt.text(0.1, 0.75, 'p = %f' % linfit[3])

    return {'f_outs': f_outs,
            'q_ins': q_ins,
            'f_out_errs': f_out_errs,
            'q_in_errs': q_in_errs}
示例#6
0
def quenching_std_curve_by_well(dpx_std_file_list, dpx_std_wells,
                                dpx_concs):
    """Calculates and plots the quenching std curve from the raw ANTS data.

    Parameters
    ----------
    dpx_std_file_list : list of strings
        Names of the text files (exported from the FlexStation plate reader)
        containing the raw fluorescence data at each quenching step.
    dpx_std_wells : list of strings
        Names of the replicate wells measured in the quenching assay,
        e.g., ['A1', 'A2', 'A3'] etc.
    dpx_concs : numpy.array
        The concentrations of DPX at each quenching step.

    Returns
    -------
    (i_avgs, i_sds)
        A tuple of arrays; the first element in the tuple is the array of mean
        quenching values, given as I / I_0, that is, the ratio of the
        fluorescence at a given amount of DPX to the unquenched fluorescence.
        The second element contains the standard deviations of this ratio at
        each concentration.
    """
    # We know how much of the stock DPX we added at each quenching step, but we
    # have to calculate the actual concentrations:
    num_dilutions = len(dpx_concs)
    num_wells = len(dpx_std_wells)

    # We'll store the means and SDs for the fluorescence intensities at
    # each DPX concentration in here:
    #dpx_intensity_avgs = np.zeros(num_dilutions)
    #dpx_intensity_sds = np.zeros(num_dilutions)
    dpx_well_avgs = np.zeros((num_dilutions, num_wells))
    dpx_well_sds = np.zeros((num_dilutions, num_wells))

    # Iterate over the files containing the intensity data
    for dilution_index, std_file in enumerate(dpx_std_file_list):
        timecourse_wells = read_flexstation_kinetics(std_file)
        # Iterate over all the wells used in the standard curve, calculate
        # the read average for each one and add it to a list
        for well_index, well_name in enumerate(dpx_std_wells):
            dpx_well_avgs[dilution_index, well_index] = \
                            np.mean(timecourse_wells[well_name][VALUE])
            dpx_well_sds[dilution_index, well_index] = \
                            np.std(timecourse_wells[well_name][VALUE])

    # Plot the intensity values at each DPX concentration
    plt.figure()
    for well_index in range(num_wells):
        plt.errorbar(dpx_concs, dpx_well_avgs[:, well_index],
                     yerr=dpx_well_sds[:, well_index])
    plt.xlabel('[DPX] (M)')
    plt.ylabel('ANTS Fluorescence (RFU)')
    plt.title('ANTS Fluorescence vs. [DPX]')

    # Now calculate the intensity ratios, I / I_0, **for each well**
    i_avgs_by_well = np.zeros((num_dilutions, num_wells))
    i_sds_by_well = np.zeros((num_dilutions, num_wells))
    for well_index in range(num_wells):
        for dilution_index in range(num_dilutions):
            # To get the standard error of the ratio, we have to account for
            # the error in both the numerator and the denominator:
            (avg, sd) = calc_ratio_mean_sd(
                                      dpx_well_avgs[dilution_index, well_index],
                                      dpx_well_sds[dilution_index, well_index],
                                      dpx_well_avgs[0, well_index],
                                      dpx_well_sds[0, well_index])
            i_avgs_by_well[dilution_index, well_index] = avg
            i_sds_by_well[dilution_index, well_index] = sd

    # Plot the individual I / I_0 curves
    plt.figure()
    for well_index in range(num_wells):
        plt.errorbar(dpx_concs, i_avgs_by_well[:, well_index],
                     yerr=i_sds_by_well[:, well_index])
    plt.xlabel('[DPX] (M)')
    plt.ylabel('$I / I_0$')
    plt.title('Quenching vs. [DPX]')

    # Now calculate the I / I_0 curve averaged over all replicates NOTE: we're
    # not taking into account the individual variances at each well (which are
    # relatively small) when we are calculate these means/sds. Doing so
    # could represent a slight improvement.
    i_avgs = np.mean(i_avgs_by_well, axis=1)
    i_sds = np.std(i_avgs_by_well, axis=1)

    fmax_avg = np.mean(dpx_well_avgs[0, :])
    fmax_sd = np.std(dpx_well_avgs[0, :])

    return (i_avgs, i_sds, fmax_avg, fmax_sd)