def __init__(self, parent=None): super(QMainWindow, self).__init__(parent=parent) self.UI = Ui_MainWindow() self.UI.setupUi(self) self.add_to_log("OpenIMU - Prêt à travailler.", LogTypes.LOGTYPE_INFO) startWindow = StartWindow() if startWindow.exec() == QDialog.Rejected: # User closed the dialog - exits! exit(0) # Init database manager self.currentFileName = startWindow.fileName self.dbMan = DBManager(self.currentFileName) # Setup signals and slots self.setup_signals() # Maximize window self.showMaximized() # Load data self.add_to_log("Chargement des données...", LogTypes.LOGTYPE_INFO) self.currentDataSet = self.dbMan.get_dataset() self.load_data_from_dataset() self.UI.treeDataSet.setCurrentItem(None) # self.loadDemoData() self.add_to_log("Données chargées!", LogTypes.LOGTYPE_DONE) # If we need to import data, show the import dialog if startWindow.importing: self.importRequested()
def ok_clicked(self): # Create and save file db = DBManager(filename=self.UI.txtFileName.text()) if self.dataSet is None: self.dataSet = DataSet() self.dataSet.creation_date = datetime.now() self.dataSet.name = self.UI.txtName.text() self.dataSet.description = self.UI.txtDesc.toPlainText() self.dataSet.author = self.UI.txtAuthor.text() self.dataSet.upload_date = self.UI.calendarUploadDate.selectedDate( ).toPyDate() db.set_dataset_infos(name=self.dataSet.name, desc=self.dataSet.description, author=self.dataSet.author, creation_date=self.dataSet.creation_date, upload_date=self.dataSet.upload_date) self.fileName = self.UI.txtFileName.text() if self.validate(): self.accept()
def test_get_all_sensors(self): manager = DBManager(filename='openimu.db', overwrite=True) # Sensor information id_sensor_type = SensorType.ACCELEROMETER name = 'Accelerometer' hw_name = 'OpenIMU-HW' location = 'wrist' sampling_rate = 30.0 data_rate = 1 count = 10 sensors = [] for i in range(0, count): sensors.append( manager.add_sensor(id_sensor_type, name, hw_name, location, sampling_rate, data_rate)) all_sensors = manager.get_all_sensors() self.assertEqual(len(all_sensors), len(sensors)) # Wrong type self.assertEqual(0, len(manager.get_all_sensors(SensorType.BATTERY))) # Compare content for i in range(0, count): self.assertEqual(sensors[i], all_sensors[i])
def ok_clicked(self): # Only create file if validate if self.validate(): try: # Create and save file db = DBManager(filename=self.UI.txtFileName.text(), newfile=True) if self.dataSet is None: self.dataSet = DataSet() self.dataSet.creation_date = datetime.now() self.dataSet.name = self.UI.txtName.text() self.dataSet.description = self.UI.txtDesc.toPlainText() self.dataSet.author = self.UI.txtAuthor.text() self.dataSet.upload_date = self.UI.dateData.date().toPyDate() db.set_dataset_infos(name=self.dataSet.name, desc=self.dataSet.description, author=self.dataSet.author, creation_date=self.dataSet.creation_date, upload_date=self.dataSet.upload_date) self.fileName = self.UI.txtFileName.text() self.accept() except (DBAPIError, DataError, DatabaseError): print('Error!') box = QMessageBox() box.setText( 'Erreur de création de DB, s.v.p. choisir une répertoire valide' ) box.exec()
def test_get_all_participants(self): manager = DBManager(filename='openimu.db', overwrite=True) # This will add participants # Participant information group = manager.update_group( Group(name='My Group', description='My Group Description')) name = 'Participant Name' description = 'Participant Description' participants = [] # Multiple participants, all the same info... for i in range(0, 10): participants.append( manager.update_participant( Participant(name=name, description=description, group=group))) # Read back list of participants all_participants = manager.get_participants_for_group(group) # Compare size self.assertEqual(len(participants), len(all_participants)) # Compare content for i in range(0, len(participants)): self.assertEqual(participants[i], all_participants[i])
def show_start_window(self): self.clear_main_widgets() self.showMinimized() start_window = StartWindow(self) if start_window.exec() == QDialog.Rejected: # User closed the dialog - exits! sys.exit(0) # Init database manager self.currentFileName = start_window.fileName self.dbMan = DBManager(self.currentFileName) # Maximize window self.showMaximized() # Load data self.add_to_log("Chargement des données...", LogTypes.LOGTYPE_INFO) self.currentDataSet = self.dbMan.get_dataset() self.load_data_from_dataset() self.UI.treeDataSet.setCurrentItem(None) self.UI.treeDataSet.owner = self # self.loadDemoData() self.add_to_log("Données chargées!", LogTypes.LOGTYPE_DONE) # If we need to import data, show the import dialog if start_window.importing: self.import_requested() gc.collect()
class ActigraphDBTest2(unittest.TestCase): @timing def setUp(self): np.set_printoptions(suppress=True) print(__file__ + ' Creating database') # Will read already existing file self.db = DBManager('actigraph.db', False, False) @timing def tearDown(self): self.db.commit() def test_read_all_participant(self): participants = self.db.get_all_participants() print(participants) for participant in participants: print(participant, participant.group) def test_read_all_data(self): recordsets = self.db.get_all_recordsets() for record in recordsets: all_data = self.db.get_all_sensor_data(record, convert=True) for data in all_data: for time in data.to_time_series()['time']: print('time', time) break
def setUp(self): np.set_printoptions(suppress=True) print(__file__ + ' Creating database') self.db = DBManager('actigraph.db', True, False) self.group = self.db.add_group('MyGroup', 'MyDescription') self.participant = self.db.add_participant(group=self.group, name='Anonymous', description='Participant')
def test_add_group(self): manager = DBManager(filename=DBManagerTest.TESTDB_NAME, overwrite=True) # Group information group = Group(name='Group Name', description='Group Description') manager.update_group(group) group2 = manager.get_group(group.id_group) self.assertEqual(group.id_group, group2.id_group) self.assertEqual(group.name, group2.name)
def test_load(self): manager = DBManager('test.db', overwrite=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) # Import to database importer = OpenIMUImporter(manager, participant) results = importer.load('../../../resources/samples/openimu_sample.oimu') # print('results', results) importer.import_to_database(results)
def test_add_channel(self): manager = DBManager(filename='openimu.db', overwrite=True) # Create sensor in DB sensor = manager.add_sensor(SensorType.ACCELEROMETER, 'Sensor Name', 'Hardware Name', 'Wrist', 30.0, 1) channel = manager.add_channel(sensor, Units.GRAVITY_G, DataFormat.FLOAT32, 'Accelerometer_X') channel2 = manager.get_channel(channel.id_channel) self.assertEqual(channel, channel2)
def test_load_zip_file(): # Testing manager = DBManager('applewatch.oi', overwrite=True, newfile=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) importer = AppleWatchImporter(manager, participant) results = importer.load('/Users/dominic/WA/OpenIMU.git/python/applewatch_data.zip') # print('results', results) importer.import_to_database(results)
def import_data_from_wimu_file(filename): # This will create the database (or overwrite it)s manager = DBManager(db_filename, overwrite=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) importer = WIMUImporter(manager, participant) # Load content of the file to the database results = importer.load(filename) importer.import_to_database(results)
def test_load_data_file(): # Testing manager = DBManager('applewatch.oi', overwrite=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) importer = AppleWatchImporter(manager, participant) results = importer.load('/Users/dominic/Documents/working_area/OpenIMU.git/python/watch_ProcessedMotion.data') # print('results', results) importer.import_to_database(results)
def test_load_zip_file(self): # Testing manager = DBManager('applewatch.db', overwrite=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) importer = AppleWatchImporter(manager, participant) results = importer.load('../../../resources/samples/AppleWatch.zip') # print('results', results) importer.import_to_database(results)
def test_loading(self): manager = DBManager('test.db', overwrite=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) # Import to database importer = ActigraphImporter(manager, participant) results = importer.load('../../../resources/samples/test.gt3x') samples = 0 for activity in results[1]['activity']: samples += 3 * len(activity[1]) print('samples imported (each channels)', samples) importer.import_to_database(results) # Reload from database manager = DBManager('test.db') recordsets = manager.get_all_recordsets() self.assertGreater(len(recordsets), 0) loaded_samples = 0 for record in recordsets: # Get all sensors in record sensors = manager.get_all_sensors() for sensor in sensors: if sensor.id_sensor_type == SensorType.ACCELEROMETER: channels = manager.get_all_channels(sensor=sensor) for channel in channels: print('processing channel: ', channel) self.assertEqual(channel.id_sensor, sensor.id_sensor, "id_sensor test for channel") # Will get all data (converted to floats) channel_data = manager.get_all_sensor_data( recordset=record, convert=True, channel=channel) print('channel_data_length', len(channel_data)) for sensor_data in channel_data: self.assertEqual(sensor_data.id_channel, channel.id_channel, "id_channel test for data") self.assertEqual(sensor_data.id_sensor, sensor.id_sensor, "id_sensor test data") loaded_samples += len(sensor_data.data) self.assertEqual(samples, loaded_samples)
def import_data(): manager = DBManager(db_filename) # Create participant participant = manager.update_participant(Participant(name='Participant', description='No description')) # Create importer importer = ActigraphImporter(manager, participant) # Load content of the file to the database results = importer.load('../../resources/samples/test.gt3x') importer.import_to_database(results)
def calculate(self, manager: DBManager, recordsets: list): results = [] for record in recordsets: # Get all sensors in record sensors = manager.get_all_sensors( id_sensor_type=SensorType.ACCELEROMETER) for sensor in sensors: # print('Found Accelerometer') channels = manager.get_all_channels(sensor=sensor) samples_num = 0 # print('Found channels: ', channels) all_channels_data = { 'Accelerometer_X': [], 'Accelerometer_Y': [], 'Accelerometer_Z': [] } for channel_index, channel in enumerate(channels): # if channel.label == 'Accelerometer_Y': # print('Processing Channel :', channel) # Will get all data (converted to floats) channel_data = manager.get_all_sensor_data( recordset=record, convert=True, sensor=sensor, channel=channel) if len(channel_data) > 0: for data in channel_data: all_channels_data[channel.label].append(data) if channel_index == 0: # Compute number of samples total, if we are at the first channel samples_num += len(data.data) if len(all_channels_data['Accelerometer_X']) > 0: # Process all sensor data result = { 'id_recordset': record.id_recordset, 'result_name': record.name + ' (' + sensor.location + '/' + sensor.name + ')', 'id_sensor': sensor.id_sensor, 'result': self.do_calculation(all_channels_data, sensor.sampling_rate, samples_num) } results.append(result) # Return an array with results for each recordset return results
def test_add_recordset(self): manager = DBManager(filename='openimu.db', overwrite=True, echo=False) # Participant information group = manager.update_group( Group(name='My Group', description='My Group Description')) name = 'Participant Name' description = 'Participant Description' participant = manager.update_participant( Participant(name=name, description=description, group=group)) # This gives datetime from seconds from epoch time1 = datetime.datetime.fromtimestamp( datetime.datetime.now().timestamp()) time2 = datetime.datetime.fromtimestamp( datetime.datetime.now().timestamp() + 1) recordset = manager.add_recordset(participant, 'Record Name', time1, time2) recordset2 = manager.get_recordset(recordset.id_recordset) self.assertGreater(recordset.id_recordset, 0) self.assertEqual(recordset.participant, participant) self.assertEqual(recordset.name, 'Record Name') self.assertEqual(recordset.start_timestamp, time1) self.assertEqual(recordset.end_timestamp, time2) self.assertEqual(recordset, recordset2) manager.close()
def test_load(self): manager = DBManager('openimu.oi', overwrite=True, newfile=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) # Import to database importer = OpenIMUImporter(manager, participant) results = importer.load( '../../../resources/samples/openimu_sample.oimu') # results = importer.load('/Users/dominic/Desktop/35.DAT') # print('results', results) importer.import_to_database(results) self.assertTrue(True)
def test_loading(self): manager = DBManager('test.db', overwrite=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) # Import to database importer = WIMUImporter(manager, participant) # results = importer.load('../../../resources/samples/WIMU_ACC_GPS_GYRO_PreProcess.zip') results = importer.load( '../../../resources/samples/REPAR_Sujet7_Semaine_T4.zip') importer.import_to_database(results) recordsets = manager.get_all_recordsets(participant) print('recordsets', recordsets) self.assertGreater(len(recordsets), 0)
def test_load(self): manager = DBManager('openimu.oi', overwrite=True, newfile=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) # Import to database importer = OpenIMUImporter(manager, participant) results = importer.load( '../../../resources/samples/openimu_sample.oimu') # results = importer.load('/Volumes/MINILOGGER/log_20190101_000034/record_20190101_000034.mdat') # print('results', results) importer.import_to_database(results) self.assertTrue(True)
def calculate(self, manager: DBManager, recordsets: list): print('FreedsonAdult1998.calculate') print('Using recordsets', recordsets) results = [] for record in recordsets: # Get all sensors in record sensors = manager.get_all_sensors( id_sensor_type=SensorType.ACCELEROMETER) for sensor in sensors: # print('Found Accelerometer') channels = manager.get_all_channels(sensor=sensor) # print('Found channels: ', channels) for channel in channels: if channel.label == 'Accelerometer_Y': # print('Processing Channel :', channel) # Will get all data (converted to floats) channel_data = manager.get_all_sensor_data( recordset=record, convert=True, sensor=sensor, channel=channel) if len(channel_data) > 0: # Process all sensor data result = { 'id_recordset': record.id_recordset, 'result_name': record.name + ' (' + sensor.location + '/' + sensor.name + ')', 'id_sensor': sensor.id_sensor, 'result': freedson_adult_1998(channel_data, sensor.sampling_rate) } results.append(result) # Return an array with results for each recordset return results
def test_add_sensor(self): manager = DBManager(filename='openimu.db', overwrite=True) # Sensor information id_sensor_type = SensorType.ACCELEROMETER name = 'Accelerometer' hw_name = 'OpenIMU-HW' location = 'wrist' sampling_rate = 30.0 data_rate = 1 sensor = manager.add_sensor(id_sensor_type, name, hw_name, location, sampling_rate, data_rate) sensor2 = manager.get_sensor(sensor.id_sensor) self.assertEqual(sensor.id_sensor, sensor2.id_sensor) self.assertEqual(sensor.id_sensor_type, sensor2.id_sensor_type) self.assertEqual(sensor.name, sensor2.name) self.assertEqual(sensor.hw_name, sensor2.hw_name) self.assertEqual(sensor.location, sensor2.location) self.assertEqual(sensor.sampling_rate, sensor2.sampling_rate) self.assertEqual(sensor.data_rate, sensor2.data_rate)
def test_async_loading(self): manager = DBManager('test.db', overwrite=True) participant = Participant(name='My Participant', description='Participant Description') manager.update_participant(participant) importer = ActigraphImporter(manager, participant) print('Starting threads...') # Start threads threads = [] for i in range(0, 1): threads.append( importer.async_load('../../../resources/samples/test.gt3x')) print('Waiting for threads...') # Wait for threads for t in threads: t.join() recordsets = manager.get_all_recordsets(participant) print('recordsets', recordsets) self.assertGreater(len(recordsets), 0)
def test_get_all_channels(self): manager = DBManager(filename='openimu.db', overwrite=True) # Create sensor in DB sensor = manager.add_sensor(SensorType.ACCELEROMETER, 'Sensor Name', 'Hardware Name', 'Wrist', 30.0, 1) channelx = manager.add_channel(sensor, Units.GRAVITY_G, DataFormat.FLOAT32, 'Accelerometer_X') channely = manager.add_channel(sensor, Units.GRAVITY_G, DataFormat.FLOAT32, 'Accelerometer_Y') channelz = manager.add_channel(sensor, Units.GRAVITY_G, DataFormat.FLOAT32, 'Accelerometer_Z') # Get all channels (from all sensor) channels = manager.get_all_channels() self.assertEqual(len(channels), 3) # Get all channels (from valid sensor) channels = manager.get_all_channels(sensor=sensor) self.assertEqual(len(channels), 3) # Get all channels (from invalid sensor) channels = manager.get_all_channels(sensor=Sensor()) self.assertEqual(len(channels), 0)
def test_add_participant(self): manager = DBManager(filename='openimu.db', overwrite=True) # Participant information group_name = 'My Group' group_description = 'My Group Description' group = Group(name=group_name, description=group_description) manager.update_group(group) participant_name = 'Participant' participant_description = 'Participant Description' participant = Participant(name=participant_name, description=participant_description, group=group) manager.update_participant(participant) participant2 = manager.get_participant(participant.id_participant) self.assertEqual(participant.group, group) self.assertEqual(participant.name, participant_name) self.assertEqual(participant.description, participant_description) self.assertGreater(participant.id_participant, 0) self.assertEqual(participant, participant2) manager.close()
# Create participant participant = db_manager.update_participant( Participant(name='Participant', description='No description')) # Create importer importer = ActigraphImporter(db_manager, participant) # Load content of the file to the database data_results = importer.load('../../resources/samples/test.gt3x') importer.import_to_database(data_results) if not os.path.isfile(db_filename): print('importing actigraph data') import_data() manager = DBManager(db_filename) # Get recordsets recordsets = manager.get_all_recordsets() for record in recordsets: # Get all sensors in record sensors = manager.get_all_sensors() for sensor in sensors: if sensor.id_sensor_type == SensorType.ACCELEROMETER: print('Found Accelerometer') channels = manager.get_all_channels(sensor=sensor) for channel in channels: if channel.label == 'Accelerometer_Y': print('Processing Channel :', channel)
class MainWindow(QMainWindow): currentFileName = '' dbMan = [] currentDataSet = DataSet() currentRecordsets = [] def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.UI = Ui_MainWindow() self.UI.setupUi(self) self.UI.dockToolBar.setTitleBarWidget(QWidget()) self.UI.dockLog.hide() self.add_to_log("OpenIMU - Prêt à travailler.", LogTypes.LOGTYPE_INFO) # Setup signals and slots self.setup_signals() self.show_start_window() def __del__(self): # Restore sys.stdout sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ def show_start_window(self): self.clear_main_widgets() self.showMinimized() start_window = StartWindow(self) if start_window.exec() == QDialog.Rejected: # User closed the dialog - exits! sys.exit(0) # Init database manager self.currentFileName = start_window.fileName self.dbMan = DBManager(self.currentFileName) # Maximize window self.showMaximized() # Load data self.add_to_log("Chargement des données...", LogTypes.LOGTYPE_INFO) self.currentDataSet = self.dbMan.get_dataset() self.load_data_from_dataset() self.UI.treeDataSet.setCurrentItem(None) self.UI.treeDataSet.owner = self # self.loadDemoData() self.add_to_log("Données chargées!", LogTypes.LOGTYPE_DONE) # If we need to import data, show the import dialog if start_window.importing: self.import_requested() gc.collect() def setup_signals(self): self.UI.treeDataSet.itemClicked.connect(self.tree_item_clicked) self.UI.btnDataSetInfos.clicked.connect(self.infos_requested) self.UI.btnAddGroup.clicked.connect(self.new_group_requested) self.UI.btnAddParticipant.clicked.connect( self.new_participant_requested) self.UI.treeDataSet.participantDragged.connect( self.participant_was_dragged) self.UI.btnDelete.clicked.connect(self.delete_requested) self.UI.btnImport.clicked.connect(self.import_requested) self.UI.btnExportCSV.clicked.connect(self.export_csv_requested) self.UI.dockDataset.visibilityChanged.connect( self.UI.btnShowDataset.setChecked) # self.UI.dockLog.visibilityChanged.connect(self.toggle_log) self.UI.btnShowDataset.clicked.connect(self.toggle_dataset) self.UI.btnShowLog.clicked.connect(self.toggle_log) self.UI.btnTransfer.clicked.connect(self.transfer_requested) self.UI.btnClose.clicked.connect(self.db_close_requested) self.UI.btnCompact.clicked.connect(self.db_compact_requested) self.UI.btnProcess.clicked.connect(self.process_data_requested) def console_log_normal(self, text): self.add_to_log(text, LogTypes.LOGTYPE_DEBUG) def console_log_error(self, text): self.add_to_log(text, LogTypes.LOGTYPE_ERROR) @pyqtSlot() def load_data_from_dataset(self): self.UI.treeDataSet.clear() self.clear_main_widgets() # Groups groups = self.dbMan.get_all_groups() for group in groups: self.UI.treeDataSet.update_group(group) # Participants participants = self.dbMan.get_all_participants() for participant in participants: self.UI.treeDataSet.update_participant(participant) # Recordsets recordsets = self.dbMan.get_all_recordsets() for recordset in recordsets: self.UI.treeDataSet.update_recordset(recordset) # Results results = self.dbMan.get_all_processed_data() for result in results: self.UI.treeDataSet.update_result(result) def update_group(self, group): item = self.UI.treeDataSet.update_group(group) self.UI.treeDataSet.setCurrentItem(item) def update_participant(self, participant): item = self.UI.treeDataSet.update_participant(participant) self.UI.treeDataSet.setCurrentItem(item) def clear_main_widgets(self): for i in reversed(range(self.UI.frmMain.layout().count())): self.UI.frmMain.layout().itemAt(i).widget().setParent(None) def show_group(self, group=None): self.clear_main_widgets() group_widget = GroupWindow(dbManager=self.dbMan, group=group) self.UI.frmMain.layout().addWidget(group_widget) group_widget.dataSaved.connect(self.data_was_saved) group_widget.dataCancelled.connect(self.data_was_cancelled) def show_participant(self, participant=None, base_group=None): self.clear_main_widgets() part_widget = ParticipantWindow(dbManager=self.dbMan, participant=participant, default_group=base_group) self.UI.frmMain.layout().addWidget(part_widget) part_widget.dataSaved.connect(self.data_was_saved) part_widget.dataCancelled.connect(self.data_was_cancelled) @pyqtSlot('QString', int) def add_to_log(self, text, log_type): if text == ' ' or text == '\n': return log_format = "" if log_type == LogTypes.LOGTYPE_INFO: log_format = "<span style='color:black'>" if log_type == LogTypes.LOGTYPE_WARNING: log_format = "<span style='color:orange;font-style:italic'>" if log_type == LogTypes.LOGTYPE_ERROR: log_format = "<span style='color:red;font-weight:bold'>" if log_type == LogTypes.LOGTYPE_DEBUG: log_format = "<span style='color:grey;font-style:italic'>" if log_type == LogTypes.LOGTYPE_DONE: log_format = "<span style='color:green;font-weight:bold'>" self.UI.txtLog.append("<span style='color:grey'>" + datetime.now().strftime("%H:%M:%S.%f") + " </span>" + log_format + text + "</span>") self.UI.txtLog.ensureCursorVisible() QApplication.processEvents() def get_current_widget_data_type(self): # TODO: checks! return self.UI.frmMain.layout().itemAt(0).widget().data_type ###################### @pyqtSlot(bool) def toggle_dataset(self, visibility): self.UI.dockDataset.setVisible(visibility) @pyqtSlot(bool) def toggle_log(self, visibility): self.UI.dockLog.setVisible(visibility) # self.UI.btnShowLog.setChecked(visibility) if visibility: sys.stdout = StdConsoleLogger(self.console_log_normal) sys.stderr = StdConsoleLogger(self.console_log_error) else: sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ # print("Test!") @pyqtSlot() def import_requested(self): importer = ImportBrowser(data_manager=self.dbMan) importer.participant_added.connect(self.load_data_from_dataset) importer.log_request.connect(self.add_to_log) importer.setStyleSheet(self.styleSheet()) if importer.exec() == QDialog.Accepted: self.load_data_from_dataset() gc.collect() @pyqtSlot() def export_csv_requested(self): exporter = ExportWindow(self.dbMan, self) exporter.setStyleSheet(self.styleSheet()) if exporter.exec() == QDialog.Accepted: print("Accepted") @pyqtSlot() def infos_requested(self): infos_window = ImportWindow(dataset=self.currentDataSet, filename=self.currentFileName) infos_window.setStyleSheet(self.styleSheet()) infos_window.noImportUI = True infos_window.infosOnly = True if infos_window.exec() != QDialog.Rejected: self.currentDataSet.name = infos_window.dataSet.name @pyqtSlot() def process_data_requested(self): if self.currentRecordsets: # Display Process Window proc_window = ProcessSelectWindow( data_manager=self.dbMan, recordsets=self.currentRecordsets, parent=self) if proc_window.exec() == QDialog.Accepted: self.UI.treeDataSet.update_item("result", proc_window.processed_data) self.UI.treeDataSet.select_item( "result", proc_window.processed_data.id_processed_data) @pyqtSlot() def db_close_requested(self): msg = QMessageBox(self) msg.setIcon(QMessageBox.Question) msg.setStyleSheet("QPushButton{min-width: 100px; min-height: 40px;}") msg.setText( "Cet ensemble de données sera fermé. Désirez-vous poursuivre?") msg.setWindowTitle("Fermeture?") msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) rval = msg.exec() if rval == QMessageBox.Yes: self.dbMan.close() self.add_to_log("Fichier " + self.currentFileName + " fermé.", LogTypes.LOGTYPE_INFO) self.hide() self.show_start_window() @pyqtSlot() def db_compact_requested(self): msg = QMessageBox(self) msg.setIcon(QMessageBox.Question) msg.setStyleSheet("QPushButton{min-width: 100px; min-height: 40px;}") msg.setText( "Le fichier de données sera nettoyé. Ceci peut prendre un certain temps. \n" "Désirez-vous poursuivre?") msg.setWindowTitle("Compactage des données") msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) rval = msg.exec() if rval == QMessageBox.Yes: task = SimpleTask("Compactage des données", self.dbMan.compact) process = BackgroundProcess([task]) dialog = ProgressDialog(process, 'Nettoyage', self) process.start() dialog.exec() @pyqtSlot() def new_group_requested(self): self.show_group() @pyqtSlot() def new_participant_requested(self): # Check if we can get a root item (group) for the current selected item or not item = self.UI.treeDataSet.currentItem() if item is not None: while item.parent() is not None: item = item.parent() default_group = None if self.UI.treeDataSet.get_item_type(item) == "group": default_group = self.UI.treeDataSet.groups[ self.UI.treeDataSet.get_item_id(item)] self.show_participant(base_group=default_group) @pyqtSlot(Participant) def participant_was_dragged(self, participant): self.dbMan.update_participant(participant) self.update_participant(participant) @pyqtSlot(QTreeWidgetItem, int) def tree_item_clicked(self, item: QTreeWidgetItem, _: int): # print(item.text(column)) item_id = self.UI.treeDataSet.get_item_id(item) item_type = self.UI.treeDataSet.get_item_type(item) # Clear all widgets self.clear_main_widgets() self.UI.btnProcess.setEnabled(False) self.currentRecordsets = [] if item_type == "group": self.show_group(self.UI.treeDataSet.groups[item_id]) # groupWidget = GroupWindow(dbManager=self.dbMan, group = self.UI.treeDataSet.groups[item_id]) # self.UI.frmMain.layout().addWidget(groupWidget) if item_type == "participant": self.show_participant(self.UI.treeDataSet.participants[item_id]) if item_type == "recordsets" or item_type == "recordset" or item_type == "subrecord" or item_type == "date": if item_type == "recordsets": part = self.UI.treeDataSet.participants[ self.UI.treeDataSet.get_item_id(item.parent())] self.currentRecordsets = self.dbMan.get_all_recordsets( participant=part) elif item_type == "date": # Find associated participant id_participant = self.UI.treeDataSet.get_item_id( item.parent().parent()) part = self.UI.treeDataSet.participants[id_participant] search_date = self.UI.treeDataSet.dates[ Treedatawidget.get_date_id(item.text(0), id_participant)] self.currentRecordsets = self.dbMan.get_all_recordsets( participant=part, start_date=search_date) else: self.currentRecordsets = [ self.UI.treeDataSet.recordsets[item_id] ] records_widget = RecordsetWindow(manager=self.dbMan, recordset=self.currentRecordsets, parent=self) # records_widget.setStyleSheet(self.styleSheet() + records_widget.styleSheet()) self.UI.frmMain.layout().addWidget(records_widget) records_widget.dataDisplayRequest.connect( self.UI.treeDataSet.select_item) records_widget.dataUpdateRequest.connect( self.UI.treeDataSet.update_item) self.UI.btnProcess.setEnabled(True) if item_type == "result": result_widget = ResultWindow( manager=self.dbMan, results=self.UI.treeDataSet.results[item_id], parent=self) self.UI.frmMain.layout().addWidget(result_widget) item.setExpanded(True) # self.UI.frmMain.update() @pyqtSlot() def data_was_saved(self): item_type = self.get_current_widget_data_type() if item_type == "group": group = self.UI.frmMain.layout().itemAt(0).widget().group self.update_group(group) self.add_to_log("Groupe " + group.name + " mis à jour.", LogTypes.LOGTYPE_DONE) if item_type == "participant": part = self.UI.frmMain.layout().itemAt(0).widget().participant self.update_participant(part) self.add_to_log("Participant " + part.name + " mis à jour.", LogTypes.LOGTYPE_DONE) @pyqtSlot() def data_was_cancelled(self): item_type = self.get_current_widget_data_type() if item_type == "group": if self.UI.frmMain.layout().itemAt(0).widget().group is None: self.clear_main_widgets() if item_type == "participant": if self.UI.frmMain.layout().itemAt(0).widget().participant is None: self.clear_main_widgets() @pyqtSlot() def delete_requested(self): item_id = self.UI.treeDataSet.get_item_id( self.UI.treeDataSet.currentItem()) item_type = self.UI.treeDataSet.get_item_type( self.UI.treeDataSet.currentItem()) # if item_type == "recordsets" or item_type == "results": # return msg = QMessageBox(self) msg.setIcon(QMessageBox.Question) msg.setStyleSheet("QPushButton{min-width: 100px; min-height: 40px;}") msg.setText("Désirez-vous vraiment supprimer \"" + self.UI.treeDataSet.currentItem().text(0) + "\" et tous les éléments associés?") msg.setWindowTitle("Confirmation de suppression") msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) rval = msg.exec() if rval == QMessageBox.Yes: item_name = self.UI.treeDataSet.currentItem().text(0) tasks = [] if item_type == "group": group = self.UI.treeDataSet.groups[item_id] self.UI.treeDataSet.remove_group(group) task = SimpleTask("Suppression de '" + group.name + "'", self.dbMan.delete_group, group) tasks.append(task) if item_type == "participant": part = self.UI.treeDataSet.participants[item_id] self.UI.treeDataSet.remove_participant(part) task = SimpleTask("Suppression de '" + part.name + "'", self.dbMan.delete_participant, part) tasks.append(task) if item_type == "recordset": # Find and remove all related results for result in self.UI.treeDataSet.results.values(): if result is not None: for ref in result.processed_data_ref: if ref.recordset.id_recordset == item_id: self.UI.treeDataSet.remove_result(result) task = SimpleTask( "Suppression de '" + result.name + "'", self.dbMan.delete_processed_data, result) tasks.append(task) # self.dbMan.delete_processed_data(result) break recordset = self.UI.treeDataSet.recordsets[item_id] task = SimpleTask("Suppression de '" + recordset.name + "'", self.dbMan.delete_recordset, recordset) tasks.append(task) # self.dbMan.delete_recordset(recordset) self.UI.treeDataSet.remove_recordset(recordset) if item_type == "result": result = self.UI.treeDataSet.results[item_id] task = SimpleTask("Suppression de '" + result.name + "'", self.dbMan.delete_processed_data, result) tasks.append(task) self.UI.treeDataSet.remove_result(result) # self.dbMan.delete_processed_data(result) if item_type == "date": # Delete all recordsets related to that date id_participant = self.UI.treeDataSet.get_item_id( self.UI.treeDataSet.currentItem().parent().parent()) search_date = self.UI.treeDataSet.dates[ Treedatawidget.get_date_id( self.UI.treeDataSet.currentItem().text(0), id_participant)] recordsets = self.dbMan.get_all_recordsets( start_date=search_date) part_id = None for recordset in recordsets: if part_id is None: part_id = recordset.id_participant task = SimpleTask( "Suppression de '" + recordset.name + "'", self.dbMan.delete_recordset, recordset) tasks.append(task) self.UI.treeDataSet.remove_recordset(recordset) self.UI.treeDataSet.remove_date( self.UI.treeDataSet.currentItem().text(0), part_id) if item_type == "recordsets": # Delete all recordsets for that participant participant = self.UI.treeDataSet.participants[ self.UI.treeDataSet.get_item_id( self.UI.treeDataSet.currentItem().parent())] recordsets = self.dbMan.get_all_recordsets( participant=participant) for recordset in recordsets: task = SimpleTask( "Suppression de '" + recordset.name + "'", self.dbMan.delete_recordset, recordset) tasks.append(task) self.UI.treeDataSet.remove_recordset(recordset) # Remove all dates from the view self.UI.treeDataSet.remove_dates_for_participant( participant.id_participant) if item_type == "results": pass if tasks: process = BackgroundProcess(tasks) # Create progress dialog dialog = ProgressDialog(process, 'Suppression', self) # Start tasks process.start() dialog.exec() # self.dbMan.clean_db() self.add_to_log(item_name + " a été supprimé.", LogTypes.LOGTYPE_DONE) self.clear_main_widgets() # def closeEvent(self, event): # return def create_chart_view(self, test_data=False): chart_view = IMUChartView(self) if test_data is True: chart_view.add_test_data() return chart_view @pyqtSlot() def transfer_requested(self): # import_man = ImportManager(dbmanager=self.dbMan, dirs=True, stream=True, parent=self) # # TODO: More intelligent refresh! # import_man.participant_added.connect(self.load_data_from_dataset) # # if import_man.exec() == QDialog.Accepted: stream_diag = StreamWindow(parent=self) stream_diag.exec() # Do the actual import # msg = QMessageBox(self) # msg.setIcon(QMessageBox.Question) # msg.setStyleSheet("QPushButton{min-width: 100px; min-height: 40px;}") # # msg.setText("Procéder à l'importation des données?") # msg.setWindowTitle("Importer?") # msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) # # rval = msg.exec() # if rval == QMessageBox.Yes: if stream_diag.folders_to_import: # Match windows matcher = ImportMatchDialog(dbmanager=self.dbMan, datas=stream_diag.folders_to_import, parent=self) if matcher.exec() == QDialog.Accepted: # for file_name, file_dataname in file_list.items(): # part = matcher.data_match[file_dataname] # file_match[file_name] = part # Build import list files = matcher.get_files_match( stream_diag.get_data_save_path()) # Start import process import_browser = ImportBrowser(data_manager=self.dbMan, parent=self) import_browser.log_request.connect(self.add_to_log) importer_id = StreamerTypes.value_importer_types[ stream_diag.get_streamer_type()] importer_name = ImporterTypes.value_names[importer_id] for file_name, file_part in files.items(): import_browser.add_file_to_list(file_name, importer_name, importer_id, file_part) import_browser.ok_clicked() # Delete files after transfer? import shutil if not stream_diag.get_delete_files_after_import(): # Move files to "Imported" folder import os target_dir = stream_diag.get_base_data_save_path( ) + os.sep + "Imported" FileManager.merge_folders(stream_diag.get_data_save_path(), target_dir) # Remove transfered files shutil.rmtree(stream_diag.get_data_save_path()) self.load_data_from_dataset()
class MainWindow(QMainWindow): currentFileName = '' dbMan = [] currentDataSet = DataSet() def __init__(self, parent=None): super(QMainWindow, self).__init__(parent=parent) self.UI = Ui_MainWindow() self.UI.setupUi(self) self.add_to_log("OpenIMU - Prêt à travailler.", LogTypes.LOGTYPE_INFO) startWindow = StartWindow() if startWindow.exec() == QDialog.Rejected: # User closed the dialog - exits! exit(0) # Init database manager self.currentFileName = startWindow.fileName self.dbMan = DBManager(self.currentFileName) # Setup signals and slots self.setup_signals() # Maximize window self.showMaximized() # Load data self.add_to_log("Chargement des données...", LogTypes.LOGTYPE_INFO) self.currentDataSet = self.dbMan.get_dataset() self.load_data_from_dataset() self.UI.treeDataSet.setCurrentItem(None) # self.loadDemoData() self.add_to_log("Données chargées!", LogTypes.LOGTYPE_DONE) # If we need to import data, show the import dialog if startWindow.importing: self.importRequested() def setup_signals(self): self.UI.treeDataSet.itemClicked.connect(self.tree_item_clicked) self.UI.btnDataSetInfos.clicked.connect(self.infosRequested) self.UI.btnAddGroup.clicked.connect(self.newGroupRequested) self.UI.btnAddParticipant.clicked.connect(self.newParticipantRequested) self.UI.treeDataSet.participantDragged.connect( self.participant_was_dragged) self.UI.btnDelete.clicked.connect(self.delete_requested) self.UI.btnImport.clicked.connect(self.importRequested) def load_data_from_dataset(self): self.UI.treeDataSet.clear() # Groups groups = self.dbMan.get_all_groups() for group in groups: self.UI.treeDataSet.update_group(group) # Participants participants = self.dbMan.get_all_participants() for participant in participants: self.UI.treeDataSet.update_participant(participant) # Recordsets recordsets = self.dbMan.get_all_recordsets() for recordset in recordsets: self.UI.treeDataSet.update_recordset(recordset) """def create_subrecord_item(self, name, id): item = QTreeWidgetItem() item.setText(0, name) item.setIcon(0, QIcon(':/OpenIMU/icons/subrecord.png')) item.setData(0, Qt.UserRole, id) item.setData(1, Qt.UserRole, 'subrecord') item.setFont(0, QFont('Helvetica', 12, QFont.Bold)) return item def create_sensor_item(self, name, id): item = QTreeWidgetItem() item.setText(0, name) item.setIcon(0, QIcon(':/OpenIMU/icons/sensor.png')) item.setData(0, Qt.UserRole, id) item.setData(1, Qt.UserRole, 'sensor') item.setFont(0, QFont('Helvetica', 12)) return item def create_result_item(self, name, id): item = QTreeWidgetItem() item.setText(0, name) item.setIcon(0, QIcon(':/OpenIMU/icons/result.png')) item.setData(0, Qt.UserRole, id) item.setData(1, Qt.UserRole, 'result') item.setFont(0, QFont('Helvetica', 12)) return item """ def update_group(self, group): item = self.UI.treeDataSet.update_group(group) self.UI.treeDataSet.setCurrentItem(item) def update_participant(self, participant): item = self.UI.treeDataSet.update_participant(participant) self.UI.treeDataSet.setCurrentItem(item) def clear_main_widgets(self): for i in reversed(range(self.UI.frmMain.layout().count())): self.UI.frmMain.layout().itemAt(i).widget().setParent(None) def show_group(self, group=None): self.clear_main_widgets() groupWidget = GroupWindow(dbManager=self.dbMan, group=group) self.UI.frmMain.layout().addWidget(groupWidget) groupWidget.dataSaved.connect(self.dataWasSaved) groupWidget.dataCancelled.connect(self.dataWasCancelled) def show_participant(self, participant=None, base_group=None): self.clear_main_widgets() partWidget = ParticipantWindow(dbManager=self.dbMan, participant=participant, default_group=base_group) self.UI.frmMain.layout().addWidget(partWidget) partWidget.dataSaved.connect(self.dataWasSaved) partWidget.dataCancelled.connect(self.dataWasCancelled) def add_to_log(self, text, log_type): format = "" if log_type == LogTypes.LOGTYPE_INFO: format = "<span style='color:black'>" if log_type == LogTypes.LOGTYPE_WARNING: format = "<span style='color:orange;font-style:italic'>" if log_type == LogTypes.LOGTYPE_ERROR: format = "<span style='color:red;font-weight:bold'>" if log_type == LogTypes.LOGTYPE_DEBUG: format = "<span style='color:grey;font-style:italic'>" if log_type == LogTypes.LOGTYPE_DONE: format = "<span style='color:green;font-weight:bold'>" self.UI.txtLog.append("<span style='color:grey'>" + datetime.now().strftime("%H:%M:%S.%f") + " </span>" + format + text + "</span>") self.UI.txtLog.ensureCursorVisible() def get_current_widget_data_type(self): # TODO: checks! return self.UI.frmMain.layout().itemAt(0).widget().data_type ###################### @pyqtSlot(QUrl) def urlChanged(self, url): print('url: ', url) @pyqtSlot() def importRequested(self): importer = ImportBrowser(dataManager=self.dbMan) if importer.exec() == QDialog.Accepted: self.load_data_from_dataset() @pyqtSlot() def infosRequested(self): infosWindow = ImportWindow(dataset=self.currentDataSet, filename=self.currentFileName) infosWindow.noImportUI = True infosWindow.infosOnly = True if infosWindow.exec() != QDialog.Rejected: # TODO: Save data self.currentDataSet.name = infosWindow.dataSet.name @pyqtSlot() def newGroupRequested(self): self.show_group() @pyqtSlot() def newParticipantRequested(self): # Check if we can get a root item (group) for the current selected item or not item = self.UI.treeDataSet.currentItem() if item is not None: while item.parent() is not None: item = item.parent() default_group = None if self.UI.treeDataSet.get_item_type(item) == "group": default_group = self.UI.treeDataSet.groups[ self.UI.treeDataSet.get_item_id(item)] self.show_participant(base_group=default_group) @pyqtSlot(Participant) def participant_was_dragged(self, participant): self.dbMan.update_participant(participant) self.update_participant(participant) @pyqtSlot(QTreeWidgetItem, int) def tree_item_clicked(self, item, column): # print(item.text(column)) item_id = self.UI.treeDataSet.get_item_id(item) item_type = self.UI.treeDataSet.get_item_type(item) # Clear all widgets self.clear_main_widgets() if item_type == "group": self.show_group(self.UI.treeDataSet.groups[item_id]) # groupWidget = GroupWindow(dbManager=self.dbMan, group = self.UI.treeDataSet.groups[item_id]) # self.UI.frmMain.layout().addWidget(groupWidget) if item_type == "participant": self.show_participant(self.UI.treeDataSet.participants[item_id]) if item_type == "recordsets" or item_type == "recordset" or item_type == "subrecord": if item_type == "recordsets": part = self.UI.treeDataSet.participants[ self.UI.treeDataSet.get_item_id(item.parent())] records = self.dbMan.get_all_recordsets(part) else: records = [self.UI.treeDataSet.recordsets[item_id]] recordsWidget = RecordsetWindow(manager=self.dbMan, recordset=records) self.UI.frmMain.layout().addWidget(recordsWidget) if item_type == "result": resultWidget = ResultWindow() self.UI.frmMain.layout().addWidget(resultWidget) self.UI.frmMain.update() @pyqtSlot() def dataWasSaved(self): item_type = self.get_current_widget_data_type() if item_type == "group": group = self.UI.frmMain.layout().itemAt(0).widget().group self.update_group(group) self.add_to_log("Groupe " + group.name + " mis à jour.", LogTypes.LOGTYPE_DONE) if item_type == "participant": part = self.UI.frmMain.layout().itemAt(0).widget().participant self.update_participant(part) self.add_to_log("Participant " + part.name + " mis à jour.", LogTypes.LOGTYPE_DONE) @pyqtSlot() def dataWasCancelled(self): item_type = self.get_current_widget_data_type() if item_type == "group": if self.UI.frmMain.layout().itemAt(0).widget().group is None: self.clear_main_widgets() if item_type == "participant": if self.UI.frmMain.layout().itemAt(0).widget().participant is None: self.clear_main_widgets() @pyqtSlot() def delete_requested(self): item_id = self.UI.treeDataSet.get_item_id( self.UI.treeDataSet.currentItem()) item_type = self.UI.treeDataSet.get_item_type( self.UI.treeDataSet.currentItem()) if item_type == "recordsets" or item_type == "results": return msg = QMessageBox() msg.setIcon(QMessageBox.Question) msg.setText("Désirez-vous vraiment supprimer " + self.UI.treeDataSet.currentItem().text(0) + " et tous les éléments associés?") msg.setWindowTitle("Confirmation de suppression") msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) rval = msg.exec() if rval == QMessageBox.Yes: item_name = self.UI.treeDataSet.currentItem().text(0) if item_type == "group": group = self.UI.treeDataSet.groups[item_id] self.dbMan.delete_group(group) self.UI.treeDataSet.remove_group(group) if item_type == "participant": part = self.UI.treeDataSet.participants[item_id] self.dbMan.delete_participant(part) self.UI.treeDataSet.remove_participant(part) if item_type == "recordset": recordset = self.UI.treeDataSet.recordsets[item_id] self.dbMan.delete_recordset(recordset) self.UI.treeDataSet.remove_recordset(recordset) self.add_to_log(item_name + " a été supprimé.", LogTypes.LOGTYPE_DONE) self.clear_main_widgets() def closeEvent(self, event): print('closeEvent') """self.jupyter.stop() del self.jupyter self.jupyter = None """ def __del__(self): print('Done!') def create_chart_view(self, test_data=False): chart_view = IMUChartView(self) if test_data is True: chart_view.add_test_data() return chart_view