anytimes 0.1.0__tar.gz
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.
- anytimes-0.1.0/ANYtimes_logo.png +0 -0
- anytimes-0.1.0/LICENSE +21 -0
- anytimes-0.1.0/MANIFEST.in +3 -0
- anytimes-0.1.0/PKG-INFO +105 -0
- anytimes-0.1.0/README.md +67 -0
- anytimes-0.1.0/anyqats/__init__.py +16 -0
- anytimes-0.1.0/anyqats/__main__.py +5 -0
- anytimes-0.1.0/anyqats/app/__init__.py +28 -0
- anytimes-0.1.0/anyqats/app/__main__.py +10 -0
- anytimes-0.1.0/anyqats/app/exceptions.py +47 -0
- anytimes-0.1.0/anyqats/app/funcs.py +245 -0
- anytimes-0.1.0/anyqats/app/gui.py +1592 -0
- anytimes-0.1.0/anyqats/app/logger.py +38 -0
- anytimes-0.1.0/anyqats/app/threading.py +67 -0
- anytimes-0.1.0/anyqats/app/widgets.py +48 -0
- anytimes-0.1.0/anyqats/cli.py +158 -0
- anytimes-0.1.0/anyqats/fatigue/__init__.py +5 -0
- anytimes-0.1.0/anyqats/fatigue/corrections.py +75 -0
- anytimes-0.1.0/anyqats/fatigue/rainflow.py +525 -0
- anytimes-0.1.0/anyqats/fatigue/sn.py +479 -0
- anytimes-0.1.0/anyqats/io/__init__.py +7 -0
- anytimes-0.1.0/anyqats/io/csv.py +52 -0
- anytimes-0.1.0/anyqats/io/direct_access.py +386 -0
- anytimes-0.1.0/anyqats/io/other.py +129 -0
- anytimes-0.1.0/anyqats/io/pickle_format.py +100 -0
- anytimes-0.1.0/anyqats/io/sima.py +358 -0
- anytimes-0.1.0/anyqats/io/sima_h5.py +219 -0
- anytimes-0.1.0/anyqats/io/sintef_mat.py +124 -0
- anytimes-0.1.0/anyqats/io/tdms.py +98 -0
- anytimes-0.1.0/anyqats/motions.py +154 -0
- anytimes-0.1.0/anyqats/signal.py +884 -0
- anytimes-0.1.0/anyqats/stats/__init__.py +5 -0
- anytimes-0.1.0/anyqats/stats/empirical.py +70 -0
- anytimes-0.1.0/anyqats/stats/gumbel.py +864 -0
- anytimes-0.1.0/anyqats/stats/gumbelmin.py +644 -0
- anytimes-0.1.0/anyqats/stats/weibull.py +1018 -0
- anytimes-0.1.0/anyqats/ts.py +1467 -0
- anytimes-0.1.0/anyqats/tsdb.py +1858 -0
- anytimes-0.1.0/anytimes/__init__.py +4 -0
- anytimes-0.1.0/anytimes/__main__.py +4 -0
- anytimes-0.1.0/anytimes/anytimes_gui.py +5840 -0
- anytimes-0.1.0/anytimes.egg-info/PKG-INFO +105 -0
- anytimes-0.1.0/anytimes.egg-info/SOURCES.txt +47 -0
- anytimes-0.1.0/anytimes.egg-info/dependency_links.txt +1 -0
- anytimes-0.1.0/anytimes.egg-info/entry_points.txt +2 -0
- anytimes-0.1.0/anytimes.egg-info/requires.txt +5 -0
- anytimes-0.1.0/anytimes.egg-info/top_level.txt +2 -0
- anytimes-0.1.0/pyproject.toml +29 -0
- anytimes-0.1.0/setup.cfg +4 -0
|
Binary file
|
anytimes-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Audun Arnesen Nyhus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
anytimes-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: anytimes
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: PySide6-based interface for exploring and editing time-series data.
|
|
5
|
+
Author: AnyTimes Developers
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 Audun Arnesen Nyhus
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/example/anytimes
|
|
29
|
+
Requires-Python: >=3.8
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Requires-Dist: numpy
|
|
33
|
+
Requires-Dist: pandas
|
|
34
|
+
Requires-Dist: scipy
|
|
35
|
+
Requires-Dist: PySide6
|
|
36
|
+
Requires-Dist: matplotlib
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<img src="ANYtimes_logo.png" alt="AnytimeSeries logo" width="200"/>
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
# ANYtimeSeries
|
|
44
|
+
|
|
45
|
+
ANYtimeSeries provides a QT-based interface for exploring and editing time-series data.
|
|
46
|
+
|
|
47
|
+
The application integrates with the bundled anyqats package and supports various file formats for loading and visualising time-series information.
|
|
48
|
+
|
|
49
|
+
Some of the features of ANYtimes
|
|
50
|
+
- loading of multiple files
|
|
51
|
+
- detection of commom variables files for effiecent work flow
|
|
52
|
+
- quick manipulation of time series using predefined operations
|
|
53
|
+
- complex manipulation of time series using equation input
|
|
54
|
+
- frequency filtering
|
|
55
|
+
- time sereis statistics
|
|
56
|
+
- many plotting options
|
|
57
|
+
- embdedded and in browser plotting
|
|
58
|
+
- Orcaflex .sim files compability
|
|
59
|
+
- extreme value statstics
|
|
60
|
+
- selection of plotting engine (plotly, bokeh or matplotlib)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
<p align="center">
|
|
64
|
+
<img src="dark_mode.png" alt="AnytimeSeries dark mode" width="700"/>
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
<p align="center">
|
|
69
|
+
<img src="light_mode.png" alt="AnytimeSeries light mode" width="700"/>
|
|
70
|
+
</p>
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
<p align="center">
|
|
74
|
+
<img src="statistics_table.png" alt="AnytimeSeries statistics" width="700"/>
|
|
75
|
+
</p>
|
|
76
|
+
|
|
77
|
+
## Installation
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install anytimes
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Requirements
|
|
84
|
+
|
|
85
|
+
- numpy
|
|
86
|
+
- pandas
|
|
87
|
+
- scipy
|
|
88
|
+
- anyqats
|
|
89
|
+
- PySide6
|
|
90
|
+
- matplotlib
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
After installation, import the GUI module in your Python project:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from anytimes import anytimes_gui
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The module exposes Qt widgets for building custom time-series exploration tools. You can also launch the GUI from the command line using the `anytimes` entry point.
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
Released under the MIT License. See [LICENSE](LICENSE) for details.
|
|
105
|
+
|
anytimes-0.1.0/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="ANYtimes_logo.png" alt="AnytimeSeries logo" width="200"/>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# ANYtimeSeries
|
|
6
|
+
|
|
7
|
+
ANYtimeSeries provides a QT-based interface for exploring and editing time-series data.
|
|
8
|
+
|
|
9
|
+
The application integrates with the bundled anyqats package and supports various file formats for loading and visualising time-series information.
|
|
10
|
+
|
|
11
|
+
Some of the features of ANYtimes
|
|
12
|
+
- loading of multiple files
|
|
13
|
+
- detection of commom variables files for effiecent work flow
|
|
14
|
+
- quick manipulation of time series using predefined operations
|
|
15
|
+
- complex manipulation of time series using equation input
|
|
16
|
+
- frequency filtering
|
|
17
|
+
- time sereis statistics
|
|
18
|
+
- many plotting options
|
|
19
|
+
- embdedded and in browser plotting
|
|
20
|
+
- Orcaflex .sim files compability
|
|
21
|
+
- extreme value statstics
|
|
22
|
+
- selection of plotting engine (plotly, bokeh or matplotlib)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
<p align="center">
|
|
26
|
+
<img src="dark_mode.png" alt="AnytimeSeries dark mode" width="700"/>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img src="light_mode.png" alt="AnytimeSeries light mode" width="700"/>
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="statistics_table.png" alt="AnytimeSeries statistics" width="700"/>
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install anytimes
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
- numpy
|
|
48
|
+
- pandas
|
|
49
|
+
- scipy
|
|
50
|
+
- anyqats
|
|
51
|
+
- PySide6
|
|
52
|
+
- matplotlib
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
After installation, import the GUI module in your Python project:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from anytimes import anytimes_gui
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The module exposes Qt widgets for building custom time-series exploration tools. You can also launch the GUI from the command line using the `anytimes` entry point.
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
Released under the MIT License. See [LICENSE](LICENSE) for details.
|
|
67
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Library for efficient processing and visualization of time series.
|
|
4
|
+
"""
|
|
5
|
+
from .ts import TimeSeries
|
|
6
|
+
from .tsdb import TsDB
|
|
7
|
+
|
|
8
|
+
# version
|
|
9
|
+
try:
|
|
10
|
+
from ._version import __version__, __version_tuple__
|
|
11
|
+
except ImportError:
|
|
12
|
+
__version__ = "0.0.0"
|
|
13
|
+
__version_tuple__ = (0, 0, 0)
|
|
14
|
+
|
|
15
|
+
# summary
|
|
16
|
+
__summary__ = __doc__
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Support for launching the AnyQATS GUI.
|
|
2
|
+
|
|
3
|
+
This module exposes a :func:`main` function that serves as an entry point
|
|
4
|
+
for the desktop application. It delegates to :func:`anyqats.cli.launch_app`
|
|
5
|
+
with default arguments, allowing the GUI to be started simply by executing
|
|
6
|
+
``python -m anyqats.app``.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main() -> None:
|
|
13
|
+
"""Launch the graphical user interface.
|
|
14
|
+
|
|
15
|
+
The heavy lifting of setting up and starting the application lives in
|
|
16
|
+
:func:`anyqats.cli.launch_app`. Importing inside the function keeps import
|
|
17
|
+
time light and avoids circular dependencies during package initialisation.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from ..cli import launch_app
|
|
21
|
+
|
|
22
|
+
# Mirror the default behaviour of ``anyqats app`` which uses the current
|
|
23
|
+
# working directory unless the user specifies otherwise.
|
|
24
|
+
launch_app(home=False)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
__all__ = ["main"]
|
|
28
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Module for custom exceptions and exception handlers
|
|
4
|
+
"""
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import traceback
|
|
8
|
+
import webbrowser
|
|
9
|
+
|
|
10
|
+
from PySide6.QtWidgets import QMessageBox
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def handle_exception(exc_type, exc_value, exc_traceback):
|
|
14
|
+
"""
|
|
15
|
+
Handle all exceptions, log it on file, warn the user via a critical message box
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
exc_type : type
|
|
20
|
+
type of exception e.g. ValueError
|
|
21
|
+
exc_value : str
|
|
22
|
+
exception string
|
|
23
|
+
exc_traceback : traceback
|
|
24
|
+
traceback for the exception
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
# retrieve traceback
|
|
28
|
+
filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop()
|
|
29
|
+
filename = os.path.basename(filename)
|
|
30
|
+
error = "%s: %s" % (exc_type.__name__, exc_value)
|
|
31
|
+
|
|
32
|
+
# display critical message box
|
|
33
|
+
msg = "<html>A critical error has occured.<br/> <b>%s</b><br/><br/>It occurred at <b>line %d</b> of file " \
|
|
34
|
+
"<b>%s</b>.<br/>Press Yes to see the full error report<br/></html>" % (error, line, filename)
|
|
35
|
+
message_box = QMessageBox().critical(None, "Error", msg.strip(), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
|
36
|
+
|
|
37
|
+
# pipe traceback to log file (env variable 'APPDATA' is assumed present on the computer)
|
|
38
|
+
log_file = os.path.join(os.getenv("APPDATA"), "QATS.launch.pyw.log")
|
|
39
|
+
with open(log_file,"w") as f:
|
|
40
|
+
f.write("".join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
|
|
41
|
+
|
|
42
|
+
# open log file in default editor if user pressed yes (trick using the webbrowser command)
|
|
43
|
+
if message_box == QMessageBox.Yes:
|
|
44
|
+
webbrowser.open(log_file)
|
|
45
|
+
|
|
46
|
+
# exit with code 1 (error)
|
|
47
|
+
sys.exit(1)
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module with functions for handling file operations and calculations. Made for multithreading.
|
|
3
|
+
"""
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from ..fatigue.rainflow import rebin as rebin_cycles
|
|
7
|
+
from ..stats.gumbel import pwm as gumbel_pwm
|
|
8
|
+
from ..tsdb import TsDB
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def calculate_psd(container, twin, fargs, nperseg, normalize):
|
|
12
|
+
"""
|
|
13
|
+
Calculate power spectral density and return as numpy arrays
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
container : dict
|
|
18
|
+
TimeSeries objects
|
|
19
|
+
twin : tuple
|
|
20
|
+
Time window. Time series are cropped to time window before estimating psd.
|
|
21
|
+
fargs : tuple
|
|
22
|
+
Filter arguments. Time series are filtered before estimating psd.
|
|
23
|
+
nperseg : int
|
|
24
|
+
Size of segments used for estimating PSD using Welch's method.
|
|
25
|
+
NOTE: the minimum of specified `nperseg` and signal length is used.
|
|
26
|
+
normalize : bool
|
|
27
|
+
Normalize power spectral density on maximum density.
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
dict
|
|
32
|
+
Frequency versus power spectral density
|
|
33
|
+
"""
|
|
34
|
+
container_out = dict()
|
|
35
|
+
|
|
36
|
+
for name, ts in container.items():
|
|
37
|
+
# NOTE: nperseg passed on as minimum of specified value and signal input length
|
|
38
|
+
# this is done in scipy anyway, which also issues a UserWArnings stating:
|
|
39
|
+
# "nperseg = {nperseg} is greater than input length = {input_length:d}, using nperseg = {input_length:d}"
|
|
40
|
+
t, _ = ts.get(twin=twin, resample=ts.dt)
|
|
41
|
+
nperseg_ = np.min((nperseg, t.size))
|
|
42
|
+
# calculate power spectral density
|
|
43
|
+
# (resampling to average time step for robustness, necessary for series with varying time step)
|
|
44
|
+
f, s = ts.psd(twin=twin, filterargs=fargs, resample=ts.dt, taperfrac=0.1, nperseg=nperseg_, normalize=normalize)
|
|
45
|
+
container_out[name] = tuple([f, s])
|
|
46
|
+
|
|
47
|
+
return container_out
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def calculate_rfc(container, twin, fargs, nbins):
|
|
51
|
+
"""
|
|
52
|
+
Count cycles using Rainflow counting method
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
container : dict
|
|
57
|
+
TimeSeries objects
|
|
58
|
+
twin : tuple
|
|
59
|
+
Time window. Time series are cropped to time window before estimating psd.
|
|
60
|
+
fargs : tuple
|
|
61
|
+
Filter arguments. Time series are filtered before estimating psd.
|
|
62
|
+
nbins : int
|
|
63
|
+
Number of bins in cycle distribution.
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
dict
|
|
68
|
+
Cycle magnitude versus count
|
|
69
|
+
"""
|
|
70
|
+
container_out = dict()
|
|
71
|
+
|
|
72
|
+
for name, ts in container.items():
|
|
73
|
+
# rainflow counting
|
|
74
|
+
cycles = ts.rfc(twin=twin, filterargs=fargs)
|
|
75
|
+
|
|
76
|
+
# rebin
|
|
77
|
+
if nbins is not None:
|
|
78
|
+
cycles = rebin_cycles(cycles, binby='range', n=nbins)
|
|
79
|
+
|
|
80
|
+
# unpack pairs (tuples) in list
|
|
81
|
+
r, _, c = zip(*cycles)
|
|
82
|
+
container_out[name] = tuple([r, c])
|
|
83
|
+
|
|
84
|
+
return container_out
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def calculate_trace(container, twin, fargs):
|
|
88
|
+
"""
|
|
89
|
+
Calculate trace and peaks/troughs of filtered time series
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
container : dict
|
|
94
|
+
TimeSeries objects
|
|
95
|
+
twin : tuple
|
|
96
|
+
Time window. Time series are cropped to time window before extracting maxima.
|
|
97
|
+
fargs : tuple
|
|
98
|
+
Filter arguments. Time series are filtered before extracting maxima.
|
|
99
|
+
|
|
100
|
+
Returns
|
|
101
|
+
-------
|
|
102
|
+
dict
|
|
103
|
+
Filtered and windowed time series and peaks/throughs
|
|
104
|
+
"""
|
|
105
|
+
container_out = dict()
|
|
106
|
+
|
|
107
|
+
for name, ts in container.items():
|
|
108
|
+
t, x = ts.get(twin=twin, filterargs=fargs)
|
|
109
|
+
xmin, tmin = ts.minima(twin=twin, filterargs=fargs, rettime=True)
|
|
110
|
+
xmax, tmax = ts.maxima(twin=twin, filterargs=fargs, rettime=True)
|
|
111
|
+
|
|
112
|
+
container_out[name] = dict(t=t, x=x, tmin=tmin, xmin=xmin,
|
|
113
|
+
tmax=tmax, xmax=xmax)
|
|
114
|
+
|
|
115
|
+
return container_out
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def calculate_stats(container, twin, fargs, minima=False):
|
|
119
|
+
"""
|
|
120
|
+
Calculate time series statistics
|
|
121
|
+
|
|
122
|
+
Parameters
|
|
123
|
+
----------
|
|
124
|
+
container : dict
|
|
125
|
+
TimeSeries objects
|
|
126
|
+
twin : tuple
|
|
127
|
+
Time window. Time series are cropped to time window before extracting maxima.
|
|
128
|
+
fargs : tuple
|
|
129
|
+
Filter arguments. Time series are filtered before extracting maxima.
|
|
130
|
+
minima : bool, optional
|
|
131
|
+
Fit to sample of minima instead of maxima. The sample is multiplied by -1 prior to parameter estimation.
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
dict
|
|
136
|
+
Filtered and windowed time series and peaks/throughs
|
|
137
|
+
"""
|
|
138
|
+
return {name: ts.stats(twin=twin, filterargs=fargs, statsdur=10800., quantiles=(0.37, 0.57, 0.9),
|
|
139
|
+
is_minima=minima, include_sample=True) for name, ts in container.items()}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def calculate_gumbel_fit(container, twin, fargs, minima=False):
|
|
143
|
+
"""
|
|
144
|
+
Calculate time series extremes and fit Gumbel distribution
|
|
145
|
+
|
|
146
|
+
Parameters
|
|
147
|
+
----------
|
|
148
|
+
container : dict
|
|
149
|
+
TimeSeries objects
|
|
150
|
+
twin : tuple
|
|
151
|
+
Time window. Time series are cropped to time window before extracting maxima.
|
|
152
|
+
fargs : tuple
|
|
153
|
+
Filter arguments. Time series are filtered before extracting maxima.
|
|
154
|
+
minima : bool, optional
|
|
155
|
+
Fit to sample of minima instead of maxima. The sample is multiplied by -1 prior to parameter estimation.
|
|
156
|
+
|
|
157
|
+
Returns
|
|
158
|
+
-------
|
|
159
|
+
dict
|
|
160
|
+
Sample and fitted gumbel distribution parameters
|
|
161
|
+
"""
|
|
162
|
+
if len(container.keys()) < 2:
|
|
163
|
+
raise ValueError(f"Select more than 1 time series to fit Gumbel CDF to extremes sample.")
|
|
164
|
+
|
|
165
|
+
# create sample of extremes
|
|
166
|
+
sample = list()
|
|
167
|
+
for name, ts in container.items():
|
|
168
|
+
_, x = ts.get(twin=twin, filterargs=fargs)
|
|
169
|
+
|
|
170
|
+
if minima:
|
|
171
|
+
# sample minimum value
|
|
172
|
+
sample.append(np.min(x))
|
|
173
|
+
else:
|
|
174
|
+
# sample maximum value
|
|
175
|
+
sample.append(np.max(x))
|
|
176
|
+
|
|
177
|
+
# numpy array sorted ascending
|
|
178
|
+
sample = np.sort(np.array(sample))
|
|
179
|
+
|
|
180
|
+
# flip sample of minima to enable Gumbel fit
|
|
181
|
+
if minima:
|
|
182
|
+
sample *= -1
|
|
183
|
+
|
|
184
|
+
# estimate gumbel distribution parameters
|
|
185
|
+
loc, scale = gumbel_pwm(sample)
|
|
186
|
+
return dict(loc=loc, scale=scale, sample=sample, minima=minima)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def export_to_file(filename, db, names, twin, fargs):
|
|
190
|
+
"""
|
|
191
|
+
Export selected time series to file
|
|
192
|
+
|
|
193
|
+
Parameters
|
|
194
|
+
----------
|
|
195
|
+
filename : str
|
|
196
|
+
File name
|
|
197
|
+
db : TsDB
|
|
198
|
+
Time series data base
|
|
199
|
+
names : list
|
|
200
|
+
Name of time series to export
|
|
201
|
+
twin : tuple
|
|
202
|
+
Time window. Time series are cropped to time window before export.
|
|
203
|
+
fargs : tuple
|
|
204
|
+
Filter arguments. Time series are filtered before export
|
|
205
|
+
"""
|
|
206
|
+
db.export(filename, names=names, exist_ok=True, basename=False, twin=twin, filterargs=fargs)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def import_from_file(files):
|
|
210
|
+
"""
|
|
211
|
+
Import time series files
|
|
212
|
+
|
|
213
|
+
Parameters
|
|
214
|
+
----------
|
|
215
|
+
files : list
|
|
216
|
+
File names
|
|
217
|
+
|
|
218
|
+
Returns
|
|
219
|
+
-------
|
|
220
|
+
TsDB
|
|
221
|
+
Time series data base
|
|
222
|
+
"""
|
|
223
|
+
db = TsDB()
|
|
224
|
+
db.load(files, read=False)
|
|
225
|
+
return db
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def read_timeseries(db, names):
|
|
229
|
+
"""
|
|
230
|
+
Read time series from files
|
|
231
|
+
|
|
232
|
+
Parameters
|
|
233
|
+
----------
|
|
234
|
+
db : TsDB
|
|
235
|
+
Time series data base
|
|
236
|
+
names : list
|
|
237
|
+
Name of time series to read
|
|
238
|
+
|
|
239
|
+
Returns
|
|
240
|
+
-------
|
|
241
|
+
dict
|
|
242
|
+
Container with TimeSeries objects
|
|
243
|
+
"""
|
|
244
|
+
return db.getm(names=names, store=False)
|
|
245
|
+
|