From b8136331c1e55c9066fbd1a2147784329a19fc97 Mon Sep 17 00:00:00 2001
From: Tamas Gal <tgal@km3net.de>
Date: Tue, 24 Mar 2020 10:49:04 +0100
Subject: [PATCH] Simplify header

---
 km3io/offline.py      | 20 +++++++++---------
 tests/test_offline.py | 47 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/km3io/offline.py b/km3io/offline.py
index 6afaa9e..97140d3 100644
--- a/km3io/offline.py
+++ b/km3io/offline.py
@@ -226,23 +226,25 @@ class Header:
     """The header"""
     def __init__(self, header):
         self._data = {}
-        self._missing_keys = set(header.keys()) - set(mc_header.keys())
 
-        for attribute, fields in mc_header.items():
-            values = header.get(attribute, '').split()
+        for attribute, fields in header.items():
+            values = fields.split()
+            fields = mc_header.get(attribute, [])
+
+            n_values = len(values)
+            n_fields = len(fields)
+            n_max = max(n_values, n_fields)
+            values += [None] * (n_max - n_values)
+            fields += ["field_{}".format(i) for i in range(n_fields, n_max)]
+
             if not values:
                 continue
+
             Constructor = namedtuple(attribute, fields)
-            if len(values) < len(fields):
-                values += [None] * (len(fields) - len(values))
             self._data[attribute] = Constructor(
                 **{f: _to_num(v)
                    for (f, v) in zip(fields, values)})
 
-        # quick fix while waiting for additional definitions in mc_header
-        for key in self._missing_keys:
-            self._data[key] = _to_num(header[key])
-
         for attribute, value in self._data.items():
             setattr(self, attribute, value)
 
diff --git a/tests/test_offline.py b/tests/test_offline.py
index c4c176a..9143c87 100644
--- a/tests/test_offline.py
+++ b/tests/test_offline.py
@@ -36,18 +36,55 @@ class TestHeader(unittest.TestCase):
         with self.assertWarns(UserWarning):
             OFFLINE_FILE.header
 
-    def test_header_wrapper(self):
+    def test_header(self):
         head = {
             'DAQ': '394',
             'PDF': '4',
-            'XSecFile': '',
-            'can': '0 1027 888.4'
+            'can': '0 1027 888.4',
+            'undefined': '1 2 test 3.4'
         }
 
         header = Header(head)
 
-        self.assertEqual(len(header._data), len(head))
-        self.assertIsNone(header._data["PDF"].i2)
+        assert 394 == header.DAQ.livetime
+        assert 4 == header.PDF.i1
+        assert header.PDF.i2 is None
+        assert 0 == header.can.zmin
+        assert 1027 == header.can.zmax
+        assert 888.4 == header.can.r
+        assert 1 == header.undefined.field_0
+        assert 2 == header.undefined.field_1
+        assert "test" == header.undefined.field_2
+        assert 3.4 == header.undefined.field_3
+
+    def test_missing_key_definitions(self):
+        head = {'a': '1 2 3', 'b': '4'}
+
+        header = Header(head)
+
+        assert 1 == header.a.field_0
+        assert 2 == header.a.field_1
+        assert 3 == header.a.field_2
+        assert 4 == header.b.field_0
+
+    def test_missing_values(self):
+        head = {'can': '1'}
+
+        header = Header(head)
+
+        assert 1 == header.can.zmin
+        assert header.can.zmax is None
+        assert header.can.r is None
+
+    def test_additional_values_compared_to_definition(self):
+        head = {'can': '1 2 3 4'}
+
+        header = Header(head)
+
+        assert 1 == header.can.zmin
+        assert 2 == header.can.zmax
+        assert 3 == header.can.r
+        assert 4 == header.can.field_3
 
 
 class TestOfflineEvents(unittest.TestCase):
-- 
GitLab