Skip to content

Commit 81810ae

Browse files
authored
Merge pull request #91 from Ergo-Tools/next-version
ActiPASS Version 2024.06.1 (2024-06-04)
2 parents 449b6f2 + 721194a commit 81810ae

File tree

1 file changed

+57
-21
lines changed

1 file changed

+57
-21
lines changed

utils/readGenericCSV.m

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
function [Data, SF, deviceID] = readGenericCSV(PATH)
2+
function [Data, SF, deviceID, devType] = readGenericCSV(PATH)
33
% readGenericCSV Read generic CSV files with specified format and ISO8601 timestamp
44
%
55
%
@@ -13,22 +13,34 @@
1313
% The acceleration axis must conform to the standard ActiPASS AX3
1414
% orientation (i.e. x-axis pointing down, z-axis inwards towards skin).
1515
%
16-
% The first four lines in the CSV file must contain the
17-
% deviceID (only numeric), the sampling frequency, start-time and the column names.
18-
% ID=<numeric devideID> (e.g. 'ID=34567850')
19-
% SF=<sampling frequency> (e.g. 'SF=50')
20-
% START=<start time in ISO8601 format> (e.g. 'START=20240301T154517.250')
21-
% x, y, z
16+
% The first lines in the CSV file must contain the:
17+
% * deviceID (only numeric)
18+
% * the sampling frequency (numeric)
19+
% * start-time (ISO8601 format)
20+
% * optional device-type. Allow device-type specific changes to algorithms. See supported device-types below
21+
% * and the column names x, y, and z.
22+
%
23+
% See example header lines and first data line below
24+
%
25+
% ID=34567850
26+
% DevType=Axivity
27+
% SF=50
28+
% START=20240301T154517.250
29+
% x,y,z
2230
%
2331
% Remarks:
2432
% 1. To improve performance and to reduce file sizes a seperate time column is excluded.
2533
% 2. Consequently, only supports data which are resampled to a fixed sampling frequency.
34+
%
35+
% Supported Device type strings:
36+
% Axivity, ActivPAL3, ActivPAL4, Actigraph, SENS, Movisens
2637
%
2738
%
2839
% Output:
2940
% Data [Nx4] datetime (Matlab datenum format) and 3D acceleration data
3041
% SF [double] the sample frequency
3142
% deviceID [double] the device ID
43+
% devType [string] the device type. Set to "Generic" if not specified in CSV file
3244

3345
% Copyright (c) 2024, Claas Lendt & Pasan Hettiarachchi
3446
% All rights reserved.
@@ -59,31 +71,55 @@
5971
Data = [];
6072
SF = NaN;
6173
deviceID = NaN;
74+
devType="";
6275

6376
try
77+
6478
% Open the file once and keep it open for reading both metadata and data
6579
fileID = fopen(PATH, 'r');
6680

67-
% Read the first three lines for metadata and start-time
68-
idLine = fgetl(fileID);
69-
sfLine = fgetl(fileID);
70-
startLine = fgetl(fileID);
81+
% a string array to store header lines
82+
headLs=strings(10,1);
83+
headerFound=false;
7184

72-
% read the column header line
73-
headL=fgetl(fileID);
74-
75-
% Extract ID and SF values using correct indexing
76-
deviceID = extractBetween(idLine,textBoundary+"ID=",textBoundary);
77-
SF = extractBetween(sfLine,textBoundary+"SF=",textBoundary);
85+
% Read first few (max 10) lines for metadata and start-time (read max 10 lines)
86+
for itr=1:10
87+
headLs(itr)=fgetl(fileID);
88+
% if the axes header line is found we have reached end of header lines
89+
if matches(headLs(itr),["x,y,z","x, y, z"],'IgnoreCase',true)
90+
headerFound=true;
91+
break;
92+
end
93+
end
7894

79-
% find the start time. If this fails function will return
80-
startT=datenum(extractBetween(startLine,textBoundary+"START=",textBoundary),'yyyymmddTHHMMSS.FFF');
95+
if ~headerFound
96+
error("unrecognized generic CSV format");
97+
end
98+
99+
row_DevID = startsWith(headLs,"ID=",'IgnoreCase',true);
100+
row_SF = startsWith(headLs,"SF=",'IgnoreCase',true);
101+
row_startT = startsWith(headLs,"START=",'IgnoreCase',true);
102+
row_devtype = startsWith(headLs,"DevType=",'IgnoreCase',true);
81103

82-
% check for file-validity by checking for DeviceID and SF
83-
if isempty(deviceID) || isempty(SF) || isempty(startT) || ~matches(headL,["x,y,z","x, y, z"],'IgnoreCase',true)
104+
% check for file-validity by checking for DeviceID and SF
105+
if isempty(headLs(row_DevID)) || isempty(headLs(row_SF)) || isempty(headLs(row_startT))
84106
error("unrecognized generic CSV format");
85107
end
86108

109+
% if a device-type header line found use it, otherwise set devType to "generic"
110+
if ~isempty(headLs(row_devtype))
111+
devType=extractBetween(headLs(row_devtype),textBoundary+"DevType=",textBoundary);
112+
else
113+
devType="Generic";
114+
end
115+
116+
% Extract ID and SF values using correct indexing
117+
deviceID = extractBetween(headLs(row_DevID),textBoundary+"ID=",textBoundary);
118+
SF = extractBetween(headLs(row_SF),textBoundary+"SF=",textBoundary);
119+
120+
% find the start time. If this fails function will return
121+
startT=datenum(extractBetween(headLs(row_startT),textBoundary+"START=",textBoundary),'yyyymmddTHHMMSS.FFF');
122+
87123
% convert SF and DeviceID to numbers (ActiPASS only supports numeric device serial-numbers)
88124
SF=str2double(SF);
89125
deviceID=str2double(deviceID);

0 commit comments

Comments
 (0)