Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions pytta/classes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,12 @@ def __truediv__(self, other):
def calib_volt(self, refSignalObj, refVrms, refFreq):
Vrms = refSignalObj.rms()[0]
freqFound = np.round(refSignalObj.freqVector[np.argmax(
refSignalObj.freqSignal)])
np.abs(refSignalObj.freqSignal[:, 0]))])
if not np.isclose(freqFound, float(refFreq), rtol=1e-4):
print('\x1b[0;30;43mATTENTION! Found calibration frequency (' +
'{:.2}'.format(freqFound) +
'{}'.format(freqFound) +
' [Hz]) differs from refFreq (' +
'{:.2}'.format(refFreq) + ' [Hz])\x1b[0m')
'{}'.format(refFreq) + ' [Hz])\x1b[0m')
self.CF = refVrms/Vrms
self.unit = 'V'
return
Expand All @@ -411,7 +411,7 @@ def calib_press(self, refSignalObj, refPrms, refFreq):
# Prms = np.max(np.abs(refSignalObj.freqSignal[:, 0])) #/ (2**(1/2))
Prms = refSignalObj.rms()[0]
freqFound = np.round(refSignalObj.freqVector[np.argmax(
refSignalObj.freqSignal)])
np.abs(refSignalObj.freqSignal[:, 0]))])
if not np.isclose(freqFound, float(refFreq), rtol=1e-4):
print('\x1b[0;30;43mATTENTION! Found calibration frequency (' +
'{}'.format(freqFound) +
Expand Down
29 changes: 29 additions & 0 deletions pytta/classes/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,35 @@ def calib_pressure(self, chIndex, refSignalObj,
raise IndexError('chIndex greater than channels number')
return

def uncalibrate(self, chIndex=None):
"""
Undo calib_pressure or calib_voltage: divide the samples of the
channel by its correction factor and set it back to full scale
(CF = 1, unit 'FS'). Channels that are not calibrated are left as
they are.

Parameters (default), (type):
------------------------------
* chIndex (None), (int):
channel index, starting in 0; None undoes every calibrated
channel.
"""
if chIndex is None:
indexes = range(self.numChannels)
elif chIndex in range(self.numChannels):
indexes = [chIndex]
else:
raise IndexError('chIndex greater than channels number')
for idx in indexes:
channel = self.channels[self.channels.mapping[idx]]
if channel.calibCheck:
self._timeSignal[:, idx] /= channel.CF
channel.CF = 1
channel.calibCheck = False
channel.unit = 'FS'
self._fft()
return

def _to_dict(self):
out = super()._to_dict()
out['channels'] = self.channels._to_dict()
Expand Down
54 changes: 54 additions & 0 deletions tests/test_uncalibrate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Tests for SignalObj.uncalibrate, which undoes calib_pressure and
calib_voltage: the samples are divided by the correction factor and the
channel goes back to full scale. Each test pins one rule.
"""
import os
import unittest

os.environ.setdefault('MPLBACKEND', 'Agg')

import numpy as np

import pytta

FS = 48000


def calibrator(rms):
tt = np.arange(FS) / FS
return pytta.SignalObj(rms * np.sqrt(2) * np.sin(2 * np.pi * 1000 * tt),
'time', FS)


class TestUncalibrate(unittest.TestCase):

def setUp(self):
rng = np.random.default_rng(0)
self.sig = pytta.SignalObj(rng.standard_normal((FS, 2)), 'time', FS)
self.raw = self.sig.timeSignal.copy()
self.sig.calib_pressure(0, calibrator(0.1), refPrms=1.0)
self.sig.calib_voltage(1, calibrator(0.2), refVrms=1.0)

def test_undoes_the_calibration_of_every_channel(self):
self.sig.uncalibrate()
self.assertTrue(np.allclose(self.sig.timeSignal, self.raw,
rtol=1e-5, atol=1e-6))
for ch in self.sig.channels.mapping:
channel = self.sig.channels[ch]
self.assertEqual((channel.CF, channel.calibCheck, channel.unit,
channel.dBRef), (1, False, 'FS', 1))

def test_undoes_one_channel(self):
calibrated = self.sig.timeSignal[:, 1].copy()
self.sig.uncalibrate(0)
self.assertTrue(np.allclose(self.sig.timeSignal[:, 0], self.raw[:, 0],
rtol=1e-5, atol=1e-6))
self.assertTrue(np.array_equal(self.sig.timeSignal[:, 1], calibrated))
self.assertEqual(self.sig.channels[2].unit, 'V')
with self.assertRaises(IndexError):
self.sig.uncalibrate(2)


if __name__ == '__main__':
unittest.main()