Skip to content

Commit

Permalink
Serve alternate waterfalls
Browse files Browse the repository at this point in the history
  • Loading branch information
anarkiwi committed Jun 7, 2024
1 parent dab0080 commit 1a2bd76
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 35 deletions.
2 changes: 1 addition & 1 deletion gamutrfwaterfall/gamutrfwaterfall/flask_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def poll_zmq(self):

def serve(self, path):
if path:
full_path = os.path.realpath(os.path.join("/", path))
full_path = os.path.realpath(os.path.join(self.tempdir, path))
if os.path.exists(full_path):
return send_file(full_path, mimetype="image/png")
return "%s: not found" % full_path, 404
Expand Down
50 changes: 35 additions & 15 deletions gamutrfwaterfall/gamutrfwaterfall/waterfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import warnings

from gamutrflib.peak_finder import get_peak_finder
from gamutrflib.zmqbucket import ZmqReceiver, parse_scanners, frame_resample
from gamutrflib.zmqbucket import ZmqReceiver, parse_scanners
from gamutrfwaterfall.argparser import argument_parser
from gamutrfwaterfall.flask_handler import (
FlaskHandler,
Expand Down Expand Up @@ -119,11 +119,41 @@ def sig_handler(_sig=None, _frame=None):
config.fft_len,
config.freq_resolution,
)
tuning_ranges = []
for scan_config in scan_configs:
for tuning_range in scan_config["tuning_ranges"].split(","):
tuning_ranges.append([int(i) for i in tuning_range.split("-")])
plot_manager.close()
plot_manager.add_plot(config, 0)
results = [
(scan_configs, frame_resample(scan_df, config.freq_resolution * 1e6))
]
if len(tuning_ranges) > 1:
for i, tuning_range in enumerate(tuning_ranges, start=1):
plot_savefig_path = os.path.join(
os.path.dirname(savefig_path),
"-".join((str(i), os.path.basename(savefig_path))),
)
logging.info(
f"tuning range {tuning_range[0]}-{tuning_range[1]} writing to {plot_savefig_path}"
)
plot_config = make_config(
scan_configs,
tuning_range[0],
tuning_range[1],
engine,
plot_snr,
plot_savefig_path,
top_n,
base_save_path,
width,
height,
waterfall_height,
waterfall_width,
batch,
rotate_secs,
save_time,
)
plot_manager.add_plot(plot_config, i)

results = [(scan_configs, scan_df)]

if config_vars_path:
get_scanner_args(api_endpoint, config_vars)
Expand All @@ -143,9 +173,7 @@ def sig_handler(_sig=None, _frame=None):
gap_time = time.time() - last_gap
if results and gap_time > refresh / 2:
break
scan_configs, scan_df = zmqr.read_buff(
scan_fres=config.freq_resolution * 1e6
)
scan_configs, scan_df = zmqr.read_buff()
if scan_df is None:
if batch and gap_time < refresh / 2:
time.sleep(0.1)
Expand Down Expand Up @@ -173,14 +201,6 @@ def sig_handler(_sig=None, _frame=None):
results = []
need_reconfig = True
break
scan_df = scan_df[
(scan_df.freq >= config.min_freq) & (scan_df.freq <= config.max_freq)
]
if scan_df.empty:
logging.info(
f"Scan is outside specified frequency range ({config.min_freq} to {config.max_freq})."
)
continue
results.append((scan_configs, scan_df))
if need_reconfig:
continue
Expand Down
16 changes: 13 additions & 3 deletions gamutrfwaterfall/gamutrfwaterfall/waterfall_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, AutoMinorLocator
from scipy.ndimage import gaussian_filter
from gamutrflib.zmqbucket import frame_resample


class WaterfallConfig:
Expand Down Expand Up @@ -237,7 +238,6 @@ def reset_mesh_psd(self, data=None):

if data is None:
data = np.zeros(X[:-1, :-1].shape)

self.state.mesh_psd = self.state.ax_psd.pcolormesh(X, Y, data, shading="flat")

def reset_mesh(self, data):
Expand Down Expand Up @@ -390,8 +390,18 @@ def update_fig(self, results):
logging.info("processing backlog of %u results", len(results))

scan_duration = 0
row_time = None

for scan_configs, scan_df in results:
for scan_configs, orig_scan_df in results:
scan_df = frame_resample(
orig_scan_df.copy(), self.config.freq_resolution * 1e6
)
scan_df = scan_df[
(scan_df.freq >= self.config.min_freq)
& (scan_df.freq <= self.config.max_freq)
]
if scan_df.empty:
continue
tune_step_hz = min(
scan_config["tune_step_hz"] for scan_config in scan_configs
)
Expand Down Expand Up @@ -443,7 +453,7 @@ def update_fig(self, results):

self.state.counter += 1

if self.state.counter % self.config.draw_rate == 0:
if row_time is not None and self.state.counter % self.config.draw_rate == 0:
now = time.time()
since_last_plot = 0
if self.state.last_plot:
Expand Down
34 changes: 18 additions & 16 deletions gamutrfwaterfall/tests/test_waterfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,28 @@


class FakeZmqReceiver:
def __init__(self, run_secs, peak_min, peak_max, peak_val):
def __init__(self, run_secs, peak_min, peak_max, peak_val, freq_min, freq_max):
self.start_time = time.time()
self.run_secs = run_secs
self.serve_results = None
self.peak_min = peak_min
self.peak_max = peak_max
self.peak_val = peak_val
self.freq_min = freq_min
self.freq_max = freq_max

def healthy(self):
return time.time() - self.start_time < self.run_secs

def read_buff(self, scan_fres):
def read_buff(self, scan_fres=1e3):
if not self.serve_results:
freq_min = 1e6
freq_max = 10e6
rows = int((freq_max - freq_min) / scan_fres)
rows = int((self.freq_max - self.freq_min) / scan_fres)
df = pd.DataFrame(
[
{
"ts": time.time(),
"freq": freq_min + (i * scan_fres),
"db": self.peak_val / 2,
"freq": self.freq_min + (i * scan_fres),
"db": self.peak_val * 2,
"tune_count": i,
}
for i in range(rows)
Expand All @@ -44,7 +44,6 @@ def read_buff(self, scan_fres):
df.loc[(df.freq >= self.peak_min) & (df.freq <= self.peak_max), "db"] = (
self.peak_val
)
df["freq"] /= 1e6
self.serve_results = [
(
[
Expand All @@ -55,6 +54,7 @@ def read_buff(self, scan_fres):
"freq_end": df.freq.max(),
"tune_step_hz": scan_fres,
"tune_step_fft": 256,
"tuning_ranges": f"{int(df.freq.min())}-{int(df.freq.max())}",
}
],
df,
Expand All @@ -73,15 +73,17 @@ def test_arg_parser(self):

def test_run_waterfall(self):
with tempfile.TemporaryDirectory() as tempdir:
peak_min = 1.50
peak_max = 1.51
peak_val = 100
peak_min = 1.50e6
peak_max = 1.52e6
peak_val = -10
freq_min = 1e6
freq_max = 2e6
savefig = os.path.join(tempdir, "test.png")
zmqr = FakeZmqReceiver(90, peak_min, peak_max, peak_val)
zmqr = FakeZmqReceiver(90, peak_min, peak_max, peak_val, freq_min, freq_max)
peak_finder = get_peak_finder("narrowband")
serve_waterfall(
1e6, # args.min_freq,
2e6, # args.max_freq,
freq_min, # args.min_freq,
freq_max, # args.max_freq,
True, # args.plot_snr,
1, # args.n_detect,
tempdir, # args.save_path,
Expand Down Expand Up @@ -117,10 +119,10 @@ def test_run_waterfall(self):
# timestamp,start_freq,end_freq,dB,type
# 1.0,1.49609375,1.5078125,100.0,narrowband
self.assertEqual(
round(peak_min, 1), round(float(row["start_freq"]), 1), row
round(peak_min / 1e6, 1), round(float(row["start_freq"]), 1), row
)
self.assertEqual(
round(peak_max, 1), round(float(row["end_freq"]), 1), row
round(peak_max / 1e6, 1), round(float(row["end_freq"]), 1), row
)
self.assertEqual(peak_val, float(row["dB"]), row)

Expand Down

0 comments on commit 1a2bd76

Please sign in to comment.