Skip to content

Commit 0d4b17c

Browse files
authored
Merge pull request #379 from fooof-tools/datap
[ENH] - Add & update for string report from data objects
2 parents 24b74ca + a9c6577 commit 0d4b17c

File tree

6 files changed

+146
-5
lines changed

6 files changed

+146
-5
lines changed

specparam/data/data.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from specparam.data import SpectrumMetaData, ModelChecks
1010
from specparam.utils.spectral import trim_spectrum
1111
from specparam.utils.checks import check_input_options
12+
from specparam.reports.strings import gen_data_str
1213
from specparam.modutils.errors import DataError, InconsistentDataError
1314
from specparam.modutils.docs import docs_get_section, replace_docstring_sections
1415
from specparam.plts.settings import PLT_COLORS
@@ -77,6 +78,17 @@ def has_data(self):
7778
return bool(np.any(self.power_spectrum))
7879

7980

81+
@property
82+
def n_freqs(self):
83+
"""Indicator for the number of frequency values."""
84+
85+
n_freqs = None
86+
if self.has_data:
87+
n_freqs = len(self.freqs)
88+
89+
return n_freqs
90+
91+
8092
def add_data(self, freqs, power_spectrum, freq_range=None):
8193
"""Add data (frequencies, and power spectrum values) to the current object.
8294
@@ -151,6 +163,18 @@ def plot(self, plt_log=False, **plt_kwargs):
151163
log_powers=False, **data_kwargs)
152164

153165

166+
def print(self, concise=False):
167+
"""Print out a data summary.
168+
169+
Parameters
170+
----------
171+
concise : bool, optional, default: False
172+
Whether to print the report in a concise mode, or not.
173+
"""
174+
175+
print(gen_data_str(self, concise))
176+
177+
154178
def set_checks(self, check_freqs=None, check_data=None):
155179
"""Set check statuses, which control if an error is raised based on check on the inputs.
156180
@@ -330,6 +354,17 @@ def has_data(self):
330354
return bool(np.any(self.power_spectra))
331355

332356

357+
@property
358+
def n_spectra(self):
359+
"""Indicator for the number of power spectra."""
360+
361+
n_spectra = None
362+
if self.has_data:
363+
n_spectra = len(self.power_spectra)
364+
365+
return n_spectra
366+
367+
333368
def add_data(self, freqs, power_spectra, freq_range=None):
334369
"""Add data (frequencies and power spectrum values) to the current object.
335370
@@ -515,6 +550,17 @@ def n_events(self):
515550
return len(self.spectrograms)
516551

517552

553+
@property
554+
def n_spectra(self):
555+
"""Redefine n_spectra marker to reflect the total number of spectra."""
556+
557+
n_spectra = None
558+
if self.has_data:
559+
n_spectra = self.n_events * self.n_time_windows
560+
561+
return n_spectra
562+
563+
518564
def add_data(self, freqs, spectrograms, freq_range=None):
519565
"""Add data (frequencies and spectrograms) to the current object.
520566

specparam/reports/strings.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,56 @@ def gen_version_str(concise=False):
118118
return output
119119

120120

121+
def gen_data_str(data, concise=False):
122+
"""Generate a string representation summarizing current data.
123+
124+
Parameters
125+
----------
126+
data : Data
127+
Data object to summarize data for.
128+
Can also be any derived data object (e.g. Data2D).
129+
concise : bool, optional, default: False
130+
Whether to print the report in concise mode.
131+
132+
Returns
133+
-------
134+
output : str
135+
Formatted string of data summary.
136+
"""
137+
138+
if not data.has_data:
139+
140+
no_data_str = "No data currently loaded in the object."
141+
str_lst = [DIVIDER,'', no_data_str, '', DIVIDER]
142+
143+
else:
144+
145+
# Get number of spectra, checking attributes for {Data3D, Data2DT, Data2D, Data}
146+
if getattr(data, 'n_events', None):
147+
n_spectra_str = '{} spectrograms with {} windows each'.format(data.n_events, data.n_time_windows)
148+
elif getattr(data, 'n_time_windows', None):
149+
n_spectra_str = '1 spectrogram with {} windows'.format(data.n_time_windows)
150+
elif getattr(data, 'n_spectra', None):
151+
n_spectra_str = '{} power spectra'.format(data.n_spectra)
152+
else:
153+
n_spectra_str = '1 power spectrum'
154+
155+
str_lst = [
156+
157+
DIVIDER,
158+
'',
159+
'The data object contains {}'.format(n_spectra_str),
160+
'with a frequency range of {} Hz'.format(data.freq_range),
161+
'and a frequency resolution of {} Hz.'.format(data.freq_res),
162+
'',
163+
DIVIDER,
164+
]
165+
166+
output = _format(str_lst, concise)
167+
168+
return output
169+
170+
121171
def gen_modes_str(modes, description=False, concise=False):
122172
"""Generate a string representation of fit modes.
123173

specparam/tests/conftest.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
from specparam.modutils.dependencies import safe_import
1010

11-
from specparam.tests.tdata import (get_tdata, get_tdata2d, get_tfm, get_tfm2, get_tfg, get_tfg2,
12-
get_tft, get_tfe, get_tbands, get_tresults, get_tmodes,
13-
get_tdocstring)
11+
from specparam.tests.tdata import (get_tdata, get_tdata2d, get_tdata2dt, get_tdata3d,
12+
get_tfm, get_tfm2, get_tfg, get_tfg2, get_tft, get_tfe,
13+
get_tbands, get_tresults, get_tmodes, get_tdocstring)
1414
from specparam.tests.tsettings import (BASE_TEST_FILE_PATH, TEST_DATA_PATH,
1515
TEST_REPORTS_PATH, TEST_PLOTS_PATH)
1616

@@ -67,6 +67,14 @@ def tdata():
6767
def tdata2d():
6868
yield get_tdata2d()
6969

70+
@pytest.fixture(scope='session')
71+
def tdata2dt():
72+
yield get_tdata2dt()
73+
74+
@pytest.fixture(scope='session')
75+
def tdata3d():
76+
yield get_tdata3d()
77+
7078
@pytest.fixture(scope='session')
7179
def tfm():
7280
yield get_tfm()

specparam/tests/data/test_data.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ def test_data():
1616

1717
tdata = Data()
1818
assert tdata
19+
assert not tdata.has_data
20+
assert not tdata.n_freqs
1921

2022
def test_data_add_data():
2123

2224
tdata = Data()
2325
freqs, pows = np.array([1, 2, 3]), np.array([10, 10, 10])
2426
tdata.add_data(freqs, pows)
2527
assert tdata.has_data
28+
assert tdata.n_freqs == len(freqs)
2629

2730
def test_data_meta_data():
2831

@@ -66,13 +69,15 @@ def test_data2d():
6669
assert tdata2d
6770
assert isinstance(tdata2d, Data)
6871
assert isinstance(tdata2d, Data2D)
72+
assert not tdata2d.has_data
6973

7074
def test_data2d_add_data():
7175

7276
tdata2d = Data2D()
7377
freqs, pows = np.array([1, 2, 3]), np.array([[10, 10, 10], [20, 20, 20]])
7478
tdata2d.add_data(freqs, pows)
7579
assert tdata2d.has_data
80+
assert tdata2d.n_spectra == len(pows)
7681

7782
@plot_test
7883
def test_data2d_plot(tdata2d, skip_if_no_mpl):
@@ -88,6 +93,7 @@ def test_data2dt():
8893
assert isinstance(tdata2dt, Data)
8994
assert isinstance(tdata2dt, Data2D)
9095
assert isinstance(tdata2dt, Data2DT)
96+
assert not tdata2dt.has_data
9197

9298
def test_data2dt_add_data():
9399

@@ -96,7 +102,7 @@ def test_data2dt_add_data():
96102
tdata2dt.add_data(freqs, pows)
97103
assert tdata2dt.has_data
98104
assert np.all(tdata2dt.spectrogram)
99-
assert tdata2dt.n_time_windows
105+
assert tdata2dt.n_spectra == tdata2dt.n_time_windows == len(pows.T)
100106

101107
## 3D Data Object
102108

@@ -108,6 +114,7 @@ def test_data3d():
108114
assert isinstance(tdata3d, Data2D)
109115
assert isinstance(tdata3d, Data2DT)
110116
assert isinstance(tdata3d, Data3D)
117+
assert not tdata3d.has_data
111118

112119
def test_data3d_add_data():
113120

@@ -117,3 +124,4 @@ def test_data3d_add_data():
117124
assert tdata3d.has_data
118125
assert np.all(tdata3d.spectrograms)
119126
assert tdata3d.n_events
127+
assert tdata3d.n_spectra == 2 * len(pows.T)

specparam/tests/reports/test_strings.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ def test_gen_version_str():
1414

1515
assert gen_version_str()
1616

17+
def test_gen_data_str(tdata, tdata2d, tdata2dt, tdata3d):
18+
19+
assert gen_data_str(tdata)
20+
assert gen_data_str(tdata2d)
21+
assert gen_data_str(tdata2dt)
22+
assert gen_data_str(tdata3d)
23+
1724
def test_gen_modes_str(tfm):
1825

1926
assert gen_modes_str(tfm.modes)

specparam/tests/tdata.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from specparam.bands import Bands
66
from specparam.modes.modes import Modes
7-
from specparam.data.data import Data, Data2D
7+
from specparam.data.data import Data, Data2D, Data2DT, Data3D
88
from specparam.data.stores import FitResults
99
from specparam.models import (SpectralModel, SpectralGroupModel,
1010
SpectralTimeModel, SpectralTimeEventModel)
@@ -50,6 +50,26 @@ def get_tdata2d():
5050

5151
return tdata2d
5252

53+
def get_tdata2dt():
54+
55+
n_spectra = 3
56+
tdata2dt = Data2DT()
57+
tdata2dt.add_data(*sim_spectrogram(n_spectra, *default_group_params()))
58+
59+
return tdata2dt
60+
61+
def get_tdata3d():
62+
63+
n_events = 2
64+
n_spectra = 3
65+
tdata3d = Data3D()
66+
freqs, spectrogram = sim_spectrogram(n_spectra, *default_group_params())
67+
tdata3d.add_data(freqs, [spectrogram] * n_events)
68+
69+
return tdata3d
70+
71+
## TEST MODEL OBJECTS
72+
5373
def get_tfm():
5474
"""Get a model object, with a fit power spectrum, for testing."""
5575

@@ -117,6 +137,8 @@ def get_tfe():
117137

118138
return tfe
119139

140+
## TEST OTHER OBJECTS
141+
120142
def get_tbands():
121143
"""Get a bands object, for testing."""
122144

0 commit comments

Comments
 (0)