|
@@ -34,6 +34,7 @@ class Structure {
|
|
|
readonly units: ReadonlyArray<Unit>;
|
|
|
|
|
|
private _props: {
|
|
|
+ parent?: Structure,
|
|
|
lookup3d?: StructureLookup3D,
|
|
|
links?: InterUnitBonds,
|
|
|
crossLinkRestraints?: PairRestraints<CrossLinkRestraint>,
|
|
@@ -49,7 +50,14 @@ class Structure {
|
|
|
transformHash: number,
|
|
|
elementCount: number,
|
|
|
polymerResidueCount: number,
|
|
|
- } = { hashCode: -1, transformHash: -1, elementCount: 0, polymerResidueCount: 0 };
|
|
|
+ coordinateSystem: SymmetryOperator
|
|
|
+ } = {
|
|
|
+ hashCode: -1,
|
|
|
+ transformHash: -1,
|
|
|
+ elementCount: 0,
|
|
|
+ polymerResidueCount: 0,
|
|
|
+ coordinateSystem: SymmetryOperator.Default
|
|
|
+ };
|
|
|
|
|
|
subsetBuilder(isSorted: boolean) {
|
|
|
return new StructureSubsetBuilder(this, isSorted);
|
|
@@ -106,6 +114,14 @@ class Structure {
|
|
|
return new Structure.ElementLocationIterator(this);
|
|
|
}
|
|
|
|
|
|
+ get parent() {
|
|
|
+ return this._props.parent;
|
|
|
+ }
|
|
|
+
|
|
|
+ get coordinateSystem() {
|
|
|
+ return this._props.coordinateSystem;
|
|
|
+ }
|
|
|
+
|
|
|
get boundary() {
|
|
|
return this.lookup3d.boundary;
|
|
|
}
|
|
@@ -174,7 +190,7 @@ class Structure {
|
|
|
return SortedArray.has(this.unitMap.get(e.unit.id).elements, e.element);
|
|
|
}
|
|
|
|
|
|
- constructor(units: ArrayLike<Unit>) {
|
|
|
+ private initUnits(units: ArrayLike<Unit>) {
|
|
|
const map = IntMap.Mutable<Unit>();
|
|
|
let elementCount = 0;
|
|
|
let polymerResidueCount = 0;
|
|
@@ -188,11 +204,18 @@ class Structure {
|
|
|
if (u.id < lastId) isSorted = false;
|
|
|
lastId = u.id;
|
|
|
}
|
|
|
- if (!isSorted) sort(units, 0, units.length, cmpUnits, arraySwap)
|
|
|
- this.unitMap = map;
|
|
|
- this.units = units as ReadonlyArray<Unit>;
|
|
|
+ if (!isSorted) sort(units, 0, units.length, cmpUnits, arraySwap);
|
|
|
this._props.elementCount = elementCount;
|
|
|
this._props.polymerResidueCount = polymerResidueCount;
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ constructor(units: ArrayLike<Unit>, parent: Structure | undefined, coordinateSystem?: SymmetryOperator) {
|
|
|
+ this.unitMap = this.initUnits(units);
|
|
|
+ this.units = units as ReadonlyArray<Unit>;
|
|
|
+ if (parent) this._props.parent = parent;
|
|
|
+ if (coordinateSystem) this._props.coordinateSystem = coordinateSystem;
|
|
|
+ else if (parent) this._props.coordinateSystem = parent.coordinateSystem;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -283,7 +306,7 @@ function getUniqueAtomicResidueIndices(structure: Structure): ReadonlyMap<UUID,
|
|
|
}
|
|
|
|
|
|
namespace Structure {
|
|
|
- export const Empty = new Structure([]);
|
|
|
+ export const Empty = new Structure([], void 0, void 0);
|
|
|
|
|
|
/** Represents a single structure */
|
|
|
export interface Loci {
|
|
@@ -302,7 +325,9 @@ namespace Structure {
|
|
|
return a.structure === b.structure
|
|
|
}
|
|
|
|
|
|
- export function create(units: ReadonlyArray<Unit>): Structure { return new Structure(units); }
|
|
|
+ export function create(units: ReadonlyArray<Unit>, parent: Structure | undefined, coordinateSystem?: SymmetryOperator): Structure {
|
|
|
+ return new Structure(units, parent, coordinateSystem);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Construct a Structure from a model.
|
|
@@ -312,7 +337,7 @@ namespace Structure {
|
|
|
*/
|
|
|
export function ofModel(model: Model): Structure {
|
|
|
const chains = model.atomicHierarchy.chainAtomSegments;
|
|
|
- const builder = new StructureBuilder();
|
|
|
+ const builder = new StructureBuilder(void 0, void 0);
|
|
|
|
|
|
for (let c = 0; c < chains.count; c++) {
|
|
|
const start = chains.offsets[c];
|
|
@@ -385,7 +410,9 @@ namespace Structure {
|
|
|
units.push(u.applyOperator(u.id, op));
|
|
|
}
|
|
|
|
|
|
- return new Structure(units);
|
|
|
+ const cs = s.coordinateSystem;
|
|
|
+ const newCS = SymmetryOperator.compose(SymmetryOperator.create(cs.name, transform, cs.assembly, cs.ncsId, cs.hkl), cs);
|
|
|
+ return new Structure(units, s, newCS);
|
|
|
}
|
|
|
|
|
|
export class StructureBuilder {
|
|
@@ -405,15 +432,21 @@ namespace Structure {
|
|
|
}
|
|
|
|
|
|
getStructure(): Structure {
|
|
|
- return create(this.units);
|
|
|
+ return create(this.units, this.parent, this.coordinateSystem);
|
|
|
}
|
|
|
|
|
|
get isEmpty() {
|
|
|
return this.units.length === 0;
|
|
|
}
|
|
|
+
|
|
|
+ constructor(private parent: Structure | undefined, private coordinateSystem: SymmetryOperator | undefined) {
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- export function Builder() { return new StructureBuilder(); }
|
|
|
+ export function Builder(parent: Structure | undefined, coordinateSystem: SymmetryOperator | undefined) {
|
|
|
+ return new StructureBuilder(parent, coordinateSystem);
|
|
|
+ }
|
|
|
|
|
|
export function hashCode(s: Structure) {
|
|
|
return s.hashCode;
|