Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

test_plot5.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import multiprocessing as mp
  2. from multiprocessing import Pipe, Value, current_process, Array
  3. import matplotlib
  4. import matplotlib.pyplot as plt
  5. # import matplotlib.animation as animation
  6. from matplotlib.animation import FuncAnimation
  7. import logging
  8. from colorlog import ColoredFormatter
  9. import numpy as np
  10. import time
  11. LOGFORMAT = "%(log_color)s %(asctime)s [%(filename)-12.12s] [%(lineno)4d] [%(processName)-12.12s] [%(threadName)-12.12s] [%(levelname)-7.7s] %(message)s"
  12. logging.root.setLevel(logging.INFO)
  13. formatter = ColoredFormatter(LOGFORMAT)
  14. stream = logging.StreamHandler()
  15. stream.setLevel(logging.INFO)
  16. stream.setFormatter(formatter)
  17. log = logging.getLogger('pythonConfig')
  18. log.setLevel(logging.INFO)
  19. log.addHandler(stream)
  20. def static_vars(**kwargs):
  21. def decorate(func):
  22. for k in kwargs:
  23. setattr(func, k, kwargs[k])
  24. return func
  25. return decorate
  26. def plot_feedback(audio_feedback_run, freq, audio_fb_target):
  27. """Plot feedback in real time. Uses normalized frequency and audio_fb_target to plot target."""
  28. log.info("Starting visual feedback")
  29. # config_file = 'paradigm.yaml'
  30. # config = self._read_config(config_file)
  31. # config = config.feedback
  32. fig = plt.figure(10, figsize=(4, 4), facecolor='black')
  33. ax = fig.add_subplot(1, 1, 1)
  34. ax.set_facecolor((0.02, 0.02, 0.02))
  35. target_x = 0.1
  36. target_w = 0.8
  37. cursor_x = 0.2
  38. cursor_y = 0.5 # variable
  39. cursor_w = 0.6
  40. cursor_h = 0.05
  41. target_ra = ax.add_patch(plt.Rectangle((target_x, 0), target_w, 0.1, fill=True, edgecolor=None, facecolor=(.7, .2, .4), linewidth=0, zorder=1))
  42. cursor_ra = ax.add_patch(plt.Rectangle((cursor_x, 0.5), cursor_w, cursor_h, fill=True, facecolor=(.4, .5, 1.0), linewidth=0, zorder=10))
  43. plt.show(False)
  44. plt.draw()
  45. def init_plot():
  46. ax.set_clip_on(False)
  47. ax.get_xaxis().set_ticks([])
  48. ax.get_yaxis().set_ticks([])
  49. ax.set_xlim(0, 1)
  50. ax.set_ylim(0, 1)
  51. for n,s in ax.spines.items():
  52. s.set_color((.2,.2,.2))
  53. return (cursor_ra, target_ra)
  54. @static_vars(is_plotting=False)
  55. def update_plot(i):
  56. if (not update_plot.is_plotting) and audio_feedback_run.value == 1:
  57. update_plot.is_plotting = True
  58. cursor_ra.set_visible(True)
  59. target_ra.set_visible(True)
  60. init_plot()
  61. elif update_plot.is_plotting and (audio_feedback_run.value == 0):
  62. update_plot.is_plotting = False
  63. cursor_ra.set_visible(False)
  64. target_ra.set_visible(False)
  65. if update_plot.is_plotting:
  66. cursor_y = freq.value - cursor_h/2.0
  67. target_y = audio_fb_target[1]
  68. target_h = audio_fb_target[2] - audio_fb_target[1]
  69. if (audio_fb_target[1] <= freq.value) and (freq.value <= audio_fb_target[2]):
  70. target_ra.set_fc((.3,1.0,.6))
  71. else:
  72. target_ra.set_fc((.7, .2, .4))
  73. cursor_ra.set_y(cursor_y)
  74. target_ra.set_y(target_y)
  75. target_ra.set_height(target_h)
  76. log.info(f'cursor_y: {cursor_y}, target_y: {target_y}, target_h: {target_h}')
  77. return (cursor_ra, target_ra)
  78. ani = FuncAnimation(fig, update_plot, frames=None,
  79. init_func=init_plot, blit=True, interval=250)
  80. plt.show()
  81. # background1 = fig.canvas.copy_from_bbox(ax.bbox)
  82. # fig.canvas.draw()
  83. # ax.draw_artist(cursor_ra)
  84. # ax.draw_artist(target_ra)
  85. # plt.show()
  86. # plt.pause(0.01)
  87. #
  88. # while True:
  89. # target_counter = 0
  90. #
  91. # while audio_feedback_run.value == 1:
  92. # # fig.canvas.restore_region(background1)
  93. #
  94. #
  95. #
  96. # update_plot(cursor_y, target_y, target_h)
  97. # log.info(f"fr: {freq.value}, pos: {cursor_y}")
  98. # # ax.draw_artist(cursor_ra)
  99. # # ax.draw_artist(target_ra)
  100. # # fig.canvas.blit(ax.bbox)
  101. #
  102. # # fig.canvas.update()
  103. # # fig.canvas.flush_events()
  104. # fig.canvas.draw()
  105. #
  106. # time.sleep(0.1)
  107. #
  108. # # time.sleep(1./params.plot.fps)
  109. # pass
  110. # time.sleep(0.1)
  111. def setup():
  112. audio_fb_freq = Value('d', 0.0) # Normalized audio feedback activity [0, 1]
  113. audio_fb_target = Array('d', 3) # Target for normalized audio feedback activity [0, 1]. Give upper and lower bound
  114. audio_feedback_run = Value('i',1) # 0: baseline, 1: stimulus, 2:response
  115. vfeedback_p = mp.Process(name='vfeedback', target=plot_feedback, args=(audio_feedback_run, audio_fb_freq, audio_fb_target))
  116. vfeedback_p.daemon = True # kill visualization if main app terminates
  117. vfeedback_p.start()
  118. return (audio_fb_freq, audio_fb_target, audio_feedback_run)
  119. if __name__ == '__main__':
  120. audio_fb_freq, audio_fb_target, audio_feedback_run = setup()
  121. audio_fb_target[0] = .5
  122. audio_fb_target[1] = .4
  123. audio_fb_target[2] = .6
  124. while True:
  125. norm_rate = audio_fb_freq.value
  126. norm_rate += (np.random.random() - 0.5) * 0.2
  127. norm_rate = np.maximum(np.minimum(norm_rate, 1), 0)
  128. audio_fb_freq.value = norm_rate
  129. td = (np.random.random() - 0.5) * 0.2
  130. audio_fb_target[1] += td
  131. audio_fb_target[2] += td
  132. if np.random.random() < 0.1:
  133. audio_feedback_run.value = 1-audio_feedback_run.value
  134. # log.info(f'fr: {audio_fb_freq.value}')
  135. time.sleep(0.25)