From ce423f5f69db33763e04274baa46174eb04bb581 Mon Sep 17 00:00:00 2001
From: Steffen Hauf <haufs@max-exfl030.desy.de>
Date: Thu, 15 Nov 2018 15:22:49 +0100
Subject: [PATCH] Add LPD tests

---
 notebooks/LPD/LPD_Correct_and_Verify.ipynb |  2 +-
 tests/correction_base.py                   | 31 ++++++++---
 tests/test_agipd.py                        |  2 +-
 tests/test_lpd.py                          | 60 ++++++++++++++++++++++
 4 files changed, 85 insertions(+), 10 deletions(-)
 create mode 100644 tests/test_lpd.py

diff --git a/notebooks/LPD/LPD_Correct_and_Verify.ipynb b/notebooks/LPD/LPD_Correct_and_Verify.ipynb
index 85ea16660..9646183bc 100644
--- a/notebooks/LPD/LPD_Correct_and_Verify.ipynb
+++ b/notebooks/LPD/LPD_Correct_and_Verify.ipynb
@@ -52,7 +52,7 @@
     "    import glob\n",
     "    import re\n",
     "    import numpy as np\n",
-    "    if sequences_per_node != 0:\n",
+    "    if sequences[0] == -1:\n",
     "        sequence_files = glob.glob(\"{}/r{:04d}/*-S*.h5\".format(in_folder, run))\n",
     "        seq_nums = set()\n",
     "        for sf in sequence_files:\n",
diff --git a/tests/correction_base.py b/tests/correction_base.py
index d7324bf53..99e5d6cd4 100644
--- a/tests/correction_base.py
+++ b/tests/correction_base.py
@@ -1,5 +1,6 @@
 from abc import abstractmethod
 import argparse
+from enum import Enum
 from functools import partial
 import glob
 import hashlib
@@ -32,6 +33,11 @@ parser.add_argument('--artefact-dir', type=str, default="./artifacts/")
 parser.add_argument('unittest_args', nargs='*')
 args = parser.parse_args()
 
+
+class Failures(Enum):
+    ARTIFACT_MISSING = "No artifact"
+    EMPTY_ARTIFACT = "Empty artifact"
+
             
 def _do_generate():
     return args.generate or args.generate_wo_execution
@@ -104,7 +110,8 @@ def parallel_hist_gen(hist_paths, artifact_dir, fname):
                 del d
     hist_fname = "{}.hist".format(fname)
     hpath = "{}/{}".format(artifact_dir, os.path.basename(hist_fname))
-    np.savez(hpath, **all_hists)
+    if len(all_hists):
+        np.savez(hpath, **all_hists)
     
     
 def parallel_hist_eval(hist_paths, cls, fname):
@@ -115,8 +122,12 @@ def parallel_hist_eval(hist_paths, cls, fname):
         hpath = "{}/{}".format(test_art_dir, os.path.basename(hist_fname))
         has_artifact = os.path.exists(hpath)
         if not has_artifact:
-            return None
-        test_hists = np.load(hpath)
+            return Failures.ARTIFACT_MISSING
+        
+        try:
+            test_hists = np.load(hpath)
+        except OSError:
+            return Failures.EMPTY_ARTIFACT  # likely empty data
         
         for path, hists in hist_paths.items():
             mpaths = _get_matching_h5_paths(f, path)
@@ -254,8 +265,10 @@ class CorrectionTestBase:
             for i, rvals in enumerate(r):
                 msg = "Verifying: {}".format(files_to_check[i])
                 with self.subTest(msg=msg):
-                    self.assertIsNotNone(rvals, "No comparison histograms found")
-                if rvals is None:
+                    self.assertNotEqual(Failures.ARTIFACT_MISSING, "No comparison histograms found")
+                if rvals is Failures.ARTIFACT_MISSING:
+                    return
+                if rvals is Failures.EMPTY_ARTIFACT:
                     return
                 else:
                     for rval in rvals:  # inner loop
@@ -323,7 +336,7 @@ class CorrectionTestBase:
                      "User requested to skip karabo data test")
     def test_karabo_data(self):
         out_folder = self._output_to_path()
-        kdata = "{}/karabo.data".format(self.artifact_dir)
+        kdata = "{}/karabo.data".format(_get_artifact_comp_dir(self.__class__))
         # we inlne the inport to be able to skip if not installed
         import karabo_data as kd
         rd = kd.RunDirectory(out_folder)
@@ -339,9 +352,11 @@ class CorrectionTestBase:
             
             def test_train_info(train, identifier):
                 
-                self.assertEqual(d[identifier]["sources"], list(train.keys()))
+                self.assertEqual(sorted(d[identifier]["sources"]),
+                                 sorted(list(train.keys())))
                 for source in train.keys():
-                    self.assertEqual(d[identifier][source]["keys"], list(train[source].keys()))
+                    self.assertEqual(sorted(d[identifier][source]["keys"]),
+                                     sorted(list(train[source].keys())))
                     for key in train[source].keys():
                         if key in self.karabo_data_inspects:
                             val = train[source][key]
diff --git a/tests/test_agipd.py b/tests/test_agipd.py
index 88056b218..51c4f7336 100644
--- a/tests/test_agipd.py
+++ b/tests/test_agipd.py
@@ -55,4 +55,4 @@ if __name__ == '__main__':
     ln = lambda f: "generate" not in f
     lncmp = lambda a, b: (ln(a) > ln(b)) - (ln(a) < ln(b))
     loader.sortTestMethodsUsing = lncmp
-    unittest.main(testLoader=loader, verbosity=2)
\ No newline at end of file
+    unittest.main(testLoader=loader, verbosity=3)
\ No newline at end of file
diff --git a/tests/test_lpd.py b/tests/test_lpd.py
new file mode 100644
index 000000000..3740602a8
--- /dev/null
+++ b/tests/test_lpd.py
@@ -0,0 +1,60 @@
+import numpy as np
+import sys
+import unittest
+
+from correction_base import CorrectionTestBase, args
+
+
+np.warnings.filterwarnings('ignore')
+
+
+class TestLPDCorrection(CorrectionTestBase, unittest.TestCase):
+    
+    detector = "LPD"
+    task = "CORRECT"
+    parms = {"in-folder": "/gpfs/exfel/exp/FXE/201831/p900038/raw/",
+             "run": 154,
+             "out-folder": "/gpfs/exfel/data/scratch/haufs/test/",
+             "calfile": "/gpfs/exfel/exp/FXE/201831/p900038/usr/calibration0818/cal_constants2.h5",
+             "sequences": 0}
+    hist_paths = {"INSTRUMENT/(.+)LPD(.+)/DET/[0-9]+CH0:xtdf/image/data": 
+                  {
+                   "broad": {"bins": 10000, "range": (-1e4, 1e6)},
+                   "detail": {"bins": 10000, "range": (-100, 9900)}
+                  },
+                  "INSTRUMENT/(.+)LPD(.+)/DET/[0-9]+CH0:xtdf/image/mask": 
+                  {
+                   "detail": {"bins": 32, "range": (0, 32),
+                              "scl_fun": np.log2}
+                  },
+                  "INSTRUMENT/(.+)LPD(.+)/DET/[0-9]+CH0:xtdf/image/gain": 
+                  {
+                   "detail": {"bins": 3, "range": (0, 3)}
+                  }
+                 }
+    
+    karabo_data_inspects = ['trailer.checksum', 'header.trainId', 'header.reserved',
+                            'image.cellId', 'header.dataId', 'header.linkId',
+                            'detector.data', 'metadata', 'image.length',
+                            'header.magicNumberBegin', 'header.majorTrainFormatVersion',
+                            'trailer.magicNumberEnd', 'image.status', 'image.trainId',
+                            'image.pulseId', 'header.minorTrainFormatVersion',
+                            'header.pulseCount', 'trailer.status', 'detector.trainId',
+                            'trailer.trainId']
+    
+    def _output_to_path(self):
+        opath = self.parms["out-folder"]
+        run = int(self.parms["run"])
+        return "{}/r{:04d}".format(opath, run)
+
+
+
+if __name__ == '__main__':
+    sys.argv[1:] = args.unittest_args
+    
+    loader = unittest.TestLoader()
+    # make sure generators get run first
+    ln = lambda f: "generate" not in f
+    lncmp = lambda a, b: (ln(a) > ln(b)) - (ln(a) < ln(b))
+    loader.sortTestMethodsUsing = lncmp
+    unittest.main(testLoader=loader, verbosity=3)
\ No newline at end of file
-- 
GitLab