From 47fb7aaf9d0b9fba4a0597d530268ae188b0ef1e Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Tue, 9 Mar 2021 15:35:03 +0100 Subject: [PATCH 01/20] first implementation of a measurement chain and demonstration in mestopy_demo. --- mestopy/mestopy.py | 245 ++++++++++++++++++++++++++++++++++++++- mestopy_demo.ipynb | 277 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 521 insertions(+), 1 deletion(-) create mode 100644 mestopy_demo.ipynb diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index dd0b80e..4843cca 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -1 +1,244 @@ -"""Main module.""" +import numpy as np +from pyfar import Signal + + +# Class to generate ref-Objects, that can bei part of the MeasurementChain +class DeviceObj(object): + """Class for device in MeasurementChain. + + This class holds methods and properties of a device in the + 'MeasurementChain' class. + """ + + def __init__(self, data, sens=1, name=''): + """Init DeviceObj with data. + + Attributes + ---------- + data : Signal + Signal data that reprensets the inverted frequency response of + the device. Data can be in domain 'freq' or 'time' and will be + transformed if necessary. + sens : float + Sensitivity of the device as a factor. + name : str + Name of the device. + """ + self.sens = sens + self.name = name + self.data = data + + @property + def freq(self): + """Return the frequency responses of the device, multiplied by + the sensitivity. + """ + return self.data * self.sens + + @property + def device_name(self): + """Return the name of the device as string.""" + return self.name + + @device_name.setter + def device_name(self, new_name): + """Set the name of the device.""" + self.name = new_name + + def __repr__(self): + """String representation of DeviceObj class.""" + repr_string = ( + f"{self.name} defined by {self.data.n_bins} freq-bins, " + f"sensitivity={self.sens}\n") + return repr_string + + +# Class for MeasurementChain as frame for RefObjs and calibration +class MeasurementChain(object): + """Class for complete measurement chain. + + This class that holds methods and properties of all devices in the + measurement chain. It can include a single or multiple devices from + 'DeviceObj' class. + """ + + def __init__(self, + sampling_rate, + sound_device=None, + devices=[], + comment=None): + """Init measurement chain with rampling rate. + + Attributes + ---------- + sampling_rate : double + Sampling rate in Hertz. + sound_device : int + Number to identify the sound device used. The default is None. + devices : list + A list of instances from 'DeviceObj' class. The default is an + empty list. + comment : str + A comment related to the measurement chain. The default is None. + """ + self.sampling_rate = sampling_rate + self.sound_device = sound_device + self.devices = devices + self.comment = comment + + def add_device(self, + device_data=None, + sens=1, + device_name=''): + """Adds a new device to the measurement chain. + + Attributes + ---------- + device_data : Signal, optional + Signal data that reprensets the inverted frequency response of the + device to add. The default is None, in this case a perfect flat + frequency response is assumed and only sensitivity as + a factor is applied. + Caution: Make sure to use frequency responses without artefacts, + as they will influence the quality of compensations calculated with + the measurement chain. Most ideal this should be regularized + inverted frequency responses. Data can be in domain 'freq' or + 'time' and will be transformed if necessary. + sens : float, optional + Sensitivity of the device as a factor. If neither device_data nor + sens is given, add_device generates a device that has no effect to + the measurement chain as it has no frequency response and a + sesitivity (factor) of 1. + device_name : str, optional + The name of the new device to add to the masurement chain. + The default is an empty string. + """ + if device_data is None: + device_data = Signal(np.full(int(self.sampling_rate/2), 1.0), + self.sampling_rate, + domain='freq') + # check if ref_signal is a pyfar.Signal, if not raise Error + if not isinstance(device_data, Signal): + raise TypeError('Input data must be of type: Signal.') + # check if there are no devices in measurement chain + if self.devices == []: + # add ref-measurement to chain + device_data.domain = 'freq' + new_device = DeviceObj(device_data, + sens, + device_name) + self.devices.append(new_device) + else: + # check if n_bins of all devices is the same + if not self.devices[0].data.n_bins == device_data.n_bins: + raise ValueError("ref_signal has wrong n_bins") + # check if sampling_rate of new device and MeasurementChain + # is the same + if not self.sampling_rate == device_data.sampling_rate: + raise ValueError("ref_signal has wrong samping_rate") + # add device to chain + new_device = DeviceObj(device_data, + sens, + device_name) + self.devices.append(new_device) + + def list_devices(self): + """Returns a list of names of all devices in the measurement chain. + """ + # list all ref-objects in chain + device_names = [] + for dev in self.devices: + name = dev.device_name + device_names.append(name) + return device_names + + def remove_device(self, num): + """Removes a single device from the measurement chain, + by name or number. + + Attributes + ---------- + num : int or str + Identifier for device to remove. Device can be found by name as string + or by number in device list as int. + """ + # remove ref-object in chain position num + if isinstance(num, int): + front = self.devices[:num] + back = self.devices[num+1:] + for i in back: + front.append(i) + self.devices = front + # remove ref-object in chain by name + elif isinstance(num, str): + i = 0 + for dev in self.devices: + if dev.name == num: + self.remove_device(i) + return + i = i + 1 + raise ValueError(f"device {num} not found") + else: + raise TypeError("device to remove must be int or str") + + # reset complete ref-object-list + def reset_devices(self): + """Resets the list of devices in the measurement chain. + Other global parameters such as sampling rate or sound device of the + measurement chain remain unchanged. + """ + self.devices = [] + + # get the freq-response of specific device in measurement chain + def device_freq(self, num): + """Returns the frequency response of a single device from the + measurement chain, by name or number. + + Attributes + ---------- + num : int or str + Identifier for device, can be name as string or by number + in device list as int. + """ + if isinstance(num, int): + dev = self.devices[num].data * self.devices[num].sens + dev.domain = 'freq' + return dev + elif isinstance(num, str): + i = 0 + for dev in self.devices: + if dev.name == num: + return self.device_freq(i) + i = i + 1 + raise ValueError(f"device {num} not found") + else: + raise TypeError("device to remove must be int or str") + + # get the freq-response of whole measurement chain as pyfar.Signal + def freq(self): + """Returns the frequency response of the complete measurement chain. + All devices (frequency response and sensitivity) are considered. + """ + if self.devices != []: + resp = Signal(np.ones(int(self.devices[0].data.n_bins)), + self.sampling_rate, + domain='freq', + fft_norm=self.devices[0].data.fft_norm, + dtype=self.devices[0].data.dtype) + for dev in self.devices: + resp = resp * dev.data * dev.sens + else: + resp = Signal(np.ones(self.sampling_rate), self.sampling_rate) + return resp + + def __repr__(self): + """String representation of MeasurementChain class. + """ + repr_string = ( + f"measurement chain with {len(self.devices)} devices " + f"@ {self.sampling_rate} Hz sampling rate.\n") + i = 1 + for dev in self.devices: + repr_string = f"{repr_string}# {i}: {dev}" + i += 1 + return repr_string diff --git a/mestopy_demo.ipynb b/mestopy_demo.ipynb new file mode 100644 index 0000000..a2e397f --- /dev/null +++ b/mestopy_demo.ipynb @@ -0,0 +1,277 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mestopy Demo-Notebook\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# import modules\n", + "import pyfar\n", + "import numpy as np\n", + "\n", + "# import from mestopy\n", + "from mestopy.mestopy import MeasurementChain" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Demo: basic functionality of Measurement Chain" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# initialise measurement chain @fs=48000\n", + "fs = 48000\n", + "chain = MeasurementChain(fs)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "measurement chain with 4 devices @ 48000 Hz sampling rate.\n", + "# 1: Device 1 defined by 24000 freq-bins, sensitivity=1.0\n", + "# 2: Device 1 defined by 24000 freq-bins, sensitivity=1.0\n", + "# 3: Device 2 defined by 24000 freq-bins, sensitivity=2.0\n", + "# 4: Device 3 defined by 24000 freq-bins, sensitivity=0.5\n", + "\n", + "['Device 1', 'Device 1', 'Device 2', 'Device 3']\n", + "['Device 1', 'Device 2', 'Device 3']\n", + "/home/alex/Git/pyfar-develop/pyfar/signal.py:507: UserWarning: Number of time samples not given, assuming an even number of samples from the number of frequency bins.\n", + " warnings.warn(\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "freq domain energy Signal:\n", + "(1,) channels with 47998 samples @ 48000 Hz sampling rate and none FFT normalization" + ] + }, + "metadata": {}, + "execution_count": 3 + } + ], + "source": [ + "# reset MeasurementChain refs, in case you run this cell multiple times\n", + "chain.reset_devices()\n", + "\n", + "# generate a flat signal\n", + "sig = pyfar.Signal(np.full(int(fs/2), 1.0), fs, domain='freq')\n", + "\n", + "# add these signals as devices to the measurement chain; attention: Device 1 is added twice by \"mistake\"\n", + "chain.add_device(sig, sens=1.0, device_name='Device 1') \n", + "chain.add_device(sig, sens=1.0, device_name='Device 1')\n", + "chain.add_device(sig, sens=2.0, device_name='Device 2')\n", + "chain.add_device(sig, sens=0.5, device_name='Device 3')\n", + "\n", + "# print measurement chain __repr__\n", + "print(chain)\n", + "\n", + "# print names of devices in measurement chain\n", + "print(chain.list_devices())\n", + "\n", + "# remove double added Device 1 from measurement chain\n", + "chain.remove_device(1)\n", + "\n", + "# print names of devices in measurement chain after removing\n", + "print(chain.list_devices())\n", + "\n", + "# get the freq-response of whole measurement chain as pyfar.Signal\n", + "chain.freq()\n", + "\n", + "# get the freq-response of specific device in measurement chain as pyfar.Signal\n", + "chain.device_freq(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 4 + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-09T15:32:17.204006\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/png": "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P/6o9PR0jRo1SqNHj9YXX3zhk33nzZunO+64Q3fffbdzrK59s7OzlZCQoJEjR2rHjh1en8+d+vTT3zVJ3vXUk3q87aevHmNt/X7wwQd14MCBeu9ZX656Hax6zvtlrxtaT2299tVj9Obnd9OmTXrqqacafM66ePvz621NjS6gQkND9cgjj2j9+vXKzs7W22+/raKiIq1cuVK9e/fWu+++q969e2vlypUBq+nNN9/U9ddf7/zaF7U888wz6tevn9555x3n/r7Yd/jw4Vq6dOlFY672LSoqUm5urtatW6elS5dq4cKFstvtXp+zLt72MxA1SZ731NN6vOmnLx9jbf0OFle9DrZf9rqhauu1r3jz8xsI/n4+bnQBdfXVV6tr166SpMsvv1ydOnWSzWZTXl6ehg0bJkkaNmyYPv7444DUc+zYMX366adKSEhwjjW0llOnTukf//iHRowYIUlq3ry5Wrdu7ZPHePPNN+uKK664aMzVvnl5eRo8eLCsVqs6dOigqKgoFRYWen3Ounjbz0DU5E1PPanH23768jHW1u/zzp07p4yMDGVlZdVrb2+56nWw6pFq73VD6nHV64bseSFvfn4vtH37dk2aNEkVFRX1Oq8rDXk+9qSmRhdQFyorK9OhQ4fUo0cPff/997r66qsl/fxNO3HiREBqWLx4saZMmSKLxeIca2gtpaWlCg8P17x585SYmKjMzEz99NNPfnuMrva12Wy65pprnOsiIyMvekLxNU/6GYiavOmpJ/V4289APEa73a7Zs2erY8eOSklJ8enenriw18Gsp7ZeN6QeV71uyJ7uuHte+Oijj7Ry5Uq98MILCg8P99l5f8mb52NPa2q0AVVZWan09HRNnz5drVq1CkoNn3zyia688kp169bNp/va7XYdOnRIo0eP1po1a3TZZZcF9LK9Lr/8QfaVhvTTlzX5oqe1Pdk1tJ++/r4vWLBA0dHRSkpK8um+nqit18Gop65e17eeunodjMe4b98+rVq1Ss8//7zLK2lf8Obn15uaGmVAnT17Vunp6fr973+v22+/XZJ05ZVXqry8XJJUXl6utm3b+r2OgoIC5efna/jw4Zo1a5b27NmjOXPmNLiWyMhIRUZGOv91OWjQIB08eNBvj9HVvpGRkTp27Jhznc1mU0REhE/OeSFv+unvmrztqSf1eNvPQHzfb7rpJu3bt0/V1dU+3ded2nodrHpc9boh9bjqdUP2dKeu54UOHTqosrJShw8f9uk5L+Tt87E3NTW6gHI4HHriiSd0/fXXa/z48c7xgQMHavPmzZKkzZs3a+DAgX6v5aGHHlJOTo42bdqk+fPn63e/+50yMzMbXMvVV1+ta665Rt99950kaffu3ercubPfHqOrfePi4pSbm6uamhqVlpaqpKREMTExPjnned720981edtTT+rxtp+B+L6PGDFC/fr104wZM3T27Fmf7u2Kq14Hqx5XvW5IPa563ZA93anreaFdu3ZatGiRMjIy9M033/jsnOfV5/nYm5oaXUAVFBQoJydHe/bsUWJiohITE7V9+3bde++92rVrl+666y7t2rVLEydODFqNvqglLS1Nc+bM0dixY/Wvf/1LkyZN8sm+M2fO1KRJk1RcXKyhQ4fqvffec7lvdHS04uPjNWbMGD388MNKT09XSEiI1+esi7f9DERNtWloPd7005ePsbZ+nzd+/Hh17dpVc+fO1blz5+q1vzdc9TpY9bhT33pq63VD9zzPm5/f8zp16qTMzEzNmDFD//nPf7w+Z13q+3zsaU183AYAwEiN7goKANA0EFAAACMRUAAAIxFQAAAjEVAAACMRUMD/9O7d2/lW2cTERJWVlQW7JJ84cOCAnn76aa+OGT58+EX3SNu7d6/zbt9AoIQGuwDAFC1atNCaNWtqnXM4HHI4HGrWrPH9m6579+7q3r17sMsAvEZAAS6UlZVpypQp6tWrl7744gstXrxYW7du1QcffKCamhrddtttSk5OliS9+uqrev/999WuXTuFh4erW7dumjBhgh588EFNmzZN3bt3V0VFhSZMmKBNmzbJbrfrxRdf1L59+1RTU6MxY8Zo1KhR2rt3r/7yl78oPDxc33zzjbp166bMzExZLBYVFhZq8eLF+umnn9S8eXO9/PLLmjp1qtLS0nTjjTdKku677z49/vjj+u1vf+t8HHv37tUbb7yh559/XsuXL9fRo0dVWlqqY8eO6Z577tHYsWO9+r5MmTLFeRub0tJSpaWlOe9cDfgSAQX8T3V1tRITEyVJ1157rR599FEVFxcrIyNDM2bM0M6dO1VSUqJVq1bJ4XDo0Ucf1eeff67LLrtMubm5WrNmjc6ePavx48e7vdnshg0bdPnll+v1119XTU2NkpKS1KdPH0nSoUOHtG7dOkVERCgpKUkFBQWKiYnRzJkztWDBAsXExOjUqVNq0aKFEhIStHnzZt14440qLi7WmTNnLgqn2hQXF2vZsmWqrKx0fqheaOivnwqSk5Odd7CorKxUp06dJElLliyRJH311VeaN2+ebr31Vm++zYDHCCjgf375K76ysjK1b99esbGxkqSdO3dq586dGjdunCQ5b3hZWVmp2267TWFhYZJ+vpeeOzt37tTXX3+tDz/8UNLPnyNUUlKi0NBQxcTEOD9u44YbblBZWZlatWqlq666ynlPvvN3jI6Pj9crr7yiqVOnauPGjR5dyfTv319Wq1VWq1Vt27bVf//734s+3uO85cuXOz8K4fxV2HkVFRWaO3eunnzyyaB9mgAufQQUUIfzoSP9/DrUxIkTNWrUqIvWrFmzxuXHYYSGhjrvuXbhXawdDofS0tLUt2/fi9bv3btXVqvV+XWzZs1kt9vlcDhqPUdYWJhuueUWffzxx/rggw/0+uuvu31Mte3vDbvdrpkzZ+r+++9Xly5dvDoW8Ebje8UXCJK+fftq48aNqqyslPTzx2B8//33uvnmm/XRRx+pqqpKp0+f1ieffOI8pn379s6PW9i2bdtFe61fv955V+vi4mLnB9vVplOnTiovL3d+su7p06edxyYkJOiZZ55R9+7d1aZNG98+6Fq8+OKL6tKli4YMGeL3c6Fp4woK8FCfPn307bffOu9O3bJlS2VmZqpr16664447lJiYqPbt26tnz57OYyZMmKAZM2YoJydHvXr1co4nJCToyJEjGjdunBwOh9q2bavFixe7PHfz5s21YMECPf3006qurlaLFi2UlZWl0NBQdevWTZdffrmGDx/ut8d+odWrV6tz587O1+uSk5MD8vE2aHq4mzngY8uXL1fLli01YcKEgJzv+PHjSk5O1vr16xvl2+ABV/i/GWjENm/erIkTJyolJYVwwiWHKygAgJH4JxcAwEgEFADASAQUAMBIBBQAwEgEFADASP8Pn6aMjIP9RicAAAAASUVORK5CYII=\n" + }, + "metadata": {} + } + ], + "source": [ + "# plot freq-response of whole measurement chain\n", + "fig1 = pyfar.plot.line.freq(chain.freq())\n", + "\n", + "# plot freq-response of element 1 of the measurement chain\n", + "pyfar.plot.line.freq(chain.device_freq(2))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "['Device 1', 'Device 2', 'Device 3']\n", + "['Device 1', 'Device 2']\n", + "/home/alex/Git/pyfar-develop/pyfar/signal.py:507: UserWarning: Number of time samples not given, assuming an even number of samples from the number of frequency bins.\n", + " warnings.warn(\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 5 + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-09T15:32:17.855719\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/png": "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a3S3r81mU3l5uWud3W5XRESEX855Pl/6GeiafO2pN/X42s9g/L3/9re/1f79+1VTU+PXfT1pqNdG1eOu102px12vm7KnJ439XOjWrZuqqqp05MgRv57zfL7+PPalpmYXUE6nU0899ZSuueYaJSYmusaHDBmiLVu2SJK2bNmiIUOGBLyWhx56SDk5Odq8ebPmzZunm266SXPnzm1yLZ06dVLnzp313XffSZL27Nmja6+9NmCv0d2+sbGxys3NVW1trUpLS1VSUqKoqCi/nLOer/0MdE2+9tSbenztZzD+3kePHq3BgwdrxowZqqur8+ve7rjrtVH1uOt1U+px1+um7OlJYz8XunTpooULFyozM1PffPON385Z72J+HvtSU7MLqIKCAuXk5Gjv3r1KSEhQQkKCduzYoXvuuUe7d+/WXXfdpd27d2vy5MmG1eiPWtLT0/Xkk09q4sSJ+te//qUpU6b4Zd+ZM2dqypQpKi4u1ogRI/TBBx+43TcyMlJxcXEaP368Hn74YWVkZCgkJMTnczbG134Go6aGNLUeX/rpz9fYUL/rJSYmqnfv3po9e7bOnj17Ufv7wl2vjarHk4utp6FeN3XPer58/9br2bOn5s6dqxkzZug///mPz+dszMX+PPa2Jh63AQAwpWZ3BQUAaBkIKACAKRFQAABTIqAAAKZEQAEATImAAv5nwIABro/KJiQkqKyszOiS/OLgwYN69tlnfTpm1KhRF9wjbd++fa67fQPBEmp0AYBZtGnTRmvXrm1wzul0yul0qlWr5vdvur59+6pv375GlwH4jIAC3CgrK9PUqVN144036ssvv9SiRYu0bds2ffjhh6qtrdVtt92mlJQUSdJrr72mv/71r+rSpYvCw8PVp08fJSUl6YEHHtC0adPUt29fVVZWKikpSZs3b5bD4dCyZcu0f/9+1dbWavz48Ro7dqz27dunV155ReHh4frmm2/Up08fzZ07VxaLRYWFhVq0aJFOnz6t1q1b6+WXX9Yjjzyi9PR0XX/99ZKke++9V48//rh+85vfuF7Hvn379MYbb+jFF1/UihUrdOzYMZWWlqq8vFx33323Jk6c6NPfy9SpU123sSktLVV6errrztWAPxFQwP/U1NQoISFBknTVVVfpscceU3FxsTIzMzVjxgzt2rVLJSUlWr16tZxOpx577DF98cUXuuyyy5Sbm6u1a9eqrq5OiYmJHm82u3HjRl1++eV6/fXXVVtbq+TkZA0cOFCSdPjwYa1fv14RERFKTk5WQUGBoqKiNHPmTM2fP19RUVE6deqU2rRpo/j4eG3ZskXXX3+9iouLdebMmQvCqSHFxcVavny5qqqqXA/VCw395Y+ClJQU1x0sqqqq1LNnT0nSkiVLJEn//Oc/NWfOHN16662+/DUDXiOggP/5+a/4ysrK1LVrV0VHR0uSdu3apV27dmnSpEmS5LrhZVVVlW677TaFhYVJOncvPU927dqlr7/+Wh999JGkc88RKikpUWhoqKKiolyP27juuutUVlamdu3a6Ve/+pXrnnz1d4yOi4vTq6++qkceeUSbNm3y6krmlltukdVqldVqVceOHfXf//73gsd71FuxYoXrUQj1V2H1KisrNXv2bD399NOGPU0Alz4CCmhEfehI596Hmjx5ssaOHXvBmrVr17p9HEZoaKjrnmvn38Xa6XQqPT1dgwYNumD9vn37ZLVaXV+3atVKDodDTqezwXOEhYXp5ptv1ieffKIPP/xQr7/+usfX1ND+vnA4HJo5c6buu+8+9erVy6djAV80v3d8AYMMGjRImzZtUlVVlaRzj8H4/vvvdcMNN+jjjz9WdXW1fvrpJ3366aeuY7p27ep63ML27dsv2GvDhg2uu1oXFxe7HmzXkJ49e6qiosL1ZN2ffvrJdWx8fLyee+459e3bVx06dPDvi27AsmXL1KtXLw0fPjzg50LLxhUU4KWBAwfq22+/dd2dum3btpo7d6569+6tO+64QwkJCeratav69+/vOiYpKUkzZsxQTk6ObrzxRtd4fHy8jh49qkmTJsnpdKpjx45atGiR23O3bt1a8+fP17PPPquamhq1adNGWVlZCg0NVZ8+fXT55Zdr1KhRAXvt51uzZo2uvfZa1/t1KSkpQXm8DVoe7mYO+NmKFSvUtm1bJSUlBeV8x48fV0pKijZs2NAsPwYPuMP/moFmbMuWLZo8ebJSU1MJJ1xyuIICAJgS/+QCAJgSAQUAMCUCCgBgSgQUAMCUCCgAgCn9P2lrREvt3FYrAAAAAElFTkSuQmCC\n" + }, + "metadata": {} + } + ], + "source": [ + "# remove devices from measurement chain by name\n", + "print(chain.list_devices())\n", + "chain.remove_device('Device 3')\n", + "print(chain.list_devices())\n", + "\n", + "# plot freq-response of whole measurement chain\n", + "fig1 = pyfar.plot.line.freq(chain.device_freq('Device 1'))\n", + "# invert ref-response and plot again\n", + "pyfar.plot.line.freq(chain.freq())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/home/alex/Git/pyfar-develop/pyfar/signal.py:507: UserWarning: Number of time samples not given, assuming an even number of samples from the number of frequency bins.\n warnings.warn(\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "measurement chain with 3 devices @ 48000 Hz sampling rate.\n", + "# 1: Device 1 defined by 24000 freq-bins, sensitivity=1.0\n", + "# 2: Device 2 defined by 24000 freq-bins, sensitivity=2.0\n", + "# 3: defined by 24000 freq-bins, sensitivity=1" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ], + "source": [ + "chain.add_device()\n", + "chain" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "['Device 1', 'Device 2', '']\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 7 + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-09T15:32:18.431976\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/png": "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uB5++GGtW7dOeXl5evPNN1VaWqoVK1aof//+euedd9S/f3+tWLHCsJpef/11XXPNNZ7HwajlmWee0aBBg/TWW2951g/GuiNHjtTixYsvGPO2bmlpqQoKCrR27VotXrxY8+bNk8vlCviYjQm0n0bUJPnfU3/rCaSfwXyODfXbLN56bbaf9rqpGup1sATy+2uEUL8eN7uAuvLKK9WrVy9J0iWXXKIePXrI6XSqsLBQI0aMkCSNGDFCH374oSH1VFZW6uOPP1ZiYqJnrKm1nDhxQv/4xz80atQoSVLr1q116aWXBuU53nDDDbrssssuGPO2bmFhoYYOHSq73a6uXbuqW7duKikpCfiYjQm0n0bUFEhP/akn0H4G8zk21O96Z8+eVXZ2tnJzcy9q7UB567VZ9UgN97op9XjrdVPWPF8gv7/n27ZtmyZPnqzq6uqLOq43TXk99qemZhdQ56uoqNCBAwfUt29ffffdd7ryyislnfuhHTt2zJAaFixYoClTpshms3nGmlpLeXm5IiMjNXv2bCUlJSknJ0c//vhjyJ6jt3WdTqc6derkmedwOC54QQk2f/ppRE2B9NSfegLtpxHP0eVy6bHHHlP37t2Vnp4e1LX9cX6vzaynoV43pR5vvW7Kmr74el344IMPtGLFCi1cuFCRkZFBO+5PBfJ67G9NzTagTp06paysLE2bNk3t27c3pYaPPvpIl19+uXr37h3UdV0ulw4cOKCxY8dq9erVatu2raGn7Y356S9ysDSln8GsKRg9bejFrqn9DPbPfe7cuYqOjlZqampQ1/VHQ702o57Gen2x9TTWazOe4549e7Ry5Uo9//zzXs+kgyGQ399AamqWAVVXV6esrCz9/ve/1+9+9ztJ0uWXX66qqipJUlVVlTp27BjyOoqLi1VUVKSRI0dq5syZ2rVrlx5//PEm1+JwOORwODz/uhwyZIj2798fsufobV2Hw6HKykrPPKfTqaioqKAc83yB9DPUNQXaU3/qCbSfRvzcf/Ob32jPnj06ffp0UNf1paFem1WPt143pR5vvW7Kmr409rrQtWtXnTp1SocOHQrqMc8X6OtxIDU1u4Byu9164okndM011yg5OdkzPnjwYG3atEmStGnTJg0ePDjktTzwwAPKz8/Xxo0bNWfOHP32t79VTk5Ok2u58sor1alTJ3377beSpJ07d+raa68N2XP0tm58fLwKCgpUW1ur8vJylZWVKSYmJijHrBdoP0NdU6A99aeeQPtpxM991KhRGjRokKZPn666urqgru2Nt16bVY+3XjelHm+9bsqavjT2utC5c2fNnz9f2dnZ+vrrr4N2zHoX83ocSE3NLqCKi4uVn5+vXbt2KSkpSUlJSdq2bZvuuusu7dixQ3fccYd27NihSZMmmVZjMGrJzMzU448/rgkTJuhf//qXJk+eHJR1Z8yYocmTJ+vgwYMaPny43n33Xa/rRkdHKyEhQePGjdODDz6orKwshYWFBXzMxgTaTyNqakhT6wmkn8F8jg31u15ycrJ69eqlWbNm6ezZsxe1fiC89dqseny52Hoa6nVT16wXyO9vvR49eignJ0fTp0/Xf/7zn4CP2ZiLfT32tyZutwEAsKRmdwYFAGgZCCgAgCURUAAASyKgAACWREABACyJgAL+p3///p6vyiYlJamiosLskoJi3759evrppwPaZ+TIkRdcI2337t2eq30DRgk3uwDAKtq0aaPVq1c3uM3tdsvtdqtVq+b3b7o+ffqoT58+ZpcBBIyAAryoqKjQlClTdOONN+rzzz/XggULtGXLFr333nuqra3VrbfeqrS0NEnSK6+8or/97W/q3LmzIiMj1bt3b6WkpOi+++7T1KlT1adPH1VXVyslJUUbN26Uy+XSkiVLtGfPHtXW1mrcuHEaM2aMdu/erZdeekmRkZH6+uuv1bt3b+Xk5Mhms6mkpEQLFizQjz/+qNatW+vFF1/UQw89pMzMTF1//fWSpLvvvluPPvqofv3rX3uex+7du/Xaa6/p+eef17Jly3TkyBGVl5ersrJSd955pyZMmBDQz2XKlCmey9iUl5crMzPTc+VqIJgIKOB/Tp8+raSkJEnSVVddpUceeUQHDx5Udna2pk+fru3bt6usrEwrV66U2+3WI488os8++0xt27ZVQUGBVq9erbq6OiUnJ/u82Oz69et1ySWX6NVXX1Vtba1SU1M1YMAASdKBAwe0du1aRUVFKTU1VcXFxYqJidGMGTM0d+5cxcTE6MSJE2rTpo0SExO1adMmXX/99Tp48KDOnDlzQTg15ODBg1q6dKlOnTrlualeePjPXwrS0tI8V7A4deqUevToIUlatGiRJOnLL7/U7NmzdcsttwTyYwb8RkAB//PTt/gqKirUpUsXxcbGSpK2b9+u7du3a+LEiZLkueDlqVOndOuttyoiIkLSuWvp+bJ9+3Z99dVXev/99yWdu49QWVmZwsPDFRMT47ndxnXXXaeKigq1b99eV1xxheeafPVXjE5ISNDLL7+shx56SBs2bPDrTObmm2+W3W6X3W5Xx44d9d///veC23vUW7ZsmedWCPVnYfWqq6s1a9YsPfnkk6bdTQC/fAQU0Ij60JHOfQ41adIkjRkz5oI5q1ev9no7jPDwcM81186/irXb7VZmZqYGDhx4wfzdu3fLbrd7Hrdq1Uoul0tut7vBY0REROimm27Shx9+qPfee0+vvvqqz+fU0PqBcLlcmjFjhu655x717NkzoH2BQDS/T3wBkwwcOFAbNmzQqVOnJJ27DcZ3332nG264QR988IFqamp08uRJffTRR559unTp4rndwtatWy9Ya926dZ6rWh88eNBzY7uG9OjRQ1VVVZ476548edKzb2Jiop555hn16dNHHTp0CO6TbsCSJUvUs2dPDRs2LOTHQsvGGRTgpwEDBuibb77xXJ26Xbt2ysnJUa9evXTbbbcpKSlJXbp0Ub9+/Tz7pKSkaPr06crPz9eNN97oGU9MTNThw4c1ceJEud1udezYUQsWLPB67NatW2vu3Ll6+umndfr0abVp00a5ubkKDw9X7969dckll2jkyJEhe+7nW7Vqla699lrP53VpaWmG3N4GLQ9XMweCbNmyZWrXrp1SUlIMOd7Ro0eVlpamdevWNcuvwQPe8LcZaMY2bdqkSZMmKT09nXDCLw5nUAAAS+KfXAAASyKgAACWREABACyJgAIAWBIBBQCwpP8H9AsoxWzebAYAAAAASUVORK5CYII=\n" + }, + "metadata": {} + } + ], + "source": [ + "print(chain.list_devices())\n", + "pyfar.plot.line.freq(chain.device_freq(''))" + ] + } + ], + "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.8.8-final" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file From b17de9f7b3a0a39fb511268993f6895edce6049a Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Fri, 12 Mar 2021 14:11:50 +0100 Subject: [PATCH 02/20] Implemented feedback --- mestopy/mestopy.py | 123 ++++++++++++++++++++++----------------------- mestopy_demo.ipynb | 72 +++++++++++--------------- 2 files changed, 87 insertions(+), 108 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 4843cca..6c0147a 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -3,15 +3,16 @@ # Class to generate ref-Objects, that can bei part of the MeasurementChain -class DeviceObj(object): +class Device(object): """Class for device in MeasurementChain. This class holds methods and properties of a device in the - 'MeasurementChain' class. + 'MeasurementChain' class. A device can be e.g., a sound card or a + pre-amplifier, described by a frequency response and/or sensitivity. """ - def __init__(self, data, sens=1, name=''): - """Init DeviceObj with data. + def __init__(self, name, data=None, sens=1, unit=None): + """Init Device with data. Attributes ---------- @@ -24,16 +25,29 @@ def __init__(self, data, sens=1, name=''): name : str Name of the device. """ + if not isinstance(name, str): + raise ValueError('Device name must be string.') + if not (isinstance(data, Signal) or data is None): + raise TypeError('Input data must be type Signal or None.') + if not (isinstance(unit, str) or unit is None): + raise ValueError('Unit of sensitivity must be string or None.') + if not isinstance(sens, (int, float)): + raise ValueError('Sensitivity must be a number (int or float).') self.sens = sens self.name = name self.data = data + self.unit = unit @property def freq(self): - """Return the frequency responses of the device, multiplied by - the sensitivity. + """Returns either a signal, representing the inverted frequency + response of the device multiplied by the sensitivity or the + sensitivity as scalar, when the device has no freqeuncy response. """ - return self.data * self.sens + if self.data is not None: + return self.data * self.sens + else: + return self.sens @property def device_name(self): @@ -47,13 +61,18 @@ def device_name(self, new_name): def __repr__(self): """String representation of DeviceObj class.""" - repr_string = ( - f"{self.name} defined by {self.data.n_bins} freq-bins, " - f"sensitivity={self.sens}\n") + if self.data is None: + repr_string = ( + f"{self.name} defined by None freq-bins, " + f"sensitivity={self.sens} unit={self.unit}\n") + else: + repr_string = ( + f"{self.name} defined by {self.data.n_bins} freq-bins, " + f"sensitivity={self.sens} unit={self.unit}\n") return repr_string -# Class for MeasurementChain as frame for RefObjs and calibration +# Class for MeasurementChain as frame for Devices class MeasurementChain(object): """Class for complete measurement chain. @@ -67,7 +86,7 @@ def __init__(self, sound_device=None, devices=[], comment=None): - """Init measurement chain with rampling rate. + """Init measurement chain with sampling rate. Attributes ---------- @@ -86,10 +105,19 @@ def __init__(self, self.devices = devices self.comment = comment + def __find_index(self, name): + """Private method to find the index of a given device name.""" + for i, dev in enumerate(self.devices): + if dev.name == name: + return i + raise ValueError(f"device {name} not found") + def add_device(self, + device_name, device_data=None, sens=1, - device_name=''): + unit=None + ): """Adds a new device to the measurement chain. Attributes @@ -113,34 +141,20 @@ def add_device(self, The name of the new device to add to the masurement chain. The default is an empty string. """ - if device_data is None: - device_data = Signal(np.full(int(self.sampling_rate/2), 1.0), - self.sampling_rate, - domain='freq') - # check if ref_signal is a pyfar.Signal, if not raise Error - if not isinstance(device_data, Signal): - raise TypeError('Input data must be of type: Signal.') + # check if device_data is type Signal or None + if not (isinstance(device_data, Signal) or device_data is None): + raise TypeError('Input data must be type Signal or None.') # check if there are no devices in measurement chain - if self.devices == []: - # add ref-measurement to chain - device_data.domain = 'freq' - new_device = DeviceObj(device_data, - sens, - device_name) - self.devices.append(new_device) - else: - # check if n_bins of all devices is the same - if not self.devices[0].data.n_bins == device_data.n_bins: - raise ValueError("ref_signal has wrong n_bins") + if not self.devices == []: # check if sampling_rate of new device and MeasurementChain # is the same - if not self.sampling_rate == device_data.sampling_rate: - raise ValueError("ref_signal has wrong samping_rate") - # add device to chain - new_device = DeviceObj(device_data, - sens, - device_name) - self.devices.append(new_device) + if device_data is not None: + if not self.sampling_rate == device_data.sampling_rate: + raise ValueError("ref_signal has wrong samping_rate") + # add device to chain + new_device = Device(device_name, data=device_data, + sens=sens, unit=unit) + self.devices.append(new_device) def list_devices(self): """Returns a list of names of all devices in the measurement chain. @@ -164,20 +178,10 @@ def remove_device(self, num): """ # remove ref-object in chain position num if isinstance(num, int): - front = self.devices[:num] - back = self.devices[num+1:] - for i in back: - front.append(i) - self.devices = front + self.devices.pop(num) # remove ref-object in chain by name elif isinstance(num, str): - i = 0 - for dev in self.devices: - if dev.name == num: - self.remove_device(i) - return - i = i + 1 - raise ValueError(f"device {num} not found") + self.remove_device(self.__find_index(num)) else: raise TypeError("device to remove must be int or str") @@ -201,18 +205,11 @@ def device_freq(self, num): in device list as int. """ if isinstance(num, int): - dev = self.devices[num].data * self.devices[num].sens - dev.domain = 'freq' - return dev + return self.devices[num].freq elif isinstance(num, str): - i = 0 - for dev in self.devices: - if dev.name == num: - return self.device_freq(i) - i = i + 1 - raise ValueError(f"device {num} not found") + return self.device_freq(self.__find_index(num)) else: - raise TypeError("device to remove must be int or str") + raise TypeError("Device must be called by int or str.") # get the freq-response of whole measurement chain as pyfar.Signal def freq(self): @@ -237,8 +234,6 @@ def __repr__(self): repr_string = ( f"measurement chain with {len(self.devices)} devices " f"@ {self.sampling_rate} Hz sampling rate.\n") - i = 1 - for dev in self.devices: - repr_string = f"{repr_string}# {i}: {dev}" - i += 1 + for i, dev in enumerate(self.devices): + repr_string = f"{repr_string}# {i:{2}}: {dev}" return repr_string diff --git a/mestopy_demo.ipynb b/mestopy_demo.ipynb index a2e397f..bb1d54a 100644 --- a/mestopy_demo.ipynb +++ b/mestopy_demo.ipynb @@ -49,27 +49,19 @@ "name": "stdout", "text": [ "measurement chain with 4 devices @ 48000 Hz sampling rate.\n", - "# 1: Device 1 defined by 24000 freq-bins, sensitivity=1.0\n", - "# 2: Device 1 defined by 24000 freq-bins, sensitivity=1.0\n", - "# 3: Device 2 defined by 24000 freq-bins, sensitivity=2.0\n", - "# 4: Device 3 defined by 24000 freq-bins, sensitivity=0.5\n", + "# 0: Device 1 defined by 24000 freq-bins, sensitivity=1.0 unit=None\n", + "# 1: Device 1 defined by 24000 freq-bins, sensitivity=1.0 unit=None\n", + "# 2: Device 2 defined by 24000 freq-bins, sensitivity=2.0 unit=None\n", + "# 3: Device 3 defined by 24000 freq-bins, sensitivity=0.5 unit=None\n", "\n", "['Device 1', 'Device 1', 'Device 2', 'Device 3']\n", "['Device 1', 'Device 2', 'Device 3']\n", + "freq domain energy Signal:\n", + "(1,) channels with 47998 samples @ 48000 Hz sampling rate and none FFT normalization\n", + "\n", "/home/alex/Git/pyfar-develop/pyfar/signal.py:507: UserWarning: Number of time samples not given, assuming an even number of samples from the number of frequency bins.\n", " warnings.warn(\n" ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "freq domain energy Signal:\n", - "(1,) channels with 47998 samples @ 48000 Hz sampling rate and none FFT normalization" - ] - }, - "metadata": {}, - "execution_count": 3 } ], "source": [ @@ -80,10 +72,10 @@ "sig = pyfar.Signal(np.full(int(fs/2), 1.0), fs, domain='freq')\n", "\n", "# add these signals as devices to the measurement chain; attention: Device 1 is added twice by \"mistake\"\n", - "chain.add_device(sig, sens=1.0, device_name='Device 1') \n", - "chain.add_device(sig, sens=1.0, device_name='Device 1')\n", - "chain.add_device(sig, sens=2.0, device_name='Device 2')\n", - "chain.add_device(sig, sens=0.5, device_name='Device 3')\n", + "chain.add_device('Device 1', sig, sens=1.0) \n", + "chain.add_device('Device 1', sig, sens=1.0)\n", + "chain.add_device('Device 2', sig, sens=2.0)\n", + "chain.add_device('Device 3', sig, sens=0.5)\n", "\n", "# print measurement chain __repr__\n", "print(chain)\n", @@ -101,7 +93,7 @@ "chain.freq()\n", "\n", "# get the freq-response of specific device in measurement chain as pyfar.Signal\n", - "chain.device_freq(1)" + "print(chain.device_freq(1))" ] }, { @@ -123,7 +115,7 @@ "output_type": "display_data", "data": { "text/plain": "
", - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-09T15:32:17.204006\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T17:35:02.018323\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", "image/png": "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P/6o9PR0jRo1SqNHj9YXX3zhk33nzZunO+64Q3fffbdzrK59s7OzlZCQoJEjR2rHjh1en8+d+vTT3zVJ3vXUk3q87aevHmNt/X7wwQd14MCBeu9ZX656Hax6zvtlrxtaT2299tVj9Obnd9OmTXrqqacafM66ePvz621NjS6gQkND9cgjj2j9+vXKzs7W22+/raKiIq1cuVK9e/fWu+++q969e2vlypUBq+nNN9/U9ddf7/zaF7U888wz6tevn9555x3n/r7Yd/jw4Vq6dOlFY672LSoqUm5urtatW6elS5dq4cKFstvtXp+zLt72MxA1SZ731NN6vOmnLx9jbf0OFle9DrZf9rqhauu1r3jz8xsI/n4+bnQBdfXVV6tr166SpMsvv1ydOnWSzWZTXl6ehg0bJkkaNmyYPv7444DUc+zYMX366adKSEhwjjW0llOnTukf//iHRowYIUlq3ry5Wrdu7ZPHePPNN+uKK664aMzVvnl5eRo8eLCsVqs6dOigqKgoFRYWen3Ounjbz0DU5E1PPanH23768jHW1u/zzp07p4yMDGVlZdVrb2+56nWw6pFq73VD6nHV64bseSFvfn4vtH37dk2aNEkVFRX1Oq8rDXk+9qSmRhdQFyorK9OhQ4fUo0cPff/997r66qsl/fxNO3HiREBqWLx4saZMmSKLxeIca2gtpaWlCg8P17x585SYmKjMzEz99NNPfnuMrva12Wy65pprnOsiIyMvekLxNU/6GYiavOmpJ/V4289APEa73a7Zs2erY8eOSklJ8enenriw18Gsp7ZeN6QeV71uyJ7uuHte+Oijj7Ry5Uq98MILCg8P99l5f8mb52NPa2q0AVVZWan09HRNnz5drVq1CkoNn3zyia688kp169bNp/va7XYdOnRIo0eP1po1a3TZZZcF9LK9Lr/8QfaVhvTTlzX5oqe1Pdk1tJ++/r4vWLBA0dHRSkpK8um+nqit18Gop65e17eeunodjMe4b98+rVq1Ss8//7zLK2lf8Obn15uaGmVAnT17Vunp6fr973+v22+/XZJ05ZVXqry8XJJUXl6utm3b+r2OgoIC5efna/jw4Zo1a5b27NmjOXPmNLiWyMhIRUZGOv91OWjQIB08eNBvj9HVvpGRkTp27Jhznc1mU0REhE/OeSFv+unvmrztqSf1eNvPQHzfb7rpJu3bt0/V1dU+3ded2nodrHpc9boh9bjqdUP2dKeu54UOHTqosrJShw8f9uk5L+Tt87E3NTW6gHI4HHriiSd0/fXXa/z48c7xgQMHavPmzZKkzZs3a+DAgX6v5aGHHlJOTo42bdqk+fPn63e/+50yMzMbXMvVV1+ta665Rt99950kaffu3ercubPfHqOrfePi4pSbm6uamhqVlpaqpKREMTExPjnned720981edtTT+rxtp+B+L6PGDFC/fr104wZM3T27Fmf7u2Kq14Hqx5XvW5IPa563ZA93anreaFdu3ZatGiRMjIy9M033/jsnOfV5/nYm5oaXUAVFBQoJydHe/bsUWJiohITE7V9+3bde++92rVrl+666y7t2rVLEydODFqNvqglLS1Nc+bM0dixY/Wvf/1LkyZN8sm+M2fO1KRJk1RcXKyhQ4fqvffec7lvdHS04uPjNWbMGD388MNKT09XSEiI1+esi7f9DERNtWloPd7005ePsbZ+nzd+/Hh17dpVc+fO1blz5+q1vzdc9TpY9bhT33pq63VD9zzPm5/f8zp16qTMzEzNmDFD//nPf7w+Z13q+3zsaU183AYAwEiN7goKANA0EFAAACMRUAAAIxFQAAAjEVAAACMRUMD/9O7d2/lW2cTERJWVlQW7JJ84cOCAnn76aa+OGT58+EX3SNu7d6/zbt9AoIQGuwDAFC1atNCaNWtqnXM4HHI4HGrWrPH9m6579+7q3r17sMsAvEZAAS6UlZVpypQp6tWrl7744gstXrxYW7du1QcffKCamhrddtttSk5OliS9+uqrev/999WuXTuFh4erW7dumjBhgh588EFNmzZN3bt3V0VFhSZMmKBNmzbJbrfrxRdf1L59+1RTU6MxY8Zo1KhR2rt3r/7yl78oPDxc33zzjbp166bMzExZLBYVFhZq8eLF+umnn9S8eXO9/PLLmjp1qtLS0nTjjTdKku677z49/vjj+u1vf+t8HHv37tUbb7yh559/XsuXL9fRo0dVWlqqY8eO6Z577tHYsWO9+r5MmTLFeRub0tJSpaWlOe9cDfgSAQX8T3V1tRITEyVJ1157rR599FEVFxcrIyNDM2bM0M6dO1VSUqJVq1bJ4XDo0Ucf1eeff67LLrtMubm5WrNmjc6ePavx48e7vdnshg0bdPnll+v1119XTU2NkpKS1KdPH0nSoUOHtG7dOkVERCgpKUkFBQWKiYnRzJkztWDBAsXExOjUqVNq0aKFEhIStHnzZt14440qLi7WmTNnLgqn2hQXF2vZsmWqrKx0fqheaOivnwqSk5Odd7CorKxUp06dJElLliyRJH311VeaN2+ebr31Vm++zYDHCCjgf375K76ysjK1b99esbGxkqSdO3dq586dGjdunCQ5b3hZWVmp2267TWFhYZJ+vpeeOzt37tTXX3+tDz/8UNLPnyNUUlKi0NBQxcTEOD9u44YbblBZWZlatWqlq666ynlPvvN3jI6Pj9crr7yiqVOnauPGjR5dyfTv319Wq1VWq1Vt27bVf//734s+3uO85cuXOz8K4fxV2HkVFRWaO3eunnzyyaB9mgAufQQUUIfzoSP9/DrUxIkTNWrUqIvWrFmzxuXHYYSGhjrvuXbhXawdDofS0tLUt2/fi9bv3btXVqvV+XWzZs1kt9vlcDhqPUdYWJhuueUWffzxx/rggw/0+uuvu31Mte3vDbvdrpkzZ+r+++9Xly5dvDoW8Ebje8UXCJK+fftq48aNqqyslPTzx2B8//33uvnmm/XRRx+pqqpKp0+f1ieffOI8pn379s6PW9i2bdtFe61fv955V+vi4mLnB9vVplOnTiovL3d+su7p06edxyYkJOiZZ55R9+7d1aZNG98+6Fq8+OKL6tKli4YMGeL3c6Fp4woK8FCfPn307bffOu9O3bJlS2VmZqpr16664447lJiYqPbt26tnz57OYyZMmKAZM2YoJydHvXr1co4nJCToyJEjGjdunBwOh9q2bavFixe7PHfz5s21YMECPf3006qurlaLFi2UlZWl0NBQdevWTZdffrmGDx/ut8d+odWrV6tz587O1+uSk5MD8vE2aHq4mzngY8uXL1fLli01YcKEgJzv+PHjSk5O1vr16xvl2+ABV/i/GWjENm/erIkTJyolJYVwwiWHKygAgJH4JxcAwEgEFADASAQUAMBIBBQAwEgEFADASP8Pn6aMjIP9RicAAAAASUVORK5CYII=\n" }, "metadata": {} @@ -166,7 +158,7 @@ "output_type": "display_data", "data": { "text/plain": "
", - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-09T15:32:17.855719\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T17:35:02.673313\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", "image/png": "iVBORw0KGgoAAAANSUhEUgAAAagAAAEYCAYAAAAJeGK1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAewElEQVR4nO3df1RUdf7H8dcIjmSm2Mqoma6FWyqyx2+nTI2DlaSbR1fy1zGEk0bFWSqzBNa0ZM3VzLLyR6RZi2aZmf3wx3JWzAqy/N0uJa7uFoUsKCObWIaAjPP9w2WOFsPMyMzcizwf53SOfD6f+7nv8b3w8jKz91qcTqdTAACYTCujCwAAoCEEFADAlAgoAIApEVAAAFMioAAAphRqdAH+MGTIEPXo0cOve546dUrt2rULyrHerPe0prF5d3O+jhslEPXQX/rrj2O9XRus/jbX3paVlWn79u2/nHBeAkaPHu33PfPy8oJ2rDfrPa1pbN7dnK/jRglEPfTXPJpzf71dG6z+NtfeJiYmNjjOr/gAAKZEQAEATImAAgCYEgEFADAlAgoAYEoEFADAlAgoAIApEVAAAFMioAAApkRAAQBMiYACAJgSAQUAMCUCCgBgSgQUAMCUCCgAgCkRUAAAUyKgAACmREABAEyJgAIAmFKo0QX4g6WuTrVHvvXrniEV5Re9p6/HerPe05rG5t3N+TpulEDUQ3/prz+O9XZtsPp7qfXW4nQ6nX6sxxDjb/o//TnstNFlAAAuwp973qQ1a9b8YvySuIJyXNlJXdOm+nXPQ4cOqXfv3kE51pv1ntY0Nu9uztdxowSiHvpLf/1xrLdrg9XfZtvb19c3OHxJBNTZyy5X+ztG+XXP6jYd1D42NijHerPe05rG5t3N+TpulEDUQ3/prz+O9XZtsPrbbHvrJqD4kAQAwJQIKACAKRFQAABTIqAAAKZEQAEATImAAgCYEgEFADAlAgoAYEqmDajPP/9cY8aMUXx8vFatWmV0OQCAIDNlQDkcDj3zzDNasmSJ3nnnHW3dulVFRUVGlwUACCJT3iz2yy+/1CuvvKJly5ZJkrKzsyVJU6ZMaXD9TUNHq9PvZ/q1hh9++EHt27cPyrHerPe0prF5d3O+jhslEPXQX/rrj2O9XRus/jbX3nbat6z53CzWbrerc+fOrq9tNpsOHDjgdr3TeVZnTv/o1xrqqk/pTGtLUI71Zr2nNY3Nu5vzddwogaiH/tJffxzr7dpg9feS663ThLZt2+Z86qmnXF9v2bLF+cwzz7hdP3r0aL/XkJeXF7RjvVnvaU1j8+7mfB03SiDqob/m0Zz76+3aYPW3ufY2MTGxwXFTvgdls9lUXl7u+tputysiIsLAigAAwWbKgOrbt69KSkpUWlqqM2fOKDc3V7EmuoU8ACDwTPkeVGhoqNLT0/Xwww/L4XDo97//vSIjI40uCwAQRKYMKEmKiYlRTEyM0WUAAAxiyl/xAQBAQAEATImAAgCYEgEFADAlAgoAYEoEFADAlAgoAIApEVAAAFMioAAApkRAAQBMiYACAJgSAQUAMCUCCgBgSgQUAMCUCCgAgCkRUAAAUyKgAACmREABAEyJgAIAmBIBBQAwJQIKAGBKBBQAwJQIKACAKRFQAABTIqAAAKZEQAEATImAAgCYEgEFADAlAgoAYEoEFADAlAgoAIApEVAAAFMioAAApkRAAQBMiYACAJhSqBEnXbx4sfLz89W6dWtdffXVyszM1BVXXCFJys7O1saNG9WqVSulp6dr0KBBRpQIADCYIVdQN998s95++22tW7dOPXr0UHZ2tiSpqKhIubm5Wr9+vZYuXaoFCxbI4XAYUSIAwGA+BVRlZaWcTmeTTzpw4ECFhp67eIuOjpbdbpck5eXladiwYbJarerWrZu6d++uwsLCJp8PAND8uP0V31dffaWlS5eqQ4cOSk5O1uzZs3Xy5EmdPXtWc+bM0eDBg/1SwKZNm3THHXdIkux2u6Kjo11zNpvNFV6Nqa6uVn5+vl/qqVdQUBC0Y71Z72lNY/Pu5nwdN0og6qG/5tGc++vt2mD191LrrduAWrhwoR588EGdOnVKf/jDH7RkyRJFR0fru+++08yZMz0GVGpqqioqKhocv/XWWyVJr732mkJCQnTnnXe63cdisXh8EWFhYYqNjfW4zldN2dPXY71Z72lNY/Pu5nwdNwr9pb/B3NOXY71dG6z+Nsferly5ssFxtwHlcDg0cOBASdLy5ctdVzY9e/b0qqisrKxG57ds2aIdO3bo5ZdfdoWQzWZTeXm5a43dbldERIRX5wMAXFrcvgd1/pVLmzZt3M5djM8//1yrV6/W888/r7CwMNd4bGyscnNzVVtbq9LSUpWUlCgqKqpJ5wIANE9ur6D+/e9/a8iQIXI6naqpqdGQIUMkyfV1UyxcuFBnzpzRgw8+KEnq16+fZs6cqcjISMXFxWn8+PEKCQlRRkaGQkJCmnQuAEDz5Dag9uzZE7CTfvDBB27nkpOTlZycHLBzAwCaB7cBdfLkyUYP7NChg9+LAQCgntuASkpKksVikdPp1LFjx1x3evjxxx/VpUsXbdq0KWhFAgBaHrcBVR9A8+fPV2xsrGJiYiRJn332WUB//QcAgOTFnSQOHjzoCidJuuWWW/TFF18EtCgAADzeLDY8PFyvvvqqRowYIYvFopycHN5/AgAEnMcrqHnz5qmyslJpaWlKS0tTZWWl5s2bF4zaAAAtmMcrqA4dOigtLS0YtQAA4MIDCwEApkRAAQBMiYACAJiSx/egTpw4offff19Hjx5VXV2dazwzMzOghQEAWjaPATV9+nT1799fAwYMUKtWXHABAILDY0BVV1dr6tSpwagFAAAXj5dEMTEx2rFjRzBqAQDAxeMV1Lp165SdnS2r1arQ0FA5nU5ZLBbl5eUFoz4AQAvlMaDy8/ODUQcAABdwG1DfffedevbsqUOHDjU437t374AVBQCA24B68803NWvWLL3wwgu/mLNYLFq+fHlACwMAtGxuA2rWrFmSpBUrVgStGAAA6vF/bAIAmBIBBQAwJQIKAGBKHgPK6XQqJydHK1eulCQdO3ZMBw4cCHhhAICWzWNALViwQF999ZW2bt0qSWrbtq0WLlwY8MIAAC2bx4A6cOCA/vjHP8pqtUqS2rdvrzNnzgS8MABAy+YxoEJDQ+VwOGSxWCSde/xG/Z8BAAgUj7c6mjhxotLS0nTixAm99NJL2r59u1JTU4NRGwCgBfMYUHfeeaf69OmjPXv2yOl0atGiRbrmmmuCURsAoAVzG1AnT550/bljx44aPnz4BXMdOnQIbGUAgBbNbUAlJSXJYrHI6XTq2LFjuuKKKyRJP/74o7p06aJNmzYFrUgAQMvjNqDqA2j+/PmKjY1VTEyMJOmzzz7Tnj17glMdAKDF8vgpvoMHD7rCSZJuueUWffHFFwEtCgAAjx+SCA8P16uvvqoRI0bIYrEoJyeH958AAAHn8Qpq3rx5qqysVFpamqZPn64TJ05o3rx5wagNANCCebyC6tChg9LS0oJRCwAALh4DKiUlpcE7R/BEXQBAIHkMqGnTprn+XFNTo48++kghISF+OfmaNWu0ePFiffjhhwoPD5ckZWdna+PGjWrVqpXS09M1aNAgv5wLANC8eAyoPn36XPB1//799cADDzT5xMeOHdPu3bvVpUsX11hRUZFyc3O1fv16HT9+XKmpqXrvvff8FogAgObD44ckTp486fqvsrJSO3fuVEVFRZNP/Pzzz2vq1KkX/PowLy9Pw4YNk9VqVbdu3dS9e3cVFhY2+VwAgObH4xXU+XeUCAkJ0VVXXaXZs2c36aR5eXmy2Wy67rrrLhi32+2Kjo52fW2z2WS32z3uV11drfz8/CbV9HMFBQVBO9ab9Z7WNDbvbs7XcaMEoh76ax7Nub/erg1Wfy+13noMqHfeeUdt2rS5YKy2ttbjxqmpqQ1eaaWmpio7O1svvfSSVwV682iPsLAwxcbGerWfL5qyp6/HerPe05rG5t3N+TpuFPpLf4O5py/Hers2WP1tjr2tf2L7z3kMqHvvvVdvvvnmBWNTpkz5xdjPZWVlNTj+9ddfq6ysTHfffbekc1dNkyZN0urVq2Wz2VReXu5aa7fbFRER4alEAMAlyG1AVVRU6Pjx46qpqdGhQ4dc46dOnVJ1dfVFn7BXr17atm2b6+tRo0ZpzZo1Cg8PV2xsrJ544glNmjRJx48fV0lJiaKioi76XACA5sttQO3atUubN2+W3W7XCy+84Bpv27atHnzwwYAUExkZqbi4OI0fP14hISHKyMjgE3wA0EK5DaiRI0dq5MiR2r59u4YOHRqwAjZv3nzB18nJyUpOTg7Y+QAAzYPbgMrJydGIESN09OhRvfHGG7+YT0xMDGhhAICWzW1AnT59WpJUVVUVtGIAAKjnNqDGjh0rSX65awQAAL7y+DHzEydO6P3339fRo0dVV1fnGs/MzAxoYQCAls1jQE2fPl39+/fXgAED1KqVxzsjAQDgFx4Dqrq6WlOnTg1GLQAAuHi8JIqJidGOHTuCUQsAAC4er6DWrVun7OxsWa1WhYaGyul0ymKxKC8vLxj1AQBaKI8B5e+7hAMA4A2PAXX+ffjqtWvXTl26dFFoqMfDAQC4KB4TZsGCBTp06JB69eol6dzdyK+77jqdPHlSjz/+uAYOHBjwIgEALY/HgOratauefPJJRUZGSjr3WPY1a9YoOTlZGRkZBBQAICA8foqvuLjYFU6SdO211+rw4cO6+uqrA1oYAKBl83gF9etf/1pPP/20hg0bJknatm2bevToodraWt6DAgAEjMeEyczM1IYNG/TWW2/J6XSqf//+mjZtmkJDQ7V8+fJg1AgAaIE8BlRYWJgSExMbfLxG27ZtA1IUAAAeA+rIkSNatmyZvv32W9XW1rrGN27cGNDCAAAtm8cPScyZM0fjxo1TSEiIli9frhEjRmjEiBHBqA0A0IJ5DKiamhoNGDBATqdTXbt2VUpKivbu3RuM2gAALZjHX/FZrVadPXtWPXr00Ntvvy2bzabvv/8+GLUBAFowj1dQ06dPV3V1tdLS0nTo0CHl5ORozpw5wagNANCCebyCioqKknTuE3s8RRcAECxuA+rRRx9t9MAXXnjB78UAAFDPbUB99dVX6ty5s4YPH65+/frJ6XQGsy4AQAvnNqC2bt2q3bt3a+vWrfrb3/6mmJgYDR8+/IL78gEAEChuAyokJESDBw/W4MGDVVtbq61btyolJUX33XefJk6cGMwaAQAtUKMfkqitrdWOHTu0detWHT16VBMnTtTtt98erNoAAC2Y24DKzMzUN998o8GDB+v+++93PbAQAIBgcBtQOTk5uuyyy3TkyBG9/fbbrnGn0ymLxaK8vLygFAgAaJncBhS3MwIAGMnjnSQAADACAQUAMCUCCgBgSgQUAMCUCCgAgCkZFlDr1q3TmDFjNGHCBC1evNg1np2drfj4eI0ZM0Y7d+40qjwAgME8Pm4jEPbt26f8/HytW7dOVqvV9QDEoqIi5ebmav369Tp+/LhSU1P13nvvKSQkxIgyAQAGMuQKasOGDbrnnntktVolSVdeeaUkKS8vT8OGDZPValW3bt3UvXt3FRYWGlEiAMBghlxBHTlyRP/4xz+UlZWlNm3a6JFHHlFUVJTsdruio6Nd62w2m+x2u8f9qqurlZ+f79caCwoKgnasN+s9rWls3t2cr+NGCUQ99Nc8mnN/vV0brP5ear0NWEClpqaqoqKiwfG6ujr98MMPWrVqlQoLC/X4449r48aNDe5jsVg8nissLEyxsbFNrvnnmrKnr8d6s97Tmsbm3c35Om4U+kt/g7mnL8d6uzZY/W2OvV25cmWD4wELqKysLLdz7777rm677TZZLBb169dPFotFlZWVstlsKi8vd62z2+2KiIgIVIkAABMz5D2oIUOGaN++fZKk4uJi1dXVKTw8XLGxscrNzVVtba1KS0tVUlKiqKgoI0oEABjMkPegRo8eraeeekoTJkxQ69at9ac//UkWi0WRkZGKi4vT+PHjFRISooyMDD7BBwAtlCEB1bp1a82dO7fBueTkZCUnJwe5IgCA2XAnCQCAKRFQAABTIqAAAKZEQAEATImAAgCYEgEFADAlAgoAYEoEFADAlAgoAIApEVAAAFMioAAApkRAAQBMiYACAJgSAQUAMCUCCgBgSgQUAMCUCCgAgCkRUAAAUyKgAACmREABAEyJgAIAmBIBBQAwJQIKAGBKBBQAwJQIKACAKRFQAABTIqAAAKZEQAEATImAAgCYEgEFADAlAgoAYEoEFADAlAgoAIApEVAAAFMioAAApmRIQB0+fFiTJ09WQkKCkpKSdODAAddcdna24uPjNWbMGO3cudOI8gAAJmBIQC1ZskT333+/1q5dq5SUFC1ZskSSVFRUpNzcXK1fv15Lly7VggUL5HA4jCgRAGAwQwLKYrHop59+kiSdOnVKERERkqS8vDwNGzZMVqtV3bp1U/fu3VVYWGhEiQAAg4UacdLp06froYce0uLFi3X27Fn95S9/kSTZ7XZFR0e71tlsNtntdiNKBAAYLGABlZqaqoqKigbH9+7dq8cee0xDhw7Vtm3bNHfuXGVlZTW4j8Vi8Xiu6upq5efnN7nm8xUUFATtWG/We1rT2Ly7OV/HjRKIeuiveTTn/nq7Nlj9vdR6G7CAchc4kpSZmam0tDRJUlxcnP785z9LOnfFVF5e7lpnt9tdv/5rTFhYmGJjY5tY8S81ZU9fj/Vmvac1jc27m/N13Cj0l/4Gc09fjvV2bbD62xx7u3LlygbHDXkPKiIiQvv375ck7d27V927d5d07oXk5uaqtrZWpaWlKikpUVRUlBElAgAMZsh7UE888YSee+45ORwOWa1WzZo1S5IUGRmpuLg4jR8/XiEhIcrIyFBISIgRJQIADGZIQPXv319vvPFGg3PJyclKTk4OckUAALPhThIAAFMioAAApkRAAQBMiYACAJgSAQUAMCUCCgBgSgQUAMCUCCgAgCkRUAAAUyKgAACmREABAEyJgAIAmBIBBQAwJQIKAGBKBBQAwJQIKACAKRFQAABTsjidTqfRRTTV0KFDddVVVxldBgDgIpSVlWn79u2/GL8kAgoAcOnhV3wAAFMioAAApkRAAQBMiYACAJgSAQUAMCUCCgBgSs0uoI4dO6aUlBSNGzdOEyZM0FtvvSVJOnnypFJTU3XXXXcpNTVVP/zwQ9BqcjgcSkhI0LRp0/xWy48//qiMjAyNHTtW48aN05dffumXfefMmaM77rhDEyZMcI01tm92drbi4+M1ZswY7dy50+fzeXIx/Qx0TZJvPfWmHl/76a/X2FC/H3jgAR08ePCi97xY7nptVD31ft7rptbTUK/99Rp9+f7dvHmznnnmmSafszG+fv/6WlOzC6jQ0FA9+uij2rBhg7Kzs/XOO++oqKhIq1at0oABA/T+++9rwIABWrVqVdBqeuutt3TNNde4vvZHLc8995wGDx6sd99917W/P/YdNWqUli5desGYu32LioqUm5ur9evXa+nSpVqwYIEcDofP52yMr/0MRk2S9z31th5f+unP19hQv43irtdG+3mvm6qhXvuLL9+/wRDon8fNLqA6deqk3r17S5Iuv/xy9ezZU3a7XXl5eRo5cqQkaeTIkfrkk0+CUk95ebk+++wzxcfHu8aaWsupU6f097//XaNHj5YktW7dWldccYVfXuMNN9yg9u3bXzDmbt+8vDwNGzZMVqtV3bp1U/fu3VVYWOjzORvjaz+DUZMvPfWmHl/76c/X2FC/6509e1aZmZnKysq6qL195a7XRtUjNdzrptTjrtdN2fN8vnz/nm/Hjh2aMmWKKisrL+q87jTl57E3NTW7gDpfWVmZDh8+rH79+un7779Xp06dJJ37Sztx4kRQali0aJGmTp0qi8XiGmtqLaWlpQoPD9ecOXOUkJCguXPn6vTp0wF7je72tdvt6ty5s2udzWa74AeKv3nTz2DU5EtPvanH134G4zU6HA498cQT6tGjh1JTU/26tzfO77WR9TTU66bU467XTdnTE08/Fz7++GOtWrVKixcvVnh4uN/O+3O+/Dz2tqZmG1BVVVXKyMjQ9OnT1a5dO0Nq+PTTT3XllVeqT58+ft3X4XDo8OHDGjdunNauXavLLrssqJftjfn5N7K/NKWf/qzJHz1t6IddU/vp77/3+fPnKzIyUsnJyX7d1xsN9dqIehrr9cXW01ivjXiN+/fv1+rVq/Xiiy+6vZL2B1++f32pqVkGVF1dnTIyMvS73/1Ot99+uyTpyiuvVEVFhSSpoqJCHTt2DHgdBQUFys/P16hRozRr1izt3btXTz75ZJNrsdlsstlsrn9dDh06VIcOHQrYa3S3r81mU3l5uWud3W5XRESEX855Pl/6GeiafO2pN/X42s9g/L3/9re/1f79+1VTU+PXfT1pqNdG1eOu102px12vm7KnJ439XOjWrZuqqqp05MgRv57zfL7+PPalpmYXUE6nU0899ZSuueYaJSYmusaHDBmiLVu2SJK2bNmiIUOGBLyWhx56SDk5Odq8ebPmzZunm266SXPnzm1yLZ06dVLnzp313XffSZL27Nmja6+9NmCv0d2+sbGxys3NVW1trUpLS1VSUqKoqCi/nLOer/0MdE2+9tSbenztZzD+3kePHq3BgwdrxowZqqur8+ve7rjrtVH1uOt1U+px1+um7OlJYz8XunTpooULFyozM1PffPON385Z72J+HvtSU7MLqIKCAuXk5Gjv3r1KSEhQQkKCduzYoXvuuUe7d+/WXXfdpd27d2vy5MmG1eiPWtLT0/Xkk09q4sSJ+te//qUpU6b4Zd+ZM2dqypQpKi4u1ogRI/TBBx+43TcyMlJxcXEaP368Hn74YWVkZCgkJMTnczbG134Go6aGNLUeX/rpz9fYUL/rJSYmqnfv3po9e7bOnj17Ufv7wl2vjarHk4utp6FeN3XPer58/9br2bOn5s6dqxkzZug///mPz+dszMX+PPa2Jh63AQAwpWZ3BQUAaBkIKACAKRFQAABTIqAAAKZEQAEATImAAv5nwIABro/KJiQkqKyszOiS/OLgwYN69tlnfTpm1KhRF9wjbd++fa67fQPBEmp0AYBZtGnTRmvXrm1wzul0yul0qlWr5vdvur59+6pv375GlwH4jIAC3CgrK9PUqVN144036ssvv9SiRYu0bds2ffjhh6qtrdVtt92mlJQUSdJrr72mv/71r+rSpYvCw8PVp08fJSUl6YEHHtC0adPUt29fVVZWKikpSZs3b5bD4dCyZcu0f/9+1dbWavz48Ro7dqz27dunV155ReHh4frmm2/Up08fzZ07VxaLRYWFhVq0aJFOnz6t1q1b6+WXX9Yjjzyi9PR0XX/99ZKke++9V48//rh+85vfuF7Hvn379MYbb+jFF1/UihUrdOzYMZWWlqq8vFx33323Jk6c6NPfy9SpU123sSktLVV6errrztWAPxFQwP/U1NQoISFBknTVVVfpscceU3FxsTIzMzVjxgzt2rVLJSUlWr16tZxOpx577DF98cUXuuyyy5Sbm6u1a9eqrq5OiYmJHm82u3HjRl1++eV6/fXXVVtbq+TkZA0cOFCSdPjwYa1fv14RERFKTk5WQUGBoqKiNHPmTM2fP19RUVE6deqU2rRpo/j4eG3ZskXXX3+9iouLdebMmQvCqSHFxcVavny5qqqqXA/VCw395Y+ClJQU1x0sqqqq1LNnT0nSkiVLJEn//Oc/NWfOHN16662+/DUDXiOggP/5+a/4ysrK1LVrV0VHR0uSdu3apV27dmnSpEmS5LrhZVVVlW677TaFhYVJOncvPU927dqlr7/+Wh999JGkc88RKikpUWhoqKKiolyP27juuutUVlamdu3a6Ve/+pXrnnz1d4yOi4vTq6++qkceeUSbNm3y6krmlltukdVqldVqVceOHfXf//73gsd71FuxYoXrUQj1V2H1KisrNXv2bD399NOGPU0Alz4CCmhEfehI596Hmjx5ssaOHXvBmrVr17p9HEZoaKjrnmvn38Xa6XQqPT1dgwYNumD9vn37ZLVaXV+3atVKDodDTqezwXOEhYXp5ptv1ieffKIPP/xQr7/+usfX1ND+vnA4HJo5c6buu+8+9erVy6djAV80v3d8AYMMGjRImzZtUlVVlaRzj8H4/vvvdcMNN+jjjz9WdXW1fvrpJ3366aeuY7p27ep63ML27dsv2GvDhg2uu1oXFxe7HmzXkJ49e6qiosL1ZN2ffvrJdWx8fLyee+459e3bVx06dPDvi27AsmXL1KtXLw0fPjzg50LLxhUU4KWBAwfq22+/dd2dum3btpo7d6569+6tO+64QwkJCeratav69+/vOiYpKUkzZsxQTk6ObrzxRtd4fHy8jh49qkmTJsnpdKpjx45atGiR23O3bt1a8+fP17PPPquamhq1adNGWVlZCg0NVZ8+fXT55Zdr1KhRAXvt51uzZo2uvfZa1/t1KSkpQXm8DVoe7mYO+NmKFSvUtm1bJSUlBeV8x48fV0pKijZs2NAsPwYPuMP/moFmbMuWLZo8ebJSU1MJJ1xyuIICAJgS/+QCAJgSAQUAMCUCCgBgSgQUAMCUCCgAgCn9P2lrREvt3FYrAAAAAElFTkSuQmCC\n" }, "metadata": {} @@ -190,29 +182,21 @@ "metadata": {}, "outputs": [ { - "output_type": "stream", - "name": "stderr", - "text": [ - "/home/alex/Git/pyfar-develop/pyfar/signal.py:507: UserWarning: Number of time samples not given, assuming an even number of samples from the number of frequency bins.\n warnings.warn(\n" + "output_type": "error", + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'sampling_rate'", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mchain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_device\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'new device'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mchain\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/Git/mestopy-master/mestopy/mestopy/mestopy.py\u001b[0m in \u001b[0;36madd_device\u001b[0;34m(self, device_name, device_data, sens, unit)\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0;31m# check if sampling_rate of new device and MeasurementChain\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 147\u001b[0m \u001b[0;31m# is the same\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 148\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msampling_rate\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mdevice_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msampling_rate\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 149\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"ref_signal has wrong samping_rate\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 150\u001b[0m \u001b[0;31m# add device to chain\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'sampling_rate'" ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "measurement chain with 3 devices @ 48000 Hz sampling rate.\n", - "# 1: Device 1 defined by 24000 freq-bins, sensitivity=1.0\n", - "# 2: Device 2 defined by 24000 freq-bins, sensitivity=2.0\n", - "# 3: defined by 24000 freq-bins, sensitivity=1" - ] - }, - "metadata": {}, - "execution_count": 6 } ], "source": [ - "chain.add_device()\n", - "chain" + "chain.add_device('new device')\n", + "print(chain)" ] }, { @@ -249,15 +233,15 @@ ], "source": [ "print(chain.list_devices())\n", - "pyfar.plot.line.freq(chain.device_freq(''))" + "pyfar.plot.line.freq(chain.device_freq('new device'))" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3.8.5 64-bit ('pyfar': conda)", "language": "python", - "name": "python3" + "name": "python38564bitpyfarconda275748b046bf426d822266ea67adf083" }, "language_info": { "codemirror_mode": { From 2a0b1fe8d6b126e976da904df500c712b43c9fe5 Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Fri, 12 Mar 2021 18:22:29 +0100 Subject: [PATCH 03/20] add propertys & setter for Device class --- mestopy/mestopy.py | 85 ++++++++++++++++++++++++++++++---------------- mestopy_demo.ipynb | 40 +++++----------------- 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 6c0147a..2e795b7 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -25,18 +25,59 @@ def __init__(self, name, data=None, sens=1, unit=None): name : str Name of the device. """ + self.name = name + self.data = data + self.sens = sens + self.unit = unit + + @property + def name(self): + """The name of the device""" + return self._name + + @name.setter + def name(self, name): if not isinstance(name, str): raise ValueError('Device name must be string.') - if not (isinstance(data, Signal) or data is None): + else: + self._name = name + + @property + def data(self): + """The freqeuncy dependent data, representing the device. + Type Signal or None.""" + return self._data + + @data.setter + def data(self, data): + if not isinstance(data, (Signal, type(None))): raise TypeError('Input data must be type Signal or None.') - if not (isinstance(unit, str) or unit is None): - raise ValueError('Unit of sensitivity must be string or None.') + else: + self._data = data + + @property + def sens(self): + """The sensitivity of the device.""" + return self._sens + + @sens.setter + def sens(self, sens): if not isinstance(sens, (int, float)): raise ValueError('Sensitivity must be a number (int or float).') - self.sens = sens - self.name = name - self.data = data - self.unit = unit + else: + self._sens = sens + + @property + def unit(self): + """The unit of the sensitivity.""" + return self._unit + + @unit.setter + def unit(self, unit): + if not (isinstance(unit, str) or unit is None): + raise ValueError('Unit of sensitivity must be string or None.') + else: + self._unit = unit @property def freq(self): @@ -49,21 +90,11 @@ def freq(self): else: return self.sens - @property - def device_name(self): - """Return the name of the device as string.""" - return self.name - - @device_name.setter - def device_name(self, new_name): - """Set the name of the device.""" - self.name = new_name - def __repr__(self): """String representation of DeviceObj class.""" if self.data is None: repr_string = ( - f"{self.name} defined by None freq-bins, " + f"{self.name} defined by " f"sensitivity={self.sens} unit={self.unit}\n") else: repr_string = ( @@ -105,7 +136,7 @@ def __init__(self, self.devices = devices self.comment = comment - def __find_index(self, name): + def _find_device_index(self, name): """Private method to find the index of a given device name.""" for i, dev in enumerate(self.devices): if dev.name == name: @@ -142,7 +173,7 @@ def add_device(self, The default is an empty string. """ # check if device_data is type Signal or None - if not (isinstance(device_data, Signal) or device_data is None): + if not isinstance(device_data, (Signal, type(None))): raise TypeError('Input data must be type Signal or None.') # check if there are no devices in measurement chain if not self.devices == []: @@ -162,7 +193,7 @@ def list_devices(self): # list all ref-objects in chain device_names = [] for dev in self.devices: - name = dev.device_name + name = dev.name device_names.append(name) return device_names @@ -181,7 +212,7 @@ def remove_device(self, num): self.devices.pop(num) # remove ref-object in chain by name elif isinstance(num, str): - self.remove_device(self.__find_index(num)) + self.remove_device(self._find_device_index(num)) else: raise TypeError("device to remove must be int or str") @@ -207,7 +238,7 @@ def device_freq(self, num): if isinstance(num, int): return self.devices[num].freq elif isinstance(num, str): - return self.device_freq(self.__find_index(num)) + return self.device_freq(self._find_device_index(num)) else: raise TypeError("Device must be called by int or str.") @@ -217,13 +248,9 @@ def freq(self): All devices (frequency response and sensitivity) are considered. """ if self.devices != []: - resp = Signal(np.ones(int(self.devices[0].data.n_bins)), - self.sampling_rate, - domain='freq', - fft_norm=self.devices[0].data.fft_norm, - dtype=self.devices[0].data.dtype) + resp = 1.0 for dev in self.devices: - resp = resp * dev.data * dev.sens + resp = dev.freq * resp else: resp = Signal(np.ones(self.sampling_rate), self.sampling_rate) return resp diff --git a/mestopy_demo.ipynb b/mestopy_demo.ipynb index bb1d54a..2f01043 100644 --- a/mestopy_demo.ipynb +++ b/mestopy_demo.ipynb @@ -115,7 +115,7 @@ "output_type": "display_data", "data": { "text/plain": "
", - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T17:35:02.018323\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T17:49:21.034876\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", "image/png": "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P/6o9PR0jRo1SqNHj9YXX3zhk33nzZunO+64Q3fffbdzrK59s7OzlZCQoJEjR2rHjh1en8+d+vTT3zVJ3vXUk3q87aevHmNt/X7wwQd14MCBeu9ZX656Hax6zvtlrxtaT2299tVj9Obnd9OmTXrqqacafM66ePvz621NjS6gQkND9cgjj2j9+vXKzs7W22+/raKiIq1cuVK9e/fWu+++q969e2vlypUBq+nNN9/U9ddf7/zaF7U888wz6tevn9555x3n/r7Yd/jw4Vq6dOlFY672LSoqUm5urtatW6elS5dq4cKFstvtXp+zLt72MxA1SZ731NN6vOmnLx9jbf0OFle9DrZf9rqhauu1r3jz8xsI/n4+bnQBdfXVV6tr166SpMsvv1ydOnWSzWZTXl6ehg0bJkkaNmyYPv7444DUc+zYMX366adKSEhwjjW0llOnTukf//iHRowYIUlq3ry5Wrdu7ZPHePPNN+uKK664aMzVvnl5eRo8eLCsVqs6dOigqKgoFRYWen3Ounjbz0DU5E1PPanH23768jHW1u/zzp07p4yMDGVlZdVrb2+56nWw6pFq73VD6nHV64bseSFvfn4vtH37dk2aNEkVFRX1Oq8rDXk+9qSmRhdQFyorK9OhQ4fUo0cPff/997r66qsl/fxNO3HiREBqWLx4saZMmSKLxeIca2gtpaWlCg8P17x585SYmKjMzEz99NNPfnuMrva12Wy65pprnOsiIyMvekLxNU/6GYiavOmpJ/V4289APEa73a7Zs2erY8eOSklJ8enenriw18Gsp7ZeN6QeV71uyJ7uuHte+Oijj7Ry5Uq98MILCg8P99l5f8mb52NPa2q0AVVZWan09HRNnz5drVq1CkoNn3zyia688kp169bNp/va7XYdOnRIo0eP1po1a3TZZZcF9LK9Lr/8QfaVhvTTlzX5oqe1Pdk1tJ++/r4vWLBA0dHRSkpK8um+nqit18Gop65e17eeunodjMe4b98+rVq1Ss8//7zLK2lf8Obn15uaGmVAnT17Vunp6fr973+v22+/XZJ05ZVXqry8XJJUXl6utm3b+r2OgoIC5efna/jw4Zo1a5b27NmjOXPmNLiWyMhIRUZGOv91OWjQIB08eNBvj9HVvpGRkTp27Jhznc1mU0REhE/OeSFv+unvmrztqSf1eNvPQHzfb7rpJu3bt0/V1dU+3ded2nodrHpc9boh9bjqdUP2dKeu54UOHTqosrJShw8f9uk5L+Tt87E3NTW6gHI4HHriiSd0/fXXa/z48c7xgQMHavPmzZKkzZs3a+DAgX6v5aGHHlJOTo42bdqk+fPn63e/+50yMzMbXMvVV1+ta665Rt99950kaffu3ercubPfHqOrfePi4pSbm6uamhqVlpaqpKREMTExPjnned720981edtTT+rxtp+B+L6PGDFC/fr104wZM3T27Fmf7u2Kq14Hqx5XvW5IPa563ZA93anreaFdu3ZatGiRMjIy9M033/jsnOfV5/nYm5oaXUAVFBQoJydHe/bsUWJiohITE7V9+3bde++92rVrl+666y7t2rVLEydODFqNvqglLS1Nc+bM0dixY/Wvf/1LkyZN8sm+M2fO1KRJk1RcXKyhQ4fqvffec7lvdHS04uPjNWbMGD388MNKT09XSEiI1+esi7f9DERNtWloPd7005ePsbZ+nzd+/Hh17dpVc+fO1blz5+q1vzdc9TpY9bhT33pq63VD9zzPm5/f8zp16qTMzEzNmDFD//nPf7w+Z13q+3zsaU183AYAwEiN7goKANA0EFAAACMRUAAAIxFQAAAjEVAAACMRUMD/9O7d2/lW2cTERJWVlQW7JJ84cOCAnn76aa+OGT58+EX3SNu7d6/zbt9AoIQGuwDAFC1atNCaNWtqnXM4HHI4HGrWrPH9m6579+7q3r17sMsAvEZAAS6UlZVpypQp6tWrl7744gstXrxYW7du1QcffKCamhrddtttSk5OliS9+uqrev/999WuXTuFh4erW7dumjBhgh588EFNmzZN3bt3V0VFhSZMmKBNmzbJbrfrxRdf1L59+1RTU6MxY8Zo1KhR2rt3r/7yl78oPDxc33zzjbp166bMzExZLBYVFhZq8eLF+umnn9S8eXO9/PLLmjp1qtLS0nTjjTdKku677z49/vjj+u1vf+t8HHv37tUbb7yh559/XsuXL9fRo0dVWlqqY8eO6Z577tHYsWO9+r5MmTLFeRub0tJSpaWlOe9cDfgSAQX8T3V1tRITEyVJ1157rR599FEVFxcrIyNDM2bM0M6dO1VSUqJVq1bJ4XDo0Ucf1eeff67LLrtMubm5WrNmjc6ePavx48e7vdnshg0bdPnll+v1119XTU2NkpKS1KdPH0nSoUOHtG7dOkVERCgpKUkFBQWKiYnRzJkztWDBAsXExOjUqVNq0aKFEhIStHnzZt14440qLi7WmTNnLgqn2hQXF2vZsmWqrKx0fqheaOivnwqSk5Odd7CorKxUp06dJElLliyRJH311VeaN2+ebr31Vm++zYDHCCjgf375K76ysjK1b99esbGxkqSdO3dq586dGjdunCQ5b3hZWVmp2267TWFhYZJ+vpeeOzt37tTXX3+tDz/8UNLPnyNUUlKi0NBQxcTEOD9u44YbblBZWZlatWqlq666ynlPvvN3jI6Pj9crr7yiqVOnauPGjR5dyfTv319Wq1VWq1Vt27bVf//734s+3uO85cuXOz8K4fxV2HkVFRWaO3eunnzyyaB9mgAufQQUUIfzoSP9/DrUxIkTNWrUqIvWrFmzxuXHYYSGhjrvuXbhXawdDofS0tLUt2/fi9bv3btXVqvV+XWzZs1kt9vlcDhqPUdYWJhuueUWffzxx/rggw/0+uuvu31Mte3vDbvdrpkzZ+r+++9Xly5dvDoW8Ebje8UXCJK+fftq48aNqqyslPTzx2B8//33uvnmm/XRRx+pqqpKp0+f1ieffOI8pn379s6PW9i2bdtFe61fv955V+vi4mLnB9vVplOnTiovL3d+su7p06edxyYkJOiZZ55R9+7d1aZNG98+6Fq8+OKL6tKli4YMGeL3c6Fp4woK8FCfPn307bffOu9O3bJlS2VmZqpr16664447lJiYqPbt26tnz57OYyZMmKAZM2YoJydHvXr1co4nJCToyJEjGjdunBwOh9q2bavFixe7PHfz5s21YMECPf3006qurlaLFi2UlZWl0NBQdevWTZdffrmGDx/ut8d+odWrV6tz587O1+uSk5MD8vE2aHq4mzngY8uXL1fLli01YcKEgJzv+PHjSk5O1vr16xvl2+ABV/i/GWjENm/erIkTJyolJYVwwiWHKygAgJH4JxcAwEgEFADASAQUAMBIBBQAwEgEFADASP8Pn6aMjIP9RicAAAAASUVORK5CYII=\n" }, "metadata": {} @@ -158,7 +158,7 @@ "output_type": "display_data", "data": { "text/plain": "
", - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T17:35:02.673313\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T17:49:21.672335\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", "image/png": "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a3S3r81mU3l5uWud3W5XRESEX855Pl/6GeiafO2pN/X42s9g/L3/9re/1f79+1VTU+PXfT1pqNdG1eOu102px12vm7KnJ439XOjWrZuqqqp05MgRv57zfL7+PPalpmYXUE6nU0899ZSuueYaJSYmusaHDBmiLVu2SJK2bNmiIUOGBLyWhx56SDk5Odq8ebPmzZunm266SXPnzm1yLZ06dVLnzp313XffSZL27Nmja6+9NmCv0d2+sbGxys3NVW1trUpLS1VSUqKoqCi/nLOer/0MdE2+9tSbenztZzD+3kePHq3BgwdrxowZqqur8+ve7rjrtVH1uOt1U+px1+um7OlJYz8XunTpooULFyozM1PffPON385Z72J+HvtSU7MLqIKCAuXk5Gjv3r1KSEhQQkKCduzYoXvuuUe7d+/WXXfdpd27d2vy5MmG1eiPWtLT0/Xkk09q4sSJ+te//qUpU6b4Zd+ZM2dqypQpKi4u1ogRI/TBBx+43TcyMlJxcXEaP368Hn74YWVkZCgkJMTnczbG134Go6aGNLUeX/rpz9fYUL/rJSYmqnfv3po9e7bOnj17Ufv7wl2vjarHk4utp6FeN3XPer58/9br2bOn5s6dqxkzZug///mPz+dszMX+PPa2Jh63AQAwpWZ3BQUAaBkIKACAKRFQAABTIqAAAKZEQAEATImAAv5nwIABro/KJiQkqKyszOiS/OLgwYN69tlnfTpm1KhRF9wjbd++fa67fQPBEmp0AYBZtGnTRmvXrm1wzul0yul0qlWr5vdvur59+6pv375GlwH4jIAC3CgrK9PUqVN144036ssvv9SiRYu0bds2ffjhh6qtrdVtt92mlJQUSdJrr72mv/71r+rSpYvCw8PVp08fJSUl6YEHHtC0adPUt29fVVZWKikpSZs3b5bD4dCyZcu0f/9+1dbWavz48Ro7dqz27dunV155ReHh4frmm2/Up08fzZ07VxaLRYWFhVq0aJFOnz6t1q1b6+WXX9Yjjzyi9PR0XX/99ZKke++9V48//rh+85vfuF7Hvn379MYbb+jFF1/UihUrdOzYMZWWlqq8vFx33323Jk6c6NPfy9SpU123sSktLVV6errrztWAPxFQwP/U1NQoISFBknTVVVfpscceU3FxsTIzMzVjxgzt2rVLJSUlWr16tZxOpx577DF98cUXuuyyy5Sbm6u1a9eqrq5OiYmJHm82u3HjRl1++eV6/fXXVVtbq+TkZA0cOFCSdPjwYa1fv14RERFKTk5WQUGBoqKiNHPmTM2fP19RUVE6deqU2rRpo/j4eG3ZskXXX3+9iouLdebMmQvCqSHFxcVavny5qqqqXA/VCw395Y+ClJQU1x0sqqqq1LNnT0nSkiVLJEn//Oc/NWfOHN16662+/DUDXiOggP/5+a/4ysrK1LVrV0VHR0uSdu3apV27dmnSpEmS5LrhZVVVlW677TaFhYVJOncvPU927dqlr7/+Wh999JGkc88RKikpUWhoqKKiolyP27juuutUVlamdu3a6Ve/+pXrnnz1d4yOi4vTq6++qkceeUSbNm3y6krmlltukdVqldVqVceOHfXf//73gsd71FuxYoXrUQj1V2H1KisrNXv2bD399NOGPU0Alz4CCmhEfehI596Hmjx5ssaOHXvBmrVr17p9HEZoaKjrnmvn38Xa6XQqPT1dgwYNumD9vn37ZLVaXV+3atVKDodDTqezwXOEhYXp5ptv1ieffKIPP/xQr7/+usfX1ND+vnA4HJo5c6buu+8+9erVy6djAV80v3d8AYMMGjRImzZtUlVVlaRzj8H4/vvvdcMNN+jjjz9WdXW1fvrpJ3366aeuY7p27ep63ML27dsv2GvDhg2uu1oXFxe7HmzXkJ49e6qiosL1ZN2ffvrJdWx8fLyee+459e3bVx06dPDvi27AsmXL1KtXLw0fPjzg50LLxhUU4KWBAwfq22+/dd2dum3btpo7d6569+6tO+64QwkJCeratav69+/vOiYpKUkzZsxQTk6ObrzxRtd4fHy8jh49qkmTJsnpdKpjx45atGiR23O3bt1a8+fP17PPPquamhq1adNGWVlZCg0NVZ8+fXT55Zdr1KhRAXvt51uzZo2uvfZa1/t1KSkpQXm8DVoe7mYO+NmKFSvUtm1bJSUlBeV8x48fV0pKijZs2NAsPwYPuMP/moFmbMuWLZo8ebJSU1MJJ1xyuIICAJgS/+QCAJgSAQUAMCUCCgBgSgQUAMCUCCgAgCn9P2lrREvt3FYrAAAAAElFTkSuQmCC\n" }, "metadata": {} @@ -182,15 +182,10 @@ "metadata": {}, "outputs": [ { - "output_type": "error", - "ename": "AttributeError", - "evalue": "'NoneType' object has no attribute 'sampling_rate'", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mchain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_device\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'new device'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mchain\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/Git/mestopy-master/mestopy/mestopy/mestopy.py\u001b[0m in \u001b[0;36madd_device\u001b[0;34m(self, device_name, device_data, sens, unit)\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0;31m# check if sampling_rate of new device and MeasurementChain\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 147\u001b[0m \u001b[0;31m# is the same\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 148\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msampling_rate\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mdevice_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msampling_rate\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 149\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"ref_signal has wrong samping_rate\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 150\u001b[0m \u001b[0;31m# add device to chain\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'sampling_rate'" + "output_type": "stream", + "name": "stdout", + "text": [ + "measurement chain with 3 devices @ 48000 Hz sampling rate.\n# 0: Device 1 defined by 24000 freq-bins, sensitivity=1.0 unit=None\n# 1: Device 2 defined by 24000 freq-bins, sensitivity=2.0 unit=None\n# 2: new device defined by None freq-bins, sensitivity=1 unit=None\n\n" ] } ], @@ -208,32 +203,13 @@ "output_type": "stream", "name": "stdout", "text": [ - "['Device 1', 'Device 2', '']\n" + "['Device 1', 'Device 2', 'new device']\n" ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ] - }, - "metadata": {}, - "execution_count": 7 - }, - { - "output_type": "display_data", - "data": { - "text/plain": "
", - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-09T15:32:18.431976\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", - "image/png": "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uB5++GGtW7dOeXl5evPNN1VaWqoVK1aof//+euedd9S/f3+tWLHCsJpef/11XXPNNZ7HwajlmWee0aBBg/TWW2951g/GuiNHjtTixYsvGPO2bmlpqQoKCrR27VotXrxY8+bNk8vlCviYjQm0n0bUJPnfU3/rCaSfwXyODfXbLN56bbaf9rqpGup1sATy+2uEUL8eN7uAuvLKK9WrVy9J0iWXXKIePXrI6XSqsLBQI0aMkCSNGDFCH374oSH1VFZW6uOPP1ZiYqJnrKm1nDhxQv/4xz80atQoSVLr1q116aWXBuU53nDDDbrssssuGPO2bmFhoYYOHSq73a6uXbuqW7duKikpCfiYjQm0n0bUFEhP/akn0H4G8zk21O96Z8+eVXZ2tnJzcy9q7UB567VZ9UgN97op9XjrdVPWPF8gv7/n27ZtmyZPnqzq6uqLOq43TXk99qemZhdQ56uoqNCBAwfUt29ffffdd7ryyislnfuhHTt2zJAaFixYoClTpshms3nGmlpLeXm5IiMjNXv2bCUlJSknJ0c//vhjyJ6jt3WdTqc6derkmedwOC54QQk2f/ppRE2B9NSfegLtpxHP0eVy6bHHHlP37t2Vnp4e1LX9cX6vzaynoV43pR5vvW7Kmr74el344IMPtGLFCi1cuFCRkZFBO+5PBfJ67G9NzTagTp06paysLE2bNk3t27c3pYaPPvpIl19+uXr37h3UdV0ulw4cOKCxY8dq9erVatu2raGn7Y356S9ysDSln8GsKRg9bejFrqn9DPbPfe7cuYqOjlZqampQ1/VHQ702o57Gen2x9TTWazOe4549e7Ry5Uo9//zzXs+kgyGQ399AamqWAVVXV6esrCz9/ve/1+9+9ztJ0uWXX66qqipJUlVVlTp27BjyOoqLi1VUVKSRI0dq5syZ2rVrlx5//PEm1+JwOORwODz/uhwyZIj2798fsufobV2Hw6HKykrPPKfTqaioqKAc83yB9DPUNQXaU3/qCbSfRvzcf/Ob32jPnj06ffp0UNf1paFem1WPt143pR5vvW7Kmr409rrQtWtXnTp1SocOHQrqMc8X6OtxIDU1u4Byu9164okndM011yg5OdkzPnjwYG3atEmStGnTJg0ePDjktTzwwAPKz8/Xxo0bNWfOHP32t79VTk5Ok2u58sor1alTJ3377beSpJ07d+raa68N2XP0tm58fLwKCgpUW1ur8vJylZWVKSYmJijHrBdoP0NdU6A99aeeQPtpxM991KhRGjRokKZPn666urqgru2Nt16bVY+3XjelHm+9bsqavjT2utC5c2fNnz9f2dnZ+vrrr4N2zHoX83ocSE3NLqCKi4uVn5+vXbt2KSkpSUlJSdq2bZvuuusu7dixQ3fccYd27NihSZMmmVZjMGrJzMzU448/rgkTJuhf//qXJk+eHJR1Z8yYocmTJ+vgwYMaPny43n33Xa/rRkdHKyEhQePGjdODDz6orKwshYWFBXzMxgTaTyNqakhT6wmkn8F8jg31u15ycrJ69eqlWbNm6ezZsxe1fiC89dqseny52Hoa6nVT16wXyO9vvR49eignJ0fTp0/Xf/7zn4CP2ZiLfT32tyZutwEAsKRmdwYFAGgZCCgAgCURUAAASyKgAACWREABACyJgAL+p3///p6vyiYlJamiosLskoJi3759evrppwPaZ+TIkRdcI2337t2eq30DRgk3uwDAKtq0aaPVq1c3uM3tdsvtdqtVq+b3b7o+ffqoT58+ZpcBBIyAAryoqKjQlClTdOONN+rzzz/XggULtGXLFr333nuqra3VrbfeqrS0NEnSK6+8or/97W/q3LmzIiMj1bt3b6WkpOi+++7T1KlT1adPH1VXVyslJUUbN26Uy+XSkiVLtGfPHtXW1mrcuHEaM2aMdu/erZdeekmRkZH6+uuv1bt3b+Xk5Mhms6mkpEQLFizQjz/+qNatW+vFF1/UQw89pMzMTF1//fWSpLvvvluPPvqofv3rX3uex+7du/Xaa6/p+eef17Jly3TkyBGVl5ersrJSd955pyZMmBDQz2XKlCmey9iUl5crMzPTc+VqIJgIKOB/Tp8+raSkJEnSVVddpUceeUQHDx5Udna2pk+fru3bt6usrEwrV66U2+3WI488os8++0xt27ZVQUGBVq9erbq6OiUnJ/u82Oz69et1ySWX6NVXX1Vtba1SU1M1YMAASdKBAwe0du1aRUVFKTU1VcXFxYqJidGMGTM0d+5cxcTE6MSJE2rTpo0SExO1adMmXX/99Tp48KDOnDlzQTg15ODBg1q6dKlOnTrlualeePjPXwrS0tI8V7A4deqUevToIUlatGiRJOnLL7/U7NmzdcsttwTyYwb8RkAB//PTt/gqKirUpUsXxcbGSpK2b9+u7du3a+LEiZLkueDlqVOndOuttyoiIkLSuWvp+bJ9+3Z99dVXev/99yWdu49QWVmZwsPDFRMT47ndxnXXXaeKigq1b99eV1xxheeafPVXjE5ISNDLL7+shx56SBs2bPDrTObmm2+W3W6X3W5Xx44d9d///veC23vUW7ZsmedWCPVnYfWqq6s1a9YsPfnkk6bdTQC/fAQU0Ij60JHOfQ41adIkjRkz5oI5q1ev9no7jPDwcM81186/irXb7VZmZqYGDhx4wfzdu3fLbrd7Hrdq1Uoul0tut7vBY0REROimm27Shx9+qPfee0+vvvqqz+fU0PqBcLlcmjFjhu655x717NkzoH2BQDS/T3wBkwwcOFAbNmzQqVOnJJ27DcZ3332nG264QR988IFqamp08uRJffTRR559unTp4rndwtatWy9Ya926dZ6rWh88eNBzY7uG9OjRQ1VVVZ476548edKzb2Jiop555hn16dNHHTp0CO6TbsCSJUvUs2dPDRs2LOTHQsvGGRTgpwEDBuibb77xXJ26Xbt2ysnJUa9evXTbbbcpKSlJXbp0Ub9+/Tz7pKSkaPr06crPz9eNN97oGU9MTNThw4c1ceJEud1udezYUQsWLPB67NatW2vu3Ll6+umndfr0abVp00a5ubkKDw9X7969dckll2jkyJEhe+7nW7Vqla699lrP53VpaWmG3N4GLQ9XMweCbNmyZWrXrp1SUlIMOd7Ro0eVlpamdevWNcuvwQPe8LcZaMY2bdqkSZMmKT09nXDCLw5nUAAAS+KfXAAASyKgAACWREABACyJgAIAWBIBBQCwpP8H9AsoxWzebAYAAAAASUVORK5CYII=\n" - }, - "metadata": {} } ], "source": [ "print(chain.list_devices())\n", - "pyfar.plot.line.freq(chain.device_freq('new device'))" + "#pyfar.plot.line.freq(chain.device_freq('new device'))" ] } ], From f1bd7eb811cb1a78bea0f3b9be308a750a4dc1c9 Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Fri, 12 Mar 2021 20:07:37 +0100 Subject: [PATCH 04/20] changed device summation to time domain with oaconvolve --- mestopy/mestopy.py | 31 +++++++++++++++++++++++-------- mestopy_demo.ipynb | 45 +++++++++++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 2e795b7..2ab29bf 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -1,4 +1,4 @@ -import numpy as np +from scipy.signal import oaconvolve from pyfar import Signal @@ -135,6 +135,7 @@ def __init__(self, self.sound_device = sound_device self.devices = devices self.comment = comment + self._freq() def _find_device_index(self, name): """Private method to find the index of a given device name.""" @@ -143,6 +144,22 @@ def _find_device_index(self, name): return i raise ValueError(f"device {name} not found") + def _freq(self): + """Private method to calculate the frequency response of the complete + measurement chain and save it to the private attribute _resp.""" + if self.devices == []: + resp = 1.0 + else: + resp = [[1.0]] + for dev in self.devices: + if isinstance(dev.freq, Signal): + resp = oaconvolve(resp, dev.freq.time) + else: + resp = oaconvolve(resp, [[dev.freq]]) + resp = Signal(resp, self.sampling_rate, domain='time') + resp.domain = 'freq' + self._resp = resp + def add_device(self, device_name, device_data=None, @@ -186,6 +203,7 @@ def add_device(self, new_device = Device(device_name, data=device_data, sens=sens, unit=unit) self.devices.append(new_device) + self._freq() def list_devices(self): """Returns a list of names of all devices in the measurement chain. @@ -215,6 +233,7 @@ def remove_device(self, num): self.remove_device(self._find_device_index(num)) else: raise TypeError("device to remove must be int or str") + self._freq() # reset complete ref-object-list def reset_devices(self): @@ -223,6 +242,7 @@ def reset_devices(self): measurement chain remain unchanged. """ self.devices = [] + self._freq() # get the freq-response of specific device in measurement chain def device_freq(self, num): @@ -243,17 +263,12 @@ def device_freq(self, num): raise TypeError("Device must be called by int or str.") # get the freq-response of whole measurement chain as pyfar.Signal + @property def freq(self): """Returns the frequency response of the complete measurement chain. All devices (frequency response and sensitivity) are considered. """ - if self.devices != []: - resp = 1.0 - for dev in self.devices: - resp = dev.freq * resp - else: - resp = Signal(np.ones(self.sampling_rate), self.sampling_rate) - return resp + return self._resp def __repr__(self): """String representation of MeasurementChain class. diff --git a/mestopy_demo.ipynb b/mestopy_demo.ipynb index 2f01043..3529f1d 100644 --- a/mestopy_demo.ipynb +++ b/mestopy_demo.ipynb @@ -46,8 +46,10 @@ "outputs": [ { "output_type": "stream", - "name": "stdout", + "name": "stderr", "text": [ + "/home/alex/Git/pyfar-develop/pyfar/signal.py:507: UserWarning: Number of time samples not given, assuming an even number of samples from the number of frequency bins.\n", + " warnings.warn(\n", "measurement chain with 4 devices @ 48000 Hz sampling rate.\n", "# 0: Device 1 defined by 24000 freq-bins, sensitivity=1.0 unit=None\n", "# 1: Device 1 defined by 24000 freq-bins, sensitivity=1.0 unit=None\n", @@ -57,10 +59,11 @@ "['Device 1', 'Device 1', 'Device 2', 'Device 3']\n", "['Device 1', 'Device 2', 'Device 3']\n", "freq domain energy Signal:\n", - "(1,) channels with 47998 samples @ 48000 Hz sampling rate and none FFT normalization\n", + "(1,) channels with 143992 samples @ 48000 Hz sampling rate and none FFT normalization\n", "\n", - "/home/alex/Git/pyfar-develop/pyfar/signal.py:507: UserWarning: Number of time samples not given, assuming an even number of samples from the number of frequency bins.\n", - " warnings.warn(\n" + "freq domain energy Signal:\n", + "(1,) channels with 47998 samples @ 48000 Hz sampling rate and none FFT normalization\n", + "\n" ] } ], @@ -90,7 +93,7 @@ "print(chain.list_devices())\n", "\n", "# get the freq-response of whole measurement chain as pyfar.Signal\n", - "chain.freq()\n", + "print(chain.freq)\n", "\n", "# get the freq-response of specific device in measurement chain as pyfar.Signal\n", "print(chain.device_freq(1))" @@ -115,7 +118,7 @@ "output_type": "display_data", "data": { "text/plain": "
", - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T17:49:21.034876\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-12T20:07:06.798012\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", "image/png": "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P/6o9PR0jRo1SqNHj9YXX3zhk33nzZunO+64Q3fffbdzrK59s7OzlZCQoJEjR2rHjh1en8+d+vTT3zVJ3vXUk3q87aevHmNt/X7wwQd14MCBeu9ZX656Hax6zvtlrxtaT2299tVj9Obnd9OmTXrqqacafM66ePvz621NjS6gQkND9cgjj2j9+vXKzs7W22+/raKiIq1cuVK9e/fWu+++q969e2vlypUBq+nNN9/U9ddf7/zaF7U888wz6tevn9555x3n/r7Yd/jw4Vq6dOlFY672LSoqUm5urtatW6elS5dq4cKFstvtXp+zLt72MxA1SZ731NN6vOmnLx9jbf0OFle9DrZf9rqhauu1r3jz8xsI/n4+bnQBdfXVV6tr166SpMsvv1ydOnWSzWZTXl6ehg0bJkkaNmyYPv7444DUc+zYMX366adKSEhwjjW0llOnTukf//iHRowYIUlq3ry5Wrdu7ZPHePPNN+uKK664aMzVvnl5eRo8eLCsVqs6dOigqKgoFRYWen3Ounjbz0DU5E1PPanH23768jHW1u/zzp07p4yMDGVlZdVrb2+56nWw6pFq73VD6nHV64bseSFvfn4vtH37dk2aNEkVFRX1Oq8rDXk+9qSmRhdQFyorK9OhQ4fUo0cPff/997r66qsl/fxNO3HiREBqWLx4saZMmSKLxeIca2gtpaWlCg8P17x585SYmKjMzEz99NNPfnuMrva12Wy65pprnOsiIyMvekLxNU/6GYiavOmpJ/V4289APEa73a7Zs2erY8eOSklJ8enenriw18Gsp7ZeN6QeV71uyJ7uuHte+Oijj7Ry5Uq98MILCg8P99l5f8mb52NPa2q0AVVZWan09HRNnz5drVq1CkoNn3zyia688kp169bNp/va7XYdOnRIo0eP1po1a3TZZZcF9LK9Lr/8QfaVhvTTlzX5oqe1Pdk1tJ++/r4vWLBA0dHRSkpK8um+nqit18Gop65e17eeunodjMe4b98+rVq1Ss8//7zLK2lf8Obn15uaGmVAnT17Vunp6fr973+v22+/XZJ05ZVXqry8XJJUXl6utm3b+r2OgoIC5efna/jw4Zo1a5b27NmjOXPmNLiWyMhIRUZGOv91OWjQIB08eNBvj9HVvpGRkTp27Jhznc1mU0REhE/OeSFv+unvmrztqSf1eNvPQHzfb7rpJu3bt0/V1dU+3ded2nodrHpc9boh9bjqdUP2dKeu54UOHTqosrJShw8f9uk5L+Tt87E3NTW6gHI4HHriiSd0/fXXa/z48c7xgQMHavPmzZKkzZs3a+DAgX6v5aGHHlJOTo42bdqk+fPn63e/+50yMzMbXMvVV1+ta665Rt99950kaffu3ercubPfHqOrfePi4pSbm6uamhqVlpaqpKREMTExPjnned720981edtTT+rxtp+B+L6PGDFC/fr104wZM3T27Fmf7u2Kq14Hqx5XvW5IPa563ZA93anreaFdu3ZatGiRMjIy9M033/jsnOfV5/nYm5oaXUAVFBQoJydHe/bsUWJiohITE7V9+3bde++92rVrl+666y7t2rVLEydODFqNvqglLS1Nc+bM0dixY/Wvf/1LkyZN8sm+M2fO1KRJk1RcXKyhQ4fqvffec7lvdHS04uPjNWbMGD388MNKT09XSEiI1+esi7f9DERNtWloPd7005ePsbZ+nzd+/Hh17dpVc+fO1blz5+q1vzdc9TpY9bhT33pq63VD9zzPm5/f8zp16qTMzEzNmDFD//nPf7w+Z13q+3zsaU183AYAwEiN7goKANA0EFAAACMRUAAAIxFQAAAjEVAAACMRUMD/9O7d2/lW2cTERJWVlQW7JJ84cOCAnn76aa+OGT58+EX3SNu7d6/zbt9AoIQGuwDAFC1atNCaNWtqnXM4HHI4HGrWrPH9m6579+7q3r17sMsAvEZAAS6UlZVpypQp6tWrl7744gstXrxYW7du1QcffKCamhrddtttSk5OliS9+uqrev/999WuXTuFh4erW7dumjBhgh588EFNmzZN3bt3V0VFhSZMmKBNmzbJbrfrxRdf1L59+1RTU6MxY8Zo1KhR2rt3r/7yl78oPDxc33zzjbp166bMzExZLBYVFhZq8eLF+umnn9S8eXO9/PLLmjp1qtLS0nTjjTdKku677z49/vjj+u1vf+t8HHv37tUbb7yh559/XsuXL9fRo0dVWlqqY8eO6Z577tHYsWO9+r5MmTLFeRub0tJSpaWlOe9cDfgSAQX8T3V1tRITEyVJ1157rR599FEVFxcrIyNDM2bM0M6dO1VSUqJVq1bJ4XDo0Ucf1eeff67LLrtMubm5WrNmjc6ePavx48e7vdnshg0bdPnll+v1119XTU2NkpKS1KdPH0nSoUOHtG7dOkVERCgpKUkFBQWKiYnRzJkztWDBAsXExOjUqVNq0aKFEhIStHnzZt14440qLi7WmTNnLgqn2hQXF2vZsmWqrKx0fqheaOivnwqSk5Odd7CorKxUp06dJElLliyRJH311VeaN2+ebr31Vm++zYDHCCjgf375K76ysjK1b99esbGxkqSdO3dq586dGjdunCQ5b3hZWVmp2267TWFhYZJ+vpeeOzt37tTXX3+tDz/8UNLPnyNUUlKi0NBQxcTEOD9u44YbblBZWZlatWqlq666ynlPvvN3jI6Pj9crr7yiqVOnauPGjR5dyfTv319Wq1VWq1Vt27bVf//734s+3uO85cuXOz8K4fxV2HkVFRWaO3eunnzyyaB9mgAufQQUUIfzoSP9/DrUxIkTNWrUqIvWrFmzxuXHYYSGhjrvuXbhXawdDofS0tLUt2/fi9bv3btXVqvV+XWzZs1kt9vlcDhqPUdYWJhuueUWffzxx/rggw/0+uuvu31Mte3vDbvdrpkzZ+r+++9Xly5dvDoW8Ebje8UXCJK+fftq48aNqqyslPTzx2B8//33uvnmm/XRRx+pqqpKp0+f1ieffOI8pn379s6PW9i2bdtFe61fv955V+vi4mLnB9vVplOnTiovL3d+su7p06edxyYkJOiZZ55R9+7d1aZNG98+6Fq8+OKL6tKli4YMGeL3c6Fp4woK8FCfPn307bffOu9O3bJlS2VmZqpr16664447lJiYqPbt26tnz57OYyZMmKAZM2YoJydHvXr1co4nJCToyJEjGjdunBwOh9q2bavFixe7PHfz5s21YMECPf3006qurlaLFi2UlZWl0NBQdevWTZdffrmGDx/ut8d+odWrV6tz587O1+uSk5MD8vE2aHq4mzngY8uXL1fLli01YcKEgJzv+PHjSk5O1vr16xvl2+ABV/i/GWjENm/erIkTJyolJYVwwiWHKygAgJH4JxcAwEgEFADASAQUAMBIBBQAwEgEFADASP8Pn6aMjIP9RicAAAAASUVORK5CYII=\n" }, "metadata": {} @@ -123,7 +126,7 @@ ], "source": [ "# plot freq-response of whole measurement chain\n", - "fig1 = pyfar.plot.line.freq(chain.freq())\n", + "fig1 = pyfar.plot.line.freq(chain.freq)\n", "\n", "# plot freq-response of element 1 of the measurement chain\n", "pyfar.plot.line.freq(chain.device_freq(2))" @@ -138,10 +141,7 @@ "output_type": "stream", "name": "stdout", "text": [ - "['Device 1', 'Device 2', 'Device 3']\n", - "['Device 1', 'Device 2']\n", - "/home/alex/Git/pyfar-develop/pyfar/signal.py:507: UserWarning: Number of time samples not given, assuming an even number of samples from the number of frequency bins.\n", - " warnings.warn(\n" + "['Device 1', 'Device 2', 'Device 3']\n['Device 1', 'Device 2']\n" ] }, { @@ -158,7 +158,7 @@ "output_type": "display_data", "data": { "text/plain": "
", - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T17:49:21.672335\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-12T20:07:07.478433\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", "image/png": "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a3S3r81mU3l5uWud3W5XRESEX855Pl/6GeiafO2pN/X42s9g/L3/9re/1f79+1VTU+PXfT1pqNdG1eOu102px12vm7KnJ439XOjWrZuqqqp05MgRv57zfL7+PPalpmYXUE6nU0899ZSuueYaJSYmusaHDBmiLVu2SJK2bNmiIUOGBLyWhx56SDk5Odq8ebPmzZunm266SXPnzm1yLZ06dVLnzp313XffSZL27Nmja6+9NmCv0d2+sbGxys3NVW1trUpLS1VSUqKoqCi/nLOer/0MdE2+9tSbenztZzD+3kePHq3BgwdrxowZqqur8+ve7rjrtVH1uOt1U+px1+um7OlJYz8XunTpooULFyozM1PffPON385Z72J+HvtSU7MLqIKCAuXk5Gjv3r1KSEhQQkKCduzYoXvuuUe7d+/WXXfdpd27d2vy5MmG1eiPWtLT0/Xkk09q4sSJ+te//qUpU6b4Zd+ZM2dqypQpKi4u1ogRI/TBBx+43TcyMlJxcXEaP368Hn74YWVkZCgkJMTnczbG134Go6aGNLUeX/rpz9fYUL/rJSYmqnfv3po9e7bOnj17Ufv7wl2vjarHk4utp6FeN3XPer58/9br2bOn5s6dqxkzZug///mPz+dszMX+PPa2Jh63AQAwpWZ3BQUAaBkIKACAKRFQAABTIqAAAKZEQAEATImAAv5nwIABro/KJiQkqKyszOiS/OLgwYN69tlnfTpm1KhRF9wjbd++fa67fQPBEmp0AYBZtGnTRmvXrm1wzul0yul0qlWr5vdvur59+6pv375GlwH4jIAC3CgrK9PUqVN144036ssvv9SiRYu0bds2ffjhh6qtrdVtt92mlJQUSdJrr72mv/71r+rSpYvCw8PVp08fJSUl6YEHHtC0adPUt29fVVZWKikpSZs3b5bD4dCyZcu0f/9+1dbWavz48Ro7dqz27dunV155ReHh4frmm2/Up08fzZ07VxaLRYWFhVq0aJFOnz6t1q1b6+WXX9Yjjzyi9PR0XX/99ZKke++9V48//rh+85vfuF7Hvn379MYbb+jFF1/UihUrdOzYMZWWlqq8vFx33323Jk6c6NPfy9SpU123sSktLVV6errrztWAPxFQwP/U1NQoISFBknTVVVfpscceU3FxsTIzMzVjxgzt2rVLJSUlWr16tZxOpx577DF98cUXuuyyy5Sbm6u1a9eqrq5OiYmJHm82u3HjRl1++eV6/fXXVVtbq+TkZA0cOFCSdPjwYa1fv14RERFKTk5WQUGBoqKiNHPmTM2fP19RUVE6deqU2rRpo/j4eG3ZskXXX3+9iouLdebMmQvCqSHFxcVavny5qqqqXA/VCw395Y+ClJQU1x0sqqqq1LNnT0nSkiVLJEn//Oc/NWfOHN16662+/DUDXiOggP/5+a/4ysrK1LVrV0VHR0uSdu3apV27dmnSpEmS5LrhZVVVlW677TaFhYVJOncvPU927dqlr7/+Wh999JGkc88RKikpUWhoqKKiolyP27juuutUVlamdu3a6Ve/+pXrnnz1d4yOi4vTq6++qkceeUSbNm3y6krmlltukdVqldVqVceOHfXf//73gsd71FuxYoXrUQj1V2H1KisrNXv2bD399NOGPU0Alz4CCmhEfehI596Hmjx5ssaOHXvBmrVr17p9HEZoaKjrnmvn38Xa6XQqPT1dgwYNumD9vn37ZLVaXV+3atVKDodDTqezwXOEhYXp5ptv1ieffKIPP/xQr7/+usfX1ND+vnA4HJo5c6buu+8+9erVy6djAV80v3d8AYMMGjRImzZtUlVVlaRzj8H4/vvvdcMNN+jjjz9WdXW1fvrpJ3366aeuY7p27ep63ML27dsv2GvDhg2uu1oXFxe7HmzXkJ49e6qiosL1ZN2ffvrJdWx8fLyee+459e3bVx06dPDvi27AsmXL1KtXLw0fPjzg50LLxhUU4KWBAwfq22+/dd2dum3btpo7d6569+6tO+64QwkJCeratav69+/vOiYpKUkzZsxQTk6ObrzxRtd4fHy8jh49qkmTJsnpdKpjx45atGiR23O3bt1a8+fP17PPPquamhq1adNGWVlZCg0NVZ8+fXT55Zdr1KhRAXvt51uzZo2uvfZa1/t1KSkpQXm8DVoe7mYO+NmKFSvUtm1bJSUlBeV8x48fV0pKijZs2NAsPwYPuMP/moFmbMuWLZo8ebJSU1MJJ1xyuIICAJgS/+QCAJgSAQUAMCUCCgBgSgQUAMCUCCgAgCn9P2lrREvt3FYrAAAAAElFTkSuQmCC\n" }, "metadata": {} @@ -171,9 +171,9 @@ "print(chain.list_devices())\n", "\n", "# plot freq-response of whole measurement chain\n", - "fig1 = pyfar.plot.line.freq(chain.device_freq('Device 1'))\n", + "fig3 = pyfar.plot.line.freq(chain.device_freq('Device 1'))\n", "# invert ref-response and plot again\n", - "pyfar.plot.line.freq(chain.freq())" + "pyfar.plot.line.freq(chain.freq)" ] }, { @@ -185,7 +185,7 @@ "output_type": "stream", "name": "stdout", "text": [ - "measurement chain with 3 devices @ 48000 Hz sampling rate.\n# 0: Device 1 defined by 24000 freq-bins, sensitivity=1.0 unit=None\n# 1: Device 2 defined by 24000 freq-bins, sensitivity=2.0 unit=None\n# 2: new device defined by None freq-bins, sensitivity=1 unit=None\n\n" + "measurement chain with 3 devices @ 48000 Hz sampling rate.\n# 0: Device 1 defined by 24000 freq-bins, sensitivity=1.0 unit=None\n# 1: Device 2 defined by 24000 freq-bins, sensitivity=2.0 unit=None\n# 2: new device defined by sensitivity=1 unit=None\n\n" ] } ], @@ -203,21 +203,26 @@ "output_type": "stream", "name": "stdout", "text": [ - "['Device 1', 'Device 2', 'new device']\n" + "freq domain energy Signal:\n(1,) channels with 95995 samples @ 48000 Hz sampling rate and none FFT normalization\n\n1.0\n" ] } ], "source": [ - "print(chain.list_devices())\n", - "#pyfar.plot.line.freq(chain.device_freq('new device'))" + "# print freq of chain, it is a Signal, because there are devices with frequency responses\n", + "print(chain.freq)\n", + "\n", + "# create measurement chain with no devices\n", + "chain2 = MeasurementChain(48000)\n", + "# print freq, it is a scalar of 1, because there are no devices\n", + "print(chain2.freq)" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.8.5 64-bit ('pyfar': conda)", + "display_name": "Python 3", "language": "python", - "name": "python38564bitpyfarconda275748b046bf426d822266ea67adf083" + "name": "python3" }, "language_info": { "codemirror_mode": { From cf707884d678d917a00e9b719538feb1e50ff031 Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Sat, 13 Mar 2021 14:01:59 +0100 Subject: [PATCH 05/20] moved docstring from MeasurementChain.add_device to Device.__init__ --- mestopy/mestopy.py | 60 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 2ab29bf..069458c 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -16,14 +16,26 @@ def __init__(self, name, data=None, sens=1, unit=None): Attributes ---------- - data : Signal - Signal data that reprensets the inverted frequency response of - the device. Data can be in domain 'freq' or 'time' and will be - transformed if necessary. - sens : float - Sensitivity of the device as a factor. name : str Name of the device. + data : Signal + Signal data that reprensets the inversed frequency response of + the device. Data can be in domain 'freq' or 'time' and will be + transformed if necessary. The default is None, in this case a + perfect flat frequency response is assumed and only sensitivity as + a factor is applied. + Caution: Make sure to use frequency responses without artefacts, + as they will influence the quality of compensations calculated with + the measurement chain. Most ideal this should be regularized + inversed frequency responses. + sens : float, optional + Sensitivity of the device as a factor. If neither device_data nor + sens is given, add_device generates a device that has no effect to + the measurement chain as it has no frequency response and a + sesitivity (factor) default of 1. + unit : str, optional + The units of the sensitivity. Basically a string to describe what + kind of units the sensitivity refers to, e.g., mV/Pa. """ self.name = name self.data = data @@ -91,7 +103,7 @@ def freq(self): return self.sens def __repr__(self): - """String representation of DeviceObj class.""" + """String representation of Device class.""" if self.data is None: repr_string = ( f"{self.name} defined by " @@ -107,9 +119,9 @@ def __repr__(self): class MeasurementChain(object): """Class for complete measurement chain. - This class that holds methods and properties of all devices in the + This class holds methods and properties of all devices in the measurement chain. It can include a single or multiple devices from - 'DeviceObj' class. + 'Device' class. """ def __init__(self, @@ -168,26 +180,14 @@ def add_device(self, ): """Adds a new device to the measurement chain. + Refer to the documentation of Device class. + Attributes ---------- - device_data : Signal, optional - Signal data that reprensets the inverted frequency response of the - device to add. The default is None, in this case a perfect flat - frequency response is assumed and only sensitivity as - a factor is applied. - Caution: Make sure to use frequency responses without artefacts, - as they will influence the quality of compensations calculated with - the measurement chain. Most ideal this should be regularized - inverted frequency responses. Data can be in domain 'freq' or - 'time' and will be transformed if necessary. + device_name : str + device_data : pyfar.Signal, optional sens : float, optional - Sensitivity of the device as a factor. If neither device_data nor - sens is given, add_device generates a device that has no effect to - the measurement chain as it has no frequency response and a - sesitivity (factor) of 1. - device_name : str, optional - The name of the new device to add to the masurement chain. - The default is an empty string. + unit : str, optional """ # check if device_data is type Signal or None if not isinstance(device_data, (Signal, type(None))): @@ -222,8 +222,8 @@ def remove_device(self, num): Attributes ---------- num : int or str - Identifier for device to remove. Device can be found by name as string - or by number in device list as int. + Identifier for device to remove. Device can be found by name as + string or by number in device list as int. """ # remove ref-object in chain position num if isinstance(num, int): @@ -252,8 +252,8 @@ def device_freq(self, num): Attributes ---------- num : int or str - Identifier for device, can be name as string or by number - in device list as int. + Identifier for device, can be name as string or by number + in device list as int. """ if isinstance(num, int): return self.devices[num].freq From 660fa11069874126ca3e569af1c9396288277d44 Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Sat, 13 Mar 2021 14:06:15 +0100 Subject: [PATCH 06/20] fixed inconstistent varibale names in MeasurementChain.add_device --- mestopy/mestopy.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 069458c..ecd2c81 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -173,8 +173,8 @@ def _freq(self): self._resp = resp def add_device(self, - device_name, - device_data=None, + name, + data=None, sens=1, unit=None ): @@ -184,23 +184,23 @@ def add_device(self, Attributes ---------- - device_name : str - device_data : pyfar.Signal, optional + name : str + data : pyfar.Signal, optional sens : float, optional unit : str, optional """ # check if device_data is type Signal or None - if not isinstance(device_data, (Signal, type(None))): + if not isinstance(data, (Signal, type(None))): raise TypeError('Input data must be type Signal or None.') # check if there are no devices in measurement chain if not self.devices == []: # check if sampling_rate of new device and MeasurementChain # is the same - if device_data is not None: - if not self.sampling_rate == device_data.sampling_rate: + if data is not None: + if not self.sampling_rate == data.sampling_rate: raise ValueError("ref_signal has wrong samping_rate") # add device to chain - new_device = Device(device_name, data=device_data, + new_device = Device(name, data=data, sens=sens, unit=unit) self.devices.append(new_device) self._freq() From 1be2d84fb37553ea650f7b194a72280ceb8f3cbc Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Tue, 16 Mar 2021 18:07:26 +0100 Subject: [PATCH 07/20] set default parameter MeasurementChain.__init__(devices=None) to avoid problems through mutability of lists --- mestopy/mestopy.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index ecd2c81..206ed38 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -127,7 +127,7 @@ class MeasurementChain(object): def __init__(self, sampling_rate, sound_device=None, - devices=[], + devices=None, comment=None): """Init measurement chain with sampling rate. @@ -145,8 +145,11 @@ def __init__(self, """ self.sampling_rate = sampling_rate self.sound_device = sound_device - self.devices = devices self.comment = comment + if isinstance(devices, type(None)): + self.devices = [] + else: + self.devices = devices self._freq() def _find_device_index(self, name): From 5c9189a53dd93129fc26790864a1373f896c9182 Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Tue, 16 Mar 2021 18:10:07 +0100 Subject: [PATCH 08/20] first implementation of tests for mestopy --- tests/test_mestopy.py | 167 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 154 insertions(+), 13 deletions(-) diff --git a/tests/test_mestopy.py b/tests/test_mestopy.py index accfdeb..41588ef 100644 --- a/tests/test_mestopy.py +++ b/tests/test_mestopy.py @@ -2,23 +2,164 @@ """Tests for `mestopy` package.""" -import pytest +from mestopy.mestopy import Device, MeasurementChain +from pyfar.testing.stub_utils import signal_stub +from pyfar import Signal -from mestopy import mestopy +import numpy.testing as npt -@pytest.fixture -def response(): - """Sample pytest fixture. +def test_Device_init(): + dev = Device('dev1') + assert isinstance(dev, Device) - See more at: http://doc.pytest.org/en/latest/fixture.html - """ - # import requests - # return requests.get('https://github.com/mberz/cookiecutter-pypackage') +def test_Device_default_parameter(): + dev = Device('dev1') + assert dev.name == 'dev1' + assert dev.data is None + assert dev.sens == 1 + assert dev.unit is None -def test_content(response): - """Sample pytest test function with the pytest fixture as an argument.""" - # from bs4 import BeautifulSoup - # assert 'GitHub' in BeautifulSoup(response.content).title.string + +def test_Device_name(): + dev = Device('dev1') + assert dev.name == 'dev1' + dev.name = 'dev2' + assert dev.name == 'dev2' + + +def test_Device_data(): + dev = Device('dev1') + assert dev.data is None + time = [1, 0, 0, 0, 0, 0, 0, 0] + freq = [1, 1, 1, 1] + sampling_rate = 44100 + fft_norm = 'none' + signal = signal_stub(time, freq, sampling_rate, fft_norm) + dev.data = signal + assert isinstance(dev.data, Signal) + assert dev.data == signal + + +def test_Device_sens(): + dev = Device('dev1') + assert dev.sens == 1 + dev.sens = 0.3 + assert dev.sens == 0.3 + + +def test_Device_unit(): + dev = Device('dev1') + assert dev.unit is None + dev.unit = 'mV/Pa' + assert dev.unit == 'mV/Pa' + + +def test_Device_freq(): + dev = Device('dev1') + assert dev.freq == 1 + time = [1, 0, 0, 0, 0, 0, 0, 0] + freq = [1, 1, 1, 1] + sampling_rate = 44100 + fft_norm = 'none' + signal = signal_stub(time, freq, sampling_rate, fft_norm) + dev = Device('dev1', signal) + assert isinstance(dev.freq, type(signal * 1.0)) + assert dev.freq == dev.data * dev.sens + + +def test_MeasurementChain_init(): + chain = MeasurementChain(44100) + assert isinstance(chain, MeasurementChain) + + +def test_MeasurementChain_default_paramerter(): + chain = MeasurementChain(44100) + assert chain.devices == [] + assert chain.freq == 1.0 + assert chain.sampling_rate == 44100 + assert chain.sound_device is None + assert chain.comment is None + + +def test_MeasurementChain_add_device(): + chain = MeasurementChain(44100) + assert len(chain.devices) == 0 + chain.add_device('dev1') + assert len(chain.devices) == 1 + chain.add_device('dev2') + assert len(chain.devices) == 2 + + +def test_MeasurementChain__find_device_index(): + chain = MeasurementChain(44100) + chain.add_device('dev1') + chain.add_device('dev2') + chain.add_device('dev3') + assert chain._find_device_index('dev2') == 1 + + +def test_MeasurementChain__freq(): + chain = MeasurementChain(44100) + assert chain._resp == 1.0 + chain.add_device('dev1', sens=2.0) + assert isinstance(chain._resp, Signal) + assert chain._resp.n_samples == 1 + assert chain._resp.time[0] == 2.0 + + +def test_MeasurementChain_list_devices(): + chain = MeasurementChain(44100) + assert chain.list_devices() == [] + chain.add_device('dev1') + chain.add_device('dev2') + chain.add_device('dev3') + assert chain.list_devices() == ['dev1', 'dev2', 'dev3'] + + +def test_MeasurementChain_remove_device(): + chain = MeasurementChain(44100) + chain.add_device('dev1') + chain.add_device('dev2') + chain.add_device('dev3') + # by number + chain.remove_device(0) + assert chain.list_devices() == ['dev2', 'dev3'] + # by name + chain.remove_device('dev3') + assert chain.list_devices() == ['dev2'] + + +def test_MeasurementChain_reset_devices(): + chain = MeasurementChain(44100) + chain.add_device('dev1') + chain.add_device('dev2') + chain.add_device('dev3') + chain.reset_devices() + assert chain.list_devices() == [] + + +def test_MeasurementChain_device_freq(): + chain = MeasurementChain(44100) + chain.add_device('dev1', sens=1.0) + chain.add_device('dev2', sens=2.0) + chain.add_device('dev3', sens=3.0) + # by number + assert chain.device_freq(1) == 2.0 + # by name + assert chain.device_freq('dev3') == 3.0 + + +def test_MeasurementChain_freq(): + freq = [1, 1, 1, 1] + sampling_rate = 44100 + signal = Signal(freq, sampling_rate, domain='freq') + chain = MeasurementChain(sampling_rate) + sens1 = 2 + sens2 = 3 + chain.add_device('dev1', sens=sens1) + chain.add_device('dev2', data=signal, sens=sens2) + assert chain.freq.n_bins == 4 + npt.assert_equal(chain.freq.freq, signal.freq*sens1*sens2) From 72459499e065bdf39c6be5c033302f122d6892d6 Mon Sep 17 00:00:00 2001 From: AlexanderDeutsch Date: Tue, 16 Mar 2021 18:29:59 +0100 Subject: [PATCH 09/20] add docstrings to tests --- tests/test_mestopy.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_mestopy.py b/tests/test_mestopy.py index 41588ef..f7bf907 100644 --- a/tests/test_mestopy.py +++ b/tests/test_mestopy.py @@ -11,11 +11,14 @@ def test_Device_init(): + """Test to init Device without optinal parameters.""" dev = Device('dev1') assert isinstance(dev, Device) def test_Device_default_parameter(): + """Test the default attributes after + init Device without optinal parameters.""" dev = Device('dev1') assert dev.name == 'dev1' assert dev.data is None @@ -24,6 +27,7 @@ def test_Device_default_parameter(): def test_Device_name(): + """Test name setter and getter of Device class.""" dev = Device('dev1') assert dev.name == 'dev1' dev.name = 'dev2' @@ -31,6 +35,8 @@ def test_Device_name(): def test_Device_data(): + """Test data setter and getter of Device class + with signal_stub.""" dev = Device('dev1') assert dev.data is None time = [1, 0, 0, 0, 0, 0, 0, 0] @@ -44,6 +50,7 @@ def test_Device_data(): def test_Device_sens(): + """Test sens setter and getter of Device class.""" dev = Device('dev1') assert dev.sens == 1 dev.sens = 0.3 @@ -51,6 +58,7 @@ def test_Device_sens(): def test_Device_unit(): + """Test unit setter and getter of Device class.""" dev = Device('dev1') assert dev.unit is None dev.unit = 'mV/Pa' @@ -58,6 +66,7 @@ def test_Device_unit(): def test_Device_freq(): + """Test freq getter of Device init with and without a Signal.""" dev = Device('dev1') assert dev.freq == 1 time = [1, 0, 0, 0, 0, 0, 0, 0] @@ -71,11 +80,14 @@ def test_Device_freq(): def test_MeasurementChain_init(): + """Test to init MeasurementChain without optinal parameters.""" chain = MeasurementChain(44100) assert isinstance(chain, MeasurementChain) def test_MeasurementChain_default_paramerter(): + """Test the default attributes after init + MeasurementChain without optinal parameters.""" chain = MeasurementChain(44100) assert chain.devices == [] assert chain.freq == 1.0 @@ -85,6 +97,7 @@ def test_MeasurementChain_default_paramerter(): def test_MeasurementChain_add_device(): + """Test add_device method of MeasurementChain class.""" chain = MeasurementChain(44100) assert len(chain.devices) == 0 chain.add_device('dev1') @@ -94,6 +107,8 @@ def test_MeasurementChain_add_device(): def test_MeasurementChain__find_device_index(): + """Test private _find_device_index method of + MeasurementChain class.""" chain = MeasurementChain(44100) chain.add_device('dev1') chain.add_device('dev2') @@ -102,6 +117,7 @@ def test_MeasurementChain__find_device_index(): def test_MeasurementChain__freq(): + """Test private _freq method of MeasurementChain class.""" chain = MeasurementChain(44100) assert chain._resp == 1.0 chain.add_device('dev1', sens=2.0) @@ -111,6 +127,7 @@ def test_MeasurementChain__freq(): def test_MeasurementChain_list_devices(): + """Test list_devices method of MeasurementChain class.""" chain = MeasurementChain(44100) assert chain.list_devices() == [] chain.add_device('dev1') @@ -120,6 +137,8 @@ def test_MeasurementChain_list_devices(): def test_MeasurementChain_remove_device(): + """Test remove_device method of MeasurementChain class. + Test with nuber and name as argument.""" chain = MeasurementChain(44100) chain.add_device('dev1') chain.add_device('dev2') @@ -133,6 +152,7 @@ def test_MeasurementChain_remove_device(): def test_MeasurementChain_reset_devices(): + """Test reset_devices method of MeasurementChain class.""" chain = MeasurementChain(44100) chain.add_device('dev1') chain.add_device('dev2') @@ -142,6 +162,9 @@ def test_MeasurementChain_reset_devices(): def test_MeasurementChain_device_freq(): + """Test device_freq method of MeasurementChain class with + devices init with only sens, but no freq-data. + Test with nuber and name as argument.""" chain = MeasurementChain(44100) chain.add_device('dev1', sens=1.0) chain.add_device('dev2', sens=2.0) @@ -153,6 +176,7 @@ def test_MeasurementChain_device_freq(): def test_MeasurementChain_freq(): + """Test freq getter of MeasurementChain class with pyfar.Signal.""" freq = [1, 1, 1, 1] sampling_rate = 44100 signal = Signal(freq, sampling_rate, domain='freq') From a1b7e53cb1ad41a33044a9294a0f7ef1f4f718f4 Mon Sep 17 00:00:00 2001 From: Fabian Brinkmann Date: Mon, 22 Mar 2021 18:58:03 +0100 Subject: [PATCH 10/20] added init structure --- mestopy/__init__.py | 6 +++++- tests/__init__.py | 1 - tests/test_mestopy.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 tests/__init__.py diff --git a/mestopy/__init__.py b/mestopy/__init__.py index 1e7566e..cb226bb 100644 --- a/mestopy/__init__.py +++ b/mestopy/__init__.py @@ -1,5 +1,9 @@ """Top-level package for mestopy.""" __author__ = """The pyfar developer""" -__email__ = 'marco.berzborn@akustik.rwth-aachen.de' +__email__ = 'info@pyfar.org' __version__ = '0.0.1' + +from .mestopy import (Device, MeasurementChain) + +__all__ = ['Device', 'MeasurementChain'] diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 172d321..0000000 --- a/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Unit test package for mestopy.""" diff --git a/tests/test_mestopy.py b/tests/test_mestopy.py index f7bf907..88a45b4 100644 --- a/tests/test_mestopy.py +++ b/tests/test_mestopy.py @@ -2,7 +2,7 @@ """Tests for `mestopy` package.""" -from mestopy.mestopy import Device, MeasurementChain +from mestopy import Device, MeasurementChain from pyfar.testing.stub_utils import signal_stub from pyfar import Signal From 6e912b36cc297f47cd0ec5e89f6e42da1e318511 Mon Sep 17 00:00:00 2001 From: a-deutsch <64502442+al-de@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:11:30 +0100 Subject: [PATCH 11/20] Update docstring of Device Co-authored-by: Fabian Brinkmann --- mestopy/mestopy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 206ed38..a0e287e 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -18,7 +18,7 @@ def __init__(self, name, data=None, sens=1, unit=None): ---------- name : str Name of the device. - data : Signal + data : Signal, None, optional Signal data that reprensets the inversed frequency response of the device. Data can be in domain 'freq' or 'time' and will be transformed if necessary. The default is None, in this case a From 59f4e82dd6635418face94001d8d7078c32add87 Mon Sep 17 00:00:00 2001 From: a-deutsch <64502442+al-de@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:14:25 +0100 Subject: [PATCH 12/20] Update docstring of Device Co-authored-by: Fabian Brinkmann --- mestopy/mestopy.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index a0e287e..b9c8fa9 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -24,10 +24,7 @@ def __init__(self, name, data=None, sens=1, unit=None): transformed if necessary. The default is None, in this case a perfect flat frequency response is assumed and only sensitivity as a factor is applied. - Caution: Make sure to use frequency responses without artefacts, - as they will influence the quality of compensations calculated with - the measurement chain. Most ideal this should be regularized - inversed frequency responses. + Caution: Avoid large gains in the frequency responses because they will boost measurement noise and might cause numerical instabilities. One possibility to avoid this is to use regularized inversion. sens : float, optional Sensitivity of the device as a factor. If neither device_data nor sens is given, add_device generates a device that has no effect to From c648e49ecb8b2560d295f076d3db6a657b050818 Mon Sep 17 00:00:00 2001 From: a-deutsch <64502442+al-de@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:15:13 +0100 Subject: [PATCH 13/20] Update d Co-authored-by: Fabian Brinkmann --- mestopy/mestopy.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index b9c8fa9..51509b0 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -31,8 +31,7 @@ def __init__(self, name, data=None, sens=1, unit=None): the measurement chain as it has no frequency response and a sesitivity (factor) default of 1. unit : str, optional - The units of the sensitivity. Basically a string to describe what - kind of units the sensitivity refers to, e.g., mV/Pa. + The phyiscal unit of the device, e.g., mV/Pa. """ self.name = name self.data = data From 20f7be26edcdb525d30f4e64c4f148520b0ae15f Mon Sep 17 00:00:00 2001 From: a-deutsch <64502442+al-de@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:16:00 +0100 Subject: [PATCH 14/20] Update docstring of MeasurementChain Co-authored-by: Fabian Brinkmann --- mestopy/mestopy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 51509b0..2d82903 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -116,8 +116,8 @@ class MeasurementChain(object): """Class for complete measurement chain. This class holds methods and properties of all devices in the - measurement chain. It can include a single or multiple devices from - 'Device' class. + measurement chain. It can include a single or multiple objects of + the Device class. """ def __init__(self, From f12ef0627476a193cbc304646a6250fa8f579c0f Mon Sep 17 00:00:00 2001 From: a-deutsch <64502442+al-de@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:16:21 +0100 Subject: [PATCH 15/20] Update docstring of MeasurementChain Co-authored-by: Fabian Brinkmann --- mestopy/mestopy.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 2d82903..f7e5d73 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -134,8 +134,7 @@ def __init__(self, sound_device : int Number to identify the sound device used. The default is None. devices : list - A list of instances from 'DeviceObj' class. The default is an - empty list. + A list of Device objects. The default is an empty list. comment : str A comment related to the measurement chain. The default is None. """ From 6990b3c0f245740e0edcd1a95ebd7ea0f3a58f49 Mon Sep 17 00:00:00 2001 From: a-deutsch <64502442+al-de@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:18:17 +0100 Subject: [PATCH 16/20] Update ValueError in case Devices samplingrates do not agree with MeasurementChain Co-authored-by: Fabian Brinkmann --- mestopy/mestopy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index f7e5d73..bce0b48 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -196,7 +196,7 @@ def add_device(self, # is the same if data is not None: if not self.sampling_rate == data.sampling_rate: - raise ValueError("ref_signal has wrong samping_rate") + raise ValueError("Sampling rate of the new device does not agree with the measurement chain.") # add device to chain new_device = Device(name, data=data, sens=sens, unit=unit) From 346632f0af87a67af37f4378dff7c4252f141ef1 Mon Sep 17 00:00:00 2001 From: a-deutsch <64502442+al-de@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:21:20 +0100 Subject: [PATCH 17/20] Update docstring of Device poperty freq Co-authored-by: Fabian Brinkmann --- mestopy/mestopy.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index bce0b48..ce2618a 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -89,9 +89,8 @@ def unit(self, unit): @property def freq(self): - """Returns either a signal, representing the inverted frequency - response of the device multiplied by the sensitivity or the - sensitivity as scalar, when the device has no freqeuncy response. + """Return the inverted frequency multiplied by the sensitivity as a signal, + or the sensitivity as scalar, when the device has no frequency response. """ if self.data is not None: return self.data * self.sens From be50803ec4463a2106a02bd18b3276e980bdf4d8 Mon Sep 17 00:00:00 2001 From: Alexander Deutsch Date: Sat, 27 Mar 2021 17:34:58 +0100 Subject: [PATCH 18/20] Update docstring of Device and resolve some linting problems --- mestopy/mestopy.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index ce2618a..1269dbd 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -20,11 +20,13 @@ def __init__(self, name, data=None, sens=1, unit=None): Name of the device. data : Signal, None, optional Signal data that reprensets the inversed frequency response of - the device. Data can be in domain 'freq' or 'time' and will be - transformed if necessary. The default is None, in this case a - perfect flat frequency response is assumed and only sensitivity as - a factor is applied. - Caution: Avoid large gains in the frequency responses because they will boost measurement noise and might cause numerical instabilities. One possibility to avoid this is to use regularized inversion. + the device. The default is None, in this case a perfect flat + frequency response is assumed and only sensitivity as a factor + is applied. + Caution: Avoid large gains in the frequency responses because + they will boost measurement noise and might cause numerical + instabilities. One possibility to avoid this is to use + regularized inversion. sens : float, optional Sensitivity of the device as a factor. If neither device_data nor sens is given, add_device generates a device that has no effect to @@ -52,8 +54,7 @@ def name(self, name): @property def data(self): - """The freqeuncy dependent data, representing the device. - Type Signal or None.""" + """The freqeuncy dependent data, representing the device.""" return self._data @data.setter @@ -90,7 +91,8 @@ def unit(self, unit): @property def freq(self): """Return the inverted frequency multiplied by the sensitivity as a signal, - or the sensitivity as scalar, when the device has no frequency response. + or the sensitivity as scalar, when the device has no frequency + response. """ if self.data is not None: return self.data * self.sens @@ -195,7 +197,8 @@ def add_device(self, # is the same if data is not None: if not self.sampling_rate == data.sampling_rate: - raise ValueError("Sampling rate of the new device does not agree with the measurement chain.") + raise ValueError("Sampling rate of the new device does" + "not agree with the measurement chain.") # add device to chain new_device = Device(name, data=data, sens=sens, unit=unit) From 39afff30e76afcb3f97e8f143dd80a0700c29d1d Mon Sep 17 00:00:00 2001 From: Alexander Deutsch Date: Sat, 27 Mar 2021 17:54:44 +0100 Subject: [PATCH 19/20] add check of sampling rates, when a list of devices is used to init MeasurementChain --- mestopy/mestopy.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mestopy/mestopy.py b/mestopy/mestopy.py index 1269dbd..69ab300 100644 --- a/mestopy/mestopy.py +++ b/mestopy/mestopy.py @@ -145,6 +145,14 @@ def __init__(self, if isinstance(devices, type(None)): self.devices = [] else: + for dev in devices: + if not isinstance(dev, Device): + raise TypeError('Input data must be type Device.') + if dev.data is None: + continue + if not dev.data.sampling_rate == self.sampling_rate: + raise ValueError("Sampling rate of device does not agree " + "with the measurement chain.") self.devices = devices self._freq() From ee55705dfc806e9c194d3966c27ef67e54ae69af Mon Sep 17 00:00:00 2001 From: Alexander Deutsch Date: Sat, 27 Mar 2021 18:36:40 +0100 Subject: [PATCH 20/20] add conftest.py with a pytest.fixture for flat_freq signal stub --- tests/conftest.py | 19 +++++++++++++++++++ tests/test_mestopy.py | 24 ++++++------------------ 2 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 tests/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..fbc618c --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,19 @@ +import pytest +from pyfar.testing.stub_utils import signal_stub + + +@pytest.fixture +def flat_freq(): + """Flat frequency signal stub. + + Returns + ------- + signal : Signal + Stub of flat freq signal + """ + time = [1, 0, 0, 0, 0, 0, 0, 0] + freq = [1, 1, 1, 1] + sampling_rate = 44100 + fft_norm = 'none' + signal = signal_stub(time, freq, sampling_rate, fft_norm) + return signal diff --git a/tests/test_mestopy.py b/tests/test_mestopy.py index f7bf907..d6a1e26 100644 --- a/tests/test_mestopy.py +++ b/tests/test_mestopy.py @@ -3,8 +3,6 @@ """Tests for `mestopy` package.""" from mestopy.mestopy import Device, MeasurementChain - -from pyfar.testing.stub_utils import signal_stub from pyfar import Signal import numpy.testing as npt @@ -34,19 +32,14 @@ def test_Device_name(): assert dev.name == 'dev2' -def test_Device_data(): +def test_Device_data(flat_freq): """Test data setter and getter of Device class with signal_stub.""" dev = Device('dev1') assert dev.data is None - time = [1, 0, 0, 0, 0, 0, 0, 0] - freq = [1, 1, 1, 1] - sampling_rate = 44100 - fft_norm = 'none' - signal = signal_stub(time, freq, sampling_rate, fft_norm) - dev.data = signal + dev.data = flat_freq assert isinstance(dev.data, Signal) - assert dev.data == signal + assert dev.data == flat_freq def test_Device_sens(): @@ -65,17 +58,12 @@ def test_Device_unit(): assert dev.unit == 'mV/Pa' -def test_Device_freq(): +def test_Device_freq(flat_freq): """Test freq getter of Device init with and without a Signal.""" dev = Device('dev1') assert dev.freq == 1 - time = [1, 0, 0, 0, 0, 0, 0, 0] - freq = [1, 1, 1, 1] - sampling_rate = 44100 - fft_norm = 'none' - signal = signal_stub(time, freq, sampling_rate, fft_norm) - dev = Device('dev1', signal) - assert isinstance(dev.freq, type(signal * 1.0)) + dev = Device('dev1', flat_freq) + assert isinstance(dev.freq, type(flat_freq * 1.0)) assert dev.freq == dev.data * dev.sens