.. vim: set fileencoding=utf-8 :
.. @author: Manuel Guenther <Manuel.Guenther@idiap.ch>
.. @date:   Thu Dec  6 12:28:25 CET 2012

================================================
 Write your own Verification Database Interface
================================================

When you write an bob.db database that should be used for verification (e.g. face, speaker, iris, finger-vein, ... verification), you should follow the structure provided by this package.
In order to assure compatibility with other verification databases, please:

1. derive your ``File`` class from :py:class:`bob.db.verification.utils.File`
2. derive your ``Database`` class from :py:class:`bob.db.verification.utils.Database`

and implement the desired abstract methods.
If your database uses the SQLite interface, you should directly derive your ``Database`` from :py:class:`bob.db.verification.utils.SQLiteDatabase`.
If you also provide functions for dealing with ZT score normalization, please **also** derive your class from :py:class:`bob.db.verification.utils.ZTDatabase`.
In any case, please call the corresponding base class constructor(s) in your constructor.


The ``File`` class
------------------

The :py:class:`bob.db.verification.utils.File` class provides the minimum common interface for a File object the can be queried from a :py:class:`bob.db.verification.utils.Database`.
During construction, it requires the ID of the client to which this file belongs, and the relative path of the file.
Additionally, the ID of the file has to be specified, unless it is automatically initialized, e.g. by using the SQLite interface.

The ``File`` base class has some common functionality that might be used on files.
E.g. you can create an absolute path for a real file by calling :py:func:`bob.db.verification.utils.File.make_path`, specifying the desired directory and file name extension.

The :py:class:`bob.db.verification.utils.File` can handle different types of file IDs.
By default (when used in combination with a :py:class:`bob.db.verification.utils.SQLiteDatabase`), the file ID is of type ``int`` and automatically generated by the SQL database.
When file IDs are specified, they can be of any hashable type (if used in combination with a :py:class:`bob.db.verification.utils.SQLiteDatabase`, this should be an SQL type like Integer or String).


The ``Database`` classes
------------------------

The :py:class:`bob.db.verification.utils.Database` class and its derivatives :py:class:`bob.db.verification.utils.SQLiteDatabase` and :py:class:`bob.db.verification.utils.ZTDatabase` provide the minimum common interface for verification databases handled by Bob.
Please assure that all abstract methods are actually implemented, using at least the parameters as given in the base class.
If you miss one of the parameter names, you will get an exception during execution.

In the :py:class:`bob.db.verification.utils.Database` class, you have to implement:

1. ``model_ids(self, groups, protocol)``
2. ``objects(self, groups, protocol, purposes, model_ids)``

In :py:class:`bob.db.verification.utils.ZTDatabase`, you additionally need to provide implementations for:

3. ``tmodel_ids(self, groups, protocol)``
4. ``tobjects(self, groups, protocol, model_ids)``
5. ``zobjects(self, groups, protocol)``

For a description of the parameters, please refer to the source code documentation.
In any case, your functions are allowed to take extra keyword arguments (but no non-keyword arguments).

The ``Database`` classes also provide some common functionality for testing valid arguments.
There are two functions: ``check_parameters_for_validity()`` and ``check_parameter_for_validity()`` (note the difference: parameters and parameter).
The first checks if the given list of parameters are contained in the list of valid parameters and returns a list of valid parameters.
The second check if the given single parameter is contained in the list of valid parameters and returns one valid parameter.

The :py:class:`bob.db.verification.utils.SQLiteDatabase` provides additional interfaces for dealing with the SQLite database.
On creation it opens a read-only connection to the given SQLite database and keeps it opened during the whole session.
To query the database, please use the :py:func:`bob.db.verification.utils.SQLiteDatabase.query` function, which is just a wrapper class for the normal SQLite query and takes the same arguments.


Annotations
-----------

Many databases come with additional information about their data.
For image databases, e.g., the locations of hand-labeled facial landmarks are provided.
Usually, these data is stored in additional text files.
For most of the available ``bob.db`` databases, there is exactly one text file for each data file.

The function :py:func:`bob.db.verification.utils.read_annotation_file` can be used to read annotation files of different types.
It will output the data as a dictionary, containing a ``key`` and the interpreted read data.
For landmark locations, the data is returned in **the common way** for bob, which is ``(y, x)``!
The following formats are currently accepted:

* ``'eyecenter'`` (for face images): Each file contains **only** the locations of the two eyes, in one row, as follows: ``re_x re_y le_x le_y``. The keys will be ``'reye'`` and ``'leye'``.
* ``'named'`` (for face images): Each file contains lines with the landmark name and the two landmark locations, e.g. ``reye re_x re_y``.
* ``'idiap'`` (for face images): The file format to read Idiap specific annotation files. It will return up to 24 key points. 22 of these are read from the file, and the ``'reye'`` and ``'leye'`` are estimated from the inner and outer corners of the eyes (if available).

.. note::
   'Left' and 'Right' positions are always expected to be from the subject perspective.
   This means that, e.g., the ``'leye'`` landmark usually has a **higher** x-coordinate than the ``'reye'``.

