drltools.py 17.6 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
45
46
    start = floatize(pt, row, 1)
    end = floatize(pt, row, 2)
    spectrum = pt.cellWidget(row, 3).figure.get_axes()[0]
Yan's avatar
Yan committed
47
48
    masses = dataset['masses']
    massargs = dt.argsubselect(masses, start, end)
49
    yshape = np.mean(dataset['matrix'], axis=0)
Yan's avatar
Yan committed
50
51
    spectrum.clear()
    dots_x = masses
52
    dots_y = yshape
Yan's avatar
Yan committed
53
54
    full_x = masses[massargs]
    full_y = yshape[massargs]
55
56
    spectrum.plot(dots_x, dots_y, ':', color='gray')
    spectrum.plot(full_x, full_y, 'r')
Yan's avatar
Yan committed
57
58
59
60
    xex = (masses[massargs[-1]]-masses[massargs[0]])*0.25
    spectrum.set_xlim(masses[massargs[0]]-xex,
                      masses[massargs[-1]]+xex)
    ymax = max(yshape[massargs])
61
62
63
    spectrum.set_ylim(ymax*-0.1, ymax*1.2)
    spectrum.figure.canvas.draw()

Yan's avatar
Yan committed
64

Yan's avatar
Yan committed
65
def get_daughterset(ptable, dtable, ds):
66
    # TODO: write a less resources demanding function
Yan's avatar
Yan committed
67
    names = []
Yan's avatar
Yan committed
68
    times = ds['chrom_dat'][0, :]
Yan's avatar
Yan committed
69
    intensities = []
Yan's avatar
Yan committed
70
    # TODO: resolve intensities trouble
Yan's avatar
Yan committed
71
    for row in range(dtable.rowCount()):
Yan's avatar
Yan committed
72
        if dtable.cellWidget(row, 0).checkState() == 2:
73
74
            startm = floatize(ptable, row, 1)
            endm = floatize(ptable, row, 2)
Yan's avatar
Yan committed
75
76
77
            massargs = dt.argsubselect(ds['masses'], startm, endm)
            intensity = (np.sum(
                ds['matrix'].T[massargs].T, axis=1)) / ds['chrom_dat'][1]
78
79
            cor = dtable.cellWidget(row, 1).currentIndex() - 1
            # TODO: check if cor still produce the mess or it started to behave
80
            if cor not in (-2, -1):
81
82
83
                factor = floatize(dtable, row, 2)
                startm = floatize(ptable, cor, 1)
                endm = floatize(ptable, cor, 2)
Yan's avatar
Yan committed
84
                massargs = dt.argsubselect(ds['masses'], startm, endm)
Yan's avatar
Yan committed
85
                correction = ((np.sum(
Yan's avatar
Yan committed
86
                    ds['matrix'].T[massargs].T, axis=1))
Yan's avatar
Yan committed
87
88
                              / ds['chrom_dat'][1]) * factor
                intensity = intensity - correction
Yan's avatar
Yan committed
89
            intensities.append(intensity)
Yan's avatar
Yan committed
90
91
92
93
            names.append("{} - {} * {}".format(
                dtable.item(row, 0).text(),
                dtable.item(row,2).text(),
                dtable.cellWidget(row,1).currentText()))
Yan's avatar
Yan committed
94
95
96
97
    return names, times, intensities


def update_drlspectrum(ptable, dtable, ds, drlspectrum):
98
    # Dont do anything when the dataset is not populated
Yan's avatar
Yan committed
99
    if isinstance(ds['masses'], type(None)):
Yan's avatar
Yan committed
100
        return
101
    colors = np.array([[0, 0, 0], [255, 0, 0], [0, 255, 0], [0, 0, 255],
102
103
104
                       [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
105

106
    # TODO: write a less resources demanding function
Yan's avatar
Yan committed
107
108
109
    names, times, intensities = get_daughterset(ptable, dtable, ds)
    for i in range(len(drlspectrum.lines)):
        drlspectrum.lines[0].remove()
110

111
    i = 0
112
    for row in range(dtable.rowCount()):
Yan's avatar
Yan committed
113
        if dtable.cellWidget(row, 0).checkState() == 2:
114
            dtable.blockSignals(True)
Yan's avatar
Yan committed
115
            dtable.item(row, 0).setBackground(QtGui.QBrush(
116
                QtGui.QColor(*colors[row % len(colors)], alpha=50)))
117
118
            dtable.blockSignals(False)
            label = " {}".format(ptable.item(row, 0).text())
119
120
121
            drlspectrum.plot(times, intensities[i], label=label,
                             color=(colors[row % len(colors)] / 255))
            i += 1
122
        else:
Yan's avatar
Yan committed
123
            dtable.item(row, 0).setBackground(QtGui.QBrush())
124

125
126
127
128
    if len(names) != 0:
        drlspectrum.set_ylim(top=np.amax(intensities)*1.1,
                             bottom=np.amax(intensities)*-0.01)
        drlspectrum.legend(loc=2)
129
130
    drlspectrum.figure.canvas.draw()

Yan's avatar
Yan committed
131

Yan's avatar
Yan committed
132
def gettableitemlist(ptable):
133
    ion_list = []
Yan's avatar
Yan committed
134
135
136
    for row in range(ptable.rowCount()):
        text = []
        for i in range(3):
137
138
            if not isinstance(ptable.item(row, i), type(None)):
                frg = ptable.item(row, i).text()
Yan's avatar
Yan committed
139
140
141
142
143
            else:
                frg = ""
            text.append(frg)
        line = "{} ({}-{})".format(*text)
        ion_list.append(line)
144
145
146
    return ion_list


147
148
149
150
151
152
153
154
155
156
157
158
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
159

160

Yan's avatar
Yan committed
161
162
def ptable_changed(row, column, ptable, dtable, ds, drlspectrum,
                   addline=True):
163
164
165
166
167
    """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
168
169
    if row == ptable.rowCount() - 1 and addline == True:
        add_line(ds, ptable, dtable, drlspectrum)
170

171

172
173
174
175
176
177
178
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)
179

Yan's avatar
Yan committed
180

181
182
183
184
185
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)
186
187


188
def remove_rows(ptable, dtable, ds, drlspectrum):
Yan's avatar
Yan committed
189
    # TODO: maybe nicer selection in future, but this works for now
190
    rows = reversed(list(set(
Yan's avatar
Yan committed
191
        map(lambda x: x.row(), ptable.selectedIndexes()))))
192
    for row in rows:
193
        dtable.cellWidget(row,0).setCheckState(0)
194
195
196
        dtable.removeRow(row)
        ptable.removeRow(row)
        for i in range(dtable.rowCount()):
197
198
199
200
201
202
            corfor = dtable.cellWidget(i, 1)
            corfor.disconnect()
            index = corfor.currentIndex()
            corfor.clear()
            corfor.addItem("")
            corfor.addItems(gettableitemlist(ptable))
203
            if index == row+1:
204
205
                corfor.setCurrentIndex(0)
                corr_changed(i, ptable, dtable, ds, drlspectrum)
206
            elif index > row+1:
207
208
209
210
211
                corfor.setCurrentIndex(index-1)
            else:
                corfor.setCurrentIndex(index)
            corfor.currentIndexChanged.connect(lambda: corr_changed(
                i, ptable, dtable, ds, drlspectrum))
212
213


Yan's avatar
Yan committed
214
def add_line(ds, parenttable, daughtertable, drlspectrum):
215
    """add parent ion to the table"""
216
217
218
219
220
221
222
223
224
225
226
227
    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))

228
    ion_graph = Figure(figsize=(3, 1.5), dpi=100, facecolor="None")
229
230
    ion_graph.add_subplot(111, facecolor=(1, 1, 1, 0.8),
                          position=(-0.01, -0.01, 1.02, 1.02))
231
232
233
234
    graph_canvas = FigureCanvas(ion_graph)
    graph_canvas.setStyleSheet("background-color:transparent;")
    graph_canvas.setAutoFillBackground(False)
    parenttable.setCellWidget(newrow, 3, graph_canvas)
235

236
    daughtertable.setRowCount(newrow + 1)
Yan's avatar
Yan committed
237
    checkbox = QtWidgets.QCheckBox()
238
239
    dname = QtWidgets.QTableWidgetItem()
    dname.setFlags(dname.flags() & ~QtCore.Qt.ItemIsEditable)
Yan's avatar
Yan committed
240
    dname.setTextAlignment(QtCore.Qt.AlignRight)
Yan's avatar
Yan committed
241
242
    daughtertable.setItem(newrow, 0, dname)
    daughtertable.setCellWidget(newrow, 0, checkbox)
243
244
245
246
247
248
249
250
    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
251
252
    ptable_changed(newrow, 1, parenttable, daughtertable, ds,
                   drlspectrum, False)
253

Yan's avatar
Yan committed
254
255
    checkbox.stateChanged.connect(lambda: update_drlspectrum(
        parenttable, daughtertable, ds, drlspectrum))
256
257
    corfor.currentIndexChanged.connect(lambda: corr_changed(
        newrow, parenttable, daughtertable, ds, drlspectrum))
258
259


Yan's avatar
Yan committed
260
def iontable(labels):
261
262
    """creates a table for ions"""
    table = QtWidgets.QTableWidget(columnCount=len(labels))
263
    table.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
264
265
                        QtWidgets.QSizePolicy.Expanding)
    table.setHorizontalHeaderLabels(labels)
266
267
268
269
270
    table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

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

273
    return table
274
275


Yan's avatar
Yan committed
276
277
278
279
280
281
282
283
284
285
286
287
288
289
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
290
291
        for i in range(1, len(rawdata)):
            rawline = rawdata[i].split(",")
Yan's avatar
Yan committed
292
293
294
295
296
297
298
299
            if len(rawline) != 6 or int(rawline[3]) not in range(3) \
                    or int(rawline[4]) not in range(len(rawdata)):
                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
300
                                   states, corrected_to, corr_factors)):
Yan's avatar
Yan committed
301
                k.append(rawline[j])
Yan's avatar
Yan committed
302
303
304
        for row in reversed(range(ptable.rowCount())):
            dtable.removeRow(row)
            ptable.removeRow(row)
Yan's avatar
Yan committed
305
        # first populate only parent table
Yan's avatar
Yan committed
306
        for i in range(len(names)):
Yan's avatar
Yan committed
307
            add_line(dataset, ptable, dtable, drlspectrum)
308
309
310
            ptable.item(i, 0).setText(names[i])
            ptable.item(i, 1).setText(start_masses[i])
            ptable.item(i, 2).setText(end_masses[i])
Yan's avatar
Yan committed
311
        # and after that daughter table
Yan's avatar
Yan committed
312
        for i in range(len(names)):
Yan's avatar
Yan committed
313
            dtable.cellWidget(i, 1).setCurrentIndex(
Yan's avatar
Yan committed
314
                int(corrected_to[i]))
315
            dtable.item(i, 2).setText(corr_factors[i])
Yan's avatar
Yan committed
316
            dtable.cellWidget(i, 0).setCheckState(int(states[i]))
Yan's avatar
Yan committed
317
318


Yan's avatar
Yan committed
319
320
321
322
323
324
325
326
327
328
329
330
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):
331
                vals.append(ptable.item(row, i).text())
Yan's avatar
Yan committed
332
333
            vals.append(dtable.cellWidget(row, 0).checkState())
            vals.append(dtable.cellWidget(row, 1).currentIndex())
334
            vals.append(dtable.item(row, 2).text())
Yan's avatar
Yan committed
335
336
337
            expf.write("{}\n".format((",".join(map(str, vals)))))
        expf.close()

Yan's avatar
Yan committed
338

Yan's avatar
Yan committed
339
340
341
342
343
344
345
346
347
348
349
350
351
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)
    exp_f_name = ft.get_save_filename(
        "Export DRL data", "comma-separated values (*.csv)", "csv", parent)
    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
352
            dataset = list()
Yan's avatar
Yan committed
353
354
355
356
357
358
            dataset.append(times[i])
            for intensity in intensities:
                dataset.append(intensity[i])
            expf.write("{}\n".format((",".join(map(str, dataset)))))
        expf.close()

Yan's avatar
Yan committed
359

Yan's avatar
Yan committed
360
def print_graph(labels, ptable, dtable, ds):
Yan's avatar
Yan committed
361
    printfig = Figure(figsize=(5, 2), dpi=100)
Yan's avatar
Yan committed
362
363
364
365
    printplot = printfig.add_subplot(111)
    printcanvas = FigureCanvas(printfig)
    gt.pop_plot(printplot, labels)
    update_drlspectrum(ptable, dtable, ds, printplot)
Yan's avatar
Yan committed
366
    widget = QtWidgets.QDialog(None, windowTitle='Print preview')
Yan's avatar
Yan committed
367
368
    layout = QtWidgets.QVBoxLayout(widget)
    layout.addWidget(printcanvas)
Yan's avatar
Yan committed
369
    widget.resize(600, 400)
Yan's avatar
Yan committed
370
371
372
373
374
375
376
    widget.show()
    dialog = QtPrintSupport.QPrintDialog()
    if dialog.exec_() == QtWidgets.QDialog.Accepted:
        printcanvas.render(dialog.printer())
    widget.close()


Yan's avatar
Yan committed
377
def main_window(parent, ds, filename, cache):
378
    """constructs a dialog window"""
Yan's avatar
Yan committed
379
380
    def saveonclose(widget, event, buffer, ptable, dautable, canvas):
        buffer[0], buffer[1], buffer[2] = ptable, dautable, canvas
Yan's avatar
Yan committed
381
        QtWidgets.QMainWindow.closeEvent(widget, event)
Yan's avatar
Yan committed
382

Yan's avatar
Yan committed
383
    window = QtWidgets.QMainWindow(
Yan's avatar
Yan committed
384
        parent, windowTitle='Delayed reactant labelling')
Yan's avatar
Yan committed
385
386
    main_widget = QtWidgets.QWidget(window)
    window.setCentralWidget(main_widget)
Yan's avatar
Yan committed
387

Yan's avatar
Yan committed
388
    window.closeEvent = lambda event: saveonclose(
Yan's avatar
Yan committed
389
        window, event, cache, pt, dtable, graph_canvas)
Yan's avatar
Yan committed
390

Yan's avatar
Yan committed
391
392
    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
393
394
395
    graph_canvas = FigureCanvas(dial_graph)
    graph_canvas.setStyleSheet("background-color:transparent;")
    graph_canvas.setAutoFillBackground(False)
Yan's avatar
Yan committed
396
    graphlabels = dict(x=[0], y=[0], line=None, name="",
Yan's avatar
Yan committed
397
398
                       xlabel="time(min)",
                       ylabel="relative intensity")
Yan's avatar
Yan committed
399
400
401
402
    gt.pan_factory(chromplot)
    gt.zoom_factory(chromplot, 1.15)
    gt.pop_plot(chromplot, graphlabels)

403
404
405
    drl_load = QtWidgets.QPushButton("&Load")
    drl_save = QtWidgets.QPushButton("&Save")
    drl_export = QtWidgets.QPushButton("&Export")
Yan's avatar
Yan committed
406
    drl_print = QtWidgets.QPushButton("&Print")
407
    close = QtWidgets.QPushButton("&Close")
Yan's avatar
Yan committed
408
    close.clicked.connect(window.close)
409

Yan's avatar
Yan committed
410
411
412
    btn_add = QtWidgets.QPushButton("&Add")
    btn_rem = QtWidgets.QPushButton("Remove")

413
414
    # pt = parenttable
    # dt = daughtertable
Yan's avatar
Yan committed
415
    if cache == [None, None, None]:
Yan's avatar
Yan committed
416
        dtable = iontable(["Name", "corrected for", "factor"])
417

Yan's avatar
Yan committed
418
        pt = iontable(["Name", "start (m/z)", "end (m/z)", "profile"])
Yan's avatar
Yan committed
419
        add_line(ds, pt, dtable, chromplot)
Yan's avatar
Yan committed
420
421
    else:
        pt = cache[0]
Yan's avatar
Yan committed
422
        dtable = cache[1]
Yan's avatar
Yan committed
423
        graph_canvas = cache[2]
424
425

    btn_add.clicked.connect(lambda: add_line(
Yan's avatar
Yan committed
426
        ds, pt, dtable, chromplot))
427
428
    btn_rem.clicked.connect(lambda: remove_rows(
        pt, dtable, ds, chromplot))
Yan's avatar
Yan committed
429
    drl_load.clicked.connect(lambda: load_drltables(
Yan's avatar
Yan committed
430
        main_widget, pt, dtable, ds, chromplot))
Yan's avatar
Yan committed
431
    drl_save.clicked.connect(lambda: save_drlconfig(
Yan's avatar
Yan committed
432
        pt, dtable, main_widget))
Yan's avatar
Yan committed
433
    drl_print.clicked.connect(lambda: print_graph(
Yan's avatar
Yan committed
434
        graphlabels, pt, dtable, ds))
Yan's avatar
Yan committed
435
    drl_export.clicked.connect(lambda: export_drlspectrum(
Yan's avatar
Yan committed
436
        main_widget, filename, pt, dtable, ds))
437

438
    pt.itemChanged.connect(lambda item: ptable_changed(
Yan's avatar
Yan committed
439
        item.row(), item.column(), pt, dtable, ds, chromplot))
440
441
442
443

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

Yan's avatar
Yan committed
444
    main_layout = QtWidgets.QVBoxLayout(main_widget)
Yan's avatar
Yan committed
445
446
    sub_layout = QtWidgets.QHBoxLayout()
    tablelayout = QtWidgets.QVBoxLayout()
Yan's avatar
Yan committed
447
    pt_butlayout = QtWidgets.QHBoxLayout()
Yan's avatar
Yan committed
448
    main_butlayout = QtWidgets.QHBoxLayout()
Yan's avatar
Yan committed
449

Yan's avatar
Yan committed
450
451
452
453
    pt_butlayout.addWidget(btn_add)
    pt_butlayout.addWidget(btn_rem)
    pt_butlayout.addStretch(0)

454
455
    main_layout.addLayout(sub_layout)
    main_layout.addWidget(HBar())
Yan's avatar
Yan committed
456
    main_layout.addLayout(main_butlayout)
457

Yan's avatar
Yan committed
458
459
    main_butlayout.addWidget(drl_load)
    main_butlayout.addWidget(drl_save)
Yan's avatar
Yan committed
460
    main_butlayout.addWidget(drl_print)
Yan's avatar
Yan committed
461
462
    main_butlayout.addStretch(1)
    main_butlayout.addWidget(drl_export)
463
    main_butlayout.addWidget(close)
Yan's avatar
Yan committed
464

465
    sub_layout.addWidget(graph_canvas, stretch=1)
Yan's avatar
Yan committed
466
    sub_layout.addLayout(tablelayout)
467

Yan's avatar
Yan committed
468
469
470
471
    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
472
    tablelayout.addWidget(dtable)
473

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