Changeset 209
- Timestamp:
- 09/23/08 18:50:44 (4 months ago)
- Files:
-
- branches/cleanup/src/analysis.py (modified) (2 diffs)
- branches/cleanup/src/io.py (modified) (4 diffs)
- branches/cleanup/src/signals.py (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/cleanup/src/analysis.py
r202 r209 8 8 9 9 import os, numpy 10 11 10 12 11 def ccf(x, y, axis=None): … … 60 59 return iFxy/varxy 61 60 62 63 64 65 66 67 68 69 70 71 def record(output, cfilename = 'SpikeTrainPlay.wav', fs=44100, enc = 'pcm26'):72 """ record the 'sound' produced by a neuron. Takes a spike train as the73 output.74 >>> record(my_spike_train)75 """76 77 78 # from the spike list79 simtime_seconds = (output.t_stop - output.t_start)/1000.80 #time = numpy.linspace(0, simtime_seconds , fs*simtime_seconds)81 (trace,time) = numpy.histogram(output.spike_times*1000., fs*simtime_seconds)82 83 # TODO convolve with proper spike...84 spike = numpy.ones((fs/1000.,)) # one ms85 trace = numpy.convolve(trace, spike, mode='same')#/2.086 trace /= numpy.abs(trace).max() * 1.187 try:88 from scikits.audiolab import wavwrite89 except ImportError:90 print "You need the scikits.audiolab package to produce sounds !"91 wavwrite(trace, cfilename, fs = fs, enc = enc)92 93 94 95 def play(output):96 """97 plays a spike list to the audio output98 play(spike_list) where spike_list is a spike_list object99 see playing_with_simple_single_neuron.py for a sample use100 >>> play(my_spike_train)101 TODO: make it possible to play multiple spike trains in stereo102 """103 104 105 from tempfile import mkstemp106 fd, cfilename = mkstemp('SpikeListPlay.wav')107 try:108 record(output, cfilename)109 import pyaudio110 import wave111 112 chunk = 1024113 wf = wave.open(cfilename, 'rb')114 p = pyaudio.PyAudio()115 116 # open stream117 stream = p.open(format =118 p.get_format_from_width(wf.getsampwidth()),119 channels = wf.getnchannels(),120 rate = wf.getframerate(),121 output = True)122 123 # read data124 data = wf.readframes(chunk)125 126 # play stream127 while data != '':128 stream.write(data)129 data = wf.readframes(chunk)130 131 stream.close()132 p.terminate()133 except:134 print "Error playing the SpikeTrain "135 # finally136 os.remove(cfilename)137 138 # Python 2.4 compatibility139 # finally:140 os.remove(cfilename)141 61 142 62 def _dict_max(D): branches/cleanup/src/io.py
r208 r209 54 54 # The simplest way to do that, for the moment, is to supposed that you have 55 55 # numpy 1.0.4 :-) 56 numpy.savetxt(filename, data )56 numpy.savetxt(filename, data, delimiter="\t") 57 57 58 58 … … 73 73 the SpikeList object, if saved in a text file 74 74 """ 75 f = open(self.filename, 'r') 76 line = f.readline() 77 while line[0] == '#': 78 key, value = line[1:].strip().replace(" ","").split("=") 79 if key == "dimensions": 80 value = value.split(" ") 81 try: 82 value.remove('') 83 except Exception: 84 pass 85 for idx in xrange(len(value)): 86 value[idx] = eval(value[idx]) 87 self.header[key] = value 88 else: 89 self.header[key] = eval(value) 90 line = f.readline() 91 f.close() 92 75 cmd = '' 76 f = open(self.filename, 'r') 77 for line in f.readlines(): 78 if line[0] == '#': 79 cmd += line[1:].strip() + ';' 80 f.close() 81 exec cmd in None, self.header 82 83 93 84 def write_header(self, spikelist, filename): 94 85 """ … … 97 88 f = open(filename,"w") 98 89 f.write("# dimensions = %s\n" % spikelist.dimensions) 99 f.write("# first_id = %d\n" % numpy.min(spikelist.id_list+1)) 100 f.write("# last_id = %d\n" % numpy.max(spikelist.id_list+1)) 90 ids = numpy.array(spikelist.id_list)+1 91 f.write("# first_id = %d\n" % numpy.min(ids)) 92 f.write("# last_id = %d\n" % numpy.max(ids)) 101 93 f.write("# dt = %g\n" % spikelist.dt) 102 94 f.close() … … 161 153 162 154 def parse_header(self): 163 f = open(self.filename, 'r') 164 line = f.readline() 165 while line[0] == '#': 166 key, value = line[1:].strip().replace(" ","").split("=") 167 if key == "dimensions": 168 value = value.split(" ") 169 try: 170 value.remove('') 171 except Exception: 172 pass 173 for idx in xrange(len(value)): 174 value[idx] = eval(value[idx]) 175 self.header[key] = value 176 else: 177 self.header[key] = eval(value) 178 line = f.readline() 179 f.close() 155 """ 156 Read the informations that may be contained in the header of 157 the SpikeList object, if saved in a text file 158 """ 159 cmd = '' 160 f = open(self.filename, 'r') 161 for line in f.readlines(): 162 if line[0] == '#': 163 cmd += line[1:].strip() + ';' 164 f.close() 165 exec cmd in None, self.header 180 166 181 167 def write_header(self, analogsignal, filename): 182 168 f = open(filename,"w") 183 169 f.write("# dimensions = %s\n" % analogsignal.dimensions) 184 f.write("# first_id = %d\n" % numpy.min(analogsignal.id_list+1)) 185 f.write("# last_id = %d\n" % numpy.max(analogsignal.id_list+1)) 170 ids = numpy.array(analogsignal.id_list)+1 171 f.write("# first_id = %d\n" % numpy.min(ids)) 172 f.write("# last_id = %d\n" % numpy.max(ids)) 186 173 f.write("# dt = %g\n" % analogsignal.dt) 187 174 f.close() branches/cleanup/src/signals.py
r208 r209 459 459 result[idx] = -(vec_2[idx]/vec_1[idx] -1) 460 460 return numpy.sum(numpy.abs(result)) 461 462 463 def record(self, filename = 'SpikeTrain.wav', fs=44100): 464 """ 465 Fancy tool, not really useful but still... 466 Record the 'sound' produced by a SpikeTrain. Need the scikits.audiolab 467 package 468 469 Inputs: 470 filename - the name of the output file (should have .wav extension) 471 fs - the sampling rate 472 473 Examples: 474 >>> spktrain.record("my_sound.wav") 475 """ 476 # from the spike list 477 simtime_seconds = (self.t_stop - self.t_start)/1000. 478 (trace,time) = numpy.histogram(self.spike_times*1000., fs*simtime_seconds) 479 # TODO convolve with proper spike... 480 spike = numpy.ones((fs/1000.,)) # one ms 481 trace = numpy.convolve(trace, spike, mode='same')#/2.0 482 trace /= numpy.abs(trace).max() * 1.1 483 try: 484 from scikits.audiolab import wavwrite 485 except ImportError: 486 print "You need the scikits.audiolab package to produce sounds !" 487 wavwrite(trace, filename, fs = fs, enc = 'pcm26') 461 488 462 489 #################################################################### … … 551 578 class SpikeList(object): 552 579 """ 553 SpikeList(spikes, id_list, dt=None, t_start=None, t_stop=None, dims=None , label='')580 SpikeList(spikes, id_list, dt=None, t_start=None, t_stop=None, dims=None) 554 581 555 582 Return a SpikeList object which will be a list of SpikeTrain objects. … … 562 589 t_stop - end of the SpikeList, in ms. If None, will be infered from the data 563 590 dims - dimensions of the recorded population, if not 1D population 564 label - optionnal name to identify the SpikeList565 591 566 592 dt, t_start and t_stop are shared for all SpikeTrains object within the SpikeList … … 704 730 self.spiketrains[id] = spktrain.time_slice(self.t_start, self.t_stop) 705 731 self.id_list.append(id) 732 self.N += 1 706 733 707 734 def get_time_parameters(self): … … 1122 1149 if len(self.dimensions) == 1: 1123 1150 return id 1124 if len( dims) == 2:1151 if len(self.dimensions) == 2: 1125 1152 x = numpy.floor(id/self.dimensions[0]) 1126 1153 y = id % self.dimensions[1] … … 1136 1163 t_start - if not defined, the one of the SpikeList is used 1137 1164 t_stop - if not defined, the one of the SpikeList is used 1138 float_positions - None by default, meaning that the dimensions attribute of the SpikeList 1139 is used to arange the ids on a 2D grid. Otherwise, if the cells have 1140 flotting positions, float_positions should be an array of size 1141 (2, nb_cells) with the x (first line) and y (second line) coordinates of 1142 the cells 1143 display - if True, a new figure is created. Could also be a subplot. The averaged 1144 spike_histogram over the whole population is then plotted 1145 kwargs - dictionary contening extra parameters that will be sent to the plot 1146 function 1165 float_positions - None by default, meaning that the dimensions attribute 1166 of the SpikeList is used to arange the ids on a 2D grid. 1167 Otherwise, if the cells have flotting positions, 1168 float_positions should be an array of size 1169 (2, nb_cells) with the x (first line) and y (second line) 1170 coordinates of the cells 1171 display - if True, a new figure is created. Could also be a subplot. 1172 The averaged spike_histogram over the whole population is 1173 then plotted 1174 kwargs - dictionary contening extra parameters that will be sent 1175 to the plot function 1147 1176 1148 1177 The 'dimensions' attribute of the SpikeList is used to turn ids into 2d positions. It should … … 1407 1436 1408 1437 1409 def activity_movie(self, time_bin=10, t_start=None, t_stop=None, float_positions=None, output="animation.mpg", fps=10):1438 def activity_movie(self, time_bin=10, t_start=None, t_stop=None, float_positions=None, output="animation.mpg", bounds=(0,5), fps=10, display = True, kwargs={}): 1410 1439 """ 1411 1440 Generate a movie of the activity between t_start and t_stop. … … 1413 1442 1414 1443 Inputs: 1415 time_bin - time step to bin activity during the movie. One frame is the mean rate during time_bin 1444 time_bin - time step to bin activity during the movie. 1445 One frame is the mean rate during time_bin 1416 1446 t_start - if not defined, the one of the SpikeList is used, in ms 1417 1447 t_stop - if not defined, the one of the SpikeList is used, in ms … … 1421 1451 (2, nb_cells) with the x (first line) and y (second line) coordinates of 1422 1452 the cells 1423 bounds - The common color bounds used during all the movies frame. This is a tuple 1453 output - The filename to store the movie 1454 bounds - The common color bounds used during all the movies frame. 1455 This is a tuple 1424 1456 of values (min, max), in spikes per frame. 1425 display - if True, a new figure is created. Could also be a subplot. The averaged1426 spike_histogram over the whole population is then plotted1457 fps - The number of frame per second in the final movie 1458 display - if True, a new figure is created. Could also be a subplot. 1427 1459 kwargs - dictionary contening extra parameters that will be sent to the plot 1428 1460 function … … 1438 1470 """ 1439 1471 subplot = self.__getdisplay__(display) 1440 if t_start is None: t_start = s pk.t_start1441 if t_stop is None: t_stop = s pk.t_stop1472 if t_start is None: t_start = self.t_start 1473 if t_stop is None: t_stop = self.t_stop 1442 1474 if not subplot or not ENABLE_PLOTS: 1443 1475 print MATPLOTLIB_ERROR 1444 1476 else: 1445 clim(bounds[0],bounds[1]) 1477 files = [] 1478 activity_map = numpy.zeros(self.dimensions) 1479 im = subplot.imshow(activity_map, **kwargs) 1480 im.set_clim(bounds[0],bounds[1]) 1481 im.colorbar() 1446 1482 count = 0 1447 manager = get_current_fig_manager()1448 t = t_start1449 if t_start != s pk.t_start or t_stop != spk.t_stop:1483 idx = 0 1484 manager = pylab.get_current_fig_manager() 1485 if t_start != self.t_start or t_stop != self.t_stop: 1450 1486 spk = spk.time_slice(t_start, t_stop) 1451 1487 else: … … 1453 1489 time, pos = spk.convert("times, ids") 1454 1490 # We sort the spikes to allow faster process later 1455 idx = time.ravel().argsort() 1456 time = time[idx] 1457 pos = pos[idx] 1491 sort_idx = time.ravel().argsort() 1492 time = time[sort_idx] 1493 pos = pos[sort_idx] 1494 1458 1495 if float_positions is None: 1459 1496 if self.dimensions is None: 1460 1497 raise Exception("Dimensions of the population are not defined ! Set spikelist.dims") 1461 while (t < t_stop):1462 activity_map s =zeros(spk.dimensions)1463 while (time[ count] <t + time_bin):1498 while (t_start < t_stop): 1499 activity_map = numpy.zeros(spk.dimensions) 1500 while (time[idx] < t_start + time_bin): 1464 1501 addr = spk.id2position(pos[idx]) 1465 activity_map s[addr] = activity_maps[addr] +11466 count+= 11467 im.set_array(activity_map s)1468 title("time = %d ms" %t)1502 activity_map[addr] += 1 1503 idx += 1 1504 im.set_array(activity_map) 1505 subplot.title("time = %d ms" %t_start) 1469 1506 manager.canvas.draw() 1470 clim(bounds[0],bounds[1])1507 im.set_clim(bounds[0],bounds[1]) 1471 1508 fname = "_tmp_spikes_%05d.png" %count 1472 1509 print " Saving Frame", fname 1473 savefig(fname)1510 pylab.savefig(fname) 1474 1511 files.append(fname) 1475 t += dt1512 t_start += time_bin 1476 1513 count += 1 1477 1514 print 'Making movie %s - this make take a while' %output … … 1482 1519 print "Clean up...." 1483 1520 for fname in files: os.remove(fname) 1484 1521 1485 1522 1486 1523 #################################################################### … … 1644 1681 def __getslice__(self, i, j): 1645 1682 """ 1646 Return a sublist of the s pike_times vector of the SpikeTrain1683 Return a sublist of the signal vector of the AnalogSignal 1647 1684 """ 1648 1685 return self.signal[i:j] … … 1661 1698 1662 1699 def time_axis(self): 1700 """ 1701 Return the time axis of the AnalogSignal 1702 """ 1663 1703 return numpy.arange(self.t_start, self.t_stop, self.dt) 1664 1704 … … 1672 1712 1673 1713 """ 1674 signal = s ignal[t_start/self.dt,t_stop/self.dt]1714 signal = self.signal[t_start/self.dt:t_stop/self.dt] 1675 1715 return AnalogSignal(signal, self.dt, t_start, t_stop) 1676 1716 … … 1690 1730 t_stop - end of the SpikeList, in ms. If None, will be infered from the data 1691 1731 dims - dimensions of the recorded population, if not 1D population 1692 label - optionnal name to identify the SpikeList1693 1732 1694 1733 dt, t_start and t_stop are shared for all SpikeTrains object within the SpikeList 1695 1734 1696 Examples:1697 >>> sl = SpikeList(3, [(0, 0.1), (1, 0.1), (0, 0.2)])1698 >>> type( sl[0] )1699 >>> <type SpikeTrain>1700 1701 1735 See also 1702 load CurrentTraces, loadMembraneTrace, loadConductanceTraces1736 load_currentlist load_vmlist, load_conductancelist 1703 1737 1704 1738 """ … … 1800 1834 1801 1835 def append(self, id, signal): 1836 """ 1837 Add an AnalogSignal object to the AnalogSignalList 1838 1839 Inputs: 1840 id - the id of the new cell 1841 signal - the AnalogSignal object representing the new cell 1842 1843 The AnalogSignal object is sliced according to the t_start and t_stop times 1844 of the AnalogSignallist object 1845 1846 See also 1847 __setitem__ 1848 """ 1802 1849 assert isinstance(signal, AnalogSignal), "An AnalogSignalList object can only contain AnalogSignal objects" 1803 1850 if id in self.id_list: 1804 raise Exception("Id already present in AnalogSignalList. Use setitem instead()")1851 raise Exception("Id already present in AnalogSignalList. Use setitem instead()") 1805 1852 else: 1806 1853 self.analog_signals[id] = signal … … 1810 1857 1811 1858 def time_axis(self): 1859 """ 1860 Return the time axis of the AnalogSignalList object 1861 """ 1812 1862 return numpy.arange(self.t_start,self.t_stop,self.dt) 1813 1863 1814 1864 def id_slice(self, id_list): 1815 pass 1816 1865 """ 1866 Return a new AnalogSignalList obtained by selecting particular ids 1867 1868 Inputs: 1869 id_list - Can be an integer (and then N random cells will be selected) 1870 or a sublist of the current ids 1871 1872 The new AnalogSignalList inherits the time parameters (t_start, t_stop, dt) 1873 1874 See also 1875 time_slice 1876 """ 1877 new_AnalogSignalList = AnalogSignalList([], [], self.dt, self.t_start, self.t_stop, self.dimensions) 1878 if isinstance(id_list, int): 1879 id_list = numpy.random.permutation(self.id_list)[0:id_list] 1880 for id in id_list: 1881 try: 1882 AnalogSignalList.append(id, self.analog_signals[id]) 1883 except Exception: 1884 print "id %d is not in the source AnalogSignalList" %id 1885 return new_AnalogSignalList 1886 1887 def time_slice(self, t_start, t_stop): 1888 """ 1889 Return a new AnalogSignalList obtained by slicing between t_start and t_stop 1890 1891 Inputs: 1892 t_start - begining of the new AnalogSignalList, in ms. 1893 t_stop - end of the new AnalogSignalList, in ms. 1894 1895 See also 1896 id_slice 1897 """ 1898 new_AnalogSignalList = AnalogSignalList([], [], self.dt, t_start, t_stop, self.dimensions) 1899 for id in self.id_list: 1900 new_AnalogSignalList.append(id, self.analog_signals[id].time_slice(t_start, t_stop)) 1901 new_AnalogSignalList.__calc_startstop() 1902 return new_AnalogSignalList 1903 1817 1904 def save(self, filename, method="text"): 1818 1905 """ … … 1834 1921 1835 1922 1836 def time_slice(self, t_start, t_stop):1837 pass1838 1839 1840 1841 1923 1842 1924 class VmList(AnalogSignalList): 1843 1925 1844 1926 def plot(self, id_list=None, v_thresh=None, display=True, kwargs={}): 1927 """ 1928 Plot all cells in the AnalogSignalList defined by id_list 1929 1930 Inputs: 1931 id_list - can be a integer (and then N cells are randomly selected) or a 1932 list of ids. If None, we use all the ids of the SpikeList 1933 v_thresh- For graphical purpose, plot a spike when Vm > V_thresh. If None, 1934 just plot the raw Vm 1935 display - if True, a new figure is created. Could also be a subplot 1936 kwargs - dictionary contening extra parameters that will be sent to the plot 1937 function 1938 1939 Examples: 1940 >>> z = subplot(221) 1941 >>> aslist.plot(5, v_thresh = -50, display=z, kwargs={'color':'r'}) 1942 """ 1845 1943 subplot = self.__getdisplay__(display) 1846 1944 id_list = self._AnalogSignalList__get_id_list(id_list) … … 1864 1962 1865 1963 def plot(self, id_list=None, v_thresh=None, display=True, kwargs={}): 1964 """ 1965 Plot all cells in the AnalogSignalList defined by id_list 1966 1967 Inputs: 1968 id_list - can be a integer (and then N cells are randomly selected) or a 1969 list of ids. If None, we use all the ids of the SpikeList 1970 display - if True, a new figure is created. Could also be a subplot 1971 kwargs - dictionary contening extra parameters that will be sent to the plot 1972 function 1973 1974 Examples: 1975 >>> z = subplot(221) 1976 >>> aslist.plot(5, display=z, kwargs={'color':'r'}) 1977 """ 1866 1978 subplot = self.__getdisplay__(display) 1867 1979 id_list = self._AnalogSignalList__get_id_list(id_list) … … 1881 1993 1882 1994 def plot(self, id_list=None, v_thresh=None, display=True, kwargs={}): 1995 """ 1996 Plot all cells in the AnalogSignalList defined by id_list 1997 1998 Inputs: 1999 id_list - can be a integer (and then N cells are randomly selected) or a 2000 list of ids. If None, we use all the ids of the SpikeList 2001 display - if True, a new figure is created. Could also be a subplot 2002 kwargs - dictionary contening extra parameters that will be sent to the plot 2003 function 2004 2005 Examples: 2006 >>> z = subplot(221) 2007 >>> aslist.plot(5, display=z, kwargs={'color':'r'}) 2008 """ 1883 2009 subplot = self.__getdisplay__(display) 1884 2010 id_list = self._AnalogSignalList__get_id_list(id_list)

