graphtools.py 16.5 KB
Newer Older
Yan's avatar
Yan committed
1
import numpy as np
Yan's avatar
Yan committed
2
import prasopes.datatools as dt
Yan's avatar
Yan committed
3
import prasopes.config as cf
4
import matplotlib
Yan's avatar
Yan committed
5
6
from PyQt5 import QtWidgets
from PyQt5 import QtCore
Yan's avatar
Yan committed
7

Yan's avatar
Yan committed
8

3Yan's avatar
3Yan committed
9
10
11
12
13
colors = np.array([[0, 0, 0], [255, 0, 0], [0, 255, 0], [0, 0, 255],
                   [0, 200, 255], [255, 200, 0], [255, 100, 0],
                   [200, 50, 0], [255, 0, 200], [0, 100, 0],
                   [0, 100, 255], [100, 100, 100]])

14
ann_bbox = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.5)
3Yan's avatar
3Yan committed
15

Yan's avatar
Yan committed
16
def zoom_factory(axis, base_scale, plot_data=None):
Yan's avatar
Yan committed
17
    """returns zooming functionality to axis"""
Yan's avatar
Yan committed
18
    def zoom_fun(event, pd, ax, scale):
Yan's avatar
Yan committed
19
        """zoom when scrolling"""
Yan's avatar
Yan committed
20
        if event.inaxes == axis:
Yan's avatar
Yan committed
21
            if event.button == 'up':
Yan's avatar
Yan committed
22
                # zoom in
Yan's avatar
Yan committed
23
                scale_factor = 1/scale
Yan's avatar
Yan committed
24
            elif event.button == 'down':
Yan's avatar
Yan committed
25
                # zoom out
Yan's avatar
Yan committed
26
                scale_factor = scale
Yan's avatar
Yan committed
27
            else:
Yan's avatar
Yan committed
28
                #  should not happen
Yan's avatar
Yan committed
29
30
                scale_factor = 1
                print(event.button)
Yan's avatar
Yan committed
31
32
            if QtWidgets.QApplication.keyboardModifiers() ==\
                    QtCore.Qt.ShiftModifier:
33
                data = event.ydata
Yan's avatar
Yan committed
34
35
                new_top = data + (ax.get_ylim()[1] - data) \
                    * scale_factor
Yan's avatar
Yan committed
36
37
38
39
                ymin = -0.01
                if type(pd) is dict and "c_ymin" in pd:
                    ymin = pd['c_ymin']
                axis.set_ylim([new_top * ymin, new_top])
40
41
            else:
                data = event.xdata
Yan's avatar
Yan committed
42
43
                x_left = data - ax.get_xlim()[0]
                x_right = ax.get_xlim()[1] - data
Yan's avatar
Yan committed
44
                ax.set_xlim([data - x_left * scale_factor,
Yan's avatar
Yan committed
45
                            data + x_right * scale_factor])
Yan's avatar
Yan committed
46
            if type(pd) is dict and "annotation" in pd:
Yan's avatar
Yan committed
47
                ann_spec(event.inaxes, pd)
48
            ax.figure.canvas.draw()
Yan's avatar
Yan committed
49

Yan's avatar
Yan committed
50
    fig = axis.get_figure()
51
52
    fig.canvas.mpl_connect('scroll_event', lambda event: zoom_fun(
        event, plot_data, axis, base_scale))
Yan's avatar
Yan committed
53
54


Yan's avatar
Yan committed
55
def pan_factory(axis, plot=None):
Yan's avatar
Yan committed
56
    """pan spectrum when you press a button"""
Yan's avatar
Yan committed
57
    def pan_fun(event, ax, pd):
Yan's avatar
Yan committed
58
        # re-scale to origin if doubleclicked
Yan's avatar
Yan committed
59
60
61
        if event.dblclick and event.inaxes == ax:
            ax.get_figure()
            ax.autoscale(True)
Yan's avatar
Yan committed
62
63
64
65
            ymin = -0.01
            if type(pd) is dict and "c_ymin" in pd:
                ymin = pd['c_ymin']
            ax.set_ylim(ax.get_ylim()[1]*ymin, ax.get_ylim()[1]*1.1)
Yan's avatar
Yan committed
66
67
            if type(pd) is dict and "annotation" in pd:
                ann_spec(ax, pd)
Yan's avatar
Yan committed
68
            ax.figure.canvas.draw()
Yan's avatar
Yan committed
69
        # otherwise pan
Yan's avatar
Yan committed
70
        elif event.button == 1 and event.inaxes == ax:
Yan's avatar
Yan committed
71
            ax.start_pan(event.x, event.y, event.button)
Yan's avatar
Yan committed
72
73
74
            id_drag = fig.canvas.mpl_connect(
                'motion_notify_event',
                lambda action: drag_fun(action, ax))
Yan's avatar
Yan committed
75
            id_release = fig.canvas.mpl_connect(
Yan's avatar
Yan committed
76
77
                'button_release_event',
                lambda action: drag_end(
Yan's avatar
Yan committed
78
                    action, id_drag, id_release, pd, ax))
Yan's avatar
Yan committed
79

80
    def drag_fun(event, ax):
Yan's avatar
Yan committed
81
82
83
        ax.drag_pan(1, 'x', event.x, event.y)
        ax.figure.canvas.draw()

Yan's avatar
Yan committed
84
    def drag_end(event, id_drag, id_release, pd, ax):
Yan's avatar
Yan committed
85
86
87
        if event.button == 1:
            fig.canvas.mpl_disconnect(id_drag)
            fig.canvas.mpl_disconnect(id_release)
Yan's avatar
Yan committed
88
89
            if type(pd) is dict and "annotation" in pd:
                ann_spec(ax, pd)
90
            ax.figure.canvas.draw()
Yan's avatar
Yan committed
91

Yan's avatar
Yan committed
92
    fig = axis.get_figure()
Yan's avatar
Yan committed
93
    fig.canvas.mpl_connect('button_press_event',
Yan's avatar
Yan committed
94
                           lambda action: pan_fun(action, axis, plot))
Yan's avatar
Yan committed
95

Yan's avatar
Yan committed
96

97
98
99
100
101
102
103
104
105
106
107
108
def textedit_factory(axis, plot_data):
    def annpicked(pickevent):
        if isinstance(pickevent.artist, matplotlib.text.Annotation) and\
                pickevent.mouseevent.button == 2:
            annotation = pickevent.artist
            textdial = QtWidgets.QInputDialog.getText(
                    None,"Enter new annotation","",
                    text=annotation.get_text())
            if textdial[1] == True:
                annotation.set_text(textdial[0])
                if len(textdial[0]) == 0 and annotation in plot_data['texts']:
                    plot_data['texts'].remove(annotation)
3Yan's avatar
3Yan committed
109
110
111
112
113
                elif annotation in plot_data['annotation']:
                        annotation.set_bbox(ann_bbox)
                        plot_data['annotation'].remove(annotation)
                        plot_data['texts'].append(annotation)
                axis.figure.canvas.draw()
114
115
116
117

    axis.figure.canvas.mpl_connect('pick_event', annpicked)


Yan's avatar
Yan committed
118
def pick_masses(x_min, x_max, ms_spec, msdata):
Yan's avatar
Yan committed
119
    """zoom the spectrum in x axis by mass range"""
Yan's avatar
Yan committed
120
    ms_spec.set_xlim(x_min, x_max)
121
    autozoomy(ms_spec)
Yan's avatar
Yan committed
122
    ann_spec(ms_spec, msdata)
Yan's avatar
Yan committed
123

Yan's avatar
Yan committed
124

3Yan's avatar
3Yan committed
125
def plot_subtime(mpl_spectrum, mpl_chromatogram, ds, ms_data, chrom_data):
Yan's avatar
Yan committed
126
    """plot averaged spectrum of subselected part of the chromatogram"""
Yan's avatar
Yan committed
127
    slims = [mpl_spectrum.get_xlim(), mpl_spectrum.get_ylim()]
3Yan's avatar
3Yan committed
128
129
    chlims = [mpl_chromatogram.get_xlim(), mpl_chromatogram.get_ylim()]
    ms_data['annotation'].clear()
130
131
    mpl_spectrum.clear()
    mpl_chromatogram.clear()
3Yan's avatar
3Yan committed
132
133

    for i,subset in enumerate(ds):
3Yan's avatar
3Yan committed
134
        selection = chrom_data['timesarg'][i]
Yan's avatar
Yan committed
135
        if len(ms_data['headers']) == len(ds):
Yan's avatar
Yan committed
136
            legend = legendize(ms_data['headers'][i][selection], chrom_data)
Yan's avatar
Yan committed
137
138
        else:
            legend = None
3Yan's avatar
3Yan committed
139
        if cf.settings().value("view/oddeven", type=bool):
140
            for j in range(2):
Yan's avatar
Yan committed
141
142
                chromx = subset['chrom_dat'][0, :][j::2]
                chromy = subset['chrom_dat'][1, :][j::2]
Yan's avatar
Yan committed
143
144
                pop_plot(chromx, chromy, mpl_chromatogram, chrom_data, i*2+j,
                         legend)
3Yan's avatar
3Yan committed
145
146
147
                if not np.array_equal(selection[j::2], []):
                    clr = i*2+j if selection[0] % 2 == 0\
                            else i*2+(1-j)
Yan's avatar
Yan committed
148
                    ms_x = subset['masses']
3Yan's avatar
3Yan committed
149
                    ms_y = np.mean(subset['matrix'][selection[j::2]], axis=0)
Yan's avatar
Yan committed
150
                    pop_plot(ms_x, ms_y, mpl_spectrum, ms_data, clr, legend)
3Yan's avatar
3Yan committed
151
152
                    dots_x = subset['chrom_dat'][0, selection[j::2]]
                    dots_y = subset['chrom_dat'][1, selection[j::2]]
Yan's avatar
Yan committed
153
                    mpl_chromatogram.plot(dots_x, dots_y, '.', color=(
3Yan's avatar
3Yan committed
154
                        colors[(clr) % len(colors)]/255))
3Yan's avatar
3Yan committed
155
156
157
        else:
            chromx = subset['chrom_dat'][0, :]
            chromy = subset['chrom_dat'][1, :]
Yan's avatar
Yan committed
158
            pop_plot(chromx, chromy, mpl_chromatogram, chrom_data, i, legend)
3Yan's avatar
3Yan committed
159
            if not np.array_equal(selection, []):
3Yan's avatar
3Yan committed
160
                ms_x = subset['masses']
3Yan's avatar
3Yan committed
161
                ms_y = np.mean(subset['matrix'][selection], axis=0)
Yan's avatar
Yan committed
162
                pop_plot(ms_x, ms_y, mpl_spectrum, ms_data, i, legend)
3Yan's avatar
3Yan committed
163
164
                dots_x = subset['chrom_dat'][0, selection]
                dots_y = subset['chrom_dat'][1, selection]
3Yan's avatar
3Yan committed
165
166
                mpl_chromatogram.plot(dots_x, dots_y, '.', color=(
                    colors[i % len(colors)]/255))
167

Yan's avatar
Yan committed
168
    mpl_spectrum.set_xlim(slims[0])
Yan's avatar
Yan committed
169
    if not cf.settings().value("view/autozoomy", type=bool):
Yan's avatar
Yan committed
170
        mpl_spectrum.set_ylim(slims[1])
Yan's avatar
Yan committed
171
172
173
    if not ms_data['headers'] == []:
        mpl_spectrum.legend(loc=2)
        mpl_chromatogram.legend(loc=2)
Yan's avatar
Yan committed
174
    else:
175
        autozoomy(mpl_spectrum)
3Yan's avatar
3Yan committed
176
177
    ann_spec(mpl_spectrum, ms_data)
    mpl_chromatogram.set_xlim(chlims[0])
Yan's avatar
Yan committed
178
    mpl_chromatogram.set_ylim(chlims[1])
179
180
181
182
    mpl_chromatogram.get_figure().canvas.draw()


def pick_times(x_min, x_max, mpl_spectrum, data_set, mpl_chromatogram,
Yan's avatar
Yan committed
183
               mass_spect, chrom_spect, table):
184
185
186
    """subselect part of the chromatogram and plot it"""
    chrom_spect['t_start'] = x_min
    chrom_spect['t_end'] = x_max
3Yan's avatar
3Yan committed
187
188
189
190
191
192
193
    times = dt.argsubselect(np.concatenate(
        [subset['chrom_dat'][0] for subset in data_set]), x_min, x_max)
    chrom_spect['timesarg'].clear()
    for subset in data_set:
        goodtimes = np.where((times < len(subset['chrom_dat'][0])) & ~(times < 0))[0]
        chrom_spect['timesarg'].append(times[goodtimes])
        times = times - len(subset['chrom_dat'][0])
Yan's avatar
Yan committed
194
    update_paramstable(table, mass_spect, chrom_spect)
195
196
197
198
    plot_subtime(mpl_spectrum, mpl_chromatogram, data_set, mass_spect,
                 chrom_spect)


Yan's avatar
Yan committed
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
def shift_times(event, spect, chrom, ds, ms_ds, chrom_ds):
    """shifts times when arrow is pressed"""
    if event.key() == QtCore.Qt.Key_Left:
        move = -1
    elif event.key() == QtCore.Qt.Key_Right:
        move = +1
    else:
        return
    if not np.array_equal(chrom_ds['timesarg'], []):
        x_min, x_max = chrom_ds['t_start'], chrom_ds['t_end']
        alltimes = np.concatenate([subset['chrom_dat'][0] for subset in ds])
        times = dt.argsubselect(alltimes, x_min, x_max) + move
        goodtimes = np.where((times < len(alltimes)) & ~(times <0))[0]
        if not np.array_equal(goodtimes, []):
            x_min, x_max = alltimes[times[goodtimes[[0,-1]]]]
            pick_times(x_min, x_max, spect, ds, chrom, ms_ds, chrom_ds)

Yan's avatar
Yan committed
216

217
def autozoomy(ms_spec):
3Yan's avatar
3Yan committed
218
219
220
    if cf.settings().value("view/autozoomy", type=bool) and not (
        np.array_equal(ms_spec.lines[0].get_xdata(), [0]) and
        len(ms_spec.lines) == 1):
Yan's avatar
Yan committed
221
        ms_spec.autoscale(True, 'y')
3Yan's avatar
3Yan committed
222
223
224
225
226
227
        gap = 0.01
        ymax = np.max([np.max(line.get_data()[1][dt.argsubselect(
            line.get_data()[0], *ms_spec.get_xlim())])
            for line in ms_spec.lines])
        ms_spec.set_ylim(-ymax*gap, ymax*1.1)
        ms_spec.figure.canvas.draw()
Yan's avatar
Yan committed
228

Yan's avatar
Yan committed
229
def ann_spec(ms_spec, msdata, ann_limit=0.01):
Yan's avatar
Yan committed
230
    """annotate spectrum
231
232
233
234
235
236

    First define the array, in which the annotation should occur.
    Then remove values which are invalid as local maximas. Then select
    local maximas from the array by forcycling. Local maximas are then
    reduced to a representation of the important ones by the sub_peaks
    function"""
237

238
    def sub_peaks(peakz, hardpeaks, xrange, yrange, coef_x=10, coef_y=10):
Yan's avatar
Yan committed
239
        """Returns reasonable subselection of local maximas"""
240
241
        hardxy = np.array(([i.xy for i in hardpeaks]), dtype=[
                ('x', float),('y', float)])
Yan's avatar
Yan committed
242
243
        sort_peaks = np.flipud(np.sort(np.array(peakz, dtype=[
            ('x', float),('y', float)]), order='y')).copy()
Yan's avatar
Yan committed
244
245
        red_x = xrange / coef_x
        red_y = yrange / coef_y
246
        big_peaks = np.array([], dtype=[('x', float),('y', float)])
3Yan's avatar
3Yan committed
247
        for peak in np.nditer(sort_peaks, flags=["zerosize_ok"]):
248
249
250
251
            if not (np.any((abs(peak['y'] - big_peaks['y']) < red_y)\
                   & (abs(peak['x'] - big_peaks['x']) < red_x)) or\
                   np.any((abs(peak['y'] - hardxy['y']) < red_y)\
                   & (abs(peak['x'] - hardxy['x']) < red_x))):
252
253
254
                big_peaks = np.append(big_peaks,peak)
        return big_peaks

Yan's avatar
Yan committed
255
    peaks = []
3Yan's avatar
3Yan committed
256
257
258
259
260
261
262
263
264
265
    for line in ms_spec.lines:
        xdata, ydata = line.get_data()
        argvis = dt.argsubselect(xdata, *ms_spec.get_xlim())
        #remove tails which cannot be evaluated as maximas
        argvis = argvis[np.where((argvis != 0)
                             & (argvis != (len(xdata)-1)))]
        lim = ms_spec.get_ylim()[1] * ann_limit
        for i in argvis:
            if ydata[i] > lim and ydata[i] > max(ydata[i-1], ydata[i+1]):
                    peaks.append((xdata[i],ydata[i]))
266
267
    s_peaks = sub_peaks(peaks, msdata['texts'],
            np.diff(ms_spec.get_xlim()), np.diff(ms_spec.get_ylim()))
Yan's avatar
Yan committed
268

Yan's avatar
Yan committed
269
    # delete objects from the spectra
Yan's avatar
Yan committed
270
    for intensity in msdata['annotation']:
Yan's avatar
Yan committed
271
        intensity.remove()
Yan's avatar
Yan committed
272
    # remove them from tracking
Yan's avatar
Yan committed
273
    msdata['annotation'].clear()
Yan's avatar
Yan committed
274

275
    for peak in s_peaks:
Yan's avatar
Yan committed
276
        if cf.settings().value("view/intensities", type=bool):
277
            annotation = '{0:.2f}\n{1: .2e}'.format(peak['x'], peak['y'])
Yan's avatar
Yan committed
278
        else:
279
            annotation = '{0:.2f}'.format(peak['x'])
280
281
282
        peaktext = ms_spec.annotate(annotation,
            xy=(peak['x'], peak['y']), textcoords='data', picker = True)
        msdata['annotation'].append(peaktext)
283

Yan's avatar
Yan committed
284

Yan's avatar
Yan committed
285
def pop_plot(xdata, ydata, plot, plot_data, colornum=0, legend=None):
Yan's avatar
Yan committed
286
    """Define and populate plot"""
3Yan's avatar
3Yan committed
287
    plot.plot(xdata, ydata, linewidth=1, color=
Yan's avatar
Yan committed
288
                  (colors[colornum % len(colors)]/255), label=legend)
Yan's avatar
Yan committed
289
    plot.set_title(plot_data['name'], loc="right")
Yan's avatar
Yan committed
290
291
    plot.set_xlabel(plot_data['xlabel'])
    plot.set_ylabel(plot_data['ylabel'])
Yan's avatar
Yan committed
292
    plot.set_ylim(plot.get_ylim()[1] * -0.01, 
Yan's avatar
Yan committed
293
                  plot.get_ylim()[1] * 1.1)
Yan's avatar
Yan committed
294
    plot.ticklabel_format(scilimits=(0, 0), axis='y')
3Yan's avatar
3Yan committed
295
296
297
    #put hardcoded annotation if there is none
    if "texts" in plot_data and not any(
            data in plot.get_children() for data in plot_data['texts']):
298
299
        plot_data['texts'] = [plot.annotate(
            a.get_text(),a.xy, picker=True, bbox=ann_bbox)
3Yan's avatar
3Yan committed
300
            for a in plot_data['texts']]
Yan's avatar
Yan committed
301
302
    if "annotation" in plot_data:
        ann_spec(plot, plot_data)
Yan's avatar
Yan committed
303
304
305
306
307
    if "xtics" in plot_data:
        plot.locator_params(nbins=plot_data["xtics"], axis='x')
        plot.minorticks_on()
        plot.tick_params(axis='y', which='minor', left=False)

Yan's avatar
Yan committed
308

Yan's avatar
Yan committed
309
def legendize(rawlegend, chrom_data):
Yan's avatar
Yan committed
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    #sanity check
    if len(rawlegend) == 0:
        return None
    marks = ["-","+"]
    quads = ["q3","q1"]
    def translate(wut):
        if wut[1] in (0,1):
            text = "{}{}ms; m/z = {:.1f}-{:.1f}".format(
                    marks[int(wut[0])], quads[int(wut[1])], *wut[4:])
        else:
            text = "{}ms^{} {:.2f}@{:.1f}V; m/z = {:.1f}-{:.1f}".format(
                    marks[int(wut[0])], *wut[1:])
        return text
    strdata = [translate(i) for i in np.unique(np.array(rawlegend), axis=0)]
Yan's avatar
Yan committed
324
325
    strtext = " and ".join(strdata) + "; t = {:.2f}-{:.2f} min".format(
                    chrom_data['t_start'], chrom_data['t_end'])
Yan's avatar
Yan committed
326
327
328
    return strtext


Yan's avatar
Yan committed
329
def populate(mpl_chromatogram, mpl_spectrum, data_set,
3Yan's avatar
3Yan committed
330
             ms_data, chrom_data):
Yan's avatar
Yan committed
331
    """populate the GUI plots with desired dataset"""
3Yan's avatar
3Yan committed
332
    if np.array_equal(data_set, []):
Yan's avatar
Yan committed
333
        return
3Yan's avatar
3Yan committed
334
    ms_data['annotation'].clear()
Yan's avatar
Yan committed
335
336
    mpl_spectrum.clear()
    mpl_chromatogram.clear()
Yan's avatar
Yan committed
337

3Yan's avatar
3Yan committed
338
339
340
341
342
343
344
    if ms_data['predict'] != None:
        maxm = np.argmax(ms_data['predict'][1]) + ms_data['predict'][0]
        maxseek = dt.argsubselect(linex, maxm-.5, maxm+.5)
        maxpos = maxseek[np.argmax(liney[maxseek])]
        crudeints = ms_data['predict'][1] * ms_data['y'][maxpos]
        crudemasses = (np.arange(len(ms_data['predict'][1])) +
                       linex[maxpos])
Yan's avatar
Yan committed
345
346
347
        pmasses, pints = [], []
        [pmasses.extend([np.nan,i,i]) for i in crudemasses]
        [pints.extend([np.nan,0,i]) for i in crudeints]
348
        mpl_spectrum.plot(pmasses,pints, linewidth=1)
Yan's avatar
Yan committed
349

3Yan's avatar
3Yan committed
350
351
352
    chrom_data['t_start'] = data_set[0]['chrom_dat'][0, 0]
    chrom_data['t_end'] = data_set[-1]['chrom_dat'][0, -1]
    for i,subset in enumerate(data_set):
Yan's avatar
Yan committed
353
        if len(ms_data['headers']) == len(data_set):
Yan's avatar
Yan committed
354
            legend = legendize(ms_data['headers'][i], chrom_data)
Yan's avatar
Yan committed
355
356
        else:
            legend = None
357
        if cf.settings().value("view/oddeven", type=bool):
3Yan's avatar
3Yan committed
358
            msx = subset['masses']
359
            for j in range(2):
3Yan's avatar
3Yan committed
360
361
362
                msy = np.mean(subset['matrix'][j::2], axis=0)
                chromx = subset['chrom_dat'][0, :][j::2]
                chromy = subset['chrom_dat'][1, :][j::2]
Yan's avatar
Yan committed
363
364
                pop_plot(msx, msy, mpl_spectrum, ms_data, i*2+j, legend)
                pop_plot(chromx, chromy, mpl_chromatogram, chrom_data, i*2+j, legend)
365
        else:
3Yan's avatar
3Yan committed
366
367
368
369
            msx = subset['masses']
            msy = np.mean(subset['matrix'], axis=0)
            chromx = subset['chrom_dat'][0, :]
            chromy = subset['chrom_dat'][1, :]
Yan's avatar
Yan committed
370
371
            pop_plot(msx, msy, mpl_spectrum, ms_data, i, legend)
            pop_plot(chromx, chromy, mpl_chromatogram, chrom_data, i, legend)
3Yan's avatar
3Yan committed
372
    for ax in (mpl_spectrum, mpl_chromatogram):
Yan's avatar
Yan committed
373
374
        if not ms_data['headers'] == []:
            ax.legend(loc=2)
3Yan's avatar
3Yan committed
375
376
377
378
        ax.autoscale(True)
        ax.set_ylim(ax.get_ylim()[1]*-0.01, ax.get_ylim()[1]*1.1)
        ax.figure.canvas.draw()
    return
Yan's avatar
Yan committed
379
380
381
382
383
384
385
386
387


def update_paramstable(table, ms, chrom):
    if len(ms['params']) == 0:
        table.setRowCount(0)
        return
    table.setRowCount(len(ms['params'][0]))
    for row, paramname in enumerate(ms['params'][0]):
        [table.setItem(row,col, QtWidgets.QTableWidgetItem())
Yan's avatar
Yan committed
388
389
390
                for col in range(1,3)]
        table.setCellWidget(row,0,QtWidgets.QCheckBox())
        table.item(row,1).setText(paramname)
Yan's avatar
Yan committed
391
392
393
        vals = [param[row] for param in ms['params'][1]
            if (param[0] >= chrom['t_start'] and param[0] <= chrom['t_end'])]
        if len(vals) == 0:
Yan's avatar
Yan committed
394
            text = ""
Yan's avatar
Yan committed
395
396
397
398
399
400
401
402
        elif all([type(val) in [np.float32, np.float64] for val in vals]):
            aver = np.average(vals)
            minim = min(vals)
            maxim = max(vals)
            text = "{:.2f} (from {:.2f} to {:.2f})".format(aver, minim, maxim)
        else:
            values = [str(i) for i in np.unique(np.array(vals), axis=0)]
            text = " or ".join(values)
Yan's avatar
Yan committed
403
        table.item(row,2).setText(text)