Commit a977f606 authored by Gregor Moenke's avatar Gregor Moenke

Merge branch 'master' into 'develop'

Update from Master

See merge request !35
parents cf0ab135 e6bab163
### pyBOAT 0.8.17
#### Version 0.8.16
- Fixed crashes during batch analysis with thresholded ridges
- Warning and on-the-fly interpolation of non-contiguous missing values (NaNs)
### pyBOAT 0.8.16
- added the pyBOAT icon
- changed version numbering scheme
#### Version 0.8.1.5
### pyBOAT 0.8.1.5
- fixed Fourier spectra crash
- changed plotting style for short signals
### Version 0.8.1
### pyBOAT 0.8.1
- fixed COI on thresholded ridge
- improved summary statistics
### Version 0.8
### pyBOAT 0.8
- added batch processing menu
- summary statistics: time-averaged power and ensemble dynamics
### Version 0.7.6.1
### pyBOAT 0.7.6.1
- reworked the SSG, catching missing parameter crashes
### Version 0.7.6
### pyBOAT 0.7.6
- Added general data import options with optional missing value interpolation
- Added NaN interpolation to the core module
### Version 0.7.5
### pyBOAT 0.7.5
- Synthetic Signal Generator, yeah!
### Version 0.7.4
### pyBOAT 0.7.4
- Amplitude envelope estimation and removal
......
......@@ -22,14 +22,14 @@ Questions, comments etc. please to <gregor.moenke@embl.de>.
pyBOAT is written in Python and therefore requires Python to be present
on the system.
An easy way to install a cross-platform scientfic Python
environment is to use the freely availabe [Anaconda](https://www.anaconda.com/products/individual).
environment is to use the freely availabe [Anaconda Distribution](https://www.anaconda.com/products/individual).
Installation instructions can be found here: https://docs.anaconda.com/anaconda/install/,
a Python 3.x version is needed.
Once the Anaconda installation is complete, starting up the ```Anaconda Navigator```
will show an interface like this:
<img src="./doc/navigator_install.png" alt="drawing" width="800"/>
<img src="./doc/navigator_install.png" alt="drawing" width="750"/>
First clicking on ```Channels``` and then on ```Add...``` will open an input field.
Type ```conda-forge``` into it and
......@@ -37,7 +37,7 @@ confirm with the &#9166; enter key. Now after hitting ```Update channels```, the
community packages hosted on the ```conda-forge``` channel will become available. As pyBOAT
is also a Navigator App, it will now (along with other apps) show up in the main Navigator window:
<img src="./doc/navigator_install2.png" alt="drawing" width="800"/>
<img src="./doc/navigator_install2.png" alt="drawing" width="600"/>
Finally hitting ```Install``` will download and install pyBOAT. Thereafter,
pyBOAT can be started by simply clicking on ```Launch``` inside the Navigator.
......@@ -45,9 +45,12 @@ pyBOAT can be started by simply clicking on ```Launch``` inside the Navigator.
#### Updates
In case you see a little blue arrow next to the version number, this means
an update is available. Clicking on that cogwheel icon in the upper right corner
an update is available. Clicking on the cogwheel icon in the upper right corner
allows to run the update and install the latest version of pyBOAT.
<img src="./doc/navigator_update.png" alt="drawing" width="400"/>
#### Installation with Anaconda on the commandline ####
For this, the download and installation of [miniconda](https://docs.conda.io/en/latest/miniconda.html)
......
......@@ -3,7 +3,7 @@
import sys,os
import argparse
__version__ = '0.8.16'
__version__ = '0.8.17'
# the object oriented API
from .api import WAnalyzer
......
......@@ -343,7 +343,14 @@ class WAnalyzer:
def get_averaged_spectrum(self):
""" Average over time """
"""
Average Wavelet spectrum over time.
Returns
-------
mfourier : Fourier spectrum estimate
"""
if not self._has_spec:
print("Need to compute a wavelet spectrum first!")
......
......@@ -38,6 +38,7 @@ def average_power_distribution(ridge_results, signal_ids = None, exclude_coi = F
'''
powers = []
ids = []
if signal_ids is None:
signal_ids = np.arange( len(ridge_results) )
......@@ -45,17 +46,21 @@ def average_power_distribution(ridge_results, signal_ids = None, exclude_coi = F
assert len(signal_ids) == len(ridge_results)
# collect the time-averaged powers
for rd in ridge_results:
for rd,_id in zip(ridge_results, signal_ids):
if exclude_coi:
# take only ridge power outside of COI
i_left, i_right = find_COI_crossing(rd)
mpower= (rd.power[i_left : i_right]).mean()
mpower= (rd.power[i_left : i_right]).mean()
else:
mpower= rd.power.mean()
powers.append( mpower )
# can happen if ridge exclusively inside COI
if not np.isnan(mpower):
powers.append( mpower )
ids.append(_id)
powers_series = pd.Series(index = signal_ids, data = powers)
powers_series = pd.Series(index = ids, data = powers)
# sort by power, descending
powers_series.sort_values(
......
''' This module provides all visualizations, both for the ui and the API '''
import matplotlib.pyplot as ppl
import numpy as np
from numpy import pi
......@@ -102,7 +104,6 @@ def draw_envelope(ax, time_vector, envelope):
ax.plot(time_vector, envelope, color=ENVELOPE_COLOR,
alpha=0.8, lw=TREND_LW, label="envelope")
def draw_detrended(ax, time_vector, detrended):
m, lw = get_marker_lw(detrended)
......@@ -543,7 +544,7 @@ def plot_ensemble_dynamics(
powers : DataFrame containing the 'median' and the
two quartiles 'Q1' and 'Q3' over time
phases : DataFrame containing 'R'
phases : DataFrame containing 1st order parameter 'R'
dt : float, the sampling interval to get a proper time axis
......
......@@ -202,6 +202,13 @@ class BatchProcessWindow(QWidget):
# for each signal and the signal_id as key
ridge_results = self.do_the_loop()
# check for empty ridge_results
if not ridge_results:
self.NoResults = MessageWindow('All ridges below threshold.. no results!','No results')
return
# compute the time-averaged powers
if self.cb_power_dis.isChecked() or self.cb_sorted_powers.isChecked():
......@@ -209,7 +216,6 @@ class BatchProcessWindow(QWidget):
ridge_results.keys(),
exclude_coi = True)
print(powers_series)
# sort by power, descending
powers_series.sort_values(
ascending = False,
......@@ -357,6 +363,8 @@ class BatchProcessWindow(QWidget):
'''
EmptyRidge = 0
if self.export_options.isChecked():
OutPath = self.get_OutPath()
if OutPath is None:
......@@ -415,8 +423,12 @@ class BatchProcessWindow(QWidget):
tvec,
power_thresh,
smoothing_wsize = rsmooth)
ridge_results[signal_id] = (ridge_data)
if ridge_data.empty:
EmptyRidge += 1
else:
ridge_results[signal_id] = ridge_data
# -- Save out individual results --
if self.cb_specs.isChecked():
......@@ -435,7 +447,8 @@ class BatchProcessWindow(QWidget):
plt.savefig(fname)
plt.close()
if self.cb_readout_plots.isChecked():
if self.cb_readout_plots.isChecked() and not ridge_data.empty:
pl.plot_readout(ridge_data)
fname = f'{OutPath}/{signal_id}_readout.png'
if self.debug:
......@@ -443,14 +456,20 @@ class BatchProcessWindow(QWidget):
plt.savefig(fname)
plt.close()
if self.cb_readout.isChecked():
if self.cb_readout.isChecked() and not ridge_data.empty:
fname = f'{OutPath}/{signal_id}_readout.csv'
if self.debug:
print(f'Saving ridge reatout to {fname}')
ridge_data.to_csv(fname, sep = ',', float_format = '%.3f', index = False)
self.progress.setValue(i)
if EmptyRidge > 0:
self.NoRidges = MessageWindow(
f'{EmptyRidge} ridge readouts entirely below threshold..',
'Discarded ridges')
return ridge_results
......
......@@ -717,10 +717,26 @@ class DataViewer(QWidget):
# checks for empty signal_id string
if signal_id:
self.raw_signal = self.df[signal_id]
raw_signal = self.df[signal_id]
# remove NaNs
self.raw_signal = self.raw_signal[~np.isnan(self.raw_signal)]
NaNswitches = np.sum( np.diff( np.isnan(raw_signal) ) )
if NaNswitches > 1:
print(f'Warning, non-contiguous NaN region found in {signal_id}!')
self.NonContiguous = MessageWindow(
'''
Non contiguous regions of missing values
encountered, using linear interpolation.
Try 'Import..' from the main menu
to interpolate missing values in all signals!
'''
, "Missing Values")
self.raw_signal = pyboat.core.interpolate_NaNs(raw_signal)
else:
# remove contiguous (like trailing) NaN region
self.raw_signal = raw_signal[~np.isnan(raw_signal)]
self.tvec = np.arange(0, len(self.raw_signal), step=1) * self.dt
return True # success
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment