Skills › Scientific Agent Skills › neuropixels-analysis › export_to_phy.py
export_to_phy.py
82 lines · skills/neuropixels-analysis/scripts/export_to_phy.py at 5f2bc03
1#!/usr/bin/env python
2"""
3Export sorting results to Phy for manual curation.
5Usage:
6 python export_to_phy.py metrics/analyzer --output phy_export/
7"""
9import argparse
10from pathlib import Path
12import spikeinterface.full as si
13from spikeinterface.exporters import export_to_phy
16def export_phy(
17 analyzer_path: str,
18 output_dir: str,
19 copy_binary: bool = True,
20 compute_amplitudes: bool = True,
21 compute_pc_features: bool = True,
22 n_jobs: int = -1,
23):
24 """Export to Phy format."""
26 print(f"Loading analyzer from: {analyzer_path}")
27 analyzer = si.load_sorting_analyzer(analyzer_path)
29 print(f"Units: {len(analyzer.sorting.unit_ids)}")
31 output_path = Path(output_dir)
33 # Compute required extensions if missing
34 if compute_amplitudes and analyzer.get_extension('spike_amplitudes') is None:
35 print("Computing spike amplitudes...")
36 analyzer.compute('spike_amplitudes')
37 analyzer.compute('amplitude_scalings')
39 if compute_pc_features and analyzer.get_extension('principal_components') is None:
40 print("Computing principal components...")
41 analyzer.compute('principal_components', n_components=5, mode='by_channel_local')
43 print(f"Exporting to Phy: {output_path}")
44 export_to_phy(
45 analyzer,
46 output_folder=output_path,
47 copy_binary=copy_binary,
48 compute_amplitudes=compute_amplitudes,
49 compute_pc_features=compute_pc_features,
50 n_jobs=n_jobs,
51 )
53 if analyzer.unit_ids.dtype.kind in {"U", "S", "O"}:
54 print("[WARN] SpikeInterface 0.105 read_phy may fail on string IDs; preserve cluster_si_unit_ids.tsv for mapping.")
55 print("\nExport complete!")
56 print(f"To open in Phy, run:")
57 print(f" phy template-gui {output_path / 'params.py'}")
60def main():
61 parser = argparse.ArgumentParser(description='Export to Phy')
62 parser.add_argument('analyzer', help='Path to sorting analyzer')
63 parser.add_argument('--output', '-o', default='phy_export/', help='Output directory')
64 parser.add_argument('--no-binary', action='store_true', help='Skip copying binary file')
65 parser.add_argument('--no-amplitudes', action='store_true', help='Skip amplitude computation')
66 parser.add_argument('--no-pc', action='store_true', help='Skip PC feature computation')
67 parser.add_argument('--n-jobs', type=int, default=-1, help='Number of parallel jobs')
69 args = parser.parse_args()
71 export_phy(
72 args.analyzer,
73 args.output,
74 copy_binary=not args.no_binary,
75 compute_amplitudes=not args.no_amplitudes,
76 compute_pc_features=not args.no_pc,
77 n_jobs=args.n_jobs,
78 )
81if __name__ == '__main__':
82 main()