From c17de26bd3485c0b3b920b2977f3acf203e51c1b Mon Sep 17 00:00:00 2001
From: Olivier Jossoud <olivier.jossoud@lsce.ipsl.fr>
Date: Fri, 6 Dec 2019 16:09:06 +0100
Subject: [PATCH] Explo. Add layer in explo provider for timeseries
 pre-processing.

---
 src/dataprovider/exploprovider.py | 107 ++++++++++++------------------
 src/uim/explouim.py               |   8 ++-
 2 files changed, 46 insertions(+), 69 deletions(-)

diff --git a/src/dataprovider/exploprovider.py b/src/dataprovider/exploprovider.py
index 22b550d..375a67b 100644
--- a/src/dataprovider/exploprovider.py
+++ b/src/dataprovider/exploprovider.py
@@ -4,6 +4,7 @@ import re
 import xml.etree.cElementTree as ET
 from io import StringIO
 from cfatools.logreader.dataset import DatasetReader
+from cfatools.processor import iceblock
 
 
 class ExploProvider:
@@ -49,6 +50,46 @@ class ExploProvider:
 
         return self.dataset_readers
 
+    ####################################################################################################################
+    # Get instrument's variables and timeseries
+    # -----------------------------------------
+    # The cfatools' DatasetReader class provides access to raw instrument's log data, which is not always adapted to
+    # what the user needs to see.
+    # So for common cases, just return raw data from DatasetReader, but if required for a specific instrument log, these
+    # data can be modified before being served to the GUI. Just add a get_XXXXX_yyyyy_instrument_variables() and a
+    # get_XXXXX_yyyyy_timeseries() function.
+
+    # Default: directly return data from DatasetReader with no post-treatment.
+    def get_instrument_variables(self, dataset: DatasetReader, instrument_name: str) -> list:
+        try:
+            custom_func = getattr(self, "get_" + instrument_name + "_instrument_variables")
+            variables = custom_func(dataset)
+        except AttributeError:
+            variables = dataset.get_instrument_variables(instrument_name)
+
+        return variables
+
+    def get_timeseries(self, dataset: DatasetReader, instrument_name: str, variable: str) -> pd.DataFrame:
+        try:
+            custom_func = getattr(self, "get_" + instrument_name + "_timeseries")
+            timeseries_df = custom_func(dataset, variable)
+        except AttributeError:
+            timeseries_df = dataset.get_timeseries(instrument_name, variable)
+
+        return timeseries_df
+
+    # ##### ICBKCTRL_instant ##### #
+    def get_ICBKCTRL_instant_instrument_variables(self, dataset: DatasetReader) -> list:
+        return ["melting"]
+
+    def get_ICBKCTRL_instant_timeseries(self, dataset: DatasetReader, variable: str) -> pd.DataFrame:
+        raw_df = dataset.get_timeseries("ICBKCTRL_instant")
+        timeseries = iceblock.get_melting_timeseries(raw_df)
+        return timeseries
+
+    ####################################################################################################################
+    # SAVED_SETUPS
+
     def save_setup(self, dataset_reader: DatasetReader,
                    setup_name: str, variable_df: pd.DataFrame, view_range: list) -> None:
         saved_setup_dir = dataset_reader.dataset_path + self.saved_setup_subdir
@@ -130,69 +171,3 @@ class ExploProvider:
 
         files_without_ext = [os.path.splitext(filename)[0] for filename in filenames]
         return files_without_ext
-
-
-class InstrumentLog:
-
-    def __init__(self, full_directory_name: str, filename: str, instrument_name: str):
-        self.full_directory_name = full_directory_name
-        self.filename = filename
-        self.full_file_name = full_directory_name + "/" + filename
-        self.instrument_name = instrument_name
-
-        self.df = self.__get_df__()
-
-    def get_variables(self):
-        raise NotImplementedError("Subclasses should implement this.")
-
-    def get_timeseries(self, variable: str) -> pd.DataFrame:
-        raise NotImplementedError("Subclasses should implement this.")
-
-    def __get_df__(self) -> pd.DataFrame:
-        raise NotImplementedError("Subclasses should implement this.")
-
-class IceblockInstantLog(InstrumentLog):
-    # TODO: Transfer these functions to cfatools package
-
-    def __init__(self, full_directory_name: str, filename: str, instrument_name: str):
-        InstrumentLog.__init__(self, full_directory_name, filename, instrument_name)
-
-    def __get_df__(self) -> pd.DataFrame:
-        df = pd.read_csv(self.full_file_name, sep=",", parse_dates=["datetime"])
-        return df
-
-    def get_variables(self):
-        return ["melting"]
-
-    def get_timeseries(self, variable: str) -> pd.DataFrame:
-        if variable == "melting":
-            timeseries_df = self.__get_melting_timeseries__()
-        else:
-            raise ValueError("Variable name [" + variable + "] not yet managed.")
-
-        return timeseries_df
-
-    def __get_melting_timeseries__(self) -> pd.DataFrame:
-        # Get the mapping between iceblock id and iceblock name (assuming that the last name's modification is the
-        # good one.
-        mapping_df = self.df[["datetime", "id", "name"]].copy()
-        mapping_df = mapping_df.groupby("id")["id", "name"].tail(1)
-        mapping_df = mapping_df.append({"id": 0, "name": "None"}, ignore_index=True)
-        mapping_df = mapping_df.set_index("id")
-        mapping_dict = mapping_df["name"].to_dict()
-
-        # Get the datetime of the beginning of each iceblock's melting
-        melting_df = self.df[["datetime", "id", "status"]].copy()
-        start_df = melting_df[melting_df["status"] == "Melting"].groupby("id")["datetime", "id"].head(1)
-
-        # Get the end of the last iceblock's melting, and set that after that the current melting block is 0/None.
-        end_df = melting_df[melting_df["status"] == "Done"].groupby("id").head(1)
-        melting_df = start_df.append({"datetime": end_df.iloc[-1]["datetime"], "id": 0},
-                                     ignore_index=True)
-
-        # Get the value (iceblocks name) and value_int (coded value, iceblock id in this case).
-        melting_df.rename(columns={"id": 'value_int'}, inplace=True)
-        melting_df["value"] = melting_df["value_int"].map(mapping_dict)
-
-        return melting_df
-
diff --git a/src/uim/explouim.py b/src/uim/explouim.py
index 5728928..9ba227a 100644
--- a/src/uim/explouim.py
+++ b/src/uim/explouim.py
@@ -13,7 +13,7 @@ from config import Config
 from dataprovider.exploprovider import ExploProvider
 from gui.uimainwindow import Ui_MainWindow
 from gui.stabwindow import StabWindow
-
+from cfatools.processor import iceblock
 
 
 class ExploUim:
@@ -213,7 +213,9 @@ class ExploUim:
             return
         variables_combobox.clear()
         instrument_name = combobox_text
-        variable_names = self.current_dataset.get_instrument_variables(instrument_name)
+
+        variable_names = self.explo_prvd.get_instrument_variables(self.current_dataset, instrument_name)
+
         for variable_name in variable_names:
             variables_combobox.addItem(variable_name)
 
@@ -232,7 +234,7 @@ class ExploUim:
         instrument_name = table.cellWidget(row_id, self.INSTRUMENT_COL).currentText()
         variable_name = table.cellWidget(row_id, self.VARIABLE_COL).currentText()
 
-        timeseries = self.current_dataset.get_timeseries(instrument_name, variable_name)
+        timeseries = self.explo_prvd.get_timeseries(self.current_dataset, instrument_name, variable_name)
 
         return timeseries
 
-- 
GitLab