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]])