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