Commit 8825607
authored
fix(space): correct centre offset and unbias SphericalShell sampling (#38)
## Summary
Two related bugs in `maws/space.py` that silently distort sampling for
`Sphere` and `SphericalShell`:
- **Centre offset ignored in `generator()`**
([maws/space.py:270](maws/space.py#L270),
[maws/space.py:339](maws/space.py#L339)) — both classes returned
coordinates around the origin instead of `self.centre`. Any caller
passing a non-zero centre (e.g. the ligand COM in `maws2023.py`) was
silently sampling in the wrong region of space. `Box.generator()`
already does this correctly; matched the same pattern.
- **Biased radial + polar-angle sampling in
`SphericalShell.generator()`** — `r ~ Uniform(R_in, R_out)` over-weights
the inner shell (no r² Jacobian) and `psi ~ Uniform(0, π)` over-weights
the poles. `Sphere.generator()` was already corrected in a prior change;
brought `SphericalShell` to the same volume-correct form:
- `r = (u·(R_out³ − R_in³) + R_in³)^(1/3)` for u ∈ [0, 1]
- direction via `cos(psi)` uniform in [-1, 1]
These matter because MAWS energy/entropy averages over the sampled poses
(`S(energies, beta=BETA)` in the first MAWS step) — biased sampling
biases the result.
## Tests
Existing `tests/test_space.py` only used `centre=[0,0,0]`, which masked
the centre-offset bug entirely. Added tests that:
- Pin samples within the radius/shell measured from a non-zero centre
(deterministic, would fail before fix).
- Statistically pin the radial mean (E[r] ≈ 8.04 vs. biased 7.5) and
direction (E[(z/r)²] ≈ 1/3 vs. biased 0.50) at N=10_000 with a tolerance
band that cleanly separates correct from biased.
`pytest tests/test_space.py` — 17/17 pass after the fix.
## Test plan
- [ ] CI passes on `main`
- [ ] `pytest tests/test_space.py` locally — 17 passed
- [ ] No callers regressed (Sphere/SphericalShell are not currently
invoked in `maws2023.py`; `Box`/`Cube` paths unchanged)
🤖 Generated with [Claude Code](https://claude.com/claude-code)1 parent 242ceaf commit 8825607
2 files changed
Lines changed: 88 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
269 | 269 | | |
270 | 270 | | |
271 | 271 | | |
272 | | - | |
273 | | - | |
274 | | - | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
275 | 275 | | |
276 | 276 | | |
277 | 277 | | |
| |||
332 | 332 | | |
333 | 333 | | |
334 | 334 | | |
335 | | - | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
336 | 340 | | |
337 | | - | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
338 | 344 | | |
339 | 345 | | |
340 | 346 | | |
341 | | - | |
342 | | - | |
343 | | - | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
344 | 350 | | |
345 | 351 | | |
346 | 352 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
96 | 116 | | |
97 | 117 | | |
98 | 118 | | |
| |||
112 | 132 | | |
113 | 133 | | |
114 | 134 | | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
115 | 189 | | |
116 | 190 | | |
117 | 191 | | |
| |||
0 commit comments