Problem with a stimulus exposition time (and code for a random magnitude dots)

Hello everyone. I have made a procedure for my study but I have a strange problem. I want to show random polygons for 0.6 s and, afterwards a mask for 0.4 s. Those timings are set directly in code but when I run this code sometimes, polygons duration is shorter (like 0.3, 0.4 s). Some of them are ok. I am not sure, but shorter exposition seems to be connected with longer fixation point exposition. I would be grateful for a tip, how can I fix this. Here is a sample code responsible for this routine:

var circle_list;
var dot_size_base;
var dots1;
var dot_size2_base;
var dots2;
var sprawdzenie;
var YellowDotsDrawing;
var BlueDotsDrawing;
var n_dots1;
var n_dots2;
var NumberSenseComponents;
function NumberSenseRoutineBegin(snapshot) {
return function () {
//------Prepare to start Routine ‘NumberSense’-------
t = 0;
NumberSenseClock.reset(); // clock
frameN = -1;
continueRoutine = true; // until we’re told otherwise
routineTimer.add(1.6000);
// update component parameters for each repeat
// keep track of which components have finished
NumberSenseComponents = ;

circle_list = [];

var n_kropek = getRandomIntInclusive(10,30)
var check_n_kropek = getRandomIntInclusive(1,4)
var check_kolejnosc = getRandomIntInclusive(1,2)

if (check_n_kropek == 1){
    var n2_kropek = Math.round(3/4 *n_kropek);
    var dots_ratio = 3/4;
}
else if (check_n_kropek == 2){
    var n2_kropek = Math.round(4/5 *n_kropek);
    var dots_ratio = 4/5;
}
else if (check_n_kropek == 3){
    var n2_kropek = Math.round(5/6 *n_kropek);
    var dots_ratio = 5/6;
}
else{
    var n2_kropek = Math.round(6/7 *n_kropek);
    var dots_ratio = 6/7;
}


if (check_kolejnosc == 1){
    n_dots1 = n_kropek;
    n_dots2 = n2_kropek;
}
else{
    n_dots1 = n2_kropek;
    n_dots2 = n_kropek;
} 


dot_size_base = [];
dots1 = [];
dot_size2_base = [];
dots2 = [];
sprawdzenie = 0;

while (dot_size_base.length < n_dots1){
    var r = getRandomIntInclusive(20,40);
    var x = getRandomIntInclusive(-700,700);
    var y = getRandomIntInclusive(-450,450);
    for (var i = 0; i < circle_list.length; i ++){
        if (euclidean_distance(x,y, circle_list[i][0], circle_list[i][1]) < r + circle_list[i][2]){
            sprawdzenie = sprawdzenie + 1;
        }
    }

    if (sprawdzenie == 0){
        circle_list.push([x,y,r]);
        dots1.push([x,y]);
        dot_size_base.push([r]);
    }
    else{
        sprawdzenie = 0;
    }
}
while (dot_size2_base.length < n_dots2){
    var r = getRandomIntInclusive(20,40);
    var x = getRandomIntInclusive(-700,700);
    var y = getRandomIntInclusive(-450,450);
    for (var i = 0; i < circle_list.length; i ++){
        if (euclidean_distance(x,y, circle_list[i][0], circle_list[i][1]) < r + circle_list[i][2]){
            sprawdzenie = sprawdzenie + 1;
        }
    }

    if (sprawdzenie == 0){
        circle_list.push([x,y,r]);
        dots2.push([x,y]);
        dot_size2_base.push([r]);
    }
    else{
        sprawdzenie = 0;
    }
}
  


YellowDotsDrawing = [];
for (var i = 0; i < n_dots1; i++) {
    YellowDotsDrawing[i] = new visual.Polygon ({
        win: psychoJS.window, name: 'yellow', units : 'pix', 
        edges: 2000, size:[dot_size_base[i][0], dot_size_base[i][0]],
        ori: 0.0, pos: [dots1[i][0], dots1[i][1]],
        lineWidth: 1.0, lineColor: new util.Color('yellow'),
        fillColor: new util.Color('yellow'),
        opacity: undefined, depth: 0, interpolate: true,
    });
}
for (var i = 0; i < n_dots1; i++) {
    NumberSenseComponents.push(YellowDotsDrawing[i]);
}


BlueDotsDrawing = [];
for (var i = 0; i < n_dots2; i++) {
    BlueDotsDrawing[i] = new visual.Polygon ({
        win: psychoJS.window, name: 'yellow', units : 'pix', 
        edges: 2000, size:[dot_size2_base[i][0], dot_size2_base[i][0]],
        ori: 0.0, pos: [dots2[i][0], dots2[i][1]],
        lineWidth: 1.0, lineColor: new util.Color('blue'),
        fillColor: new util.Color('blue'),
        opacity: undefined, depth: 0, interpolate: true,
    });
}
for (var i = 0; i < n_dots2; i++) {
    NumberSenseComponents.push(BlueDotsDrawing[i]);
}



for (const thisComponent of NumberSenseComponents)
  if ('status' in thisComponent)
    thisComponent.status = PsychoJS.Status.NOT_STARTED;
psychoJS.experiment.addData("DotsRatio", dots_ratio);
psychoJS.experiment.addData("YellowDots", n_dots1);
psychoJS.experiment.addData("BlueDots", n_dots2);
psychoJS.experiment.addData("YellowDotsRadius", dot_size_base);
psychoJS.experiment.addData("YellowDotsPosition", dots1);
psychoJS.experiment.addData("BlueDotsRadius", dot_size2_base);
psychoJS.experiment.addData("BlueDotsPosition", dots2);
return Scheduler.Event.NEXT;

}
}

function NumberSenseRoutineEachFrame(snapshot) {
return function () {
//------Loop for each frame of Routine ‘NumberSense’-------
// get current time
t = NumberSenseClock.getTime();
frameN = frameN + 1;// number of completed frames (so 0 is the first frame)
// update/draw components on each frame

for (var i = 0; i < n_dots1; i++) {
    // *yellow* updates
    if (t >= 0.0 && YellowDotsDrawing[i].status === PsychoJS.Status.NOT_STARTED) {
      // keep track of start time/frame for later
      YellowDotsDrawing[i].tStart = t;  // (not accounting for frame time here)
      YellowDotsDrawing[i].frameNStart = frameN;  // exact frame index
      
      YellowDotsDrawing[i].setAutoDraw(true);
    }

    frameRemains = 0.0 + 0.6 - psychoJS.window.monitorFramePeriod * 0.75;  // most of one frame period left
    if (YellowDotsDrawing[i].status === PsychoJS.Status.STARTED && t >= frameRemains) {
      YellowDotsDrawing[i].setAutoDraw(false);
    }
}

for (var i = 0; i < n_dots2; i++) {
        // *blue* updates
    if (t >= 0.0 && BlueDotsDrawing[i].status === PsychoJS.Status.NOT_STARTED) {
      // keep track of start time/frame for later
      BlueDotsDrawing[i].tStart = t;  // (not accounting for frame time here)
      BlueDotsDrawing[i].frameNStart = frameN;  // exact frame index
      
      BlueDotsDrawing[i].setAutoDraw(true);
    }

    frameRemains = 0.0 + 0.6 - psychoJS.window.monitorFramePeriod * 0.75;  // most of one frame period left
    if (BlueDotsDrawing[i].status === PsychoJS.Status.STARTED && t >= frameRemains) {
      BlueDotsDrawing[i].setAutoDraw(false);
    }
}
// check for quit (typically the Esc key)
if (psychoJS.experiment.experimentEnded || psychoJS.eventManager.getKeys({keyList:['escape']}).length > 0) {
  return quitPsychoJS('The [Escape] key was pressed. Goodbye!', false);
}

// check if the Routine should terminate
if (!continueRoutine) {  // a component has requested a forced-end of Routine
  return Scheduler.Event.NEXT;
}

continueRoutine = false;  // reverts to True if at least one component still running
for (const thisComponent of NumberSenseComponents)
  if ('status' in thisComponent && thisComponent.status !== PsychoJS.Status.FINISHED) {
    continueRoutine = true;
    break;
  }

// refresh the screen if continuing
if (continueRoutine && routineTimer.getTime() > 0) {
  return Scheduler.Event.FLIP_REPEAT;
} else {
  return Scheduler.Event.NEXT;
}

};
}

function NumberSenseRoutineEnd(snapshot) {
return function () {
//------Ending Routine ‘NumberSense’-------
for (const thisComponent of NumberSenseComponents) {
if (typeof thisComponent.setAutoDraw === ‘function’) {
thisComponent.setAutoDraw(false);
}
}
return Scheduler.Event.NEXT;
};
}

and mask routine:
var maskComponents;
function maskRoutineBegin(snapshot) {
return function () {
//------Prepare to start Routine ‘mask’-------
t = 0;
maskClock.reset(); // clock
frameN = -1;
continueRoutine = true; // until we’re told otherwise
routineTimer.add(0.400000);
// update component parameters for each repeat
// keep track of which components have finished
maskComponents = ;
maskComponents.push(image);

for (const thisComponent of maskComponents)
  if ('status' in thisComponent)
    thisComponent.status = PsychoJS.Status.NOT_STARTED;
return Scheduler.Event.NEXT;

}
}

function maskRoutineEachFrame(snapshot) {
return function () {
//------Loop for each frame of Routine ‘mask’-------
// get current time
t = maskClock.getTime();
frameN = frameN + 1;// number of completed frames (so 0 is the first frame)
// update/draw components on each frame

// *image* updates
if (t >= 0.0 && image.status === PsychoJS.Status.NOT_STARTED) {
  // keep track of start time/frame for later
  image.tStart = t;  // (not accounting for frame time here)
  image.frameNStart = frameN;  // exact frame index
  
  image.setAutoDraw(true);
}

frameRemains = 0.0 + 0.4 - psychoJS.window.monitorFramePeriod * 0.75;  // most of one frame period left
if (image.status === PsychoJS.Status.STARTED && t >= frameRemains) {
  image.setAutoDraw(false);
}
// check for quit (typically the Esc key)
if (psychoJS.experiment.experimentEnded || psychoJS.eventManager.getKeys({keyList:['escape']}).length > 0) {
  return quitPsychoJS('The [Escape] key was pressed. Goodbye!', false);
}

// check if the Routine should terminate
if (!continueRoutine) {  // a component has requested a forced-end of Routine
  return Scheduler.Event.NEXT;
}

continueRoutine = false;  // reverts to True if at least one component still running
for (const thisComponent of maskComponents)
  if ('status' in thisComponent && thisComponent.status !== PsychoJS.Status.FINISHED) {
    continueRoutine = true;
    break;
  }

// refresh the screen if continuing
if (continueRoutine && routineTimer.getTime() > 0) {
  return Scheduler.Event.FLIP_REPEAT;
} else {
  return Scheduler.Event.NEXT;
}

};
}

function maskRoutineEnd(snapshot) {
return function () {
//------Ending Routine ‘mask’-------
for (const thisComponent of maskComponents) {
if (typeof thisComponent.setAutoDraw === ‘function’) {
thisComponent.setAutoDraw(false);
}
}
return Scheduler.Event.NEXT;
};
}

Have you coded this in Builder?

Please could you show the key components and custom code (preferably in Python where you are using Auto translate).

Pasting code generated by PsychoPy makes it difficult to debug.

Thanks for your response :slight_smile: Thankfully I solved this problem. Somehow my code was overwriting some part in a loop, and there was memory overload. I modified my code to clear those problematic variables at the end of each iteration, and it has solved both problems.

Best regards!

1 Like