|
@@ -0,0 +1,89 @@
|
|
|
+/**
|
|
|
+ * Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
+ *
|
|
|
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
|
+ */
|
|
|
+
|
|
|
+import { CifCategory, CifField } from '../../../mol-io/reader/cif';
|
|
|
+import { mmCIF_Schema } from '../../../mol-io/reader/cif/schema/mmcif';
|
|
|
+import { Tokens } from '../../../mol-io/reader/common/text/tokenizer';
|
|
|
+
|
|
|
+export function parseConect(lines: Tokens, lineStart: number, lineEnd: number, sites: { [K in keyof mmCIF_Schema['atom_site']]?: CifField }): CifCategory {
|
|
|
+ const idMap: { [k: string]: number } = {};
|
|
|
+ for (let i = 0, il = sites.id!.rowCount; i < il; ++i) {
|
|
|
+ idMap[sites.id!.str(i)] = i;
|
|
|
+ }
|
|
|
+
|
|
|
+ const getLine = (n: number) => lines.data.substring(lines.indices[2 * n], lines.indices[2 * n + 1]);
|
|
|
+
|
|
|
+ const id: string[] = [];
|
|
|
+ const conn_type_id: string[] = [];
|
|
|
+
|
|
|
+ const ptnr1_label_asym_id: string[] = [];
|
|
|
+ const ptnr1_label_seq_id: number[] = [];
|
|
|
+ const ptnr1_auth_seq_id: number[] = [];
|
|
|
+ const ptnr1_label_atom_id: string[] = [];
|
|
|
+
|
|
|
+ const ptnr2_label_asym_id: string[] = [];
|
|
|
+ const ptnr2_label_seq_id: number[] = [];
|
|
|
+ const ptnr2_auth_seq_id: number[] = [];
|
|
|
+ const ptnr2_label_atom_id: string[] = [];
|
|
|
+
|
|
|
+ const pos = [11, 16, 21, 26];
|
|
|
+
|
|
|
+ let k = 1;
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ for (let j = 0; j < 4; ++j) {
|
|
|
+ const idB = parseInt(line.substr(pos[j], 5));
|
|
|
+ if (Number.isNaN(idB)) continue;
|
|
|
+
|
|
|
+ const idxB = idMap[idB];
|
|
|
+ if (idxB === undefined) continue;
|
|
|
+ if (idxA > idxB) continue;
|
|
|
+
|
|
|
+ // TODO: interpret records where a 'idxB' atom is given multiple times
|
|
|
+ // as double/triple bonds, e.g. CONECT 1529 1528 1528 is a double bond
|
|
|
+ if (bondIndex[idxB] !== undefined) continue;
|
|
|
+
|
|
|
+ id.push(`covale${k}`);
|
|
|
+ conn_type_id.push('covale');
|
|
|
+
|
|
|
+ ptnr1_label_asym_id.push(sites.label_asym_id!.str(idxA));
|
|
|
+ ptnr1_auth_seq_id.push(sites.auth_seq_id!.int(idxA));
|
|
|
+ ptnr1_label_seq_id.push(sites.label_seq_id!.int(idxA));
|
|
|
+ ptnr1_label_atom_id.push(sites.label_atom_id!.str(idxA));
|
|
|
+
|
|
|
+ ptnr2_label_asym_id.push(sites.label_asym_id!.str(idxB));
|
|
|
+ ptnr2_auth_seq_id.push(sites.auth_seq_id!.int(idxB));
|
|
|
+ ptnr2_label_seq_id.push(sites.label_seq_id!.int(idxB));
|
|
|
+ ptnr2_label_atom_id.push(sites.label_atom_id!.str(idxB));
|
|
|
+
|
|
|
+ k += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const struct_conn: Partial<CifCategory.Fields<mmCIF_Schema['struct_conn']>> = {
|
|
|
+ id: CifField.ofStrings(id),
|
|
|
+ conn_type_id: CifField.ofStrings(conn_type_id),
|
|
|
+
|
|
|
+ ptnr1_label_asym_id: CifField.ofStrings(ptnr1_label_asym_id),
|
|
|
+ ptnr1_auth_seq_id: CifField.ofNumbers(ptnr1_auth_seq_id),
|
|
|
+ ptnr1_label_seq_id: CifField.ofNumbers(ptnr1_label_seq_id),
|
|
|
+ ptnr1_label_atom_id: CifField.ofStrings(ptnr1_label_atom_id),
|
|
|
+
|
|
|
+ ptnr2_label_asym_id: CifField.ofStrings(ptnr2_label_asym_id),
|
|
|
+ ptnr2_label_seq_id: CifField.ofNumbers(ptnr2_label_seq_id),
|
|
|
+ ptnr2_auth_seq_id: CifField.ofNumbers(ptnr2_auth_seq_id),
|
|
|
+ ptnr2_label_atom_id: CifField.ofStrings(ptnr2_label_atom_id),
|
|
|
+ };
|
|
|
+
|
|
|
+ return CifCategory.ofFields('struct_conn', struct_conn);
|
|
|
+}
|