dissertation/examples/music.py
2026-07-30 07:25:42 +01:00

119 lines
3.6 KiB
Python

import logging
import numpy as np
import torch
from where_fi.application import CSIApplication
from where_fi.collection import CSIMatrix
from where_fi.collection.ingest import RealtimeCSIProducer
from where_fi.config import config
from where_fi.processing.aoa import AoA
from where_fi.visualise import server as visualise
app = CSIApplication(visualise_raw=True)
logging.basicConfig(level=logging.INFO)
T = 500
N_sub1 = config.antennas.count // 2
N_sub2 = config.subcarriers // 2
L2 = config.subcarriers - N_sub2 + 1
L1 = config.antennas.count - N_sub1 + 1
N_sensors = config.subcarriers * config.antennas.count
historical = torch.zeros(T, N_sensors, N_sensors, dtype=torch.complex64)
cnt = 0
@app.on_sample
def _(sample: CSIMatrix) -> None:
global cnt
sample_before_resize = sample[:, :, 0].T
sample_after = sample_before_resize.reshape(-1, 1)
sample_tensor = torch.tensor(sample_after)
historical[cnt] = sample_tensor @ torch.conj(sample_tensor).T
print(
f"{sample.shape} => {sample_before_resize.shape} => {sample_after.shape} "
f"=> {historical[cnt].shape}"
)
cnt = (cnt + 1) % T
def get_steering(theta: float, tau: float) -> torch.Tensor:
"""
Calculate the alpha value for the given angle and time delay.
"""
sub, ant = np.indices((N_sub1, N_sub2))
alpha = np.exp(
-1j
* (
2 * np.pi * (sub * config.delta_f * tau)
+ 2
* np.pi
* (
ant
* config.antennas.spacing
* np.sin(theta)
* 299_792_458
/ (config.central_freq_hz + (sub - 28) * config.delta_f)
)
)
)
alpha = sub + 1j * ant
alpha = alpha.reshape(-1, 1)
return torch.tensor(alpha, dtype=torch.complex64)
aoa = AoA()
@app.on_process
def _(_: CSIMatrix) -> None:
R: torch.Tensor = torch.mean(historical, axis=0)
# Rss = torch.zeros(N_sub1 * N_sub2, N_sub1 * N_sub2, dtype=torch.complex64)
# for i in range(L1):
# for j in range(L2):
# Rss += R[i : i + N_sub1 * N_sub2, j : j + N_sub1 * N_sub2]
# Rss /= L1 * L2
Rss = R
aoa.historical_autocorr = torch.unsqueeze(Rss, 0)
aoa.heatmap(app.visualise_data)
# eigvals, eigvecs = torch.linalg.eig(Rss)
# app.visualise_data(eigvals.numpy(), visualise.figures.Figure.MUSIC_EIGENVALUES)
# E_n = eigvecs[:, torch.abs(eigvals) < config.music.eigval_threshold]
# E_n_H = torch.conj(E_n.T)
# heatmap = np.zeros(
# (config.music.heatmap.tof_resolution, config.music.heatmap.theta_resolution)
# )
# for i_theta, theta in enumerate(
# np.linspace(0, np.pi, config.music.heatmap.theta_resolution)
# ):
# for i_tau, tau in enumerate(
# np.linspace(
# 0, config.music.heatmap.tof_max, config.music.heatmap.tof_resolution
# )
# ):
# steering = get_steering(theta, tau)
# steering_h = torch.conj(steering.T)
# c = 1 / (steering_h @ E_n @ E_n_H @ steering)
# heatmap[i_tau, i_theta] = torch.abs(c)
# print(steering)
# app.visualise_data(heatmap, visualise.figures.Figure.AOA_HEATMAP)
# eigvals, eigvecs = torch.linalg.eig(Rss)
# app.visualise_data(eigvals.numpy(), visualise.figures.Figure.MUSIC_EIGENVALUES)
# E_n = eigvecs[:, torch.abs(eigvals) < config.music.eigval_threshold]
# print(E_n)
# c: torch.Tensor = 1 / (steering_h @ E_n @ E_n_H @ steering)
# return torch.abs(c)[:, 0, 0]
if __name__ == "__main__":
producer = RealtimeCSIProducer()
app.set_producer(producer)
app.start()