Prettify fft comparisons

This commit is contained in:
jaseg 2020-02-20 19:21:09 +00:00
parent 0a042733dd
commit 99b9c0ecc1
3 changed files with 180 additions and 64 deletions

View file

@ -104,7 +104,7 @@
},
{
"cell_type": "code",
"execution_count": 40,
"execution_count": 221,
"metadata": {},
"outputs": [
{
@ -116,7 +116,7 @@
}
],
"source": [
"with open('/mnt/c/Users/jaseg/shared/raw_freq.bin', 'rb') as f:\n",
"with open('data/raw_freq.bin', 'rb') as f:\n",
" mains_noise = np.copy(np.frombuffer(f.read(), dtype='float32'))\n",
" print('mean:', np.mean(mains_noise), 'len:', len(mains_noise))\n",
" mains_noise -= np.mean(mains_noise)"
@ -610,13 +610,21 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 220,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<ipython-input-220-44ad44d9c4c6>:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" fig, ax = plt.subplots(figsize=(12, 9))\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "3bcd7f07ef26458da90f748fd74addfb",
"model_id": "f63ab2c387f948b29d992a3edd04f4fa",
"version_major": 2,
"version_minor": 0
},
@ -630,10 +638,10 @@
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7f23d0aa37f0>"
"<matplotlib.legend.Legend at 0x7f00ecacf3a0>"
]
},
"execution_count": 7,
"execution_count": 220,
"metadata": {},
"output_type": "execute_result"
}
@ -645,7 +653,7 @@
"# ser, std = np.mean(sers), np.std(sers)\n",
"# results = { nbits: [ res.get() for res in series ] for nbits, series in results.items() }\n",
"\n",
"with open(f'/mnt/c/Users/jaseg/shared/dsss_experiments_res-2020-02-19-19-30-05.json', 'r') as f:\n",
"with open(f'data/dsss_experiments_res-2020-02-19-19-30-05.json', 'r') as f:\n",
" results = json.load(f)\n",
"\n",
"for nbits, series in results.items():\n",
@ -666,21 +674,21 @@
},
{
"cell_type": "code",
"execution_count": 36,
"execution_count": 218,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<ipython-input-36-8e813d331cd8>:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
"<ipython-input-218-eb5258414ca6>:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" fig, ((ax, cbar_ax), (intercept_ax, empty)) = plt.subplots(2, 2, figsize=(12, 9), gridspec_kw={'width_ratios': [1, 0.05]})\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "c05f590a7c0040628c5c5d4032bb7c8e",
"model_id": "6651827b5eca4a0ba46effefd605f06c",
"version_major": 2,
"version_minor": 0
},
@ -795,9 +803,9 @@
"\n",
"results = []\n",
"for fn in [\n",
" '/mnt/c/Users/jaseg/shared/dsss_experiments_res-2020-02-20-12-18-35.json',\n",
" '/mnt/c/Users/jaseg/shared/dsss_experiments_res-2020-02-20-12-26-07.json',\n",
" '/mnt/c/Users/jaseg/shared/dsss_experiments_res-2020-02-20-12-29-02.json'\n",
" 'data/dsss_experiments_res-2020-02-20-12-18-35.json',\n",
" 'data/dsss_experiments_res-2020-02-20-12-26-07.json',\n",
" 'data/dsss_experiments_res-2020-02-20-12-29-02.json'\n",
"]:\n",
" with open(fn, 'r') as f:\n",
" results += json.load(f)\n",
@ -893,21 +901,21 @@
},
{
"cell_type": "code",
"execution_count": 35,
"execution_count": 268,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<ipython-input-35-cafaa6062c72>:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" fig, ((ax, cbar_ax), (intercept_ax, empty)) = plt.subplots(2, 2, figsize=(12, 9), gridspec_kw={'width_ratios': [1, 0.05]})\n"
"<ipython-input-268-fd9510d5c128>:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" fig, ((ax, cbar_ax), (intercept_ax, empty)) = plt.subplots(2, 2, figsize=(12, 9), gridspec_kw={'width_ratios': [1, 0.05], 'hspace': 0.4})\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "fa93fb31355840148f941dab8b60f51c",
"model_id": "be4678ec02394b81b8aee83c759e1009",
"version_major": 2,
"version_minor": 0
},
@ -922,21 +930,22 @@
"name": "stderr",
"output_type": "stream",
"text": [
"<ipython-input-35-cafaa6062c72>:16: RuntimeWarning: divide by zero encountered in log10\n",
"<ipython-input-268-fd9510d5c128>:17: RuntimeWarning: divide by zero encountered in log10\n",
" cm_func = lambda x: cmap(np.log10(x - min(decimations)) / (np.log10(max(decimations)) - np.log10(min(decimations))))\n"
]
}
],
"source": [
"fig, ((ax, cbar_ax), (intercept_ax, empty)) = plt.subplots(2, 2, figsize=(12, 9), gridspec_kw={'width_ratios': [1, 0.05]})\n",
"fig, ((ax, cbar_ax), (intercept_ax, empty)) = plt.subplots(2, 2, figsize=(12, 9), gridspec_kw={'width_ratios': [1, 0.05], 'hspace': 0.4})\n",
"empty.axis('off')\n",
"#fig.tight_layout()\n",
"\n",
"results = []\n",
"\n",
"for fn in [\n",
" '/mnt/c/Users/jaseg/shared/dsss_experiments_res-2020-02-20-14-10-13.json',\n",
" '/mnt/c/Users/jaseg/shared/dsss_experiments_res-2020-02-20-13-21-57.json',\n",
" '/mnt/c/Users/jaseg/shared/dsss_experiments_res-2020-02-20-13-23-47.json',\n",
" 'data/dsss_experiments_res-2020-02-20-14-10-13.json',\n",
" 'data/dsss_experiments_res-2020-02-20-13-21-57.json',\n",
" 'data/dsss_experiments_res-2020-02-20-13-23-47.json',\n",
"]:\n",
" with open(fn, 'r') as f:\n",
" results += json.load(f)\n",
@ -953,16 +962,27 @@
" stds = np.array([ np.std(values) for values in data ])\n",
" decimation_sers[decimation] = list(zip(amps, sers, stds))\n",
" \n",
" amps = [ amp*1000 for amp in amps ]\n",
" l, = ax.plot(amps, np.clip(sers, 0, 1), label=f'decimation={decimation}', color=cm_func(decimation))\n",
" ax.fill_between(amps, np.clip(sers + stds, 0, 1), np.clip(sers - stds, 0, 1), facecolor=l.get_color(), alpha=0.2)\n",
" ax.axhline(0.5, color='gray', ls=(0, (3, 4)), lw=0.8)\n",
"ax.grid()\n",
"ax.set_xlabel('Amplitude in mHz')\n",
"ax.set_xlabel('Amplitude [mHz]')\n",
"ax.set_ylabel('Symbol error rate')\n",
"\n",
"norm = matplotlib.colors.Normalize(vmin=np.log10(min(decimations)), vmax=np.log10(max(decimations)))\n",
"cb1 = matplotlib.colorbar.ColorbarBase(cbar_ax, cmap=cmap, norm=norm, orientation='vertical', label=\"Decimation\", ticks=[np.log10(d) for d in decimations])\n",
"cb1.ax.set_yticklabels([f'{d:.1f}' for d in decimations])\n",
"yticks = [np.log10(d) for d in decimations]\n",
"cb1 = matplotlib.colorbar.ColorbarBase(cbar_ax, cmap=cmap, norm=norm, orientation='vertical', ticks=yticks)\n",
"cb1t = cbar_ax.twinx()\n",
"cb1t.set_ylim(cbar_ax.get_ylim())\n",
"cb1t.set_yticks(yticks)\n",
"\n",
"cbar_ax.set_yticklabels([f'{d/sampling_rate:.1f}' for d in decimations])\n",
"cbar_ax.set_ylabel(\"chip duration [s]\", labelpad=-70)\n",
"\n",
"cb1t.set_yticklabels([f'{d/sampling_rate * 2**nbits:.1f}' for d in decimations])\n",
"cb1t.set_ylabel(\"symbol duration [s]\")\n",
"\n",
"\n",
"def plot_intercepts(ax, SER_TH = 0.5):\n",
" intercepts = {}\n",
@ -988,8 +1008,10 @@
" std = data[:,1]\n",
" \n",
" ax.set_xlim([min(x), max(x)])\n",
" l = ax.plot(x, y, label='Amplitude at SER=0.5', color='orange')\n",
" ax.legend(loc=3)\n",
" y = [ v*1000 if v is not None else v for v in y ]\n",
" l = ax.plot(x, y, label='Amplitude at SER=0.5 [mHz]', color='orange')\n",
" #ax.legend(loc=3)\n",
" ax.set_ylabel('Amplitude at SER=0.5 [mHz]')\n",
" ax.grid()\n",
" \n",
" x, y, std = zip(*[ (le_x, le_y, le_std) for le_x, le_y, le_std in zip(x, y, std) if le_y is not None ])\n",
@ -1002,12 +1024,43 @@
" ax.set_ylim([min(y)*0.9, max(y)*1.1])\n",
" ax.set_xscale('log')\n",
" ax.xaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, _: '{:g}'.format(x)))\n",
" ax.set_xticks([1, 2, 5, 10, 20, 50])\n",
" xticks = [1, 2, 5, 10, 20, 50]\n",
" ax.set_xticks(xticks)\n",
" ax.set_xticklabels([ f'{x/sampling_rate:.1f}' for x in xticks ])\n",
" ax.set_xlim([1, 60])\n",
" ax.set_xlabel('chip duration [s]')\n",
" \n",
" axt = ax.twiny()\n",
" axt.set_xlim(ax.get_xlim())\n",
" axt.set_xscale('log')\n",
" axt.set_xticks(xticks)\n",
" axt.set_xticklabels([ f'{x/sampling_rate * 2**nbits:.1f}' for x in xticks ])\n",
" axt.set_xlabel('symbol duration [s]')\n",
" \n",
" return l\n",
"\n",
"l1 = plot_intercepts(intercept_ax)\n"
]
},
{
"cell_type": "code",
"execution_count": 227,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"41.6"
]
},
"execution_count": 227,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"13 * 2**5 / 10"
]
}
],
"metadata": {

View file

@ -141,13 +141,21 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 72,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<ipython-input-72-51d3a7cc1678>:20: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" fig, ax = plt.subplots()\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "fd94bc97a276400db0539b703c4eeeac",
"model_id": "2991d932b113496a9135d569f9577abe",
"version_major": 2,
"version_minor": 0
},
@ -161,10 +169,10 @@
{
"data": {
"text/plain": [
"(1.6666666666666667e-05, 0.5)"
"(5e-07, 0.02)"
]
},
"execution_count": 23,
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
@ -194,8 +202,14 @@
"ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _pos: f'{1/x:.1f}'))\n",
"ax.set_xlabel('T in s')\n",
"ax.set_ylabel('Amplitude Δf')\n",
"\n",
"for i, t in enumerate([45, 60, 600, 1200, 1800, 3600]):\n",
" ax.axvline(1/t, color='red', alpha=0.5)\n",
" ax.annotate(f'{t} s', xy=(1/t, 3e-3), xytext=(-15, 0), xycoords='data', textcoords='offset pixels', rotation=90)\n",
"#ax.text(1/60, 10,'60 s', ha='left')\n",
"ax.grid()\n",
"ax.set_xlim([1/60000, 0.5])"
"ax.set_xlim([1/60000, 0.5])\n",
"ax.set_ylim([5e-7, 2e-2])"
]
},
{

View file

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 104,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@ -36,7 +36,7 @@
"metadata": {},
"outputs": [],
"source": [
"db = sqlite3.connect('/mnt/c/Users/jaseg/shared/waveform-raspi.sqlite3')"
"db = sqlite3.connect('data/waveform-raspi.sqlite3')"
]
},
{
@ -100,7 +100,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "f960454ab93244db97e039ae7ebd02ee",
"model_id": "55690b4f59d54454b83deb5200c05f09",
"version_major": 2,
"version_minor": 0
},
@ -177,7 +177,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "264a9f8478e449289c1592c9595dc6cc",
"model_id": "cf5c2e35008740379508eaaedfcf3b31",
"version_major": 2,
"version_minor": 0
},
@ -246,7 +246,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7c2382eb8e124ef9b29546ecaed3e155",
"model_id": "efa9db02cdfc4f6c86d1eadd4769d097",
"version_major": 2,
"version_minor": 0
},
@ -279,7 +279,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d29e8ee5bf7f4e94a1749239aec24d6d",
"model_id": "e4122530c1444f75aca410ad51d4a733",
"version_major": 2,
"version_minor": 0
},
@ -356,7 +356,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "47c40f28b5a34a94b4a631fd62107521",
"model_id": "a36a994f6f484a6cba81b6e680c9eee1",
"version_major": 2,
"version_minor": 0
},
@ -412,7 +412,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "4a4cb62296df496bad37d93547d3c26a",
"model_id": "e4116959544f44f6a4b898419a5d51db",
"version_major": 2,
"version_minor": 0
},
@ -490,7 +490,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
@ -509,21 +509,13 @@
},
{
"cell_type": "code",
"execution_count": 81,
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<ipython-input-81-a751e13723ea>:17: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" fig, ax = plt.subplots(figsize=(9,5))\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "3809a1a83b5844e3906f1d74bcd15b5d",
"model_id": "09069e2c9cb740d5b58846371aeea0f2",
"version_major": 2,
"version_minor": 0
},
@ -548,7 +540,7 @@
"5.0"
]
},
"execution_count": 81,
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
@ -585,21 +577,13 @@
},
{
"cell_type": "code",
"execution_count": 156,
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<ipython-input-156-ddde6af5dee1>:20: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" fig, ax = plt.subplots()\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d137ae59ed7947ce8e3f7295e102f2f0",
"model_id": "b812e4b240a642398f09bb3cff8f5cee",
"version_major": 2,
"version_minor": 0
},
@ -616,7 +600,7 @@
"(1.6666666666666667e-05, 0.5)"
]
},
"execution_count": 156,
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
@ -649,6 +633,71 @@
"ax.grid()\n",
"ax.set_xlim([1/60000, 0.5])"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "c835382368b6423ab5446835c5785afd",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(5e-07, 0.02)"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Number of samplepoints\n",
"N = len(data)\n",
"# sample spacing\n",
"T = 1.0 / 10.0\n",
"x = np.linspace(0.0, N*T, N)\n",
"yf = scipy.fftpack.fft(data)\n",
"xf = np.linspace(0.0, 1.0/(2.0*T), N//2)\n",
"\n",
"yf = 2.0/N * np.abs(yf[:N//2])\n",
"\n",
"average_from = lambda val, start, average_width: np.hstack([val[:start], [ np.mean(val[i:i+average_width]) for i in range(start, len(val), average_width) ]])\n",
"\n",
"average_width = 6\n",
"average_start = 20\n",
"yf = average_from(yf, average_start, average_width)\n",
"xf = average_from(xf, average_start, average_width)\n",
"yf = average_from(yf, 70, 4)\n",
"xf = average_from(xf, 70, 4)\n",
"\n",
"fig, ax = plt.subplots()\n",
"ax.loglog(xf, yf)\n",
"ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _pos: f'{1/x:.1f}'))\n",
"ax.set_xlabel('T in s')\n",
"ax.set_ylabel('Amplitude Δf')\n",
"\n",
"for i, t in enumerate([45, 60, 600, 1200, 1800, 3600]):\n",
" ax.axvline(1/t, color='red', alpha=0.5)\n",
" ax.annotate(f'{t} s', xy=(1/t, 3e-5), xytext=(-15, 0), xycoords='data', textcoords='offset pixels', rotation=90)\n",
"#ax.text(1/60, 10,'60 s', ha='left')\n",
"ax.grid()\n",
"ax.set_xlim([1/60000, 0.5])\n",
"ax.set_ylim([5e-7, 2e-2])"
]
}
],
"metadata": {