grouping_tab_widget_model.py 10.1 KB
Newer Older
1
2
3
# Mantid Repository : https://github.com/mantidproject/mantid
#
# Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI,
4
5
#   NScD Oak Ridge National Laboratory, European Spallation Source,
#   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6
# SPDX - License - Identifier: GPL - 3.0 +
7
from Muon.GUI.Common.contexts.muon_data_context import construct_empty_group, construct_empty_pair
8
9
from Muon.GUI.Common.muon_diff import MuonDiff
from Muon.GUI.Common.muon_group import MuonGroup
10
from Muon.GUI.Common.muon_pair import MuonPair
11
from Muon.GUI.Common.muon_group import MuonRun
12
13
14
15
16
17
18
from enum import Enum


class RowValid(Enum):
    invalid_for_all_runs = 0
    valid_for_all_runs = 2
    valid_for_some_runs = 1
19

20

21
22
23
24
25
26
27
28
class GroupingTabModel(object):
    """
    The model for the grouping tab should be shared between all widgets of the tab.
    It keeps a record of the groups and pairs defined for the current instance of the interface.

    pairs and groups should be of type MuonGroup and MuonPair respectively.
    """

29
    def __init__(self, context=None):
30
        self._context = context
31
        self._data = context.data_context
32
33
        self._groups_and_pairs = context.group_pair_context
        self._gui_variables = context.gui_context
34

35
    def get_group_workspace(self, group_name, run):
36
37
38
39
40
        """
        Return the workspace associated to group_name, creating one if
        it doesn't already exist (e.g. if group added to table but no update yet triggered).
        """
        try:
41
            workspace = self._groups_and_pairs[group_name].workspace[MuonRun(run)].workspace
42
        except AttributeError:
43
            workspace = self._context.calculate_group(group_name, run, rebin=False)
44
            self._groups_and_pairs[group_name].update_counts_workspace(workspace, MuonRun(run))
45
46
47
48
        return workspace

    @property
    def groups(self):
49
        return self._groups_and_pairs.groups
50
51
52

    @property
    def pairs(self):
Matthew Andrew's avatar
Matthew Andrew committed
53
        return self._groups_and_pairs.pairs
54

55
56
57
58
    @property
    def diffs(self):
        return self._groups_and_pairs.diffs

59
60
    @property
    def group_names(self):
61
        return self._groups_and_pairs.group_names
62

63
64
65
66
    @property
    def diff_names(self):
        return self._groups_and_pairs.diff_names

67
68
    @property
    def pair_names(self):
69
        return self._groups_and_pairs.pair_names
70

71
72
73
    def get_diffs(self, group_or_pair):
        return self._groups_and_pairs.get_diffs(group_or_pair)

74
75
76
77
78
79
80
81
    def get_names(self, group_or_pair):
        if group_or_pair == "group":
            return self.group_names
        elif group_or_pair == "pair":
            return self.pair_names
        else:
            return []

82
83
    @property
    def group_and_pair_names(self):
84
        return self._groups_and_pairs.group_names + self._groups_and_pairs.pair_names + self._groups_and_pairs.diff_names
85

86
87
88
89
90
91
92
93
    @property
    def selected_groups(self):
        return self._groups_and_pairs.selected_groups

    @property
    def selected_pairs(self):
        return self._groups_and_pairs.selected_pairs

94
95
96
97
    @property
    def selected_diffs(self):
        return self._groups_and_pairs.selected_diffs

98
99
    @property
    def selected_groups_and_pairs(self):
100
        return self._groups_and_pairs.selected_groups_and_pairs
101

102
    def show_all_groups_and_pairs(self):
Matthew Andrew's avatar
Matthew Andrew committed
103
104
        self._context.show_all_groups()
        self._context.show_all_pairs()
105
        self._context.show_all_diffs()
106
107

    def clear_groups(self):
Matthew Andrew's avatar
Matthew Andrew committed
108
        self._groups_and_pairs.clear_groups()
109
110

    def clear_pairs(self):
Matthew Andrew's avatar
Matthew Andrew committed
111
        self._groups_and_pairs.clear_pairs()
112

113
114
    def clear_diffs(self, group_or_pair):
        self._groups_and_pairs.clear_diffs(group_or_pair)
115

116
117
118
119
120
121
    def clear_selected_pairs(self):
        self._groups_and_pairs.clear_selected_pairs()

    def clear_selected_groups(self):
        self._groups_and_pairs.clear_selected_groups()

122
123
124
    def clear_selected_diffs(self):
        self._groups_and_pairs.clear_selected_diffs()

125
126
127
    def clear(self):
        self.clear_groups()
        self.clear_pairs()
128
129
        self.clear_diffs("group")
        self.clear_diffs("pair")
130
        self.clear_selected_groups()
131
        self.clear_selected_diffs()
132
133
134
135
136
        self.clear_selected_pairs()

    def select_all_groups_to_analyse(self):
        self._groups_and_pairs.set_selected_groups_to_all()

137
138
139
140
141
142
    def check_group_in_use(self, name):
        used_by = ""
        # check pairs
        for pair in self._groups_and_pairs.pairs:
            if name == pair.forward_group or name == pair.backward_group:
                used_by += pair.name + ", "
143
144
145
146
        # Check diffs
        used_by_diffs = self.check_if_used_by_diff(name, True)
        if used_by_diffs:
            used_by += used_by_diffs + ", "
147
148
        if used_by:
            # the -2 removes the space and comma
149
            return name + " is used by: " + used_by[0:-2]
150
151
152
        else:
            return used_by

153
    def check_if_used_by_diff(self, name, called_from_check_group=False):
154
        # check diffs
155
        used_by = ""
156
        for diff in self._groups_and_pairs.diffs:
157
            if name == diff.positive or name == diff.negative:
158
                used_by += diff.name + ", "
159
160
        if used_by:
            # the -2 removes the space and comma
161
162
163
            if called_from_check_group:
                return used_by[0:-2]
            return name + " is used by: " + used_by[0:-2]
164
165
166
        else:
            return used_by

167
168
169
170
171
172
173
174
175
176
177
    def remove_group_from_analysis(self, group):
        self._groups_and_pairs.remove_group_from_selected_groups(group)

    def add_group_to_analysis(self, group):
        self._groups_and_pairs.add_group_to_selected_groups(group)

    def remove_pair_from_analysis(self, pair):
        self._groups_and_pairs.remove_pair_from_selected_pairs(pair)

    def add_pair_to_analysis(self, pair):
        self._groups_and_pairs.add_pair_to_selected_pairs(pair)
178

179
180
181
182
183
184
    def remove_diff_from_analysis(self, diff):
        self._groups_and_pairs.remove_diff_from_selected_diffs(diff)

    def add_diff_to_analysis(self, diff):
        self._groups_and_pairs.add_diff_to_selected_diffs(diff)

185
186
    def add_group(self, group):
        assert isinstance(group, MuonGroup)
187
        self._groups_and_pairs.add_group(group)
188
189
190

    def add_pair(self, pair):
        assert isinstance(pair, MuonPair)
191
        self._groups_and_pairs.add_pair(pair)
192

193
194
195
196
    def add_diff(self, diff):
        assert isinstance(diff, MuonDiff)
        self._groups_and_pairs.add_diff(diff)

197
198
    def remove_groups_by_name(self, name_list):
        for name in name_list:
Matthew Andrew's avatar
Matthew Andrew committed
199
            self._groups_and_pairs.remove_group(name)
200
201
202

    def remove_pairs_by_name(self, name_list):
        for name in name_list:
Matthew Andrew's avatar
Matthew Andrew committed
203
            self._groups_and_pairs.remove_pair(name)
204

205
206
207
208
    def remove_diffs_by_name(self, name_list):
        for name in name_list:
            self._groups_and_pairs.remove_diff(name)

209
    def construct_empty_group(self, _group_index):
Matthew Andrew's avatar
Matthew Andrew committed
210
        return construct_empty_group(self.group_names, _group_index)
211
212

    def construct_empty_pair(self, _pair_index):
Matthew Andrew's avatar
Matthew Andrew committed
213
        return construct_empty_pair(self.group_names, self.pair_names, _pair_index)
214
215
216
217
218
219

    def construct_empty_pair_with_group_names(self, name1, name2):
        """
        Create a default pair with specific group names.
        The pair name is auto-generated and alpha=1.0
        """
Matthew Andrew's avatar
Matthew Andrew committed
220
        pair = construct_empty_pair(self.group_names, self.pair_names, 0)
221
222
        pair.forward_group = name1
        pair.backward_group = name2
223
224
225
        return pair

    def reset_groups_and_pairs_to_default(self):
226
227
        if not self._context.current_runs:
            return "failed"
228
        maximum_number_of_periods = max([self._context.num_periods(run) for run in self._context.current_runs])
229

Matthew Andrew's avatar
Matthew Andrew committed
230
        self._groups_and_pairs.reset_group_and_pairs_to_default(self._data.current_workspace, self._data.instrument,
231
                                                                self._data.main_field_direction, maximum_number_of_periods)
232
        return "success"
233

234
235
236
    def reset_selected_groups_and_pairs(self):
        self._groups_and_pairs.reset_selected_groups_and_pairs()

237
    def update_pair_alpha(self, pair_name, new_alpha):
Matthew Andrew's avatar
Matthew Andrew committed
238
        self._groups_and_pairs[pair_name].alpha = new_alpha
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

    @property
    def num_detectors(self):
        return self._data.num_detectors

    @property
    def instrument(self):
        return self._data.instrument

    @property
    def main_field_direction(self):
        return self._data.main_field_direction

    def is_data_loaded(self):
        return self._data.is_data_loaded()
254
255
256

    def get_last_data_from_file(self):
        if self._data.current_runs:
257
258
259
            return round(max(
                self._data.get_loaded_data_for_run(self._data.current_runs[-1])['OutputWorkspace'][0].workspace.dataX(
                    0)), 3)
260
        else:
Matt Cumber's avatar
Matt Cumber committed
261
            return 1.0
262
263
264

    def get_first_good_data_from_file(self):
        if self._data.current_runs:
265
            return self._data.get_loaded_data_for_run(self._data.current_runs[-1])["FirstGoodData"]
266
267
        else:
            return 0.0
268
269
270
271
272
273
274
275
276
277
278
279
280
281

    # ------------------------------------------------------------------------------------------------------------------
    # Periods
    # ------------------------------------------------------------------------------------------------------------------

    def is_data_multi_period(self):
        return self._data.is_multi_period()

    def number_of_periods(self):
        if self.is_data_multi_period():
            return len(self._data.current_data["OutputWorkspace"])
        else:
            return 1

282
283
284
    def validate_periods_list(self, periods):
        invalid_runs = []
        current_runs = self._context.current_runs
285

286
287
288
        for run in current_runs:
            if any([period < 1 or self._context.num_periods(run) < period for period in periods]):
                invalid_runs.append(run)
289

290
291
292
293
294
295
        if not invalid_runs:
            return RowValid.valid_for_all_runs
        elif len(invalid_runs) == len(current_runs):
            return RowValid.invalid_for_all_runs
        else:
            return RowValid.valid_for_some_runs
296
297
298

    def get_periods(self, name):
        return self._groups_and_pairs[name].periods
299
300
301
302
303
304

    def get_period_labels(self):
        return self._data.period_labels

    def get_num_period_cycles(self):
        return self._data.num_period_cycles