Reply To: Partial randomization of trial sequence

PennController for IBEX Forums Support Partial randomization of trial sequence Reply To: Partial randomization of trial sequence

#5134
Jeremy
Keymaster

Hi,

What you are asking for is a little advanced, so I wrote a snippet for it. Add a .js file to your Controllers (js_includes) folder containing this code:

let subsequence;
let repeat;

(function (){
    function Times(n,predicate){
        this.predicate = predicate;
        this.n = n;
    }
    
    repeat = (predicate,n) => {
        if (n<=0) return predicate;
        else return new Times(n,predicate);
    };
    
    function Subsequence(...predicates) {
        this.args = [];
        this.times = [];
        for (let i = 0; i < predicates.length; i++){
            let predicate = predicates[i];
            if (predicate instanceof Times){
                this.args.push(predicate.predicate);
                this.times.push(predicate.n);
            }
            else{
                this.args.push(predicate);
                this.times.push(1);
            }
        }
    
        this.run = function(arrays) {
            let remainingPredicates = arrays.length;
            let newArray = [];
        
            while (remainingPredicates > 0){
                for (let n = 0; n < arrays.length; n++){
                    let predicate = arrays[n];
                    for (let times = 0; times < this.times[n] && predicate.length > 0; times++)
                        newArray.push( predicate.pop() );
                    if (predicate.length===0) remainingPredicates--;
                }
            }
            return newArray;
        };
    }
    
    subsequence = (...predicates) => new Subsequence(...predicates);
}());

Then you can use it like this in the Sequence command:

Sequence( "intro" , subsequence( repeat(randomize("main"),2) ,"sep" ) , "end" )

The command subsequence will return a series of interleaved trials with corresponding labels, exhausting them all, so if you simply had subsequence("main","sep") you would get a series of [main,sep,main,sep,main,sep,...] trials containing all the main and sep trials.

You can use the repeat command inside the subsequence command to control how frequently your interleave things, as illustrated above. You could even do something like this: subsequence( repeat("main",2) , repeat("sep",2) ) and you would get series of 2 main trials followed by 2 sep trials (ordered as defined in your script, since there’s no randomize command here).

Note that if you have more trials than necessary, they will be appended at the end of the subsequence: say you have 41 main trials and 22 sep trials, then subsequence( repeat(randomize("main"),2) ,"sep" ) will give you a series of 20 times [2 main trials followed by 1 sep trial] and then 1 remaining main trial followed by 2 remaining sep trials.

Jeremy