def rain_split(qlwell, channel_num=0, threshold=None, pct_boundary=0.3, split_all_peaks=False): """ Splits between rain and non-rain. If you want the well's auto threshold to be used, use None as a threshold parameter (the default). If you do not want a threshold to be calculated, use '0'. (little unclear from the spec) Returns tuple (rain, non-rain) """ if threshold is None: threshold = qlwell.channels[channel_num].statistics.threshold ok_peaks = accepted_peaks(qlwell) prain, rain, nrain, p_thresh, mh_thresh, ml_thresh, l_thresh = \ rain_pvalues_thresholds(ok_peaks, channel_num=channel_num, threshold=threshold, pct_boundary=pct_boundary) if split_all_peaks: peaks = qlwell.peaks else: peaks = ok_peaks # this would be useful as a standalone, but for efficiency's sake will cut out for now rain_condition_arr = [channel_amplitudes(peaks, channel_num) > p_thresh] if mh_thresh and ml_thresh: rain_condition_arr.append(np.logical_and(channel_amplitudes(peaks, channel_num) > ml_thresh, channel_amplitudes(peaks, channel_num) < mh_thresh)) rain_condition_arr.append(channel_amplitudes(peaks, channel_num) < l_thresh) rain_condition = reduce(np.logical_or, rain_condition_arr) nonrain_condition = np.logical_not(rain_condition) rain = np.extract(rain_condition, peaks) nonrain = np.extract(nonrain_condition, peaks) return rain, nonrain
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
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 temporal_galaxy(self, id=None, channel_num=0, *args, **kwargs): from qtools.lib.nstats.peaks import above_min_amplitude_peaks from pyqlb.nstats.peaks import peak_times, channel_amplitudes, channel_widths qlwell = self.__qlwell_from_threshold_form(id) self.__set_threshold_context(qlwell) c.channel_num = int(channel_num) ok_peaks = above_min_amplitude_peaks(qlwell) c.taw = zip(peak_times(ok_peaks), channel_amplitudes(ok_peaks, c.channel_num), channel_widths(ok_peaks, c.channel_num)) if c.channel_num == 0: c.channel_name = 'FAM' else: c.channel_name = 'VIC' return render('/well/temporal_galaxy.html')
def 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) min_gate, max_gate = well_static_width_gates(well) if middle_high and middle_low: extracluster_peaks = np.extract(np.logical_not( np.logical_or( reduce(np.logical_and, (channel_widths(peaks, channel_num) > min_gate, channel_widths(peaks, channel_num) < max_gate, channel_amplitudes(peaks, channel_num) > middle_high, channel_amplitudes(peaks, channel_num) < pos)), reduce(np.logical_and, (channel_widths(peaks, channel_num) > min_gate, channel_widths(peaks, channel_num) < max_gate, channel_amplitudes(peaks, channel_num) > neg, channel_amplitudes(peaks, channel_num) < middle_low)) ) ), peaks) else: extracluster_peaks = np.extract(np.logical_not( reduce(np.logical_and, (channel_widths(peaks, channel_num) > min_gate, channel_widths(peaks, channel_num) < max_gate, channel_amplitudes(peaks, channel_num) > neg, channel_amplitudes(peaks, channel_num) < pos) ) ), peaks) return (extracluster_peaks, (pos, middle_high, middle_low, neg), (min_gate, max_gate))
def gap_air(qlwell, channel_num=0, threshold=None, pct_boundary=0.3, gap_size=10000, gap_buffer=250, max_amp=1000): """ Return the air (gap rain < max_amp) in the gaps between non-rain droplets. :param channel_num: The channel on which to detect air droplets. :param threshold: The threshold dividing positives and negatives (used to detect 'rain') :param pct_boundary: The percentage outside of which a droplet is classified as rain. :param gap_size: The minimum size (in samples) of a gap. Default 0.1s. :param gap_buffer: The distance a droplet must be from the main population to be considered an air droplet, in samples. Default 0.0025s. :param max_amp: The maximum color-corrected amplitude of an air droplet. Default 1000 RFU. """ rain, nonrain = rain_split(qlwell, channel_num=channel_num, threshold=threshold, pct_boundary=pct_boundary, split_all_peaks=True) low_amp = np.extract(channel_amplitudes(rain, channel_num) < max_amp, rain) times = peak_times(nonrain) if nonrain is None or len(nonrain) < 2: return np.ndarray([0], dtype=peak_dtype(2)) intervals = np.ediff1d(times, to_begin=0, to_end=0) big_intervals = intervals > gap_size # find beginning of gaps with extract beginnings = [b+gap_buffer for b in np.extract(big_intervals[1:], times)] ends = [e-gap_buffer for e in np.extract(big_intervals[:-1], times)] gap_intervals = zip(beginnings, ends) gap_intervals.insert(0, (0, times[0]-gap_buffer)) gap_intervals.append((times[-1]+gap_buffer, times[-1]*100)) # count the rain in the intervals gap_drops = np.extract(reduce(np.logical_or, [np.logical_and(peak_times(low_amp) > b, peak_times(low_amp) < e) for b, e in gap_intervals]), low_amp) return gap_drops
def stats_for_qlp_well(well, compute_clusters=False, override_thresholds=None): """ Return statistics about a QLWell object read from a QLP file. The QLWell object should have a populated `peaks` attribute (reading from QLBs won't work) For parameter explanations and return values, see :func:`stats_for_qlp_well`. """ from pyqlb.nstats.peaks import cluster_1d, channel_amplitudes from pyqlb.nstats.well import accepted_peaks, above_min_amplitude_peaks, well_channel_sp_values, well_cluster_peaks from pyqlb.nstats.well import well_observed_positives_negatives, well_s2d_values, getClusters from pyqlb.nstats.well import high_flier_droplets, low_flier_droplets, singleRain_droplets, doubleRain_droplets, diagonal_scatter from numpy import mean as np_mean, std as np_std if not override_thresholds: override_thresholds = (None, None) statistics = well_statistics(well, override_thresholds=override_thresholds) accepted = len(accepted_peaks(well)) num_above_min = len(above_min_amplitude_peaks(well)) if num_above_min > 0 and accepted > 0: if well.sum_amplitude_bins: peaksets, boundaries, amps = revb_polydisperse_peaks(well, 0, threshold=override_thresholds[0]) poly_peaks = sum([len(p) for p in peaksets]) statistics[0].revb_polydispersity_pct = 100*float(poly_peaks)/num_above_min else: peaksets, boundaries, width_gates = polydisperse_peaks(well, 0, threshold=override_thresholds[0]) poly_peaks = sum([len(p) for p in peaksets]) statistics[0].revb_polydispersity_pct = 100*float(poly_peaks)/num_above_min else: statistics[0].revb_polydispersity_pct = 0 s, p_plus, p, p_minus = well_channel_sp_values(well, 0, override_threshold=override_thresholds[0]) statistics[0].s_value = s statistics[0].p_plus = p_plus statistics[0].p_plus_drops = int(p_plus*accepted) if p_plus is not None else None statistics[0].p = p statistics[0].p_drops = int(p*accepted) if p is not None else None statistics[0].p_minus = p_minus statistics[0].p_minus_drops = int(p_minus*accepted) if p_minus is not None else None if num_above_min > 0 and accepted > 0: if well.sum_amplitude_bins: peaksets, boundaries, amps = revb_polydisperse_peaks(well, 1, threshold=override_thresholds[1]) poly_peaks = sum([len(p) for p in peaksets]) statistics[1].revb_polydispersity_pct = 100*float(poly_peaks)/num_above_min else: peaksets, boundaries, width_gates = polydisperse_peaks(well, 1, threshold=override_thresholds[1]) poly_peaks = sum([len(p) for p in peaksets]) statistics[1].revb_polydispersity_pct = 100*float(poly_peaks)/num_above_min else: statistics[1].revb_polydispersity_pct = 0 s, p_plus, p, p_minus = well_channel_sp_values(well, 1, override_threshold=override_thresholds[1]) statistics[1].s_value = s statistics[1].p_plus = p_plus statistics[1].p_plus_drops = int(p_plus*accepted) if p_plus is not None else None statistics[1].p = p statistics[1].p_drops = int(p*accepted) if p is not None else None statistics[1].p_minus = p_minus statistics[1].p_minus_drops = int(p_minus*accepted) if p_minus is not None else None ## compute s2d plots s2d_vals = well_s2d_values( well, thresholds=override_thresholds) statistics[0].s2d_value = s2d_vals[0] if s2d_vals is not None else None statistics[1].s2d_value = s2d_vals[1] if s2d_vals is not None else None ## compute extra cluster metrics clusters = getClusters( well, override_thresholds ) dscatter = diagonal_scatter( clusters ) statistics.diagonal_scatter = dscatter[1] if dscatter is not None else None statistics.diagonal_scatter_pct = dscatter[2] *100 if dscatter is not None else None for channel in [0,1]: high_fliers = high_flier_droplets( clusters, channel ) statistics[channel].high_flier_value = high_fliers[1] if high_fliers is not None else None statistics[channel].high_flier_pct = high_fliers[2] * 100 if high_fliers is not None else None low_fliers = low_flier_droplets( clusters, channel ) statistics[channel].low_flier_value = low_fliers[1] if low_fliers is not None else None statistics[channel].low_flier_pct = low_fliers[2] * 100 if low_fliers is not None else None singleRain = singleRain_droplets( clusters, channel ) statistics[channel].single_rain_value = singleRain[1] if singleRain is not None else None statistics[channel].single_rain_pct = singleRain[2] * 100 if singleRain is not None else None doubleRain = doubleRain_droplets( clusters, channel ) statistics[channel].double_rain_value = doubleRain[1] if doubleRain is not None else None statistics[channel].double_rain_pct = doubleRain[2] * 100 if doubleRain is not None else None if compute_clusters: clusters = well_cluster_peaks(well, override_thresholds) else: clusters = {'positive_peaks': {'positive_peaks': [], 'negative_peaks': []}, 'negative_peaks': {'positive_peaks': [], 'negative_peaks': []}} # cheap hack statistics.alg_version = "%s.%s/%s.%s" % (well.statistics.peak_alg_major_version, well.statistics.peak_alg_minor_version, well.statistics.quant_alg_major_version, well.statistics.quant_alg_minor_version) statistics.ref_copy_num = well.ref_copy_num statistics[0].decision_tree = well.channels[0].decision_tree_verbose statistics[1].decision_tree = well.channels[1].decision_tree_verbose # end cheap hack # SNR for chan in (0,1): if override_thresholds[chan]: # TODO add this to pyqlb.nstats.well instead pos, neg = cluster_1d(accepted_peaks(well), chan, override_thresholds[chan]) else: pos, neg, unknown = well_observed_positives_negatives(well, chan) for attr, coll in (('positive_snr', pos),('negative_snr',neg)): if len(pos) > 0: amps = channel_amplitudes(coll, chan) amp_mean = np_mean(amps) amp_std = np_std(amps) if amp_std > 0: setattr(statistics[chan], attr, amp_mean/amp_std) else: setattr(statistics[chan], attr, 10000) else: setattr(statistics[chan], attr, 0) for channel in [0,1]: means,stds = total_events_amplitude_vals(well,channel) statistics[channel].total_events_amplitude_mean = means if means is not None else None statistics[channel].total_events_amplitude_stdev = stds if stds is not None else None return statistics, clusters
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))))
def revb_extracluster_peaks_by_region(well, channel_num, threshold=None, pct_boundary=0.3, exclude_min_amplitude_peaks=True): """ Return the peaks that are not desired (outside clusters) and separate them by region. The region order is: -- positive large peaks -- positive rain -- positive small peaks -- positive wide peaks (directly above positive cluster) -- positive narrow peaks (directly below positive cluster) -- middle large peaks -- middle rain -- middle small peaks -- negative large peaks -- negative rain -- negative small peaks -- negative wide peaks (directly above positive cluster) -- negative narrow peaks (directly below positive cluster) Returns this 9-tuple, then rain gates, then mean of FAM and VIC. """ extra_peaks, rain_gates, means = \ revb_extracluster_peaks(well, channel_num, threshold=threshold, pct_boundary=pct_boundary, exclude_min_amplitude_peaks=exclude_min_amplitude_peaks) pos_gate, midhigh_gate, midlow_gate, neg_gate = rain_gates binned_peaks = bin_peaks_by_amplitude(extra_peaks, well.sum_amplitude_bins) plpeaks = np.ndarray([0], dtype=peak_dtype(2)) prpeaks = np.ndarray([0], dtype=peak_dtype(2)) pspeaks = np.ndarray([0], dtype=peak_dtype(2)) pwpeaks = np.ndarray([0], dtype=peak_dtype(2)) pnpeaks = np.ndarray([0], dtype=peak_dtype(2)) mlpeaks = np.ndarray([0], dtype=peak_dtype(2)) mrpeaks = np.ndarray([0], dtype=peak_dtype(2)) mspeaks = np.ndarray([0], dtype=peak_dtype(2)) nlpeaks = np.ndarray([0], dtype=peak_dtype(2)) nrpeaks = np.ndarray([0], dtype=peak_dtype(2)) nspeaks = np.ndarray([0], dtype=peak_dtype(2)) nwpeaks = np.ndarray([0], dtype=peak_dtype(2)) nnpeaks = np.ndarray([0], dtype=peak_dtype(2)) for bin, (min_gate, max_gate, boundary) in zip(binned_peaks, well.sum_amplitude_bins): plpeaks = np.hstack([plpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) > max_gate, channel_amplitudes(bin, channel_num) > pos_gate) ), bin)]) prpeaks = np.hstack([prpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) >= min_gate, channel_widths(bin, channel_num) <= max_gate, channel_amplitudes(bin, channel_num) > pos_gate) ), bin)]) pspeaks = np.hstack([pspeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) < min_gate, channel_amplitudes(bin, channel_num) > pos_gate) ), bin)]) if midhigh_gate and midlow_gate: mlpeaks = np.hstack([mlpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) > max_gate, channel_amplitudes(bin, channel_num) < midhigh_gate, channel_amplitudes(bin, channel_num) > midlow_gate) ), bin)]) mrpeaks = np.hstack([mrpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) >= min_gate, channel_widths(bin, channel_num) <= max_gate, channel_amplitudes(bin, channel_num) < midhigh_gate, channel_amplitudes(bin, channel_num) > midlow_gate) ), bin)]) mspeaks = np.hstack([mspeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) < min_gate, channel_amplitudes(bin, channel_num) < midhigh_gate, channel_amplitudes(bin, channel_num) > midlow_gate) ), bin)]) # this means there are positives pwpeaks = np.hstack([pwpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) > max_gate, channel_amplitudes(bin, channel_num) >= midhigh_gate, channel_amplitudes(bin, channel_num) <= pos_gate) ), bin)]) pnpeaks = np.hstack([pnpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) < min_gate, channel_amplitudes(bin, channel_num) >= midhigh_gate, channel_amplitudes(bin, channel_num) <= pos_gate) ), bin)]) nwpeaks = np.hstack([nwpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) > max_gate, channel_amplitudes(bin, channel_num) >= neg_gate, channel_amplitudes(bin, channel_num) <= midlow_gate) ), bin)]) nnpeaks = np.hstack([nnpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) < min_gate, channel_amplitudes(bin, channel_num) >= neg_gate, channel_amplitudes(bin, channel_num) <= midlow_gate) ), bin)]) else: nwpeaks = np.hstack([nwpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) > max_gate, channel_amplitudes(bin, channel_num) >= neg_gate, channel_amplitudes(bin, channel_num) <= pos_gate) ), bin)]) nnpeaks = np.hstack([nnpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) < min_gate, channel_amplitudes(bin, channel_num) >= neg_gate, channel_amplitudes(bin, channel_num) <= pos_gate) ), bin)]) nlpeaks = np.hstack([nlpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) > max_gate, channel_amplitudes(bin, channel_num) < neg_gate) ), bin)]) nrpeaks = np.hstack([nrpeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) >= min_gate, channel_widths(bin, channel_num) <= max_gate, channel_amplitudes(bin, channel_num) < neg_gate) ), bin)]) pbpeaks = np.hstack([pspeaks, np.extract( reduce(np.logical_and, (channel_widths(bin, channel_num) < min_gate, channel_amplitudes(bin, channel_num) >= midhigh_gate, channel_amplitudes(bin, channel_num) <= pos_gate) ), bin)]) return ((plpeaks, prpeaks, pspeaks, pwpeaks, pnpeaks, mlpeaks, mrpeaks, mspeaks, nlpeaks, nrpeaks, nspeaks, nwpeaks, nnpeaks), rain_gates, means)
def polydisperse_peaks(well, channel_num, threshold=None, pct_boundary=0.3, exclude_min_amplitude_peaks=True): """ Returns a 3-tuple (4-tuple, 4-tuple, 2-tuple). The first 4-tuple is: * positive rain above the width gates. * middle rain above the width gates. * middle rain below the width gates. * negative rain below the width gates. 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 last 2-tuple is: * computed min width gate * computed max width gate Positives & negatives are computed on the specified channel number. """ if not threshold: threshold = well.channels[channel_num].statistics.threshold if not threshold: threshold = None # filter out min_amplitude_peaks 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) min_gate, max_gate = well_static_width_gates(well) pos_peaks = np.extract( reduce(np.logical_and, (channel_widths(peaks, channel_num) > max_gate, channel_amplitudes(peaks, channel_num) > pos)), peaks) if middle_high and middle_low: midhigh_peaks = np.extract( reduce(np.logical_and, (channel_widths(peaks, channel_num) > max_gate, reduce(np.logical_and, (channel_amplitudes(peaks, channel_num) < middle_high, channel_amplitudes(peaks, channel_num) > middle_low)))), peaks) midlow_peaks = np.extract( reduce(np.logical_and, (channel_widths(peaks, channel_num) < min_gate, reduce(np.logical_and, (channel_amplitudes(peaks, channel_num) < middle_high, channel_amplitudes(peaks, channel_num) > middle_low)))), peaks) else: midhigh_peaks = np.ndarray([0],dtype=peak_dtype(2)) midlow_peaks = np.ndarray([0],dtype=peak_dtype(2)) neg_peaks = np.extract( reduce(np.logical_and, (channel_widths(peaks, channel_num) < min_gate, channel_amplitudes(peaks, channel_num) < neg)), peaks) return ((pos_peaks, midhigh_peaks, midlow_peaks, neg_peaks), (pos, middle_high, middle_low, neg), (min_gate, max_gate))
def total_events_amplitude_vals(well,ch): peaks = well.peaks return (np.mean(channel_amplitudes(peaks, ch)), np.std(channel_amplitudes(peaks, ch)))