From da5ef4ed38c10b7197ec9b95c54c575093e7b58a Mon Sep 17 00:00:00 2001
From: ahmedk <karim.ahmed@xfel.eu>
Date: Tue, 4 Jul 2023 16:04:29 +0200
Subject: [PATCH] replace with new function
 display_markdown_retrieved_constants()

---
 ...Jungfrau_Gain_Correct_and_Verify_NBC.ipynb |  2 +-
 .../ePix100/Correction_ePix100_NBC.ipynb      |  4 +-
 notebooks/pnCCD/Correct_pnCCD_NBC.ipynb       |  4 +-
 src/cal_tools/calcat_interface.py             | 89 +++++++++++++------
 4 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/notebooks/Jungfrau/Jungfrau_Gain_Correct_and_Verify_NBC.ipynb b/notebooks/Jungfrau/Jungfrau_Gain_Correct_and_Verify_NBC.ipynb
index ebb0d15f3..7b1508799 100644
--- a/notebooks/Jungfrau/Jungfrau_Gain_Correct_and_Verify_NBC.ipynb
+++ b/notebooks/Jungfrau/Jungfrau_Gain_Correct_and_Verify_NBC.ipynb
@@ -207,7 +207,7 @@
     "\n",
     "jf_metadata = jf_cal.metadata(calibrations=constant_names)\n",
     "# Display retrieved calibration constants timestamps\n",
-    "display(Markdown(jf_cal.calibrations_timestamps_markdown(metadata=jf_metadata)))"
+    "jf_cal.display_markdown_retrieved_constants(metadata=jf_metadata)"
    ]
   },
   {
diff --git a/notebooks/ePix100/Correction_ePix100_NBC.ipynb b/notebooks/ePix100/Correction_ePix100_NBC.ipynb
index ae7f91d9e..515837397 100644
--- a/notebooks/ePix100/Correction_ePix100_NBC.ipynb
+++ b/notebooks/ePix100/Correction_ePix100_NBC.ipynb
@@ -280,10 +280,8 @@
     "    client=rest_cfg.calibration_client(),\n",
     ")\n",
     "const_metadata = epix_cal.metadata(calibrations=constant_names)\n",
-    "\n",
     "# Display retrieved calibration constants timestamps\n",
-    "display(Markdown(epix_cal.calibrations_timestamps_markdown(metadata=const_metadata)))\n",
-    "\n",
+    "epix_cal.display_markdown_retrieved_constants(metadata=const_metadata)\n",
     "# Load the constant data from files\n",
     "const_data = epix_cal.ndarray_map(metadata=const_metadata)[karabo_da]\n",
     "\n",
diff --git a/notebooks/pnCCD/Correct_pnCCD_NBC.ipynb b/notebooks/pnCCD/Correct_pnCCD_NBC.ipynb
index f8faf8b71..edbada307 100644
--- a/notebooks/pnCCD/Correct_pnCCD_NBC.ipynb
+++ b/notebooks/pnCCD/Correct_pnCCD_NBC.ipynb
@@ -343,7 +343,9 @@
     "        corr_bools['relgain'] = False\n",
     "\n",
     "# Display retrieved calibration constants timestamps\n",
-    "display(Markdown(pnccd_cal.calibrations_timestamps_markdown(metadata=pnccd_metadata)))\n",
+    "pnccd_cal.display_markdown_retrieved_constants(metadata=pnccd_metadata)\n",
+    "\n",
+    "# display(Markdown(pnccd_cal.report_retrieved_constants_timestamps(metadata=pnccd_metadata)))\n",
     "\n",
     "metadata = pnccd_metadata[karabo_da]\n",
     "\n",
diff --git a/src/cal_tools/calcat_interface.py b/src/cal_tools/calcat_interface.py
index e812c2695..cc62c9977 100644
--- a/src/cal_tools/calcat_interface.py
+++ b/src/cal_tools/calcat_interface.py
@@ -14,6 +14,8 @@ from calibration_client.modules import (
     Parameter,
     PhysicalDetectorUnit,
 )
+from IPython.display import Markdown, display
+from tabulate import tabulate
 
 from cal_tools.tools import module_index_to_qm
 
@@ -692,39 +694,76 @@ class CalibrationData:
 
         return self.load_constants_from_metadata(metadata)
 
-    def calibrations_timestamps_markdown(
+    def display_markdown_retrieved_constants(
         self,
         metadata=None,
-        ccvs_url = "https://in.xfel.eu/calibration/calibration_constant_versions/",  # noqa
-        ):
-        """Return Markdown text for all detector modules
-        and their retrieved constants creation time
-        with a reference link to the CCV CalCat urls.
+        ccvs_url="https://in.xfel.eu/calibration/calibration_constant_versions/"  # noqa
+    ):
+        """
+        Display markdown table with reference links for the
+        retrieved constants. Tables are split into groups of a
+        maximum of 4 modules.
 
         Args:
-            metadata (CCVMetadata):
-                The detector CCV metadata object with all retrieved
-                constants metadata. If metadata is None. Metadata for
-                all calibrations and latest snapshot_at and event_at are used.
-            ccvs_url (Str): The calibration constant version CalCat url.
-        Returns:
-            (Str): markdown text that can be displayed properly using
-                `from IPython.display import Markdown, display`.
+            metadata (dict, optional): Metadata for calibration constants.
+                Defaults to None.
+            ccvs_url (str, optional): URL for calibration constant versions.
+                Defaults to
+                "https://in.xfel.eu/calibration/calibration_constant_versions/".
         """
-        markdown_text = ""
+
+        def remove_timezone_seconds(timestamp):
+            """Remove timezone and seconds.
+
+            Args:
+                timestamp (str): isoformat timestamp string.
+
+            Returns:
+                str: timestamp after remove the timezone and seconds.
+            """
+            # Parse the datetime and remove timezone and seconds.
+            dt = datetime.fromisoformat(timestamp).replace(
+                tzinfo=None, second=0, microsecond=0)
+            return dt.strftime("%Y-%m-%d %H:%M")
+
         mod_to_pdu = self.mod_to_pdu
+
         if metadata is None:
             metadata = self.metadata()
-        for mod, mod_md in metadata.items():
-            # Add module name.
-            markdown_text += f"{mod}({mod_to_pdu[mod]}):<br />"
-            # Add calibration constant name with link to CalCat
-            # and add creation time.
-            for cname, c_mdata in mod_md.items():
-                markdown_text += (
-                    f"- [{cname}]({ccvs_url}/{c_mdata['ccv_id']}): "
-                    f"{c_mdata['begin_validity_at']}<br />")
-        return markdown_text
+        num_groups = max(len(mod_to_pdu) // 4, 1)
+
+        for g in range(num_groups):
+            group_modules = list(mod_to_pdu)[4*g:4*(g+1)]
+            table = [["Constants"] + group_modules]
+
+            # Loop over calibrations and modules to form the next rows.
+            for cname in self.calibrations:
+                constants = []
+
+                for mod in group_modules:
+                    c_mdata = metadata[mod].get(cname)
+                    # A calibration that is not available in given metadata.
+                    if c_mdata is None:
+                        continue
+                    else:
+                        # Have the creation time a reference
+                        # link to the CCV on CALCAT.
+                        constants.append(
+                            f"[{remove_timezone_seconds(c_mdata['begin_validity_at'])}]"  # noqa
+                            f"({ccvs_url}/{c_mdata['ccv_id']})")
+
+                if any(constants):
+                    table.append([cname] + constants)
+
+            display(
+                Markdown(
+                    tabulate(
+                        table,
+                        tablefmt="pipe",
+                        headers="firstrow",
+                        )
+                    )
+                )
 
     def _build_condition(self, parameters):
         cond = dict()
-- 
GitLab