1
- import datajoint as dj
1
+ import gc
2
+ import importlib
3
+ import inspect
2
4
import pathlib
3
5
import re
4
- import numpy as np
5
- import inspect
6
- import importlib
7
- import gc
8
6
from decimal import Decimal
9
- import pandas as pd
10
7
11
- from element_interface .utils import find_root_directory , find_full_path , dict_to_uuid
8
+ import datajoint as dj
9
+ import numpy as np
10
+ import pandas as pd
11
+ from element_interface .utils import dict_to_uuid , find_full_path , find_root_directory
12
12
13
- from .readers import spikeglx , kilosort , openephys
14
- from . import probe , get_logger , ephys_report
13
+ from . import ephys_report , get_logger , probe
14
+ from .readers import kilosort , openephys , spikeglx
15
15
16
16
log = get_logger (__name__ )
17
17
@@ -127,7 +127,7 @@ class AcquisitionSoftware(dj.Lookup):
127
127
"""
128
128
129
129
definition = """ # Software used for recording of neuropixels probes
130
- acq_software: varchar(24)
130
+ acq_software: varchar(24)
131
131
"""
132
132
contents = zip (["SpikeGLX" , "Open Ephys" ])
133
133
@@ -264,7 +264,7 @@ class EphysRecording(dj.Imported):
264
264
265
265
definition = """
266
266
# Ephys recording from a probe insertion for a given session.
267
- -> ProbeInsertion
267
+ -> ProbeInsertion
268
268
---
269
269
-> probe.ElectrodeConfig
270
270
-> AcquisitionSoftware
@@ -465,9 +465,9 @@ class Electrode(dj.Part):
465
465
466
466
definition = """
467
467
-> master
468
- -> probe.ElectrodeConfig.Electrode
468
+ -> probe.ElectrodeConfig.Electrode
469
469
---
470
- lfp: longblob # (uV) recorded lfp at this electrode
470
+ lfp: longblob # (uV) recorded lfp at this electrode
471
471
"""
472
472
473
473
# Only store LFP for every 9th channel, due to high channel density,
@@ -615,7 +615,7 @@ class ClusteringParamSet(dj.Lookup):
615
615
# Parameter set to be used in a clustering procedure
616
616
paramset_idx: smallint
617
617
---
618
- -> ClusteringMethod
618
+ -> ClusteringMethod
619
619
paramset_desc: varchar(128)
620
620
param_set_hash: uuid
621
621
unique index (param_set_hash)
@@ -800,7 +800,7 @@ class Clustering(dj.Imported):
800
800
# Clustering Procedure
801
801
-> ClusteringTask
802
802
---
803
- clustering_time: datetime # time of generation of this set of clustering results
803
+ clustering_time: datetime # time of generation of this set of clustering results
804
804
package_version='': varchar(16)
805
805
"""
806
806
@@ -841,6 +841,10 @@ def make(self, key):
841
841
spikeglx_meta_filepath .parent
842
842
)
843
843
spikeglx_recording .validate_file ("ap" )
844
+ run_CatGT = (
845
+ params .pop ("run_CatGT" , True )
846
+ and "_tcat." not in spikeglx_meta_filepath .stem
847
+ )
844
848
845
849
if clustering_method .startswith ("pykilosort" ):
846
850
kilosort_triggering .run_pykilosort (
@@ -861,7 +865,7 @@ def make(self, key):
861
865
ks_output_dir = kilosort_dir ,
862
866
params = params ,
863
867
KS2ver = f'{ Decimal (clustering_method .replace ("kilosort" , "" )):.1f} ' ,
864
- run_CatGT = True ,
868
+ run_CatGT = run_CatGT ,
865
869
)
866
870
run_kilosort .run_modules ()
867
871
elif acq_software == "Open Ephys" :
@@ -925,11 +929,11 @@ class Curation(dj.Manual):
925
929
-> Clustering
926
930
curation_id: int
927
931
---
928
- curation_time: datetime # time of generation of this set of curated clustering results
932
+ curation_time: datetime # time of generation of this set of curated clustering results
929
933
curation_output_dir: varchar(255) # output directory of the curated results, relative to root data directory
930
934
quality_control: bool # has this clustering result undergone quality control?
931
935
manual_curation: bool # has manual curation been performed on this clustering result?
932
- curation_note='': varchar(2000)
936
+ curation_note='': varchar(2000)
933
937
"""
934
938
935
939
def create1_from_clustering_task (self , key , curation_note = "" ):
@@ -978,7 +982,7 @@ class CuratedClustering(dj.Imported):
978
982
979
983
definition = """
980
984
# Clustering results of a curation.
981
- -> Curation
985
+ -> Curation
982
986
"""
983
987
984
988
class Unit (dj .Part ):
@@ -1005,7 +1009,7 @@ class Unit(dj.Part):
1005
1009
spike_count: int # how many spikes in this recording for this unit
1006
1010
spike_times: longblob # (s) spike times of this unit, relative to the start of the EphysRecording
1007
1011
spike_sites : longblob # array of electrode associated with each spike
1008
- spike_depths=null : longblob # (um) array of depths associated with each spike, relative to the (0, 0) of the probe
1012
+ spike_depths=null : longblob # (um) array of depths associated with each spike, relative to the (0, 0) of the probe
1009
1013
"""
1010
1014
1011
1015
def make (self , key ):
@@ -1131,8 +1135,8 @@ class Waveform(dj.Part):
1131
1135
# Spike waveforms and their mean across spikes for the given unit
1132
1136
-> master
1133
1137
-> CuratedClustering.Unit
1134
- -> probe.ElectrodeConfig.Electrode
1135
- ---
1138
+ -> probe.ElectrodeConfig.Electrode
1139
+ ---
1136
1140
waveform_mean: longblob # (uV) mean waveform across spikes of the given unit
1137
1141
waveforms=null: longblob # (uV) (spike x sample) waveforms of a sampling of spikes at the given electrode for the given unit
1138
1142
"""
@@ -1260,7 +1264,7 @@ class QualityMetrics(dj.Imported):
1260
1264
1261
1265
definition = """
1262
1266
# Clusters and waveforms metrics
1263
- -> CuratedClustering
1267
+ -> CuratedClustering
1264
1268
"""
1265
1269
1266
1270
class Cluster (dj .Part ):
@@ -1285,26 +1289,26 @@ class Cluster(dj.Part):
1285
1289
contamination_rate (float): Frequency of spikes in the refractory period.
1286
1290
"""
1287
1291
1288
- definition = """
1292
+ definition = """
1289
1293
# Cluster metrics for a particular unit
1290
1294
-> master
1291
1295
-> CuratedClustering.Unit
1292
1296
---
1293
- firing_rate=null: float # (Hz) firing rate for a unit
1297
+ firing_rate=null: float # (Hz) firing rate for a unit
1294
1298
snr=null: float # signal-to-noise ratio for a unit
1295
1299
presence_ratio=null: float # fraction of time in which spikes are present
1296
1300
isi_violation=null: float # rate of ISI violation as a fraction of overall rate
1297
1301
number_violation=null: int # total number of ISI violations
1298
1302
amplitude_cutoff=null: float # estimate of miss rate based on amplitude histogram
1299
1303
isolation_distance=null: float # distance to nearest cluster in Mahalanobis space
1300
- l_ratio=null: float #
1304
+ l_ratio=null: float #
1301
1305
d_prime=null: float # Classification accuracy based on LDA
1302
1306
nn_hit_rate=null: float # Fraction of neighbors for target cluster that are also in target cluster
1303
1307
nn_miss_rate=null: float # Fraction of neighbors outside target cluster that are in target cluster
1304
1308
silhouette_score=null: float # Standard metric for cluster overlap
1305
1309
max_drift=null: float # Maximum change in spike depth throughout recording
1306
- cumulative_drift=null: float # Cumulative change in spike depth throughout recording
1307
- contamination_rate=null: float #
1310
+ cumulative_drift=null: float # Cumulative change in spike depth throughout recording
1311
+ contamination_rate=null: float #
1308
1312
"""
1309
1313
1310
1314
class Waveform (dj .Part ):
@@ -1324,7 +1328,7 @@ class Waveform(dj.Part):
1324
1328
velocity_below (float) inverse velocity of waveform propagation from soma toward the bottom of the probe.
1325
1329
"""
1326
1330
1327
- definition = """
1331
+ definition = """
1328
1332
# Waveform metrics for a particular unit
1329
1333
-> master
1330
1334
-> CuratedClustering.Unit
@@ -1476,20 +1480,20 @@ def get_neuropixels_channel2electrode_map(
1476
1480
return channel2electrode_map
1477
1481
1478
1482
1479
- def generate_electrode_config (probe_type : str , electrodes : list ) -> dict :
1483
+ def generate_electrode_config (probe_type : str , electrode_keys : list ) -> dict :
1480
1484
"""Generate and insert new ElectrodeConfig
1481
1485
1482
1486
Args:
1483
1487
probe_type (str): probe type (e.g. neuropixels 2.0 - SS)
1484
- electrodes (list): Electrode dict ( keys of the probe.ProbeType.Electrode table)
1488
+ electrode_keys (list): list of keys of the probe.ProbeType.Electrode table
1485
1489
1486
1490
Returns:
1487
1491
dict: representing a key of the probe.ElectrodeConfig table
1488
1492
"""
1489
1493
# compute hash for the electrode config (hash of dict of all ElectrodeConfig.Electrode)
1490
- electrode_config_hash = dict_to_uuid ({k ["electrode" ]: k for k in electrodes })
1494
+ electrode_config_hash = dict_to_uuid ({k ["electrode" ]: k for k in electrode_keys })
1491
1495
1492
- electrode_list = sorted ([k ["electrode" ] for k in electrodes ])
1496
+ electrode_list = sorted ([k ["electrode" ] for k in electrode_keys ])
1493
1497
electrode_gaps = (
1494
1498
[- 1 ]
1495
1499
+ np .where (np .diff (electrode_list ) > 1 )[0 ].tolist ()
@@ -1514,7 +1518,7 @@ def generate_electrode_config(probe_type: str, electrodes: list) -> dict:
1514
1518
}
1515
1519
)
1516
1520
probe .ElectrodeConfig .Electrode .insert (
1517
- {** electrode_config_key , ** electrode } for electrode in electrodes
1521
+ {** electrode_config_key , ** electrode } for electrode in electrode_keys
1518
1522
)
1519
1523
1520
1524
return electrode_config_key
0 commit comments