def locate_valleys(self, scale=0.3, smooth=1, interpolate_past=200):
        xs = self.xs
        ys = self.ys

        if len(xs) > interpolate_past:
            xs, ys = self.interpolate(xs, ys, interpolate_past)

        if smooth:
            ys = smooth_leveled(xs, ys, smooth)

        maxima_indices, minima_indices = self._extreme_indices(ys)
        candidates = []

        for i in range(len(maxima_indices)):
            max_i = maxima_indices[i]
            for j in range(i + 1, len(maxima_indices)):
                max_j = maxima_indices[j]
                for k in range(len(minima_indices)):
                    min_k = minima_indices[k]
                    y_i = ys[max_i]
                    y_j = ys[max_j]
                    y_k = ys[min_k]
                    if max_i < min_k < max_j and (y_i - y_k) > (y_i * scale) and (
                            y_j - y_k) > (y_j * scale):
                        point = ValleyPoint(y_i, y_k, y_j, xs[max_i], xs[min_k], xs[max_j])
                        candidates.append(point)
        if candidates:
            candidates = sorted(candidates, key=lambda x: x.total_distance, reverse=True)
            best_point = candidates[0]
            self.partition_sites.append(best_point)

        return candidates
    def locate_valleys(self, scale=0.3, smooth=1, interpolate_past=200):
        xs = self.xs
        ys = self.ys

        if len(xs) > interpolate_past:
            xs, ys = self.interpolate(xs, ys, interpolate_past)

        if smooth:
            ys = smooth_leveled(xs, ys, smooth)

        maxima_indices, minima_indices = self._extreme_indices(ys)
        candidates = []

        for i in range(len(maxima_indices)):
            max_i = maxima_indices[i]
            for j in range(i + 1, len(maxima_indices)):
                max_j = maxima_indices[j]
                for k in range(len(minima_indices)):
                    min_k = minima_indices[k]
                    y_i = ys[max_i]
                    y_j = ys[max_j]
                    y_k = ys[min_k]
                    if max_i < min_k < max_j and (y_i - y_k) > (y_i * scale) and (
                            y_j - y_k) > (y_j * scale):
                        point = ValleyPoint(y_i, y_k, y_j, xs[max_i], xs[min_k], xs[max_j])
                        candidates.append(point)
        if candidates:
            candidates = sorted(candidates, key=lambda x: x.total_distance, reverse=True)
            best_point = candidates[0]
            self.partition_sites.append(best_point)

        return candidates
def is_flat(feature, fraction=0.5, smooth=1):
    xs, ys = feature.as_arrays()
    ys = smooth_leveled(xs, ys, smooth)
    apex = ys.max()
    return apex * fraction < ys[0] and apex * fraction < ys[-1]
def is_flat(feature, fraction=0.5, smooth=1):
    xs, ys = feature.as_arrays()
    ys = smooth_leveled(xs, ys, smooth)
    apex = ys.max()
    return apex * fraction < ys[0] and apex * fraction < ys[-1]