def testSearchSimilarPatterns(self): template_start_time = 1 template_duration = 2 template_end_time = template_start_time + template_duration template = np.ones((n_leads, template_duration * sampling_freq)) template_start_index = template_start_time * sampling_freq template_end_index = template_end_time * sampling_freq self.base_data[:, template_start_index:template_end_index] = template target_start_time = 5 target_end_time = target_start_time + template_duration target_start_index = target_start_time * sampling_freq target_end_index = target_end_time * sampling_freq self.base_data[:, target_start_index:target_end_index] = template patterns_found = similarity.SearchSimilarPatterns(self.base_data, template_start_time, template_duration, sampling_freq, top_n=3) self.assertLen(patterns_found, 3) target_similar_pattern = similarity_pb2.SimilarPattern() target_similar_pattern.score = 1 target_similar_pattern.start_time = target_start_time target_similar_pattern.duration = template_duration self.assertIn(target_similar_pattern, patterns_found)
def testSearchSimilarPatterns(self): template_start_time = 1 template_duration = 2 template = np.ones((n_leads, template_duration * sampling_freq)) set_slice_value(self.base_data, template, template_start_time, sampling_freq) target_start_time = 5 set_slice_value(self.base_data, template, target_start_time, sampling_freq) patterns_found = similarity.SearchSimilarPatterns(self.base_data, template_start_time, template_duration, [], sampling_freq, top_n=3) self.assertLen(patterns_found, 3) target_similar_pattern = similarity_pb2.SimilarPattern() target_similar_pattern.score = 1 target_similar_pattern.start_time = target_start_time target_similar_pattern.duration = template_duration self.assertIn(target_similar_pattern, patterns_found)
def SearchSimilarPatterns(full_data, window_start, window_duration, seen_events, sampling_freq, top_n=5, merge_close_results=False, merge_threshold=1): """Searches similar patterns for a target window in a 2d array. Args: full_data: numpy array that holds the full data to analyze. Must have shape (n_channels, n_data_points). window_start: the start of the window in seconds. window_duration: the duration of the window in seconds. seen_events: array of TimeSpan marking events already seen. sampling_freq: sampling frequency used in the data. top_n: Amount of similar results to return. merge_close_results: Boolean indicating if merge between near results should be performed. merge_threshold: Amount of seconds to use as merge_threshold. Returns: Array of SimilarPatterns, holding the most similar patterns found. """ window_start_index = int(sampling_freq * window_start) window_end_index = window_start_index + int( sampling_freq * window_duration) window_data = full_data[:, window_start_index:window_end_index] _, n_samples = window_data.shape if window_end_index <= window_start_index or n_samples == 0: raise ValueError( 'Window must have positive duration: found %s-%s, (%s samples)' % (window_end_index, window_start_index, n_samples)) scores = cv2.matchTemplate(full_data, window_data, cv2.TM_CCORR_NORMED)[0] similar_patterns = [] for index, score in enumerate(scores): sim_pattern = similarity_pb2.SimilarPattern() sim_pattern.score = score sim_pattern.duration = window_duration sim_pattern.start_time = float(index) / sampling_freq similar_patterns.append(sim_pattern) similar_patterns = _FilterSeenResults(similar_patterns, seen_events) top_results = _GetTopNonOverlappingResults(similar_patterns, top_n, merge_close_results, merge_threshold) return top_results
def SearchSimilarPatterns(full_data, window_start, window_duration, seen_events, sampling_freq=200, top_n=5): """Searches similar patterns for a target window in a 2d array. Args: full_data: numpy array that holds the full data to analyze. Must have shape (n_channels, n_data_points). window_start: the start of the window in seconds. window_duration: the duration of the window in seconds. seen_events: array of TimeSpan marking events already seen. sampling_freq: sampling frequency used in the data. top_n: Amount of similar results to return. Returns: Array of SimilarPattern proto objects, holding the most similar patterns found. """ window_start_index = int(sampling_freq * window_start) window_duration_index = int(sampling_freq * window_duration) window_end_index = window_start_index + window_duration_index window_data = full_data[:, window_start_index:window_end_index] _, n_samples = window_data.shape if window_end_index <= window_start_index or n_samples == 0: raise ValueError( 'Window must have positive duration: found %s-%s, (%s samples)' % (window_end_index, window_start_index, n_samples)) sims = cv2.matchTemplate(full_data, window_data, cv2.TM_CCORR_NORMED)[0] sims = list(enumerate(sims)) sims = _FilterOverlappedResults(sims, seen_events, sampling_freq) sims = sorted(sims, key=lambda x: x[1], reverse=True) sims = _GetTopNonOverlappingResults(sims, top_n, window_duration_index) sim_patterns = [] for index, score in sims: sim_pattern = similarity_pb2.SimilarPattern() sim_pattern.score = score sim_pattern.duration = window_duration sim_pattern.start_time = float(index) / sampling_freq sim_patterns.append(sim_pattern) return sim_patterns
def _MergePatterns(base_pattern, patterns): """Merges a list of patterns into a base pattern. Keeps the longest span possible and the maximum score. Args: base_pattern: a SimilarPattern instance. patterns: array of SimilarPatterns. Returns: A SimilarPattern with the merged information. """ start_time = base_pattern.start_time end_time = base_pattern.start_time + base_pattern.duration score = base_pattern.score for other_pattern in patterns: start_time = min(start_time, other_pattern.start_time) end_time = max(end_time, other_pattern.start_time + other_pattern.duration) score = max(score, other_pattern.score) merged_pattern = similarity_pb2.SimilarPattern() merged_pattern.start_time = start_time merged_pattern.duration = end_time - start_time merged_pattern.score = score return merged_pattern