oscarbranson / latools_gui

GUI for LAtools
2 stars 1 forks source link

autorange pop-up plot #84

Open oscarbranson opened 6 years ago

oscarbranson commented 6 years ago

Create a pop-up plot for choosing autorange parameters.

The component parts of the 'autorange' algorithm can be accessed using the new 'autorange_components; function in latools.processes.signal_id. This returns all the data that autorange considers when identifying signal and background regions.

This can be used to re-create a plot that highlights the meaning of all the autorange parameters. for example:

d = la.analyse('path/to/test/data/')
d.despike()
# select a single sample
di = d.data['STD-1']

# get time and data to use
t = di.Time
sig = di.data['total_counts']

# get autorange components
t, sig, sigs, tsig, tsigs, kde_x, yd, g, trans, thresh = autorange_components(t, sig, # data to consider
                                                                              transform='log',  # data transformation
                                                                              swin=7,  # signal-smoothing window (n-point running mean)
                                                                              gwin=7,  # gradient calculation window (n-point running gradient)
                                                                              win=20,  # data region to consider in peak fitting (n points either side of rough center)
                                                                              on_mult=(1.5, 1.0), off_mult=(1.0, 1.5))  # FWHM multiples used to exclude transitions

# make a plot
fig, axs = plt.subplots(2, 1, sharex=True, figsize=[12, 7])

sax, gax = axs

# plot raw signal and smoothed signal
sax.plot(t, tsig, c='k', alpha=0.3, label='raw data')  # plot raw data
sax.plot(t, tsigs, c='k', label='smoothed data')  # plot smoothed data

# plot gradient
gax.plot(t, g, c='k', label='absolute gradient')

# y axis labels
sax.set_ylabel('counts')
sax.set_yticklabels([])
gax.set_ylabel('|gradient|')
gax.set_yticklabels([])
gax.set_xlim(0, max(t))

gax.set_xlabel('Time (s)')

# figure layout
fig.tight_layout()

# shrink axes
for ax in axs:
    p = ax.axes.get_position()
    pn = [p.x0, p.y0, p.width * 0.8, p.height]

# create axis for kernel density (kde) estimator plot
p = sax.axes.get_position()
hax = fig.add_axes((p.x0 + p.width + 0.02, p.y0, p.width * 0.18 / 0.8, p.height))
hax.set_yticklabels([])
hax.set_xticklabels([])
hax.set_ylim(sax.get_ylim())

# plot kde
hax.fill_betweenx(kde_x, yd)
hax.set_title('Data Density', loc='left')

# add in threshold calculated from kde
for ax in [sax, hax]:
    ax.axhline(thresh, ls='dashed', c=(0,0,0,0.3))

# plot transitions
i = 1  # index of highlight transition

# draw guide lines on plot
for n in range(len(trans['zeros'])):
    # change colour of highlighted plot
    if n == i:
        c = 'b'
    else:
        c = 'r'

    # Draw 'firt guess' positions
    gax.axvline(t[trans['zeros'][n]], c=c, alpha=0.3, ls='dashed')
    sax.axvline(t[trans['zeros'][n]], c=c, alpha=0.6, ls='dashed')

    # draw regions considered in peak fits
    gax.axvspan(*t[trans['lohi'][n]], ls='dashed', facecolor=(0,0,0,0.05), edgecolor=(0,0,0,0.8))

    # draw transition centres from peak fits
    gax.axvline(trans['pgs'][n][1], c=c, alpha=0.8)

    # shade excluded transition regions
    gax.axvspan(*trans['excl'][n], color=c, alpha=0.1, lw=0)

# draw close-up of highlighted transition in panel
p = gax.axes.get_position()
pax = fig.add_axes((p.x0 + p.width + 0.02, p.y0, p.width * 0.18 / 0.8, p.height))

pax.set_yticklabels([])
pax.set_ylim(gax.get_ylim())
pax.set_xlabel('Time (s)')

# draw data
pax.scatter(trans['xs'][i], trans['ys'][i], c='k', s=10, label='data')
# draw fitted peak
pax.plot(trans['xs'][i], gauss(trans['xs'][i], *trans['pgs'][i]), c='r', label='fit')

# draw transition info
pax.axvline(t[trans['zeros'][i]], c='b', alpha=0.3, ls='dashed', label='centre (rough)')   # rough centre
pax.axvline(trans['pgs'][i][1], c='b', alpha=0.8, label='centre (fitted)')  # fitted centre
pax.axvspan(*trans['excl'][i], color='b', alpha=0.1, lw=0, label='excluded transition')  # shade transition
pax.axvspan(*t[trans['lohi'][i]], ls='dashed', facecolor=(0,0,0,0.05), edgecolor=(0,0,0,0.8))  # shade total considered region

# legends
sax.legend(loc='upper right')
pax.legend(loc='upper right')

image

Each of the autorange parameters should be available alongside a plot like this, and the plot should update when the parameters are changed. Those parameters are:

If the plot were formatted like this, you should be able to switch which transition you were looking at in the bottom right panel by clicking on one of the transition regions, and be able to switch which sample you were looking at.

oscarbranson commented 6 years ago

PS, you'll have to re-pull the gui branch of latools to get the new autorange_components function.