|
@@ -10,6 +10,7 @@ import { IntAdjacencyGraph } from '../../../../../mol-math/graph';
|
|
|
import Unit from '../../unit';
|
|
|
import StructureElement from '../../element';
|
|
|
import { Link } from '../links';
|
|
|
+import { InterUnitGraph } from '../../../../../mol-math/graph/inter-unit-graph';
|
|
|
|
|
|
type IntraUnitLinks = IntAdjacencyGraph<{ readonly order: ArrayLike<number>, readonly flags: ArrayLike<LinkType.Flag> }>
|
|
|
|
|
@@ -17,128 +18,23 @@ namespace IntraUnitLinks {
|
|
|
export const Empty: IntraUnitLinks = IntAdjacencyGraph.create([], [], [], 0, { flags: [], order: [] });
|
|
|
}
|
|
|
|
|
|
-class InterUnitBonds {
|
|
|
- /** Number of inter-unit bonds */
|
|
|
- readonly bondCount: number
|
|
|
- /** Array of inter-unit bonds */
|
|
|
- readonly bonds: ReadonlyArray<InterUnitBonds.Bond>
|
|
|
- private readonly bondKeyIndex: Map<string, number>
|
|
|
- private readonly elementKeyIndex: Map<string, number[]>
|
|
|
-
|
|
|
- /** Get an array of unit-pair-bonds that are linked to the given unit */
|
|
|
- getLinkedUnits(unit: Unit): ReadonlyArray<InterUnitBonds.UnitPairBonds> {
|
|
|
- if (!this.map.has(unit.id)) return emptyArray;
|
|
|
- return this.map.get(unit.id)!;
|
|
|
- }
|
|
|
-
|
|
|
- /** Index into this.bonds */
|
|
|
- getBondIndex(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit): number {
|
|
|
- const bondKey = InterUnitBonds.getBondKey(indexA, unitA, indexB, unitB)
|
|
|
- const index = this.bondKeyIndex.get(bondKey)
|
|
|
- return index !== undefined ? index : -1
|
|
|
- }
|
|
|
-
|
|
|
- /** Check if bond exists */
|
|
|
- hasBond(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit): boolean {
|
|
|
- return this.getBondIndex(indexA, unitA, indexB, unitB) !== -1
|
|
|
- }
|
|
|
-
|
|
|
- /** Get inter-unit bond given a pair of indices and units */
|
|
|
- getBond(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit): InterUnitBonds.Bond | undefined {
|
|
|
- const index = this.getBondIndex(indexA, unitA, indexB, unitB)
|
|
|
- return index !== -1 ? this.bonds[index] : undefined
|
|
|
- }
|
|
|
+type InterUnitEdgeProps = { readonly order: number, readonly flag: LinkType.Flag }
|
|
|
|
|
|
+class InterUnitBonds extends InterUnitGraph<Unit.Atomic, StructureElement.UnitIndex, InterUnitEdgeProps> {
|
|
|
/** Get inter-unit bond given a link-location */
|
|
|
getBondFromLocation(l: Link.Location) {
|
|
|
- return this.getBond(l.aIndex, l.aUnit, l.bIndex, l.bUnit);
|
|
|
- }
|
|
|
-
|
|
|
- /** Indices into this.bonds */
|
|
|
- getBondIndices(index: StructureElement.UnitIndex, unit: Unit): ReadonlyArray<number> {
|
|
|
- return this.elementKeyIndex.get(InterUnitBonds.getElementKey(index, unit)) || []
|
|
|
+ return Unit.isAtomic(l.aUnit) && Unit.isAtomic(l.bUnit) ? this.getEdge(l.aIndex, l.aUnit, l.bIndex, l.bUnit) : undefined;
|
|
|
}
|
|
|
|
|
|
- constructor(private map: Map<number, InterUnitBonds.UnitPairBonds[]>) {
|
|
|
- let count = 0
|
|
|
- const bonds: (InterUnitBonds.Bond)[] = []
|
|
|
- const bondKeyIndex = new Map<string, number>()
|
|
|
- const elementKeyIndex = new Map<string, number[]>()
|
|
|
-
|
|
|
- this.map.forEach(pairBondsArray => {
|
|
|
- pairBondsArray.forEach(pairBonds => {
|
|
|
- count += pairBonds.bondCount
|
|
|
- pairBonds.linkedElementIndices.forEach(indexA => {
|
|
|
- pairBonds.getBonds(indexA).forEach(bondInfo => {
|
|
|
- const { unitA, unitB } = pairBonds
|
|
|
-
|
|
|
- const bondKey = InterUnitBonds.getBondKey(indexA, unitA, bondInfo.indexB, unitB)
|
|
|
- bondKeyIndex.set(bondKey, bonds.length)
|
|
|
-
|
|
|
- const elementKey = InterUnitBonds.getElementKey(indexA, unitA)
|
|
|
- const e = elementKeyIndex.get(elementKey)
|
|
|
- if (e === undefined) elementKeyIndex.set(elementKey, [bonds.length])
|
|
|
- else e.push(bonds.length)
|
|
|
-
|
|
|
- bonds.push({ ...bondInfo, indexA, unitA, unitB })
|
|
|
- })
|
|
|
- })
|
|
|
- })
|
|
|
- })
|
|
|
-
|
|
|
- this.bondCount = count
|
|
|
- this.bonds = bonds
|
|
|
- this.bondKeyIndex = bondKeyIndex
|
|
|
- this.elementKeyIndex = elementKeyIndex
|
|
|
+ /** Get inter-unit bond index given a link-location */
|
|
|
+ getBondIndexFromLocation(l: Link.Location) {
|
|
|
+ return Unit.isAtomic(l.aUnit) && Unit.isAtomic(l.bUnit) ? this.getEdgeIndex(l.aIndex, l.aUnit, l.bIndex, l.bUnit) : -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
namespace InterUnitBonds {
|
|
|
- export class UnitPairBonds {
|
|
|
- hasBonds(indexA: StructureElement.UnitIndex) {
|
|
|
- return this.linkMap.has(indexA);
|
|
|
- }
|
|
|
-
|
|
|
- getBonds(indexA: StructureElement.UnitIndex): ReadonlyArray<InterUnitBonds.BondInfo> {
|
|
|
- if (!this.linkMap.has(indexA)) return emptyArray;
|
|
|
- return this.linkMap.get(indexA)!;
|
|
|
- }
|
|
|
-
|
|
|
- get areUnitsOrdered() {
|
|
|
- return this.unitA.id < this.unitB.id;
|
|
|
- }
|
|
|
-
|
|
|
- constructor(public unitA: Unit.Atomic, public unitB: Unit.Atomic,
|
|
|
- public bondCount: number, public linkedElementIndices: ReadonlyArray<StructureElement.UnitIndex>,
|
|
|
- private linkMap: Map<number, BondInfo[]>) {
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- export interface BondInfo {
|
|
|
- /** indexInto */
|
|
|
- readonly indexB: StructureElement.UnitIndex,
|
|
|
- readonly order: number,
|
|
|
- readonly flag: LinkType.Flag
|
|
|
- }
|
|
|
-
|
|
|
- export interface Bond {
|
|
|
- readonly unitA: Unit.Atomic,
|
|
|
- readonly unitB: Unit.Atomic,
|
|
|
- readonly indexA: StructureElement.UnitIndex,
|
|
|
- readonly indexB: StructureElement.UnitIndex,
|
|
|
- readonly order: number,
|
|
|
- readonly flag: LinkType.Flag
|
|
|
- }
|
|
|
-
|
|
|
- export function getBondKey(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit) {
|
|
|
- return `${indexA}|${unitA.id}|${indexB}|${unitB.id}`
|
|
|
- }
|
|
|
-
|
|
|
- export function getElementKey(index: StructureElement.UnitIndex, unit: Unit) {
|
|
|
- return `${index}|${unit.id}`
|
|
|
- }
|
|
|
+ export class UnitPairBonds extends InterUnitGraph.UnitPairEdges<Unit.Atomic, StructureElement.UnitIndex, InterUnitEdgeProps> {}
|
|
|
+ export type BondInfo = InterUnitGraph.EdgeInfo<StructureElement.UnitIndex, InterUnitEdgeProps>
|
|
|
}
|
|
|
|
|
|
-const emptyArray: any[] = [];
|
|
|
-
|
|
|
export { IntraUnitLinks, InterUnitBonds }
|