Changeset 408
- Timestamp:
- 07/16/09 11:50:11 (3 years ago)
- Location:
- branches/interval/src/signals
- Files:
-
- 2 modified
-
intervals.py (modified) (4 diffs)
-
spikes.py (modified) (45 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/interval/src/signals/intervals.py
r401 r408 22 22 """ 23 23 24 def __init__(self, s tart_times, end_times):24 def __init__(self, sub_intervals): 25 25 """ 26 26 Constructor of the Interval object. 27 27 28 28 """ 29 if HAVE_INTERVAL: 30 self.start_times = start_times 31 self.end_times = end_times 32 # write the intervals to an interval object (pyinterval) 33 test = isinstance(start_times, int) or isinstance(start_times, float) 34 if test: 35 start_times = [start_times] 36 test = isinstance(end_times, int) or isinstance(end_times, float) 37 if test: 38 end_times = [end_times] 39 if len(start_times) != len(end_times) : 40 raise Exception("There sould be an equal number of starts and stops") 41 self.interval_data = interval(*numpy.transpose(numpy.array([start_times,end_times]))) 42 else: 43 test = isinstance(start_times, int) or isinstance(start_times, float) 44 assert test, "Interval package not present, start_times should be a number !" 45 test = isinstance(end_times, int) or isinstance(end_times, float) 46 assert test, "Interval package not present, end_times should be a number !" 47 self.start_times = start_times 48 self.end_times = end_times 29 if not type(sub_intervals) is list: 30 sub_intervals = list((sub_intervals,)) 31 32 self._check_interval(sub_intervals) 33 self.sub_intervals = sub_intervals 34 self.start_times = numpy.array(self.sub_intervals)[:,0] 35 self.end_times = numpy.array(self.sub_intervals)[:,1] 36 37 if HAVE_INTERVAL: 38 self.interval_data = interval(*numpy.transpose(numpy.array([self.start_times, self.end_times]))) 39 40 def _check_interval(self, sub_intervals): 41 if not HAVE_INTERVAL: 42 assert len(sub_intervals) == 1, "Interval package not present, interval must be (t_start, t_stop) !" 43 for item in sub_intervals: 44 assert (len(item) == 2), "Intervals must be a list of tuple (t_start, t_stop) !" 45 assert item[1] > item[0], "Intervals must have tuple with t_start < t_stop !" 49 46 50 47 def intersect(self, itv) : 51 self.interval_data = self.interval_data & itv.interval_data 48 result = Interval(self.sub_intervals) 49 result.interval_data = result.interval_data & itv.interval_data 50 return result 52 51 53 52 def union(self, itv) : 54 self.interval_data = self.interval_data | itv.interval_data 55 53 if HAVE_INTERVAL: 54 result = Interval(self.sub_intervals) 55 result.interval_data = result.interval_data & itv.interval_data 56 result.interval_data = result.interval_data | itv.interval_data 57 else: 58 result = Interval(self.sub_intervals) 59 result.start_times = min(result.start_times, spiketrain.start_times) 60 result.end_times = max(result.end_times, spiketrain.end_times) 61 return result 62 56 63 def __str__(self): 57 64 return str(self.interval_data) … … 60 67 return shape(self.interval_data)[0] 61 68 69 def __iter__(self): 70 return iter(self.sub_intervals) 71 62 72 def __getslice__(self, i, j): 63 73 """ … … 90 100 """ 91 101 return Interval(self.start_times, self.end_times, self.t_start, self.t_stop) 102 103 104 def offset_start(self, shift, from_stop=False) : 105 """ 106 Shift all stop times of the interval by shift (ms). If from_start is 107 true, use start times as the reference to compute the new stop times 108 """ 109 interval_array = numpy.array(self.interval_data) 110 111 if from_stop == False : 112 if (interval_array[:,0] + shift > interval_array[:,1]).any() : 113 raise Exception("the shift is too big to preserve start/stop temporal order") 114 interval_array[:,0] += shift 115 else : 116 if shift > 0 : 117 raise Exception("the shift should be negative to preserve start/stop temporal order") 118 interval_array[:,0] = interval_array[:,1] + shift 119 120 self.interval_data = interval(*interval_array) 121 122 123 def offset_stop(self, shift, from_start=False) : 124 """ 125 Shift all stop times of the interval by shift (ms). If from_start is 126 true, use start times as the reference to compute the new stop times 127 """ 128 interval_array = numpy.array(self.interval_data) 129 130 if from_start == False : 131 if (interval_array[:,1] + shift < interval_array[:,0]).any() : 132 raise Exception("the shift is too big to preserve start/stop temporal order") 133 interval_array[:,1] += shift 134 else : 135 if shift < 0 : 136 raise Exception("the shift should be positive to preserve start/stop temporal order") 137 interval_array[:,1] = interval_array[:,0] + shift 138 139 self.interval_data = interval(*interval_array) 140 141 def offset_full(self, shift) : 142 """ 143 Shift the whole interval by 'shift' ms 144 """ 145 self.interval_data += shift 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 92 161 93 162 def offset(self, start=None, end=None) : … … 144 213 return numpy.extract(spikes_selector, times) 145 214 215 def is_equal(self, itv) : 216 return self.sub_intervals == itv.sub_intervals 146 217 147 218 -
branches/interval/src/signals/spikes.py
r406 r408 49 49 50 50 newnum = check_numpy_version() 51 51 INTERVAL_WARNING = "WARNING: t_start, t_stop are deprecated ! Use a syntax like interval=(t_start, t_stop) instead" 52 52 53 53 class SpikeTrain(object): … … 76 76 ## Constructor and key methods to manipulate the SpikeTrain objects ## 77 77 ####################################################################### 78 def __init__(self, spike_times, t_start=None, t_stop=None):78 def __init__(self, spike_times, interval=None): 79 79 """ 80 80 Constructor of the SpikeTrain object … … 83 83 SpikeTrain 84 84 """ 85 86 self.t_start = t_start 87 self.t_stop = t_stop 88 self.spike_times = numpy.array(spike_times, numpy.float32) 89 90 # If t_start is not None, we resize the spike_train keeping only 91 # the spikes with t >= t_start 92 if self.t_start is not None: 93 self.spike_times = numpy.extract((self.spike_times >= self.t_start), self.spike_times) 94 95 # If t_stop is not None, we resize the spike_train keeping only 96 # the spikes with t <= t_stop 97 if self.t_stop is not None: 98 self.spike_times = numpy.extract((self.spike_times <= self.t_stop), self.spike_times) 85 if interval is not None: 86 self.interval = interval 87 else: 88 try: 89 t_start = min(spike_times) 90 except Exception: 91 print "Error in guessing t_start (first spike), spikes may be empty !" 92 t_start = 0 93 try: 94 t_stop = max(spike_times) 95 except Exception: 96 print "Error in guessing t_stop (last spike), spikes may be empty !" 97 t_stop = 0.1 98 self.interval = Interval((t_start, t_stop)) 99 100 self.spike_times = self.interval.slice_times(numpy.array(spike_times, numpy.float32)) 99 101 100 102 # We sort the spike_times. May be slower, but is necessary by the way for quite a … … 107 109 # 1 element : t_start = time, t_stop = time + 0.1 108 110 # several : t_start = min(time), t_stop = max(time) 109 110 size = len(self.spike_times) 111 if size == 0: 112 if self.t_start is None: 113 self.t_start = 0 114 if self.t_stop is None: 115 self.t_stop = 0.1 116 elif size == 1: # spike list may be empty 117 if self.t_start is None: 118 self.t_start = self.spike_times[0] 119 if self.t_stop is None: 120 self.t_stop = self.spike_times[0] + 0.1 121 elif size > 1: 122 if self.t_start is None: 123 self.t_start = numpy.min(self.spike_times) 124 if numpy.any(self.spike_times < self.t_start): 125 raise ValueError("Spike times must not be less than t_start") 126 if self.t_stop is None: 127 self.t_stop = numpy.max(self.spike_times) 128 if numpy.any(self.spike_times > self.t_stop): 129 raise ValueError("Spike times must not be greater than t_stop") 130 131 if self.t_start >= self.t_stop : 132 raise Exception("Incompatible time interval : t_start = %s, t_stop = %s" % (self.t_start, self.t_stop)) 133 if self.t_start < 0: 134 raise ValueError("t_start must not be negative") 135 if numpy.any(self.spike_times < 0): 136 raise ValueError("Spike times must not be negative") 111 112 137 113 138 114 def __str__(self): … … 152 128 Return the time parameters of the SpikeTrain (t_start, t_stop) 153 129 """ 154 return (self. t_start, self.t_stop)130 return (self.interval.t_start(), self.interval.t_stop()) 155 131 156 132 def is_equal(self, spktrain): … … 165 141 time_parameters() 166 142 """ 167 test = (self. time_parameters() == spktrain.time_parameters())143 test = (self.interval.is_equal(spktrain.interval)) 168 144 return numpy.all(self.spike_times == spktrain.spike_times) and test 169 145 … … 172 148 Return a copy of the SpikeTrain object 173 149 """ 174 return SpikeTrain(self.spike_times, self.t_start, self.t_stop)150 return SpikeTrain(self.spike_times, interval=self.interval) 175 151 176 152 … … 179 155 Return the duration of the SpikeTrain 180 156 """ 181 return self. t_stop - self.t_start157 return self.interval.total_duration() 182 158 183 159 … … 202 178 self.spike_times = numpy.insert(self.spike_times, self.spike_times.searchsorted(spiketrain.spike_times), \ 203 179 spiketrain.spike_times) 204 self.t_start = min(self.t_start, spiketrain.t_start) 205 self.t_stop = max(self.t_stop, spiketrain.t_stop) 180 self.interval = self.interval.union(spiketrain.interval) 206 181 207 182 def format(self, relative=False, quantized=False): … … 244 219 """ 245 220 246 return SpikeTrain(self.spike_times+jitter*(numpy.random.normal(loc=0.0,scale=1.0,size=self.spike_times.shape[0])),t_start=self.t_start,t_stop=self.t_stop) 221 spk = self.spike_times+jitter*(numpy.random.normal(loc=0.0,scale=1.0,size=self.spike_times.shape[0])) 222 return SpikeTrain(spk, interval=self.interval) 247 223 248 224 … … 266 242 return numpy.diff(self.spike_times) 267 243 268 def mean_rate(self, t_start=None, t_stop=None):244 def mean_rate(self, interval=None): 269 245 """ 270 246 Returns the mean firing rate between t_start and t_stop, in Hz 271 247 272 248 Inputs: 273 t_start - in ms. If not defined, the one of the SpikeTrain object is used 274 t_stop - in ms. If not defined, the one of the SpikeTrain object is used 249 interval - An interval object 275 250 276 251 Examples: … … 278 253 34.2 279 254 """ 280 if (t_start == None) & (t_stop == None): 281 t_start = self.t_start 282 t_stop = self.t_stop 283 idx = self.spike_times 284 else: 285 if t_start == None: 286 t_start = self.t_start 287 else: 288 t_start = max(self.t_start, t_start) 289 if t_stop == None: 290 t_stop=self.t_stop 291 else: 292 t_stop = min(self.t_stop, t_stop) 293 idx = numpy.where((self.spike_times >= t_start) & (self.spike_times <= t_stop))[0] 294 return 1000.*len(idx)/(t_stop-t_start) 255 if interval: 256 new_interval = interval.intersect(self.interval) 257 idx = new_interval.slice_times(self.spike_times) 258 else: 259 idx = self.spike_times 260 new_interval = self.interval 261 return 1000.*len(idx)/new_interval.total_duration() 295 262 296 263 def cv_isi(self): … … 396 363 """ 397 364 if newnum: 398 axis = numpy.arange(self. t_start, self.t_stop+time_bin, time_bin)399 else: 400 axis = numpy.arange(self. t_start, self.t_stop, time_bin)365 axis = numpy.arange(self.interval.t_start(), self.interval.t_stop()+time_bin, time_bin) 366 else: 367 axis = numpy.arange(self.interval.t_start(), self.interval.t_stop(), time_bin) 401 368 return axis 402 369 403 def raster_plot(self, t_start=None, t_stop=None,interval=None, display=True, kwargs={}):370 def raster_plot(self, interval=None, display=True, kwargs={}): 404 371 """ 405 372 Generate a raster plot with the SpikeTrain in a subwindow of interest, … … 407 374 408 375 Inputs: 409 t_start - in ms. If not defined, the one of the SpikeTrain object is used 410 t_stop - in ms. If not defined, the one of the SpikeTrain object is used 376 interval - An interval object 411 377 display - if True, a new figure is created. Could also be a subplot 412 378 kwargs - dictionary contening extra parameters that will be sent to the plot … … 420 386 SpikeList.raster_plot 421 387 """ 422 if t_start is None: t_start = self.t_start423 if t_stop is None: t_stop = self.t_stop424 388 425 389 if interval is None: 426 interval = Interval(t_start, t_stop)390 interval = self.interval 427 391 428 392 spikes = interval.slice_times(self.spike_times) … … 454 418 120., 130., 140.] 455 419 """ 456 self.t_start += offset 457 self.t_stop += offset 420 self.interval.offset_full(offset) 458 421 self.spike_times += offset 459 422 … … 474 437 100 475 438 """ 476 spikes = numpy.extract((self.spike_times >= t_start) & (self.spike_times <= t_stop), self.spike_times)477 return SpikeTrain (spikes, t_start, t_stop)439 interval = Interval((t_start, t_stop)) 440 return SpikeTrain.interval_slice(interval) 478 441 479 442 def interval_slice(self, interval): … … 492 455 100 493 456 """ 494 times = interval.slice_times(self.spike_times) 495 t_start, t_stop = interval.time_parameters() 496 return SpikeTrain(times, t_start, t_stop) 457 times = interval.slice_times(self.spike_times) 458 return SpikeTrain(times, interval=interval) 497 459 498 460 … … 534 496 is substracted to spike_times, t_start and t_stop 535 497 """ 536 if self.t_start != 0:537 self.spike_times -= self.t_start538 self. t_stop -= self.t_start539 self. t_start = 0.0498 padding = -self.interval.t_start() 499 if padding != 0: 500 self.spike_times += padding 501 self.interval.offset_full(padding) 540 502 541 503 def distance_victorpurpura(self, spktrain, cost=0.5): … … 586 548 VictorPurpuraDistance 587 549 """ 588 N = (self.t_stop-self.t_start)/dt 550 551 N = (self.interval.t_stop()-self.interval.t_start())/dt 589 552 vec_1 = numpy.zeros(N, numpy.float32) 590 553 vec_2 = numpy.zeros(N, numpy.float32) … … 730 693 hist = self.time_histogram(time_bin, normalized=False) 731 694 freq_spect = analysis.simple_frequency_spectrum(hist) 732 freq_bin = 1000.0/self. duration() # Hz695 freq_bin = 1000.0/self.interval.total_duration() # Hz 733 696 freq_axis = numpy.arange(len(freq_spect)) * freq_bin 734 697 return freq_spect, freq_axis … … 746 709 freq_spect = self.frequency_spectrum(time_bin)[0] 747 710 F0 = freq_spect[0] 748 freq_bin = 1000.0/self. duration()711 freq_bin = 1000.0/self.interval.total_duration() 749 712 try: 750 713 F1 = freq_spect[int(round(f_stim/freq_bin))] … … 783 746 ## Constructor and key methods to manipulate the SpikeList objects ## 784 747 ####################################################################### 785 def __init__(self, spikes, id_list, t_start=None, t_stop=None, dims=None):748 def __init__(self, spikes, id_list, interval=None, dims=None): 786 749 """ 787 750 Constructor of the SpikeList object … … 790 753 SpikeList, load_spikelist 791 754 """ 792 self.t_start = t_start 793 self.t_stop = t_stop 755 #if t_start or t_stop: 756 757 self.interval = interval 794 758 self.dimensions = dims 795 759 self.spiketrains = {} … … 808 772 spikes = spikes[idx] 809 773 logging.debug("sorted spikes[:10,:] = %s" % str(spikes[:10,:])) 810 811 774 break_points = numpy.where(numpy.diff(spikes[:, 0]) > 0)[0] + 1 812 775 break_points = numpy.concatenate(([0], break_points)) … … 815 778 id = spikes[break_points[idx], 0] 816 779 if id in id_list: 817 self.spiketrains[id] = SpikeTrain(spikes[break_points[idx]:break_points[idx+1], 1], self.t_start, self.t_stop)818 819 if len(self) > 0 and (self. t_start is None or self.t_stopis None):780 self.spiketrains[id] = SpikeTrain(spikes[break_points[idx]:break_points[idx+1], 1], interval=self.interval) 781 782 if len(self) > 0 and (self.interval is None): 820 783 self.__calc_startstop() 821 784 … … 847 810 """ 848 811 if len(self) > 0: 849 if self.t_start is None: 850 start_times = numpy.array([self.spiketrains[idx].t_start for idx in self.id_list()], numpy.float32) 851 self.t_start = numpy.min(start_times) 852 logging.debug("Warning, t_start is infered from the data : %f" %self.t_start) 812 if self.interval is None: 813 start_times = numpy.array([self.spiketrains[idx].interval.t_start() for idx in self.id_list()], numpy.float32) 814 t_start = numpy.min(start_times) 815 logging.debug("Warning, t_start is infered from the data : %f" %t_start) 816 817 stop_times = numpy.array([self.spiketrains[idx].interval.t_stop() for idx in self.id_list()], numpy.float32) 818 t_stop = numpy.max(stop_times) 819 logging.debug("Warning, t_stop is infered from the data : %f" %t_stop) 820 853 821 for id in self.spiketrains.keys(): 854 self.spiketrains[id].t_start = self.t_start 855 if self.t_stop is None: 856 stop_times = numpy.array([self.spiketrains[idx].t_stop for idx in self.id_list()], numpy.float32) 857 self.t_stop = numpy.max(stop_times) 858 logging.debug("Warning, t_stop is infered from the data : %f" %self.t_stop) 859 for id in self.spiketrains.keys(): 860 self.spiketrains[id].t_stop = self.t_stop 822 self.spiketrains[id].interval = Interval((t_start, t_stop)) 861 823 else: 862 824 raise Exception("No SpikeTrains") … … 952 914 raise Exception("id %d already present in SpikeList. Use __setitem__ (spk[id]=...) instead()" %id) 953 915 else: 954 self.spiketrains[id] = spktrain. time_slice(self.t_start, self.t_stop)916 self.spiketrains[id] = spktrain.interval_slice(self.interval) 955 917 956 918 def time_parameters(self): … … 958 920 Return the time parameters of the SpikeList (t_start, t_stop) 959 921 """ 960 return (self. t_start, self.t_stop)922 return (self.interval.t_start(), self.interval.t_stop()) 961 923 962 924 def time_axis(self, time_bin): … … 971 933 """ 972 934 if newnum: 973 axis = numpy.arange(self. t_start, self.t_stop+time_bin, time_bin)974 else: 975 axis = numpy.arange(self. t_start, self.t_stop, time_bin)935 axis = numpy.arange(self.interval.t_start(), self.interval.t_stop() + time_bin, time_bin) 936 else: 937 axis = numpy.arange(self.interval.t_start(), self.interval.t_stop(), time_bin) 976 938 return axis 977 939 … … 993 955 # We check that Spike Lists have similar time_axis 994 956 for sl in spklists: 995 if not sl. time_parameters() == self.time_parameters():957 if not sl.interval.is_equal(self.interval): 996 958 raise Exception("Spike Lists should have similar time_axis") 997 959 for sl in spklists: … … 1043 1005 missing_ids = id_list.difference(set(self.id_list())) 1044 1006 for id in missing_ids: 1045 self.append(id, SpikeTrain([],self. t_start, self.t_stop))1007 self.append(id, SpikeTrain([],self.interval)) 1046 1008 1047 1009 … … 1066 1028 time_slice, interval_slice 1067 1029 """ 1068 new_SpkList = SpikeList([], [], self. t_start, self.t_stop, self.dimensions)1030 new_SpkList = SpikeList([], [], self.interval, self.dimensions) 1069 1031 id_list = self.__sub_id_list(id_list) 1070 1032 for id in id_list: … … 1086 1048 id_slice, interval_slice 1087 1049 """ 1088 new_SpkList = SpikeList([], [], t_start, t_stop, self.dimensions) 1089 for id in self.id_list(): 1090 new_SpkList.append(id, self.spiketrains[id].time_slice(t_start, t_stop)) 1091 new_SpkList.__calc_startstop() 1092 return new_SpkList 1050 interval = Interval((t_start, t_stop)) 1051 return self.interval_slice(interval) 1052 1093 1053 1094 1054 def interval_slice(self, interval): … … 1103 1063 id_slice, time_slice 1104 1064 """ 1105 t_start, t_stop = interval.time_parameters() 1106 new_SpkList = SpikeList([], [], t_start, t_stop, self.dimensions) 1065 new_SpkList = SpikeList([], [], interval, self.dimensions) 1107 1066 for id in self.id_list(): 1108 1067 new_SpkList.append(id, self.spiketrains[id].interval_slice(interval)) … … 1124 1083 1050 1125 1084 """ 1126 self.t_start += offset 1127 self.t_stop += offset 1085 self.interval.offset_full(offset) 1128 1086 for id in self.id_list(): 1129 1087 self.spiketrains[id].time_offset(offset) … … 1156 1114 Get the time of the first real spike in the SpikeList 1157 1115 """ 1158 first_spike = self. t_stop1116 first_spike = self.interval.t_stop() 1159 1117 is_empty = True 1160 1118 for id in self.id_list(): … … 1172 1130 Get the time of the last real spike in the SpikeList 1173 1131 """ 1174 last_spike = self. t_start1132 last_spike = self.interval.t_start() 1175 1133 is_empty = True 1176 1134 for id in self.id_list(): … … 1458 1416 1459 1417 1460 def mean_rate(self, t_start=None, t_stop=None):1418 def mean_rate(self, interval=None): 1461 1419 """ 1462 1420 Return the mean firing rate averaged accross all SpikeTrains between t_start and t_stop. 1463 1421 1464 1422 Inputs: 1465 t_start - begining of the selected area to compute mean_rate, in ms 1466 t_stop - end of the selected area to compute mean_rate, in ms 1423 interval - An interval object 1467 1424 1468 1425 If t_start or t_stop are not defined, those of the SpikeList are used … … 1478 1435 1479 1436 1480 def mean_rate_std(self, t_start=None, t_stop=None):1437 def mean_rate_std(self, interval=None): 1481 1438 """ 1482 1439 Standard deviation of the firing rates accross all SpikeTrains … … 1484 1441 1485 1442 Inputs: 1486 t_start - begining of the selected area to compute std(mean_rate), in ms 1487 t_stop - end of the selected area to compute std(mean_rate), in ms 1443 interval - An interval object 1488 1444 1489 1445 If t_start or t_stop are not defined, those of the SpikeList are used … … 1496 1452 mean_rate, mean_rates 1497 1453 """ 1498 return numpy.std(self.mean_rates( t_start, t_stop))1499 1500 1501 def mean_rates(self, t_start=None, t_stop=None):1454 return numpy.std(self.mean_rates(interval)) 1455 1456 1457 def mean_rates(self, interval=None): 1502 1458 """ 1503 1459 Returns a vector of the size of id_list giving the mean firing rate for each neuron 1504 1460 1505 1461 Inputs: 1506 t_start - begining of the selected area to compute std(mean_rate), in ms 1507 t_stop - end of the selected area to compute std(mean_rate), in ms 1462 interval - An interval object 1508 1463 1509 1464 If t_start or t_stop are not defined, those of the SpikeList are used … … 1514 1469 rates = [] 1515 1470 for id in self.id_list(): 1516 rates.append(self.spiketrains[id].mean_rate( t_start, t_stop))1471 rates.append(self.spiketrains[id].mean_rate(interval)) 1517 1472 return rates 1518 1473 … … 2032 1987 2033 1988 2034 def raster_plot(self, id_list=None, t_start=None, t_stop=None, display=True, kwargs={}):1989 def raster_plot(self, id_list=None, interval=None, display=True, kwargs={}): 2035 1990 """ 2036 1991 Generate a raster plot for the SpikeList in a subwindow of interest, … … 2060 2015 spk = self.id_slice(id_list) 2061 2016 2062 if t_start is None: t_start = spk.t_start 2063 if t_stop is None: t_stop = spk.t_stop 2064 if t_start != spk.t_start or t_stop != spk.t_stop: 2065 spk = spk.time_slice(t_start, t_stop) 2017 if interval is None: 2018 interval = spk.interval 2019 2020 if not interval.is_equal(spk.interval): 2021 spk = spk.interval_slice(interval) 2066 2022 2067 2023 if not subplot or not HAVE_PYLAB:
