trigger TMS + collect responses during stimulus presentation

Paul Gr pauls_postbus at hotmail.com
Sat Jun 16 00:44:05 UTC 2007


Dear Bianca,
 
Just a few questions and hints:
 
Did you define sufficient prerelease times in mainstimulus and mainmask2? This would be required since you reload images during the time critical loop. (But read on...;)
 
The place of the mainstimulus.OnsetSignal statements are a bit unusual. Normally you would initialize these before mainstimulus.Run. That would be required if the TMS trigger should be in sync with ALL (including the very first) mainstimulus onsets. 
 
There are several good arguments for not placing the mainstimulus preparation and execution inside the first loop. The prefered way would be to run the mainstimulus object just before the loop. Then use a simplified loop to generate the trigger pulses that should be generated during the target. Also use the sleep() instruction inside the loop to specify the delays for each iteration. You should also place the OnsetSignal initialisation script somewhere before mainstimulus.run. Also set the duration and prerelease vaules of mainstimulus to the required duration of the target. This will prevent large timing error values for the following objects.
The declaration of the i1 integer variable is probably misplaced because it should be declared outside the loop. I'm not sure if E-Basic will reinitialize the variable each time to zero at the start of the loop, but most programming languages will indeed do this. If this is the case then the lines inside the 'if i1 = 0 then' block will be executed each iteration. However, E-Prime probable doesn't reinitialize i1 to zero again because this would have introduced an infinite loop because the mainstimonset wouldn't grow.
 
The reason for the missing responses in the second part is caused by the continuous reinitialization of the input mask. The solution is the same as for the first loop: place the preparation and execution of mainmask2 before the second loop so it is ran only once. Also configure the input object to accept 2 responses and use InputMaskManager.Responses to extract the RT and RESP values of both responses. An example for this kan be found in the E-Basic help documentation.
 
I also noticed that you used the WritePort command several times in sequence. This is probably required because you immediatly reset the printer port values to zero each time. This will cause VERY short pulses on fast computers. The prefered way is to reset the value to zero after a specific time. (Using sleep() for example.)
Below you fill find some example script, which can be used as starting point. (Note that i wasn't sure about the number of pulses during the target.)
hope this helps
Paul
 
 
Paul Groot
VU University
Amsterdam
The Netherlands
 
'create pulsecount to make sure each pulse is only fired oncedim PulseCount%dim RespCount%dim MainStimOnset as longdim PulseTime as longdim StimDisplayDuration as longConst RefreshDuration% = 20
'''''' at start of experimentwriteport &H378, 0
'''''' script 1mainstimulus.OnsetSignalEnabled = Truemainstimulus.OnsetSignalPort = &H378mainstimulus.OnsetSignalData = &HFF
''''' show targetmainstimulus.duration = StimDisplayDurationmainstimulus.prerelease = mainstimulus.duration'mainstimulus.Filename = c.GetAttrib("mainstimulus")mainstimulus.Loadmainstimulus.Run ' stim onset and first triggerPulseCount = 1MainStimOnset = mainstimulus.OnsetTime c.SetAttrib "PulseTime1", MainStimOnsetc.SetAttrib "mainstimulus.OnsetDelay",mainstimulus.OnsetDelayc.SetAttrib "mainstimulus.OnsetTime", mainstimulus.OnsetTimec.SetAttrib "mainstimulus.PreRelease",mainstimulus.PreReleasedebug.print PulseCount & " onset=" & MainStimOnset
dim nextPulse as longdim waitms as long
'''''' block wave during targetSleep(0.5*RefreshDuration) ' start with high pulse of 50% duty cycledo    ' you can modify the pulse duration by replacing RefreshDuration nextPulse = MainStimOnset + PulseCount*RefreshDuration waitms = nextPulse - clock.read() writeport &H378, 0 if waitms>0 then Sleep(waitms) writeport &H378, &HFF PulseCount = PulseCount + 1 c.SetAttrib "PulseTime" & PulseCount, clock.read() debug.print PulseCount & " onset=" & clock.read() & ", wait=" & waitms Sleep(0.5*RefreshDuration)loop until clock.read() >= MainStimOnset + StimDisplayDuration - RefreshDurationwriteport &H378, 0
'''''' show maskmainmask2.InputMasks.Resetmainmask2EchoClients.RemoveAllmainmask2.InputMasks.Add Keyboard.CreateInputMask("{ANY}", "", CLng("-1"), CLng("2"), ebEndResponseActionNone, CLogical("Yes"), "", "", "ResponseMode:All ProcessBackspace:Yes")mainmask2.Duration = 0mainmask2.Run
'''''' generate remaining pulses and stop after two responsesDim stimDisplayMasks As InputMaskManagerSet stimDisplayMasks = mainmask2.InputMaskswhile PulseCount<5 And stimDisplayMasks.Item(1).Responses.Count<2 ' time between remaining pulses = 5 refreshes ? nextPulse = MainStimOnset + 5*(PulseCount-1)*RefreshDuration  waitms = nextPulse - clock.read() if waitms>0 then Sleep(waitms) WritePort &H378, &HFF PulseCount = PulseCount + 1 c.SetAttrib "PulseTime" & PulseCount, clock.read() debug.print PulseCount & " onset=" & clock.read() & ", wait=" & waitms Sleep(0.5*RefreshDuration) WritePort &H378,0wend' two reponses yet?doloop until stimDisplayMasks.Item(1).Responses.Count = 2' save attributesc.SetAttrib "resp1", stimDisplayMasks.Item(1).Responses(1).RESPc.SetAttrib "rt1", stimDisplayMasks.Item(1).Responses(1).RTc.SetAttrib "resp2", stimDisplayMasks.Item(1).Responses(2).RESPc.SetAttrib "rt2", stimDisplayMasks.Item(1).Responses(2).RTc.SetAttrib "mainmask2.OnsetDelay", mainmask2.OnsetDelayc.SetAttrib "mainmask2.OnsetTime", mainmask2.OnsetTimec.SetAttrib "mainmask2.RESP", mainmask2.RESPc.SetAttrib "mainmask2.CRESP", mainmask2.CRESPc.SetAttrib "mainmask2.ACC", mainmask2.ACC
 
 
 
 
 
 
 



> From: bianca.de-haan at klinikum.uni-tuebingen.de> To: eprime at mail.talkbank.org> Subject: trigger TMS + collect responses during stimulus presentation> Date: Fri, 15 Jun 2007 16:22:19 +0200> > Dear E-prime list,> > I've been racking my brain over this problem longer than I care to think> about, so I hope someone can help me figure this out.> > I want to present a targetstimulus (mainstimulus) followed by a maskstimulus> (mainmask2). Depending on the targetstimulus duration (titrated in a> previous block) an x amount of TMS pulses occur during presentation of the> targetstimulus (first pulse synchronized with stimulus onset) and the> remaining TMS pulses occur during presentation of the maskstimulus.> Furthermore, during presentation of the maskstimulus, I would also like to> be able to collect 2 button presses.> > Mostly, I've managed to get it all to work (see code at the end of this> email). I have put the ImageDisplays of both the targetstimulus and the> mainstimulus under unreferenced objects with a duration of 0, time limit> infinite and end action none. The stimuli are presented correctly and the> tms pulses are fired during stimulus presentation) However, there are 2> problems I can't seem to solve.> > Firstly, the timing seems to be way off. The most critical timing is the> timing of the targetstimulus and the TMS pulses. I have applied all the> tricks in the Timing-chapter of the E-Prime manual. Furthermore, I have run> the RefreshClockTest which shows that my computer is theoretically capable> of achieving millisecond precision. Finally, I calculate the exact Refresh> duration at the start of the experiment (using part of the code of the> RefreshClockTest experiment) and specify all my timings in multiples of the> calculated refresh duration (8.333ms at 120Hz monitor) with half a refresh> duration subtracted to make sure events happen on the exact vertical> refresh. Still, I don't achieve anything near good timing, especially for> the TMS pulses. > > Secondly, during presentation of the maskstimulus it does not register all> button presses. Sometimes a button press is detected, sometimes it's not.> I've had a look at monitoring responses using Inputmasks, but have not been> able to get this to work at all (mainmask2.Inputmasks.(Responses?).RT <> 0> cannot be compiled).> > If anyone can provide me with any tips or tricks as to how to solve these 2> problems, they will earn my eternal gratitude.> > Many thanks,> > Bianca de Haan> > Excerpt of code follows:> ################################################################> > 'create pulsecount to make sure each pulse is only fired once> PulseCount = 1> > do 'start loop that will display mainstimulus till> stimdisplayduration has elapsed> > dim i1 as integer 'start loop counter> > 'draw mainstimulus for infinite duration, terminated by> StimDisplayDuration> mainstimulus.Filename = c.GetAttrib("mainstimulus")> mainstimulus.Load> mainstimulus.Run 
 
 
 
 
> > 'onsettime will only be collected in first loop and first> tms pulse synched with stimulus onset> if i1 = 0 then > MainStimOnset = mainstimulus.OnsetTime > mainstimulus.OnsetSignalEnabled = True> 'send pulse at stimulus onset> mainstimulus.OnsetSignalPort = &H378> mainstimulus.OnsetSignalData = &HFF> 'write time that the pulse was really sent> PulseTime = clock.read()> c.SetAttrib "PulseTime1", PulseTime> 'switch port off again to enable second pulse> writeport &H378, 0> PulseCount = PulseCount + 1> end if> > i1 = i1 + 1> > 'end loop when stimulus duration has elapsed> loop until clock.read() > MainStimOnset + StimDisplayDuration> > > 'create respcount to count the responses> RespCount = 0> 'create place to log the 2 responses> dim resp1 as Integer> dim resp2 as Integer> > do 'start loop that runs mainmask2 until 2 responses are collected> while firing remaining tms pulses> > mainmask2.InputMasks.Reset> mainmask2EchoClients.RemoveAll> mainmask2.InputMasks.Add Keyboard.CreateInputMask("{ANY}",> "", CLng("-1"), CLng("2"), ebEndResponseActionNone, CLogical("Yes"), "", "",> "ResponseMode:All ProcessBackspace:Yes")> mainmask2.Run> c.SetAttrib "mainmask2.OnsetDelay", mainmask2.OnsetDelay> c.SetAttrib "mainmask2.OnsetTime", mainmask2.OnsetTime> c.SetAttrib "mainmask2.RTTime", mainmask2.RTTime> c.SetAttrib "mainmask2.ACC", mainmask2.ACC> c.SetAttrib "mainmask2.RT", mainmask2.RT> c.SetAttrib "mainmask2.RESP", mainmask2.RESP> c.SetAttrib "mainmask2.CRESP", mainmask2.CRESP> > 'fire pulse 2> if clock.read() >= MainStimOnset + (4.5 * RefreshDuration)> and PulseCount = 2 then> WritePort &H378,255> WritePort &H378,255> WritePort &H378,255> PulseTime = clock.read()> c.SetAttrib "PulseTime2", PulseTime> WritePort &H378,0> PulseCount = PulseCount + 1> end if > > 'fire pulse 3> if clock.read() >= MainStimOnset + (9.5 * RefreshDuration)> and PulseCount = 3 then> WritePort &H378,255> WritePort &H378,255> WritePort &H378,255> PulseTime = clock.read()> c.SetAttrib "PulseTime3", PulseTime> WritePort &H378,0> PulseCount = PulseCount + 1> end if > > 'fire pulse 4> if clock.read() >= MainStimOnset + (14.5 * RefreshDuration)> and PulseCount = 4 then> WritePort &H378,255> WritePort &H378,255> WritePort &H378,255> PulseTime = clock.read()> c.SetAttrib "PulseTime4", PulseTime> WritePort &H378,0> PulseCount = PulseCount + 1> end if > > 'fire pulse 5> if clock.read() >= MainStimOnset + (19.5 * RefreshDuration)> and PulseCount = 5 then> WritePort &H378,255> WritePort &H378,255> WritePort &H378,255> PulseTime = clock.read()> c.SetAttrib "PulseTime5", PulseTime> WritePort &H378,0> PulseCount = PulseCount + 1> end if > > 'continuously check whether a response has been made and> then log which> 'response has been made> if mainmask2.RT <> 0 then> RespCount = RespCount + 1> > if RespCount = 1 then> resp1 = mainmask2.RESP> c.SetAttrib "resp1", resp1> elseif RespCount = 2 then> resp2 = mainmask2.RESP> c.SetAttrib "resp2", resp2> 'collate the 2 responses in 1 column so I don't have> to change a previous response assignment> c.SetAttrib "BothResps", resp1 & resp2> end if> > end if> > 'loop until 2 responses are collected> loop until RespCount = 2> > ############################################################################> #> > 
_________________________________________________________________
Jouw nieuws: wereldnieuws! Beleef 't op MSN.nl
http://reporter.msn.nl/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listserv.linguistlist.org/pipermail/eprime/attachments/20070616/e204bfda/attachment.htm>


More information about the Eprime mailing list