def dye_by_bin(plate_objects, analyzed_wells, eventful_wells, analyzed_sample_names, eventful_sample_names, bin_func, channel='FAM'): """ @deprecated -- use metrics """ # assumes standard dye concentrations (see bin_plots) bins = set([bin_func(w) for w in analyzed_wells]) bin_plots = dict([(bin, [[3,None],[10,None],[30,None],[100,None],[300,None],[500,None]]) for bin in bins]) groups = [] groups.extend([(sample_name, groupinto(sample_name_filter(analyzed_wells, sample_name), bin_func)) for sample_name in analyzed_sample_names]) groups.extend([(sample_name, groupinto(sample_name_filter(eventful_wells, sample_name), bin_func)) for sample_name in eventful_sample_names]) for i, (sample, group) in enumerate(groups): for bin, wells in group: amp_array = None for w in wells: qplate = plate_objects[(w.plate.file.dirname, w.plate.file.basename)] well = qplate.wells[w.well_name] if channel == 'VIC': if amp_array is None: amp_array = vic_amplitudes(well.peaks) else: amp_array = np.concatenate([amp_array, vic_amplitudes(well.peaks)]) else: if amp_array is None: amp_array = fam_amplitudes(well.peaks) else: amp_array = np.concatenate([amp_array, fam_amplitudes(well.peaks)]) if amp_array is not None: amp_mean = np.mean(amp_array) amp_sigma = np.std(amp_array) bin_plots[bin][i][1] = (amp_mean, amp_sigma) return bin_plots
def compute(self, qlwell, qlwell_channel, well_channel_metric, dyeset=None): if dyeset: blue_hi, blue_lo, green_hi, green_lo = single_well_calibration_clusters(qlwell, dyeset) elif qlwell.sample_name == DYES_FAM_VIC_LABEL: blue_hi, blue_lo, green_hi, green_lo = single_well_calibration_clusters(qlwell, DYES_FAM_VIC) elif qlwell.sample_name == DYES_FAM_HEX_LABEL: blue_hi, blue_lo, green_hi, green_lo = single_well_calibration_clusters(qlwell, DYES_FAM_HEX) else: # do not know how to compute, return wcm return well_channel_metric if well_channel_metric.channel_num == 0: hi_amplitudes = fam_amplitudes(blue_hi) lo_amplitudes = fam_amplitudes(blue_lo) well_channel_metric.positive_peaks = len(blue_hi) well_channel_metric.positive_mean = np.mean(hi_amplitudes) well_channel_metric.positive_stdev = np.std(hi_amplitudes) well_channel_metric.negative_peaks = len(blue_lo) well_channel_metric.negative_mean = np.mean(lo_amplitudes) well_channel_metric.negative_stdev = np.std(lo_amplitudes) well_channel_metric.width_mean_hi = np.mean( fam_widths( blue_hi ) ) elif well_channel_metric.channel_num == 1: hi_amplitudes = vic_amplitudes(green_hi) lo_amplitudes = vic_amplitudes(green_lo) well_channel_metric.positive_peaks = len(green_hi) well_channel_metric.positive_mean = np.mean(hi_amplitudes) well_channel_metric.positive_stdev = np.std(hi_amplitudes) well_channel_metric.negative_peaks = len(green_lo) well_channel_metric.negative_mean = np.mean(lo_amplitudes) well_channel_metric.negative_stdev = np.std(lo_amplitudes) well_channel_metric.width_mean_hi = np.mean( fam_widths( green_hi )) return well_channel_metric
def cluster_csv(self, id=None, show_only_gated=True, *args, **kwargs): from pyqlb.nstats.well import accepted_peaks qlwell = self.__qlwell_from_threshold_form(id) if show_only_gated != 'False': peaks = accepted_peaks(qlwell) else: peaks = qlwell.peaks from pyqlb.nstats.peaks import fam_amplitudes, fam_widths, vic_amplitudes, vic_widths, peak_times from pyqlb.nstats.well import well_observed_cluster_assignments response.headers['Content-Type'] = 'text/csv' h.set_download_response_header(request, response, "%s_%s%s.csv" % \ (str(c.well.plate.plate.name), str(c.well.well_name), '' if show_only_gated != 'False' else '_all')) out = StringIO.StringIO() csvwriter = csv_pkg.writer(out) csvwriter.writerow(['Plate',c.well.plate.plate.name]) csvwriter.writerow(['Well',c.well.well_name]) csvwriter.writerow([]) csvwriter.writerow(['Time','FAMAmplitude','FAMWidth','VICAmplitude','VICWidth','Cluster']) csvwriter.writerow([]) pts = peak_times(peaks) fas = fam_amplitudes(peaks) fws = fam_widths(peaks) vas = vic_amplitudes(peaks) vws = vic_widths(peaks) cls = well_observed_cluster_assignments(qlwell, peaks) for row in zip(pts, fas, fws, vas, vws, cls): csvwriter.writerow(row) csv = out.getvalue() out.close() return csv
def revb_extracluster_peaks(well, channel_num, threshold=None, pct_boundary=0.3, exclude_min_amplitude_peaks=True): """ Return the peaks that are outside the clusters. A superset of polydispersity peaks, meant primarily for dye wells, where there should be no biological basis for rain. Returns a 3-tuple: peaks, rain gates, width gates """ if not threshold: threshold = well.channels[channel_num].statistics.threshold if not threshold: threshold = None if exclude_min_amplitude_peaks: peaks = above_min_amplitude_peaks(well) else: peaks = well.peaks # get rain_pvalues p_plus, p, p_minus, pos, middle_high, middle_low, neg = \ rain_pvalues_thresholds(peaks, channel_num=channel_num, threshold=threshold, pct_boundary=pct_boundary) binned_peaks = bin_peaks_by_amplitude(peaks, well.sum_amplitude_bins) extra_peaks = np.ndarray([0], dtype=peak_dtype(2)) for bin, (min_gate, max_gate, boundary) in zip(binned_peaks, well.sum_amplitude_bins): if middle_high and middle_low: extra_peaks = np.hstack([extra_peaks, np.extract(np.logical_not( np.logical_or( reduce(np.logical_and, (channel_widths(bin, channel_num) > min_gate, channel_widths(bin, channel_num) < max_gate, channel_amplitudes(bin, channel_num) > middle_high, channel_amplitudes(bin, channel_num) < pos)), reduce(np.logical_and, (channel_widths(bin, channel_num) > min_gate, channel_widths(bin, channel_num) < max_gate, channel_amplitudes(bin, channel_num) > neg, channel_amplitudes(bin, channel_num) < middle_low)) ) ), bin)]) else: extra_peaks = np.hstack([extra_peaks, np.extract(np.logical_not( reduce(np.logical_and, (channel_widths(bin, channel_num) > min_gate, channel_widths(bin, channel_num) < max_gate, channel_amplitudes(bin, channel_num) > neg, channel_amplitudes(bin, channel_num) < pos) ) ), bin)]) return (extra_peaks, (pos, middle_high, middle_low, neg), (np.mean(fam_amplitudes(peaks)), np.mean(vic_amplitudes(peaks))))
def temporal2d(self, id=None, *args, **kwargs): from qtools.lib.nstats.peaks import accepted_peaks from pyqlb.nstats.peaks import peak_times, fam_amplitudes, vic_amplitudes qlwell = self.__qlwell_from_threshold_form(id) self.__set_threshold_context(qlwell) ok_peaks = accepted_peaks(qlwell) c.tvf = zip(peak_times(ok_peaks), vic_amplitudes(ok_peaks), fam_amplitudes(ok_peaks)) return render('/well/temporal2d.html')
def test_single_well_calibration_clusters(self): fam_hi, fam_lo, vic_hi, vic_lo = single_well_calibration_clusters( self.vic_well, DYES_FAM_VIC) assert len(fam_hi) == 5495 assert len(fam_lo) == 5201 assert len(vic_hi) == 5326 assert len(vic_lo) == 5257 fam_amp = np.mean(fam_amplitudes(fam_hi)) assert abs(20000 - fam_amp) < 10 fam_lo_amp = np.mean(fam_amplitudes(fam_lo)) assert abs(2369 - fam_lo_amp) < 10 vic_amp = np.mean(vic_amplitudes(vic_hi)) assert abs(10000 - vic_amp) < 15 vic_lo_amp = np.mean(vic_amplitudes(vic_lo)) assert abs(2025 - vic_lo_amp) < 10 fam_hi, fam_lo, hex_hi, hex_lo = single_well_calibration_clusters( self.hex_well, DYES_FAM_HEX) assert len(fam_hi) == 3623 assert len(fam_lo) == 3456 assert len(hex_hi) == 3719 assert len(hex_lo) == 3599 fam_amp = np.mean(fam_amplitudes(fam_hi)) assert abs(20000 - fam_amp) < 10 fam_lo_amp = np.mean(fam_amplitudes(fam_lo)) assert abs(2790 - fam_lo_amp) < 10 hex_amp = np.mean(vic_amplitudes(hex_hi)) assert abs(10000 - hex_amp) < 15 hex_lo_amp = np.mean(vic_amplitudes(hex_lo)) assert abs(2010 - hex_lo_amp) < 10
def fam_variation(well): amps = fam_amplitudes(well.peaks) mean = np.mean(amps) bins = amp_bins(amps, num_bins=129) histvals, histpos = np.histogram(amps, bins=bins) histposp = bin_centers(histpos) #params, model, errors, chisq = onedgaussfit(histpos[1:], histvals, # fixed=[True,False,True,False], # params=[0, max(histvals), np.mean(amps), histposp[1]-histposp[0]]) (gamp, gmean, gsigma), covar = curve_fit(gauss, histposp, histvals, p0=[max(histvals), mean, histposp[1]-histposp[0]]) # c1 from matlab is sqrt(2)*sigma, as (sqrt(2)*sigma)**2 = 2*sigma**2-- lines up with Klint's calc. # real sigma is c1/sqrt(2) return gsigma/gmean
def fam_variation_splits(well, threshold=None): """ Returns a 8-tuple: the gaussian parameters (A, mu, sigma) overall, then for the first half of the amplitudes, then for the second half; the overall mean, mean of the first half and the mean of the second half, and the number of peaks on each half. """ from scipy.optimize import curve_fit if threshold is not None: positives, negatives = cluster_1d(well.peaks, 0, threshold) peaks = positives else: peaks = well.peaks amps = fam_amplitudes(peaks) first_half = amps[:len(amps)/2] second_half = amps[len(amps)/2:] fbins = amp_bins(first_half, num_bins=257) fvals, fpos = np.histogram(first_half, bins=fbins) fcenters = bin_centers(fpos) sbins = amp_bins(second_half, num_bins=257) svals, spos = np.histogram(second_half, bins=sbins) scenters = bin_centers(spos) abins = amp_bins(amps, num_bins=257) avals, apos = np.histogram(amps, bins=abins) acenters = bin_centers(apos) (gamp1, gmean1, gsigma1), covar = curve_fit(gauss, fcenters, fvals, p0=[max(fvals), np.mean(first_half), fpos[1]-fpos[0]]) (gamp2, gmean2, gsigma2), covar = curve_fit(gauss, scenters, svals, p0=[max(svals), np.mean(second_half), spos[1]-spos[0]]) (gamp, gmean, gsigma), covar = curve_fit(gauss, acenters, avals, p0=[max(avals), np.mean(amps), apos[1]-apos[0]]) return ((gamp, gmean, gsigma), (gamp1, gmean1, gsigma1), (gamp2, gmean2, gsigma2), np.mean(amps), np.mean(first_half), np.mean(second_half), peak_count(fvals, min_peak_val=max(fvals)/3), peak_count(svals, min_peak_val=max(svals)/3))
def bin_peaks_by_amplitude(peaks, amplitude_bins): """ Given a set of peaks and bins, bin the peaks into the bins by sum channel. """ amplitude_sums = fam_amplitudes(peaks) + vic_amplitudes(peaks) amplitude_boundaries = [bin[2] for bin in amplitude_bins] MAX_AMPLITUDE = 32768 amplitude_regions = zip(amplitude_boundaries[:-1],amplitude_boundaries[1:]) \ + [(amplitude_boundaries[-1], MAX_AMPLITUDE)] binned_peaks = [] for region in amplitude_regions: binned_peaks.append(np.extract( reduce(np.logical_and, (amplitude_sums >= region[0], amplitude_sums < region[1])), peaks)) return binned_peaks
def peak_csv(self, id=None, show_only_gated=True, *args, **kwargs): from qtools.lib.nstats.peaks import accepted_peaks qlwell = self.__qlwell_from_threshold_form(id) if show_only_gated != 'False': peaks = accepted_peaks(qlwell) else: peaks = qlwell.peaks from pyqlb.nstats.peaks import fam_amplitudes, fam_widths, fam_quality, vic_amplitudes, vic_widths, vic_quality, peak_times response.headers['Content-Type'] = 'text/csv' h.set_download_response_header(request, response, "%s_%s%s.csv" % \ (str(c.well.plate.plate.name), str(c.well.well_name), '' if show_only_gated != 'False' else '_all')) out = StringIO.StringIO() csvwriter = csv_pkg.writer(out) csvwriter.writerow(['Plate',c.well.plate.plate.name]) csvwriter.writerow(['Well',c.well.well_name]) csvwriter.writerow([]) csvwriter.writerow(['FAMThreshold',qlwell.channels[0].statistics.threshold]) csvwriter.writerow(['VICThreshold',qlwell.channels[1].statistics.threshold]) csvwriter.writerow(['WidthGate',qlwell.channels[0].statistics.min_width_gate,qlwell.channels[0].statistics.max_width_gate]) csvwriter.writerow(['MinQualityGate',qlwell.channels[0].statistics.min_quality_gate]) csvwriter.writerow([]) csvwriter.writerow(['Time','FAMAmplitude','FAMWidth','FAMQuality','VICAmplitude','VICWidth','VICQuality']) csvwriter.writerow([]) pts = peak_times(peaks) fas = fam_amplitudes(peaks) fws = fam_widths(peaks) fqs = fam_quality(peaks) vas = vic_amplitudes(peaks) vws = vic_widths(peaks) vqs = vic_quality(peaks) for row in zip(pts, fas, fws, fqs, vas, vws, vqs): csvwriter.writerow(row) csv = out.getvalue() out.close() return csv
import numpy as np factory = QLNumpyObjectFactory() class LWPlate(object): def add_well(self, well, fulldata): # Should throw an exception if wellname exists, but have not figure out perl exception handling yet if fulldata: self.well_list[well.name] = well else: self.well_list[well.name] = "" def wells(self): print self return self.well_list def __init__(self, filename, platename): self.filename = filename self.platename = platename self.well_list = {} plate = factory.parse_plate( "\\Users\\rrymer\\Documents\\Processing\\Data\\EvaGreenPPEDNRnoBGDNAAttempt3.qlp" ) # this should be quick! a01 = plate.analyzed_wells["A01"] mean = np.mean(fam_amplitudes(a01.peaks)) print mean
def single_well_calibration_clusters(qlwell, dye_cal_props): """ Returns the clusters for the specified color calibration well. Returns them in ch0-HI, ch0-LO, ch1-HI, ch1-LO order. :param qlwell: The well to analyze :param dye_cal_props: A list of dye properties representing the calibration properties on the dyes for each channel. (Should be a 2-tuple.) """ ok_peaks = accepted_peaks(qlwell) if ( len( ok_peaks ) < 1 ): #pass back a 4-tuple of empty peaks return ( ok_peaks,ok_peaks,ok_peaks,ok_peaks) peaks = color_uncorrected_peaks(accepted_peaks(qlwell), qlwell.color_compensation_matrix) # FAM is y, VIC is x. polars = np.array([cmath.polar(complex(f, v)) for f, v in zip(vic_amplitudes(peaks), fam_amplitudes(peaks))]) blue_hi = np.extract(reduce(np.logical_and, (polars[...,1] >= THETA_THRESHOLD, polars[...,0] >= dye_cal_props[0].expected_magnitude_threshold)), ok_peaks) blue_lo = np.extract(reduce(np.logical_and, (polars[...,1] >= THETA_THRESHOLD, polars[...,0] < dye_cal_props[0].expected_magnitude_threshold)), ok_peaks) green_hi = np.extract(reduce(np.logical_and, (polars[...,1] < THETA_THRESHOLD, polars[...,0] >= dye_cal_props[1].expected_magnitude_threshold)), ok_peaks) green_lo = np.extract(reduce(np.logical_and, (polars[...,1] < THETA_THRESHOLD, polars[...,0] < dye_cal_props[1].expected_magnitude_threshold)), ok_peaks) return blue_hi, blue_lo, green_hi, green_lo
def revb_polydisperse_peaks(well, channel_num, threshold=None, pct_boundary=0.3, exclude_min_amplitude_peaks=True): """ Computes polydispersity for a well which has amplitude bins defined. Returns a 3-tuple (4-tuple, 4-tuple, 2-tuple). The first 4-tuple is: * positive droplets, with widths above the width gate set for that droplet's amplitude bin. * middle rain, with widths above the bin width gate. * middle rain, with width below the bin width gate. * negative rain, with width below the bin width gate. The second 4-tuple is: * positive rain boundary * middle rain upper boundary (can be None) * middle rain lower boundary (can be None) * negative rain boundary The third 2-tuple is: * mean FAM amplitude * mean VIC amplitude This is for being able to draw approximate single-channel polydispersity graphs down the line (this does beg the question, is there a better 2D definition of polydispersity?) Will raise an error if amplitude bins are not defined on the well. """ if not hasattr(well, 'sum_amplitude_bins') or len(well.sum_amplitude_bins) == 0: raise ValueError("No amplitude bins for this well.") if not threshold: threshold = well.channels[channel_num].statistics.threshold if not threshold: threshold = None if exclude_min_amplitude_peaks: peaks = above_min_amplitude_peaks(well) else: peaks = well.peaks p_plus, p, p_minus, pos, middle_high, middle_low, neg = \ rain_pvalues_thresholds(peaks, channel_num=channel_num, threshold=threshold, pct_boundary=pct_boundary) binned_peaks = bin_peaks_by_amplitude(peaks, well.sum_amplitude_bins) pos_peaks = np.ndarray([0], dtype=peak_dtype(2)) midhigh_peaks = np.ndarray([0], dtype=peak_dtype(2)) midlow_peaks = np.ndarray([0], dtype=peak_dtype(2)) neg_peaks = np.ndarray([0], dtype=peak_dtype(2)) for bin, (min_gate, max_gate, boundary) in zip(binned_peaks, well.sum_amplitude_bins): pos_peaks = np.hstack([pos_peaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) > max_gate, channel_amplitudes(bin, channel_num) > pos)), bin)]) if middle_high and middle_low: midhigh_peaks = np.hstack([midhigh_peaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) > max_gate, reduce(np.logical_and, (channel_amplitudes(bin, channel_num) < middle_high, channel_amplitudes(bin, channel_num) > middle_low)))), bin)]) midlow_peaks = np.hstack([midlow_peaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) < min_gate, reduce(np.logical_and, (channel_amplitudes(bin, channel_num) < middle_high, channel_amplitudes(bin, channel_num) > middle_low)))), bin)]) neg_peaks = np.hstack([neg_peaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) < min_gate, channel_amplitudes(bin, channel_num) < neg)), bin)]) return ((pos_peaks, midhigh_peaks, midlow_peaks, neg_peaks), (pos, middle_high, middle_low, neg), (np.mean(fam_amplitudes(peaks)), np.mean(vic_amplitudes(peaks))))
from pyqlb.nstats.peaks import fam_amplitudes import numpy as np factory = QLNumpyObjectFactory() class LWPlate(object): def add_well(self, well, fulldata): # Should throw an exception if wellname exists, but have not figure out perl exception handling yet if fulldata: self.well_list[well.name] = well else: self.well_list[well.name] = "" def wells(self): print self return (self.well_list) def __init__(self, filename, platename): self.filename = filename self.platename = platename self.well_list = {} plate = factory.parse_plate( '\\Users\\rrymer\\Documents\\Processing\\Data\\EvaGreenPPEDNRnoBGDNAAttempt3.qlp' ) # this should be quick! a01 = plate.analyzed_wells['A01'] mean = np.mean(fam_amplitudes(a01.peaks)) print mean