Repository: DARMA-tasking/LB-analysis-framework

Issue:
Load subphase data from input files

Discussion:

Patch:
diff --git a/src/lbaf/IO/lbsVTDataReader.py b/src/lbaf/IO/lbsVTDataReader.py
index bd1c7cf..7d3f443 100644
--- a/src/lbaf/IO/lbsVTDataReader.py
+++ b/src/lbaf/IO/lbsVTDataReader.py
@@ -201,11 +201,13 @@ class LoadReader:
                 entity = task.get("entity")
                 task_object_id = entity.get("id")
                 task_used_defined = task.get("user_defined")
+                subphases = task.get("subphases")
 
                 # Update rank if iteration was requested
                 if phase_ids in (phase_id, -1):
                     # Instantiate object with retrieved parameters
-                    obj = Object(task_object_id, task_time, node_id, user_defined=task_used_defined)
+                    obj = Object(task_object_id, task_time, node_id, user_defined=task_used_defined,
+                                 subphases=subphases)
                     # If this iteration was never encountered initialize rank object
                     returned_dict.setdefault(phase_id, Rank(node_id, logger=self.__logger))
                     # Add object to rank given its type
diff --git a/src/lbaf/Model/lbsObject.py b/src/lbaf/Model/lbsObject.py
index b13efbb..b176dc0 100644
--- a/src/lbaf/Model/lbsObject.py
+++ b/src/lbaf/Model/lbsObject.py
@@ -7,7 +7,8 @@ from ..Utils.exception_handler import exc_handler
 class Object:
     """ A class representing an object with time and communicator
     """
-    def __init__(self, i: int, t: float, p: int = None, c: ObjectCommunicator = None, user_defined: dict = None):
+    def __init__(self, i: int, t: float, p: int = None, c: ObjectCommunicator = None, user_defined: dict = None,
+                 subphases: list = None):
         # Object index
         if not isinstance(i, int) or isinstance(i, bool):
             sys.excepthook = exc_handler
@@ -43,6 +44,13 @@ class Object:
             sys.excepthook = exc_handler
             raise TypeError(f"user_defined: {user_defined} is type of {type(user_defined)}! Must be <class 'dict'>!")
 
+        # Sub-phases
+        if isinstance(subphases, list) or subphases is None:
+            self.__subphases = subphases
+        else:
+            sys.excepthook = exc_handler
+            raise TypeError(f"subphases: {subphases} is type of {type(subphases)}! Must be <class 'list'>!")
+
     def __repr__(self):
         return f"Object id: {self.__index}, time: {self.__time}"
 
@@ -102,3 +110,8 @@ class Object:
         # Perform sanity check prior to assignment
         if isinstance(c, ObjectCommunicator):
             self.__communicator = c
+
+    def get_subphases(self) -> list:
+        """ Return subphases of this object
+        """
+        return self.__subphases


Test patch:
diff --git a/tests/test_lbs_object.py b/tests/test_lbs_object.py
index bc47435..bf4af1f 100644
--- a/tests/test_lbs_object.py
+++ b/tests/test_lbs_object.py
@@ -17,7 +17,15 @@ from src.lbaf.Model.lbsObjectCommunicator import ObjectCommunicator
 class TestConfig(unittest.TestCase):
     def setUp(self):
         self.logger = logging.getLogger()
-        self.simple_obj_001 = Object(i=1, t=2.5)
+        self.subphases = [
+            {'id': 0, 'time': 1.3960000018187202e-06}, {'id': 1, 'time': 3.2324999992283665e-05},
+            {'id': 2, 'time': 7.802999995476512e-06}, {'id': 3, 'time': 0.00017973499998902298},
+            {'id': 4, 'time': 4.138999999980797e-05}, {'id': 5, 'time': 0.0002490769999923259},
+            {'id': 6, 'time': 1.6039999977124353e-06}, {'id': 7, 'time': 3.9705999995476304e-05},
+            {'id': 8, 'time': 1.5450000034888944e-06}, {'id': 9, 'time': 5.735999998535135e-06},
+            {'id': 10, 'time': 0.00021168499999646428}, {'id': 11, 'time': 0.0007852130000003399},
+            {'id': 12, 'time': 1.642999997386596e-06}, {'id': 13, 'time': 3.634999998780586e-06}]
+        self.simple_obj_001 = Object(i=1, t=2.5, subphases=self.subphases)
         self.simple_obj_002 = Object(i=2, t=4.5, p=0)
         self.oc = ObjectCommunicator(i=3, logger=self.logger)
         self.simple_obj_003 = Object(i=3, t=3.5, p=2, c=self.oc)
@@ -248,6 +256,10 @@ class TestConfig(unittest.TestCase):
         obj_with_comm = Object(i=23, t=3.5, p=2, c=oc)
         self.assertEqual(obj_with_comm.get_received_volume(), 4.5)
 
+    def test_object_get_subphases(self):
+        self.assertEqual(self.simple_obj_001.get_subphases(), self.subphases)
+        self.assertEqual(self.simple_obj_002.get_subphases(), None)
+
 
 if __name__ == "__main__":
     unittest.main()