rm RfFrameWithMetaMsg

add launch count
This commit is contained in:
flandre 2025-04-16 17:53:18 +08:00
parent 9a4d7eca5d
commit aa9141dc1a
15 changed files with 455 additions and 272 deletions

View File

@ -1,6 +1,7 @@
import logging
import multiprocessing
import os
import time
import tomllib
from enum import Enum
from pathlib import Path
@ -19,7 +20,7 @@ from flandre.nodes.ImageFFMPEG import ImageFFMPEG
from flandre.nodes.ImageQt import ImageQt
from flandre.nodes.Midi import Midi
from flandre.nodes.Mi import Mi
from flandre.utils.Msg import KillMsg
from flandre.utils.Msg import KillMsg, TickMsg, Msg1
from flandre.config import CONFIG_FOLDER
@ -38,31 +39,40 @@ class LaunchComponent(Enum):
def launch(arg: dict[LaunchComponent, dict]):
ps = [
Broker()
]
logging.basicConfig(level=logging.INFO)
multiprocessing.set_start_method('spawn')
bp = multiprocessing.Process(target=Broker(broker=True))
bp.start()
# time.sleep(1)
ps = []
for k, v in arg.items():
if k == LaunchComponent.MainUI and os.environ.get('XDG_CURRENT_DESKTOP', None) == 'KDE':
ps.append(kde_pyqt6_mainui)
continue
ps.append(k.value(**v))
logging.basicConfig(level=logging.INFO)
multiprocessing.set_start_method('spawn')
multiprocessing.Pool()
pps = []
for p in ps:
pps.append(multiprocessing.Process(target=p))
for p in pps:
p.start()
c = BusClient(KillMsg)
c = BusClient(KillMsg, TickMsg)
cnt = 0
while True:
x: KillMsg = c.recv()
if x.name == '':
break
msg = c.recv()
if isinstance(msg, KillMsg):
if msg.name == '':
break
if isinstance(msg, TickMsg):
cnt += 1
logging.error(f'{cnt}')
if cnt == len(ps):
c.send(Msg1())
for p in pps:
p.kill()
bp.kill()
def launch_from_file(file: Path):

View File

@ -10,10 +10,10 @@ from flandre.beamformer.dist import direct_dist
from flandre.config import C
from flandre.nodes.Node import Node
from flandre.utils.Config import DeviceConfig
from flandre.utils.Msg import ImageArgMsg, Msg, RfFrameWithMetaMsg, BeamformerMsg, \
SeqMetaMsg, RfMatMsg, RGB888Msg
from flandre.utils.RfFile import RfSequenceMeta
from flandre.utils.Msg import ImageArgMsg, Msg, BeamformerMsg, \
SeqMetaMsg, RfMatMsg, RGB888Msg, RfFrameMsg
from flandre.utils.RfMat import RfMat
from flandre.utils.RfMeta import RfSequenceMeta
logger = logging.getLogger(__name__)
@ -54,7 +54,6 @@ class Beamformer(Node):
# self.send(RGB888Msg(d2.__bytes__(), d2.w, d2.h))
def loop(self):
time.sleep(1)
dc = DeviceConfig()
pwi, _ = gen_pwi(direct_dist(dc), dc)
last_v2 = 5900
@ -73,21 +72,16 @@ class Beamformer(Node):
continue
r = msg.value
id2 = r.index(Msg.magic(), 1)
id3 = r.index(Msg.magic(), id2 + 1)
seq_msg: SeqMetaMsg = Msg.decode_msg(r[:id2])
arg_msg: ImageArgMsg = Msg.decode_msg(r[id2:id3])
b_msg: RfFrameWithMetaMsg = Msg.decode_msg(r[id3:])
s = b_msg.data
fb1 = cp.frombuffer(s, dtype=cp.int16)
seq_meta = RfSequenceMeta.from_name(seq_msg.name)
mat = RfMat(fb1.reshape(seq_meta.shape), b_msg.meta, seq_meta)
arg_msg: ImageArgMsg = Msg.decode_msg(r[:id2])
rf_frame_msg: RfFrameMsg = Msg.decode_msg(r[id2:])
mat = RfMat.from_rf_frame(rf_frame_msg.rf_frame, 'gpu')
if arg_msg.v2 != last_v2 or arg_msg.f_rows != last_f_rows:
last_v2 = arg_msg.v2
last_f_rows = arg_msg.f_rows
dc = DeviceConfig(v2=arg_msg.v2, rows=arg_msg.f_rows)
pwi, _ = gen_pwi(direct_dist(dc), dc)
try:
if seq_meta.mode == RfSequenceMeta.RfSequenceMode.PWI:
if mat.seq_meta.mode == RfSequenceMeta.RfSequenceMode.PWI:
self.process_pwi(mat, arg_msg, pwi)
except Exception as e:
logger.warning(e)

View File

@ -4,17 +4,21 @@ import zmq
from zmq import ContextTerminated
from flandre.nodes.Node import Node
from flandre.utils.Msg import KillMsg
from flandre.utils.Msg import KillMsg, TickMsg
class Broker(Node):
def loop(self):
def t():
while True:
r:KillMsg = self.recv()
if r.name == '':
self.context.term()
break
msg = self.recv()
if isinstance(msg, TickMsg):
pass
elif isinstance(msg, KillMsg):
if msg.name == '':
self.context.term()
break
threading.Thread(target=t, daemon=True).start()
frontend = self.context.socket(zmq.XSUB)
backend = self.context.socket(zmq.XPUB)

View File

@ -11,9 +11,10 @@ from flandre.BusClient import BusClient
from flandre.config import C
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 flandre.utils.RfMeta import RfFrameMeta
DeviceConnectedMsg, SetDeviceConfigMsg, DeviceOnlineMsg, DeviceConfigListMsg, RequestRfFrameMsg, \
DeviceZero, SetDeviceSwitchMsg, DeviceSwitchMsg, SeqMetaMsg, RefreshDeviceMsg, RfFrameMsg
from flandre.utils.RfFrame import RfFrameMemory
from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
logger = logging.getLogger(__name__)
@ -43,7 +44,7 @@ class Device(Node):
def __init__(self, level=logging.INFO):
super(Device, self).__init__(level=level)
self.arg = ImageArgMsg('', t_start=0, t_end=1499)
self.seq_meta = None
self.seq_meta: RfSequenceMeta | None = None
self.req_driver_socket: zmq.Socket = None
self.rep_socket: zmq.Socket = None
self.ok = b'ok\x00'
@ -147,8 +148,10 @@ class Device(Node):
def get_seq_meta_name(self):
self.device_cmd(DeviceCmd.GetName)
rb = self.req_driver_socket.recv()
name = rb.decode()
self.seq_meta = RfSequenceMeta.from_name(name)
if rb != b'':
self.send(SeqMetaMsg('live', rb.decode()))
self.send(SeqMetaMsg('live', name))
def get_connection(self):
self.device_cmd(DeviceCmd.GetConnection)
@ -235,6 +238,7 @@ class Device(Node):
self.disconnect()
elif isinstance(msg, SetDeviceConfigMsg):
self.set_name_and_file(msg.name, msg.txt)
self.seq_meta = RfSequenceMeta.from_name(msg.name)
self.send(SeqMetaMsg('live', msg.name))
elif isinstance(msg, RequestRfFrameMsg):
if self.switch:
@ -244,10 +248,14 @@ class Device(Node):
continue
_, sequence_id, encoder = struct.unpack_from('=iqi', braw)
buffer = braw[4 + 8 + 4:]
# logger.debug('send')
self.send(RfFrameWithMetaMsg(0, RfFrameMeta(
encoder=encoder, sequence_id=sequence_id
), buffer))
if self.seq_meta is not None:
self.send(RfFrameMsg(0, RfFrameMemory(
RfFrameMeta(encoder=encoder, sequence_id=sequence_id),
self.seq_meta,
buffer,
)))
else:
logger.warning(f'no seq meta msg')
else:
logger.warning('device not online')
elif isinstance(msg, DeviceZero):

View File

@ -7,8 +7,8 @@ import zmq
from flandre.config import C, ISDEV
from flandre.nodes.Node import Node
from flandre.utils.Msg import MoveAxisMsg, KillMsg, SetSeqMetaMsg, SeqIdMinMax, SetBaseMsg, PlaybackSeqListMsg, \
SeqIdList, SetSidMsg, RfFrameWithMetaMsg
from flandre.utils.RfFile import RfSequence
SeqIdList, SetSidMsg, RfFrameMsg
from flandre.utils.RfSequence import RfSequence
logger = logging.getLogger(__name__)
@ -30,18 +30,14 @@ class Loader(Node):
if msg.axis == 'S':
pass
elif isinstance(msg, SetSidMsg):
frame = rff.frames[msg.value]
self.send(RfFrameWithMetaMsg(1, frame.meta, frame.bytes, frame.is_zip))
self.send(RfFrameMsg(1, rff.frames[msg.value]))
elif isinstance(msg, SetSeqMetaMsg):
if base is None:
continue
if msg.target == 'playback':
logger.info(f'load {msg.name}')
if msg.name.endswith('.zip'):
rff = RfSequence.from_zip(base / msg.name)
else:
rff = RfSequence.from_folder(base / msg.name)
rff = RfSequence(base / msg.name)
self.send(SeqIdMinMax(*rff.seq_id_minmax))
self.send(SeqIdList([f.meta.sequence_id for f in rff.frames]))
self.send(SetSidMsg(0))

View File

@ -8,27 +8,26 @@ import zmq
from flandre.config import C
from flandre.nodes.Node import Node
from flandre.utils.Msg import ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, \
ImagingConfigNameListMsg, RfFrameWithMetaMsg, BeamformerMsg, RobotRtsiMsg, SeqMetaMsg, DeviceEnabledMsg
from flandre.utils.RfFile import RfSequenceMeta
from flandre.utils.RfMeta import RfFrameMeta
from flandre.utils.archive import zip_to_bytes
ImagingConfigNameListMsg, BeamformerMsg, RobotRtsiMsg, SeqMetaMsg, DeviceEnabledMsg, RfFrameMsg
from flandre.utils.RfFrame import RfFrameMemory
from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
logger = logging.getLogger(__name__)
class Muxer(Node):
topics = [SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, RfFrameWithMetaMsg,
topics = [SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, RfFrameMsg,
ImageArgMsg, RobotRtsiMsg, SeqMetaMsg, DeviceEnabledMsg]
def __init__(self, level=logging.INFO):
super(Muxer, self).__init__(level=level)
self.seq_meta = None
self.seq_meta_live = None
self.seq_meta_live: RfSequenceMeta = None
self.seq_meta_playback = None
self.play_mode = None
self.rep_socket: zmq.Socket = None
self.req_driver_socket: zmq.Socket = None
self.playback_rf_msg: RfFrameWithMetaMsg | None = None
self.playback_rf_msg: RfFrameMsg | None = None
self.device_enabled = False
def custom_setup(self):
@ -38,14 +37,6 @@ class Muxer(Node):
self.req_driver_socket.connect(C.driver_rep_socket)
self.c.poller.register(self.rep_socket, zmq.POLLIN)
@property
def current_meta(self):
seq_meta: RfSequenceMeta | None = {
"live": self.seq_meta_live,
"playback": self.seq_meta_playback,
}.get(self.play_mode, None)
return seq_meta
def handle_rep_socket(self):
self.rep_socket.recv()
if self.play_mode is None:
@ -53,22 +44,11 @@ class Muxer(Node):
return
match self.play_mode:
case 'playback':
# logger.warning(f'test, {self.playback_rf_msg}')
if self.playback_rf_msg is None:
self.rep_socket.send(BeamformerMsg(b'nop').encode_msg())
return
data_msg = self.playback_rf_msg
# logger.info(f'bb {data_msg._header.is_zip}')
if data_msg._header.is_zip:
p = Path(data_msg.data.decode())
if p.suffix == '.zst':
data_msg = RfFrameWithMetaMsg(
data_msg.sender,
data_msg.meta,
zip_to_bytes(p.parent, int(p.stem))
)
else:
raise NotImplementedError()
case 'live':
if not self.device_enabled:
self.rep_socket.send(BeamformerMsg(b'init').encode_msg())
@ -82,17 +62,32 @@ class Muxer(Node):
return
_, _, sequence_id, encoder = struct.unpack_from('=iiii', driver_data_raw)
driver_data_body = driver_data_raw[4 + 8 + 4:]
# print(driver_data_body.__len__()/256/2)
data_msg = RfFrameWithMetaMsg(0, RfFrameMeta(
encoder=encoder, sequence_id=sequence_id
), driver_data_body)
data_msg = RfFrameMsg(0, RfFrameMemory(
RfFrameMeta(
encoder=encoder,
sequence_id=sequence_id,
robot_x=self.rtsi.pos[0],
robot_y=self.rtsi.pos[1],
robot_z=self.rtsi.pos[2],
robot_roll=self.rtsi.pos[3],
robot_pitch=self.rtsi.pos[4],
robot_yal=self.rtsi.pos[5],
robot_force_x=self.rtsi.force[0],
robot_force_y=self.rtsi.force[1],
robot_force_z=self.rtsi.force[2],
robot_force_roll=self.rtsi.force[3],
robot_force_pitch=self.rtsi.force[4],
robot_force_yal=self.rtsi.force[5],
),
self.seq_meta_live,
driver_data_body
))
case _:
raise NotImplementedError()
if (data_msg.data.__len__() // 2) != self.current_meta.prod():
self.rep_socket.send(BeamformerMsg(b'nop').encode_msg())
return
# if (data_msg.data.__len__() // 2) != data_msg.rf_frame.prod():
# self.rep_socket.send(BeamformerMsg(b'nop').encode_msg())
# return
self.rep_socket.send(BeamformerMsg(
SeqMetaMsg('any', self.current_meta.name).encode_msg() +
self.arg.encode_msg() +
data_msg.encode_msg()
).encode_msg())
@ -106,7 +101,6 @@ class Muxer(Node):
self.arg = ImageArgMsg('', t_start=0, t_end=1499)
self.c.poller.register(device_socket, zmq.POLLIN)
time.sleep(1)
self.send(ImagingConfigNameListMsg([path.stem for path in C.imaging_config_folder.glob('*.json')]))
while True:
socks = dict(self.c.poller.poll())
@ -117,31 +111,12 @@ class Muxer(Node):
self.handle_rep_socket()
if k == self.c.sub:
msg = self.recv()
if isinstance(msg, RfFrameWithMetaMsg):
if msg.sender == 0 and self.play_mode == 'live':
msg.meta.robot_x = self.rtsi.pos[0]
msg.meta.robot_y = self.rtsi.pos[1]
msg.meta.robot_z = self.rtsi.pos[2]
msg.meta.robot_roll = self.rtsi.pos[3]
msg.meta.robot_pitch = self.rtsi.pos[4]
msg.meta.robot_yal = self.rtsi.pos[5]
msg.meta.robot_force_x = self.rtsi.force[0]
msg.meta.robot_force_y = self.rtsi.force[1]
msg.meta.robot_force_z = self.rtsi.force[2]
msg.meta.robot_force_roll = self.rtsi.force[3]
msg.meta.robot_force_pitch = self.rtsi.force[4]
msg.meta.robot_force_yal = self.rtsi.force[5]
self.send(BeamformerMsg(
SetSeqMetaMsg('any', self.seq_meta_live.name).encode_msg() +
self.arg.encode_msg() +
msg.encode_msg()
))
elif msg.sender == 1:
self.playback_rf_msg = msg
elif isinstance(msg, KillMsg):
if isinstance(msg, KillMsg):
if msg.name == '':
return
elif isinstance(msg, RfFrameMsg):
if msg.sender == 1:
self.playback_rf_msg = msg
elif isinstance(msg, ImageArgMsg):
self.arg = msg
elif isinstance(msg, SetSeqMetaMsg):

View File

@ -1,10 +1,11 @@
import logging
import time
from abc import abstractmethod
import zmq
from flandre.BusClient import BusClient
from flandre.utils.Msg import Msg, KillMsg
from flandre.utils.Msg import Msg, KillMsg, TickMsg, Msg1
class Node:
@ -12,11 +13,12 @@ class Node:
bp = BusClient.bp
topics = []
def __init__(self, enable_init=True, level=logging.INFO, conflare=False):
def __init__(self, enable_init=True, level=logging.INFO, conflare=False, broker=False):
self.enable_init = enable_init
self.isalive = True
self.level = level
self.conflare = conflare
self.broker = broker
def recv(self):
return self.c.recv()
@ -38,10 +40,10 @@ class Node:
def base_setup(self):
FORMAT = '[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s'
FORMAT = '"%(pathname)s:%(lineno)d" [%(asctime)s.%(msecs)03d] %(levelname)s - %(message)s'
logging.basicConfig(level=self.level, format=FORMAT,datefmt = '%Y-%m-%d %H:%M:%S',)
logging.basicConfig(level=self.level, format=FORMAT, datefmt='%Y-%m-%d %H:%M:%S', )
rootLogger = logging.getLogger()
logFormatter = logging.Formatter(FORMAT,datefmt = '%Y-%m-%d %H:%M:%S',)
logFormatter = logging.Formatter(FORMAT, datefmt='%Y-%m-%d %H:%M:%S', )
fileHandler = logging.FileHandler("log.log")
fileHandler.setFormatter(logFormatter)
@ -53,9 +55,13 @@ class Node:
self.context = zmq.Context()
if self.enable_init:
self.c = BusClient(*([KillMsg] + self.topics), poller=True, conflare=self.conflare)
self.c = BusClient(*([KillMsg, Msg1] + self.topics), poller=True, conflare=self.conflare)
def __call__(self, *args, **kwargs):
self.setup()
if not self.broker:
time.sleep(1)
self.send(TickMsg())
self.recv()
self.loop()
print(self.__class__.__name__, 'exiting')

View File

@ -35,7 +35,6 @@ class Recorder(Node):
)
device_socket = self.context.socket(zmq.PULL)
self.c.poller.register(device_socket, zmq.POLLIN)
time.sleep(1)
while True:
socks = dict(self.c.poller.poll())
for k in socks:

View File

@ -6,8 +6,9 @@ from pathlib import Path
import numpy as np
# from flandre.utils.RfMat import RfMat
from flandre.utils.RfFrame import RfFrame, RfFrameMemory, RfFrameFile
from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
from flandre.utils.RfSequence import RfSequence
class BG(Enum):
@ -40,8 +41,7 @@ class BG(Enum):
SetWindowVisibleMsg = auto()
SetSidMsg = auto()
ImagingConfigNameListMsg = auto()
RfFrameMsg = auto()
RfFrameWithMetaMsg = auto()
BytesMsg = auto()
BeamformerMsg = auto()
RequestRfFrameMsg = auto()
@ -51,7 +51,11 @@ class BG(Enum):
SetDeviceSwitchMsg = auto()
DeviceSwitchMsg = auto()
HeaderByteMsg = auto()
RfFrameMsg = auto()
# RfFrameWithMetaMsg = auto()
RfMatMsg = auto()
KeyPressMsg = auto()
RGB888Msg = auto()
@ -96,6 +100,8 @@ class HeaderByteMsg(Msg):
def __init__(self, header: dict, data: bytes):
self.header = header
self.data = data
if self.data is None:
self.data = b''
def encode(self) -> bytes:
e = json.dumps(self.header).encode()
@ -299,25 +305,47 @@ class BMMsg(Msg):
)
class RfFrameMsg(Msg):
def __init__(self, sequence_id: int, encoder: int, data: bytes):
self.sequence_id = sequence_id
self.encoder = encoder
self.data = data
def encode(self) -> bytes:
return struct.pack(
'II',
self.sequence_id,
self.encoder,
) + self.data
class RfFrameMsg(HeaderByteMsg):
def __init__(self, sender: int, rf_frame: RfFrame):
self.sender = sender
self.rf_frame = rf_frame
if isinstance(rf_frame, RfFrameFile):
super().__init__(dict(
sender=sender,
type='RfFrameFile',
frame_meta=rf_frame.meta.name,
frame_filename=rf_frame.filename,
seq_path=rf_frame.seq.path.__str__(),
), rf_frame.data)
elif isinstance(rf_frame, RfFrameMemory):
super().__init__(dict(
sender=sender,
type='RfFrameMemory',
frame_meta=rf_frame.meta.name,
seq_meta=rf_frame.seq_meta,
), rf_frame.data)
@classmethod
def decode(cls, data: bytes) -> 'RfFrameMsg':
return cls(
*struct.unpack('II', data[:8]),
data[8:]
)
msg = super(RfFrameMsg, cls).decode(data)
if msg.header['type'] == 'RfFrameFile':
return RfFrameMsg(
msg.header['sender'],
RfFrameFile(
RfFrameMeta.from_name(msg.header['frame_meta']),
RfSequence(msg.header['seq_path']),
msg.data if msg.data.__len__() > 0 else None,
msg.header['frame_filename']
))
elif msg.header['type'] == 'RfFrameMemory':
return RfFrameMsg(
msg.header['sender'],
RfFrameMemory(
RfFrameMeta.from_name(msg.header['frame_meta']),
RfSequenceMeta.from_name(msg.header['seq_meta']),
msg.data,
))
raise NotImplementedError()
class RGB888Msg(HeaderByteMsg):
@ -359,30 +387,30 @@ class RfMatMsg(HeaderByteMsg):
return RfMatMsg(rfmat)
class RfFrameWithMetaMsg(HeaderByteMsg):
@dataclasses.dataclass
class Header:
sender: int
meta: str
is_zip: bool
def __init__(self, sender: int, meta: RfFrameMeta, data: bytes, is_zip: bool = False):
self._header = self.Header(sender, meta.name, is_zip)
super().__init__(self._header.__dict__, data)
@property
def sender(self) -> int:
return self._header.sender
@property
def meta(self) -> RfFrameMeta:
return RfFrameMeta.from_name(self._header.meta)
@classmethod
def decode(cls, data) -> 'RfFrameWithMetaMsg':
msg = super(RfFrameWithMetaMsg, cls).decode(data)
header = cls.Header(**msg.header)
return RfFrameWithMetaMsg(header.sender, RfFrameMeta.from_name(header.meta), msg.data, header.is_zip)
# class RfFrameWithMetaMsg(HeaderByteMsg):
# @dataclasses.dataclass
# class Header:
# sender: int
# meta: str
# is_zip: bool
#
# def __init__(self, sender: int, meta: RfFrameMeta, data: bytes, is_zip: bool = False):
# self._header = self.Header(sender, meta.name, is_zip)
# super().__init__(self._header.__dict__, data)
#
# @property
# def sender(self) -> int:
# return self._header.sender
#
# @property
# def meta(self) -> RfFrameMeta:
# return RfFrameMeta.from_name(self._header.meta)
#
# @classmethod
# def decode(cls, data) -> 'RfFrameWithMetaMsg':
# msg = super(RfFrameWithMetaMsg, cls).decode(data)
# header = cls.Header(**msg.header)
# return RfFrameWithMetaMsg(header.sender, RfFrameMeta.from_name(header.meta), msg.data, header.is_zip)
@dataclasses.dataclass

View File

@ -1,109 +1,118 @@
import json
import zipfile
from pathlib import Path
import cupy as cp
import numpy as np
from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
class RfFrame:
def __init__(self, data: bytes | Path, meta: RfFrameMeta, seq: 'RfSequence' = None):
self.data = data
self.meta = meta
self._seq = seq
self.is_zip = False
if isinstance(self.data, Path):
if self.data.parent.suffix == '.zip':
self.is_zip = True
def save(self, folder: Path):
(folder / self.meta.name).write_bytes(self.bytes)
@property
def seq(self):
if self._seq is None and isinstance(self.data, Path):
return RfSequence.from_folder(self.data.parent)
return self._seq
@property
def bytes(self):
if self.is_zip:
return self.data.__str__().encode()
if isinstance(self.data, bytes):
return self.data
if isinstance(self.data, Path):
return self.data.read_bytes()
def mat(self, device='gpu'):
from flandre.utils.RfMat import RfMat
if device == 'gpu':
arr = cp.frombuffer(self.bytes, dtype=cp.int16)
else:
arr = np.frombuffer(self.bytes, dtype=np.int16)
return RfMat(arr.reshape(self.seq.meta.shape), frame_meta=self.meta, seq_meta=self.seq.meta)
class RfSequence:
def __init__(self, frames: list[RfFrame], meta: RfSequenceMeta):
self.frames = frames
self.meta = meta
@classmethod
def from_folder(cls, folder: Path | str) -> 'RfSequence':
folder = Path(folder)
if not folder.exists():
raise FileNotFoundError
meta = RfSequenceMeta.from_path(folder)
rs = RfSequence([], meta)
for f in folder.glob('*.bin'):
rs.frames.append(RfFrame(f, RfFrameMeta.from_path(f), seq=rs))
return rs
@classmethod
def from_zip(cls, z: Path | str) -> 'RfSequence':
z = Path(z)
if not z.exists():
raise FileNotFoundError
meta = RfSequenceMeta.from_name(z.stem)
rs = RfSequence([], meta)
zz = zipfile.ZipFile(z)
max_idx = max([int(Path(item.filename).stem) for item in zz.infolist()])
for i in range(max_idx + 1):
j = json.loads(zz.open(f'{i}.json').read())
rs.frames.append(RfFrame(z / f'{i}.zst', RfFrameMeta(**j), seq=rs))
return rs
@property
def all(self):
pass
def query(self):
pass
@property
def seq_id_minmax(self):
mmin = 2 ** 32
mmax = 0
for f in self.frames:
mmin = min(mmin, f.meta.sequence_id)
mmax = max(mmax, f.meta.sequence_id)
return mmin, mmax
if __name__ == '__main__':
# t = (1, 2)
# f = RfSequenceMeta.from_name('123123,U=321,S=(1 2 3),M=PWI')
# print(f.commit)
# print(f.name)
# print(RfSequence.RfSequenceMeta.p2t)
# f = RfFrame.RfFrameMeta(123, 345)
# print(f.name)
# rs = RfSequence([], RfSequenceMeta())
rs = RfSequence.from_folder(
'/run/media/lambda/b86dccdc-f134-464b-a310-6575ee9ae85c/cap4/trim/R1.1,U=30,M=PWI,S=(256 1502)')
# print(rs.meta)
for frame in rs.frames:
if frame.mat().rotate90().show((1080, 1920)) == ord('q'):
break
# import json
# import zipfile
# from pathlib import Path
#
# import cupy as cp
# import numpy as np
#
# from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
#
#
# class RfFrame:
# def __init__(self, data: bytes | Path, meta: RfFrameMeta, seq: 'RfSequence' = None):
# self.data = data
# self.meta = meta
# self._seq = seq
# self.is_zip = False
# if isinstance(self.data, Path):
# if self.data.parent.suffix == '.zip':
# self.is_zip = True
#
# def save(self, folder: Path):
# (folder / self.meta.name).write_bytes(self.bytes)
#
# @property
# def seq(self):
# if self._seq is None and isinstance(self.data, Path):
# return RfSequence.from_folder(self.data.parent)
# return self._seq
#
# @property
# def bytes(self):
# if self.is_zip:
# return self.data.__str__().encode()
# if isinstance(self.data, bytes):
# return self.data
# if isinstance(self.data, Path):
# return self.data.read_bytes()
#
# def mat(self, device='gpu'):
# from flandre.utils.RfMat import RfMat
#
# if device == 'gpu':
# arr = cp.frombuffer(self.bytes, dtype=cp.int16)
# else:
# arr = np.frombuffer(self.bytes, dtype=np.int16)
# return RfMat(arr.reshape(self.seq.meta.shape), frame_meta=self.meta, seq_meta=self.seq.meta)
#
#
# class RfSequence:
# def __init__(self, frames: list[RfFrame], meta: RfSequenceMeta):
# self.frames = frames
# self.meta = meta
#
# @classmethod
# def from_folder(cls, folder: Path | str) -> 'RfSequence':
# folder = Path(folder)
# if not folder.exists():
# raise FileNotFoundError
# meta = RfSequenceMeta.from_path(folder)
# rs = RfSequence([], meta)
# for f in folder.glob('*.bin'):
# rs.frames.append(RfFrame(f, RfFrameMeta.from_path(f), seq=rs))
# return rs
#
# @classmethod
# def from_zip(cls, z: Path | str) -> 'RfSequence':
# z = Path(z)
# if not z.exists():
# raise FileNotFoundError
# meta = RfSequenceMeta.from_name(z.stem)
# rs = RfSequence([], meta)
# zz = zipfile.ZipFile(z)
# max_idx = max([int(Path(item.filename).stem) for item in zz.infolist()])
# for i in range(max_idx + 1):
# j = json.loads(zz.open(f'{i}.json').read())
# rs.frames.append(RfFrame(z / f'{i}.zst', RfFrameMeta(**j), seq=rs))
# return rs
#
# @property
# def all(self):
# pass
#
# def query(self):
# pass
#
# @property
# def seq_id_minmax(self):
# mmin = 2 ** 32
# mmax = 0
# for f in self.frames:
# mmin = min(mmin, f.meta.sequence_id)
# mmax = max(mmax, f.meta.sequence_id)
# return mmin, mmax
#
#
#
#
#
# if __name__ == '__main__':
# f = RfSequence2('/mnt/16T/private_dataset/us/steel-top,U=30,M=PWI,S=(256 1502).zip').frames
# for f2 in f:
# print(f2.__bytes__().__len__())
# # print(Path('xxx/asdasdasd_asd=a1,ds1.123').with_suffix(''))
# # print(Path('xxx/asdasdasd_asd=a1,ds1.123').stem)
# # t = (1, 2)
# # f = RfSequenceMeta.from_name('123123,U=321,S=(1 2 3),M=PWI')
# # print(f.commit)
# # print(f.name)
# # print(RfSequence.RfSequenceMeta.p2t)
# # f = RfFrame.RfFrameMeta(123, 345)
# # print(f.name)
# # rs = RfSequence([], RfSequenceMeta())
# # rs = RfSequence.from_folder(
# # '/run/media/lambda/b86dccdc-f134-464b-a310-6575ee9ae85c/cap4/trim/R1.1,U=30,M=PWI,S=(256 1502)')
# # # print(rs.meta)
# # for frame in rs.frames:
# # if frame.mat().rotate90().show((1080, 1920)) == ord('q'):
# # break

39
flandre/utils/RfFrame.py Normal file
View File

@ -0,0 +1,39 @@
from pathlib import Path
from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
from flandre.utils.RfSequence import RfSequence
class RfFrame:
def __bytes__(self) -> bytes:
raise NotImplementedError()
class RfFrameFile(RfFrame):
def __init__(self, meta: RfFrameMeta, seq: RfSequence, data: bytes = None, filename: str = None):
self.seq = seq
self.meta = meta
self.data = data
self.filename = filename
def __bytes__(self):
if self.data is not None:
return self.data
match self.seq.type:
case 'zip':
from flandre.utils.archive import zip_to_bytes
if self.filename is not None:
return zip_to_bytes(self.seq.path, int(Path(self.filename).stem))
case 'dir':
return (self.seq.path / self.filename).read_bytes()
raise NotImplementedError()
class RfFrameMemory(RfFrame):
def __init__(self, meta: RfFrameMeta, seq_meta: RfSequenceMeta, data: bytes):
self.seq_meta = seq_meta
self.meta = meta
self.data = data
def __bytes__(self):
return self.data

View File

@ -16,8 +16,8 @@ import scipy.signal
from cupyx.scipy.fft import dctn, idctn
from scipy.stats import norm as norms
from flandre.utils.RfFile import RfFrame, RfSequenceMeta
from flandre.utils.RfMeta import RfFrameMeta
from flandre.utils.RfFrame import RfFrame, RfFrameFile, RfFrameMemory
from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
def hsv_to_rgb(hsv):
@ -123,6 +123,19 @@ def bypassClass(original_class):
@bypassClass
class RfMat:
@staticmethod
def from_rf_frame(frame: RfFrame, device='cpu'):
if isinstance(frame, RfFrameFile):
seq_meta = frame.seq.meta
elif isinstance(frame, RfFrameMemory):
seq_meta = frame.seq_meta
else:
raise NotImplementedError()
m = np.frombuffer(frame.__bytes__(), dtype=np.int16).reshape(seq_meta.shape)
if device == 'gpu':
m = cp.asarray(m)
return RfMat(m, frame.meta, seq_meta)
def __init__(self,
data: cp.ndarray,
frame_meta: RfFrameMeta = None,
@ -339,6 +352,7 @@ class RfMat:
addend = self.p.zeros((1, h), dtype=self.p.float32)
addend[:, start:] = (self.p.arange(h - start) * scale) + 1
return self.copy(self.m * addend)
def time_gain_compensation_linear(self, scale: float, start: int = 0):
h = self.m.shape[-1]
addend = self.p.zeros((1, h), dtype=np.int64)
@ -363,5 +377,6 @@ class RfMat:
self.m = self.m.astype(np.int64)
return self
if __name__ == '__main__':
cp.zeros((1, 2, 3)) + 1

View File

@ -0,0 +1,47 @@
import zipfile
from pathlib import Path
from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
class RfSequence:
def __init__(self, path: Path | str):
from flandre.utils.RfFrame import RfFrameFile
path = Path(path)
if not path.exists():
raise FileNotFoundError()
if path.is_dir():
self.type = 'dir'
elif path.suffix == '.zip':
self.type = 'zip'
self.path = path
self.meta = RfSequenceMeta.from_name(path.stem)
self._frames: list[RfFrameFile] | None = None
@property
def frames(self):
from flandre.utils.RfFrame import RfFrameFile
if self._frames is None:
arr = []
match self.type:
case 'zip':
zip_file = zipfile.ZipFile(self.path)
max_idx = max([int(Path(item.filename).stem) for item in zip_file.infolist()])
for i in range(max_idx + 1):
meta = RfFrameMeta.from_name(zip_file.open(f'{i}.meta').read().decode())
arr.append(RfFrameFile(meta, seq=self, filename=f'{i}.zst'))
case 'dir':
for f in self.path.glob('*.bin'):
meta = RfFrameMeta.from_name(f.stem)
arr.append(RfFrameFile(meta, seq=self, filename=f.name))
self._frames = arr
return self._frames
@property
def seq_id_minmax(self):
mmin = 2 ** 32
mmax = 0
for f in self.frames:
mmin = min(mmin, f.meta.sequence_id)
mmax = max(mmax, f.meta.sequence_id)
return mmin, mmax

View File

@ -42,8 +42,8 @@ def to_zip(li: list[tuple[Path, 'RfFrameMeta', list[tuple[Path, str]]]], temp_ds
dst = temp_dst / f'{i}.zst'
subprocess.run(['zstd', '-f', src, '-o', dst])
dstj = temp_dst / f'{i}.json'
dstj.write_text(meta.json_str)
dstj = temp_dst / f'{i}.meta'
dstj.write_text(meta.name)
for srcf, suffix in farr:
dstf = temp_dst / f'{i}{suffix}'
@ -54,9 +54,12 @@ def to_zip(li: list[tuple[Path, 'RfFrameMeta', list[tuple[Path, str]]]], temp_ds
def zip_to_bytes(file: Path, name: int):
return zstd.loads(zipfile.ZipFile(file).open(f'{name}.zst').read())
def zip_to_bytes2(file: Path, name: str):
return zstd.loads(zipfile.ZipFile(file).open(name).read())
if __name__ == '__main__':
pass
to_zip()
# pass
# cli()
# folder_to_zip(Path('/mnt/16T/private_dataset/us/R1,U=30,M=PWI,S=(256 1502)'))
# r = get(Path('/mnt/16T/private_dataset/New Folder/ST,U=60,M=FMC,S=(256 256 3002).zip'), 3)

View File

@ -3,8 +3,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-13T05:31:00.380352Z",
"start_time": "2025-04-13T05:31:00.366988Z"
"end_time": "2025-04-15T16:57:56.708615Z",
"start_time": "2025-04-15T16:57:56.374273Z"
}
},
"cell_type": "code",
@ -25,8 +25,17 @@
"from matplotlib import pyplot as plt"
],
"id": "5518f8a97320440e",
"outputs": [],
"execution_count": 6
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/lambda/source/scarlet/flandre/.venv/lib/python3.12/site-packages/cupyx/jit/_interface.py:173: FutureWarning: cupyx.jit.rawkernel is experimental. The interface can change in the future.\n",
" cupy._util.experimental('cupyx.jit.rawkernel')\n"
]
}
],
"execution_count": 2
},
{
"metadata": {
@ -137,6 +146,47 @@
}
],
"execution_count": 19
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-15T16:58:11.825438Z",
"start_time": "2025-04-15T16:58:00.002256Z"
}
},
"cell_type": "code",
"source": [
"from flandre.utils.RfFile import RfSequence\n",
"\n",
"rff = RfSequence.from_zip(Path('/mnt/16T/private_dataset/us/R1,U=90,M=PWI,S=(256 4502).zip'))"
],
"id": "4acfc7303fa58cf",
"outputs": [],
"execution_count": 3
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-15T16:59:00.287886Z",
"start_time": "2025-04-15T16:59:00.285593Z"
}
},
"cell_type": "code",
"source": "rff.frames[0].data",
"id": "75e9c5f82736241",
"outputs": [
{
"data": {
"text/plain": [
"PosixPath('/mnt/16T/private_dataset/us/R1,U=90,M=PWI,S=(256 4502).zip/0.zst')"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 10
}
],
"metadata": {