Read out certain levels only

475 views
Skip to first unread message

Vera

unread,
May 6, 2010, 5:17:11 AM5/6/10
to E-Prime
Dear forum members,

I already got some very useful help here and as I am now running into
a new problem with E-Prime, I will see if you can help me out (again).
I did all my homework: yes I looked at the reference guide, getting
started guide, all other documents concerning E-Prime, yes I combed
through this forum, yes I combed through the PST-forum. :-)

So here's the problem:

I created a list of conditions (and all that has been working fine
until now) and as we are moving on to another experimental setup, it
is now very important that half of the conditions appear on one type
of stimulus and the other half of conditions appear on another type of
stimulus.

To be more clear:

On Trigger1 I want only a certain type of the 18 conditions I have to
be executed.
On Trigger2 I want the other 18 conditions (another type) to be
executed.

I know I could be able to do this over nested lists (probably), but it
would take a lot of time too, as then "big surgery" has to be done on
my program. ;-)

So I figured that there should be some way to add a few lines of code,
which tell E-Prime that it should only use a certain level in a
certain condition.

I wrote:
If (NewTriggerValue > 0) AND (NewTriggerValue < 7) Then
c.getAttrib("TriggerPos") = 1
ElseIf NewTriggerValue = 0 Then
c.getAttrib("TriggerPos") = 0
End If

TriggerPos = the type of trigger (1 or 0) which I added as an
attribute in my designlist.
When I try to execute, Eprime tells me "Can't Assign to Constant"

Ok. But what do I need to add then in order to make it work? Basically
I want Eprime in certain conditions only to use the levels that have
"1" in the attribute "TriggerPos".

I know that I am not very far from a solution. Any help would be very
much appreciated. :-)

Vera

--
You received this message because you are subscribed to the Google Groups "E-Prime" group.
To post to this group, send email to e-p...@googlegroups.com.
To unsubscribe from this group, send email to e-prime+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/e-prime?hl=en.

Vera

unread,
May 6, 2010, 8:31:26 AM5/6/10
to E-Prime
Ok, got a bit further (but it's still not working fine):

I added this inline:

If (NewTriggerValue > 0) AND (NewTriggerValue < 7) Then
Set DesignList.Deletion = PickOne(c.GetAttrib("TriggerPos") = "1")
ElseIf NewTriggerValue = 0 Then
Set DesignList.Deletion = PickOne(c.GetAttrib("TriggerPos") = "0")
End If

It's based on something David once wrote concerning counterbalancing
(it would have been so much easier if E-Prime could just
counterbalance for any attribute and not just Group, Subject and
Session). I am actually hoping to tell E-Prime with this, that it
needs to take any of the 18 levels which has either 1 or 0 in the
TriggerPos attribute. It doesn't seem to work though. :-(

E-Prime now only runs 1 trials (instead of 36). Any hints on that?

Grrr, I know I am not very far from a solution...

Greetings, Vera

Vera

unread,
May 7, 2010, 3:24:03 AM5/7/10
to E-Prime
Ok guys, just to let you know that I am really trying here, a small
update:

Yesterday I tried to solve this problem with nested lists (knowing
that nested lists very quickly get very complicated and taking into
account that Michiel pointed out in his E-Prime doc that the random
doesn't seem to be completely "trustable") but the problem is that I
get to the same thing: I would basically have two lines, 1 pointing to
the condition for trigger 1 and another one pointing to trigger 2. But
then, how to access this line??
I need to figure out some way to tell E-Prime:

If trigger 1 then PLEASE take only line 1

(Or in the old solution, which I very much preferred, because it was
much cleaner - nested lists do have a high "sudoku-effect"):

If trigger 1 PLEASE take any of the lines for which attribute.trigger1
= 1

Down to the beginning again, I don't know how to solve this. :-( Any
ideas are very welcome. :-)

Greetings, Vera

Michiel Spape

unread,
May 7, 2010, 6:25:10 AM5/7/10
to e-p...@googlegroups.com
Hi Vera & Group,
I like that "Sudoku-effect"! In fact, I think I might have misstated that nested-lists are untrustworthy - in general, people are much more prone to making errors than computers, and indeed, this to me is the main problem of nested lists. I do, however, use them all the time, myself, but usually not for my main 'triallist'.

Anyway, I'm sorry for the lack of help I'm going to offer, I'm just not entirely clear on what you want to achieve. Do you want to run certain conditions based on a trigger readout from TMS (err, I never worked with TMS)? Does that mean certain stimuli? Certain different orderings?

Lacking a clear idea on what exactly it is you want, I can help with certain specifics:

"If trigger 1 then PLEASE take only line 1"
...
You mean, of a list, right?

This can be achieved in a quick and dirty way by adding a bit of inline that sets all weights of a list to 0 except line 1. From E-basic help, and adjusted

Dim nLevel As Integer 'originally Long, but how many people really have lists that have more than 32768 levels?
For nLevel = 1 To List1.Size
If nLevel = 1 then List1.SetWeight nLevel, 1 else List1.SetWeight nLevel, 0
Next 'nLevel
List1.Reset

You can even put this List1 in unreferenced objects (i.e. your garbage can) and run it on request (List1.Run).
Hope any of this helps (I might be way off in understanding your problem),
Mich






Michiel Spapé
Research Fellow
Perception & Action group
University of Nottingham
School of Psychology
This message has been checked for viruses but the contents of an attachment
may still contain software viruses which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.

Vera

unread,
May 7, 2010, 7:07:24 AM5/7/10
to E-Prime
Michiel,

I am going to see what your solution can do (it seems to be pointing
in "some direction" at least, which is way better than the "no-
direction" I am having right now. ;-)

But for the moment, I just copy you what I wrote in the PSTNET-Forum
this morning (and in which I maybe have been clearer):

I am trying to read out an attribute (ok, GetAttrib solves this) but
then I would like to tell E-Prime that in certain conditions, it
should only use the levels (lines) in the list that correspond to
certain values of this attribute.

Let's say I have 20 lines in my list. 10 lines for which the attribute
"Trigger" has the value 1 and 10 other lines for which the value of
the attribute "Trigger" is 2.

I would like to tell E-Prime that on a certain trigger (coming in over
the Parallel Port) it should only use trials (lines) for which the
Attribute "Trigger" corresponds to a certain value.

So, something like: If Trigger 1, then only use any of the 10 lines
for which Attribute.Trigger = 1 (I know this syntax is wrong, it's
just to make you understand). If Trigger is 2, then only use any of
the 10 lines for which Attribute.Trigger = 2.

See what I mean?

Greetings, Vera


On May 7, 12:25 pm, Michiel Spape <Michiel.Sp...@nottingham.ac.uk>
wrote:
> For more options, visit this group athttp://groups.google.com/group/e-prime?hl=en.

Vera

unread,
May 7, 2010, 7:42:14 AM5/7/10
to E-Prime
Ok, I now had a closer look at your solution (I wasn't on the right PC
before, with the USB-stick-licence it's kind of a hassle sometimes,
making a lot of kms in the institute! ;-) ) and I think I might try
something with your solution.

So to get back at your question:

"If trigger 1 then PLEASE take only line 1"
...
"You mean, of a list, right?"

Yes, I mean of a list (so a level of a list). Of course I simplified
the whole a bit, pretending that I had only two levels in my list and
two triggers. In reality I have 20 lines and two triggers (so the list
kind of gets separated into two). :-)

So basically what I want to do is
"If trigger = 1 then take any of the lines for which attribute.trigger
= 1" (any of 10 in a random manner)

Oh and then don't worry about TMS, it's already all working fine. :-)
I am getting the triggers and all, E-Prime just doesn't know what to
do with them for the moment (ok if I am more precise: E-Prime knows
what to do with the triggers, but I can't control the conditions,
making sure that the design is completely perfectly counterbalanced
over the two conditions). :-)

I am going back to my experimental setup again, seeing what I can do
with your solution in mind. I definitely should get internet there,
but that's the hassle with experimental computers: you want to keep
them clean from anything that might slow them such as anti-virus and
stuff. :-| But feel free to reply if you came up with another idea, I
will check for input anyway. :-)

Greetings, Vera




On May 7, 12:25 pm, Michiel Spape <Michiel.Sp...@nottingham.ac.uk>
wrote:
> For more options, visit this group athttp://groups.google.com/group/e-prime?hl=en.

Michiel Spape

unread,
May 7, 2010, 9:58:49 AM5/7/10
to e-p...@googlegroups.com
Hi Vera & List,

If I understand it correctly, you might be able to do something like this much the same way I explained earlier:

I wrote earlier:

> Dim nLevel As Integer 'originally Long, but how many people really have lists that have more than 32768 levels?
> For nLevel = 1 To List1.Size
> If nLevel = 1 then List1.SetWeight nLevel, 1 else List1.SetWeight nLevel, 0
> Next 'nLevel
> List1.Reset

Now, let's say you want only Level X, based on an attribute which gives you X:

> Dim nLevel As Integer > For nLevel = 1 To List1.Size
> If nLevel = c.GetAttrib("YourXAttribute") then List1.SetWeight nLevel, 1 else List1.SetWeight nLevel, 0
> Next 'nLevel
> List1.Reset

You could, of course, also speed through your trial (never showing anything by just skipping over the entire trial, if the current trial is not exactly what you want) - but perhaps that will be difficult to do in a controllable/balanced manner.

"Let's say I have 20 lines in my list. 10 lines for which the attribute
"Trigger" has the value 1 and 10 other lines for which the value of
the attribute "Trigger" is 2. I would like to tell E-Prime that on a certain trigger (coming in over
the Parallel Port) it should only use trials (lines) for which the
Attribute "Trigger" corresponds to a certain value."

... to do that, you can simply add checks to see whether certain levels need to be set to 0 weight:
(see help on Factor.GetAttrib level, AttributeName)

Dim nLevel As Integer

'What trigger?
If myTrigger = 1 then
For nLevel = 1 To List1.Size
If List1.GetAttrib(nLevel, "YourXAttribute") = 1 then List1.SetWeight nLevel, 1 else List1.SetWeight nLevel, 0
Next 'nLevel
else
For nLevel = 1 To List1.Size
If List1.GetAttrib(nLevel, "YourXAttribute") = 2 then List1.SetWeight nLevel, 1 else List1.SetWeight nLevel, 0
Next 'nLevel
End if
List1.Reset

Hope that helps! And sorry in advance for any mistakes and/or sloppy programming advice (trying to finish stuff before weekend - I'm sure I'm not alone at that)
Cheers,

Vera

unread,
May 7, 2010, 11:05:00 AM5/7/10
to E-Prime
Ok, found a way to be at the experimental setup AND have internet
(whew!!!). ;-)

So the thing I did was:

If (NewTriggerValue > 0) AND (NewTriggerValue < 7) Then
For nLevel = 1 to DesignList.Size
If c.GetAttrib("Trigger") = "1" Then
DesignList.SetWeight nLevel, 1
Else DesignList.SetWeight nLevel, 0
End If
Next nLevel
ElseIf NewTriggerValue = 0 Then
For nLevel = 1 to DesignList.Size
If c.GetAttrib("Trigger") = "0" Then
DesignList.SetWeight nLevel, 1
Else DesignList.SetWeight nLevel, 0
End If
Next nLevel
End If

And now that I could finally connect, I see that you proposed me the
same thing. :-)
And the best thing: it works!!!! Checked the database with E-DataAid
and it's all perfectly balanced. :-)

Thanks a lot for giving me the idea!

Have a great weekend!

Vera

Vera

unread,
May 7, 2010, 1:11:48 PM5/7/10
to E-Prime
:-(

I seem to have cheered too early. :-( Some filteringin E-DataAid
showed that E-Prime is still exactly doing as it likes.

I also had some mistakes in the previous code, here it is again:

Dim nLevel as Integer
Dim TriggerValue as Integer

If (NewTriggerValue > 0) AND (NewTriggerValue < 7) Then
For nLevel = 1 to DesignList.Size
TriggerValue = DesignList.GetAttrib(nLevel,"Trigger")
If TriggerValue = 1 Then
DesignList.SetWeight nLevel, 1
Else DesignList.SetWeight nLevel, 0
End If
Next nLevel
' DesignList.Reset
ElseIf NewTriggerValue = 0 Then
For nLevel = 1 to DesignList.Size
TriggerValue = DesignList.GetAttrib(nLevel,"Trigger")
If TriggerValue = 0 Then
DesignList.SetWeight nLevel, 1
Else DesignList.SetWeight nLevel, 0
End If
Next nLevel
' DesignList.Reset
End If

A few remarks to this code:

1. E-Prime is still doing what it likes, guaranteeing me no
counterbalancing whatsoever.
2. I had to add: TriggerValue = DesignList.GetAttrib(nLevel,"Trigger")
- If TriggerValue = 0 Then and I know I could have been doing that
more elegantly (like you did Michiel), but then E-Prime complains that
there are "too many variables".
3. If I add this piece of code, not only will E-Prime still not do
what I expect it to do, but it will also generate blocks as it likes.
Sometimes 3, sometimes 4... But never 7 as it is supposed to do!! In
my last test run it even stopped in the middle of a trial going
immediately to the block feedback! Anybody any idea why that could be?
It seems to me that this piece of script has nothing to do with the
number of blocks or anything.
4. As you can see, DesignList.Reset has been commented out, because
when I add this, E-Prime runs only one trials (instead of 36 in a
normal block) and then goes immediately to the Block Feedback.

I don't understand this program, it makes absolutely no sense to me. :-
(

Greetings, Vera
> ...
>
> Erfahren Sie mehr »

David McFarlane

unread,
May 11, 2010, 9:41:13 AM5/11/10
to e-p...@googlegroups.com
Vera,

[Took me awhile to get to this because I had other business to attend
to and I wanted to write this up properly.]

As to "counterbalancing" on attributes other than Group, Subject, and
Session... As I hinted in the thread at
http://groups.google.com/group/e-prime/browse_thread/thread/26d2e1e83c6a09bb
, although the E-Studio GUI allows options only for Subject, Session,
and Group, you may "counterbalance" on any other attribute simply
through a proper application of inline code before the List runs, e.g.,

Set List.Deletion = PickOne(c.GetAttrib("AnyAttribYouLike"))

In fact, List.Order does not have a "Counterbalance" option --
instead, Counterbalance in E-Studio just generates a combination of
settings that makes EP pick a numbered row from the List at runtime
and run just that, once. The best way to see this is to use
Counterbalance in E-Studio and then look at the generated code (and
IMO if you do not care to look at or understand generated E-Basic
code, then you should leave this work to somebody else who
does). For the record, and to spare you the trouble, here is an
example of the relevant generated code from the InitObjects subroutine:

Set List.Order = New SequentialOrder
Set List.Deletion = PickOne(c.GetAttrib("Subject"))
List.ResetEveryRun = True
Set List.TerminateCondition = Samples(1)
Set List.ResetCondition = Samples(1)

-- David McFarlane, Professional Faultfinder


At 5/6/2010 08:31 AM Thursday, you wrote:
>Ok, got a bit further (but it's still not working fine):
>
>I added this inline:
>
>If (NewTriggerValue > 0) AND (NewTriggerValue < 7) Then
> Set DesignList.Deletion = PickOne(c.GetAttrib("TriggerPos") = "1")
>ElseIf NewTriggerValue = 0 Then
> Set DesignList.Deletion = PickOne(c.GetAttrib("TriggerPos") = "0")
>End If
>
>It's based on something David once wrote concerning counterbalancing
>(it would have been so much easier if E-Prime could just
>counterbalance for any attribute and not just Group, Subject and
>Session).

David McFarlane

unread,
May 11, 2010, 10:33:51 AM5/11/10
to e-p...@googlegroups.com
Vera,

Don't know why your code does not work, but just
a couple comments on your code fragment here...

First, almost every time we have resorted to
using List.SetWeight it turned out that we had a
poor design structure, and once we restructured
the design it eliminated the need for
List.SetWeight and solved a host of other lurking
problems as well. So I urge you to first take a
serious look at your design structure.

Next, when we did use List.SetWeight, we
absolutely had to execute a List.Reset, otherwise
the List ignored our .SetWeight changes. So if
your code does not work with the List.Reset
command in place, then your code has other problems.

And since you must do the List.Reset for either
branch of the If...Then...ElseIf, then you may as
well pull it out from within the branches and put
it after the whole If...Then...ElseIf block.

Finally, what happens if TriggerValue < 0 or
TriggerValue >= 7? As it stands, in this case
your code will simply leave the List intact. Is
this what you meant? Perhaps you think it
impossible for TriggerValue to ever take on
values outside of 0-6, but good coding practice
requires that you either include a final Else to
handle outliers or at least add a comment to
explain what you mean the code to do.

So just as an exercise, here is your code
fragement again (keeping your TriggerValue
variable because I do not want to get into that
issue, using "<=" instead of "<" just because I
think that makes the intent clearer, and adding a
Const to get rid of one "magic number"; hmm, on
further thought I restructured this to pull the
common inner loops out of the main loop, etc.):

Const TriggerValueMax as Integer = 6
Dim nLevel as Integer
Dim TriggerValue as Integer, TriggerValueToRun as Integer
' Assign TriggerValueToRun based on NewTriggerValue:
If (NewTriggerValue = 0) Then
TriggerValueToRun = 0
ElseIf ((1 <= NewTriggerValue) AND _
(NewTriggerValue <= TriggerValueMax)) Then
TriggerValueToRun = 1
Else MsgBox "NewTriggerValue " & NewTriggerValue _
& "out of range! Please contact programmer."
End If
' Now set List level weights according to match between TriggerValue &
' TriggerValueToRun:
For nLevel = 1 to DesignList.Size
TriggerValue = DesignList.GetAttrib(nLevel,"Trigger")
If TriggerValue = TriggerValueToRun Then
DesignList.SetWeight nLevel, 1
Else DesignList.SetWeight nLevel, 0
End If
Next nLevel
DesignList.Reset


Or just for fun, let's do this with a Select Case:

Const TriggerValueMax as Integer = 6
Dim nLevel as Integer
Dim TriggerValue as Integer, TriggerValueToRun as Integer
' Assign TriggerValueToRun based on NewTriggerValue:
Select Case NewTriggerValue
Case 0
TriggerValueToRun = 0
Case 1 to 6
TriggerValueToRun = 1
Case Else
MsgBox "NewTriggerValue " & NewTriggerValue _
& "out of range! Please contact programmer."
End Select
' Now set List level weights according to match between TriggerValue &
' TriggerValueToRun:
For nLevel = 1 to DesignList.Size
TriggerValue = DesignList.GetAttrib(nLevel,"Trigger")
If TriggerValue = TriggerValueToRun Then
DesignList.SetWeight nLevel, 1
Else DesignList.SetWeight nLevel, 0
End If
Next nLevel
DesignList.Reset

-- David McFarlane, Professional Faultfinder


Vera

unread,
May 19, 2010, 7:42:34 AM5/19/10
to E-Prime
David,

thanks for the reply. I had already been trying to have a look at the
code generated by E-Prime (and I already tried to do what you did with
the Set List.Deletion = PickOne(c.GetAttrib("AnyAttribYouLike")) , but
it generated another number of errors).

Anyway, we found a solution now (we just have two different lists
(which is not the solution I prefer, because it gets incredibly messy
with Labels and Gotos in all directions, but hey, it's working, and
that was the goal...)).

I think that you are right that the weight level solution isn't the
best one.

We tried to apply another one, working with two arrays, which I think
is the perfect, cleanest solution (unfortunately I am not a
programming hero and so I got it almost to working, but I am still
convinced to get it working someday). As time was running out, we took
the "E-Prime solution" (mentionned above, including two designlists
and a lot of Labels and Gotos) which as I said is working.

To the trigger value question, you are probably right that I should
foresee what happens is the trigger is < 0 or > 7. But in practice
this will just not happen, as we are using the first 4 bits of a
parallelport only (0, 1, 2, 4). :-) Thanks for the general programming
tip though.

So thanks to you and Michiel for trying to help me out!

Greetings, Vera
> ...
>
> read more »

David McFarlane

unread,
May 20, 2010, 2:39:53 PM5/20/10
to e-p...@googlegroups.com
Vera,

Thanks for writing back with the update...

At 5/19/2010 07:42 AM Wednesday, you wrote:
>To the trigger value question, you are probably right that I should
>foresee what happens is the trigger is < 0 or > 7. But in practice
>this will just not happen, as we are using the first 4 bits of a
>parallelport only (0, 1, 2, 4). :-)

Just on that point, 4 bits still allows values from 0 all the way to
decimal 15, so you should still think about what happens with
responses > 6. Three bits, OTOH, would indeed restrict values to <=
7, but even then courtesy dictates a comment to that effect.

(Also, if it were me, I would still apply a mask to absolutely
eliminate mistakes from stray signals, e.g.,

Const WireMask as Integer = &H0F ' lower 4 bits, decimal 15
NewTriggerValue = NewTriggerValue or WireMask ' do bitwise Or

.)

Ever harping on minutiae,
-- David McFarlane, Professional Faultfinder

Reply all
Reply to author
Forward
0 new messages