Reply To: Catch Trials

PennController for IBEX Forums Support Catch Trials Reply To: Catch Trials

#5627
Jeremy
Keymaster

Hi Nickolas,

So if I understood you correctly, you need to present your trials in blocks of N trials each, each block consisting of N-1 test trials and 1 catch trial presented in a total random order, ie. within each block whether the catch trial occurs at the beginning, in the middle or at the end is random—as a consequence, no two catch trials can be separated by more than 2*(N-1) test trials. Did I get this right?

I wrote this to do just what I described, but feel free to edit the code if your needs are different:

function ShuffleInChunks(...args) {
    this.args = [];
    this.numbers = [];
    for (let i = 0; i < args.length; i++){
        if (i%2) this.numbers.push(args[i]);
        else this.args.push(args[i]);
    }
    
    this.run = function(arrays) {
        let newarray = [];
        for (let i = 0; i < arrays.length; i++) fisherYates(arrays[i]);
        while (arrays.filter(a=>a.length>0).length){
            let currentChunk = [];
            for (let i = 0; i < arrays.length; i++) {
                let currentArray = arrays[i]
                for (let n = 0; n < this.numbers[i]; n++){
                    if (currentArray.length) currentChunk.push(currentArray.pop());
                    else break;
                }
            }
            fisherYates(currentChunk);
            newarray = newarray.concat(currentChunk);
        }
        return newarray;
    };
}
function shuffleInChunks(...args) { return new ShuffleInChunks(...args) }

You can use it like this, which would give you blocks of 11 trials---10 test trials and 1 catch trial, randomly shuffled:

Sequence( shuffleInChunks("test",10,"catch",1) )

To answer your question, Template does not return an array, it actually feeds the native-Ibex items array with the output of each newTrial loop on the table's row. It is also executed asynchronously, which means that you cannot simply write a Template command in your script and operate on its output by just writing some more code below it. This is why I'm suggesting the solution above: not only is it conceptually cleaner (you can directly tell the trial order just by looking at Sequence) but the trial order as defined by Sequence is computed after the native-Ibex items array has been filled, including with the outputs of Template.

Let me know if you have questions

Jeremy