temapy 1.0.0__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.
temapy/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,30 @@
1
+ """
2
+ Test script that adds an update action to calculate the average pos of
3
+ every sample in two sequences.
4
+ """
5
+
6
+ from temapy.gateway import TemaGateway
7
+ from temapy.sequences import Status
8
+
9
+
10
+ tema_gateway = TemaGateway()
11
+
12
+
13
+ @tema_gateway.update_action(
14
+ input_sequences=("p1_pos", "p2_pos"), output_sequences=("avg_pos",)
15
+ )
16
+ def average_per_sample(seq_1, seq_2, seq_out):
17
+ """
18
+ calculates the average pos of every sample in two sequences.
19
+
20
+ :param seq_1: the first sequence
21
+ :param seq_2: the second sequence
22
+ :param seq_out: sequence to put result in
23
+ :return:
24
+ """
25
+ both_sequences = zip(seq_1.samples.items(), seq_2.samples.values())
26
+ for (time_1, sample_1), sample_2 in both_sequences:
27
+ if seq_1.samples[time_1].status.is_valid():
28
+ seq_out.samples[time_1].data[0] = (sample_1.data[0] + sample_2.data[0]) / 2
29
+ seq_out.samples[time_1].data[1] = (sample_1.data[1] + sample_2.data[1]) / 2
30
+ seq_out.samples[time_1].status = Status.CALCULATED
temapy/gateway.py ADDED
@@ -0,0 +1,291 @@
1
+ """
2
+ Module to set up a connection to a running Tema session.
3
+ """
4
+
5
+ import argparse
6
+ import threading
7
+
8
+ from py4j.clientserver import ClientServer
9
+ from py4j.java_gateway import DEFAULT_PORT
10
+ from py4j.java_gateway import JavaGateway, CallbackServerParameters, GatewayParameters
11
+
12
+ from temapy.sequences import Sequence
13
+
14
+
15
+ class TemaGateway:
16
+ """
17
+ To make your script tema compatible, import and instantiate a
18
+ TemaGateway. Then add your wanted update actions (calculating
19
+ functions) using either the add_update_action function or the
20
+ update_action decorator.
21
+
22
+ Typical usage example:
23
+
24
+ # Establish connection
25
+ tema_gateway = TemaGateway()
26
+
27
+ # Register a calculation function
28
+ @tema_gateway.update_action(
29
+ input_sequences=("seq_1", "seq_2"),
30
+ output_sequences=("seq_3",)
31
+ )
32
+ def my_calculator(first_seq, second_seq, out_seq):
33
+ # your implementation
34
+ """
35
+
36
+ class Java:
37
+ """
38
+ This describes to Py4J that the TemaGateway implements the Java
39
+ interface "temapyCallbackInterface". This allows java to call the python
40
+ methods defined in the interface.
41
+
42
+ Setting the auto_connect argument to false means that the connection to
43
+ Tema will not be setup automatically and that the self.connect method
44
+ needs to be called to connect to Tema. this can be used to test the
45
+ script without running via Tema.
46
+ """
47
+
48
+ implements = ["se.imagesystems.python.temapyCallbackInterface"]
49
+
50
+ def __init__(self, auto_connect=True):
51
+ """
52
+ Creates a new TemaGateway that handles communication with Tema and
53
+ allows you to add update actions to modify Tema sequences.
54
+
55
+ :param auto_connect: if the gateway should attempt to automatically
56
+ connect to Tema or not.
57
+ """
58
+ self.update_actions = []
59
+ self.input_sequences = {}
60
+ self.output_sequences = {}
61
+ self.shutdown = threading.Event()
62
+ self.tema = None
63
+ self.connection_thread = None
64
+ self.port = None
65
+ self._parse_tema_port()
66
+ if auto_connect:
67
+ self.connect()
68
+
69
+ def connect(self):
70
+ """
71
+ Connects temapy to a running Tema application. Should only be called if
72
+ the script is started via Tema.
73
+
74
+ If a connection already exist this method does nothing.
75
+ (see request_shutdown(self))
76
+ :return:
77
+ """
78
+ if isinstance(self.tema, ClientServer):
79
+ return
80
+ self._setup_server()
81
+ self._notify_tema()
82
+
83
+ def _setup_server(self):
84
+ """
85
+ Creates a client server pair used for sending and receiving commands
86
+ to/from Tema.
87
+
88
+ The connection will remain active until the request_shutdown() method is
89
+ called.
90
+ :return:
91
+ """
92
+ # Start py4j Java Gateway with a callback server
93
+ self.tema = JavaGateway(
94
+ gateway_parameters=GatewayParameters(port=self.tema_port),
95
+ # Dynamically allocate a port for the callback server
96
+ callback_server_parameters=CallbackServerParameters(port=0),
97
+ python_server_entry_point=self,
98
+ )
99
+
100
+ # Gets the actually allocated port for the callback server
101
+ self.port = self.tema.get_callback_server().get_listening_port()
102
+
103
+ def _notify_tema(self):
104
+ """
105
+ Sends the port number of the Python server to Tema so that Tema can
106
+ communicate with python.
107
+
108
+ This also indicates to tema that the python process is ready to perform
109
+ calculations.
110
+ :return:
111
+ """
112
+ self.tema.entry_point.setPythonPort(self.port)
113
+
114
+ def add_update_action(self, action, *, input_sequences=(), output_sequences=()):
115
+ """
116
+ Adds an update action to be run when Tema calls for a recalculation.
117
+
118
+ The action should be a function or other callable that takes sequences
119
+ as input arguments matching the ones supplied in the input_sequences and
120
+ output_sequences arguments in the same order.
121
+
122
+ The action should refrain from changing the sequences specified as
123
+ input, as doing so would change the input for subsequent actions in the
124
+ same update. Additionally, changes to input sequences will not be sent
125
+ to Tema.
126
+
127
+ Changes made to any sequence specified as output will be copied back
128
+ into tema after all added update actions have run. If multiple actions
129
+ writes to the same output, they will operate on the same sequence and
130
+ might overwrite each other.
131
+
132
+ :param action: The action to be performed on the sequences.
133
+ :param input_sequences: The sequences to be used as input to the action
134
+ function.
135
+ :param output_sequences: The sequences to be used as output.
136
+ """
137
+
138
+ def do_action():
139
+ # Get the actual output and input sequences
140
+ in_sequences = []
141
+ for wanted_sequence_name in input_sequences:
142
+ try:
143
+ in_sequences.append(self.input_sequences[wanted_sequence_name])
144
+ except KeyError as e:
145
+ raise KeyError(
146
+ f"No input sequence named {wanted_sequence_name}"
147
+ ) from e
148
+ out_sequences = []
149
+ for wanted_sequence_name in output_sequences:
150
+ try:
151
+ out_sequences.append(self.output_sequences[wanted_sequence_name])
152
+ except KeyError as e:
153
+ raise KeyError(
154
+ f"No output sequence named {wanted_sequence_name}"
155
+ ) from e
156
+
157
+ # Run user action
158
+ action(*in_sequences, *out_sequences)
159
+
160
+ self.update_actions.append(do_action)
161
+
162
+ def update_action(self, *, input_sequences=(), output_sequences=()):
163
+ """
164
+ Decorator used to add an update action to the given sequences.
165
+
166
+ The action should be a function or other callable that takes sequences
167
+ as input arguments matching the ones supplied in the input_sequences and
168
+ output_sequences arguments in the same order.
169
+
170
+ The action should refrain from changing the sequences specified as
171
+ input, as doing so would change the input for subsequent actions in the
172
+ same update.
173
+
174
+ Changes made to any sequence specified as output will be copied back
175
+ into tema after all added update actions have run. If multiple actions
176
+ writes to the same output, they will operate on the same sequence and
177
+ might overwrite each other.
178
+
179
+ :param input_sequences: The sequences to be used as input to the action
180
+ function.
181
+ :param output_sequences: The sequences to be used as output.
182
+ """
183
+
184
+ def decorator(action):
185
+ self.add_update_action(
186
+ action,
187
+ input_sequences=input_sequences,
188
+ output_sequences=output_sequences,
189
+ )
190
+
191
+ def inner(*args, **kwargs):
192
+ action(*args, **kwargs)
193
+
194
+ return inner
195
+
196
+ return decorator
197
+
198
+ def update(self):
199
+ """
200
+ Performs all registered update actions.
201
+ """
202
+ self._read_sequences_from_tema()
203
+ for action in self.update_actions:
204
+ action()
205
+ self._write_sequences_to_tema()
206
+
207
+ def request_shutdown(self):
208
+ """
209
+ Requests that the python-java bridge be shutdown.
210
+ :return:
211
+ """
212
+
213
+ def wait_for_shutdown():
214
+ # Wait for shutdown request
215
+ self.shutdown.wait()
216
+ self.shutdown.clear()
217
+ self.tema.shutdown()
218
+
219
+ self.connection_thread = threading.Thread(target=wait_for_shutdown)
220
+ self.connection_thread.start()
221
+
222
+ self.shutdown.set()
223
+
224
+ def _read_sequences_from_tema(self):
225
+ """
226
+ Updates the sequences available to temapy with new input data from tema.
227
+
228
+ Runs every time tema calls for an update.
229
+ """
230
+ # FIXME: Future improvement to utilize the updated range to minimize
231
+ # Java-Python data transfer
232
+ for (
233
+ tema_sequence_name,
234
+ tema_sequence,
235
+ ) in self.tema.entry_point.getInputSequences().items():
236
+ self.input_sequences[str(tema_sequence_name)] = Sequence.of_tema_sequence(
237
+ tema_sequence
238
+ )
239
+
240
+ for (
241
+ tema_sequence_name,
242
+ tema_sequence,
243
+ ) in self.tema.entry_point.getOutputSequences().items():
244
+ self.output_sequences[str(tema_sequence_name)] = Sequence.of_tema_sequence(
245
+ tema_sequence
246
+ )
247
+
248
+ def _write_sequences_to_tema(self):
249
+ """
250
+ Updates tema with the values of the sequences in temapy.
251
+ """
252
+ # FIXME: Future improvement to utilize the updated range to minimize
253
+ # Java-Python data transfer
254
+ tema = self.tema.entry_point
255
+ for sequence_name, tema_sequence in tema.getOutputSequences().items():
256
+ if sequence_name not in self.output_sequences:
257
+ continue
258
+
259
+ tema_sequence_samples = tema_sequence.getSamples()
260
+
261
+ for timestamp, sample in self.output_sequences[
262
+ sequence_name
263
+ ].samples.items():
264
+ java_double_array = self.tema.new_array(
265
+ self.tema.jvm.double, len(sample.data)
266
+ )
267
+
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
+ def _parse_tema_port(self):
275
+ """
276
+ Parses the --tema_port program argument if it exists and sets the
277
+ self.tema_port member accordingly.
278
+
279
+ If the argument is not specified python will start its server on the
280
+ default port (see py4j.java_gateway.DEFAULT_PORT)
281
+ """
282
+ parser = argparse.ArgumentParser()
283
+ parser.add_argument(
284
+ "--tema_port", help="The port the java server is running on"
285
+ )
286
+ args = parser.parse_args()
287
+ if args.tema_port is None:
288
+ self.tema_port = DEFAULT_PORT
289
+ return
290
+
291
+ self.tema_port = int(args.tema_port)
temapy/sequences.py ADDED
@@ -0,0 +1,140 @@
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
+ ]
@@ -0,0 +1,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: temapy
3
+ Version: 1.0.0
4
+ Summary: Python interface for scripting with TEMA
5
+ Author-email: Image Systems <support@imagesystems.se>
6
+ License-Expression: Apache-2.0
7
+ Classifier: Programming Language :: Python :: 3.13
8
+ Classifier: Operating System :: Microsoft :: Windows
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: py4j
12
+
13
+ # TemaPy
14
+
15
+ This package is designed to be used with Image Systems TEMA Platform Python
16
+ module to enable Python scripting functionality to TEMA.
17
+
18
+ For detail instructions on how to enable your scripts in TEMA see the
19
+ corresponding help pages in TEMA Connect.
20
+
21
+ ## install using pip:
22
+
23
+ To develop and run scripts in TEMA you need this package installed in the
24
+ Python environment that you will use in TEMA.
25
+
26
+ pip install temapy
27
+
28
+ ## Getting started: Create a TEMA compatible script
29
+
30
+ To create a TEMA compatible script, first import the `TemaGateway` class from
31
+ the `gateway` module and create a `TemaGateway`.
32
+
33
+ ```python
34
+ from temapy.gateway import TemaGateway
35
+
36
+ gateway = TemaGateway()
37
+ ```
38
+
39
+ If the script is started using TEMA the `TemaGateway` will handle the connection
40
+ and data transfer between TemaPy and TEMA automatically. The only thing left to
41
+ do is to write your calculation function, referred to as an "update action", and
42
+ register it using the Gateway.
43
+
44
+ Here is an example update action that takes two input sequences, and for each
45
+ sample calculates the average value and store it in a third output sequence.
46
+
47
+ ```python
48
+ def average_per_sample(seq_1, seq_2, seq_out):
49
+ both_sequences = zip(seq_1.samples.items(), seq_2.samples.values())
50
+ for (time_1, sample_1), sample_2 in both_sequences:
51
+ if seq_1.samples[time_1].status.is_valid():
52
+ seq_out.samples[time_1].data[0] = (sample_1.data[0] + sample_2.data[0]) / 2
53
+ seq_out.samples[time_1].data[1] = (sample_1.data[1] + sample_2.data[1]) / 2
54
+ seq_out.samples[time_1].status = Status.CALCULATED
55
+ ```
56
+
57
+ **Note:** The output sequence is supplied as an input to the function. This is
58
+ because TemaPy is not allowed to create new sequences, only change data in the
59
+ sequences supplied by TEMA.
60
+
61
+ There are two ways of registering your function so that TEMA will run it when
62
+ input sequences change, either by calling the `add_update_action` method in the
63
+ `TemaGateway` or by using the `update_action` decorator, also from the
64
+ `TemaGateway` class.
65
+
66
+ ```python
67
+ # Using the add_update_action() function
68
+ def average_per_sample(seq_1, seq_2, seq_out):
69
+ ...
70
+
71
+ gateway.add_update_action(average_per_sample,
72
+ input_sequences=("p1_pos", "p2_pos"),
73
+ output_sequences=("avg_pos",))
74
+
75
+ # Using the update_action decorator
76
+ @gateway.update_action(input_sequences=("p1_pos", "p2_pos"), output_sequences=("avg_pos",))
77
+ def average_per_sample(seq_1, seq_2, seq_out):
78
+ ...
79
+ ```
80
+
81
+ In both cases the `input_sequences` and `output_sequences` parameter specify
82
+ what TEMA sequences the update action will operate on. The strings in those
83
+ parameters should correspond with the variable names given to the sequences in
84
+ the Python Script Setup pane in TEMA. The sequences from TEMA will then
85
+ automatically map to the input parameters in your update action in order, first
86
+ input sequences and then output sequences. In this example this means that the
87
+ sequence named "p1_pos" in TEMA is mapped to the `seq_1` parameter in the
88
+ function, "p2_pos" is mapped to `seq_2` and "avg_pos" is mapped to `out_seq`.
89
+
90
+ Now your script is ready to be used in TEMA, for more information about how to
91
+ enable your script in TEMA, see the corresponding help pages in TEMA Connect.
92
+
93
+ For more details on how to work with TemaPy, continue reading below.
94
+ Additionally, more example scripts can be found in the `temapy.examples`
95
+ package.
96
+
97
+ ## The gateway
98
+
99
+ The `TemaGateway` handles the connection to TEMA and allows you to access and
100
+ manipulate data sequences specified using the TEMA Python Scripting Setup. The
101
+ connection is handled mostly automatically as soon as an instance of
102
+ `TemaGateway` is created.
103
+
104
+ ### Update actions
105
+
106
+ The update actions are your calculation functions that are run each time the
107
+ input sequences specified in TEMA are updated. This means for example that each
108
+ update action will run again for each tracked frame as long as the script is
109
+ active.
110
+
111
+ While it is not possible to run multiple Python scripts simultaneously in TEMA,
112
+ it is possible to add multiple update actions to the same script. Whenever TEMA
113
+ calls for the script to update, all update actions will be executed in the order
114
+ they were added. Any changes made to sequences in an update action will be
115
+ carried over to any following update actions which means that it is possible to
116
+ chain actions together.
117
+
118
+ The input and output sequences used by your update actions are copies of the
119
+ data in TEMA.
120
+
121
+ The input sequences are sequences that already exists in TEMA and are added from
122
+ a list of available sequences in TEMA. While it is possible to change an input
123
+ sequence in your update actions, this is not recommended, as data in input
124
+ sequences will **not** be returned to TEMA and changing input sequences might
125
+ cause the scripts sequences to diverge from the sequences supplied by TEMA.
126
+
127
+ The output sequences are created by the TEMA Scripting Module for your TemaPy
128
+ script to edit. The output sequences will be initialized with invalid
129
+ placeholder values for each sample and it is up to your update actions to fill
130
+ them with new values, see the sections about sequences and samples for
131
+ instructions on how to work with sequences.
132
+
133
+ It is important to note that the separation between output and input sequences
134
+ does not necessarily reflect their use in your update functions. Instead it is
135
+ the distinction between the sequences that already exists in TEMA (input) and
136
+ those that are created by the scripting module (output).
137
+
138
+ ## TEMA data
139
+
140
+ The data available from TEMA is in the form of sequences. In TemaPy these are
141
+ represented by the classes found in the `temapy.sequences` module.
142
+
143
+ The following sections describe how the data is structured and how to work with
144
+ it.
145
+
146
+ ### Sequences
147
+
148
+ The `Sequence` is the data structure that your update actions will operate on.
149
+ A sequence represents a set of measurements for each frame in the original image
150
+ sequence in TEMA. For each frame there is a `Sample` that contains numerical
151
+ data from that frame of the image sequence.
152
+
153
+ #### updated range
154
+
155
+ Each sequence also has a `updated_range` which is a tuple of two integers. These
156
+ integers represent the first (inclusive) and last (exclusive) frame of the
157
+ sequence that has changed since the update actions were last run. This range can
158
+ be used to avoid unnecessary recalculations and slowdown during tracking in TEMA
159
+ with an active script. It is also good to adjust the `updated_range` of the
160
+ output sequences to no wider than the range of values that have been changed.
161
+ Otherwise, it will be assumed that all frames have been updated and the sequence
162
+ will be copied to tema in its entirety which might cause significant slow-down
163
+ during tracking.
164
+
165
+ #### Samples
166
+
167
+ The `samples` attribute is a dictionary that maps a frame number, to a `Sample`.
168
+ The `Sample` contains the data of that specific frame of the image sequence used
169
+ in TEMA. As this is a standard Python dictionary, it supports all standard dict
170
+ operations in Python.
171
+
172
+ ### Sample
173
+
174
+ The `Sample` class contains data for a specific frame of the image sequence,
175
+
176
+ #### Data
177
+
178
+ The data of each
179
+ `Sample` is a tuple of numerical value, each value representing a
180
+ certain component of the data. What components are available depends on the type
181
+ of sequence. In a 2D position sequence, for example, each `Sample` contains two
182
+ data components, the x position and the y position (x, y).
183
+
184
+ #### Status
185
+
186
+ The `Status` of the `Sample` describe the nature of the `Sample` and if it
187
+ should be used for calculations. Usually it is enough to use the
188
+ `Status.is_valid()` method do determine if the `Sample` should be used or not.
189
+ For more fine grade control, each `Status` is described below.
190
+
191
+ **NONE:** No or unknown `Status`.
192
+
193
+ **FAILED:**
194
+ The data of the `Sample` failed in creation and that the data might not even be
195
+ readable, will cause undefined behaviour if used and might cause the script to
196
+ fail. Is invalid and cannot be used for calculations.
197
+
198
+ **SLEEPING:**
199
+ The data of the `Sample` is currently set to be ignored for calculation. The
200
+ data may be meaningful but should be considered invalid and not be used for
201
+ calculations.
202
+
203
+ **PREDICTED:**
204
+ Used by trackers for failed Samples that are predicted until they are either
205
+ found again or declared lost. The data of the `Sample` may be meaningful but
206
+ should be considered invalid and not be used for calculations.
207
+
208
+ **MANUAL:**
209
+ The data of the `Sample` has been set manually and is therefore considered to be
210
+ valid for calculations.
211
+
212
+ **CALCULATED:**
213
+ The data of the `Sample` has been successfully calculated and
214
+ may be used for further calculations.
215
+
216
+ **INTERPOLATED:**
217
+ Similar to `CALCULATED` but the data is interpolated from other Samples.
@@ -0,0 +1,9 @@
1
+ temapy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ temapy/gateway.py,sha256=NmwYyd6j2sBKUMlBfpaqqzewGTbNegcnDmT2GEpB-ak,10648
3
+ temapy/sequences.py,sha256=baSkENB9TuieU5OXGmklI3ewhPNjOHi9bJSKtfkt1y4,4292
4
+ temapy/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ temapy/examples/average_as_new_sequence.py,sha256=CjmFEkeWnwLbQl8PMt1-0Lkewi-3iFG2XTliygghuLw,1034
6
+ temapy-1.0.0.dist-info/METADATA,sha256=9SX0wzkaNWlO8RqkWSVXWeir5O7krIX-K0yfafgNu2s,9279
7
+ temapy-1.0.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
8
+ temapy-1.0.0.dist-info/top_level.txt,sha256=vGCOwZT-j1DnKtCnzs1ytwrK6I-fks-nss1_9NB6Juk,7
9
+ temapy-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (78.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ temapy