@@ -7,7 +7,7 @@ use crate::core::models::residue::{Residue, ResidueType};
77use crate :: core:: models:: system:: MolecularSystem ;
88use crate :: core:: models:: topology:: BondOrder ;
99use nalgebra:: Point3 ;
10- use std:: collections:: { BTreeSet , HashMap } ;
10+ use std:: collections:: { BTreeMap , HashMap } ;
1111use std:: io:: { self , BufRead , Write } ;
1212use thiserror:: Error ;
1313
@@ -270,25 +270,41 @@ impl MolecularFile for BgfFile {
270270 }
271271
272272 // --- Phase 4: Write CONECT records using the new serial numbers ---
273- let mut bond_pairs = BTreeSet :: new ( ) ;
274- for bond in system. bonds ( ) {
275- if let ( Some ( & serial1) , Some ( & serial2) ) = (
276- atom_id_to_new_serial. get ( & bond. atom1_id ) ,
277- atom_id_to_new_serial. get ( & bond. atom2_id ) ,
278- ) {
279- let bond_pair = if serial1 < serial2 {
280- ( serial1, serial2)
281- } else {
282- ( serial2, serial1)
283- } ;
284- bond_pairs. insert ( bond_pair) ;
273+
274+ // Step 4.1: Build an adjacency list using the new serial numbers.
275+ let mut serial_adjacency_list = BTreeMap :: < usize , Vec < usize > > :: new ( ) ;
276+ for canonical_atom in & sorted_atoms {
277+ let base_serial = atom_id_to_new_serial[ & canonical_atom. id ] ;
278+
279+ if let Some ( neighbor_ids) = system. get_bonded_neighbors ( canonical_atom. id ) {
280+ if neighbor_ids. is_empty ( ) {
281+ continue ;
282+ }
283+
284+ let neighbor_serials: Vec < usize > = neighbor_ids
285+ . iter ( )
286+ . map ( |neighbor_id| atom_id_to_new_serial[ neighbor_id] )
287+ . collect ( ) ;
288+
289+ serial_adjacency_list. insert ( base_serial, neighbor_serials) ;
285290 }
286291 }
287292
288293 writeln ! ( writer, "FORMAT CONECT (a6,12i6)" ) ?;
289294
290- for ( s1, s2) in bond_pairs {
291- writeln ! ( writer, "CONECT {:>5} {:>6}" , s1, s2) ?;
295+ // Step 4.2: Write a CONECT record for each atom that has bonds.
296+ const MAX_NEIGHBORS_PER_LINE : usize = 12 ;
297+
298+ for ( base_serial, mut neighbors) in serial_adjacency_list {
299+ neighbors. sort_unstable ( ) ;
300+
301+ for neighbor_chunk in neighbors. chunks ( MAX_NEIGHBORS_PER_LINE ) {
302+ let mut line = format ! ( "CONECT{:>6}" , base_serial) ;
303+ for & neighbor_serial in neighbor_chunk {
304+ line. push_str ( & format ! ( "{:>6}" , neighbor_serial) ) ;
305+ }
306+ writeln ! ( writer, "{}" , line) ?;
307+ }
292308 }
293309
294310 writeln ! ( writer, "END" ) ?;
@@ -513,11 +529,12 @@ ATOM 6 CA ALA B 2 3.00000 0.00000 1.00000 C_3 1 4 0.07000
513529ATOM 7 CB ALA B 2 3.50000 1.50000 1.00000 C_3 1 4 -0.18000
514530FORMAT CONECT (a6,12i6)
515531CONECT 1 2
516- CONECT 2 3
517- CONECT 3 4
518- CONECT 3 5
519- CONECT 5 6
520- CONECT 6 7
532+ CONECT 2 1 3
533+ CONECT 3 2 4 5
534+ CONECT 4 3
535+ CONECT 5 3 6
536+ CONECT 6 5 7
537+ CONECT 7 6
521538END
522539"# ;
523540
661678 . iter ( )
662679 . filter ( |l| l. starts_with ( "CONECT" ) )
663680 . collect ( ) ;
664- assert_eq ! ( conect_lines. len( ) , 2 ) ;
681+ assert_eq ! ( conect_lines. len( ) , 4 ) ;
665682
666683 let bond1_found = conect_lines
667684 . iter ( )
0 commit comments