tsdf 0.5.1__tar.gz → 0.6.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.
- {tsdf-0.5.1 → tsdf-0.6.0}/PKG-INFO +12 -10
- {tsdf-0.5.1 → tsdf-0.6.0}/README.md +9 -7
- {tsdf-0.5.1 → tsdf-0.6.0}/pyproject.toml +16 -8
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/numpy_utils.py +2 -0
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/parse_metadata.py +32 -12
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/read_tsdf.py +2 -1
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/tsdfmetadata.py +54 -4
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/write_binary.py +7 -9
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/write_tsdf.py +7 -4
- {tsdf-0.5.1 → tsdf-0.6.0}/LICENSE +0 -0
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/__init__.py +0 -0
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/constants.py +0 -0
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/file_utils.py +0 -0
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/legacy_tsdf_utils.py +0 -0
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/read_binary.py +0 -0
- {tsdf-0.5.1 → tsdf-0.6.0}/src/tsdf/validator.py +0 -0
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tsdf
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: A Python library that provides methods for encoding and decoding TSDF (Time Series Data Format) data, which allows you to easily create, manipulate and serialize TSDF files in your Python code.
|
|
5
5
|
Home-page: https://github.com/biomarkersParkinson/tsdf
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Keywords: Time Series Data Format (TSDF),binary data,digital sensors
|
|
8
8
|
Author: Peter Kok
|
|
9
9
|
Author-email: p.kok@esciencecenter.nl
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.10,<4.0
|
|
11
11
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
12
|
Classifier: Programming Language :: Python
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Requires-Dist: numpy (>=1.24.1,<2.0.0)
|
|
18
18
|
Requires-Dist: pandas (>=2.1.3,<3.0.0)
|
|
19
19
|
Project-URL: Repository, https://github.com/biomarkersParkinson/tsdf
|
|
@@ -25,7 +25,7 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
| Badges | |
|
|
26
26
|
|:----:|----|
|
|
27
27
|
| **Packages and Releases** | [](https://github.com/biomarkersparkinson/tsdf/releases/latest) [](https://pypi.python.org/pypi/tsdf/) [](https://research-software-directory.org/software/tsdf) |
|
|
28
|
-
| **Build Status** | [](https://www.python.org/downloads/)  [](https://github.com/biomarkersParkinson/tsdf/actions/workflows/pytype-checking.yml) |
|
|
29
29
|
| **DOI** | [](https://doi.org/10.5281/zenodo.7867899) |
|
|
30
30
|
| **License** | [](https://github.com/biomarkersparkinson/tsdf/blob/main/LICENSE) |
|
|
31
31
|
| **Fairness** | [](https://fair-software.eu) [](https://www.bestpractices.dev/projects/8083) |
|
|
@@ -38,7 +38,7 @@ A package ([documentation](https://biomarkersparkinson.github.io/tsdf/)) to load
|
|
|
38
38
|
|
|
39
39
|
### Using `pip`
|
|
40
40
|
|
|
41
|
-
The package is available in PyPi and requires [Python 3.
|
|
41
|
+
The package is available in PyPi and requires [Python 3.10](https://www.python.org/downloads/) or higher. It can be installed using:
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
44
|
$ pip install tsdf
|
|
@@ -59,17 +59,19 @@ poetry run pytest
|
|
|
59
59
|
|
|
60
60
|
### Building the documentation
|
|
61
61
|
|
|
62
|
-
We use [
|
|
62
|
+
We use [Sphinx](https://www.sphinx-doc.org/) to build the documentation. Use this command to build the documentation locally:
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
|
-
|
|
66
|
-
mkdocs serve # serve the documentation on a local server
|
|
67
|
-
mkdocs gh-deploy # deploy the documentation to GitHub pages
|
|
65
|
+
poetry run make html --directory docs
|
|
68
66
|
```
|
|
69
67
|
|
|
70
68
|
## Contributing
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for more details on coding standards, how to get started, and the submission process.
|
|
71
|
+
|
|
72
|
+
## Code of Conduct
|
|
73
|
+
|
|
74
|
+
To ensure a welcoming and respectful community, all contributors and participants are expected to adhere to our [Code of Conduct](CONDUCT.md). By participating in this project, you agree to abide by its terms.
|
|
73
75
|
|
|
74
76
|
## License
|
|
75
77
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
| Badges | |
|
|
5
5
|
|:----:|----|
|
|
6
6
|
| **Packages and Releases** | [](https://github.com/biomarkersparkinson/tsdf/releases/latest) [](https://pypi.python.org/pypi/tsdf/) [](https://research-software-directory.org/software/tsdf) |
|
|
7
|
-
| **Build Status** | [](https://www.python.org/downloads/)  [](https://github.com/biomarkersParkinson/tsdf/actions/workflows/pytype-checking.yml) |
|
|
8
8
|
| **DOI** | [](https://doi.org/10.5281/zenodo.7867899) |
|
|
9
9
|
| **License** | [](https://github.com/biomarkersparkinson/tsdf/blob/main/LICENSE) |
|
|
10
10
|
| **Fairness** | [](https://fair-software.eu) [](https://www.bestpractices.dev/projects/8083) |
|
|
@@ -17,7 +17,7 @@ A package ([documentation](https://biomarkersparkinson.github.io/tsdf/)) to load
|
|
|
17
17
|
|
|
18
18
|
### Using `pip`
|
|
19
19
|
|
|
20
|
-
The package is available in PyPi and requires [Python 3.
|
|
20
|
+
The package is available in PyPi and requires [Python 3.10](https://www.python.org/downloads/) or higher. It can be installed using:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
$ pip install tsdf
|
|
@@ -38,17 +38,19 @@ poetry run pytest
|
|
|
38
38
|
|
|
39
39
|
### Building the documentation
|
|
40
40
|
|
|
41
|
-
We use [
|
|
41
|
+
We use [Sphinx](https://www.sphinx-doc.org/) to build the documentation. Use this command to build the documentation locally:
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
|
|
45
|
-
mkdocs serve # serve the documentation on a local server
|
|
46
|
-
mkdocs gh-deploy # deploy the documentation to GitHub pages
|
|
44
|
+
poetry run make html --directory docs
|
|
47
45
|
```
|
|
48
46
|
|
|
49
47
|
## Contributing
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for more details on coding standards, how to get started, and the submission process.
|
|
50
|
+
|
|
51
|
+
## Code of Conduct
|
|
52
|
+
|
|
53
|
+
To ensure a welcoming and respectful community, all contributors and participants are expected to adhere to our [Code of Conduct](CONDUCT.md). By participating in this project, you agree to abide by its terms.
|
|
52
54
|
|
|
53
55
|
## License
|
|
54
56
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "tsdf"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.0"
|
|
4
4
|
description = "A Python library that provides methods for encoding and decoding TSDF (Time Series Data Format) data, which allows you to easily create, manipulate and serialize TSDF files in your Python code."
|
|
5
5
|
authors = ["Peter Kok <p.kok@esciencecenter.nl>",
|
|
6
6
|
"Pablo Rodríguez <p.rodriguez-sanchez@esciencecenter.nl>",
|
|
@@ -16,23 +16,31 @@ keywords = ["Time Series Data Format (TSDF)", "binary data", "digital sensors"]
|
|
|
16
16
|
repository = "https://github.com/biomarkersParkinson/tsdf"
|
|
17
17
|
|
|
18
18
|
[tool.poetry.dependencies]
|
|
19
|
-
python = "^3.
|
|
19
|
+
python = "^3.10"
|
|
20
20
|
numpy = "^1.24.1"
|
|
21
21
|
pandas = "^2.1.3"
|
|
22
22
|
|
|
23
23
|
[tool.poetry.group.dev.dependencies]
|
|
24
|
+
coverage = "^7.0.0"
|
|
25
|
+
matplotlib = "^3.6.3"
|
|
26
|
+
pytype = "^2024.4.11"
|
|
27
|
+
myst-parser = "^3.0.1"
|
|
28
|
+
|
|
29
|
+
[tool.poetry.group.testing.dependencies]
|
|
30
|
+
ipykernel = "^6.19.2"
|
|
24
31
|
pytest = "^7.2.0"
|
|
25
32
|
pytest-cov = "^4.0.0"
|
|
26
33
|
pytest-datadir = "^1.4.1"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
|
|
35
|
+
[tool.poetry.group.docs.dependencies]
|
|
36
|
+
sphinx = "^7.3.7"
|
|
37
|
+
myst-nb = "^1.1.0"
|
|
38
|
+
sphinx-autoapi = "^3.1.2"
|
|
39
|
+
sphinx-rtd-theme = "^2.0.0"
|
|
33
40
|
|
|
34
41
|
[tool.poetry.scripts]
|
|
35
42
|
validate-tsdf = "tsdf.validator:main"
|
|
43
|
+
#docs = "sphinx.cmd.build:main"
|
|
36
44
|
|
|
37
45
|
[build-system]
|
|
38
46
|
requires = ["poetry-core>=1.0.0"]
|
|
@@ -61,6 +61,7 @@ _map_from_numpy_endianness = {
|
|
|
61
61
|
"<": "little",
|
|
62
62
|
">": "big",
|
|
63
63
|
"=": sys.byteorder,
|
|
64
|
+
"|": "not applicable",
|
|
64
65
|
}
|
|
65
66
|
""" Supported endianness values. """
|
|
66
67
|
|
|
@@ -79,6 +80,7 @@ def endianness_numpy_to_tsdf(data: np.ndarray) -> str:
|
|
|
79
80
|
_map_to_numpy_endianness = {
|
|
80
81
|
"little": "<",
|
|
81
82
|
"big": ">",
|
|
83
|
+
"not applicable": "|",
|
|
82
84
|
}
|
|
83
85
|
""" Supported endianness values. """
|
|
84
86
|
|
|
@@ -6,6 +6,8 @@ Reference: https://arxiv.org/abs/2211.11294
|
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
8
|
from typing import Any, Dict, List
|
|
9
|
+
import re
|
|
10
|
+
from dateutil import parser
|
|
9
11
|
|
|
10
12
|
from tsdf import constants
|
|
11
13
|
from tsdf import tsdfmetadata
|
|
@@ -82,7 +84,7 @@ def _read_struct(
|
|
|
82
84
|
# levels of the TSDF structure.
|
|
83
85
|
# Extend the mapping recursively with values provided at those levels.
|
|
84
86
|
for key, value in remaining_data.items():
|
|
85
|
-
if
|
|
87
|
+
if isinstance(value, list):
|
|
86
88
|
for each_value in value:
|
|
87
89
|
all_streams = all_streams | _read_struct(
|
|
88
90
|
each_value, defined_properties.copy(), source_path, version
|
|
@@ -135,17 +137,6 @@ def _contains_file_name(data: Any) -> bool:
|
|
|
135
137
|
return False
|
|
136
138
|
|
|
137
139
|
|
|
138
|
-
def _is_a_list(value) -> bool:
|
|
139
|
-
"""
|
|
140
|
-
Function returns True if the value is a list, otherwise it returns False.
|
|
141
|
-
|
|
142
|
-
:param value: value to be checked.
|
|
143
|
-
|
|
144
|
-
:return: True if the value is a list, otherwise False.
|
|
145
|
-
"""
|
|
146
|
-
return isinstance(value, list)
|
|
147
|
-
|
|
148
|
-
|
|
149
140
|
def contains_tsdf_mandatory_fields(dictionary: Dict[str, Any]) -> bool:
|
|
150
141
|
"""
|
|
151
142
|
Verifies that all the mandatory properties for TSDF metadata are provided,
|
|
@@ -242,4 +233,33 @@ def confirm_dir_of_metadata(metadatas: List["tsdfmetadata.TSDFMetadata"]) -> Non
|
|
|
242
233
|
if init_metadata.file_name == curr_metadata.file_name:
|
|
243
234
|
raise tsdfmetadata.TSDFMetadataFieldValueError(
|
|
244
235
|
"Two metadata objects cannot reference the same binary file (file_name)."
|
|
236
|
+
#TODO: why not?
|
|
245
237
|
)
|
|
238
|
+
|
|
239
|
+
def is_iso8601(date_string: str) -> bool:
|
|
240
|
+
"""
|
|
241
|
+
Checks if the given date string is in ISO8601 format.
|
|
242
|
+
|
|
243
|
+
:param date_string: date string to be checked.
|
|
244
|
+
"""
|
|
245
|
+
# Note that we need both the regex and the parser to validate the date string
|
|
246
|
+
# The regex only still allows for invalid dates, e.g. 2021-02-29
|
|
247
|
+
# The parser is too lenient in accepting different formats
|
|
248
|
+
iso8601_regex = r"^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])(T(2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]+)?(?:Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?)?$"
|
|
249
|
+
if re.match(iso8601_regex, date_string):
|
|
250
|
+
try:
|
|
251
|
+
parser.parse(date_string)
|
|
252
|
+
return True
|
|
253
|
+
except tsdfmetadata.TSDFMetadataFieldValueError:
|
|
254
|
+
return False
|
|
255
|
+
return False
|
|
256
|
+
|
|
257
|
+
def validate_datetimes(metadata: tsdfmetadata.TSDFMetadata) -> bool:
|
|
258
|
+
"""
|
|
259
|
+
Validates the start and end date format of the TSDFMetaData object.
|
|
260
|
+
"""
|
|
261
|
+
if not is_iso8601(metadata.start_iso8601):
|
|
262
|
+
raise tsdfmetadata.TSDFMetadataFieldValueError(f"Invalid start_iso8601: {metadata.start_iso8601}")
|
|
263
|
+
if not is_iso8601(metadata.end_iso8601):
|
|
264
|
+
raise tsdfmetadata.TSDFMetadataFieldValueError(f"Invalid end_iso8601: {metadata.end_iso8601}")
|
|
265
|
+
return True
|
|
@@ -6,6 +6,7 @@ Reference: https://arxiv.org/abs/2211.11294
|
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
8
|
import os
|
|
9
|
+
from pathlib import Path
|
|
9
10
|
from typing import Dict, List
|
|
10
11
|
from tsdf import file_utils
|
|
11
12
|
from tsdf.constants import METADATA_NAMING_PATTERN
|
|
@@ -71,7 +72,7 @@ def load_metadatas_from_dir(
|
|
|
71
72
|
return metadatas
|
|
72
73
|
|
|
73
74
|
|
|
74
|
-
def load_metadata_from_path(path:
|
|
75
|
+
def load_metadata_from_path(path: Path) -> Dict[str, TSDFMetadata]:
|
|
75
76
|
"""
|
|
76
77
|
Loads a TSDF metadata file, returns a dictionary
|
|
77
78
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
from typing import Any, Dict, List
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from dateutil import parser
|
|
3
5
|
|
|
4
6
|
from tsdf import parse_metadata
|
|
5
7
|
|
|
@@ -48,11 +50,11 @@ class TSDFMetadata:
|
|
|
48
50
|
|
|
49
51
|
file_dir_path: str
|
|
50
52
|
""" A reference to the directory path, so we don't need it again when reading associated binary files. """
|
|
51
|
-
metadata_file_name: str
|
|
53
|
+
metadata_file_name: str #TODO: do we need this?? / is it used?
|
|
52
54
|
""" A reference to the source path, so we don't need it again when reading associated binary files. """
|
|
53
55
|
|
|
54
56
|
def __init__(
|
|
55
|
-
self, dictionary: Dict[str, Any], dir_path: str, metadata_file_name: str = ""
|
|
57
|
+
self, dictionary: Dict[str, Any], dir_path: str, metadata_file_name: str = "", do_validate: bool = True
|
|
56
58
|
) -> None:
|
|
57
59
|
"""
|
|
58
60
|
The default constructor takes a dictionary as an argument and creates each
|
|
@@ -61,14 +63,34 @@ class TSDFMetadata:
|
|
|
61
63
|
|
|
62
64
|
:param dictionary: dictionary containing TSDF metadata.
|
|
63
65
|
:param dir_path: path to the directory where the metadata file is stored.
|
|
64
|
-
:param
|
|
66
|
+
:param metadata_file_name: (optional) name of the metadata file.
|
|
67
|
+
:param do_validate: (optional) flag to validate the metadata.
|
|
65
68
|
"""
|
|
66
|
-
|
|
69
|
+
|
|
70
|
+
# Copy the attributes from the dictionary to the object
|
|
67
71
|
for key, value in dictionary.items():
|
|
68
72
|
setattr(self, key, value)
|
|
69
73
|
self.file_dir_path = dir_path
|
|
70
74
|
self.metadata_file_name = metadata_file_name
|
|
71
75
|
|
|
76
|
+
# Validate the metadata
|
|
77
|
+
if do_validate:
|
|
78
|
+
if not self.validate():
|
|
79
|
+
raise TSDFMetadataFieldValueError("The provided metadata is invalid.")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def validate(self) -> bool:
|
|
83
|
+
isValid: bool = True
|
|
84
|
+
|
|
85
|
+
# Validate presence of mandatory fields
|
|
86
|
+
dict = self.get_plain_tsdf_dict_copy()
|
|
87
|
+
isValid = isValid and parse_metadata.contains_tsdf_mandatory_fields(dict)
|
|
88
|
+
|
|
89
|
+
# Validate datetimes
|
|
90
|
+
isValid = isValid and parse_metadata.validate_datetimes(self)
|
|
91
|
+
|
|
92
|
+
return isValid
|
|
93
|
+
|
|
72
94
|
def get_plain_tsdf_dict_copy(self) -> Dict[str, Any]:
|
|
73
95
|
"""
|
|
74
96
|
Method returns the a copy of the dict containing fields needed for the TSDF file.
|
|
@@ -81,3 +103,31 @@ class TSDFMetadata:
|
|
|
81
103
|
if simple_dict.get("metadata_file_name") is not None:
|
|
82
104
|
simple_dict.pop("metadata_file_name")
|
|
83
105
|
return simple_dict
|
|
106
|
+
|
|
107
|
+
def set_start_datetime(self, date_time: datetime) -> None:
|
|
108
|
+
"""
|
|
109
|
+
Sets the start date of the recording in ISO8601 format.
|
|
110
|
+
:param date_time: datetime object containing the start date.
|
|
111
|
+
"""
|
|
112
|
+
self.start_iso8601 = date_time.isoformat()
|
|
113
|
+
|
|
114
|
+
def get_start_datetime(self) -> datetime:
|
|
115
|
+
"""
|
|
116
|
+
Returns the start date of the recording as a datetime object.
|
|
117
|
+
:return: datetime object containing the start date.
|
|
118
|
+
"""
|
|
119
|
+
return parser.parse(self.start_iso8601)
|
|
120
|
+
|
|
121
|
+
def set_end_datetime(self, date_time: datetime) -> None:
|
|
122
|
+
"""
|
|
123
|
+
Sets the end date of the recording in ISO8601 format.
|
|
124
|
+
:param date_time: datetime object containing the end date.
|
|
125
|
+
"""
|
|
126
|
+
self.end_iso8601 = date_time.isoformat()
|
|
127
|
+
|
|
128
|
+
def get_end_datetime(self) -> datetime:
|
|
129
|
+
"""
|
|
130
|
+
Returns the end date of the recording as a datetime object.
|
|
131
|
+
:return: datetime object containing the end date.
|
|
132
|
+
"""
|
|
133
|
+
return parser.parse(self.end_iso8601)
|
|
@@ -5,26 +5,24 @@ Reference: https://arxiv.org/abs/2211.11294
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
|
-
from typing import Any, Dict
|
|
8
|
+
from typing import Any, Dict, List
|
|
9
9
|
import numpy as np
|
|
10
10
|
import pandas as pd
|
|
11
|
-
from tsdf import numpy_utils
|
|
11
|
+
from tsdf import numpy_utils
|
|
12
12
|
|
|
13
13
|
from tsdf.tsdfmetadata import TSDFMetadata
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def write_dataframe_to_binaries(
|
|
17
|
-
file_dir: str, df: pd.DataFrame, metadatas: [TSDFMetadata]
|
|
17
|
+
file_dir: str, df: pd.DataFrame, metadatas: List[TSDFMetadata]
|
|
18
18
|
) -> None:
|
|
19
19
|
"""
|
|
20
20
|
Save binary file based on the provided pandas DataFrame.
|
|
21
21
|
|
|
22
|
-
:param file_dir:
|
|
23
|
-
:param
|
|
24
|
-
:param
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
:return: TSDFMetadata object.
|
|
22
|
+
:param file_dir: path to the directory where the file will be saved.
|
|
23
|
+
:param df: pandas DataFrame containing the data.
|
|
24
|
+
:param metadatas: list of metadata objects to be saved, also contains
|
|
25
|
+
channels to be retrieved from dataframe.
|
|
28
26
|
"""
|
|
29
27
|
for metadata in metadatas:
|
|
30
28
|
file_name = metadata.file_name
|
|
@@ -19,6 +19,9 @@ def write_metadata(metadatas: List[TSDFMetadata], file_name: str) -> None:
|
|
|
19
19
|
|
|
20
20
|
:raises TSDFMetadataFieldValueError: if the metadata files cannot be combined (e.g. they have no common fields) or if the list of TSDFMetadata objects is empty.
|
|
21
21
|
"""
|
|
22
|
+
for meta in metadatas:
|
|
23
|
+
meta.validate()
|
|
24
|
+
|
|
22
25
|
if len(metadatas) == 0:
|
|
23
26
|
raise TSDFMetadataFieldValueError(
|
|
24
27
|
"Metadata cannot be saved, as the list of TSDFMetadata objects is empty."
|
|
@@ -42,7 +45,7 @@ def write_metadata(metadatas: List[TSDFMetadata], file_name: str) -> None:
|
|
|
42
45
|
)
|
|
43
46
|
|
|
44
47
|
if len(plain_meta) > 0:
|
|
45
|
-
overlap["sensors"] =
|
|
48
|
+
overlap["sensors"] = _calculate_overlaps_rec(plain_meta)
|
|
46
49
|
file_utils.write_to_file(overlap, metadatas[0].file_dir_path, file_name)
|
|
47
50
|
|
|
48
51
|
|
|
@@ -76,7 +79,7 @@ def _extract_common_fields(metadatas: List[Dict[str, Any]]) -> Dict[str, Any]:
|
|
|
76
79
|
return meta_overlap
|
|
77
80
|
|
|
78
81
|
|
|
79
|
-
def
|
|
82
|
+
def _calculate_overlaps_rec(metadatas: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
80
83
|
"""
|
|
81
84
|
A recursive call that optimises the structure of the TSDF metadata, by grouping common values. For the input the list of dictionaries
|
|
82
85
|
corresponds to a list of "flat" metadata dictionaries. The output is a list of dictionaries (potentially of length 1) that contain
|
|
@@ -107,11 +110,11 @@ def _calculate_ovelaps_rec(metadatas: List[Dict[str, Any]]) -> List[Dict[str, An
|
|
|
107
110
|
# Handle the first group
|
|
108
111
|
first_overlap = _extract_common_fields(first_group)
|
|
109
112
|
if len(first_group) > 0:
|
|
110
|
-
first_overlap["sensors"] =
|
|
113
|
+
first_overlap["sensors"] = _calculate_overlaps_rec(first_group)
|
|
111
114
|
final_metadata.append(first_overlap)
|
|
112
115
|
|
|
113
116
|
# Handle the rest of the elements
|
|
114
|
-
second_overlap =
|
|
117
|
+
second_overlap = _calculate_overlaps_rec(second_grop)
|
|
115
118
|
final_metadata.extend(second_overlap)
|
|
116
119
|
|
|
117
120
|
return final_metadata
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|