@@ -60,6 +60,53 @@ def test_amber_cmap(tmpdir, amber_cmap):
6060 assert line1 == line2
6161
6262
63+ def test_amber_multichain_cmap (tmpdir , multichain_cmap ):
64+ """Regression test for multi-chain CMAP write bug.
65+
66+ When a topology has more than one molecule with CMAP terms, the write path
67+ previously applied a spurious '/= 3' to the per-molecule atom offset,
68+ producing wrong global atom indices for molecules 2, 3, … . The re-parse
69+ of the generated text then raised:
70+ "there is a cmap between more than one different molecule"
71+ """
72+ mols = multichain_cmap
73+
74+ # Collect per-molecule CMAP term counts indexed by position in the
75+ # molecule list. There must be at least two molecules with CMAP
76+ # to trigger the multi-chain bug.
77+ cmap_counts = {}
78+ for i , mol in enumerate (mols .molecules ()):
79+ if mol .has_property ("cmap" ):
80+ cmap_counts [i ] = len (mol .property ("cmap" ).parameters ())
81+
82+ assert (
83+ len (cmap_counts ) >= 2
84+ ), "Expected at least two molecules with CMAP terms in this topology"
85+
86+ dir = tmpdir .mkdir ("test_amber_multichain_cmap" )
87+
88+ # Write the topology back to file. (This is where the bug used to trigger.)
89+ f = sr .save (mols , dir .join ("output" ), format = "prm7" )
90+
91+ # Reead the file back in.
92+ mols2 = sr .load (f )
93+
94+ # Each molecule must still have the same number of CMAP terms after the
95+ # roundtrip.
96+ for i , count in cmap_counts .items ():
97+ mol2 = mols2 [i ]
98+ assert mol2 .has_property (
99+ "cmap"
100+ ), f"Molecule at index { i } lost its cmap property after roundtrip"
101+ count2 = len (mol2 .property ("cmap" ).parameters ())
102+ assert (
103+ count2 == count
104+ ), f"Molecule at index { i } : CMAP count changed from { count } to { count2 } "
105+
106+ # Verify a second write also succeeds without error.
107+ sr .save (mols2 , dir .join ("output2" ), format = "prm7" )
108+
109+
63110def test_amber_cmap_grotop (tmpdir , amber_cmap ):
64111 """Testing reading and writing from amber to gromacs and back to amber."""
65112 mols = amber_cmap .clone ()
0 commit comments