Skip to content

Commit

Permalink
Merge pull request #15 from tensionhead/14-ensemble-averaged-wavelet-…
Browse files Browse the repository at this point in the history
…spectrum

14 ensemble averaged wavelet spectrum
  • Loading branch information
tensionhead authored Jan 3, 2023
2 parents a249387 + 7d73a7f commit ad5c7a9
Show file tree
Hide file tree
Showing 11 changed files with 813 additions and 603 deletions.
3 changes: 3 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[flake8]
ignore = E501, E731
extend_ignore = W503, W504
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
**/__pycache__/
**/*__pycache__*
__pycache__
*.pyc
**/.DS_store
.DS_Store
src/.DS_Store
dist/
32 changes: 24 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
#### pyBOAT 0.9.9
### pyBOAT 0.9.10

##### New

- Global wavelet spectrum (ensemble average)
- load and save pyBOAT analysis settings to custom .ini file

##### Changes
- redesigned "Analyze All" batch processing menu
- NaN interpolation: now strips of trailing NaNs before interpolation

##### Fixes
- repaired NaN interpolation, np.nonzero on boolean Series apparently broke
- minor UI tweaks, further anchor warning boxes
- fixed period axis for single time averaged wavelet spectra

### pyBOAT 0.9.9

##### Changes
- the UI dataviewer is not plotting envelope + trend anymore, but only the envelope (see [here](https://github.com/tensionhead/pyBOAT/discussions/13) for details)
Expand All @@ -7,40 +23,40 @@
##### Fixes
- minor UI tweaks, MesageBoxes are anchored to their parent window

#### pyBOAT 0.9.8
### pyBOAT 0.9.8

- Low-level core.sinc_filter had hardcoded max. size of 2000,
removed this such that core.sinc_smooth(..., M=..) can freely
select the filter size again. For the GUI the max. size still
is 2000, otherwise defaults to signal length if this is smaller.


#### pyBOAT 0.9.7
### pyBOAT 0.9.7

- hotfix: data loading via import menu repaired

#### pyBOAT 0.9.6
### pyBOAT 0.9.6

- matplotlib >3.5.1 has a new API for the lines drawn on an axis, made the necessary changes
- improved window closing behavior, 'x' closing the main window should now kill all other open windows
- fixed time-averaged wavelet (Fourier estimate) save routine to also write out the periods
- code formatting via black for all source files

#### pyBOAT 0.9.5
### pyBOAT 0.9.5

- fixed a bunch of additional UI bugs introduced by newer PyQT versions
- New setting 'Data' for specifying default table output format (csv, txt or xslx)

#### pyBOAT 0.9.4
### pyBOAT 0.9.4

- just added the link to the gitter chat to the Help menu
- removed bulky talk pdf

#### pyBOAT 0.9.3
### pyBOAT 0.9.3

- fixed UI bugs concerning ridge smoothing/thresholding and SSG noise strength

#### pyBOAT 0.9.2
### pyBOAT 0.9.2

- Scripting interface for significance tests with empirical backgrounds,
see the new [empirical_backgrounds_demo.py](empirical_backgrounds_demo.py)
Expand Down
2 changes: 1 addition & 1 deletion pyboat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
import argparse

__version__ = "0.9.9"
__version__ = "0.9.10"

# the object oriented API
from .api import WAnalyzer
Expand Down
56 changes: 51 additions & 5 deletions pyboat/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

from pyboat.core import get_COI_branches, find_COI_crossing

# --- define colors ---
# --- Plot Styling ---

rgb_2mpl = lambda R, G, B: np.array((R, G, B)) / 255
rgba_2mpl = lambda R, G, B, A: np.array((R, G, B, A)) / 255

# data viewer
SIG_COLOR = "darkslategray"
TREND_COLOR = rgb_2mpl(165, 105, 189) # orchidy
ENVELOPE_COLOR = "orange"
Expand Down Expand Up @@ -42,7 +44,7 @@
# --- define line widths ---
TREND_LW = 2.0
SIGNAL_LW = 1.5
MARKER_SIZE = 4
MARKER_SIZE = 3

# --- standard sizes ---
label_size = 18
Expand All @@ -52,7 +54,7 @@
# match dimensions of spectrum and signal plots
x_size = 6.5

# --- default styles as dictionaries ---
# default styles as dictionaries
# can be used with ppl.plot(..., **STYLE)

SIGNAL_STYLE = {
Expand Down Expand Up @@ -90,7 +92,7 @@ def get_marker_lw(signal):
return m, lw


# --- Signal and Trend -----------------------------------------------
# --- Plotting Signal and Trend ---


def mk_signal_ax(time_unit="a.u.", fig=None):
Expand Down Expand Up @@ -253,7 +255,6 @@ def averaged_Wspec(averaged_Wspec, periods, time_unit="a.u", fig=None):

# --- Wavelet spectrum ------


def mk_signal_modulus_ax(time_unit="a.u.", height_ratios=[1, 2.5], fig=None):

if fig is None:
Expand All @@ -274,6 +275,20 @@ def mk_signal_modulus_ax(time_unit="a.u.", height_ratios=[1, 2.5], fig=None):
return axs


def mk_modulus_ax(time_unit="a.u.", fig=None):

if fig is None:
fig = ppl.figure(figsize=(x_size, 6.5))
fig.subplots_adjust(bottom=0.07, top=0.97)
ax = fig.subplots()

ax.set_xlabel("Time (" + time_unit + ")", fontsize=label_size)
ax.set_ylabel("Period (" + time_unit + ")", fontsize=label_size)
ax.tick_params(axis="both", labelsize=tick_label_size)

return ax


def plot_signal_modulus(axs, time_vector, signal, modulus, periods, p_max=None):

"""
Expand Down Expand Up @@ -322,6 +337,37 @@ def plot_signal_modulus(axs, time_vector, signal, modulus, periods, p_max=None):
cb.set_label("Wavelet Power", rotation="0", labelpad=-12, fontsize=0.9 * label_size)


def plot_modulus(mod_ax, time_vector, modulus, periods, p_max=None):

"""
Plot the wavelet power spectrum.
"""

# Plot Wavelet Power Spectrum

extent = (time_vector[0], time_vector[-1], periods[0], periods[-1])
im = mod_ax.imshow(
modulus[::-1], cmap=CMAP, vmin=0, vmax=p_max, extent=extent, aspect="auto"
)

mod_ax.set_ylim((periods[0], periods[-1]))
mod_ax.set_xlim((time_vector[0], time_vector[-1]))
mod_ax.grid(axis="y", color="0.6", lw=1.0, alpha=0.5) # vertical grid lines

if p_max is None:
cb_ticks = [0, int(np.floor(modulus.max()))]
else:
cb_ticks = [0, p_max]

cb = ppl.colorbar(
im, ax=mod_ax, orientation="horizontal", fraction=0.08, shrink=0.6, pad=0.15
)
cb.set_ticks(cb_ticks)
cb.ax.set_xticklabels(cb_ticks, fontsize=tick_label_size)
# cb.set_label('$|\mathcal{W}_{\Psi}(t,T)|^2$',rotation = '0',labelpad = 5,fontsize = 15)
cb.set_label("Wavelet Power", rotation="0", labelpad=-12, fontsize=0.9 * label_size)


def draw_Wavelet_ridge(ax, ridge_data, marker_size=1.5):

"""
Expand Down
14 changes: 9 additions & 5 deletions pyboat/ui/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ def initUI(self, position):

# Start ridge detection
maxRidgeButton = QPushButton("Detect Maximum Ridge", self)
maxRidgeButton.setStatusTip("Finds the time-consecutive power maxima")
maxRidgeButton.setStatusTip("Traces the time-consecutive power maxima")
maxRidgeButton.setStyleSheet("background-color: lightblue")

maxRidgeButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
maxRidgeButton.clicked.connect(self.do_maxRidge_detection)
Expand Down Expand Up @@ -566,7 +567,7 @@ def ini_plot_readout(self):

def ini_average_spec(self):

self.avWspecWindow = AveragedWaveletWindow(self.modulus, parent=self)
self.avWspecWindow = AveragedWaveletWindow(parent=self)


class mkWaveletCanvas(FigureCanvas):
Expand Down Expand Up @@ -730,15 +731,17 @@ def __init__(self):


class AveragedWaveletWindow(QMainWindow):
def __init__(self, modulus, parent):
# `parent` is a `WaveletAnalyzer` instance
def __init__(self, parent):

super().__init__(parent=parent)

# --- calculate time averaged power spectrum <-> Fourier estimate ---
self.avWspec = np.sum(modulus, axis=1) / modulus.shape[1]
self.avWspec = np.sum(parent.modulus, axis=1) / parent.modulus.shape[1]
# -------------------------------------------------------------------

# the Wavelet analysis window spawning *this* Widget
self.parentWA = parent
self.parentWA = parent
self.DEBUG = parent.DEBUG
self.initUI()

Expand Down Expand Up @@ -785,6 +788,7 @@ def initUI(self):
def save_out(self):

df_out = pd.DataFrame(data=self.avWspec, columns=["power"])
df_out.index = self.parentWA.periods
df_out.index.name = "periods"

dialog = QFileDialog()
Expand Down
Loading

0 comments on commit ad5c7a9

Please sign in to comment.