Skip to content

Commit

Permalink
Merge pull request #69 from dhuppenkothen/dhuppenk_improve_error
Browse files Browse the repository at this point in the history
automatic conversion of data column names to lowercase
  • Loading branch information
ceb8 authored Dec 16, 2022
2 parents 00cbc6f + 0f7cab6 commit d2d7450
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 29 deletions.
14 changes: 13 additions & 1 deletion astronify/series/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,19 @@ def data(self):

@data.setter
def data(self, data_table):
assert isinstance(data_table, Table), 'Data must be a Table.'

if not isinstance(data_table, Table):
raise TypeError('Data must be an astropy.table.Table object.')

for c in list(data_table.columns):
data_table.rename_column(c, c.lower())


if self.time_col not in data_table.columns:
raise AttributeError(f"Input Table must contain time column '{self.time_col}'")

if self.val_col not in data_table.columns:
raise AttributeError(f"Input Table must contain a value column '{self.val_col}'")

# Removing any masked values as they interfere with the sonification
if isinstance(data_table[self.val_col], MaskedColumn):
Expand Down
94 changes: 66 additions & 28 deletions astronify/series/tests/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,76 @@ def my_map_func(data): # dummy function
assert (my_pitchmapper([1, 1]) == [0.5, 0.5]).all()


def test_soniseries(tmpdir):
"""
Testing SoniSeries class.
"""
class TestSoniSeries(object):

@classmethod
def setup_class(cls):

cls.data = Table({"time": [0, 1, 2, 3, 4, 5, 6],
"Flux": [1, 2, 1, 2, 5, 3, np.nan]})

cls.soni_obj = SoniSeries(cls.data)

data = Table({"time": [0, 1, 2, 3, 4, 5, 6],
"flux": [1, 2, 1, 2, 5, 3, np.nan]})

# defaults
soni_obj = SoniSeries(data)
assert soni_obj.note_duration == 0.5
assert soni_obj.note_spacing == 0.01
assert soni_obj.gain == 0.05
assert isinstance(soni_obj.server, Server)
assert len(soni_obj.data) == len(data) - 1 # nan row should be removed
assert ~np.isnan(soni_obj.data["flux"]).any()
assert soni_obj.data["flux"].dtype == np.float64

soni_obj.sonify()
assert "asf_pitch" in soni_obj.data.colnames
assert "asf_onsets" in soni_obj.data.colnames
assert soni_obj.data.meta['asf_exposure_time'] == 1
assert soni_obj.data.meta['asf_note_duration'] == soni_obj.note_duration
assert soni_obj.data.meta['asf_spacing'] == soni_obj.note_spacing
def test_soniseries_initializes(self):
SoniSeries(self.data)

def test_conversion_to_lowercase(self):
assert list(self.soni_obj.data.columns)[1] == "flux"

def test_assert_time_exists(self):

new_data = Table({"foo": [0, 1, 2, 3, 4, 5, 6],
"Flux": [1, 2, 1, 2, 5, 3, np.nan]})

onset_spacing = soni_obj.data['asf_onsets'][1:]-soni_obj.data['asf_onsets'][:-1]
assert (np.isclose(onset_spacing, soni_obj.note_spacing)).all()
with pytest.raises(AttributeError):
SoniSeries(new_data)

def test_assert_flux_exists(self):

new_data = Table({"time": [0, 1, 2, 3, 4, 5, 6],
"bar": [1, 2, 1, 2, 5, 3, np.nan]})

with pytest.raises(AttributeError):
SoniSeries(new_data)

def test_default_parameters(self):
assert self.soni_obj.note_duration == 0.5
assert self.soni_obj.note_spacing == 0.01
assert self.soni_obj.gain == 0.05

pitch_min, pitch_max = soni_obj.pitch_mapper.pitch_map_args["pitch_range"]
assert soni_obj.data["asf_pitch"].min() >= pitch_min
assert soni_obj.data["asf_pitch"].max() <= pitch_max
def test_server_class(self):
assert isinstance(self.soni_obj.server, Server)

def test_nans_removed(self):
assert len(self.soni_obj.data) == len(self.data) - 1 # nan row should be removed
assert ~np.isnan(self.soni_obj.data["flux"]).any()

def test_flux_type_correct(self):
assert self.soni_obj.data["flux"].dtype == np.float64

def test_sonify_works(self):
self.soni_obj.sonify()

def test_sonify_new_columns_exist(self):
assert "asf_pitch" in self.soni_obj.data.colnames
assert "asf_onsets" in self.soni_obj.data.colnames

def test_sonify_metadata(self):
assert self.soni_obj.data.meta['asf_exposure_time'] == 1
assert self.soni_obj.data.meta['asf_note_duration'] == self.soni_obj.note_duration
assert self.soni_obj.data.meta['asf_spacing'] == self.soni_obj.note_spacing

def test_onset_spacing(self):
onset_spacing = self.soni_obj.data['asf_onsets'][1:]-self.soni_obj.data['asf_onsets'][:-1]
assert (np.isclose(onset_spacing, self.soni_obj.note_spacing)).all()

def test_pitch_min_max(self):
pitch_min, pitch_max = self.soni_obj.pitch_mapper.pitch_map_args["pitch_range"]
assert self.soni_obj.data["asf_pitch"].min() >= pitch_min
assert self.soni_obj.data["asf_pitch"].max() <= pitch_max

# TODO: change args and test

# TODO: test write


0 comments on commit d2d7450

Please sign in to comment.