diff --git a/.gitignore b/.gitignore
index b8afedd4fabe76662e1ef277c0a7b285fc0ff256..a99d934baa22d69071fb20b7e4e28c5e3adf8722 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 *.swp
 *.pyc
 bin
+build
 eggs
 parts
 .installed.cfg
diff --git a/bob/paper/nir_patch_pooling/config/patch_pooling_lr.py b/bob/paper/nir_patch_pooling/config/patch_pooling_lr.py
index 192e9d29c69732d2a8c0add2b13504e662010f70..eba399526c8e57afcc0885eaeee144665a65644d 100644
--- a/bob/paper/nir_patch_pooling/config/patch_pooling_lr.py
+++ b/bob/paper/nir_patch_pooling/config/patch_pooling_lr.py
@@ -15,25 +15,24 @@ sub_directory = "pooling_lr"
 from bob.pad.face.preprocessor import FaceCropAlign
 from bob.bio.video.preprocessor import Wrapper
 from bob.bio.video.utils import FrameSelector
-
+from bob.pad.face.preprocessor.FaceCropAlign import auto_norm_image as _norm_func
 
 # parameters and constants
 FACE_SIZE = 128
 RGB_OUTPUT_FLAG = False
 USE_FACE_ALIGNMENT = True
 ALIGNMENT_TYPE = "lightcnn"
-MAX_IMAGE_SIZE = None
-FACE_DETECTION_METHOD = None
 MIN_FACE_SIZE = 50
+NORMALIZATION_FUNCTION = _norm_func
+NORMALIZATION_FUNCTION_KWARGS = {'n_sigma':3.0, 'norm_method':'MAD'}
 
 _image_preprocessor = FaceCropAlign(face_size=FACE_SIZE,
         rgb_output_flag=RGB_OUTPUT_FLAG,
         use_face_alignment=USE_FACE_ALIGNMENT,
         alignment_type=ALIGNMENT_TYPE,
-        max_image_size=MAX_IMAGE_SIZE,
-        face_detection_method=FACE_DETECTION_METHOD,
         min_face_size=MIN_FACE_SIZE,
-        )
+        normalization_function = NORMALIZATION_FUNCTION,
+        normalization_function_kwargs = NORMALIZATION_FUNCTION_KWARGS)
 
 _frame_selector = FrameSelector(selection_style = "all")
 
@@ -49,7 +48,7 @@ from bob.bio.video.extractor import Wrapper
 from bob.extension import rc
 import os
 
-_model_directory = rc["lightcnn9.model.directory"]
+_model_directory = rc["lightcnn9.model_directory"]
 _model_name = "LightCNN_9Layers_checkpoint.pth.tar"
 _model_file = os.path.join(_model_directory, _model_name)
 
diff --git a/bob/paper/nir_patch_pooling/config/run.sh b/bob/paper/nir_patch_pooling/config/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4e002d94195c12cc83efd2f7de8da33953ab59fb
--- /dev/null
+++ b/bob/paper/nir_patch_pooling/config/run.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+set -ex
+
+echo "Run experiments from ICIP 2020 paper"
+echo "-----------------------------------"
+
+expt="wmca"
+
+base_directory="/idiap/temp/kkotwal/icip20/expt"
+
+# expt: WMCA
+if [[ "${expt}" == "wmca" ]]; then
+    output_directory="${base_directory}/wmca"
+    db_config="wmca_mask.py"
+    protocol="grandtest"
+
+elif [[ "${expt}" == "mlfp" ]]; then
+    output_directory="${base_directory}/mlfp"
+    db_config="mlfp.py"
+    protocol="cv1"
+
+else
+    echo "Unknown expt"
+    exit -1
+fi
+
+
+cmd="spoof.py ${db_config} patch_pooling_lr.py -s ${output_directory} -vv --grid idiap"
+#echo ${cmd}
+$cmd
+
+cmd="bob pad metriics -v -e ${output_directory}/${protocol}/scores/scores-{dev,eval}"
+echo ${cmd}
+#$cmd
+
+#--------------
diff --git a/bob/paper/nir_patch_pooling/database/__init__.py b/bob/paper/nir_patch_pooling/database/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..42f4bbb4c55e0cb856b93e321c28669dd647782c 100644
--- a/bob/paper/nir_patch_pooling/database/__init__.py
+++ b/bob/paper/nir_patch_pooling/database/__init__.py
@@ -0,0 +1,2 @@
+from .wmca_mask import WMCAMask
+from .mlfp import MLFPDatabase
diff --git a/bob/paper/nir_patch_pooling/database/lists/grandtest/dev/for_attack.lst b/bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/dev/for_attack.lst
similarity index 100%
rename from bob/paper/nir_patch_pooling/database/lists/grandtest/dev/for_attack.lst
rename to bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/dev/for_attack.lst
diff --git a/bob/paper/nir_patch_pooling/database/lists/grandtest/dev/for_real.lst b/bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/dev/for_real.lst
similarity index 100%
rename from bob/paper/nir_patch_pooling/database/lists/grandtest/dev/for_real.lst
rename to bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/dev/for_real.lst
diff --git a/bob/paper/nir_patch_pooling/database/lists/grandtest/eval/for_attack.lst b/bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/eval/for_attack.lst
similarity index 100%
rename from bob/paper/nir_patch_pooling/database/lists/grandtest/eval/for_attack.lst
rename to bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/eval/for_attack.lst
diff --git a/bob/paper/nir_patch_pooling/database/lists/grandtest/eval/for_real.lst b/bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/eval/for_real.lst
similarity index 100%
rename from bob/paper/nir_patch_pooling/database/lists/grandtest/eval/for_real.lst
rename to bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/eval/for_real.lst
diff --git a/bob/paper/nir_patch_pooling/database/lists/grandtest/train/for_attack.lst b/bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/train/for_attack.lst
similarity index 100%
rename from bob/paper/nir_patch_pooling/database/lists/grandtest/train/for_attack.lst
rename to bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/train/for_attack.lst
diff --git a/bob/paper/nir_patch_pooling/database/lists/grandtest/train/for_real.lst b/bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/train/for_real.lst
similarity index 100%
rename from bob/paper/nir_patch_pooling/database/lists/grandtest/train/for_real.lst
rename to bob/paper/nir_patch_pooling/database/lists/wmca_mask/grandtest/train/for_real.lst
diff --git a/bob/paper/nir_patch_pooling/database/wmca_mask.py b/bob/paper/nir_patch_pooling/database/wmca_mask.py
index ded9a6f94f342134946ead614b8f1f8b4047b5e9..3824bcf87a1475479b1b41e397795a18ecc28f6e 100644
--- a/bob/paper/nir_patch_pooling/database/wmca_mask.py
+++ b/bob/paper/nir_patch_pooling/database/wmca_mask.py
@@ -12,11 +12,9 @@ from bob.pad.face.database.batl import BatlPadFile
 from bob.db.batl.models import VideoFile
 from bob.extension import rc
 from bob.bio.video.utils import FrameSelector
-from bob.pad.face.preprocessor.FaceCropAlign import detect_face_landmarks_in_image
 
 import os
 import json
-from bob.io.base import create_directories_safe
 
 import pkg_resources
 
@@ -57,7 +55,6 @@ class WMCAMask(FileListPadDatabase):
             original_extension = ".h5",
             protocol = "grandtest",
             annotation_directory = None,
-            landmark_detect_method = "mtcnn",
             pad_file_class = BatlPadFile,
             low_level_pad_file_class = File,
             **kwargs,
@@ -149,7 +146,7 @@ class WMCAMask(FileListPadDatabase):
         # create objects for each file where the class is BATLPadFile
 
         # aux information
-        stream_type = "nir"
+        stream_type = "infrared" # nir => infrared
         num_frames = 50
 
         files = [self.pad_file_class(f=f, stream_type=stream_type,
@@ -162,8 +159,7 @@ class WMCAMask(FileListPadDatabase):
     def annotations(self, f):
         """
         Returns annotations for a given file object ``f``.
-        If annotations do not exist, these will be computed and saved in annotation_
-        directory.
+        Annotations must be precomputed.
 
         **Parameters:**
 
@@ -187,38 +183,19 @@ class WMCAMask(FileListPadDatabase):
 
         file_path = os.path.join(self.annotation_directory, f.f.path + ".json")
 
-        # if annotations exist, load from file_path
         if os.path.isfile(file_path): 
 
             with open(file_path, "r") as json_file:
                 annotations = json.load(json_file)
-               
-        else: 
-
-            # find and save annotations
-            annotations = {}
-            video = f.load(directory=self.original_directory, extension=self.original_extension)
-
-            for idx, image in enumerate(video.as_array()):
-                frame_annotations = detect_face_landmarks_in_image(image, method=self.landmark_detect_method)
-                if frame_annotations:
-                    annotations[str(idx)] = frame_annotations
-
-            # save to file_path
-            create_directories_safe(directory=os.path.split(file_path)[0], dryrun=False)
-            with open(file_path, 'w+') as json_file:
-                json_file.write(json.dumps(annotations))
+                                      
+            if not annotations:  # if dictionary is empty
+                logger.warning("Empty annotations for %s", f.path)
+                return None
 
+            return annotations
         
-        if not annotations:  # if dictionary is empty
-            logger.warning("Empty annotations for {}".format(f.path))
+        else: 
+            logger.warning("Annotation file for %s does not exist. (Overall path: %s)", f.path, file_path)
             return None
 
-        return annotations
-
 #------------------------------------------------------------------------------
-
-
-
-
-
diff --git a/bob/paper/nir_patch_pooling/extractor/__init__.py b/bob/paper/nir_patch_pooling/extractor/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bb19ad5c71fc252538fbb58e5f10acc6510c56bf 100644
--- a/bob/paper/nir_patch_pooling/extractor/__init__.py
+++ b/bob/paper/nir_patch_pooling/extractor/__init__.py
@@ -0,0 +1,2 @@
+from .patch_pooling_cnn import PatchPoolingCNN
+