Example #1
0
    def compute(self, qlplate, plate_metric):
        wells = qlplate.analyzed_wells.values()
        fam_hi = [w for w in wells if w.sample_name in ('FAM HI', 'FAM 350nM')]
        fam_lo = [w for w in wells if w.sample_name in ('FAM LO', 'FAM 40nM')]
        vic_hi = [w for w in wells if w.sample_name in ('VIC HI', 'VIC 350nM')]
        vic_lo = [w for w in wells if w.sample_name in ('VIC LO', 'VIC 70nM')]

        if fam_hi and vic_hi:
            fam_hi_peaks = accepted_peaks(fam_hi[0])
            vic_hi_peaks = accepted_peaks(vic_hi[0])

            # get tight rain boundaries (3.25% CV*3) -- below fam_hi, below vic_hi
            nil, nil, nil, nil, nil, nil, fam_low = rain_pvalues_thresholds(fam_hi_peaks, channel_num=0, threshold=None, pct_boundary=.0975)
            nil, nil, nil, nil, nil, nil, vic_low = rain_pvalues_thresholds(vic_hi_peaks, channel_num=1, threshold=None, pct_boundary=.135)

            all_peaks = np.hstack([fam_hi_peaks, vic_hi_peaks])
            # find total % of all peaks
            dontcare, dontcare, dontcare, rain = cluster_2d(all_peaks, fam_low, vic_low)
            plate_metric.hi_cluster_rain = float(len(rain))/len(all_peaks)
        
        if fam_lo and vic_lo:
            fam_lo_peaks = accepted_peaks(fam_lo[0])
            vic_lo_peaks = accepted_peaks(vic_lo[0])

            # get tight rain boundaries (4.5% CV*3) -- below fam_hi, below vic_hi
            nil, nil, nil, nil, nil, nil, fam_low = rain_pvalues_thresholds(fam_lo_peaks, channel_num=0, threshold=None, pct_boundary=.0975)
            nil, nil, nil, nil, nil, nil, vic_low = rain_pvalues_thresholds(vic_lo_peaks, channel_num=1, threshold=None, pct_boundary=.135)

            all_peaks = np.hstack([fam_lo_peaks, vic_lo_peaks])
            # find total % of all peaks
            dontcare, dontcare, dontcare, rain = cluster_2d(all_peaks, fam_low, vic_low)
            plate_metric.lo_cluster_rain = float(len(rain))/len(all_peaks)
        
        return plate_metric
Example #2
0
def fpfn_by_bin(plate_objects, vic_channels, sample_names, bin_func):
    bins = set([bin_func(c) for c in vic_channels])
    bin_plots = dict([(bin, []) for bin in bins])

    bin_wells = defaultdict(list)
    # divide into plates
    for bin, group in groupinto(vic_channels, bin_func):
        # this is a wacky grouping, but for reuse in plate_objects (why did I not pick plate ids again?)
        plate_groups = groupinto(group, lambda c: (c.well.plate.file.dirname, c.well.plate.file.basename))
        for plate_id, channels in plate_groups:
            qplate = plate_objects[plate_id]
            positives = [c for c in channels if c.well.well_name in fpfn_positive_well_names]
            negatives = [c for c in channels if c.well.well_name in fpfn_negative_well_names]
            
            # compute a threshold which is 1/4 between the positive and negative means for the plate
            positive_means = []
            negative_means = []
            for p in positives:
                amps = vic_amplitudes(accepted_peaks(qplate.wells[p.well.well_name]))
                positive_means.append((len(amps), np.mean(amps)*len(amps)))
            
            if positive_means:
                positive_mean = sum([pm[1] for pm in positive_means])/sum([pm[0] for pm in positive_means])
            else:
                positive_mean = 32767
            
            for n in negatives:
                amps = vic_amplitudes(accepted_peaks(qplate.wells[n.well.well_name]))
                negative_means.append((len(amps), np.mean(amps)*len(amps)))
            
            if negative_means:
                negative_mean = sum([nm[1] for nm in negative_means])/sum([nm[0] for nm in negative_means])
            else:
                negative_mean = 0
            
            threshold = ((3*negative_mean)+positive_mean)/4

            fps = [c for c in channels if c.well.well_name in fpfn_fp_well_names]
            fns = [c for c in channels if c.well.well_name in fpfn_fn_well_names]

            fp_counts = []
            fn_counts = []

            for f in fps:
                pos, neg = cluster_1d(accepted_peaks(qplate.wells[f.well.well_name]), 1, threshold)
                fp_counts.append((f.well.id, len(pos),
                                  10000*(float(len(pos))/(float(len(pos))+float(len(neg)))),
                                  qplate.wells[f.well.well_name]))
            
            for f in fns:
                pos, neg = cluster_1d(accepted_peaks(qplate.wells[f.well.well_name]), 1, threshold)
                fn_counts.append((f.well.id, len(neg),
                                  10000*(float(len(neg))/(float(len(pos))+float(len(neg))))))
            
            bin_wells[bin].append((fp_counts, fn_counts, threshold))
    
    return bin_wells
Example #3
0
    def compute(self, qlplate, plate_metric):
        wells = qlplate.analyzed_wells.values()

        fam_hi = [w for w in wells if w.sample_name in ('FAM HI', 'FAM 350nM')]
        fam_lo = [w for w in wells if w.sample_name in ('FAM LO', 'FAM 40nM')]
        vic_hi = [w for w in wells if w.sample_name in ('VIC HI', 'VIC 350nM')]
        vic_lo = [w for w in wells if w.sample_name in ('VIC LO', 'VIC 70nM')]
        if fam_hi and fam_lo and vic_hi and vic_lo:
            fam_hi_peaks = accepted_peaks(fam_hi[0])
            fam_lo_peaks = accepted_peaks(fam_lo[0])
            vic_hi_peaks = accepted_peaks(vic_hi[0])
            vic_lo_peaks = accepted_peaks(vic_lo[0])

            fam_hi_f = np.mean(fam_amplitudes(fam_hi_peaks))
            fam_hi_v = np.mean(vic_amplitudes(fam_hi_peaks))
            fam_lo_f = np.mean(fam_amplitudes(fam_lo_peaks))
            fam_lo_v = np.mean(vic_amplitudes(fam_lo_peaks))

            vic_hi_f = np.mean(fam_amplitudes(vic_hi_peaks))
            vic_hi_v = np.mean(vic_amplitudes(vic_hi_peaks))
            vic_lo_f = np.mean(fam_amplitudes(vic_lo_peaks))
            vic_lo_v = np.mean(vic_amplitudes(vic_lo_peaks))

            fam_vec = [fam_hi_v-fam_lo_v, fam_hi_f-fam_lo_f]
            vic_vec = [vic_hi_v-vic_lo_v, vic_hi_f-vic_lo_f]
            dot = np.dot(fam_vec, vic_vec)
            norm_diff = abs(90-np.rad2deg(math.acos(dot/(math.hypot(*fam_vec)*math.hypot(*vic_vec)))))
            fam_diff = np.rad2deg(math.atan(fam_vec[0]/fam_vec[1]))
            vic_diff = np.rad2deg(math.atan(vic_vec[1]/vic_vec[0]))

            # maybe there is an easier way to do this, but this is how my brain works
            # y = mx + b forever
            mf = fam_vec[1]/fam_vec[0]
            mv = vic_vec[1]/vic_vec[0]
            bf = fam_hi_f - mf*fam_hi_v
            bv = vic_hi_f - mv*vic_hi_v
            xv = (bv-bf)/(mf-mv)
            xf = mf*xv + bf

            origin_diff = math.sqrt(xv**2+xf**2)
            plate_metric.fam_normal_offset = fam_diff
            plate_metric.vic_normal_offset = vic_diff
            plate_metric.famvic_normal_offset = norm_diff
            plate_metric.famvic_origin_offset = origin_diff
        else:
            plate_metric.fam_normal_offset = None
            plate_metric.vic_normal_offset = None
            plate_metric.famvic_normal_offset = None
            plate_metric.famvic_origin_offset = None
        
        return plate_metric
Example #4
0
    def air_hist(self, id=None, channel_num=0, *args, **kwargs):
        from qtools.lib.nstats.peaks import gap_air
        from pyqlb.nstats.well import accepted_peaks
        from pyqlb.nstats.peaks import color_uncorrected_peaks, channel_amplitudes, peak_times
        from qtools.lib.mplot import air_hist, cleanup, render as plt_render

        qlwell = self.__qlwell_from_threshold_form(id)
        self.__set_threshold_context(qlwell)
        c.channel_num = int(channel_num)
        threshold = c.vic_threshold if c.channel_num == 1 else c.fam_threshold
        cutoff = request.params.get('cutoff', 500)

        # can detect air on either channel (especially if VICs super low)
        # but always report VIC amplitude
        air_drops = gap_air(qlwell, c.channel_num, threshold=threshold)
        uncorrected_air = color_uncorrected_peaks(air_drops, qlwell.color_compensation_matrix)

        # count number of accepted peak times
        air_drop_times = peak_times(air_drops)
        accepted_times = peak_times(accepted_peaks(qlwell))
        num_air_accepted = len([t for t in air_drop_times if t in accepted_times])

        # always gate on VIC
        air_amps = channel_amplitudes(uncorrected_air, 1)

        title = 'Air Droplet Histogram - %s, %s (%s)' % (c.well.plate.plate.name, c.well.well_name, 'VIC' if c.channel_num == 1 else 'FAM')
        fig = air_hist(title, air_amps, cutoff=cutoff, num_accepted=num_air_accepted)
        response.content_type = 'image/png'
        imgdata = plt_render(fig, dpi=72)
        cleanup(fig)
        return imgdata
Example #5
0
    def svilen(self, id=None, *args, **kwargs):
        from pyqlb.nstats.well import accepted_peaks
        from pyqlb.nstats.peaks import cluster_2d, peak_times, fam_widths
        from pyqlb.factory import QLNumpyObjectFactory
        from qtools.lib.mplot import svilen, cleanup, render as plt_render

        qlwell = self.__qlwell_from_threshold_form(id)
        self.__set_threshold_context(qlwell)
        well_path = self.__well_path()
        # oh shit
        factory = QLNumpyObjectFactory()
        raw_well = factory.parse_well(well_path)

        crap, crap, gold, crap = cluster_2d(accepted_peaks(qlwell), c.fam_threshold,
                                            c.vic_threshold)
        
        times = peak_times(gold)
        widths = fam_widths(gold)

        title = "VIC+/FAM- droplet traces (accepted events)"
        ranges = [(int(t-(w*2)), int(t+(w*2))) for t, w in zip(times, widths)]
        if c.fam_threshold == 0 or c.vic_threshold == 0:
            ranges = []
            title = "%s (no events in quadrant)" % title
        elif len(ranges) > 100:
            ranges = ranges[:100]
            title = "%s (truncated at first 100)" % title

        
        fig = svilen(title, raw_well.samples, ranges, widths)
        response.content_type = 'image/png'
        imgdata = plt_render(fig, dpi=72)
        cleanup(fig)
        return imgdata
Example #6
0
    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
Example #7
0
def dnr_by_bin(plate_objects, fam_channels, sample_names, bin_func):
    """
    @deprecated - use metrics
    """
    bins = set([bin_func(c) for c in fam_channels])
    # TODO: do sample names here
    bin_plots = dict([(bin, [[0.001,None],[0.01,None],[0.1,None],[1,None],[5,None]]) for bin in bins])

    groups = []
    groups.extend([(sample_name, groupinto(sample_name_channel_filter(fam_channels, sample_name), bin_func)) for sample_name in sample_names])

    for i, (sample, group) in enumerate(groups):
        for bin, channels in group:
            conc_array = []
            for c in channels:
                qplate = plate_objects[(c.well.plate.file.dirname, c.well.plate.file.basename)]
                well = qplate.wells[c.well.well_name]
                # TODO: use dynamic threshold or keep 4000?
                pos, neg = cluster_1d(accepted_peaks(well), 0, 4000)
                conc, clow, chigh = concentration_interval(len(pos), len(neg), droplet_vol=well.droplet_volume)
                conc_array.append((max(conc,0.0001), max(clow,0.0001), max(chigh,0.0001)))
            
            if len(conc_array) > 0:
                conc_mean = np.mean([ca[0] for ca in conc_array])
                bin_plots[bin][i][1] = (conc_mean, conc_array)
    
    return bin_plots
Example #8
0
    def compute(self, qlwell, well_metric):
        target_channel = qlwell.channels[self.target_channel_num]
        reference_channel = qlwell.channels[self.reference_channel_num]

        cnv, cnv_low, cnv_high = well_observed_cnv_interval(qlwell, self.target_channel_num, self.reference_channel_num)
        inverse_cnv, inverse_cnv_low, inverse_cnv_high = well_observed_cnv_interval(qlwell, self.reference_channel_num, self.target_channel_num)

        well_metric.cnv = cnv
        well_metric.cnv_lower_bound = cnv_low
        well_metric.cnv_upper_bound = cnv_high

        well_metric.inverse_cnv = inverse_cnv
        well_metric.inverse_cnv_lower_bound = inverse_cnv_low
        well_metric.inverse_cnv_upper_bound = inverse_cnv_high
        
        # cnv calc mode is only used for display at the moment, should rename and take out of CNVCalculator.
        if qlwell.clusters_defined:
            well_metric.cnv_calc_mode = QLWellChannelStatistics.CONC_CALC_MODE_CLUSTER
        else:
            well_metric.cnv_calc_mode = QLWellChannelStatistics.CONC_CALC_MODE_THRESHOLD

        if not target_channel.statistics.threshold or not reference_channel.statistics.threshold:
           # cannot compute CNV rise ratio if cannot compute threshold -- pos/neg unknown
           convert_nan_to_none(well_metric)
           return well_metric

        ok_peaks = accepted_peaks(qlwell)
        qsize = len(ok_peaks)/4

        # CLUSTER-TODO: fix
        if(qsize >= 1000):
            fq = ok_peaks[:qsize]
            lq = ok_peaks[(len(ok_peaks)-qsize):]
            fq_target_pos, fq_target_neg = cluster_1d(fq, self.target_channel_num,
                                                      qlwell.channels[self.target_channel_num].statistics.threshold)
            lq_target_pos, lq_target_neg = cluster_1d(lq, self.target_channel_num,
                                                      qlwell.channels[self.target_channel_num].statistics.threshold)
            fq_reference_pos, fq_reference_neg = cluster_1d(fq, self.reference_channel_num,
                                                      qlwell.channels[self.reference_channel_num].statistics.threshold)
            lq_reference_pos, lq_reference_neg = cluster_1d(lq, self.reference_channel_num,
                                                      qlwell.channels[self.reference_channel_num].statistics.threshold)
            
            fq_cnv = get_cnv(len(fq_target_pos), len(fq_target_neg),
                             len(fq_reference_pos), len(fq_reference_neg),
                             reference_copies=qlwell.ref_copy_num)
            lq_cnv = get_cnv(len(lq_target_pos), len(lq_target_neg),
                             len(lq_reference_pos), len(lq_reference_neg),
                             reference_copies=qlwell.ref_copy_num)
            
            if not fq_cnv:
                well_metric.cnv_rise_ratio = None
            else:
                well_metric.cnv_rise_ratio = lq_cnv/fq_cnv


        # TODO: probably best done elsewhere
        convert_nan_to_none(well_metric)
        return well_metric
Example #9
0
 def compute(self, qlwell, qlwell_channel, well_channel_metric):
     if qlwell.sample_name and 'NTC' in qlwell.sample_name:
         ap = accepted_peaks(qlwell)
         if qlwell_channel.channel_num == 0:
             threshold = self.fam_threshold
         else:
             threshold = self.vic_threshold
         ntc_pos, ntc_neg = cluster_1d(ap, qlwell_channel.channel_num, threshold)
         well_channel_metric.ntc_positives = len(ntc_pos)
     return well_channel_metric
Example #10
0
    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')
Example #11
0
def count_positives_in_well(well, channel):
    # return count of positives and total events
    from pyqlb.nstats.peaks import cluster_1d, width_gated, quality_gated
    chn_stats = well.channels[channel].statistics
    threshold = chn_stats.threshold
    min_width_gate = chn_stats.min_width_gate
    max_width_gate = chn_stats.max_width_gate
    min_quality_gate = chn_stats.min_quality_gate
    accepted_events = accepted_peaks(well)
    positives, negatives = cluster_1d(accepted_events, channel, threshold)
    return len(positives), len(positives)+len(negatives)
Example #12
0
 def compute(self, qlwell, well_metric):
     if qlwell.sample_name not in self.test_well_names:
         return well_metric
     
     air_drops = gap_air(qlwell, self.channel_num,
                         max_amp=self.air_max_threshold,
                         threshold=qlwell.channels[self.channel_num].statistics.threshold or None)
     # Rev A: droplets would not be there if below min amplitude
     # Rev B: droplets will have min amplitude flag if they were below 500
     # in the VIC channel
     accepted_times = peak_times(accepted_peaks(qlwell))
     air_times = peak_times(air_drops)
     well_metric.air_droplets = len([t for t in air_times if t in accepted_times])
     well_metric.air_droplets_threshold = qlwell.channels[1].statistics.trigger_min_amplitude
Example #13
0
 def compute(self, qlplate, plate_metric):
     wmd = plate_metric.well_metric_name_dict
     twm = [wmd.get(name, None) for name in self.threshold_well_names]
     twm = [t for t in twm if t]
     thresholds = self._compute_thresholds(twm)
     
     for name in self.measurement_well_names:
         wm = wmd.get(name, None)
         if not wm:
             continue
         for num in self.channel_nums:
             pos, neg = cluster_1d(accepted_peaks(qlplate.analyzed_wells[name]), num, thresholds[num])
             wm.well_channel_metrics[num].false_positive_peaks = len(pos)
             wm.well_channel_metrics[num].manual_threshold = thresholds[num]
     
     return plate_metric
Example #14
0
    def amphist(self, id=None, channel_num=0, *args, **kwargs):
        from qtools.lib.mplot import plot_amp_hist, cleanup, render as plt_render
        from pyqlb.nstats.well import accepted_peaks

        response.content_type = 'image/png'
        c.channel_num = int(channel_num)
        qlwell = self.__qlwell_from_threshold_form(id)
        
        self.__set_threshold_context(qlwell)
        peaks = accepted_peaks(qlwell)
        fig = plot_amp_hist(peaks,
                            title='%s - %s' % (c.well.plate.plate.name, c.well.well_name),
                            channel_num=c.channel_num,
                            threshold=(c.vic_threshold if c.channel_num == 1 else c.fam_threshold))
        imgdata = plt_render(fig, dpi=72)
        cleanup(fig)
        return imgdata
Example #15
0
 def compute(self, qlwell, well_metric):
     # do not compute a metric if neither well has a threshold set
     channels = qlwell.channels
     if not channels or len(channels) != 2:
         return None
     
     for c in channels:
         if c.statistics.threshold == 0 or not c.statistics.threshold:
             return None
     
     # get clusters
     peaks = accepted_peaks(qlwell)
     fampos_vicpos, fampos_vicneg, famneg_vicpos, famneg_vicneg = \
         cluster_2d(peaks, channels[0].statistics.threshold, channels[1].statistics.threshold)
     
     well_metric.null_linkage = linkage_2d(len(fampos_vicpos), len(fampos_vicneg),
                                           len(famneg_vicpos), len(famneg_vicneg))
     return well_metric
Example #16
0
    def compute(self, qlplate, plate_metric):
        wmd = plate_metric.well_metric_name_dict
        pwm = [wmd.get(name, None) for name in self.positive_well_names]
        nwm = [wmd.get(name, None) for name in self.negative_well_names]
        pwm = [p for p in pwm if p]
        nwm = [n for n in nwm if n]
        thresholds = self._compute_thresholds(pwm, nwm)

        for name in self.measurement_well_names:
            wm = wmd.get(name, None)
            if not wm:
                continue
            for num in self.channel_nums:
                pos, neg = cluster_1d(accepted_peaks(qlplate.analyzed_wells[name]), num, thresholds[num])
                wm.well_channel_metrics[num].false_negative_peaks = len(neg)
                wm.well_channel_metrics[num].manual_threshold = thresholds[num]
        
        return plate_metric
Example #17
0
def _compute_well_metrics(qlwell, well_metric):
    """
    Populate the well_metric object with statistics derived from
    the QLWell object.  This computes well-specific metrics, which
    are channel-agnostic, such as width, number of accepted peaks,
    and B-score.

    :param qlwell: QLWell record read from QLP.
    :param well_metric: WellMetric object meant to be stored.
    :return: The WellMetric object, though it gets side-effected.
    """
    # assume that width, events are same in both channels; so the width
    # and quality gates should be OK
    accepted_events = accepted_peaks(qlwell)
    wm = well_metric # for convenience
    wm.accepted_event_count = len(accepted_events)
    wm.total_event_count = len(qlwell.peaks)

    # TODO: double check on desired values for these (width of accepted, or overall width?)
    # current hunch is to use the width of all events
    width_peaks = above_min_amplitude_peaks(qlwell)
    wm.width_mean = np.mean(fam_widths(width_peaks))
    wm.width_variance = np.std(fam_widths(width_peaks))
    wm.accepted_width_mean = np.mean(fam_widths(accepted_events))
    wm.accepted_width_stdev = np.std(fam_widths(accepted_events))
    wm.rejected_peaks = qlwell.statistics.rejected_peaks
    wm.min_amplitude_peaks = len(min_amplitude_peaks(qlwell))
    wm.vertical_streak_events = qlwell.statistics.vertical_streak_peaks
    wm.sum_baseline_mean = qlwell.statistics.sum_baseline_mean
    wm.sum_baseline_stdev = qlwell.statistics.sum_baseline_stdev
    wm.short_interval_count = narrow_droplet_spacing_count(qlwell, threshold=NARROW_NORMALIZED_DROPLET_SPACING)
    wm.short_interval_threshold = NARROW_NORMALIZED_DROPLET_SPACING
    wm.balance_score = well_balance_score_2d(qlwell)[0]
    wm.fragmentation_probability = well_fragmentation_probability(qlwell)[0]

    #new droplet metrics -> Diagonal scatter....
    NEW_DROPLET_CLUSTER_WELL_METRICS_CALCULATOR.compute(qlwell, wm)
	
    global DEFAULT_CNV_CALC
    DEFAULT_CNV_CALC.compute(qlwell, wm)
    global DEFAULT_NULL_LINKAGE_CALC
    DEFAULT_NULL_LINKAGE_CALC.compute(qlwell, wm)

    return wm
Example #18
0
    def cluster(self, id=None, *args, **kwargs):
        from qtools.lib.mplot import plot_threshold_2d, cleanup, render as plt_render
        from qtools.lib.nstats.peaks import accepted_peaks
        
        response.content_type = 'image/png'
        qlwell = self.__qlwell_from_threshold_form(id)
        self.__set_threshold_context(qlwell)
        max_amplitudes = [self.form_result['max_fam_amplitude'], self.form_result['max_vic_amplitude']]
        boundaries = (-2000,-2000,max_amplitudes[1],max_amplitudes[0])

        # to emulate current behavior -- include gated events
        peaks = accepted_peaks(qlwell)
        fig = plot_threshold_2d(peaks,
                                thresholds=(c.fam_threshold, c.vic_threshold),
                                boundaries=boundaries)
        response.content_type = 'image/png'
        imgdata = plt_render(fig, dpi=72)
        cleanup(fig)
        return imgdata
Example #19
0
    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
Example #20
0
 def threshold(self, id=None, show_only_gated=True, *args, **kwargs):
     from qtools.lib.mplot import plot_fam_vic_peaks, cleanup, render as plt_render
     from qtools.lib.nstats.peaks import accepted_peaks
     response.content_type = 'image/png'
     
     qlwell = self.__qlwell_from_threshold_form(id)
     self.__set_threshold_context(qlwell)
     max_amplitudes = [self.form_result['max_fam_amplitude'], self.form_result['max_vic_amplitude']]
     
     # to emulate current behavior -- include gated events
     if show_only_gated != 'False':
         peaks = accepted_peaks(qlwell)
     else:
         peaks = qlwell.peaks
     
     fig = plot_fam_vic_peaks(peaks, thresholds=(c.fam_threshold, c.vic_threshold),
                              max_amplitudes=max_amplitudes,
                              background_rgbs=self.__get_1d_background_rgbs(qlwell))
     response.content_type = 'image/png'
     imgdata = plt_render(fig, dpi=72)
     cleanup(fig)
     return imgdata
Example #21
0
    def cluster2d(self, id=None, *args, **kwargs):
        from qtools.lib.mplot import plot_cluster_2d, cleanup, render as plt_render
        from qtools.lib.nstats.peaks import accepted_peaks
        
        response.content_type = 'image/png'
        qlwell = self.__qlwell_from_threshold_form(id)
        self.__set_threshold_context(qlwell)
        max_amplitudes = [self.form_result['max_fam_amplitude'], self.form_result['max_vic_amplitude']]
        boundaries = (-2000,-2000,max_amplitudes[1],max_amplitudes[0])

        # to emulate current behavior -- include gated events
        peaks = accepted_peaks(qlwell)
        threshold_fallback = qlwell.clustering_method == QLWell.CLUSTERING_TYPE_THRESHOLD
        fig = plot_cluster_2d(peaks,
                              thresholds=(c.fam_threshold, c.vic_threshold),
                              boundaries=boundaries,
                              use_manual_clusters=not well_channel_automatic_classification(qlwell),
                              highlight_thresholds=threshold_fallback)
        response.content_type = 'image/png'
        imgdata = plt_render(fig, dpi=72)
        cleanup(fig)
        return imgdata
Example #22
0
def _compute_well_channel_metrics(qlwell, well_channel_metric, channel_num):
    """
    Internal method for populating a WellChannelMetric object from statistics
    determined by analyzing the QLWell's channel object.

    This will populate the well_channel_metric object with information such
    as positives and negatives, concentration, polydispersity, and other
    metrics that have separate values for FAM and VIC channels.

    :param qlwell: The QLWell object created by reading a QLP file.
    :param well_channel_metric: The WellChannelMetric object to populate.
    :param channel_num: Which channel to analyze.
    """
    # for convenience
    wcm = well_channel_metric
    stats = qlwell.channels[channel_num].statistics
    wcm.min_quality_gating = stats.min_quality_gate
    wcm.min_quality_gating_conf = stats.min_quality_gate_conf
    wcm.min_width_gate = stats.min_width_gate
    wcm.min_width_gate_conf = stats.min_width_gate_conf
    wcm.max_width_gate = stats.max_width_gate
    wcm.max_width_gate_conf = stats.max_width_gate_conf
    wcm.width_gating_sigma = stats.width_gating_sigma
    # TODO: try to guarantee automatic threshold here?
    wcm.threshold = stats.threshold
    wcm.threshold_conf = stats.threshold_conf
    wcm.auto_threshold_expected = False
    wcm.concentration = stats.concentration
    wcm.conc_lower_bound = stats.concentration_lower_bound
    wcm.conc_upper_bound = stats.concentration_upper_bound
    wcm.conc_calc_mode = stats.concentration_calc_mode
    wcm.clusters_automatic = well_channel_automatic_classification(qlwell, channel_num)

    wcm.decision_tree_flags = qlwell.channels[channel_num].decision_tree_flags

    ap = accepted_peaks(qlwell)
    
    if channel_num == 0:
        ampfunc = fam_amplitudes
    elif channel_num == 1:
        ampfunc = vic_amplitudes
    else:
        raise ValueError, "Incompatible channel number: %s" % channel_num

    wcm.amplitude_mean = np.mean(ampfunc(ap))
    wcm.amplitude_stdev = np.std(ampfunc(ap))

    allpeaks = qlwell.peaks
    wcm.total_events_amplitude_mean  = np.mean(ampfunc(allpeaks))
    wcm.total_events_amplitude_stdev = np.std(ampfunc(allpeaks))

    above_min_peaks = above_min_amplitude_peaks(qlwell)
    quality_gated_peaks = quality_rejected(above_min_peaks, wcm.min_quality_gating, channel_num, include_vertical_streak_flagged=False)
    wcm.quality_gated_peaks = len(quality_gated_peaks)
    width_gated_peaks = width_rejected(above_min_peaks, wcm.min_width_gate, wcm.max_width_gate, channel_num)
    wcm.width_gated_peaks = len(width_gated_peaks)
    # TODO add min amplitude, vertical streak

    wcm.s_value = separation_value(ap, channel_num, wcm.threshold)
    p_plus, p, p_minus = rain_pvalues(ap, channel_num, wcm.threshold)
   
    wcm.rain_p_plus = p_plus
    wcm.rain_p = p
    wcm.rain_p_minus = p_minus

    ## extra cluster events...
    NEW_DROPLET_CLUSTER_METRICS_CALCULATOR.compute(qlwell, qlwell.channels[channel_num], wcm)

#    DEFAULT_TEAVALS.compute(qlwell, qlwell.channels[channel_num], wcm)
    DEFAULT_POLYD_CALC.compute(qlwell, qlwell.channels[channel_num], wcm)
    DEFAULT_EXTRAC_CALC.compute(qlwell, qlwell.channels[channel_num], wcm)
    DEFAULT_NTC_POSITIVE_CALCULATOR.compute(qlwell, qlwell.channels[channel_num], wcm)

    wcm.baseline_mean = qlwell.channels[channel_num].statistics.baseline_mean
    wcm.baseline_stdev = qlwell.channels[channel_num].statistics.baseline_stdev
    wcm.cluster_conf = qlwell.channels[channel_num].statistics.cluster_conf

    positive_peaks, negative_peaks, unclassified_peaks = well_observed_positives_negatives(qlwell, channel_num)
    if len(positive_peaks) > 0 or len(negative_peaks) > 0:
        wcm.positive_peaks = len(positive_peaks)
        wcm.negative_peaks = len(negative_peaks)
        wcm.positive_mean = np.mean(ampfunc(positive_peaks))
        wcm.positive_stdev = np.std(ampfunc(positive_peaks))
        wcm.negative_mean = np.mean(ampfunc(negative_peaks))
        wcm.negative_stdev = np.std(ampfunc(negative_peaks))

        wcm.positive_skew = skew(positive_peaks, channel_num)
        wcm.positive_kurtosis = kurtosis(positive_peaks, channel_num)
        wcm.nonpositive_skew = skew(negative_peaks, channel_num)
        wcm.nonpositive_kurtosis = kurtosis(negative_peaks, channel_num)

        # CLUSTER-TODO: this is not going to be right for clusters.  Consider
        # changing this.
        wcm.concentration_rise_ratio = quartile_concentration_ratio(qlwell, peaks=ap,
                                                                    channel_num=channel_num, threshold=wcm.threshold,
                                                                    min_events=4000)

        del positive_peaks
        del negative_peaks
        del unclassified_peaks
    else:
        wcm.nonpositive_skew = skew(ap, channel_num)
        wcm.nonpositive_kurtosis = kurtosis(ap, channel_num)
    
    del ap
    # daisy chain just in case
    return wcm