drltools.py 19 KB
Newer Older
Yan's avatar
Yan committed
1
2
3
4
5
#!/usr/bin/env python3
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PyQt5 import QtCore
from PyQt5 import QtWidgets
6
from PyQt5 import QtGui
Yan's avatar
Yan committed
7
from PyQt5 import QtPrintSupport
Yan's avatar
Yan committed
8
9
import matplotlib
import numpy as np
Yan's avatar
Yan committed
10
11
import prasopes.datatools as dt
import prasopes.graphtools as gt
Yan's avatar
Yan committed
12
import prasopes.filetools as ft
Yan's avatar
Yan committed
13
14
matplotlib.use("Qt5Agg")

Yan's avatar
Yan committed
15

Yan's avatar
Yan committed
16
class HBar(QtWidgets.QFrame):
17
    """horizontal bar class"""
Yan's avatar
Yan committed
18
19
20
21
22
23
    def __init__(self):
        super(HBar, self).__init__()
        self._main = QtWidgets.QWidget()
        self.setFrameShape(QtWidgets.QFrame.HLine)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def floatize(table, row, column):
    """grabs the tableWidgetItem and transforms its text safely to
    float, if the text is not acceptable as float, returns zero"""
    imptext = table.item(row, column).text()
    validator = QtGui.QDoubleValidator()
    validator.setBottom(0)
    status = validator.validate(imptext, 0)[0]
    if status == QtGui.QValidator.Acceptable:
        outfloat = float(imptext)
    else:
        outfloat = 0
    return outfloat


def update_profile(pt, row, dataset):
39
    """spectrum updating procedure"""
Yan's avatar
Yan committed
40
41
    # Dont do anything to graph when the spectrum is not populated
    if isinstance(dataset['masses'], type(None)):
42
43
        return

44
    spectrum = pt.cellWidget(row, 3).figure.get_axes()[0]
Yan's avatar
Yan committed
45
    masses = dataset['masses']
46
47
    massargs = dt.argsubselect(
        masses, floatize(pt, row, 1), floatize(pt, row, 2))
48
    yshape = np.mean(dataset['matrix'], axis=0)
Yan's avatar
Yan committed
49
    spectrum.clear()
50
51
52
    spectrum.plot(masses, yshape, ':', color='gray')
    spectrum.plot(masses[massargs], yshape[massargs], 'r')
    xex = max((masses[massargs[-1]]-masses[massargs[0]])*0.25, 0.20)
Yan's avatar
Yan committed
53
54
55
    spectrum.set_xlim(masses[massargs[0]]-xex,
                      masses[massargs[-1]]+xex)
    ymax = max(yshape[massargs])
56
57
58
    spectrum.set_ylim(ymax*-0.1, ymax*1.2)
    spectrum.figure.canvas.draw()

Yan's avatar
Yan committed
59

Yan's avatar
Yan committed
60
61
62
63
64
65
66
67
68
def get_intensity(row, ptable, dtable, ds):
    startm = floatize(ptable, row, 1)
    endm = floatize(ptable, row, 2)
    massargs = dt.argsubselect(ds['masses'], startm, endm)
    intensity = (np.sum(
        ds['matrix'].T[massargs].T, axis=1)) / ds['chrom_dat'][1]
    return intensity


Yan's avatar
Yan committed
69
def get_daughterset(ptable, dtable, ds):
Yan's avatar
Yan committed
70
    # TODO: write a less resources demanding function - probably "per-line"
Yan's avatar
Yan committed
71
    names = []
Yan's avatar
Yan committed
72
    times = ds['chrom_dat'][0, :]
Yan's avatar
Yan committed
73
    intensities = []
Yan's avatar
Yan committed
74
    # TODO: resolve intensities trouble
Yan's avatar
Yan committed
75
    for row in range(dtable.rowCount()):
Yan's avatar
Yan committed
76
        if dtable.cellWidget(row, 0).checkState() == 2:
Yan's avatar
Yan committed
77
            intensity = get_intensity(row, ptable, dtable, ds)
78
79
            cor = dtable.cellWidget(row, 1).currentIndex() - 1
            # TODO: check if cor still produce the mess or it started to behave
80
            # testing in this alpha stage
81
            if cor not in (-2, -1):
82
                factor = floatize(dtable, row, 2)
Yan's avatar
Yan committed
83
84
                correction = get_intensity(cor, ptable, dtable, ds)\
                    * factor
Yan's avatar
Yan committed
85
                intensity = intensity - correction
Yan's avatar
Yan committed
86
            intensities.append(intensity)
Yan's avatar
Yan committed
87
88
89
90
            names.append("{} - {} * {}".format(
                dtable.item(row, 0).text(),
                dtable.item(row,2).text(),
                dtable.cellWidget(row,1).currentText()))
Yan's avatar
Yan committed
91
92
93
    return names, times, intensities


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def get_parentset(ptable, dtable, ds):
    names = []
    times = ds['chrom_dat'][0, :]
    intensities = []
    # TODO: resolve intensities trouble
    rowlist = []
    for row in range(dtable.rowCount()):
        if dtable.cellWidget(row, 0).checkState() == 2:
            rowlist.append(row)
            if dtable.cellWidget(row, 1).currentIndex() > 0\
                    and floatize(dtable, row, 2) != 0:
                rowlist.append(
                    dtable.cellWidget(row, 1).currentIndex()-1)
    for row in set(rowlist):
            intensity = get_intensity(row, ptable, dtable, ds)
            intensities.append(intensity)
            names.append(dtable.item(row, 0).text())
    return names, times, intensities


Yan's avatar
Yan committed
114
def update_drlspectrum(ptable, dtable, ds, drlspectrum):
115
    # Dont do anything when the dataset is not populated
Yan's avatar
Yan committed
116
    if isinstance(ds['masses'], type(None)):
Yan's avatar
Yan committed
117
        return
118
    colors = np.array([[0, 0, 0], [255, 0, 0], [0, 255, 0], [0, 0, 255],
119
120
121
                       [0, 200, 255], [255, 200, 0], [255, 100, 0],
                       [200, 50, 0], [255, 0, 200], [0, 100, 0],
                       [0, 100, 255], [100, 100, 100]])
Yan's avatar
Yan committed
122

123
    # TODO: write a less resources demanding function
Yan's avatar
Yan committed
124
125
126
    names, times, intensities = get_daughterset(ptable, dtable, ds)
    for i in range(len(drlspectrum.lines)):
        drlspectrum.lines[0].remove()
127

128
    i = 0
129
    for row in range(dtable.rowCount()):
Yan's avatar
Yan committed
130
        if dtable.cellWidget(row, 0).checkState() == 2:
131
            dtable.blockSignals(True)
Yan's avatar
Yan committed
132
            dtable.item(row, 0).setBackground(QtGui.QBrush(
133
                QtGui.QColor(*colors[row % len(colors)], alpha=50)))
134
135
            dtable.blockSignals(False)
            label = " {}".format(ptable.item(row, 0).text())
136
137
138
            drlspectrum.plot(times, intensities[i], label=label,
                             color=(colors[row % len(colors)] / 255))
            i += 1
139
        else:
Yan's avatar
Yan committed
140
            dtable.item(row, 0).setBackground(QtGui.QBrush())
141

142
143
144
145
    if len(names) != 0:
        drlspectrum.set_ylim(top=np.amax(intensities)*1.1,
                             bottom=np.amax(intensities)*-0.01)
        drlspectrum.legend(loc=2)
146
147
    drlspectrum.figure.canvas.draw()

Yan's avatar
Yan committed
148

Yan's avatar
Yan committed
149
def gettableitemlist(ptable):
150
    ion_list = []
Yan's avatar
Yan committed
151
152
153
    for row in range(ptable.rowCount()):
        text = []
        for i in range(3):
154
155
            if not isinstance(ptable.item(row, i), type(None)):
                frg = ptable.item(row, i).text()
Yan's avatar
Yan committed
156
157
158
159
160
            else:
                frg = ""
            text.append(frg)
        line = "{} ({}-{})".format(*text)
        ion_list.append(line)
161
162
163
    return ion_list


164
165
166
167
168
169
170
171
172
173
174
175
def update_corrfors(ptable, dtable):
    """update corrections selection layout of the daughter table"""
    ionlist = gettableitemlist(ptable)
    for row in range(dtable.rowCount()):
        corfor = dtable.cellWidget(row, 1)
        index = corfor.currentIndex()
        corfor.blockSignals(True)
        corfor.clear()
        corfor.addItem("")
        corfor.addItems(ionlist)
        corfor.setCurrentIndex(index)
        corfor.blockSignals(False)
Yan's avatar
Yan committed
176

177

Yan's avatar
Yan committed
178
179
def ptable_changed(row, column, ptable, dtable, ds, drlspectrum,
                   addline=True):
180
181
182
183
184
    """routine called by change of the ptable spectra"""
    update_corrfors(ptable, dtable)
    dtable.item(row, 0).setText(gettableitemlist(ptable)[row])
    if column in (1, 2):
        update_profile(ptable, row, ds)
Yan's avatar
Yan committed
185
186
    if row == ptable.rowCount() - 1 and addline == True:
        add_line(ds, ptable, dtable, drlspectrum)
187

188

189
190
191
192
193
194
195
def dtable_changed(row, column, ptable, dtable, ds, drlspectrum):
    """routine called by change of the dtable spectra"""
    if dtable.cellWidget(row, 0).checkState() == 2:
        if (column == 0)\
           or (column == 2
               and dtable.cellWidget(row, 1).currentIndex() != 0):
                update_drlspectrum(ptable, dtable, ds, drlspectrum)
196

Yan's avatar
Yan committed
197

198
199
200
201
202
def corr_changed(row, ptable, dtable, ds, drlspectrum):
    """routine called by change of correction for ion"""
    if (dtable.cellWidget(row, 0).checkState() == 2
       and floatize(dtable, row, 2) != 0):
        update_drlspectrum(ptable, dtable, ds, drlspectrum)
203
204


205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
def delete_row(row, ptable, dtable, ds, drlspectrum):
    dtable.cellWidget(row,0).setCheckState(0)
    dtable.removeRow(row)
    ptable.removeRow(row)
    for i in range(dtable.rowCount()):
        corfor = dtable.cellWidget(i, 1)
        corfor.disconnect()
        index = corfor.currentIndex()
        corfor.clear()
        corfor.addItem("")
        corfor.addItems(gettableitemlist(ptable))
        if index == row+1:
            corfor.setCurrentIndex(0)
            corr_changed(i, ptable, dtable, ds, drlspectrum)
        elif index > row+1:
            corfor.setCurrentIndex(index-1)
        else:
            corfor.setCurrentIndex(index)
        corfor.currentIndexChanged.connect(lambda: corr_changed(
            i, ptable, dtable, ds, drlspectrum))


227
def remove_rows(ptable, dtable, ds, drlspectrum):
Yan's avatar
Yan committed
228
    # TODO: maybe nicer selection in future, but this works for now
229
    rows = reversed(list(set(
Yan's avatar
Yan committed
230
        map(lambda x: x.row(), ptable.selectedIndexes()))))
231
    for row in rows:
232
        delete_row(row, ptable, dtable, ds, drlspectrum)
233
234


Yan's avatar
Yan committed
235
def add_line(ds, parenttable, daughtertable, drlspectrum):
236
    """add parent ion to the table"""
237
238
239
240
241
242
243
244
245
246
247
248
    newrow = parenttable.rowCount()

    parenttable.blockSignals(True)
    daughtertable.blockSignals(True)

    parenttable.setRowCount(newrow + 1)
    for i in range(3):
        parenttable.setItem(newrow, i, QtWidgets.QTableWidgetItem())
        if newrow is not 0:
            parenttable.item(newrow, i).setText(str(floatize(
                    parenttable, newrow-1, i)+1))

249
    ion_graph = Figure(figsize=(3, 1.5), dpi=100, facecolor="None")
250
251
    ion_graph.add_subplot(111, facecolor=(1, 1, 1, 0.8),
                          position=(-0.01, -0.01, 1.02, 1.02))
252
253
254
255
    graph_canvas = FigureCanvas(ion_graph)
    graph_canvas.setStyleSheet("background-color:transparent;")
    graph_canvas.setAutoFillBackground(False)
    parenttable.setCellWidget(newrow, 3, graph_canvas)
256

257
    daughtertable.setRowCount(newrow + 1)
Yan's avatar
Yan committed
258
    checkbox = QtWidgets.QCheckBox()
259
260
    dname = QtWidgets.QTableWidgetItem()
    dname.setFlags(dname.flags() & ~QtCore.Qt.ItemIsEditable)
Yan's avatar
Yan committed
261
    dname.setTextAlignment(QtCore.Qt.AlignRight)
Yan's avatar
Yan committed
262
263
    daughtertable.setItem(newrow, 0, dname)
    daughtertable.setCellWidget(newrow, 0, checkbox)
264
265
266
267
268
269
270
271
    corfor = QtWidgets.QComboBox()
    corfor.setFrame(False)
    daughtertable.setCellWidget(newrow, 1, corfor)
    daughtertable.setItem(newrow, 2, QtWidgets.QTableWidgetItem())

    parenttable.blockSignals(False)
    daughtertable.blockSignals(False)

Yan's avatar
Yan committed
272
273
    ptable_changed(newrow, 1, parenttable, daughtertable, ds,
                   drlspectrum, False)
274

Yan's avatar
Yan committed
275
276
    checkbox.stateChanged.connect(lambda: update_drlspectrum(
        parenttable, daughtertable, ds, drlspectrum))
277
278
    corfor.currentIndexChanged.connect(lambda: corr_changed(
        newrow, parenttable, daughtertable, ds, drlspectrum))
279
280


Yan's avatar
Yan committed
281
def iontable(labels):
282
283
    """creates a table for ions"""
    table = QtWidgets.QTableWidget(columnCount=len(labels))
284
    table.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
285
286
                        QtWidgets.QSizePolicy.Expanding)
    table.setHorizontalHeaderLabels(labels)
287
288
289
290
291
    table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

    for n in range(table.columnCount()):
        table.horizontalHeader().setSectionResizeMode(
            n, QtWidgets.QHeaderView.Stretch)
Yan's avatar
Yan committed
292
    table.setMinimumSize(600, 0)
293

294
    return table
295
296


Yan's avatar
Yan committed
297
298
299
300
301
302
303
304
305
306
307
308
309
310
def load_drltables(parent, ptable, dtable, dataset, drlspectrum):
    filename = QtWidgets.QFileDialog.getOpenFileName(
            caption="Load DRL config tables",
            filter="comma-separated values (*.csv)")[0]
    if filename is not '':
        names = []
        start_masses = []
        end_masses = []
        states = []
        corrected_to = []
        corr_factors = []

        with open(filename, 'r') as cfile:
            rawdata = cfile.read().splitlines()
Yan's avatar
Yan committed
311
312
        for i in range(1, len(rawdata)):
            rawline = rawdata[i].split(",")
313
            # TODO: rawline[4] can be -1 - decide if accept this behaviour
Yan's avatar
Yan committed
314
            if len(rawline) != 6 or int(rawline[3]) not in range(3) \
315
                    or int(rawline[4]) not in range(-1,len(rawdata)):
Yan's avatar
Yan committed
316
317
318
319
320
321
                QtWidgets.QMessageBox.warning(
                    parent, "Load DRL config tables",
                    "Config file corrupted on line {},"
                    " cancelling request".format(i+1))
                return
            for j, k in enumerate((names, start_masses, end_masses,
Yan's avatar
Yan committed
322
                                   states, corrected_to, corr_factors)):
Yan's avatar
Yan committed
323
                k.append(rawline[j])
Yan's avatar
Yan committed
324
325
326
        for row in reversed(range(ptable.rowCount())):
            dtable.removeRow(row)
            ptable.removeRow(row)
327
        # first populate only the parent table
Yan's avatar
Yan committed
328
        for i in range(len(names)):
Yan's avatar
Yan committed
329
            add_line(dataset, ptable, dtable, drlspectrum)
330
331
332
            ptable.item(i, 0).setText(names[i])
            ptable.item(i, 1).setText(start_masses[i])
            ptable.item(i, 2).setText(end_masses[i])
333
        # and after that the daughter table
Yan's avatar
Yan committed
334
        for i in range(len(names)):
Yan's avatar
Yan committed
335
            dtable.cellWidget(i, 1).setCurrentIndex(
Yan's avatar
Yan committed
336
                int(corrected_to[i]))
337
            dtable.item(i, 2).setText(corr_factors[i])
Yan's avatar
Yan committed
338
            dtable.cellWidget(i, 0).setCheckState(int(states[i]))
Yan's avatar
Yan committed
339
340


Yan's avatar
Yan committed
341
342
343
344
345
346
347
348
349
350
351
352
def save_drlconfig(ptable, dtable, parent):
    """safe DRL table layout so it can be summoned when needed"""
    exp_f_name = ft.get_save_filename(
        "Save DRL table layout", "comma-separated values (*.csv)",
        "csv", parent)
    if exp_f_name is not '':
        expf = open(exp_f_name, 'w')
        expf.write("#ion_name, start m/z, end m/z, visible,"
                   "corrected_to, factor\n")
        for row in range(ptable.rowCount()):
            vals = []
            for i in range(3):
353
                vals.append(ptable.item(row, i).text())
Yan's avatar
Yan committed
354
355
            vals.append(dtable.cellWidget(row, 0).checkState())
            vals.append(dtable.cellWidget(row, 1).currentIndex())
356
            vals.append(dtable.item(row, 2).text())
Yan's avatar
Yan committed
357
358
359
            expf.write("{}\n".format((",".join(map(str, vals)))))
        expf.close()

Yan's avatar
Yan committed
360

Yan's avatar
Yan committed
361
362
363
364
365
366
367
def export_drlspectrum(parent, fn, ptable, dtable, ds):
    if fn[0] is None:
        QtWidgets.QMessageBox.warning(
            main_window, "Export DRL dataset",
            "Nothing to export, cancelling request")
        return
    names, times, intensities = get_daughterset(ptable, dtable, ds)
368
    pnames, ptimes, pintensities = get_parentset(ptable, dtable, ds)
Yan's avatar
Yan committed
369
370
    exp_f_name = ft.get_save_filename(
        "Export DRL data", "comma-separated values (*.csv)", "csv", parent)
371
372
373
    names.append(" ")
    for name in pnames:
        names.append(name)
Yan's avatar
Yan committed
374
375
376
377
    if exp_f_name is not '':
        expf = open(exp_f_name, 'w')
        expf.write("times, {}\n".format((",".join(names))))
        for i in range(len(times)):
Yan's avatar
Yan committed
378
            dataset = list()
Yan's avatar
Yan committed
379
380
381
            dataset.append(times[i])
            for intensity in intensities:
                dataset.append(intensity[i])
382
383
384
            dataset.append(" ")
            for intensity in pintensities:
                dataset.append(intensity[i])
Yan's avatar
Yan committed
385
386
387
            expf.write("{}\n".format((",".join(map(str, dataset)))))
        expf.close()

Yan's avatar
Yan committed
388

Yan's avatar
Yan committed
389
def print_graph(labels, ptable, dtable, ds):
Yan's avatar
Yan committed
390
    printfig = Figure(figsize=(5, 2), dpi=100)
Yan's avatar
Yan committed
391
392
393
394
    printplot = printfig.add_subplot(111)
    printcanvas = FigureCanvas(printfig)
    gt.pop_plot(printplot, labels)
    update_drlspectrum(ptable, dtable, ds, printplot)
Yan's avatar
Yan committed
395
    widget = QtWidgets.QDialog(None, windowTitle='Print preview')
Yan's avatar
Yan committed
396
397
    layout = QtWidgets.QVBoxLayout(widget)
    layout.addWidget(printcanvas)
Yan's avatar
Yan committed
398
    widget.resize(600, 400)
Yan's avatar
Yan committed
399
400
401
402
403
404
405
    widget.show()
    dialog = QtPrintSupport.QPrintDialog()
    if dialog.exec_() == QtWidgets.QDialog.Accepted:
        printcanvas.render(dialog.printer())
    widget.close()


406
407
408
409
410
def key_pressed(event, ptable, dtable, ds, drlspectrum):
    if event.key() == QtCore.Qt.Key_Delete:
        for row in map(lambda x: x.row(),
                       ptable.selectionModel().selectedRows()):
            delete_row(row, ptable, dtable, ds, drlspectrum)
Yan's avatar
Yan committed
411
412
413
414
    if event.key() == QtCore.Qt.Key_F5:
        update_drlspectrum(ptable, dtable, ds, drlspectrum)
        for row in range(ptable.rowCount()):
            update_profile(ptable, row, ds)
415
416


Yan's avatar
Yan committed
417
def main_window(parent, ds, filename, cache):
418
    """constructs a dialog window"""
Yan's avatar
Yan committed
419
420
    def saveonclose(widget, event, buffer, ptable, dautable, canvas):
        buffer[0], buffer[1], buffer[2] = ptable, dautable, canvas
Yan's avatar
Yan committed
421
        QtWidgets.QMainWindow.closeEvent(widget, event)
Yan's avatar
Yan committed
422

Yan's avatar
Yan committed
423
    window = QtWidgets.QMainWindow(
Yan's avatar
Yan committed
424
        parent, windowTitle='Delayed reactant labelling')
Yan's avatar
Yan committed
425
426
    main_widget = QtWidgets.QWidget(window)
    window.setCentralWidget(main_widget)
Yan's avatar
Yan committed
427

Yan's avatar
Yan committed
428
    window.closeEvent = lambda event: saveonclose(
Yan's avatar
Yan committed
429
        window, event, cache, pt, dtable, graph_canvas)
Yan's avatar
Yan committed
430

Yan's avatar
Yan committed
431
432
    dial_graph = Figure(figsize=(5, 2), dpi=100, facecolor="None")
    chromplot = dial_graph.add_subplot(111, facecolor=(1, 1, 1, 0.8))
Yan's avatar
Yan committed
433
434
435
    graph_canvas = FigureCanvas(dial_graph)
    graph_canvas.setStyleSheet("background-color:transparent;")
    graph_canvas.setAutoFillBackground(False)
Yan's avatar
Yan committed
436
    graphlabels = dict(x=[0], y=[0], line=None, name="",
Yan's avatar
Yan committed
437
438
                       xlabel="time(min)",
                       ylabel="relative intensity")
Yan's avatar
Yan committed
439
440
441
442
    gt.pan_factory(chromplot)
    gt.zoom_factory(chromplot, 1.15)
    gt.pop_plot(chromplot, graphlabels)

443
444
445
    drl_load = QtWidgets.QPushButton("&Load")
    drl_save = QtWidgets.QPushButton("&Save")
    drl_export = QtWidgets.QPushButton("&Export")
Yan's avatar
Yan committed
446
    drl_print = QtWidgets.QPushButton("&Print")
447
    close = QtWidgets.QPushButton("&Close")
Yan's avatar
Yan committed
448
    close.clicked.connect(window.close)
449

Yan's avatar
Yan committed
450
451
452
    btn_add = QtWidgets.QPushButton("&Add")
    btn_rem = QtWidgets.QPushButton("Remove")

453
454
    # pt = parenttable
    # dt = daughtertable
Yan's avatar
Yan committed
455
    if cache == [None, None, None]:
Yan's avatar
Yan committed
456
        dtable = iontable(["Name", "corrected for", "factor"])
457

Yan's avatar
Yan committed
458
        pt = iontable(["Name", "start (m/z)", "end (m/z)", "profile"])
Yan's avatar
Yan committed
459
        add_line(ds, pt, dtable, chromplot)
Yan's avatar
Yan committed
460
461
    else:
        pt = cache[0]
Yan's avatar
Yan committed
462
        dtable = cache[1]
Yan's avatar
Yan committed
463
        graph_canvas = cache[2]
464

465
466
467
    window.keyPressEvent = lambda event: key_pressed(
        event, pt, dtable, ds, chromplot)

468
    btn_add.clicked.connect(lambda: add_line(
Yan's avatar
Yan committed
469
        ds, pt, dtable, chromplot))
470
471
    btn_rem.clicked.connect(lambda: remove_rows(
        pt, dtable, ds, chromplot))
Yan's avatar
Yan committed
472
    drl_load.clicked.connect(lambda: load_drltables(
Yan's avatar
Yan committed
473
        main_widget, pt, dtable, ds, chromplot))
Yan's avatar
Yan committed
474
    drl_save.clicked.connect(lambda: save_drlconfig(
Yan's avatar
Yan committed
475
        pt, dtable, main_widget))
Yan's avatar
Yan committed
476
    drl_print.clicked.connect(lambda: print_graph(
Yan's avatar
Yan committed
477
        graphlabels, pt, dtable, ds))
Yan's avatar
Yan committed
478
    drl_export.clicked.connect(lambda: export_drlspectrum(
Yan's avatar
Yan committed
479
        main_widget, filename, pt, dtable, ds))
480

481
    pt.itemChanged.connect(lambda item: ptable_changed(
Yan's avatar
Yan committed
482
        item.row(), item.column(), pt, dtable, ds, chromplot))
483
484
485
486

    dtable.itemChanged.connect(lambda item: dtable_changed(
        item.row(), item.column(), pt, dtable, ds, chromplot))

Yan's avatar
Yan committed
487
    main_layout = QtWidgets.QVBoxLayout(main_widget)
Yan's avatar
Yan committed
488
489
    sub_layout = QtWidgets.QHBoxLayout()
    tablelayout = QtWidgets.QVBoxLayout()
Yan's avatar
Yan committed
490
    pt_butlayout = QtWidgets.QHBoxLayout()
Yan's avatar
Yan committed
491
    main_butlayout = QtWidgets.QHBoxLayout()
Yan's avatar
Yan committed
492

Yan's avatar
Yan committed
493
494
495
496
    pt_butlayout.addWidget(btn_add)
    pt_butlayout.addWidget(btn_rem)
    pt_butlayout.addStretch(0)

497
498
    main_layout.addLayout(sub_layout)
    main_layout.addWidget(HBar())
Yan's avatar
Yan committed
499
    main_layout.addLayout(main_butlayout)
500

Yan's avatar
Yan committed
501
502
    main_butlayout.addWidget(drl_load)
    main_butlayout.addWidget(drl_save)
Yan's avatar
Yan committed
503
    main_butlayout.addWidget(drl_print)
Yan's avatar
Yan committed
504
505
    main_butlayout.addStretch(1)
    main_butlayout.addWidget(drl_export)
506
    main_butlayout.addWidget(close)
Yan's avatar
Yan committed
507

508
    sub_layout.addWidget(graph_canvas, stretch=1)
Yan's avatar
Yan committed
509
    sub_layout.addLayout(tablelayout)
510

Yan's avatar
Yan committed
511
512
513
514
    tablelayout.addWidget(QtWidgets.QLabel("Raw ions table:"))
    tablelayout.addWidget(pt)
    tablelayout.addLayout(pt_butlayout)
    tablelayout.addWidget(QtWidgets.QLabel("Corrected ions table:"))
Yan's avatar
Yan committed
515
    tablelayout.addWidget(dtable)
516

Yan's avatar
Yan committed
517
    window.show()