Code covered by the BSD License  

Highlights from
Edinburgh Handedness Inventory Data Collection Form

image thumbnail

Edinburgh Handedness Inventory Data Collection Form

by

 

GUI form to collect responses on the Edinburgh Handedness Inventory (Oldfield, 1971).

EHICollect.m
function [Gender, Age, ScoreFor10, ScoreFor12, EHILineScores] = EHICollect
%EHICollect: Collect Age, Gender, & EHI info

% Derived from AgeTextbox, GenderRadio, & EHIBoxes.

% TotalFigure is the full GUI window for the EHI.
% It values are specified in absolute screen coordinates:
TotalFigureLowerLeftX = 100;
TotalFigureLowerLeftY = 100;
TotalFigureWidth = 700;
TotalFigureHeight = 650;

% **********************************************************************
% This block of parameters specifies the placement of the controls (e.g., check boxes) within TotalFigure.
% All coordinates are relative to the lower left of the figure.

TopGap = 10;  % Gap between top of overall figure and top of the title

TitleX = 50;
TitleHeight = 20;
TitleWidth = 300;
TitleToTopRadioButtonVerticalGap = 10;

% Radio buttons are used for Gender:
RadioButtonX = 20;
RadioButtonHeight = 20;
RadioButtonWidth = 80;

% These control the age label and edit box:
RadioToAgeXGap = 20;
AgeLabelWidth = 90;
AgeLabelHeight = 20;
AgeEditBoxWidth = 30;
AgeEditBoxHeight = AgeLabelHeight + 4;   % Looks good a bit greater than AgeLabelHeight
AgeErrMessWidth = 150;
AgeEditBoxNudgeDown = 2;  % Looks better with Age edit box slightly lower than its label

InstructionWidth = 600;
InstructionHeight = 160;
GapBelowInstructions = 20;  % Vertical gap between instructions and Left/Right labels

LeftRightLabelWidth = 40;
LeftRightLabelHeight = 20;
GapBelowLeftRightLabel = 5;  % Vertical gap between Left/Right labels & top of check boxes.

CheckBoxHeight = 15;
CheckBoxWidth = 15;
WidthWithString = 300;
ComplainWidth = 200;  % Width of complaint message that activity ticks are not legal.
ColStartX = 22;
ColMidGap = 30;  % Additional gap between cols 2 & 3
GapY = 10;
GapX = 8;

DoneButtonWidth = 60;
DoneButtonHeight = 20;
DoneButtonX = ColStartX+3*GapX+ColMidGap+4*CheckBoxWidth;  % Line up left edge of button with Activity names.
DoneButtonY = 5;

% That is the end of the parameters specifying control placements.
% **********************************************************************

% **********************************************************************
% Here are the main text strings:

FormLabel ='Form for Collecting Edinburgh Handedness Inventory';
MainTitle = 'Edinburgh Handedness Inventory';
MaleStr = 'Male';
FemaleStr = 'Female';
AgeStr = 'Age in years:';
AgeErrStr='Illegal number for age!';

% Note: Must use sprintf(Instruction) to interpret newlines.
Instr1 = 'INSTRUCTIONS:\nPlease indicate your hand preference for each of the activities shown by ticking the appropriate boxes.\n';
Instr2 = '	Where your preference for one hand is so strong that you would never attempt to use the other hand unless absolutely forced to do so, put TWO ticks in the left or right column for the preferred hand.\n';
Instr3 = '	If you have a clear preference for one hand but not as strong as the above, put one tick in either box of the left or right column.\n';
Instr4 = '	If you are indifferent between hands, put one tick in BOTH the left and right columns.\n';
Instr5 = '	Some of the activities require both hands.  In these cases, we indicated in brackets the part of the task or object for which hand preference is wanted.';
Instr6 = '\n\nPlease call the experimenter if you have any questions.';

LeftStr = 'Left';
RightStr = 'Right';

Activity{1} = 'Writing';
Activity{2} = 'Drawing';
Activity{3} = 'Throwing';
Activity{4} = 'Scissors';
Activity{5} = 'Toothbrush';
Activity{6} = 'Knife (without fork)';
Activity{7} = 'Spoon';
Activity{8} = 'Broom (upper hand)';
Activity{9} = 'Striking match';
Activity{10} = 'Opening box (lid)';
Activity{11} = 'Which foot do you prefer to kick with?';
Activity{12} = 'Which eye do you use when using only one eye?';

BadTicksErrStr = 'This pattern of ticks is not allowed!';

DoneStr = 'Done';

% That is the end of the parameters specifying control placements.
% **********************************************************************

% Here is the overall figure for the form:
FormFigHandle = figure('MenuBar','None','NumberTitle','off','name',FormLabel, ...
    'Position',[TotalFigureLowerLeftX, TotalFigureLowerLeftY, TotalFigureWidth, TotalFigureHeight]);

TitleY = TotalFigureHeight - TitleHeight - TopGap;
TitleHandle = uicontrol(FormFigHandle,'Style','text','String',MainTitle, ...
    'FontSize',12,'FontWeight','bold', ...
    'Position',[TitleX TitleY TitleWidth TitleHeight]);

RadioButtonY = TitleY-TitleHeight-TitleToTopRadioButtonVerticalGap;  % TotalFigureHeight - TopGap;
handles.radio(1) = uicontrol('Style', 'radiobutton', ...
    'Callback', @myRadio, ...
    'Units',    'pixels', ...
    'Position', [RadioButtonX, RadioButtonY, RadioButtonWidth, RadioButtonHeight], ...
    'String',   MaleStr, ...
    'Value',    0);
handles.radio(2) = uicontrol('Style', 'radiobutton', ...
    'Callback', @myRadio, ...
    'Units',    'pixels', ...
    'Position', [RadioButtonX, RadioButtonY-RadioButtonHeight, RadioButtonWidth, RadioButtonHeight], ...
    'String',   FemaleStr, ...
    'Value',    1);
guidata(FormFigHandle, handles);

AgeLabelX = RadioButtonX + RadioButtonWidth + RadioToAgeXGap;
AgeLabelY = RadioButtonY - RadioButtonHeight/2;
AgeLabelHandle = uicontrol(FormFigHandle,'Style','text','String',AgeStr,'Position',[AgeLabelX AgeLabelY AgeLabelWidth AgeLabelHeight]);
AgeEditHandle = uicontrol(FormFigHandle,'Style','edit','Position',[AgeLabelX+AgeLabelWidth AgeLabelY-AgeEditBoxNudgeDown AgeEditBoxWidth AgeEditBoxHeight]);
AgeErrorMessHandle = uicontrol(FormFigHandle,'Style','text','Visible','off','ForegroundColor','red','Position',[AgeLabelX+AgeLabelWidth+AgeEditBoxWidth AgeLabelY AgeErrMessWidth AgeLabelHeight],'String',AgeErrStr);

InstructionX = RadioButtonX;
InstructionY = RadioButtonY-2*RadioButtonHeight-InstructionHeight;
InstructionHandle = uicontrol(FormFigHandle,'Style','text','String', ...
    sprintf([Instr1 Instr2 Instr3 Instr4 Instr5 Instr6]), ...
    'HorizontalAlignment','left', ...
    'Position',[InstructionX InstructionY InstructionWidth InstructionHeight]);

LeftRightLabelY = InstructionY-GapBelowInstructions-LeftRightLabelHeight;
LeftLabelX = ColStartX;
RightLabelX = ColStartX + 2*(CheckBoxHeight + GapY) + ColMidGap;
LeftLabelHandle = uicontrol(FormFigHandle,'Style','text','FontWeight','Bold','String',LeftStr,'Position',[LeftLabelX LeftRightLabelY LeftRightLabelWidth LeftRightLabelHeight]);
RightLabelHandle = uicontrol(FormFigHandle,'Style','text','FontWeight','Bold','String',RightStr,'Position',[RightLabelX LeftRightLabelY LeftRightLabelWidth LeftRightLabelHeight]);

NActivities = length(Activity);
NBoxCols = 4;
TopRowStartY = LeftRightLabelY-GapBelowLeftRightLabel-CheckBoxHeight;

TicBox = zeros(NActivities,NBoxCols);
ActivityErrorMessages = zeros(NActivities,1);
for iActivity = 1:NActivities
    BoxStartY = TopRowStartY - (iActivity-1)*(CheckBoxHeight + GapY);
    for iCol = 1:NBoxCols
        BoxStartX = ColStartX + (iCol-1)*(CheckBoxWidth+GapX);
        if iCol > 2
            BoxStartX = BoxStartX + ColMidGap;
        end
        if iCol == 4
            ThisString = Activity{iActivity};
            ThisWidth = WidthWithString;
        else
            ThisString = '';
            ThisWidth = CheckBoxWidth;
        end
        TicBox(iActivity,iCol) = uicontrol(FormFigHandle,'Style','checkbox','String',ThisString,'Position',[BoxStartX,BoxStartY,ThisWidth,CheckBoxHeight] ) ;
    end
    ActivityErrorMessages(iActivity) = uicontrol(FormFigHandle,'Style','text','String',BadTicksErrStr, ...
        'Visible','off','ForegroundColor','red','HorizontalAlignment','left', ...  
        'Position',[BoxStartX+ThisWidth BoxStartY ComplainWidth CheckBoxHeight]);
end

DoneButtonHandle = uicontrol('Position', [DoneButtonX DoneButtonY DoneButtonWidth DoneButtonHeight], 'String',DoneStr, ...
    'Callback', 'uiresume(gcbf)');

% ****************************************************************
% **************** Start definitions for scoring and checking of form.
% ****************************************************************

% ScoreSet defines a single numerical score for each possible combination of (NLeft+1,NRight+1) tics.
% Certain combinations are legal/illegal according to the instructions.  }
ScoreSet(1,1) = 7;  % "illegal"
ScoreSet(1,2) = 4;  % "legal"
ScoreSet(1,3) = 5;  % "legal"
ScoreSet(2,1) = 2;  % "legal"
ScoreSet(2,2) = 3;  % "legal"
ScoreSet(2,3) = 9;  % "illegal"
ScoreSet(3,1) = 1;  % "legal"
ScoreSet(3,2) = 6;  % "illegal"
ScoreSet(3,3) = 8;  % "illegal"
MaxLegalScore = 5;

Incomplete = 1;
Tic = zeros(NActivities,NBoxCols);

while Incomplete > 0
    uiwait(FormFigHandle);
    
    Incomplete = 0;
    
    % Retrieve & check Age:
    AgeStr = get(AgeEditHandle,'String');
    Age = str2double(AgeStr);
    if isnan(Age) ||  (Age<1) || (Age>110)
        Incomplete = 1;
        set(AgeErrorMessHandle,'Visible','on');
    else
        set(AgeErrorMessHandle,'Visible','off','ForegroundColor','red');
    end
    
    % Retrieve Gender:
    Gender = get(handles.radio(2),'Value');  % 0 = Male, 1 = Female.
    
    % Retrieve & check EHI:
    for iActivity = 1:NActivities
        for iCol = 1:NBoxCols
            Tic(iActivity,iCol) = get(TicBox(iActivity,iCol),'Value');
        end
    end
    
    for iActivity = 1:NActivities
        if Score(iActivity,Tic,ScoreSet) > MaxLegalScore
            Incomplete = 1;
            set(ActivityErrorMessages(iActivity),'Visible','on');
        else
            set(ActivityErrorMessages(iActivity),'Visible','off','ForegroundColor','red');
        end
    end
    
end


ScoreFor10 = EHITtl(10,Tic);
ScoreFor12 = EHITtl(12,Tic);
EHILineScores = zeros(NActivities,1);
for iActivity = 1:NActivities
    EHILineScores(iActivity) = Score(iActivity, Tic, ScoreSet);
end

close(FormFigHandle);

end  % function EHIForm


function myRadio(RadioH, ~)
handles = guidata(RadioH);
otherRadio = handles.radio(handles.radio ~= RadioH);
set(otherRadio, 'Value', 0);
end

function ThisScore = Score(iActivity, Tic, ScoreSet)
NLeft = 0;
NRight = 0;
if Tic(iActivity,1)
    NLeft = 1;
end
if Tic(iActivity,2)
    NLeft = NLeft+1;
end
if Tic(iActivity,3)
    NRight = 1;
end
if Tic(iActivity,4)
    NRight = NRight+1;
end
ThisScore = ScoreSet(NLeft+1,NRight+1);
end


function ThisEHITtl = EHITtl(NToScore,Tic)
NLeft = 0;
NRight = 0;
for iActivity = 1:NToScore
    if Tic(iActivity,1)
        NLeft = NLeft+1;
    end
    if Tic(iActivity,2)
        NLeft = NLeft+1;
    end
    if Tic(iActivity,3)
        NRight = NRight+1;
    end
    if Tic(iActivity,4)
        NRight = NRight+1;
    end
end
if NRight + NLeft > 0
    ThisEHITtl = 100.0 * (NRight - NLeft) / (NRight + NLeft);
else
    ThisEHITtl = -1;
end
end

Contact us