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
109
110
111
112
113
114
115
116
117
118
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:
                    annotation.set_bbox(ann_bbox)
                    if annotation in plot_data['annotation']:
                        plot_data['annotation'].remove(annotation)
                        plot_data['texts'].append(annotation)
                if len(textdial[0]) == 0 and annotation in plot_data['texts']:
                    plot_data['texts'].remove(annotation)
            axis.figure.canvas.draw()

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


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

Yan's avatar
Yan committed
125

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

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

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


def pick_times(x_min, x_max, mpl_spectrum, data_set, mpl_chromatogram,
Yan's avatar
Yan committed
184
               mass_spect, chrom_spect, table):
185
186
187
    """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
188
189
190
191
192
193
194
    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
195
    update_paramstable(table, mass_spect, chrom_spect)
196
197
198
199
    plot_subtime(mpl_spectrum, mpl_chromatogram, data_set, mass_spect,
                 chrom_spect)


Yan's avatar
Yan committed
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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
217

218
def autozoomy(ms_spec):
3Yan's avatar
3Yan committed
219
220
221
    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
222
        ms_spec.autoscale(True, 'y')
3Yan's avatar
3Yan committed
223
224
225
226
227
228
        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
229

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

    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"""
238

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

Yan's avatar
Yan committed
256
    peaks = []
3Yan's avatar
3Yan committed
257
258
259
260
261
262
263
264
265
266
    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]))
267
268
    s_peaks = sub_peaks(peaks, msdata['texts'],
            np.diff(ms_spec.get_xlim()), np.diff(ms_spec.get_ylim()))
Yan's avatar
Yan committed
269

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

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

Yan's avatar
Yan committed
285

Yan's avatar
Yan committed
286
def pop_plot(xdata, ydata, plot, plot_data, colornum=0, legend=None):
Yan's avatar
Yan committed
287
    """Define and populate plot"""
3Yan's avatar
3Yan committed
288
    plot.plot(xdata, ydata, linewidth=1, color=
Yan's avatar
Yan committed
289
                  (colors[colornum % len(colors)]/255), label=legend)
Yan's avatar
Yan committed
290
    plot.set_title(plot_data['name'], loc="right")
Yan's avatar
Yan committed
291
292
    plot.set_xlabel(plot_data['xlabel'])
    plot.set_ylabel(plot_data['ylabel'])
Yan's avatar
Yan committed
293
    plot.set_ylim(plot.get_ylim()[1] * -0.01, 
Yan's avatar
Yan committed
294
                  plot.get_ylim()[1] * 1.1)
Yan's avatar
Yan committed
295
    plot.ticklabel_format(scilimits=(0, 0), axis='y')
296
297
298
299
300
301
    if "texts" in plot_data:
        oldtexts = plot_data['texts']
        plot_data['texts'] = [plot.annotate(
            a.get_text(),a.xy, picker=True, bbox=ann_bbox)
            for a in oldtexts]
        plot_data['texts'] = oldtexts
Yan's avatar
Yan committed
302
303
    if "annotation" in plot_data:
        ann_spec(plot, plot_data)
Yan's avatar
Yan committed
304
305
306
307
308
    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
309

Yan's avatar
Yan committed
310
def legendize(rawlegend, chrom_data):
Yan's avatar
Yan committed
311
312
313
314
315
316
317
318
319
320
321
322
323
324
    #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
325
326
    strtext = " and ".join(strdata) + "; t = {:.2f}-{:.2f} min".format(
                    chrom_data['t_start'], chrom_data['t_end'])
Yan's avatar
Yan committed
327
328
329
    return strtext


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

3Yan's avatar
3Yan committed
339
340
341
342
343
344
345
    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
346
347
348
        pmasses, pints = [], []
        [pmasses.extend([np.nan,i,i]) for i in crudemasses]
        [pints.extend([np.nan,0,i]) for i in crudeints]
349
        mpl_spectrum.plot(pmasses,pints, linewidth=1)
Yan's avatar
Yan committed
350

3Yan's avatar
3Yan committed
351
352
353
    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
354
        if len(ms_data['headers']) == len(data_set):
Yan's avatar
Yan committed
355
            legend = legendize(ms_data['headers'][i], chrom_data)
Yan's avatar
Yan committed
356
357
        else:
            legend = None
358
        if cf.settings().value("view/oddeven", type=bool):
3Yan's avatar
3Yan committed
359
            msx = subset['masses']
360
            for j in range(2):
3Yan's avatar
3Yan committed
361
362
363
                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
364
365
                pop_plot(msx, msy, mpl_spectrum, ms_data, i*2+j, legend)
                pop_plot(chromx, chromy, mpl_chromatogram, chrom_data, i*2+j, legend)
366
        else:
3Yan's avatar
3Yan committed
367
368
369
370
            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
371
372
            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
373
    for ax in (mpl_spectrum, mpl_chromatogram):
Yan's avatar
Yan committed
374
375
        if not ms_data['headers'] == []:
            ax.legend(loc=2)
3Yan's avatar
3Yan committed
376
377
378
379
        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
380
381
382
383
384
385
386
387
388


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
389
390
391
                for col in range(1,3)]
        table.setCellWidget(row,0,QtWidgets.QCheckBox())
        table.item(row,1).setText(paramname)
Yan's avatar
Yan committed
392
393
394
        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
395
            text = ""
Yan's avatar
Yan committed
396
397
398
399
400
401
402
403
        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
404
        table.item(row,2).setText(text)