Changeset 356
- Timestamp:
- 11/19/08 15:41:48 (2 months ago)
- Files:
-
- trunk/src/signals.py (modified) (18 diffs)
- trunk/src/stgen.py (modified) (4 diffs)
- trunk/test/test_signals.py (modified) (5 diffs)
- trunk/test/test_stgen.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/signals.py
r346 r356 519 519 self.t_start = 0.0 520 520 521 def distance_victorpurpura(self, spktrain, cost ):521 def distance_victorpurpura(self, spktrain, cost=0.5): 522 522 """ 523 523 Function to calculate the Victor-Purpura distance between two spike trains. 524 524 See J. D. Victor and K. P. Purpura, 525 525 Nature and precision of temporal coding in visual cortex: a metric-space 526 analysis.,526 analysis., 527 527 J Neurophysiol,76(2):1310-1326, 1996 528 528 529 529 Inputs: 530 530 spktrain - the other SpikeTrain 531 cost - The cost parameter. See the paper for more information s531 cost - The cost parameter. See the paper for more information 532 532 """ 533 533 nspk_1 = len(self) … … 2151 2151 class AnalogSignal(object): 2152 2152 """ 2153 AnalogSignal(signal, dt, t_start= None, t_stop=None)2154 2155 Return a AnalogSignal object which will be a analog signal trace2153 AnalogSignal(signal, dt, t_start=0, t_stop=None) 2154 2155 Return a AnalogSignal object which will be an analog signal trace 2156 2156 2157 2157 Inputs: 2158 2158 signal - the vector with the data of the AnalogSignal 2159 2159 dt - the time step between two data points of the sampled analog signal 2160 t_start - begining of the signal, in ms. If None, will be set to 02161 t_stop - end of the SpikeList, in ms. If None, will be infer ed from the data2160 t_start - begining of the signal, in ms. 2161 t_stop - end of the SpikeList, in ms. If None, will be inferred from the data 2162 2162 2163 2163 Examples: 2164 >> as = AnalogSignal(range(100), dt=0.1, t_start=0, t_stop=10)2164 >> s = AnalogSignal(range(100), dt=0.1, t_start=0, t_stop=10) 2165 2165 2166 2166 See also 2167 2167 AnalogSignalList, load_currentlist, load_vmlist, load_conductancelist, load 2168 2168 """ 2169 def __init__(self, signal, dt, t_start= None, t_stop=None):2170 2171 self.signal = numpy.array(signal, float)2172 self.dt = dt2173 self.t_start = t_start2169 def __init__(self, signal, dt, t_start=0, t_stop=None): 2170 2171 self.signal = numpy.array(signal, float) 2172 self.dt = float(dt) 2173 self.t_start = float(t_start) 2174 2174 self.t_stop = t_stop 2175 2175 2176 # If t_start is not None, we resize the signal keeping only 2177 # elements with t >= t_start 2178 if self.t_start is not None: 2179 self.signal = self.signal[numpy.floor(self.t_start/self.dt):] 2180 2181 # If t_stop is not None, we resize the signal keeping only 2182 # elements with t <= t_stop 2176 # If t_stop is not None, we test that the signal has the correct number 2177 # of elements 2183 2178 if self.t_stop is not None: 2184 self.signal = self.signal[:numpy.floor((self.t_stop-self.t_start)/self.dt)] 2185 2186 if len(self.signal) > 0: # spike list may be empty 2187 if self.t_start is None: 2188 self.t_start = 0. 2189 if self.t_stop is None: 2190 self.t_stop = len(self.signal)*self.dt 2191 else: 2192 self.t_start = 0. 2193 self.t_stop = self.dt 2179 if self.t_stop-self.t_start != self.dt * len(self.signal): 2180 raise Exception("Inconsistent arguments: t_start=%g, t_stop=%g, dt=%g implies %d elements, actually %d" % ( 2181 t_start, t_stop, dt, int((t_stop-t_start)/float(dt)), len(signal))) 2182 else: 2183 self.t_stop = self.t_start + len(self.signal)*self.dt 2184 2194 2185 # TODO raise an error if some data is outside [t_start, t_stop] ? 2195 2186 # TODO return an exception if self.t_stop < self.t_start (when not empty) 2196 if self.t_start >= self.t_stop :2187 if self.t_start >= self.t_stop: 2197 2188 raise Exception("Incompatible time interval for the creation of the AnalogSignal") 2198 2189 … … 2238 2229 else: 2239 2230 norm = 0. 2240 return numpy.linspace(self.t_start-norm, self.t_stop-norm, len(self.signal)) 2241 2231 return numpy.arange(self.t_start-norm, self.t_stop-norm, self.dt) 2242 2232 2243 2233 def time_offset(self, offset): … … 2301 2291 t_stop - end of the new SpikeTrain, in ms. 2302 2292 """ 2303 assert t_start >self.t_start2304 assert t_stop <=self.t_stop2305 assert t_stop >t_start2293 assert t_start >= self.t_start 2294 assert t_stop <= self.t_stop 2295 assert t_stop > t_start 2306 2296 2307 2297 t = self.time_axis() 2308 i_start = numpy.searchsorted(t,t_start,'right')-1 2309 i_stop = numpy.searchsorted(t,t_stop,'right')-1 2310 2298 i_start = int((t_start-self.t_start)/self.dt) 2299 i_stop = int((t_stop-self.t_start)/self.dt) 2311 2300 signal = self.signal[i_start:i_stop] 2312 result = AnalogSignal(signal, self.dt, 0.0, t_stop-t_start) 2313 result.time_offset(t_start) 2301 result = AnalogSignal(signal, self.dt, t_start, t_stop) 2314 2302 return result 2315 2303 … … 2439 2427 def slice_by_events(self,events,t_min=100,t_max=100): 2440 2428 """ 2441 Returns a dict containing new AnalogSignals c outout around events.2429 Returns a dict containing new AnalogSignals cutout around events. 2442 2430 2443 2431 Inputs: … … 2465 2453 t_start_new = (spike-t_min) 2466 2454 t_stop_new = (spike+t_max) 2467 result[index] = AnalogSignal(self.signal, self.dt, t_start=t_start_new, t_stop=t_stop_new) 2468 2455 result[index] = self.time_slice(t_start_new, t_stop_new) 2469 2456 return result 2470 2457 … … 2483 2470 id_list - the list of the ids of all recorded cells (needed for silent cells) 2484 2471 dt - if dt is specified, time values should be floats 2485 t_start - begining of the SpikeList, in ms. If None, will be infered from the data2472 t_start - begining of the SpikeList, in ms. 2486 2473 t_stop - end of the SpikeList, in ms. If None, will be infered from the data 2487 2474 dims - dimensions of the recorded population, if not 1D population … … 2492 2479 load_currentlist load_vmlist, load_conductancelist 2493 2480 """ 2494 def __init__(self, signals, id_list, dt, t_start= None, t_stop=None, dims=None):2495 2496 self.t_start = t_start2481 def __init__(self, signals, id_list, dt, t_start=0, t_stop=None, dims=None): 2482 2483 self.t_start = float(t_start) 2497 2484 self.t_stop = t_stop 2498 self.dt = dt2485 self.dt = float(dt) 2499 2486 self.dimensions = dims 2500 2487 self.analog_signals = {} … … 2513 2500 self.analog_signals.pop(id) 2514 2501 2515 if t_start is None or t_stop is None: 2516 self.__calc_startstop() 2502 if id_list: 2503 self.signal_length = len(self.analog_signals[min(id_list)]) 2504 for signal in self.analog_signals.values(): 2505 if len(signal) != self.signal_length: 2506 raise Exception("Signals must all be the same length %d != %d" % (self.signal_length, len(signal))) 2507 else: 2508 self.signal_length = 0 2509 2510 if t_stop is None: 2511 self.t_stop = self.t_start + self.signal_length*self.dt 2517 2512 2518 2513 def id_list(self): … … 2532 2527 aslist.append(id, self.analog_signals[id]) 2533 2528 return aslist 2534 2535 def __calc_startstop(self):2536 """2537 t_start and t_stop are shared for all neurons, so we take min and max values respectively.2538 TO DO : check the t_start and t_stop parameters for a SpikeList. Is it commun to2539 all the spikeTrains within the spikelist or each spikelistes do need its own.2540 """2541 if len(self) > 0:2542 if self.t_start is None:2543 start_times = numpy.array([self.analog_signals[idx].t_start for idx in self.id_list()])2544 self.t_start = numpy.min(start_times)2545 logging.debug("Warning, t_start is infered from the data : %f" %self.t_start)2546 for id in self.analog_signals.keys():2547 self.analog_signals[id].t_start = self.t_start2548 if self.t_stop is None:2549 stop_times = numpy.array([self.analog_signals[idx].t_stop for idx in self.id_list()])2550 self.t_stop = numpy.max(stop_times)2551 logging.debug("Warning, t_stop is infered from the data : %f" %self.t_stop)2552 for id in self.analog_signals.keys():2553 self.analog_signals[id].t_stop = self.t_stop2554 else:2555 raise Exception("No Analog Signals !")2556 2529 2557 2530 def __getitem__(self, id): … … 2563 2536 def __setitem__(self, i, val): 2564 2537 assert isinstance(val, AnalogSignal), "An AnalogSignalList object can only contain AnalogSignal objects" 2538 if len(self) > 0: 2539 errmsgs = [] 2540 for attr in "dt", "t_start", "t_stop": 2541 if getattr(val, attr) != getattr(self, attr): 2542 errmsgs.append("%s: %g != %g" % attr, getattr(val, attr), getattr(self, attr)) 2543 if len(val) != self.signal_length: 2544 errmsgs.append("signal length: %g != %g" % (len(val), self.signal_length)) 2545 if errmsgs: 2546 raise Exception("AnalogSignal being added does not match the existing signals: "+", ".join(errmsgs)) 2547 else: 2548 self.signal_length = len(val) 2565 2549 self.analog_signals[i] = val 2566 self.__calc_startstop()2567 2550 2568 2551 def __len__(self): … … 2598 2581 raise Exception("Id already present in AnalogSignalList. Use setitem instead()") 2599 2582 else: 2600 self.analog_signals[id] = signal 2601 self.__calc_startstop() 2583 self[id] = signal 2602 2584 2603 2585 def time_axis(self): … … 2605 2587 Return the time axis of the AnalogSignalList object 2606 2588 """ 2607 return numpy.arange(self.t_start, self.t_stop,self.dt)2589 return numpy.arange(self.t_start, self.t_stop, self.dt) 2608 2590 2609 2591 def id_offset(self, offset): … … 2622 2604 [10,11,12,13,14] 2623 2605 """ 2624 id_list = numpy.sort(self.id_list()) 2625 N = len(id_list) 2626 2606 id_list = numpy.sort(self.id_list()) 2607 N = len(id_list) 2627 2608 for idx in xrange(1,len(id_list)+1): 2628 2609 id = id_list[N-idx] 2629 2610 spk = self.analog_signals.pop(id) 2630 2611 self.analog_signals[id + offset] = spk 2631 2632 2612 2633 2613 def id_slice(self, id_list): … … 2667 2647 for id in self.id_list(): 2668 2648 new_AnalogSignalList.append(id, self.analog_signals[id].time_slice(t_start, t_stop)) 2669 new_AnalogSignalList.__calc_startstop()2670 2649 return new_AnalogSignalList 2671 2650 … … 2792 2771 result = numpy.zeros((len(self), int((self.t_stop - self.t_start)/self.dt)),float) 2793 2772 for count, id in enumerate(self.id_list()): 2794 result[count,:] = self.analog_signals[id].signal 2795 return numpy.var(result, axis=0) 2773 try: 2774 result[count,:] = self.analog_signals[id].signal 2775 except ValueError: 2776 print result[count,:].shape, self.analog_signals[id].signal.shape 2777 raise 2778 return numpy.std(result, axis=0) 2796 2779 2797 2780 def event_triggered_average(self, eventdict, events_ids = None, analogsignal_ids = None, average = True, t_min = 0, t_max = 100, ylim = None, display = False, mode = 'same', kwargs={}): … … 2904 2887 subplot.plot(time_axis, to_be_plot, **kwargs) 2905 2888 subplot.hold(1) 2906 pylab.draw()2889 #pylab.draw() 2907 2890 2908 2891 … … 3034 3017 3035 3018 3036 def load_vmlist(user_file, id_list=None, dt=None, t_start= None, t_stop=None, dims=None):3019 def load_vmlist(user_file, id_list=None, dt=None, t_start=0, t_stop=None, dims=None): 3037 3020 """ 3038 3021 Returns a VmList object from a file. If the file has been generated by PyNN, trunk/src/stgen.py
r352 r356 700 700 return (y,t) 701 701 702 result = AnalogSignal(y,dt,t_start=0,t_stop=t_stop-t_start) 703 result.time_offset(t_start) 702 result = AnalogSignal(y, dt, t_start, t_stop) 704 703 return result 705 704 … … 755 754 return (y,t) 756 755 757 result = AnalogSignal(y,dt,t_start=0,t_stop=t_stop-t_start) 758 result.time_offset(t_start) 756 result = AnalogSignal(y, dt, t_start, t_stop) 759 757 return result 760 758 … … 829 827 return (y,t) 830 828 831 result = AnalogSignal(y,dt,t_start=0,t_stop=t_stop-t_start) 832 result.time_offset(t_start) 829 result = AnalogSignal(y,dt,t_start,t_stop) 833 830 return result 834 831 … … 881 878 st = spike_train 882 879 883 assert t_stop>t_start 880 if t_start is not None and t_stop is not None: 881 assert t_stop>t_start 884 882 885 883 # time of vanishing significance trunk/test/test_signals.py
r320 r356 411 411 def testCreateAnalogSignalWithTstart(self): 412 412 sig = signals.AnalogSignal(numpy.sin(numpy.arange(10000.)), 0.1, 10) 413 assert len(sig) == (10000 - 10/0.1) 413 self.assertEqual(len(sig), 10000) 414 self.assertEqual(sig.t_start, 10.0) 415 self.assertEqual(sig.t_stop, 10.0+10000*0.1) 414 416 415 417 def testCreateAnalogSignalWithTstartTstop(self): 416 sig = signals.AnalogSignal(numpy.sin(numpy.arange(10000.)), 0.1, 10, 990) 417 assert len(sig) == (10000 - 20/0.1) 418 sig = signals.AnalogSignal(numpy.sin(numpy.arange(10000.)), 0.1, 10, 1010) 419 self.assertEqual(len(sig), 10000) 420 self.assertEqual(sig.t_start, 10.0) 421 self.assertEqual(sig.t_stop, 1010.0) 418 422 419 423 def testCreateAnalogSignalWrongTimes(self): … … 427 431 sig = signals.AnalogSignal(numpy.sin(numpy.arange(10000.)), 0.1) 428 432 res = sig.time_slice(0,500) 429 assert len(res) == 5000 433 self.assertEqual(len(res), 5000) 434 res = sig.time_slice(250,750) 435 self.assertEqual(len(res), 5000) 430 436 431 437 def testSliceByEvents(self): … … 470 476 new_analog = self.analog.time_slice(0, 50.) 471 477 assert (new_analog.t_start == self.analog.t_start) and (new_analog.t_stop == 50.) 478 new_analog = self.analog.time_slice(self.analog.t_start, self.analog.t_stop) 479 self.assertEqual(len(new_analog[0]), len(self.analog[0])) 472 480 473 481 def testCreateAnalogSignalList(self): 474 analog = signals.AnalogSignalList(self.values, range(10), 0.1, 0, 20)475 assert analog.t_start == 0 and analog.t_stop == 20482 analog = signals.AnalogSignalList(self.values, range(10), 0.1, 0, 100) 483 assert analog.t_start == 0 and analog.t_stop == 100 476 484 477 485 def testSaveAndLoadTxt(self): … … 482 490 def testSaveAndLoadTxtTimePart(self): 483 491 self.analog.save("tmp.txt") 484 analog2 = signals.load_vmlist("tmp.txt", t_start=0, t_stop= 50)485 assert analog2.t_stop == 50492 analog2 = signals.load_vmlist("tmp.txt", t_start=0, t_stop=100) 493 assert analog2.t_stop == 100 486 494 487 495 def testSaveAndLoadTxtIdsPart(self): … … 499 507 file = io.StandardPickleFile("tmp.pickle") 500 508 self.analog.save(file) 501 analog2 = signals.load_vmlist(file, t_start=0, t_stop= 50)502 assert analog2.t_stop == 50509 analog2 = signals.load_vmlist(file, t_start=0, t_stop=100) 510 assert analog2.t_stop == 100 503 511 504 512 def testSaveAndLoadPickleIdsPart(self): trunk/test/test_stgen.py
r337 r356 303 303 st = stg.poisson_generator(10.0,0.0,1000.0) 304 304 305 ge = s hotnoise_fromspikes(st,2.0,10.0,dt=0.1)305 ge = stgen.shotnoise_fromspikes(st,2.0,10.0,dt=0.1) 306 306 307 307 assert ge.t_start==0.0 … … 309 309 310 310 st = stg.poisson_generator(10.0,0.0,1000.0) 311 ge = s hotnoise_fromspikes(st,2.0,10.0,dt=0.1,t_start=500.0,t_stop=1500.0)311 ge = stgen.shotnoise_fromspikes(st,2.0,10.0,dt=0.1,t_start=500.0,t_stop=1500.0) 312 312 313 313 assert ge.t_start==500.0

