-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrepeat.py
More file actions
110 lines (91 loc) · 4.29 KB
/
repeat.py
File metadata and controls
110 lines (91 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
from typing import Optional
import numpy as np
from waveform_editor.tendencies.base import BaseTendency
class RepeatTendency(BaseTendency):
"""
Tendency class for a repeated signal.
"""
def __init__(self, **kwargs):
waveform = kwargs.pop("user_waveform", []) or []
from waveform_editor.waveform import Waveform
self.waveform = Waveform(waveform=waveform, is_repeated=True)
super().__init__(**kwargs)
if not self.waveform.tendencies:
error_msg = "There are no tendencies in the repeated waveform.\n"
self.annotations.add(self.line_number, error_msg)
return
if self.waveform.tendencies[0].start != 0:
error_msg = "The starting point of the first repeated must be set to 0.\n"
self.annotations.add(self.line_number, error_msg)
if self.duration < self.waveform.tendencies[-1].end:
error_msg = (
"The repeated tendency has not completed a single repetition.\n"
"Perhaps increase the duration of the repeated tendency?\n"
)
self.annotations.add(self.line_number, error_msg, is_warning=True)
# Link the last tendency to the first tendency in the repeated waveform
# We must lock the start to 0, otherwise it will take the start value of the
# previous tendency.
self.waveform.tendencies[0].user_start = 0
self.waveform.tendencies[0].set_previous_tendency(self.waveform.tendencies[-1])
self.waveform.tendencies[-1].set_next_tendency(self.waveform.tendencies[0])
self._set_bounds()
self.annotations.add_annotations(self.waveform.annotations)
def _set_bounds(self):
"""Sets the start and end values, as well as derivatives"""
_, start_values = self.get_value(np.array([self.start]))
self.start_value = start_values[0]
start_derivatives = self.get_derivative(np.array([self.start]))
self.start_derivative = start_derivatives[0]
_, end_values = self.get_value(np.array([self.end]))
self.end_value = end_values[0]
end_derivatives = self.get_derivative(np.array([self.end]))
self.end_derivative = end_derivatives[0]
def get_value(
self, time: Optional[np.ndarray] = None
) -> tuple[np.ndarray, np.ndarray]:
"""Get the tendency values at the provided time array. If no time array is
provided, the individual tendencies are responsible for creating a time array,
and these are appended.
Args:
time: The time array on which to generate points.
Returns:
Tuple containing the time and its tendency values.
"""
if not self.waveform.tendencies:
return np.array([0]), np.array([0])
length = self.waveform.calc_length()
if time is None:
time, values = self.waveform.get_value()
repeat = int(np.ceil(self.duration / length))
repetition_array = np.arange(repeat) * length
time = (time + repetition_array[:, np.newaxis]).flatten() + self.start
values = np.tile(values, repeat)
# cut off everything after self.end
assert time[-1] >= self.end
cut_index = np.argmax(time >= self.end)
time = time[: cut_index + 1]
values = values[: cut_index + 1]
if time[-1] != self.end:
time[-1] = self.end
_, end_array = self.waveform.get_value(
np.array([(self.end - self.start) % length])
)
values[-1] = end_array[0]
else:
relative_times = (time - self.start) % length
_, values = self.waveform.get_value(relative_times)
return time, values
def get_derivative(self, time: np.ndarray) -> np.ndarray:
"""Get the values of the derivatives at the provided time array.
Args:
time: The time array on which to generate points.
Returns:
numpy array containing the derivatives
"""
if not self.waveform.tendencies:
return np.array([0])
length = self.waveform.calc_length()
relative_times = (time - self.start) % length
derivatives = self.waveform.get_derivative(relative_times)
return derivatives