diff --git a/bob/bio/base/__init__.py b/bob/bio/base/__init__.py index 5b2461a9b9400164f5010f4413fbabf26d2c17b3..48dbde118eeb3b217a39ed298c8f7c45e6065dfc 100644 --- a/bob/bio/base/__init__.py +++ b/bob/bio/base/__init__.py @@ -1,5 +1,4 @@ from .utils import * -from . import database from . import preprocessor from . import extractor from . import algorithm diff --git a/bob/bio/base/database/Database.py b/bob/bio/base/database/Database.py deleted file mode 100644 index cb9cc675149c819307f025922e467fbd5cd41e04..0000000000000000000000000000000000000000 --- a/bob/bio/base/database/Database.py +++ /dev/null @@ -1,490 +0,0 @@ -class Database: - """This class represents the basic API for database access. - Please use this class as a base class for your database access classes. - Do not forget to call the constructor of this base class in your derived class. - - **Parameters:** - - name : str - A unique name for the database. - - original_directory : str - The directory where the original data of the database are stored. - - original_extension : str - The file name extension of the original data. - - annotation_directory : str - The directory where the image annotations of the database are stored, if any. - - annotation_extension : str - The file name extension of the annotation files. - - annotation_type : str - The type of the annotation file to read, see :py:func:`bob.db.verification.utils.read_annotation_file` for accepted formats. - - protocol : str or ``None`` - The name of the protocol that defines the default experimental setup for this database. - - .. todo:: Check if the ``None`` protocol is supported. - - training_depends_on_protocol : bool - Specifies, if the training set used for training the extractor and the projector depend on the protocol. - This flag is used to avoid re-computation of data when running on the different protocols of the same database. - - models_depend_on_protocol : bool - Specifies, if the models depend on the protocol. - This flag is used to avoid re-computation of models when running on the different protocols of the same database. - - kwargs - Ignored extra arguments. - """ - - def __init__( - self, - name, - original_directory = None, - original_extension = None, - annotation_directory = None, - annotation_extension = '.pos', - annotation_type = None, - protocol = 'Default', - training_depends_on_protocol = False, - models_depend_on_protocol = False, - **kwargs - ): - assert isinstance(name, str) - - self.name = name - self.original_directory = original_directory - self.original_extension = original_extension - self.annotation_directory = annotation_directory - self.annotation_extension = annotation_extension - self.annotation_type = annotation_type - self.protocol = protocol - self.training_depends_on_protocol = training_depends_on_protocol - self.models_depend_on_protocol = models_depend_on_protocol - - - def __str__(self): - """__str__() -> info - - This function returns all parameters of this class. - - **Returns:** - - info : str - A string containing the full information of all parameters of this class. - """ - params = "name=%s, protocol=%s, original_directory=%s, original_extension=%s" % (self.name, self.protocol, self.original_directory, self.original_extension) - if self.annotation_type is not None: - params += ", annotation_type=%s" % annotation_type - if self.annotation_directory: params += ", annotation_directory=%s" % self.annotation_directory - params += ", annotation_extension=%s" % self.annotation_extension - params += ", training_depends_on_protocol=%s, models_depend_on_protocol=%s" % (self.training_depends_on_protocol, self.models_depend_on_protocol) - return "%s(%s)" % (str(self.__class__), params) - - - ########################################################################### - ### Helper functions that you might want to use in derived classes - ########################################################################### - def sort(self, files): - """sort(files) -> sorted - - Returns a sorted version of the given list of File's (or other structures that define an 'id' data member). - The files will be sorted according to their id, and duplicate entries will be removed. - - **Parameters:** - - files : [:py:class:`File`] - The list of files to be uniquified and sorted. - - **Returns:** - - sorted : [:py:class:`File`] - The sorted list of files, with duplicate :py:attr:`File.id`\s being removed. - """ - # sort files using their sort function - sorted_files = sorted(files) - # remove duplicates - return [f for i,f in enumerate(sorted_files) if not i or sorted_files[i-1].id != f.id] - - - def arrange_by_client(self, files): - """arrange_by_client(files) -> files_by_client - - Arranges the given list of files by client id. - This function returns a list of lists of File's. - - **Parameters:** - - files : :py:class:`File` - A list of files that should be split up by :py:attr:`File.client_id`. - - **Returns:** - - files_by_client : [[:py:class:`File`]] - The list of lists of files, where each sub-list groups the files with the same :py:attr:`File.client_id` - """ - client_files = {} - for file in files: - if file.client_id not in client_files: - client_files[file.client_id] = [] - client_files[file.client_id].append(file) - - files_by_clients = [] - for client in sorted(client_files.keys()): - files_by_clients.append(client_files[client]) - return files_by_clients - - - def annotations(self, file): - """annotations(file) -> annots - - Returns the annotations for the given File object, if available. - It uses :py:func:`bob.db.verification.utils.read_annotation_file` to load the annotations. - - **Parameters:** - - file : :py:class:`File` - The file for which annotations should be returned. - - **Returns:** - - annots : dict or None - The annotations for the file, if available. - """ - if self.annotation_directory: - try: - import bob.db.verification.utils - annotation_path = os.path.join(self.annotation_directory, file.path + self.annotation_extension) - return bob.db.verification.utils.read_annotation_file(annotation_path, self.annotation_type) - except ImportError as e: - from .. import utils - utils.error("Cannot import bob.db.verification.utils: '%s'. No annotation is read." % e) - - return None - - - def uses_probe_file_sets(self): - """Defines if, for the current protocol, the database uses several probe files to generate a score. - By default, ``False`` is returned. Overwrite the default if you need different behavior.""" - return False - - - def file_names(self, files, directory, extension): - """file_names(files, directory, extension) -> paths - - Returns the full path of the given File objects. - - **Parameters:** - - files : [:py:class:`File`] - The list of file object to retrieve the file names for. - - directory : str - The base directory, where the files can be found. - - extension : str - The file name extension to add to all files. - - **Returns:** - - paths : [str] or [[str]] - The paths extracted for the files, in the same order. - If this database provides file sets, a list of lists of file names is returned, one sub-list for each file set. - """ - # return the paths of the files - if self.uses_probe_file_sets() and files and hasattr(files[0], 'files'): - # List of Filesets: do not remove duplicates - return [[f.make_path(directory, extension) for f in file_set.files] for file_set in files] - else: - # List of files, do not remove duplicates - return [f.make_path(directory, extension) for f in files] - - def original_file_names(self, files): - """original_file_names(files) -> paths - - Returns the full path of the original data of the given File objects. - - **Parameters:** - - files : [:py:class:`File`] - The list of file object to retrieve the original data file names for. - - **Returns:** - - paths : [str] or [[str]] - The paths extracted for the files, in the same order. - If this database provides file sets, a list of lists of file names is returned, one sub-list for each file set. - """ - assert self.original_directory is not None - assert self.original_extension is not None - return self.file_names(files, self.original_directory, self.original_extension) - - - ########################################################################### - ### Interface functions that you need to implement in your class. - ########################################################################### - - def all_files(self, groups = None): - """all_files(groups=None) -> files - - Returns all files of the database. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - groups : some of ``('world', 'dev', 'eval')`` or ``None`` - The groups to get the data for. - If ``None``, data for all groups is returned. - - **Returns:** - - files : [:py:class:`File`] - The sorted and unique list of all files of the database. - """ - raise NotImplementedError("Please implement this function in derived classes") - - - def training_files(self, step = None, arrange_by_client = False): - """training_files(step = None, arrange_by_client = False) -> files - - Returns all training File objects for the given step, and arranges them by client, if desired. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - step : one of ``('train_extractor', 'train_projector', 'train_enroller')`` or ``None`` - The step for which the training data should be returned. - Might be ignored in derived class implementations. - - arrange_by_client : bool - Should the training files be arranged by client? - - .. note:: - You can use :py:meth:`arrange_by_client` in derived class implementations to arrange the files. - - **Returns:** - - files : [:py:class:`File`] or [[:py:class:`File`]] - The (arranged) list of files used for the training of the given step. - """ - raise NotImplementedError("Please implement this function in derived classes") - - - def model_ids(self, group = 'dev'): - """model_ids(group = 'dev') -> ids - - Returns a list of model ids for the given group. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the model ids for. - - **Returns:** - - ids : [int] or [str] - The list of (unique) model ids for the given group. - """ - raise NotImplementedError("Please implement this function in derived classes") - - - def client_id_from_model_id(self, model_id, group = 'dev'): - """client_id_from_model_id(model_id, group = 'dev') -> client_id - - In some databases, each client can contain several models. - Hence, client and model ids differ. - This function converts the given model id into its according the client id. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - model_id : int or str - A unique ID that identifies the model for the client. - - group : one of ``('dev', 'eval')`` - The group to get the client ids for. - - **Returns:** - - client_id : [int] or [str] - A unique ID that identifies the client, to which the model belongs. - """ - raise NotImplementedError("Please implement this function in derived classes") - - - def enroll_files(self, model_id, group = 'dev'): - """enroll_files(model_id, group = 'dev') -> files - - Returns a list of File objects that should be used to enroll the model with the given model id from the given group. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - model_id : int or str - A unique ID that identifies the model. - - group : one of ``('dev', 'eval')`` - The group to get the enrollment files for. - - **Returns:** - - files : [:py:class:`File`] - The list of files used for to enroll the model with the given model id. - """ - raise NotImplementedError("Please implement this function in derived classes") - - - def probe_files(self, model_id = None, group = 'dev'): - """probe_files(model_id = None, group = 'dev') -> files - - Returns a list of probe File objects. - If a ``model_id`` is specified, only the probe files that should be compared with the given model id are returned (for most databases, these are all probe files of the given group). - Otherwise, all probe files of the given group are returned. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - model_id : int or str or ``None`` - A unique ID that identifies the model. - - group : one of ``('dev', 'eval')`` - The group to get the enrollment files for. - - **Returns:** - - files : [:py:class:`File`] - The list of files used for to probe the model with the given model id. - """ - raise NotImplementedError("Please implement this function in derived classes") - - - def probe_file_sets(self, model_id = None, group = 'dev'): - """probe_file_sets(model_id = None, group = 'dev') -> files - - Returns a list of probe FileSet objects. - If a ``model_id`` is specified, only the probe files that should be compared with the given model id are returned (for most databases, these are all probe files of the given group). - Otherwise, all probe files of the given group are returned. - This function needs to be implemented in derived class implementations, if the :py:meth:`uses_probe_file_sets` returns ``True``. - - **Parameters:** - - model_id : int or str or ``None`` - A unique ID that identifies the model. - - group : one of ``('dev', 'eval')`` - The group to get the enrollment files for. - - **Returns:** - - files : [:py:class:`FileSet`] - The list of file sets used to probe the model with the given model id.""" - raise NotImplementedError("Please implement this function in derived classes") - - - -class DatabaseZT (Database): - """This class defines additional API functions that are required to compute ZT score normalization. - This class does not define a constructor. - During construction of a derived class, please call the constructor of the base class :py:class:`Database` directly.""" - - def t_model_ids(self, group = 'dev'): - """t_model_ids(group = 'dev') -> ids - - Returns a list of model ids of T-Norm models for the given group. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the model ids for. - - **Returns:** - - ids : [int] or [str] - The list of (unique) model ids for T-Norm models of the given group. - """ - raise NotImplementedError("Please implement this function in derived classes") - - - def client_id_from_t_model_id(self, t_model_id, group = 'dev'): - """client_id_from_t_model_id(t_model_id, group = 'dev') -> client_id - - Returns the client id for the given T-Norm model id. - In this base class implementation, we just use the :py:meth:`client_id_from_model_id` function. - Overload this function if you need another behavior. - - **Parameters:** - - t_model_id : int or str - A unique ID that identifies the T-Norm model. - - group : one of ``('dev', 'eval')`` - The group to get the client ids for. - - **Returns:** - - client_id : [int] or [str] - A unique ID that identifies the client, to which the T-Norm model belongs. - """ - return self.client_id_from_model_id(t_model_id, group) - - def t_enroll_files(self, t_model_id, group = 'dev'): - """t_enroll_files(t_model_id, group = 'dev') -> files - - Returns a list of File objects that should be used to enroll the T-Norm model with the given model id from the given group. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - t_model_id : int or str - A unique ID that identifies the model. - - group : one of ``('dev', 'eval')`` - The group to get the enrollment files for. - - **Returns:** - - files : [:py:class:`File`] - The list of files used for to enroll the model with the given model id. - """ - raise NotImplementedError("Please implement this function in derived classes") - - def z_probe_files(self, group = 'dev'): - """z_probe_files(group = 'dev') -> files - - Returns a list of probe File objects used to compute the Z-Norm. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the Z-norm probe files for. - - **Returns:** - - files : [:py:class:`File`] - The unique list of files used to compute the Z-norm. - """ - raise NotImplementedError("Please implement this function in derived classes") - - def z_probe_file_sets(self, group = 'dev'): - """z_probe_file_sets(group = 'dev') -> files - - Returns a list of probe FileSet objects used to compute the Z-Norm. - This function needs to be implemented in derived class implementations. - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the Z-norm probe files for. - - **Returns:** - - files : [:py:class:`FileSet`] - The unique list of file sets used to compute the Z-norm. - """ - raise NotImplementedError("Please implement this function in derived classes") diff --git a/bob/bio/base/database/DatabaseBob.py b/bob/bio/base/database/DatabaseBob.py deleted file mode 100644 index 38d7857770324d9d7d9eb7616ef5307b3fb6610a..0000000000000000000000000000000000000000 --- a/bob/bio/base/database/DatabaseBob.py +++ /dev/null @@ -1,505 +0,0 @@ -from .Database import Database, DatabaseZT -import os - -import bob.db.verification.utils - -class DatabaseBob (Database): - """This class can be used whenever you have a database that follows the Bob verification database interface, which is defined in :py:class:`bob.db.verification.utils.Database` - - **Parameters:** - - database : derivative of :py:class:`bob.db.verification.utils.Database` - The database instance (such as a :py:class:`bob.db.atnt.Database`) that provides the actual interface, see :ref:`verification_databases` for a list. - - all_files_options : dict - Dictionary of options passed to the :py:meth:`bob.db.verification.utils.Database.objects` database query when retrieving all data. - - extractor_training_options : dict - Dictionary of options passed to the :py:meth:`bob.db.verification.utils.Database.objects` database query used to retrieve the files for the extractor training. - - projector_training_options : dict - Dictionary of options passed to the :py:meth:`bob.db.verification.utils.Database.objects` database query used to retrieve the files for the projector training. - - enroller_training_options : dict - Dictionary of options passed to the :py:meth:`bob.db.verification.utils.Database.objects` database query used to retrieve the files for the enroller training. - - check_original_files_for_existence : bool - Enables to test for the original data files when querying the database. - - kwargs : ``key=value`` pairs - The arguments of the :py:class:`Database` base class constructor. - - .. note:: Usually, the ``name``, ``protocol``, ``training_depends_on_protocol`` and ``models_depend_on_protocol`` keyword parameters of the base class constructor need to be specified. - """ - - def __init__( - self, - database, # The bob database that is used - all_files_options = {}, # additional options for the database query that can be used to extract all files - extractor_training_options = {}, # additional options for the database query that can be used to extract the training files for the extractor training - projector_training_options = {}, # additional options for the database query that can be used to extract the training files for the extractor training - enroller_training_options = {}, # additional options for the database query that can be used to extract the training files for the extractor training - check_original_files_for_existence = False, - **kwargs # The default parameters of the base class - ): - - Database.__init__( - self, - **kwargs - ) - - assert isinstance(database, bob.db.verification.utils.Database), "Only databases derived from bob.db.verification.utils.Database are supported by this interface. Please implement your own bob.bio.base.database.Database interface." - - self.database = database - self.original_directory = database.original_directory - try: - self.annotation_directory = database.annotation_directory - except AttributeError: - pass - - self.all_files_options = all_files_options - self.extractor_training_options = extractor_training_options - self.projector_training_options = projector_training_options - self.enroller_training_options = enroller_training_options - self.check_existence = check_original_files_for_existence - - self._kwargs = kwargs - - - def __str__(self): - """__str__() -> info - - This function returns all parameters of this class (and its derived class). - - **Returns:** - - info : str - A string containing the full information of all parameters of this (and the derived) class. - """ - params = ", ".join(["%s=%s" % (key, value) for key, value in self._kwargs.items()]) - params += ", original_directory=%s, original_extension=%s" % (self.original_directory, self.original_extension) - if self.all_files_options: params += ", all_files_options=%s"%self.all_files_options - if self.extractor_training_options: params += ", extractor_training_options=%s"%self.extractor_training_options - if self.projector_training_options: params += ", projector_training_options=%s"%self.projector_training_options - if self.enroller_training_options: params += ", enroller_training_options=%s"%self.enroller_training_options - - return "%s(%s)" % (str(self.__class__), params) - - - def replace_directories(self, replacements = None): - """This helper function replaces the ``original_directory`` and the ``annotation_directory`` of the database with the directories read from the given replacement file. - - This function is provided for convenience, so that the database configuration files do not need to be modified. - Instead, this function uses the given dictionary of replacements to change the original directory and the original extension (if given). - - The given ``replacements`` can be of type ``dict``, including all replacements, or a file name (as a ``str``), in which case the file is read. - The structure of the file should be: - - .. code-block:: text - - # Comments starting with # and empty lines are ignored - - [YOUR_..._DATA_DIRECTORY] = /path/to/your/data - [YOUR_..._ANNOTATION_DIRECTORY] = /path/to/your/annotations - - If no annotation files are available (e.g. when they are stored inside the ``database``), the annotation directory can be left out. - - **Parameters:** - - replacements : dict or str - A dictionary with replacements, or a name of a file to read the dictionary from. - If the file name does not exist, no directories are replaced. - """ - if replacements is None: - return - if isinstance(replacements, str): - if not os.path.exists(replacements): - return - # Open the database replacement file and reads its content - with open(replacements) as f: - replacements = {} - for line in f: - if line.strip() and not line.startswith("#"): - splits = line.split("=") - assert len(splits) == 2 - replacements[splits[0].strip()] = splits[1].strip() - - assert isinstance(replacements, dict) - - if self.original_directory in replacements: - self.original_directory = replacements[self.original_directory] - self.database.original_directory = replacements[self.database.original_directory] - - try: - if self.annotation_directory in replacements: - self.annotation_directory = replacements[self.annotation_directory] - self.database.annotation_directory = replacements[self.database.annotation_directory] - except AttributeError: - pass - - - def uses_probe_file_sets(self): - """Defines if, for the current protocol, the database uses several probe files to generate a score.""" - return self.database.provides_file_set_for_protocol(self.protocol) - - - def all_files(self, groups = None): - """all_files(groups=None) -> files - - Returns all files of the database, respecting the current protocol. - The files can be limited using the ``all_files_options`` in the constructor. - - **Parameters:** - - groups : some of ``('world', 'dev', 'eval')`` or ``None`` - The groups to get the data for. - If ``None``, data for all groups is returned. - - **Returns:** - - files : [:py:class:`bob.db.verification.utils.File`] - The sorted and unique list of all files of the database. - """ - return self.sort(self.database.objects(protocol = self.protocol, groups = groups, **self.all_files_options)) - - - def training_files(self, step = None, arrange_by_client = False): - """training_files(step = None, arrange_by_client = False) -> files - - Returns all training files for the given step, and arranges them by client, if desired, respecting the current protocol. - The files for the steps can be limited using the ``..._training_options`` defined in the constructor. - - **Parameters:** - - step : one of ``('train_extractor', 'train_projector', 'train_enroller')`` or ``None`` - The step for which the training data should be returned. - - arrange_by_client : bool - Should the training files be arranged by client? - If set to ``True``, training files will be returned in [[:py:class:`bob.db.verification.utils.File`]], where each sub-list contains the files of a single client. - Otherwise, all files will be stored in a simple [:py:class:`bob.db.verification.utils.File`]. - - **Returns:** - - files : [:py:class:`bob.db.verification.utils.File`] or [[:py:class:`bob.db.verification.utils.File`]] - The (arranged) list of files used for the training of the given step. - """ - if step is None: - training_options = self.all_files_options - elif step == 'train_extractor': - training_options = self.extractor_training_options - elif step == 'train_projector': - training_options = self.projector_training_options - elif step == 'train_enroller': - training_options = self.enroller_training_options - else: - raise ValueError("The given step '%s' must be one of ('train_extractor', 'train_projector', 'train_enroller')" % step) - - files = self.sort(self.database.objects(protocol = self.protocol, groups = 'world', **training_options)) - if arrange_by_client: - return self.arrange_by_client(files) - else: - return files - - def test_files(self, groups = ['dev']): - """test_files(groups = ['dev']) -> files - - Returns all test files (i.e., files used for enrollment and probing) for the given groups, respecting the current protocol. - The files for the steps can be limited using the ``all_files_options`` defined in the constructor. - - **Parameters:** - - groups : some of ``('dev', 'eval')`` - The groups to get the data for. - - **Returns:** - - files : [:py:class:`bob.db.verification.utils.File`] - The sorted and unique list of test files of the database. - """ - return self.sort(self.database.test_files(protocol = self.protocol, groups = groups, **self.all_files_options)) - - def model_ids(self, group = 'dev'): - """model_ids(group = 'dev') -> ids - - Returns a list of model ids for the given group, respecting the current protocol. - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the model ids for. - - **Returns:** - - ids : [int] or [str] - The list of (unique) model ids for the given group. - """ - return sorted(self.database.model_ids(protocol = self.protocol, groups = group)) - - - def client_id_from_model_id(self, model_id, group = 'dev'): - """client_id_from_model_id(model_id, group = 'dev') -> client_id - - Uses :py:meth:`bob.db.verification.utils.Database.get_client_id_from_model_id` to retrieve the client id for the given model id. - - **Parameters:** - - model_id : int or str - A unique ID that identifies the model for the client. - - group : one of ``('dev', 'eval')`` - The group to get the client ids for. - - **Returns:** - - client_id : [int] or [str] - A unique ID that identifies the client, to which the model belongs. - """ - return self.database.get_client_id_from_model_id(model_id) - - - def enroll_files(self, model_id, group = 'dev'): - """enroll_files(model_id, group = 'dev') -> files - - Returns a list of File objects that should be used to enroll the model with the given model id from the given group, respecting the current protocol. - - **Parameters:** - - model_id : int or str - A unique ID that identifies the model. - - group : one of ``('dev', 'eval')`` - The group to get the enrollment files for. - - **Returns:** - - files : [:py:class:`bob.db.verification.utils.File`] - The list of files used for to enroll the model with the given model id. - """ - return self.sort(self.database.objects(protocol = self.protocol, groups = group, model_ids = (model_id,), purposes = 'enroll', **self.all_files_options)) - - - def probe_files(self, model_id = None, group = 'dev'): - """probe_files(model_id = None, group = 'dev') -> files - - Returns a list of probe File objects, respecting the current protocol. - If a ``model_id`` is specified, only the probe files that should be compared with the given model id are returned (for most databases, these are all probe files of the given group). - Otherwise, all probe files of the given group are returned. - - **Parameters:** - - model_id : int or str or ``None`` - A unique ID that identifies the model. - - group : one of ``('dev', 'eval')`` - The group to get the enrollment files for. - - **Returns:** - - files : [:py:class:`bob.db.verification.utils.File`] - The list of files used for to probe the model with the given model id. - """ - if model_id is not None: - files = self.database.objects(protocol = self.protocol, groups = group, model_ids = (model_id,), purposes = 'probe', **self.all_files_options) - else: - files = self.database.objects(protocol = self.protocol, groups = group, purposes = 'probe', **self.all_files_options) - return self.sort(files) - - - def probe_file_sets(self, model_id = None, group = 'dev'): - """probe_file_sets(model_id = None, group = 'dev') -> files - - Returns a list of probe FileSet objects, respecting the current protocol. - If a ``model_id`` is specified, only the probe files that should be compared with the given model id are returned (for most databases, these are all probe files of the given group). - Otherwise, all probe files of the given group are returned. - - **Parameters:** - - model_id : int or str or ``None`` - A unique ID that identifies the model. - - group : one of ``('dev', 'eval')`` - The group to get the enrollment files for. - - **Returns:** - - files : [:py:class:`FileSet`] or something similar - The list of file sets used to probe the model with the given model id.""" - if model_id is not None: - file_sets = self.database.object_sets(protocol = self.protocol, groups = group, model_ids = (model_id,), purposes = 'probe', **self.all_files_options) - else: - file_sets = self.database.object_sets(protocol = self.protocol, groups = group, purposes = 'probe', **self.all_files_options) - return self.sort(file_sets) - - - def annotations(self, file): - """annotations(file) -> annots - - Returns the annotations for the given File object, if available. - - **Parameters:** - - file : :py:class:`bob.db.verification.utils.File` - The file for which annotations should be returned. - - **Returns:** - - annots : dict or None - The annotations for the file, if available. - """ - return self.database.annotations(file) - - - def original_file_names(self, files): - """original_file_names(files) -> paths - - Returns the full path of the original data of the given File objects, as returned by :py:meth:`bob.db.verification.utils.Database.original_file_names`. - - **Parameters:** - - files : [:py:class:`bob.db.verification.utils.File`] - The list of file object to retrieve the original data file names for. - - **Returns:** - - paths : [str] - The paths extracted for the files, in the same order. - """ - return self.database.original_file_names(files, self.check_existence) - - - -class DatabaseBobZT (DatabaseBob, DatabaseZT): - """This class can be used whenever you have a database that follows the Bob ZT-norm verification database interface, which is defined in :py:class:`bob.db.verification.utils.ZTDatabase`. - - **Parameters:** - - database : derivative of :py:class:`bob.db.verification.utils.ZTDatabase` - The database instance (such as a :py:class:`bob.db.mobio.Database`) that provides the actual interface, see :ref:`verification_databases` for a list. - - z_probe_options : dict - Dictionary of options passed to the :py:meth:`bob.db.verification.utils.ZTDatabase.z_probe_files` database query when retrieving files for Z-probing. - - kwargs : ``key=value`` pairs - The arguments of the :py:class:`DatabaseBob` base class constructor. - - .. note:: Usually, the ``name``, ``protocol``, ``training_depends_on_protocol`` and ``models_depend_on_protocol`` keyword parameters of the :py:class:`Database` base class constructor need to be specified. - """ - - def __init__( - self, - database, - z_probe_options = {}, # Limit the z-probes - **kwargs - ): -# assert isinstance(database, bob.db.verification.utils.ZTDatabase) // fails in tests - # call base class constructor, passing all the parameters to it - DatabaseBob.__init__(self, database = database, z_probe_options = z_probe_options, **kwargs) - - self.z_probe_options = z_probe_options - - - def all_files(self, groups = ['dev']): - """all_files(groups=None) -> files - - Returns all files of the database, including those for ZT norm, respecting the current protocol. - The files can be limited using the ``all_files_options`` and the the ``z_probe_options`` in the constructor. - - **Parameters:** - - groups : some of ``('world', 'dev', 'eval')`` or ``None`` - The groups to get the data for. - If ``None``, data for all groups is returned. - - **Returns:** - - files : [:py:class:`bob.db.verification.utils.File`] - The sorted and unique list of all files of the database. - """ - files = self.database.objects(protocol = self.protocol, groups = groups, **self.all_files_options) - - # add all files that belong to the ZT-norm - for group in groups: - if group == 'world': continue - files += self.database.tobjects(protocol = self.protocol, groups = group, model_ids = None) - files += self.database.zobjects(protocol = self.protocol, groups = group, **self.z_probe_options) - return self.sort(files) - - - def t_model_ids(self, group = 'dev'): - """t_model_ids(group = 'dev') -> ids - - Returns a list of model ids of T-Norm models for the given group, respecting the current protocol. - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the model ids for. - - **Returns:** - - ids : [int] or [str] - The list of (unique) model ids for T-Norm models of the given group. - """ - return sorted(self.database.t_model_ids(protocol = self.protocol, groups = group)) - - - def t_enroll_files(self, t_model_id, group = 'dev'): - """t_enroll_files(t_model_id, group = 'dev') -> files - - Returns a list of File objects that should be used to enroll the T-Norm model with the given model id from the given group, respecting the current protocol. - - **Parameters:** - - t_model_id : int or str - A unique ID that identifies the model. - - group : one of ``('dev', 'eval')`` - The group to get the enrollment files for. - - **Returns:** - - files : [:py:class:`bob.db.verification.utils.File`] - The sorted list of files used for to enroll the model with the given model id. - """ - return self.sort(self.database.t_enroll_files(protocol = self.protocol, groups = group, model_id = t_model_id)) - - - def z_probe_files(self, group = 'dev'): - """z_probe_files(group = 'dev') -> files - - Returns a list of probe files used to compute the Z-Norm, respecting the current protocol. - The Z-probe files can be limited using the ``z_probe_options`` in the query to :py:meth:`bob.db.verification.utils.ZTDatabase.z_probe_files` - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the Z-norm probe files for. - - **Returns:** - - files : [:py:class:`bob.db.verification.utils.File`] - The unique list of files used to compute the Z-norm. - """ - files = self.database.z_probe_files(protocol = self.protocol, groups = group, **self.z_probe_options) - return self.sort(files) - - - def z_probe_file_sets(self, group = 'dev'): - """z_probe_file_sets(group = 'dev') -> files - - Returns a list of probe FileSet objects used to compute the Z-Norm. - The Z-probe files can be limited using the ``z_probe_options`` in the query to - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the Z-norm probe files for. - - **Returns:** - - files : [:py:class:`FileSet`] or similar - The unique list of file sets used to compute the Z-norm. - """ - file_sets = self.database.z_probe_file_sets(protocol = self.protocol, groups = group, **self.z_probe_options) - return self.sort(file_sets) diff --git a/bob/bio/base/database/DatabaseFileList.py b/bob/bio/base/database/DatabaseFileList.py deleted file mode 100644 index e78bf9465633f8295cb6f539e4d160b6614ec55c..0000000000000000000000000000000000000000 --- a/bob/bio/base/database/DatabaseFileList.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# @author: Manuel Guenther <Manuel.Guenther@idiap.ch> -# @date: Wed Oct 3 10:31:51 CEST 2012 -# -# Copyright (C) 2011-2012 Idiap Research Institute, Martigny, Switzerland -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - - -from .DatabaseBob import DatabaseBobZT -import bob.db.verification.filelist - -class DatabaseFileList (DatabaseBobZT): - """This class can be used whenever you have a database that uses the Bob filelist database interface, which is defined in :py:class:`bob.db.verification.filelist.Database` - - **Parameters:** - - database : a :py:class:`bob.db.verification.filelist.Database` - The database instance that provides the actual interface. - - kwargs : ``key=value`` pairs - The arguments of the :py:class:`DatabaseBobZT` or :py:class:`DatabaseBob` base class constructors. - - .. note:: Usually, the ``name``, ``protocol``, ``training_depends_on_protocol`` and ``models_depend_on_protocol`` keyword parameters of the base class constructor need to be specified. - """ - - def __init__( - self, - database, # The bob database that is used - **kwargs # The default parameters of the base class - ): - - DatabaseBobZT.__init__( - self, - database = database, - **kwargs - ) - - assert isinstance(database, bob.db.verification.filelist.Database) - - - def all_files(self, groups = ['dev']): - """all_files(groups=None) -> files - - Returns all files of the database, respecting the current protocol. - If the current protocol is ``'None'``, ``None`` will be used instead. - When the underlying file list database provides files for ZT score normalization, these files are returned as well. - The files can be limited using the ``all_files_options`` in the constructor. - - **Parameters:** - - groups : some of ``('world', 'dev', 'eval')`` or ``None`` - The groups to get the data for. - If ``None``, data for all groups is returned. - - **Returns:** - - files : [:py:class:`bob.db.verification.filelist.File`] - The sorted and unique list of all files of the database. - """ - protocol = self.protocol if self.protocol != 'None' else None - files = self.database.objects(protocol = protocol, groups = groups, **self.all_files_options) - - # add all files that belong to the ZT-norm - for group in groups: - if group == 'world': continue - if self.database.implements_zt(protocol = protocol, groups = group): - files += self.database.tobjects(protocol = protocol, groups = group, model_ids = None) - files += self.database.zobjects(protocol = protocol, groups = group, **self.z_probe_options) - return self.sort(files) - - - def uses_probe_file_sets(self): - """File sets are not (yet) supported in the :py:class:`bob.db.verification.filelist.Database`, so this function returns ``False`` throughout.""" - return False - - - def model_ids(self, group = 'dev'): - """model_ids(group = 'dev') -> ids - - Returns a list of model ids for the given group, respecting the current protocol. - If the current protocol is ``'None'``, ``None`` will be used instead. - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the model ids for. - - **Returns:** - - ids : [str] - The list of (unique) model ids for the given group. - """ - return sorted(self.database.model_ids(protocol = self.protocol if self.protocol != 'None' else None, groups = group)) - - - def client_id_from_model_id(self, model_id, group = 'dev'): - """client_id_from_model_id(model_id, group = 'dev') -> client_id - - Uses :py:meth:`bob.db.verification.filelist.Database.get_client_id_from_model_id` to retrieve the client id for the given model id. - If the current protocol is ``'None'``, ``None`` will be used instead. - - **Parameters:** - - model_id : str - A unique ID that identifies the model for the client. - - group : one of ``('dev', 'eval')`` - The group to get the client ids for. - - **Returns:** - - client_id : str - A unique ID that identifies the client, to which the model belongs. - """ - return self.database.get_client_id_from_model_id(model_id, groups = group, protocol = self.protocol if self.protocol != 'None' else None) - - - def client_id_from_t_model_id(self, t_model_id, group = 'dev'): - """client_id_from_t_model_idt_(model_id, group = 'dev') -> client_id - - Uses :py:meth:`bob.db.verification.filelist.Database.get_client_id_from_t_model_id` to retrieve the client id for the T-norm given model id. - If the current protocol is ``'None'``, ``None`` will be used instead. - - **Parameters:** - - t_model_id : str - A unique ID that identifies the T-Norm model. - - group : one of ``('dev', 'eval')`` - The group to get the client ids for. - - **Returns:** - - client_id : str - A unique ID that identifies the client, to which the T-Norm model belongs. - """ - return self.database.get_client_id_from_tmodel_id(t_model_id, groups = group, protocol = self.protocol if self.protocol != 'None' else None) - - - def t_model_ids(self, group = 'dev'): - """t_model_ids(group = 'dev') -> ids - - Returns a list of model ids of T-Norm models for the given group, respecting the current protocol. - If the current protocol is ``'None'``, ``None`` will be used instead. - - **Parameters:** - - group : one of ``('dev', 'eval')`` - The group to get the model ids for. - - **Returns:** - - ids : [int] or [str] - The list of (unique) model ids for T-Norm models of the given group. - """ - return sorted(self.database.tmodel_ids(protocol = self.protocol if self.protocol != 'None' else None, groups = group)) diff --git a/bob/bio/base/database/__init__.py b/bob/bio/base/database/__init__.py deleted file mode 100644 index 945cd33ebec6cc299460208f41a20b86ee0eeea6..0000000000000000000000000000000000000000 --- a/bob/bio/base/database/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from .utils import File, FileSet - -from .Database import Database, DatabaseZT -from .DatabaseBob import DatabaseBob, DatabaseBobZT -from .DatabaseFileList import DatabaseFileList - -# gets sphinx autodoc done right - don't remove it -__all__ = [_ for _ in dir() if not _.startswith('_')] diff --git a/bob/bio/base/database/utils.py b/bob/bio/base/database/utils.py deleted file mode 100644 index 8473d07ef4123a15287e587318b57999da7818de..0000000000000000000000000000000000000000 --- a/bob/bio/base/database/utils.py +++ /dev/null @@ -1,97 +0,0 @@ -import os - -class File: - """This class defines the minimum interface of a database file that needs to be exported. - - Each file has a path, an id and an associated client (aka. identity, person, user). - Usually, this file is part of a database, which has a common directory for all files. - The path of this file is usually *relative* to that common directory, and it is usually stored *without* filename extension. - The file id can be anything hashable, but needs to be unique all over the database. - The client id can be anything hashable, but needs to be identical for different files of the same client, and different between clients. - - **Parameters:** - - file_id : str or int - A unique ID that identifies the file. - This ID might be identical to the ``path``, though integral IDs perform faster. - - client_id : str or int - A unique ID that identifies the client (user) to which this file belongs. - This ID might be the name of the person, though integral IDs perform faster. - - path : str - The file path of the file, which is relative to the common database directory, and without filename extension. - """ - - def __init__(self, file_id, client_id, path): - # The **unique** id of the file - self.id = file_id - # The id of the client that is attached to the file - self.client_id = client_id - # The **relative** path of the file according to the base directory of the database, without file extension - self.path = path - - def __lt__(self, other): - """Defines an order between files by using the order of the file ids.""" - # compare two File objects by comparing their IDs - return self.id < other.id - - def make_path(self, directory = None, extension = None): - """make_path(directory = None, extension = None) -> path - - Generates the full path using the given directory and filename extension. - - **Parameters:** - - directory : str or ``None`` - The directory to prepend. - If ``None``, no directory will be preprended. - - extension : str or ``None`` - The filename extension to append. - If ``None``, no file name extension will be appended. - - **Returns:** - - path : str - The full path including directory and extension. - """ - if directory is None: directory = '.' - if extension is None: extension = '' - - return os.path.join(directory, self.path + extension) - - -class FileSet: - """This class defines the minimum interface of a set of database files that needs to be exported. - - Use this class, whenever the database provides several files that belong to the same probe. - - Each file set has an id, and a list of associated files, which are of type :py:class:`File` of the same client. - The file set id can be anything hashable, but needs to be unique all over the database. - - **Parameters:** - - file_set_id : str or int - A unique ID that identifies the file set. - - files : [:py:class:`File`] - A list of File objects that should be stored inside this file. - All files of that list need to have the same client ID. - """ - - def __init__(self, file_set_id, files, path=None): - # The **unique** id of the file set - self.id = file_set_id - # The id of the client that is attached to the file - assert len(files) - self.client_id = files[0].client_id - assert all(f.client_id == self.client_id for f in files) - # The list of files contained in this set - self.files = files - self.path = "+".join(f.path for f in files) - - def __lt__(self, other): - """Defines an order between file sets by using the order of the file set ids.""" - # compare two File set objects by comparing their IDs - return self.id < other.id diff --git a/bob/bio/base/test/dummy/database.py b/bob/bio/base/test/dummy/database.py index 90c440ea290a024c93fe3fbc5648556fca6f7d0b..c79f36e33a57d45b955d1b20fe2e4f6c0321e696 100644 --- a/bob/bio/base/test/dummy/database.py +++ b/bob/bio/base/test/dummy/database.py @@ -1,34 +1,40 @@ -import bob.db.atnt -import os - -from bob.bio.base.database import DatabaseBob, DatabaseBobZT +from bob.bio.db import ZTBioDatabase, AtntBioDatabase from bob.bio.base.test.utils import atnt_database_directory -class DummyDatabase (DatabaseBobZT): - def __init__(self): - # call base class constructor with useful parameters - DatabaseBobZT.__init__( - self, - database = bob.db.atnt.Database( - original_directory = atnt_database_directory() - ), - name = 'test', - check_original_files_for_existence = True, - training_depends_on_protocol = False, - models_depend_on_protocol = False - ) +class DummyDatabase(ZTBioDatabase): + + def __init__(self): + # call base class constructor with useful parameters + super(DummyDatabase, self).__init__( + name='test', + original_directory=atnt_database_directory(), + original_extension='.pgm', + check_original_files_for_existence=True, + training_depends_on_protocol=False, + models_depend_on_protocol=False + ) + self.__db = AtntBioDatabase() + + def model_ids(self, group=None, protocol=None, gender=None): + return self.__db.model_ids(group, protocol, gender) + + def objects(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs): + return self.__db.objects(groups, protocol, purposes, model_ids, **kwargs) + + def tobjects(self, groups=None, protocol=None, model_ids=None, **kwargs): + return [] - def all_files(self, groups = ['dev']): - return DatabaseBob.all_files(self, groups) + def zobjects(self, groups=None, protocol=None, **kwargs): + return [] - def t_model_ids(self, group = 'dev'): - return self.model_ids(group) + def tmodel_ids(self, protocol=None, groups=None, **kwargs): + return self.__db.model_ids(groups) - def t_enroll_files(self, t_model_id, group = 'dev'): - return self.enroll_files(t_model_id, group) + def t_enroll_files(self, t_model_id, group='dev'): + return self.__db.enroll_files(t_model_id, group) - def z_probe_files(self, group = 'dev'): - return self.probe_files(None, group) + def z_probe_files(self, group='dev'): + return self.__db.probe_files(None, group) database = DummyDatabase() diff --git a/bob/bio/base/test/dummy/filelist.py b/bob/bio/base/test/dummy/filelist.py deleted file mode 100644 index dc59e4a170147bf32fe1e3f274668127df248f32..0000000000000000000000000000000000000000 --- a/bob/bio/base/test/dummy/filelist.py +++ /dev/null @@ -1,25 +0,0 @@ -import bob.db.verification.filelist -from bob.bio.base.database import DatabaseFileList -from bob.bio.base.test.utils import atnt_database_directory -import pkg_resources - -database = DatabaseFileList( - database = bob.db.verification.filelist.Database( - base_dir = pkg_resources.resource_filename('bob.bio.base.test', 'data/atnt'), - original_directory = atnt_database_directory(), - original_extension = ".pgm", - dev_subdir = '.', - eval_subdir = '.', - world_filename = 'world.lst', - models_filename = 'models.lst', - probes_filename = 'probes.lst', - tnorm_filename = 'models.lst', - znorm_filename = 'probes.lst', - keep_read_lists_in_memory = True - ), - name = 'test_filelist', - protocol = None, - check_original_files_for_existence = True, - training_depends_on_protocol = False, - models_depend_on_protocol = False -) diff --git a/bob/bio/base/test/dummy/fileset.py b/bob/bio/base/test/dummy/fileset.py index 17fb51b7f171001d5d8ade8b2f958ebd5e153e14..bfc6172c10d7a2ab3fbfb9dd836830311e9a724b 100644 --- a/bob/bio/base/test/dummy/fileset.py +++ b/bob/bio/base/test/dummy/fileset.py @@ -1,53 +1,60 @@ -import bob.db.atnt -import os - -from bob.bio.base.database import DatabaseBob, DatabaseBobZT, File, FileSet +from bob.bio.db import ZTBioDatabase, BioFileSet, BioFile, AtntBioDatabase from bob.bio.base.test.utils import atnt_database_directory -class FileSetDatabase (DatabaseBobZT): - - def __init__(self): - # call base class constructor with useful parameters - DatabaseBobZT.__init__( - self, - database = bob.db.atnt.Database( - original_directory = atnt_database_directory(), - ), - name = 'test_fileset', - check_original_files_for_existence = True, - training_depends_on_protocol = False, - models_depend_on_protocol = False - ) - - def uses_probe_file_sets(self): - return True - - def probe_file_sets(self, model_id = None, group = 'dev'): - """Returns the list of probe File objects (for the given model id, if given).""" - files = self.arrange_by_client(self.sort(self.database.objects(protocol = None, groups = group, purposes = 'probe'))) - # arrange files by clients - file_sets = [] - for client_files in files: - # convert into our File objects (so that they are tested as well) - our_files = [File(f.id, f.client_id, f.path) for f in client_files] - # generate file set for each client - file_set = FileSet(our_files[0].client_id, our_files) - file_sets.append(file_set) - return file_sets - - def all_files(self, groups = ['dev']): - return DatabaseBob.all_files(self, groups) - - def t_model_ids(self, group = 'dev'): - return self.model_ids(group) - - def t_enroll_files(self, t_model_id, group = 'dev'): - return self.enroll_files(t_model_id, group) - - def z_probe_files(self, group = 'dev'): - return self.probe_files(None, group) - - def z_probe_file_sets(self, group = 'dev'): - return self.probe_file_sets(None, group) - -database = FileSetDatabase() + +class DummyDatabase(ZTBioDatabase): + + def __init__(self): + # call base class constructor with useful parameters + super(DummyDatabase, self).__init__( + name='test_fileset', + original_directory=atnt_database_directory(), + original_extension='.pgm', + check_original_files_for_existence=True, + training_depends_on_protocol=False, + models_depend_on_protocol=False + ) + self.__db = AtntBioDatabase() + + def uses_probe_file_sets(self): + return True + + def probe_file_sets(self, model_id=None, group='dev'): + """Returns the list of probe File objects (for the given model id, if given).""" + # import ipdb; ipdb.set_trace() + files = self.arrange_by_client(self.sort(self.objects(protocol=None, groups=group, purposes='probe'))) + # arrange files by clients + file_sets = [] + for client_files in files: + # convert into our File objects (so that they are tested as well) + our_files = [BioFile(f.client_id, f.path, f.id) for f in client_files] + # generate file set for each client + file_set = BioFileSet(our_files[0].client_id, our_files) + file_sets.append(file_set) + return file_sets + + def model_ids(self, group=None, protocol=None, gender=None): + return self.__db.model_ids(group, protocol, gender) + + def objects(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs): + return self.__db.objects(groups, protocol, purposes, model_ids, **kwargs) + + def tobjects(self, groups=None, protocol=None, model_ids=None, **kwargs): + return [] + + def zobjects(self, groups=None, protocol=None, **kwargs): + return [] + + def tmodel_ids(self, protocol=None, groups=None, **kwargs): + return self.__db.model_ids(groups) + + def t_enroll_files(self, t_model_id, group='dev'): + return self.__db.enroll_files(t_model_id, group) + + def z_probe_files(self, group='dev'): + return self.__db.probe_files(None, group) + + def z_probe_file_sets(self, group='dev'): + return self.probe_file_sets(None, group) + +database = DummyDatabase() diff --git a/bob/bio/base/test/test_databases.py b/bob/bio/base/test/test_databases.py deleted file mode 100644 index 8691421ba4464073da3992b99a8f2939d43e91af..0000000000000000000000000000000000000000 --- a/bob/bio/base/test/test_databases.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 : -# @author: Manuel Guenther <Manuel.Guenther@idiap.ch> -# @date: Thu May 24 10:41:42 CEST 2012 -# -# Copyright (C) 2011-2012 Idiap Research Institute, Martigny, Switzerland -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, version 3 of the License. -# -# This program 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. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - - -import os -from nose.plugins.skip import SkipTest - -import bob.bio.base - -import pkg_resources -dummy_dir = pkg_resources.resource_filename('bob.bio.base', 'test/dummy') - -def test_verification_filelist(): - try: - db1 = bob.bio.base.load_resource(os.path.join(dummy_dir, 'database.py'), 'database') - except Exception as e: - raise SkipTest("This test is skipped since the atnt database is not available.") - try: - db2 = bob.bio.base.load_resource(os.path.join(dummy_dir, 'filelist.py'), 'database') - except Exception as e: - raise SkipTest("This test is skipped since the verification.filelist database is not available.") - # The test of the verification.filelist database is a bit different. - # here, we test the output of two different ways of querying the AT&T database - # where actually both ways are uncommon... - - # assure that different kind of queries result in the same file lists - assert set([str(id) for id in db1.model_ids()]) == set(db2.model_ids()) - assert set([str(id) for id in db1.t_model_ids()]) == set(db2.t_model_ids()) - - def _check_files(f1, f2): - assert set([file.path for file in f1]) == set([file.path for file in f2]) - - _check_files(db1.all_files(), db2.all_files()) - _check_files(db1.training_files('train_extractor'), db2.training_files('train_extractor')) - _check_files(db1.enroll_files(model_id=22), db2.enroll_files(model_id='22')) - _check_files(db1.probe_files(model_id=22), db2.probe_files(model_id='22')) - - _check_files(db1.t_enroll_files(t_model_id=22), db2.t_enroll_files(t_model_id='22')) - _check_files(db1.z_probe_files(), db2.z_probe_files()) - - f1 = db1.all_files()[0] - f2 = [f for f in db2.all_files() if f.path == f1.path][0] - - assert f1.make_path(directory='xx', extension='.yy') == f2.make_path(directory='xx', extension='.yy') - - m1 = sorted([str(id) for id in db1.model_ids()])[0] - m2 = sorted([str(id) for id in db2.model_ids()])[0] - assert str(db1.client_id_from_model_id(m1)) == db2.client_id_from_model_id(m2) diff --git a/bob/bio/base/test/test_scripts.py b/bob/bio/base/test/test_scripts.py index 57e10b908c820eca96b008dc9a41fd48eb96dcb2..20cb89a943c4fc1a1b5bfeae42bb5bc9d7f44eba 100644 --- a/bob/bio/base/test/test_scripts.py +++ b/bob/bio/base/test/test_scripts.py @@ -214,57 +214,6 @@ def test_verify_fileset(): _verify(parameters, test_dir, 'test_fileset', ref_modifier="-fileset") - -def test_verify_filelist(): - try: - import bob.db.verification.filelist - except ImportError: - raise SkipTest("Skipping test since bob.db.verification.filelist is not available") - test_dir = tempfile.mkdtemp(prefix='bobtest_') - # define dummy parameters - parameters = [ - '-d', os.path.join(dummy_dir, 'filelist.py'), - '-p', 'dummy', - '-e', 'dummy', - '-a', 'dummy', - '--zt-norm', - '-vs', 'test_filelist', - '--temp-directory', test_dir, - '--result-directory', test_dir, - '--preferred-package', 'bob.bio.base' - ] - - print (bob.bio.base.tools.command_line(parameters)) - - try: - from bob.bio.base.script.verify import main - main(parameters) - - # assert that the score file exists - score_files = [os.path.join(test_dir, 'test_filelist', 'None', norm, 'scores-dev') for norm in ('nonorm', 'ztnorm')] - assert os.path.exists(score_files[0]), "Score file %s does not exist" % score_files[0] - assert os.path.exists(score_files[1]), "Score file %s does not exist" % score_files[1] - - # assert that the scores are are identical (might be in a different order, though - reference_files = [os.path.join(data_dir, 'scores-%s-dev' % norm) for norm in ('nonorm', 'ztnorm')] - - for i in (0,1): - # load scores - a1, b1 = bob.measure.load.split_four_column(score_files[i]) - a2, b2 = bob.measure.load.split_four_column(reference_files[i]) - # sort scores - a1 = sorted(a1); a2 = sorted(a2); b1 = sorted(b1); b2 = sorted(b2) - - # assert that scores are almost equal - for i in range(len(a1)): - abs(a1[i] - a2[i]) < 1e-6 - for i in range(len(b1)): - abs(b1[i] - b2[i]) < 1e-6 - - finally: - shutil.rmtree(test_dir) - - def test_verify_missing(): test_dir = tempfile.mkdtemp(prefix='bobtest_') # define dummy parameters diff --git a/bob/bio/base/tools/FileSelector.py b/bob/bio/base/tools/FileSelector.py index 2a3e56df2983f7390a8faa7dc1ad28d835b04b96..9dbc23dc7cd801277ab2971cb576e121b3c68233 100644 --- a/bob/bio/base/tools/FileSelector.py +++ b/bob/bio/base/tools/FileSelector.py @@ -110,6 +110,10 @@ class FileSelector: """Returns the list of original data that can be used for preprocessing.""" return self.database.original_file_names(self.database.all_files(groups=groups)) + def original_data_list_files(self, groups = None): + """Returns the list of original data that can be used for preprocessing.""" + return (self.database.all_files(groups=groups), self.database.original_directory, self.database.original_extension) + def annotation_list(self, groups = None): """Returns the list of annotations objects.""" return self.database.all_files(groups=groups) diff --git a/bob/bio/base/tools/command_line.py b/bob/bio/base/tools/command_line.py index ffad31af0fd6d3b7ae993a7dff2aaeb43fdcb058..3749b36e29f7cb224371e75bcad321c7c55cce5e 100644 --- a/bob/bio/base/tools/command_line.py +++ b/bob/bio/base/tools/command_line.py @@ -8,7 +8,7 @@ logger = bob.core.log.setup("bob.bio.base") from .. import utils from . import FileSelector -from .. import database +from bob.bio.db import BioDatabase """Execute biometric recognition algorithms on a certain biometric database. """ @@ -249,7 +249,7 @@ def initialize(parsers, command_line_parameters = None, skips = []): model_sub_dir = protocol if args.database.models_depend_on_protocol else enroller_sub_dir # Database directories, which should be automatically replaced - if isinstance(args.database, database.DatabaseBob): + if isinstance(args.database, BioDatabase): args.database.replace_directories(args.database_directories_file) # initialize the file selector diff --git a/bob/bio/base/tools/preprocessor.py b/bob/bio/base/tools/preprocessor.py index 01dea478a7976255216d159ba4d1653d9c1e05b5..86ec390c0f10f2adc4935841a31777341a6a019b 100644 --- a/bob/bio/base/tools/preprocessor.py +++ b/bob/bio/base/tools/preprocessor.py @@ -42,7 +42,7 @@ def preprocess(preprocessor, groups = None, indices = None, allow_missing_files fs = FileSelector.instance() # get the file lists - data_files = fs.original_data_list(groups=groups) + data_files, original_directory, original_extension = fs.original_data_list_files(groups=groups) preprocessed_data_files = fs.preprocessed_data_list(groups=groups) # select a subset of keys to iterate @@ -60,12 +60,16 @@ def preprocess(preprocessor, groups = None, indices = None, allow_missing_files # iterate over the selected files for i in index_range: preprocessed_data_file = preprocessed_data_files[i] - file_name = data_files[i] + file_object = data_files[i] + file_name = file_object.make_path(original_directory, original_extension) # check for existence if not utils.check_file(preprocessed_data_file, force, 1000): logger.debug("... Processing original data file '%s'", file_name) - data = preprocessor.read_original_data(file_name) + if hasattr(file_object, 'load'): + data = file_object.load(original_directory, original_extension) + else: + data = preprocessor.read_original_data(file_name) # create output directory before reading the data file (is sometimes required, when relative directories are specified, especially, including a .. somewhere) bob.io.base.create_directories_safe(os.path.dirname(preprocessed_data_file)) diff --git a/buildout.cfg b/buildout.cfg index 026c9c5b43130b84cad35f1baf92784666c3bd78..e77e863af0476b326dfb64ef7db5e9e57ea8853b 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -21,8 +21,7 @@ develop = src/bob.extension src/bob.learn.em src/bob.measure src/bob.db.base - src/bob.db.verification.utils - src/bob.db.verification.filelist + src/bob.bio.db src/bob.db.atnt src/bob.io.image . @@ -44,8 +43,7 @@ bob.learn.linear = git https://github.com/bioidiap/bob.learn.linear bob.learn.em = git https://github.com/bioidiap/bob.learn.em bob.measure = git https://github.com/bioidiap/bob.measure bob.db.base = git https://github.com/bioidiap/bob.db.base -bob.db.verification.utils = git https://github.com/bioidiap/bob.db.verification.utils -bob.db.verification.filelist = git https://github.com/bioidiap/bob.db.verification.filelist +bob.bio.db = git https://gitlab.idiap.ch/biometric/bob.bio.db bob.db.atnt = git https://github.com/bioidiap/bob.db.atnt bob.io.image = git https://github.com/bioidiap/bob.io.image diff --git a/requirements.txt b/requirements.txt index 71eba5d0fcc37c4bceaa124f02d6e95bcfcb255a..73661d793cbe832cc400f2f8c66c8692af8b9df0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,8 +11,7 @@ bob.sp bob.learn.em bob.measure bob.db.base -bob.db.verification.utils -bob.db.verification.filelist +bob.bio.db bob.db.atnt # for test purposes bob.io.image # for test purposes matplotlib # for plotting