def auto_assign_participants(self, participants): """ :type participants: list of Participant :return: """ if len(participants) == 0: return if len(participants) == 1: for message in self.messages: message.participant = participants[0] return rssis = np.array([msg.rssi for msg in self.messages], dtype=np.float32) min_rssi, max_rssi = util.minmax(rssis) center_spacing = (max_rssi - min_rssi) / (len(participants) - 1) centers = [ min_rssi + i * center_spacing for i in range(0, len(participants)) ] rssi_assigned_centers = [] for rssi in rssis: center_index = 0 diff = 999 for i, center in enumerate(centers): if abs(center - rssi) < diff: center_index = i diff = abs(center - rssi) rssi_assigned_centers.append(center_index) participants.sort(key=lambda participant: participant.relative_rssi) for message, center_index in zip(self.messages, rssi_assigned_centers): if message.participant is None: message.participant = participants[center_index]
def detect_noise_level(magnitudes): if len(magnitudes) <= 3: return 0 # 1% for best accuracy and performance for large signals chunksize_percent = 1 chunksize = max(1, int(len(magnitudes) * chunksize_percent / 100)) chunks = [ magnitudes[i - chunksize:i] for i in range(len(magnitudes), 0, -chunksize) if i - chunksize >= 0 ] mean_values = np.fromiter((np.mean(chunk) for chunk in chunks), dtype=np.float32, count=len(chunks)) minimum, maximum = util.minmax(mean_values) if maximum == 0 or minimum / maximum > 0.9: # Mean values are very close to each other, so there is probably no noise in the signal return 0 # Get all indices for values which are in range of 10% of minimum mean value indices = np.nonzero(mean_values <= 1.1 * np.min(mean_values))[0] try: result = np.max( [np.max(chunks[i]) for i in indices if len(chunks[i]) > 0]) except ValueError: return 0 # Round up to fourth digit return math.ceil(result * 10000) / 10000
def auto_assign_participants(self, participants): """ :type participants: list of Participant :return: """ if len(participants) == 0: return if len(participants) == 1: for message in self.messages: message.participant = participants[0] return rssis = np.array([msg.rssi for msg in self.messages], dtype=np.float32) min_rssi, max_rssi = util.minmax(rssis) center_spacing = (max_rssi - min_rssi) / (len(participants) - 1) centers = [min_rssi + i * center_spacing for i in range(0, len(participants))] rssi_assigned_centers = [] for rssi in rssis: center_index = 0 diff = 999 for i, center in enumerate(centers): if abs(center - rssi) < diff: center_index = i diff = abs(center - rssi) rssi_assigned_centers.append(center_index) participants.sort(key=lambda participant: participant.relative_rssi) for message, center_index in zip(self.messages, rssi_assigned_centers): if message.participant is None: message.participant = participants[center_index]
def detect_center(rectangular_signal: np.ndarray): rect = rectangular_signal[rectangular_signal > -4] # do not consider noise hist_min, hist_max = util.minmax(rect) hist_step = 0.05 y, x = np.histogram(rect, bins=np.arange(hist_min, hist_max + hist_step, hist_step)) num_values = 2 most_common_levels = [] for index in np.argsort(y)[::-1]: # check if we have a local maximum in histogram, if yes, append the value left = y[index - 1] if index > 0 else 0 right = y[index + 1] if index < len(y) - 1 else 0 if left < y[index] and y[index] > right: most_common_levels.append(x[index]) if len(most_common_levels) == num_values: break if len(most_common_levels) == 0: return None # todo if num values greater two return more centers return np.mean(most_common_levels)
def detect_noise_level(magnitudes): if len(magnitudes) <= 3: return 0 # 1% for best accuracy and performance for large signals chunksize_percent = 1 chunksize = max(1, int(len(magnitudes) * chunksize_percent / 100)) chunks = [magnitudes[i - chunksize:i] for i in range(len(magnitudes), 0, -chunksize) if i - chunksize >= 0] mean_values = np.fromiter((np.mean(chunk) for chunk in chunks), dtype=np.float32, count=len(chunks)) minimum, maximum = util.minmax(mean_values) if minimum / maximum > 0.9: # Mean values are very close to each other, so there is probably no noise in the signal return 0 # Get all indices for values which are in range of 10% of minimum mean value indices = np.nonzero(mean_values <= 1.1 * np.min(mean_values))[0] try: result = np.max([np.max(chunks[i]) for i in indices if len(chunks[i]) > 0]) except ValueError: return 0 # Round up to fourth digit return math.ceil(result * 10000) / 10000
def auto_fit_view(self): super().auto_fit_view() plot_min, plot_max = util.minmax(self.signal.real_plot_data) data_min, data_max = IQArray.min_max_for_dtype(self.signal.real_plot_data.dtype) self.scale(1, (data_max - data_min) / (plot_max-plot_min)) self.centerOn(self.view_rect().x() + self.view_rect().width() / 2, self.y_center)
def detect_center(rectangular_signal: np.ndarray, max_size=None): rect = rectangular_signal[rectangular_signal > -4] # do not consider noise # Ignore the first and last 5% of samples, # because there tends to be an overshoot at start/end of rectangular signal rect = rect[int(0.05 * len(rect)):int(0.95 * len(rect))] if max_size is not None and len(rect) > max_size: rect = rect[0:max_size] hist_min, hist_max = util.minmax(rect) # The step size of histogram is set to variance of the rectangular signal # If a signal has low variance we need to be more accurate at center detection hist_step = float(np.var(rect)) try: y, x = np.histogram(rect, bins=np.arange(hist_min, hist_max + hist_step, hist_step)) except (ZeroDivisionError, ValueError): # For a segment with zero variance (constant line) it is not possible to find a center return None num_values = 2 most_common_levels = [] window_size = max(2, int(0.05 * len(y)) + 1) def get_elem(arr, index: int, default): if 0 <= index < len(arr): return arr[index] else: return default for index in np.argsort(y)[::-1]: # check if we have a local maximum in histogram, if yes, append the value if all(y[index] > get_elem(y, index + i, 0) and y[index] > get_elem(y, index - i, 0) for i in range(1, window_size)): most_common_levels.append(x[index]) if len(most_common_levels) == num_values: break if len(most_common_levels) == 0: return None # todo if num values greater two return more centers return np.mean(most_common_levels)
def detect_center(rectangular_signal: np.ndarray, max_size=None): rect = rectangular_signal[rectangular_signal > -4] # do not consider noise # Ignore the first and last 5% of samples, # because there tends to be an overshoot at start/end of rectangular signal rect = rect[int(0.05*len(rect)):int(0.95*len(rect))] if max_size is not None and len(rect) > max_size: rect = rect[0:max_size] hist_min, hist_max = util.minmax(rect) # The step size of histogram is set to variance of the rectangular signal # If a signal has low variance we need to be more accurate at center detection hist_step = float(np.var(rect)) try: y, x = np.histogram(rect, bins=np.arange(hist_min, hist_max + hist_step, hist_step)) except ZeroDivisionError: # For a segment with zero variance (constant line) it is not possible to find a center return None num_values = 2 most_common_levels = [] window_size = max(2, int(0.05*len(y))) def get_elem(arr, index: int, default): if 0 <= index < len(arr): return arr[index] else: return default for index in np.argsort(y)[::-1]: # check if we have a local maximum in histogram, if yes, append the value if all(y[index] > get_elem(y, index+i, 0) and y[index] > get_elem(y, index-i, 0) for i in range(1, window_size+1)): most_common_levels.append(x[index]) if len(most_common_levels) == num_values: break if len(most_common_levels) == 0: return None # todo if num values greater two return more centers return np.mean(most_common_levels)
def auto_assign_participants(messages, participants): """ :type messages: list of Message :type participants: list of Participant :return: """ if len(participants) == 0: return if len(participants) == 1: for message in messages: # type: Message message.participant = participants[0] return # Try to assign participants based on SRC_ADDRESS label and participant address for msg in filter(lambda m: m.participant is None, messages): src_address = msg.get_src_address_from_data() if src_address: try: msg.participant = next(p for p in participants if p.address_hex == src_address) except StopIteration: pass # Assign remaining participants based on RSSI of messages rssis = np.array([msg.rssi for msg in messages], dtype=np.float32) min_rssi, max_rssi = util.minmax(rssis) center_spacing = (max_rssi - min_rssi) / (len(participants) - 1) centers = [ min_rssi + i * center_spacing for i in range(0, len(participants)) ] rssi_assigned_centers = [] for rssi in rssis: center_index = np.argmin(np.abs(rssi - centers)) rssi_assigned_centers.append(int(center_index)) participants.sort(key=lambda participant: participant.relative_rssi) for message, center_index in zip(messages, rssi_assigned_centers): if message.participant is None: message.participant = participants[center_index]
def init_scene(self): self.set_text("") if self.num_samples == 0: return if math.isnan(self.minimum) or math.isnan(self.maximum): minimum, maximum = util.minmax(self.plot_data) else: minimum, maximum = self.minimum, self.maximum if abs(minimum) > abs(maximum): minimum = -self.padding*abs(minimum) maximum = -self.padding*minimum else: maximum = abs(maximum) minimum = -maximum # self.scene.setSceneRect(0, -1, num_samples, 2) self.scene.setSceneRect(0, minimum, self.num_samples, maximum - minimum) self.scene.setBackgroundBrush(constants.BGCOLOR) self.line_item.setLine(0, 0, self.num_samples, 0)
def init_scene(self, apply_padding=True): if self.num_samples == 0: return if math.isnan(self.minimum) or math.isnan(self.maximum): minimum, maximum = util.minmax(self.plot_data) else: minimum, maximum = self.minimum, self.maximum padding = self.padding if apply_padding else 1 if abs(minimum) > abs(maximum): minimum = -padding * abs(minimum) maximum = -padding * minimum else: maximum = padding * abs(maximum) minimum = -padding * maximum self.scene.setSceneRect(0, minimum, self.num_samples, maximum - minimum) self.scene.setBackgroundBrush(constants.BGCOLOR) self.line_item.setLine(0, 0, self.num_samples, 0)
def auto_assign_participants(self, participants): """ :type participants: list of Participant :return: """ if len(participants) == 0: return if len(participants) == 1: for message in self.messages: message.participant = participants[0] return # Try to assign participants based on SRC_ADDRESS label and participant address for msg in filter(lambda m: m.participant is None, self.messages): src_address = msg.get_src_address_from_data() if src_address: try: msg.participant = next(p for p in participants if p.address_hex == src_address) except StopIteration: pass # Assign remaining participants based on RSSI of messages rssis = np.array([msg.rssi for msg in self.messages], dtype=np.float32) min_rssi, max_rssi = util.minmax(rssis) center_spacing = (max_rssi - min_rssi) / (len(participants) - 1) centers = [min_rssi + i * center_spacing for i in range(0, len(participants))] rssi_assigned_centers = [] for rssi in rssis: center_index = np.argmin(np.abs(rssi - centers)) rssi_assigned_centers.append(int(center_index)) participants.sort(key=lambda participant: participant.relative_rssi) for message, center_index in zip(self.messages, rssi_assigned_centers): if message.participant is None: message.participant = participants[center_index]
def init_scene(self, apply_padding=True): if self.num_samples == 0: return if math.isnan(self.minimum) or math.isnan(self.maximum): minimum, maximum = util.minmax(self.plot_data) else: minimum, maximum = self.minimum, self.maximum padding = self.padding if apply_padding else 1 if abs(minimum) > abs(maximum): minimum = -padding * abs(minimum) maximum = -padding * minimum else: maximum = padding * abs(maximum) minimum = -padding * maximum self.scene.setSceneRect(0, minimum, self.num_samples, maximum - minimum) self.scene.setBackgroundBrush(constants.BGCOLOR) if self.line_item is not None: self.line_item.setLine(0, 0, self.num_samples, 0)