Skip to content
Snippets Groups Projects
Commit be60dba2 authored by leufen1's avatar leufen1
Browse files

climFIR data handler can create a sample plot if a path is provided.

parent 3bf973c8
No related branches found
No related tags found
5 merge requests!319add all changes of dev into release v1.4.0 branch,!318Resolve "release v1.4.0",!317enabled window_lead_time=1,!295Resolve "data handler FIR filter",!259Draft: Resolve "WRF-Datahandler should inherit from SingleStationDatahandler"
Pipeline #67032 passed
...@@ -301,12 +301,13 @@ class DataHandlerClimateFirFilterSingleStation(DataHandlerFirFilterSingleStation ...@@ -301,12 +301,13 @@ class DataHandlerClimateFirFilterSingleStation(DataHandlerFirFilterSingleStation
_hash = DataHandlerFirFilterSingleStation._hash + ["apriori_type", "apriori_sel_opts"] _hash = DataHandlerFirFilterSingleStation._hash + ["apriori_type", "apriori_sel_opts"]
_store_attributes = DataHandlerFirFilterSingleStation.store_attributes() + ["apriori"] _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.apriori_type = apriori_type
self.climate_filter_coeff = None # coefficents of the used FIR filter 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.apriori = apriori # exogenous apriori information or None to calculate from data (endogenous)
self.all_apriori = None # collection of all apriori information self.all_apriori = None # collection of all apriori information
self.apriori_sel_opts = apriori_sel_opts # ensure to separate exogenous and endogenous 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) super().__init__(*args, **kwargs)
@TimeTrackingWrapper @TimeTrackingWrapper
...@@ -316,7 +317,7 @@ class DataHandlerClimateFirFilterSingleStation(DataHandlerFirFilterSingleStation ...@@ -316,7 +317,7 @@ class DataHandlerClimateFirFilterSingleStation(DataHandlerFirFilterSingleStation
climate_filter = ClimateFIRFilter(self.input_data, self.fs, self.filter_order, self.filter_cutoff_freq, 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, self.filter_window_type, time_dim=self.time_dim, var_dim=self.target_dim,
apriori_type=self.apriori_type, apriori=self.apriori, 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 self.climate_filter_coeff = climate_filter.filter_coefficients
# store apriori information: store all if residuum_stat method was used, otherwise just store initial apriori # store apriori information: store all if residuum_stat method was used, otherwise just store initial apriori
......
...@@ -2,6 +2,7 @@ import gc ...@@ -2,6 +2,7 @@ import gc
import warnings import warnings
from typing import Union from typing import Union
import logging import logging
import os
import datetime import datetime
import numpy as np import numpy as np
...@@ -54,7 +55,7 @@ class FIRFilter: ...@@ -54,7 +55,7 @@ class FIRFilter:
class ClimateFIRFilter: class ClimateFIRFilter:
def __init__(self, data, fs, order, cutoff, window, time_dim, var_dim, apriori=None, apriori_type=None, 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 data: data to filter
:param fs: sampling frequency in 1/days -> 1d: fs=1 -> 1H: fs=24 :param fs: sampling frequency in 1/days -> 1d: fs=1 -> 1H: fs=24
...@@ -69,6 +70,8 @@ class ClimateFIRFilter: ...@@ -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 the residuum either the value zero is used (apriori_type is None or "zeros") or a climatology on the
residua is used ("residuum_stats"). residua is used ("residuum_stats").
""" """
self.plot_path = plot_path
self.plot_name = plot_name
filtered = [] filtered = []
h = [] h = []
sel_opts = sel_opts if isinstance(sel_opts, dict) else {time_dim: sel_opts} sel_opts = sel_opts if isinstance(sel_opts, dict) else {time_dim: sel_opts}
...@@ -81,7 +84,7 @@ class ClimateFIRFilter: ...@@ -81,7 +84,7 @@ class ClimateFIRFilter:
# calculate climatological filter # calculate climatological filter
fi, hi, apriori = self.clim_filter(input_data, fs, cutoff[i], order[i], apriori=apriori_list[i], 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, 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) filtered.append(fi)
h.append(hi) h.append(hi)
...@@ -194,7 +197,7 @@ class ClimateFIRFilter: ...@@ -194,7 +197,7 @@ class ClimateFIRFilter:
return apriori return apriori
def clim_filter(self, data, fs, cutoff_high, order, apriori=None, padlen=None, sel_opts=None, sampling="1d", 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 # calculate apriori information from data if not given and extend its range if not sufficient long enough
if apriori is None: if apriori is None:
...@@ -226,16 +229,28 @@ class ClimateFIRFilter: ...@@ -226,16 +229,28 @@ class ClimateFIRFilter:
tmp_filter, _ = fir_filter(tmp_comb, fs, cutoff_high=cutoff_high, order=order, causal=False, tmp_filter, _ = fir_filter(tmp_comb, fs, cutoff_high=cutoff_high, order=order, causal=False,
padlen=_padlen, dim=var_dim, window=window, h=h) padlen=_padlen, dim=var_dim, window=window, h=h)
res.loc[{time_dim: t0}] = tmp_filter.loc[{time_dim: t0}] 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: except IndexError:
res.loc[{time_dim: t0}] = np.nan 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 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 @property
def filter_coefficients(self): def filter_coefficients(self):
return self._h return self._h
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment