diff --git a/src/BusClient.py b/flandre/BusClient.py similarity index 97% rename from src/BusClient.py rename to flandre/BusClient.py index 6adb4f9..40cb1ca 100644 --- a/src/BusClient.py +++ b/flandre/BusClient.py @@ -1,7 +1,7 @@ import zmq from zmq import Context -from utils.Msg import Msg +from flandre.utils.Msg import Msg class BusClient: diff --git a/flandre/__init__.py b/flandre/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/beamformer/das.py b/flandre/beamformer/das.py similarity index 95% rename from src/beamformer/das.py rename to flandre/beamformer/das.py index 33c307b..f04f008 100644 --- a/src/beamformer/das.py +++ b/flandre/beamformer/das.py @@ -4,9 +4,9 @@ from typing import Callable import cupy as cp import numpy as np -from beamformer.dist import refraction_dist, direct_dist -from beamformer.kernels import dist_mat_to_yids, dist_mat_to_yids_pwi -from utils.Config import DeviceConfig +from flandre.beamformer.dist import refraction_dist, direct_dist +from flandre.beamformer.kernels import dist_mat_to_yids, dist_mat_to_yids_pwi +from flandre.utils.Config import DeviceConfig def repeat_range_in_axis(shape: tuple, axis: int,p=cp): diff --git a/src/beamformer/dist.py b/flandre/beamformer/dist.py similarity index 96% rename from src/beamformer/dist.py rename to flandre/beamformer/dist.py index 39feef0..d320111 100644 --- a/src/beamformer/dist.py +++ b/flandre/beamformer/dist.py @@ -5,8 +5,8 @@ where f(y,x) is the pixel distance in echo pulse RF signal between point(0,0) an import numpy as np from scipy.optimize import fsolve -from config import DS -from utils.Config import DeviceConfig +from flandre.config import DS +from flandre.utils.Config import DeviceConfig def refraction_dist(dev_cfg=DeviceConfig()): diff --git a/src/beamformer/kernels.py b/flandre/beamformer/kernels.py similarity index 97% rename from src/beamformer/kernels.py rename to flandre/beamformer/kernels.py index 2aa3db4..28adacc 100644 --- a/src/beamformer/kernels.py +++ b/flandre/beamformer/kernels.py @@ -7,9 +7,9 @@ xri: x receive index xrs: x receive shape """ import cupy as cp -from beamformer.dist import direct_dist +from flandre.beamformer.dist import direct_dist -from utils.Config import DeviceConfig +from flandre.utils.Config import DeviceConfig def dist_mat_to_yids(dist_mat: cp.ndarray, dev_cfg=DeviceConfig()): diff --git a/src/beamformer/process.py b/flandre/beamformer/process.py similarity index 80% rename from src/beamformer/process.py rename to flandre/beamformer/process.py index adcd89e..707a712 100644 --- a/src/beamformer/process.py +++ b/flandre/beamformer/process.py @@ -1,15 +1,15 @@ import cupy as cp -from beamformer.das import TFM -from utils.Config import ImagingConfig -from utils.ScanData import ScanData +from flandre.beamformer.das import TFM +from flandre.utils.Config import ImagingConfig +from flandre.utils.ScanData import ScanData tfm_cache = [None] def pwi_process(s: ScanData, icfg: ImagingConfig, pwi): return (s - .filter_max_persent(icfg.bscan_max/1000, bid=True) + .filter_max_persent(icfg.bscan_max / 1000, bid=True) .sum(cond=s.d == 3) .dct(icfg.dct_start, icfg.dct_end) .call(lambda m: m.astype(cp.int16)) @@ -18,7 +18,7 @@ def pwi_process(s: ScanData, icfg: ImagingConfig, pwi): .argrelextrema() .conv_guass(b=icfg.beta * 0.01) .clip(icfg.focus_start, icfg.focus_end) - .filter_max_persent(icfg.focus_max/100, mmax=icfg.focus_mmax if icfg.uafm else None) + .filter_max_persent(icfg.focus_max / 100, mmax=icfg.focus_mmax if icfg.uafm else None) .time_gain_compensation_linear_max(icfg.tgcl, mmax=icfg.focus_mmax if icfg.uafm else None) .cpu() .get() @@ -29,7 +29,7 @@ def tfm_process(s: ScanData, icfg: ImagingConfig, disable_cache: bool, tfm: TFM) # print(icfg.changed_field, icfg.changed_field in ['dct_start', 'dct_end', 'bscan_max'], disable_cache) if icfg.changed_field in ['dct_start', 'dct_end', 'bscan_max'] or tfm_cache[0] is None or disable_cache: tfm_cache[0] = (s.dct(icfg.dct_start, icfg.dct_end) - .filter_max_persent(icfg.bscan_max/1000, bid=True) + .filter_max_persent(icfg.bscan_max / 1000, bid=True) .call(lambda m: m.astype(cp.int16)) .call(tfm)) return (tfm_cache[0] diff --git a/src/config.py b/flandre/config.py similarity index 55% rename from src/config.py rename to flandre/config.py index f6839a3..3cc0469 100644 --- a/src/config.py +++ b/flandre/config.py @@ -1,9 +1,8 @@ import dataclasses import json +import sys from pathlib import Path -from PIL.TiffImagePlugin import SOFTWARE - PLAYBACK_SOCKET_PORT = 5003 PLAYBACK_SOCKET = f'127.0.0.1:{PLAYBACK_SOCKET_PORT}' LIVE_SOCKET_IP = '11.6.1.71' @@ -12,8 +11,6 @@ LIVE_SOCKET = f'{LIVE_SOCKET_IP}:5555' LIVE_REP_SOCKET = f'{LIVE_SOCKET_IP}:{LIVE_REP_SOCKET_PORT}' MI_REP_SOCKET_PORT = 5557 DEVICE_PY_REP_SOCKET_PORT = 5558 -VIDEO_HEIGHT = 1920 -VIDEO_WIDTH = 1080 SWITCH1_IP = 'c1' SWITCH1_TOKEN = '7ad51e0016e7a9d22f753d5110f76c7d' @@ -44,24 +41,37 @@ SOFTWARE_CONFIG_PATH = BASE / 'software.json' @dataclasses.dataclass class SoftwareConfig: base_dir: Path = DS + video_height = 1920 + video_width = 1080 @staticmethod - def read_config(): - j = json.loads(SOFTWARE_CONFIG_PATH.read_text(encoding='utf-8')) - sc = SoftwareConfig() - sc.base_dir = Path(j['base_dir']) + def read_config(path: Path): + j = json.loads(path.read_text(encoding='utf-8')) + arg_d = dict() + for field in dataclasses.fields(SoftwareConfig): + match field.type: + case Path(): + arg_d[field.name] = Path(j[field.name]) + case _: + arg_d[field.name] = j[field.name] + sc = SoftwareConfig(**arg_d) return sc def write_config(self): - SOFTWARE_CONFIG_PATH.write_text(json.dumps(dict( - base_dir=self.base_dir.__str__(), - ), indent=4), encoding='utf-8') + arg_d = dict() + for field in dataclasses.fields(SoftwareConfig): + match field.type: + case Path(): + arg_d[field.name] = str(self.__getattribute__(field.name)) + case _: + arg_d[field.name] = self.__getattribute__(field.name) + SOFTWARE_CONFIG_PATH.write_text(json.dumps(arg_d, indent=4), encoding='utf-8') -SOFTWARE_CONFIG = SoftwareConfig() +C = SoftwareConfig() -if SOFTWARE_CONFIG_PATH.exists(): - SOFTWARE_CONFIG = SoftwareConfig.read_config() +if SOFTWARE_CONFIG_PATH.exists() and '--debug' not in sys.argv: + C = SoftwareConfig.read_config(SOFTWARE_CONFIG_PATH) if __name__ == '__main__': - print(SOFTWARE_CONFIG) + print(C) diff --git a/src/main.py b/flandre/main.py similarity index 100% rename from src/main.py rename to flandre/main.py diff --git a/src/nodes/Beamformer.py b/flandre/nodes/Beamformer.py similarity index 84% rename from src/nodes/Beamformer.py rename to flandre/nodes/Beamformer.py index 5f51187..a6d1901 100644 --- a/src/nodes/Beamformer.py +++ b/flandre/nodes/Beamformer.py @@ -5,12 +5,12 @@ import cupy as cp import cv2 import zmq -from config import VIDEO_WIDTH, VIDEO_HEIGHT -from nodes.Node import Node -from utils.Msg import BMMsg, ImageArgMsg, SetSeqMetaMsg, Msg, RfFrameWithMetaMsg, BeamformerMsg, RequestRfFrameMsg, \ +from flandre.config import C.video_width, C.video_height +from flandre.nodes.Node import Node +from flandre.utils.Msg import BMMsg, ImageArgMsg, SetSeqMetaMsg, Msg, RfFrameWithMetaMsg, BeamformerMsg, RequestRfFrameMsg, \ SeqMetaMsg -from utils.RfFile import RfSequenceMeta -from utils.RfMat import RfMat +from flandre.utils.RfFile import RfSequenceMeta +from flandre.utils.RfMat import RfMat logger = logging.getLogger(__name__) @@ -35,7 +35,7 @@ class Beamformer(Node): .rotate90() .grey() .cpu() - .resize((VIDEO_WIDTH, VIDEO_HEIGHT)) + .resize((C.video_width, C.video_height)) .watermark() .call(cv2.cvtColor, cv2.COLOR_GRAY2RGBA) ) diff --git a/src/nodes/Broker.py b/flandre/nodes/Broker.py similarity index 89% rename from src/nodes/Broker.py rename to flandre/nodes/Broker.py index 144ab4d..5abbdc0 100644 --- a/src/nodes/Broker.py +++ b/flandre/nodes/Broker.py @@ -3,8 +3,8 @@ import threading import zmq from zmq import ContextTerminated -from nodes.Node import Node -from utils.Msg import KillMsg +from flandre.nodes.Node import Node +from flandre.utils.Msg import KillMsg class Broker(Node): diff --git a/src/nodes/Device.py b/flandre/nodes/Device.py similarity index 97% rename from src/nodes/Device.py rename to flandre/nodes/Device.py index 1c7014e..3d9f142 100644 --- a/src/nodes/Device.py +++ b/flandre/nodes/Device.py @@ -7,13 +7,13 @@ from threading import Thread import zmq -from BusClient import BusClient +from flandre.BusClient import BusClient from config import LIVE_REP_SOCKET, DEVICE_CONFIG -from nodes.Node import Node -from utils.Msg import ImageArgMsg, KillMsg, SetDeviceConnectedMsg, SetDeviceEnabledMsg, DeviceEnabledMsg, \ +from flandre.nodes.Node import Node +from flandre.utils.Msg import ImageArgMsg, KillMsg, SetDeviceConnectedMsg, SetDeviceEnabledMsg, DeviceEnabledMsg, \ DeviceConnectedMsg, SetDeviceConfigMsg, DeviceOnlineMsg, DeviceConfigListMsg, RequestRfFrameMsg, RfFrameWithMetaMsg, \ DeviceZero, SetDeviceSwitchMsg, DeviceSwitchMsg, SeqMetaMsg, RefreshDeviceMsg -from utils.RfMeta import RfFrameMeta +from flandre.utils.RfMeta import RfFrameMeta logger = logging.getLogger(__name__) diff --git a/src/nodes/ImageCV.py b/flandre/nodes/ImageCV.py similarity index 83% rename from src/nodes/ImageCV.py rename to flandre/nodes/ImageCV.py index 8ccf265..6b42d8a 100644 --- a/src/nodes/ImageCV.py +++ b/flandre/nodes/ImageCV.py @@ -4,9 +4,9 @@ import cv2 import numpy as np import zmq -from config import VIDEO_HEIGHT, VIDEO_WIDTH -from nodes.Node import Node -from utils.Msg import BMMsg, SetWindowVisibleMsg +from flandre.config import C +from flandre.nodes.Node import Node +from flandre.utils.Msg import BMMsg, SetWindowVisibleMsg logger = logging.getLogger(__name__) @@ -17,7 +17,7 @@ class ImageCV(Node): def __init__(self, level=logging.INFO): super().__init__(level=level) self.show = True - self.buffer = np.zeros((VIDEO_HEIGHT, VIDEO_WIDTH, 3), dtype=np.uint8) + 128 + self.buffer = np.zeros((C.video_height, C.video_width, 3), dtype=np.uint8) + 128 def loop(self): cv2.namedWindow('image', cv2.WINDOW_NORMAL) @@ -27,7 +27,7 @@ class ImageCV(Node): msg = self.recv() if isinstance(msg, BMMsg): b = np.frombuffer(msg.data, dtype=np.uint8) - b = np.reshape(b, (VIDEO_HEIGHT, VIDEO_WIDTH, 4)) + b = np.reshape(b, (C.video_height, C.video_width, 4)) self.buffer = b elif isinstance(msg, SetWindowVisibleMsg): if msg.name == 'bscan' and msg.sender != 'cv': diff --git a/src/nodes/ImageFFMPEG.py b/flandre/nodes/ImageFFMPEG.py similarity index 85% rename from src/nodes/ImageFFMPEG.py rename to flandre/nodes/ImageFFMPEG.py index 596ecf6..c12f39c 100644 --- a/src/nodes/ImageFFMPEG.py +++ b/flandre/nodes/ImageFFMPEG.py @@ -5,10 +5,10 @@ import time import numpy as np import zmq -from BusClient import BusClient -from config import VIDEO_HEIGHT, VIDEO_WIDTH -from nodes.Node import Node -from utils.Msg import BMMsg, SetWindowVisibleMsg, Msg +from flandre.BusClient import BusClient +from flandre.config import C.video_height, C.video_width +from flandre.nodes.Node import Node +from flandre.utils.Msg import BMMsg, SetWindowVisibleMsg, Msg logger = logging.getLogger(__name__) @@ -18,7 +18,7 @@ class ImageFFMPEG(Node): def __init__(self, level=logging.INFO): super().__init__(level=level) - self.buffer = np.zeros((VIDEO_HEIGHT, VIDEO_WIDTH, 3), dtype=np.uint8) + 128 + self.buffer = np.zeros((C.video_height, C.video_width, 3), dtype=np.uint8) + 128 self.buffer = self.buffer.tobytes() def loop(self): @@ -56,7 +56,7 @@ class ImageFFMPEG(Node): if events: msg: BMMsg = Msg.decode_msg(events[0][0].recv()) b = np.frombuffer(msg.data, dtype=np.uint8) - b = np.reshape(b, (VIDEO_HEIGHT, VIDEO_WIDTH, 4))[:, :, :3] + b = np.reshape(b, (C.video_height, C.video_width, 4))[:, :, :3] self.buffer = b.tobytes() p.stdin.write(self.buffer) # time.sleep(1 / 60) diff --git a/src/nodes/ImageQt.py b/flandre/nodes/ImageQt.py similarity index 80% rename from src/nodes/ImageQt.py rename to flandre/nodes/ImageQt.py index 5d6244b..2588be7 100644 --- a/src/nodes/ImageQt.py +++ b/flandre/nodes/ImageQt.py @@ -5,11 +5,11 @@ from PyQt6.QtCore import QByteArray from PyQt6.QtGui import QImage, QPixmap from PyQt6.QtWidgets import QMainWindow, QApplication -from Image import Ui_MainWindow -from ZMQReceiver import ZMQReceiver -from config import VIDEO_HEIGHT, VIDEO_WIDTH -from nodes.Node import Node -from utils.Msg import KillMsg, Msg, ImageArgMsg, BMMsg +from flandre.pyqt.Image import Ui_MainWindow +from flandre.pyqt.ZMQReceiver import ZMQReceiver +from flandre.config import C.video_height, C.video_width +from flandre.nodes.Node import Node +from flandre.utils.Msg import KillMsg, Msg, ImageArgMsg, BMMsg class Adv(QMainWindow, Ui_MainWindow): @@ -31,7 +31,7 @@ class Adv(QMainWindow, Ui_MainWindow): # height, width, channel = cvImg.shape # bytesPerLine = 3 * width # qImg = QImage(cvImg.data, width, height, bytesPerLine, QImage.Format.Format_RGB888).rgbSwapped() - qImg = QImage(msg.data, VIDEO_WIDTH, VIDEO_HEIGHT, 4 * VIDEO_WIDTH, QImage.Format.Format_RGB888).rgbSwapped() + qImg = QImage(msg.data, C.video_width, C.video_height, 4 * C.video_width, QImage.Format.Format_RGB888).rgbSwapped() self.label.setPixmap(QPixmap(qImg)) @QtCore.pyqtSlot(int) diff --git a/src/nodes/JoyStick.py b/flandre/nodes/JoyStick.py similarity index 97% rename from src/nodes/JoyStick.py rename to flandre/nodes/JoyStick.py index 0bddc8b..a0b7126 100644 --- a/src/nodes/JoyStick.py +++ b/flandre/nodes/JoyStick.py @@ -7,8 +7,8 @@ import zmq from mido.backends.rtmidi import Input, Output from pyjoystick.sdl2 import Key, Joystick, run_event_loop -from nodes.Node import Node -from utils.Msg import KillMsg, Msg, ImageArgMsg, JoystickMsg +from flandre.nodes.Node import Node +from flandre.utils.Msg import KillMsg, Msg, ImageArgMsg, JoystickMsg logger = logging.getLogger(__name__) diff --git a/src/nodes/Loader.py b/flandre/nodes/Loader.py similarity index 83% rename from src/nodes/Loader.py rename to flandre/nodes/Loader.py index dc9aef3..bb0c77d 100644 --- a/src/nodes/Loader.py +++ b/flandre/nodes/Loader.py @@ -5,11 +5,11 @@ from pathlib import Path import zmq -from config import PLAYBACK_SOCKET_PORT, SOFTWARE_CONFIG -from nodes.Node import Node -from utils.Msg import MoveAxisMsg, KillMsg, SetSeqMetaMsg, SeqIdMinMax, SetBaseMsg, SeqListMsg, SeqIdList, \ +from flandre.config import PLAYBACK_SOCKET_PORT, C +from flandre.nodes.Node import Node +from flandre.utils.Msg import MoveAxisMsg, KillMsg, SetSeqMetaMsg, SeqIdMinMax, SetBaseMsg, SeqListMsg, SeqIdList, \ SetSidMsg, RfFrameWithMetaMsg -from utils.RfFile import RfSequence +from flandre.utils.RfFile import RfSequence logger = logging.getLogger(__name__) @@ -48,8 +48,8 @@ class Loader(Node): if not seq_list: logger.warning(f'No sequences found in {base}') else: - SOFTWARE_CONFIG.base_dir = base - SOFTWARE_CONFIG.write_config() + C.base_dir = base + C.write_config() self.send(SeqListMsg(seq_list)) elif isinstance(msg, KillMsg): if msg.name == '': diff --git a/src/nodes/MainUI.py b/flandre/nodes/MainUI.py similarity index 98% rename from src/nodes/MainUI.py rename to flandre/nodes/MainUI.py index 017351b..d5e876b 100644 --- a/src/nodes/MainUI.py +++ b/flandre/nodes/MainUI.py @@ -11,16 +11,16 @@ from PyQt6 import QtCore, QtWidgets, QtGui from PyQt6.QtCore import QByteArray from PyQt6.QtWidgets import QMainWindow, QApplication, QFrame, QMessageBox, QFileDialog, QLineEdit -from Main import Ui_MainWindow -from ZMQReceiver import ZMQReceiver -from config import DS, SOFTWARE_CONFIG, IMAGING_CONFIG, ASSETS, MI_REP_SOCKET_PORT -from nodes.Node import Node -from utils.Msg import KillMsg, Msg, ImageArgMsg, SeqIdMinMax, MoveAxisMsg, SeqListMsg, SetBaseMsg, \ +from flandre.pyqt.Main import Ui_MainWindow +from flandre.pyqt.ZMQReceiver import ZMQReceiver +from flandre.config import DS, C, IMAGING_CONFIG, ASSETS, MI_REP_SOCKET_PORT +from flandre.nodes.Node import Node +from flandre.utils.Msg import KillMsg, Msg, ImageArgMsg, SeqIdMinMax, MoveAxisMsg, SeqListMsg, SetBaseMsg, \ SetSeqMetaMsg, SetPlayMode, DeviceConnectedMsg, DeviceEnabledMsg, DeviceOnlineMsg, SetDeviceEnabledMsg, \ SetDeviceConnectedMsg, DeviceConfigListMsg, SetDeviceConfigMsg, SetRecordMsg, RobotRtsiMsg, RecordFrameMsg, \ SeqIdList, SetWindowVisibleMsg, SetSidMsg, ImagingConfigNameListMsg, DeviceZero, DeviceSwitchMsg, \ SetDeviceSwitchMsg, SeqMetaMsg, RefreshDeviceMsg -from utils.RfMeta import RfSequenceMeta +from flandre.utils.RfMeta import RfSequenceMeta logger = logging.getLogger(__name__) @@ -99,7 +99,7 @@ class Adv(QMainWindow, Ui_MainWindow): # self.b_device_connected.clicked.connect(lambda: self.p.send(SetDeviceConnectedMsg(not self.device_connected))) # self.c_live_seq_name.currentIndexChanged.connect(self.on_seq_meta) self.b_live_seq_apply.clicked.connect(self.on_seq_meta) - self.l_base.setText(SOFTWARE_CONFIG.base_dir.__str__()) + self.l_base.setText(C.base_dir.__str__()) self.l_base.textChanged.connect(lambda e: self.l_base.setStyleSheet("") if Path(e).exists() else diff --git a/src/nodes/Mi.py b/flandre/nodes/Mi.py similarity index 100% rename from src/nodes/Mi.py rename to flandre/nodes/Mi.py diff --git a/src/nodes/Midi.py b/flandre/nodes/Midi.py similarity index 95% rename from src/nodes/Midi.py rename to flandre/nodes/Midi.py index 7cda2e5..264cc0f 100644 --- a/src/nodes/Midi.py +++ b/flandre/nodes/Midi.py @@ -7,8 +7,8 @@ import zmq from mido import Message from mido.backends.rtmidi import Input, Output -from nodes.Node import Node -from utils.Msg import KillMsg, MidiMsg, Msg, ImageArgMsg +from flandre.nodes.Node import Node +from flandre.utils.Msg import KillMsg, MidiMsg, Msg, ImageArgMsg logger = logging.getLogger(__name__) diff --git a/src/nodes/Monitor.py b/flandre/nodes/Monitor.py similarity index 69% rename from src/nodes/Monitor.py rename to flandre/nodes/Monitor.py index fe3497b..61bc86e 100644 --- a/src/nodes/Monitor.py +++ b/flandre/nodes/Monitor.py @@ -5,13 +5,13 @@ import time import zmq -from BusClient import BusClient -from config import LIVE_REP_SOCKET, CONFIG, DEVICE_CONFIG -from nodes.Node import Node -from utils.Msg import ImageArgMsg, KillMsg, SetDeviceConnectedMsg, SetDeviceEnabledMsg, DeviceEnabledMsg, \ +from flandre.BusClient import BusClient +from flandre.config import LIVE_REP_SOCKET, CONFIG, DEVICE_CONFIG +from flandre.nodes.Node import Node +from flandre.utils.Msg import ImageArgMsg, KillMsg, SetDeviceConnectedMsg, SetDeviceEnabledMsg, DeviceEnabledMsg, \ DeviceConnectedMsg, SetDeviceConfigMsg, DeviceOnlineMsg, DeviceConfigListMsg, RequestRfFrameMsg, RfFrameMsg, \ RfFrameWithMetaMsg -from utils.RfMeta import RfFrameMeta +from flandre.utils.RfMeta import RfFrameMeta logger = logging.getLogger(__name__) diff --git a/src/nodes/Muxer.py b/flandre/nodes/Muxer.py similarity index 96% rename from src/nodes/Muxer.py rename to flandre/nodes/Muxer.py index 5530c36..4ae4705 100644 --- a/src/nodes/Muxer.py +++ b/flandre/nodes/Muxer.py @@ -5,11 +5,11 @@ import time import zmq from config import IMAGING_CONFIG -from nodes.Node import Node -from utils.Msg import ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, \ +from flandre.nodes.Node import Node +from flandre.utils.Msg import ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, \ ImagingConfigNameListMsg, RfFrameWithMetaMsg, BeamformerMsg, RobotRtsiMsg, SeqMetaMsg -from utils.RfFile import RfSequenceMeta -from utils.RfMeta import RfFrameMeta +from flandre.utils.RfFile import RfSequenceMeta +from flandre.utils.RfMeta import RfFrameMeta logger = logging.getLogger(__name__) diff --git a/src/nodes/Node.py b/flandre/nodes/Node.py similarity index 95% rename from src/nodes/Node.py rename to flandre/nodes/Node.py index 4b6c865..768dbb2 100644 --- a/src/nodes/Node.py +++ b/flandre/nodes/Node.py @@ -3,8 +3,8 @@ from abc import abstractmethod import zmq -from BusClient import BusClient -from utils.Msg import Msg, KillMsg +from flandre.BusClient import BusClient +from flandre.utils.Msg import Msg, KillMsg class Node: diff --git a/src/nodes/Recorder.py b/flandre/nodes/Recorder.py similarity index 89% rename from src/nodes/Recorder.py rename to flandre/nodes/Recorder.py index 8609b2d..90572bf 100644 --- a/src/nodes/Recorder.py +++ b/flandre/nodes/Recorder.py @@ -6,13 +6,12 @@ from pathlib import Path import numpy as np import zmq -from config import IMAGING_CONFIG, LIVE_SOCKET -from nodes.Node import Node -from utils.Msg import ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg, \ - ImagingConfigNameListMsg, RfFrameWithMetaMsg, BeamformerMsg, RequestRfFrameMsg, RecordFrameMsg, RobotRtsiMsg -from utils.RfFile import RfSequenceMeta -from utils.RfMat import RfMat -from utils.RfMeta import RfFrameMeta +from flandre.config import LIVE_SOCKET +from flandre.nodes.Node import Node +from flandre.utils.Msg import ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg, \ + RfFrameWithMetaMsg, RequestRfFrameMsg, RecordFrameMsg, RobotRtsiMsg +from flandre.utils.RfFile import RfSequenceMeta +from flandre.utils.RfMeta import RfFrameMeta logger = logging.getLogger(__name__) diff --git a/src/nodes/Robot.py b/flandre/nodes/Robot.py similarity index 92% rename from src/nodes/Robot.py rename to flandre/nodes/Robot.py index 8c5e069..4e610cd 100644 --- a/src/nodes/Robot.py +++ b/flandre/nodes/Robot.py @@ -3,11 +3,11 @@ import threading import zmq -from nodes.Node import Node -from utils.Msg import KillMsg, RobotRtsiMsg, Msg -from utils.network import check_port -from utils.rtsi import rtsi -from utils.rtsi.serialize import DataObject +from flandre.nodes.Node import Node +from flandre.utils.Msg import KillMsg, RobotRtsiMsg, Msg +from flandre.utils.network import check_port +from flandre.utils.rtsi import rtsi +from flandre.utils.rtsi.serialize import DataObject logger = logging.getLogger(__name__) diff --git a/src/ui/Image.py b/flandre/pyqt/Image.py similarity index 100% rename from src/ui/Image.py rename to flandre/pyqt/Image.py diff --git a/src/ui/Image.ui b/flandre/pyqt/Image.ui similarity index 100% rename from src/ui/Image.ui rename to flandre/pyqt/Image.ui diff --git a/src/ui/Main.py b/flandre/pyqt/Main.py similarity index 99% rename from src/ui/Main.py rename to flandre/pyqt/Main.py index 5d024a0..1f51cd6 100644 --- a/src/ui/Main.py +++ b/flandre/pyqt/Main.py @@ -446,7 +446,7 @@ class Ui_MainWindow(object): self.label_15 = QtWidgets.QLabel(parent=self.centralwidget) self.label_15.setObjectName("label_15") self.gridLayout_5.addWidget(self.label_15, 3, 0, 1, 1) - self.s_t_start = QtWidgets.QSlider(parent=self.centralwidget) + self.s_t_start = QJumpSlider(parent=self.centralwidget) self.s_t_start.setOrientation(QtCore.Qt.Orientation.Horizontal) self.s_t_start.setObjectName("s_t_start") self.gridLayout_5.addWidget(self.s_t_start, 3, 1, 1, 1) @@ -614,3 +614,4 @@ class Ui_MainWindow(object): self.label.setText(_translate("MainWindow", "Base Path")) self.b_select_base.setText(_translate("MainWindow", "Select")) self.b_base.setText(_translate("MainWindow", "Open")) +from flandre.pyqt.QJumpSlider import QJumpSlider diff --git a/src/ui/Main.ui b/flandre/pyqt/Main.ui similarity index 99% rename from src/ui/Main.ui rename to flandre/pyqt/Main.ui index 3db0642..008712f 100644 --- a/src/ui/Main.ui +++ b/flandre/pyqt/Main.ui @@ -836,7 +836,7 @@ border-radius: 7px; - + Qt::Orientation::Horizontal @@ -1017,6 +1017,13 @@ border-radius: 7px; + + + QJumpSlider + QSlider +
flandre.pyqt.QJumpSlider.h
+
+
diff --git a/flandre/pyqt/QJumpSlider.py b/flandre/pyqt/QJumpSlider.py new file mode 100644 index 0000000..4458e63 --- /dev/null +++ b/flandre/pyqt/QJumpSlider.py @@ -0,0 +1,15 @@ +from PyQt6.QtWidgets import * +from PyQt6.QtCore import Qt + + +class ProxyStyle(QProxyStyle): + def styleHint(self, hint, opt=None, widget=None, returnData=None): + res = super().styleHint(hint, opt, widget, returnData) + res |= Qt.MouseButton.LeftButton.value + return res + + +class QJumpSlider(QSlider): + def __init__(self, parent=None): + super().__init__(parent) + self.setStyle(ProxyStyle()) \ No newline at end of file diff --git a/src/ui/ZMQReceiver.py b/flandre/pyqt/ZMQReceiver.py similarity index 91% rename from src/ui/ZMQReceiver.py rename to flandre/pyqt/ZMQReceiver.py index a4f16b1..bfc7a42 100644 --- a/src/ui/ZMQReceiver.py +++ b/flandre/pyqt/ZMQReceiver.py @@ -2,7 +2,7 @@ import threading from PyQt6 import QtCore -from nodes.Node import Node +from flandre.nodes.Node import Node class ZMQReceiver(QtCore.QObject): diff --git a/src/utils/Config.py b/flandre/utils/Config.py similarity index 96% rename from src/utils/Config.py rename to flandre/utils/Config.py index 7e081da..a79ad0d 100644 --- a/src/utils/Config.py +++ b/flandre/utils/Config.py @@ -1,7 +1,7 @@ import dataclasses import json -from config import CONFIG_FOLDER +from flandre.config import CONFIG_FOLDER @dataclasses.dataclass diff --git a/src/utils/Msg.py b/flandre/utils/Msg.py similarity index 99% rename from src/utils/Msg.py rename to flandre/utils/Msg.py index dd203ea..348435f 100644 --- a/src/utils/Msg.py +++ b/flandre/utils/Msg.py @@ -4,7 +4,7 @@ import struct from enum import auto, Enum from pathlib import Path -from utils.RfMeta import RfFrameMeta +from flandre.utils.RfMeta import RfFrameMeta class BG(Enum): diff --git a/src/utils/RfFile.py b/flandre/utils/RfFile.py similarity index 97% rename from src/utils/RfFile.py rename to flandre/utils/RfFile.py index baef95b..e8fac8e 100644 --- a/src/utils/RfFile.py +++ b/flandre/utils/RfFile.py @@ -3,7 +3,7 @@ from pathlib import Path import cupy as cp import numpy as np -from utils.RfMeta import RfFrameMeta, RfSequenceMeta +from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta class RfFrame: diff --git a/src/utils/RfMat.py b/flandre/utils/RfMat.py similarity index 97% rename from src/utils/RfMat.py rename to flandre/utils/RfMat.py index ebc3946..ad17a28 100644 --- a/src/utils/RfMat.py +++ b/flandre/utils/RfMat.py @@ -2,8 +2,8 @@ import cv2 import numpy as np import cupy as cp -from utils.RfFile import RfFrame, RfSequenceMeta -from utils.RfMeta import RfFrameMeta +from flandre.utils.RfFile import RfFrame, RfSequenceMeta +from flandre.utils.RfMeta import RfFrameMeta def bypass(f): diff --git a/src/utils/RfMeta.py b/flandre/utils/RfMeta.py similarity index 100% rename from src/utils/RfMeta.py rename to flandre/utils/RfMeta.py diff --git a/src/utils/ScanData.py b/flandre/utils/ScanData.py similarity index 99% rename from src/utils/ScanData.py rename to flandre/utils/ScanData.py index 10b5662..e2b15d2 100644 --- a/src/utils/ScanData.py +++ b/flandre/utils/ScanData.py @@ -1,16 +1,15 @@ from pathlib import Path -import numpy as np - import cupy as cp import cupyx -import cv2 -import matplotlib -import scipy -import cupyx.scipy.signal -import scipy.signal import cupyx.scipy.fft import cupyx.scipy.ndimage +import cupyx.scipy.signal +import cv2 +import matplotlib +import numpy as np +import scipy +import scipy.signal from cupyx.scipy.fft import dctn, idctn from scipy.stats import norm as norms diff --git a/src/utils/mi.py b/flandre/utils/mi.py similarity index 95% rename from src/utils/mi.py rename to flandre/utils/mi.py index 5ebd058..d24709a 100644 --- a/src/utils/mi.py +++ b/flandre/utils/mi.py @@ -1,7 +1,7 @@ import click from miio.miioprotocol import MiIOProtocol -from config import SWITCH1_IP, SWITCH1_TOKEN, SWITCH2_IP, SWITCH2_TOKEN +from flandre.config import SWITCH1_IP, SWITCH1_TOKEN, SWITCH2_IP, SWITCH2_TOKEN def c1(): diff --git a/src/utils/network.py b/flandre/utils/network.py similarity index 100% rename from src/utils/network.py rename to flandre/utils/network.py diff --git a/src/utils/rtsi/__init__.py b/flandre/utils/rtsi/__init__.py similarity index 100% rename from src/utils/rtsi/__init__.py rename to flandre/utils/rtsi/__init__.py diff --git a/src/utils/rtsi/rtsi.py b/flandre/utils/rtsi/rtsi.py similarity index 100% rename from src/utils/rtsi/rtsi.py rename to flandre/utils/rtsi/rtsi.py diff --git a/src/utils/rtsi/serialize.py b/flandre/utils/rtsi/serialize.py similarity index 100% rename from src/utils/rtsi/serialize.py rename to flandre/utils/rtsi/serialize.py diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..9c00655 --- /dev/null +++ b/gui.py @@ -0,0 +1,31 @@ +import logging +import multiprocessing + +from flandre.BusClient import BusClient + +from flandre.nodes.MainUI import MainUI +from flandre.utils.Msg import KillMsg + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + multiprocessing.set_start_method('spawn') + multiprocessing.Pool() + pps = [] + ps = [ + MainUI(), + ] + for p in ps: + pps.append(multiprocessing.Process(target=p)) + for p in pps: + p.start() + + c = BusClient(KillMsg) + while True: + x: KillMsg = c.recv() + if x.name == '': + break + for p in pps: + p.kill() + +if __name__ == '__main__': + pass diff --git a/src/ui/Main.ui.bak b/src/ui/Main.ui.bak deleted file mode 100644 index 97834fb..0000000 --- a/src/ui/Main.ui.bak +++ /dev/null @@ -1,442 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 1177 - 910 - - - - MainWindow - - - - - - - EXIT - - - - - - - - - - - - TextLabel - - - - - - - TextLabel - - - - - - - 1 - - - 1500 - - - Qt::Horizontal - - - - - - - - 20 - 50 - false - - - - Imaging - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - t_end - - - - - - - Qt::Horizontal - - - - - - - - - - - - - Qt::Horizontal - - - - - - - t_start - - - - - - - - - - - - - - - - - Z - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - - - - Qt::Horizontal - - - - - - - Y - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - - - - - 20 - 50 - false - - - - Probe Position - - - Qt::AlignCenter - - - - - - - E - - - - - - - X - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Roll - - - - - - - Pitch - - - - - - - Yal - - - - - - - - - - - - - - - - - - - - - TextLabel - - - - - - - - - - - - Beam - - - - - - - Connection - - - - - - - - 15 - - - - background-color: pink; - - - Device Offline - - - Qt::AlignCenter - - - - - - - - - - - false - - - - - - - false - - - background-color : red - - - Playback - - - - - - - false - - - Record - - - - - - - Qt::Horizontal - - - - - - - Frame ID - - - - - - - SetBase - - - - - - - /mnt/16T/private_dataset/us/ - - - - - - - Base Path - - - - - - - Live - - - - - - - false - - - false - - - - Unset - - - - - - - - - - - - - - - 0 - 0 - 1177 - 30 - - - - - - - - diff --git a/test/testpy.py b/test/testpy.py new file mode 100644 index 0000000..2f2cc0a --- /dev/null +++ b/test/testpy.py @@ -0,0 +1,21 @@ +import dataclasses +import inspect + + +@dataclasses.dataclass +class ASD: + aaa: int = 1 + bbb: int = 1 + ccc: int = 1 + + def b(self): + return self.aaa + + +if __name__ == '__main__': + # print(dir(ASD())) + # print(ASD.__dict__) + # print(inspect.getmembers(ASD)) + # print(inspect.getmembers(ASD)) + for f in dataclasses.fields(ASD): + print(f.name, f.type)