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

Working on structure data model

parent 01380f7c
No related branches found
No related tags found
No related merge requests found
...@@ -32,6 +32,20 @@ export interface Chains extends DataTable<Chain> { } ...@@ -32,6 +32,20 @@ export interface Chains extends DataTable<Chain> { }
export interface Entity { key: number, id: string } export interface Entity { key: number, id: string }
export interface Entities extends DataTable<Entity> { } export interface Entities extends DataTable<Entity> { }
export interface Bonds extends Readonly<{
/**
* Where bonds for atom A start and end.
* Start at idx, end at idx + 1
*/
offset: ArrayLike<number>,
neighbor: ArrayLike<number>,
order: ArrayLike<number>,
flags: ArrayLike<number>,
count: number
}> { }
export type SourceData = export type SourceData =
| { kind: 'mmCIF', data: any } // TODO | { kind: 'mmCIF', data: any } // TODO
| { kind: 'custom', data: any } // TODO | { kind: 'custom', data: any } // TODO
......
...@@ -5,22 +5,32 @@ ...@@ -5,22 +5,32 @@
*/ */
import * as Data from './data' import * as Data from './data'
import { Selectors } from './selectors'
import { Vec3, Mat4 } from '../utils/linear-algebra' import { Vec3, Mat4 } from '../utils/linear-algebra'
let _uid = 0;
/** Model-related unique identifiers */
export function getUid() { return _uid++; }
/** Unit = essentially a list of residues (usually a chain) */ /** Unit = essentially a list of residues (usually a chain) */
export interface Unit extends Readonly<{ export interface Unit extends Readonly<{
operator: Unit.Operator,
/** The static part (essentially residue annotations) */ /** The static part (essentially residue annotations) */
structre: Unit.Structure, structure: Unit.Structure,
/** 3D arrangement that often changes with time. */ /** 3D arrangement that often changes with time. */
conformation: Unit.Conformation conformation: Unit.Conformation,
/** Position of i-th atom. Special function for this because it's the only one that depends on "operator" */
atomPosition(i: number, p: Vec3): Vec3,
/** Property access */
selectors: Selectors
}> { } }> { }
export namespace Unit { export namespace Unit {
export interface Structure extends Readonly<{ export interface Structure extends Readonly<{
/** A globally unique identifier for this instance (to easily determine unique structures within a model) */
id: number,
/** Source data for this structure */
data: Data.Structure, data: Data.Structure,
/** A globally unique number for this instance (to easily determine unique structures within a model) */
key: number,
/** Reference to the data.entities table */ /** Reference to the data.entities table */
entity: number, entity: number,
/** Reference to the data.chains table */ /** Reference to the data.chains table */
...@@ -29,32 +39,40 @@ export namespace Unit { ...@@ -29,32 +39,40 @@ export namespace Unit {
residues: ArrayLike<number>, residues: ArrayLike<number>,
/** Offsets of atoms in the residue layer. start = offsets[i], endExclusive = offsets[i + 1] */ /** Offsets of atoms in the residue layer. start = offsets[i], endExclusive = offsets[i + 1] */
atomOffsets: ArrayLike<number>, atomOffsets: ArrayLike<number>,
/** Indices into data.atoms table */
atoms: ArrayLike<number>
/** Index of a residue in the corresponding residues array. */ /** Index of a residue in the corresponding residues array. */
atomResidue: number atomResidue: ArrayLike<number>
}> { } }> { }
export interface Bonds extends Readonly<{ export interface Conformation extends Readonly<{
/** /** A globally unique identifier for this instance (to easily determine unique structures within a model) */
* Where bonds for atom A start and end. id: number,
* Start at idx, end at idx + 1
*/
offset: ArrayLike<number>,
neighbor: ArrayLike<number>,
order: ArrayLike<number>, positions: Data.Positions,
flags: ArrayLike<number>,
count: number /** Per residue secondary structure assignment. */
}> { } secondaryStructure: Data.SecondaryStructures,
export interface Conformation extends Readonly<{ '@spatialLookup': any, // TODO
positions: Data.Positions '@boundingSphere': Readonly<{ center: Vec3, radius: number }>,
spatialLookup: any, // TODO '@bonds': Data.Bonds
boundingSphere: { readonly center: Vec3, readonly radius: number },
secodaryStructure: Data.SecondaryStructures,
bonds: Bonds
}> { } }> { }
export namespace Conformation {
export function spatialLookup(conformation: Conformation): any {
throw 'not implemented'
}
export function boundingSphere(conformation: Conformation): any {
throw 'not implemented'
}
export function bonds(conformation: Conformation): any {
throw 'not implemented'
}
}
export type OperatorKind = export type OperatorKind =
| { kind: 'identity' } | { kind: 'identity' }
| { kind: 'symmetry', id: string, hkl: Vec3 } | { kind: 'symmetry', id: string, hkl: Vec3 }
...@@ -66,31 +84,38 @@ export namespace Unit { ...@@ -66,31 +84,38 @@ export namespace Unit {
inverse: Mat4 inverse: Mat4
}> { } }> { }
export interface Lookup3D { export interface SpatialLookup {
// TODO // TODO
} }
} }
export interface Model extends Readonly<{ export interface Model extends Readonly<{
index: number, units: Unit[],
structure: Model.Structure, structure: { [id: number]: Unit.Structure },
conformation: Model.Conformation conformation: { [id: number]: Unit.Conformation },
'@unitLookup'?: Unit.SpatialLookup,
/** bonds between units */
'@unitBonds'?: Data.Bonds
}> { } }> { }
export namespace Model { export namespace Model {
// TODO: model residues between units export function unitLookup(model: Model): Unit.SpatialLookup {
// use a map of map of bonds? throw 'not implemented';
}
export interface Structure extends Readonly<{ export function unitBonds(model: Model): Data.Bonds {
operators: Unit.Operator[], throw 'not implemented';
units: Unit.Structure[] }
}> { }
export interface Conformation extends Readonly<{ export function join(a: Model, b: Model): Model {
units: Unit.Conformation[], return {
spatialLookup: Unit.Lookup3D units: [...a.units, ...b.units],
}> { } structure: { ...a.structure, ...b.structure },
conformation: { ...a.conformation, ...b.conformation }
}
}
} }
export namespace Atom { export namespace Atom {
...@@ -100,30 +125,49 @@ export namespace Atom { ...@@ -100,30 +125,49 @@ export namespace Atom {
* a both number[] and Float64Array(), making it much * a both number[] and Float64Array(), making it much
* more efficient than storing an array of objects. * more efficient than storing an array of objects.
*/ */
export type Reference = number export type PackedReference = number
export interface Location { unit: number, atom: number } export interface Reference { unit: number, atom: number }
export type Selection = ArrayLike<PackedReference>
const { _uint32, _float64 } = (function() { const { _uint32, _float64 } = (function() {
const data = new ArrayBuffer(8); const data = new ArrayBuffer(8);
return { _uint32: new Uint32Array(data), _float64: new Float64Array(data) }; return { _uint32: new Uint32Array(data), _float64: new Float64Array(data) };
}()); }());
export function emptyLocation(): Location { return { unit: 0, atom: 0 }; } export function emptyLocation(): Reference { return { unit: 0, atom: 0 }; }
export function getRef(location: Location) { export function packRef(location: Reference) {
_uint32[0] = location.unit; _uint32[0] = location.unit;
_uint32[1] = location.atom; _uint32[1] = location.atom;
return _float64[0]; return _float64[0];
} }
export function getLocation(ref: Reference) { export function unpackRef(ref: PackedReference) {
return updateLocation(ref, emptyLocation()); return updateRef(ref, emptyLocation());
} }
export function updateLocation(ref: Reference, location: Location): Location { export function updateRef(ref: PackedReference, location: Reference): Reference {
_float64[0] = ref; _float64[0] = ref;
location.unit = _uint32[0]; location.unit = _uint32[0];
location.atom = _uint32[1]; location.atom = _uint32[1];
return location; return location;
} }
} }
export interface Selector<T> {
'@type': T,
create(m: Model, u: number): (a: number, v?: T) => T
}
export function Selector<T>(create: (m: Model, u: number) => (a: number, v?: T) => T): Selector<T> {
return { create } as Selector<T>;
}
export namespace Selector {
export type Field<T> = (a: number, v?: T) => T;
export type Category = { [s: string]: Selector<any> };
export type Unit<C extends Category> = { [F in keyof C]: Field<C[F]['@type']> }
export type Set<S extends { [n: string]: Category }> = { [C in keyof S]: Unit<S[C]> }
}
\ No newline at end of file
/**
* Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Selector } from './model'
const set = {};
export type Selectors = Selector.Set<typeof set>
\ No newline at end of file
// /**
// * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
// *
// * @author David Sehnal <david.sehnal@gmail.com>
// */
// import { Selector } from '../model'
// //import * as Data from '../data'
// //import { Vec3 } from '../../utils/linear-algebra'
// export const atom = {
// name: Selector((m, u) => {
// const unit = m.units[u].structure;
// const atoms = unit.atoms;
// const name = unit.data.atoms.name;
// return a => name[atoms[a]];
// }),
// // position: Selector<Vec3>((m, u) => {
// // const unit = m.units[u].structure;
// // const atoms = unit.atoms;
// // const { positions: { x, y, z } } = m.conformation[u];
// // const { operator: { transform } } = unit;
// // return (atom, position) => {
// // const a = atoms[atom];
// // const p = position || Vec3.zero();
// // Vec3.set(p, x[a], y[a], z[a]);
// // return Vec3.transformMat4(p, p, transform);
// // };
// // }),
// // inversePosition: Selector<Vec3>((m, u) => {
// // const unit = m.structure[u];
// // const atoms = unit.atoms;
// // const { positions: { x, y, z } } = m.conformation[u];
// // const { operator: { inverse } } = unit;
// // return (atom, position) => {
// // const a = atoms[atom];
// // const p = position || Vec3.zero();
// // Vec3.set(p, x[a], y[a], z[a]);
// // return Vec3.transformMat4(p, p, inverse);
// // };
// // })
// }
// export const residue = {
// }
\ No newline at end of file
// /**
// * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
// *
// * @author David Sehnal <david.sehnal@gmail.com>
// */
// import { Model, Unit, PropertyGetterProvider } from '../model'
// import * as Data from '../data'
// //import { Vec3 } from '../../utils/linear-algebra'
// // function provider<T>(p: (model: Model) => Property<T>): PropertyProvider<T> {
// // return p;
// // }
// function atomPropertyProvider<T>(property: (ps: Model['structure']['properties']) => ArrayLike<T>): PropertyGetterProvider<T> {
// return m => {
// const a = m.structure.properties.atoms;
// const p = property(m.structure.properties);
// return ({ unit, atom }) => p[a[unit][atom]];
// };
// }
// function unitStructureProvider<T>(p: (structure: Unit.Structure, data: Data.Structure, atom: number) => T): PropertyGetterProvider<T> {
// return m => {
// const units = m.structure.units;
// const data = m.structure.properties.data;
// return ({ unit, atom }) => p(units[unit], data[unit], atom);
// };
// }
// export const atom_site = {
// label_atom_id: atomPropertyProvider(ps => ps.),
// label_comp_id: unitStructureProvider((u, d, a) => d.residues.name[u.atomResidue[a]])
// }
\ No newline at end of file
...@@ -572,8 +572,7 @@ export namespace Vec3 { ...@@ -572,8 +572,7 @@ export namespace Vec3 {
export function transformMat4(out: number[], a: number[], m: number[]) { export function transformMat4(out: number[], a: number[], m: number[]) {
let x = a[0], y = a[1], z = a[2], let x = a[0], y = a[1], z = a[2],
w = m[3] * x + m[7] * y + m[11] * z + m[15]; w = (m[3] * x + m[7] * y + m[11] * z + m[15]) || 1.0;
w = w || 1.0;
out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment