def onTransition(self, event: QEvent): super().onTransition(event) # Change active session session_id = self.machine().s9.session_id logger.debug(f'[{type(self).__name__}] Change active session to {session_id}') with session_scope(self.database) as s: session = s.query(Session).filter(Session.session_id == session_id).first() self.machine().session = session
def onEntry(self, event: QEvent): super().onEntry(event) self.main_window.show() # Set focus on Start button so that pressing Enter will trigger it logger.debug('Set focus on Start button') self.main_window.measurement_widget.stop_button.setDefault(False) self.main_window.measurement_widget.start_button.setDefault(True) self.main_window.measurement_widget.start_button.setFocus()
def onTransition(self, event: QEvent): super().onTransition(event) with session_scope(self.database) as s: for e in self.machine().annotated_events: logger.debug(f'Remove {str(e)} from database') s.query(AnnotatedEvent).filter( AnnotatedEvent.document_id == e.document_id ).filter(AnnotatedEvent.event_type == e.event_type).filter( AnnotatedEvent.event_num == e.event_num ).delete()
def session_id(self) -> str: """ Return session_id of active (selected) session. If no session is selected, None is returned. """ try: session_id = self.table_widget.item( self.table_widget.currentRow(), 0 ).text() except AttributeError: # AttributeError: 'NoneType' object has no attribute 'text' session_id = None logger.debug(f'Active session_id = {session_id}') return session_id
def keyPressEvent(self, event): # Increase add count when up arrow is pressed if event.key() == Qt.Key_Up: n = self.get_add_count() + 1 logger.debug(f'Increase add count to {n} (Up arrow pressed)') self.set_add_count(n) # Decrease add count when up arrow is pressed elif event.key() == Qt.Key_Down: n = self.get_add_count() - 1 logger.debug(f'Decrease add count to {n} (Down arrow pressed)') self.set_add_count(n) return super().keyPressEvent(event)
def onTransition(self, event: QEvent): super().onTransition(event) logger.debug('Update document in database') with session_scope(self.database) as s: document = ( s.query(Document) .filter(Document.document_id == self.document.document_id) .first() ) document.notes = self.document.notes document.full_turn_count = self.document.full_turn_count logger.debug(str(document))
def create_dummy_sensor() -> Sensor: """ Create a dummy torque (Nm) sensor. :return: Sensor object """ logger.debug('Initialize dummy torque sensor') sensor = Sensor() sensor.value_generator = random_value_generator ch = ChannelInfo('torque', 'Nm') sensor.register_channel(ch) return sensor
def keyPressEvent(self, event): # Increase active distractor when up arrow is pressed if event.key() == QtCore.Qt.Key_Up: self.distractor = self.distractor + 1 logger.debug( f'Change active distractor to {self.distractor} (Up arrow pressed)' ) # Decrease active distractor when down arrow is pressed elif event.key() == QtCore.Qt.Key_Down: self.distractor = self.distractor - 1 logger.debug( f'Change active distractor to {self.distractor} (Down arrow pressed)' ) return super().keyPressEvent(event)
def update_focus(self): """ If no regions have been entered, set focus on Add so that pressing Enter triggers it. Otherwise, set focus on Ok. :return: """ if not self.region_count(): logger.debug('Set focus on Add button') self.region_plot_widget.add_button.setDefault(True) self.ok_button.setDefault(False) else: logger.debug('Set focus on Ok button') self.region_plot_widget.add_button.setDefault(False) self.ok_button.setDefault(True)
def onEntry(self, event: QEvent): super().onEntry(event) # Set default full turn count event_count = len(self.document.get_related_events(self.database)) with session_scope(self.database) as s: sensor_info = (s.query(SensorInfo).filter( SensorInfo.sensor_serial_number == self.document.sensor_serial_number).first()) self.full_turn_count = event_count / float( sensor_info.turns_in_full_turn) logger.debug( f'Calculate default full_turn_count = {self.full_turn_count} = ' f'{event_count} / {sensor_info.turns_in_full_turn}') self.notes = '' self.dialog.open()
def add_button_clicked(self): """ Add a number of regions to the plot matching the number in the add spin box. The region edges are initialized so that the region widths are constant and the regions do not overlap. :return: """ count = self.get_add_count() logger.debug(f'{type(self).__name__} add button clicked (add count={count})') if len(self.x_arr) == 0: logger.error('Unable to add region to empty plot') return 0 if count > 0: x_min = min(self.x_arr) interval = (max(self.x_arr) - x_min) / count for i in range(count): # insert at uniform intervals low = x_min + i * interval high = x_min + (i + 1) * interval self.add_region([low, high])
def onEntry(self, event: QEvent): super().onEntry(event) # MeasurementStateTransition ensures that only one sensor is connected sensor = self.machine().sensor # Create new document self.document = self.create_document() self.main_window.measurement_widget.update_timer.start( self.main_window.measurement_widget.update_interval * 1000) # Clear plot logger.debug('Clear plot') self.main_window.measurement_widget.clear() # Insert sensor info and document to database sensor.enter_info_to_database(self.database) logger.debug(f'Enter document: {str(self.document)}') self.database.insert(self.document) # Kill old producer process if self.main_window.producer_process is not None: self.main_window.producer_process.join() # Create producer process and register connected sensor self.main_window.producer_process = ProducerProcess( 'Torque producer process', document=self.document) self.main_window.register_sensor_with_producer() # Start producing! self.main_window.measurement_widget.producer_process.start() # Set focus on Start button so that pressing Enter will trigger it logger.debug('Set focus on Stop button') self.main_window.measurement_widget.start_button.setDefault(False) self.main_window.measurement_widget.stop_button.setDefault(True) self.main_window.measurement_widget.stop_button.setFocus()
def onTransition(self, event: QEvent): super().onTransition(event) # Assign annotated events and link to document logger.debug('Assign annotated events and link to document') self.annotated_events = self.sourceState().get_annotated_events() for e in self.annotated_events: e.document_id = self.document.document_id logger.debug('Enter annotated events to database') for e in self.annotated_events: self.database.insert(e) logger.debug(str(e))
def add_new(cls, patient_id: str, database: Database): patient = cls(patient_id=patient_id) logger.debug(f'Add patient {patient.patient_id} to database') database.insert(patient)
def onEntry(self, event: QEvent): logger.debug(f'Enter {self.name}')
def onExit(self, event: QEvent): logger.debug(f'Exit {self.name}')
def ok_button_clicked(self): logger.debug('Ok button clicked')
def clear_regions(self): logger.debug('Clear regions') ret = self.region_plot_widget.remove_all() self.update_focus() return ret
def producer_process(self, value: ProducerProcess): self._producer_process = value logger.debug( f'Set measurement widget producer process to {self._producer_process}' ) self.measurement_widget.producer_process = self._producer_process
def closeEvent(self, event): """ User has clicked X on the dialog or QWidget.close() has been called programmatically. """ super().closeEvent(event) logger.debug('X (close) button clicked') self.signal_close.emit()
def enter_info_to_database(cls, database: Database) -> SensorInfo: """ Enter copy of self.sensor_info to a database. """ logger.debug(f'Enter sensor info: {str(cls.sensor_info)}') database.insert(cls.sensor_info, insert_if_exists=False) return cls.sensor_info
def test_event_detection_state_flow(machine, qtbot): pytest.helpers.transition_machine_to_s1(machine) # Assign document machine.document = machine.s2.create_document() # Enter sensor info and document machine.sensor.enter_info_to_database(machine.database) machine.database.insert(machine.document) # Generate and enter data n = 10 time_s = list(range(n)) torque_Nm = list(range(n)) machine.document.insert_time_series(machine.database, time_s, torque_Nm) # Trigger hidden transition from s1 to s3 (EventDetectionState) machine._s1_to_s3_signal.emit() app.processEvents() # Note that regions (sensor_info.turns_in_full_turn) are created on state entry region_count = machine.s3.region_count() # Remove regions machine.s3.dialog.clear_regions() machine.s3.dialog.set_add_count(0) assert machine.s3.region_count() == 0 region_count = 2 # Increase region count by up arrow press for i in range(region_count): with qtbot.waitSignal(machine.s3.signal_value_changed): qtbot.keyPress(machine.s3.dialog, Qt.Key_Up) assert machine.s3.dialog.get_add_count() == i + 1 # Decrease region count by down arrow press for i in reversed(range(region_count)): with qtbot.waitSignal(machine.s3.signal_value_changed): qtbot.keyPress(machine.s3.dialog, Qt.Key_Down) assert machine.s3.dialog.get_add_count() == i # Set correct add count machine.s3.dialog.set_add_count(region_count) # No existing regions -> press enter clicks Add with qtbot.waitSignal(machine.s3.signal_add): qtbot.keyPress(machine.s3.dialog, Qt.Key_Enter) assert machine.s3.region_count() == region_count logger.debug('Regions added and asserted') # Regions exist -> press enter clicks Ok with qtbot.waitSignal(machine.s3.signal_ok): qtbot.keyPress(machine.s3.dialog, Qt.Key_Enter) assert machine.in_state(machine.s6) # Verify that annotated events were entered with session_scope(machine.database) as s: events = ( s.query(AnnotatedEvent) .filter(AnnotatedEvent.document_id == machine.document.document_id) .all() ) assert len(events) == region_count region_edits = [ machine.s3.dialog.get_region_edit(i) for i in range(region_count) ] # Verify region edges for region_edit, event in zip(region_edits, events): assert region_edit.left_edge() == event.event_begin assert region_edit.right_edge() == event.event_end # Trigger transition back to s3 and verify that annotated events were removed machine.s6.signal_close.emit() assert machine.in_state(machine.s3) # Trigger transition back to s6 with qtbot.waitSignal(machine.s3.signal_ok): qtbot.keyPress(machine.s3.dialog, Qt.Key_Enter) assert machine.in_state(machine.s6) # Trigger transition from s6 to s7 (i.e., click Ok on NotesWindow) machine.s6.signal_ok.emit() app.processEvents() # Trigger transition back to s6 (i.e., click No on "are you sure?" prompt) machine.s7.signal_no.emit() app.processEvents() # Enter data in NotesWindow notes = 'foo' full_turn_count = 1.2 machine.s6.dialog.notes = notes machine.s6.dialog.full_turn_count = full_turn_count # Trigger transition from s6 to s7 (i.e., click Ok on NotesWindow) machine.s6.signal_ok.emit() app.processEvents() # Trigger transition from s7 to s1 (i.e., click Yes on "are you sure?" prompt) machine.s7.signal_yes.emit() app.processEvents() # Verify that document updates were entered to database with session_scope(machine.database) as s: document = ( s.query(Document) .filter(Document.document_id == machine.document.document_id) .first() ) assert document.notes == notes assert float(document.full_turn_count) == full_turn_count
def onTransition(self, event: QEvent): super().onTransition(event) patient_id = self.machine().s0_1.dialog.textValue() logger.debug(f'Add patient "{patient_id}" to database') Patient.add_new(patient_id=patient_id, database=self.database)
def connect_dummy_sensor(self): self.sensor = create_dummy_sensor() logger.debug('Connected dummy sensor')
def connect_imada_sensor(self): self.sensor = Imada() logger.debug( f'Connected Imada sensor with serial number "{self.sensor.sensor_info.sensor_serial_number}"' )