Can we randomize time with newTimer() ?

PennController for IBEX Forums Support Can we randomize time with newTimer() ?

Viewing 15 posts - 1 through 15 (of 59 total)
  • Author
    Posts
  • #7872
    Larissa_Cury
    Participant

    Hello, everyone!

    I’m wondering two things about NewTimer:

    a) Is it possible to randomize time? I mean, in the code below I need to estabilish D1 to be randomly from 1000 to 1600 milisseconds, how can I do that?
    I’ve tried newTimer(“timer-D1”, 1000, 1600) and It didn’t give me any bugs, but I’m wondering if it’s actually working

    b) Is it possible to force my partipant to answer within a pre-determined timer? In my case, I need to estabilish that she or he will press either K or S within 1700 milisseconds. (let’s call this RT)

    c) Is it possible to estabilish a timer based on a previous one? In my case, I need wait-separacao to be 3500 – RT – timer-D1

    Template("tabela-target.csv" , row => 
        newTrial("trial_1_no_cue_DOWN",
    defaultText
            .center()
           .cssContainer({"position": "absolute",
                          "top": "50%",
                          "left": "50%",
                          "transform": "translate(-50%, +50%)"})
            .print()
    ,
        newText("D1", "<br><b>+</b>")
        .cssContainer({
        "font-size":"100px",
        "color":"blue"})
        .center()
        .print()
    ,
       newTimer("timer-D1",1000)
        .start()
        .wait()
    ,
       getText("D1")
       .remove()
    ,
    newText("cue", "<br> <b>+</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"green"})
       .center()
       .print()
    ,
        newTimer("timer_cue_D2",100)
        .start()
        .wait()
    ,
       getText("cue","D2")
       .remove()
    ,
       newText("D3", "<br> <b>+</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"pink"})
       .center()
       .print()
    ,
       newTimer("timer_D3",400)
        .start()
        .wait()
    ,
       getText("D3")
       .remove()
    ,
        newImage("imagens", row.imagem)
        .size(500, 200)
    ,
    newText("cruz_central", "<br> <b>+</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"black"})
       .center()
       .print()
    ,
        //para baixo//
        newCanvas("center", 150,150)
        .add( "center at 50%" , "center at 50%" , getImage("imagens"))
        .cssContainer({
        "position": "absolute",
        "margin-top": "340px"})
        .center()
        .log()
        .print()
    ,
        newKey("keypress1","SK")
        .wait()
        .log()
    ,
         getText("cruz_central")
        .remove()
    ,
        getCanvas("center")
        .remove()
    ,
        newText("separacao", "<br> <b>+</b>")
       .cssContainer({
        "font-size":"100px",
        "color":"yellow"})
       .center()
       .print()
    ,
        newTimer("wait-separacao",2500)
        .start()
        .wait()
    )
       .log("imagens", row.imagem)
       .log("item", row.versao)
    );

    This is the code for my project: https://farm.pcibex.net/r/OIkUNc/
    I’ve made a post earlier on asking how to center things, but I already solved that, but I didn’t know how to delete my post, so I’m sorry for overposting…

    Thanks in advance!!!

    #7881
    Jeremy
    Keymaster

    Hi Larissa,

    a) See my answer on this thread

    b) See the code in this message for an illustration of a timeout implementation. The basic idea is: start a Timer element, create (and print, if applicable) your interactive element and make sure to .log() it, wait for the Timer to elapse, then disable/remove the interactive element

    c) Just set separacao to 3500 and start it before timer-D1, but only wait for it at the end of the trial, eg:

    newTrial(
      newText("instructions", "Quick! Press F or J now!").print()
      ,
      newTimer("separacao", 3500)
      ,
      newTimer("timer-D1", 1000+Math.round(600*Math.random()) ).start(),
      newKey("FJ").log("all").callback( getTimer("timer-D1").stop() ),
      getTimer("timer-D1").wait()
      ,
      getKey("FJ").disable(),
      getText("instructions").remove()
      ,
      newText("Next trial incoming...").print(),
      getTimer("separacao").wait()
    )

    Jeremy

    • This reply was modified 2 years, 8 months ago by Jeremy. Reason: changed allottedtime for timer-D1
    #7883
    Larissa_Cury
    Participant

    Dear Jeremy,

    I can never thank you enough, but thank you very very much once again! I’ll try to set all these timers as you told me to do! I’m so happy that it’s possible to do that! I just have one question, what would the timer “allottedtime” stand for?

    Best,

    • This reply was modified 2 years, 8 months ago by Larissa_Cury.
    #7887
    Larissa_Cury
    Participant

    Dear Jeremy,

    Would it be possible to show the participants some feedback over the practice trial? I mean, before “instructions_E” appear on the screen, would it be possible to show them how much time they’ve spent on the practice trial as well as their accuracy? If so, how?

    Ops: not how much time they’ve spent, but rather their avarage RT

    Thanks in advance, if it would be better to open another topic for this question I can do that 🙂

    • This reply was modified 2 years, 8 months ago by Larissa_Cury. Reason: typo
    #7888
    Jeremy
    Keymaster

    My bad, it’s a typo from a previous version of my code, it should be timer-D1—I have edited my message accordingly

    Jeremy

    #7890
    Larissa_Cury
    Participant

    Oh, no problem! Concerning my new question, something like this: You have completed the practice trials: Your accuracy is: x % correct and average responde speed is: y ms” Is it possible?

    #7891
    Jeremy
    Keymaster

    would it be possible to show them how much time they’ve spent on the practice trial as well as their accuracy? If so, how?

    EDIT: I just saw your new message, which asks about average response time per practice trial rather than time spent on the whole practice block. I’ll address that later

    You could add this at the end of your keyboard_warning trial, after getText("keyboard-text").remove(): newVar("startPractice").global().set(()=>Date.now())

    Then before the test on your Key element in the code of your practice trials, add newVar("accurate", []).global() and inside the success and failure commands, add getVar("accurate").set(v=>[...v,true])/getVar("accurate").set(v=>[...v,false]) (respectively)

    You can add a trial before instructions_E that would do something like:

    newTrial("feedback",
      newVar("timeText").set( getVar("startPractice").global() ).set(v=> "You spent "+Math.round((Date.now()-v)/600)/100+"min practicing" ),
      newText( "feedbackTime" ).text( getVar("timeText") ).print()
      ,
      newVar("accuracyText").set( getVar("accurate").global() ).set(v=> "You got "+v.filter(a=>a==true).length+" correct answers out of "+v.length ),
      newText( "feedbackAccuracy" ).text( getVar("accuracyText") ).print()
      ,
      newButton("Continue").print().wait()
    )
    

    Jeremy

    #7892
    Larissa_Cury
    Participant

    All right! That sounds amazing! I’ll wait for the reaction average time feedback, I’m sorry I typed that wrong! Thank you!!

    • This reply was modified 2 years, 8 months ago by Larissa_Cury. Reason: typo
    #7895
    Jeremy
    Keymaster

    The logic for average RT per trial is the same as average accuracy: add newVar("localRT").set(v=>Date.now()) above newKey("keypress1","SK") and below the wait command add getVar("localRT").set(v=>Date.now()-v) , newVar("practiceRTs",[]).global().set(v=>[...v,getVar("localRT").value])

    Then your feedback trial would look like this:

    newTrial("feedback",
      newVar("timeText").set( getVar("practiceRTs").global() ).set(v=> "You spent "+(v.reduce((n,m)=>n+m)/v.length)/1000+"s per trial on average" ),
      newText( "feedbackTime" ).text( getVar("timeText") ).print()
      ,
      newVar("accuracyText").set( getVar("accurate").global() ).set(v=> "You got "+v.filter(a=>a==true).length+" correct answers out of "+v.length ),
      newText( "feedbackAccuracy" ).text( getVar("accuracyText") ).print()
      ,
      newButton("Continue").print().wait()
    )

    Jeremy

    #7896
    Larissa_Cury
    Participant

    Thank you so much, Jeremy!! I’ll work on all these codes! Thank you for your kind answers as always 🙂

    #7901
    Larissa_Cury
    Participant

    Dear Jeremy,

    What if I need to show feedback together with the test.pressed feebback? I mean, I still need the averege one, but I’d need something like this after each item:

    “correct! your speed was: 150 ms!
    “incorrect! your speed was 500ms!” etc

    Is it possible, if so, how?

    #7907
    Larissa_Cury
    Participant

    Dear Jeremy, I was able to take steps a and b, but I’m struggling with step c:

    Template("tabela-target.csv" , row => 
        newTrial("trial_2_center_cue_UP",
    defaultText
            .center()
           .cssContainer({"position": "absolute",
                          "top": "50%",
                          "left": "50%",
                          "transform": "translate(-50%, +50%)"})
            .print()
    ,
        newText("D1", "<br><b>+</b>")
        .cssContainer({
        "font-size":"100px",
        "color":"blue"})
        .center()
        .print()
    ,
       newTimer("timer-D1",1000+Math.round(1600*Math.random())) // ------------------------------> my new random time between 400 and 1600 ms
        .start()
        .wait()
    ,
       getText("D1")
       .remove()
    ,
    newText("cue", "<br> <b>*</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"green"})
       .center()
       .print()
    ,
        newTimer("timer_cue_D2",100)
        .start()
        .wait()
    ,
       getText("cue","D2")
       .remove()
    ,
       newText("D3", "<br> <b>+</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"pink"})
       .center()
       .print()
    ,
       newTimer("timer_D3",400)
        .start()
        .wait()
    ,
       getText("D3")
       .remove()
    ,
    newTimer("timer-RT",1700) // <-------------------------------------------- my new RT trial which imposes the answer within 1700 ms
        .start()
    ,
        newImage("imagens", row.imagem)
        .size(500, 200)
    ,
       newText("cruz_central", "<br> <b>+</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"black"})
       .center()
       .print()
    ,
        //para cima//
        newCanvas("center", 150,150)
        .add( "center at 50%" , "center at 50%" , getImage("imagens"))
        .cssContainer({
        "position": "absolute",
        "margin-top": "85px"})
        .center()
        .log()
        .print()
    ,
        newKey("keypress1","SK")
        .log()
        .callback( getTimer("timer-RT").stop())
    ,
        getTimer("timer-RT").wait()
    ,
         getKey("keypress1").disable(),
         getText("cruz_central"),
         getCanvas("center")
        .remove()
    ,
       newText("separacao", "<br> <b>+</b>") // <------------------------- this should be 3500 ms - timer-RT - timer-D1
       .cssContainer({
        "font-size":"100px",
        "color":"yellow"})
       .center()
       .print()
    ,
        newTimer("wait-separacao",2500)
        .start()
        .wait()
    )
      .log("imagens", row.imagem)
      .log("item", row.versao)
    );

    I don’t see how putting “wait separação” before D1 would make it be: WAIT SEPARAÇÃO = 3500 MINUS timer-RT MINUS timer-D1 . Would you mind explaining it again, please?

    Thanks in advance, as always!

    #7910
    Jeremy
    Keymaster

    Hi Larissa,

    If you want the totality of your trial to be 3800ms (because timer-RT = 1700ms, max timer-D1 = 1600ms, timer_cue_D2 = 100ms and timer_D3 = 400ms) start the timer at the beginning of the trial, and wait for it at the end:

    Template("tabela-target.csv" , row => 
      newTrial("trial_2_center_cue_UP",
        defaultText
            .center()
            .cssContainer({"position": "absolute",
                           "top": "50%",
                           "left": "50%",
                           "transform": "translate(-50%, +50%)"})
            .print()
        ,
        newTimer("wait-separacao",3800).start()
        ,
        newText("D1", "<br><b>+</b>")
            .cssContainer({"font-size":"100px",
                           "color":"blue"})
            .center()
            .print()
        ,
        newTimer("timer-D1",400+Math.round(1200*Math.random())) // if you want between 400ms and 1600ms, you need 400+[0--1200]
            .start()
            .wait()
        ,
        getText("D1").remove()
        ,
        newText("cue", "<br> <b>*</b>")
           .cssContainer({"font-size":"100px",
                          "color":"green"})
           .center()
           .print()
        ,
        newTimer("timer_cue_D2",100)
            .start()
            .wait()
        ,
        getText("cue","D2").remove()
        ,
        newText("D3", "<br> <b>+</b>")
           .cssContainer({"font-size":"100px",
                          "color":"pink"})
           .center()
           .print()
        ,
        newTimer("timer_D3",400)
            .start()
            .wait()
        ,
        getText("D3").remove()
        ,
        newTimer("timer-RT",1700).start()
        ,
        newImage("imagens", row.imagem).size(500, 200)
        ,
        newText("cruz_central", "<br> <b>+</b>")
            .cssContainer({"font-size":"100px",
                           "color":"black"})
            .center()
            .print()
        ,
        //para cima//
        newCanvas("center", 150,150)
            .add( "center at 50%" , "center at 50%" , getImage("imagens"))
            .cssContainer({"position": "absolute",
                           "margin-top": "85px"})
            .center()
            .log()
            .print()
        ,
        newKey("keypress1","SK")
            .log()
            .callback( getTimer("timer-RT").stop() )
        ,
        getTimer("timer-RT").wait()
        ,
        getKey("keypress1").disable(),
        getText("cruz_central"),
        getCanvas("center").remove()
        ,
        newText("separacao", "<br> <b>+</b>")
            .cssContainer({"font-size":"100px",
                           "color":"yellow"})
            .center()
            .print()
        ,
        getTimer("wait-separacao").wait()
      )
      .log("imagens", row.imagem)
      .log("item", row.versao)
    );

    Also, re. the feedback on each trial, just use the Var named localRT to set a Text element in the success/failure commands. For example, in success:

    newVar("positiveFeedbackText").set( getVar("localRT") ).set( v => "Correct! Your speed was: "+v+"ms!" )
    ,
    newText("positiveFeedback").text( getVar("positiveFeedbackText") ).print()

    Jeremy

    #7913
    Larissa_Cury
    Participant

    Thank you for your kind answer! I’m struggling to add the feedback on each trial together with the final one:

    This is what I’ve already done (and it shows the feedback on the feedback trial):

    //////////////////////////////////////////trial_1 - no_cue// PARA CIMA/LEFT//////////////////////////////////////////////////////
        Template("tabela-target_left.csv" , row => 
        newTrial("p_trial_1_no_cue_UP",
    defaultText
            .center()
           .cssContainer({"position": "absolute",
                          "top": "50%",
                          "left": "50%",
                          "transform": "translate(-50%, +50%)"})
            .print()
    ,
        newText("D1", " <br> <b>+</b>")
        .cssContainer({
        "font-size":"100px",
        "color":"blue"})
        .center()
        .print()
    ,
       newTimer("timer-D1",1000)
        .start()
        .wait()
    ,
       getText("D1")
       .remove()
    ,
    newText("cue", "<br> <b>+</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"green"})
       .center()
       .print()
    ,
        newTimer("timer_cue_D2",100)
        .start()
        .wait()
    ,
       getText("cue","D2")
       .remove()
    ,
       newText("D3", "<br> <b>+</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"pink"})
       .center()
       .print()
    ,
       newTimer("timer_D3",400)
        .start()
        .wait()
    ,
       getText("D3")
       .remove()
    ,
        newImage("imagens", row.imagem)
        .size(500, 200)
    ,
       newText("cruz_central", "<br> <b>+</b>")
       .cssContainer({
       "font-size":"100px",
       "color":"black"})
       .center()
       .print()
    ,
        //para cima//
        newCanvas("center", 150,150)
        .add( "center at 50%" , "center at 50%" , getImage("imagens"))
        .cssContainer({
        "position": "absolute",
        "margin-top": "85px"})
        .center()
        .log()
        .print()
    ,
    newVar("localRT").set(v=>Date.now()),
        newKey("keypress1","SK")
        .wait()
    ,
        getVar("localRT").set(v=>Date.now()-v),
        newVar("practiceRTs",[]).global().set(v=>[...v,getVar("localRT").value])
    ,
        newVar("accurate", []).global()
    ,
        getKey("keypress1")
         .test.pressed("S")
        .success(newText("success", "Correto!").print()
        .cssContainer({"font-size":"30px", "margin-top":"255px","font-family":"Comic Sans MS", "color":"green"}).center(),
        getVar("accurate").set(v=>[...v,true]))
        .failure( newText("failure", "Incorreto!").print() 
        .cssContainer({"font-size":"30px", "margin-top":"255px", "font-family":"Comic Sans MS", "color":"red"}).center(),
        getVar("accurate").set(v=>[...v,false]))
    ,
         getText("cruz_central")
         .remove()
    ,
         getCanvas("center")
        .remove()
    ,
        newTimer("wait-success",400)
        .start()
        .wait()
    ,
        getText("success")
        .remove()
    ,
        getText("failure")
        .remove()
    ,
       newText("separacao", "<br> <b>+</b>")
       .cssContainer({
        "font-size":"100px",
        "color":"yellow"})
       .center()
       .print()
    ,
        newTimer("wait-separacao",2500)
        .start()
        .wait()
    ));

    How do I manage to do both? I mean: both during each trial but also in my ‘feedback” ? (https://farm.pcibex.net/r/yBeBcJ/)

    Sequence(
        "instructions_A",  "instructions_B", "instructions_C", "instructions_D","instructions_Extra","keyboard_warning",
        rshuffle("p_trial_1_no_cue_UP","p_trial_1_no_cue_DOWN","p_trial_2_center_cue_UP","p_trial_2_center_cue_DOWN",
             "p_trial_3_double_cue_UP","p_trial_3_double_cue_DOWN","p_trial_4_spatial_cue_UP","p_trial_4_spatial_cue_DOWN"),
        "feedback",
        "instructions_E",

    etc etc etc

    #7914
    Jeremy
    Keymaster

    Place the commands in the success and the feedback commands, eg. for success from the code in your message:

    .success(
        newVar("positiveFeedback").set( getVar("localRT") ).set( v=> "Correto! You spent "+v+"ms on this trial" )
        ,
        newText("success")
            .text( getVar("positiveFeedback") )
            .cssContainer({"font-size":"30px", "margin-top":"255px","font-family":"Comic Sans MS", "color":"green"})
        ,
        getVar("accurate").set(v=>[...v,true])
    )

    Your script already achieves including a trial (labeled “feedback”) that prints the average time spent on the practice trials

    Jeremy

Viewing 15 posts - 1 through 15 (of 59 total)
  • You must be logged in to reply to this topic.