add support for custom visualisations

This commit is contained in:
Christos Falas 2025-05-14 16:48:08 +01:00
parent 398b7b0946
commit af9faa3d07
No known key found for this signature in database
3 changed files with 23 additions and 7 deletions

View File

@ -12,6 +12,7 @@ from where_fi.collection.protocols import CSIProducer, MergedCSI
from where_fi.config import config from where_fi.config import config
from where_fi.processing.preprocess import Preprocessor from where_fi.processing.preprocess import Preprocessor
from where_fi.visualise import server as visualise from where_fi.visualise import server as visualise
from where_fi.visualise.server import figures
class Receiver(NamedTuple): class Receiver(NamedTuple):
@ -89,9 +90,20 @@ class CSIApplication:
self.processing_callback = None self.processing_callback = None
self.preprocessor = Preprocessor() self.preprocessor = Preprocessor()
self.custom_figures: dict[
visualise.figures.FigureId, visualise.figures.SpecificFigure
] = {}
def register_figure(
self,
figure_id: visualise.figures.FigureId,
figure: visualise.figures.SpecificFigure,
) -> None:
self.custom_figures[figure_id] = figure
figures.all_figures[figure_id] = figure
def visualise_data( def visualise_data(
self, data: npt.NDArray[Any], dtype: visualise.figures.Figure self, data: npt.NDArray[Any], dtype: visualise.figures.FigureId
) -> None: ) -> None:
""" """
Update a visualisation with the given data. The available visualisations are as Update a visualisation with the given data. The available visualisations are as
@ -155,7 +167,7 @@ class CSIApplication:
self.raw_csi_callback(sample.matrix) self.raw_csi_callback(sample.matrix)
if self.pre_merge_callback is not None: if self.pre_merge_callback is not None:
self.pre_merge_callback(sample.frames) self.pre_merge_callback(sample.frames)
processed = self.preprocessor.preprocess(sample.matrix) processed = self.preprocessor.preprocess(sample.matrix, sample.frames)
if self.visualise_raw: if self.visualise_raw:
self.visualise_data(processed, visualise.figures.Figure.PROCESSED_CSI) self.visualise_data(processed, visualise.figures.Figure.PROCESSED_CSI)
if self.preprocessed_csi_callback is not None: if self.preprocessed_csi_callback is not None:

View File

@ -18,7 +18,7 @@ from . import figures
@dataclass @dataclass
class VisualiserData: class VisualiserData:
data: npt.NDArray[Any] data: npt.NDArray[Any]
dtype: figures.Figure dtype: figures.FigureId
class FigureServer(figure_pb2_grpc.FigureServiceServicer): class FigureServer(figure_pb2_grpc.FigureServiceServicer):
@ -30,8 +30,8 @@ class FigureServer(figure_pb2_grpc.FigureServiceServicer):
def GetFigure( def GetFigure(
self, request: figure_pb2.FigureRequest, context: grpc.ServicerContext self, request: figure_pb2.FigureRequest, context: grpc.ServicerContext
) -> Generator[figure_pb2.Figure, None, None]: ) -> Generator[figure_pb2.Figure, None, None]:
for figure_group in figures.Figure: for figure_group in figures.all_figures.values():
for figure in figure_group.figure_class().figures: for figure in figure_group.figures:
yield figure yield figure
def GetFigureUpdate( def GetFigureUpdate(
@ -65,7 +65,7 @@ class Webapp:
self.figure_server = FigureServer() self.figure_server = FigureServer()
def add_data( def add_data(
self, dtype: figures.Figure, new_data: npt.NDArray[np.complex128] self, dtype: figures.FigureId, new_data: npt.NDArray[np.complex128]
) -> None: ) -> None:
updates = figures.all_figures[dtype].update(new_data) updates = figures.all_figures[dtype].update(new_data)
for fig_id, update in updates.items(): for fig_id, update in updates.items():

View File

@ -271,12 +271,15 @@ class Figure(Enum):
MUSIC_EIGENVALUES = 3 MUSIC_EIGENVALUES = 3
AOA_HEATMAP = 4 AOA_HEATMAP = 4
PHASE_ANALYSIS = 5 PHASE_ANALYSIS = 5
MAGN_ANALYSIS = 6
def figure_class(self) -> SpecificFigure: def figure_class(self) -> SpecificFigure:
return all_figures[self] return all_figures[self]
all_figures = { FigureId = str | Figure
all_figures: dict[FigureId, SpecificFigure] = {
Figure.RAW_CSI: PerAntennaFigure( Figure.RAW_CSI: PerAntennaFigure(
[ [
SimpleLineChart("Raw CSI Phase", "Subcarrier", "Phase"), SimpleLineChart("Raw CSI Phase", "Subcarrier", "Phase"),
@ -297,4 +300,5 @@ all_figures = {
Figure.MUSIC_EIGENVALUES: MusicEigenvalueHistogram(), Figure.MUSIC_EIGENVALUES: MusicEigenvalueHistogram(),
Figure.AOA_HEATMAP: HeatmapFigure(), Figure.AOA_HEATMAP: HeatmapFigure(),
Figure.PHASE_ANALYSIS: RandomVariable("Phase"), Figure.PHASE_ANALYSIS: RandomVariable("Phase"),
Figure.MAGN_ANALYSIS: RandomVariable("Magnitude"),
} }