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

predicates

parent bd201285
Branches
Tags
No related merge requests found
...@@ -7,11 +7,13 @@ ...@@ -7,11 +7,13 @@
import Selection from './query/selection' import Selection from './query/selection'
import Query from './query/query' import Query from './query/query'
import * as generators from './query/generators' import * as generators from './query/generators'
import * as props from './query/properties' import props from './query/properties'
import pred from './query/predicates'
export const Queries = { export const Queries = {
generators, generators,
props props,
pred
} }
export { Selection, Query } export { Selection, Query }
\ No newline at end of file
...@@ -6,11 +6,13 @@ ...@@ -6,11 +6,13 @@
import Query from './query' import Query from './query'
import Selection from './selection' import Selection from './selection'
import * as P from './properties' import P from './properties'
import { Structure, AtomSet, Atom } from '../structure' import { Structure, AtomSet, Atom } from '../structure'
import { OrderedSet, Segmentation } from 'mol-base/collections/integer' import { OrderedSet, Segmentation } from 'mol-base/collections/integer'
export interface AtomGroupsSpec { export const all: Query = s => s;
export interface AtomGroupsParams {
entityTest: Atom.Predicate, entityTest: Atom.Predicate,
chainTest: Atom.Predicate, chainTest: Atom.Predicate,
residueTest: Atom.Predicate, residueTest: Atom.Predicate,
...@@ -18,21 +20,19 @@ export interface AtomGroupsSpec { ...@@ -18,21 +20,19 @@ export interface AtomGroupsSpec {
groupBy: Atom.Property<any> groupBy: Atom.Property<any>
} }
export const all: Query = s => s; export function atoms(params?: Partial<AtomGroupsParams>): Query {
if (!params || (!params.atomTest && !params.residueTest && !params.chainTest && !params.entityTest && !params.groupBy)) return all;
if (!!params.atomTest && !params.residueTest && !params.chainTest && !params.entityTest && !params.groupBy) return atomGroupsLinear(params.atomTest);
export function atomGroups(spec?: Partial<AtomGroupsSpec>): Query { const normalized: AtomGroupsParams = {
if (!spec || (!spec.atomTest && !spec.residueTest && !spec.chainTest && !spec.entityTest && !spec.groupBy)) return all; entityTest: params.entityTest || P.constant.true,
if (!!spec.atomTest && !spec.residueTest && !spec.chainTest && !spec.entityTest && !spec.groupBy) return atomGroupsLinear(spec.atomTest); chainTest: params.chainTest || P.constant.true,
residueTest: params.residueTest || P.constant.true,
const normalized: AtomGroupsSpec = { atomTest: params.atomTest || P.constant.true,
entityTest: spec.entityTest || P.constant.true, groupBy: params.groupBy || P.constant.zero,
chainTest: spec.entityTest || P.constant.true,
residueTest: spec.residueTest || P.constant.true,
atomTest: spec.atomTest || P.constant.true,
groupBy: spec.entityTest || P.constant.zero,
}; };
if (!spec.groupBy) return atomGroupsSegmented(normalized) if (!params.groupBy) return atomGroupsSegmented(normalized)
return atomGroupsGrouped(normalized); return atomGroupsGrouped(normalized);
} }
...@@ -60,7 +60,7 @@ function atomGroupsLinear(atomTest: Atom.Predicate): Query { ...@@ -60,7 +60,7 @@ function atomGroupsLinear(atomTest: Atom.Predicate): Query {
}; };
} }
function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: AtomGroupsSpec): Query { function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: AtomGroupsParams): Query {
return structure => { return structure => {
const { atoms, units } = structure; const { atoms, units } = structure;
const unitIds = AtomSet.unitIds(atoms); const unitIds = AtomSet.unitIds(atoms);
...@@ -151,8 +151,43 @@ class LinearGroupingBuilder { ...@@ -151,8 +151,43 @@ class LinearGroupingBuilder {
constructor(private structure: Structure) { } constructor(private structure: Structure) { }
} }
function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, groupBy }: AtomGroupsSpec): Query { function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, groupBy }: AtomGroupsParams): Query {
return structure => { return structure => {
throw 'nyi' const { atoms, units } = structure;
const unitIds = AtomSet.unitIds(atoms);
const l = Atom.Location();
const builder = new LinearGroupingBuilder(structure);
for (let i = 0, _i = unitIds.length; i < _i; i++) {
const unitId = unitIds[i];
const unit = units[unitId];
l.unit = unit;
const set = AtomSet.unitGetByIndex(atoms, i);
const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set);
const residuesIt = Segmentation.transientSegments(unit.hierarchy.residueSegments, set);
while (chainsIt.hasNext) {
const chainSegment = chainsIt.move();
l.atom = OrderedSet.getAt(set, chainSegment.start);
// test entity and chain
if (!entityTest(l) || !chainTest(l)) continue;
residuesIt.setSegment(chainSegment);
while (residuesIt.hasNext) {
const residueSegment = residuesIt.move();
l.atom = OrderedSet.getAt(set, residueSegment.start);
// test residue
if (!residueTest(l)) continue;
for (let j = residueSegment.start, _j = residueSegment.end; j < _j; j++) {
l.atom = OrderedSet.getAt(set, j);
if (atomTest(l)) builder.add(groupBy(l), unitId, l.atom);
}
}
}
}
return builder.getSelection();
}; };
} }
\ No newline at end of file
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Atom } from '../structure'
import P from './properties'
namespace Predicates {
interface SetLike<A> { has(v: A): boolean }
function isSetLike<A>(x: any): x is SetLike<A> { return !!x && !!x.has }
export function eq<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) === value; }
export function lt<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) < value; }
export function lte<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) <= value; }
export function gt<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) > value; }
export function gte<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) >= value; }
export function inSet<A>(p: Atom.Property<A>, values: SetLike<A> | ArrayLike<A>): Atom.Predicate {
if (isSetLike(values)) {
return l => values.has(p(l));
} else {
const set = new Set<A>();
for (let i = 0; i < values.length; i++) set.add(values[i]);
return l => set.has(p(l));
}
}
export function and(...ps: Atom.Predicate[]): Atom.Predicate {
switch (ps.length) {
case 0: return P.constant.true;
case 1: return ps[0];
case 2: {
const a = ps[0], b = ps[1];
return l => a(l) && b(l);
}
case 3: {
const a = ps[0], b = ps[1], c = ps[2];
return l => a(l) && b(l) && c(l);
}
case 4: {
const a = ps[0], b = ps[1], c = ps[2], d = ps[3];
return l => a(l) && b(l) && c(l) && d(l);
}
case 5: {
const a = ps[0], b = ps[1], c = ps[2], d = ps[3], e = ps[4];
return l => a(l) && b(l) && c(l) && d(l) && e(l);
}
case 6: {
const a = ps[0], b = ps[1], c = ps[2], d = ps[3], e = ps[4], f = ps[5];
return l => a(l) && b(l) && c(l) && d(l) && e(l) && f(l);
}
default: {
const count = ps.length;
return l => {
for (let i = 0; i < count; i++) if (!ps[i]) return false;
return true;
}
}
}
}
export function or(...ps: Atom.Predicate[]): Atom.Predicate {
switch (ps.length) {
case 0: return P.constant.true;
case 1: return ps[0];
case 2: {
const a = ps[0], b = ps[1];
return l => a(l) || b(l);
}
case 3: {
const a = ps[0], b = ps[1], c = ps[2];
return l => a(l) || b(l) || c(l);
}
case 4: {
const a = ps[0], b = ps[1], c = ps[2], d = ps[3];
return l => a(l) || b(l) || c(l) || d(l);
}
case 5: {
const a = ps[0], b = ps[1], c = ps[2], d = ps[3], e = ps[4];
return l => a(l) || b(l) || c(l) || d(l) || e(l);
}
case 6: {
const a = ps[0], b = ps[1], c = ps[2], d = ps[3], e = ps[4], f = ps[5];
return l => a(l) || b(l) || c(l) || d(l) || e(l) || f(l);
}
default: {
const count = ps.length;
return l => {
for (let i = 0; i < count; i++) if (ps[i]) return true;
return false;
}
}
}
}
}
export default Predicates
\ No newline at end of file
...@@ -6,21 +6,33 @@ ...@@ -6,21 +6,33 @@
import { Atom } from '../structure' import { Atom } from '../structure'
export const constant = { const constant = {
true: Atom.property(l => true), true: Atom.property(l => true),
false: Atom.property(l => false), false: Atom.property(l => false),
zero: Atom.property(l => 0) zero: Atom.property(l => 0)
} }
export const atom = { const atom = {
type_symbol: Atom.property(l => l.unit.hierarchy.atoms.type_symbol.value(l.atom)) type_symbol: Atom.property(l => l.unit.hierarchy.atoms.type_symbol.value(l.atom))
} }
export const residue = { const residue = {
key: Atom.property(l => l.unit.hierarchy.residueKey.value(l.unit.residueIndex[l.atom])),
auth_seq_id: Atom.property(l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])), auth_seq_id: Atom.property(l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])),
auth_comp_id: Atom.property(l => l.unit.hierarchy.residues.auth_comp_id.value(l.unit.residueIndex[l.atom])) auth_comp_id: Atom.property(l => l.unit.hierarchy.residues.auth_comp_id.value(l.unit.residueIndex[l.atom]))
} }
export const chain = { const chain = {
auth_asym_id: Atom.property(l => l.unit.hierarchy.chains.auth_asym_id.value(l.unit.chainIndex[l.atom])) auth_asym_id: Atom.property(l => l.unit.hierarchy.chains.auth_asym_id.value(l.unit.chainIndex[l.atom]))
} }
\ No newline at end of file
const Properties = {
constant,
atom,
residue,
chain
}
type Properties = typeof Properties
export default Properties
\ No newline at end of file
...@@ -10,7 +10,7 @@ import * as util from 'util' ...@@ -10,7 +10,7 @@ import * as util from 'util'
import * as fs from 'fs' import * as fs from 'fs'
import CIF from 'mol-io/reader/cif' import CIF from 'mol-io/reader/cif'
import { Structure, Model, Queries as Q, Atom, AtomSet } from 'mol-data/structure' import { Structure, Model, Queries as Q, Atom, AtomSet, Selection } from 'mol-data/structure'
import { OrderedSet as OrdSet, Segmentation } from 'mol-base/collections/integer' import { OrderedSet as OrdSet, Segmentation } from 'mol-base/collections/integer'
require('util.promisify').shim(); require('util.promisify').shim();
...@@ -235,8 +235,8 @@ export namespace PropertyAccess { ...@@ -235,8 +235,8 @@ export namespace PropertyAccess {
// } // }
export async function run() { export async function run() {
const { structures, models } = await readCIF('./examples/1cbs_full.bcif'); //const { structures, models } = await readCIF('./examples/1cbs_full.bcif');
//const { structures, models } = await readCIF('e:/test/quick/1jj2_full.bcif'); const { structures, models } = await readCIF('e:/test/quick/1jj2_full.bcif');
//const { structures, models } = await readCIF('e:/test/quick/3j3q_updated.cif'); //const { structures, models } = await readCIF('e:/test/quick/3j3q_updated.cif');
console.log('parsed'); console.log('parsed');
...@@ -258,9 +258,14 @@ export namespace PropertyAccess { ...@@ -258,9 +258,14 @@ export namespace PropertyAccess {
//const auth_asym_id = Q.props.chain.auth_asym_id; //const auth_asym_id = Q.props.chain.auth_asym_id;
//const set = new Set(['A', 'B', 'C', 'D']); //const set = new Set(['A', 'B', 'C', 'D']);
//const q = Q.generators.atomGroups({ atomTest: l => auth_seq_id(l) < 3 }); //const q = Q.generators.atomGroups({ atomTest: l => auth_seq_id(l) < 3 });
const q = Q.generators.atomGroups({ atomTest: l => auth_comp_id(l) === 'ALA' }); const q = Q.generators.atoms({ atomTest: Q.pred.eq(Q.props.residue.auth_comp_id, 'ALA') });
const q1 = Q.generators.atomGroups({ residueTest: l => auth_comp_id(l) === 'ALA' }); //const q0 = Q.generators.atoms({ atomTest: l => auth_comp_id(l) === 'ALA' });
//const q2 = Q.generators.atomGroups({ chainTest: l => set.has(auth_asym_id(l)), residueTest: l => auth_comp_id(l) === 'ALA' }); const q1 = Q.generators.atoms({ residueTest: l => auth_comp_id(l) === 'ALA' });
const q2 = Q.generators.atoms({ residueTest: l => auth_comp_id(l) === 'ALA', groupBy: Q.props.residue.key });
const q3 = Q.generators.atoms({
chainTest: Q.pred.inSet(Q.props.chain.auth_asym_id, ['A', 'B', 'C', 'D']),
residueTest: Q.pred.eq(Q.props.residue.auth_comp_id, 'ALA')
});
q(structures[0]); q(structures[0]);
console.time('q1') console.time('q1')
q1(structures[0]); q1(structures[0]);
...@@ -268,12 +273,19 @@ export namespace PropertyAccess { ...@@ -268,12 +273,19 @@ export namespace PropertyAccess {
console.time('q1') console.time('q1')
q1(structures[0]); q1(structures[0]);
console.timeEnd('q1') console.timeEnd('q1')
console.time('q2')
const q2r = q2(structures[0]);
console.timeEnd('q2')
console.log(Selection.structureCount(q2r))
//console.log(q1(structures[0])); //console.log(q1(structures[0]));
//const col = models[0].conformation.atomId.value; //const col = models[0].conformation.atomId.value;
const suite = new B.Suite(); const suite = new B.Suite();
suite suite
.add('test q', () => q1(structures[0])) //.add('test q', () => q1(structures[0]))
//.add('test q', () => q(structures[0]))
.add('test q1', () => q1(structures[0]))
.add('test q3', () => q3(structures[0]))
//.add('test int', () => sumProperty(structures[0], l => col(l.atom))) //.add('test int', () => sumProperty(structures[0], l => col(l.atom)))
// .add('sum residue', () => sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom]))) // .add('sum residue', () => sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment