hierarchy-keys.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /**
  2. * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import Column from '../../../mol-base/collections/column'
  7. import { HierarchyData, HierarchySegmentation, HierarchyKeys } from '../properties/hierarchy'
  8. import Segmentation from '../../../mol-base/collections/integer/segmentation'
  9. import Interval from '../../../mol-base/collections/integer/interval'
  10. function getResidueId(comp_id: string, seq_id: number, ins_code: string) {
  11. return `${comp_id} ${seq_id} ${ins_code}`;
  12. }
  13. function getElementKey(map: Map<string, number>, key: string, counter: { index: number }) {
  14. if (map.has(key)) return map.get(key)!;
  15. const ret = counter.index++;
  16. map.set(key, ret);
  17. return ret;
  18. }
  19. function getElementSubstructureKeyMap(map: Map<number, Map<string, number>>, key: number) {
  20. if (map.has(key)) return map.get(key)!;
  21. const ret = new Map<string, number>();
  22. map.set(key, ret);
  23. return ret;
  24. }
  25. function createLookUp(entity: Map<string, number>, chain: Map<number, Map<string, number>>, residue: Map<number, Map<string, number>>) {
  26. const findEntityKey: HierarchyKeys['findEntityKey'] = (id) => entity.has(id) ? entity.get(id)! : -1;
  27. const findChainKey: HierarchyKeys['findChainKey'] = (e, c) => {
  28. if (!entity.has(e)) return -1;
  29. const cm = chain.get(entity.get(e)!)!;
  30. if (!cm.has(c)) return -1;
  31. return cm.get(c)!;
  32. }
  33. const findResidueKey: HierarchyKeys['findResidueKey'] = (e, c, name, seq, ins) => {
  34. if (!entity.has(e)) return -1;
  35. const cm = chain.get(entity.get(e)!)!;
  36. if (!cm.has(c)) return -1;
  37. const rm = residue.get(cm.get(c)!)!
  38. const id = getResidueId(name, seq, ins);
  39. if (!rm.has(id)) return -1;
  40. return rm.get(id)!;
  41. }
  42. return { findEntityKey, findChainKey, findResidueKey };
  43. }
  44. function isMonotonous(xs: ArrayLike<number>) {
  45. for (let i = 1, _i = xs.length; i < _i; i++) {
  46. if (xs[i] < xs[i - 1]) {
  47. return false;
  48. }
  49. }
  50. return true;
  51. }
  52. function create(data: HierarchyData, segments: HierarchySegmentation): HierarchyKeys {
  53. const { chains, residues, entities } = data;
  54. const entityMap = Column.createFirstIndexMap(entities.id);
  55. const chainMaps = new Map<number, Map<string, number>>(), chainCounter = { index: 0 };
  56. const residueMaps = new Map<number, Map<string, number>>(), residueCounter = { index: 0 };
  57. const residueKey = new Int32Array(residues._rowCount);
  58. const chainKey = new Int32Array(chains._rowCount);
  59. const entityKey = new Int32Array(chains._rowCount);
  60. const { label_comp_id, auth_seq_id, pdbx_PDB_ins_code } = data.residues;
  61. const { label_entity_id, label_asym_id } = data.chains;
  62. const atomSet = Interval.ofBounds(0, data.atoms._rowCount);
  63. const chainsIt = Segmentation.transientSegments(segments.chainSegments,atomSet);
  64. while (chainsIt.hasNext) {
  65. const chainSegment = chainsIt.move();
  66. const cI = chainSegment.index;
  67. const eKey = entityMap.get(label_entity_id.value(cI)) || 0;
  68. const chainMap = getElementSubstructureKeyMap(chainMaps, eKey);
  69. const cKey = getElementKey(chainMap, label_asym_id.value(cI), chainCounter);
  70. chainKey[cI] = cKey;
  71. entityKey[cI] = eKey;
  72. const residueMap = getElementSubstructureKeyMap(residueMaps, cKey);
  73. const residuesIt = Segmentation.transientSegments(segments.residueSegments, atomSet, chainSegment);
  74. while (residuesIt.hasNext) {
  75. const residueSegment = residuesIt.move();
  76. const rI = residueSegment.index;
  77. const residueId = getResidueId(label_comp_id.value(rI), auth_seq_id.value(rI), pdbx_PDB_ins_code.value(rI));
  78. residueKey[rI] = getElementKey(residueMap, residueId, residueCounter);
  79. }
  80. }
  81. const { findEntityKey, findChainKey, findResidueKey } = createLookUp(entityMap, chainMaps, residueMaps);
  82. return {
  83. isMonotonous: isMonotonous(entityKey) && isMonotonous(chainKey) && isMonotonous(residueKey),
  84. residueKey: residueKey,
  85. chainKey: chainKey,
  86. entityKey: entityKey,
  87. findEntityKey,
  88. findChainKey,
  89. findResidueKey
  90. };
  91. }
  92. export default create;