Add heatmap visualisation
This commit is contained in:
parent
a94a9b4ec4
commit
61be734752
@ -52,7 +52,7 @@ def heatmap() -> None:
|
|||||||
def callback(antenna_data: npt.NDArray[np.complex64]) -> None:
|
def callback(antenna_data: npt.NDArray[np.complex64]) -> None:
|
||||||
logger.info(f"Got final CSI data with shape {antenna_data.shape}")
|
logger.info(f"Got final CSI data with shape {antenna_data.shape}")
|
||||||
visualise_data(antenna_data, visualise.DataType.RAW_CSI)
|
visualise_data(antenna_data, visualise.DataType.RAW_CSI)
|
||||||
processed = preprocessor.preprocess(antenna_data)
|
processed = preprocessor.preprocess(antenna_data, visualiser=visualise_data)
|
||||||
visualise_data(processed, visualise.DataType.PROCESSED_CSI)
|
visualise_data(processed, visualise.DataType.PROCESSED_CSI)
|
||||||
logger.info(f"Processed CSI data with shape {processed.shape}")
|
logger.info(f"Processed CSI data with shape {processed.shape}")
|
||||||
processed_tensor = torch.tensor(processed, device=device)
|
processed_tensor = torch.tensor(processed, device=device)
|
||||||
|
|||||||
@ -6,4 +6,5 @@ server/generated: protos/*.proto
|
|||||||
find protos/ -type f -name "*.proto" | xargs uv run protol --create-package --in-place --python-out server/generated/ protoc --proto-path=protos/
|
find protos/ -type f -name "*.proto" | xargs uv run protol --create-package --in-place --python-out server/generated/ protoc --proto-path=protos/
|
||||||
|
|
||||||
frontend/src/grpc: protos/*.proto
|
frontend/src/grpc: protos/*.proto
|
||||||
find protos/ -name "*.proto" | xargs npm exec --prefix frontend/ protoc --ts_out frontend/src/grpc -I protos/
|
mkdir -p frontend/src/grpc
|
||||||
|
cd frontend && find ../protos/ -name "*.proto" | xargs npx protoc --ts_out=src/grpc -I../protos/
|
||||||
|
|||||||
@ -11,6 +11,18 @@ import { computed } from 'vue'
|
|||||||
const { figure, paused = false } = defineProps<{ figure: Figure; paused?: boolean }>()
|
const { figure, paused = false } = defineProps<{ figure: Figure; paused?: boolean }>()
|
||||||
const cancel = ref<boolean>(false)
|
const cancel = ref<boolean>(false)
|
||||||
|
|
||||||
|
function reshape(data: number[], width: number) {
|
||||||
|
if (data.length % width != 0) {
|
||||||
|
throw new Error('Data length is not divisible by width')
|
||||||
|
}
|
||||||
|
const height = data.length / width
|
||||||
|
const result: number[][] = new Array(height)
|
||||||
|
for (let i = 0; i < height; i++) {
|
||||||
|
result[i] = data.slice(i * width, (i + 1) * width)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
const data = ref<FigureData | null>(null)
|
const data = ref<FigureData | null>(null)
|
||||||
const plotData = computed(() => {
|
const plotData = computed(() => {
|
||||||
if (data.value) {
|
if (data.value) {
|
||||||
@ -24,16 +36,12 @@ const plotData = computed(() => {
|
|||||||
color: line.color ? line.color : undefined,
|
color: line.color ? line.color : undefined,
|
||||||
}))
|
}))
|
||||||
case 'heatmap':
|
case 'heatmap':
|
||||||
return []
|
return [
|
||||||
/* data.value.figure.heatmap.lines.map((line) => {
|
{
|
||||||
return {
|
z: reshape(data.value.figure.heatmap.data, data.value.figure.heatmap.width),
|
||||||
x: line.x,
|
type: 'heatmap' as const,
|
||||||
y: line.y,
|
},
|
||||||
type: 'scatter',
|
]
|
||||||
name: line.label,
|
|
||||||
color: line.color,
|
|
||||||
}
|
|
||||||
})*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
@ -43,6 +51,7 @@ const layout = {
|
|||||||
title: { text: figure.title },
|
title: { text: figure.title },
|
||||||
xaxis: { title: { text: figure.xLabel } },
|
xaxis: { title: { text: figure.xLabel } },
|
||||||
yaxis: { title: { text: figure.yLabel } },
|
yaxis: { title: { text: figure.yLabel } },
|
||||||
|
height: 700,
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateGraph() {
|
function updateGraph() {
|
||||||
|
|||||||
@ -2,9 +2,8 @@ syntax = "proto3";
|
|||||||
|
|
||||||
message HeatmapData {
|
message HeatmapData {
|
||||||
string uuid = 1;
|
string uuid = 1;
|
||||||
repeated float x = 2;
|
repeated float data = 2;
|
||||||
repeated float y = 3;
|
uint32 width = 3;
|
||||||
uint32 width = 4;
|
uint32 height = 4;
|
||||||
uint32 height = 5;
|
string cmap = 5;
|
||||||
string cmap = 6;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,8 +23,9 @@ clients_lock = threading.Lock()
|
|||||||
|
|
||||||
class DataType(Enum):
|
class DataType(Enum):
|
||||||
RAW_CSI = 1
|
RAW_CSI = 1
|
||||||
PROCESSED_CSI = 2
|
UNWRAPPED_PHASE = 2
|
||||||
HEATMAP = 3
|
PROCESSED_CSI = 3
|
||||||
|
HEATMAP = 4
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -40,6 +41,12 @@ figures = {
|
|||||||
x_label="Subcarrier",
|
x_label="Subcarrier",
|
||||||
y_label="Phase",
|
y_label="Phase",
|
||||||
),
|
),
|
||||||
|
"unwrapped_phase": figure_pb2.Figure(
|
||||||
|
uuid=str(uuid.uuid4()),
|
||||||
|
title="Unwrapped CSI Phase",
|
||||||
|
x_label="Subcarrier",
|
||||||
|
y_label="Unwrapped phase",
|
||||||
|
),
|
||||||
"processed_phase": figure_pb2.Figure(
|
"processed_phase": figure_pb2.Figure(
|
||||||
uuid=str(uuid.uuid4()),
|
uuid=str(uuid.uuid4()),
|
||||||
title="Preprocessed CSI Phase",
|
title="Preprocessed CSI Phase",
|
||||||
@ -48,9 +55,9 @@ figures = {
|
|||||||
),
|
),
|
||||||
"aoa_heatmap": figure_pb2.Figure(
|
"aoa_heatmap": figure_pb2.Figure(
|
||||||
uuid=str(uuid.uuid4()),
|
uuid=str(uuid.uuid4()),
|
||||||
title="Preprocessed CSI Phase",
|
title="AoA Heatmap",
|
||||||
x_label="Subcarrier",
|
x_label="ToF",
|
||||||
y_label="Phase",
|
y_label="AoA",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +111,25 @@ def add_data(dtype: DataType, new_data: npt.NDArray[np.complex128]) -> None:
|
|||||||
for q in clients.get(uuid, []):
|
for q in clients.get(uuid, []):
|
||||||
q.put(figure_pb2.FigureData(uuid=uuid, line=linechart))
|
q.put(figure_pb2.FigureData(uuid=uuid, line=linechart))
|
||||||
case DataType.HEATMAP:
|
case DataType.HEATMAP:
|
||||||
|
uuid = figures["aoa_heatmap"].uuid
|
||||||
|
heatmap = heatmap_pb2.HeatmapData(
|
||||||
|
uuid=uuid,
|
||||||
|
data=new_data.flatten(),
|
||||||
|
width=new_data.shape[1],
|
||||||
|
height=new_data.shape[0],
|
||||||
|
)
|
||||||
|
for q in clients.get(uuid, []):
|
||||||
|
q.put(figure_pb2.FigureData(uuid=uuid, heatmap=heatmap))
|
||||||
pass
|
pass
|
||||||
|
case DataType.UNWRAPPED_PHASE:
|
||||||
|
uuid = figures["unwrapped_phase"].uuid
|
||||||
|
lines = [
|
||||||
|
line_pb2.LineChartData.Line(y=new_data[:, i, 0], label=f"Antenna {i}")
|
||||||
|
for i in range(new_data.shape[1])
|
||||||
|
]
|
||||||
|
linechart = line_pb2.LineChartData(lines=lines)
|
||||||
|
for q in clients.get(uuid, []):
|
||||||
|
q.put(figure_pb2.FigureData(uuid=uuid, line=linechart))
|
||||||
|
|
||||||
|
|
||||||
def listen_for_data(data_queue: "mp.Queue[VisualiserData]") -> None:
|
def listen_for_data(data_queue: "mp.Queue[VisualiserData]") -> None:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user