Applying circular mask with periodic boundary conditions in python Applying circular mask with periodic boundary conditions in python numpy numpy

Applying circular mask with periodic boundary conditions in python


One way could just be to create the mask of required size in the center of the array and then use np.roll to shift the mask along an axis (this causes the mask to wrap around the edges of the array).

Following the method in the linked question and answer:

ones = np.ones((8, 8))a, b = 3, 3n = 8r = 3mask = x**2 + y**2 <= r**2

constructs mask like this:

array([[False, False, False,  True, False, False, False, False],       [False,  True,  True,  True,  True,  True, False, False],       [False,  True,  True,  True,  True,  True, False, False],       [ True,  True,  True,  True,  True,  True,  True, False],       [False,  True,  True,  True,  True,  True, False, False],       [False,  True,  True,  True,  True,  True, False, False],       [False, False, False,  True, False, False, False, False],       [False, False, False, False, False, False, False, False]], dtype=bool)

Then rolling mask two places up and two places left and using it on ones...

>>> rolled_mask = np.roll(np.roll(mask, -2, axis=0), -2, axis=1)>>> ones[rolled_mask] = 255>>> onesarray([[ 255.,  255.,  255.,  255.,    1.,    1.,    1.,  255.],       [ 255.,  255.,  255.,  255.,  255.,    1.,  255.,  255.],       [ 255.,  255.,  255.,  255.,    1.,    1.,    1.,  255.],       [ 255.,  255.,  255.,  255.,    1.,    1.,    1.,  255.],       [   1.,  255.,    1.,    1.,    1.,    1.,    1.,    1.],       [   1.,    1.,    1.,    1.,    1.,    1.,    1.,    1.],       [   1.,  255.,    1.,    1.,    1.,    1.,    1.,    1.],       [ 255.,  255.,  255.,  255.,    1.,    1.,    1.,  255.]])


If you want to create the mask directly, the following works:

>>> N = 10>>> row, col = 8, 7>>> radius = 4>>> rows = np.arange(N) - row>>> rows = np.minimum(np.abs(rows), rows % N)>>> cols = np.arange(N) - col>>> cols = np.minimum(np.abs(cols), cols % N)>>> (rows[:, None]**2 + cols**2 <= radius**2).astype(int)array([[1, 0, 0, 0, 1, 1, 1, 1, 1, 1],       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],       [0, 0, 0, 0, 0, 0, 0, 1, 0, 0],       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 0, 0, 0, 0, 1, 0, 0],       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],       [1, 0, 0, 0, 1, 1, 1, 1, 1, 1],       [1, 0, 0, 0, 1, 1, 1, 1, 1, 1],       [1, 1, 0, 1, 1, 1, 1, 1, 1, 1],       [1, 0, 0, 0, 1, 1, 1, 1, 1, 1]])