|
6 | 6 | "source": [ |
7 | 7 | "## Quality Metrics\n", |
8 | 8 | "\n", |
9 | | - "Visualize the spike sorting quality metrics that are generated from Kilosort (`metrics.csv`) and stored in the DataJoint pipeline (`element-array-ephys`).\n", |
| 9 | + "Visualize the spike sorting quality metrics that are generated from the [Kilosort](https://github.com/MouseLand/Kilosort) results with the [ecephys_spike_sorting](https://github.com/datajoint/ecephys_spike_sorting) package (i.e. `metrics.csv`) and stored in the DataJoint pipeline (i.e. `element-array-ephys`).\n", |
10 | 10 | "\n", |
11 | 11 | "If you are new to using this DataJoint pipeline for analyzing electrophysiology recordings from Neuropixels probes, please see the [tutorial](./tutorial.ipynb) notebook for an in-depth explanation to set up and run the workflow.\n", |
12 | 12 | "\n", |
|
59 | 59 | "\n", |
60 | 60 | "| Metric | Description |\n", |
61 | 61 | "| --- | --- |\n", |
62 | | - "| Firing rates (Hz) | Total number of spikes per time in seconds. |\n", |
| 62 | + "| Firing rate (Hz) | Total number of spikes per second. |\n", |
63 | 63 | "| Signal-to-noise ratio | Ratio of the maximum amplitude of the mean spike waveform to the standard deviation of the background noise on a given channel. |\n", |
64 | 64 | "| Presence ratio | Proportion of time during a session that a unit is spiking, ranging from 0 to 0.99. |\n", |
65 | | - "| ISI (Interspike interval) violation | Rate of ISI violation as a fraction of overall rate. |\n", |
| 65 | + "| Interspike interval (ISI) violation | Rate of ISI violation as a fraction of overall rate. |\n", |
66 | 66 | "| Number violation | Total number of ISI violations. |\n", |
67 | 67 | "| Amplitude cut-off | False negative rate of a unit measured by the degree to which its distribution of spike amplitudes is truncated, indicating the fraction of missing spikes. An amplitude cutoff of 0.1 indicates approximately 10% missing spikes. |\n", |
68 | 68 | "| Isolation distance | A metric that uses the principal components (PCs) of a unit's waveforms, which are projected into a lower-dimensional PC space after spike sorting. This quantifies how well-isolated the unit is from other potential clusters. |\n", |
|
488 | 488 | "cell_type": "markdown", |
489 | 489 | "metadata": {}, |
490 | 490 | "source": [ |
491 | | - "#### Plot histograms of cluster metrics. " |
| 491 | + "Plot histograms of the cluster metrics." |
492 | 492 | ] |
493 | 493 | }, |
494 | 494 | { |
|
497 | 497 | "metadata": {}, |
498 | 498 | "outputs": [], |
499 | 499 | "source": [ |
500 | | - "# Plotting function\n", |
501 | | - "def plot_metric(ax, data, bins, x_axis_label=None, title=None, color='k', max_value=-1, smoothing=True, density=False):\n", |
| 500 | + "def plot_metric(ax, data, bins, x_axis_label=None, title=None, color='k', smoothing=True, density=False):\n", |
502 | 501 | " \"\"\"A function modified from https://allensdk.readthedocs.io/en/latest/_static/examples/nb/ecephys_quality_metrics.html\n", |
503 | 502 | " \"\"\"\n", |
504 | 503 | " from scipy.ndimage import gaussian_filter1d\n", |
505 | | - " if any(data) and np.nansum(data) :\n", |
506 | | - " # Plot data\n", |
| 504 | + " if any(data) and np.nansum(data):\n", |
507 | 505 | " h, b = np.histogram(data, bins=bins, density=density)\n", |
508 | 506 | " x = b[:-1]\n", |
509 | 507 | "\n", |
|
532 | 530 | } |
533 | 531 | ], |
534 | 532 | "source": [ |
535 | | - "# Plot the results\n", |
536 | 533 | "fig, axes = plt.subplots(4, 4, figsize=(12, 9))\n", |
537 | 534 | "axes = axes.flatten()\n", |
538 | 535 | "plt.suptitle(f\"Cluster Quality Metrics for {key}\", y=.99, fontsize=12)\n", |
|
561 | 558 | "# Number Violation\n", |
562 | 559 | "data = query.fetch(\"number_violation\")\n", |
563 | 560 | "bins = np.linspace(0, 1000, 100)\n", |
564 | | - "plot_metric(axes[4], data, bins, title=\"Number violation\")\n", |
| 561 | + "plot_metric(axes[4], data, bins, title=\"Number Violation\")\n", |
565 | 562 | "axes[4].set_ylabel(\"Count\")\n", |
566 | 563 | "\n", |
567 | 564 | "# Amplitude Cutoff\n", |
568 | 565 | "data = query.fetch(\"amplitude_cutoff\")\n", |
569 | 566 | "bins = np.linspace(0, 0.5, 100)\n", |
570 | | - "plot_metric(axes[5], data, bins, title=\"Amplitude cutoff\")\n", |
| 567 | + "plot_metric(axes[5], data, bins, title=\"Amplitude Cutoff\")\n", |
571 | 568 | "\n", |
572 | 569 | "# Isolation Distance\n", |
573 | 570 | "data = query.fetch(\"isolation_distance\")\n", |
|
585 | 582 | "plot_metric(axes[8], data, bins, title=\"d-Prime\")\n", |
586 | 583 | "axes[8].set_ylabel(\"Count\")\n", |
587 | 584 | "\n", |
588 | | - "# Nearest-Neighbor Hit Rate\n", |
| 585 | + "# Nearest-Neighbors Hit Rate\n", |
589 | 586 | "data = query.fetch(\"nn_hit_rate\")\n", |
590 | 587 | "bins = np.linspace(0, 1, 100)\n", |
591 | | - "plot_metric(axes[9], data, bins, title=\"Nearest Neighbor Hit Rate\")\n", |
| 588 | + "plot_metric(axes[9], data, bins, title=\"Nearest-Neighbors Hit Rate\")\n", |
592 | 589 | "\n", |
593 | | - "# Nearest-Neighbor Miss Rate\n", |
| 590 | + "# Nearest-Neighbors Miss Rate\n", |
594 | 591 | "data = query.fetch(\"nn_miss_rate\")\n", |
595 | 592 | "bins = np.linspace(0, 1, 100)\n", |
596 | | - "plot_metric(axes[10], data, bins, title=\"Nearest Neighbor Miss Rate\")\n", |
| 593 | + "plot_metric(axes[10], data, bins, title=\"Nearest-Neighbors Miss Rate\")\n", |
597 | 594 | "\n", |
598 | 595 | "# Silhouette Score\n", |
599 | 596 | "data = query.fetch(\"silhouette_score\")\n", |
|
624 | 621 | "\n", |
625 | 622 | "| Metric | Description |\n", |
626 | 623 | "| -- | -- |\n", |
627 | | - "| `Amplitude (μV)` | Absolute difference between the waveform peak and trough. |\n", |
628 | | - "| `Duration (ms)` | Time interval between the waveform peak and trough. |\n", |
629 | | - "| `Peak-to-Trough (PT) Ratio` | Absolute amplitude of the peak divided by the absolute amplitude of the trough relative to 0. |\n", |
630 | | - "| `Repolarization Slope` | Slope of the fitted regression line to the first 30μs from trough to peak. |\n", |
631 | | - "| `Recovery Slope` | Slope of the fitted regression line to the first 30μs from peak to tail. |\n", |
632 | | - "| `Spread (μm)` | Spatial extent of channels where the waveform amplitude exceeds 12% of the peak amplitude. |\n", |
633 | | - "| `Velocity Above (s/m)` | Inverse velocity of waveform propagation from the soma toward the top of the probe. |\n", |
634 | | - "| `Velocity Below (s/m)` | Inverse velocity of waveform propagation from the soma toward the bottom of the probe. |" |
| 624 | + "| Amplitude (μV) | Absolute difference between the waveform peak and trough. |\n", |
| 625 | + "| Duration (ms) | Time interval between the waveform peak and trough. |\n", |
| 626 | + "| Peak-to-Trough (PT) Ratio | Absolute amplitude of the peak divided by the absolute amplitude of the trough relative to 0. |\n", |
| 627 | + "| Repolarization Slope | Slope of the fitted regression line to the first 30μs from trough to peak. |\n", |
| 628 | + "| Recovery Slope | Slope of the fitted regression line to the first 30μs from peak to tail. |\n", |
| 629 | + "| Spread (μm) | Spatial extent of channels where the waveform amplitude exceeds 12% of the peak amplitude. |\n", |
| 630 | + "| Velocity Above (s/m) | Inverse velocity of waveform propagation from the soma toward the top of the probe. |\n", |
| 631 | + "| Velocity Below (s/m) | Inverse velocity of waveform propagation from the soma toward the bottom of the probe. |" |
635 | 632 | ] |
636 | 633 | }, |
637 | 634 | { |
|
944 | 941 | "query" |
945 | 942 | ] |
946 | 943 | }, |
| 944 | + { |
| 945 | + "attachments": {}, |
| 946 | + "cell_type": "markdown", |
| 947 | + "metadata": {}, |
| 948 | + "source": [ |
| 949 | + "Plot histograms of the waveform metrics." |
| 950 | + ] |
| 951 | + }, |
947 | 952 | { |
948 | 953 | "cell_type": "code", |
949 | 954 | "execution_count": 8, |
|
976 | 981 | "bins = np.linspace(0, 3, 100)\n", |
977 | 982 | "plot_metric(axes[1], data, bins, title=\"Duration (ms)\")\n", |
978 | 983 | "\n", |
979 | | - "# PT Ratio\n", |
| 984 | + "# Peak-to-Trough Ratio\n", |
980 | 985 | "data = query.fetch(\"pt_ratio\")\n", |
981 | 986 | "bins = np.linspace(0, 1, 100)\n", |
982 | 987 | "plot_metric(axes[2], data, bins, title=\"Peak-to-Trough Ratio\")\n", |
|
0 commit comments