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

refactoring

parent 6d65923d
Branches
Tags
No related merge requests found
Showing with 65 additions and 115 deletions
......@@ -248,7 +248,7 @@ function subtractIS(a: I, b: S) {
let offset = 0;
for (let i = min; i < fst; i++) ret[offset++] = i;
for (let i = fst; i <= last; i++) {
if (S.indexOfInterval(b, i, interval) < 0) ret[offset++] = i;
if (S.indexOfInInterval(b, i, interval) < 0) ret[offset++] = i;
}
for (let i = last + 1; i <= max; i++) ret[offset++] = i;
return ofSortedArray(ret);
......
......@@ -35,7 +35,7 @@ export function indexOf(xs: Nums, v: number) {
const l = xs.length;
return l === 0 ? -1 : xs[0] <= v && v <= xs[l - 1] ? binarySearchRange(xs, v, 0, l) : -1;
}
export function indexOfInterval(xs: Nums, v: number, bounds: Interval) {
export function indexOfInInterval(xs: Nums, v: number, bounds: Interval) {
const l = xs.length;
const s = Interval.start(bounds), e = Interval.end(bounds);
return l === 0 || e <= s ? -1 : xs[s] <= v && v <= xs[e - 1] ? binarySearchRange(xs, v, s, e) : -1;
......
......@@ -16,8 +16,7 @@ namespace SortedArray {
export const has: (array: SortedArray, x: number) => boolean = Impl.has as any;
export const indexOf: (array: SortedArray, x: number) => number = Impl.indexOf as any;
export const indexOfInterval: (array: SortedArray, x: number, bounds: Interval) => number = Impl.indexOfInterval as any;
//export const getAt: (array: SortedArray, i: number) => number = Impl.getAt as any;
export const indexOfInInterval: (array: SortedArray, x: number, bounds: Interval) => number = Impl.indexOfInInterval as any;
export const start: (array: SortedArray) => number = Impl.start as any;
export const end: (array: SortedArray) => number = Impl.end as any;
......
......@@ -5,9 +5,7 @@
*/
/**
* ES6 compatible iterator.
*
* "Idiomatic" usage is to use the move function, because it does not make any allocations.
* "Idiomatic" usage:
*
* const it = ...;
* while (it.hasNext) { const v = it.move(); ... }
......
......@@ -7,7 +7,11 @@
interface BitFlags<Flags> { '@type': Flags }
namespace BitFlags {
export function create<F>(flags: F): BitFlags<F> { return flags as any; }
export function has<F>(flags: BitFlags<F>, flag: F) { return ((flags as any) & (flag as any)) !== 0; }
// toCheck must be non-zero
export function hasAll<F>(flags: BitFlags<F>, toCheck: BitFlags<F>) { return !!toCheck && ((flags as any) & (toCheck as any)) === (toCheck as any); }
}
export default BitFlags
\ No newline at end of file
......@@ -11,13 +11,15 @@ interface Conformation {
id: UUID,
// ID is part of conformation because mmCIF is a leaky abstraction
// thats assigns different atom ids to corresponding atoms in different models
// that assigns different atom ids to corresponding atoms in different models
// ... go figure.
atomId: Column<number>,
occupancy: Column<number>,
B_iso_or_equiv: Column<number>
// Coordinates. Generally, not to be accessed directly because the coordinate might be
// transformed by an operator. Use Unit.getPosition instead.
__x: ArrayLike<number>,
__y: ArrayLike<number>,
__z: ArrayLike<number>
......
......@@ -12,12 +12,12 @@ import * as Base from './structure/base'
//import Operator from './structure/operator'
// TODO: do "single model" version of the structure?
export interface Structure extends Readonly<{
interface Structure extends Readonly<{
units: { readonly [id: number]: Unit },
atoms: AtomSet
}> { }
export namespace Structure {
namespace Structure {
export const Empty = Base.Empty;
export const ofModel = Base.ofModel;
......
......@@ -46,7 +46,7 @@ namespace AtomSet {
// TODO: bounding sphere
// TODO: distance, areWithIn?
// TODO: check connected
// TODO: add "parent" property? how to avoid using too much memory? Transitive parents?
// TODO: add "parent" property? how to avoid using too much memory? Transitive parents? Parent unlinking?
}
interface AtomSet { '@type': 'atom-set' }
......
......@@ -4,3 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
// TODO: bounding sphere
// TODO: distance, areWithIn?
// TODO: check connected
// TODO: add "parent" property? how to avoid using too much memory? Transitive parents? Parent unlinking?
\ No newline at end of file
......@@ -5,6 +5,8 @@
*/
import Tuple from '../../mol-base/collections/integer/tuple'
import Unit from './unit'
import Structure from '../structure'
/** Atom pointer */
interface Atom { '@type': Tuple['@type'] }
......@@ -17,6 +19,17 @@ namespace Atom {
export const index: (a: Atom) => number = Tuple.snd;
export const areEqual: (a: Atom, b: Atom) => boolean = Tuple.areEqual;
export const hashCode: (a: Atom) => number = Tuple.hashCode;
/** All the information required to access atom properties */
export interface Location { unit: Unit, atom: number }
export function Location(): Location { return { unit: {} as any, atom: 0 }; }
export interface Property<T> { (location: Location): T }
export interface Predicate extends Property<boolean> { }
export function setLocation(structure: Structure, l: Location, atom: Atom) {
l.unit = structure.units[unit(atom)];
l.atom = index(atom);
}
}
export default Atom
\ No newline at end of file
......@@ -11,7 +11,7 @@ import Operator from './operator'
import AtomSet from './atom-set'
import OrderedSet from '../../mol-base/collections/integer/ordered-set'
class Builder {
export class StructureBuilder {
private units = Object.create(null);
private atoms = Object.create(null);
......@@ -25,7 +25,7 @@ export const Empty: Structure = { units: {}, atoms: AtomSet.Empty };
export function ofModel(model: Model): Structure {
const chains = model.hierarchy.chainSegments;
const builder = new Builder();
const builder = new StructureBuilder();
for (let c = 0; c < chains.count; c++) {
const unit = Unit.create(model, Operator.Identity);
......
/**
* Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Structure from '../structure'
import Atom from './atom'
import Unit from './unit'
import Model from '../model'
import Column from '../../mol-base/collections/column'
/** Atom pointer */
interface Property<T> { (location: Property.Location): T }
namespace Property {
export interface Predicate extends Property<boolean> { }
/** All the information required to access atom properties */
export interface Location {
//structure: Structure,
unit: Unit,
// hierarchy: Model['hierarchy'],
// conformation: Model['conformation'],
atomIndex: number,
// residueIndex: number,
// chainIndex: number
}
export function createLocation(): Location {
return {
//structure: structure!,
unit: {} as any,
//hierarchy: (!unit ? void 0 : unit.model.hierarchy)!,
//conformation: (!unit ? void 0 : unit.model.conformation)!,
atomIndex: 0
//residueIndex: 0,
//chainIndex: 0
};
}
export function update(l: Location, structure: Structure, atom: Atom) {
// const u = structure.units[Atom.unit(atom)];
// const i = Atom.index(atom);
// l.structure = structure;
// l.unit = u;
// l.atomIndex = i;
// l.residueIndex = u.residueIndex[i];
// l.chainIndex = u.chainIndex[i];
throw 'not implemented'
}
export function naive<T>(p: Property<T>) { return p; }
export function cachedAtomColumn<T>(col: (model: Model) => Column<T>): Property<T> {
let lastUnit: Unit | undefined = void 0;
let cached: ((row: number) => T) | undefined = void 0;
return function (location) {
if (location.unit === lastUnit && !!cached) return cached(location.atomIndex);
lastUnit = location.unit;
cached = col(lastUnit.model).value;
return cached(location.atomIndex);
};
}
// TODO: cached versions of other properties.
}
export default Property
\ No newline at end of file
......@@ -12,7 +12,6 @@ import CIF from '../mol-io/reader/cif'
import buildModels from '../mol-data/model/builders/mmcif'
import { ofModel } from '../mol-data/structure/base'
import Property from '../mol-data/structure/property'
import Model from '../mol-data/Model'
import Structure from '../mol-data/structure'
import OrdSet from '../mol-base/collections/integer/ordered-set'
......@@ -80,10 +79,10 @@ export namespace PropertyAccess {
return s;
}
function sumProperty(structure: Structure, p: Property<number>) {
function sumProperty(structure: Structure, p: Atom.Property<number>) {
const { atoms, units } = structure;
const unitIds = AtomSet.unitIds(atoms);
const l = Property.createLocation();
const l = Atom.Location();
let s = 0;
......@@ -92,7 +91,7 @@ export namespace PropertyAccess {
const set = AtomSet.unitGetByIndex(atoms, i);
for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
l.atomIndex = OrdSet.getAt(set, j);
l.atom = OrdSet.getAt(set, j);
s += p(l);
}
}
......@@ -100,10 +99,10 @@ export namespace PropertyAccess {
return s;
}
function sumPropertySegmented(structure: Structure, p: Property<number>) {
function sumPropertySegmented(structure: Structure, p: Atom.Property<number>) {
const { atoms, units } = structure;
const unitIds = AtomSet.unitIds(atoms);
const l = Property.createLocation();
const l = Atom.Location();
let s = 0;
......@@ -120,7 +119,7 @@ export namespace PropertyAccess {
while (residuesIt.hasNext) {
const residueSegment = residuesIt.move();
for (let j = residueSegment.start, _j = residueSegment.end; j < _j; j++) {
l.atomIndex = OrdSet.getAt(set, j);
l.atom = OrdSet.getAt(set, j);
s += p(l);
}
}
......@@ -130,10 +129,10 @@ export namespace PropertyAccess {
return s;
}
function sumPropertyResidue(structure: Structure, p: Property<number>) {
function sumPropertyResidue(structure: Structure, p: Atom.Property<number>) {
const { atoms, units } = structure;
const unitIds = AtomSet.unitIds(atoms);
const l = Property.createLocation();
const l = Atom.Location();
let s = 0;
......@@ -143,7 +142,7 @@ export namespace PropertyAccess {
const set = AtomSet.unitGetByIndex(atoms, i);
const residuesIt = Segmentation.transientSegments(unit.hierarchy.residueSegments, set);
while (residuesIt.hasNext) {
l.atomIndex = OrdSet.getAt(set, residuesIt.move().start);
l.atom = OrdSet.getAt(set, residuesIt.move().start);
s += p(l);
}
}
......@@ -151,16 +150,16 @@ export namespace PropertyAccess {
return s;
}
function sumPropertyAtomSetIt(structure: Structure, p: Property<number>) {
function sumPropertyAtomSetIt(structure: Structure, p: Atom.Property<number>) {
const { atoms, units } = structure;
let s = 0;
const atomsIt = AtomSet.atoms(atoms);
const l = Property.createLocation();
const l = Atom.Location();
while (atomsIt.hasNext) {
const a = atomsIt.move();
l.unit = units[Atom.unit(a)];
l.atomIndex = Atom.index(a);
l.atom = Atom.index(a);
s += p(l);
}
return s;
......@@ -186,7 +185,7 @@ export namespace PropertyAccess {
// while (residuesIt.hasNext) {
// const residueSegment = residuesIt.move();
// for (let j = residueSegment.start, _j = residueSegment.end; j < _j; j++) {
// l.atomIndex = OrdSet.getAt(set, j);
// l.atom = OrdSet.getAt(set, j);
// s += p(l);
// }
// }
......@@ -232,7 +231,7 @@ export namespace PropertyAccess {
// for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
// const aI = OrdSet.getAt(set, j);
// l.atomIndex = aI;
// l.atom = aI;
// l.residueIndex = residueIndex[aI];
// l.chainIndex = chainIndex[aI];
// s[s.length] = p(l);
......@@ -251,33 +250,33 @@ export namespace PropertyAccess {
console.log(baseline(models[0]));
console.log(baselineRaw(models[0]));
console.log(sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)));
console.log(sumPropertySegmented(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)));
//console.log(sumPropertySegmentedMutable(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)));
console.log(sumPropertyAtomSetIt(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)));
console.log(sumProperty(structures[0], Property.cachedAtomColumn(m => m.conformation.atomId)));
console.log(sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
console.log(sumPropertySegmented(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
//console.log(sumPropertySegmentedMutable(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
console.log(sumPropertyAtomSetIt(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
//console.log(sumProperty(structures[0], Property.cachedAtomColumn(m => m.conformation.atomId)));
console.log(sumDirect(structures[0]));
console.log('r', sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atomIndex])));
console.log('r', sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])));
//const col = models[0].conformation.atomId.value;
const suite = new B.Suite();
suite
//.add('test int', () => sumProperty(structures[0], l => col(l.atomIndex)))
//.add('test int', () => sumProperty(structures[0], l => col(l.atom)))
// .add('baseline raw', () => baselineRaw(models[0]))
.add('sum residue', () => sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atomIndex])))
.add('sum residue', () => sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])))
.add('baseline', () => baseline(models[0]))
.add('direct', () => sumDirect(structures[0]))
//.add('normal int', () => sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)))
//.add('atom set it int', () => sumPropertyAtomSetIt(structures[0], l => l.unit.conformation.atomId.value(l.atomIndex)))
// .add('segmented faster int', () => sumPropertySegmented(structures[0], l => l.unit.conformation.atomId.value(l.atomIndex)))
// .add('faster int', () => sumProperty(structures[0], l => l.unit.conformation.atomId.value(l.atomIndex)))
.add('segmented faster _x', () => sumPropertySegmented(structures[0], l => l.unit.conformation.__x[l.atomIndex]))
.add('faster _x', () => sumProperty(structures[0], l => l.unit.conformation.__x[l.atomIndex] + l.unit.conformation.__y[l.atomIndex] + l.unit.conformation.__z[l.atomIndex]))
//.add('segmented mut faster int', () => sumPropertySegmentedMutable(structures[0], l => l.unit.conformation.atomId.value(l.atomIndex)))
//.add('normal shortcut int', () => sumProperty(structures[0], l => l.conformation.atomId.value(l.atomIndex)))
//.add('normal int', () => sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)))
//.add('atom set it int', () => sumPropertyAtomSetIt(structures[0], l => l.unit.conformation.atomId.value(l.atom)))
// .add('segmented faster int', () => sumPropertySegmented(structures[0], l => l.unit.conformation.atomId.value(l.atom)))
// .add('faster int', () => sumProperty(structures[0], l => l.unit.conformation.atomId.value(l.atom)))
.add('segmented faster _x', () => sumPropertySegmented(structures[0], l => l.unit.conformation.__x[l.atom]))
.add('faster _x', () => sumProperty(structures[0], l => l.unit.conformation.__x[l.atom] + l.unit.conformation.__y[l.atom] + l.unit.conformation.__z[l.atom]))
//.add('segmented mut faster int', () => sumPropertySegmentedMutable(structures[0], l => l.unit.conformation.atomId.value(l.atom)))
//.add('normal shortcut int', () => sumProperty(structures[0], l => l.conformation.atomId.value(l.atom)))
//.add('cached int', () => sumProperty(structures[0], Property.cachedAtomColumn(m => m.conformation.atomId)))
//.add('concat str', () => concatProperty(structures[0], l => l.unit.model.hierarchy.atoms.auth_atom_id.value(l.atomIndex)))
//.add('concat str', () => concatProperty(structures[0], l => l.unit.model.hierarchy.atoms.auth_atom_id.value(l.atom)))
//.add('cached concat str', () => concatProperty(structures[0], Property.cachedAtomColumn(m => m.hierarchy.atoms.auth_atom_id)))
.on('cycle', (e: any) => console.log(String(e.target)))
.run();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment