diff --git a/docs/general/parameter_file.md b/docs/general/parameter_file.md index 9713cb9e..5010b9c6 100644 --- a/docs/general/parameter_file.md +++ b/docs/general/parameter_file.md @@ -130,6 +130,7 @@ The level of output is controlled through the integer `logging_level`: | write_matrices | logical | whether to write the matrices to the datfile | `.false.` | | write_eigenvectors | logical | whether to write the eigenvectors to the datfile | `.false.` | | write_residuals | logial | whether to write the residuals to the datfile | `.false.` | +| write_background | logical | whether to write the background to the datfile | `.true.` | | write_eigenfunctions | logical | whether to write the eigenfunctions to the datfile | `.true.` | | write_derived_eigenfunctions | logical | whether to write the derived eigenfunctions to the datfile | `.false.` | | write_eigenfunction_subset | logical | if `.true.` only writes eigenfunctions for eigenvalues inside a given radius around a point in the complex plane | `.false.` | diff --git a/post_processing/pylbo/automation/defaults.py b/post_processing/pylbo/automation/defaults.py index 1062575f..ef5c6afa 100644 --- a/post_processing/pylbo/automation/defaults.py +++ b/post_processing/pylbo/automation/defaults.py @@ -18,6 +18,7 @@ ("write_matrices", bool), ("write_eigenvectors", bool), ("write_residuals", bool), + ("write_background", bool), ("write_eigenfunctions", bool), ("write_derived_eigenfunctions", bool), ("show_results", bool), diff --git a/post_processing/pylbo/data_containers.py b/post_processing/pylbo/data_containers.py index f539dddb..11ea4b42 100644 --- a/post_processing/pylbo/data_containers.py +++ b/post_processing/pylbo/data_containers.py @@ -7,6 +7,7 @@ import numpy as np from pylbo._version import VersionHandler from pylbo.exceptions import ( + BackgroundNotPresent, EigenfunctionsNotPresent, EigenvectorsNotPresent, MatricesNotPresent, @@ -55,6 +56,10 @@ def ef_grid(self): def ef_names(self): pass + @abstractmethod + def has_background(self): + pass + @abstractmethod def has_derived_efs(self): pass @@ -229,6 +234,11 @@ def parameters(self) -> dict: """Returns the parameters in a dict with the parameter names as keys""" return self._parameters + @property + def has_background(self) -> bool: + """Returns `True` if background is present.""" + return self.header["has_background"] + @property def has_efs(self) -> bool: """Returns `True` if eigenfunctions are present.""" @@ -294,6 +304,8 @@ def get_sound_speed(self, which_values=None) -> Union[float, np.ndarray]: Array with the sound speed at every grid point, or a float corresponding to the value of `which_values` if provided. """ + if not self.has_background: + raise BackgroundNotPresent(self.datfile, "get sound speed") pressure = self.equilibria["T0"] * self.equilibria["rho0"] cs = np.sqrt(self.gamma * pressure / self.equilibria["rho0"]) return get_values(cs, which_values) @@ -314,6 +326,8 @@ def get_alfven_speed(self, which_values=None) -> Union[float, np.ndarray]: Array with the Alfvén speed at every grid point, or a float corresponding to the value of `which_values` if provided. """ + if not self.has_background: + raise BackgroundNotPresent(self.datfile, "get Alfvén speed") cA = self.equilibria["B0"] / np.sqrt(self.equilibria["rho0"]) return get_values(cA, which_values) @@ -334,16 +348,17 @@ def get_tube_speed(self, which_values=None) -> Union[float, np.ndarray]: or a float corresponding to the value of `which_values` if provided. Returns `None` if the geometry is not cylindrical. """ + if not self.has_background: + raise BackgroundNotPresent(self.datfile, "get tube speed") if not self.geometry == "cylindrical": pylboLogger.warning( "geometry is not cylindrical, unable to calculate tube speed" ) return None - else: - cA = self.get_alfven_speed() - cs = self.get_sound_speed() - ct = cs * cA / np.sqrt(cs**2 + cA**2) - return get_values(ct, which_values) + cA = self.get_alfven_speed() + cs = self.get_sound_speed() + ct = cs * cA / np.sqrt(cs**2 + cA**2) + return get_values(ct, which_values) def get_reynolds_nb(self, which_values=None) -> Union[float, np.ndarray]: """ @@ -363,6 +378,8 @@ def get_reynolds_nb(self, which_values=None) -> Union[float, np.ndarray]: or a float corresponding to the value of `which_values` if provided. Returns `None` if the resistivity is zero somewhere on the domain. """ + if not self.has_background: + raise BackgroundNotPresent(self.datfile, "get Reynolds number") cs = self.get_sound_speed() a = self.x_end - self.x_start eta = self.equilibria["eta"] @@ -372,9 +389,8 @@ def get_reynolds_nb(self, which_values=None) -> Union[float, np.ndarray]: "calculate the Reynolds number" ) return None - else: - Re = a * cs / eta - return get_values(Re, which_values) + Re = a * cs / eta + return get_values(Re, which_values) def get_magnetic_reynolds_nb(self, which_values=None) -> Union[float, np.ndarray]: """ @@ -394,6 +410,8 @@ def get_magnetic_reynolds_nb(self, which_values=None) -> Union[float, np.ndarray or a float corresponding to the value of `which_values` if provided. Returns `None` if the resistivity is zero somewhere on the domain. """ + if not self.has_background: + raise BackgroundNotPresent(self.datfile, "get magnetic Reynolds number") cA = self.get_alfven_speed() a = self.x_end - self.x_start eta = self.equilibria["eta"] @@ -403,9 +421,8 @@ def get_magnetic_reynolds_nb(self, which_values=None) -> Union[float, np.ndarray "calculate the magnetic Reynolds number" ) return None - else: - Rm = a * cA / eta - return get_values(Rm, which_values) + Rm = a * cA / eta + return get_values(Rm, which_values) def get_k0_squared(self) -> float: """ @@ -715,7 +732,10 @@ def continua(self) -> dict: Returns the continua. Each key corresponds to a multiple Numpy arrays, one for each dataset. """ - keys = self[0].continua.keys() + continua = self[0].continua + if continua is None: + return np.array([None] * len(self), dtype=object) + keys = continua.keys() _continua = {key: [] for key in keys} for ds in self: for key in keys: @@ -735,6 +755,11 @@ def parameters(self) -> dict: _params[key].append(ds.parameters[key]) return {key: np.array(values) for key, values in _params.items()} + @property + def has_background(self) -> np.ndarray: + """Returns `True` if background is present.""" + return np.array([ds.has_background for ds in self.datasets], dtype=bool) + @property def has_efs(self) -> np.ndarray: """Returns `True` if eigenfunctions are present.""" diff --git a/post_processing/pylbo/exceptions.py b/post_processing/pylbo/exceptions.py index 8cd94b7b..0171cd38 100644 --- a/post_processing/pylbo/exceptions.py +++ b/post_processing/pylbo/exceptions.py @@ -29,6 +29,29 @@ def __str__(self): return f"{self.file} is not a valid Legolas file" +class BackgroundNotPresent(LegolasException): + """ + Handles trying to query for the background when this is not present in the datfile. + + Parameters + ---------- + file : str, ~os.PathLike + The path to the file. + unable_to_do : str + The thing that was unable to be done. + """ + + def __init__(self, file, unable_to_get=None): + self.file = file + self.unable_to_do = unable_to_get + + def __str__(self): + msg = f"No background present in {self.file}" + if self.unable_to_do is not None: + msg = f"{msg}, unable to {self.unable_to_do}" + return msg + + class EigenfunctionsNotPresent(LegolasException): """ Handles trying to query for eigenfunctions when these diff --git a/post_processing/pylbo/utilities/datfiles/file_reader.py b/post_processing/pylbo/utilities/datfiles/file_reader.py index a5200d84..0010a07d 100644 --- a/post_processing/pylbo/utilities/datfiles/file_reader.py +++ b/post_processing/pylbo/utilities/datfiles/file_reader.py @@ -1,4 +1,5 @@ from __future__ import annotations + from os import PathLike from typing import BinaryIO diff --git a/post_processing/pylbo/utilities/datfiles/header.py b/post_processing/pylbo/utilities/datfiles/header.py index dc9a5ab1..977d0092 100644 --- a/post_processing/pylbo/utilities/datfiles/header.py +++ b/post_processing/pylbo/utilities/datfiles/header.py @@ -217,7 +217,12 @@ def _read_parameters(self, istream: BinaryIO) -> dict: def _read_equilibrium_names(self, istream: BinaryIO) -> dict: nb_names, len_name = read_int_from_istream(istream, amount=2) - names = read_string_from_istream(istream, length=len_name, amount=nb_names) + self.data["has_background"] = nb_names > 0 + names = ( + read_string_from_istream(istream, length=len_name, amount=nb_names) + if self.data["has_background"] + else [] + ) return {"equilibrium_names": names} def _get_eigenfunction_offsets(self, istream: BinaryIO) -> dict: diff --git a/post_processing/pylbo/utilities/datfiles/header_legacy.py b/post_processing/pylbo/utilities/datfiles/header_legacy.py index 292e5133..96339511 100644 --- a/post_processing/pylbo/utilities/datfiles/header_legacy.py +++ b/post_processing/pylbo/utilities/datfiles/header_legacy.py @@ -205,3 +205,4 @@ def _handle_entries_not_in_datfile_for_compatibility(self) -> None: "dim_quadblock": 2 * 8 * 2, "dim_matrix": self.data["gridpoints"] * 8 * 2, } + self.data["has_background"] = True diff --git a/post_processing/pylbo/visualisation/api.py b/post_processing/pylbo/visualisation/api.py index ab09252c..935880eb 100644 --- a/post_processing/pylbo/visualisation/api.py +++ b/post_processing/pylbo/visualisation/api.py @@ -196,6 +196,12 @@ def plot_equilibrium(data, figsize=None, interactive=True, **kwargs): The profile instance containing the equilibrium plots. """ ensure_dataset(data) + if not data.has_background: + pylboLogger.warning( + "The dataset does not contain a background, equilibrium profiles " + "can not be plotted." + ) + return p = EquilibriumProfile(data, figsize, interactive, **kwargs) return p @@ -218,6 +224,13 @@ def plot_equilibrium_balance(data, figsize=None, **kwargs): p : ~pylbo.visualisation.profiles.EquilibriumBalance The profile instance containing the equilibrium balance plots. """ + ensure_dataset(data) + if not data.has_background: + pylboLogger.warning( + "The dataset does not contain a background, equilibrium balance " + "can not be plotted." + ) + return p = EquilibriumBalance(data, figsize, **kwargs) return p diff --git a/post_processing/pylbo/visualisation/continua.py b/post_processing/pylbo/visualisation/continua.py index d758f3d4..f9937659 100644 --- a/post_processing/pylbo/visualisation/continua.py +++ b/post_processing/pylbo/visualisation/continua.py @@ -35,9 +35,13 @@ def calculate_continua(ds): Returns ------- - continua : dict - Dictonary containing the various continua as numpy arrays. + continua : dict, None + Dictonary containing the various continua as numpy arrays. If the + dataset does not contain a background, `None` is returned. """ + if not ds.has_background: + return None + rho = ds.equilibria["rho0"] B02 = ds.equilibria["B02"] B03 = ds.equilibria["B03"] diff --git a/post_processing/pylbo/visualisation/modes/mode_data.py b/post_processing/pylbo/visualisation/modes/mode_data.py index c8469b50..f8901b38 100644 --- a/post_processing/pylbo/visualisation/modes/mode_data.py +++ b/post_processing/pylbo/visualisation/modes/mode_data.py @@ -5,6 +5,7 @@ import numpy as np from pylbo.data_containers import LegolasDataSet +from pylbo.exceptions import BackgroundNotPresent from pylbo.utilities.logger import pylboLogger from pylbo.visualisation.utils import ef_name_to_latex, validate_ef_name @@ -56,6 +57,8 @@ def __init__( self.ds = ds self.use_real_part = use_real_part self.complex_factor = self._validate_complex_factor(complex_factor) + if add_background and not ds.has_background: + raise BackgroundNotPresent(ds.datfile, "add background to solution") self.add_background = add_background self._print_bg_info = True diff --git a/post_processing/pylbo/visualisation/spectra/spectrum_figure.py b/post_processing/pylbo/visualisation/spectra/spectrum_figure.py index fc39f744..239ee0f8 100644 --- a/post_processing/pylbo/visualisation/spectra/spectrum_figure.py +++ b/post_processing/pylbo/visualisation/spectra/spectrum_figure.py @@ -2,6 +2,7 @@ from copy import copy +import numpy as np from matplotlib.axes import Axes as mpl_axes from matplotlib.figure import Figure as mpl_fig from pylbo.visualisation.figure_window import InteractiveFigureWindow @@ -125,6 +126,12 @@ def add_eigenfunctions(self): def add_derived_eigenfunctions(self): raise NotImplementedError() + def has_valid_continua(self, data): + continua = getattr(data, "continua", None) + if isinstance(continua, (list, np.ndarray)): + return all([c is not None for c in continua]) + return continua is not None + @property def c_handler(self): """Property, returns the continua handler.""" diff --git a/post_processing/pylbo/visualisation/spectra/spectrum_multi.py b/post_processing/pylbo/visualisation/spectra/spectrum_multi.py index 12a0a57f..484ab31e 100644 --- a/post_processing/pylbo/visualisation/spectra/spectrum_multi.py +++ b/post_processing/pylbo/visualisation/spectra/spectrum_multi.py @@ -176,6 +176,8 @@ def add_continua(self, interactive=True): interactive : bool If `True`, makes the legend interactive. """ + if not self.has_valid_continua(self.dataseries): + return if self._c_handler is None: self._c_handler = ContinuaHandler(interactive=interactive) diff --git a/post_processing/pylbo/visualisation/spectra/spectrum_single.py b/post_processing/pylbo/visualisation/spectra/spectrum_single.py index bef95819..162cb323 100644 --- a/post_processing/pylbo/visualisation/spectra/spectrum_single.py +++ b/post_processing/pylbo/visualisation/spectra/spectrum_single.py @@ -89,6 +89,8 @@ def add_continua(self, interactive=True): c_handler : ~pylbo.continua.ContinuaHandler The legendhandler used to plot the continua. """ + if not self.has_valid_continua(self.dataset): + return if self._c_handler is None: self._c_handler = ContinuaHandler(interactive=interactive) diff --git a/src/dataIO/mod_console.f08 b/src/dataIO/mod_console.f08 index 77f75bfb..537bc816 100644 --- a/src/dataIO/mod_console.f08 +++ b/src/dataIO/mod_console.f08 @@ -271,14 +271,19 @@ subroutine log_io_info(settings) call logger%info(" << DataIO settings >>") call logger%info("datfile name : " // settings%io%get_basename_datfile()) call logger%info("output folder : " // settings%io%get_output_folder()) + call logger%info("write background : " // str(settings%io%write_background)) call logger%info("write matrices : " // str(settings%io%write_matrices)) - call logger%info("write eigenvectors : " // str(settings%io%write_eigenvectors)) - call logger%info("write residuals : " // str(settings%io%write_residuals)) call logger%info("write eigenfunctions : " // str(settings%io%write_eigenfunctions)) call logger%info( & "write derived eigenfunctions : " & // str(settings%io%write_derived_eigenfunctions) & ) + if (settings%io%write_eigenvectors) then + call logger%info("write eigenvectors : " // str(settings%io%write_eigenvectors)) + end if + if (settings%io%write_residuals) then + call logger%info("write residuals : " // str(settings%io%write_residuals)) + end if if (.not. settings%io%write_ef_subset) return call logger%info( & "write eigenfunction subset : " // str(settings%io%write_ef_subset) & diff --git a/src/dataIO/mod_input.f08 b/src/dataIO/mod_input.f08 index 2b31026f..3d93d6f3 100644 --- a/src/dataIO/mod_input.f08 +++ b/src/dataIO/mod_input.f08 @@ -90,7 +90,7 @@ subroutine read_savelist(unit, settings) integer :: iostat character(str_len) :: iomsg - logical :: write_matrices, write_eigenvectors, write_residuals + logical :: write_matrices, write_eigenvectors, write_residuals, write_background logical :: write_eigenfunctions, write_derived_eigenfunctions logical :: write_eigenfunction_subset logical :: show_results @@ -100,8 +100,8 @@ subroutine read_savelist(unit, settings) character(len=str_len) :: basename_datfile, output_folder namelist /savelist/ & - write_matrices, write_eigenvectors, write_residuals, write_eigenfunctions, & - write_derived_eigenfunctions, write_eigenfunction_subset, & + write_matrices, write_eigenvectors, write_residuals, write_background, & + write_eigenfunctions, write_derived_eigenfunctions, write_eigenfunction_subset, & show_results, basename_datfile, output_folder, logging_level, & eigenfunction_subset_radius, eigenfunction_subset_center @@ -109,6 +109,7 @@ subroutine read_savelist(unit, settings) write_matrices = settings%io%write_matrices write_eigenvectors = settings%io%write_eigenvectors write_residuals = settings%io%write_residuals + write_background = settings%io%write_background write_eigenfunctions = settings%io%write_eigenfunctions write_derived_eigenfunctions = settings%io%write_derived_eigenfunctions write_eigenfunction_subset = settings%io%write_ef_subset @@ -127,6 +128,7 @@ subroutine read_savelist(unit, settings) settings%io%write_matrices = write_matrices settings%io%write_eigenvectors = write_eigenvectors settings%io%write_residuals = write_residuals + settings%io%write_background = write_background settings%io%write_eigenfunctions = write_eigenfunctions settings%io%write_derived_eigenfunctions = write_derived_eigenfunctions settings%io%write_ef_subset = write_eigenfunction_subset diff --git a/src/dataIO/mod_output.f08 b/src/dataIO/mod_output.f08 index 0e741b09..ae16b8e3 100644 --- a/src/dataIO/mod_output.f08 +++ b/src/dataIO/mod_output.f08 @@ -86,7 +86,9 @@ subroutine create_datfile( & write(dat_fh) size(eigenvalues), eigenvalues write(dat_fh) grid%base_grid, grid%gaussian_grid - call write_equilibrium_data(settings, grid, background, physics) + if (settings%io%write_background) then + call write_background_data(settings, grid, background, physics) + end if if (settings%io%write_eigenfunctions) then call write_base_eigenfunction_data(grid, eigenfunctions) end if @@ -114,7 +116,7 @@ subroutine write_header(settings) call write_units_info(settings) call write_physics_info(settings) call write_parameters(settings) - call write_equilibrium_names() + call write_background_names(settings) end subroutine write_header @@ -311,7 +313,8 @@ subroutine write_parameters(settings) end subroutine write_parameters - subroutine write_equilibrium_names() + subroutine write_background_names(settings) + type(settings_t), intent(in) :: settings integer, parameter :: nb_names = 38 character(len=str_len_arr) :: equilibrium_names(nb_names) @@ -329,12 +332,16 @@ subroutine write_equilibrium_names() "gravity", & "Hall", "inertia" & ] + if (.not. settings%io%write_background) then + write(dat_fh) 0, 0 + return + end if write(dat_fh) nb_names, len(equilibrium_names(1)) write(dat_fh) equilibrium_names - end subroutine write_equilibrium_names + end subroutine write_background_names - subroutine write_equilibrium_data(settings, grid, background, physics) + subroutine write_background_data(settings, grid, background, physics) use mod_function_utils, only: from_function type(settings_t), intent(in) :: settings @@ -382,7 +389,7 @@ subroutine write_equilibrium_data(settings, grid, background, physics) write(dat_fh) from_function(physics%gravity%g0, grid%gaussian_grid) write(dat_fh) from_function(physics%hall%hallfactor, grid%gaussian_grid) write(dat_fh) from_function(physics%hall%inertiafactor, grid%gaussian_grid) - end subroutine write_equilibrium_data + end subroutine write_background_data subroutine write_base_eigenfunction_data(grid, eigenfunctions) diff --git a/src/settings/mod_io_settings.f08 b/src/settings/mod_io_settings.f08 index ec10b100..d5c73f49 100644 --- a/src/settings/mod_io_settings.f08 +++ b/src/settings/mod_io_settings.f08 @@ -8,6 +8,7 @@ module mod_io_settings logical, public :: write_matrices logical, public :: write_eigenvectors logical, public :: write_residuals + logical, public :: write_background logical, public :: write_eigenfunctions logical, public :: write_derived_eigenfunctions logical, public :: write_ef_subset @@ -42,6 +43,7 @@ pure function new_io_settings() result(io_settings) io_settings%write_matrices = .false. io_settings%write_eigenvectors = .false. io_settings%write_residuals = .false. + io_settings%write_background = .true. io_settings%write_eigenfunctions = .true. io_settings%write_derived_eigenfunctions = .false. io_settings%write_ef_subset = .false. diff --git a/tests/pylbo_tests/conftest.py b/tests/pylbo_tests/conftest.py index 17a40726..51e5eb80 100644 --- a/tests/pylbo_tests/conftest.py +++ b/tests/pylbo_tests/conftest.py @@ -200,6 +200,12 @@ def ds_v200_mri_efs(): return pylbo.load(utils / "v2.0.0_mri_subset_efs.dat") +@pytest.mark.timeout(5) +@pytest.fixture(scope="session") +def ds_v200_tear_nobg(): + return pylbo.load(utils / "v2.0.0_tear_nobg.dat") + + @pytest.mark.timeout(5) @pytest.fixture def series_v100(): @@ -216,3 +222,9 @@ def series_v112(): @pytest.fixture def series_v112_eta(): return pylbo.load_series([utils / "v1.1.2_datfile_eta.dat"] * 5) + + +@pytest.mark.timeout(5) +@pytest.fixture +def series_v200_nobg(): + return pylbo.load_series([utils / "v2.0.0_tear_nobg.dat"] * 7) diff --git a/tests/pylbo_tests/test_dataseries.py b/tests/pylbo_tests/test_dataseries.py index 7c5222ce..6054ba50 100644 --- a/tests/pylbo_tests/test_dataseries.py +++ b/tests/pylbo_tests/test_dataseries.py @@ -1,5 +1,7 @@ import numpy as np +import pytest from pylbo.data_containers import LegolasDataSeries, LegolasDataSet +from pylbo.exceptions import BackgroundNotPresent def test_series_iterable(series_v112): @@ -119,3 +121,28 @@ def test_series_get_parameters(series_v112): for value in params.values(): assert isinstance(value, np.ndarray) assert len(value) == len(series_v112) + + +def test_series_no_bg(series_v200_nobg): + assert not any(series_v200_nobg.has_background) + + +def test_series_nobg_continua(series_v200_nobg): + continua = series_v200_nobg.continua + assert isinstance(continua, np.ndarray) + assert all(val is None for val in continua) + + +def test_series_nobg_soundspeed(series_v200_nobg): + with pytest.raises(BackgroundNotPresent): + series_v200_nobg.get_sound_speed() + + +def test_series_nobg_alfven_speed(series_v200_nobg): + with pytest.raises(BackgroundNotPresent): + series_v200_nobg.get_alfven_speed() + + +def test_series_nobg_tube_speed(series_v200_nobg): + with pytest.raises(BackgroundNotPresent): + series_v200_nobg.get_tube_speed() diff --git a/tests/pylbo_tests/test_dataset.py b/tests/pylbo_tests/test_dataset.py index 89b4873a..7855ada8 100644 --- a/tests/pylbo_tests/test_dataset.py +++ b/tests/pylbo_tests/test_dataset.py @@ -1,6 +1,6 @@ import numpy as np import pytest -from pylbo.exceptions import MatricesNotPresent +from pylbo.exceptions import BackgroundNotPresent, MatricesNotPresent ds_v112_ev_guess = -0.14360602 + 0.00688731j ds_v112_ev_idx = 158 @@ -187,3 +187,39 @@ def test_ds_get_parameters(ds_v112): assert isinstance(params, dict) for value in params.values(): assert np.isscalar(value) + + +def test_ds_nobg_empty_equilibria_dict(ds_v200_tear_nobg): + bg = ds_v200_tear_nobg.equilibria + assert not ds_v200_tear_nobg.has_background + assert isinstance(bg, dict) + assert not bg + + +def test_ds_nobg_continua(ds_v200_tear_nobg): + assert ds_v200_tear_nobg.continua is None + + +def test_ds_nobg_soundspeed(ds_v200_tear_nobg): + with pytest.raises(BackgroundNotPresent): + ds_v200_tear_nobg.get_sound_speed() + + +def test_ds_nobg_alfvenspeed(ds_v200_tear_nobg): + with pytest.raises(BackgroundNotPresent): + ds_v200_tear_nobg.get_alfven_speed() + + +def test_ds_nobg_tube_speed(ds_v200_tear_nobg): + with pytest.raises(BackgroundNotPresent): + ds_v200_tear_nobg.get_tube_speed() + + +def test_ds_nobg_reynolds(ds_v200_tear_nobg): + with pytest.raises(BackgroundNotPresent): + ds_v200_tear_nobg.get_reynolds_nb() + + +def test_ds_nobg_magnetic_reynolds(ds_v200_tear_nobg): + with pytest.raises(BackgroundNotPresent): + ds_v200_tear_nobg.get_magnetic_reynolds_nb() diff --git a/tests/pylbo_tests/test_visualisations_profiles.py b/tests/pylbo_tests/test_visualisations_profiles.py index 68560408..77ce5101 100644 --- a/tests/pylbo_tests/test_visualisations_profiles.py +++ b/tests/pylbo_tests/test_visualisations_profiles.py @@ -15,3 +15,13 @@ def test_plot_equilibrium_balance(ds_v112): def test_plot_matrices(ds_v100): pylbo.plot_matrices(ds_v100) + + +def test_plot_equilibrium_profile_no_bg(ds_v200_tear_nobg): + p = pylbo.plot_equilibrium(ds_v200_tear_nobg) + assert p is None + + +def test_plot_equilibrium_balance_no_bg(ds_v200_tear_nobg): + p = pylbo.plot_equilibrium_balance(ds_v200_tear_nobg) + assert p is None diff --git a/tests/pylbo_tests/test_visualisations_spectra.py b/tests/pylbo_tests/test_visualisations_spectra.py index f321b716..f684a270 100644 --- a/tests/pylbo_tests/test_visualisations_spectra.py +++ b/tests/pylbo_tests/test_visualisations_spectra.py @@ -3,7 +3,7 @@ import numpy as np import pylbo import pytest -from pylbo.exceptions import EigenfunctionsNotPresent +from pylbo.exceptions import BackgroundNotPresent, EigenfunctionsNotPresent from pylbo.utilities.toolbox import get_axis_geometry from pylbo.visualisation.spectra.spectrum_single import SingleSpectrumPlot @@ -125,6 +125,12 @@ def test_spectrum_plot_figlabel(ds_v112): assert p.figure_id == "testfig" +def test_spectrum_plot_nobg_continua(ds_v200_tear_nobg): + p = pylbo.plot_spectrum(ds_v200_tear_nobg) + p.add_continua() + assert getattr(p, "c_handler") is None + + def test_multispectrum_plot_invalid_data(ds_v112): with pytest.raises(TypeError): pylbo.plot_spectrum_multi(ds_v112, xdata="k2") @@ -239,6 +245,12 @@ def test_multispectrum_plot_eigenfunctions_notpresent(series_v100): p.add_eigenfunctions() +def test_multispectrum_plot_nobg_continua(series_v200_nobg): + p = pylbo.plot_spectrum_multi(series_v200_nobg, xdata="k3") + p.add_continua() + assert getattr(p, "c_handler") is None + + def test_merged_plot(series_v112): p = pylbo.plot_merged_spectrum(series_v112) p.draw() @@ -326,3 +338,17 @@ def test_comparison_plot_eigenfunctions(ds_v112): assert get_axis_geometry(p.panel2.ax) == (2, 1, 0) assert get_axis_geometry(p.panel2.ef_ax) == (2, 1, 1) assert len(p.fig.get_axes()) == 4 + + +def test_2d_visualisation_no_bg(ds_v200_tear_nobg): + with pytest.raises(BackgroundNotPresent): + pylbo.plot_2d_slice( + ds_v200_tear_nobg, + omega=0.1, + ef_name="rho", + u2=np.linspace(0, 1, 20), + u3=0.5, + time=0, + slicing_axis="z", + add_background=True, + ) diff --git a/tests/pylbo_tests/utility_files/v2.0.0_tear_nobg.dat b/tests/pylbo_tests/utility_files/v2.0.0_tear_nobg.dat new file mode 100644 index 00000000..fce8f536 Binary files /dev/null and b/tests/pylbo_tests/utility_files/v2.0.0_tear_nobg.dat differ