function varargout=jv_genea_120119(varargin) %Reading GENEActive (http://www.geneactiv.co.uk/) binary files % Returning int16/int8 data structure % .x .y .z uncalibrated acceleration values, when reading watch % .light x is up, y is right, z toward wrist % .marker % % .time contains Matlab datenum points, -693960 for Excel % date/time % % .time only once in 300 datapoint block % .temperature % .battery % % Versions: % 120119 calibrate returns single precision values and also time % field % 120117 corrected number of pages, calibration, close file, light % marker. % 120116 first version, tested with model 1.1m firmware 1.30 % % Examples: % genea=@jv_genea_120117; % data=genea('tst.bin'); %read all blocks % data=genea('tst.bin',1); % data=genea('tst.bin',0:data.pages-1) % data=genea('tst.bin',1200); %read every 1200th block % data=genea('tst.bin',0:99); %read first 100 blocks % data=genea('tst.bin',0); %read only first block % % xyz=genea(data); %calibrate % xyz=genea(data,100); %calibrate, every 100th sample % % plot(xyz.time,xyz.x); % datetick('keeplimits'); % xlim([xyz.t(1)+12/24 xyz.t(1)+24/24]); % datetick('keeplimits'); % % References % Based on geneactiv_instruction_manual_v1.1.pdf % jussi.virkkala@ttl.fi @neuroupdate.com %%main part file=varargin{1}; if nargin<2, index=1; else index=varargin{2}; end if isstruct(file), data=calibrate(file,index); else data=read(file,index); end varargout{1}=data; %%Calibrate %2012-01-19 Returning single precision, also time function xyz=calibrate(g,index); if length(index)==1, index=1:index:length(g.x); end %2012-01-18 single %2012-01-17 corrected )*100 xyz.x=(single(g.x(index))*100-g.x_offset)/g.x_gain; xyz.y=(single(g.y(index))*100-g.y_offset)/g.y_gain; xyz.z=(single(g.z(index))*100-g.z_offset)/g.z_gain; xyz.light=(single(g.light(index))*g.lux)/g.volts; xyz.time=(index-1)'/24/3600/g.rate+g.time(1); %%Reading data function g=read(file,index); f=fopen(file,'r'); e=~feof(f); while e, r=fgetl(f); if r==-1,r='';end %last one -1 e=~feof(f); i=findstr([r ':'],':'); switch(r(1:i(1)-1)), case 'Device Identity', g.device_identity=r; for i=2:6,g.device_identity=str2mat(g.device_identity,fgetl(f));end case 'Device Capabilities', g.device_capabilities=r; for i=2:10,g.device_capabilities=str2mat(g.device_capabilities,fgetl(f));end case 'Configuration Info', g.configuration=r; for i=2:5,g.configuration=str2mat(g.configuration,fgetl(f));end case 'Trial Info', g.trial=r; for i=2:11,g.trial=str2mat(g.trial,fgetl(f));end case 'Subject Info', g.subject_info=r; for i=2:9, r=fgetl(f); if i==2,g.location=r(22:end);end if i==3,g.subject=r(14:end);end g.subject_info=str2mat(g.subject_info,r); end case 'Calibration Data', %x gain:25576 r=fgetl(f);g.x_gain=eval(r(8:end)); %x offset:694 r=fgetl(f);g.x_offset=eval(r(10:end)); %y gain:25813 r=fgetl(f);g.y_gain=eval(r(8:end)); %y offset:-407 r=fgetl(f);g.y_offset=eval(r(10:end)); %z gain:25421 r=fgetl(f);g.z_gain=eval(r(8:end)); %z offset:-2102 r=fgetl(f);g.z_offset=eval(r(10:end)); %Volts:300 r=fgetl(f);g.volts=eval(r(7:end)); %Lux:800 r=fgetl(f);g.lux=eval(r(5:end)); case 'Memory Status', %Number of pages: r=fgetl(f); np=eval(r(17:length(r))); g.pages=np; if length(index)==1, if index, %2012-01-17 (np-1) index=0:index:(np-1); end end g.x=zeros(length(index)*300,1,'int16'); g.y=g.x; g.z=g.x; g.light=g.x; g.marker=zeros(length(index)*300,1,'uint8'); g.battery=zeros(length(index),1); g.time=g.battery; g.temperature=g.time; g.serial=''; g.rate=0; cp=0; cpd=-1; case 'Recorded Data', %skip data blocks while cpcpd,disp(['...' r]);cpd=cpd+1200;end %Unassigned: r=fgetl(f); %Temperature:30.1 r=fgetl(f); g.temperature(cp)=eval(r(13:end)); %Battery voltage:4.2090 r=fgetl(f); g.battery(cp)=eval(r(17:end)); %Device Status:Recording fgetl(f); %Measurement Frequency:100.0 r=fgetl(f); g.rate=eval(r(23:end)); %300 measurements*6*2 hex=fgetl(f); cpi=[cp*300-299:cp*300]; dec=hex2dec(reshape(hex,2,1800)'); mat=reshape(dec,6,300)'; %x, 12 bit x=bitshift(mat(:,1),4)+bitshift(mat(:,2),-4); g.x(cpi)=bitand(x,2047)-bitand(x,2048); %y, 12 bit y=bitshift(mat(:,2),8)+mat(:,3); g.y(cpi)=bitand(y,2047)-bitand(y,2048); %z, 12 bit z=bitshift(mat(:,4),4)+bitshift(mat(:,5),-4); g.z(cpi)=bitand(z,2047)-bitand(z,2048); %light 0-1024 %2012-01-17 (cpi) g.light(cpi)=bitshift(bitand(mat(:,5),15),2)+bitshift(mat(:,6),-2); if find(g.light(cpi)<0);errordlg('Light level should non negative');end %marker button %2012-01-17 (cpi) g.marker(cpi)=bitand(mat(:,6),3); if find(g.marker(cpi)==1),errodlg('Last reserved bit should be zero');end index=index(2:end); if isempty(index), e=0; end end end %2012-01-17 closing file fclose(f); %end