Esempio n. 1
0
 def test_waveletcoefficients(self):
     data = numpy.random.random((10, 10))
     ts = time_series.TimeSeries(data=data)
     dt = spectral.WaveletCoefficients(
         source=ts,
         mother='morlet',
         sample_period=7.8125,
         frequencies=[0.008, 0.028, 0.048, 0.068],
         normalisation="energy",
         q_ratio=5.0,
         array_data=numpy.random.random((10, 10)),
     )
     dt.configure()
     summary_info = dt.summary_info
     self.assertEqual(summary_info['Maximum frequency'], 0.068)
     self.assertEqual(summary_info['Minimum frequency'], 0.008)
     self.assertEqual(summary_info['Normalisation'], 'energy')
     self.assertEqual(summary_info['Number of scales'], 4)
     self.assertEqual(summary_info['Q-ratio'], 5.0)
     self.assertEqual(summary_info['Sample period'], 7.8125)
     self.assertEqual(summary_info['Spectral type'], 'WaveletCoefficients')
     self.assertEqual(summary_info['Wavelet type'], 'morlet')
     self.assertEqual(dt.q_ratio, 5.0)
     self.assertEqual(dt.sample_period, 7.8125)
     self.assertEqual(dt.shape, (10, 10))
     self.assertTrue(dt.source is not None)
Esempio n. 2
0
 def test_waveletcoefficients(self):
     data = numpy.random.random((10, 10))
     ts = time_series.TimeSeries(data=data)
     dt = spectral.WaveletCoefficients(
         source=ts,
         mother='morlet',
         sample_period=7.8125,
         frequencies=numpy.array([0.008, 0.028, 0.048, 0.068]),
         normalisation="energy",
         q_ratio=5.0,
         array_data=numpy.random.random((10, 10)),
     )
     # dt.configure()
     summary_info = dt.summary_info()
     assert summary_info['Maximum frequency'] == 0.068
     assert summary_info['Minimum frequency'] == 0.008
     assert summary_info['Normalisation'], 'energy'
     assert summary_info['Number of scales'] == 4
     assert summary_info['Q-ratio'] == 5.0
     assert summary_info['Sample period'] == 7.8125
     assert summary_info['Spectral type'] == 'WaveletCoefficients'
     assert summary_info['Wavelet type'] == 'morlet'
     assert dt.q_ratio == 5.0
     assert dt.sample_period == 7.8125
     assert dt.array_data.shape == (10, 10)
     assert dt.source is not None
Esempio n. 3
0
    def evaluate(self):
        """
        Calculate the continuous wavelet transform of time_series.
        """
        cls_attr_name = self.__class__.__name__ + ".time_series"
        self.time_series.trait["data"].log_debug(owner=cls_attr_name)

        ts_shape = self.time_series.data.shape

        if self.frequencies.step == 0:
            LOG.warning(
                "Frequency step can't be 0! Trying default step, 2e-3.")
            self.frequencies.step = 0.002

        freqs = numpy.arange(self.frequencies.lo, self.frequencies.hi,
                             self.frequencies.step)

        if (freqs.size == 0) or any(
                freqs <= 0.0
        ):  #TODO: Maybe should limit number of freqs... ~100 is probably a reasonable upper bound.
            LOG.warning("Invalid frequency range! Falling back to default.")
            util.log_debug_array(LOG, freqs, "freqs")
            self.frequencies = basic.Range(lo=0.008, hi=0.060, step=0.002)
            freqs = numpy.arange(self.frequencies.lo, self.frequencies.hi,
                                 self.frequencies.step)

        util.log_debug_array(LOG, freqs, "freqs")

        sample_rate = self.time_series.sample_rate

        # Duke: code below is as given by Andreas Spiegler, I've just wrapped
        # some of the original argument names
        nf = len(freqs)
        temporal_step = max(
            (1, iround(self.sample_period / self.time_series.sample_period)))
        nt = int(numpy.ceil(ts_shape[0] / temporal_step))

        if not isinstance(self.q_ratio, numpy.ndarray):
            Q_ratio = self.q_ratio * numpy.ones((1, nf))

        if numpy.nanmin(Q_ratio) < 5:
            msg = "Q_ratio must be not lower than 5 !"
            LOG.error(msg)
            raise Exception(msg)

        if numpy.nanmax(freqs) > sample_rate / 2.0:
            msg = "Sampling rate is too low for the requested frequency range !"
            LOG.error(msg)
            raise Exception(msg)

        #TODO: This isn't used, but min frequency seems like it should be important... Check with A.S.
        #  fmin = 3.0 * numpy.nanmin(Q_ratio) * sample_rate / numpy.pi / nt
        sigma_f = freqs / Q_ratio
        sigma_t = 1.0 / (2.0 * numpy.pi * sigma_f)

        if self.normalisation == 'energy':
            Amp = 1.0 / numpy.sqrt(
                sample_rate * numpy.sqrt(numpy.pi) * sigma_t)
        elif self.normalisation == 'gabor':
            Amp = numpy.sqrt(2.0 / numpy.pi) / sample_rate / sigma_t

        coef_shape = (nf, nt, ts_shape[1], ts_shape[2], ts_shape[3])

        coef = numpy.zeros(coef_shape, dtype=numpy.complex128)
        util.log_debug_array(LOG, coef, "coef")
        scales = numpy.arange(0, nf, 1)
        for i in scales:
            f0 = freqs[i]
            SDt = sigma_t[(0, i)]
            A = Amp[(0, i)]
            x = numpy.arange(0, 4.0 * SDt * sample_rate, 1) / sample_rate
            wvlt = A * numpy.exp(-x**2 / (2.0 * SDt**2)) * numpy.exp(
                2j * numpy.pi * f0 * x)
            wvlt = numpy.hstack((numpy.conjugate(wvlt[-1:0:-1]), wvlt))
            #util.log_debug_array(LOG, wvlt, "wvlt")

            for var in range(ts_shape[1]):
                for node in range(ts_shape[2]):
                    for mode in range(ts_shape[3]):
                        data = self.time_series.data[:, var, node, mode]
                        wt = signal.convolve(data, wvlt, 'same')
                        #util.log_debug_array(LOG, wt, "wt")
                        res = wt[0::temporal_step]
                        #NOTE: this is a horrible horrible quick hack (alas, a solution) to avoid broadcasting errors
                        # when using dt and sample periods which are not powers of 2.
                        coef[i, :, var, node, mode] = res if len(
                            res) == nt else res[:coef.shape[1]]

        util.log_debug_array(LOG, coef, "coef")

        spectra = spectral.WaveletCoefficients(
            source=self.time_series,
            mother=self.mother,
            sample_period=self.sample_period,
            frequencies=self.frequencies,
            normalisation=self.normalisation,
            q_ratio=self.q_ratio,
            array_data=coef,
            use_storage=False)

        return spectra
Esempio n. 4
0
def compute_continuous_wavelet_transform(time_series, frequencies,
                                         sample_period, q_ratio, normalisation,
                                         mother):
    """
    # type: (TimeSeries, Range, float, float, str, str)  -> WaveletCoefficients
    Calculate the continuous wavelet transform of time_series.

    Parameters
    __________

    time_series : TimeSeries
    The timeseries to which the wavelet is to be applied.

    frequencies : Range
    The frequency resolution and range returned. Requested frequencies
    are converted internally into appropriate scales.

    sample_period : float
    The sampling period of the computed wavelet spectrum.

    q_ratio : float
    NFC. Must be greater than 5. Ratios of the center frequencies to bandwidths.

    normalisation : str
    The type of normalisation for the resulting wavet spectrum. Default is 'energy', options are: 'energy'; 'gabor'.

    mother : str
    The mother wavelet function used in the transform.
    """
    ts_shape = time_series.data.shape

    if frequencies.step == 0:
        log.warning("Frequency step can't be 0! Trying default step, 2e-3.")
        frequencies.step = 0.002

    freqs = numpy.arange(frequencies.lo, frequencies.hi, frequencies.step)

    if (freqs.size == 0) or any(freqs <= 0.0):
        # TODO: Maybe should limit number of freqs... ~100 is probably a reasonable upper bound.
        log.warning("Invalid frequency range! Falling back to default.")
        log.debug("freqs")
        log.debug(narray_describe(freqs))
        frequencies = Range(lo=0.008, hi=0.060, step=0.002)
        freqs = numpy.arange(frequencies.lo, frequencies.hi, frequencies.step)

    log.debug("freqs")
    log.debug(narray_describe(freqs))

    sample_rate = time_series.sample_rate

    # Duke: code below is as given by Andreas Spiegler, I've just wrapped
    # some of the original argument names
    nf = len(freqs)
    temporal_step = max(
        (1,
         ReferenceBackend.iround(sample_period / time_series.sample_period)))
    nt = int(numpy.ceil(ts_shape[0] / temporal_step))

    if not isinstance(q_ratio, numpy.ndarray):
        new_q_ratio = q_ratio * numpy.ones((1, nf))

    if numpy.nanmin(new_q_ratio) < 5:
        msg = "q_ratio must be not lower than 5 !"
        log.error(msg)
        raise Exception(msg)

    if numpy.nanmax(freqs) > sample_rate / 2.0:
        msg = "Sampling rate is too low for the requested frequency range !"
        log.error(msg)
        raise Exception(msg)

    # TODO: This isn't used, but min frequency seems like it should be important... Check with A.S.
    #  fmin = 3.0 * numpy.nanmin(q_ratio) * sample_rate / numpy.pi / nt
    sigma_f = freqs / new_q_ratio
    sigma_t = 1.0 / (2.0 * numpy.pi * sigma_f)

    if normalisation == 'energy':
        Amp = 1.0 / numpy.sqrt(sample_rate * numpy.sqrt(numpy.pi) * sigma_t)
    elif normalisation == 'gabor':
        Amp = numpy.sqrt(2.0 / numpy.pi) / sample_rate / sigma_t

    coef_shape = (nf, nt, ts_shape[1], ts_shape[2], ts_shape[3])

    coef = numpy.zeros(coef_shape, dtype=numpy.complex128)
    log.debug("coef")
    log.debug(narray_describe(coef))

    scales = numpy.arange(0, nf, 1)
    for i in scales:
        f0 = freqs[i]
        SDt = sigma_t[(0, i)]
        A = Amp[(0, i)]
        x = numpy.arange(0, 4.0 * SDt * sample_rate, 1) / sample_rate
        wvlt = A * numpy.exp(-x**2 / (2.0 * SDt**2)) * numpy.exp(
            2j * numpy.pi * f0 * x)
        wvlt = numpy.hstack((numpy.conjugate(wvlt[-1:0:-1]), wvlt))
        # util.self.log_debug_array(self.log, wvlt, "wvlt")

        for var in range(ts_shape[1]):
            for node in range(ts_shape[2]):
                for mode in range(ts_shape[3]):
                    data = time_series.data[:, var, node, mode]
                    wt = signal.convolve(data, wvlt, 'same')
                    # util.self.log_debug_array(self.log, wt, "wt")
                    res = wt[0::temporal_step]
                    # NOTE: this is a horrible horrible quick hack (alas, a solution) to avoid broadcasting errors
                    # when using dt and sample periods which are not powers of 2.
                    coef[i, :, var, node,
                         mode] = res if len(res) == nt else res[:coef.shape[1]]

    log.debug("coef")
    log.debug(narray_describe(coef))

    spectra = spectral.WaveletCoefficients(source=time_series,
                                           mother=mother,
                                           sample_period=sample_period,
                                           frequencies=frequencies.to_array(),
                                           normalisation=normalisation,
                                           q_ratio=q_ratio,
                                           array_data=coef)

    return spectra