comp.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /**
  2. * Copyright (c) 2017-2020 Mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { Model } from '../../../../mol-model/structure/model/model'
  8. import { BondType } from '../../../../mol-model/structure/model/types'
  9. import { CustomPropertyDescriptor } from '../../../../mol-model/structure';
  10. import { mmCIF_Schema } from '../../../../mol-io/reader/cif/schema/mmcif';
  11. import { CifWriter } from '../../../../mol-io/writer/cif'
  12. import { Table } from '../../../../mol-data/db';
  13. import { FormatPropertyProvider } from '../../common/property';
  14. export interface ComponentBond {
  15. readonly data: Table<mmCIF_Schema['chem_comp_bond']>
  16. readonly entries: ReadonlyMap<string, ComponentBond.Entry>
  17. }
  18. export namespace ComponentBond {
  19. export const Descriptor: CustomPropertyDescriptor = {
  20. name: 'chem_comp_bond',
  21. cifExport: {
  22. prefix: '',
  23. categories: [{
  24. name: 'chem_comp_bond',
  25. instance(ctx) {
  26. const p = Provider.get(ctx.firstModel);
  27. if (!p) return CifWriter.Category.Empty;
  28. const chem_comp_bond = p.data;
  29. if (!chem_comp_bond) return CifWriter.Category.Empty;
  30. const comp_names = ctx.structures[0].uniqueResidueNames;
  31. const { comp_id, _rowCount } = chem_comp_bond;
  32. const indices: number[] = [];
  33. for (let i = 0; i < _rowCount; i++) {
  34. if (comp_names.has(comp_id.value(i))) indices[indices.length] = i;
  35. }
  36. return CifWriter.Category.ofTable(chem_comp_bond, indices)
  37. }
  38. }]
  39. }
  40. }
  41. export const Provider = FormatPropertyProvider.create<ComponentBond>(Descriptor)
  42. export function chemCompBondFromTable(model: Model, table: Table<mmCIF_Schema['chem_comp_bond']>): Table<mmCIF_Schema['chem_comp_bond']> {
  43. return Table.pick(table, mmCIF_Schema.chem_comp_bond, (i: number) => {
  44. return model.properties.chemicalComponentMap.has(table.comp_id.value(i))
  45. })
  46. }
  47. export function getEntriesFromChemCompBond(data: Table<mmCIF_Schema['chem_comp_bond']>) {
  48. const entries: Map<string, Entry> = new Map();
  49. function addEntry(id: string) {
  50. let e = new Entry(id);
  51. entries.set(id, e);
  52. return e;
  53. }
  54. const { comp_id, atom_id_1, atom_id_2, value_order, pdbx_aromatic_flag, _rowCount } = data;
  55. let entry = addEntry(comp_id.value(0)!);
  56. for (let i = 0; i < _rowCount; i++) {
  57. const id = comp_id.value(i)!;
  58. const nameA = atom_id_1.value(i)!;
  59. const nameB = atom_id_2.value(i)!;
  60. const order = value_order.value(i)!;
  61. const aromatic = pdbx_aromatic_flag.value(i) === 'Y';
  62. if (entry.id !== id) {
  63. entry = addEntry(id);
  64. }
  65. let flags: number = BondType.Flag.Covalent;
  66. let ord = 1;
  67. if (aromatic) flags |= BondType.Flag.Aromatic;
  68. switch (order.toLowerCase()) {
  69. case 'doub':
  70. case 'delo':
  71. ord = 2;
  72. break;
  73. case 'trip': ord = 3; break;
  74. case 'quad': ord = 4; break;
  75. }
  76. entry.add(nameA, nameB, ord, flags);
  77. }
  78. return entries
  79. }
  80. export class Entry {
  81. readonly map: Map<string, Map<string, { order: number, flags: number }>> = new Map();
  82. add(a: string, b: string, order: number, flags: number, swap = true) {
  83. let e = this.map.get(a);
  84. if (e !== void 0) {
  85. let f = e.get(b);
  86. if (f === void 0) {
  87. e.set(b, { order, flags });
  88. }
  89. } else {
  90. let map = new Map<string, { order: number, flags: number }>();
  91. map.set(b, { order, flags });
  92. this.map.set(a, map);
  93. }
  94. if (swap) this.add(b, a, order, flags, false);
  95. }
  96. constructor(public readonly id: string) { }
  97. }
  98. }