refactor: reorganize backend modules into sub-packages for models, data, visualization, wafer, and controllers
This commit is contained in:
@@ -5,13 +5,13 @@ from PySide6.QtQml import QQmlApplicationEngine
|
||||
from PySide6.QtQuickControls2 import QQuickStyle
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
from pygui.backend.device_controller import DeviceController
|
||||
from pygui.backend.local_settings import LocalSettings
|
||||
from pygui.backend.local_settings_model import LocalSettingsModel
|
||||
from pygui.backend.file_browser import FileBrowser
|
||||
from pygui.backend.session_controller import SessionController
|
||||
from pygui.backend.controllers.device_controller import DeviceController
|
||||
from pygui.backend.data.local_settings import LocalSettings
|
||||
from pygui.backend.data.local_settings_model import LocalSettingsModel
|
||||
from pygui.backend.data.file_browser import FileBrowser
|
||||
from pygui.backend.controllers.session_controller import SessionController
|
||||
# Importing wafer_map_item registers the @QmlElement WaferMapItem (QML: import ISC.Wafer).
|
||||
from pygui.backend.wafer_map_item import WaferMapItem
|
||||
from pygui.backend.visualization.wafer_map_item import WaferMapItem
|
||||
|
||||
# ===== Application Entry Point =====
|
||||
def main() -> int:
|
||||
|
||||
@@ -1 +1,32 @@
|
||||
# ===== Backend Package Marker =====
|
||||
# ===== Backend Package =====
|
||||
# Backward-compatible re-exports so existing callers keep working
|
||||
# while imports are migrated to the new sub-package paths.
|
||||
|
||||
from pygui.backend.controllers.device_controller import DeviceController # noqa: F401
|
||||
from pygui.backend.controllers.session_controller import SessionController # noqa: F401
|
||||
|
||||
from pygui.backend.models.frame import Frame # noqa: F401
|
||||
from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data # noqa: F401
|
||||
from pygui.backend.models.frame_stats import Stats, compute_stats # noqa: F401
|
||||
from pygui.backend.models.session_model import SessionModel # noqa: F401
|
||||
from pygui.backend.models.data_model import TemperatureTableModel # noqa: F401
|
||||
from pygui.backend.models.sensor_editor import SensorEditor # noqa: F401
|
||||
from pygui.backend.models.threshold_classifier import ThresholdConfig # noqa: F401
|
||||
from pygui.backend.models.stability_detector import StabilityDetector # noqa: F401
|
||||
|
||||
from pygui.backend.data.csv_recorder import CsvRecorder # noqa: F401
|
||||
from pygui.backend.data.csv_file_metadata import CSVFileMetadata # noqa: F401
|
||||
from pygui.backend.data.data_records import read_data_records # noqa: F401
|
||||
from pygui.backend.data.data_segment import DataSegment # noqa: F401
|
||||
from pygui.backend.data.file_browser import FileBrowser # noqa: F401
|
||||
from pygui.backend.data.local_settings import LocalSettings # noqa: F401
|
||||
from pygui.backend.data.local_settings_model import LocalSettingsModel # noqa: F401
|
||||
|
||||
from pygui.backend.visualization.wafer_map_item import WaferMapItem # noqa: F401
|
||||
from pygui.backend.visualization.graph_view import GraphView # noqa: F401
|
||||
from pygui.backend.visualization.rbf_heatmap import interpolate_field # noqa: F401
|
||||
from pygui.backend.visualization.contour_models import ContourLine, ContourSegment # noqa: F401
|
||||
|
||||
from pygui.backend.wafer.zwafer_models import ZWaferData, Sensor, DataRecord # noqa: F401
|
||||
from pygui.backend.wafer.zwafer_parser import ZWaferParser # noqa: F401
|
||||
from pygui.backend.wafer.wafer_layouts import load_layout, available_families # noqa: F401
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# ===== Controllers Sub-package =====
|
||||
from pygui.backend.controllers.device_controller import DeviceController
|
||||
from pygui.backend.controllers.session_controller import SessionController
|
||||
|
||||
__all__ = ["DeviceController", "SessionController"]
|
||||
|
||||
+4
-4
@@ -15,9 +15,9 @@ from typing import Any, Optional
|
||||
|
||||
from PySide6.QtCore import QObject, Property, Qt, Signal, Slot
|
||||
|
||||
from pygui.backend.data_model import TemperatureTableModel
|
||||
from pygui.backend.graph_view import GraphView
|
||||
from pygui.backend.local_settings import LocalSettings
|
||||
from pygui.backend.models.data_model import TemperatureTableModel
|
||||
from pygui.backend.visualization.graph_view import GraphView
|
||||
from pygui.backend.data.local_settings import LocalSettings
|
||||
from pygui.serialcomm.data_parser import (
|
||||
convert_to_temperatures,
|
||||
parse_binary_data,
|
||||
@@ -26,7 +26,7 @@ from pygui.serialcomm.data_parser import (
|
||||
)
|
||||
from pygui.serialcomm.device_service import DeviceService
|
||||
from pygui.serialcomm.serial_port import WaferInfo
|
||||
from pygui.backend.session_controller import SessionController
|
||||
from pygui.backend.controllers.session_controller import SessionController
|
||||
# import pygui.backend.wafer_map_item
|
||||
|
||||
stream_controller = SessionController()
|
||||
+9
-9
@@ -5,15 +5,15 @@ from typing import Any, Optional
|
||||
|
||||
from PySide6.QtCore import QObject, Property, QTimer, Qt, Signal, Slot
|
||||
|
||||
from pygui.backend.csv_recorder import CsvRecorder
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.frame_player import FramePlayer, frames_from_wafer_data
|
||||
from pygui.backend.session_model import SessionModel
|
||||
from pygui.backend.threshold_classifier import ThresholdConfig
|
||||
from pygui.backend.zwafer_models import Sensor
|
||||
from pygui.backend.zwafer_parser import ZWaferParser
|
||||
from pygui.backend.data.csv_recorder import CsvRecorder
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data
|
||||
from pygui.backend.models.session_model import SessionModel
|
||||
from pygui.backend.models.threshold_classifier import ThresholdConfig
|
||||
from pygui.backend.wafer.zwafer_models import Sensor
|
||||
from pygui.backend.wafer.zwafer_parser import ZWaferParser
|
||||
from pygui.serialcomm.stream_reader import StreamReader
|
||||
from pygui.backend.sensor_editor import SensorEditor
|
||||
from pygui.backend.models.sensor_editor import SensorEditor
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -155,7 +155,7 @@ class SessionController(QObject):
|
||||
# ---- review: file load + playback ----
|
||||
@Slot(str)
|
||||
def loadFile(self, file_path: str) -> None:
|
||||
from pygui.backend.data_records import is_official_csv, read_data_records, read_official_csv
|
||||
from pygui.backend.data.data_records import is_official_csv, read_data_records, read_official_csv
|
||||
|
||||
sensors: list[Sensor] = []
|
||||
frames = []
|
||||
@@ -0,0 +1,2 @@
|
||||
# ===== Crypto Sub-package =====
|
||||
from pygui.backend.crypto.crypto_helper import * # noqa: F403
|
||||
@@ -0,0 +1,16 @@
|
||||
# ===== Data Sub-package =====
|
||||
from pygui.backend.data.csv_recorder import CsvRecorder
|
||||
from pygui.backend.data.csv_file_metadata import CSVFileMetadata
|
||||
from pygui.backend.data.data_records import read_data_records, is_official_csv, read_official_csv
|
||||
from pygui.backend.data.data_segment import DataSegment
|
||||
from pygui.backend.data.file_browser import FileBrowser
|
||||
from pygui.backend.data.local_settings import LocalSettings
|
||||
from pygui.backend.data.local_settings_model import LocalSettingsModel
|
||||
|
||||
__all__ = [
|
||||
"CsvRecorder", "CSVFileMetadata",
|
||||
"read_data_records", "is_official_csv", "read_official_csv",
|
||||
"DataSegment",
|
||||
"FileBrowser",
|
||||
"LocalSettings", "LocalSettingsModel",
|
||||
]
|
||||
@@ -5,8 +5,8 @@ from pathlib import Path
|
||||
from typing import Optional, TextIO
|
||||
|
||||
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.zwafer_models import Sensor
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.backend.wafer.zwafer_models import Sensor
|
||||
|
||||
class CsvRecorder:
|
||||
def __init__(self) -> None:
|
||||
@@ -2,7 +2,7 @@
|
||||
from __future__ import annotations
|
||||
from pathlib import Path
|
||||
|
||||
from pygui.backend.zwafer_models import DataRecord, Sensor
|
||||
from pygui.backend.wafer.zwafer_models import DataRecord, Sensor
|
||||
|
||||
def read_data_records(file_path: str) -> list[DataRecord]:
|
||||
records: list[DataRecord] = []
|
||||
@@ -40,7 +40,7 @@ def is_official_csv(file_path: str) -> bool:
|
||||
|
||||
def read_official_csv(file_path: str) -> tuple[list[Sensor], list[DataRecord]]:
|
||||
"""Parse the headerless official CSV: row 0 = sensor names, rows 1+ = values (no timestamp)."""
|
||||
from pygui.backend.wafer_layouts import load_layout_for_wafer_id
|
||||
from pygui.backend.wafer.wafer_layouts import load_layout_for_wafer_id
|
||||
|
||||
stem = Path(file_path).stem
|
||||
wafer_id = stem.split("-")[0] if "-" in stem else stem
|
||||
@@ -8,8 +8,8 @@ from pathlib import Path
|
||||
from PySide6.QtCore import QObject, Property, QStandardPaths, Signal, Slot
|
||||
from PySide6.QtWidgets import QFileDialog, QMessageBox
|
||||
|
||||
from pygui.backend.csv_file_metadata import CSVFileMetadata
|
||||
from pygui.backend.zwafer_parser import ZWaferParser
|
||||
from pygui.backend.data.csv_file_metadata import CSVFileMetadata
|
||||
from pygui.backend.wafer.zwafer_parser import ZWaferParser
|
||||
|
||||
|
||||
# ===== File Browser Model =====
|
||||
+1
-1
@@ -6,7 +6,7 @@ from typing import Any
|
||||
|
||||
from PySide6.QtCore import QObject, Property, QDateTime, QStandardPaths, Signal, Slot
|
||||
|
||||
from pygui.backend.local_settings import LocalSettings
|
||||
from pygui.backend.data.local_settings import LocalSettings
|
||||
|
||||
|
||||
MASTER_FAMILIES = ("A", "B", "C", "D", "E", "F", "P", "X", "Z")
|
||||
@@ -0,0 +1,19 @@
|
||||
# ===== Models Sub-package =====
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data
|
||||
from pygui.backend.models.frame_stats import Stats, compute_stats
|
||||
from pygui.backend.models.session_model import SessionModel, SessionUpdate
|
||||
from pygui.backend.models.data_model import TemperatureTableModel
|
||||
from pygui.backend.models.sensor_editor import SensorEditor
|
||||
from pygui.backend.models.threshold_classifier import ThresholdConfig, classify, resolve_bounds
|
||||
from pygui.backend.models.stability_detector import StabilityDetector
|
||||
|
||||
__all__ = [
|
||||
"Frame", "FramePlayer", "frames_from_wafer_data",
|
||||
"Stats", "compute_stats",
|
||||
"SessionModel", "SessionUpdate",
|
||||
"TemperatureTableModel",
|
||||
"SensorEditor",
|
||||
"ThresholdConfig", "classify", "resolve_bounds",
|
||||
"StabilityDetector",
|
||||
]
|
||||
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.zwafer_models import ZWaferData
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.backend.wafer.zwafer_models import ZWaferData
|
||||
|
||||
def frames_from_wafer_data(data: ZWaferData, records) -> list[Frame]:
|
||||
"""Build Frames from parsed DataRecords (records = list[DataRecord].)"""
|
||||
@@ -1,10 +1,10 @@
|
||||
from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.frame_stats import Stats, compute_stats
|
||||
from pygui.backend.stability_detector import StabilityDetector
|
||||
from pygui.backend.threshold_classifier import ThresholdConfig, classify, resolve_bounds
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.backend.models.frame_stats import Stats, compute_stats
|
||||
from pygui.backend.models.stability_detector import StabilityDetector
|
||||
from pygui.backend.models.threshold_classifier import ThresholdConfig, classify, resolve_bounds
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SessionUpdate:
|
||||
@@ -0,0 +1,11 @@
|
||||
# ===== Visualization Sub-package =====
|
||||
from pygui.backend.visualization.wafer_map_item import WaferMapItem
|
||||
from pygui.backend.visualization.graph_view import GraphView
|
||||
from pygui.backend.visualization.rbf_heatmap import interpolate_field
|
||||
from pygui.backend.visualization.contour_models import ContourLine, ContourSegment
|
||||
|
||||
__all__ = [
|
||||
"WaferMapItem", "GraphView",
|
||||
"interpolate_field",
|
||||
"ContourLine", "ContourSegment",
|
||||
]
|
||||
+1
-1
@@ -2,7 +2,7 @@ from typing import List, Tuple, Optional
|
||||
|
||||
import numpy as np
|
||||
|
||||
from pygui.backend.contour_models import ContourLine, ContourSegment
|
||||
from pygui.backend.visualization.contour_models import ContourLine, ContourSegment
|
||||
|
||||
|
||||
# ===== Contour Generation =====
|
||||
+2
-2
@@ -20,8 +20,8 @@ from PySide6.QtGui import (
|
||||
from PySide6.QtQml import QmlElement
|
||||
from PySide6.QtQuick import QQuickPaintedItem
|
||||
|
||||
from pygui.backend.rbf_heatmap import interpolate_field
|
||||
from pygui.backend.zwafer_models import Sensor
|
||||
from pygui.backend.visualization.rbf_heatmap import interpolate_field
|
||||
from pygui.backend.wafer.zwafer_models import Sensor
|
||||
|
||||
QML_IMPORT_NAME = "ISC.Wafer"
|
||||
QML_IMPORT_MAJOR_VERSION = 1
|
||||
@@ -0,0 +1,10 @@
|
||||
# ===== Wafer Sub-package =====
|
||||
from pygui.backend.wafer.zwafer_models import ZWaferData, Sensor, DataRecord
|
||||
from pygui.backend.wafer.zwafer_parser import ZWaferParser
|
||||
from pygui.backend.wafer.wafer_layouts import load_layout, available_families
|
||||
|
||||
__all__ = [
|
||||
"ZWaferData", "Sensor", "DataRecord",
|
||||
"ZWaferParser",
|
||||
"load_layout", "available_families",
|
||||
]
|
||||
@@ -16,9 +16,9 @@ from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
from pygui.backend.zwafer_models import Sensor
|
||||
from pygui.backend.wafer.zwafer_models import Sensor
|
||||
|
||||
_LAYOUTS_DIR = Path(__file__).parent.parent / "assets" / "layouts"
|
||||
_LAYOUTS_DIR = Path(__file__).parent.parent.parent / "assets" / "layouts"
|
||||
|
||||
|
||||
def _family_name(raw_name: str) -> str:
|
||||
@@ -2,7 +2,7 @@ from pathlib import Path
|
||||
from typing import Tuple, Optional
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from pygui.backend.zwafer_models import ZWaferData, Sensor
|
||||
from pygui.backend.wafer.zwafer_models import ZWaferData, Sensor
|
||||
|
||||
|
||||
# ===== Z-Wafer CSV Parser =====
|
||||
@@ -11,7 +11,7 @@ from typing import Optional
|
||||
|
||||
import serial.tools.list_ports
|
||||
|
||||
from pygui.backend.local_settings import LocalSettings
|
||||
from pygui.backend.data.local_settings import LocalSettings
|
||||
from pygui.serialcomm.serial_port import SerialPort, WaferInfo
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -4,7 +4,7 @@ import logging
|
||||
import threading
|
||||
from typing import Callable
|
||||
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.models.frame import Frame
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from pygui.backend.csv_recorder import CsvRecorder
|
||||
from pygui.backend.data_records import read_data_records
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.zwafer_models import Sensor
|
||||
from pygui.backend.zwafer_parser import ZWaferParser
|
||||
from pygui.backend.data.csv_recorder import CsvRecorder
|
||||
from pygui.backend.data.data_records import read_data_records
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.backend.wafer.zwafer_models import Sensor
|
||||
from pygui.backend.wafer.zwafer_parser import ZWaferParser
|
||||
|
||||
|
||||
def test_recording_roundtrips_through_parser(tmp_path):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Tests for src/pygui/backend/data_records.py."""
|
||||
from pygui.backend.data_records import read_data_records
|
||||
from pygui.backend.data.data_records import read_data_records
|
||||
|
||||
|
||||
def test_reads_rows_after_data_marker(tmp_path):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.frame_player import FramePlayer
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.backend.models.frame_player import FramePlayer
|
||||
|
||||
def frames(n):
|
||||
return [Frame(seq=i, time=float(i), values=[149.0 + i])for i in range(n)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import math
|
||||
import pytest
|
||||
from pygui.backend.frame_stats import compute_stats, Stats
|
||||
from pygui.backend.models.frame_stats import compute_stats, Stats
|
||||
|
||||
|
||||
def test_basic_stat():
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Tests for src/pygui/backend/rbf_heatmap.py."""
|
||||
import numpy as np
|
||||
from pygui.backend.rbf_heatmap import interpolate_field, BACKEND
|
||||
from pygui.backend.visualization.rbf_heatmap import interpolate_field, BACKEND
|
||||
|
||||
|
||||
def test_field_shape_and_interpolates_at_sites():
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Tests for src/pygui/backend/sensor_editor.py."""
|
||||
import pytest
|
||||
from pygui.backend.sensor_editor import SensorEditor
|
||||
from pygui.backend.models.sensor_editor import SensorEditor
|
||||
|
||||
|
||||
def test_replace_overrides_raw_value():
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.threshold_classifier import ThresholdConfig, BAND_HIGH, BAND_IN, BAND_LOW
|
||||
from pygui.backend.session_model import SessionModel, SessionUpdate
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.backend.models.threshold_classifier import ThresholdConfig, BAND_HIGH, BAND_IN, BAND_LOW
|
||||
from pygui.backend.models.session_model import SessionModel, SessionUpdate
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from pygui.backend.stability_detector import (
|
||||
from pygui.backend.models.stability_detector import (
|
||||
StabilityDetector, STATE_IDLE, STATE_RAMP, STATE_SET,
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import time
|
||||
from pygui.backend.frame import Frame
|
||||
from pygui.backend.models.frame import Frame
|
||||
from pygui.serialcomm.stream_reader import StreamReader
|
||||
|
||||
class FakeTransport:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import math
|
||||
|
||||
from pygui.backend.threshold_classifier import (
|
||||
from pygui.backend.models.threshold_classifier import (
|
||||
ThresholdConfig, classify, classify_all, resolve_bounds,
|
||||
BAND_IN, BAND_HIGH, BAND_LOW
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Tests for src/pygui/backend/wafer_layouts.py."""
|
||||
import pytest
|
||||
from pygui.backend.wafer_layouts import load_layout, available_families
|
||||
from pygui.backend.zwafer_models import Sensor
|
||||
from pygui.backend.wafer.wafer_layouts import load_layout, available_families
|
||||
from pygui.backend.wafer.zwafer_models import Sensor
|
||||
|
||||
|
||||
def test_lists_bundled_families():
|
||||
|
||||
Reference in New Issue
Block a user