Skip to content

Commit

Permalink
Merge pull request #91 from anarkiwi/discardmax
Browse files Browse the repository at this point in the history
Discard windows where max power, is less than requested minimum.
  • Loading branch information
anarkiwi authored Jul 25, 2023
2 parents 00c68a6 + 262717e commit aeb01b0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
7 changes: 7 additions & 0 deletions lib/retune_fft_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,13 @@ namespace gr {
--skip_fft_count_;
continue;
}
// Discard windows where max power, is less than requested minimum.
// Ettus radios periodically output low power after retuning. This
// avoids having to use a static skip_fft_count setting.
input_type in_max = *std::max_element(in, in + nfft_);
if (in_max < fft_min_) {
continue;
}
write_items_(in);
sum_items_(in);
++sample_count_;
Expand Down
2 changes: 1 addition & 1 deletion lib/retune_fft_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ namespace gr {
void process_items_(size_t c, const input_type* &in);
void output_buckets_(const std::string &name, const std::list<std::pair<double, double>> &buckets, std::stringstream &ss);
void reopen_(double host_now, uint64_t rx_freq);
void write_buckets_(double host_now, uint64_t rx_freq);
void write_buckets_(double host_now, uint64_t rx_freq);
void process_tags_(const input_type *in, size_t in_count, size_t in_first);
void write_(const char *data, size_t len);
void open_(const std::string &file);
Expand Down
31 changes: 18 additions & 13 deletions python/iqtlabs/qa_retune_fft.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,15 @@ def __init__(self):
self.tb = None

def retune_fft(self, fft_roll):
points = int(1024)
points = int(2048)
samp_rate = points * points
freq_start = int(1e9 / samp_rate) * samp_rate
freq_end = int(1.1e9 / samp_rate) * samp_rate
freq_mid = ((freq_end - freq_start) / 2) + freq_start
tuning_ranges = f"{freq_start}-{freq_mid},{freq_mid+samp_rate}-{freq_end}"
fft_write_count = 2
bucket_range = 1
fft_min = -1e9

with tempfile.TemporaryDirectory() as tmpdir:
test_file = os.path.join(tmpdir, "samples.csv")
Expand All @@ -296,8 +297,8 @@ def retune_fft(self, fft_roll):
64,
2,
fft_roll,
1e-4,
1e4,
fft_min,
1e9,
tmpdir,
fft_write_count,
bucket_range,
Expand Down Expand Up @@ -372,7 +373,7 @@ def retune_fft(self, fft_roll):
line = linebuffer.strip()
linebuffer = ""
record = json.loads(line)
ts = float(record["ts"])
ts = record["ts"]
self.assertGreater(ts, last_ts)
last_ts = ts
config = record["config"]
Expand Down Expand Up @@ -408,9 +409,9 @@ def retune_fft(self, fft_roll):
new_records = [
{
"ts": ts,
"f": float(freq),
"f": int(freq),
"v": float(value),
"t": tuning_range,
"t": int(tuning_range),
}
for freq, value in buckets.items()
]
Expand All @@ -426,21 +427,25 @@ def retune_fft(self, fft_roll):
]
expected_buckets = round(points * bucket_range)
self.assertEqual(top_count[0], expected_buckets)
all_df = pd.DataFrame(records)[["f", "v", "t"]].sort_values("f")
all_df["v"] = all_df["v"].round(2)
all_df = pd.DataFrame(records)[["t", "f", "v"]]
all_df["v"] = all_df["v"].round(1)
all_df = all_df.sort_values(["t", "f", "v"])

for _, df in all_df.groupby("t"):
# must have plausible unscaled dB value
self.assertTrue(0 <= df["v"].min() <= 1, df["v"].min())
self.assertTrue(50 <= df["v"].max() <= 60, df["v"].max())
self.assertTrue(fft_min <= df["v"].min() <= 1, df["v"].min())
self.assertTrue(50 <= df["v"].max() <= 61, df["v"].max())
df["u"] = df.groupby("f")["v"].transform("nunique")
non_unique_v = df[df["u"] != 1]
df["m"] = df.groupby("f")["v"].transform("diff")
df["m"] = df["m"].abs().max()
non_unique_v = df[df["m"] > 2]
# every frequency must have power values within 1-2dB (accounts for precision loss in FFT block)
self.assertTrue(non_unique_v.empty, non_unique_v)
f_count = df.groupby("f").count()
pd.set_option("display.max_rows", None)
# pd.set_option("display.max_rows", None)
f_count_min = f_count["u"].min()
# every frequency must be observed more than once.
self.assertGreater(f_count_min, 1, df[df["u"] == 1])
self.assertTrue(non_unique_v.empty, (non_unique_v, df))
# must have even frequency coverage within the range
df["d"] = df["f"].diff()
df = df[(df["d"] != 0) & (df["d"].notna())]
Expand Down

0 comments on commit aeb01b0

Please sign in to comment.