Forum Replies Created
-
AuthorPosts
-
Larissa_CuryParticipant
Ohhhhhhhhhh, now I got it! Thank you, Jeremy, once more!!! đ
I have a question that’s not related to the timing, so if it’s better I can open a new forum discussion for that (let me known đ ) which is: there isn’t a problem if two or more participants take the experiment at once, right? Supposly, a class of students each with his/hers own computer?
Larissa_CuryParticipantDear Jeremy!
I’m so so happy it worked!!!!! Thank you for your feedback!!!Ohhhh, concerning the Var element…oh, all right. Yeah, you got my idea, which was to try to create a new collumn which would have the timers from Instructions_E up to the end of the experiment, so that then I could make the function in R use it as its parameter, but now that the 1:n() solution is working, I don’t think that adding a new Var is the best option, right? I guess that it is making the experiment kinda slower…but, If I did include that, would it look sth like this?
newTrial("blocks-timer-trial", newText("blocks-text","Espere...") .cssContainer({ "font-size":"30px", "position": "absolute", "margin-top": "255px", //places it in the middle of the screen "white-space": "nowrap"}) .center() .print() , newTimer("blocks-text-timer",1500) .start() .wait() , getText("blocks-text").remove() , getVar("BLOCKS").global().set( v => Date.now() - v ) , ->......... it returns me an error when I try to separate them .log( "BlocksTimer" , getVar("BLOCKS") ) );
Larissa_CuryParticipantDear Jeremy,
Thank you for your kind answer as always! Well, I’ve tried many many many things but none of them seemed to work, but, then, I came up with this very crazy idea that seems to be working just fine!Basically, I thought “well, the function counts max values of EventTime, since the “nevers” are there, it’s not getting quite right”…So I created a new column with 1: up to the n rows and it seems to be working just fine, let me show it to you. It seems to be labelling the trials accurately, is it, indeed?
# Read in results file results <- read.pcibex("results (12).csv") ############################################### create new collumn "Randowm" with 1:n(row)##################################### results1 <- results %>% mutate(Random = as.numeric(seq(1:n())) ) ###########################function################################################################# add_blocks <- function (df,id) { PRACTICE_TO_FIRST <- max(df$Random[df$Label=="instructions_E"]) <--------------------I've changed the reference column FIRST_TO_SECOND <- max(df$Random[df$Label=="instructions_F"]) SECOND_TO_THIRD <- max(df$Random[df$Label=="instructions_G"]) df$block <- 0 df$block[df$Random>PRACTICE_TO_FIRST] <- 1 df$block[df$Random>FIRST_TO_SECOND] <- 2 df$block[df$Random>SECOND_TO_THIRD] <- 3 return(df) } results_blocks <- results1 %>% group_by(id) %>% group_modify(add_blocks) ########## filter the relevant columns and transform the answer column ######################################## data_results <- results_blocks %>% filter(Parameter %in% c("Key","PressedKey","Key")) %>% select(id,Label,imagens,Value,Parameter,ReactionTime,block) %>% group_by(id) %>% mutate(Answer = case_when(is.na(Value) ~ "0", Value == "S" ~ "S", Value == "K" ~ "K")) %>% select(-Value) %>% select(id,Label,imagens,Answer,ReactionTime,block) ---
This results file 12 can be seen here => https://github.com/LariCury/Sample-results.git
The output of this code is called “Exemplo_Resultados”, it’s also on my git đ—
I’m just wondering sth, I tried to create a Var element in order to capture the timing from this Var instead of EventTime, but it didn’t work, let me show it to you => https://farm.pcibex.net/r/MVMhVB/
I’ve set the var on Instructions_E and called it back on a new trial called “”blocks-timer-trial”)…why didn’t it log? shouldn’t it?best,
Larissa_CuryParticipantJust an update =>
I figure it out that the problem was that when there’s no pressed key, there’s no EventTime for that as well, then R couldn’t work properly…So I’ve research a lot here on the forum and on the documentation and I came up with the solution of adding a var element to compute my reaction time (below) which is working just fine! My only problem is that now I cannot label the trials according to my blocks, the labeling is all messed around, let me show it to you:
new (https://farm.pcibex.net/r/XSJAnP/)
newVar("RT").global().set( v => Date.now() ) <-------------- this is working just fine I guess =) , newKey("keypress1","SK") .log() .callback( getTimer("timer-RT").stop() ) , getTimer("timer-RT").wait() , getVar("RT").set( v => Date.now() - v ) .... .log( "ReactionTime" , getVar("RT") )
In R:
#Read PciBex's function read.pcibex <- function(filepath, auto.colnames=TRUE, fun.col=function(col,cols){cols[cols==col]<-paste(col,"Ibex",sep=".");return(cols)}) { n.cols <- max(count.fields(filepath,sep=",",quote=NULL),na.rm=TRUE) if (auto.colnames){ cols <- c() con <- file(filepath, "r") while ( TRUE ) { line <- readLines(con, n = 1, warn=FALSE) if ( length(line) == 0) { break } m <- regmatches(line,regexec("^# (\\d+)\\. (.+)\\.$",line))[[1]] if (length(m) == 3) { index <- as.numeric(m[2]) value <- m[3] if (is.function(fun.col)){ cols <- fun.col(value,cols) } cols[index] <- value if (index == n.cols){ break } } } close(con) return(read.csv(filepath, comment.char="#", header=FALSE, col.names=cols)) } else{ return(read.csv(filepath, comment.char="#", header=FALSE, col.names=seq(1:n.cols))) } } # Read in results file results <- read.pcibex("results (11).csv") ### add function <-------------- sth not quite right (maybe because now the EventTime has "never" as valuues, but I don't know how to fix it :( add_blocks <- function (df,id) { PRACTICE_TO_FIRST <- max(df$EventTime[df$Label=="instructions_E"]) FIRST_TO_SECOND <- max(df$EventTime[df$Label=="instructions_F"]) SECOND_TO_THIRD <- max(df$EventTime[df$Label=="instructions_G"]) df$block <- 0 df$block[df$EventTime>PRACTICE_TO_FIRST] <- 1 df$block[df$EventTime>FIRST_TO_SECOND] <- 2 df$block[df$EventTime>SECOND_TO_THIRD] <- 3 return(df) } ###add blocks with the new function results_blocks <- results %>% group_by(id) %>% group_modify(add_blocks) ######################################################## my new filter data_results <- results_blocks %>% filter(Parameter %in% c("Key","PressedKey")) %>% select(id,Label,imagens,Value,Parameter,ReactionTime,block) %>% group_by(id) %>% mutate(Answer = case_when(is.na(Value) ~ "0", Value == "S" ~ "S", Value == "K" ~ "K")) %>% select(-Value) %>% select(id,Label,imagens,Answer,ReactionTime,block)
This result file is here => (results (11)) => https://github.com/LariCury/Sample-results.git
I should have 96 items per block, but I guess that the missing values on EventTime are messing the count, I just don’t know how to fix it…Do you have any suggestion?
Best,
- This reply was modified 2 years, 1 month ago by Larissa_Cury. Reason: add information
Larissa_CuryParticipantadd =>
I’ve just found something funny, I counted both older (working) and the new (not working) versions, and the output were quite interesting =>
my_count <- data_results %>% count(Label, block) %>% group_by(Label)
In the older version, I get this => https://drive.google.com/file/d/1ENUnc-zm1QLQWLLPPF3QClNZtWNefV-1/view?usp=sharing
In the new version, I get this => https://drive.google.com/file/d/1EqryhXxTo9jrNxxOFVtjhDpwQ2_0QUe1/view?usp=sharing
ps: I forgot to say that the older version had E and I as the keys and now I have S and K, I’ve upload in my github an example of results file of the older version as well, which is working just fine
(https://farm.pcibex.net/r/mGDSNL/)
I’m trying to understand what messed the count, I was thinking that the Nas were the matter…
- This reply was modified 2 years, 1 month ago by Larissa_Cury. Reason: add my code link
Larissa_CuryParticipantDear Jeremy,
My R code was running just fine for this same code before I had to make the timing alterations. My guess is that before the timeout alteration, I had to had a pressed key such as S or K, but now, because of the required timeout, it is not necessarialy anymore…I guess that the code is struggling with the NAs. Would you have any recommendations?This is an example results file from the code with the timing alterations => https://github.com/LariCury/Sample-results.git
##install.packages("ddlyr","tidyverse") library(dplyr) library(tidyverse) library(writexl) #Read PciBex's function read.pcibex <- function(filepath, auto.colnames=TRUE, fun.col=function(col,cols){cols[cols==col]<-paste(col,"Ibex",sep=".");return(cols)}) { n.cols <- max(count.fields(filepath,sep=",",quote=NULL),na.rm=TRUE) if (auto.colnames){ cols <- c() con <- file(filepath, "r") while ( TRUE ) { line <- readLines(con, n = 1, warn=FALSE) if ( length(line) == 0) { break } m <- regmatches(line,regexec("^# (\\d+)\\. (.+)\\.$",line))[[1]] if (length(m) == 3) { index <- as.numeric(m[2]) value <- m[3] if (is.function(fun.col)){ cols <- fun.col(value,cols) } cols[index] <- value if (index == n.cols){ break } } } close(con) return(read.csv(filepath, comment.char="#", header=FALSE, col.names=cols)) } else{ return(read.csv(filepath, comment.char="#", header=FALSE, col.names=seq(1:n.cols))) } } # Read in results file results <- read.pcibex("Result_Example.csv") add_blocks <- function (df,id) { PRACTICE_TO_FIRST <- max(df$EventTime[df$Label=="instructions_E"]) FIRST_TO_SECOND <- max(df$EventTime[df$Label=="instructions_F"]) SECOND_TO_THIRD <- max(df$EventTime[df$Label=="instructions_G"]) df$block <- 0 df$block[df$EventTime>PRACTICE_TO_FIRST] <- 1 df$block[df$EventTime>FIRST_TO_SECOND] <- 2 df$block[df$EventTime>SECOND_TO_THIRD] <- 3 return(df) } results_blocks <- results %>% group_by(id) %>% group_modify(add_blocks) ##the DF name is results_blocks #Filter the relevant collumns and create the Reaction_Time collumn data_results <- results_blocks %>% filter(Parameter %in% c("Print","PressedKey")) %>% select(id,Label,imagens,block,Value,EventTime,Parameter) %>% group_by(id) %>% mutate(event = case_when(Parameter == "Print" ~ "Time1", Parameter == "PressedKey" ~ "Time2")) %>% ungroup() %>% #select(-Parameter) %>% pivot_wider(names_from = event, values_from = EventTime) ## Omit NA from Time2 and Time1: a <- na.omit(data_results$Time2) b <- na.omit(data_results$Time1) ## Reaction_Time = Time2-Time1: RT <- a-b ## Create the REACTION_TIME collumn: data_results_final <- data_results %>% filter(Value %in% c("S","K")) %>% data_results_final$newRT <- RT ## Omit irrelevant colluns (Time1 and Time2) clean_data <- subset(data_results_final, select = -c(Time1,Time2))
This is an example results file from the code with the timing alterations => https://github.com/LariCury/Sample-results.git
- This reply was modified 2 years, 1 month ago by Larissa_Cury. Reason: typo
Larissa_CuryParticipantDear Jeremy,
I’ve already made this change and it worked nicely! Thank you once more!
Larissa_CuryParticipantDear Jeremy,
but I don’t think that I put the accuracy var on this page. Let me show it to you: this is the “instructions_E” page =>
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","PRATICAR DE NOVO") .callback(newVar("practiceRTs").global().set( [] ),jump(startsWith("p_trial")) , end() ) .css("margin","1.5em") .center() .print() , newText("instructions-blocks","<p><center>A tarefa terĂĄ 3 blocos. <b style=color:red;>Cada bloco dura aproximadamente 5 minutos.</b> No total, vocĂȘ deve demorar 15 minutos.</p></center>") .cssContainer({ "font-size":"22px", "text-align": "center", "white-space":"nowrap"}) .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() );
the page that shows the feedback is the previous one of Instructions_E, this one here:
newTrial("feedback-trial", defaultText .print() , newText("feedback-text","Seus resultados:") .cssContainer({ "border": "5px solid black", "background-color": "yellow", "color": "black", "margin":"1em", "font-size":"50px"}) .center() , newVar("timeText").set( getVar("practiceRTs").global() ).set(v=> "VocĂȘ demorou "+(v.reduce((n,m)=>n+m)/v.length)+"ms por pergunta em mĂ©dia" ), newText( "feedbackTime" ).text( getVar("timeText") ).print() .cssContainer({ "font-size":"22px", "text-align": "left", "white-space":"nowrap"}) , newVar("accuracyText").set( getVar("accurate").global() ).set(v=> "VocĂȘ acertou "+v.filter(a=>a==true).length+" do total de "+v.length ), newText( "feedbackAccuracy" ).text( getVar("accuracyText") ).print() .cssContainer({ "font-size":"22px", "text-align": "left", "white-space":"nowrap"}) , newButton("CONTINUAR") .center() .cssContainer({"margin":"1em"}) .print() .wait() );
So the sequence is this: instructions + practice trial with feedback within + final feedback + instructions_E
should I add the accuracy inside the callbutton? Like this:
newButton("come back","PRATICAR DE NOVO") .callback(newVar("practiceRTs").global().set( [] ),newVar("accurate").global().set( [] ),jump(startsWith("p_trial")) , end() ) .css("margin","1.5em") .center() .print()
would that work?
Larissa_CuryParticipantDear Jeremy,
Huhh….I guess I’m still doing sth wrong, ’cause it is still couting the 24 trials twice, let me show it you:
newButton(“come back”,”PRATICAR DE NOVO”)
.callback(newVar(“practiceRTs”).global().set( [] ),jump(startsWith(“p_trial”)) , end() )
.css(“margin”,”1.5em”)
.center()
.print()
?I still get: “VocĂȘ acertou 14 do total de 48” (which means you’ve got 14 out of 48)
ps: do you think that maybe setting 5800 rather than 6000 would be more precise? My idea was: “ok, I have to show a 2000ms feedback, so I’ll just count this time”
- This reply was modified 2 years, 1 month ago by Larissa_Cury. Reason: add a question
Larissa_CuryParticipantDear Jeremy,
Thank you for your kind answer as always. I’ve went through what we’ve discussed and I wasn’t able to notice before that the 4000 timeout trial had, indeed, the same formula as the original paper had (D1 + D2 + D3 + DRt + DWait = 4000 equals DWait = 3500 – D1 – DRT), I’m so sorry I took your time for trying to explaining that to me, but I really appreaciate your kindness, so, thank you once more. and thank you more going over the alternative method, I didn’t have a clue about using the Java option, so i’m sure that will contribuite for my future codes! I’ve already updated the whole model with the 4000 timeout approach, I only have 2 final concerns:In order to use this approach to the practice trial, I’ve ajusted the Wait timer to 6000, not 4000, since the feedback takes 2000ms, like this:
//////////////////////////////////////////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() , newTimer("wait-separacao",6000).start() , newText("D1", " <br> <b>+</b>") .cssContainer({ "font-size":"100px", "color":"blue"}) .center() .print() , newTimer("timer-D1",400+Math.round(1200*Math.random())) .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() , newVar("localRT").set(v=>Date.now()), newKey("keypress1","SK") .log() .callback( getTimer("timer-RT").stop() ) , getTimer("timer-RT").wait() , getKey("keypress1").disable(), getText("cruz_central").remove() , getCanvas("center").remove() , 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( newVar("positiveFeedback").set( getVar("localRT") ).set( v=> "Correto! VocĂȘ demorou "+v+"ms para responder" ) , newText("success") .text( getVar("positiveFeedback") ) .cssContainer({"font-size":"30px", "text-align":"center", "margin-top":"255px","font-family":"Comic Sans MS", "color":"green","white-space":"nowrap"}) , getVar("accurate").set(v=>[...v,true]) ) .failure( newVar("negativeFeedback").set( getVar("localRT") ).set( v=> "Incorreto! VocĂȘ demorou "+v+"ms para responder" ) , newText("failure") .text( getVar("negativeFeedback") ) .cssContainer({"font-size":"30px", "text-align":"center", "margin-top":"255px","font-family":"Comic Sans MS", "color":"red","white-space":"nowrap"}) , getVar("accurate").set(v=>[...v,false]) ) , newTimer("wait-success",2000) //timer for the success or failure messenge .start() .wait() , getText("success") .remove() , getText("failure") .remove() , newText("separacao", "<br> <b>+</b>") .cssContainer({ "font-size":"100px", "color":"yellow"}) .center() .print() , getTimer("wait-separacao").wait() ));
It seems to me that it’s working just fine, I’d just like to check if the math is right, is it?
Btw, I wasn’t able to fiz the “come back” button as you’ve explained me to do, it keeps on duplicating the trials, I’m sure I’ve did something wrong, but I don’t know what:
newText("instructions-14","<p><center> Se vocĂȘ quiser praticar de novo, clique aqui:") .cssContainer({ "font-size":"22px", "text-align": "center" }) .center() .print() , newVar("practiceRTs").set( [] ) // --------------------------------- here (I've tried to put it before the jumping inside the callback(), but it didn't work too (I probably did sth wrong, though) , newButton("come back","PRATICAR DE NOVO") .callback(jump(startsWith("p_trial")) , end() ) .css("margin","1.5em") .center() .print()
best,
- This reply was modified 2 years, 1 month ago by Larissa_Cury. Reason: add relevant information to the post
Larissa_CuryParticipantThank you, Jeremy! I’m total new to Java script (all I know concerns the Pcibex script itself)…I read the documentation you’ve recommended, but I couldn’t find a solution to solve the set problem. I really wanted to use this approach. Thank you once more for your time and patience.
- This reply was modified 2 years, 2 months ago by Larissa_Cury. Reason: add information
Larissa_CuryParticipantThat’s what I’ve done so far:
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() , timerd1duration = 400+Math.round(1200*Math.random()) , newTimer("timer-D1",timerd1duration) .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() , newVar("newTimerDuration").set( v=>Date.now() ) , 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() , getVar("newTimerDuration").set( v=> 3500 - timerd1duration - (Date.now()-v) ) , newTimer("wait-separacao").set( getVar("newTimerDuration") ) .start() , 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) );
that’s the error I get = Invalid duration for Timer “wait-separacao” (newTrial: 47)…What should I do?
- This reply was modified 2 years, 2 months ago by Larissa_Cury. Reason: include information
- This reply was modified 2 years, 2 months ago by Larissa_Cury. Reason: add information
Larissa_CuryParticipantOhhhhhhh, now I got the reason why 1200! I’m sorry, that’s right. I need between 400 and 1600 exactly. Thank you! What do you mean that won’t work? What should I do to change it for the desirable outcome?
Larissa_CuryParticipantOhhh, all right! Then, I should do this, right:
, timerd1duration = 400+Math.round(1200*Math.random()) ,
I just didn’t understand why 1200 and not 1600 ?
Best,
Larissa_CuryParticipantorrrrr, should I do this =
getVar("newTimerDuration").set( v=> 3500 - timerd1duration - (Date.now()-v) )
replacing timerd1duration by “timer-D1”, since it’s the label for my d1 timer?
-
AuthorPosts