26
26
find_members ,
27
27
)
28
28
29
-
30
29
hv .extension ("bokeh" )
31
30
from bokeh .plotting import show
32
31
from itertools import product
@@ -41,9 +40,11 @@ def __init__(
41
40
spatial_bin_size_radians = 0.05 ,
42
41
S_std_thresh = 1 ,
43
42
velocity_threshold = 7 ,
43
+ place_cell_alpha = 0.001 ,
44
+ place_cell_transient_threshold = 40 ,
44
45
overwrite_synced_data = False ,
45
46
overwrite_placefields = False ,
46
- overwrite_placefield_trials = False ,
47
+ overwrite_placefield_trials = True ,
47
48
overwrite_assemblies = False ,
48
49
local = True ,
49
50
):
@@ -196,6 +197,11 @@ def __init__(
196
197
with open (fpath , "wb" ) as file :
197
198
pkl .dump (self .assemblies , file )
198
199
200
+ self .spatial .data ['place_cells' ] = self .get_place_cells (alpha = place_cell_alpha ,
201
+ transient_threshold = place_cell_transient_threshold )
202
+ self .spatial .meta ['place_cell_pval' ] = place_cell_alpha
203
+ self .spatial .meta ['place_cell_transient_threshold' ] = place_cell_transient_threshold
204
+
199
205
def get_pkl_path (self , fname ):
200
206
if self .meta ["local" ]:
201
207
local_path = get_equivalent_local_path (self .meta ["folder" ])
@@ -367,7 +373,8 @@ def spatial_activity_by_trial(self):
367
373
368
374
# Get occupancy this trial.
369
375
occupancy = spatial_bin (
370
- positions_this_trial , filler , bins = bin_edges , one_dim = True
376
+ positions_this_trial , filler , bins = bin_edges , one_dim = True ,
377
+ weights = running_this_trial .astype (int )
371
378
)[0 ]
372
379
373
380
# Weight position by activity of each neuron.
@@ -386,6 +393,68 @@ def spatial_activity_by_trial(self):
386
393
387
394
return fields , occ_map_by_trial
388
395
396
+ def get_place_cells (self , alpha = 0.001 , transient_threshold = 40 ):
397
+ n_transients = np .sum (np .sum (self .spatial .data ['rasters' ], axis = 1 ), axis = 1 )
398
+ place_cells = np .where (np .logical_and (self .spatial .data ['spatial_info_pvals' ] < alpha ,
399
+ n_transients > transient_threshold ))[0 ]
400
+
401
+ return place_cells
402
+
403
+ def placefield_reliability (self , neuron , field_threshold = 0.15 , even_split = True , split = 4 ,
404
+ show_plot = True ):
405
+ """
406
+ Compute the trial-by-trial in-field consistency of a neuron (whether it fired in field).
407
+
408
+ :parameters
409
+ ---
410
+ neuron: int
411
+ Neuron number.
412
+
413
+ field_threshold: float
414
+ Percentage of field peak to be considered part of the field.
415
+
416
+ even_split: bool
417
+ Flag to split trials evenly into n parts (defined by the argument split). If False,
418
+ instead split is the number of trials in each split.
419
+
420
+ split: int
421
+ If even_split, the number of parts to divide the trial into.
422
+ If not even_split, the number of trials in each split.
423
+
424
+ """
425
+ raster = self .spatial .data ['rasters' ][neuron ]
426
+ placefield = self .spatial .data ['placefields_normalized' ][neuron ]
427
+
428
+ field_bins = np .where (placefield > max (placefield ) * field_threshold )[0 ]
429
+ fired_in_field = np .any (raster [:, field_bins ], axis = 1 )
430
+
431
+ if not even_split :
432
+ split = np .arange (split , len (fired_in_field ), split )
433
+
434
+ split_fired_in_field = np .array_split (fired_in_field , split )
435
+
436
+ # Handles cases where you don't actually want to split the reliability across trials.
437
+ if split == 1 and even_split :
438
+ reliability = np .sum (split_fired_in_field [0 ])/ len (split_fired_in_field [0 ])
439
+ else :
440
+ reliability = [np .sum (fired_in_field ) / len (fired_in_field ) for fired_in_field in split_fired_in_field ]
441
+
442
+ if show_plot and even_split :
443
+ fig , axs = plt .subplots (1 ,2 )
444
+ axs [0 ].imshow (raster > 0 , aspect = 'auto' )
445
+ axs [0 ].set_xlabel ('Position' )
446
+ axs [0 ].set_ylabel ('Trials' )
447
+
448
+ axs [1 ].plot (reliability , range (len (reliability )))
449
+ axs [1 ].set_xlim ([0 , 1 ])
450
+ axs [1 ].invert_yaxis ()
451
+ axs [1 ].set_ylabel (f'Trial block #, { len (split_fired_in_field [0 ])} trials per block' )
452
+ axs [1 ].set_xlabel ('Proportion of trials with '
453
+ '\n in-field calcium transient' )
454
+ fig .tight_layout ()
455
+
456
+ return reliability
457
+
389
458
def viz_spatial_trial_activity (self , neurons = range (10 ), preserve_neuron_idx = True ):
390
459
"""
391
460
Visualize single cell activity binned in spatial and separated
0 commit comments