yanyan
|
|
Group: Forum Members
Posts: 12,
Visits: 31
|
+x+x+x+x+x+x+x+x+x+xDear all, I have a question about the EEG triggers. I have modified a dot probe task based on the template from milllisecond library. I want to connect it to neuroscan, and I used the <port> to set up triggers. I set multiple triggers in different time points.
For example, I set up three triggers, and the problem is that only the first trigger works ( could be recorded). <trial MS_NA> /ontrialbegin = [values.fixationduration=random(1600,1700,1800,1900,2000,2100,2200)] / ontrialbegin = [values.valid = 0; values.validcorrect = 0; values.trialcount += 1; values.category="MS_NA"] / ontrialbegin = [values.itemnumber = list.mortality_itemnumbers.nextvalue] / ontrialbegin = [values.target_position = list.mortality_positions.nextvalue] / ontrialbegin = [values.congruence = list.mortalityprobe_congruence.nextvalue] / ontrialbegin = [if (values.target_position == 1) {values.mortality_x = values.target_left_x; values.negative_x = values.target_right_x} else {values.mortality_x = values.target_right_x; values.negative_x = values.target_left_x}] / ontrialbegin = [if (values.congruence == 1) {values.probe_x = values.mortality_x} else {values.probe_x = values.negative_x}] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.mortality, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.negative, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime( port.ms_na_word, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(shape.eraser, (values.fixationduration + values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.fixation, (values.fixationduration+values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.probe, (values.fixationduration + values.targetduration ))] / ontrialbegin = [if (values.congruence ==1) trial.MS_NA.insertstimulustime( port.ms_na_con, (values.fixationduration + values.targetduration ))] / ontrialbegin = [if (values.congruence ==2) trial.MS_NA.insertstimulustime( port.ms_na_incon, (values.fixationduration + values.targetduration ))] / ontrialend = [trial.MS_NA.resetstimulusframes()] / stimulusframes = [1 = fixation] / beginresponsetime = values.fixationduration + values.targetduration / responseinterrupt = immediate / isvalidresponse = [trial.MS_NA.response == values.responsekey_left || trial.MS_NA.response == values.responsekey_right] / iscorrectresponse = [(values.probe_x == values.target_left_x && trial.MS_NA.response == values.responsekey_left) || (values.probe_x == values.target_right_x && trial.MS_NA.response == values.responsekey_right)] / ontrialend = [if (trial.MS_NA.latency >= values.minimum_latency) values.valid = 1] / ontrialend = [if (values.valid == 1 && trial.MS_NA.correct) values.validcorrect = 1] / ontrialend = [if (values.validcorrect == 1) {values.sumcorrect += 1; values.sumrt += trial.MS_NA.latency}] / ontrialend = [if (values.congruence == 1) values.count_congruent_MS_NA += 1 else values.count_incongruent_MS_NA += 1] / ontrialend = [if (values.validcorrect == 1 && values.congruence == 1) {values.sumcorrect_congruent_MS_NA += 1; values.sumrt_congruent_MS_NA += trial.MS_NA.latency}] / ontrialend = [if (values.validcorrect == 1 && values.congruence == 2) {values.sumcorrect_incongruent_MS_NA += 1; values.sumrt_incongruent_MS_NA += trial.MS_NA.latency}] / timeout = (values.fixationduration + values.targetduration + values.probeduration) </trial> <port MS_NA_word> / port = LPT1 / subport = data / items = ("00000001") </port> <port MS_NA_con> / port = LPT1 / subport = data / items = ("00000100") <port MS_NA_incon> / port = LPT1 / subport = data / items = ("00000111") </port> Only the MS_NA_word trigger could be recorded in the EEG maker file. The other two are not recorded. Does anyone know why and how to resolve this? Thank you so much! Best, Yan #1: Neuroscan generally requires a specific sequence of triggers sent via different subports. See https://www.millisecond.com/download/library/neuroscan/#2: Even with systems which do not require this specific setup of triggers sent to different subports, what you'lll generally want to do is return to baseline a short time after each individual marker in order to get a clear separation between the (here:three) markers. I.e. do something like <trial MS_NA> ... / ontrialbegin = [trial.MS_NA.insertstimulustime(text.mortality, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.negative, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime( port.ms_na_word, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(port.allbitstolow, values.fixationduration+50)]/ ontrialbegin = [trial.MS_NA.insertstimulustime(shape.eraser, (values.fixationduration + values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.fixation, (values.fixationduration+values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.probe, (values.fixationduration + values.targetduration ))] ... </trial> with <port allbitstolow> / port = LPT1 / subport = data / items = ("00000000")</port> Hope this helps. Hi Dave, It helps. Thank you very much for your quick reply! However, I have met another question about stimulus onset in a Stroop task. I found that when I set /beginresponsetime, the actual stimulus onset recorded in the data file is 20 but not 0. Where is the delay from? Then I'm not sure the EEG trigger of the stimulus onset is sent at 0 time point or at the 20? I mean, is the trigger also delay 20 ms as the actual onset? When I delete the /beginresponsetime, the stimulus onset is 0. But there is a problem that some responses are not recorded (as 0 in data file, I am sure I have made valid response), especially for those too fast response. <trial NeutralWord> /ontrialbegin = [values.fixationcrosspresentationtime=random(1500,1600,1700,1800,1900,2000)] / ontrialbegin = [trial.neutralword.insertstimulustime( port.allbitstolow,50)] /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] / isvalidresponse = [trial.NeutralWord.response == values.keyred || trial.NeutralWord.response == values.keyblue] /monkeyresponse = (33, 36) /iscorrectresponse = [(text.NeutralWord.textcolor == red && trial.NeutralWord.response == values.keyred) || (text.NeutralWord.textcolor == blue && trial.NeutralWord.response == values.keyblue)] /errormessage = ( errorneutral,0) /correctmessage = ( correctneutral,0) /ontrialend = [trial.NeutralWord.resetstimulusframes()] /ontrialend = [values.target = text.NeutralWord.currentitem] /ontrialend = [if (text.NeutralWord.textcolor == red) values.color = "red" else if (text.NeutralWord.textcolor == blue) values.color = "blue"] /ontrialend = [if (trial.NeutralWord.correct) {values.correct_neutralwords += 1; values.sumrt_neu += trial.neutralword.latency}] /trialduration = (values.fixationcrosspresentationtime+400) /responseinterrupt = frames /beginresponsetime = 0</trial> with <port neutralsignal> / port = LPT1 / subport = data / items = ("00000011") </port> <port correctneutral> / port = LPT1 / subport = data / items = ("00001001") </port> <port errorneutral> / port = LPT1 / subport = data / items = ("00000110") </port> <port allbitstolow> / port = LPT1 / subport = data / items = ("00000000") </port> Also, as in my code, is that correct way to send correct or error response trigger by /correctmessage and /errormessage? Cheers, Yan > Where is the delay from? It's possible that the additional overhead caused by initializing the the response listener at the very start causes the trial to miss the 1st frame for stimulus display. I.e., the first opportunity to to "catch" the beginning of a new display refresh cycle and draw stimuli would be the 2nd frame. On a display running at 50Hz, the 2nd frame would start at 20ms which would be consistent with the 20ms onset delay you observed. > I mean, is the trigger also delay 20 ms as the actual onset? Yes, the port signals are locked to refresh cycles just like any visual stimuli (<text>, <picture>, etc.). I.e., despite the 20ms delay the TTL signal would still be in sync with the visual stimuli. > Also, as in my code, is that correct way to send correct or error response trigger by /correctmessage and /errormessage? Yes, it's generally correct, although you *may* not want to use a value of 0 for the duration. I'd instead pick a value high enough to ensure the signal is raised long enough to be picked up reliably by your external equipment. E.g. /correctmessage = ( correctneutral,50) You can also use /responsemessage attributes instead of or in addition to /errormessage and /correctmessage. A <trial> may only have one /errormessage attribute and one /correctmessage attribute, but you may define multiple /responsemessage attributes. Thank you so much for your reply, Dave! So the 20ms delay doesn't matter given that the TTL signal would still be in sync with the visual stimuli, right? Also, when I set /correctmessage = (correctneutral, 50), is the response trigger immediately sent once correct response made? I mean, would there be any delay of the trigger which "may" caused by the duration of 50? Cheers, Yan > So the 20ms delay doesn't matter given that the TTL signal would still be in sync with the visual stimuli, right? Yes. In terms of synchronization between the TTL signal and the visual stimuli, it should not matter. > /correctmessage = (correctneutral, 50), is the response trigger immediately sent once correct response made? Since your <trial> is set to /responseinterrupt = frames the response trigger would not necessarily be sent immediately upon response. If the response occurred prior to the stimulus presentation sequence finishing /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] i.e. before 400ms, the trial would first finish the presentation sequence and only *then* execute /correctmessage. If the response occurred only after the presentation of all stimuli, i.e. after ~400ms, /correctmessage would be executed immediately upon registering the response. Many thanks, Dave! Well, that's a problem, because I have to send response trigger immediately when response occurs, (i.e, including response before 400 ms). Then I prefer not using /responseinterrupt = frames and /beginresponsetime = 0 in my code. However, when I delete these two attributes, many of my responses are not recorded in my data file. That is, these responses are recorded as 0, while I am sure I have made responses. It seems would happen when I respond very fast (maybe before 400 ms?). Why these responses could not been recorded? Do you know how to fix this problem? Best, Yan By default, Inquisit starts listening for responses once all stimuli have been presented. I.e. with /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] and no /beginresponsetime attribute specified, response logging would only begin 400ms into the trial -- once blank, fixation, ..., havce been displayed. What you'll want to do if you *need* the trigger sent directly upon response *and* want to consider responses made from the start, you should specify / beginresponsetime = 0 and / responseinterrupt = immediate The consequence of this, however, will be that /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] blank, fixation, redreminder and bluereminder will *not* be displayed *if* the response occurs before the 400ms mark. Thank you, Dave! I understand. However, I need the blank, fixation, redreminder, bluereminder to be displayed after response, so I think I still need to use the / beginresponsetime = 0and / responseinterrupt = frame
However, I changed a way to send response trigger: <trial NeutralWord> /ontrialbegin = [values.fixationcrosspresentationtime=random(1500,1600,1700,1800,1900,2000)] /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] / isvalidresponse = [trial.NeutralWord.response == values.keyred || trial.NeutralWord.response == values.keyblue] /monkeyresponse = (33, 36) /iscorrectresponse = [(text.NeutralWord.textcolor == red && trial.NeutralWord.response == values.keyred) || (text.NeutralWord.textcolor == blue && trial.NeutralWord.response == values.keyblue)] /ontrialbegin = [if(trial.neutralword.correct) trial.neutralword.insertstimulustime( port.correctneutral,trial.neutralword.latency)] /ontrialbegin = [if(trial.neutralword.error) trial.neutralword.insertstimulustime( port.errorneutral,trial.neutralword.latency)] /ontrialend = [trial.NeutralWord.resetstimulusframes()] /ontrialend = [values.target = text.NeutralWord.currentitem] /ontrialend = [if (text.NeutralWord.textcolor == red) values.color = "red" else if (text.NeutralWord.textcolor == blue) values.color = "blue"] /ontrialend = [if (trial.NeutralWord.correct) {values.correct_neutralwords += 1; values.sumrt_neu += trial.neutralword.latency}] /trialduration = (values.fixationcrosspresentationtime+400) / beginresponsetime = 0/ responseinterrupt = frame</trial> Is that a correct way to send response trigger immediately when a response occurs (i.e., based on latency)? Best, Yan /ontrialbegin = [if(trial.neutralword.correct) trial.neutralword.insertstimulustime( port.correctneutral,trial.neutralword.latency)] /ontrialbegin = [if(trial.neutralword.error) trial.neutralword.insertstimulustime( port.errorneutral,trial.neutralword.latency)] That cannot possibly work. Whether the response will be correct and at what time it will correct is simply _not known_ at the start of the trial (/ontrialbegin). This will *not* send response triggers in any sensible way. You _ought to_ use /correctmessage and /errormessage for that AND you ought to set /responseinterrupt to immediate if you want them without delay no matter when the response occurs. What you can do to have blank, fixation, redreminder, bluereminder displayed if a response occurs before 400ms -- the time they would normally be displayed -- is use /responsemessage attributes to display them. Thanks, Dave. It seems a good way to set /responsemessage to display the remaining stimuli after response (i.e.., blank, fixation, redreminder, bluereminder).However, there is a problem. The stimuli 0= neutralword should been displayed for 400 ms. If I set as you said, it would disappear immediately after response made before 400 ms. Do you know how to resolve this? Cheers, Yan
|
|
|
Dave
|
|
Group: Administrators
Posts: 13K,
Visits: 104K
|
+x+x+x+x+x+x+x+x+x+x+xDear all, I have a question about the EEG triggers. I have modified a dot probe task based on the template from milllisecond library. I want to connect it to neuroscan, and I used the <port> to set up triggers. I set multiple triggers in different time points.
For example, I set up three triggers, and the problem is that only the first trigger works ( could be recorded). <trial MS_NA> /ontrialbegin = [values.fixationduration=random(1600,1700,1800,1900,2000,2100,2200)] / ontrialbegin = [values.valid = 0; values.validcorrect = 0; values.trialcount += 1; values.category="MS_NA"] / ontrialbegin = [values.itemnumber = list.mortality_itemnumbers.nextvalue] / ontrialbegin = [values.target_position = list.mortality_positions.nextvalue] / ontrialbegin = [values.congruence = list.mortalityprobe_congruence.nextvalue] / ontrialbegin = [if (values.target_position == 1) {values.mortality_x = values.target_left_x; values.negative_x = values.target_right_x} else {values.mortality_x = values.target_right_x; values.negative_x = values.target_left_x}] / ontrialbegin = [if (values.congruence == 1) {values.probe_x = values.mortality_x} else {values.probe_x = values.negative_x}] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.mortality, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.negative, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime( port.ms_na_word, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(shape.eraser, (values.fixationduration + values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.fixation, (values.fixationduration+values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.probe, (values.fixationduration + values.targetduration ))] / ontrialbegin = [if (values.congruence ==1) trial.MS_NA.insertstimulustime( port.ms_na_con, (values.fixationduration + values.targetduration ))] / ontrialbegin = [if (values.congruence ==2) trial.MS_NA.insertstimulustime( port.ms_na_incon, (values.fixationduration + values.targetduration ))] / ontrialend = [trial.MS_NA.resetstimulusframes()] / stimulusframes = [1 = fixation] / beginresponsetime = values.fixationduration + values.targetduration / responseinterrupt = immediate / isvalidresponse = [trial.MS_NA.response == values.responsekey_left || trial.MS_NA.response == values.responsekey_right] / iscorrectresponse = [(values.probe_x == values.target_left_x && trial.MS_NA.response == values.responsekey_left) || (values.probe_x == values.target_right_x && trial.MS_NA.response == values.responsekey_right)] / ontrialend = [if (trial.MS_NA.latency >= values.minimum_latency) values.valid = 1] / ontrialend = [if (values.valid == 1 && trial.MS_NA.correct) values.validcorrect = 1] / ontrialend = [if (values.validcorrect == 1) {values.sumcorrect += 1; values.sumrt += trial.MS_NA.latency}] / ontrialend = [if (values.congruence == 1) values.count_congruent_MS_NA += 1 else values.count_incongruent_MS_NA += 1] / ontrialend = [if (values.validcorrect == 1 && values.congruence == 1) {values.sumcorrect_congruent_MS_NA += 1; values.sumrt_congruent_MS_NA += trial.MS_NA.latency}] / ontrialend = [if (values.validcorrect == 1 && values.congruence == 2) {values.sumcorrect_incongruent_MS_NA += 1; values.sumrt_incongruent_MS_NA += trial.MS_NA.latency}] / timeout = (values.fixationduration + values.targetduration + values.probeduration) </trial> <port MS_NA_word> / port = LPT1 / subport = data / items = ("00000001") </port> <port MS_NA_con> / port = LPT1 / subport = data / items = ("00000100") <port MS_NA_incon> / port = LPT1 / subport = data / items = ("00000111") </port> Only the MS_NA_word trigger could be recorded in the EEG maker file. The other two are not recorded. Does anyone know why and how to resolve this? Thank you so much! Best, Yan #1: Neuroscan generally requires a specific sequence of triggers sent via different subports. See https://www.millisecond.com/download/library/neuroscan/#2: Even with systems which do not require this specific setup of triggers sent to different subports, what you'lll generally want to do is return to baseline a short time after each individual marker in order to get a clear separation between the (here:three) markers. I.e. do something like <trial MS_NA> ... / ontrialbegin = [trial.MS_NA.insertstimulustime(text.mortality, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.negative, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime( port.ms_na_word, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(port.allbitstolow, values.fixationduration+50)]/ ontrialbegin = [trial.MS_NA.insertstimulustime(shape.eraser, (values.fixationduration + values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.fixation, (values.fixationduration+values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.probe, (values.fixationduration + values.targetduration ))] ... </trial> with <port allbitstolow> / port = LPT1 / subport = data / items = ("00000000")</port> Hope this helps. Hi Dave, It helps. Thank you very much for your quick reply! However, I have met another question about stimulus onset in a Stroop task. I found that when I set /beginresponsetime, the actual stimulus onset recorded in the data file is 20 but not 0. Where is the delay from? Then I'm not sure the EEG trigger of the stimulus onset is sent at 0 time point or at the 20? I mean, is the trigger also delay 20 ms as the actual onset? When I delete the /beginresponsetime, the stimulus onset is 0. But there is a problem that some responses are not recorded (as 0 in data file, I am sure I have made valid response), especially for those too fast response. <trial NeutralWord> /ontrialbegin = [values.fixationcrosspresentationtime=random(1500,1600,1700,1800,1900,2000)] / ontrialbegin = [trial.neutralword.insertstimulustime( port.allbitstolow,50)] /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] / isvalidresponse = [trial.NeutralWord.response == values.keyred || trial.NeutralWord.response == values.keyblue] /monkeyresponse = (33, 36) /iscorrectresponse = [(text.NeutralWord.textcolor == red && trial.NeutralWord.response == values.keyred) || (text.NeutralWord.textcolor == blue && trial.NeutralWord.response == values.keyblue)] /errormessage = ( errorneutral,0) /correctmessage = ( correctneutral,0) /ontrialend = [trial.NeutralWord.resetstimulusframes()] /ontrialend = [values.target = text.NeutralWord.currentitem] /ontrialend = [if (text.NeutralWord.textcolor == red) values.color = "red" else if (text.NeutralWord.textcolor == blue) values.color = "blue"] /ontrialend = [if (trial.NeutralWord.correct) {values.correct_neutralwords += 1; values.sumrt_neu += trial.neutralword.latency}] /trialduration = (values.fixationcrosspresentationtime+400) /responseinterrupt = frames /beginresponsetime = 0</trial> with <port neutralsignal> / port = LPT1 / subport = data / items = ("00000011") </port> <port correctneutral> / port = LPT1 / subport = data / items = ("00001001") </port> <port errorneutral> / port = LPT1 / subport = data / items = ("00000110") </port> <port allbitstolow> / port = LPT1 / subport = data / items = ("00000000") </port> Also, as in my code, is that correct way to send correct or error response trigger by /correctmessage and /errormessage? Cheers, Yan > Where is the delay from? It's possible that the additional overhead caused by initializing the the response listener at the very start causes the trial to miss the 1st frame for stimulus display. I.e., the first opportunity to to "catch" the beginning of a new display refresh cycle and draw stimuli would be the 2nd frame. On a display running at 50Hz, the 2nd frame would start at 20ms which would be consistent with the 20ms onset delay you observed. > I mean, is the trigger also delay 20 ms as the actual onset? Yes, the port signals are locked to refresh cycles just like any visual stimuli (<text>, <picture>, etc.). I.e., despite the 20ms delay the TTL signal would still be in sync with the visual stimuli. > Also, as in my code, is that correct way to send correct or error response trigger by /correctmessage and /errormessage? Yes, it's generally correct, although you *may* not want to use a value of 0 for the duration. I'd instead pick a value high enough to ensure the signal is raised long enough to be picked up reliably by your external equipment. E.g. /correctmessage = ( correctneutral,50) You can also use /responsemessage attributes instead of or in addition to /errormessage and /correctmessage. A <trial> may only have one /errormessage attribute and one /correctmessage attribute, but you may define multiple /responsemessage attributes. Thank you so much for your reply, Dave! So the 20ms delay doesn't matter given that the TTL signal would still be in sync with the visual stimuli, right? Also, when I set /correctmessage = (correctneutral, 50), is the response trigger immediately sent once correct response made? I mean, would there be any delay of the trigger which "may" caused by the duration of 50? Cheers, Yan > So the 20ms delay doesn't matter given that the TTL signal would still be in sync with the visual stimuli, right? Yes. In terms of synchronization between the TTL signal and the visual stimuli, it should not matter. > /correctmessage = (correctneutral, 50), is the response trigger immediately sent once correct response made? Since your <trial> is set to /responseinterrupt = frames the response trigger would not necessarily be sent immediately upon response. If the response occurred prior to the stimulus presentation sequence finishing /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] i.e. before 400ms, the trial would first finish the presentation sequence and only *then* execute /correctmessage. If the response occurred only after the presentation of all stimuli, i.e. after ~400ms, /correctmessage would be executed immediately upon registering the response. Many thanks, Dave! Well, that's a problem, because I have to send response trigger immediately when response occurs, (i.e, including response before 400 ms). Then I prefer not using /responseinterrupt = frames and /beginresponsetime = 0 in my code. However, when I delete these two attributes, many of my responses are not recorded in my data file. That is, these responses are recorded as 0, while I am sure I have made responses. It seems would happen when I respond very fast (maybe before 400 ms?). Why these responses could not been recorded? Do you know how to fix this problem? Best, Yan By default, Inquisit starts listening for responses once all stimuli have been presented. I.e. with /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] and no /beginresponsetime attribute specified, response logging would only begin 400ms into the trial -- once blank, fixation, ..., havce been displayed. What you'll want to do if you *need* the trigger sent directly upon response *and* want to consider responses made from the start, you should specify / beginresponsetime = 0 and / responseinterrupt = immediate The consequence of this, however, will be that /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] blank, fixation, redreminder and bluereminder will *not* be displayed *if* the response occurs before the 400ms mark. Thank you, Dave! I understand. However, I need the blank, fixation, redreminder, bluereminder to be displayed after response, so I think I still need to use the / beginresponsetime = 0and / responseinterrupt = frame
However, I changed a way to send response trigger: <trial NeutralWord> /ontrialbegin = [values.fixationcrosspresentationtime=random(1500,1600,1700,1800,1900,2000)] /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] / isvalidresponse = [trial.NeutralWord.response == values.keyred || trial.NeutralWord.response == values.keyblue] /monkeyresponse = (33, 36) /iscorrectresponse = [(text.NeutralWord.textcolor == red && trial.NeutralWord.response == values.keyred) || (text.NeutralWord.textcolor == blue && trial.NeutralWord.response == values.keyblue)] /ontrialbegin = [if(trial.neutralword.correct) trial.neutralword.insertstimulustime( port.correctneutral,trial.neutralword.latency)] /ontrialbegin = [if(trial.neutralword.error) trial.neutralword.insertstimulustime( port.errorneutral,trial.neutralword.latency)] /ontrialend = [trial.NeutralWord.resetstimulusframes()] /ontrialend = [values.target = text.NeutralWord.currentitem] /ontrialend = [if (text.NeutralWord.textcolor == red) values.color = "red" else if (text.NeutralWord.textcolor == blue) values.color = "blue"] /ontrialend = [if (trial.NeutralWord.correct) {values.correct_neutralwords += 1; values.sumrt_neu += trial.neutralword.latency}] /trialduration = (values.fixationcrosspresentationtime+400) / beginresponsetime = 0/ responseinterrupt = frame</trial> Is that a correct way to send response trigger immediately when a response occurs (i.e., based on latency)? Best, Yan /ontrialbegin = [if(trial.neutralword.correct) trial.neutralword.insertstimulustime( port.correctneutral,trial.neutralword.latency)] /ontrialbegin = [if(trial.neutralword.error) trial.neutralword.insertstimulustime( port.errorneutral,trial.neutralword.latency)] That cannot possibly work. Whether the response will be correct and at what time it will correct is simply _not known_ at the start of the trial (/ontrialbegin). This will *not* send response triggers in any sensible way. You _ought to_ use /correctmessage and /errormessage for that AND you ought to set /responseinterrupt to immediate if you want them without delay no matter when the response occurs. What you can do to have blank, fixation, redreminder, bluereminder displayed if a response occurs before 400ms -- the time they would normally be displayed -- is use /responsemessage attributes to display them. Thanks, Dave. It seems a good way to set /responsemessage to display the remaining stimuli after response (i.e.., blank, fixation, redreminder, bluereminder).However, there is a problem. The stimuli 0= neutralword should been displayed for 400 ms. If I set as you said, it would disappear immediately after response made before 400 ms. Do you know how to resolve this? Cheers, Yan > If I set as you said, it would disappear immediately after response made before 400 ms. Yes, that is correct. > Do you know how to resolve this? No, I cannot think of a way.
|
|
|
yanyan
|
|
Group: Forum Members
Posts: 12,
Visits: 31
|
+x+x+x+x+x+x+x+x+x+x+x+xDear all, I have a question about the EEG triggers. I have modified a dot probe task based on the template from milllisecond library. I want to connect it to neuroscan, and I used the <port> to set up triggers. I set multiple triggers in different time points.
For example, I set up three triggers, and the problem is that only the first trigger works ( could be recorded). <trial MS_NA> /ontrialbegin = [values.fixationduration=random(1600,1700,1800,1900,2000,2100,2200)] / ontrialbegin = [values.valid = 0; values.validcorrect = 0; values.trialcount += 1; values.category="MS_NA"] / ontrialbegin = [values.itemnumber = list.mortality_itemnumbers.nextvalue] / ontrialbegin = [values.target_position = list.mortality_positions.nextvalue] / ontrialbegin = [values.congruence = list.mortalityprobe_congruence.nextvalue] / ontrialbegin = [if (values.target_position == 1) {values.mortality_x = values.target_left_x; values.negative_x = values.target_right_x} else {values.mortality_x = values.target_right_x; values.negative_x = values.target_left_x}] / ontrialbegin = [if (values.congruence == 1) {values.probe_x = values.mortality_x} else {values.probe_x = values.negative_x}] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.mortality, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.negative, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime( port.ms_na_word, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(shape.eraser, (values.fixationduration + values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.fixation, (values.fixationduration+values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.probe, (values.fixationduration + values.targetduration ))] / ontrialbegin = [if (values.congruence ==1) trial.MS_NA.insertstimulustime( port.ms_na_con, (values.fixationduration + values.targetduration ))] / ontrialbegin = [if (values.congruence ==2) trial.MS_NA.insertstimulustime( port.ms_na_incon, (values.fixationduration + values.targetduration ))] / ontrialend = [trial.MS_NA.resetstimulusframes()] / stimulusframes = [1 = fixation] / beginresponsetime = values.fixationduration + values.targetduration / responseinterrupt = immediate / isvalidresponse = [trial.MS_NA.response == values.responsekey_left || trial.MS_NA.response == values.responsekey_right] / iscorrectresponse = [(values.probe_x == values.target_left_x && trial.MS_NA.response == values.responsekey_left) || (values.probe_x == values.target_right_x && trial.MS_NA.response == values.responsekey_right)] / ontrialend = [if (trial.MS_NA.latency >= values.minimum_latency) values.valid = 1] / ontrialend = [if (values.valid == 1 && trial.MS_NA.correct) values.validcorrect = 1] / ontrialend = [if (values.validcorrect == 1) {values.sumcorrect += 1; values.sumrt += trial.MS_NA.latency}] / ontrialend = [if (values.congruence == 1) values.count_congruent_MS_NA += 1 else values.count_incongruent_MS_NA += 1] / ontrialend = [if (values.validcorrect == 1 && values.congruence == 1) {values.sumcorrect_congruent_MS_NA += 1; values.sumrt_congruent_MS_NA += trial.MS_NA.latency}] / ontrialend = [if (values.validcorrect == 1 && values.congruence == 2) {values.sumcorrect_incongruent_MS_NA += 1; values.sumrt_incongruent_MS_NA += trial.MS_NA.latency}] / timeout = (values.fixationduration + values.targetduration + values.probeduration) </trial> <port MS_NA_word> / port = LPT1 / subport = data / items = ("00000001") </port> <port MS_NA_con> / port = LPT1 / subport = data / items = ("00000100") <port MS_NA_incon> / port = LPT1 / subport = data / items = ("00000111") </port> Only the MS_NA_word trigger could be recorded in the EEG maker file. The other two are not recorded. Does anyone know why and how to resolve this? Thank you so much! Best, Yan #1: Neuroscan generally requires a specific sequence of triggers sent via different subports. See https://www.millisecond.com/download/library/neuroscan/#2: Even with systems which do not require this specific setup of triggers sent to different subports, what you'lll generally want to do is return to baseline a short time after each individual marker in order to get a clear separation between the (here:three) markers. I.e. do something like <trial MS_NA> ... / ontrialbegin = [trial.MS_NA.insertstimulustime(text.mortality, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.negative, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime( port.ms_na_word, values.fixationduration)] / ontrialbegin = [trial.MS_NA.insertstimulustime(port.allbitstolow, values.fixationduration+50)]/ ontrialbegin = [trial.MS_NA.insertstimulustime(shape.eraser, (values.fixationduration + values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.fixation, (values.fixationduration+values.targetduration))] / ontrialbegin = [trial.MS_NA.insertstimulustime(text.probe, (values.fixationduration + values.targetduration ))] ... </trial> with <port allbitstolow> / port = LPT1 / subport = data / items = ("00000000")</port> Hope this helps. Hi Dave, It helps. Thank you very much for your quick reply! However, I have met another question about stimulus onset in a Stroop task. I found that when I set /beginresponsetime, the actual stimulus onset recorded in the data file is 20 but not 0. Where is the delay from? Then I'm not sure the EEG trigger of the stimulus onset is sent at 0 time point or at the 20? I mean, is the trigger also delay 20 ms as the actual onset? When I delete the /beginresponsetime, the stimulus onset is 0. But there is a problem that some responses are not recorded (as 0 in data file, I am sure I have made valid response), especially for those too fast response. <trial NeutralWord> /ontrialbegin = [values.fixationcrosspresentationtime=random(1500,1600,1700,1800,1900,2000)] / ontrialbegin = [trial.neutralword.insertstimulustime( port.allbitstolow,50)] /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] / isvalidresponse = [trial.NeutralWord.response == values.keyred || trial.NeutralWord.response == values.keyblue] /monkeyresponse = (33, 36) /iscorrectresponse = [(text.NeutralWord.textcolor == red && trial.NeutralWord.response == values.keyred) || (text.NeutralWord.textcolor == blue && trial.NeutralWord.response == values.keyblue)] /errormessage = ( errorneutral,0) /correctmessage = ( correctneutral,0) /ontrialend = [trial.NeutralWord.resetstimulusframes()] /ontrialend = [values.target = text.NeutralWord.currentitem] /ontrialend = [if (text.NeutralWord.textcolor == red) values.color = "red" else if (text.NeutralWord.textcolor == blue) values.color = "blue"] /ontrialend = [if (trial.NeutralWord.correct) {values.correct_neutralwords += 1; values.sumrt_neu += trial.neutralword.latency}] /trialduration = (values.fixationcrosspresentationtime+400) /responseinterrupt = frames /beginresponsetime = 0</trial> with <port neutralsignal> / port = LPT1 / subport = data / items = ("00000011") </port> <port correctneutral> / port = LPT1 / subport = data / items = ("00001001") </port> <port errorneutral> / port = LPT1 / subport = data / items = ("00000110") </port> <port allbitstolow> / port = LPT1 / subport = data / items = ("00000000") </port> Also, as in my code, is that correct way to send correct or error response trigger by /correctmessage and /errormessage? Cheers, Yan > Where is the delay from? It's possible that the additional overhead caused by initializing the the response listener at the very start causes the trial to miss the 1st frame for stimulus display. I.e., the first opportunity to to "catch" the beginning of a new display refresh cycle and draw stimuli would be the 2nd frame. On a display running at 50Hz, the 2nd frame would start at 20ms which would be consistent with the 20ms onset delay you observed. > I mean, is the trigger also delay 20 ms as the actual onset? Yes, the port signals are locked to refresh cycles just like any visual stimuli (<text>, <picture>, etc.). I.e., despite the 20ms delay the TTL signal would still be in sync with the visual stimuli. > Also, as in my code, is that correct way to send correct or error response trigger by /correctmessage and /errormessage? Yes, it's generally correct, although you *may* not want to use a value of 0 for the duration. I'd instead pick a value high enough to ensure the signal is raised long enough to be picked up reliably by your external equipment. E.g. /correctmessage = ( correctneutral,50) You can also use /responsemessage attributes instead of or in addition to /errormessage and /correctmessage. A <trial> may only have one /errormessage attribute and one /correctmessage attribute, but you may define multiple /responsemessage attributes. Thank you so much for your reply, Dave! So the 20ms delay doesn't matter given that the TTL signal would still be in sync with the visual stimuli, right? Also, when I set /correctmessage = (correctneutral, 50), is the response trigger immediately sent once correct response made? I mean, would there be any delay of the trigger which "may" caused by the duration of 50? Cheers, Yan > So the 20ms delay doesn't matter given that the TTL signal would still be in sync with the visual stimuli, right? Yes. In terms of synchronization between the TTL signal and the visual stimuli, it should not matter. > /correctmessage = (correctneutral, 50), is the response trigger immediately sent once correct response made? Since your <trial> is set to /responseinterrupt = frames the response trigger would not necessarily be sent immediately upon response. If the response occurred prior to the stimulus presentation sequence finishing /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] i.e. before 400ms, the trial would first finish the presentation sequence and only *then* execute /correctmessage. If the response occurred only after the presentation of all stimuli, i.e. after ~400ms, /correctmessage would be executed immediately upon registering the response. Many thanks, Dave! Well, that's a problem, because I have to send response trigger immediately when response occurs, (i.e, including response before 400 ms). Then I prefer not using /responseinterrupt = frames and /beginresponsetime = 0 in my code. However, when I delete these two attributes, many of my responses are not recorded in my data file. That is, these responses are recorded as 0, while I am sure I have made responses. It seems would happen when I respond very fast (maybe before 400 ms?). Why these responses could not been recorded? Do you know how to fix this problem? Best, Yan By default, Inquisit starts listening for responses once all stimuli have been presented. I.e. with /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] and no /beginresponsetime attribute specified, response logging would only begin 400ms into the trial -- once blank, fixation, ..., havce been displayed. What you'll want to do if you *need* the trigger sent directly upon response *and* want to consider responses made from the start, you should specify / beginresponsetime = 0 and / responseinterrupt = immediate The consequence of this, however, will be that /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] blank, fixation, redreminder and bluereminder will *not* be displayed *if* the response occurs before the 400ms mark. Thank you, Dave! I understand. However, I need the blank, fixation, redreminder, bluereminder to be displayed after response, so I think I still need to use the / beginresponsetime = 0and / responseinterrupt = frame
However, I changed a way to send response trigger: <trial NeutralWord> /ontrialbegin = [values.fixationcrosspresentationtime=random(1500,1600,1700,1800,1900,2000)] /stimulustimes = [0=neutralword, neutralsignal, redreminder, bluereminder; 400=blank, fixation, redreminder, bluereminder] / isvalidresponse = [trial.NeutralWord.response == values.keyred || trial.NeutralWord.response == values.keyblue] /monkeyresponse = (33, 36) /iscorrectresponse = [(text.NeutralWord.textcolor == red && trial.NeutralWord.response == values.keyred) || (text.NeutralWord.textcolor == blue && trial.NeutralWord.response == values.keyblue)] /ontrialbegin = [if(trial.neutralword.correct) trial.neutralword.insertstimulustime( port.correctneutral,trial.neutralword.latency)] /ontrialbegin = [if(trial.neutralword.error) trial.neutralword.insertstimulustime( port.errorneutral,trial.neutralword.latency)] /ontrialend = [trial.NeutralWord.resetstimulusframes()] /ontrialend = [values.target = text.NeutralWord.currentitem] /ontrialend = [if (text.NeutralWord.textcolor == red) values.color = "red" else if (text.NeutralWord.textcolor == blue) values.color = "blue"] /ontrialend = [if (trial.NeutralWord.correct) {values.correct_neutralwords += 1; values.sumrt_neu += trial.neutralword.latency}] /trialduration = (values.fixationcrosspresentationtime+400) / beginresponsetime = 0/ responseinterrupt = frame</trial> Is that a correct way to send response trigger immediately when a response occurs (i.e., based on latency)? Best, Yan /ontrialbegin = [if(trial.neutralword.correct) trial.neutralword.insertstimulustime( port.correctneutral,trial.neutralword.latency)] /ontrialbegin = [if(trial.neutralword.error) trial.neutralword.insertstimulustime( port.errorneutral,trial.neutralword.latency)] That cannot possibly work. Whether the response will be correct and at what time it will correct is simply _not known_ at the start of the trial (/ontrialbegin). This will *not* send response triggers in any sensible way. You _ought to_ use /correctmessage and /errormessage for that AND you ought to set /responseinterrupt to immediate if you want them without delay no matter when the response occurs. What you can do to have blank, fixation, redreminder, bluereminder displayed if a response occurs before 400ms -- the time they would normally be displayed -- is use /responsemessage attributes to display them. Thanks, Dave. It seems a good way to set /responsemessage to display the remaining stimuli after response (i.e.., blank, fixation, redreminder, bluereminder).However, there is a problem. The stimuli 0= neutralword should been displayed for 400 ms. If I set as you said, it would disappear immediately after response made before 400 ms. Do you know how to resolve this? Cheers, Yan > If I set as you said, it would disappear immediately after response made before 400 ms. Yes, that is correct. > Do you know how to resolve this? No, I cannot think of a way. Anyway, thank you very much, Dave! Best, Yan
|
|
|