Can we randomize time with newTimer() ?

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

Viewing 15 posts - 16 through 30 (of 59 total)
  • Author
    Posts
  • #7915
    Larissa_Cury
    Participant

    I’m probably doing something wrong, the thing with the timers is (this is from the original article which is the base of my experiment):

    “Each trial consisted of five events. First, there was a fixation period for a random variable duration (400–1600 msec) (MY TIMER D1). Then, a warning cue was presented for 100 msec (MY TIMER- D2). There was a short fixation period for 400 msec (MY TIMER D3) after the warning cue and then the target and flankers appeared simultaneously. The target and flankers were presented until the participant responded, but for no longer than 1700 msec. (MY TIMER RT) After participants made a response, the target and flankers disappeared immediately and there was a posttarget fixation period for a variable duration which was based on the duration of the first fixation and RT (3500 msec minus duration of the first fixation minus RT). (MY TIMER WAIT-SEPARACAO)
    After this interval the next trial began. Each trial lasted for 4000 msec.”

    but I agree with you, the count is 3800, not 4000. I really don’t know what’s wrong… Anyway, is there a formula that I could use on timer-wait-separação? as we did with the random ?

    #7916
    Jeremy
    Keymaster

    The solution I give does *not* create a final Timer element with a variable duration. Instead, the solution I suggest (which, in my opinion, is simpler and cleaner, at least when implemented in PCIbex) consists in starting a Timer element at the beginning of the trial of a fixed duration, ie. the intended overall duration of the trial, and wait for it to elapse at the end of the trial before proceeding to the next one

    The excerpt you quote includes three timers with a variable duration: D1 (400ms–1600ms) RT (0ms–1700ms) and WAIT (3500ms minus D1 minus RT). Then there are two timers with a fixed duration: D2 (100ms) and D3 (400ms) which makes for a total of 500ms. Because of how WAIT is calculated, adding the duration of the five timers totals to 4000ms

    I misunderstood your previous messages as suggesting that you meant to have a total trial duration of max(D1)+max(RT)+D2+D3, which is why I proposed creating a Timer element of 3800ms. But if you want to replicate the design from that quote, set the very first Timer element (the one you need to wait for at the end) to 4000 instead

    Jeremy

    #7917
    Larissa_Cury
    Participant

    Thank you once again, Jeremy! You’re always kind with me, thank you. Now the feedback seems to be working just fine! Thank you!! Regarging the timer issue, I get that setting the timer before is simplier and easier, but I’m afraid (even thoug the effect is the same), some reviwers could argue that I’d not be following the original design strictly, is there a way to come up with a matematical form for the last timer making it be 3500 minus rt minus D1?

    #7918
    Jeremy
    Keymaster

    You would need to use the method that you use with the Var element named localRT to dynamically calculate the duration in another Var element, and set the duration of a final Timer element using that Var element. Be aware, though, that each command takes a non-null time to be executed, so the value of a Var element set the way localRT is set is not guaranteed to be exact to the millisecond:

    newVar("localRT").set(v=>Date.now()),
    newKey("keypress1","SK").wait(),
    getVar("localRT").set(v=>Date.now()-v),

    Both newKey and wait (and set too, to some extent) take some time to be executed, which means that Date.now()-v might represent a time difference that’s slightly greater (by up to a couple milliseconds) than the actual time that passed between the creation of the Key element and a keypress. Also, all the commands that come after the wait command of the previous Timer element (timer_D3) and before newVar take time to be executed too, so those few milliseconds are not taken into account either if you create the Var element a few commands after waiting for the end of the previous Timer element

    Moreover, your actual trials won’t have the wait command on the Key element, but rather on the Timer element named timer-RT, so that’s the one after which you would need to set a Var element like localRT. So simplifying the structure a little bit, you would have something like this:

    timerd1duration = 400+Math.round(1200*Math.random())
    ,
    newTimer("timer-D1",timerd1duration).start().wait()
    ,
    getText("D1").remove()
    ,
    newText("cue", "*").color("green")
    ,
    newTimer("timer_cue_D2",100).start().wait()
    ,
    getText("cue").remove()
    ,
    newText("D3", "+").color("pink")
    ,
    newTimer("timer_D3",400).start().wait()
    ,
    newVar("newTimerDuration").set( v=>Date.now() )
    ,
    getText("D3").remove()
    ,
    newTimer("timer-RT",1700).start()
    ,
    newImage("imagens", row.imagem).size(500, 200)
    ,
    newText("cruz_central", "+").color("black")
    ,
    newCanvas("center", 150,150).add( "center at 50%" , "center at 50%" , getImage("imagens")).print()
    ,
    newKey("keypress1","SK").log().callback( getTimer("timer-RT").stop() )
    ,
    getTimer("timer-RT").wait()
    ,
    getVar("newTimerDuration").set( v=> 3500 - timerd1duration - (Date.now()-v) )
    ,
    newTimer("separacao").set( getVar("newTimerDuration") ).start()
    ,
    getKey("keypress1").disable(),getText("cruz_central"),getCanvas("center").remove()
    ,
    newText("+").color("yellow")
    ,
    getTimer("separacao").wait()

    Finally, let me point that any reviewer who would argue that the design is not replicated using the method I suggested earlier either would not understand it, or (unless I myself misunderstood the design as described in the excerpt you quoted) would be completely dishonest in their assessment (keeping in mind that there is a myriad of other technical points of divergence when implementing the same design using different codes and engines)

    Jeremy

    #7919
    Larissa_Cury
    Participant

    Thank you once again, Jeremy! And also thank you for your comment! By doing the other way around, the timing would be more precise or the slight delay occur one way or another?

    #7921
    Jeremy
    Keymaster

    My initial suggestion is to set a duration of 4000ms, so the duration between the start command of the Timer element and its end (which would coincide with the completion of its wait command) would be as close to 4000ms as you could get, barring any performance or technical issue with the participant’s browser/device

    Jeremy

    #7922
    Larissa_Cury
    Participant

    Got it! So, using the VAR option means that the possible delays would depend on the participants internet/browser/etc? while the first option would mitigate this by determining the fixed 4000 ms? concerning the delay, how bad could that be in pratical terms?

    ps: thank you once more!

    #7923
    Jeremy
    Keymaster

    No, performance issues are orthogonal to the method you use: if a participant’s browser is having a hard time running the script of the pages they are visiting, the whole execution of the experiment will be affected

    The delays, as I said, come from the fact that every single command takes a non-null time to be executed, which means that even two consecutive commands cannot be considered to happen at the same time, so that a sequence newTimer(100).start().wait(),newTimer(200).start().wait() cannot be taken to last exactly 300ms with 100% certainty. The advantage of creating an overall Timer element of 4000ms is that you don’t depend on a sequence of commands to calculate its duration, and are therefore not at risk of accumulating such delays in doing so

    Jeremy

    #7924
    Larissa_Cury
    Participant

    Ohhhhhhh, now it’s clear. So, whenever we code and print things, they’ll take time, ok. The difference is that with presetting the time (4000ms) then we know for sure that the role thing lasted for 4000, using the VAR option, I’d have to say something as such “the trials lasted aproximately 4000 ms”, right? Does it also make a difference in computing the reaction time afterwards ? I mean, I’m currently doing this in R => Key Element EventTime – Canvas EventTime = “how long it took for my participant to press the key”
    Would that be the same in both methods?

    #7925
    Jeremy
    Keymaster

    The event times reported in the results file correspond to when the relevant events occurred. For the Key element, it stands for when the relevant key was pressed, and for the Canvas element, it stands for when the print command was executed. So the difference you calculate corresponds to how many milliseconds passed between when the print command of the Canvas element was executed (which should be almost exactly when its content started being visible on the page, barring performance issues) and when the keypress was detected (which should be almost instantaneous, again barring performance issues). That difference includes the time it took for all the commands between the printing of the Canvas element and the keypress to be executed (basically,just newKey and log, so maybe 1ms) but that shouldn’t matter because all you care about is how long it actually took for the participant to press a key after seeing the Canvas element, regardless of whether the script executed commands during that time

    Jeremy

    #7926
    Larissa_Cury
    Participant

    Thank you once again! So, for the purposes of my current study, basically the only thing that actually matters is that reaction time that I’ve described (i.e, I need to know how long it took the participant to press the button)…So, If I understood it correctly, there should be not such a diffence between using the 4000s preset method or the VAR method concerning this, right?

    edit: to press the button after seeing the target image (i.e, the canvas)

    • This reply was modified 2 years, 1 month ago by Larissa_Cury. Reason: edit
    #7928
    Jeremy
    Keymaster

    Well, there are the differences I just described, having to do with cumulative delays when setting a final Timer element using the VAR method, vs using an overall 4000ms Timer element which introduces no such delay

    Jeremy

    #7929
    Larissa_Cury
    Participant

    Right, thank you for you patience for explaining this to me! In practical terms, the difference would be that one around one ms?

    #7930
    Jeremy
    Keymaster

    It’s hard to tell, one would have to run a few tests using each method and proceed to comparisons, but my guess would be that, under normal circumstances (ie good performance) the delays associated with the Var method probably shouldn’t exceed a couple tens of milliseconds

    Jeremy

    #7931
    Larissa_Cury
    Participant

    Got it! Thank you SO MUCH for your kindness, I really appreciate it!! I think that now I’ve understood it properly!

    Let me ask you something about the feedback trials: they’re working properly and I’ve already made the changes you’ve tought me how to do. However, on my “instructions_E” trial (below) =>

    newTrial("instructions_E",
      newText("instructions-12","Você está pronto?")
        .cssContainer({
            "border": "5px solid black",
            "background-color": "yellow",
            "color": "black",
            "font-size":"50px"
        })
        .center()
        .print()
      ,
      newText("instructions-17","<p>Sinta-se livre para fazer uma pausa agora</p>")
        .cssContainer({
            "font-size":"22px",
            "text-align": "center"
        })
        .center()
        .print()
      ,
      newImage("boy-image","boy.png")
        .size(200,200)
        .center()
        .print()
      ,
      newText("instructions-14","<p><center> Se você quiser praticar de novo, clique aqui:")
        .cssContainer({
            "font-size":"22px",
            "text-align": "center"
        })
        .center()
        .print()
      ,
      newButton("come back","Voltar à prática")
        .callback( jump(startsWith("p_trial")) , end() )
        .css("margin","1.5em")
        .center()
        .print()
      ,
      newText("instructions-15","<p><center>Quando você se sentir <b style=color:red;>PRONTO</b>, clique no botão abaixo:</p></center>")
        .cssContainer({
            "font-size":"22px",
            "text-align": "center"
        })
        .center()
        .print()
      ,
      newButton("wait","Começar")
        .center()
        .print()
        .wait()
    );

    If I press the COME BACK button, it does come back, but it sums all trials. For example, if I take the practice trial twice, then it shows me my feedback for 48 trials. Is there a way to make it “reset” to only one time if the participant decides to come back?

    In the feedback trial,

    newVar("timeText").set( getVar("practiceRTs").global() ).set(v=> "Você demorou "+(v.reduce((n,m)=>n+m)/v.length)/1000+"s por pergunta em média" ), newText( "feedbackTime" ).text( getVar("timeText") ).print() .cssContainer({ "font-size":"22px", "text-align": "left", "white-space":"nowrap"})

    If I drop the 1000, then I would have the answer in ms, right?

    Thank you once more!

    • This reply was modified 2 years, 1 month ago by Larissa_Cury. Reason: edit typos
Viewing 15 posts - 16 through 30 (of 59 total)
  • You must be logged in to reply to this topic.