def test_need_both_frequency_and_sideband(self): frequency = 311.25 * u.MHz + (np.arange(8.) // 2) * 16. * u.MHz sideband = np.tile([-1, +1], 4) with pytest.raises(ValueError): SetAttribute(self.fh, frequency=frequency) with pytest.raises(ValueError): SetAttribute(self.fh, sideband=sideband)
def test_dtype(self): expected = self.fh.read() sa = SetAttribute(self.fh, dtype='f2') assert isinstance(sa.dtype, np.dtype) assert sa.dtype == 'f2' data = sa.read() assert data.dtype == 'f2' assert np.all(data == expected.astype('f2'))
def setup(self): self.fh = baseband.open(baseband.data.SAMPLE_VDIF) self.data = self.fh.read() self.fh.seek(0) frequency = 311.25 * u.MHz + (np.arange(8.) // 2) * 16. * u.MHz sideband = np.tile([-1, +1], 4) self.wrapped = SetAttribute(self.fh, frequency=frequency, sideband=sideband)
def test_polarization_propagation(self): # Add polarization information by hand. fh = SetAttribute(self.fh, polarization=np.array(['L', 'R'])) pt = Power(fh) assert np.all(pt.polarization == np.array(['LL', 'RR', 'LR', 'RL'])) assert repr(pt).startswith('Power(ih)\n') # Swap order. fh2 = SetAttribute(self.fh, polarization=np.array(['R', 'L'])) pt = Power(fh2) assert np.all(pt.polarization == np.array(['RR', 'LL', 'RL', 'LR'])) pt.close()
def test_wrong_time(self): fh = self.fh s1 = GetItem(fh, slice(None, 4)) s2 = SetAttribute(GetItem(fh, slice(4, None)), start_time=fh.start_time + 1.5 / fh.sample_rate) with pytest.raises(ValueError): Concatenate([s1, s2])
def test_wrong_polarization_vdif(self): with pytest.raises(AttributeError): Power(self.fh) fh = SetAttribute(self.fh, polarization=np.array(['L', 'R'] * 4)) with pytest.raises(ValueError): # Too many. Power(fh)
class StreamSetup: def setup(self): self.fh = baseband.open(baseband.data.SAMPLE_VDIF) self.data = self.fh.read() self.fh.seek(0) frequency = 311.25 * u.MHz + (np.arange(8.) // 2) * 16. * u.MHz sideband = np.tile([-1, +1], 4) self.wrapped = SetAttribute(self.fh, frequency=frequency, sideband=sideband) def teardown(self): self.wrapped.close() self.fh.close() def check(self, stream, header, attrs=None, exclude=()): if attrs is None: if hasattr(stream, 'bps'): attrs = ('sample_shape', 'sample_rate', 'time', 'bps', 'complex_data') exclude = ('dtype', ) else: attrs = ('sample_shape', 'dtype', 'sample_rate', 'time', 'frequency', 'sideband') is_header = isinstance(header, hdf5.HDF5Header) if 'shape' not in exclude: assert stream.shape[0] == header.samples_per_frame if is_header: assert stream.shape[0] == header['samples_per_frame'] for attr in attrs: stream_attr = getattr(stream, (attr if attr != 'time' else 'start_time')) header_attr = getattr(header, attr) if attr == 'time': assert np.all(np.abs(header_attr - stream_attr) < 1. * u.ns) else: assert np.all(header_attr == stream_attr) if is_header: if attr in exclude: assert attr not in header else: header_value = header[attr] assert np.all(header_value == stream_attr)
def setup(self): super().setup() self.n = 1024 # Add frequency information by hand for now. self.fh_freq = SetAttribute( self.fh, frequency=self.fh.header0['FREQ']*u.MHz, sideband=np.where(self.fh.header0.sideband, 1, -1))
def test_set_basics(self): expected = self.fh.read() frequency = 311.25 * u.MHz + (np.arange(8.) // 2) * 16. * u.MHz sideband = np.tile([-1, +1], 4) sa = SetAttribute(self.fh, frequency=frequency, sideband=sideband) assert np.all(sa.frequency == frequency) assert np.all(sa.sideband == sideband) for attr in ('start_time', 'sample_rate', 'samples_per_frame', 'shape', 'dtype'): assert getattr(sa, attr) == getattr(self.fh, attr) # Check that frequency does not propagate. frequency[...] = 0 assert np.all(sa.frequency != 0) sideband[...] = 0 assert np.all(np.abs(sa.sideband) == 1) # Check data can be read. data = sa.read() assert np.all(data == expected) # Check we didn't magically define polarization. with pytest.raises(AttributeError): sa.polarization sa.close()
def test_frequency_sideband_propagation(self): # Add frequency and sideband information by hand. # (Note: sideband is incorrect; just for testing purposes) fh = SetAttribute( self.fh, frequency=311.25 * u.MHz + (np.arange(8.) // 2) * 16. * u.MHz, sideband=np.tile([-1, +1], 4), polarization=np.tile(['L', 'R'], 4)) st = Square(fh) assert np.all(st.frequency == fh.frequency) assert np.all(st.sideband == fh.sideband) assert np.all(st.polarization == np.tile(['LL', 'RR'], 4)) st.close()
def get_tel(self, delay=None, n=None): """Get signal from CHIME-like telescope.""" if delay is None: fh = self.raw else: delay_time = delay / self.raw.sample_rate fh = SetAttribute(self.raw, start_time=self.start_time - delay_time) if n is None: n = self.ns_chan # Observe the raw, possibly delayed samples, using channelizer return Channelize(fh, n, frequency=self.full_sample_rate, sideband=self.sideband)
def test_frequency_sideband_polarization_propagation2(self): # Add different frequency, sideband, and polarization information. # (Note: these are incorrect; just for testing purposes.) fh = SetAttribute(self.fh, frequency=311.25 * u.MHz + (np.arange(8.) // 4) * 16. * u.MHz, sideband=np.tile([-1, 1], 4), polarization=np.tile(['L', 'L', 'R', 'R'], 2)) tt = self.get_reshape_and_transpose(fh, (2, 2, 2), (-1, -3, -2)) assert tt.frequency.shape == (2, 1) assert np.all(tt.frequency == fh.frequency[::4].reshape(2, 1)) assert tt.sideband.shape == (2, 1, 1) assert np.all(tt.sideband == fh.sideband[:2].reshape(2, 1, 1)) assert tt.polarization.shape == (2, ) assert np.all(tt.polarization == fh.polarization[:4:2])
def test_channelize_frequency_complex(self): """Test frequency calculation.""" fh = self.fh_freq ct = Channelize(fh, self.n) ref_frequency = (320. * u.MHz + np.fft.fftfreq(self.n, 1. / fh.sample_rate)) assert np.all(ct.sideband == fh.sideband) assert np.all(ct.frequency == ref_frequency[:, np.newaxis]) fh = SetAttribute(self.fh, frequency=self.fh_freq.frequency, sideband=-self.fh_freq.sideband) ct = Channelize(fh, self.n) ref_frequency = (320. * u.MHz - np.fft.fftfreq(self.n, 1. / fh.sample_rate)) assert np.all(ct.sideband == fh.sideband) assert np.all(ct.frequency == ref_frequency[:, np.newaxis])
def test_metadata_propagation(self): sa = SetAttribute(self.fh) sa.meta['parrot'] = 'dead' assert not hasattr(sa, 'frequency') sa2 = SetAttribute(sa, frequency=300 * u.MHz, sideband=1) assert sa2.frequency is not None assert sa2.sideband is not None assert set(sa2.meta) == {'parrot', '__attributes__'} assert sa2.meta['parrot'] == 'dead' sa2.meta['parrot'] = 'goner' assert sa2.meta['parrot'] == 'goner' assert sa.meta['parrot'] == 'dead'
def test_samples_per_frame(self): expected = self.fh.read() sa = SetAttribute(self.fh, samples_per_frame=11111) assert sa.shape == (33333, 8) data = sa.read() assert np.all(data == expected[:33333]) sa2 = SetAttribute(self.fh, samples_per_frame=11111, shape=self.fh.shape) assert sa2.shape == self.fh.shape data2 = sa2.read() assert np.all(data2 == expected)
def get_tel(self, delay=None, n=None): """Get signal as observed at a telescope with the given delay and number of channels.""" if delay is None: fh = self.raw else: delay_time = delay / self.raw.sample_rate fh = SetAttribute(self.raw, start_time=self.start_time - delay_time) # Observe the raw, possibly delayed samples, using mix_downsample. obs = Task(fh, self.mix_downsample, dtype=self.dtype, sample_rate=self.sample_rate, frequency=self.lo, sideband=self.sideband) if n is None: return obs else: return Channelize(obs, n)
def test_complex_stream(self, tmpdir): filename = str(tmpdir.join('copy.hdf5')) with baseband.vdif.open(baseband.data.SAMPLE_AROCHIME_VDIF, 'rs', sample_rate=800 * u.MHz / 2048) as fh: wrapped = SetAttribute(fh) data = wrapped.read() wrapped.seek(0) with hdf5.open(filename, 'w', template=wrapped) as f5w: assert f5w.complex_data assert f5w.header0.encoded_dtype == 'c8' wrapped.read(out=f5w) with hdf5.open(filename, 'r') as f5r: self.check(wrapped, f5r, ('sample_shape', 'dtype', 'sample_rate', 'time')) assert f5r.header0.encoded_dtype == 'c8' recovered = f5r.read() # Cannot recover exactly, given scaling, but should be within # tolerance for float16. assert_array_equal(recovered, data)
def setup(self): """Pre-calculate channelized data.""" super().setup() self.n = 1024 self.ref_start_time = self.fh.start_time self.ref_sample_rate = self.fh.sample_rate data = self.fh.read() self.raw_data = data last_sample = self.n * (data.shape[0] // self.n) part = data[:last_sample].reshape((-1, self.n) + data.shape[1:]) rfft = fft_maker(shape=part.shape, dtype=part.dtype, axis=1, sample_rate=self.ref_sample_rate) self.ref_data = rfft(part) # Note: sideband is actually incorrect for this VDIF file; # this is for testing only. self.ref_sideband = np.tile([-1, 1], 4) self.ref_frequency = ((311.25 + 16 * (np.arange(8) // 2)) * u.MHz + self.ref_sideband * rfft.frequency) self.fh_freq = SetAttribute( self.fh, frequency=311.25*u.MHz+(np.arange(8.)//2)*16.*u.MHz, sideband=np.tile([-1, +1], 4))
def test_time_offsets(self, samples_per_frame): fh = self.fh s1 = GetItem(fh, slice(None, 4)) s2 = SetAttribute(GetItem(fh, slice(4, None)), start_time=fh.start_time + 10 / fh.sample_rate) fh_data = self.fh.read() expected_data = np.concatenate((fh_data[10:, :4], fh_data[:-10, 4:]), axis=1) ch = Concatenate([s1, s2], samples_per_frame=samples_per_frame) assert ch.start_time == s2.start_time assert ch.shape == (fh.shape[0] - 10, ) + fh.sample_shape if samples_per_frame is None: assert ch.samples_per_frame == s1.samples_per_frame else: assert ch.samples_per_frame == samples_per_frame assert ch.sample_rate == fh.sample_rate assert ch.dtype == fh.dtype assert_array_equal(ch.frequency, fh.frequency) assert_array_equal(ch.sideband, fh.sideband) assert_array_equal(ch.polarization, fh.polarization) data = ch.read() assert_array_equal(data, expected_data) ch.close()
def test_complex_stream_as_c4(self, tmpdir): filename = str(tmpdir.join('copy.hdf5')) with baseband.vdif.open(baseband.data.SAMPLE_AROCHIME_VDIF, 'rs', sample_rate=800 * u.MHz / 2048) as fh: wrapped = SetAttribute(fh) data = wrapped.read() wrapped.seek(0) with hdf5.open(filename, 'w', template=wrapped, encoded_dtype='c4') as f5w: assert f5w.complex_data assert f5w.header0.encoded_dtype == hdf5.payload.DTYPE_C4 wrapped.read(out=f5w) with hdf5.open(filename, 'r') as f5r: self.check(wrapped, f5r, ('sample_shape', 'dtype', 'sample_rate', 'time')) assert f5r.header0.encoded_dtype == hdf5.payload.DTYPE_C4 recovered = f5r.read() # Cannot recover exactly, given scaling, but should be within # tolerance for float16. assert np.allclose(recovered, data, atol=0, rtol=np.finfo('f2').eps)
def test_set_start_time(self): expected = self.fh.read() offset = 0.1 * u.s sa = SetAttribute(self.fh, start_time=self.fh.start_time + offset) assert sa.start_time == self.fh.start_time + offset for attr in ('sample_rate', 'samples_per_frame', 'shape', 'dtype'): assert getattr(sa, attr) == getattr(self.fh, attr) data = sa.read() assert np.all(data == expected) sa.seek(10) data2 = sa.read(10) assert np.all(data2 == expected[10:20]) sa.seek(10 / sa.sample_rate) data3 = sa.read(10) assert np.all(data3 == expected[10:20]) sa.seek(sa.start_time + 10 / self.fh.sample_rate) data4 = sa.read(10) assert np.all(data4 == expected[10:20]) for attr in ('frequency', 'sideband', 'polarization'): with pytest.raises(AttributeError): getattr(sa, attr) sa.close()
def test_fail_on_unknown_attribute(self): with pytest.raises(TypeError): SetAttribute(self.fh, freq=1. * u.MHz)