2
2
Function utilities to convert data acquired on an OpenBCI
3
3
Cyton board using the SD card logging strategy.
4
4
5
- TODO: We should look into optimizing this conversion. We currently
6
- convert one line at a time, while a vectorized approach would be much more efficient,
7
- as the conversion of a line does not depend on the other lines.
8
5
TODO: Consider cropping file (from bed to wake up time) here, before the for loop. Have to consider
9
6
not all lines hold sample values (i.e. first line with comment and second line with a single timestamp).
10
7
17
14
from mne import create_info
18
15
from mne .io import RawArray
19
16
import numpy as np
17
+ import pandas as pd
20
18
21
19
from classification .exceptions import ClassificationError
22
20
from classification .config .constants import (
@@ -41,16 +39,19 @@ def get_raw_array(file):
41
39
Returns:
42
40
- mne.RawArray of the two EEG channels of interest
43
41
"""
44
- lines = file .readlines ()
45
- eeg_raw = np .zeros ((len (lines ) - SKIP_ROWS , len (EEG_CHANNELS )))
46
42
47
- for index , line in enumerate (lines [SKIP_ROWS :]):
48
- line_splitted = line .decode ('utf-8' ).split (',' )
43
+ retained_columns = tuple (range (1 , len (EEG_CHANNELS ) + 1 ))
49
44
50
- if len (line_splitted ) < CYTON_TOTAL_NB_CHANNELS :
51
- raise ClassificationError ()
45
+ try :
46
+ eeg_raw = pd .read_csv (file ,
47
+ skiprows = SKIP_ROWS ,
48
+ usecols = retained_columns
49
+ ).to_numpy ()
50
+ except Exception :
51
+ raise ClassificationError ()
52
52
53
- eeg_raw [index ] = _get_decimals_from_hexadecimal_strings (line_splitted )
53
+ hexstr_to_int = np .vectorize (_hexstr_to_int )
54
+ eeg_raw = hexstr_to_int (eeg_raw )
54
55
55
56
raw_object = RawArray (
56
57
SCALE_V_PER_COUNT * np .transpose (eeg_raw ),
@@ -71,38 +72,11 @@ def get_raw_array(file):
71
72
return raw_object
72
73
73
74
74
- def _get_decimals_from_hexadecimal_strings (lines ):
75
- """Converts the array of hexadecimal strings to an array of decimal values of the EEG channels
76
- Input:
77
- - lines: splitted array of two complement hexadecimal
78
- Returns:
79
- - array of decimal values for each EEG channel of interest
80
- """
81
- return np .array ([
82
- _convert_hexadecimal_to_signed_decimal (hex_value )
83
- for hex_value in lines [FILE_COLUMN_OFFSET :FILE_COLUMN_OFFSET + len (EEG_CHANNELS )]
84
- ])
85
-
86
-
87
- def _convert_hexadecimal_to_signed_decimal (hex_value ):
88
- """Converts the hexadecimal value encoded on OpenBCI Cyton SD card to signed decimal
89
- Input:
90
- - hex_value: signed hexadecimal value
91
- Returns:
92
- - decimal value
93
- """
94
- return _get_twos_complement (hex_value ) if len (hex_value ) % 2 == 0 else 0
95
-
96
-
97
- def _get_twos_complement (hexstr ):
75
+ def _hexstr_to_int (hexstr ):
98
76
"""Converts a two complement hexadecimal value in a string to a signed float
99
77
Input:
100
78
- hex_value: signed hexadecimal value
101
79
Returns:
102
80
- decimal value
103
81
"""
104
- bits = len (hexstr ) * 4
105
- value = int (hexstr , 16 )
106
- if value & (1 << (bits - 1 )):
107
- value -= 1 << bits
108
- return value
82
+ return int .from_bytes (bytes .fromhex (hexstr ), byteorder = 'big' , signed = True )
0 commit comments