Visual Analog Scales, IFIS, and Button Response Units
Daniel.J.Bates at wheaton.edu
Daniel.J.Bates at wheaton.edu
Wed Jul 30 19:25:32 UTC 2003
Hello Everyone...
Over the last three months, I have posted several sections of code outlining
how to create a visual analog scale in E-Prime. Unfortunately, none of those
portions of code run with IFIS or Button Response Units. For whatever reason,
BRUs are not directly connected to the computer. Input is first sent to a
small box located inside the MRI room. This box sends a discrete value (rather
than a continuous stream) to the computer saying that a button has been
pressed. Unfortunately, this decreases the flexibility of the Visual Analog
Scale (explained later). I, therefore, have changed the code so that E-Prime
users can use visual analog scales inside MRI machines. I hope someone finds
this information helpful.
Good luck...
Daniel
--------------------------------------------------
Visual Analog Scale Construction
--------------------------------------------------
1) Composed of 5 E-Prime objects in the following order
a) InlineCode1: Defines two variables
b) Label1
c) Slide1
d) Wait1
e) InlineCode2: Responsible for the movement of the vertical bar.
2) Object Parameters
a) InlineCode1: Cannot change parameter
b) Label1: Cannot change parameters
c) Slide1
i) 3 Text Boxes
ii) 2 images superimposed on each other (a horizontal rectangle and a
vertical bar). These images were created in Microsoft Paint and are named
SlideBar1 and SliderButton2 respectively.
iii) SlideDuration = 80 ms
iv) InputDevices = Keyboard
v) AllowableInput = 12345
vi) Timelimit = [Same as duration)
d) Wait1
i) WaitDuration = -1 (infinite)
ii) InputDevices = Keyboard
iii) AllowableInput = 12345
iv) Timelimit = [Same as duration]
v) Logging: RESP: Records actual response of subject
3) Inline Code Explained
a) InlineCode1
i) Code:
Dim ButtonPosn As Integer
Dim NewButtonPosn As Integer
ButtonPosn = 139
NewButtonPosn = ButtonPosn
ii) Defines initial values of ButtonPosn and NewButtonPosn.
iii) Placing this code before Label1 allows the default values of
ButtonPosn and NewButtonPosn to change
b) InlineCode2
i) Code:
Dim FinalSelection As Integer
Dim ScreenWidth As Integer
Dim slrLeft As Integer
Dim slrRight As Integer
Dim KeyAscii As Integer
Dim KeyAscii2 As Integer
Dim Tag As String
Dim StopLoop As Integer
ScreenWidth = 640
slrLeft = 139
slrRight = 493
FinalSelection = 0
KeyAscii = Wait1.Resp
Select Case KeyAscii
Case 1
StopLoop = 0
Do
StopLoop = StopLoop + 1
If (Slide1.RESP = Empty) OR (StopLoop = 1) THEN
StopLoop = StopLoop + 1
If ButtonPosn >= slrLeft + 2 Then
NewButtonPosn = ButtonPosn - 2
Else
NewButtonPosn = slrLeft
End If
CSlideImage(Slide1.States.Item("Default").Objects(1)).X =
NewButtonPosn
ButtonPosn = NewButtonPosn
Slide1.InputMasks.Reset
Slide1.InputMasks.Add Keyboard.CreateInputMask("12345", "", Val
(Slide1.Duration), Val("1"), ebEndResponseActionTerminate, True, "", "", "")
Slide1.Run
Else
StopLoop = 501
End If
Loop until StopLoop > 500
Case 3
FinalSelection = 1
Tag = Str((NewButtonPosn - slrLeft) / (slrRight - slrLeft) * 100)
c.SetAttrib "PainResponse" , Tag
CSlideImage(Slide1.States.Item("Default").Objects(1)).X = 139
Slide1.Run
Case 5
Do
StopLoop = StopLoop + 1
If (Slide1.RESP = Empty) OR (StopLoop = 1) THEN
StopLoop = StopLoop + 1
If ButtonPosn >= slrLeft + 2 Then
NewButtonPosn = ButtonPosn - 2
Else
NewButtonPosn = slrLeft
End If
CSlideImage(Slide1.States.Item("Default").Objects(1)).X =
NewButtonPosn
ButtonPosn = NewButtonPosn
Slide1.InputMasks.Reset
Slide1.InputMasks.Add Keyboard.CreateInputMask("12345", "", Val
(Slide1.Duration), Val("1"), ebEndResponseActionTerminate, True, "", "", "")
Slide1.Run
Else
StopLoop = 501
End If
Loop until StopLoop > 500
End Select
If FinalSelection = 0 Then
Goto Label1
End If
---------------------------------------------------
Visual Analog Scale Code Explained
---------------------------------------------------
The VAS code is composed of three cases (i.e. key-presses) and several loops.
The subject enters the first loop as soon as he/she sees visualizes the slide
(Case Select...End Select...Go to Label 1 if...). Since the duration of Wait1
is infinite, E-Prime waits indefinitely for some kind of input from the
subject. This input is collected by the wait object (KeyAscii = Wait1.RESP).
Acceptable input = 1, 3, and/or 5. If the subject enters either 1 or 5, then
he/she enters the second loop (Do...Loop Until). This loop changes the
numerical value of ButtonPosn and NewButtonPosn by +/- 2 pixels and changes the
position of SliderButton2 on the screen. Note that the values of ButtonPosn
and NewButtonPosn are constrained by the values of slrLeft and slrRight. This
is to prevent the vertical bar from straying outside of the scales limits.
Also, note that the position of SliderButton2 does not change until Slide1 is
run (Slide1.Run). Since the second loop is looking for input from the Slide1
and since Slide1 only has a duration of 80 ms, the computer moves the position
of SliderButton2 approximately 10 times per second. Unfortunately, this low
refresh rate makes the bar flash a little while it is moving and it is not
possible to fix the problem without severely hampering the efficacy of the VAS
(explained in point v).
There are two ways out if the second loop. The normal way out is to press a
key on the keyboard. This changes the value of Slide1.RESP to something other
than empty and, therefore, prevents the subject from entering the second loop
again. The second way is just a safety net; to prevent the computer from
entering a never-ending loop, the computer counts the number of times it has
gone through the loop (StopLoop = StopLoop + 1) and exits when it reaches a
number > 300 (Loop until StopLoop > 300). Once the subject has exited the
first case, the computer exits the Select Case
End Select function, realizes
that FinalSelection still equals 0, and then returns to Label1. The entire
process then repeats itself.
The only way to exit the first loop (and finalize the position of
SliderButton2) is to press #3. This instructs the computer to do several
things. First, it changes the value of FinalSelection from 0 to 1. Second, it
computes the position SliderButton2 on the scale as a percentage (Tag =).
Third, it records that value in an. edat file (c.SetAttrib NameOfColomn,
Tag). Fourth, it resets the numerical values of ButtonPosn and NewButtonPosn.
Fifth, it moves the position of SliderButton2 so that it equals the numerical
values of ButtonPosn and NewButtonPosn (Slide1.Run). The computer then moves
to the next part in the paradigm.
This code has one major flaw. The computer can only collect input from the
WaitObject or the SlideObject during the object's duration. Since it takes a
small amount of time for the computer to perform the rest of the code, it is
possible for the subject to press a key without the code entering or exiting a
loop. Increasing the SlideObjects duration decreases the probability of this
happening. In my opinion, the optimal length of the duration is 80 ms, but
that time length can be increased. If the duration is increased, however, it
will take longer for the program to move the image 2 pixels. The motion will,
therefore, look somewhat jerky. Even though the computer will catch more key-
presses, the efficacy of the Visual Analog Scale will be decreased.
Unfortunately, since this flaw is caused by a hardware rather than a software
problem, it is not easily patched. It is rumored that IFIS is working on new
box that fixes this problem, but, as of July 2003, it had not been completed.
---------------------------------------------------------
Explanation of particular lines of code: Destroying the Black Box
---------------------------------------------------------
1) Slide1.InputMasks: this section of code tells the computer to look for input
from Slide2. I do not know what all of the values mean; this code was cut-and-
pasted from another portion of the E-Prime code.
2) CSlideImage(Slide1.States.Item("Default").Objects(#)): another, more
complicated, name for SliderButton2.
3) CSlideImage(Slide1.States.Item("Default").Objects(#)).X : the pixel position
of SliderButton2.
4) Slide1.InputMasks.Reset: Empties the value of Slide1.Resp.
5) Slide1.InputMasks.Add Keyboard.CreateInputMasks
: This is a really strange
way of telling the computer to collect the input from Slide1. In this
particular case, the numbers 1, 2, 3, 4, and 5 are acceptable kinds of input.
More information about the Eprime
mailing list