generated_data.py 4.7 KB

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