Add modulation filter algorithm

This commit is contained in:
alessandro90
2018-11-11 12:58:17 +01:00
parent 7f124e30ff
commit af54095d19
5 changed files with 220 additions and 19 deletions

View File

@@ -59,11 +59,11 @@ class DownloadWindow(QWidget, Ui_Download_window):
@pyqtSlot()
def wait_close(self):
if self.download_thread.status == ThreadStatus.ok:
if self.download_thread.status == ThreadStatus.OK:
self.close()
elif self.download_thread.status == ThreadStatus.no_connection_err:
elif self.download_thread.status == ThreadStatus.NO_CONNECTION_ERR:
self.show_no_connection_warning()
elif self.download_thread.status == ThreadStatus.bad_download_err:
elif self.download_thread.status == ThreadStatus.BAD_DOWNLOAD_ERR:
self.show_bad_download_warning
else:
self.close()

65
main.py
View File

@@ -10,8 +10,10 @@ from PyQt5.QtWidgets import (QMainWindow,
QMessageBox,
qApp,
QDesktopWidget,
QListWidgetItem,)
from PyQt5.QtGui import QPixmap
QListWidgetItem,
QTreeView,
QTreeWidgetItem)
from PyQt5.QtGui import QPixmap, QStandardItemModel, QStandardItem
from PyQt5 import uic
from PyQt5.QtCore import (QFileInfo,
QSize,
@@ -35,7 +37,6 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.download_window = DownloadWindow()
self.actionExit.triggered.connect(qApp.quit)
self.action_update_database.triggered.connect(self.download_db)
self.db_version = None
self.db = None
self.current_signal_name = ''
self.signal_names = []
@@ -267,6 +268,17 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.url_button.clicked.connect(self.go_to_web_page_signal)
# Set modulation TreeView
self.set_mode_tree_widget()
self.mode_tree_widget.itemSelectionChanged.connect(self.manage_mode_selections)
self.reset_mode_filters_btn.clicked.connect(self.reset_mode_filters)
self.apply_remove_mode_filter_btn.set_texts("Apply", "Remove")
self.apply_remove_mode_filter_btn.set_slave_filters([self.mode_tree_widget])
self.apply_remove_mode_filter_btn.clicked.connect(self.display_signals)
self.reset_mode_filters_btn.clicked.connect(self.reset_mode_filters)
# ##########################################################################################
self.show()
self.load_db()
@@ -279,7 +291,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.volume,
self.audio_progress,
Constants.data_folder,
Constants.audio_folder)
Constants.audio_folder) # Da togliere/////////////////
BandLabel = namedtuple("BandLabel", ["left", "center", "right"])
self.band_labels = [
@@ -296,6 +308,24 @@ class MyApp(QMainWindow, Ui_MainWindow):
BandLabel(self.ehf_left, self.ehf, self.ehf_right),
]
def set_mode_tree_widget(self):
for parent, children in Constants.modes.items():
iparent = QTreeWidgetItem([parent])
self.mode_tree_widget.addTopLevelItem(iparent)
for child in children:
ichild = QTreeWidgetItem([child])
iparent.addChild(ichild)
self.mode_tree_widget.expandAll()
def manage_mode_selections(self):
selected_items = self.mode_tree_widget.selectedItems()
parents = Constants.modes.keys()
for parent in parents:
for item in selected_items:
if parent == item.text(0):
for i in range(len(Constants.modes[parent])):
item.child(i).setSelected(True)
def set_initial_size(self):
"""
Function to handle high resolution screens. The function sets bigger sizes
@@ -494,7 +524,8 @@ class MyApp(QMainWindow, Ui_MainWindow):
if text.lower() in signal.lower() and \
self.frequency_filters_ok(signal) and \
self.band_filters_ok(signal) and \
self.category_filters_ok(signal):
self.category_filters_ok(signal) and \
self.mode_filters_ok(signal):
self.result_list.addItem(signal)
available_signals += 1
self.update_status_tip(available_signals)
@@ -552,6 +583,13 @@ class MyApp(QMainWindow, Ui_MainWindow):
f.setChecked(False) if f.isChecked() else None
self.cat_at_least_one.setChecked(True)
def reset_mode_filters(self):
if self.apply_remove_mode_filter_btn.isChecked():
self.apply_remove_mode_filter_btn.setChecked(False)
self.apply_remove_mode_filter_btn.clicked.emit()
for item in self.mode_tree_widget.selectedItems():
item.setSelected(False)
def frequency_filters_ok(self, signal_name):
if not self.apply_remove_freq_filter_btn.isChecked():
return True
@@ -632,6 +670,22 @@ class MyApp(QMainWindow, Ui_MainWindow):
else:
return cat_checked == positive_cases and cat_checked > 0
def mode_filters_ok(self, signal_name):
if not self.apply_remove_mode_filter_btn.isChecked():
return True
selected_items = [item for item in self.mode_tree_widget.selectedItems()]
selected_items_text = [i.text(0) for i in selected_items]
parents = [item for item in selected_items_text if item in Constants.modes.keys()]
children = [item for item in selected_items_text if item not in parents]
signal_mode = self.db.at[signal_name, "mode"]
ok = []
for item in selected_items:
if item.text(0) in parents:
ok.append(item.text(0) in signal_mode)
elif not item.parent().isSelected():
ok.append(item.text(0) == signal_mode)
return any(ok)
@staticmethod
def filters_ok(spinbox, filter_unit, confidence, sign = 1):
band_filter = spinbox.value() * Constants.conversion_factors[filter_unit.currentText()]
@@ -779,6 +833,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.reset_frequency_filters_btn.clicked.emit()
self.reset_band_filters_btn.clicked.emit()
self.reset_cat_filters_btn.clicked.emit()
self.reset_mode_filters_btn.clicked.emit()
@pyqtSlot()
def go_to_web_page_signal(self):

View File

@@ -323,7 +323,7 @@ QPushButton:!enabled {
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<property name="movable">
<bool>true</bool>
@@ -1962,7 +1962,7 @@ QPushButton:checked {
</string>
</property>
<property name="currentIndex">
<number>0</number>
<number>3</number>
</property>
<property name="movable">
<bool>true</bool>
@@ -3691,6 +3691,142 @@ Inactive</string>
<attribute name="title">
<string>Mode</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QWidget" name="mode_filter_container" native="true">
<property name="styleSheet">
<string notr="true">QWidget#mode_filter_container {
border: 1px solid gray;
border-radius: 15px;
}
QWidget#FM_container, QWidget#SK_container, QWidget#SB_container{
border: 1px solid gray;
border-radius: 10px;
}
QWidget#xFM_container, QWidget#xSK_container, QWidget#xSB_container{
border: 1px solid gray;
border-radius: 8px;
}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QPushButton" name="pushButton">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Include unknown modulations</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_26">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QTreeWidget" name="mode_tree_widget">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="animated">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<property name="columnCount">
<number>1</number>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="DoubleTextButton" name="apply_remove_mode_filter_btn">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Apply</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="reset_mode_filters_btn">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_7">
<attribute name="title">

View File

@@ -9,15 +9,15 @@ from PyQt5.QtCore import QThread
from utilities import checksum_ok, Constants
class ThreadStatus(Enum):
ok = auto()
no_connection_err = auto()
no_file_err = auto()
bad_download_err = auto()
OK = auto()
NO_CONNECTION_ERR = auto()
UNKNOWN_ERR = auto()
BAD_DOWNLOAD_ERR = auto()
class DownloadThread(QThread):
def __init__(self):
super().__init__()
self.__status = ThreadStatus.ok
self.__status = ThreadStatus.OK
self.reason = 0
@property
@@ -34,14 +34,14 @@ class DownloadThread(QThread):
# db = urllib.request.urlopen(Constants.db_location)
# raise urllib.error.URLError('Test')
except urllib3.exceptions.MaxRetryError: # No internet connection.
self.__status = ThreadStatus.no_connection_err
self.__status = ThreadStatus.NO_CONNECTION_ERR
return
if db.status != 200:
self.reason = db.reason
self.__status = ThreadStatus.bad_download_err
self.__status = ThreadStatus.BAD_DOWNLOAD_ERR
return
if not checksum_ok(db.data, "folder"):
self.__status = ThreadStatus.bad_download_err
self.__status = ThreadStatus.BAD_DOWNLOAD_ERR
return
if os.path.exists(Constants.data_folder):
rmtree(Constants.data_folder)
@@ -50,4 +50,4 @@ class DownloadThread(QThread):
with ZipFile(BytesIO(db.data)) as zipped:
zipped.extractall()
except:
self.__status = ThreadStatus.bad_file_err
self.__status = ThreadStatus.UNKNOWN_ERR

View File

@@ -36,6 +36,16 @@ class Constants(object):
active_color = _ReadOnlyProperty("#39eaff")
inactive_color = _ReadOnlyProperty("#9f9f9f")
conversion_factors = _ReadOnlyProperty({"Hz":1, "kHz":1000, "MHz":1000000, "GHz":1000000000})
modes = _ReadOnlyProperty({"FM": ["NFM", "WFM"],
"AM": [],
"CW": [],
"SK": ["FSK", "PSK", "MSK"],
"SB": ["LSB", "USB", "DSB"],
"Chirp Spread Spectrum": [],
"FHSS-TDM": [],
"RAW": [],
"SC-FDMA": [],}
)
def checksum_ok(data, what):