Commit 44f359d6 authored by Gregory Ashton's avatar Gregory Ashton

Add basic time-frequency interoperability

- Adds a time_array and time_domain_strain to the
  InterferometerStrainData
- Adds a test for consistency between the time and frequency domain
  strain
parent e2418f44
......@@ -358,6 +358,22 @@ class TestInterferometerStrainData(unittest.TestCase):
sampling_frequency=sampling_frequency, start_time=10)
self.assertTrue(self.ifosd.start_time == 10)
def test_time_array_frequency_array_consistency(self):
duration = 1
sampling_frequency = 10
time_array = tupak.core.utils.create_time_series(
sampling_frequency=sampling_frequency, duration=duration)
time_domain_strain = np.random.normal(0, 1, len(time_array))
self.ifosd.set_from_time_domain_strain(
time_domain_strain=time_domain_strain, duration=duration,
sampling_frequency=sampling_frequency)
frequency_domain_strain, freqs = tupak.core.utils.nfft(
time_domain_strain, sampling_frequency)
self.assertTrue(np.all(
frequency_domain_strain == self.ifosd.frequency_domain_strain))
#def test_sampling_duration_init(self):
# self.assertIsNone(self.ifo.duration)
......
......@@ -33,6 +33,25 @@ def get_sampling_frequency(time_series):
return 1. / (time_series[1] - time_series[0])
def get_sampling_frequency_and_duration_from_time_array(time_array):
"""
Calculate sampling frequency and duration from a time array
Returns
-------
sampling_frequency, duration:
Raises
-------
ValueError: If the time_array is not evenly sampled.
"""
sampling_frequency = get_sampling_frequency(time_array)
duration = time_array[-1] - time_array[0]
return sampling_frequency, duration
def get_sampling_frequency_and_duration_from_frequency_array(frequency_array):
"""
Calculate sampling frequency and duration from a frequency array
......
......@@ -100,6 +100,16 @@ class InterferometerStrainData(object):
self.start_time = None
self._frequency_domain_strain = None
self._time_domain_strain = None
def _calculate_time_array(self):
""" Calculate the frequency array
Called after sampling_frequency and duration have been set.
"""
self.time_array = utils.create_time_series(
sampling_frequency=self.sampling_frequency, duration=self.duration,
starting_time=self.start_time)
def _calculate_frequency_array(self):
""" Calculate the frequency array
......@@ -107,7 +117,7 @@ class InterferometerStrainData(object):
Called after sampling_frequency and duration have been set.
"""
self.frequency_array = utils.create_frequency_series(
self.sampling_frequency, self.duration)
sampling_frequency=self.sampling_frequency, duration=self.duration)
def time_within_data(self, time):
""" Check if time is within the data span
......@@ -159,16 +169,76 @@ class InterferometerStrainData(object):
return ((self.frequency_array > self.minimum_frequency) &
(self.frequency_array < self.maximum_frequency))
@property
def time_domain_strain(self):
if self._time_domain_strain is not None:
return self._time_domain_strain
elif self._frequency_domain_strain is not None:
time_domain_strain = utils.infft(
self.frequency_domain_strain, self.frequency_array)
self._time_domain_strain = time_domain_strain
return self._time_domain_strain
else:
raise ValueError("time domain strain data not yet set")
@property
def frequency_domain_strain(self):
if self._frequency_domain_strain is not None:
return self._frequency_domain_strain * self.frequency_mask
elif self._time_domain_strain is not None:
frequency_domain_strain, _ = utils.nfft(
self._time_domain_strain, self.sampling_frequency)
self._frequency_domain_strain = frequency_domain_strain
return self._frequency_domain_strain
else:
raise ValueError("strain_data not yet set")
raise ValueError("frequency domain strain data not yet set")
def add_to_frequency_domain_strain(self, x):
self._frequency_domain_strain += x
def _infer_time_domain_dependence(
self, sampling_frequency, duration, time_array):
""" Helper function to figure out if the time_array, or
sampling_frequency and duration where given
"""
if (sampling_frequency is not None) and (duration is not None):
if time_array is not None:
raise ValueError(
"You have given the sampling_frequency, duration, and "
"time_array")
self.sampling_frequency = sampling_frequency
self.duration = duration
self._calculate_time_array()
self._calculate_frequency_array()
elif any(x is not None for x in [sampling_frequency, duration]):
raise ValueError(
"You must provide both sampling_frequency and duration")
elif time_array is not None:
self.sampling_frequency, self.duration = (
utils.get_sampling_frequency_and_duration_from_time_array(
time_array))
self.time_array = np.array(time_array)
else:
raise ValueError(
"Insufficient information given to set time_array")
def set_from_time_domain_strain(
self, time_domain_strain, sampling_frequency=None, duration=None,
start_time=0, time_array=None):
self.start_time = start_time
self._infer_time_domain_dependence(
sampling_frequency=sampling_frequency, duration=duration,
time_array=time_array)
logging.debug('Setting data using provided time_domain_strain')
if np.shape(time_domain_strain) == np.shape(self.time_array):
self._time_domain_strain = time_domain_strain
else:
raise ValueError("Data times do not match time array")
def _infer_frequency_domain_dependence(
self, sampling_frequency, duration, frequency_array):
""" Helper function to figure out if the frequency_array, or
......@@ -182,6 +252,7 @@ class InterferometerStrainData(object):
"frequency_array")
self.sampling_frequency = sampling_frequency
self.duration = duration
self._calculate_time_array()
self._calculate_frequency_array()
elif any(x is not None for x in [sampling_frequency, duration]):
raise ValueError(
......
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