Initial commit: merge nuescan, pymso, pybbd202, and pypewpewhops into scanengine-3

- Merged four separate hardware control projects into unified platform
- Created unified requirements.txt with all dependencies
- Added comprehensive .gitignore
- Added project overview README

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Thomas Ales [M S E]
2026-01-16 20:11:31 -06:00
commit fc43fbe4b0
65 changed files with 19127 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
"""
nueScan - Status Dialog Controller
Handles all UI interactions for the status dialog
Copyright (C) 2025 Thomas Ales
Licensed under GNU General Public License v2.0
"""
import os
from PyQt6 import uic
from PyQt6.QtWidgets import QDialog
class StatusDialog(QDialog):
"""Status dialog for nueScan application"""
def __init__(self, parent, thorlabs_stage, t3r_device, microscope):
super().__init__(parent)
# Store hardware controllers
self.thorlabs_stage = thorlabs_stage
self.t3r_device = t3r_device
self.microscope = microscope
# Load UI file
ui_path = os.path.join(os.path.dirname(__file__), '..', 'nuescan_status_dialog.ui')
uic.loadUi(ui_path, self)
# Set window title
self.setWindowTitle("nueScan - Status Indicators")
def update_all_status(self):
"""Update all status labels with current hardware states"""
self._update_stage_status()
self._update_t3r_status()
self._update_microscope_status()
self._update_transfer_system_status()
def _update_stage_status(self):
"""Update ThorLabs stage status indicators"""
status = self.thorlabs_stage.get_status()
self.l_is_mls_connected.setText("Yes" if status['connected'] else "No")
self.l_is_mls_x_home.setText("Yes" if status['x_homed'] else "No")
self.l_is_mls_y_home.setText("Yes" if status['y_homed'] else "No")
self.l_is_mls_ready.setText("Yes" if status['ready'] else "No")
self.l_is_mls_scanning.setText("Yes" if status['scanning'] else "No")
def _update_t3r_status(self):
"""Update T3R device status indicators"""
status = self.t3r_device.get_status()
self.l_is_t3r_connected.setText("Yes" if status['connected'] else "No")
self.l_is_t3r_homed.setText("Yes" if status['homed'] else "No")
self.l_is_t3r_ready.setText("Yes" if status['ready'] else "No")
def _update_microscope_status(self):
"""Update microscope (Genesis/Helios) status indicators"""
status = self.microscope.get_status()
# Helios status
self.l_is_helios_ready.setText("Yes" if status['helios_ready'] else "No")
self.l_is_helios_interlocked.setText("Yes" if status['helios_interlocked'] else "No")
# Genesis status
self.l_is_genesis_ready.setText("Yes" if status['genesis_ready'] else "No")
self.l_is_genesis_interlocked.setText("Yes" if status['genesis_interlocked'] else "No")
def _update_transfer_system_status(self):
"""Update Robo-met.3D transfer system status indicators"""
# Stub implementation - would read from actual I/O
# These represent digital I/O states
io_states = self._read_transfer_io_states()
# SRAS outputs
self.l_sras_ok.setText("High (1)" if io_states['sras_ok'] else "Low (0)")
self.l_sras_ctl.setText("High (1)" if io_states['sras_ctl'] else "Low (0)")
self.l_sras_done.setText("High (1)" if io_states['sras_done'] else "Low (0)")
self.l_sras_error.setText("High (1)" if io_states['sras_error'] else "Low (0)")
# R3D inputs
self.l_r3d_estop_ok.setText("High (1)" if io_states['r3d_estop'] else "Low (0)")
self.l_r3d_rtl.setText("High (1)" if io_states['r3d_ready_to_load'] else "Low (0)")
self.l_r3d_rts.setText("High (1)" if io_states['r3d_ready_to_start'] else "Low (0)")
self.l_r3d_spare.setText("High (1)" if io_states['r3d_spare'] else "Low (0)")
def _read_transfer_io_states(self):
"""
Stub method to read transfer system I/O states
In production, this would read from actual hardware I/O
"""
return {
'sras_ok': False,
'sras_ctl': False,
'sras_done': False,
'sras_error': False,
'r3d_estop': True, # Active low, so True = OK
'r3d_ready_to_load': False,
'r3d_ready_to_start': False,
'r3d_spare': False
}