label.ts 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. * @author David Sehnal <david.sehnal@gmail.com>
  6. */
  7. import { Unit, StructureElement, StructureProperties as Props, Link } from 'mol-model/structure';
  8. import { Loci } from 'mol-model/loci';
  9. import { OrderedSet } from 'mol-data/int';
  10. // for `labelFirst`, don't create right away to avoid problems with circular dependencies/imports
  11. let elementLocA: StructureElement
  12. let elementLocB: StructureElement
  13. function setElementLocation(loc: StructureElement, unit: Unit, index: StructureElement.UnitIndex) {
  14. loc.unit = unit
  15. loc.element = unit.elements[index]
  16. }
  17. export function labelFirst(loci: Loci): string {
  18. switch (loci.kind) {
  19. case 'structure-loci':
  20. return loci.structure.models.map(m => m.label).join(', ')
  21. case 'element-loci':
  22. const e = loci.elements[0]
  23. if (e) {
  24. const el = e.unit.elements[OrderedSet.getAt(e.indices, 0)];
  25. return elementLabel(StructureElement.create(e.unit, el))
  26. } else {
  27. return 'Unknown'
  28. }
  29. case 'link-loci':
  30. const link = loci.links[0]
  31. return link ? linkLabel(link) : 'Unknown'
  32. case 'group-loci':
  33. const g = loci.groups[0]
  34. if (g) {
  35. return loci.shape.labels.ref.value[OrderedSet.getAt(g.ids, 0)]
  36. } else {
  37. return 'Unknown'
  38. }
  39. case 'every-loci':
  40. return 'Everything'
  41. case 'empty-loci':
  42. return 'Nothing'
  43. case 'data-loci':
  44. return ''
  45. }
  46. }
  47. export function linkLabel(link: Link.Location) {
  48. if (!elementLocA) elementLocA = StructureElement.create()
  49. if (!elementLocB) elementLocB = StructureElement.create()
  50. setElementLocation(elementLocA, link.aUnit, link.aIndex)
  51. setElementLocation(elementLocB, link.bUnit, link.bIndex)
  52. return `${elementLabel(elementLocA)} - ${elementLabel(elementLocB)}`
  53. }
  54. export function elementLabel(location: StructureElement) {
  55. const model = location.unit.model.label
  56. const instance = location.unit.conformation.operator.name
  57. let label = ''
  58. if (Unit.isAtomic(location.unit)) {
  59. const asym_id = Props.chain.auth_asym_id(location)
  60. const seq_id = Props.residue.auth_seq_id(location)
  61. const comp_id = Props.residue.auth_comp_id(location)
  62. const atom_id = Props.atom.auth_atom_id(location)
  63. const alt_id = Props.atom.label_alt_id(location)
  64. label = `[${comp_id}]${seq_id}:${asym_id}.${atom_id}${alt_id ? `%${alt_id}` : ''}`
  65. } else if (Unit.isCoarse(location.unit)) {
  66. const asym_id = Props.coarse.asym_id(location)
  67. const seq_id_begin = Props.coarse.seq_id_begin(location)
  68. const seq_id_end = Props.coarse.seq_id_end(location)
  69. if (seq_id_begin === seq_id_end) {
  70. const entityIndex = Props.coarse.entityKey(location)
  71. const seq = location.unit.model.sequence.byEntityKey[entityIndex]
  72. const comp_id = seq.compId.value(seq_id_begin - 1) // 1-indexed
  73. label = `[${comp_id}]${seq_id_begin}:${asym_id}`
  74. } else {
  75. label = `${seq_id_begin}-${seq_id_end}:${asym_id}`
  76. }
  77. } else {
  78. label = 'unknown'
  79. }
  80. return `${model} ${instance} ${label}`
  81. }