Commit 8577d403 authored by Philip ABBET's avatar Philip ABBET

Refactoring: reassign some classes from beat.core

parent 14bb7f2d
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
###############################################################################
# #
# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.backend.python module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
# or FITNESS FOR A PARTICULAR PURPOSE. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
"""Various functions for hashing platform contributions and others"""
import hashlib
def hashFileContents(path):
"""Hashes the file contents using :py:func:`hashlib.sha256`."""
with open(path, 'rb') as f:
return hashlib.sha256(f.read()).hexdigest()
......@@ -36,9 +36,141 @@ import zmq
from .baseformat import baseformat
class SynchronizationListener:
"""A callback mechanism to keep Inputs and Outputs in groups and lists
synchronized together."""
def __init__(self):
self.data_index_start = -1
self.data_index_end = -1
def onIntervalChanged(self, data_index_start, data_index_end):
self.data_index_start = data_index_start
self.data_index_end = data_index_end
#----------------------------------------------------------
class Output:
"""Represents one output of a processing block
A list of outputs implementing this interface is provided to the algorithms
(see :py:class:`beat.core.outputs.OutputList`).
Parameters:
name (str): Name of the output
data_sink (beat.core.data.DataSink): Sink of data to be used by the output,
pre-configured with the correct data format.
Attributes:
name (str): Name of the output (algorithm-specific)
data_sink (beat.core.data.DataSink): Sink of data used by the output
last_written_data_index (int): Index of the last block of data written by
the output
nb_data_blocks_written (int): Number of data blocks written so far
"""
def __init__(self, name, data_sink, synchronization_listener=None,
dataset_output=False, force_start_index=0):
self.name = name
self.data_sink = data_sink
self._synchronization_listener = synchronization_listener
self._dataset_output = dataset_output
self.last_written_data_index = force_start_index-1
self.nb_data_blocks_written = 0
def _createData(self):
"""Retrieves an uninitialized block of data corresponding to the data
format of the output
This method must be called to correctly create a new block of data
"""
if hasattr(self.data_sink, 'dataformat'):
return self.data_sink.dataformat.type()
else:
raise RuntimeError("The currently used data sink is not bound to " \
"a dataformat - you cannot create uninitialized data under " \
"these circumstances")
def write(self, data, end_data_index=None):
"""Write a block of data on the output
Parameters:
data (beat.core.baseformat.baseformat): The block of data to write, or
None (if the algorithm doesn't want to write any data)
end_data_index (int): Last index of the written data (see the section
*Inputs synchronization* of the User's Guide). If not specified, the
*current end data index* of the Inputs List is used
"""
if self._dataset_output:
if end_data_index is None:
end_data_index = self.last_written_data_index + 1
elif end_data_index < self.last_written_data_index + 1:
raise KeyError("Database wants to write an `end_data_index' (%d) " \
"which is smaller than the last written index (%d) " \
"+1 - this is a database bug - Fix it!" % \
(end_data_index, self.last_written_data_index))
elif end_data_index is not None:
if (end_data_index < self.last_written_data_index + 1) or \
((self._synchronization_listener is not None) and \
(end_data_index > self._synchronization_listener.data_index_end)):
raise KeyError("Algorithm logic error on write(): `end_data_index' " \
"is not consistent with last written index")
elif self._synchronization_listener is not None:
end_data_index = self._synchronization_listener.data_index_end
else:
end_data_index = self.last_written_data_index + 1
# if the user passes a dictionary, converts to the proper baseformat type
if isinstance(data, dict):
d = self.data_sink.dataformat.type()
d.from_dict(data, casting='safe', add_defaults=False)
data = d
self.data_sink.write(data, self.last_written_data_index + 1, end_data_index)
self.last_written_data_index = end_data_index
self.nb_data_blocks_written += 1
def isDataMissing(self):
return not(self._dataset_output) and \
(self._synchronization_listener is not None) and \
(self._synchronization_listener.data_index_end != self.last_written_data_index)
def isConnected(self):
return self.data_sink.isConnected()
#----------------------------------------------------------
class RemoteOutput:
"""Represents one output of a processing block
A list of outputs implementing this interface is provided to the algorithms
(see :py:class:`beat.backend.python.outputs.OutputList`).
......@@ -54,7 +186,6 @@ class Output:
"""
def __init__(self, name, data_format, socket):
self.name = name
......@@ -127,6 +258,9 @@ class Output:
return answer == 'tru'
#----------------------------------------------------------
class OutputList:
"""Represents the list of outputs of a processing block
......@@ -155,7 +289,6 @@ class OutputList:
"""
def __init__(self):
self._outputs = []
......@@ -170,14 +303,15 @@ class OutputList:
if index < len(self._outputs): return self._outputs[index]
return None
def __iter__(self):
def __iter__(self):
for k in self._outputs: yield k
def __len__(self):
def __len__(self):
return len(self._outputs)
def add(self, output):
"""Adds an output to the list
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment