From 00f6d036185b362668f28e6f56bd7b3fe3478832 Mon Sep 17 00:00:00 2001
From: Tiago Freitas Pereira <tiagofrepereira@gmail.com>
Date: Thu, 26 Mar 2020 11:00:54 +0100
Subject: [PATCH] Fixing vanilla_biometrics. We can run the first pca_atnt
 example without dask

---
 bob/bio/base/__init__.py                       |  1 -
 bob/bio/base/config/examples/pca_atnt.py       |  8 ++++----
 .../vanilla_biometrics/abstract_classes.py     | 11 ++++-------
 .../pipelines/vanilla_biometrics/legacy.py     | 18 ++++++++----------
 .../pipelines/vanilla_biometrics/mixins.py     |  5 +++--
 bob/bio/base/script/vanilla_biometrics.py      | 10 ++++------
 6 files changed, 23 insertions(+), 30 deletions(-)

diff --git a/bob/bio/base/__init__.py b/bob/bio/base/__init__.py
index fece5d10..82ce2a09 100644
--- a/bob/bio/base/__init__.py
+++ b/bob/bio/base/__init__.py
@@ -4,7 +4,6 @@ from . import preprocessor
 from . import extractor
 from . import algorithm
 from . import annotator
-from . import mixins
 
 from . import script
 from . import test
diff --git a/bob/bio/base/config/examples/pca_atnt.py b/bob/bio/base/config/examples/pca_atnt.py
index 76015a79..792e6774 100644
--- a/bob/bio/base/config/examples/pca_atnt.py
+++ b/bob/bio/base/config/examples/pca_atnt.py
@@ -1,7 +1,7 @@
 from bob.bio.base.pipelines.vanilla_biometrics.legacy import DatabaseConnector
 from sklearn.pipeline import make_pipeline
 from bob.pipelines.transformers import CheckpointSampleLinearize, CheckpointSamplePCA
-from bob.bio.base.pipelines.vanilla_biometrics.biometric_algorithm import (
+from bob.bio.base.pipelines.vanilla_biometrics.implemented import (
     CheckpointDistance,
 )
 from bob.bio.face.database import AtntBioDatabase
@@ -20,9 +20,9 @@ algorithm = CheckpointDistance(features_dir="./example/")
 
 # comment out the code below to disable dask
 from bob.pipelines.mixins import estimator_dask_it, mix_me_up
-from bob.bio.base.pipelines.vanilla_biometrics.biometric_algorithm import (
+from bob.bio.base.pipelines.vanilla_biometrics.mixins import (
     BioAlgDaskMixin,
 )
 
-transformer = estimator_dask_it(transformer)
-algorithm = mix_me_up([BioAlgDaskMixin], algorithm)
+#transformer = estimator_dask_it(transformer)
+#algorithm = mix_me_up(BioAlgDaskMixin, algorithm)
diff --git a/bob/bio/base/pipelines/vanilla_biometrics/abstract_classes.py b/bob/bio/base/pipelines/vanilla_biometrics/abstract_classes.py
index 1fbfce94..74e2f175 100644
--- a/bob/bio/base/pipelines/vanilla_biometrics/abstract_classes.py
+++ b/bob/bio/base/pipelines/vanilla_biometrics/abstract_classes.py
@@ -1,6 +1,6 @@
 from abc import ABCMeta, abstractmethod
 from bob.pipelines.sample import Sample, SampleSet, DelayedSample
-
+import functools
 
 class BioAlgorithm(metaclass=ABCMeta):
     """Describes a base biometric comparator for the Vanilla Biometrics Pipeline :ref:`_bob.bio.base.struct_bio_rec_sys`_.
@@ -95,6 +95,7 @@ class BioAlgorithm(metaclass=ABCMeta):
         # a sampleset either after or before scoring.
         # To be honest, this should be the default behaviour
         retval = []
+
         for subprobe_id, (s, parent) in enumerate(zip(data, sampleset.samples)):
             # Creating one sample per comparison
             subprobe_scores = []
@@ -201,13 +202,9 @@ def save_scores_four_columns(path, probe):
             line = "{0} {1} {2} {3}\n".format(
                 biometric_reference.subject,
                 probe.subject,
-                probe.key,
+                probe.path,
                 biometric_reference.data,
             )
             f.write(line)
 
-    def load():
-        with open(path) as f:
-            return [float(line.split()[-1]) for line in f]
-
-    return DelayedSample(load, parent=probe)
+    return  DelayedSample(functools.partial(open, path), parent=probe)
diff --git a/bob/bio/base/pipelines/vanilla_biometrics/legacy.py b/bob/bio/base/pipelines/vanilla_biometrics/legacy.py
index 6e629ad0..fcf80a02 100644
--- a/bob/bio/base/pipelines/vanilla_biometrics/legacy.py
+++ b/bob/bio/base/pipelines/vanilla_biometrics/legacy.py
@@ -7,7 +7,7 @@ import os
 import functools
 from collections import defaultdict
 
-from .... import utils
+from bob.bio.base import utils
 from .abstract_classes import BioAlgorithm, Database, save_scores_four_columns
 from bob.io.base import HDF5File
 from bob.pipelines.mixins import SampleMixin, CheckpointMixin
@@ -30,7 +30,7 @@ def _biofile_to_delayed_sample(biofile, database):
     )
 
 
-class LegacyDatabaseConnector(Database):
+class DatabaseConnector(Database):
     """Wraps a bob.bio.base database and generates conforming samples
 
     This connector allows wrapping generic bob.bio.base datasets and generate
@@ -50,8 +50,7 @@ class LegacyDatabaseConnector(Database):
 
     """
 
-    def __init__(self, database, **kwargs):
-        super().__init__(**kwargs)
+    def __init__(self, database, **kwargs):        
         self.database = database
 
     def background_model_samples(self):
@@ -96,7 +95,7 @@ class LegacyDatabaseConnector(Database):
         retval = []
         for m in self.database.model_ids(groups=group):
 
-            objects = self.database.enroll_files(groups=group, model_id=m)
+            objects = self.database.enroll_files(group=group, model_id=m)
 
             retval.append(
                 SampleSet(
@@ -137,7 +136,6 @@ class LegacyDatabaseConnector(Database):
             # Getting all the probe objects from a particular biometric
             # reference
             objects = self.database.probe_files(group=group, model_id=m)
-
             # Creating probe samples
             for o in objects:
                 if o.id not in probes:
@@ -194,7 +192,7 @@ def _get_pickable_method(method):
     return method
 
 
-class LegacyPreprocessor(CheckpointMixin, SampleMixin, _Preprocessor):
+class Preprocessor(CheckpointMixin, SampleMixin, _Preprocessor):
     def __init__(self, callable, **kwargs):
         instance = callable()
         super().__init__(
@@ -236,7 +234,7 @@ class _Extractor(_NonPickableWrapper, TransformerMixin):
         return {"requires_fit": self.instance.requires_training}
 
 
-class LegacyExtractor(CheckpointMixin, SampleMixin, _Extractor):
+class Extractor(CheckpointMixin, SampleMixin, _Extractor):
     def __init__(self, callable, model_path, **kwargs):
         instance = callable()
 
@@ -288,7 +286,7 @@ class _AlgorithmTransformer(_NonPickableWrapper, TransformerMixin):
         return {"requires_fit": self.instance.requires_projector_training}
 
 
-class LegacyAlgorithmAsTransformer(CheckpointMixin, SampleMixin, _AlgorithmTransformer):
+class AlgorithmAsTransformer(CheckpointMixin, SampleMixin, _AlgorithmTransformer):
     """Class that wraps :py:class:`bob.bio.base.algorithm.Algoritm`
 
     :py:method:`LegacyAlgorithmrMixin.fit` maps to :py:method:`bob.bio.base.algorithm.Algoritm.train_projector`
@@ -341,7 +339,7 @@ class LegacyAlgorithmAsTransformer(CheckpointMixin, SampleMixin, _AlgorithmTrans
         return self
 
 
-class LegacyAlgorithmAsBioAlg(BioAlgorithm, _NonPickableWrapper):
+class AlgorithmAsBioAlg(BioAlgorithm, _NonPickableWrapper):
     """Biometric Algorithm that handles legacy :py:class:`bob.bio.base.algorithm.Algorithm`
 
 
diff --git a/bob/bio/base/pipelines/vanilla_biometrics/mixins.py b/bob/bio/base/pipelines/vanilla_biometrics/mixins.py
index 5655e0df..a61f9a59 100644
--- a/bob/bio/base/pipelines/vanilla_biometrics/mixins.py
+++ b/bob/bio/base/pipelines/vanilla_biometrics/mixins.py
@@ -26,7 +26,7 @@ class BioAlgCheckpointMixin(CheckpointMixin):
 
     """
 
-    def __init__(self, features_dir, **kwargs):
+    def __init__(self, features_dir="", **kwargs):
         super().__init__(features_dir=features_dir, **kwargs)
         self.biometric_reference_dir = os.path.join(
             features_dir, "biometric_references"
@@ -63,15 +63,16 @@ class BioAlgCheckpointMixin(CheckpointMixin):
             # If sample already there, just load
             delayed_enrolled_sample = self.load(path)
             delayed_enrolled_sample.key = sampleset.key
+            delayed_enrolled_sample.subject = sampleset.subject
 
         return delayed_enrolled_sample
 
     def _score_sample_set(self, sampleset, biometric_references):
         """Given a sampleset for probing, compute the scores and retures a sample set with the scores
         """
+
         # Computing score
         scored_sample_set = super()._score_sample_set(sampleset, biometric_references)
-
         for s in scored_sample_set:
             # Checkpointing score
             path = os.path.join(self.score_dir, str(s.path) + ".txt")
diff --git a/bob/bio/base/script/vanilla_biometrics.py b/bob/bio/base/script/vanilla_biometrics.py
index c0cba089..26c9a008 100644
--- a/bob/bio/base/script/vanilla_biometrics.py
+++ b/bob/bio/base/script/vanilla_biometrics.py
@@ -156,7 +156,7 @@ def vanilla_biometrics(
     import dask.bag
     import itertools
     import os
-    from bob.pipelines.sample import Sample
+    from bob.pipelines.sample import Sample, DelayedSample
 
     if not os.path.exists(output):
         os.makedirs(output, exist_ok=True)
@@ -189,12 +189,10 @@ def vanilla_biometrics(
             result = itertools.chain(*result)
             for probe in result:
                 for sample in probe.samples:
-
                     if isinstance(sample, Sample):
-                        line = "{0} {1} {2} {3}\n".format(
-                            sample.key, probe.key, probe.path, sample.data
-                        )
-                        f.write(line)
+                        f.write("{0} {1} {2} {3}\n".format(sample.key, probe.key, probe.path, sample.data))
+                    elif isinstance(sample, DelayedSample):
+                        f.writelines(sample.load().readlines())
                     else:
                         raise TypeError("The output of the pipeline is not writeble")
 
-- 
GitLab