Protenix bond merging changes crossed copy pairings
- Dominant language
- Python
- Stars
- 100
- Forks
- 12
- PR merge metrics
- No merged PRs in 30d
Description
## Description
`ProtenixInput.to_json()` can collapse crossed copy-specific covalent bonds into a copy-agnostic bond. Loading that JSON expands it as identity-paired bonds, so the round trip changes molecular topology.
## Minimal reproduction
Create two entities with `count=2` and these bonds at the same residue/atom positions:
```text
entity 1 copy 1 -> entity 2 copy 2
entity 1 copy 2 -> entity 2 copy 1
```
Then run:
```python
encoded = source.to_json()
roundtrip = ProtenixInput.from_json(encoded)
```
Observed result at current `main` (`72117242154d0c9f52ce727dc352210aab76d495`):
```text
before: [(1, 2), (2, 1)]
JSON: one bond with copy1/copy2 omitted
after: [(1, 1), (2, 2)]
```
Expected: serialization should preserve `[(1, 2), (2, 1)]`.
## Root cause
`_merge_covalent_bonds()` groups by entity, position and atom while ignoring copy IDs. It removes both copy fields whenever the number of grouped bonds equals both entity counts. `from_json()` interprets missing copy fields as identity pairing (`c -> c`), which is not equivalent for crossed or otherwise permuted pairings.
## Impact
A valid-looking Protenix JSON round trip can silently connect different molecular copies than the input requested.
## Why this issue does not include a PR yet
A safe fix needs the maintainers to confirm the intended Protenix serialization contract: whether non-identity copy pairings must always remain explicit, and which complete copy-pair sets are legal to compress. Preserving every copy field is lossless but may give up schema-level compression expected by downstream Protenix consumers. Once that contract is confirmed, a focused round-trip regression test and minimal merge predicate change should be straightforward.
## Environment
- Python 3.11.15
- PXMeter current `main`: `72117242154d0c9f52ce727dc352210aab76d495`
- Reproduced entirely in memory; no model, CIF or external service required
Contributor guide
Research direction
Start with ProtenixInput.to_json(), from_json(), and _merge_covalent_bonds(), then run the in-memory crossed-pair reproduction from the issue. Confirm with maintainers which copy-pair sets may omit copy fields; done means the agreed serialization contract preserves [(1, 2), (2, 1)] after a JSON round trip and includes a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- bioinformatics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100