pyCLINE 0.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyCLINE/__init__.py +22 -0
- pyCLINE/example.py +164 -0
- pyCLINE/generate_data.py +105 -0
- pyCLINE/model.py +1045 -0
- pyCLINE/recovery_methods/__init__.py +15 -0
- pyCLINE/recovery_methods/data_preparation.py +394 -0
- pyCLINE/recovery_methods/nn_training.py +417 -0
- pycline-0.1.7.dist-info/LICENSE +23 -0
- pycline-0.1.7.dist-info/METADATA +40 -0
- pycline-0.1.7.dist-info/RECORD +12 -0
- pycline-0.1.7.dist-info/WHEEL +5 -0
- pycline-0.1.7.dist-info/top_level.txt +1 -0
pyCLINE/model.py
ADDED
@@ -0,0 +1,1045 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import pandas as pd
|
3
|
+
import os
|
4
|
+
import matplotlib.pyplot as plt
|
5
|
+
import jitcdde as jitcdde
|
6
|
+
|
7
|
+
# ------------------- FitzHugh-Nagumo oscillator -------------------
|
8
|
+
class FHN:
|
9
|
+
"""
|
10
|
+
The Fitzhuge-Nagumo model is a simplified model of the electrical activity of a neuron. In this form taken from Prokop et al., iScience (2024).
|
11
|
+
"""
|
12
|
+
def __init__(self, p=[1, 1, 0.3, 0.5, 0.0]):
|
13
|
+
self.p = p # parameters of the model
|
14
|
+
|
15
|
+
def model(self, U):
|
16
|
+
"""
|
17
|
+
Model formulation of the FHN model.
|
18
|
+
With:
|
19
|
+
p = [c, d, eps, b, a]
|
20
|
+
p = [1, 1, 0.3, 0.5, 0.0]
|
21
|
+
Prokop et al., iScience (2024)
|
22
|
+
|
23
|
+
Args:
|
24
|
+
U (array): Array of initial conditions for the model.
|
25
|
+
|
26
|
+
Returns:
|
27
|
+
U (array): Array of the next state of the model.
|
28
|
+
"""
|
29
|
+
u= U[0]
|
30
|
+
v= U[1]
|
31
|
+
# p = [c, d, eps, b, a]; Prokop et al., iScience (2024)
|
32
|
+
# p = [1, 1, 0.3, 0.5, 0.0]
|
33
|
+
return np.array([-u**3 + self.p[0]*u**2 + self.p[1]*u - v,
|
34
|
+
self.p[2]*(u - self.p[3]*v + self.p[4])])
|
35
|
+
|
36
|
+
def vnull(self, u):
|
37
|
+
"""
|
38
|
+
Calculate the v-nullcline of the FHN model
|
39
|
+
|
40
|
+
Args:
|
41
|
+
u (array): Array of values of the v-variable.
|
42
|
+
|
43
|
+
Returns:
|
44
|
+
v: Array of values of the v-nullcline.
|
45
|
+
"""
|
46
|
+
return -u**3 + self.p[0]*u**2 + self.p[1]*u
|
47
|
+
|
48
|
+
def unull(self, v):
|
49
|
+
"""
|
50
|
+
Calculate the u-nullcline of the FHN model
|
51
|
+
|
52
|
+
Args:
|
53
|
+
v (array): Array of values of the v-variable.
|
54
|
+
|
55
|
+
Returns:
|
56
|
+
u: Array of values of the u-nullcline.
|
57
|
+
"""
|
58
|
+
return self.p[3]*v - self.p[4]
|
59
|
+
|
60
|
+
def fixed_points(self):
|
61
|
+
"""
|
62
|
+
Calculate the fixed points of the FHN model.
|
63
|
+
|
64
|
+
Returns:
|
65
|
+
fp (Array): Array of fixed points of the model.
|
66
|
+
"""
|
67
|
+
sol = np.roots([-self.p[3], self.p[3]*self.p[0], (self.p[1]*self.p[3]-1), -self.p[4]])
|
68
|
+
|
69
|
+
rids = np.where(np.imag(sol)==0)
|
70
|
+
rsol = sol[rids]
|
71
|
+
|
72
|
+
fp = np.zeros([2,rsol.shape[0]])
|
73
|
+
|
74
|
+
fp[0,:] = np.real(rsol)
|
75
|
+
fp[1,:] = (fp[0,:] + self.p[4])/self.p[3]
|
76
|
+
|
77
|
+
return fp
|
78
|
+
|
79
|
+
def simulate(self, U, dt):
|
80
|
+
"""
|
81
|
+
Generates the next state of the FHN model using the Runge-Kutta 4th order solver.
|
82
|
+
|
83
|
+
Args:
|
84
|
+
U (array): Array of initial conditions for the model.
|
85
|
+
dt (float): Time step.
|
86
|
+
|
87
|
+
Returns:
|
88
|
+
U (array): Array of the next state of the model.
|
89
|
+
"""
|
90
|
+
return rk4_solver(self.model, U, dt)
|
91
|
+
|
92
|
+
def generate_data(self, x0, dt, N=10000, save=True, plot=False, max_time=2, check_period=False):
|
93
|
+
"""
|
94
|
+
Generates synthetic data for the FHN model.
|
95
|
+
|
96
|
+
Args:
|
97
|
+
x0 (array): Array of initial conditions for the model.
|
98
|
+
dt (float): Time step.
|
99
|
+
N (int, optional): Number of time steps. Defaults to 10000.
|
100
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
101
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
102
|
+
max_time (int, optional): Maximum time for the plot. Defaults to 2.
|
103
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
104
|
+
"""
|
105
|
+
df=simulate_data(self.simulate, x0, dt, N, check_period)
|
106
|
+
if save:
|
107
|
+
save_data(df, f'{self.__class__.__name__}_eps={self.p[2]}_a={self.p[4]}.csv')
|
108
|
+
if plot:
|
109
|
+
plot_data(df, max_time=max_time)
|
110
|
+
|
111
|
+
|
112
|
+
# ------------------- bicubic oscillator -------------------
|
113
|
+
class Bicubic:
|
114
|
+
"""
|
115
|
+
The bicubic model if a model with two nonlinear nullclines (one bistable and one s-shaped) taken from Prokop et al., Chaos (2024).
|
116
|
+
"""
|
117
|
+
def __init__(self,p=[-0.5, 0.5, -0.3]):
|
118
|
+
self.p = p
|
119
|
+
|
120
|
+
def model(self, U):
|
121
|
+
"""
|
122
|
+
Model formulation of the bicubic model.
|
123
|
+
With:
|
124
|
+
p = [-0.5, 0.5, -0.3];
|
125
|
+
Prokop et al., Chaos (2024)
|
126
|
+
|
127
|
+
Args:
|
128
|
+
U (array): Array of initial conditions for the model.
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
U (array): Array of the next state of the model.
|
132
|
+
"""
|
133
|
+
|
134
|
+
u= U[0]
|
135
|
+
v= U[1]
|
136
|
+
return np.array([-u**3 + u**2 + u - v,
|
137
|
+
self.p[0]*v**3 + self.p[1]*v**2 + self.p[2]*v + u])
|
138
|
+
|
139
|
+
def vnull(self, u):
|
140
|
+
"""
|
141
|
+
Calculate the v-nullcline of the bicubic model
|
142
|
+
|
143
|
+
Args:
|
144
|
+
u (array): Array of values of the v-variable.
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
v: Array of values of the v-nullcline.
|
148
|
+
"""
|
149
|
+
return -u**3 + u**2 + u
|
150
|
+
|
151
|
+
def unull(self, v):
|
152
|
+
"""
|
153
|
+
Calculate the u-nullcline of the bicubic model
|
154
|
+
|
155
|
+
Args:
|
156
|
+
v (array): Array of values of the v-variable.
|
157
|
+
|
158
|
+
Returns:
|
159
|
+
u: Array of values of the u-nullcline.
|
160
|
+
"""
|
161
|
+
return -(self.p[0]*v**3 + self.p[1]*v**2 + self.p[2]*v)
|
162
|
+
|
163
|
+
def simulate(self, U, dt):
|
164
|
+
"""
|
165
|
+
Generates the next state of the bicubic model using the Runge-Kutta 4th order solver.
|
166
|
+
|
167
|
+
Args:
|
168
|
+
U (array): Array of initial conditions for the model.
|
169
|
+
dt (float): Time step.
|
170
|
+
|
171
|
+
Returns:
|
172
|
+
U (array): Array of the next state of the model.
|
173
|
+
"""
|
174
|
+
return rk4_solver(self.model, U, dt)
|
175
|
+
|
176
|
+
def generate_data(self, x0, dt, N=10000, save=True, plot=False, max_time=2, check_period=False):
|
177
|
+
"""
|
178
|
+
Generates synthetic data for the biubic model.
|
179
|
+
|
180
|
+
Args:
|
181
|
+
x0 (array): Array of initial conditions for the model.
|
182
|
+
dt (float): Time step.
|
183
|
+
N (int, optional): Number of time steps. Defaults to 10000.
|
184
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
185
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
186
|
+
max_time (int, optional): Maximum time for the plot. Defaults to 2.
|
187
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
188
|
+
"""
|
189
|
+
df=simulate_data(self.simulate, x0, dt, N, check_period)
|
190
|
+
if save:
|
191
|
+
save_data(df, f'{self.__class__.__name__}.csv')
|
192
|
+
if plot:
|
193
|
+
plot_data(df, max_time=max_time)
|
194
|
+
|
195
|
+
# ------------------- gene expression oscillator -------------------
|
196
|
+
class GeneExpression:
|
197
|
+
"""
|
198
|
+
The gene expression model is a model of the regulation of gene expression taken from Novak & Tyson, Nature Rev Mol Cell Biol (2008).
|
199
|
+
"""
|
200
|
+
def __init__(self, p=[1, 0.05, 1, 0.05, 1, 0.05, 1, 1, 0.1, 2]):
|
201
|
+
self.p = p
|
202
|
+
|
203
|
+
def model(self, U):
|
204
|
+
"""
|
205
|
+
Model formulation of the gene expression model.
|
206
|
+
With:
|
207
|
+
p = [S, k1, Kd, kdx, ksy, kdy, k2, ET, Km, KI]
|
208
|
+
p = [1, 0.05, 1, 0.05, 1, 0.05, 1, 1, 0.1, 2];
|
209
|
+
Novak & Tyson, Nature Rev Mol Cell Biol (2008)
|
210
|
+
|
211
|
+
Args:
|
212
|
+
U (array): Array of initial conditions for the model.
|
213
|
+
|
214
|
+
Returns:
|
215
|
+
U (array): Array of the next state of the model.
|
216
|
+
"""
|
217
|
+
u= U[0]
|
218
|
+
v= U[1]
|
219
|
+
# p = [S, k1, Kd, kdx, ksy, kdy, k2, ET, Km, KI]
|
220
|
+
# p = [1, 0.05, 1, 0.05, 1, 0.05, 1, 1, 0.1, 2]; Novak & Tyson, Nature Rev Mol Cell Biol (2008)
|
221
|
+
return np.array([self.p[4]*v - self.p[5]*u - self.p[6]*self.p[7]*u/(self.p[8] + u + self.p[9]*u**2),
|
222
|
+
self.p[1]*self.p[0]*self.p[2]**4/(self.p[2]**4 + u**4) - self.p[3]*v])
|
223
|
+
|
224
|
+
def vnull(self, v):
|
225
|
+
"""
|
226
|
+
Calculate the v-nullcline of the gene expression model
|
227
|
+
|
228
|
+
Args:
|
229
|
+
v (array): Array of values of the v-variable.
|
230
|
+
|
231
|
+
Returns:
|
232
|
+
u: Array of values of the v-nullcline.
|
233
|
+
"""
|
234
|
+
return self.p[1]*self.p[0]/self.p[3]*self.p[2]**4/(self.p[2]**4 + v**4)
|
235
|
+
|
236
|
+
def unull(self, v):
|
237
|
+
"""
|
238
|
+
Calculate the u-nullcline of the gene expression model
|
239
|
+
|
240
|
+
Args:
|
241
|
+
v (array): Array of values of the v-variable.
|
242
|
+
|
243
|
+
Returns:
|
244
|
+
u: Array of values of the u-nullcline.
|
245
|
+
"""
|
246
|
+
return self.p[5]*v/self.p[4] + self.p[6]*self.p[7]*v/(self.p[8] + v + self.p[9]*v**2)
|
247
|
+
|
248
|
+
def simulate(self, U, dt):
|
249
|
+
"""
|
250
|
+
Generates the next state of the gene expression model using the Runge-Kutta 4th order solver.
|
251
|
+
|
252
|
+
Args:
|
253
|
+
U (array): Array of initial conditions for the model.
|
254
|
+
dt (float): Time step.
|
255
|
+
|
256
|
+
Returns:
|
257
|
+
U (array): Array of the next state of the model.
|
258
|
+
"""
|
259
|
+
return rk4_solver(self.model, U, dt)
|
260
|
+
|
261
|
+
def generate_data(self, x0, dt, N=10000, save=True, plot=False, max_time=10, check_period=False):
|
262
|
+
"""
|
263
|
+
Generates synthetic data for the gene expression model.
|
264
|
+
|
265
|
+
Args:
|
266
|
+
x0 (array): Array of initial conditions for the model.
|
267
|
+
dt (float): Time step.
|
268
|
+
N (int, optional): Number of time steps. Defaults to 10000.
|
269
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
270
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
271
|
+
max_time (int, optional): Maximum time for the plot. Defaults to 10.
|
272
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
273
|
+
"""
|
274
|
+
df=simulate_data(self.simulate, x0, dt, N, check_period)
|
275
|
+
if save:
|
276
|
+
save_data(df, f'{self.__class__.__name__}.csv')
|
277
|
+
if plot:
|
278
|
+
plot_data(df, max_time=max_time)
|
279
|
+
|
280
|
+
# ------------------- Gylcolytic oscillator -------------------
|
281
|
+
class GlycolyticOscillations:
|
282
|
+
"""
|
283
|
+
The glycolytic oscillator is a model of glycolytic oscillations introduced in Prokop et al., iScience (2024) and in
|
284
|
+
this form taken from Prokop et al., Chaos (2024).
|
285
|
+
"""
|
286
|
+
def __init__(self, p=[-0.3, -2.2, 0.25, -0.5, 0.5, 1.8, 0.7, -0.3]):
|
287
|
+
self.p = p
|
288
|
+
|
289
|
+
def model(self, U):
|
290
|
+
"""
|
291
|
+
Model formulation of the glycolytic oscillations model.
|
292
|
+
With:
|
293
|
+
p = [a, b, c, d, e, f, g, h]
|
294
|
+
p = [-0.3, -2.2, 0.25, -0.5, 0.5, 1.8, 0.7, -0.3]
|
295
|
+
Prokop et al., Chaos (2024)
|
296
|
+
|
297
|
+
Args:
|
298
|
+
U (array): Array of initial conditions for the model.
|
299
|
+
|
300
|
+
Returns:
|
301
|
+
U (array): Array of the next state of the model.
|
302
|
+
"""
|
303
|
+
u= U[0]
|
304
|
+
v= U[1]
|
305
|
+
|
306
|
+
return np.array([self.p[0]*u + self.p[1]*v + self.p[2]*u**2 + self.p[3]*u**3 + self.p[4]*v**3,
|
307
|
+
self.p[5]*u+self.p[6]*v+self.p[7]*u**3])
|
308
|
+
|
309
|
+
def simulate(self, U, dt):
|
310
|
+
"""
|
311
|
+
Generates the next state of the glycolytic oscillations model using the Runge-Kutta 4th order solver.
|
312
|
+
|
313
|
+
Args:
|
314
|
+
U (array): Array of initial conditions for the model.
|
315
|
+
dt (float): Time step.
|
316
|
+
|
317
|
+
Returns:
|
318
|
+
U (array): Array of the next state of the model.
|
319
|
+
"""
|
320
|
+
return rk4_solver(self.model, U, dt)
|
321
|
+
|
322
|
+
def generate_data(self, x0, dt, N=10000, save=True, plot=False, max_time=10, check_period=False):
|
323
|
+
"""
|
324
|
+
Generates synthetic data for the glycolytic oscillations model.
|
325
|
+
|
326
|
+
Args:
|
327
|
+
x0 (array): Array of initial conditions for the model.
|
328
|
+
dt (float): Time step.
|
329
|
+
N (int, optional): Number of time steps. Defaults to 10000.
|
330
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
331
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
332
|
+
max_time (int, optional): Maximum time for the plot. Defaults to 10.
|
333
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
334
|
+
"""
|
335
|
+
df=simulate_data(self.simulate, x0, dt, N, check_period)
|
336
|
+
if save:
|
337
|
+
save_data(df, f'{self.__class__.__name__}.csv')
|
338
|
+
if plot:
|
339
|
+
plot_data(df, max_time=max_time)
|
340
|
+
|
341
|
+
# ------------------- Goodwin oscillator -------------------
|
342
|
+
class Goodwin:
|
343
|
+
"""
|
344
|
+
The Goodwin model is a three dimensional model for phosphorylation/dephosphorylation processes of a transcription factor,
|
345
|
+
taken in this form from Gonze et al., Acta Biotheoretica (2021), parameters from Prokop et al. (2024).
|
346
|
+
"""
|
347
|
+
def __init__(self, p=[1,1,1,0.1,0.1,0.1,10,1]):
|
348
|
+
self.p = p
|
349
|
+
|
350
|
+
def model(self, U):
|
351
|
+
"""
|
352
|
+
Model formulation of the Goodwin model.
|
353
|
+
With:
|
354
|
+
p = [a,b,c,d,e,f,n,K]
|
355
|
+
p = [1,1,1,0.1,0.1,0.1,10,1]
|
356
|
+
Prokop et al., iScience (2024)
|
357
|
+
|
358
|
+
Args:
|
359
|
+
U (array): Array of initial conditions for the model.
|
360
|
+
|
361
|
+
Returns:
|
362
|
+
U (array): Array of the next state of the model.
|
363
|
+
"""
|
364
|
+
u= U[0]
|
365
|
+
v= U[1]
|
366
|
+
w= U[2]
|
367
|
+
# p = [a,b,c,d,e,f,n,K]
|
368
|
+
# p = [1,1,1,0.1,0.1,0.1,10,1]; from Prokop et al. (2024)
|
369
|
+
return np.array([self.p[0]*(self.p[7]**self.p[6])/(self.p[7]**self.p[6] + w**self.p[6]) - self.p[3]*u,
|
370
|
+
self.p[1]*u - self.p[4]*v,
|
371
|
+
self.p[2]*v - self.p[5]*w])
|
372
|
+
def unull(self, v, w):
|
373
|
+
"""
|
374
|
+
Calculate the u-nullcline of the Goodwin model
|
375
|
+
|
376
|
+
Args:
|
377
|
+
v (array): Array of values of the v-variable.
|
378
|
+
w (array): Array of values of the w-variable.
|
379
|
+
|
380
|
+
Returns:
|
381
|
+
u: Array of values of the u-nullcline.
|
382
|
+
"""
|
383
|
+
return self.p[0]/self.p[3]*((self.p[7]**self.p[6])/(self.p[7]**self.p[6] + w**self.p[6])) + 0 * v
|
384
|
+
|
385
|
+
def vnull(self, u, w):
|
386
|
+
"""
|
387
|
+
Calculate the v-nullcline of the Goodwin model
|
388
|
+
|
389
|
+
Args:
|
390
|
+
u (array): Array of values of the v-variable.
|
391
|
+
w (array): Array of values of the w-variable.
|
392
|
+
|
393
|
+
Returns:
|
394
|
+
v: Array of values of the v-nullcline.
|
395
|
+
"""
|
396
|
+
return self.p[1]*u/self.p[4] + 0 * w
|
397
|
+
|
398
|
+
def wnull(self, u, v):
|
399
|
+
"""
|
400
|
+
Calculate the w-nullcline of the Goodwin model
|
401
|
+
|
402
|
+
Args:
|
403
|
+
u (array): Array of values of the u-variable.
|
404
|
+
v (array): Array of values of the v-variable.
|
405
|
+
|
406
|
+
Returns:
|
407
|
+
w: Array of values of the w-nullcline.
|
408
|
+
"""
|
409
|
+
return self.p[2]*v/self.p[5] + 0 * u
|
410
|
+
|
411
|
+
def simulate(self, U, dt):
|
412
|
+
"""
|
413
|
+
Generates the next state of the Goodwin model using the Runge-Kutta 4th order solver.
|
414
|
+
|
415
|
+
Args:
|
416
|
+
U (array): Array of initial conditions for the model.
|
417
|
+
dt (float): Time step.
|
418
|
+
|
419
|
+
Returns:
|
420
|
+
U (array): Array of the next state of the model.
|
421
|
+
"""
|
422
|
+
return rk4_solver(self.model, U, dt)
|
423
|
+
|
424
|
+
def generate_data(self, x0, dt, N=10000, save=True, plot=False, max_time=10, check_period=False):
|
425
|
+
"""
|
426
|
+
Generates synthetic data for the gene expression model.
|
427
|
+
|
428
|
+
Args:
|
429
|
+
x0 (array): Array of initial conditions for the model.
|
430
|
+
dt (float): Time step.
|
431
|
+
N (int, optional): Number of time steps. Defaults to 10000.
|
432
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
433
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
434
|
+
max_time (int, optional): Maximum time for the plot. Defaults to 10.
|
435
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
436
|
+
"""
|
437
|
+
df=simulate_data(self.simulate, x0, dt, N, check_period)
|
438
|
+
if save:
|
439
|
+
save_data(df, f'{self.__class__.__name__}.csv')
|
440
|
+
if plot:
|
441
|
+
plot_data(df, max_time=max_time)
|
442
|
+
|
443
|
+
# ------------------- Oregonator oscillator -------------------
|
444
|
+
|
445
|
+
class Oregonator:
|
446
|
+
"""
|
447
|
+
The Oregonator model is a model of the Belousov-Zhabotinsky reaction, taken from Tyson, Journal of Chemical Physics (1975).
|
448
|
+
"""
|
449
|
+
def __init__(self, p = [0.005,3,0.60,1e-2]):
|
450
|
+
self.p = p
|
451
|
+
|
452
|
+
def model(self, U):
|
453
|
+
"""
|
454
|
+
Model formulation of the Oregonator model.
|
455
|
+
With:
|
456
|
+
p = [q,p,f,e]
|
457
|
+
p = [0.005,3,0.60,1e-2]
|
458
|
+
Tyson, Journal of Chemical Physics (1975)
|
459
|
+
|
460
|
+
Args:
|
461
|
+
U (array): Array of initial conditions for the model.
|
462
|
+
|
463
|
+
Returns:
|
464
|
+
U (array): Array of the next state of the model.
|
465
|
+
"""
|
466
|
+
x, y, z = U
|
467
|
+
#1977 Tyson
|
468
|
+
q=self.p[0]
|
469
|
+
p=self.p[1]
|
470
|
+
f=self.p[2] #0.1-2.0
|
471
|
+
e=self.p[3]
|
472
|
+
a=1-f+(3*f)*q/(1-f)
|
473
|
+
b=(1-f)/(q)-(1-3*f)/(1-f)
|
474
|
+
g=f-(f*q)/(1-f)
|
475
|
+
d=(1-f)/(q)+(1+f)/(1-f)
|
476
|
+
|
477
|
+
dx=(1/e)*(-a*x-b*y-q*x**2-x*y)
|
478
|
+
dy=-g*x-d*y+f*z-x*y
|
479
|
+
dz=(1/p)*(x-z)
|
480
|
+
return np.array([dx, dy, dz])
|
481
|
+
|
482
|
+
def xnull(self, x, z):
|
483
|
+
"""
|
484
|
+
Calculate the x-nullcline of the Oregonator model
|
485
|
+
|
486
|
+
Args:
|
487
|
+
x (array): Array of values of the x-variable.
|
488
|
+
z (array): Array of values of the z-variable.
|
489
|
+
|
490
|
+
Returns:
|
491
|
+
y: Array of values of the x-nullcline.
|
492
|
+
"""
|
493
|
+
q=self.p[0]
|
494
|
+
p=self.p[1]
|
495
|
+
f=self.p[2] #0.1-2.0
|
496
|
+
e=self.p[3]
|
497
|
+
a=1-f+(3*f)*q/(1-f)
|
498
|
+
b=(1-f)/(q)-(1-3*f)/(1-f)
|
499
|
+
g=f-(f*q)/(1-f)
|
500
|
+
d=(1-f)/(q)+(1+f)/(1-f)
|
501
|
+
return (-a*x-q*x**2)/(b+x) + 0*z
|
502
|
+
|
503
|
+
def ynull(self, x, y):
|
504
|
+
"""
|
505
|
+
Calculate the y-nullcline of the Oregonator model
|
506
|
+
|
507
|
+
Args:
|
508
|
+
x (array): Array of values of the x-variable.
|
509
|
+
y (array): Array of values of the y-variable.
|
510
|
+
|
511
|
+
Returns:
|
512
|
+
z: Array of values of the y-nullcline.
|
513
|
+
"""
|
514
|
+
q=self.p[0]
|
515
|
+
p=self.p[1]
|
516
|
+
f=self.p[2] #0.1-2.0
|
517
|
+
e=self.p[3]
|
518
|
+
a=1-f+(3*f)*q/(1-f)
|
519
|
+
b=(1-f)/(q)-(1-3*f)/(1-f)
|
520
|
+
g=f-(f*q)/(1-f)
|
521
|
+
d=(1-f)/(q)+(1+f)/(1-f)
|
522
|
+
return (1/f)*(g*x+d*y+x*y)
|
523
|
+
|
524
|
+
def znull(self, x, y):
|
525
|
+
"""
|
526
|
+
Calculate the x-nullcline of the Oregonator model
|
527
|
+
|
528
|
+
Args:
|
529
|
+
x (array): Array of values of the x-variable.
|
530
|
+
y (array): Array of values of the y-variable.
|
531
|
+
|
532
|
+
Returns:
|
533
|
+
z: Array of values of the z-nullcline.
|
534
|
+
"""
|
535
|
+
return x + 0*y
|
536
|
+
|
537
|
+
def simulate(self, U, dt):
|
538
|
+
"""
|
539
|
+
Generates the next state of the Oregonator model using the Runge-Kutta 4th order solver.
|
540
|
+
|
541
|
+
Args:
|
542
|
+
U (array): Array of initial conditions for the model.
|
543
|
+
dt (float): Time step.
|
544
|
+
|
545
|
+
Returns:
|
546
|
+
U (array): Array of the next state of the model.
|
547
|
+
"""
|
548
|
+
return rk4_solver(self.model, U, dt)
|
549
|
+
|
550
|
+
def generate_data(self, x0, dt, N=10000, save=True, plot=False, max_time=10, check_period=False):
|
551
|
+
"""
|
552
|
+
Generates synthetic data for the Oregonator model.
|
553
|
+
|
554
|
+
Args:
|
555
|
+
x0 (array): Array of initial conditions for the model.
|
556
|
+
dt (float): Time step.
|
557
|
+
N (int, optional): Number of time steps. Defaults to 10000.
|
558
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
559
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
560
|
+
max_time (int, optional): Maximum time for the plot. Defaults to 10.
|
561
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
562
|
+
"""
|
563
|
+
df=simulate_data(self.simulate, x0, dt, N, check_period)
|
564
|
+
if save:
|
565
|
+
save_data(df, f'{self.__class__.__name__}.csv')
|
566
|
+
if plot:
|
567
|
+
plot_data(df, max_time=max_time)
|
568
|
+
|
569
|
+
class Lorenz:
|
570
|
+
"""
|
571
|
+
The Lorenz model is a simple model of atmospheric convection, taken from Lorenz, Journal of the Atmospheric Sciences (1963).
|
572
|
+
"""
|
573
|
+
def __init__(self, p = [-0.5,65]):
|
574
|
+
self.p = p
|
575
|
+
|
576
|
+
def model(self, U):
|
577
|
+
"""
|
578
|
+
Model formulation of the Lorenz model.
|
579
|
+
With:
|
580
|
+
p = [a, rho]
|
581
|
+
p = [-0.5,65]
|
582
|
+
|
583
|
+
Args:
|
584
|
+
U (array): Array of initial conditions for the model.
|
585
|
+
|
586
|
+
Returns:
|
587
|
+
U (array): Array of the next state of the model.
|
588
|
+
"""
|
589
|
+
x,y,z = U
|
590
|
+
a, rho = self.p
|
591
|
+
return np.array([a*rho*(x-y)-a*y*z, rho*x - y -x*z, -z +x*y])
|
592
|
+
|
593
|
+
def xnull(self, y, z):
|
594
|
+
"""
|
595
|
+
Calculate the x-nullcline of the Lorenz model
|
596
|
+
|
597
|
+
Args:
|
598
|
+
y (array): Array of values of the y-variable.
|
599
|
+
z (array): Array of values of the z-variable.
|
600
|
+
|
601
|
+
Returns:
|
602
|
+
x: Array of values of the x-nullcline.
|
603
|
+
"""
|
604
|
+
a, rho = self.p
|
605
|
+
return (1/rho)*y*z +y
|
606
|
+
|
607
|
+
def ynull(self, x, z):
|
608
|
+
"""
|
609
|
+
Calculate the y-nullcline of the Lorenz model
|
610
|
+
|
611
|
+
Args:
|
612
|
+
x (array): Array of values of the x-variable.
|
613
|
+
z (array): Array of values of the z-variable.
|
614
|
+
|
615
|
+
Returns:
|
616
|
+
y: Array of values of the y-nullcline.
|
617
|
+
"""
|
618
|
+
a, rho = self.p
|
619
|
+
return x*z - rho*x
|
620
|
+
|
621
|
+
def znull(self, x, y):
|
622
|
+
"""
|
623
|
+
Calculate the z-nullcline of the Lorenz model
|
624
|
+
|
625
|
+
Args:
|
626
|
+
x (array): Array of values of the x-variable.
|
627
|
+
y (array): Array of values of the y-variable.
|
628
|
+
|
629
|
+
Returns:
|
630
|
+
z: Array of values of the z-nullcline.
|
631
|
+
"""
|
632
|
+
return x*y
|
633
|
+
|
634
|
+
def simulate(self, U, dt):
|
635
|
+
"""
|
636
|
+
Generates the next state of the Lorenz model using the Runge-Kutta 4th order solver.
|
637
|
+
|
638
|
+
Args:
|
639
|
+
U (array): Array of initial conditions for the model.
|
640
|
+
dt (float): Time step.
|
641
|
+
|
642
|
+
Returns:
|
643
|
+
U (array): Array of the next state of the model.
|
644
|
+
"""
|
645
|
+
return rk4_solver(self.model, U, dt)
|
646
|
+
|
647
|
+
def generate_data(self, x0, dt, N=10000, save=True, plot=False, max_time=25, check_period=False):
|
648
|
+
"""
|
649
|
+
Generates synthetic data for the Oregonator model.
|
650
|
+
|
651
|
+
Args:
|
652
|
+
x0 (array): Array of initial conditions for the model.
|
653
|
+
dt (float): Time step.
|
654
|
+
N (int, optional): Number of time steps. Defaults to 10000.
|
655
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
656
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
657
|
+
max_time (int, optional): Maximum time for the plot. Defaults to 25.
|
658
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
659
|
+
"""
|
660
|
+
df=simulate_data(self.simulate, x0, dt, N, check_period)
|
661
|
+
if save:
|
662
|
+
save_data(df, f'{self.__class__.__name__}.csv')
|
663
|
+
if plot:
|
664
|
+
plot_data(df, max_time=max_time)
|
665
|
+
|
666
|
+
class Roessler:
|
667
|
+
"""
|
668
|
+
The Roessler model is a simple model of a chaotic oscillator, taken from Roessler, Zeitschrift für Naturforschung A (1976).
|
669
|
+
"""
|
670
|
+
def __init__(self, p = [0.2,0.2,1]):
|
671
|
+
self.p = p
|
672
|
+
|
673
|
+
def model(self, U):
|
674
|
+
"""
|
675
|
+
Model formulation of the Roessler model.
|
676
|
+
With:
|
677
|
+
p = [abc]
|
678
|
+
p = [0.2,0.2,1]
|
679
|
+
Roessler, Zeitschrift für Naturforschung A (1976)
|
680
|
+
|
681
|
+
Args:
|
682
|
+
U (array): Array of initial conditions for the model.
|
683
|
+
|
684
|
+
Returns:
|
685
|
+
U (array): Array of the next state of the model.
|
686
|
+
"""
|
687
|
+
x,y,z = U
|
688
|
+
a,b,c=self.p
|
689
|
+
dx=-y-z
|
690
|
+
dy = x+a*y
|
691
|
+
dz = b+(x-c)*z
|
692
|
+
return np.array([dx, dy, dz])
|
693
|
+
|
694
|
+
def xnull(self, x, z):
|
695
|
+
"""
|
696
|
+
Calculate the x-nullcline of the Roessler model
|
697
|
+
|
698
|
+
Args:
|
699
|
+
x (array): Array of values of the x-variable.
|
700
|
+
z (array): Array of values of the z-variable.
|
701
|
+
|
702
|
+
Returns:
|
703
|
+
y: Array of values of the x-nullcline.
|
704
|
+
"""
|
705
|
+
a,b,c=self.p
|
706
|
+
return -z
|
707
|
+
|
708
|
+
def ynull(self, x, z):
|
709
|
+
"""
|
710
|
+
Calculate the y-nullcline of the Roessler model
|
711
|
+
|
712
|
+
Args:
|
713
|
+
x (array): Array of values of the x-variable.
|
714
|
+
z (array): Array of values of the z-variable.
|
715
|
+
|
716
|
+
Returns:
|
717
|
+
y: Array of values of the y-nullcline.
|
718
|
+
"""
|
719
|
+
a,b,c=self.p
|
720
|
+
return -(1/a)*x
|
721
|
+
|
722
|
+
def znull(self, x, y):
|
723
|
+
"""
|
724
|
+
Calculate the z-nullcline of the Roessler model
|
725
|
+
|
726
|
+
Args:
|
727
|
+
x (array): Array of values of the x-variable.
|
728
|
+
y (array): Array of values of the y-variable.
|
729
|
+
|
730
|
+
Returns:
|
731
|
+
z: Array of values of the z-nullcline.
|
732
|
+
"""
|
733
|
+
a,b,c=self.p
|
734
|
+
return b/(c-x)
|
735
|
+
|
736
|
+
def simulate(self, U, dt):
|
737
|
+
"""
|
738
|
+
Generates the next state of the Roessler model using the Runge-Kutta 4th order solver.
|
739
|
+
|
740
|
+
Args:
|
741
|
+
U (array): Array of initial conditions for the model.
|
742
|
+
dt (float): Time step.
|
743
|
+
|
744
|
+
Returns:
|
745
|
+
U (array): Array of the next state of the model.
|
746
|
+
"""
|
747
|
+
return rk4_solver(self.model, U, dt)
|
748
|
+
|
749
|
+
def generate_data(self, x0, dt, N=10000, save=True, plot=False, max_time=25, check_period=False):
|
750
|
+
"""
|
751
|
+
Generates synthetic data for the Roessler model.
|
752
|
+
|
753
|
+
Args:
|
754
|
+
x0 (array): Array of initial conditions for the model.
|
755
|
+
dt (float): Time step.
|
756
|
+
N (int, optional): Number of time steps. Defaults to 10000.
|
757
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
758
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
759
|
+
max_time (int, optional): Maximum time for the plot. Defaults to 25.
|
760
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
761
|
+
"""
|
762
|
+
df=simulate_data(self.simulate, x0, dt, N, check_period)
|
763
|
+
if save:
|
764
|
+
save_data(df, f'{self.__class__.__name__}.csv')
|
765
|
+
if plot:
|
766
|
+
plot_data(df, max_time=max_time)
|
767
|
+
|
768
|
+
# ------------------- Delay oscillator -------------------
|
769
|
+
class DelayOscillator:
|
770
|
+
"""
|
771
|
+
Simple model of a Delay Oscillator with a single delay, inspired by Lewis, Current Biology (2003)
|
772
|
+
"""
|
773
|
+
def __init__(self, p=[4,10,2]):
|
774
|
+
self.p = p
|
775
|
+
|
776
|
+
def model(self):
|
777
|
+
"""
|
778
|
+
Model formulation of the delay oscillator model.
|
779
|
+
With:
|
780
|
+
p = [beta, tau, n]
|
781
|
+
p = [4,10,2]
|
782
|
+
|
783
|
+
Args:
|
784
|
+
U (array): Array of initial conditions for the model.
|
785
|
+
|
786
|
+
Returns:
|
787
|
+
U (array): Array of the next state of the model.
|
788
|
+
"""
|
789
|
+
self.DDE = [self.p[0]/(1+jitcdde.y(0,jitcdde.t-self.p[1])**self.p[2])-jitcdde.y(0)]
|
790
|
+
return self.DDE
|
791
|
+
|
792
|
+
def unull(self, y):
|
793
|
+
"""
|
794
|
+
Calculate the u-nullcline of the delay oscillator model
|
795
|
+
|
796
|
+
Args:
|
797
|
+
y (array): Array of values of the v-variable.
|
798
|
+
|
799
|
+
Returns:
|
800
|
+
x: Array of values of the u-nullcline.
|
801
|
+
"""
|
802
|
+
return self.p[0]/(1+y**self.p[2])
|
803
|
+
|
804
|
+
def vnull(self, x):
|
805
|
+
"""
|
806
|
+
Calculate the u-nullcline of the delay oscillator model
|
807
|
+
|
808
|
+
Args:
|
809
|
+
x (array): Array of values of the u-variable.
|
810
|
+
|
811
|
+
Returns:
|
812
|
+
y: Array of values of the v-nullcline.
|
813
|
+
"""
|
814
|
+
return (self.p[0]/x-1)**(1/self.p[2])
|
815
|
+
|
816
|
+
def simulate(self, dt, t_max, y_0=0):
|
817
|
+
"""
|
818
|
+
Simulates the delay oscillatory model using the jitcdde solver.
|
819
|
+
|
820
|
+
Args:
|
821
|
+
dt (float): Time step.
|
822
|
+
t_max (float): Maximum time of the simulation.
|
823
|
+
y_0 (int, optional): Initial condition. Defaults to 0.
|
824
|
+
|
825
|
+
Returns:
|
826
|
+
array : Simulated data of the model.
|
827
|
+
"""
|
828
|
+
self.model()
|
829
|
+
DDE = jitcdde.jitcdde(self.DDE)
|
830
|
+
DDE.constant_past(y_0)
|
831
|
+
DDE.step_on_discontinuities()
|
832
|
+
|
833
|
+
data = []
|
834
|
+
for time in np.arange(DDE.t, DDE.t +t_max, dt):
|
835
|
+
data.append(DDE.integrate(time))
|
836
|
+
data = np.array(data)
|
837
|
+
|
838
|
+
return data
|
839
|
+
|
840
|
+
def generate_data(self, y_0, dt, t_max, save=True, plot=False, check_period=False):
|
841
|
+
"""
|
842
|
+
Generates synthetic data for the delay oscillator model.
|
843
|
+
|
844
|
+
Args:
|
845
|
+
y_0 (float): Initial condition for the model.
|
846
|
+
dt (float): Time step.
|
847
|
+
t_max (float): Maximum time of the simulation.
|
848
|
+
save (bool, optional): Save the generated data to a csv file. Defaults to True.
|
849
|
+
plot (bool, optional): Plot the generated data. Defaults to False.
|
850
|
+
check_period (bool, optional): Check the period of the oscillation. Defaults to False.
|
851
|
+
"""
|
852
|
+
data = self.simulate( dt, t_max,y_0)
|
853
|
+
df = pd.DataFrame(data, columns=['u'])
|
854
|
+
df['time'] = np.arange(data.shape[0])*dt
|
855
|
+
if save:
|
856
|
+
save_data(df, f'{self.__class__.__name__}.csv')
|
857
|
+
if plot:
|
858
|
+
plot_data(df, max_time=t_max)
|
859
|
+
|
860
|
+
|
861
|
+
|
862
|
+
# ------------------- 4th-order Runge-Kutta solver -------------------
|
863
|
+
|
864
|
+
def rk4_solver(f, u, dt):
|
865
|
+
"""
|
866
|
+
Rung-Kutta 4th order solver for a system of ODEs.
|
867
|
+
|
868
|
+
Args:
|
869
|
+
f (function): Function that describes the system of ODEs. For model classes it is the model method.
|
870
|
+
u (float): Value of a state variable at time t.
|
871
|
+
dt (float): Time step.
|
872
|
+
|
873
|
+
Returns:
|
874
|
+
u[i+1] (float): Value of a state variable at time t+dt.
|
875
|
+
"""
|
876
|
+
k1 = f(u)
|
877
|
+
k2 = f(u + k1*dt/2)
|
878
|
+
k3 = f(u + k2*dt/2)
|
879
|
+
k4 = f(u + k3*dt)
|
880
|
+
|
881
|
+
return u + dt/6*(k1 + 2*k2 + 2*k3 + k4)
|
882
|
+
|
883
|
+
# ------------------- Generate and save data of multiple IC to csv -------------------
|
884
|
+
|
885
|
+
def simulate_data (simulate, x0, dt, N=10000, check_period=False):
|
886
|
+
"""
|
887
|
+
Generate synthetic data for a given model and initial conditions.
|
888
|
+
|
889
|
+
Args:
|
890
|
+
simulate (method): Method that simulates the model. For model classes it is the simulate method.
|
891
|
+
x0 (array of floats): Initial conditions for the model.
|
892
|
+
dt (float): Time step.
|
893
|
+
N (int, optional): Number of timesteps. Defaults to 10000.
|
894
|
+
check_period (bool, optional): Limits the amount of periods calculated. Defaults to True.
|
895
|
+
|
896
|
+
Returns:
|
897
|
+
df (pandas DataFrame): DataFrame with the synthetic data.
|
898
|
+
"""
|
899
|
+
df = pd.DataFrame()
|
900
|
+
sim_count = 1
|
901
|
+
time = np.arange(N)*dt
|
902
|
+
# print(x0,len(x0), N)
|
903
|
+
u = np.zeros((len(x0),N))
|
904
|
+
if len(x0)==2:
|
905
|
+
for i in range(x0[0,:,:].shape[0]):
|
906
|
+
for j in range(x0[0,:,:].shape[1]):
|
907
|
+
|
908
|
+
u[:,0] = [x0[0,i,j], x0[1,i,j]]
|
909
|
+
|
910
|
+
|
911
|
+
for n in range(1,N):
|
912
|
+
u[:,n] = simulate(u[:,n-1], dt)
|
913
|
+
|
914
|
+
df_sim = pd.DataFrame()
|
915
|
+
|
916
|
+
df_sim['sim'] = np.ones(u.shape[1])*sim_count
|
917
|
+
df_sim['time'] = time
|
918
|
+
var_name=['u', 'v', 'w', 'x', 'y']
|
919
|
+
for i_var in range(len(x0)):
|
920
|
+
df_sim[f'{var_name[i_var]}'] = u[i_var,:]
|
921
|
+
|
922
|
+
|
923
|
+
|
924
|
+
if check_period:
|
925
|
+
_,_,period,_=calculate_period(df_sim['u'].to_numpy(), df_sim['time'].to_numpy())
|
926
|
+
if period is not None:
|
927
|
+
max_time = 6 * period
|
928
|
+
df_sim = df_sim[df_sim['time'] <= max_time]
|
929
|
+
|
930
|
+
sim_count += 1
|
931
|
+
|
932
|
+
df = pd.concat((df, df_sim), ignore_index=True)
|
933
|
+
if len(x0)==3:
|
934
|
+
for i in range(x0[0,:,:,:].shape[0]):
|
935
|
+
for j in range(x0[0,:,:,:].shape[1]):
|
936
|
+
for k in range(x0[0,:,:,:].shape[2]):
|
937
|
+
u[:,0] = [x0[0,i,j,k], x0[1,i,j,k], x0[2,i,j,k]]
|
938
|
+
|
939
|
+
for n in range(1,N):
|
940
|
+
u[:,n] = simulate(u[:,n-1], dt)
|
941
|
+
|
942
|
+
df_sim = pd.DataFrame()
|
943
|
+
|
944
|
+
df_sim['sim'] = np.ones(u.shape[1])*sim_count
|
945
|
+
df_sim['time'] = time
|
946
|
+
var_name=['u', 'v', 'w']
|
947
|
+
for i_var in range(len(x0)):
|
948
|
+
df_sim[f'{var_name[i_var]}'] = u[i_var,:]
|
949
|
+
|
950
|
+
if check_period:
|
951
|
+
_,_,period,_=calculate_period(df_sim['u'].to_numpy(), df_sim['time'].to_numpy())
|
952
|
+
if period is not None:
|
953
|
+
max_time = 6 * period
|
954
|
+
df_sim = df_sim[df_sim['time'] <= max_time]
|
955
|
+
|
956
|
+
sim_count += 1
|
957
|
+
|
958
|
+
df = pd.concat((df, df_sim), ignore_index=True)
|
959
|
+
|
960
|
+
return df
|
961
|
+
|
962
|
+
def save_data(df, filename):
|
963
|
+
"""
|
964
|
+
Save the generated data to a csv file.
|
965
|
+
|
966
|
+
Args:
|
967
|
+
df (pandas DataFrame): DataFrame with the synthetic data.
|
968
|
+
filename (str): Name of the file, usually taking the name of the model.
|
969
|
+
"""
|
970
|
+
# Create 'data' directory if it does not exist
|
971
|
+
if not os.path.exists('data/synthetic_data'):
|
972
|
+
os.makedirs('data/synthetic_data')
|
973
|
+
|
974
|
+
# Save the DataFrame to the 'data' directory
|
975
|
+
filepath = os.path.join('data/synthetic_data', filename)
|
976
|
+
|
977
|
+
# Save the DataFrame to the 'data/synthetic_data' directory
|
978
|
+
df.to_csv(filepath, index=False)
|
979
|
+
print('Generated data saved to', filepath)
|
980
|
+
|
981
|
+
|
982
|
+
def plot_data(df, max_time):
|
983
|
+
"""
|
984
|
+
Plot the generated data.
|
985
|
+
|
986
|
+
Args:
|
987
|
+
df (pandas DataFrame): DataFrame with the synthetic data.
|
988
|
+
max_time (float): Maximum time for the plot.
|
989
|
+
"""
|
990
|
+
fig, ax = plt.subplots(1,1)
|
991
|
+
|
992
|
+
for i in df['sim'].unique():
|
993
|
+
df_sim = df[(df['sim']==i) & (df['time']<=max_time)].copy()
|
994
|
+
df_sim.plot.line(x='u', y='v', ax=ax, legend=False)
|
995
|
+
|
996
|
+
ax.set_ylabel('v')
|
997
|
+
|
998
|
+
|
999
|
+
from scipy.signal import find_peaks
|
1000
|
+
|
1001
|
+
#### General functions
|
1002
|
+
def calculate_period(x_train, t_train):
|
1003
|
+
"""
|
1004
|
+
Calculate the period of an oscillation.
|
1005
|
+
|
1006
|
+
Parameters
|
1007
|
+
----------
|
1008
|
+
x_train : np.array
|
1009
|
+
Time series of data.
|
1010
|
+
t_train : np.array
|
1011
|
+
Time of the time series.
|
1012
|
+
|
1013
|
+
Returns
|
1014
|
+
-------
|
1015
|
+
peaks_u : np.array
|
1016
|
+
Size of peaks detected in the time series.
|
1017
|
+
peaks_t : np.array
|
1018
|
+
Time points where peaks occur in the data set.
|
1019
|
+
period : float
|
1020
|
+
Period of Time Series.
|
1021
|
+
peaks[0]: list
|
1022
|
+
Array of all indicies of local maxima
|
1023
|
+
|
1024
|
+
"""
|
1025
|
+
if len(x_train.shape)<2:
|
1026
|
+
peaks=find_peaks(x_train)
|
1027
|
+
peaks_t=t_train[peaks[0]]
|
1028
|
+
peaks_u=x_train[peaks[0]]
|
1029
|
+
elif x_train.shape[1]==2 or x_train.shape[1]==3:
|
1030
|
+
peaks=find_peaks(x_train[:,0])
|
1031
|
+
peaks_t=t_train[peaks[0]]
|
1032
|
+
peaks_u=x_train[peaks[0],0]
|
1033
|
+
elif x_train.shape[1]==5:
|
1034
|
+
peaks=find_peaks(x_train[:,1])
|
1035
|
+
peaks_t=t_train[peaks[0]]
|
1036
|
+
peaks_u=x_train[peaks[0],1]
|
1037
|
+
|
1038
|
+
period_temp=0
|
1039
|
+
for i in range(len(peaks_t)-1):
|
1040
|
+
period_temp=period_temp+(peaks_t[i+1]-peaks_t[i])
|
1041
|
+
if len(peaks_t)>1:
|
1042
|
+
subtract=1
|
1043
|
+
else: subtract=0
|
1044
|
+
period=period_temp/(len(peaks_t)-subtract)
|
1045
|
+
return peaks_u, peaks_t, period, peaks[0]
|