Skip to content

Fix kernel to be symetric and properly spheroid#609

Open
matham wants to merge 1 commit intobrainglobe:mainfrom
matham:kernel
Open

Fix kernel to be symetric and properly spheroid#609
matham wants to merge 1 commit intobrainglobe:mainfrom
matham:kernel

Conversation

@matham
Copy link
Copy Markdown
Contributor

@matham matham commented Mar 26, 2026

Description

What is this PR

  • Bug fix
  • Addition of a new feature
  • Other

Why is this PR needed?

I noticed a bit of wonkiness in the kernel of the ball filter. I'm not sure how much of this intentional, so this PR edits it to how I would naively think the kernel should look so we can see if/what needs to change.

Primarily the issues I noticed is

  1. When the kernel size is odd, things look okay. But when it's even it's not symmetric and further it's a bit offset from where the center (centre 😉) should be between voxels. So the filtered data gets a bit shifted.
  2. This seems more of a bug, but the radius of the sphere is mostly the xy radius. So if the z radius is larger, it's essentially clipped to the xy radius instead of being a spheroid.

Following I printed out the kernel values so you can get a sense of what it's doing:

def print_kernel(ball_xy_size, ball_z_size):
    d = np.moveaxis(get_kernel(ball_xy_size, ball_z_size), 2, 0)
    for z in range(d.shape[0]):
        for y in range(d.shape[1]):
            print("\t".join([f"{v:0.2f}" for v in np.round(d[z, y], 2).tolist()]))
        print()

for xy in range(1, 5):
    for z in range(1, 5):
        print(f"Kernel: xy={xy}, z={z}")
        print_kernel(xy, z)

This gives for main:

Kernel: xy=1, z=1
0.52

Kernel: xy=1, z=2
0.21

0.31

Kernel: xy=1, z=3
0.00

0.52

0.00

Kernel: xy=1, z=4
0.00

0.21

0.31

0.00

Kernel: xy=1, z=5
0.00

0.00

0.52

0.00

0.00

Kernel: xy=2, z=1
0.59	0.71
0.71	0.85

Kernel: xy=2, z=2
0.37	0.46
0.46	0.57

0.46	0.57
0.57	0.69

Kernel: xy=2, z=3
0.12	0.15
0.15	0.20

0.59	0.71
0.71	0.85

0.12	0.15
0.15	0.20

Kernel: xy=2, z=4
0.00	0.00
0.00	0.00

0.37	0.46
0.46	0.57

0.46	0.57
0.57	0.69

0.00	0.00
0.00	0.00

Kernel: xy=2, z=5
0.00	0.00
0.00	0.00

0.12	0.15
0.15	0.20

0.59	0.71
0.71	0.85

0.12	0.15
0.15	0.20

0.00	0.00
0.00	0.00

Kernel: xy=3, z=1
0.52	0.97	0.52
0.97	1.00	0.97
0.52	0.97	0.52

Kernel: xy=3, z=2
0.39	0.83	0.39
0.83	1.00	0.83
0.39	0.83	0.39

0.44	0.90	0.44
0.90	1.00	0.90
0.44	0.90	0.44

Kernel: xy=3, z=3
0.17	0.52	0.17
0.52	0.97	0.52
0.17	0.52	0.17

0.52	0.97	0.52
0.97	1.00	0.97
0.52	0.97	0.52

0.17	0.52	0.17
0.52	0.97	0.52
0.17	0.52	0.17

Kernel: xy=3, z=4
0.01	0.10	0.01
0.10	0.39	0.10
0.01	0.10	0.01

0.39	0.83	0.39
0.83	1.00	0.83
0.39	0.83	0.39

0.44	0.90	0.44
0.90	1.00	0.90
0.44	0.90	0.44

0.03	0.18	0.03
0.18	0.54	0.18
0.03	0.18	0.03

Kernel: xy=3, z=5
0.00	0.00	0.00
0.00	0.00	0.00
0.00	0.00	0.00

0.17	0.52	0.17
0.52	0.97	0.52
0.17	0.52	0.17

0.52	0.97	0.52
0.97	1.00	0.97
0.52	0.97	0.52

0.17	0.52	0.17
0.52	0.97	0.52
0.17	0.52	0.17

0.00	0.00	0.00
0.00	0.00	0.00
0.00	0.00	0.00

Kernel: xy=4, z=1
0.20	0.79	0.83	0.29
0.79	1.00	1.00	0.94
0.83	1.00	1.00	0.97
0.29	0.94	0.97	0.41

Kernel: xy=4, z=2
0.14	0.71	0.75	0.22
0.71	1.00	1.00	0.85
0.75	1.00	1.00	0.90
0.22	0.85	0.90	0.31

0.16	0.75	0.79	0.24
0.75	1.00	1.00	0.90
0.79	1.00	1.00	0.93
0.24	0.90	0.93	0.35

Kernel: xy=4, z=3
0.06	0.50	0.55	0.10
0.50	1.00	1.00	0.64
0.55	1.00	1.00	0.69
0.10	0.64	0.69	0.17

0.20	0.79	0.83	0.29
0.79	1.00	1.00	0.94
0.83	1.00	1.00	0.97
0.29	0.94	0.97	0.41

0.06	0.50	0.55	0.10
0.50	1.00	1.00	0.64
0.55	1.00	1.00	0.69
0.10	0.64	0.69	0.17

Kernel: xy=4, z=4
0.00	0.14	0.16	0.01
0.14	0.71	0.75	0.22
0.16	0.75	0.79	0.24
0.01	0.22	0.24	0.03

0.14	0.71	0.75	0.22
0.71	1.00	1.00	0.85
0.75	1.00	1.00	0.90
0.22	0.85	0.90	0.31

0.16	0.75	0.79	0.24
0.75	1.00	1.00	0.90
0.79	1.00	1.00	0.93
0.24	0.90	0.93	0.35

0.01	0.22	0.24	0.03
0.22	0.85	0.90	0.31
0.24	0.90	0.93	0.35
0.03	0.31	0.35	0.05

Kernel: xy=4, z=5
0.00	0.01	0.01	0.00
0.01	0.29	0.32	0.03
0.01	0.32	0.36	0.03
0.00	0.03	0.03	0.00

0.06	0.50	0.55	0.10
0.50	1.00	1.00	0.64
0.55	1.00	1.00	0.69
0.10	0.64	0.69	0.17

0.20	0.79	0.83	0.29
0.79	1.00	1.00	0.94
0.83	1.00	1.00	0.97
0.29	0.94	0.97	0.41

0.06	0.50	0.55	0.10
0.50	1.00	1.00	0.64
0.55	1.00	1.00	0.69
0.10	0.64	0.69	0.17

0.00	0.01	0.01	0.00
0.01	0.29	0.32	0.03
0.01	0.32	0.36	0.03
0.00	0.03	0.03	0.00

Kernel: xy=5, z=1
0.12	0.76	0.99	0.76	0.12
0.76	1.00	1.00	1.00	0.76
0.99	1.00	1.00	1.00	0.99
0.76	1.00	1.00	1.00	0.76
0.12	0.76	0.99	0.76	0.12

Kernel: xy=5, z=2
0.09	0.68	0.91	0.68	0.09
0.68	1.00	1.00	1.00	0.68
0.91	1.00	1.00	1.00	0.91
0.68	1.00	1.00	1.00	0.68
0.09	0.68	0.91	0.68	0.09

0.10	0.71	0.94	0.71	0.10
0.71	1.00	1.00	1.00	0.71
0.94	1.00	1.00	1.00	0.94
0.71	1.00	1.00	1.00	0.71
0.10	0.71	0.94	0.71	0.10

Kernel: xy=5, z=3
0.04	0.51	0.76	0.51	0.04
0.51	1.00	1.00	1.00	0.51
0.76	1.00	1.00	1.00	0.76
0.51	1.00	1.00	1.00	0.51
0.04	0.51	0.76	0.51	0.04

0.12	0.76	0.99	0.76	0.12
0.76	1.00	1.00	1.00	0.76
0.99	1.00	1.00	1.00	0.99
0.76	1.00	1.00	1.00	0.76
0.12	0.76	0.99	0.76	0.12

0.04	0.51	0.76	0.51	0.04
0.51	1.00	1.00	1.00	0.51
0.76	1.00	1.00	1.00	0.76
0.51	1.00	1.00	1.00	0.51
0.04	0.51	0.76	0.51	0.04

Kernel: xy=5, z=4
0.00	0.20	0.39	0.20	0.00
0.20	0.89	1.00	0.89	0.20
0.39	1.00	1.00	1.00	0.39
0.20	0.89	1.00	0.89	0.20
0.00	0.20	0.39	0.20	0.00

0.09	0.68	0.91	0.68	0.09
0.68	1.00	1.00	1.00	0.68
0.91	1.00	1.00	1.00	0.91
0.68	1.00	1.00	1.00	0.68
0.09	0.68	0.91	0.68	0.09

0.10	0.71	0.94	0.71	0.10
0.71	1.00	1.00	1.00	0.71
0.94	1.00	1.00	1.00	0.94
0.71	1.00	1.00	1.00	0.71
0.10	0.71	0.94	0.71	0.10

0.01	0.27	0.50	0.27	0.01
0.27	0.95	1.00	0.95	0.27
0.50	1.00	1.00	1.00	0.50
0.27	0.95	1.00	0.95	0.27
0.01	0.27	0.50	0.27	0.01

Kernel: xy=5, z=5
0.00	0.04	0.12	0.04	0.00
0.04	0.51	0.76	0.51	0.04
0.12	0.76	0.99	0.76	0.12
0.04	0.51	0.76	0.51	0.04
0.00	0.04	0.12	0.04	0.00

0.04	0.51	0.76	0.51	0.04
0.51	1.00	1.00	1.00	0.51
0.76	1.00	1.00	1.00	0.76
0.51	1.00	1.00	1.00	0.51
0.04	0.51	0.76	0.51	0.04

0.12	0.76	0.99	0.76	0.12
0.76	1.00	1.00	1.00	0.76
0.99	1.00	1.00	1.00	0.99
0.76	1.00	1.00	1.00	0.76
0.12	0.76	0.99	0.76	0.12

0.04	0.51	0.76	0.51	0.04
0.51	1.00	1.00	1.00	0.51
0.76	1.00	1.00	1.00	0.76
0.51	1.00	1.00	1.00	0.51
0.04	0.51	0.76	0.51	0.04

0.00	0.04	0.12	0.04	0.00
0.04	0.51	0.76	0.51	0.04
0.12	0.76	0.99	0.76	0.12
0.04	0.51	0.76	0.51	0.04
0.00	0.04	0.12	0.04	0.00

You can see how skewed the kernel gets in either direction when xy is significantly different than z.

What does this PR do?

I changed the sphere shape to be properly spheroid and to be centered between voxels when the kernel is even.

With this PR, the printout is instead:

Kernel: xy=1, z=1
0.52

Kernel: xy=1, z=2
0.52

0.52

Kernel: xy=1, z=3
0.43

0.76

0.43

Kernel: xy=1, z=4
0.31

0.73

0.73

0.31

Kernel: xy=1, z=5
0.28

0.67

0.76

0.67

0.28

Kernel: xy=2, z=1
0.56	0.56
0.56	0.56

Kernel: xy=2, z=2
0.54	0.54
0.54	0.54

0.54	0.54
0.54	0.54

Kernel: xy=2, z=3
0.42	0.42
0.42	0.42

0.77	0.77
0.77	0.77

0.42	0.42
0.42	0.42

Kernel: xy=2, z=4
0.33	0.33
0.33	0.33

0.72	0.72
0.72	0.72

0.72	0.72
0.72	0.72

0.33	0.33
0.33	0.33

Kernel: xy=2, z=5
0.27	0.27
0.27	0.27

0.66	0.66
0.66	0.66

0.77	0.77
0.77	0.77

0.66	0.66
0.66	0.66

0.27	0.27
0.27	0.27

Kernel: xy=3, z=1
0.29	0.68	0.29
0.68	1.00	0.68
0.29	0.68	0.29

Kernel: xy=3, z=2
0.28	0.65	0.28
0.65	0.99	0.65
0.28	0.65	0.28

0.28	0.65	0.28
0.65	0.99	0.65
0.28	0.65	0.28

Kernel: xy=3, z=3
0.17	0.52	0.17
0.52	0.97	0.52
0.17	0.52	0.17

0.52	0.97	0.52
0.97	1.00	0.97
0.52	0.97	0.52

0.17	0.52	0.17
0.52	0.97	0.52
0.17	0.52	0.17

Kernel: xy=3, z=4
0.10	0.40	0.10
0.40	0.92	0.40
0.10	0.40	0.10

0.47	0.91	0.47
0.91	1.00	0.91
0.47	0.91	0.47

0.47	0.91	0.47
0.91	1.00	0.91
0.47	0.91	0.47

0.10	0.40	0.10
0.40	0.92	0.40
0.10	0.40	0.10

Kernel: xy=3, z=5
0.06	0.33	0.06
0.33	0.92	0.33
0.06	0.33	0.06

0.39	0.84	0.39
0.84	1.00	0.84
0.39	0.84	0.39

0.53	0.98	0.53
0.98	1.00	0.98
0.53	0.98	0.53

0.39	0.84	0.39
0.84	1.00	0.84
0.39	0.84	0.39

0.06	0.33	0.06
0.33	0.92	0.33
0.06	0.33	0.06

Kernel: xy=4, z=1
0.12	0.51	0.51	0.12
0.51	0.95	0.95	0.51
0.51	0.95	0.95	0.51
0.12	0.51	0.51	0.12

Kernel: xy=4, z=2
0.13	0.54	0.54	0.13
0.54	0.92	0.92	0.54
0.54	0.92	0.92	0.54
0.13	0.54	0.54	0.13

0.13	0.54	0.54	0.13
0.54	0.92	0.92	0.54
0.54	0.92	0.92	0.54
0.13	0.54	0.54	0.13

Kernel: xy=4, z=3
0.06	0.34	0.34	0.06
0.34	0.87	0.87	0.34
0.34	0.87	0.87	0.34
0.06	0.34	0.34	0.06

0.28	0.88	0.88	0.28
0.88	1.00	1.00	0.88
0.88	1.00	1.00	0.88
0.28	0.88	0.88	0.28

0.06	0.34	0.34	0.06
0.34	0.87	0.87	0.34
0.34	0.87	0.87	0.34
0.06	0.34	0.34	0.06

Kernel: xy=4, z=4
0.01	0.24	0.24	0.01
0.24	0.83	0.83	0.24
0.24	0.83	0.83	0.24
0.01	0.24	0.24	0.01

0.24	0.83	0.83	0.24
0.83	1.00	1.00	0.83
0.83	1.00	1.00	0.83
0.24	0.83	0.83	0.24

0.24	0.83	0.83	0.24
0.83	1.00	1.00	0.83
0.83	1.00	1.00	0.83
0.24	0.83	0.83	0.24

0.01	0.24	0.24	0.01
0.24	0.83	0.83	0.24
0.24	0.83	0.83	0.24
0.01	0.24	0.24	0.01

Kernel: xy=4, z=5
0.00	0.15	0.15	0.00
0.15	0.78	0.78	0.15
0.15	0.78	0.78	0.15
0.00	0.15	0.15	0.00

0.15	0.71	0.71	0.15
0.71	1.00	1.00	0.71
0.71	1.00	1.00	0.71
0.15	0.71	0.71	0.15

0.31	0.91	0.91	0.31
0.91	1.00	1.00	0.91
0.91	1.00	1.00	0.91
0.31	0.91	0.91	0.31

0.15	0.71	0.71	0.15
0.71	1.00	1.00	0.71
0.71	1.00	1.00	0.71
0.15	0.71	0.71	0.15

0.00	0.15	0.15	0.00
0.15	0.78	0.78	0.15
0.15	0.78	0.78	0.15
0.00	0.15	0.15	0.00

Kernel: xy=5, z=1
0.03	0.38	0.55	0.38	0.03
0.38	0.80	0.92	0.80	0.38
0.55	0.92	1.00	0.92	0.55
0.38	0.80	0.92	0.80	0.38
0.03	0.38	0.55	0.38	0.03

Kernel: xy=5, z=2
0.04	0.36	0.55	0.36	0.04
0.36	0.81	0.91	0.81	0.36
0.55	0.91	1.00	0.91	0.55
0.36	0.81	0.91	0.81	0.36
0.04	0.36	0.55	0.36	0.04

0.04	0.36	0.55	0.36	0.04
0.36	0.81	0.91	0.81	0.36
0.55	0.91	1.00	0.91	0.55
0.36	0.81	0.91	0.81	0.36
0.04	0.36	0.55	0.36	0.04

Kernel: xy=5, z=3
0.00	0.20	0.36	0.20	0.00
0.20	0.71	0.85	0.71	0.20
0.36	0.85	1.00	0.85	0.36
0.20	0.71	0.85	0.71	0.20
0.00	0.20	0.36	0.20	0.00

0.10	0.72	0.95	0.72	0.10
0.72	1.00	1.00	1.00	0.72
0.95	1.00	1.00	1.00	0.95
0.72	1.00	1.00	1.00	0.72
0.10	0.72	0.95	0.72	0.10

0.00	0.20	0.36	0.20	0.00
0.20	0.71	0.85	0.71	0.20
0.36	0.85	1.00	0.85	0.36
0.20	0.71	0.85	0.71	0.20
0.00	0.20	0.36	0.20	0.00

Kernel: xy=5, z=4
0.00	0.09	0.20	0.09	0.00
0.09	0.61	0.79	0.61	0.09
0.20	0.79	1.00	0.79	0.20
0.09	0.61	0.79	0.61	0.09
0.00	0.09	0.20	0.09	0.00

0.07	0.64	0.88	0.64	0.07
0.64	1.00	1.00	1.00	0.64
0.88	1.00	1.00	1.00	0.88
0.64	1.00	1.00	1.00	0.64
0.07	0.64	0.88	0.64	0.07

0.07	0.64	0.88	0.64	0.07
0.64	1.00	1.00	1.00	0.64
0.88	1.00	1.00	1.00	0.88
0.64	1.00	1.00	1.00	0.64
0.07	0.64	0.88	0.64	0.07

0.00	0.09	0.20	0.09	0.00
0.09	0.61	0.79	0.61	0.09
0.20	0.79	1.00	0.79	0.20
0.09	0.61	0.79	0.61	0.09
0.00	0.09	0.20	0.09	0.00

Kernel: xy=5, z=5
0.00	0.04	0.12	0.04	0.00
0.04	0.51	0.76	0.51	0.04
0.12	0.76	0.99	0.76	0.12
0.04	0.51	0.76	0.51	0.04
0.00	0.04	0.12	0.04	0.00

0.04	0.51	0.76	0.51	0.04
0.51	1.00	1.00	1.00	0.51
0.76	1.00	1.00	1.00	0.76
0.51	1.00	1.00	1.00	0.51
0.04	0.51	0.76	0.51	0.04

0.12	0.76	0.99	0.76	0.12
0.76	1.00	1.00	1.00	0.76
0.99	1.00	1.00	1.00	0.99
0.76	1.00	1.00	1.00	0.76
0.12	0.76	0.99	0.76	0.12

0.04	0.51	0.76	0.51	0.04
0.51	1.00	1.00	1.00	0.51
0.76	1.00	1.00	1.00	0.76
0.51	1.00	1.00	1.00	0.51
0.04	0.51	0.76	0.51	0.04

0.00	0.04	0.12	0.04	0.00
0.04	0.51	0.76	0.51	0.04
0.12	0.76	0.99	0.76	0.12
0.04	0.51	0.76	0.51	0.04
0.00	0.04	0.12	0.04	0.00

References

Please reference any existing issues/PRs that relate to this PR.

How has this PR been tested?

I added a test that checks for symmetry.

Is this a breaking change?

In a way it's a break, because the kernel size parameter would behave a bit differently for even kernels and when xy is different than z.

Does this PR require an update to the documentation?

No.

Checklist:

  • The code has been tested locally
  • Tests have been added to cover all new functionality (unit & integration)
  • The documentation has been updated to reflect any changes
  • The code has been formatted with pre-commit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant