Skip to content
Snippets Groups Projects
Commit 039b0719 authored by David Sehnal's avatar David Sehnal
Browse files

Positions

parent a636b9e0
No related branches found
No related tags found
No related merge requests found
......@@ -568,7 +568,7 @@ export namespace Vec3 {
return out;
}
export function transformMat4(out: Vec3, a: Vec3, m: number[]) {
export function transformMat4(out: Vec3, a: Vec3, m: Mat4) {
const x = a[0], y = a[1], z = a[2],
w = (m[3] * x + m[7] * y + m[11] * z + m[15]) || 1.0;
out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
......
......@@ -13,6 +13,10 @@ const constant = {
}
const atom = {
x: Atom.property(l => l.unit.x(l.atom)),
y: Atom.property(l => l.unit.y(l.atom)),
z: Atom.property(l => l.unit.z(l.atom)),
type_symbol: Atom.property(l => l.unit.hierarchy.atoms.type_symbol.value(l.atom))
}
......
......@@ -28,7 +28,7 @@ namespace Atom {
export interface Property<T> { (location: Location): T }
export interface Predicate extends Property<boolean> { }
export function setLocation(structure: Structure, l: Location, atom: Atom) {
export function updateLocation(structure: Structure, l: Location, atom: Atom) {
l.unit = structure.units[unit(atom)];
l.atom = index(atom);
}
......
......@@ -9,7 +9,7 @@ import { Mat4 } from 'mol-base/math/linear-algebra-3d'
interface Operator extends Readonly<{
name: string,
hkl: number[], // defaults to [0, 0, 0] for non symmetry entries
transform: Mat4,
matrix: Mat4,
// cache the inverse of the transform
inverse: Mat4,
// optimize the identity case
......@@ -17,7 +17,7 @@ interface Operator extends Readonly<{
}> { }
namespace Operator {
export const Identity: Operator = { name: '1_555', hkl: [0, 0, 0], transform: Mat4.identity(), inverse: Mat4.identity(), isIdentity: true };
export const Identity: Operator = { name: '1_555', hkl: [0, 0, 0], matrix: Mat4.identity(), inverse: Mat4.identity(), isIdentity: true };
}
export default Operator
\ No newline at end of file
......@@ -6,6 +6,7 @@
import { Model } from '../model'
import Operator from './operator'
import { Vec3, Mat4 } from 'mol-base/math/linear-algebra-3d'
interface Unit extends Readonly<{
// Structure-level unique identifier of the unit.
......@@ -18,22 +19,30 @@ interface Unit extends Readonly<{
// The transform and and inverse are baked into the "getPosition" function
operator: Operator,
// Cache residue and chain indices for fast access.
// Reference some commonly accessed things for faster access.
residueIndex: ArrayLike<number>,
chainIndex: ArrayLike<number>,
hierarchy: Model['hierarchy'],
conformation: Model['conformation']
}> {
// // returns the untransformed position. Used for spatial queries.
// getInvariantPosition(atom: number, slot: Vec3): Vec3
// returns the untransformed position. Used for spatial queries.
getInvariantPosition(atom: number, slot: Vec3): Vec3,
// // gets the transformed position of the specified atom
// getPosition(atom: number, slot: Vec3): Vec3
// gets the transformed position of the specified atom.
getPosition(atom: number, slot: Vec3): Vec3,
// optimized x/y/z coordinate projections for your query needs.
x(atom: number): number,
y(atom: number): number,
z(atom: number): number
}
namespace Unit {
export function create(model: Model, operator: Operator): Unit {
const h = model.hierarchy;
const { __x: x, __y: y, __z: z } = model.conformation;
const getInvariantPosition = makeGetInvariantPosition(x, y, z);
const getPosition = operator.isIdentity ? getInvariantPosition : makeGetPosition(operator.matrix, x, y, z);
return {
id: nextUnitId(),
model,
......@@ -41,7 +50,12 @@ namespace Unit {
residueIndex: h.residueSegments.segmentMap,
chainIndex: h.chainSegments.segmentMap,
hierarchy: model.hierarchy,
conformation: model.conformation
conformation: model.conformation,
getInvariantPosition,
getPosition,
x: operator.isIdentity ? makeGetCoord(x) : makeX(operator.matrix, x, y, z),
y: operator.isIdentity ? makeGetCoord(y) : makeY(operator.matrix, x, y, z),
z: operator.isIdentity ? makeGetCoord(z) : makeZ(operator.matrix, x, y, z)
};
}
}
......@@ -53,4 +67,73 @@ function nextUnitId() {
const ret = _id;
_id = (_id + 1) % 0x3fffffff;
return ret;
}
function makeGetInvariantPosition(x: ArrayLike<number>, y: ArrayLike<number>, z: ArrayLike<number>) {
return (a: number, r: Vec3): Vec3 => {
r[0] = x[a];
r[1] = y[a];
r[2] = z[a];
return r;
}
}
function makeGetCoord(xs: ArrayLike<number>) {
return (i: number) => xs[i];
}
function isWConst(m: Mat4) {
return m[3] === 0 && m[7] === 0 && m[11] === 0;
}
function makeX(m: Mat4, xs: ArrayLike<number>, ys: ArrayLike<number>, zs: ArrayLike<number>) {
const xx = m[0], yy = m[4], zz = m[8], ww = m[12];
if (isWConst(m)) {
const w = m[15] || 1.0;
return (i: number) => (xx * xs[i] + yy * ys[i] + zz * zs[i] + ww) / w;
}
return (i: number) => {
const x = xs[i], y = ys[i], z = zs[i], w = (m[3] * x + m[7] * y + m[11] * z + m[15]) || 1.0;
return (xx * x + yy * y + zz * z + ww) / w;
}
}
function makeY(m: Mat4, xs: ArrayLike<number>, ys: ArrayLike<number>, zs: ArrayLike<number>) {
const xx = m[1], yy = m[5], zz = m[9], ww = m[13];
if (isWConst(m)) {
const w = m[15] || 1.0;
return (i: number) => (xx * xs[i] + yy * ys[i] + zz * zs[i] + ww) / w;
}
return (i: number) => {
const x = xs[i], y = ys[i], z = zs[i], w = (m[3] * x + m[7] * y + m[11] * z + m[15]) || 1.0;
return (xx * x + yy * y + zz * z + ww) / w;
}
}
function makeZ(m: Mat4, xs: ArrayLike<number>, ys: ArrayLike<number>, zs: ArrayLike<number>) {
const xx = m[2], yy = m[6], zz = m[10], ww = m[14];
if (isWConst(m)) {
const w = m[15] || 1.0;
return (i: number) => (xx * xs[i] + yy * ys[i] + zz * zs[i] + ww) / w;
}
return (i: number) => {
const x = xs[i], y = ys[i], z = zs[i], w = (m[3] * x + m[7] * y + m[11] * z + m[15]) || 1.0;
return (xx * x + yy * y + zz * z + ww) / w;
}
}
function makeGetPosition(m: Mat4, x: ArrayLike<number>, y: ArrayLike<number>, z: ArrayLike<number>) {
return (a: number, r: Vec3): Vec3 => {
r[0] = x[a];
r[1] = y[a];
r[2] = z[a];
Vec3.transformMat4(r, r, m);
return r;
}
}
\ No newline at end of file
......@@ -251,6 +251,13 @@ export namespace PropertyAccess {
console.log(sumDirect(structures[0]));
console.log('r', sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])));
console.time('atom.x');
console.log('atom.x', sumProperty(structures[0], Q.props.atom.x));
console.timeEnd('atom.x');
console.time('__x')
console.log('__x', sumProperty(structures[0], l => l.unit.conformation.__x[l.atom]));
console.timeEnd('__x')
//const authSeqId = Atom.property(l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom]));
//const auth_seq_id = Q.props.residue.auth_seq_id;
......@@ -277,7 +284,7 @@ export namespace PropertyAccess {
console.time('q2')
const q2r = q2(structures[0]);
console.timeEnd('q2')
console.log(Selection.structureCount(q2r))
console.log(Selection.structureCount(q2r));
//console.log(q1(structures[0]));
//const col = models[0].conformation.atomId.value;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment