entity.ts 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 { MoleculeType, isPolymer } from '../../../mol-model/structure/model/types';
  7. import { Column, Table } from '../../../mol-data/db';
  8. import { BasicSchema } from '../basic/schema';
  9. export type EntityCompound = { chains: string[], description: string }
  10. // TODO add support for `branched`
  11. type EntityType = 'water' | 'polymer' | 'non-polymer'
  12. export class EntityBuilder {
  13. private count = 0;
  14. private ids: string[] = [];
  15. private types: EntityType[] = [];
  16. private descriptions: string[][] = [];
  17. private compoundsMap = new Map<string, string>();
  18. private namesMap = new Map<string, string>();
  19. private heteroMap = new Map<string, string>();
  20. private chainMap = new Map<string, string>();
  21. private waterId?: string;
  22. private set(type: EntityType, description: string) {
  23. this.count += 1;
  24. this.ids.push(`${this.count}`);
  25. this.types.push(type);
  26. this.descriptions.push([description]);
  27. }
  28. getEntityId(compId: string, moleculeType: MoleculeType, chainId: string, options?: { customName?: string }): string {
  29. if (moleculeType === MoleculeType.Water) {
  30. if (this.waterId === undefined) {
  31. this.set('water', options?.customName || 'Water');
  32. this.waterId = `${this.count}`;
  33. }
  34. return this.waterId;
  35. } else if (isPolymer(moleculeType)) {
  36. if (this.compoundsMap.has(chainId)) {
  37. return this.compoundsMap.get(chainId)!;
  38. } else {
  39. if (!this.chainMap.has(chainId)) {
  40. this.set('polymer', options?.customName || `Polymer ${this.chainMap.size + 1}`);
  41. this.chainMap.set(chainId, `${this.count}`);
  42. }
  43. return this.chainMap.get(chainId)!;
  44. }
  45. } else {
  46. if (!this.heteroMap.has(compId)) {
  47. this.set('non-polymer', options?.customName || this.namesMap.get(compId) || compId);
  48. this.heteroMap.set(compId, `${this.count}`);
  49. }
  50. return this.heteroMap.get(compId)!;
  51. }
  52. }
  53. getEntityTable() {
  54. return Table.ofPartialColumns(BasicSchema.entity, {
  55. id: Column.ofStringArray(this.ids),
  56. type: Column.ofStringAliasArray(this.types),
  57. pdbx_description: Column.ofStringListArray(this.descriptions),
  58. }, this.count);
  59. }
  60. setCompounds(compounds: EntityCompound[]) {
  61. for (let i = 0, il = compounds.length; i < il; ++i) {
  62. const { chains, description } = compounds[i];
  63. this.set('polymer', description);
  64. for (let j = 0, jl = chains.length; j < jl; ++j) {
  65. this.compoundsMap.set(chains[j], `${this.count}`);
  66. }
  67. }
  68. }
  69. setNames(names: [string, string][]) {
  70. names.forEach(n => this.namesMap.set(n[0], n[1]));
  71. }
  72. }