对Brainflow这一python提供给脑机接口设备的库中的代码进行解读。这一篇是关于Markers的解读。
使用设备:openBCI
使用软件:openBCI Hub + openBCI GUI v5.1.0, Pycharm
使用文件:自己使用CYTON_BOARD生成的数据文件
使用语言:Python
因为看官方文档时看的都是英文,所以注释也使用英文写了,如有疑问可以交流。
代码原型参考这个网址。
在接下来的代码中,只有一个“#”的注释是官方原有的注释,有两个“#”的注释是我个人添加的注释。
## author: Mocode
## create time: 2023-01-12
## update time: 2023-03-13
## purpose:
## Insert markers into an existing file which recorded data from openBCI (SYNTHETIC_BOARD).
## Use "PLAYBACK_FILE_BOARD" to complete this task.
## (Symbol '!' has been used to marked key functions after "##" in this program)
import argparse
import time
# from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds, BrainFlowPresets
## UPDATE, "BrainFlowPresets" is not needed in this program
## UPDATE, "BoardIds" is not needed either, since we can use an Integer to represent a borad
## In this program, according to DOCS(https://brainflow.readthedocs.io/en/stable/UserAPI.html#brainflow-board-shim), we use "-1" to represent "BoardIds.SYNTHETIC_BOARD"
from brainflow.board_shim import BoardShim, BrainFlowInputParams
def main():
BoardShim.enable_dev_board_logger() ## You can comment this line to ignore the output of log.
## Set parameters
parser = argparse.ArgumentParser()
# use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port
## The lines I comment are useless argument for "PLAYBACK_FILE_BOARD", according to DOCS
# parser.add_argument('--timeout', type=int, help='timeout for device discovery or connection', required=False,
# default=0)
# parser.add_argument('--ip-port', type=int, help='ip port', required=False, default=0)
# parser.add_argument('--ip-protocol', type=int, help='ip protocol, check IpProtocolType enum', required=False,
# default=0)
# parser.add_argument('--ip-address', type=str, help='ip address', required=False, default='')
# parser.add_argument('--serial-port', type=str, help='serial port', required=False, default='')
# parser.add_argument('--mac-address', type=str, help='mac address', required=False, default='')
# parser.add_argument('--other-info', type=str, help='other info', required=False, default='-1')
# parser.add_argument('--serial-number', type=str, help='serial number', required=False, default='')
parser.add_argument('--board-id', type=int, help='board id, check docs to get a list of supported boards',
required=True)
## For "--board-id", since "required" is set to "True", this parameter cannot use "default" to set.
## Instead, Add it in "Configuration" of Pycharm. See this blog for guidance: https://blog.csdn.net/counte_rking/article/details/78837028?spm=1001.2014.3001.5506
parser.add_argument('--file', type=str, help='file', required=False, default='.../Recordings/OpenBCISession_.../BrainFlow-RAW_....csv') ## Change the "default" content to the route of your file.
## For "--file", the route of ".csv" file is needed, not ".txt" file, though they are saved in the same folder.
parser.add_argument('--master-board', type=int, help='master board id for streaming and playback boards',
required=False, default=-1) ## Since the file in argument '--file' is recorded use CYTON Board, I set the default to '-1', which represents the id of this board.
# parser.add_argument('--preset', type=int, help='preset for streaming and playback boards',
# required=False, default=BrainFlowPresets.DEFAULT_PRESET)
args = parser.parse_args()
## Initialize
params = BrainFlowInputParams()
## The lines I comment are useless argument for "PLAYBACK_FILE_BOARD", according to DOCS.
# params.ip_port = args.ip_port
# params.serial_port = args.serial_port
# params.mac_address = args.mac_address
# params.other_info = args.other_info
# params.serial_number = args.serial_number
# params.ip_address = args.ip_address
# params.ip_protocol = args.ip_protocol
# params.timeout = args.timeout
params.file = args.file
params.master_board = args.master_board
# params.preset = args.preset
board = BoardShim(args.board_id, params)
## Start to record data
board.prepare_session()
board.start_stream()
for i in range(10):
time.sleep(1) ## Let the data stream "sleep" for a second, so that the "buffer" of the stream can store some data, which will be processed by you.
board.insert_marker(i + 1) ## ! After using this function, the "marker" channel of the data in this moment will be filled with the number you set.
## More codes to observe how the "insert_marker" function works.
print(i)
data = board.get_board_data() ## Now get all data and remove it from internal buffer.
marker_channel = BoardShim.get_marker_channel(args.master_board) ## ! This function get the index of "marker" channel of the data.
# print("marker_channel: {}".format(marker_channel)) ## In the file I use, the output is "marker_channel: 31".
data_marker = data[marker_channel] ## Get the data of "marker" channel.
print(data_marker)
## When "i == 0", you maynot see anything different.
## But when "i > 0", you will see the marker you insert into the stream appearing in the first data point in the outpur.
# data = board.get_board_data()
board.stop_stream()
board.release_session()
if __name__ == "__main__":
main()