mirror of
https://gitlab.science.ru.nl/mthesis-edeboone/m-thesis-introduction.git
synced 2024-12-22 11:33:32 +01:00
Some old work to start a simulation
This commit is contained in:
parent
5bbc4a88f7
commit
8e433d5bd9
1 changed files with 288 additions and 0 deletions
288
simulations/03_emitter_receiver_simulation.ipynb
Normal file
288
simulations/03_emitter_receiver_simulation.ipynb
Normal file
|
@ -0,0 +1,288 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Emitter/Receiver Simulation with Signals"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%matplotlib inline\n",
|
||||
"\n",
|
||||
"import numpy as np\n",
|
||||
"import scipy.fft as ft\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import matplotlib.gridspec as gridspec\n",
|
||||
"import matplotlib.ticker as tck\n",
|
||||
"\n",
|
||||
"rng = np.random.default_rng()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Signal"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# copied from 02_discrete_signal_translation.ipynb #ae7aba6\n",
|
||||
"class TravelSignal:\n",
|
||||
" \"\"\"\n",
|
||||
" Model an arbitrary digitised signal that can be translated to another position and time.\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" def __init__(self, signal, sample_rate, t_0 = 0, x_0 = 0, periodic=True, interp1d_kw = None):\n",
|
||||
" \"\"\"\n",
|
||||
" Initialise by saving the raw signal\n",
|
||||
" \n",
|
||||
" Parameters\n",
|
||||
" ----------\n",
|
||||
" signal : arraylike\n",
|
||||
" The raw signal to wrap.\n",
|
||||
" sample_rate : float\n",
|
||||
" Sample rate of the raw signal.\n",
|
||||
" t_0 : float, optional\n",
|
||||
" Time that this signal is sent out.\n",
|
||||
" x_0 : float, optional\n",
|
||||
" Location that this signal is sent out from.\n",
|
||||
" periodic : bool, optional\n",
|
||||
" Translated signal is 0 if it is not periodic\n",
|
||||
" and the time/distance is outside the samples.\n",
|
||||
" interp1d_kw : bool or dict, optional\n",
|
||||
" Use scipy.interpolate's interp1d_kw for interpolation.\n",
|
||||
" Set to True, or a dictionary to enable.\n",
|
||||
" Dictionary will be entered in as **kwargs.\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" self.raw = signal\n",
|
||||
" self.periodic = periodic\n",
|
||||
"\n",
|
||||
" self.sample_rate = sample_rate # Hz\n",
|
||||
" self.sample_length = len(self.raw)\n",
|
||||
" self.time_length = self.sample_length*sample_rate # s\n",
|
||||
" \n",
|
||||
" self.x_0 = x_0\n",
|
||||
" self.t_0 = t_0\n",
|
||||
"\n",
|
||||
" # choose interpolation method\n",
|
||||
" if not interp1d_kw:\n",
|
||||
" self.interp_f = None\n",
|
||||
"\n",
|
||||
" else:\n",
|
||||
" # offload interpolation to scipy.interpolate\n",
|
||||
" import scipy.interpolate as interp\n",
|
||||
"\n",
|
||||
" interp1d_kw_defaults = {\n",
|
||||
" \"copy\": False,\n",
|
||||
" \"kind\": 'linear',\n",
|
||||
" \"assume_sorted\": True,\n",
|
||||
" \"bounds_error\": True\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" if self.periodic:\n",
|
||||
" interp1d_kw_defaults['bounds_error'] = False\n",
|
||||
" interp1d_kw_defaults['fill_value'] = (self.raw[-1], self.raw[0])\n",
|
||||
" \n",
|
||||
" # merge kwargs\n",
|
||||
" if interp1d_kw is not True:\n",
|
||||
" interp1d_kw = { **interp1d_kw_defaults, **interp1d_kw }\n",
|
||||
"\n",
|
||||
" self.interp_f = interp.interp1d(\n",
|
||||
" np.arange(0, self.sample_length),\n",
|
||||
" self.raw,\n",
|
||||
" **interp1d_kw\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" def __len__(self):\n",
|
||||
" return self.sample_length\n",
|
||||
" \n",
|
||||
" def __call__(self, t_f = None, x_f = None, **kwargs):\n",
|
||||
" \"\"\"\n",
|
||||
" Allow this class to be used as a function.\n",
|
||||
" \"\"\"\n",
|
||||
" return self._translate(t_f, x_f, **kwargs)[0]\n",
|
||||
" \n",
|
||||
" def _translate(self, t_f = None, x_f = None, t_0 = None, x_0 = None, velocity = None):\n",
|
||||
" \"\"\"\n",
|
||||
" Translate the signal from (t_0, x_0) to (t_f, x_f) with optional velocity.\n",
|
||||
" \n",
|
||||
" Returns the signal at (t_f, x_f)\n",
|
||||
" \"\"\"\n",
|
||||
" \n",
|
||||
" if t_0 is None:\n",
|
||||
" t_0 = self.t_0\n",
|
||||
" \n",
|
||||
" if velocity is None:\n",
|
||||
" velocity = 1\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" ## spatial offset\n",
|
||||
" if x_f is None:\n",
|
||||
" spatial_time_offset = 0\n",
|
||||
" else:\n",
|
||||
" x_f = np.asarray(x_f)\n",
|
||||
" if x_0 is None:\n",
|
||||
" x_0 = self.x_0\n",
|
||||
"\n",
|
||||
" spatial_time_offset = np.sum(np.sqrt( (x_f - x_0)**2 )/velocity)\n",
|
||||
"\n",
|
||||
" ## temporal offset\n",
|
||||
" if t_f is None:\n",
|
||||
" temporal_time_offset = 0\n",
|
||||
" else:\n",
|
||||
" t_f = np.asarray(t_f)\n",
|
||||
" \n",
|
||||
" if t_0 is None:\n",
|
||||
" t_0 = self.t_0\n",
|
||||
" \n",
|
||||
" temporal_time_offset = t_f - t_0\n",
|
||||
"\n",
|
||||
" # total offset\n",
|
||||
" total_time_offset = spatial_time_offset + temporal_time_offset\n",
|
||||
" n_offset = (total_time_offset * sample_rate )\n",
|
||||
"\n",
|
||||
" # periodic signal\n",
|
||||
" if self.periodic:\n",
|
||||
" n_offset = n_offset % self.sample_length\n",
|
||||
"\n",
|
||||
" # non-periodic and outside the bounds\n",
|
||||
" else:\n",
|
||||
" mask_idx = np.nonzero( (0 > n_offset) | (n_offset >= self.sample_length) )\n",
|
||||
" n_offset[mask_idx] = 0\n",
|
||||
"\n",
|
||||
" # offload to scipy interpolation\n",
|
||||
" if self.interp_f:\n",
|
||||
" amplitude = self.interp_f(n_offset)\n",
|
||||
" \n",
|
||||
" # self written linear interpolation\n",
|
||||
" else:\n",
|
||||
" n_offset_eps, n_offset_int = np.modf(n_offset)\n",
|
||||
" n_offset_int = n_offset.astype(int)\n",
|
||||
"\n",
|
||||
" if True:\n",
|
||||
" amplitude = (1-n_offset_eps) * self.raw[n_offset_int] \\\n",
|
||||
" + n_offset_eps * self.raw[(n_offset_int + 1) % self.sample_length]\n",
|
||||
"\n",
|
||||
" # use nearest value instead of interpolation\n",
|
||||
" else:\n",
|
||||
" amplitude = self.raw[n_offset_int]\n",
|
||||
"\n",
|
||||
" if not self.periodic:\n",
|
||||
" amplitude[mask_idx] = 0\n",
|
||||
" \n",
|
||||
" return amplitude, total_time_offset"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## New code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"### Location\n",
|
||||
"class Location:\n",
|
||||
" \"\"\"\n",
|
||||
" A location is a point designated by a spatial coordinate x.\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" def __init__(self, x):\n",
|
||||
" self.x = np.asarray(x) \n",
|
||||
"\n",
|
||||
" def __repr__(self):\n",
|
||||
" return \"Location({})\".format(repr(self.x))\n",
|
||||
"\n",
|
||||
" def __getitem__(self, key):\n",
|
||||
" return self.x[key]\n",
|
||||
"\n",
|
||||
" def __setitem__(self, key, val):\n",
|
||||
" self.x[key] = val\n",
|
||||
"\n",
|
||||
" def __add__(self, other):\n",
|
||||
" if isinstance(other, self.__class__):\n",
|
||||
" other = other.x\n",
|
||||
"\n",
|
||||
" return self.__class__(self.x + other)\n",
|
||||
"\n",
|
||||
" def __sub__(self, other):\n",
|
||||
" if isinstance(other, self.__class__):\n",
|
||||
" other = other.x\n",
|
||||
"\n",
|
||||
" return self.__class__(self.x - other)\n",
|
||||
" \n",
|
||||
" def __eq__(self, other):\n",
|
||||
" if isinstance(other, self.__class__):\n",
|
||||
" other = other.x\n",
|
||||
"\n",
|
||||
" return np.all(self.x == other)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"### Receiver\n",
|
||||
"class Receiver(Location):\n",
|
||||
" \"\"\"\n",
|
||||
" Receive a signal at position x and time t\n",
|
||||
" \"\"\"\n",
|
||||
" pass"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
" ### Emitter\n",
|
||||
"class Emitter(TravelSignal):\n",
|
||||
" \"\"\"\n",
|
||||
" Emit a signal from position x_0 (and time t_0)\n",
|
||||
" \"\"\"\n",
|
||||
" pass"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
Loading…
Reference in a new issue