Skip to content

Commit

Permalink
psycho: improved rounding up of texture sizes
Browse files Browse the repository at this point in the history
- only round up when strictly necessary
- fixed incorrect texture sizes with psychopy backend
- related to #804
  • Loading branch information
smathot committed Nov 6, 2023
1 parent e8e56a9 commit 457218b
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions openexp/_canvas/_element/psycho.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from libopensesame.py3compat import *
import numpy as np
from openexp._canvas import canvas
from libopensesame.oslogging import oslogger


class PsychoElement:
Expand All @@ -39,6 +40,25 @@ def _on_attribute_change(self, **kwargs):

if self._canvas.auto_prepare:
self.prepare()

@staticmethod
def _power_of_two(n):
n = int(n)
# A power of two always has exactly one bit set and does not have any
# bitwise overlap with one number lower:
# 4: 100
# 3: 011
# &: 000
if (n & (n - 1) == 0) and n != 0:
return n
# The bit_length is the number of bits necessary to represent a number
# so for 3 this would be 2: 11. The bit_length for one number lower in
# this case is still 2: 10. The next power of two is 2 raised by this
# number, so 2 ** 2 = 4.
rounded_up = 2 ** ((n - 1).bit_length())
oslogger.warning(
f"Warning: {n} is not a power of two, rounding up to {rounded_up}.")
return rounded_up

def _mask(self, env, size, stdev):
r"""Generates a PsychoPy mask for Gabor and NoisePatch stimuli.
Expand All @@ -57,9 +77,6 @@ def _mask(self, env, size, stdev):
ndarray
A PsychoPy mask, which is a numpy array.
"""
# Get the smallest power-of-two that is larger than or equal to the
# given size
size = int(np.ceil(np.sqrt(size))**2)
# Create a PsychoPy mask
env = canvas._match_env(env)
if env == u'c':
Expand All @@ -69,6 +86,9 @@ def _mask(self, env, size, stdev):
if env == u'r':
return u'None', size
if env == u'l':
# Get the smallest power-of-two that is larger than or equal to
# the given size
size = self._power_of_two(size)
_env = np.zeros([size, size])
for x in range(size):
for y in range(size):
Expand Down

0 comments on commit 457218b

Please sign in to comment.