Skip to content

Commit eae2b27

Browse files
committed
Update wfs-referencing.ipynb
- nicer code structure, format - subplot(2,1) instead of (1,2) seems nicer - scatter plot for ref contour - tapering not needed - add difference as magnitude plot
1 parent 4cdbb56 commit eae2b27

File tree

1 file changed

+71
-41
lines changed

1 file changed

+71
-41
lines changed

doc/examples/wfs-referencing.ipynb

Lines changed: 71 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@
99
"Illustrates the usage of the SFS toolbox for the simulation of different 2.5D WFS referencing schemes for contours within the listening area that exhibit amplitude correct synthesis, cf. Ch. 4.1.3 in <cite data-cite=\"Firtha2019\">[Firtha19]</cite> and <cite data-cite=\"Firtha2017\">(FFSS17)</cite>."
1010
]
1111
},
12+
{
13+
"cell_type": "code",
14+
"execution_count": null,
15+
"metadata": {},
16+
"outputs": [],
17+
"source": [
18+
"import matplotlib.pyplot as plt\n",
19+
"import numpy as np\n",
20+
"import sfs"
21+
]
22+
},
1223
{
1324
"cell_type": "markdown",
1425
"metadata": {},
@@ -22,19 +33,12 @@
2233
"metadata": {},
2334
"outputs": [],
2435
"source": [
25-
"import matplotlib.pyplot as plt\n",
26-
"import numpy as np\n",
27-
"import sfs\n",
28-
"\n",
29-
"R = 1.5 # Radius of circular loudspeaker array\n",
30-
"array = sfs.array.circular(N=64, R=R)\n",
36+
"R = 1.5 # Radius of circular loudspeaker array, in m\n",
37+
"array = sfs.array.circular(N=64, R=R) # with N loudspeakers\n",
3138
"grid = sfs.util.xyz_grid([-2, 2], [-2, 2], 0, spacing=0.02)\n",
3239
"\n",
33-
"xs = sfs.util.asarray_of_rows((-4, 0, 0)) # point source on negative x-axis\n",
34-
"normalize_gain = 4 * np.pi * np.linalg.norm(xs)\n",
35-
"wavelength = 1 / 4 # m\n",
36-
"f = sfs.default.c / wavelength # Hz\n",
37-
"omega = 2 * np.pi * f # rad/s"
40+
"xs = -4, 0, 0 # point source on negative x-axis\n",
41+
"wavelength = 1 / 4 # m"
3842
]
3943
},
4044
{
@@ -43,32 +47,40 @@
4347
"metadata": {},
4448
"outputs": [],
4549
"source": [
46-
"def sound_field(d, xref, selection,\n",
47-
" secondary_source, array, grid, tapering=True):\n",
48-
" if tapering:\n",
49-
" tapering_window = sfs.tapering.kaiser(selection, beta=1)\n",
50-
" else:\n",
51-
" tapering_window = sfs.tapering.none(selection)\n",
50+
"def sound_field(\n",
51+
" d, xref, selection, secondary_source, array, grid):\n",
5252
"\n",
53-
" p = sfs.fd.synthesize(d, tapering_window,\n",
54-
" array, secondary_source, grid=grid)\n",
53+
" p = sfs.fd.synthesize(\n",
54+
" d, selection, array, secondary_source, grid=grid)\n",
5555
"\n",
56-
" fig, axs = plt.subplots(1, 2, figsize=(10, 8))\n",
57-
" sfs.plot2d.amplitude(p, grid, vmax=2, vmin=-2, ax=axs[0])\n",
58-
" sfs.plot2d.level(p, grid, vmax=6, vmin=-6, ax=axs[1],\n",
59-
" cmap='seismic', colorbar_kwargs={'label': 'dB'})\n",
60-
" for i in range(axs.shape[0]):\n",
61-
" sfs.plot2d.loudspeakers(array.x, array.n,\n",
62-
" tapering_window,\n",
63-
" size=0.125, ax=axs[i])\n",
64-
" axs[i].plot(xref[:, 0][selection],\n",
65-
" xref[:, 1][selection],\n",
66-
" marker='o', linestyle='', color='dimgray', ms=4)\n",
67-
" axs[i].grid(True)\n",
56+
" fig, [ax_amp, ax_lvl] = plt.subplots(2, 1, sharex=True)\n",
57+
" fig.set_figheight(fig.get_figwidth() * 3/2)\n",
58+
" sfs.plot2d.amplitude(p, grid, vmax=2, vmin=-2, ax=ax_amp)\n",
59+
" sfs.plot2d.level(\n",
60+
" p, grid, vmax=6, vmin=-6, ax=ax_lvl, cmap='seismic',\n",
61+
" colorbar_kwargs={'label': 'dB'})\n",
62+
" for ax in ax_amp, ax_lvl:\n",
63+
" sfs.plot2d.loudspeakers(\n",
64+
" array.x, array.n, selection, size=0.125, ax=ax)\n",
65+
" ax.scatter(*xref[selection, :2].T, s=20, c='dimgray',\n",
66+
" zorder=3)\n",
67+
" ax.grid(True)\n",
6868
" plt.tight_layout()\n",
6969
" return p\n"
7070
]
7171
},
72+
{
73+
"cell_type": "code",
74+
"execution_count": null,
75+
"metadata": {},
76+
"outputs": [],
77+
"source": [
78+
"xs = sfs.util.asarray_of_rows((-4, 0, 0))\n",
79+
"f = sfs.default.c / wavelength # Hz\n",
80+
"omega = 2 * np.pi * f # rad/s\n",
81+
"normalize_gain = 4 * np.pi * np.linalg.norm(xs)"
82+
]
83+
},
7284
{
7385
"cell_type": "markdown",
7486
"metadata": {},
@@ -89,13 +101,14 @@
89101
"# calc reference contour xref(x0), cf. [FFSS17, eq. (24), (31), (52)]\n",
90102
"# this code assumes virtual point source on x-axis\n",
91103
"cosbeta = (array.n @ [1, 0, 0]).reshape(-1, 1)\n",
92-
"xref = array.x + (xs - array.x) * \\\n",
93-
" (xref_line + R * cosbeta) / (xs[0, 0] + R * cosbeta)\n",
104+
"xref = array.x + \\\n",
105+
" (xs - array.x) * (xref_line + R * cosbeta) / (xs[0, 0] + R * cosbeta)\n",
94106
"\n",
95107
"d, selection, secondary_source = sfs.fd.wfs.point_25d(\n",
96108
" omega, array.x, array.n, xs, xref=xref)\n",
97-
"p_line = sound_field(d * normalize_gain, xref, selection,\n",
98-
" secondary_source, array, grid, tapering=False)"
109+
"p_line = sound_field(\n",
110+
" d * normalize_gain, xref, selection,\n",
111+
" secondary_source, array, grid)"
99112
]
100113
},
101114
{
@@ -123,8 +136,9 @@
123136
"\n",
124137
"d, selection, secondary_source = sfs.fd.wfs.point_25d(\n",
125138
" omega, array.x, array.n, xs, xref=xref)\n",
126-
"p_circ = sound_field(d * normalize_gain, xref, selection,\n",
127-
" secondary_source, array, grid, tapering=False)"
139+
"p_circ = sound_field(\n",
140+
" d * normalize_gain, xref, selection,\n",
141+
" secondary_source, array, grid)"
128142
]
129143
},
130144
{
@@ -134,10 +148,26 @@
134148
"outputs": [],
135149
"source": [
136150
"# (complex-valued) ratio between the two soundfields tells\n",
137-
"# us about the difference of both approaches\n",
138-
"sfs.plot2d.level(p_line / p_circ, grid, vmax=1, vmin=-1,\n",
139-
" cmap='seismic', colorbar_kwargs={'label': 'dB'})\n",
140-
"sfs.plot2d.loudspeakers(array.x, array.n, size=0.125)\n",
151+
"# us about the difference of both approaches in terms of dB\n",
152+
"sfs.plot2d.level(\n",
153+
" p_line / p_circ, grid, vmax=1, vmin=-1, cmap='seismic',\n",
154+
" colorbar_kwargs={'label': 'dB'})\n",
155+
"sfs.plot2d.loudspeakers(array.x, array.n, selection, size=0.125)\n",
156+
"plt.grid(True)\n",
157+
"plt.tight_layout()"
158+
]
159+
},
160+
{
161+
"cell_type": "code",
162+
"execution_count": null,
163+
"metadata": {},
164+
"outputs": [],
165+
"source": [
166+
"# (complex-valued) difference between the two soundfields tells\n",
167+
"# us about the difference of both approaches in terms of magnitude\n",
168+
"sfs.plot2d.amplitude(\n",
169+
" p_line - p_circ, grid, vmax=1e-1, vmin=-1e-1)\n",
170+
"sfs.plot2d.loudspeakers(array.x, array.n, selection, size=0.125)\n",
141171
"plt.grid(True)\n",
142172
"plt.tight_layout()"
143173
]

0 commit comments

Comments
 (0)