diff --git a/mlair/data_handler/data_handler_with_filter.py b/mlair/data_handler/data_handler_with_filter.py index 67902cd0eae0c6698021baef4ea066ff850ba01a..7be76082445f71381e6a609537eda9c0cf9efb28 100644 --- a/mlair/data_handler/data_handler_with_filter.py +++ b/mlair/data_handler/data_handler_with_filter.py @@ -301,12 +301,13 @@ class DataHandlerClimateFirFilterSingleStation(DataHandlerFirFilterSingleStation _hash = DataHandlerFirFilterSingleStation._hash + ["apriori_type", "apriori_sel_opts"] _store_attributes = DataHandlerFirFilterSingleStation.store_attributes() + ["apriori"] - def __init__(self, *args, apriori=None, apriori_type=None, apriori_sel_opts=None, **kwargs): + def __init__(self, *args, apriori=None, apriori_type=None, apriori_sel_opts=None, plot_path=None, **kwargs): self.apriori_type = apriori_type self.climate_filter_coeff = None # coefficents of the used FIR filter self.apriori = apriori # exogenous apriori information or None to calculate from data (endogenous) self.all_apriori = None # collection of all apriori information self.apriori_sel_opts = apriori_sel_opts # ensure to separate exogenous and endogenous information + self.plot_path = plot_path # use this path to create insight plots super().__init__(*args, **kwargs) @TimeTrackingWrapper @@ -316,7 +317,7 @@ class DataHandlerClimateFirFilterSingleStation(DataHandlerFirFilterSingleStation climate_filter = ClimateFIRFilter(self.input_data, self.fs, self.filter_order, self.filter_cutoff_freq, self.filter_window_type, time_dim=self.time_dim, var_dim=self.target_dim, apriori_type=self.apriori_type, apriori=self.apriori, - sel_opts=self.apriori_sel_opts) + sel_opts=self.apriori_sel_opts, plot_path=self.plot_path, plot_name=str(self)) self.climate_filter_coeff = climate_filter.filter_coefficients # store apriori information: store all if residuum_stat method was used, otherwise just store initial apriori diff --git a/mlair/helpers/filter.py b/mlair/helpers/filter.py index 4fce4f50f106ea4ec11f74724ba6089f80955c3e..5b521f7d8aeb56f781ab0a00387f6025e93c2af2 100644 --- a/mlair/helpers/filter.py +++ b/mlair/helpers/filter.py @@ -2,6 +2,7 @@ import gc import warnings from typing import Union import logging +import os import datetime import numpy as np @@ -54,7 +55,7 @@ class FIRFilter: class ClimateFIRFilter: def __init__(self, data, fs, order, cutoff, window, time_dim, var_dim, apriori=None, apriori_type=None, - sel_opts=None): + sel_opts=None, plot_path=None, plot_name=None): """ :param data: data to filter :param fs: sampling frequency in 1/days -> 1d: fs=1 -> 1H: fs=24 @@ -69,6 +70,8 @@ class ClimateFIRFilter: the residuum either the value zero is used (apriori_type is None or "zeros") or a climatology on the residua is used ("residuum_stats"). """ + self.plot_path = plot_path + self.plot_name = plot_name filtered = [] h = [] sel_opts = sel_opts if isinstance(sel_opts, dict) else {time_dim: sel_opts} @@ -81,7 +84,7 @@ class ClimateFIRFilter: # calculate climatological filter fi, hi, apriori = self.clim_filter(input_data, fs, cutoff[i], order[i], apriori=apriori_list[i], sel_opts=sel_opts, sampling=sampling, time_dim=time_dim, window=window, - var_dim=var_dim) + var_dim=var_dim, plot_index=i) filtered.append(fi) h.append(hi) @@ -194,7 +197,7 @@ class ClimateFIRFilter: return apriori def clim_filter(self, data, fs, cutoff_high, order, apriori=None, padlen=None, sel_opts=None, sampling="1d", - time_dim="datetime", var_dim="variables", window="hamming"): + time_dim="datetime", var_dim="variables", window="hamming", plot_index=None): # calculate apriori information from data if not given and extend its range if not sufficient long enough if apriori is None: @@ -226,16 +229,28 @@ class ClimateFIRFilter: tmp_filter, _ = fir_filter(tmp_comb, fs, cutoff_high=cutoff_high, order=order, causal=False, padlen=_padlen, dim=var_dim, window=window, h=h) res.loc[{time_dim: t0}] = tmp_filter.loc[{time_dim: t0}] + if i == 720 and self.plot_path is not None: + self.plot(data, tmp_comb, var_dim, time_dim, slice(dt[i_m], dt[i_p + 1]), t0, plot_index) except IndexError: res.loc[{time_dim: t0}] = np.nan - # if i == 720: - # for var in data.coords[var_dim]: - # data.sel({var_dim: var, time_dim: slice(dt[i_m], dt[i_p+1])}).plot() - # tmp_comb.sel({var_dim: var}).plot() - # plt.title(var) - # plt.show() return res, h, apriori + def plot(self, data, tmp_comb, var_dim, time_dim, time_dim_slice, t0, plot_index): + try: + plot_folder = os.path.join(os.path.abspath(self.plot_path), "climFIR") + if not os.path.exists(plot_folder): + os.makedirs(plot_folder) + for var in data.coords[var_dim]: + data.sel({var_dim: var, time_dim: time_dim_slice}).plot() + tmp_comb.sel({var_dim: var}).plot() + plt.axvline(t0, color="lightgrey") + plt.title(str(var.values)) + plot_name = os.path.join(plot_folder, f"climFIR_{self.plot_name}_{str(var.values)}_{plot_index}.pdf") + plt.savefig(plot_name, dpi=300) + plt.close('all') + except: + pass + @property def filter_coefficients(self): return self._h