trainingColorSpeller.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Created on Tue Jul 24 13:32:51 2018
  5. @author: ale
  6. """
  7. # import logging
  8. from aux import log
  9. from paradigm import Paradigm
  10. class TrainingColorSpeller(Paradigm):
  11. '''
  12. Paradigm to train the user capability of using the color speller.
  13. Letters are grouped in different colors. Based on a training string and a
  14. confirmation method the algorithm will provide a list of the stimuli.
  15. '''
  16. def __init__(self, pyttsx_rate=100, **kwargs):
  17. '''
  18. Initialize the paradigm.
  19. Variables:
  20. trigger: list[int] (triggers for start and end of stimulus presentation)
  21. states: list[string] (structure of the grid with the letters)
  22. training_string: string (string that will be spelled)
  23. mode: string (mode of the paradigm)
  24. num_confirmation_yes: int (number of yes needed for selecting)
  25. num_confirmation_no: int (number of no needed for skipping)
  26. list_of_stimuli: list[str] (stimuli that will be presented)
  27. current_string = string (string currently written)
  28. current_selection = string (string of the current selection)
  29. history: list[string] (history of the presented stimuli)
  30. '''
  31. super().__init__(**kwargs)
  32. self.engine.setProperty('rate',pyttsx_rate)
  33. log.info(f'pyttsx3 rate is: {pyttsx_rate}')
  34. self.trigger = [1, 2]
  35. config = self.params.paradigms.training_color
  36. self.states = config.states
  37. self.training_string = config.training_string.upper()
  38. self.mode = config.mode[config.selected_mode]
  39. self.num_confirmation_yes = config.confirmation_yes
  40. self.num_confirmation_no = config.confirmation_no
  41. self.list_of_stimuli = []
  42. self.response_list = []
  43. self._create_list(self.training_string)
  44. self.current_string = ''
  45. self.current_selection = self.list_of_stimuli.pop(0)
  46. self.current_response = self.response_list.pop(0 )
  47. self.history = []
  48. def _create_list(self,string):
  49. '''
  50. Create the list of stimuli needed for spelling a string. The list will
  51. use the num_confirmation_yes and no for selecting or skipping.
  52. Parameters:
  53. string: str (string to spell)
  54. '''
  55. for train_letter in string:
  56. for row in self.states:
  57. if train_letter in row[1]:
  58. for i in range(self.num_confirmation_yes):
  59. self.list_of_stimuli.append(row[0])
  60. self.response_list.append('yes')
  61. for letter in row[1]:
  62. if train_letter == letter:
  63. for i in range(self.num_confirmation_yes):
  64. self.list_of_stimuli.append(letter)
  65. self.response_list.append('yes')
  66. break
  67. else:
  68. for i in range(self.num_confirmation_no):
  69. self.list_of_stimuli.append(letter)
  70. self.response_list.append('no')
  71. break
  72. else:
  73. for i in range(self.num_confirmation_no):
  74. self.list_of_stimuli.append(row[0])
  75. self.response_list.append('no')
  76. def process_result(self,decision=None):
  77. '''
  78. Append the last stimulus to history.
  79. Update the current_stimulus variable
  80. Parameters:
  81. decision: boolean (value of the last decision)
  82. Return:
  83. finish: boolean (True if the paradigm is finished, False otherwise)
  84. '''
  85. self.history.append([self.current_selection])
  86. if len(self.current_selection)==1 and (
  87. not self.list_of_stimuli or len(self.list_of_stimuli[0])>1):
  88. self.current_string += self.current_selection
  89. if self.list_of_stimuli:
  90. self.current_selection = self.list_of_stimuli.pop(0)
  91. self.current_response = self.response_list.pop(0)
  92. finish = False
  93. # log.info(f'History: {self.history}')
  94. else:
  95. finish = True
  96. self.current_selection = ''
  97. log.info('Stimulus list is empty.')
  98. return finish
  99. def present_stimulus(self, audio=True):
  100. '''
  101. Play auditorly the current stimulus using the say function defined in
  102. the abstract class
  103. Return:
  104. current_stimulus: string (the stimulus that is presented)
  105. '''
  106. '''stimulus = self.current_selection
  107. if audio is True:
  108. if not self.current_string:
  109. str2s = ''
  110. elif self.current_string[-1] == ' ' or len(self.list_of_stimuli)%10==0:
  111. str2s = 'Satz: '+self.current_string+'.\n Naechster: '
  112. else:
  113. str2s = ''
  114. stim2s = stimulus
  115. t2s = str2s + stim2s
  116. self._say(t2s.lower(),self.trigger[0],self.trigger[1])
  117. return stimulus'''
  118. if self.current_selection == '':
  119. log.warning('Stimulus list is empty!')
  120. return None
  121. stimulus = self.current_selection
  122. # log.info(f'Current stimulus: {stimulus}')
  123. if audio is True:
  124. if not self.current_string:
  125. str2s = ''
  126. stim2s = ''
  127. # elif self.current_string[-1] == ' ' or len(self.history)%10==0:
  128. elif self.current_string[-1] == ' ':
  129. # str2s = 'Satz: '+self.current_string
  130. str2s = self.current_string
  131. stim2s = 'Naechster: '
  132. else:
  133. str2s = ''
  134. stim2s = ''
  135. if stimulus == '<':
  136. stim2s += 'Loeschen'
  137. elif stimulus == ' ':
  138. stim2s += 'Anschlag'
  139. elif stimulus == '?':
  140. stim2s += 'Fragezeichen'
  141. elif stimulus == '^':
  142. stim2s += 'Zurueck zu den Farben?'
  143. elif stimulus == 'word':
  144. stim2s += 'Woerterbuch?'
  145. elif stimulus == 'end':
  146. stim2s += 'Programm beenden?'
  147. else:
  148. stim2s += stimulus
  149. if str2s:
  150. t2s = [str2s.lower(), stim2s.lower()]
  151. else:
  152. t2s = stim2s.lower()
  153. try:
  154. self._say(t2s, self.trigger[0], self.trigger[1])
  155. except:
  156. print('ERROR')
  157. raise
  158. return stimulus
  159. def get_current_state(self):
  160. '''
  161. Return the current state
  162. Return:
  163. current_string: str (current selected string)
  164. current_selection: str (current selection)
  165. '''
  166. return self.current_string, f'{self.current_selection}, {self.current_response}'
  167. def get_mode(self):
  168. '''
  169. Return the mode of the used paradigm
  170. Return:
  171. mode: string (mode of the paradigm)
  172. '''
  173. return self.mode
  174. def save_log(self):
  175. '''
  176. Save the log
  177. '''
  178. pass