From 6daa97c1cbe8ff702715c731a5535e39573a776c Mon Sep 17 00:00:00 2001 From: Moritz Huebner <moritz.huebner@ligo.org> Date: Mon, 4 Feb 2019 22:40:41 -0600 Subject: [PATCH] Utils upgrade --- CHANGELOG.md | 2 + bilby/core/__init__.py | 2 +- bilby/{gw => core}/series.py | 6 +- bilby/core/utils.py | 154 +++++++++++++++++++-------------- bilby/gw/__init__.py | 2 +- bilby/gw/detector.py | 2 +- bilby/gw/waveform_generator.py | 2 +- test/detector_test.py | 7 +- test/noise_realisation_test.py | 16 ++-- test/series_test.py | 63 ++++++++------ test/utils_test.py | 101 ++++++++++++++++++--- 11 files changed, 233 insertions(+), 124 deletions(-) rename bilby/{gw => core}/series.py (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 593e16b1..f22560ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - ### Changed +- Time/frequency array generation/conversion improved. We now impose `duration` is an integer multiple of + `sampling_frequency`. Converting back and forth between time/frequency arrays now works for all valid arrays. - Updates the bilby.core.utils constants to match those of Astropy v3.0.4 ### Removed diff --git a/bilby/core/__init__.py b/bilby/core/__init__.py index daa0c453..9d1dd51e 100644 --- a/bilby/core/__init__.py +++ b/bilby/core/__init__.py @@ -1,2 +1,2 @@ from __future__ import absolute_import -from . import likelihood, prior, result, sampler, utils +from . import likelihood, prior, result, sampler, series, utils diff --git a/bilby/gw/series.py b/bilby/core/series.py similarity index 97% rename from bilby/gw/series.py rename to bilby/core/series.py index a83a0a65..980c6c11 100644 --- a/bilby/gw/series.py +++ b/bilby/core/series.py @@ -1,4 +1,4 @@ -from ..core import utils +from . import utils class CoupledTimeAndFrequencySeries(object): @@ -15,8 +15,8 @@ class CoupledTimeAndFrequencySeries(object): start_time: float, optional Starting time of the time array """ - self.duration = duration - self.sampling_frequency = sampling_frequency + self._duration = duration + self._sampling_frequency = sampling_frequency self.start_time = start_time self._frequency_array_updated = False self._time_array_updated = False diff --git a/bilby/core/utils.py b/bilby/core/utils.py index ce634a6e..1b3b1cfa 100644 --- a/bilby/core/utils.py +++ b/bilby/core/utils.py @@ -20,6 +20,8 @@ parsec = 3.0856775814671916e+16 # m solar_mass = 1.9884754153381438e+30 # Kg radius_of_earth = 6378100.0 # m +_TOL = 14 + def infer_parameters_from_function(func): """ Infers the arguments of a function @@ -59,13 +61,18 @@ def _infer_args_from_function_except_for_first_arg(func): return parameters -def get_sampling_frequency(time_series): +def get_sampling_frequency(time_array): """ Calculate sampling frequency from a time series + Attributes: + ------- + time_array: array_like + Time array to get sampling_frequency from + Returns ------- - float: Sampling frequency of the time series + Sampling frequency of the time series: float Raises ------- @@ -73,19 +80,24 @@ def get_sampling_frequency(time_series): """ tol = 1e-10 - if np.ptp(np.diff(time_series)) > tol: + if np.ptp(np.diff(time_array)) > tol: raise ValueError("Your time series was not evenly sampled") else: - return 1. / (time_series[1] - time_series[0]) + return np.round(1. / (time_array[1] - time_array[0]), decimals=_TOL) def get_sampling_frequency_and_duration_from_time_array(time_array): """ Calculate sampling frequency and duration from a time array + Attributes: + ------- + time_array: array_like + Time array to get sampling_frequency/duration from: array_like + Returns ------- - sampling_frequency, duration: + sampling_frequency, duration: float, float Raises ------- @@ -94,7 +106,7 @@ def get_sampling_frequency_and_duration_from_time_array(time_array): """ sampling_frequency = get_sampling_frequency(time_array) - duration = time_array[-1] - time_array[0] + duration = len(time_array) / sampling_frequency return sampling_frequency, duration @@ -102,9 +114,14 @@ def get_sampling_frequency_and_duration_from_frequency_array(frequency_array): """ Calculate sampling frequency and duration from a frequency array + Attributes: + ------- + frequency_array: array_like + Frequency array to get sampling_frequency/duration from: array_like + Returns ------- - sampling_frequency, duration: + sampling_frequency, duration: float, float Raises ------- @@ -118,8 +135,9 @@ def get_sampling_frequency_and_duration_from_frequency_array(frequency_array): number_of_frequencies = len(frequency_array) delta_freq = frequency_array[1] - frequency_array[0] - duration = 1 / delta_freq - sampling_frequency = 2 * number_of_frequencies / duration + duration = np.round(1 / delta_freq, decimals=_TOL) + + sampling_frequency = np.round(2 * (number_of_frequencies - 1) / duration, decimals=14) return sampling_frequency, duration @@ -137,7 +155,57 @@ def create_time_series(sampling_frequency, duration, starting_time=0.): float: An equidistant time series given the parameters """ - return np.arange(starting_time, starting_time + duration, 1. / sampling_frequency) + _check_legal_sampling_frequency_and_duration(sampling_frequency, duration) + number_of_samples = int(duration * sampling_frequency) + return np.linspace(start=starting_time, + stop=duration + starting_time - 1 / sampling_frequency, + num=number_of_samples) + + +def create_frequency_series(sampling_frequency, duration): + """ Create a frequency series with the correct length and spacing. + + Parameters + ------- + sampling_frequency: float + duration: float + + Returns + ------- + array_like: frequency series + + """ + _check_legal_sampling_frequency_and_duration(sampling_frequency, duration) + number_of_samples = int(np.round(duration * sampling_frequency)) + number_of_frequencies = int(np.round(number_of_samples / 2) + 1) + + return np.linspace(start=0, + stop=sampling_frequency / 2, + num=number_of_frequencies) + + +def _check_legal_sampling_frequency_and_duration(sampling_frequency, duration): + """ By convention, sampling_frequency and duration have to multiply to an integer + + This will check if the product of both parameters multiplies reasonably close + to an integer. + + Parameters + ------- + sampling_frequency: float + duration: float + + """ + num = sampling_frequency * duration + if np.abs(num - np.round(num)) > _TOL: + raise IllegalDurationAndSamplingFrequencyException( + '\nYour sampling frequency and duration must multiply to a number' + 'up to (tol = {}) decimals close to an integer number. ' + '\nBut sampling_frequency={} and duration={} multiply to {}'.format( + _TOL, sampling_frequency, duration, + sampling_frequency * duration + ) + ) def ra_dec_to_theta_phi(ra, dec, gmst): @@ -190,38 +258,6 @@ def gps_time_to_gmst(gps_time): return gmst -def create_frequency_series(sampling_frequency, duration): - """ Create a frequency series with the correct length and spacing. - - Parameters - ------- - sampling_frequency: float - duration: float - duration of data - - Returns - ------- - array_like: frequency series - - """ - number_of_samples = duration * sampling_frequency - number_of_samples = int(np.round(number_of_samples)) - - # prepare for FFT - number_of_frequencies = (number_of_samples - 1) // 2 - delta_freq = 1. / duration - - frequencies = delta_freq * np.linspace(1, number_of_frequencies, number_of_frequencies) - - if len(frequencies) % 2 == 1: - frequencies = np.concatenate(([0], frequencies, [sampling_frequency / 2.])) - else: - # no Nyquist frequency when N=odd - frequencies = np.concatenate(([0], frequencies)) - - return frequencies - - def create_white_noise(sampling_frequency, duration): """ Create white_noise which is then coloured by a given PSD @@ -279,30 +315,18 @@ def nfft(time_domain_strain, sampling_frequency): Returns ------- - frequency_domain_strain, frequency_array: (array, array) + frequency_domain_strain, frequency_array: (array_like, array_like) Single-sided FFT of time domain strain normalised to units of strain / Hz, and the associated frequency_array. """ - - if np.ndim(sampling_frequency) != 0: - raise ValueError("Sampling frequency must be interger or float") - - # add one zero padding if time series doesn't have even number of samples - if np.mod(len(time_domain_strain), 2) == 1: - time_domain_strain = np.append(time_domain_strain, 0) - LL = len(time_domain_strain) - # frequency range - frequency_array = sampling_frequency / 2 * np.linspace(0, 1, int(LL / 2 + 1)) - - # calculate FFT - # rfft computes the fft for real inputs frequency_domain_strain = np.fft.rfft(time_domain_strain) + frequency_domain_strain /= sampling_frequency - # normalise to units of strain / Hz - norm_frequency_domain_strain = frequency_domain_strain / sampling_frequency + frequency_array = np.linspace( + 0, sampling_frequency / 2, len(frequency_domain_strain)) - return norm_frequency_domain_strain, frequency_array + return frequency_domain_strain, frequency_array def infft(frequency_domain_strain, sampling_frequency): @@ -313,18 +337,14 @@ def infft(frequency_domain_strain, sampling_frequency): frequency_domain_strain: array_like Single-sided, normalised FFT of the time-domain strain data (in units of strain / Hz). - sampling_frequency: float + sampling_frequency: int, float Sampling frequency of the data. Returns ------- - time_domain_strain: array + time_domain_strain: array_like An array of the time domain strain """ - - if np.ndim(sampling_frequency) != 0: - raise ValueError("Sampling frequency must be integer or float") - time_domain_strain_norm = np.fft.irfft(frequency_domain_strain) time_domain_strain = time_domain_strain_norm * sampling_frequency return time_domain_strain @@ -729,3 +749,7 @@ else: break except Exception: print(traceback.format_exc()) + + +class IllegalDurationAndSamplingFrequencyException(Exception): + pass diff --git a/bilby/gw/__init__.py b/bilby/gw/__init__.py index b76318a7..75e3a380 100644 --- a/bilby/gw/__init__.py +++ b/bilby/gw/__init__.py @@ -1,4 +1,4 @@ -from . import (calibration, conversion, detector, likelihood, prior, series, source, +from . import (calibration, conversion, detector, likelihood, prior, source, utils, waveform_generator, result) from .waveform_generator import WaveformGenerator diff --git a/bilby/gw/detector.py b/bilby/gw/detector.py index 599f4924..38db420b 100644 --- a/bilby/gw/detector.py +++ b/bilby/gw/detector.py @@ -12,8 +12,8 @@ import deepdish as dd from . import utils as gwutils from ..core import utils from ..core.utils import logger +from ..core.series import CoupledTimeAndFrequencySeries from .calibration import Recalibrate -from .series import CoupledTimeAndFrequencySeries try: import gwpy diff --git a/bilby/gw/waveform_generator.py b/bilby/gw/waveform_generator.py index 6e9a5f6a..00e24bde 100644 --- a/bilby/gw/waveform_generator.py +++ b/bilby/gw/waveform_generator.py @@ -1,7 +1,7 @@ import numpy as np from ..core import utils -from ..gw.series import CoupledTimeAndFrequencySeries +from ..core.series import CoupledTimeAndFrequencySeries class WaveformGenerator(object): diff --git a/test/detector_test.py b/test/detector_test.py index 527f1e74..95b2f5f3 100644 --- a/test/detector_test.py +++ b/test/detector_test.py @@ -545,7 +545,8 @@ class TestInterferometerStrainData(unittest.TestCase): sampling_frequency = 10 time_array = bilby.core.utils.create_time_series( sampling_frequency=sampling_frequency, duration=duration) - time_domain_strain = np.random.normal(0, 1, len(time_array)) + time_domain_strain = np.random.normal( + 0, duration - 1 / sampling_frequency, len(time_array)) self.ifosd.roll_off = 0 self.ifosd.set_from_time_domain_strain( time_domain_strain=time_domain_strain, duration=duration, @@ -711,11 +712,11 @@ class TestInterferometerStrainDataEquals(unittest.TestCase): self.assertNotEqual(self.ifosd_1, self.ifosd_2) def test_eq_different_sampling_frequency(self): - self.ifosd_1.sampling_frequency -= 0.1 + self.ifosd_1.sampling_frequency *= 2 self.assertNotEqual(self.ifosd_1, self.ifosd_2) def test_eq_different_sampling_duration(self): - self.ifosd_1.duration -= 0.1 + self.ifosd_1.duration *= 2 self.assertNotEqual(self.ifosd_1, self.ifosd_2) def test_eq_different_start_time(self): diff --git a/test/noise_realisation_test.py b/test/noise_realisation_test.py index 026af6d0..15aa404f 100644 --- a/test/noise_realisation_test.py +++ b/test/noise_realisation_test.py @@ -22,27 +22,25 @@ class TestNoiseRealisation(unittest.TestCase): a = np.nan_to_num(interferometer.amplitude_spectral_density_array / factor * interferometer.frequency_mask) b = asd_avg - print(a, b) self.assertTrue(np.allclose(a, b, rtol=1e-1)) def test_noise_normalisation(self): - time_duration = 1. + duration = 1. sampling_frequency = 4096. - time_array = bilby.core.utils.create_time_series(sampling_frequency=sampling_frequency, duration=time_duration) + time_array = bilby.core.utils.create_time_series( + sampling_frequency=sampling_frequency, duration=duration) # generate some toy-model signal for matched filtering SNR testing n_avg = 1000 snr = np.zeros(n_avg) - mu = np.exp(-(time_array-time_duration/2.)**2 / (2.*0.1**2)) * np.sin(2*np.pi*100*time_array) + mu = (np.exp(-(time_array-duration/2.)**2 / (2.*0.1**2)) + * np.sin(2 * np.pi * 100 * time_array)) muf, frequency_array = bilby.core.utils.nfft(mu, sampling_frequency) for x in range(0, n_avg): interferometer = bilby.gw.detector.get_empty_interferometer('H1') interferometer.set_strain_data_from_power_spectral_density( - sampling_frequency=sampling_frequency, duration=time_duration) - hf_tmp = interferometer.strain_data.frequency_domain_strain - psd = interferometer.power_spectral_density - snr[x] = bilby.gw.utils.inner_product(hf_tmp, muf, frequency_array, psd) \ - / np.sqrt(bilby.gw.utils.inner_product(muf, muf, frequency_array, psd)) + sampling_frequency=sampling_frequency, duration=duration) + snr[x] = interferometer.matched_filter_snr(signal=muf) self.assertTrue(np.isclose(np.std(snr), 1.00, atol=1e-1)) diff --git a/test/series_test.py b/test/series_test.py index 685164ab..1eeec8ca 100644 --- a/test/series_test.py +++ b/test/series_test.py @@ -1,8 +1,10 @@ from __future__ import absolute_import import unittest -import bilby import numpy as np +from bilby.core.utils import create_frequency_series, create_time_series +from bilby.core.series import CoupledTimeAndFrequencySeries + class TestCoupledTimeAndFrequencySeries(unittest.TestCase): @@ -10,9 +12,9 @@ class TestCoupledTimeAndFrequencySeries(unittest.TestCase): self.duration = 2 self.sampling_frequency = 4096 self.start_time = -1 - self.series = bilby.gw.series.CoupledTimeAndFrequencySeries(duration=self.duration, - sampling_frequency=self.sampling_frequency, - start_time=self.start_time) + self.series = CoupledTimeAndFrequencySeries( + duration=self.duration, sampling_frequency=self.sampling_frequency, + start_time=self.start_time) def tearDown(self): del self.duration @@ -21,17 +23,19 @@ class TestCoupledTimeAndFrequencySeries(unittest.TestCase): del self.series def test_repr(self): - expected = 'CoupledTimeAndFrequencySeries(duration={}, sampling_frequency={}, start_time={})'\ - .format(self.series.duration, - self.series.sampling_frequency, - self.series.start_time) + expected =\ + 'CoupledTimeAndFrequencySeries(duration={}, sampling_frequency={},'\ + ' start_time={})'.format( + self.series.duration, self.series.sampling_frequency, + self.series.start_time) self.assertEqual(expected, repr(self.series)) def test_duration_from_init(self): self.assertEqual(self.duration, self.series.duration) def test_sampling_from_init(self): - self.assertEqual(self.sampling_frequency, self.series.sampling_frequency) + self.assertEqual( + self.sampling_frequency, self.series.sampling_frequency) def test_start_time_from_init(self): self.assertEqual(self.start_time, self.series.start_time) @@ -43,24 +47,26 @@ class TestCoupledTimeAndFrequencySeries(unittest.TestCase): self.assertIsInstance(self.series.time_array, np.ndarray) def test_frequency_array_from_init(self): - expected = bilby.core.utils.create_frequency_series(sampling_frequency=self.sampling_frequency, - duration=self.duration) + expected = create_frequency_series( + sampling_frequency=self.sampling_frequency, duration=self.duration) self.assertTrue(np.array_equal(expected, self.series.frequency_array)) def test_time_array_from_init(self): - expected = bilby.core.utils.create_time_series(sampling_frequency=self.sampling_frequency, - duration=self.duration, - starting_time=self.start_time) + expected = create_time_series( + sampling_frequency=self.sampling_frequency, duration=self.duration, + starting_time=self.start_time) self.assertTrue(np.array_equal(expected, self.series.time_array)) def test_frequency_array_setter(self): new_sampling_frequency = 100 new_duration = 3 - new_frequency_array = bilby.core.utils.create_frequency_series(sampling_frequency=new_sampling_frequency, - duration=new_duration) + new_frequency_array = create_frequency_series( + sampling_frequency=new_sampling_frequency, duration=new_duration) self.series.frequency_array = new_frequency_array - self.assertTrue(np.array_equal(new_frequency_array, self.series.frequency_array)) - self.assertLessEqual(np.abs(new_sampling_frequency - self.series.sampling_frequency), 1) + self.assertTrue(np.array_equal( + new_frequency_array, self.series.frequency_array)) + self.assertLessEqual(np.abs( + new_sampling_frequency - self.series.sampling_frequency), 1) self.assertAlmostEqual(new_duration, self.series.duration) self.assertAlmostEqual(self.start_time, self.series.start_time) @@ -68,12 +74,13 @@ class TestCoupledTimeAndFrequencySeries(unittest.TestCase): new_sampling_frequency = 100 new_duration = 3 new_start_time = 4 - new_time_array = bilby.core.utils.create_time_series(sampling_frequency=new_sampling_frequency, - duration=new_duration, - starting_time=new_start_time) + new_time_array = create_time_series( + sampling_frequency=new_sampling_frequency, duration=new_duration, + starting_time=new_start_time) self.series.time_array = new_time_array self.assertTrue(np.array_equal(new_time_array, self.series.time_array)) - self.assertAlmostEqual(new_sampling_frequency, self.series.sampling_frequency, places=1) + self.assertAlmostEqual( + new_sampling_frequency, self.series.sampling_frequency, places=1) self.assertAlmostEqual(new_duration, self.series.duration, places=1) self.assertAlmostEqual(new_start_time, self.series.start_time, places=1) @@ -81,22 +88,26 @@ class TestCoupledTimeAndFrequencySeries(unittest.TestCase): self.series.sampling_frequency = None self.series.duration = 4 with self.assertRaises(ValueError): - test = self.series.time_array + _ = self.series.time_array def test_time_array_without_duration(self): self.series.sampling_frequency = 4096 self.series.duration = None with self.assertRaises(ValueError): - test = self.series.time_array + _ = self.series.time_array def test_frequency_array_without_sampling_frequency(self): self.series.sampling_frequency = None self.series.duration = 4 with self.assertRaises(ValueError): - test = self.series.frequency_array + _ = self.series.frequency_array def test_frequency_array_without_duration(self): self.series.sampling_frequency = 4096 self.series.duration = None with self.assertRaises(ValueError): - test = self.series.frequency_array + _ = self.series.frequency_array + + +if __name__ == '__main__': + unittest.main() diff --git a/test/utils_test.py b/test/utils_test.py index ad1d2278..3b5645c8 100644 --- a/test/utils_test.py +++ b/test/utils_test.py @@ -26,25 +26,27 @@ class TestConstants(unittest.TestCase): class TestFFT(unittest.TestCase): def setUp(self): - pass + self.sampling_frequency = 10 def tearDown(self): - pass + del self.sampling_frequency - def test_nfft_frequencies(self): - f = 2.1 - sampling_frequency = 10 - times = np.arange(0, 100, 1/sampling_frequency) - tds = np.sin(2*np.pi*times * f + 0.4) - fds, freqs = bilby.core.utils.nfft(tds, sampling_frequency) - self.assertTrue(np.abs((f-freqs[np.argmax(np.abs(fds))])/f < 1e-15)) + def test_nfft_sine_function(self): + injected_frequency = 2.7324 + duration = 100 + times = utils.create_time_series(self.sampling_frequency, duration) + + time_domain_strain = np.sin(2 * np.pi * times * injected_frequency + 0.4) + + frequency_domain_strain, frequencies = bilby.core.utils.nfft(time_domain_strain, self.sampling_frequency) + frequency_at_peak = frequencies[np.argmax(np.abs(frequency_domain_strain))] + self.assertAlmostEqual(injected_frequency, frequency_at_peak, places=1) def test_nfft_infft(self): - sampling_frequency = 10 - tds = np.random.normal(0, 1, 10) - fds, _ = bilby.core.utils.nfft(tds, sampling_frequency) - tds2 = bilby.core.utils.infft(fds, sampling_frequency) - self.assertTrue(np.all(np.abs((tds - tds2) / tds) < 1e-12)) + time_domain_strain = np.random.normal(0, 1, 10) + frequency_domain_strain, _ = bilby.core.utils.nfft(time_domain_strain, self.sampling_frequency) + new_time_domain_strain = bilby.core.utils.infft(frequency_domain_strain, self.sampling_frequency) + self.assertTrue(np.allclose(time_domain_strain, new_time_domain_strain)) class TestInferParameters(unittest.TestCase): @@ -76,5 +78,76 @@ class TestInferParameters(unittest.TestCase): self.assertListEqual(expected, actual) +class TestTimeAndFrequencyArrays(unittest.TestCase): + + def setUp(self): + self.start_time = 1.3 + self.sampling_frequency = 5 + self.duration = 1.6 + self.frequency_array = utils.create_frequency_series(sampling_frequency=self.sampling_frequency, + duration=self.duration) + self.time_array = utils.create_time_series(sampling_frequency=self.sampling_frequency, + duration=self.duration, + starting_time=self.start_time) + + def tearDown(self): + del self.start_time + del self.sampling_frequency + del self.duration + del self.frequency_array + del self.time_array + + def test_create_time_array(self): + expected_time_array = np.array([1.3, 1.5, 1.7, 1.9, 2.1, 2.3, 2.5, 2.7]) + time_array = utils.create_time_series(sampling_frequency=self.sampling_frequency, + duration=self.duration, starting_time=self.start_time) + self.assertTrue(np.allclose(expected_time_array, time_array)) + + def test_create_frequency_array(self): + expected_frequency_array = np.array([0.0, 0.625, 1.25, 1.875, 2.5]) + frequency_array = utils.create_frequency_series(sampling_frequency=self.sampling_frequency, + duration=self.duration) + self.assertTrue(np.allclose(expected_frequency_array, frequency_array)) + + def test_get_sampling_frequency_from_time_array(self): + new_sampling_freq, _ = utils.get_sampling_frequency_and_duration_from_time_array( + self.time_array) + self.assertEqual(self.sampling_frequency, new_sampling_freq) + + def test_get_duration_from_time_array(self): + _, new_duration = utils.get_sampling_frequency_and_duration_from_time_array(self.time_array) + self.assertEqual(self.duration, new_duration) + + def test_get_start_time_from_time_array(self): + new_start_time = self.time_array[0] + self.assertEqual(self.start_time, new_start_time) + + def test_get_sampling_frequency_from_frequency_array(self): + new_sampling_freq, _ = utils.get_sampling_frequency_and_duration_from_frequency_array( + self.frequency_array) + self.assertEqual(self.sampling_frequency, new_sampling_freq) + + def test_get_duration_from_frequency_array(self): + _, new_duration = utils.get_sampling_frequency_and_duration_from_frequency_array( + self.frequency_array) + self.assertEqual(self.duration, new_duration) + + def test_consistency_time_array_to_time_array(self): + new_sampling_frequency, new_duration = \ + utils.get_sampling_frequency_and_duration_from_time_array(self.time_array) + new_start_time = self.time_array[0] + new_time_array = utils.create_time_series(sampling_frequency=new_sampling_frequency, + duration=new_duration, + starting_time=new_start_time) + self.assertTrue(np.allclose(self.time_array, new_time_array)) + + def test_consistency_frequency_array_to_frequency_array(self): + new_sampling_frequency, new_duration = utils.get_sampling_frequency_and_duration_from_frequency_array(self.frequency_array) + new_frequency_array = \ + utils.create_frequency_series(sampling_frequency=new_sampling_frequency, + duration=new_duration) + self.assertTrue(np.allclose(self.frequency_array, new_frequency_array)) + + if __name__ == '__main__': unittest.main() -- GitLab