temapy 1.0.0__tar.gz → 1.2.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.
- {temapy-1.0.0 → temapy-1.2.0}/PKG-INFO +80 -22
- {temapy-1.0.0 → temapy-1.2.0}/README.md +79 -21
- {temapy-1.0.0 → temapy-1.2.0}/pyproject.toml +4 -3
- temapy-1.2.0/src/temapy/examples/outline_width.py +25 -0
- temapy-1.2.0/src/temapy/examples/two_points_to_line.py +32 -0
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy/gateway.py +5 -10
- temapy-1.2.0/src/temapy/sequences.py +282 -0
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy.egg-info/PKG-INFO +80 -22
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy.egg-info/SOURCES.txt +3 -1
- temapy-1.0.0/src/temapy/sequences.py +0 -140
- {temapy-1.0.0 → temapy-1.2.0}/setup.cfg +0 -0
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy/__init__.py +0 -0
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy/examples/__init__.py +0 -0
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy/examples/average_as_new_sequence.py +0 -0
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy.egg-info/dependency_links.txt +0 -0
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy.egg-info/requires.txt +0 -0
- {temapy-1.0.0 → temapy-1.2.0}/src/temapy.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: temapy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Python interface for scripting with TEMA
|
|
5
5
|
Author-email: Image Systems <support@imagesystems.se>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -25,6 +25,11 @@ Python environment that you will use in TEMA.
|
|
|
25
25
|
|
|
26
26
|
pip install temapy
|
|
27
27
|
|
|
28
|
+
To upgrade an existing installation to a newer temapy (required when a TEMA
|
|
29
|
+
release asks for a minimum version):
|
|
30
|
+
|
|
31
|
+
pip install --upgrade temapy
|
|
32
|
+
|
|
28
33
|
## Getting started: Create a TEMA compatible script
|
|
29
34
|
|
|
30
35
|
To create a TEMA compatible script, first import the `TemaGateway` class from
|
|
@@ -147,8 +152,8 @@ it.
|
|
|
147
152
|
|
|
148
153
|
The `Sequence` is the data structure that your update actions will operate on.
|
|
149
154
|
A sequence represents a set of measurements for each frame in the original image
|
|
150
|
-
sequence in TEMA. For each frame there is a
|
|
151
|
-
|
|
155
|
+
sequence in TEMA. For each frame there is a sample that contains data from that
|
|
156
|
+
frame of the image sequence.
|
|
152
157
|
|
|
153
158
|
#### updated range
|
|
154
159
|
|
|
@@ -164,54 +169,107 @@ during tracking.
|
|
|
164
169
|
|
|
165
170
|
#### Samples
|
|
166
171
|
|
|
167
|
-
The `samples` attribute is a dictionary that maps a frame number
|
|
168
|
-
|
|
169
|
-
in
|
|
170
|
-
|
|
172
|
+
The `samples` attribute is a dictionary that maps a frame number to a sample.
|
|
173
|
+
As this is a standard Python dictionary, it supports all standard dict
|
|
174
|
+
operations in Python. The concrete sample type depends on the sequence:
|
|
175
|
+
`NumericSample` for numeric data, `OutlineSample` for outlines, and
|
|
176
|
+
`LineSample` for 2D lines.
|
|
171
177
|
|
|
172
178
|
### Sample
|
|
173
179
|
|
|
174
|
-
|
|
180
|
+
`Sample` is the base class shared by all Temapy samples. Every sample has a
|
|
181
|
+
`status`. Scripts normally work with one of the concrete subclasses below.
|
|
182
|
+
|
|
183
|
+
### NumericSample
|
|
184
|
+
|
|
185
|
+
The `NumericSample` class contains numeric data for a specific frame of the
|
|
186
|
+
image sequence.
|
|
175
187
|
|
|
176
188
|
#### Data
|
|
177
189
|
|
|
178
|
-
The data of each
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
190
|
+
The data of each `NumericSample` is a list of numerical values, each value
|
|
191
|
+
representing a certain component of the data. What components are available
|
|
192
|
+
depends on the type of sequence. In a 2D position sequence, for example, each
|
|
193
|
+
`NumericSample` contains two data components, the x position and the y position
|
|
194
|
+
(`[x, y]`). A Length scalar uses a single component in `data[0]`.
|
|
195
|
+
|
|
196
|
+
#### Outline samples
|
|
197
|
+
|
|
198
|
+
An outline (chain code) input sequence contains `OutlineSample` objects instead
|
|
199
|
+
of `NumericSample` objects. Each outline sample provides:
|
|
200
|
+
|
|
201
|
+
- `points`: a list of `(x, y)` tuples describing the contour. Lens correction
|
|
202
|
+
and coordinate transformation have already been applied by TEMA.
|
|
203
|
+
- `start`: the raw `(x, y)` starting point of the chain code.
|
|
204
|
+
- `links`: the raw chain links as a string containing `U`, `D`, `L`, and `R`.
|
|
205
|
+
- `status`: the sample status, used in the same way as for numeric samples.
|
|
206
|
+
|
|
207
|
+
Outline sequences are currently input-only. Scripts can derive values from an
|
|
208
|
+
outline and write those values to numeric output sequences. See
|
|
209
|
+
`temapy.examples.outline_width` for an example.
|
|
210
|
+
|
|
211
|
+
#### 2D line outputs
|
|
212
|
+
|
|
213
|
+
A 2D line output uses a `LineSample`. Its `start` and `end` attributes are
|
|
214
|
+
coordinate lists describing the line's two endpoints (currently `[x, y]`):
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
line_sample.start = [x1, y1]
|
|
218
|
+
line_sample.end = [x2, y2]
|
|
219
|
+
line_sample.status = Status.CALCULATED
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Choose **2D line** as the output physical type in TEMA. The line can be added
|
|
223
|
+
to the Image Diagram as a distance overlay.
|
|
224
|
+
|
|
225
|
+
Output sequences share a world feature named by the prefix before the first
|
|
226
|
+
``_`` (for example ``point_position`` and ``point_speed`` both map to feature
|
|
227
|
+
``point``). 2D line arrays and 2D distances use a line feature; other types use
|
|
228
|
+
a point feature.
|
|
229
|
+
|
|
230
|
+
To show the length in meters on a line overlay (and in Time Table / 2D Diagram),
|
|
231
|
+
add a second output such as ``line_distance`` next to ``line`` with physical
|
|
232
|
+
type **2D distance**, and write the offset components:
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
line_distance.samples[frame].data[0] = end[0] - start[0]
|
|
236
|
+
line_distance.samples[frame].data[1] = end[1] - start[1]
|
|
237
|
+
line_distance.samples[frame].status = Status.CALCULATED
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
See `temapy.examples.two_points_to_line`.
|
|
183
241
|
|
|
184
242
|
#### Status
|
|
185
243
|
|
|
186
|
-
The `Status` of
|
|
244
|
+
The `Status` of a sample describes the nature of the sample and if it
|
|
187
245
|
should be used for calculations. Usually it is enough to use the
|
|
188
|
-
`Status.is_valid()` method
|
|
246
|
+
`Status.is_valid()` method to determine if the sample should be used or not.
|
|
189
247
|
For more fine grade control, each `Status` is described below.
|
|
190
248
|
|
|
191
249
|
**NONE:** No or unknown `Status`.
|
|
192
250
|
|
|
193
251
|
**FAILED:**
|
|
194
|
-
The data of the
|
|
252
|
+
The data of the sample failed in creation and that the data might not even be
|
|
195
253
|
readable, will cause undefined behaviour if used and might cause the script to
|
|
196
254
|
fail. Is invalid and cannot be used for calculations.
|
|
197
255
|
|
|
198
256
|
**SLEEPING:**
|
|
199
|
-
The data of the
|
|
257
|
+
The data of the sample is currently set to be ignored for calculation. The
|
|
200
258
|
data may be meaningful but should be considered invalid and not be used for
|
|
201
259
|
calculations.
|
|
202
260
|
|
|
203
261
|
**PREDICTED:**
|
|
204
|
-
Used by trackers for failed
|
|
205
|
-
found again or declared lost. The data of the
|
|
262
|
+
Used by trackers for failed samples that are predicted until they are either
|
|
263
|
+
found again or declared lost. The data of the sample may be meaningful but
|
|
206
264
|
should be considered invalid and not be used for calculations.
|
|
207
265
|
|
|
208
266
|
**MANUAL:**
|
|
209
|
-
The data of the
|
|
267
|
+
The data of the sample has been set manually and is therefore considered to be
|
|
210
268
|
valid for calculations.
|
|
211
269
|
|
|
212
270
|
**CALCULATED:**
|
|
213
|
-
The data of the
|
|
271
|
+
The data of the sample has been successfully calculated and
|
|
214
272
|
may be used for further calculations.
|
|
215
273
|
|
|
216
274
|
**INTERPOLATED:**
|
|
217
|
-
Similar to `CALCULATED` but the data is interpolated from other
|
|
275
|
+
Similar to `CALCULATED` but the data is interpolated from other samples.
|
|
@@ -13,6 +13,11 @@ Python environment that you will use in TEMA.
|
|
|
13
13
|
|
|
14
14
|
pip install temapy
|
|
15
15
|
|
|
16
|
+
To upgrade an existing installation to a newer temapy (required when a TEMA
|
|
17
|
+
release asks for a minimum version):
|
|
18
|
+
|
|
19
|
+
pip install --upgrade temapy
|
|
20
|
+
|
|
16
21
|
## Getting started: Create a TEMA compatible script
|
|
17
22
|
|
|
18
23
|
To create a TEMA compatible script, first import the `TemaGateway` class from
|
|
@@ -135,8 +140,8 @@ it.
|
|
|
135
140
|
|
|
136
141
|
The `Sequence` is the data structure that your update actions will operate on.
|
|
137
142
|
A sequence represents a set of measurements for each frame in the original image
|
|
138
|
-
sequence in TEMA. For each frame there is a
|
|
139
|
-
|
|
143
|
+
sequence in TEMA. For each frame there is a sample that contains data from that
|
|
144
|
+
frame of the image sequence.
|
|
140
145
|
|
|
141
146
|
#### updated range
|
|
142
147
|
|
|
@@ -152,54 +157,107 @@ during tracking.
|
|
|
152
157
|
|
|
153
158
|
#### Samples
|
|
154
159
|
|
|
155
|
-
The `samples` attribute is a dictionary that maps a frame number
|
|
156
|
-
|
|
157
|
-
in
|
|
158
|
-
|
|
160
|
+
The `samples` attribute is a dictionary that maps a frame number to a sample.
|
|
161
|
+
As this is a standard Python dictionary, it supports all standard dict
|
|
162
|
+
operations in Python. The concrete sample type depends on the sequence:
|
|
163
|
+
`NumericSample` for numeric data, `OutlineSample` for outlines, and
|
|
164
|
+
`LineSample` for 2D lines.
|
|
159
165
|
|
|
160
166
|
### Sample
|
|
161
167
|
|
|
162
|
-
|
|
168
|
+
`Sample` is the base class shared by all Temapy samples. Every sample has a
|
|
169
|
+
`status`. Scripts normally work with one of the concrete subclasses below.
|
|
170
|
+
|
|
171
|
+
### NumericSample
|
|
172
|
+
|
|
173
|
+
The `NumericSample` class contains numeric data for a specific frame of the
|
|
174
|
+
image sequence.
|
|
163
175
|
|
|
164
176
|
#### Data
|
|
165
177
|
|
|
166
|
-
The data of each
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
178
|
+
The data of each `NumericSample` is a list of numerical values, each value
|
|
179
|
+
representing a certain component of the data. What components are available
|
|
180
|
+
depends on the type of sequence. In a 2D position sequence, for example, each
|
|
181
|
+
`NumericSample` contains two data components, the x position and the y position
|
|
182
|
+
(`[x, y]`). A Length scalar uses a single component in `data[0]`.
|
|
183
|
+
|
|
184
|
+
#### Outline samples
|
|
185
|
+
|
|
186
|
+
An outline (chain code) input sequence contains `OutlineSample` objects instead
|
|
187
|
+
of `NumericSample` objects. Each outline sample provides:
|
|
188
|
+
|
|
189
|
+
- `points`: a list of `(x, y)` tuples describing the contour. Lens correction
|
|
190
|
+
and coordinate transformation have already been applied by TEMA.
|
|
191
|
+
- `start`: the raw `(x, y)` starting point of the chain code.
|
|
192
|
+
- `links`: the raw chain links as a string containing `U`, `D`, `L`, and `R`.
|
|
193
|
+
- `status`: the sample status, used in the same way as for numeric samples.
|
|
194
|
+
|
|
195
|
+
Outline sequences are currently input-only. Scripts can derive values from an
|
|
196
|
+
outline and write those values to numeric output sequences. See
|
|
197
|
+
`temapy.examples.outline_width` for an example.
|
|
198
|
+
|
|
199
|
+
#### 2D line outputs
|
|
200
|
+
|
|
201
|
+
A 2D line output uses a `LineSample`. Its `start` and `end` attributes are
|
|
202
|
+
coordinate lists describing the line's two endpoints (currently `[x, y]`):
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
line_sample.start = [x1, y1]
|
|
206
|
+
line_sample.end = [x2, y2]
|
|
207
|
+
line_sample.status = Status.CALCULATED
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Choose **2D line** as the output physical type in TEMA. The line can be added
|
|
211
|
+
to the Image Diagram as a distance overlay.
|
|
212
|
+
|
|
213
|
+
Output sequences share a world feature named by the prefix before the first
|
|
214
|
+
``_`` (for example ``point_position`` and ``point_speed`` both map to feature
|
|
215
|
+
``point``). 2D line arrays and 2D distances use a line feature; other types use
|
|
216
|
+
a point feature.
|
|
217
|
+
|
|
218
|
+
To show the length in meters on a line overlay (and in Time Table / 2D Diagram),
|
|
219
|
+
add a second output such as ``line_distance`` next to ``line`` with physical
|
|
220
|
+
type **2D distance**, and write the offset components:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
line_distance.samples[frame].data[0] = end[0] - start[0]
|
|
224
|
+
line_distance.samples[frame].data[1] = end[1] - start[1]
|
|
225
|
+
line_distance.samples[frame].status = Status.CALCULATED
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
See `temapy.examples.two_points_to_line`.
|
|
171
229
|
|
|
172
230
|
#### Status
|
|
173
231
|
|
|
174
|
-
The `Status` of
|
|
232
|
+
The `Status` of a sample describes the nature of the sample and if it
|
|
175
233
|
should be used for calculations. Usually it is enough to use the
|
|
176
|
-
`Status.is_valid()` method
|
|
234
|
+
`Status.is_valid()` method to determine if the sample should be used or not.
|
|
177
235
|
For more fine grade control, each `Status` is described below.
|
|
178
236
|
|
|
179
237
|
**NONE:** No or unknown `Status`.
|
|
180
238
|
|
|
181
239
|
**FAILED:**
|
|
182
|
-
The data of the
|
|
240
|
+
The data of the sample failed in creation and that the data might not even be
|
|
183
241
|
readable, will cause undefined behaviour if used and might cause the script to
|
|
184
242
|
fail. Is invalid and cannot be used for calculations.
|
|
185
243
|
|
|
186
244
|
**SLEEPING:**
|
|
187
|
-
The data of the
|
|
245
|
+
The data of the sample is currently set to be ignored for calculation. The
|
|
188
246
|
data may be meaningful but should be considered invalid and not be used for
|
|
189
247
|
calculations.
|
|
190
248
|
|
|
191
249
|
**PREDICTED:**
|
|
192
|
-
Used by trackers for failed
|
|
193
|
-
found again or declared lost. The data of the
|
|
250
|
+
Used by trackers for failed samples that are predicted until they are either
|
|
251
|
+
found again or declared lost. The data of the sample may be meaningful but
|
|
194
252
|
should be considered invalid and not be used for calculations.
|
|
195
253
|
|
|
196
254
|
**MANUAL:**
|
|
197
|
-
The data of the
|
|
255
|
+
The data of the sample has been set manually and is therefore considered to be
|
|
198
256
|
valid for calculations.
|
|
199
257
|
|
|
200
258
|
**CALCULATED:**
|
|
201
|
-
The data of the
|
|
259
|
+
The data of the sample has been successfully calculated and
|
|
202
260
|
may be used for further calculations.
|
|
203
261
|
|
|
204
262
|
**INTERPOLATED:**
|
|
205
|
-
Similar to `CALCULATED` but the data is interpolated from other
|
|
263
|
+
Similar to `CALCULATED` but the data is interpolated from other samples.
|
|
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "temapy"
|
|
10
|
-
version = "1.
|
|
10
|
+
version = "1.2.0"
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "Image Systems", email = "support@imagesystems.se" }
|
|
13
13
|
]
|
|
@@ -46,6 +46,7 @@ env_list = [
|
|
|
46
46
|
"lint",
|
|
47
47
|
# FIXME: Disabled to not prevent merging. We should probably do type-checking in the future
|
|
48
48
|
# "type",
|
|
49
|
+
"3.14",
|
|
49
50
|
"3.13",
|
|
50
51
|
"3.12",
|
|
51
52
|
"3.11",
|
|
@@ -67,7 +68,7 @@ commands = [
|
|
|
67
68
|
description = "run linters"
|
|
68
69
|
deps = ["pylint"]
|
|
69
70
|
commands = [
|
|
70
|
-
["pylint", { replace = "posargs", default = ["src"
|
|
71
|
+
["pylint", { replace = "posargs", default = ["src"], extend = true }, "--disable=fixme,too-few-public-methods, too-many-instance-attributes", ],
|
|
71
72
|
]
|
|
72
73
|
|
|
73
74
|
|
|
@@ -75,5 +76,5 @@ commands = [
|
|
|
75
76
|
description = "run type checks"
|
|
76
77
|
deps = ["mypy"]
|
|
77
78
|
commands = [
|
|
78
|
-
["mypy", { replace = "posargs", default = ["src"
|
|
79
|
+
["mypy", { replace = "posargs", default = ["src"], extend = true }],
|
|
79
80
|
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Calculates the axis-aligned width of an outline for every valid sample.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from temapy.gateway import TemaGateway
|
|
6
|
+
from temapy.sequences import Status
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
tema_gateway = TemaGateway()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@tema_gateway.update_action(
|
|
13
|
+
input_sequences=("outline",), output_sequences=("width",)
|
|
14
|
+
)
|
|
15
|
+
def calculate_outline_width(outline, width):
|
|
16
|
+
"""
|
|
17
|
+
Writes the difference between the largest and smallest x coordinate.
|
|
18
|
+
"""
|
|
19
|
+
for frame, sample in outline.samples.items():
|
|
20
|
+
if not sample.status.is_valid() or not sample.points:
|
|
21
|
+
continue
|
|
22
|
+
|
|
23
|
+
x_coordinates = [x for x, _ in sample.points]
|
|
24
|
+
width.samples[frame].data[0] = max(x_coordinates) - min(x_coordinates)
|
|
25
|
+
width.samples[frame].status = Status.CALCULATED
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Builds a 2D line from two point sequences, plus a 2D distance sibling for the overlay.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from temapy.gateway import TemaGateway
|
|
6
|
+
from temapy.sequences import Status
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
tema_gateway = TemaGateway()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@tema_gateway.update_action(
|
|
13
|
+
input_sequences=("p1", "p2"), output_sequences=("line", "line_distance")
|
|
14
|
+
)
|
|
15
|
+
def make_line(p1, p2, line, line_distance):
|
|
16
|
+
"""
|
|
17
|
+
Writes a two-point line and its 2D distance for every frame where both points are valid.
|
|
18
|
+
|
|
19
|
+
Name the distance output with the same prefix as the line (here ``line_distance`` next to
|
|
20
|
+
``line``) and set its physical type to **2D distance** so both share the same line feature.
|
|
21
|
+
"""
|
|
22
|
+
for frame, sample_p1 in p1.samples.items():
|
|
23
|
+
sample_p2 = p2.samples[frame]
|
|
24
|
+
if sample_p1.status.is_valid() and sample_p2.status.is_valid():
|
|
25
|
+
start = [sample_p1.data[0], sample_p1.data[1]]
|
|
26
|
+
end = [sample_p2.data[0], sample_p2.data[1]]
|
|
27
|
+
line.samples[frame].start = start
|
|
28
|
+
line.samples[frame].end = end
|
|
29
|
+
line.samples[frame].status = Status.CALCULATED
|
|
30
|
+
line_distance.samples[frame].data[0] = end[0] - start[0]
|
|
31
|
+
line_distance.samples[frame].data[1] = end[1] - start[1]
|
|
32
|
+
line_distance.samples[frame].status = Status.CALCULATED
|
|
@@ -89,9 +89,10 @@ class TemaGateway:
|
|
|
89
89
|
called.
|
|
90
90
|
:return:
|
|
91
91
|
"""
|
|
92
|
-
# Start py4j Java Gateway with a callback server
|
|
92
|
+
# Start py4j Java Gateway with a callback server.
|
|
93
93
|
self.tema = JavaGateway(
|
|
94
|
-
gateway_parameters=GatewayParameters(port=self.tema_port
|
|
94
|
+
gateway_parameters=GatewayParameters(port=self.tema_port,
|
|
95
|
+
auto_convert=True),
|
|
95
96
|
# Dynamically allocate a port for the callback server
|
|
96
97
|
callback_server_parameters=CallbackServerParameters(port=0),
|
|
97
98
|
python_server_entry_point=self,
|
|
@@ -261,16 +262,10 @@ class TemaGateway:
|
|
|
261
262
|
for timestamp, sample in self.output_sequences[
|
|
262
263
|
sequence_name
|
|
263
264
|
].samples.items():
|
|
264
|
-
|
|
265
|
-
|
|
265
|
+
sample.write_to_tema_sample(
|
|
266
|
+
tema_sequence_samples[timestamp]
|
|
266
267
|
)
|
|
267
268
|
|
|
268
|
-
for i, data_point in enumerate(sample.data):
|
|
269
|
-
java_double_array[i] = data_point
|
|
270
|
-
|
|
271
|
-
tema_sequence_samples[timestamp].setData(java_double_array)
|
|
272
|
-
tema_sequence_samples[timestamp].setStatus(sample.status.value)
|
|
273
|
-
|
|
274
269
|
def _parse_tema_port(self):
|
|
275
270
|
"""
|
|
276
271
|
Parses the --tema_port program argument if it exists and sets the
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Classes to represent TEMA sequence data in Python.
|
|
3
|
+
|
|
4
|
+
Users should not need to create their own sequences or samples but
|
|
5
|
+
simply edit those that are provided by Temapy.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from array import array
|
|
10
|
+
from enum import Enum
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
from py4j.protocol import Py4JError
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Sequence:
|
|
17
|
+
"""
|
|
18
|
+
Represents a sequence as a dict mapping a frame-index to a Sample. Also
|
|
19
|
+
provides the updated_range, i.e. the range of indexes that have changed
|
|
20
|
+
since the last update, as a tuple.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, samples, updated_range):
|
|
24
|
+
self.samples = samples
|
|
25
|
+
self.updated_range = updated_range
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def of_tema_sequence(cls, tema_sequence):
|
|
29
|
+
"""
|
|
30
|
+
Factory method to create a new sequence with data copied from the given
|
|
31
|
+
sequence from Tema.
|
|
32
|
+
|
|
33
|
+
:param tema_sequence: The sequence to copy as returned from Tema
|
|
34
|
+
:return: A copy of the Tema sequence
|
|
35
|
+
"""
|
|
36
|
+
# TODO: Future improvement to utilize the updated range to
|
|
37
|
+
# minimize Java-Python data transfer
|
|
38
|
+
try:
|
|
39
|
+
sample_type = str(tema_sequence.getSampleType())
|
|
40
|
+
except Py4JError:
|
|
41
|
+
# Older TEMA versions only expose numeric samples.
|
|
42
|
+
sample_type = "NUMERIC"
|
|
43
|
+
sample_factory = _SAMPLE_FACTORIES.get(sample_type, NumericSample)
|
|
44
|
+
samples = {}
|
|
45
|
+
for timestamp, tema_sample in tema_sequence.getSamples().items():
|
|
46
|
+
samples[timestamp] = sample_factory.of_tema_sample(tema_sample)
|
|
47
|
+
|
|
48
|
+
updated_range = (
|
|
49
|
+
int(tema_sequence.getUpdatedRange().start()),
|
|
50
|
+
int(tema_sequence.getUpdatedRange().stop()),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return cls(samples, updated_range)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class Sample(ABC):
|
|
57
|
+
"""
|
|
58
|
+
Base class for all Temapy samples.
|
|
59
|
+
|
|
60
|
+
Concrete sample types share a ``status`` and type-specific data attributes.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def __init__(self, status):
|
|
64
|
+
self.status = status
|
|
65
|
+
|
|
66
|
+
@classmethod
|
|
67
|
+
@abstractmethod
|
|
68
|
+
def of_tema_sample(cls, tema_sample):
|
|
69
|
+
"""
|
|
70
|
+
Factory method to create a new sample with data copied from the given
|
|
71
|
+
sample from TEMA.
|
|
72
|
+
|
|
73
|
+
NOTE: This method is not intended to be used directly when writing
|
|
74
|
+
scripts.
|
|
75
|
+
|
|
76
|
+
:param tema_sample: The sample to copy as returned from Tema.
|
|
77
|
+
:return: A copy of the Tema sample
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
@abstractmethod
|
|
81
|
+
def write_to_tema_sample(self, tema_sample):
|
|
82
|
+
"""
|
|
83
|
+
Copies this sample to its corresponding TEMA sample.
|
|
84
|
+
|
|
85
|
+
NOTE: This method is used internally by the gateway.
|
|
86
|
+
|
|
87
|
+
:param tema_sample: The TEMA sample to write to.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class NumericSample(Sample):
|
|
92
|
+
"""
|
|
93
|
+
Represents a numeric sample as a list of data components and a status.
|
|
94
|
+
|
|
95
|
+
For 2D positional data the data components are [x, y], i.e. data[0] will
|
|
96
|
+
give the x component and data[1] the y component. Scalars such as Length
|
|
97
|
+
use a single component in data[0].
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
def __init__(self, data, status):
|
|
101
|
+
super().__init__(status)
|
|
102
|
+
self.data = data
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
def of_tema_sample(cls, tema_sample):
|
|
106
|
+
"""
|
|
107
|
+
Factory method to create a new sample with data copied from the given
|
|
108
|
+
sample from TEMA.
|
|
109
|
+
|
|
110
|
+
NOTE: This method is not intended to be used directly when writing
|
|
111
|
+
scripts.
|
|
112
|
+
|
|
113
|
+
:param tema_sample: The sample to copy as returned from Tema.
|
|
114
|
+
:return: A copy of the Tema sample
|
|
115
|
+
"""
|
|
116
|
+
data = [float(data_point) for data_point in tema_sample.getData()]
|
|
117
|
+
status = Status(tema_sample.getStatusAsInt())
|
|
118
|
+
return cls(list(data), status)
|
|
119
|
+
|
|
120
|
+
def write_to_tema_sample(self, tema_sample):
|
|
121
|
+
"""
|
|
122
|
+
Copies this numeric sample to its corresponding TEMA sample.
|
|
123
|
+
|
|
124
|
+
NOTE: This method is used internally by the gateway.
|
|
125
|
+
"""
|
|
126
|
+
# auto_convert turns this list into a Java List for setData
|
|
127
|
+
tema_sample.setData(list(self.data))
|
|
128
|
+
tema_sample.setStatus(self.status.value)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class LineSample(Sample):
|
|
132
|
+
"""
|
|
133
|
+
Represents a two-point line sample.
|
|
134
|
+
|
|
135
|
+
``start`` and ``end`` are coordinate lists, currently ``[x, y]`` for 2D
|
|
136
|
+
lines in TEMA. A line always has exactly these two endpoints.
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
def __init__(self, start, end, status):
|
|
140
|
+
super().__init__(status)
|
|
141
|
+
self.start = start
|
|
142
|
+
self.end = end
|
|
143
|
+
|
|
144
|
+
@classmethod
|
|
145
|
+
def of_tema_sample(cls, tema_sample):
|
|
146
|
+
"""
|
|
147
|
+
Factory method to copy a line sample returned from TEMA.
|
|
148
|
+
|
|
149
|
+
NOTE: This method is not intended to be used directly when writing
|
|
150
|
+
scripts.
|
|
151
|
+
"""
|
|
152
|
+
start = [float(tema_sample.getStartX()), float(tema_sample.getStartY())]
|
|
153
|
+
end = [float(tema_sample.getEndX()), float(tema_sample.getEndY())]
|
|
154
|
+
status = Status(tema_sample.getStatusAsInt())
|
|
155
|
+
return cls(start, end, status)
|
|
156
|
+
|
|
157
|
+
def write_to_tema_sample(self, tema_sample):
|
|
158
|
+
"""
|
|
159
|
+
Copies this line sample to its corresponding TEMA sample.
|
|
160
|
+
|
|
161
|
+
NOTE: This method is used internally by the gateway.
|
|
162
|
+
"""
|
|
163
|
+
tema_sample.setStartX(self.start[0])
|
|
164
|
+
tema_sample.setStartY(self.start[1])
|
|
165
|
+
tema_sample.setEndX(self.end[0])
|
|
166
|
+
tema_sample.setEndY(self.end[1])
|
|
167
|
+
tema_sample.setStatus(self.status.value)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class OutlineSample(Sample):
|
|
171
|
+
"""
|
|
172
|
+
Represents an outline sample.
|
|
173
|
+
|
|
174
|
+
``points`` contains the lens-corrected and coordinate-transformed contour
|
|
175
|
+
as ``(x, y)`` tuples. ``start`` and ``links`` contain the raw chain code.
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
def __init__(self, points, start, links, status):
|
|
179
|
+
super().__init__(status)
|
|
180
|
+
self.points = points
|
|
181
|
+
self.start = start
|
|
182
|
+
self.links = links
|
|
183
|
+
|
|
184
|
+
@classmethod
|
|
185
|
+
def of_tema_sample(cls, tema_sample):
|
|
186
|
+
"""
|
|
187
|
+
Factory method to copy an outline sample returned from TEMA.
|
|
188
|
+
|
|
189
|
+
NOTE: This method is not intended to be used directly when writing
|
|
190
|
+
scripts.
|
|
191
|
+
"""
|
|
192
|
+
values = array("d")
|
|
193
|
+
values.frombytes(tema_sample.getPoints())
|
|
194
|
+
if sys.byteorder == "little":
|
|
195
|
+
values.byteswap()
|
|
196
|
+
|
|
197
|
+
points = [(values[i], values[i+1]) for i in range(0, len(values), 2)]
|
|
198
|
+
start = (float(tema_sample.getStartX()), float(tema_sample.getStartY()))
|
|
199
|
+
links = str(tema_sample.getLinks())
|
|
200
|
+
status = Status(tema_sample.getStatusAsInt())
|
|
201
|
+
return cls(points, start, links, status)
|
|
202
|
+
|
|
203
|
+
def write_to_tema_sample(self, tema_sample):
|
|
204
|
+
"""
|
|
205
|
+
Outline samples are not written back to TEMA.
|
|
206
|
+
|
|
207
|
+
NOTE: This method is used internally by the gateway.
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
_SAMPLE_FACTORIES = {
|
|
212
|
+
"NUMERIC": NumericSample,
|
|
213
|
+
"CHAIN_CODE": OutlineSample,
|
|
214
|
+
"LINE": LineSample,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class Status(Enum):
|
|
219
|
+
"""
|
|
220
|
+
Enum for statuses compatible with Tema.
|
|
221
|
+
|
|
222
|
+
In the normal case, any sample that is not valid (see Status.is_valid())
|
|
223
|
+
should not be used for calculation.
|
|
224
|
+
|
|
225
|
+
Any sample changed by a script should usually be given the Status CALCULATED.
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
NONE = 1
|
|
229
|
+
"""
|
|
230
|
+
No status or unknown status.
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
FAILED = 2
|
|
234
|
+
"""
|
|
235
|
+
Failed status. The data of the Sample failed in creation and that the data
|
|
236
|
+
might not even be readable. Is invalid and cannot be used for calculations.
|
|
237
|
+
"""
|
|
238
|
+
|
|
239
|
+
SLEEPING = 3
|
|
240
|
+
"""
|
|
241
|
+
Sleeping status. The data of the Sample is currently set to be ignored for
|
|
242
|
+
calculation. The data may be meaningful but should be considered invalid
|
|
243
|
+
and not be used for calculations.
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
PREDICTED = 4
|
|
247
|
+
"""
|
|
248
|
+
Predicted status. Used by trackers for failed samples that are predicted
|
|
249
|
+
until they are either found again or declared lost. The data of the Sample
|
|
250
|
+
may be meaningful but should be considered invalid and not be used for
|
|
251
|
+
calculations.
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
MANUAL = 5
|
|
255
|
+
"""
|
|
256
|
+
Manual status. The data of the Sample has been set manually and is therefore
|
|
257
|
+
considered to be valid for calculations.
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
CALCULATED = 6
|
|
261
|
+
"""
|
|
262
|
+
Calculated status. The data of the Sample has been successfully calculated
|
|
263
|
+
and may be used for further calculations.
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
INTERPOLATED = 7
|
|
267
|
+
"""
|
|
268
|
+
Interpolated status. Similar to CALCULATED but the data is interpolated from
|
|
269
|
+
other Samples.
|
|
270
|
+
"""
|
|
271
|
+
|
|
272
|
+
def is_valid(self):
|
|
273
|
+
"""
|
|
274
|
+
Checks if the status is noe that is considered valid
|
|
275
|
+
:return: True if the Status is valid
|
|
276
|
+
"""
|
|
277
|
+
return self not in [
|
|
278
|
+
Status.NONE,
|
|
279
|
+
Status.FAILED,
|
|
280
|
+
Status.SLEEPING,
|
|
281
|
+
Status.PREDICTED,
|
|
282
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: temapy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Python interface for scripting with TEMA
|
|
5
5
|
Author-email: Image Systems <support@imagesystems.se>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -25,6 +25,11 @@ Python environment that you will use in TEMA.
|
|
|
25
25
|
|
|
26
26
|
pip install temapy
|
|
27
27
|
|
|
28
|
+
To upgrade an existing installation to a newer temapy (required when a TEMA
|
|
29
|
+
release asks for a minimum version):
|
|
30
|
+
|
|
31
|
+
pip install --upgrade temapy
|
|
32
|
+
|
|
28
33
|
## Getting started: Create a TEMA compatible script
|
|
29
34
|
|
|
30
35
|
To create a TEMA compatible script, first import the `TemaGateway` class from
|
|
@@ -147,8 +152,8 @@ it.
|
|
|
147
152
|
|
|
148
153
|
The `Sequence` is the data structure that your update actions will operate on.
|
|
149
154
|
A sequence represents a set of measurements for each frame in the original image
|
|
150
|
-
sequence in TEMA. For each frame there is a
|
|
151
|
-
|
|
155
|
+
sequence in TEMA. For each frame there is a sample that contains data from that
|
|
156
|
+
frame of the image sequence.
|
|
152
157
|
|
|
153
158
|
#### updated range
|
|
154
159
|
|
|
@@ -164,54 +169,107 @@ during tracking.
|
|
|
164
169
|
|
|
165
170
|
#### Samples
|
|
166
171
|
|
|
167
|
-
The `samples` attribute is a dictionary that maps a frame number
|
|
168
|
-
|
|
169
|
-
in
|
|
170
|
-
|
|
172
|
+
The `samples` attribute is a dictionary that maps a frame number to a sample.
|
|
173
|
+
As this is a standard Python dictionary, it supports all standard dict
|
|
174
|
+
operations in Python. The concrete sample type depends on the sequence:
|
|
175
|
+
`NumericSample` for numeric data, `OutlineSample` for outlines, and
|
|
176
|
+
`LineSample` for 2D lines.
|
|
171
177
|
|
|
172
178
|
### Sample
|
|
173
179
|
|
|
174
|
-
|
|
180
|
+
`Sample` is the base class shared by all Temapy samples. Every sample has a
|
|
181
|
+
`status`. Scripts normally work with one of the concrete subclasses below.
|
|
182
|
+
|
|
183
|
+
### NumericSample
|
|
184
|
+
|
|
185
|
+
The `NumericSample` class contains numeric data for a specific frame of the
|
|
186
|
+
image sequence.
|
|
175
187
|
|
|
176
188
|
#### Data
|
|
177
189
|
|
|
178
|
-
The data of each
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
190
|
+
The data of each `NumericSample` is a list of numerical values, each value
|
|
191
|
+
representing a certain component of the data. What components are available
|
|
192
|
+
depends on the type of sequence. In a 2D position sequence, for example, each
|
|
193
|
+
`NumericSample` contains two data components, the x position and the y position
|
|
194
|
+
(`[x, y]`). A Length scalar uses a single component in `data[0]`.
|
|
195
|
+
|
|
196
|
+
#### Outline samples
|
|
197
|
+
|
|
198
|
+
An outline (chain code) input sequence contains `OutlineSample` objects instead
|
|
199
|
+
of `NumericSample` objects. Each outline sample provides:
|
|
200
|
+
|
|
201
|
+
- `points`: a list of `(x, y)` tuples describing the contour. Lens correction
|
|
202
|
+
and coordinate transformation have already been applied by TEMA.
|
|
203
|
+
- `start`: the raw `(x, y)` starting point of the chain code.
|
|
204
|
+
- `links`: the raw chain links as a string containing `U`, `D`, `L`, and `R`.
|
|
205
|
+
- `status`: the sample status, used in the same way as for numeric samples.
|
|
206
|
+
|
|
207
|
+
Outline sequences are currently input-only. Scripts can derive values from an
|
|
208
|
+
outline and write those values to numeric output sequences. See
|
|
209
|
+
`temapy.examples.outline_width` for an example.
|
|
210
|
+
|
|
211
|
+
#### 2D line outputs
|
|
212
|
+
|
|
213
|
+
A 2D line output uses a `LineSample`. Its `start` and `end` attributes are
|
|
214
|
+
coordinate lists describing the line's two endpoints (currently `[x, y]`):
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
line_sample.start = [x1, y1]
|
|
218
|
+
line_sample.end = [x2, y2]
|
|
219
|
+
line_sample.status = Status.CALCULATED
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Choose **2D line** as the output physical type in TEMA. The line can be added
|
|
223
|
+
to the Image Diagram as a distance overlay.
|
|
224
|
+
|
|
225
|
+
Output sequences share a world feature named by the prefix before the first
|
|
226
|
+
``_`` (for example ``point_position`` and ``point_speed`` both map to feature
|
|
227
|
+
``point``). 2D line arrays and 2D distances use a line feature; other types use
|
|
228
|
+
a point feature.
|
|
229
|
+
|
|
230
|
+
To show the length in meters on a line overlay (and in Time Table / 2D Diagram),
|
|
231
|
+
add a second output such as ``line_distance`` next to ``line`` with physical
|
|
232
|
+
type **2D distance**, and write the offset components:
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
line_distance.samples[frame].data[0] = end[0] - start[0]
|
|
236
|
+
line_distance.samples[frame].data[1] = end[1] - start[1]
|
|
237
|
+
line_distance.samples[frame].status = Status.CALCULATED
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
See `temapy.examples.two_points_to_line`.
|
|
183
241
|
|
|
184
242
|
#### Status
|
|
185
243
|
|
|
186
|
-
The `Status` of
|
|
244
|
+
The `Status` of a sample describes the nature of the sample and if it
|
|
187
245
|
should be used for calculations. Usually it is enough to use the
|
|
188
|
-
`Status.is_valid()` method
|
|
246
|
+
`Status.is_valid()` method to determine if the sample should be used or not.
|
|
189
247
|
For more fine grade control, each `Status` is described below.
|
|
190
248
|
|
|
191
249
|
**NONE:** No or unknown `Status`.
|
|
192
250
|
|
|
193
251
|
**FAILED:**
|
|
194
|
-
The data of the
|
|
252
|
+
The data of the sample failed in creation and that the data might not even be
|
|
195
253
|
readable, will cause undefined behaviour if used and might cause the script to
|
|
196
254
|
fail. Is invalid and cannot be used for calculations.
|
|
197
255
|
|
|
198
256
|
**SLEEPING:**
|
|
199
|
-
The data of the
|
|
257
|
+
The data of the sample is currently set to be ignored for calculation. The
|
|
200
258
|
data may be meaningful but should be considered invalid and not be used for
|
|
201
259
|
calculations.
|
|
202
260
|
|
|
203
261
|
**PREDICTED:**
|
|
204
|
-
Used by trackers for failed
|
|
205
|
-
found again or declared lost. The data of the
|
|
262
|
+
Used by trackers for failed samples that are predicted until they are either
|
|
263
|
+
found again or declared lost. The data of the sample may be meaningful but
|
|
206
264
|
should be considered invalid and not be used for calculations.
|
|
207
265
|
|
|
208
266
|
**MANUAL:**
|
|
209
|
-
The data of the
|
|
267
|
+
The data of the sample has been set manually and is therefore considered to be
|
|
210
268
|
valid for calculations.
|
|
211
269
|
|
|
212
270
|
**CALCULATED:**
|
|
213
|
-
The data of the
|
|
271
|
+
The data of the sample has been successfully calculated and
|
|
214
272
|
may be used for further calculations.
|
|
215
273
|
|
|
216
274
|
**INTERPOLATED:**
|
|
217
|
-
Similar to `CALCULATED` but the data is interpolated from other
|
|
275
|
+
Similar to `CALCULATED` but the data is interpolated from other samples.
|
|
@@ -9,4 +9,6 @@ src/temapy.egg-info/dependency_links.txt
|
|
|
9
9
|
src/temapy.egg-info/requires.txt
|
|
10
10
|
src/temapy.egg-info/top_level.txt
|
|
11
11
|
src/temapy/examples/__init__.py
|
|
12
|
-
src/temapy/examples/average_as_new_sequence.py
|
|
12
|
+
src/temapy/examples/average_as_new_sequence.py
|
|
13
|
+
src/temapy/examples/outline_width.py
|
|
14
|
+
src/temapy/examples/two_points_to_line.py
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Classes to represent TEMA sequence data in Python.
|
|
3
|
-
|
|
4
|
-
Users should not need to create their own sequences or samples but
|
|
5
|
-
simply edit those that are provided by Temapy.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from enum import Enum
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class Sequence:
|
|
12
|
-
"""
|
|
13
|
-
Represents a sequence as a dict mapping a frame-index to a Sample. Also
|
|
14
|
-
provides the updated_range, i.e. the range of indexes that have changed
|
|
15
|
-
since the last update, as a tuple.
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
def __init__(self, samples, updated_range):
|
|
19
|
-
self.samples = samples
|
|
20
|
-
self.updated_range = updated_range
|
|
21
|
-
|
|
22
|
-
@classmethod
|
|
23
|
-
def of_tema_sequence(cls, tema_sequence):
|
|
24
|
-
"""
|
|
25
|
-
Factory method to create a new sequence with data copied from the given
|
|
26
|
-
sequence from Tema.
|
|
27
|
-
|
|
28
|
-
:param tema_sequence: The sequence to copy as returned from Tema
|
|
29
|
-
:return: A copy of the Tema sequence
|
|
30
|
-
"""
|
|
31
|
-
# TODO: Future improvement to utilize the updated range to
|
|
32
|
-
# minimize Java-Python data transfer
|
|
33
|
-
samples = {}
|
|
34
|
-
for timestamp, tema_sample in tema_sequence.getSamples().items():
|
|
35
|
-
samples[timestamp] = Sample.of_tema_sample(tema_sample)
|
|
36
|
-
|
|
37
|
-
updated_range = (
|
|
38
|
-
int(tema_sequence.getUpdatedRange().start()),
|
|
39
|
-
int(tema_sequence.getUpdatedRange().stop()),
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
return cls(samples, updated_range)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class Sample:
|
|
46
|
-
"""
|
|
47
|
-
Represents a sample as a list of data points and a status.
|
|
48
|
-
|
|
49
|
-
For 2D positional data the data components are [x, y], i.e. data[0] will
|
|
50
|
-
give the x component and data[1] the y component.
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
def __init__(self, data, status):
|
|
54
|
-
self.data = data
|
|
55
|
-
# TODO: status should be represented as an enum, will be done
|
|
56
|
-
# when Java side is being implemented.
|
|
57
|
-
self.status = status
|
|
58
|
-
|
|
59
|
-
@classmethod
|
|
60
|
-
def of_tema_sample(cls, tema_sample):
|
|
61
|
-
"""
|
|
62
|
-
Factory method to create a new sample with data copied from the given
|
|
63
|
-
sample from TEMA.
|
|
64
|
-
|
|
65
|
-
NOTE: This method is not intended to be used directly when writing
|
|
66
|
-
scripts.
|
|
67
|
-
|
|
68
|
-
:param tema_sample: The sample to copy as returned from Tema.
|
|
69
|
-
:return: A copy of the Tema sample
|
|
70
|
-
"""
|
|
71
|
-
data = [float(data_point) for data_point in tema_sample.getData()]
|
|
72
|
-
status = Status(tema_sample.getStatusAsInt())
|
|
73
|
-
return cls(list(data), status)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class Status(Enum):
|
|
77
|
-
"""
|
|
78
|
-
Enum for statuses compatible with Tema.
|
|
79
|
-
|
|
80
|
-
In the normal case, any sample that is not valid (see Status.is_valid())
|
|
81
|
-
should not be used for calculation.
|
|
82
|
-
|
|
83
|
-
Any sample changed by a script should usually be given the Status CALCULATED.
|
|
84
|
-
"""
|
|
85
|
-
|
|
86
|
-
NONE = 1
|
|
87
|
-
"""
|
|
88
|
-
No status or unknown status.
|
|
89
|
-
"""
|
|
90
|
-
|
|
91
|
-
FAILED = 2
|
|
92
|
-
"""
|
|
93
|
-
Failed status. The data of the Sample failed in creation and that the data
|
|
94
|
-
might not even be readable. Is invalid and cannot be used for calculations.
|
|
95
|
-
"""
|
|
96
|
-
|
|
97
|
-
SLEEPING = 3
|
|
98
|
-
"""
|
|
99
|
-
Sleeping status. The data of the Sample is currently set to be ignored for
|
|
100
|
-
calculation. The data may be meaningful but should be considered invalid
|
|
101
|
-
and not be used for calculations.
|
|
102
|
-
"""
|
|
103
|
-
|
|
104
|
-
PREDICTED = 4
|
|
105
|
-
"""
|
|
106
|
-
Predicted status. Used by trackers for failed samples that are predicted
|
|
107
|
-
until they are either found again or declared lost. The data of the Sample
|
|
108
|
-
may be meaningful but should be considered invalid and not be used for
|
|
109
|
-
calculations.
|
|
110
|
-
"""
|
|
111
|
-
|
|
112
|
-
MANUAL = 5
|
|
113
|
-
"""
|
|
114
|
-
Manual status. The data of the Sample has been set manually and is therefore
|
|
115
|
-
considered to be valid for calculations.
|
|
116
|
-
"""
|
|
117
|
-
|
|
118
|
-
CALCULATED = 6
|
|
119
|
-
"""
|
|
120
|
-
Calculated status. The data of the Sample has been successfully calculated
|
|
121
|
-
and may be used for further calculations.
|
|
122
|
-
"""
|
|
123
|
-
|
|
124
|
-
INTERPOLATED = 7
|
|
125
|
-
"""
|
|
126
|
-
Interpolated status. Similar to CALCULATED but the data is interpolated from
|
|
127
|
-
other Samples.
|
|
128
|
-
"""
|
|
129
|
-
|
|
130
|
-
def is_valid(self):
|
|
131
|
-
"""
|
|
132
|
-
Checks if the status is noe that is considered valid
|
|
133
|
-
:return: True if the Status is valid
|
|
134
|
-
"""
|
|
135
|
-
return self not in [
|
|
136
|
-
Status.NONE,
|
|
137
|
-
Status.FAILED,
|
|
138
|
-
Status.SLEEPING,
|
|
139
|
-
Status.PREDICTED,
|
|
140
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|