Merge pull request #1669 from papillot/pdb-conect-to-bond-order

Get bonds orders from CONECT records
This commit is contained in:
Alexander Rose
2025-10-11 16:20:24 -07:00
committed by GitHub
2 changed files with 25 additions and 5 deletions

View File

@@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file, following t
Note that since we don't clearly distinguish between a public and private interfaces there will be changes in non-major versions that are potentially breaking. If we make breaking changes to less used interfaces we will highlight it in here.
## [Unreleased]
- Get bond orders from non-standard CONECT records in PDB files
## [v5.0.0] - 2025-09-28
- [Breaking] Renamed some color schemes ('inferno' -> 'inferno-no-black', 'magma' -> 'magma-no-black', 'turbo' -> 'turbo-no-black', 'rainbow' -> 'simple-rainbow')

View File

@@ -1,8 +1,9 @@
/**
* Copyright (c) 2021-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2021-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Yakov Pechersky <ffxen158@gmail.com>
* @author Paul Pillot <paul.pillot@tandemai.com>
*/
import { CifCategory, CifField } from '../../../mol-io/reader/cif';
@@ -19,6 +20,7 @@ export function parseConect(lines: Tokens, lineStart: number, lineEnd: number, s
const id: string[] = [];
const conn_type_id: string[] = [];
const bondOrder: number[] = [];
const ptnr1_label_asym_id: string[] = [];
const ptnr1_label_seq_id: number[] = [];
@@ -37,15 +39,21 @@ export function parseConect(lines: Tokens, lineStart: number, lineEnd: number, s
const pos = [11, 16, 21, 26];
let k = 1;
let currentIdxA = -1;
let bondIndex: {[k: number]: number} = {};
let hasMultipleBonds = false;
for (let i = lineStart; i < lineEnd; i++) {
const line = getLine(i);
const idxA = idMap[parseInt(line.substr(6, 5))];
const bondIndex: {[k: number]: number} = {};
if (idxA === undefined) continue;
if (currentIdxA !== idxA) {
currentIdxA = idxA;
bondIndex = {};
}
for (let j = 0; j < 4; ++j) {
const idB = parseInt(line.substr(pos[j], 5));
if (Number.isNaN(idB)) continue;
@@ -54,12 +62,18 @@ export function parseConect(lines: Tokens, lineStart: number, lineEnd: number, s
if (idxB === undefined) continue;
if (idxA > idxB) continue;
// TODO: interpret records where a 'idxB' atom is given multiple times
// Records where a 'idxB' atom is given multiple times are interpreted
// as double/triple bonds, e.g. CONECT 1529 1528 1528 is a double bond
if (bondIndex[idxB] !== undefined) continue;
if (bondIndex[idxB] !== undefined) {
bondOrder[bondIndex[idxB]] += 1;
hasMultipleBonds = true;
continue;
}
bondIndex[idxB] = k - 1;
id.push(`covale${k}`);
conn_type_id.push('covale');
bondOrder.push(1);
ptnr1_label_asym_id.push(sites.label_asym_id!.str(idxA));
ptnr1_label_seq_id.push(sites.label_seq_id!.int(idxA));
@@ -98,5 +112,10 @@ export function parseConect(lines: Tokens, lineStart: number, lineEnd: number, s
pdbx_ptnr2_PDB_ins_code: CifField.ofStrings(ptnr2_PDB_ins_code),
};
if (hasMultipleBonds) {
const valueOrder = ['sing', 'doub', 'trpl', 'quad'];
struct_conn.pdbx_value_order = CifField.ofStrings(bondOrder.map(bo => valueOrder[bo - 1] || 'sing'));
}
return CifCategory.ofFields('struct_conn', struct_conn);
}