Public Access
fix Signalpath.phase(): do not modify original data in place
phase() overwrote the underlying channel arrays (y[i] *= -1) and returned self, so rotated copies aliased the original object and negative phase angles garbled shared data. It now returns a copy with new arrays and uses numpy.deg2rad for arbitrary angles. Add unittests for phase() including negative angles and non-mutation.
This commit is contained in:
1 parent
e963c2ef3c
commit
8d7d241ec7
2 files changed
+114
-13
No files matched your search
@@ -1,3 +1,5 @@
|
||||
import copy
|
||||
|
||||
import numpy as N
|
||||
|
||||
class Signalpath:
|
||||
@@ -5,33 +7,35 @@ class Signalpath:
|
||||
"""
|
||||
rotate signal by **degrees** for phase cycling, etc.
|
||||
|
||||
The signalpath object itself is not modified, a copy containing the
|
||||
rotated data is returned.
|
||||
|
||||
:param degrees: rotate signal by this value
|
||||
:return:
|
||||
:return: copy of the signalpath object with rotated data
|
||||
"""
|
||||
if self.get_number_of_channels() != 2:
|
||||
raise Exception("rotation defined only for 2 channels")
|
||||
rotated = copy.copy(self)
|
||||
# simple case 0, 90, 180, 270 degree
|
||||
reduced_angle = divmod(degrees, 90)
|
||||
if abs(reduced_angle[1]) < 1e-6:
|
||||
reduced_angle = reduced_angle[0] % 4
|
||||
if reduced_angle == 0:
|
||||
return self
|
||||
rotated.y = list(self.y)
|
||||
|
||||
elif reduced_angle == 1:
|
||||
self.y[1] *= -1
|
||||
self.y = [self.y[1], self.y[0]]
|
||||
rotated.y = [-self.y[1], self.y[0]]
|
||||
|
||||
elif reduced_angle == 2:
|
||||
self.y[0] *= -1
|
||||
self.y[1] *= -1
|
||||
rotated.y = [-self.y[0], -self.y[1]]
|
||||
|
||||
elif reduced_angle == 3:
|
||||
self.y[0] *= -1
|
||||
self.y = [self.y[1], self.y[0]]
|
||||
rotated.y = [self.y[1], -self.y[0]]
|
||||
else:
|
||||
sin_angle = N.sin(degrees / 180.0 * N.pi)
|
||||
cos_angle = N.cos(degrees / 180.0 * N.pi)
|
||||
self.y = [cos_angle * self.y[0] - sin_angle * self.y[1],
|
||||
sin_angle * self.y[0] + cos_angle * self.y[1]]
|
||||
rad_angle = N.deg2rad(degrees)
|
||||
sin_angle = N.sin(rad_angle)
|
||||
cos_angle = N.cos(rad_angle)
|
||||
rotated.y = [cos_angle * self.y[0] - sin_angle * self.y[1],
|
||||
sin_angle * self.y[0] + cos_angle * self.y[1]]
|
||||
|
||||
return self
|
||||
return rotated
|
||||
Reference in new issue
Block a user