%Simple analog diaplay
clear all;
clc; 
daqreset;

%define the input
adaptor = 'nidaq'; %defining adaptor as NIDAQ
adaptorData = daqhwinfo(adaptor); % data collected from adaptor defined as NIDAQ
id = adaptorData.InstalledBoardIds{1} ; 
Fs = 2500; %sampling frequency

% Analog input object Configuration.
% Create an analog input object with two channels.
ai = analoginput(adaptor, id); %analong input from NIDAQ
addchannel(ai, [0 1 2 3]);%four channel input

% Configure for single-ended input
set(ai, 'InputType', 'SingleEnded'); %single ended input

% Configure the analog input rate.
sr = 2500; %sampling rate
set(ai, 'SampleRate', sr); %sampling rate of 2500 samples per second
%collects data every second (Fs/sr) = 1

% Configure the analog input object to trigger manually.
set(ai, 'SamplesPerTrigger', Fs); % samples ever 1/2500 second for 1 second
set(ai, 'TriggerRepeat', 1);%one trigger at a time
set(ai, 'TriggerType', 'manual'); %data collection occurs by manually calling getdata for each trigger

freq = 1.1; %frequency of bioimpedence input square wave
hgt = 178; % default height in centimeters
age = 22; %default age in years
weight = 70;  % default weight in kg
sex = 1; %default sex (where male = 1, and female =0)
tbw = 60; tbw_bi = 60; %default hydration values
body_fat = 12; body_fat_bi = 12; %default body fat values

dt = 4e-4;
maxt = 1; %one second
time = 0:dt:maxt; %time vector
n = 2501; %number of points plotted at a time

%define the stop button
stopbutton=uicontrol('style','pushbutton',... %pushbutton to stop program
   'string','Stop', ... %button says stop
   'fontsize',12, ...%button says stop in size 12 font
   'position',[0 0 50 20], ...%button is in bottom left corner
   'callback','stopit=1;');%callback used to cause program to stop when "Stop" button  is pressed
     

%display text before total body water display
uicontrol('style','text',...%text
   'string','total body water=',...%text says total body water= before display
   'fontsize',12, ...%button says stop in size 12 font
   'position',[60,30,120,20]); %text at bottom a little to the right and above the stop button

%define updating display for the tbw determined by optical method
hdisp = uicontrol('style','text',... 
    'fontsize',12,...
    'position',[200 30 40 20],...%text at bottom a little to the right of the total body water text
    'String', num2str(tbw));%update to value that tbw is defined as whenever tbw is defined

%define updating display for the tbw determined by bioimpedence
 hdisp2 = uicontrol('style','text',...
    'fontsize',12,...
    'position',[350 30 40 20],...%text at bottom a little to the right of the optically determined total body water 
    'String', num2str(tbw_bi)); %update to value that tbw is defined as whenever tbw is defined
     

%display text before body fat displays
uicontrol('style','text',...%text 
   'string','body fat=',...%text saying body fat= before display
   'fontsize',12, ...%text in size 12 font
   'position',[60,0,100,20]); %text at bottom a little to the right of the stop button

%define updating display for body fat value determined optically
fdisp = uicontrol('style','text',...%text
    'fontsize',12,...%size 12
    'position',[200 0 80 20],... %display at bottom a little to the right of body fat text
    'String', num2str(body_fat));%update value that body_fat is defined as whenever it is defined

%define updating display for body fat value determined by bioelectric
%impedence
 fdisp2 = uicontrol('style','text',...%text
    'fontsize',12,...%size 12
    'position',[350 0 80 20],...%display at bottom a little to the right of the optically determined body fat value
    'String', num2str(body_fat_bi));%update value that body fat is defined as whenever it is define

%define text before age input
uicontrol('style','text',...%text
   'string','age (years)=',...%text says "age (years)=" before input box
   'fontsize',12, ...%size 12
   'position',[500,60,50,20]); %3 lines up on right side of GUI

%define editable text box for age
old = uicontrol('style','edit',...%editable text
    'fontsize',12,...%size 12
    'position',[1000 60 80 20],...%box is 3 lines up on right side of age text
    'String', num2str(age)); %takes in number inputed as variable age

%define text before height input
uicontrol('style','text',...%text
   'string','height(cm)=',...%text says "height (cm)=" before input box
   'fontsize',12, ...%size 12
   'position',[500,30,100,20]); %3 lines up on right side of GUI

%define editable text box for height
tall = uicontrol('style','edit',...%editable text
    'fontsize',12,... %size 12
    'position',[1000 30 80 20],... %box is 2 lines up on right side of height text
    'String', num2str(hgt)); %takes in number inputed as variable height

%define text before weight input
uicontrol('style','text',...%text
   'string','weight (kg)=',...%text says "weight (kg)=" before input box
   'fontsize',12, ... %size 12
   'position',[500,0,180,20]);%last line on right side of GUI

%define editable text box for height
fat = uicontrol('style','edit',...%editable text
    'fontsize',12,...%size 12
    'position',[1000 0 80 20],...%box is on last line on right side of height text
    'String', num2str(weight));%takes in number inputed as variable weight

%define text before gender input
uicontrol('style','text',...%text
   'string','gender (M/F)=',...%text that says "gender (M/F)=" before the radiobuttons
   'fontsize',12, ...%size 12
   'position',[500,90,180,20]); %text is 4 lines up from bottom on right side GUI

 %define radiobutton for male option
 gender = uicontrol('style','radiobutton',...
    'fontsize',12,...
    'position',[900 90 80 20],...
    'String',   'M', ...
     'Value',    1,...
     'HandleVisibility','off');
%define radiobutton for female option
 gender2 = uicontrol('style','radiobutton',...
    'fontsize',12,...
    'position',[1000 90 80 20],...
    'String',   'F', ...
     'Value',    0,...
     'HandleVisibility','off');

 
%Main event loop
stopit=0; %wait for a stop button push

% Object Execution.
% Start the analog input object.
sample = zeros(1,n); %initial square wave input sample signal set to zero
actual = zeros(1,n);%initial actual between electrodes sample signal set to zero
ir = zeros(1,n); %initial IR current signal set to zero
ref = zeros(1,n); %initial current from emitter of BJT signal set to zero


%main program loop
while (stopit==0)

%and draw it 
drawnow

    %start data collection and trigger it
    start(ai); 
    trigger(ai); 
    
    % Obtain the available time and data as stime and asample respectively
     [asample, stime] = getdata(ai, ai.SamplesPerTrigger);
      
    %stop data collection
     stop(ai); 
     
    
  
    sample(1,(n-(n-2):end)) = asample(:,1)'; %write new sample collected
    actual(1,(n-(n-2):end)) = asample(:,2)'; %write new actual sample between electrodes collected
    ir(1, (n-(n-2):end)) = asample(:,3)'; %write new IR optical current collected
    ref(1, (n-(n-2):end)) = asample(:,4)'; %write new reference current collected



    hgt= get(tall,'string'); %get height inputed in the GUI 
    weight= get(fat,'string');%get weight inputed in the GUI 
    age= get(old,'string');%get age inputed in the GUI 
    sex= get(gender,'Value');%get gender inputed in the GUI; value as binary
    
 
    hgt=str2double(hgt); %convert string to double before using
    weight=str2double(weight);%convert string to double before using
    age=str2double(age);%convert string to double before using
    
    
    %bioimpedence calculations
    s = n/2; %half of length of vector used to find mangintude of rise or fall
    a= max((actual(n-s:end))); %max point 
    b= find(actual ==a); %find index of max point
    c= min((actual(n-s:end)));%minimum point
    d = find(actual ==c); %find index of min point
    
        b = b(1,length(b));  %use last value in case multiple indicies have same max value
        d = d(1,length(d)); %use last value in case multiple indicies have same min value
        
    magnitude = abs(actual(b) - actual(d)) %find magnitude by subtracting the max value from the min value
    m = .632*magnitude; %find 0.632 of the magnitude before finding tau
    m2 = c +m; %add magnitude of 0.632 of whole magnitude to min to find value at 0.632 of magnitude
    [val,ind] = min(abs(actual(s:end) - (m2.*ones(1,s+1))))   %find closest index to 0.632 of magnitude
    ind = ind + s;  %put index in context of n, not s
    if(b>d)
        m2 = c +m; %add magnitude of 0.632 of whole magnitude to min to find value at 0.632 of magnitude when rising
        [val,ind] = min(abs(actual(s:end) - (m2.*ones(1,s+1))))   %find closest index to 0.632 of magnitude
        ind = ind + s;  %put index in context of n, not s
        tau = abs((b-ind)./(Fs)); %find tau if rising
    else
        m2 = a -m; %subtract magnitude of 0.632 of whole magnitude from max to find value at 0.632 of magnitude when falling
        [val,ind] = min(abs(actual(s:end) - (m2.*ones(1,s+1))))   %find closest index to 0.632 of magnitude
        ind = ind + s;  %put index in context of n, not s
        tau = abs((d-ind)./(Fs)); %find tau of falling
    end
    %ideally tau would be necessary for taking into account capacitance in
    %impedence, but for the purposes of this study, only resistance was
    %used
    
     curr = 0.2/100000; %current, 100k resistor used
     resis = magnitude./(curr) %resistance found using magnitude calculated divided by current


    hyd_coeff = [    0.8339    6.6941    0.3769   -0.4107   12.6142]; %coefficients for tbw calculated using mvregress and resistance with pateint parameters as inputs
    fat_coeff = [   0.2748  -13.1645   -0.0748    0.4350  -13.1485];%coefficients for body fat calculated using mvregress and resistance with pateint parameters as inputs
    
    
    tbw_bi =  hyd_coeff(1)*age + hyd_coeff(2)*(hgt.^2/resis) + hyd_coeff(3)*hgt + hyd_coeff(4)*weight + hyd_coeff(5)*sex %calculation of percent total body water using coefficients 

    body_fat_bi =  fat_coeff(1)*age + fat_coeff(2)*(hgt.^2/resis) + fat_coeff(3)*hgt + fat_coeff(4)*weight + fat_coeff(5)*sex %calculation of percent body fat using coefficients 


   % optical current
    curr_opt = ir./100;  



    sig = abs(mean(curr_opt)); %optical current detected by photosensor
    r = mean(ref./200); %reference current at emitter of transistor
    i = sig/r %ratio of currents
    l = log(1/i); %log of recip of ratio of currents
    
    hyd_coeff2 = [ 0.6986 ; 0.4140; -0.4919; 14.6143; 2.6389]; %coefficients for tbw calculated using mvregress and optical current ratio with pateint parameters as inputs
    fat_coeff2 = [ 0.2577;-0.1120; 0.5073;-14.1437;3.7705]; %coefficients for tbw calculated using mvregress and optical current ratio with pateint parameters as inputs

    tbw =  hyd_coeff2(1)*age + hyd_coeff2(2)*hgt + hyd_coeff2(3)*weight + hyd_coeff2(4)*sex + hyd_coeff2(5)*l %calculation of percent tbw using coefficients 
    body_fat =  fat_coeff2(1)*age + fat_coeff2(2)*hgt + fat_coeff2(3)*weight + fat_coeff2(4)*sex + fat_coeff2(5)*l %calculation of percent body fat using coefficients 
    
    set(hdisp2, 'string', num2str(tbw_bi)); %display calculated tbw with bioimpedence
    set(fdisp2, 'string', num2str(body_fat_bi)); %display calculated body fat with bioimpedence
    set(hdisp, 'string', num2str(tbw)); %display calculated tbw with IR
    set(fdisp, 'string', num2str(body_fat)); %display calculated body fat with IR
  
    
end
close;

delete(ai);
