def serialise_to_dict(self, request): json_file = request.param spec1d = get_spectrum1d(json_file) expected_spec1d = get_expected_spectrum1d(json_file) # Convert to dict, then back to object to test spec1d_dict = spec1d.to_dict() spec1d_from_dict = Spectrum1D.from_dict(spec1d_dict) return spec1d_from_dict, expected_spec1d
def test_plot_single_spectrum(self, spectrum_args, spectrum_kwargs, expected_data, expected_ticks, axes): plot_1d_to_axis(Spectrum1D(*spectrum_args, **spectrum_kwargs), axes) assert len(expected_data) == len(axes.lines) for line, expected in zip(axes.lines, expected_data): npt.assert_allclose(line.get_xdata(), expected[0]) npt.assert_allclose(line.get_ydata(), expected[1]) tick_locs, tick_labels = zip(*expected_ticks) npt.assert_allclose(axes.get_xticks(), tick_locs) assert [label.get_text() for label in axes.get_xticklabels()] == list(tick_labels)
class TestPlot1DCore: @pytest.mark.parametrize('spectra, expected_error', [ ('wrong_type', TypeError), ]) def test_1d_core_errors(self, spectra, expected_error, axes): with pytest.raises(expected_error): plot_1d_to_axis(spectra, axes) spec1d_args = (np.array([0., 1., 2.]) * ureg('meV'), np.array([2., 3., 2.]) * ureg('angstrom^-2')) spec1d_split_args = (np.array([0., 1., 1., 2.]) * ureg('meV'), np.array([2., 3., 2., 4.]) * ureg('angstrom^-2')) @pytest.mark.parametrize( 'spectrum_args, spectrum_kwargs, expected_data, expected_ticks', [ # Case 1: Trivial (spec1d_args, { 'x_tick_labels': [(0, 'A'), (2, 'B')] }, ([[0., 1., 2.], [2., 3., 2]], ), [(0., 'A'), (2., 'B')]), # Case 2: Split points create new line ( spec1d_split_args, { 'x_tick_labels': [(1, 'B'), (2, 'B'), (3, 'C')] }, ([[0., 1.], [2., 3.]], [[1., 2.], [2., 4.]]), # Note that duplicated points get plotted twice. Weird but harmless. [(1., 'B'), (1., 'B'), (2., 'C')]) ]) def test_plot_single_spectrum(self, spectrum_args, spectrum_kwargs, expected_data, expected_ticks, axes): plot_1d_to_axis(Spectrum1D(*spectrum_args, **spectrum_kwargs), axes) assert len(expected_data) == len(axes.lines) for line, expected in zip(axes.lines, expected_data): npt.assert_allclose(line.get_xdata(), expected[0]) npt.assert_allclose(line.get_ydata(), expected[1]) tick_locs, tick_labels = zip(*expected_ticks) npt.assert_allclose(axes.get_xticks(), tick_locs) assert [label.get_text() for label in axes.get_xticklabels()] == list(tick_labels) spec1dcol_args = (np.array([0., 1., 2.]) * ureg('meV'), np.array([[2., 3., 2.], [3., 4., 3.]]) * ureg('angstrom^-2')) spec1dcol_split_args = (np.array([0., 1., 1., 2.]) * ureg('meV'), np.array([[2., 3., 2., 4.], [5., 4., 3., 2.]]) * ureg('angstrom^-2')) @pytest.mark.parametrize( 'spectrum_args, expected_data', [ # Case 1: Two lines (spec1dcol_args, ([[0., 1., 2.], [2., 3., 2.]], [[0., 1., 2.], [3., 4., 3.]])), # Case 2: Two lines with split points (spec1dcol_split_args, ([[0., 1.], [2., 3.]], [[1., 2.], [2., 4.]], [[0., 1.], [5., 4.]], [[1., 2.], [3., 2.]])) ]) def test_plot_collection(self, spectrum_args, expected_data, axes): plot_1d_to_axis(Spectrum1DCollection(*spectrum_args), axes) assert len(expected_data) == len(axes.lines) for line, expected in zip(axes.lines, expected_data): npt.assert_allclose(line.get_xdata(), expected[0]) npt.assert_allclose(line.get_ydata(), expected[1]) @pytest.mark.parametrize('spec, labels_kwarg, expected_legend_labels', [ (Spectrum1D(*spec1d_args), None, []), (Spectrum1D(*spec1d_args), ['Line B'], ['Line B']), (Spectrum1D(*spec1d_args, metadata={'label': 'Line B' }), None, ['Line B']), (Spectrum1D(*spec1d_args, metadata={'label': 'Line B' }), ['Line C'], ['Line C']), (Spectrum1D(*spec1d_split_args, metadata={'label': 'Line B' }), 'Line C', ['Line C']), (Spectrum1DCollection( *spec1dcol_args, metadata={'line_data': [{ 'label': 'Line B' }, { 'label': 'Line C' }]}), None, ['Line B', 'Line C']), (Spectrum1DCollection( *spec1dcol_args, metadata={'line_data': [{ 'label': 'Line B' }, { 'label': 'Line C' }]}), ['Line D', 'Line E'], ['Line D', 'Line E']), (Spectrum1DCollection( *spec1dcol_args, metadata={'line_data': [{ 'label': 'Line B' }, { 'label': 'Line C' }]}), ['', ''], []), (Spectrum1DCollection( *spec1dcol_split_args, metadata={'line_data': [{ 'label': 'Line B' }, { 'label': 'Line C' }]}), None, ['Line B', 'Line C']) ]) def test_plot_labels(self, spec, labels_kwarg, expected_legend_labels, axes_with_line_and_legend): existing_line_label = ['Line A'] plot_1d_to_axis(spec, axes_with_line_and_legend, labels=labels_kwarg) legend = axes_with_line_and_legend.get_legend() assert ([x.get_text() for x in legend.get_texts() ] == existing_line_label + expected_legend_labels) @pytest.mark.parametrize( 'spec, labels', [(Spectrum1D(*spec1d_args), ['Line B', 'Line C']), (Spectrum1DCollection(*spec1dcol_args), ['Line B'])]) def test_incorrect_length_labels_raises_value_error( self, spec, labels, axes): with pytest.raises(ValueError): plot_1d_to_axis(spec, axes, labels=labels)
def band_segments(self): spec1 = Spectrum1D([0., 1., 2.] * ureg('angstrom^-1'), [1., 2., 1.] * ureg('meV')) spec2 = Spectrum1D([4., 6., 7.] * ureg('angstrom^-1'), [1., 2., 1.] * ureg('meV')) return [spec1, spec2]
class TestPlot1D: @staticmethod def mock_core(mocker): return mocker.patch('euphonic.plot.plot_1d_to_axis', return_value=None) @pytest.fixture def band_segments(self): spec1 = Spectrum1D([0., 1., 2.] * ureg('angstrom^-1'), [1., 2., 1.] * ureg('meV')) spec2 = Spectrum1D([4., 6., 7.] * ureg('angstrom^-1'), [1., 2., 1.] * ureg('meV')) return [spec1, spec2] spec1d_args = ([0., 1., 2.] * ureg('meV'), [1., 2., 1.] * ureg('angstrom^-2')) spec1dcol_args = ([0., 1., 2.] * ureg('meV'), [[1., 2., 1.], [2., 3., 2.]] * ureg('angstrom^-2')) @pytest.mark.parametrize('spectrum, labels, kwargs', [ (Spectrum1D(*spec1d_args), ['Line A'], { 'lw': 2 }), (Spectrum1D(*spec1d_args), 'Line A', { 'lw': 2 }), (Spectrum1D(*spec1d_args, metadata={'label': ['Line B']}), None, { 'ls': '--' }), (Spectrum1DCollection( *spec1dcol_args, x_tick_labels=[(1, 'A')]), ['Line D', 'Line E'], { 'ls': '.-' }), (Spectrum1DCollection( *spec1dcol_args, metadata={'line_data': [{ 'label': 'Line B' }, { 'label': 'Line C' }]}), ['Line D', 'Line E'], {}) ]) def test_plot_single(self, mocker, spectrum, labels, kwargs): core = self.mock_core(mocker) fig = plot_1d(spectrum, labels=labels, **kwargs) # Check args were as expected assert core.call_args[0][0] == spectrum assert core.call_args[0][1] in fig.axes assert core.call_args[0][2] == labels assert core.call_args[1] == kwargs plt.close(fig) @pytest.mark.parametrize('spec1_units', [('angstrom^-1', 'hartree'), ('bohr^-1', 'meV')]) def test_plot_badunits(self, spec1_units, band_segments): spec1, spec2 = band_segments spec1.x_data_unit, spec1.y_data_unit = spec1_units spec2.x_data_unit, spec2.y_data_unit = ('angstrom^-1', 'meV') with pytest.raises(ValueError): plot_1d([spec1, spec2]) @pytest.mark.parametrize('kwargs, expected_labels', [({ 'labels': ['band A'], 'x_label': 'X_LABEL', 'y_label': 'Y_LABEL', 'title': 'TITLE' }, ['band A']), ({}, None)]) def test_plot_multi_segments(self, mocker, band_segments, kwargs, expected_labels): suptitle = mocker.patch.object(matplotlib.figure.Figure, 'suptitle') fig = plot_1d(band_segments, **kwargs) legend = fig.axes[0].get_legend() if expected_labels is None: assert legend == None else: for text, label in zip(legend.get_texts(), expected_labels): assert text.get_text() == label # Ensure legend only on first subplot for ax in fig.axes[1:]: assert ax.get_legend() == None if 'x_label' in kwargs: assert fig.axes[-1].get_xlabel() == kwargs['x_label'] if 'y_label' in kwargs: assert fig.axes[-1].get_ylabel() == kwargs['y_label'] if 'title' in kwargs: suptitle.assert_called_once_with(kwargs['title']) for ax in fig.axes[:-1]: if 'y_min' in kwargs: assert ax.get_ylim()[0] == pytest.approx(kwargs.get('y_min')) if 'y_max' in kwargs: assert ax.get_ylim()[0] == pytest.approx(kwargs.get('y_max')) def test_plot_with_incorrect_labels_raises_valueerror(self, band_segments): with pytest.raises(ValueError): fig = plot_1d(band_segments, labels=['Band A', 'Band B'])
def get_spectrum1d(json_filename): return Spectrum1D.from_json_file(get_json_file(json_filename))
def test_serialise_to_json_file(self, spec1d, tmpdir): output_file = str(tmpdir.join('tmp.test')) spec1d.to_json_file(output_file) check_json_metadata(output_file, 'Spectrum1D') deserialised_spec1d = Spectrum1D.from_json_file(output_file) check_spectrum1d(spec1d, deserialised_spec1d)
def test_faulty_object_creation(self, inject_faulty_elements): faulty_args, faulty_kwargs, expected_exception = inject_faulty_elements with pytest.raises(expected_exception): Spectrum1D(*faulty_args, **faulty_kwargs)
def create_from_castep_phonon_dos(self, request): material, phonon_dos_file, kwargs, json_file = request.param expected_spec1d = get_expected_spectrum1d(json_file) spec1d = Spectrum1D.from_castep_phonon_dos( get_castep_path(material, phonon_dos_file), **kwargs) return spec1d, expected_spec1d
def create_from_dict(self, request): json_file = request.param expected_spec1d = get_expected_spectrum1d(json_file) spec1d = Spectrum1D.from_dict(expected_spec1d.to_dict()) return spec1d, expected_spec1d
def create_from_json(self, request): json_file = request.param expected_spec1d = get_expected_spectrum1d(json_file) spec1d = Spectrum1D.from_json_file(get_json_file(json_file)) return spec1d, expected_spec1d
def create_from_constructor(self, request): expected_spec1d = request.param args, kwargs = expected_spec1d.to_constructor_args() spec1d = Spectrum1D(*args, **kwargs) return spec1d, expected_spec1d