atomic-keys.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /**
  2. * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import { AtomicData, AtomicSegments, AtomicKeys } from '../atomic'
  7. import { Interval, Segmentation } from 'mol-data/int'
  8. import { Entities } from '../common'
  9. import { ChainIndex, ResidueIndex, EntityIndex } from '../../indexing';
  10. function getResidueId(comp_id: string, seq_id: number, ins_code: string) {
  11. // TODO: add new index that support comp_id again?
  12. return `${seq_id} ${ins_code}`;
  13. //return `${comp_id} ${seq_id} ${ins_code}`;
  14. }
  15. function getElementKey(map: Map<string, number>, key: string, counter: { index: number }) {
  16. if (map.has(key)) return map.get(key)!;
  17. const ret = counter.index++;
  18. map.set(key, ret);
  19. return ret;
  20. }
  21. function getElementSubstructureKeyMap(map: Map<number, Map<string, number>>, key: number) {
  22. if (map.has(key)) return map.get(key)!;
  23. const ret = new Map<string, number>();
  24. map.set(key, ret);
  25. return ret;
  26. }
  27. function createLookUp(entities: Entities, chain: Map<number, Map<string, number>>, residue: Map<number, Map<string, number>>) {
  28. const getEntKey = entities.getEntityIndex;
  29. const findChainKey: AtomicKeys['findChainKey'] = (e, c) => {
  30. let eKey = getEntKey(e);
  31. if (eKey < 0) return -1 as ChainIndex;
  32. const cm = chain.get(eKey)!;
  33. if (!cm.has(c)) return -1 as ChainIndex;
  34. return cm.get(c)! as ChainIndex;
  35. }
  36. const findResidueKey: AtomicKeys['findResidueKey'] = (e, c, name, seq, ins) => {
  37. let eKey = getEntKey(e);
  38. if (eKey < 0) return -1 as ResidueIndex;
  39. const cm = chain.get(eKey)!;
  40. if (!cm.has(c)) return -1 as ResidueIndex;
  41. const rm = residue.get(cm.get(c)!)!
  42. const id = getResidueId(name, seq, ins);
  43. if (!rm.has(id)) return -1 as ResidueIndex;
  44. return rm.get(id)! as ResidueIndex;
  45. }
  46. return { findChainKey, findResidueKey };
  47. }
  48. function missingEntity(k: string) {
  49. throw new Error(`Missing entity entry for entity id '${k}'.`);
  50. }
  51. export function getAtomicKeys(data: AtomicData, entities: Entities, segments: AtomicSegments): AtomicKeys {
  52. const { chains, residues } = data;
  53. const chainMaps = new Map<number, Map<string, number>>(), chainCounter = { index: 0 };
  54. const residueMaps = new Map<number, Map<string, number>>(), residueCounter = { index: 0 };
  55. const residueKey = new Int32Array(residues._rowCount);
  56. const chainKey = new Int32Array(chains._rowCount);
  57. const entityKey = new Int32Array(chains._rowCount);
  58. const { label_comp_id, auth_seq_id, pdbx_PDB_ins_code } = data.residues;
  59. const { label_entity_id, label_asym_id } = data.chains;
  60. const atomSet = Interval.ofBounds(0, data.atoms._rowCount);
  61. const chainsIt = Segmentation.transientSegments(segments.chainAtomSegments, atomSet);
  62. while (chainsIt.hasNext) {
  63. const chainSegment = chainsIt.move();
  64. const cI = chainSegment.index;
  65. let eKey = entities.getEntityIndex(label_entity_id.value(cI));
  66. if (eKey < 0) missingEntity(label_entity_id.value(cI));
  67. const chainMap = getElementSubstructureKeyMap(chainMaps, eKey);
  68. const cKey = getElementKey(chainMap, label_asym_id.value(cI), chainCounter);
  69. chainKey[cI] = cKey;
  70. entityKey[cI] = eKey;
  71. const residueMap = getElementSubstructureKeyMap(residueMaps, cKey);
  72. const residuesIt = Segmentation.transientSegments(segments.residueAtomSegments, atomSet, chainSegment);
  73. while (residuesIt.hasNext) {
  74. const residueSegment = residuesIt.move();
  75. const rI = residueSegment.index;
  76. const residueId = getResidueId(label_comp_id.value(rI), auth_seq_id.value(rI), pdbx_PDB_ins_code.value(rI));
  77. residueKey[rI] = getElementKey(residueMap, residueId, residueCounter);
  78. }
  79. }
  80. const { findChainKey, findResidueKey } = createLookUp(entities, chainMaps, residueMaps);
  81. return { getEntityKey: cI => entityKey[cI] as EntityIndex, findChainKey, findResidueKey };
  82. }