nucleotide.ts 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. */
  6. import { Unit, StructureElement } from 'mol-model/structure';
  7. import { getNucleotideElements } from 'mol-model/structure/structure/util/nucleotide';
  8. import { Loci, EmptyLoci } from 'mol-model/loci';
  9. import { OrderedSet, Interval } from 'mol-data/int';
  10. import { LocationIterator } from 'mol-geo/util/location-iterator';
  11. import { PickingId } from 'mol-geo/geometry/picking';
  12. import { StructureGroup } from 'mol-repr/structure/units-visual';
  13. export namespace NucleotideLocationIterator {
  14. export function fromGroup(group: Unit.SymmetryGroup): LocationIterator {
  15. const u = group.units[0]
  16. const nucleotideElementIndices = Unit.isAtomic(u) ? getNucleotideElements(u) : []
  17. const groupCount = nucleotideElementIndices.length
  18. const instanceCount = group.units.length
  19. const location = StructureElement.create()
  20. const getLocation = (groupIndex: number, instanceIndex: number) => {
  21. const unit = group.units[instanceIndex]
  22. location.unit = unit
  23. location.element = nucleotideElementIndices[groupIndex]
  24. return location
  25. }
  26. return LocationIterator(groupCount, instanceCount, getLocation)
  27. }
  28. }
  29. export function getNucleotideElementLoci(pickingId: PickingId, structureGroup: StructureGroup, id: number) {
  30. const { objectId, instanceId, groupId } = pickingId
  31. if (id === objectId) {
  32. const { structure, group } = structureGroup
  33. const unit = group.units[instanceId]
  34. if (Unit.isAtomic(unit)) {
  35. const unitIndex = OrderedSet.indexOf(unit.elements, unit.nucleotideElements[groupId]) as StructureElement.UnitIndex
  36. if (unitIndex !== -1) {
  37. const indices = OrderedSet.ofSingleton(unitIndex)
  38. return StructureElement.Loci(structure, [{ unit, indices }])
  39. }
  40. }
  41. }
  42. return EmptyLoci
  43. }
  44. export function markNucleotideElement(loci: Loci, structureGroup: StructureGroup, apply: (interval: Interval) => boolean) {
  45. let changed = false
  46. if (!StructureElement.isLoci(loci)) return false
  47. const { structure, group } = structureGroup
  48. if (loci.structure !== structure) return false
  49. const unit = group.units[0]
  50. if (!Unit.isAtomic(unit)) return false
  51. const groupCount = unit.nucleotideElements.length
  52. for (const e of loci.elements) {
  53. const unitIdx = group.unitIndexMap.get(e.unit.id)
  54. if (unitIdx !== undefined && Unit.isAtomic(e.unit)) {
  55. if (Interval.is(e.indices)) {
  56. const min = OrderedSet.indexOf(e.unit.nucleotideElements, e.unit.elements[Interval.min(e.indices)])
  57. const max = OrderedSet.indexOf(e.unit.nucleotideElements, e.unit.elements[Interval.max(e.indices)])
  58. if (min !== -1 && max !== -1) {
  59. if (apply(Interval.ofRange(unitIdx * groupCount + min, unitIdx * groupCount + max))) changed = true
  60. }
  61. } else {
  62. for (let i = 0, _i = e.indices.length; i < _i; i++) {
  63. const idx = OrderedSet.indexOf(e.unit.nucleotideElements, e.unit.elements[e.indices[i]])
  64. if (idx !== -1) {
  65. if (apply(Interval.ofSingleton(unitIdx * groupCount + idx))) changed = true
  66. }
  67. }
  68. }
  69. }
  70. }
  71. return changed
  72. }