write_data.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #!/usr/bin/env python3.7
  2. # -*- coding: utf-8 -*-
  3. # python version 3.7.6
  4. """
  5. @author: yannansu
  6. @created at: 19.03.21 10:38
  7. This module contains all writing and reading functions for configuration files for the color-noise experiment.
  8. Functions for writing:
  9. function write_cfg: write experiment config file *.yaml
  10. function write_par: write parameter file *.yaml
  11. class WriteXpp: write session log file *.yaml
  12. function write_xrl: write subject log file *.xrl
  13. Functions for reading:
  14. function read_yml: read all types of *.yaml
  15. function read_xrl: read subject log file *.xrl
  16. """
  17. import os
  18. import numpy as np
  19. import yaml
  20. import sys
  21. import xlsxwriter
  22. import copy
  23. import psychopy
  24. # from .yml2dict import yml2dict
  25. from exp.yml2dict import yml2dict
  26. class WriteData:
  27. def __init__(self, subject, idx, dir_path='data'):
  28. """
  29. Create a log YAML file for one session.
  30. :param subject: subject name [string]
  31. :param idx: date and time [string]
  32. :param dir_path: the directory for storing. default: data/subject
  33. """
  34. base = os.path.join(dir_path, subject, 'raw_data')
  35. if not os.path.exists(base):
  36. os.makedirs(base)
  37. self.idx = idx
  38. self.file_path = os.path.join(base, subject + '_' + idx + '.yaml')
  39. self.f = open(self.file_path, 'w+')
  40. def head(self, cfg_file, par_file):
  41. """
  42. Copy the metadata from experiment config and parameter file into the head part of this log file.
  43. :param cfg_file: experiment config file path
  44. :param par_file: parameter file path
  45. :return: the log file path
  46. """
  47. info = {'time': self.idx,
  48. 'cfg_file': cfg_file,
  49. 'par_file': par_file}
  50. # yaml.safe_dump(info, self.f, default_flow_style=False, sort_keys=False)
  51. cfg_dict = yml2dict(cfg_file)
  52. par_dict = yml2dict(par_file)
  53. yaml.safe_dump({**info, **cfg_dict, **par_dict}, self.f, default_flow_style=False, sort_keys=False)
  54. return self.file_path
  55. def write(self, count, trial_type, result_dict):
  56. """
  57. Append log of every single trials in iterations to this log file.
  58. cond, patch_xlims, rot, disp_intensity, press_key, judge, react_time, trial_stamp
  59. :param count: count of this trial
  60. :param trial_type: trial type, 'trial' or 'warmup'
  61. :param result_dict: a dictionary of results
  62. """
  63. if trial_type != 'trial' and trial_type != 'warmup':
  64. raise ValueError("The trial type is incorrect!")
  65. this_trial = trial_type + '_' + str(count)
  66. trial_dict = {this_trial: result_dict}
  67. yaml.dump(trial_dict, self.f, default_flow_style=False, sort_keys=False)
  68. self.f.flush()
  69. class WriteActivity:
  70. def __init__(self, subject, idx, dir_path='data'):
  71. """
  72. Create a log YAML file for one session.
  73. :param subject: subject name [string]
  74. :param idx: date and time [string]
  75. :param dir_path: the directory for storing. default: data/subject
  76. """
  77. base = os.path.join(dir_path, subject)
  78. if not os.path.exists(base):
  79. os.makedirs(base)
  80. self.file_path = os.path.join(base, subject + '.yaml')
  81. if os.path.exists(self.file_path):
  82. self.f = open(self.file_path, 'a+')
  83. else:
  84. self.f = open(self.file_path, 'w+')
  85. self.idx = idx
  86. def write(self, cfg_file, par_file, data_file, status=None):
  87. """
  88. :param cfg_file: experiment config file path
  89. :param par_file: parameter file path
  90. :param data_file: parameter file path
  91. :param status:
  92. :return: the log file path
  93. """
  94. if yml2dict(self.file_path) is None:
  95. session_count = 1
  96. else:
  97. session_count = len(yml2dict(self.file_path).keys()) + 1
  98. start_info = {'session_count': session_count,
  99. 'session_idx': self.idx,
  100. 'cfg_file': cfg_file,
  101. 'par_file': par_file,
  102. 'data_file': data_file,
  103. 'status': status}
  104. session_dict = {self.idx: start_info}
  105. yaml.safe_dump(session_dict, self.f, default_flow_style=False, sort_keys=False)
  106. # self.f.flush()
  107. return self.file_path
  108. # def stop(self, status):
  109. # """
  110. #
  111. # :param status: 'completed', 'practice', 'userbreak'
  112. # :return:
  113. # """
  114. # this_session = yml2dict(self.file_path)[self.idx]
  115. # this_session['status'] = status
  116. # session_dict = {self.idx: this_session}
  117. # yaml.safe_dump(session_dict, self.f, default_flow_style=False, sort_keys=False)
  118. # self.f.flush()