• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mantidproject / mslice / 18116790343

26 Sep 2025 09:37AM UTC coverage: 87.013% (+0.03%) from 86.984%
18116790343

push

github

web-flow
Merge pull request #1110 from cailafinn/877_cache_temperature_log

Cache the Temperature Log Entered for Use in Subsequent Slices

8 of 9 new or added lines in 1 file covered. (88.89%)

3082 of 3542 relevant lines covered (87.01%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.08
/src/mslice/presenters/slice_plotter_presenter.py
1
from typing import Optional
1✔
2

3
from matplotlib.colors import Normalize
1✔
4

5
from mslice.models.slice.slice_functions import compute_slice, compute_recoil_line
1✔
6
from mslice.models.powder.powder_functions import compute_powder_line
1✔
7
from mslice.models.cmap import ALLOWED_CMAPS
1✔
8
from mslice.models.slice.slice import Slice
1✔
9
from mslice.models.labels import is_momentum, is_twotheta
1✔
10
from mslice.models.units import convert_energy_to_meV
1✔
11
from mslice.views.slice_plotter import (
1✔
12
    set_colorbar_label,
13
    plot_cached_slice,
14
    create_slice_figure,
15
)
16
from mslice.models.workspacemanager.workspace_provider import get_workspace_handle
1✔
17
from mslice.plotting.plot_window.overplot_interface import (
1✔
18
    plot_overplot_line,
19
    remove_line,
20
)
21
from mslice.presenters.presenter_utility import PresenterUtility
1✔
22

23

24
class SlicePlotterPresenter(PresenterUtility):
1✔
25
    def __init__(self):
1✔
26
        self._main_presenter = None
1✔
27
        self._slice_cache = {}
1✔
28
        self._cached_temp = None
1✔
29

30
    def plot_slice(
1✔
31
        self,
32
        selected_ws,
33
        x_axis,
34
        y_axis,
35
        intensity_start,
36
        intensity_end,
37
        norm_to_one,
38
        colourmap,
39
    ):
40
        workspace = get_workspace_handle(selected_ws)
1✔
41
        self.create_slice(
1✔
42
            workspace,
43
            x_axis,
44
            y_axis,
45
            intensity_start,
46
            intensity_end,
47
            norm_to_one,
48
            colourmap,
49
        )
50
        self.plot_from_cache(workspace)
1✔
51

52
    def create_slice(
1✔
53
        self,
54
        selected_ws,
55
        x_axis,
56
        y_axis,
57
        intensity_start,
58
        intensity_end,
59
        norm_to_one,
60
        colourmap,
61
    ):
62
        norm = Normalize(vmin=intensity_start, vmax=intensity_end)
1✔
63
        slice = compute_slice(selected_ws, x_axis, y_axis, norm_to_one)
1✔
64
        self._cache_slice(slice, colourmap, norm, None, x_axis, y_axis)
1✔
65
        self._slice_cache[selected_ws.name].norm_to_one = norm_to_one
1✔
66
        return slice
1✔
67

68
    def plot_from_cache(self, workspace):
1✔
69
        ws_name = workspace.name.lstrip("__")
1✔
70
        create_slice_figure(ws_name, self)
1✔
71
        self.show_scattering_function(ws_name)
1✔
72

73
    def change_intensity(self, workspace_name, intensity_start, intensity_end):
1✔
74
        workspace_name = workspace_name.lstrip("__")
×
75
        intensity_start, intensity_end = self.validate_intensity(
×
76
            intensity_start, intensity_end
77
        )
78
        norm = Normalize(vmin=intensity_start, vmax=intensity_end)
×
79
        self._slice_cache[workspace_name].norm = norm
×
80

81
    def change_colourmap(self, workspace_name, colourmap):
1✔
82
        if colourmap in ALLOWED_CMAPS:
×
83
            workspace_name = workspace_name.lstrip("__")
×
84
            self._slice_cache[workspace_name].colourmap = colourmap
×
85
        else:
86
            raise ValueError("colourmap not recognised")
×
87

88
    def update_displayed_workspaces(self):
1✔
89
        self._main_presenter.update_displayed_workspaces()
×
90

91
    def _cache_slice(self, slice, colourmap, norm, sample_temp, x_axis, y_axis):
1✔
92
        rotated = not is_twotheta(x_axis.units) and not is_momentum(x_axis.units)
1✔
93
        (q_axis, e_axis) = (x_axis, y_axis) if not rotated else (y_axis, x_axis)
1✔
94
        self._slice_cache[slice.name[2:]] = Slice(
1✔
95
            slice, colourmap, norm, sample_temp, q_axis, e_axis, rotated
96
        )
97

98
    def get_slice_cache(self, workspace):
1✔
99
        return self._slice_cache[
1✔
100
            workspace.name[2:] if hasattr(workspace, "name") else workspace
101
        ]
102

103
    def show_scattering_function(self, workspace_name):
1✔
104
        slice_cache = self._slice_cache[workspace_name]
1✔
105
        plot_cached_slice(slice_cache, slice_cache.scattering_function)
1✔
106

107
    def show_dynamical_susceptibility(self, workspace_name):
1✔
108
        slice_cache = self._slice_cache[workspace_name]
×
109
        plot_cached_slice(slice_cache, slice_cache.chi)
×
110

111
    def show_dynamical_susceptibility_magnetic(self, workspace_name):
1✔
112
        slice_cache = self._slice_cache[workspace_name]
×
113
        plot_cached_slice(slice_cache, slice_cache.chi_magnetic)
×
114
        set_colorbar_label(
×
115
            "chi''(Q,E) |F(Q)|$^2$ ($mu_B$ $meV^{-1} sr^{-1} f.u.^{-1}$)"
116
        )
117

118
    def show_d2sigma(self, workspace_name):
1✔
119
        slice_cache = self._slice_cache[workspace_name]
×
120
        plot_cached_slice(slice_cache, slice_cache.d2sigma)
×
121

122
    def show_symmetrised(self, workspace_name):
1✔
123
        slice_cache = self._slice_cache[workspace_name]
×
124
        plot_cached_slice(slice_cache, slice_cache.symmetrised)
×
125

126
    def show_gdos(self, workspace_name):
1✔
127
        slice_cache = self._slice_cache[workspace_name]
×
128
        plot_cached_slice(slice_cache, slice_cache.gdos)
×
129

130
    def hide_overplot_line(self, workspace, key):
1✔
131
        cache = self._slice_cache[workspace]
1✔
132
        if key in cache.overplot_lines:
1✔
133
            line = cache.overplot_lines.pop(key)
1✔
134
            remove_line(line)
1✔
135

136
    def add_overplot_line(
1✔
137
        self,
138
        workspace_name,
139
        key,
140
        recoil,
141
        cif=None,
142
        y_has_logarithmic=None,
143
        datum=None,
144
        intensity_correction=None,
145
        **kwargs,
146
    ):
147
        cache = self._slice_cache[workspace_name]
1✔
148
        if recoil:
1✔
149
            x, y = compute_recoil_line(workspace_name, cache.momentum_axis, key)
1✔
150
        else:
151
            x, y = compute_powder_line(
1✔
152
                workspace_name, cache.momentum_axis, key, cif_file=cif
153
            )
154
        y = convert_energy_to_meV(y, cache.energy_axis.e_unit)
1✔
155
        cache.overplot_lines[key] = plot_overplot_line(
1✔
156
            x, y, key, recoil, cache, **kwargs
157
        )
158

159
    def validate_intensity(self, intensity_start, intensity_end):
1✔
160
        intensity_start = self._to_float(intensity_start)
1✔
161
        intensity_end = self._to_float(intensity_end)
1✔
162
        if (
1✔
163
            intensity_start is not None
164
            and intensity_end is not None
165
            and intensity_start > intensity_end
166
        ):
167
            raise ValueError()
1✔
168
        return intensity_start, intensity_end
1✔
169

170
    def set_sample_temperature(
1✔
171
        self, workspace_name, temp, temp_value_raw=None, is_cached=False, is_field=True
172
    ):
173
        self._slice_cache[workspace_name].sample_temp = temp
1✔
174
        if is_cached:
1✔
175
            self.set_cached_sample_temp((temp_value_raw, is_field))
1✔
176

177
    def get_cached_sample_temp(self) -> Optional[tuple[[float | str], bool]]:
1✔
NEW
178
        return self._cached_temp
×
179

180
    def set_cached_sample_temp(self, value: Optional[tuple[[float | str], bool]]):
1✔
181
        self._cached_temp = value
1✔
182

183
    def workspace_selection_changed(self):
1✔
184
        pass
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc