@@ -55,6 +55,23 @@ def _spike_map(x, y, t, spike_times, xbins, ybins):
5555 return values
5656
5757
58+ def interpolate_nan_2D (array , method = 'nearest' ):
59+ from scipy import interpolate
60+ x = np .arange (0 , array .shape [1 ])
61+ y = np .arange (0 , array .shape [0 ])
62+ #mask invalid values
63+ array = np .ma .masked_invalid (array )
64+ xx , yy = np .meshgrid (x , y )
65+ #get only the valid values
66+ x1 = xx [~ array .mask ]
67+ y1 = yy [~ array .mask ]
68+ newarr = array [~ array .mask ]
69+
70+ return interpolate .griddata (
71+ (x1 , y1 ), newarr .ravel (), (xx , yy ),
72+ method = method , fill_value = 0 )
73+
74+
5875class SpatialMap :
5976 def __init__ (self , x , y , t , spike_times , box_size , bin_size , bin_count = None ):
6077 box_size , bin_size = _adjust_bin_size (box_size , bin_size , bin_count )
@@ -79,25 +96,60 @@ def spike_map(self, smoothing, mask_zero_occupancy=False, **kwargs):
7996
8097 return spmap
8198
82- def occupancy_map (self , smoothing , mask_zero_occupancy = False , ** kwargs ):
83- if smoothing == 0.0 :
84- ocmap = copy (self .time_pos )
85- else :
86- ocmap = smooth_map (self .time_pos , self .bin_size , smoothing , ** kwargs )
99+ def occupancy_map (self , smoothing , mask_zero_occupancy = False , threshold = None , ** kwargs ):
100+ '''Compute occupancy map as a histogram of postition
101+ weighted with time spent.
102+ Parameters:
103+ -----------
104+ mask_zero_occupancy : bool
105+ Set zero occupancy to nan
106+ threshold : float
107+ Set low occupancy times to zero as not to get spurious
108+ large values in rate.
109+
110+ '''
111+ ocmap = copy (self .time_pos )
112+ if threshold is not None :
113+ scmap [self .time_pos <= threshold ] = 0
114+ if smoothing > 0 :
115+ ocmap = smooth_map (ocmap , self .bin_size , smoothing , ** kwargs )
87116
88117 if mask_zero_occupancy :
89118 ocmap [self .time_pos == 0 ] = np .nan
90119
91120 return ocmap
92121
93- def rate_map (self , smoothing , mask_zero_occupancy = False , ** kwargs ):
122+ def rate_map (self , smoothing , mask_zero_occupancy = False , interpolate_invalid = False , threshold = None , ** kwargs ):
123+ '''Calculate rate map as spike_map / occupancy_map
124+ Parameters
125+ ----------
126+ smoothing : float
127+ Smoothing of spike_map and occupancy_map before division
128+ mask_zero_occupancy : bool
129+ Set pixels of zero occupancy to nan
130+ interpolate_invalid : bool
131+ Interpolate rate_map after division to remove invalid values,
132+ if False, and mask_zero_occupancy is False,
133+ invalid values are set to zero.
134+ threshold : float
135+ Low occupancy can produce spurious high rate, a threshold sets
136+ occupancy below this to zero.
137+ kwargs : key word arguments to scipy.interpolate, when smoothing > 0
138+ Returns
139+ -------
140+ rate_map : array
141+ '''
94142 spike_map = self .spike_map (smoothing = smoothing , ** kwargs )
95- occupancy_map = self .occupancy_map (smoothing = smoothing , ** kwargs )
143+ occupancy_map = self .occupancy_map (
144+ smoothing = smoothing , threshold = threshold , ** kwargs )
96145 if mask_zero_occupancy :
97146 # to avoid infinity (x/0) we set zero occupancy to nan
98147 # this can be handy when analyzing low occupancy maps
99148 rate_map = spike_map / occupancy_map
100149 rate_map [self .time_pos == 0 ] = np .nan
150+ elif interpolate_invalid :
151+ rate_map = spike_map / occupancy_map
152+ rate_map = interpolate_nan_2D (rate_map )
101153 else :
102154 rate_map = spike_map / occupancy_map
103155 rate_map [np .isinf (rate_map )] = 0
0 commit comments