1
1

generated_data.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. """
  2. This is an example for creating simple plots from various Neo structures.
  3. It includes a function that generates toy data.
  4. """
  5. import numpy as np
  6. import quantities as pq
  7. from matplotlib import pyplot as plt
  8. import neo
  9. def generate_block(n_segments=3, n_channels=4, n_units=3,
  10. data_samples=1000, feature_samples=100):
  11. """
  12. Generate a block with a single recording channel group and a number of
  13. segments, recording channels and units with associated analog signals
  14. and spike trains.
  15. """
  16. feature_len = feature_samples / data_samples
  17. # Create Block to contain all generated data
  18. block = neo.Block()
  19. # Create multiple Segments
  20. block.segments = [neo.Segment(index=i) for i in range(n_segments)]
  21. # Create multiple ChannelIndexes
  22. block.channel_indexes = [neo.ChannelIndex(name='C%d' % i, index=i) for i in range(n_channels)]
  23. # Attach multiple Units to each ChannelIndex
  24. for channel_idx in block.channel_indexes:
  25. channel_idx.units = [neo.Unit('U%d' % i) for i in range(n_units)]
  26. # Create synthetic data
  27. for seg in block.segments:
  28. feature_pos = np.random.randint(0, data_samples - feature_samples)
  29. # Analog signals: Noise with a single sinewave feature
  30. wave = 3 * np.sin(np.linspace(0, 2 * np.pi, feature_samples))
  31. for channel_idx in block.channel_indexes:
  32. sig = np.random.randn(data_samples)
  33. sig[feature_pos:feature_pos + feature_samples] += wave
  34. signal = neo.AnalogSignal(sig * pq.mV, sampling_rate=1 * pq.kHz)
  35. seg.analogsignals.append(signal)
  36. channel_idx.analogsignals.append(signal)
  37. # Spike trains: Random spike times with elevated rate in short period
  38. feature_time = feature_pos / data_samples
  39. for u in channel_idx.units:
  40. random_spikes = np.random.rand(20)
  41. feature_spikes = np.random.rand(5) * feature_len + feature_time
  42. spikes = np.hstack([random_spikes, feature_spikes])
  43. train = neo.SpikeTrain(spikes * pq.s, 1 * pq.s)
  44. seg.spiketrains.append(train)
  45. u.spiketrains.append(train)
  46. block.create_many_to_one_relationship()
  47. return block
  48. block = generate_block()
  49. # In this example, we treat each segment in turn, averaging over the channels
  50. # in each:
  51. for seg in block.segments:
  52. print("Analysing segment %d" % seg.index)
  53. siglist = seg.analogsignals
  54. time_points = siglist[0].times
  55. avg = np.mean(siglist, axis=0) # Average over signals of Segment
  56. plt.figure()
  57. plt.plot(time_points, avg)
  58. plt.title("Peak response in segment %d: %f" % (seg.index, avg.max()))
  59. # The second alternative is spatial traversal of the data (by channel), with
  60. # averaging over trials. For example, perhaps you wish to see which physical
  61. # location produces the strongest response, and each stimulus was the same:
  62. # There are multiple ChannelIndex objects connected to the block, each
  63. # corresponding to a a physical electrode
  64. for channel_idx in block.channel_indexes:
  65. print("Analysing channel %d: %s" % (channel_idx.index, channel_idx.name))
  66. siglist = channel_idx.analogsignals
  67. time_points = siglist[0].times
  68. avg = np.mean(siglist, axis=0) # Average over signals of RecordingChannel
  69. plt.figure()
  70. plt.plot(time_points, avg)
  71. plt.title("Average response on channel %d" % channel_idx.index)
  72. # There are three ways to access the spike train data: by Segment,
  73. # by ChannelIndex or by Unit.
  74. # By Segment. In this example, each Segment represents data from one trial,
  75. # and we want a peristimulus time histogram (PSTH) for each trial from all
  76. # Units combined:
  77. for seg in block.segments:
  78. print("Analysing segment %d" % seg.index)
  79. stlist = [st - st.t_start for st in seg.spiketrains]
  80. count, bins = np.histogram(np.hstack(stlist))
  81. plt.figure()
  82. plt.bar(bins[:-1], count, width=bins[1] - bins[0])
  83. plt.title("PSTH in segment %d" % seg.index)
  84. # By Unit. Now we can calculate the PSTH averaged over trials for each Unit:
  85. for unit in block.list_units:
  86. stlist = [st - st.t_start for st in unit.spiketrains]
  87. count, bins = np.histogram(np.hstack(stlist))
  88. plt.figure()
  89. plt.bar(bins[:-1], count, width=bins[1] - bins[0])
  90. plt.title("PSTH of unit %s" % unit.name)
  91. # By ChannelIndex. Here we calculate a PSTH averaged over trials by
  92. # channel location, blending all Units:
  93. for chx in block.channel_indexes:
  94. stlist = []
  95. for unit in chx.units:
  96. stlist.extend([st - st.t_start for st in unit.spiketrains])
  97. count, bins = np.histogram(np.hstack(stlist))
  98. plt.figure()
  99. plt.bar(bins[:-1], count, width=bins[1] - bins[0])
  100. plt.title("PSTH blend of recording channel group %s" % chx.name)
  101. plt.show()