Coverage for /opt/obspy/update-docs/src/obspy/obspy/signal/tf_misfit : 30%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
#!/usr/bin/env python #------------------------------------------------------------------- # Filename: tf_misfit.py # Purpose: Various Time Frequency Misfit Functions # Author: Martin van Driel # Email: vandriel@sed.ethz.ch # # Copyright (C) 2012 Martin van Driel #--------------------------------------------------------------------- Various Time Frequency Misfit Functions based on Kristekova et. al. (2006) and Kristekova et. al. (2009).
.. seealso:: [Kristekova2006]_ and [Kristekova2009]_
:copyright: The ObsPy Development Team (devs@obspy.org) :license: GNU Lesser General Public License, Version 3 (http://www.gnu.org/copyleft/lesser.html) """
""" Continuous Wavelet Transformation in the Frequency Domain.
.. seealso:: [Kristekova2006]_, eq. (4)
:param st: time dependent signal. :param dt: time step between two samples in st :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param f: frequency discretization, type numpy.ndarray. :param wl: wavelet to use, for now only 'morlet' is implemented
:return: time frequency representation of st, type numpy.ndarray of complex values. """
np.exp(-t ** 2 / 2.) else: raise ValueError('wavelet type "' + wl + '" not defined!')
# time shift necessary, because wavelet is defined around t = 0 (t[1] - t[0])
st2_isref=True): """ Time Frequency Envelope Misfit
.. seealso:: [Kristekova2009]_, Table 1. and 2.
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference
:return: time frequency representation of Envelope Misfit, type numpy.ndarray with shape (nf, len(st1)) for single component data and (number of components, nf, len(st1)) for multicomponent data """
else: W1 = np.zeros((st1.shape[0], nf, st1.shape[1]), dtype=np.complex) W2 = np.zeros((st2.shape[0], nf, st2.shape[1]), dtype=np.complex)
for i in np.arange(st1.shape[0]): W1[i] = cwt(st1[i], dt, w0, fmin, fmax, nf) W2[i] = cwt(st2[i], dt, w0, fmin, fmax, nf)
else: if np.abs(W1).max() > np.abs(W2).max(): Ar = np.abs(W1) else: Ar = np.abs(W2)
else: return TFEM / np.max(Ar) elif norm == 'local': if len(st1.shape) == 1: return TFEM[0] / Ar[0] else: return TFEM / Ar else: raise ValueError('norm "' + norm + '" not defined!')
st2_isref=True): """ Time Frequency Phase Misfit
.. seealso:: [Kristekova2009]_, Table 1. and 2.
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference
:return: time frequency representation of Phase Misfit, type numpy.ndarray with shape (nf, len(st1)) for single component data and (number of components, nf, len(st1)) for multicomponent data """
else: W1 = np.zeros((st1.shape[0], nf, st1.shape[1]), dtype=np.complex) W2 = np.zeros((st2.shape[0], nf, st2.shape[1]), dtype=np.complex)
for i in np.arange(st1.shape[0]): W1[i] = cwt(st1[i], dt, w0, fmin, fmax, nf) W2[i] = cwt(st2[i], dt, w0, fmin, fmax, nf)
else: if np.abs(W1).max() > np.abs(W2).max(): Ar = np.abs(W1) else: Ar = np.abs(W2)
else: return Ar * TFPM / np.max(Ar) elif norm == 'local': if len(st1.shape) == 1: return TFPM[0] else: return TFPM else: raise ValueError('norm "' + norm + '" not defined!')
st2_isref=True): """ Time-dependent Envelope Misfit
.. seealso:: [Kristekova2009]_, Table 1. and 2.
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference
:return: Time-dependent Envelope Misfit, type numpy.ndarray with shape (len(st1),) for single component data and (number of components, len(st1)) for multicomponent data """
else: W1 = np.zeros((st1.shape[0], nf, st1.shape[1]), dtype=np.complex) W2 = np.zeros((st2.shape[0], nf, st2.shape[1]), dtype=np.complex)
for i in np.arange(st1.shape[0]): W1[i] = cwt(st1[i], dt, w0, fmin, fmax, nf) W2[i] = cwt(st2[i], dt, w0, fmin, fmax, nf)
else: if np.abs(W1).max() > np.abs(W2).max(): Ar = np.abs(W1) else: Ar = np.abs(W2)
else: return TEM / np.max(np.sum(Ar, axis=1)) elif norm == 'local': if len(st1.shape) == 1: return TEM[0] / np.sum(Ar, axis=1)[0] else: return TEM / np.sum(Ar, axis=1) else: raise ValueError('norm "' + norm + '" not defined!')
st2_isref=True): """ Time-dependent Phase Misfit
.. seealso:: [Kristekova2009]_, Table 1. and 2.
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference
:return: Time-dependent Phase Misfit, type numpy.ndarray with shape (len(st1),) for single component data and (number of components, len(st1)) for multicomponent data """
else: W1 = np.zeros((st1.shape[0], nf, st1.shape[1]), dtype=np.complex) W2 = np.zeros((st2.shape[0], nf, st2.shape[1]), dtype=np.complex)
for i in np.arange(st1.shape[0]): W1[i] = cwt(st1[i], dt, w0, fmin, fmax, nf) W2[i] = cwt(st2[i], dt, w0, fmin, fmax, nf)
else: if np.abs(W1).max() > np.abs(W2).max(): Ar = np.abs(W2) else: Ar = np.abs(W1)
else: return TPM / np.max(np.sum(Ar, axis=1)) elif norm == 'local': if len(st1.shape) == 1: return TPM[0] / np.sum(Ar, axis=1)[0] else: return TPM / np.sum(Ar, axis=1) else: raise ValueError('norm "' + norm + '" not defined!')
st2_isref=True): """ Frequency-dependent Envelope Misfit
.. seealso:: [Kristekova2009]_, Table 1. and 2.
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference
:return: Frequency-dependent Envelope Misfit, type numpy.ndarray with shape (nf,) for single component data and (number of components, nf) for multicomponent data """
else: W1 = np.zeros((st1.shape[0], nf, st1.shape[1]), dtype=np.complex) W2 = np.zeros((st2.shape[0], nf, st2.shape[1]), dtype=np.complex)
for i in np.arange(st1.shape[0]): W1[i] = cwt(st1[i], dt, w0, fmin, fmax, nf) W2[i] = cwt(st2[i], dt, w0, fmin, fmax, nf)
else: if np.abs(W1).max() > np.abs(W2).max(): Ar = np.abs(W1) else: Ar = np.abs(W2)
else: return TEM / np.max(np.sum(Ar, axis=2)) elif norm == 'local': if len(st1.shape) == 1: return TEM[0] / np.sum(Ar, axis=2)[0] else: return TEM / np.sum(Ar, axis=2) else: raise ValueError('norm "' + norm + '" not defined!')
st2_isref=True): """ Frequency-dependent Phase Misfit
.. seealso:: [Kristekova2009]_, Table 1. and 2.
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference
:return: Frequency-dependent Phase Misfit, type numpy.ndarray with shape (nf,) for single component data and (number of components, nf) for multicomponent data """
else: W1 = np.zeros((st1.shape[0], nf, st1.shape[1]), dtype=np.complex) W2 = np.zeros((st2.shape[0], nf, st2.shape[1]), dtype=np.complex)
for i in np.arange(st1.shape[0]): W1[i] = cwt(st1[i], dt, w0, fmin, fmax, nf) W2[i] = cwt(st2[i], dt, w0, fmin, fmax, nf)
else: if np.abs(W1).max() > np.abs(W2).max(): Ar = np.abs(W1) else: Ar = np.abs(W2)
else: return TPM / np.max(np.sum(Ar, axis=2)) elif norm == 'local': if len(st1.shape) == 1: return TPM[0] / np.sum(Ar, axis=2)[0] else: return TPM / np.sum(Ar, axis=2) else: raise ValueError('norm "' + norm + '" not defined!')
st2_isref=True): """ Single Valued Envelope Misfit
.. seealso:: [Kristekova2009]_, Table 1. and 2.
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference
:return: Single Valued Envelope Misfit """
else: W1 = np.zeros((st1.shape[0], nf, st1.shape[1]), dtype=np.complex) W2 = np.zeros((st2.shape[0], nf, st2.shape[1]), dtype=np.complex)
for i in np.arange(st1.shape[0]): W1[i] = cwt(st1[i], dt, w0, fmin, fmax, nf) W2[i] = cwt(st2[i], dt, w0, fmin, fmax, nf)
else: if np.abs(W1).max() > np.abs(W2).max(): Ar = np.abs(W1) else: Ar = np.abs(W2)
else: return EM / ((np.sum(np.sum(Ar ** 2, axis=2), axis=1)) ** .5).max() elif norm == 'local': if len(st1.shape) == 1: return EM[0] / (np.sum(Ar ** 2)) ** .5 else: return EM / (np.sum(np.sum(Ar ** 2, axis=2), axis=1)) ** .5 else: raise ValueError('norm "' + norm + '" not defined!')
st2_isref=True): """ Single Valued Phase Misfit
.. seealso:: [Kristekova2009]_, Table 1. and 2.
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference
:return: Single Valued Phase Misfit """
else: W1 = np.zeros((st1.shape[0], nf, st1.shape[1]), dtype=np.complex) W2 = np.zeros((st2.shape[0], nf, st2.shape[1]), dtype=np.complex)
for i in np.arange(st1.shape[0]): W1[i] = cwt(st1[i], dt, w0, fmin, fmax, nf) W2[i] = cwt(st2[i], dt, w0, fmin, fmax, nf)
else: if np.abs(W1).max() > np.abs(W2).max(): Ar = np.abs(W1) else: Ar = np.abs(W2)
else: return PM / ((np.sum(np.sum(Ar ** 2, axis=2), axis=1)) ** .5).max() elif norm == 'local': if len(st1.shape) == 1: return PM[0] / (np.sum(Ar ** 2)) ** .5 else: return PM / (np.sum(np.sum(Ar ** 2, axis=2), axis=1)) ** .5 else: raise ValueError('norm "' + norm + '" not defined!')
st2_isref=True, A=10., k=1.): """ Time Frequency Envelope Goodness-Of-Fit
.. seealso:: [Kristekova2009]_, Eq.(15)
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit
:return: time frequency representation of Envelope Goodness-Of-Fit, type numpy.ndarray with shape (nf, len(st1)) for single component data and (number of components, nf, len(st1)) for multicomponent data """ st2_isref=st2_isref)
st2_isref=True, A=10., k=1.): """ Time Frequency Phase Goodness-Of-Fit
.. seealso:: [Kristekova2009]_, Eq.(16)
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit
:return: time frequency representation of Phase Goodness-Of-Fit, type numpy.ndarray with shape (nf, len(st1)) for single component data and (number of components, nf, len(st1)) for multicomponent data """ st2_isref=st2_isref)
st2_isref=True, A=10., k=1.): """ Time Dependent Envelope Goodness-Of-Fit
.. seealso:: [Kristekova2009]_, Eq.(15)
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit
:return: time dependent Envelope Goodness-Of-Fit, type numpy.ndarray with shape (len(st1),) for single component data and (number of components, len(st1)) for multicomponent data """ st2_isref=st2_isref)
st2_isref=True, A=10., k=1.): """ Time Dependent Phase Goodness-Of-Fit
.. seealso:: [Kristekova2009]_, Eq.(16)
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit
:return: time dependent Phase Goodness-Of-Fit, type numpy.ndarray with shape (len(st1),) for single component data and (number of components, len(st1)) for multicomponent data """ st2_isref=st2_isref)
st2_isref=True, A=10., k=1.): """ Frequency Dependent Envelope Goodness-Of-Fit
.. seealso:: [Kristekova2009]_, Eq.(15)
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit
:return: frequency dependent Envelope Goodness-Of-Fit, type numpy.ndarray with shape (nf,) for single component data and (number of components, nf) for multicomponent data """ st2_isref=st2_isref)
st2_isref=True, A=10., k=1.): """ Frequency Dependent Phase Goodness-Of-Fit
.. seealso:: [Kristekova2009]_, Eq.(16)
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit
:return: frequency dependent Phase Goodness-Of-Fit, type numpy.ndarray with shape (nf,) for single component data and (number of components, nf) for multicomponent data """ st2_isref=st2_isref)
st2_isref=True, A=10., k=1.): """ Single Valued Envelope Goodness-Of-Fit
.. seealso:: [Kristekova2009]_, Eq.(15)
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit
:return: Single Valued Envelope Goodness-Of-Fit """ st2_isref=st2_isref)
st2_isref=True, A=10., k=1.): """ Single Valued Phase Goodness-Of-Fit
.. seealso:: [Kristekova2009]_, Eq.(16)
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit
:return: Single Valued Phase Goodness-Of-Fit """ st2_isref=st2_isref)
norm='global', st2_isref=True, left=0.1, bottom=0.1, h_1=0.2, h_2=0.125, h_3=0.2, w_1=0.2, w_2=0.6, w_cb=0.01, d_cb=0.0, show=True, plot_args=['k', 'r', 'b'], ylim=0., clim=0., cmap=None): """ Plot all timefrequency misfits and the time series in one plot (per component).
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param t0: starting time for plotting :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param left: plot distance from the left of the figure :param bottom: plot distance from the bottom of the figure :param h_1: height of the signal axes :param h_2: height of the TEM and TPM axes :param h_3: height of the TFEM and TFPM axes :param w_1: width of the FEM and FPM axes :param w_2: width of the TFEM, TFPM, signal etc. axes :param w_cb: width of the colorbar axes :param d_cb: distance of the colorbar axes to the other axes :param show: show figure or return :param plot_args: list of plot arguments passed to the signal 1/2 and TEM/TPM/FEM/FPM plots :param ylim: limits in misfit for TEM/TPM/FEM/FPM :param clim: limits of the colorbars :param cmap: colormap for TFEM/TFPM, either a string or matplotlib.cm.Colormap instance
:return: If show is False, returns a maplotlib.pyplot.figure object (single component data) or a list of figure objects (multi component data)
.. rubric:: Example
For a signal with pure phase error
.. seealso:: [Kristekova2006]_, Fig.(4)
>>> import numpy as np >>> from scipy.signal import hilbert >>> tmax = 6. >>> dt = 0.01 >>> npts = int(tmax / dt + 1) >>> t = np.linspace(0., tmax, npts) >>> A1 = 4. >>> t1 = 2. >>> f1 = 2. >>> phi1 = 0. >>> phase_shift = 0.1 >>> H1 = (np.sign(t - t1) + 1)/ 2 >>> st1 = (A1 * (t - t1) * np.exp(-2*(t - t1)) * ... np.cos(2. * np.pi * f1 * (t - t1) + phi1 * np.pi) * H1) >>> # Reference signal >>> st2 = st1.copy() >>> # Distorted signal: >>> # generate analytical signal (hilbert transform) and add phase shift >>> st1 = hilbert(st1) >>> st1 = np.real(np.abs(st1) * np.exp((np.angle(st1) + ... phase_shift * np.pi) * 1j)) >>> plotTfMisfits(st1, st2, dt=dt, fmin=1., fmax=10.) # doctest: +SKIP
.. plot::
import numpy as np from scipy.signal import hilbert from obspy.signal.tf_misfit import plotTfMisfits tmax = 6. dt = 0.01 npts = int(tmax / dt + 1) t = np.linspace(0., tmax, npts) A1 = 4. t1 = 2. f1 = 2. phi1 = 0. phase_shift = 0.1 H1 = (np.sign(t - t1) + 1)/ 2 st1 = (A1 * (t - t1) * np.exp(-2*(t - t1)) * np.cos(2. * np.pi * f1 * (t - t1) + phi1 * np.pi) * H1) # Reference signal st2 = st1.copy() # Distorted signal: # generate analytical signal (hilbert transform) and add phase shift st1 = hilbert(st1) st1 = np.real(np.abs(st1) * np.exp((np.angle(st1) + phase_shift * np.pi) * 1j)) plotTfMisfits(st1, st2, dt=dt, fmin=1., fmax=10.) """ npts = st1.shape[-1] tmax = (npts - 1) * dt t = np.linspace(0., tmax, npts) + t0 f = np.logspace(np.log10(fmin), np.log10(fmax), nf)
if cmap == None: CDICT_TFM = {'red': ((0.0, 0.0, 0.0), (0.2, 0.0, 0.0), (0.4, 0.0, 0.0), (0.5, 1.0, 1.0), (0.6, 1.0, 1.0), (0.8, 1.0, 1.0), (1.0, 0.2, 0.2)), 'green': ((0.0, 0.0, 0.0), (0.2, 0.0, 0.0), (0.4, 1.0, 1.0), (0.5, 1.0, 1.0), (0.6, 1.0, 1.0), (0.8, 0.0, 0.0), (1.0, 0.0, 0.0)), 'blue': ((0.0, 0.2, 0.2), (0.2, 1.0, 1.0), (0.4, 1.0, 1.0), (0.5, 1.0, 1.0), (0.6, 0.0, 0.0), (0.8, 0.0, 0.0), (1.0, 0.0, 0.0))}
cmap = LinearSegmentedColormap('cmap_tfm', CDICT_TFM, 1024)
# compute time frequency misfits TFEM = tfem(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref) TEM = tem(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref) FEM = fem(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref) EM = em(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref) TFPM = tfpm(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref) TPM = tpm(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref) FPM = fpm(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref) PM = pm(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref)
if len(st1.shape) == 1: TFEM = TFEM.reshape((1, nf, npts)) TEM = TEM.reshape((1, npts)) FEM = FEM.reshape((1, nf)) EM = EM.reshape((1, 1)) TFPM = TFPM.reshape((1, nf, npts)) TPM = TPM.reshape((1, npts)) FPM = FPM.reshape((1, nf)) PM = PM.reshape((1, 1)) st1 = st1.reshape((1, npts)) st2 = st2.reshape((1, npts)) ntr = 1 else: ntr = st1.shape[0]
figs = []
for itr in np.arange(ntr): fig = plt.figure()
# plot signals ax_sig = fig.add_axes([left + w_1, bottom + h_2 + h_3, w_2, h_1]) ax_sig.plot(t, st1[itr], plot_args[0]) ax_sig.plot(t, st2[itr], plot_args[1])
# plot TEM ax_TEM = fig.add_axes([left + w_1, bottom + h_1 + h_2 + h_3, w_2, h_2]) ax_TEM.plot(t, TEM[itr], plot_args[2])
# plot TFEM ax_TFEM = fig.add_axes([left + w_1, bottom + h_1 + 2 * h_2 + h_3, w_2, h_3]) img_TFEM = ax_TFEM.imshow(TFEM[itr], interpolation='nearest', cmap=cmap, extent=[t[0], t[-1], fmin, fmax], aspect='auto', origin='lower') ax_TFEM.set_yscale('log')
# plot FEM ax_FEM = fig.add_axes([left, bottom + h_1 + 2 * h_2 + h_3, w_1, h_3]) ax_FEM.semilogy(FEM[itr], f, plot_args[2]) ax_FEM.set_ylim(fmin, fmax)
# plot TPM ax_TPM = fig.add_axes([left + w_1, bottom, w_2, h_2]) ax_TPM.plot(t, TPM[itr], plot_args[2])
# plot TFPM ax_TFPM = fig.add_axes([left + w_1, bottom + h_2, w_2, h_3]) img_TFPM = ax_TFPM.imshow(TFPM[itr], interpolation='nearest', cmap=cmap, extent=[t[0], t[-1], f[0], f[-1]], aspect='auto', origin='lower') ax_TFPM.set_yscale('log')
# add colorbars ax_cb_TFPM = fig.add_axes([left + w_1 + w_2 + d_cb + w_cb, bottom, w_cb, h_2 + h_3]) fig.colorbar(img_TFPM, cax=ax_cb_TFPM)
# plot FPM ax_FPM = fig.add_axes([left, bottom + h_2, w_1, h_3]) ax_FPM.semilogy(FPM[itr], f, plot_args[2]) ax_FPM.set_ylim(fmin, fmax)
# set limits ylim_sig = np.max([np.abs(st1).max(), np.abs(st2).max()]) * 1.1 ax_sig.set_ylim(-ylim_sig, ylim_sig)
if ylim == 0.: ylim = np.max([np.abs(TEM).max(), np.abs(TPM).max(), np.abs(FEM).max(), np.abs(FPM).max()]) * 1.1
ax_TEM.set_ylim(-ylim, ylim) ax_FEM.set_xlim(-ylim, ylim) ax_TPM.set_ylim(-ylim, ylim) ax_FPM.set_xlim(-ylim, ylim)
ax_sig.set_xlim(t[0], t[-1]) ax_TEM.set_xlim(t[0], t[-1]) ax_TPM.set_xlim(t[0], t[-1])
if clim == 0.: clim = np.max([np.abs(TFEM).max(), np.abs(TFPM).max()])
img_TFPM.set_clim(-clim, clim) img_TFEM.set_clim(-clim, clim)
# add text box for EM + PM textstr = 'EM = %.2f\nPM = %.2f' % (EM[itr], PM[itr]) props = dict(boxstyle='round', facecolor='white') ax_sig.text(-0.3, 0.5, textstr, transform=ax_sig.transAxes, verticalalignment='center', horizontalalignment='left', bbox=props)
ax_TPM.set_xlabel('time') ax_FEM.set_ylabel('frequency') ax_FPM.set_ylabel('frequency')
# add text boxes props = dict(boxstyle='round', facecolor='white', alpha=0.5) ax_TFEM.text(0.95, 0.85, 'TFEM', transform=ax_TFEM.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_TFPM.text(0.95, 0.85, 'TFPM', transform=ax_TFPM.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_TEM.text(0.95, 0.75, 'TEM', transform=ax_TEM.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_TPM.text(0.95, 0.75, 'TPM', transform=ax_TPM.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_FEM.text(0.9, 0.85, 'FEM', transform=ax_FEM.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_FPM.text(0.9, 0.85, 'FPM', transform=ax_FPM.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props)
# remove axis labels ax_TFPM.xaxis.set_major_formatter(NullFormatter()) ax_TFEM.xaxis.set_major_formatter(NullFormatter()) ax_TEM.xaxis.set_major_formatter(NullFormatter()) ax_sig.xaxis.set_major_formatter(NullFormatter()) ax_TFPM.yaxis.set_major_formatter(NullFormatter()) ax_TFEM.yaxis.set_major_formatter(NullFormatter())
figs.append(fig)
if show: plt.show() else: if len(st1.shape) == 1: return figs[0] else: return figs
norm='global', st2_isref=True, A=10., k=1., left=0.1, bottom=0.1, h_1=0.2, h_2=0.125, h_3=0.2, w_1=0.2, w_2=0.6, w_cb=0.01, d_cb=0.0, show=True, plot_args=['k', 'r', 'b'], ylim=0., clim=0., cmap=None): """ Plot all timefrequency Goodnes-Of-Fits and the time series in one plot (per component).
:param st1: signal 1 of two signals to compare, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param st2: signal 2 of two signals to compare, type and shape as st1 :param dt: time step between two samples in st1 and st2 :param t0: starting time for plotting :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param norm: 'global' or 'local' normalization of the misfit :param st2_isref: Boolean, True if st2 is a reference signal, False if none is a reference :param A: Maximum value of Goodness-Of-Fit for perfect agreement :param k: sensitivity of Goodness-Of-Fit to the misfit :param left: plot distance from the left of the figure :param bottom: plot distance from the bottom of the figure :param h_1: height of the signal axes :param h_2: height of the TEM and TPM axes :param h_3: height of the TFEM and TFPM axes :param w_1: width of the FEM and FPM axes :param w_2: width of the TFEM, TFPM, signal etc. axes :param w_cb: width of the colorbar axes :param d_cb: distance of the colorbar axes to the other axes :param show: show figure or return :param plot_args: list of plot arguments passed to the signal 1/2 and TEM/TPM/FEM/FPM plots :param ylim: limits in misfit for TEM/TPM/FEM/FPM :param clim: limits of the colorbars :param cmap: colormap for TFEM/TFPM, either a string or matplotlib.cm.Colormap instance
:return: If show is False, returns a maplotlib.pyplot.figure object (single component data) or a list of figure objects (multi component data)
.. rubric:: Example
For a signal with pure amplitude error
>>> import numpy as np >>> from scipy.signal import hilbert >>> tmax = 6. >>> dt = 0.01 >>> npts = int(tmax / dt + 1) >>> t = np.linspace(0., tmax, npts) >>> A1 = 4. >>> t1 = 2. >>> f1 = 2. >>> phi1 = 0. >>> phase_shift = 0.1 >>> H1 = (np.sign(t - t1) + 1)/ 2 >>> st1 = (A1 * (t - t1) * np.exp(-2*(t - t1)) * ... np.cos(2. * np.pi * f1 * (t - t1) + phi1 * np.pi) * H1) >>> # Reference signal >>> st2 = st1.copy() >>> # Distorted signal: >>> st1 = st1 * 3. >>> plotTfGofs(st1, st2, dt=dt, fmin=1., fmax=10.) # doctest: +SKIP
.. plot::
import numpy as np from obspy.signal.tf_misfit import plotTfGofs tmax = 6. dt = 0.01 npts = int(tmax / dt + 1) t = np.linspace(0., tmax, npts) A1 = 4. t1 = 2. f1 = 2. phi1 = 0. phase_shift = 0.1 H1 = (np.sign(t - t1) + 1)/ 2 st1 = (A1 * (t - t1) * np.exp(-2*(t - t1)) * np.cos(2. * np.pi * f1 * (t - t1) + phi1 * np.pi) * H1) # Reference signal st2 = st1.copy() # Distorted signal: st1 = st1 * 3. plotTfGofs(st1, st2, dt=dt, fmin=1., fmax=10.) """ npts = st1.shape[-1] tmax = (npts - 1) * dt t = np.linspace(0., tmax, npts) + t0 f = np.logspace(np.log10(fmin), np.log10(fmax), nf)
if cmap == None: CDICT_GOF = {'red': ((0.0, 0.6, 0.6), (0.4, 0.6, 1.0), (0.6, 1.0, 1.0), (0.8, 1.0, 1.0), (1.0, 1.0, 1.0)), 'green': ((0.0, 0.0, 0.0), (0.4, 0.0, 0.5), (0.6, 0.5, 1.0), (0.8, 1.0, 1.0), (1.0, 1.0, 1.0)), 'blue': ((0.0, 0.0, 0.0), (0.4, 0.0, 0.0), (0.6, 0.0, 0.0), (0.8, 0.0, 1.0), (1.0, 1.0, 1.0))}
cmap = LinearSegmentedColormap('cmap_gof', CDICT_GOF, 1024)
# compute time frequency misfits TFEG = tfeg(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref, A=A, k=k) TEG = teg(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref, A=A, k=k) FEG = feg(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref, A=A, k=k) EG = eg(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref, A=A, k=k) TFPG = tfpg(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref, A=A, k=k) TPG = tpg(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref, A=A, k=k) FPG = fpg(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref, A=A, k=k) PG = pg(st1, st2, dt=dt, fmin=fmin, fmax=fmax, nf=nf, w0=w0, norm=norm, st2_isref=st2_isref, A=A, k=k)
if len(st1.shape) == 1: TFEG = TFEG.reshape((1, nf, npts)) TEG = TEG.reshape((1, npts)) FEG = FEG.reshape((1, nf)) EG = EG.reshape((1, 1)) TFPG = TFPG.reshape((1, nf, npts)) TPG = TPG.reshape((1, npts)) FPG = FPG.reshape((1, nf)) PG = PG.reshape((1, 1)) st1 = st1.reshape((1, npts)) st2 = st2.reshape((1, npts)) ntr = 1 else: ntr = st1.shape[0]
figs = []
for itr in np.arange(ntr): fig = plt.figure()
# plot signals ax_sig = fig.add_axes([left + w_1, bottom + h_2 + h_3, w_2, h_1]) ax_sig.plot(t, st1[itr], plot_args[0]) ax_sig.plot(t, st2[itr], plot_args[1])
# plot TEG ax_TEG = fig.add_axes([left + w_1, bottom + h_1 + h_2 + h_3, w_2, h_2]) ax_TEG.plot(t, TEG[itr], plot_args[2])
# plot TFEG ax_TFEG = fig.add_axes([left + w_1, bottom + h_1 + 2 * h_2 + h_3, w_2, h_3]) img_TFEG = ax_TFEG.imshow(TFEG[itr], interpolation='nearest', cmap=cmap, extent=[t[0], t[-1], fmin, fmax], aspect='auto', origin='lower') ax_TFEG.set_yscale('log')
# plot FEG ax_FEG = fig.add_axes([left, bottom + h_1 + 2 * h_2 + h_3, w_1, h_3]) ax_FEG.semilogy(FEG[itr], f, plot_args[2]) ax_FEG.set_ylim(fmin, fmax)
# plot TPG ax_TPG = fig.add_axes([left + w_1, bottom, w_2, h_2]) ax_TPG.plot(t, TPG[itr], plot_args[2])
# plot TFPG ax_TFPG = fig.add_axes([left + w_1, bottom + h_2, w_2, h_3]) img_TFPG = ax_TFPG.imshow(TFPG[itr], interpolation='nearest', cmap=cmap, extent=[t[0], t[-1], f[0], f[-1]], aspect='auto', origin='lower') ax_TFPG.set_yscale('log')
# add colorbars ax_cb_TFPG = fig.add_axes([left + w_1 + w_2 + d_cb + w_cb, bottom, w_cb, h_2 + h_3]) fig.colorbar(img_TFPG, cax=ax_cb_TFPG)
# plot FPG ax_FPG = fig.add_axes([left, bottom + h_2, w_1, h_3]) ax_FPG.semilogy(FPG[itr], f, plot_args[2]) ax_FPG.set_ylim(fmin, fmax)
# set limits ylim_sig = np.max([np.abs(st1).max(), np.abs(st2).max()]) * 1.1 ax_sig.set_ylim(-ylim_sig, ylim_sig)
if ylim == 0.: ylim = np.max([np.abs(TEG).max(), np.abs(TPG).max(), np.abs(FEG).max(), np.abs(FPG).max()]) * 1.1
ax_TEG.set_ylim(0., ylim) ax_FEG.set_xlim(0., ylim) ax_TPG.set_ylim(0., ylim) ax_FPG.set_xlim(0., ylim)
ax_sig.set_xlim(t[0], t[-1]) ax_TEG.set_xlim(t[0], t[-1]) ax_TPG.set_xlim(t[0], t[-1])
if clim == 0.: clim = np.max([np.abs(TFEG).max(), np.abs(TFPG).max()])
img_TFPG.set_clim(0., clim) img_TFEG.set_clim(0., clim)
# add text box for EG + PG textstr = 'EG = %2.2f\nPG = %2.2f' % (EG[itr], PG[itr]) props = dict(boxstyle='round', facecolor='white') ax_sig.text(-0.3, 0.5, textstr, transform=ax_sig.transAxes, verticalalignment='center', horizontalalignment='left', bbox=props)
ax_TPG.set_xlabel('time') ax_FEG.set_ylabel('frequency') ax_FPG.set_ylabel('frequency')
# add text boxes props = dict(boxstyle='round', facecolor='white', alpha=0.5) ax_TFEG.text(0.95, 0.85, 'TFEG', transform=ax_TFEG.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_TFPG.text(0.95, 0.85, 'TFPG', transform=ax_TFPG.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_TEG.text(0.95, 0.75, 'TEG', transform=ax_TEG.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_TPG.text(0.95, 0.75, 'TPG', transform=ax_TPG.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_FEG.text(0.9, 0.85, 'FEG', transform=ax_FEG.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props) ax_FPG.text(0.9, 0.85, 'FPG', transform=ax_FPG.transAxes, verticalalignment='top', horizontalalignment='right', bbox=props)
# remove axis labels ax_TFPG.xaxis.set_major_formatter(NullFormatter()) ax_TFEG.xaxis.set_major_formatter(NullFormatter()) ax_TEG.xaxis.set_major_formatter(NullFormatter()) ax_sig.xaxis.set_major_formatter(NullFormatter()) ax_TFPG.yaxis.set_major_formatter(NullFormatter()) ax_TFEG.yaxis.set_major_formatter(NullFormatter())
figs.append(fig)
if show: plt.show() else: if len(st1.shape) == 1: return figs[0] else: return figs
bottom=0.1, h_1=0.2, h_2=0.6, w_1=0.2, w_2=0.6, w_cb=0.01, d_cb=0.0, show=True, plot_args=['k', 'k'], clim=0., cmap=None, mode='absolute', fft_zero_pad_fac=0): """ Plot time-frequency representation, spectrum and time series of the signal.
:param st: signal, type numpy.ndarray with shape (number of components, number of time samples) or (number of timesamples, ) for single component data :param dt: time step between two samples in st :param t0: starting time for plotting :param fmin: minimal frequency to be analyzed :param fmax: maximal frequency to be analyzed :param nf: number of frequencies (will be chosen with logarithmic spacing) :param w0: parameter for the wavelet, tradeoff between time and frequency resolution :param left: plot distance from the left of the figure :param bottom: plot distance from the bottom of the figure :param h_1: height of the signal axis :param h_2: height of the TFR/spectrum axis :param w_1: width of the spectrum axis :param w_2: width of the TFR/signal axes :param w_cb: width of the colorbar axes :param d_cb: distance of the colorbar axes to the other axes :param show: show figure or return :param plot_args: list of plot arguments passed to the signal and spectrum plots :param clim: limits of the colorbars :param cmap: colormap for TFEM/TFPM, either a string or matplotlib.cm.Colormap instance :param mode: 'absolute' for absolute value of TFR, 'power' for |TFR|^2 :param fft_zero_pad_fac: integer, if > 0, the signal is zero padded to nfft = nextpow2(len(st)) * fft_zero_pad_fac to get smoother spectrum in the low frequencies (has no effect on the TFR and might make demeaning/tapering necessary to avoid artefacts)
:return: If show is False, returns a maplotlib.pyplot.figure object (single component data) or a list of figure objects (multi component data)
.. rubric:: Example
>>> from obspy import read >>> tr = read("http://examples.obspy.org/a02i.2008.240.mseed")[0] >>> plotTfr(tr.data, dt=tr.stats.delta, fmin=.01, # doctest: +SKIP ... fmax=50., w0=8., nf=512, fft_zero_pad_fac=4)
.. plot::
from obspy.signal.tf_misfit import plotTfr from obspy import read tr = read("http://examples.obspy.org/a02i.2008.240.mseed")[0] plotTfr(tr.data, dt=tr.stats.delta, fmin=.01, fmax=50., w0=8., nf=512, fft_zero_pad_fac=4) """ npts = st.shape[-1] tmax = (npts - 1) * dt t = np.linspace(0., tmax, npts) + t0
if fft_zero_pad_fac == 0: nfft = npts else: nfft = util.nextpow2(npts) * fft_zero_pad_fac
f_lin = np.linspace(0, 0.5 / dt, nfft / 2 + 1)
if cmap == None: CDICT_TFR = {'red': ((0.0, 1.0, 1.0), (0.05, 1.0, 1.0), (0.2, 0.0, 0.0), (0.4, 0.0, 0.0), (0.6, 0.0, 0.0), (0.8, 1.0, 1.0), (1.0, 1.0, 1.0)), 'green': ((0.0, 1.0, 1.0), (0.05, 0.0, 0.0), (0.2, 0.0, 0.0), (0.4, 1.0, 1.0), (0.6, 1.0, 1.0), (0.8, 1.0, 1.0), (1.0, 0.0, 0.0)), 'blue': ((0.0, 1.0, 1.0), (0.05, 1.0, 1.0), (0.2, 1.0, 1.0), (0.4, 1.0, 1.0), (0.6, 0.0, 0.0), (0.8, 0.0, 0.0), (1.0, 0.0, 0.0))}
cmap = LinearSegmentedColormap('cmap_tfr', CDICT_TFR, 1024)
if len(st.shape) == 1: W = np.zeros((1, nf, npts), dtype=np.complex) W[0] = cwt(st, dt, w0, fmin, fmax, nf) ntr = 1
spec = np.zeros((1, nfft / 2 + 1), dtype=np.complex) spec[0] = np.fft.rfft(st, n=nfft) * dt
st = st.reshape((1, npts)) else: W = np.zeros((st.shape[0], nf, npts), dtype=np.complex) spec = np.zeros((st.shape[0], nfft / 2 + 1), dtype=np.complex)
for i in np.arange(st.shape[0]): W[i] = cwt(st[i], dt, w0, fmin, fmax, nf) spec[i] = np.fft.rfft(st[i], n=nfft) * dt
ntr = st.shape[0]
print W.shape
if mode == 'absolute': TFR = np.abs(W) spec = np.abs(spec) elif mode == 'power': TFR = np.abs(W) ** 2 spec = np.abs(spec) ** 2 else: raise ValueError('mode "' + mode + '" not defined!')
figs = []
for itr in np.arange(ntr): fig = plt.figure()
# plot signals ax_sig = fig.add_axes([left + w_1, bottom, w_2, h_1]) ax_sig.plot(t, st[itr], plot_args[0])
# plot TFR ax_TFR = fig.add_axes([left + w_1, bottom + h_1, w_2, h_2]) img_TFR = ax_TFR.imshow(TFR[itr], interpolation='nearest', cmap=cmap, extent=[t[0], t[-1], fmin, fmax], aspect='auto', origin='lower') ax_TFR.set_yscale('log')
# plot spectrum ax_spec = fig.add_axes([left, bottom + h_1, w_1, h_2]) ax_spec.semilogy(spec[itr], f_lin, plot_args[1])
# add colorbars ax_cb_TFR = fig.add_axes([left + w_1 + w_2 + d_cb + w_cb, bottom + h_1, w_cb, h_2]) fig.colorbar(img_TFR, cax=ax_cb_TFR)
# set limits ax_sig.set_ylim(st.min() * 1.1, st.max() * 1.1) ax_sig.set_xlim(t[0], t[-1])
xlim = spec.max() * 1.1
ax_spec.set_xlim(xlim, 0.) ax_spec.set_ylim(fmin, fmax)
if clim == 0.: clim = TFR.max()
img_TFR.set_clim(0., clim)
ax_sig.set_xlabel('time') ax_spec.set_ylabel('frequency')
# remove axis labels ax_TFR.xaxis.set_major_formatter(NullFormatter()) ax_TFR.yaxis.set_major_formatter(NullFormatter())
figs.append(fig)
if show: plt.show() else: if len(st.shape) == 1: return figs[0] else: return figs
if __name__ == '__main__': import doctest doctest.testmod(exclude_empty=True) |