Completed
Push — pulsed_with_queued_connections ( d810d5...0b7aaa )
by
unknown
02:22
created

BlockEditor.set_activation_config()   A

Complexity

Conditions 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
from qtpy import QtCore
2
from qtpy import QtWidgets
3
import numpy as np
4
from collections import OrderedDict
5
6
from logic.pulse_objects import PulseBlockElement
7
from logic.pulse_objects import PulseBlock
8
from logic.pulse_objects import PulseBlockEnsemble
9
from logic.pulse_objects import PulseSequence
10
from logic.sampling_functions import SamplingFunctions
11
12
from .spinbox_delegate import SpinBoxDelegate
13
from .doublespinbox_delegate import DoubleSpinBoxDelegate
14
from .combobox_delegate import ComboBoxDelegate
15
from .checkbox_delegate import CheckBoxDelegate
16
17
18
class BlockEditor:
19
    def __init__(self, block_editor_widget):
20
        self.be_widget = block_editor_widget
21
        self.parameter_dict = OrderedDict()
22
        self.parameter_dict['length'] = {'unit': 's', 'init_val': 0.0, 'min': 0.0, 'max': np.inf,
23
                                         'view_stepsize': 1e-9, 'dec': 8, 'unit_prefix': 'n', 'type': float}
24
        self.parameter_dict['increment'] = {'unit': 's', 'init_val': 0.0, 'min': 0.0, 'max': np.inf,
25
                                            'view_stepsize': 1e-9, 'dec': 8, 'unit_prefix': 'n', 'type': float}
26
        self.parameter_dict['use as tick?'] = {'unit': '', 'init_val': 0, 'min': 0, 'max': 1, 'view_stepsize': 1,
27
                                               'dec': 0, 'unit_prefix': '', 'type': bool}
28
        self.activation_config = None
29
        self.function_config = SamplingFunctions().func_config
30
        self._cfg_param_pbe = None
31
        return
32
33 View Code Duplication
    def initialize_cells(self, start_row, stop_row=None, start_col=None, stop_col=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
34
        """ Initialize the desired cells in the block editor table.
35
36
        @param start_row: int, index of the row, where the initialization
37
                          should start
38
        @param stop_row: int, optional, index of the row, where the
39
                         initalization should end.
40
        @param start_col: int, optional, index of the column where the
41
                          initialization should start
42
        @param stop_col: int, optional, index of the column, where the
43
                         initalization should end.
44
45
        With this function it is possible to reinitialize specific elements or
46
        part of a row or even the whole row. If start_row is set to 0 the whole
47
        row is going to be initialzed to the default value.
48
        """
49
        if stop_row is None:
50
            stop_row = start_row + 1
51
        if start_col is None:
52
            start_col = 0
53
        if stop_col is None:
54
            stop_col = self.be_widget.columnCount()
55
        for col_num in range(start_col, stop_col):
56
            for row_num in range(start_row, stop_row):
57
                # get the model, here are the data stored:
58
                model = self.be_widget.model()
59
                # get the corresponding index of the current element:
60
                index = model.index(row_num, col_num)
61
                # get the initial values of the delegate class which was uses for this column:
62
                ini_values = self.be_widget.itemDelegateForColumn(col_num).get_initial_value()
63
                # set initial values:
64
                model.setData(index, ini_values[0], ini_values[1])
65
        return
66
67
    def _get_list(self):
68
        return list(self.function_config)
69
70
    def _set_columns(self):
71
        self.be_widget.blockSignals(True)
72
        # Determine the function with the most parameters. Use also that function as a construction plan to create all
73
        # the needed columns for the parameters.
74
        num_max_param = 0
75
        for func in self.function_config:
76
            if num_max_param < len(self.function_config[func]):
77
                num_max_param = len(self.function_config[func])
78
                biggest_func = func
79
80
        # Erase the delegate from the column, pass a None reference:
81
        for column in range(self.be_widget.columnCount()):
82
            self.be_widget.setItemDelegateForColumn(column, None)
83
        # clear the number of columns:
84
        self.be_widget.setColumnCount(0)
85
        # total number of analog and digital channels:
86
        num_of_columns = 0
87
        for channel in self.activation_config:
88
            if 'd_ch' in channel:
89
                num_of_columns += 1
90
            elif 'a_ch' in channel:
91
                num_of_columns += num_max_param + 1
92
        self.be_widget.setColumnCount(num_of_columns)
93
94
        column_count = 0
95
        for channel in self.activation_config:
96
            if 'a_ch' in channel:
97
                self.be_widget.setHorizontalHeaderItem(column_count, QtWidgets.QTableWidgetItem())
98
                self.be_widget.horizontalHeaderItem(column_count).setText('ACh{0}\nfunction'
99
                                                                          ''.format(channel.split('ch')[-1]))
100
                self.be_widget.setColumnWidth(column_count, 70)
101
102
                item_dict = {'get_list_method': self._get_list}
103
                delegate = ComboBoxDelegate(self.be_widget, item_dict)
104
                self.be_widget.setItemDelegateForColumn(column_count, delegate)
105
106
                column_count += 1
107
                # fill here all parameter columns for the current analogue channel
108
                for parameter in self.function_config[biggest_func]:
109
                    # initial block:
110
                    item_dict = self.function_config[biggest_func][parameter]
111
                    self.be_widget.setHorizontalHeaderItem(column_count, QtWidgets.QTableWidgetItem())
112
                    self.be_widget.horizontalHeaderItem(column_count).setText('ACh{0}\n{1} ({2})'
113
                                                                              ''.format(channel.split('ch')[-1],
114
                                                                                        parameter, item_dict['unit']))
115
                    self.be_widget.setColumnWidth(column_count, 100)
116
117
                    # extract the classname from the _param_a_ch list to be able to deligate:
118
                    delegate = DoubleSpinBoxDelegate(self.be_widget, item_dict)
119
                    self.be_widget.setItemDelegateForColumn(column_count, delegate)
120
                    column_count += 1
121
122
            elif 'd_ch' in channel:
123
                self.be_widget.setHorizontalHeaderItem(column_count, QtWidgets.QTableWidgetItem())
124
                self.be_widget.horizontalHeaderItem(column_count).setText('DCh{0}'.format(channel.split('ch')[-1]))
125
                self.be_widget.setColumnWidth(column_count, 40)
126
127
                # itemlist for checkbox
128
                item_dict = {'init_val': QtCore.Qt.Unchecked}
129
                checkDelegate = CheckBoxDelegate(self.be_widget, item_dict)
130
                self.be_widget.setItemDelegateForColumn(column_count, checkDelegate)
131
132
                column_count += 1
133
134
        # Insert the additional parameters (length etc.)
135
136
        for column, parameter in enumerate(self.parameter_dict):
137
            # add the new properties to the whole column through delegate:
138
            item_dict = self.parameter_dict[parameter]
139
140
            self.be_widget.insertColumn(num_of_columns + column)
141
            self.be_widget.setHorizontalHeaderItem(num_of_columns + column, QtWidgets.QTableWidgetItem())
142
            self.be_widget.horizontalHeaderItem(num_of_columns + column).setText('{0} ({1})'.format(parameter,
143
                                                                                                    item_dict['unit']))
144
            self.be_widget.setColumnWidth(num_of_columns + column, 90)
145
146
            # Use only DoubleSpinBox as delegate:
147
            if item_dict['type'] is bool:
148
                delegate = CheckBoxDelegate(self.be_widget, item_dict)
149
            else:
150
                delegate = DoubleSpinBoxDelegate(self.be_widget, item_dict)
151
            self.be_widget.setItemDelegateForColumn(num_of_columns + column, delegate)
152
153
            # initialize the whole row with default values:
154
            for row_num in range(self.be_widget.rowCount()):
155
                # get the model, here are the data stored:
156
                model = self.be_widget.model()
157
                # get the corresponding index of the current element:
158
                index = model.index(row_num, num_of_columns + column)
159
                # get the initial values of the delegate class which was uses for this column:
160
                ini_values = delegate.get_initial_value()
161
                # set initial values:
162
                model.setData(index, ini_values[0], ini_values[1])
163
164
        self.initialize_cells(0, self.be_widget.rowCount())
165
        self._set_cfg_param()
166
        self.be_widget.blockSignals(False)
167
        return
168
169 View Code Duplication
    def _set_cfg_param(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
170
        """ Set the parameter configuration of the Pulse_Block according to the
171
        current table configuration and updates the dict.
172
        """
173
        cfg_param_pbe = OrderedDict()
174
        for column in range(self.be_widget.columnCount()):
175
            text = self.be_widget.horizontalHeaderItem(column).text()
176
            split_text = text.split()
177
            if 'DCh' in split_text[0]:
178
                cfg_param_pbe['digital_' + split_text[0][3]] = column
179
            elif 'ACh' in split_text[0]:
180
                cfg_param_pbe[split_text[1] + '_' + split_text[0][3]] = column
181
            else:
182
                cfg_param_pbe[split_text[0]] = column
183
        self._cfg_param_pbe = cfg_param_pbe
184
        return
185
186
    def set_activation_config(self, activation_config):
187
        """
188
189
        @param activation_config:
190
        @return:
191
        """
192
        self.activation_config = activation_config
193
        self._set_columns()
194
        return
195
196
    def set_function_config(self, function_config):
197
        """
198
199
        @param function_config:
200
        @return:
201
        """
202
        self.function_config = function_config
203
        self._set_columns()
204
        return
205
206
    def clear_table(self):
207
        """ Delete all rows in the block editor table. """
208
        self.be_widget.blockSignals(True)
209
        self.be_widget.setRowCount(1)
210
        self.be_widget.clearContents()
211
        self.initialize_cells(start_row=0)
212
        self.be_widget.blockSignals(False)
213
        # FIXME: Implement a proper way to update the current block ensemble parameters
214
        return
215
216
    def delete_row(self, index):
217
        """ Delete row number 'index' """
218
        self.be_widget.blockSignals(True)
219
        self.be_widget.removeRow(index)
220
        self.be_widget.blockSignals(False)
221
        # FIXME: Implement a proper way to update the current block ensemble parameters
222
        return
223
224
    def insert_rows(self, index, number_to_add=1):
225
        """ Add 'number_to_add' rows after row number 'index' """
226
        self.be_widget.blockSignals(True)
227
        for i in range(number_to_add):
228
            self.be_widget.insertRow(index)
229
        self.initialize_cells(start_row=index, stop_row=index + number_to_add)
230
        self.be_widget.blockSignals(False)
231
        # FIXME: Implement a proper way to update the current block ensemble parameters
232
        return
233
234
    def set_element(self, row, column, value):
235
        """ Simplified wrapper function to set the data to a specific cell in the table.
236
237
        @param int row: row index
238
        @param int column: column index
239
240
        Note that the order of the arguments in this function (first row index
241
        and then column index) was taken from the Qt convention.
242
        A type check will be performed for the passed value argument. If the
243
        type does not correspond to the delegate, then the value will not be
244
        changed. You have to ensure that
245
        """
246
        model = self.be_widget.model()
247
        access = self.be_widget.itemDelegateForColumn(column).model_data_access
248
        data = model.index(row, column).data(access)
249
        if type(data) == type(value):
250
            model.setData(model.index(row, column), value, access)
251
            return value
252
        else:
253
            return data
254
255
    def get_element(self, row, column):
256
        """ Simplified wrapper function to get the data from a specific cell in the table.
257
258
        @param int row: row index
259
        @param int column: column index
260
        @return: the value of the corresponding cell, which can be a string, a
261
                 float or an integer. Remember that the checkbox state
262
                 unchecked corresponds to 0 and check to 2. That is Qt
263
                 convention.
264
265
        Note that the order of the arguments in this function (first row index
266
        and then column index) was taken from the Qt convention.
267
        """
268
        # Get from the corresponding delegate the data access model
269
        access = self.be_widget.itemDelegateForColumn(column).model_data_access
270
        data = self.be_widget.model().index(row, column).data(access)
271
        return data
272
273
    def load_pulse_block(self, block):
274
        """
275
276
        @param block:
277
        @return:
278
        """
279
        if block is None:
280
            return
281
        # seperate active analog and digital channels in lists
282
        active_analog = [chnl for chnl in self.activation_config if 'a_ch' in chnl]
283
        active_digital = [chnl for chnl in self.activation_config if 'd_ch' in chnl]
284
285
        # clear table
286
        self.clear_table()
287
        # get amout of rows needed for display
288
        rows = len(block.element_list)
289
        # since one is already present
290
        self.insert_rows(1, rows - 1)
291
292
        for row_index, elem in enumerate(block.element_list):
293
            # set at first all digital channels:
294
            for digital_ch in range(elem.digital_channels):
295
                column = self._cfg_param_pbe['digital_' + active_digital[digital_ch].split('ch')[-1]]
296
                value = elem.digital_high[digital_ch]
297
                if value:
298
                    value = 2
299
                else:
300
                    value = 0
301
                self.set_element(row_index, column, value)
302
303
            # now set all parameters for the analog channels:
304
            for analog_ch in range(elem.analog_channels):
305
                # the function text:
306
                column = self._cfg_param_pbe['function_' + active_analog[analog_ch].split('ch')[-1]]
307
                func_text = elem.pulse_function[analog_ch]
308
                self.set_element(row_index, column, func_text)
309
                # then the parameter dictionary:
310
                parameter_dict = elem.parameters[analog_ch]
311
                for parameter in parameter_dict:
312
                    column = self._cfg_param_pbe[parameter + '_' + active_analog[analog_ch].split('ch')[-1]]
313
                    value = np.float(parameter_dict[parameter])
314
                    self.set_element(row_index, column, value)
315
316
            # now set use as tick parameter:
317
            column = self._cfg_param_pbe['use']
318
            value = elem.use_as_tick
319
            # the ckeckbox has a special input value, it is 0, 1 or 2. (tri-state)
320
            if value:
321
                value = 2
322
            else:
323
                value = 0
324
            self.set_element(row_index, column, value)
325
326
            # and set the init_length:
327
            column = self._cfg_param_pbe['length']
328
            value = elem.init_length_s
329
            self.set_element(row_index, column, value)
330
331
            # and set the increment parameter
332
            column = self._cfg_param_pbe['increment']
333
            value = elem.increment_s
334
            self.set_element(row_index, column, value)
335
        return
336
337
    def generate_block_object(self, pb_name):
338
        """ Generates from an given table block_matrix a block_object.
339
340
        @param pb_name: string, Name of the created Pulse_Block Object
341
        """
342
343
        # list of all the pulse block element objects
344
        pbe_obj_list = [None] * self.be_widget.rowCount()
345
346
        # seperate digital and analogue channels
347
        analog_chnl_names = [chnl for chnl in self.activation_config if 'a_ch' in chnl]
348
        digital_chnl_names = [chnl for chnl in self.activation_config if 'd_ch' in chnl]
349
350
        for row_index in range(self.be_widget.rowCount()):
351
            # get length:
352
            init_length_s = self.get_element(row_index, self._cfg_param_pbe['length'])
353
            # get increment:
354
            increment_s = self.get_element(row_index, self._cfg_param_pbe['increment'])
355
356
            # get the proper pulse_functions and its parameters:
357
            pulse_function = [None] * len(analog_chnl_names)
358
            parameter_list = [None] * len(analog_chnl_names)
359
            for chnl_index, chnl in enumerate(analog_chnl_names):
360
                # get the number of the analogue channel according to the channel activation_config
361
                a_chnl_number = chnl.split('ch')[-1]
362
                pulse_function[chnl_index] = self.get_element(row_index, self._cfg_param_pbe['function_' + a_chnl_number])
363
364
                # search for this function in the dictionary and get all the parameter with their names in list:
365
                param_dict = self.function_config[pulse_function[chnl_index]]
366
                parameters = {}
367
                for entry in list(param_dict):
368
                    # Obtain how the value is displayed in the table:
369
                    param_value = self.get_element(row_index,
370
                                                   self._cfg_param_pbe[entry + '_' + a_chnl_number])
371
                    parameters[entry] = param_value
372
                parameter_list[chnl_index] = parameters
373
374
            digital_high = [None] * len(digital_chnl_names)
375
            for chnl_index, chnl in enumerate(digital_chnl_names):
376
                # get the number of the digital channel according to the channel activation_config
377
                d_chnl_number = chnl.split('ch')[-1]
378
                digital_high[chnl_index] = bool(self.get_element(row_index, self._cfg_param_pbe['digital_' + d_chnl_number]))
379
380
            use_as_tick = bool(self.get_element(row_index, self._cfg_param_pbe['use']))
381
382
            # create here actually the object with all the obtained information:
383
            pbe_obj_list[row_index] = PulseBlockElement(init_length_s=init_length_s,
384
                                                          increment_s=increment_s,
385
                                                          pulse_function=pulse_function,
386
                                                          digital_high=digital_high,
387
                                                          parameters=parameter_list,
388
                                                          use_as_tick=use_as_tick)
389
        pb_obj = PulseBlock(pb_name, pbe_obj_list)
390
        return pb_obj
391
392
393
class BlockOrganizer:
394
    def __init__(self, block_organizer_widget):
395
        self.bo_widget = block_organizer_widget
396
        self.parameter_dict = OrderedDict()
397
        self.parameter_dict['repetitions'] = {'unit': '#', 'init_val': 0, 'min': 0,
398
                                              'max': (2 ** 31 - 1), 'view_stepsize': 1, 'dec': 0,
399
                                              'unit_prefix': '', 'type': int}
400
        self._cfg_param_pb = None
401
        self.block_dict = None
402
        return
403
404
    def set_block_dict(self, block_dict):
405
        if self.block_dict is None:
406
            self.block_dict = block_dict
407
            self._set_columns()
408
        else:
409
            self.block_dict = block_dict
410
411
        for row in range(self.bo_widget.rowCount()):
412
            data = self.get_element(row, 0)
413
            if data not in list(self.block_dict):
414
                self.initialize_cells(start_row=row, stop_row=row+1, start_col=0, stop_col=1)
415
        return
416
417
    def _get_list(self):
418
        return list(self.block_dict)
419
420 View Code Duplication
    def initialize_cells(self, start_row, stop_row=None, start_col=None, stop_col=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
421
        """ Initialize the desired cells in the block organizer table.
422
423
        @param start_row: int, index of the row, where the initialization
424
                          should start
425
        @param stop_row: int, optional, index of the row, where the
426
                         initalization should end.
427
        @param start_col: int, optional, index of the column where the
428
                          initialization should start
429
        @param stop_col: int, optional, index of the column, where the
430
                         initalization should end.
431
432
        With this function it is possible to reinitialize specific elements or
433
        part of a row or even the whole row. If start_row is set to 0 the whole
434
        row is going to be initialzed to the default value.
435
        """
436
        if stop_row is None:
437
            stop_row = start_row +1
438
        if start_col is None:
439
            start_col = 0
440
        if stop_col is None:
441
            stop_col = self.bo_widget.columnCount()
442
        for col_num in range(start_col, stop_col):
443
            for row_num in range(start_row,stop_row):
444
                # get the model, here are the data stored:
445
                model = self.bo_widget.model()
446
                # get the corresponding index of the current element:
447
                index = model.index(row_num, col_num)
448
                # get the initial values of the delegate class which was uses for this column:
449
                ini_values = self.bo_widget.itemDelegateForColumn(col_num).get_initial_value()
450
                # set initial values:
451
                model.setData(index, ini_values[0], ini_values[1])
452
        return
453
454
    def _set_columns(self):
455
        # Erase the delegate from the column, i.e. pass a None reference:
456
        for column in range(self.bo_widget.columnCount()):
457
            self.bo_widget.setItemDelegateForColumn(column, None)
458
        # clear the number of columns and set them to 1:
459
        self.bo_widget.setColumnCount(1)
460
        self.bo_widget.setHorizontalHeaderItem(0, QtWidgets.QTableWidgetItem())
461
        self.bo_widget.horizontalHeaderItem(0).setText('Pulse Block')
462
        self.bo_widget.setColumnWidth(0, 100)
463
464
        item_dict = {}
465
        item_dict['get_list_method'] = self._get_list
466
        comboDelegate = ComboBoxDelegate(self.bo_widget, item_dict)
467
        self.bo_widget.setItemDelegateForColumn(0, comboDelegate)
468
469
        for column, parameter in enumerate(self.parameter_dict):
470
            # add the new properties to the whole column through delegate:
471
            item_dict = self.parameter_dict[parameter]
472
            unit_text = item_dict['unit_prefix'] + item_dict['unit']
473
            self.bo_widget.insertColumn(1+column)
474
            self.bo_widget.setHorizontalHeaderItem(1+column, QtWidgets.QTableWidgetItem())
475
            self.bo_widget.horizontalHeaderItem(1+column).setText('{0} ({1})'.format(parameter,unit_text))
476
            self.bo_widget.setColumnWidth(1+column, 80)
477
            # Use only DoubleSpinBox as delegate:
478
            if item_dict['unit'] == 'bool':
479
                delegate = CheckBoxDelegate(self.bo_widget, item_dict)
480
            elif parameter == 'repetitions':
481
                delegate = SpinBoxDelegate(self.bo_widget, item_dict)
482
            else:
483
                delegate = DoubleSpinBoxDelegate(self.bo_widget, item_dict)
484
            self.bo_widget.setItemDelegateForColumn(1+column, delegate)
485
486
        self.initialize_cells(start_row=0, stop_row=self.bo_widget.rowCount())
487
        self._set_cfg_param()
488
        # FIXME: Implement a proper way to update the current block ensemble parameters
489
        return
490
491 View Code Duplication
    def _set_cfg_param(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
492
        """ Set the parameter configuration of the Pulse_Block according to the
493
        current table configuration and updates the dict.
494
        """
495
        cfg_param_pb = OrderedDict()
496
        for column in range(self.bo_widget.columnCount()):
497
            text = self.bo_widget.horizontalHeaderItem(column).text()
498
            if 'Pulse Block' in text:
499
                cfg_param_pb['pulse_block'] = column
500
            elif 'repetitions' in text:
501
                cfg_param_pb['repetitions'] = column
502
            else:
503
                print('text:', text)
504
                raise NotImplementedError
505
        self._cfg_param_pb = cfg_param_pb
506
        return
507
508
    def clear_table(self):
509
        """ Delete all rows in the block editor table. """
510
        self.bo_widget.blockSignals(True)
511
        self.bo_widget.setRowCount(1)
512
        self.bo_widget.clearContents()
513
        self.initialize_cells(start_row=0)
514
        self.bo_widget.blockSignals(False)
515
        # FIXME: Implement a proper way to update the current block ensemble parameters
516
        return
517
518
    def delete_row(self, index):
519
        """ Delete row number 'index' """
520
        self.bo_widget.removeRow(index)
521
        # FIXME: Implement a proper way to update the current block ensemble parameters
522
        return
523
524
    def insert_rows(self, index, number_to_add=1):
525
        """ Add 'number_to_add' rows after row number 'index' """
526
        self.bo_widget.blockSignals(True)
527
        for i in range(number_to_add):
528
            self.bo_widget.insertRow(index)
529
        self.initialize_cells(start_row=index, stop_row=index + number_to_add)
530
        self.bo_widget.blockSignals(False)
531
        # FIXME: Implement a proper way to update the current block ensemble parameters
532
        return
533
534
    def set_element(self, row, column, value):
535
        """ Simplified wrapper function to set the data to a specific cell in the table.
536
537
        @param int row: row index
538
        @param int column: column index
539
540
        Note that the order of the arguments in this function (first row index and then column
541
        index) was taken from the Qt convention. A type check will be performed for the passed
542
        value argument. If the type does not correspond to the delegate, then the value will not be
543
        changed. You have to ensure that.
544
        """
545
        model = self.bo_widget.model()
546
        access = self.bo_widget.itemDelegateForColumn(column).model_data_access
547
        data = self.bo_widget.model().index(row, column).data(access)
548
        if type(data) == type(value):
549
            model.setData(model.index(row, column), value, access)
550
            return value
551
        else:
552
            return data
553
554
    def get_element(self, row, column):
555
        """ Simplified wrapper function to get the data from a specific cell in the table.
556
557
        @param int row: row index
558
        @param int column: column index
559
        @return: the value of the corresponding cell, which can be a string, a
560
                 float or an integer. Remember that the checkbox state
561
                 unchecked corresponds to 0 and check to 2. That is Qt
562
                 convention.
563
564
        Note that the order of the arguments in this function (first row index
565
        and then column index) was taken from the Qt convention.
566
        """
567
        # Get from the corresponding delegate the data access model
568
        access = self.bo_widget.itemDelegateForColumn(column).model_data_access
569
        data = self.bo_widget.model().index(row, column).data(access)
570
        return data
571
572
    def load_pulse_block_ensemble(self, ensemble):
573
        """
574
575
        @param ensemble:
576
        """
577
        # Sanity checks:
578
        if ensemble is None:
579
            return
580
        # clear the block organizer table
581
        self.clear_table()
582
        # get amout of rows needed for display
583
        rows = len(ensemble.block_list)
584
        # add as many rows as there are blocks in the ensemble minus 1 because a single row is
585
        # already present after clear
586
        self.insert_rows(1, rows - 1)
587
        # run through all blocks in the block_elements block_list to fill in the row informations
588
        for row_index, (pulse_block, repetitions) in enumerate(ensemble.block_list):
589
            column = self._cfg_param_pb['pulse_block']
590
            self.set_element(row_index, column, pulse_block.name)
591
            column = self._cfg_param_pb['repetitions']
592
            self.set_element(row_index, column, int(repetitions))
593
        return
594
595
    def generate_ensemble_object(self, ensemble_name, rotating_frame=True):
596
        """
597
        Generates from an given table ensemble_matrix a ensemble object.
598
599
        @param str ensemble_name: Name of the created PulseBlockEnsemble object
600
        @param bool rotating_frame: optional, whether the phase preservation is mentained
601
                                    throughout the sequence.
602
        """
603
        # list of all the pulse block element objects
604
        pb_obj_list = [None] * self.bo_widget.rowCount()
605
606
        for row_index in range(self.bo_widget.rowCount()):
607
            pulse_block_name = self.get_element(row_index, self._cfg_param_pb['pulse_block'])
608
            pulse_block_reps = self.get_element(row_index, self._cfg_param_pb['repetitions'])
609
            # Fetch previously saved block object
610
            block = self.block_dict[pulse_block_name]
611
            # Append block object along with repetitions to the block list
612
            pb_obj_list[row_index] = (block, pulse_block_reps)
613
614
        # Create the Pulse_Block_Ensemble object
615
        pulse_block_ensemble = PulseBlockEnsemble(name=ensemble_name, block_list=pb_obj_list,
616
                                                    rotating_frame=rotating_frame)
617
        return pulse_block_ensemble
618