question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Changes to AmplitudeView

See original GitHub issue

I’ve prototyped some changes to the Amplitude view that would add some functionality.

Feature # 1 Allow the user to define the ‘amplitude’ plotted in the AmplitudeView. Options for ‘Amplitude’ could be:

  1. Raw amplitude - max value minus min value of the mean waveform (mV) on CHANNEL.
  2. Projection onto principal component 0 (same as FeatureView) on CHANNEL
  3. Projection onto template of the first selected cluster

CHANNEL would be the primary channel of the first selected cluster (not the primary channel of each cluster) by default and could be modified by a ctrl+left click on the WaveformView (same as for FeatureView).

It would be great to have a hotkey that enabled toggling between these. Perhaps Ctrl+1,2,3…

Feature # 2 Show all ‘background’ events associated with clusters which share a channel with the primary channel of the selected cluster.

For example, suppose I have only 3 clusters.
Cluster 1: primary channel is channel 10 and in the TemplateView, Channels 7-13 are displayed Cluster 2: primary channel is channel 12 and in the TemplateView, Channels 9-15 are displayed Cluster 3: primary channel is channel 14 and in the TemplateView, Channels 11-17 are displayed

If I select Cluster 1, then CHANNEL would be 10 and the events associated with Cluster 1 would be displayed as well as the events from Cluster 2, since channel 10 is displayed in the TemplateView, but Cluster 3 would not be displayed because 10 is not within 11-17.

I used the implementation below to prototype these features and would be happy to re-write following your style, but it may just be easier for you to do it.

apps/template/gui.py

    #MODIFIED
    def get_amplitudes(self, cluster_ids, chan=None, load_all=False):
        n = self.n_spikes_amplitudes if not load_all else None
        m = self.model
        data_bounds = [0., 0., m.duration, None]
        full_l = (self.supervisor.clustering.cluster_ids)
        if chan is None:
            chan=self.get_best_channel(cluster_ids[0])
        bunchs = []
        for cid in full_l:
            if chan in self.get_best_channels(cid):
                spike_ids = self.selector.select_spikes([cid], n)
                
                #raw amplitude (mV) -- very slow because doing max-min every time
                #data = m.get_waveforms(spike_ids,[chan])
                #y = np.subtract(np.amax(data,axis=1),np.amin(data,axis=1))
                #x = m.spike_times[spike_ids]
                
                #PC0
                y = self.get_features(cid,[chan]).data[:,0,0]
                x = self.get_spike_times(cid).data
                
                # Projection onto selected Cluster template -- breaks on new cluster assignment (merge/split)
                #y = m.get_template_features(spike_ids)[:,cluster_ids[0]]
                #x = m.spike_times[spike_ids]
                
                if not (cid in cluster_ids):
                    bunchs.append(Bunch(x=x, y=y, spike_ids=spike_ids,
                        data_bounds=data_bounds, br=True, col=[1,1,1,.15]))
                else:
                    bunchs.append(Bunch(x=x, y=y, spike_ids=spike_ids, 
                        data_bounds=data_bounds, br=False, col=cluster_ids.index(cid)))
    
        ymax = max(b.y.max() for b in bunchs)
        for bunch in bunchs:
            bunch.data_bounds[-1] = ymax
        return bunchs

cluster/views/scatter.py

    # in imports:
    import phy.apps.template.gui as pat
    #to ensure that I only respond to channel click with AmplitudeView in on_channel_click

    #MODIFIED
    def _plot_points(self, bunchs, data_bounds):
        ms = self._default_marker_size
        xmin, ymin, xmax, ymax = data_bounds
        self.visual.reset_batch()
        for i, d in enumerate(bunchs):
            x, y = d.x, d.y
            assert x.ndim == y.ndim == 1
            assert x.shape == y.shape
            if hasattr(d,'br'):
                if d.br:
                    color = d.col
                else:
                    color = selected_cluster_color(d.col,0.75)
            else:
                color = selected_cluster_color(i,0.75)

            # Create one visual per cluster.
            self.visual.add_batch_data(x=x, y=y, color=color, size=ms, data_bounds=data_bounds)
        self.canvas.update_visual(self.visual)

    #ADDED
    def on_channel_click(self, sender=None, channel_id=None, key=None, button=None):
        if channel_id is not None and isinstance(self,pat.AmplitudeView):
            bunchs = self.coords(self.cluster_ids,chan=channel_id)
            if bunchs is None:
                self.visual.hide()
                self.canvas.update()
                return
            self.visual.show()
            self.data_bounds = self._get_data_bounds(bunchs)
    
            self._plot_points(bunchs, self.data_bounds)
            self.canvas.axes.reset_data_bounds(self.data_bounds)
            self.canvas.update()
    
    #MODIFIED
    def attach(self, gui):
        super(ScatterView, self).attach(gui)
        connect(self.on_request_split)
        connect(self.on_channel_click)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
rossantcommented, Jun 20, 2019

Thank you for the details and for the prototype, it was really helpful for implementing these features properly. Your proposal is now part of phy natively and I believe it will be useful to many users!

I ended up implementing just a single amplitude view where you can toggle betweel template, raw, and feature amplitude types by pressing a. You can still split in that view. Histograms are shown as well. And, for the feature type, you can choose the dimension from the feature view with alt+left click for the x axis, and alt+right click for the y axis.

Please try it and let me know if you have any issues or suggestions.

image

1reaction
rossantcommented, Jun 17, 2019

@mswallac Thanks. FYI you can directly edit your comment on this issue instead of creating a new one

Read more comments on GitHub >

github_iconTop Results From Across the Web

Interactive visualization of ephys data - Read the Docs
You can change the current time range with Alt+click in the amplitude view: that will automatically change the time range in the trace...
Read more >
2021 Lecture 2.4 - Curating sorted spikes with Phy - YouTube
Amplitude View. Amplitude View. 6:08 · Amplitude View. 6:08. Firing Rate View. Firing Rate View. 7:12 · Firing Rate View. 7:12 ...
Read more >
2020 Lecture 2.05 - Using Phy to curate spike sorting - YouTube
2020 UCL Neuropixels Coursehttps://www.ucl.ac.uk/neuropixels/training/2020-neuropixels-course.
Read more >
Methods and apparatus for layered waveform amplitude view of ...
Methods and apparatus for layered waveform amplitude view of multiple audio ... it will be understood by those skilled in the art that...
Read more >
Look up event data for individual users
To see a live stream of all events coming into Amplitude, set the Live event updates toggle in the top right corner to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found