Basically I am fine with the kp_circular_patch version, but you could do the following to avoid it:

     ...
    for c in range(7):
        if circular_mask[r, c]:
            mu[p, q] = ...

But for performance reasons I would then reverse the loop order: first "for r, c in ...", then "for p, q" - this way you save a lot of masking tests.