contacts-builder.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /**
  2. * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Features } from './features';
  7. import { IntAdjacencyGraph } from '../../../mol-math/graph';
  8. import { InteractionType, InteractionsIntraContacts, InteractionsInterContacts, InteractionFlag } from './common';
  9. import { Unit } from '../../../mol-model/structure/structure';
  10. import { NumberArray } from '../../../mol-util/type-helpers';
  11. import { IntMap } from '../../../mol-data/int';
  12. import { InterUnitGraph } from '../../../mol-math/graph/inter-unit-graph';
  13. export { IntraContactsBuilder };
  14. interface IntraContactsBuilder {
  15. add: (indexA: Features.FeatureIndex, indexB: Features.FeatureIndex, type: InteractionType) => void
  16. getContacts: () => InteractionsIntraContacts
  17. }
  18. namespace IntraContactsBuilder {
  19. export function create(features: Features, elementsCount: number): IntraContactsBuilder {
  20. const aIndices: Features.FeatureIndex[] = [];
  21. const bIndices: Features.FeatureIndex[] = [];
  22. const types: number[] = [];
  23. return {
  24. add(indexA: Features.FeatureIndex, indexB: Features.FeatureIndex, type: InteractionType) {
  25. aIndices[aIndices.length] = indexA;
  26. bIndices[bIndices.length] = indexB;
  27. types[types.length] = type;
  28. },
  29. getContacts() {
  30. const builder = new IntAdjacencyGraph.EdgeBuilder(features.count, aIndices, bIndices);
  31. const type = new Int8Array(builder.slotCount) as ArrayLike<InteractionType>;
  32. const flag = new Int8Array(builder.slotCount) as NumberArray;
  33. for (let i = 0, _i = builder.edgeCount; i < _i; i++) {
  34. builder.addNextEdge();
  35. builder.assignProperty(type, types[i]);
  36. }
  37. const graph = builder.createGraph({ type, flag });
  38. let elementsIndex: InteractionsIntraContacts.ElementsIndex;
  39. const contacts: InteractionsIntraContacts = Object.defineProperty(graph, 'elementsIndex', {
  40. get: () => {
  41. return elementsIndex || (elementsIndex = InteractionsIntraContacts.createElementsIndex(graph, features, elementsCount));
  42. }
  43. }) as any;
  44. return contacts;
  45. }
  46. };
  47. }
  48. }
  49. export { InterContactsBuilder };
  50. interface InterContactsBuilder {
  51. startUnitPair: (unitA: Unit, unitB: Unit) => void
  52. finishUnitPair: () => void
  53. add: (indexA: Features.FeatureIndex, indexB: Features.FeatureIndex, type: InteractionType) => void
  54. getContacts: (unitsFeatures: IntMap<Features>) => InteractionsInterContacts
  55. }
  56. namespace InterContactsBuilder {
  57. export function create(): InterContactsBuilder {
  58. const builder = new InterUnitGraph.Builder<number, Features.FeatureIndex, InteractionsInterContacts.Props>();
  59. return {
  60. startUnitPair(unitA: Unit, unitB: Unit) {
  61. builder.startUnitPair(unitA.id, unitB.id);
  62. },
  63. finishUnitPair() {
  64. builder.finishUnitPair();
  65. },
  66. add(indexA: Features.FeatureIndex, indexB: Features.FeatureIndex, type: InteractionType) {
  67. builder.add(indexA, indexB, { type, flag: InteractionFlag.None });
  68. },
  69. getContacts(unitsFeatures: IntMap<Features>) {
  70. return new InteractionsInterContacts(builder.getMap(), unitsFeatures);
  71. }
  72. };
  73. }
  74. }