aboutsummaryrefslogtreecommitdiffstats
path: root/analyze_aligned_rx_tx.py
diff options
context:
space:
mode:
Diffstat (limited to 'analyze_aligned_rx_tx.py')
-rw-r--r--analyze_aligned_rx_tx.py132
1 files changed, 132 insertions, 0 deletions
diff --git a/analyze_aligned_rx_tx.py b/analyze_aligned_rx_tx.py
new file mode 100644
index 0000000..2b9f70c
--- /dev/null
+++ b/analyze_aligned_rx_tx.py
@@ -0,0 +1,132 @@
+"""
+Generate analytic plots from aligned TX/RX recordings.
+"""
+
+import argparse
+import numpy as np
+import matplotlib.pyplot as plt
+import src.dab_util as du
+import scipy.stats as st
+from sklearn.neighbors import KernelDensity
+import os
+
+SCATTER_SIZE = 0.0001
+
+def kde2D(x, y, bandwidth, xbins=256j, ybins=256j, **kwargs):
+ xx, yy = np.mgrid[x.min():x.max():xbins,
+ y.min():y.max():ybins]
+
+ xy_sample = np.vstack([yy.ravel(), xx.ravel()]).T
+ xy_train = np.vstack([y, x]).T
+
+ kde_skl = KernelDensity(bandwidth=bandwidth, **kwargs)
+ kde_skl.fit(xy_train)
+
+ z = np.exp(kde_skl.score_samples(xy_sample))
+ return xx, yy, np.reshape(z, xx.shape)
+
+def plot_density(x, y, scatter=False, path=None):
+ x = np.abs(x)
+ y = np.abs(y)
+
+ x = x - np.min(x)
+ x = x / np.max(x)
+ y = y - np.min(y)
+ y = y / np.max(y)
+
+ max_val = max(np.max(x), np.max(y))
+ min_val = max(np.min(x), np.min(y))
+
+ xx, yy, zz = kde2D(x, y, (max_val - min_val) * 0.01)
+ plt.pcolormesh(xx, yy, zz)
+
+ plt.xlabel("Normalized Absolute TX Amplitude")
+ plt.ylabel("Normalized Absolute RX Amplitude")
+
+ plt.savefig(path)
+
+def scatter(x_pos, y_pos, x_neg, y_neg, path=None):
+ x_pos, y_pos, x_neg, y_neg = np.abs(x_pos), np.abs(y_pos), np.abs(x_neg), np.abs(y_neg)
+ plt.scatter(x_pos, y_pos, s=SCATTER_SIZE, facecolor='blue', label="Positive TX/RX")
+ plt.scatter(x_neg, y_neg, s=SCATTER_SIZE, facecolor='red', label="Negative TX/RX")
+ plt.xlabel("Absolute TX Amplitude")
+ plt.ylabel("Absolute RX Amplitude")
+ plt.legend()
+ plt.savefig(path)
+ plt.clf()
+
+def scatter_phase(x_pos, y_pos, x_neg, y_neg, path=None):
+ x_pos_abs = np.abs(x_pos)
+ x_neg_abs = np.abs(x_neg)
+
+ phase_diff_pos = np.angle(x_pos, deg=True) - np.angle(y_pos, deg=True)
+ phase_diff_neg = np.angle(x_neg, deg=True) - np.angle(y_neg, deg=True)
+
+ phase_diff_pos = np.mod(phase_diff_pos, 180)
+ phase_diff_neg = np.mod(phase_diff_neg, 180)
+
+ plt.scatter(x_pos_abs, phase_diff_pos, s=SCATTER_SIZE, facecolor='blue', label="Positive TX/RX")
+ plt.scatter(x_neg_abs, phase_diff_neg, s=SCATTER_SIZE, facecolor='red', label="Negative TX/TX")
+
+ plt.ylabel("Phase difference")
+ plt.xlabel("Absolute Amplitude")
+ plt.legend()
+
+ plt.savefig(path)
+ plt.clf()
+
+def plot_time(rx_rec, tx_rec, path=None, samples=256):
+ plt.plot(np.angle(rx_rec[:256]), c='blue', label="RX")
+ plt.plot(np.angle(tx_rec[:256]), c='red', label="TX")
+ plt.ylabel("Phase")
+ plt.xlabel("Sample")
+ plt.savefig(path)
+ plt.clf()
+
+def main():
+ if not os.path.isdir(FLAGS.out_dir):
+ os.makedirs(FLAGS.out_dir)
+
+ rx_rec = du.fromfile(filename=FLAGS.rx_path)
+ tx_rec = du.fromfile(filename=FLAGS.tx_path)
+
+ sel_pos = (rx_rec > 0) & (tx_rec > 0)
+ rx_rec_pos = rx_rec[sel_pos]
+ tx_rec_pos = tx_rec[sel_pos]
+
+
+ sel_pos = (rx_rec < 0) & (tx_rec < 0)
+ rx_rec_neg = rx_rec[sel_pos]
+ tx_rec_neg = tx_rec[sel_pos]
+
+ scatter(tx_rec_pos, rx_rec_pos, tx_rec_neg, rx_rec_neg, path=FLAGS.out_dir + '/am_am_scatter.pdf')
+ scatter_phase(tx_rec_pos, rx_rec_pos, tx_rec_neg, rx_rec_neg, path=FLAGS.out_dir + '/am_pm_pos_scatter.pdf')
+
+ plot_time(rx_rec, tx_rec, path=FLAGS.out_dir + '/phase_over_time.pdf')
+
+ plot_density(tx_rec_pos, rx_rec_pos, path=FLAGS.out_dir + '/am_am_pos.pdf')
+ plot_density(tx_rec_neg, rx_rec_neg, path=FLAGS.out_dir + '/am_am_neg.pdf')
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--rx_path',
+ type=str,
+ default='/tmp/record/2_rx_record.iq',
+ help="Path to complex64 rx recording"
+ )
+ parser.add_argument(
+ '--tx_path',
+ type=str,
+ default='/tmp/record/2_tx_record.iq',
+ help="Path to complex64 tx recording"
+ )
+ parser.add_argument(
+ '--out_dir',
+ type=str,
+ default='/tmp/analyze_aligned_rx_tx',
+ help="Output path"
+ )
+ FLAGS, unparsed = parser.parse_known_args()
+
+ main()