%% Human Activity Labeling
% This example shows how to label human activity using triaxial acceleration data.
%% Introduction
%
% The original dataset is available from the UCI Machine Learning Repository. The dataset is available courtesy of Davide Anguita, Alessandro Ghio, Luca Oneto, Xavier Parra and Jorge L. Reyes-Ortiz. "A Public Domain Dataset for Human Activity Recognition Using Smartphones." 21st European Symposium on Artificial Neural Networks, Computational Intelligence and Machine Learning, ESANN 2013. Bruges, Belgium 24-26 April 2013. The authors modeled the dataset using machine learning algorithms in "Human Activity Recognition on Smartphones Using a Multiclass Hardware-Friendly Support Vector Machine".
%
% The data was collected from 30 subjects between ages 19 and 48, performing one of the following activities: Walking, Walking Upstairs, Walking Downstairs, Sitting, Standing and Laying. Each subject performed these activities while wearing a waist-mounted smartphone to record the movement data.
% The data recorded includes the linear acceleration in x,y and z directions, and the triaxial gyroscopic data (angular velocity). The observations were recorded at a 50 Hz frequency.
%
% A pre-processed version of the dataset was made available by the authors. The pre-processing steps implemented were as follows:
% Pre-processing accelerometer and gyroscope using noise filters.
% Splitting data into fixed windows of 2.56 seconds (128 data points) with 50% overlap.
% Splitting of accelerometer data into gravitational (total) and body motion components.
% Feature extraction was performed on the windowed data, and a copy of the data with these engineered features was made available.
% The training dataset comprises of data from 70% of the subjects, whereas the test dataset contains data from the remaining 30%.
%
% Unzipping creates the folder UCI HAR Dataset in your temporary directory. This folder contains the text file README.txt and the following files:
% activity_labels.txt
% features.txt
% features_info.txt
% The folders train and test contain the training and test data sets respectively. The train and test folders have similar contents. Specifically, both folder contain a subfolder called Inertial Signals that contains the preprocessed data. Additionally they also contain X_Train.txt (X_Test.txt for the test folder) which contains the extracted features. The file y_Train.txt (y_Test.txt for the test folder) contains the class labels (ranging from 1–6) for each observation.
%
% The folder Inertial Signals under train contains the following nine files:
% total_acc_x_train.txt, total_acc_y_train.txt, total_acc_z_train.txt: Gravitational acceleration data from the smartphone accelerometer axes in standard gravity units 'g'.
%  body_acc_x_train.txt, body_acc_y_train.txt, body_acc_z_train.txt: Body acceleration data obtained by subtracting the effect of gravity from total acceleration
%  body_gyro_x_train.txt, body_gyro_y_train.txt, body_gyro_z_train.txt: Body gyroscope data or the angular velocity vector measured by the gyroscope for each window sample.
% The folder Inertial Signals under test has a similar structure.
%
% The function used to prepare the data reads the total acceleration data in the original Human Activity Recognition dataset, re-organizes it and saves it in a new set of MATLAB data (.mat) files. The first step is to download these .mat files from the GitHub repository. To download the data, click Clone or download and select Download ZIP. Save the file Human-Activity-Labeling-master.zip in a folder where you have write permission. The instructions for this example assume you have downloaded the file to your temporary directory, (tempdir in MATLAB). Modify the subsequent instructions for unzipping and loading the data if you choose to download the data in folder different from tempdir. If you are familiar with Git, you can download the latest version of the tools (git) and obtain the data from a system command prompt using git clone https://github.com/upasanaclemson/Human-Activity-Labeling.

unzip(fullfile(tempdir,'Human-Activity-Labeling-master.zip'),tempdir)

% Unzipping the file Human-Activity-Labeling-master.zip creates a folder zip with the following .mat files:
% BufferFeatures.mat
% BufferedAccelerations.mat
% RecordedAccelerationsBySubject.mat
% In addition, the function used to prepare the data and its helper functions are also available in this .zip file.
% The file BufferFeatures.mat contains the set of feature vectors (feat) and cell array of feature names (featlabels). BufferedAccelerations.mat loads buffered sigs using only known activity IDs for buffers. RecordedAccelerationsBySubject.mat contains the triaxial acceleration data for each individual subject.
%

clear
load(fullfile(tempdir,'Human-Activity-Labeling-master','RecordedAccelerationsBySubject.mat'))
load(fullfile(tempdir,'Human-Activity-Labeling-master','BufferedAccelerations.mat'))

%
% Use a custom function to retrieve all three total acceleration components for each subject. Also retrieve the signal IDs corresponding to the specific activities and the length of acceleration data for each subject. Set 'AccelerationType' to 'bodyacc' to remove the effects of gravity.

ns = numel(subjects);
sig = cell(1,ns);
sigId = cell(1,ns);
tCell = cell(1,ns);
for nsub = 1:ns
    [acc, actid, t] = getRawAcceleration('SubjectID',nsub,...
        'Component','xyz');
    sig(:,nsub) =  {acc};
    sigId(:,nsub) = {actid};
    tCell(:,nsub) = {t};
end

%
% Create an empty array of signalLabelDefinition objects.
% Define the signal labels to attach to the signal. The label type is region-of-interest (ROI) that captures the activity type of the subject. The labels are named after the six activities specified in the variable actnames.

lblDefinitions = signalLabelDefinition.empty([numel(actnames),0]);
for i = 1:numel(actnames)
    lblDefinitions(i) = signalLabelDefinition(actnames{i},...
        'LabelType','roi',...
        'LabelDataType','string',...
        'Description','Activity type');
end

%
% Create a labeledSignalSet with number of members equal to the number of subjects. The members of the labeledSignalSet correspond to the triaxial acceleration data of each subject. Get the names of the labels in the set.

lss = labeledSignalSet(sig,lblDefinitions,...
    'TimeValues',tCell,'Description','Characterize activity');

%
% For each labeled signal, set the value of the labels based on the activity id. Find the points where the activity id of the signal changes, and label that part of the signal using the corresponding activity name.

idx = 0;
for nId = 1:lss.NumMembers
    
    accsigId = cell2mat(sigId(nId));
    tVal = cell2mat(tCell(nId));
    accsig =  cell2mat(sig(nId));
    
    
    
    fhp = hpfilter;
    ab = filter(fhp,accsig);
    
    ipt = findchangepts(accsigId,'MaxNumChanges',20,'Statistic','linear');
    t = [tVal(1) tVal(ipt)' tVal(end)];
    
    for jk = 1:numel(t)-1
        
        tId = t(jk)+0.02*(jk~=1);
        tReg(jk,:) = {tVal(tVal >= tId & tVal <= t(jk+1))};
        actReg(jk) = unique(accsigId(tVal >= tId & tVal <= t(jk+1)-1));
        XData(idx+jk,:) = {[accsig(tVal>=tId & tVal<=t(jk+1)-1,:)]'};
        YData(idx+jk,:) = unique(actReg(jk));
        setLabelValue(lss,nId,actnames{actReg(jk)},[tReg{jk}(1) tReg{jk}(end)],actnames{actReg(jk)});
    end
    idx = idx+jk;
end

%
% Start Signal Analyzer and drag the labeled signal set to the Signal table. Click Label on the Analyzer tab and pick a random member of the labeled signal set. To visualize the triaxial acceleration data,  check the box next to the signal name. Select all three signals for the given member. The ROIs are labeled with the activity names
%
%
%
% hpfilter designs a highpass filter using designfilt to filter out the effects of gravitation.
% getRawAcceleration helps retrieve acceleration data from relevant file. Input arguments need to be Name,Value pairs. Acceptable names are
% – SubjectID: Subject ID, ranging from 1 to 30
% – AccelerationType: Acceleration type, as a choice between 'total' and 'body' (with gravity contributions filtered out)
% – Component: Coordinate name, as a choice between 'x', 'y', 'z', or 'xyz'.

function Hd = hpfilter
Hd = designfilt('highpassiir','PassbandFrequency',0.8,'StopbandFrequency',0.4,...
    'SampleRate',50,'StopbandAttenuation',60,'PassbandRipple',1,...
    'DesignMethod','cheby2','MatchExactly','passband');
end

function [acc, actid, t, fs] = getRawAcceleration(varargin) %#ok<STOUT>

% Copyright 2014-2015 The MathWorks, Inc.

load(fullfile(tempdir,'Human-Activity-Labeling-master','RecordedAccelerationsBySubject.mat'))


p = inputParser;

defaultAccelerationType = 'total';
validAccelerationTypes = {'total','body'};
checkAccelerationType = @(x) any(validatestring(x,validAccelerationTypes));

defaultSubject = 1;

defaultComponent = 'x';
validComponents = {'x','y','z','xyz'};
checkComponent = @(x) any(validatestring(x,validComponents));

addParameter (p,'SubjectID',defaultSubject,@(x) x > 0 && x <= length(subjects));
addParameter (p,'AccelerationType',defaultAccelerationType,checkAccelerationType)
addParameter (p,'Component',defaultComponent,checkComponent)

parse(p,varargin{:})

subid = p.Results.SubjectID;
switch p.Results.AccelerationType
    case 'total', type = 'totalacc';
    case 'body', type = 'bodyacc';
end
switch p.Results.Component
    case 'x', component = 1;
    case 'y', component = 2;
    case 'z', component = 3;
    case 'xyz', component = [1 2 3];
end

acc = subjects(subid).(type)(:,component);
actid = subjects(subid).actid;
t = (1/fs) * (0:length(acc)-1)';
end

% Copyright 2018 The MathWorks, Inc.