conect.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. * Copyright (c) 2021-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. * @author Yakov Pechersky <ffxen158@gmail.com>
  6. */
  7. import { CifCategory, CifField } from '../../../mol-io/reader/cif';
  8. import { mmCIF_Schema } from '../../../mol-io/reader/cif/schema/mmcif';
  9. import { Tokens } from '../../../mol-io/reader/common/text/tokenizer';
  10. export function parseConect(lines: Tokens, lineStart: number, lineEnd: number, sites: { [K in keyof mmCIF_Schema['atom_site']]?: CifField }): CifCategory {
  11. const idMap: { [k: string]: number } = {};
  12. for (let i = 0, il = sites.id!.rowCount; i < il; ++i) {
  13. idMap[sites.id!.str(i)] = i;
  14. }
  15. const getLine = (n: number) => lines.data.substring(lines.indices[2 * n], lines.indices[2 * n + 1]);
  16. const id: string[] = [];
  17. const conn_type_id: string[] = [];
  18. const ptnr1_label_asym_id: string[] = [];
  19. const ptnr1_label_seq_id: number[] = [];
  20. const ptnr1_auth_seq_id: number[] = [];
  21. const ptnr1_label_atom_id: string[] = [];
  22. const ptnr1_label_alt_id: string[] = [];
  23. const ptnr1_PDB_ins_code: string[] = [];
  24. const ptnr2_label_asym_id: string[] = [];
  25. const ptnr2_label_seq_id: number[] = [];
  26. const ptnr2_auth_seq_id: number[] = [];
  27. const ptnr2_label_atom_id: string[] = [];
  28. const ptnr2_label_alt_id: string[] = [];
  29. const ptnr2_PDB_ins_code: string[] = [];
  30. const pos = [11, 16, 21, 26];
  31. let k = 1;
  32. for (let i = lineStart; i < lineEnd; i++) {
  33. const line = getLine(i);
  34. const idxA = idMap[parseInt(line.substr(6, 5))];
  35. const bondIndex: {[k: number]: number} = {};
  36. if (idxA === undefined) continue;
  37. for (let j = 0; j < 4; ++j) {
  38. const idB = parseInt(line.substr(pos[j], 5));
  39. if (Number.isNaN(idB)) continue;
  40. const idxB = idMap[idB];
  41. if (idxB === undefined) continue;
  42. if (idxA > idxB) continue;
  43. // TODO: interpret records where a 'idxB' atom is given multiple times
  44. // as double/triple bonds, e.g. CONECT 1529 1528 1528 is a double bond
  45. if (bondIndex[idxB] !== undefined) continue;
  46. id.push(`covale${k}`);
  47. conn_type_id.push('covale');
  48. ptnr1_label_asym_id.push(sites.label_asym_id!.str(idxA));
  49. ptnr1_label_seq_id.push(sites.label_seq_id!.int(idxA));
  50. ptnr1_auth_seq_id.push(sites.auth_seq_id!.int(idxA));
  51. ptnr1_label_atom_id.push(sites.label_atom_id!.str(idxA));
  52. ptnr1_label_alt_id.push(sites.label_alt_id!.str(idxA));
  53. ptnr1_PDB_ins_code.push(sites.pdbx_PDB_ins_code!.str(idxA));
  54. ptnr2_label_asym_id.push(sites.label_asym_id!.str(idxB));
  55. ptnr2_label_seq_id.push(sites.label_seq_id!.int(idxB));
  56. ptnr2_auth_seq_id.push(sites.auth_seq_id!.int(idxB));
  57. ptnr2_label_atom_id.push(sites.label_atom_id!.str(idxB));
  58. ptnr2_label_alt_id.push(sites.label_alt_id!.str(idxB));
  59. ptnr2_PDB_ins_code.push(sites.pdbx_PDB_ins_code!.str(idxB));
  60. k += 1;
  61. }
  62. }
  63. const struct_conn: Partial<CifCategory.Fields<mmCIF_Schema['struct_conn']>> = {
  64. id: CifField.ofStrings(id),
  65. conn_type_id: CifField.ofStrings(conn_type_id),
  66. ptnr1_label_asym_id: CifField.ofStrings(ptnr1_label_asym_id),
  67. ptnr1_label_seq_id: CifField.ofNumbers(ptnr1_label_seq_id),
  68. ptnr1_auth_seq_id: CifField.ofNumbers(ptnr1_auth_seq_id),
  69. ptnr1_label_atom_id: CifField.ofStrings(ptnr1_label_atom_id),
  70. pdbx_ptnr1_label_alt_id: CifField.ofStrings(ptnr1_label_alt_id),
  71. pdbx_ptnr1_PDB_ins_code: CifField.ofStrings(ptnr1_PDB_ins_code),
  72. ptnr2_label_asym_id: CifField.ofStrings(ptnr2_label_asym_id),
  73. ptnr2_label_seq_id: CifField.ofNumbers(ptnr2_label_seq_id),
  74. ptnr2_auth_seq_id: CifField.ofNumbers(ptnr2_auth_seq_id),
  75. ptnr2_label_atom_id: CifField.ofStrings(ptnr2_label_atom_id),
  76. pdbx_ptnr2_label_alt_id: CifField.ofStrings(ptnr2_label_alt_id),
  77. pdbx_ptnr2_PDB_ins_code: CifField.ofStrings(ptnr2_PDB_ins_code),
  78. };
  79. return CifCategory.ofFields('struct_conn', struct_conn);
  80. }