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

queries are now synchronous due to performance reasons

parent 6afe8085
No related branches found
No related tags found
No related merge requests found
......@@ -34,14 +34,14 @@ function createQuery(entityId: string, label_seq_id: number) {
// TODO: this is really ineffective and should be done using a canvas.
class EntitySequence extends React.Component<{ ctx: Context, seq: StructureSequence.Entity, structure: Structure }> {
async raiseInteractityEvent(seqId?: number) {
raiseInteractityEvent(seqId?: number) {
if (typeof seqId === 'undefined') {
InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, EmptyLoci);
return;
}
const query = createQuery(this.props.seq.entityId, seqId);
const loci = StructureSelection.toLoci(await StructureQuery.run(query, this.props.structure));
const loci = StructureSelection.toLoci(StructureQuery.run1(query, this.props.structure));
if (loci.elements.length === 0) InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, EmptyLoci);
else InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, loci);
}
......
......@@ -4,7 +4,6 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { RuntimeContext } from 'mol-task';
import { Structure, StructureElement } from '../structure';
export interface QueryContextView {
......@@ -17,7 +16,6 @@ export class QueryContext implements QueryContextView {
private currentLocked = false;
readonly inputStructure: Structure;
readonly taskCtx: RuntimeContext;
/** Current element */
readonly element: StructureElement = StructureElement.create();
......@@ -44,9 +42,8 @@ export class QueryContext implements QueryContextView {
(this.currentStructure as any) = void 0;
}
constructor(structure: Structure, taskCtx: RuntimeContext) {
constructor(structure: Structure) {
this.inputStructure = structure;
this.taskCtx = taskCtx;
}
}
......
......@@ -4,38 +4,37 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
// import { StructureQuery } from '../query'
// import { StructureSelection } from '../selection'
// import { Unit, StructureProperties as P, Structure } from '../../structure'
// import { Segmentation, SortedArray } from 'mol-data/int'
// import { LinearGroupingBuilder } from '../utils/builders';
// import { QueryPredicate, QueryFn, QueryContextView } from '../context';
import { SortedArray } from 'mol-data/int';
import { Structure } from '../../structure';
import { QueryPredicate } from '../context';
import { StructureQuery } from '../query';
import { StructureSelection } from '../selection';
// export function pick(query: StructureQuery, pred: QueryPredicate): StructureQuery {
// return async ctx => {
// const sel = await query(ctx);
export function pick(query: StructureQuery, pred: QueryPredicate): StructureQuery {
return ctx => {
const sel = query(ctx);
// if (StructureSelection.isSingleton(sel)) {
// const ret = StructureSelection.LinearBuilder(ctx.inputStructure);
// for (const unit of ctx.inputStructure.units) {
// const { elements } = unit;
// for (let i = 0, _i = elements.length; i < _i; i++) {
// // TODO: optimize this somehow???
// const s = Structure.create([unit.getChild(SortedArray.ofSingleton(elements[i]))]);
// ctx.lockCurrentStructure(s);
// if (pred(ctx)) ret.add(s);
// ctx.unlockCurrentStructure();
// }
// }
// return ret.getSelection();
// } else {
// const ret = StructureSelection.LinearBuilder(ctx.inputStructure);
// for (const s of sel.structures) {
// ctx.lockCurrentStructure(s);
// if (pred(ctx)) ret.add(s);
// ctx.unlockCurrentStructure();
// }
// return ret.getSelection();
// }
// };
// }
if (StructureSelection.isSingleton(sel)) {
const ret = StructureSelection.LinearBuilder(ctx.inputStructure);
for (const unit of ctx.inputStructure.units) {
const { elements } = unit;
for (let i = 0, _i = elements.length; i < _i; i++) {
// TODO: optimize this somehow???
const s = Structure.create([unit.getChild(SortedArray.ofSingleton(elements[i]))]);
ctx.lockCurrentStructure(s);
if (pred(ctx)) ret.add(s);
ctx.unlockCurrentStructure();
}
}
return ret.getSelection();
} else {
const ret = StructureSelection.LinearBuilder(ctx.inputStructure);
for (const s of sel.structures) {
ctx.lockCurrentStructure(s);
if (pred(ctx)) ret.add(s);
ctx.unlockCurrentStructure();
}
return ret.getSelection();
}
};
}
......@@ -11,7 +11,7 @@ import { Segmentation } from 'mol-data/int'
import { LinearGroupingBuilder } from '../utils/builders';
import { QueryPredicate, QueryFn, QueryContextView } from '../context';
export const all: StructureQuery = async (ctx) => StructureSelection.Singletons(ctx.inputStructure, ctx.inputStructure);
export const all: StructureQuery = ctx => StructureSelection.Singletons(ctx.inputStructure, ctx.inputStructure);
export interface AtomsQueryParams {
entityTest: QueryPredicate,
......@@ -44,13 +44,12 @@ export function atoms(params?: Partial<AtomsQueryParams>): StructureQuery {
}
function atomGroupsLinear(atomTest: QueryPredicate): StructureQuery {
return async (ctx) => {
return ctx => {
const { inputStructure } = ctx;
const { units } = inputStructure;
const l = ctx.pushCurrentElement();
const builder = inputStructure.subsetBuilder(true);
let progress = 0;
for (const unit of units) {
l.unit = unit;
const elements = unit.elements;
......@@ -61,9 +60,6 @@ function atomGroupsLinear(atomTest: QueryPredicate): StructureQuery {
if (atomTest(ctx)) builder.addElement(l.element);
}
builder.commitUnit();
progress++;
if (ctx.taskCtx.shouldUpdate) await ctx.taskCtx.update({ message: 'Atom Groups', current: progress, max: units.length });
}
ctx.popCurrentElement();
return StructureSelection.Singletons(inputStructure, builder.getStructure());
......@@ -71,13 +67,12 @@ function atomGroupsLinear(atomTest: QueryPredicate): StructureQuery {
}
function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: AtomsQueryParams): StructureQuery {
return async (ctx) => {
return ctx => {
const { inputStructure } = ctx;
const { units } = inputStructure;
const l = ctx.pushCurrentElement();
const builder = inputStructure.subsetBuilder(true);
let progress = 0;
for (const unit of units) {
if (unit.kind !== Unit.Kind.Atomic) continue;
......@@ -110,9 +105,6 @@ function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: A
}
}
builder.commitUnit();
progress++;
if (ctx.taskCtx.shouldUpdate) await ctx.taskCtx.update({ message: 'Atom Groups', current: progress, max: units.length });
}
ctx.popCurrentElement();
return StructureSelection.Singletons(inputStructure, builder.getStructure());
......@@ -120,13 +112,12 @@ function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: A
}
function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, groupBy }: AtomsQueryParams): StructureQuery {
return async (ctx) => {
return ctx => {
const { inputStructure } = ctx;
const { units } = inputStructure;
const l = ctx.pushCurrentElement();
const builder = new LinearGroupingBuilder(inputStructure);
let progress = 0;
for (const unit of units) {
if (unit.kind !== Unit.Kind.Atomic) continue;
......@@ -155,9 +146,6 @@ function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, group
}
}
}
progress++;
if (ctx.taskCtx.shouldUpdate) await ctx.taskCtx.update({ message: 'Atom Groups', current: progress, max: units.length });
}
ctx.popCurrentElement();
return builder.getSelection();
......
......@@ -5,14 +5,13 @@
*/
import { Segmentation } from 'mol-data/int';
import { RuntimeContext } from 'mol-task';
import { Structure, Unit } from '../../structure';
import { StructureQuery } from '../query';
import { StructureSelection } from '../selection';
import { UniqueStructuresBuilder } from '../utils/builders';
import { StructureUniqueSubsetBuilder } from '../../structure/util/unique-subset-builder';
function getWholeResidues(ctx: RuntimeContext, source: Structure, structure: Structure) {
function getWholeResidues(source: Structure, structure: Structure) {
const builder = source.subsetBuilder(true);
for (const unit of structure.units) {
if (unit.kind !== Unit.Kind.Atomic) {
......@@ -38,17 +37,14 @@ function getWholeResidues(ctx: RuntimeContext, source: Structure, structure: Str
}
export function wholeResidues(query: StructureQuery, isFlat: boolean): StructureQuery {
return async (ctx) => {
const inner = await query(ctx);
return ctx => {
const inner = query(ctx);
if (StructureSelection.isSingleton(inner)) {
return StructureSelection.Singletons(ctx.inputStructure, getWholeResidues(ctx.taskCtx, ctx.inputStructure, inner.structure));
return StructureSelection.Singletons(ctx.inputStructure, getWholeResidues(ctx.inputStructure, inner.structure));
} else {
const builder = new UniqueStructuresBuilder(ctx.inputStructure);
let progress = 0;
for (const s of inner.structures) {
builder.add(getWholeResidues(ctx.taskCtx, ctx.inputStructure, s));
progress++;
if (ctx.taskCtx.shouldUpdate) await ctx.taskCtx.update({ message: 'Whole Residues', current: progress, max: inner.structures.length });
builder.add(getWholeResidues(ctx.inputStructure, s));
}
return builder.getSelection();
}
......@@ -64,12 +60,11 @@ export interface IncludeSurroundingsParams {
wholeResidues?: boolean
}
async function getIncludeSurroundings(ctx: RuntimeContext, source: Structure, structure: Structure, params: IncludeSurroundingsParams) {
function getIncludeSurroundings(source: Structure, structure: Structure, params: IncludeSurroundingsParams) {
const builder = new StructureUniqueSubsetBuilder(source);
const lookup = source.lookup3d;
const r = params.radius;
let progress = 0;
for (const unit of structure.units) {
const { x, y, z } = unit.conformation;
const elements = unit.elements;
......@@ -77,23 +72,21 @@ async function getIncludeSurroundings(ctx: RuntimeContext, source: Structure, st
const e = elements[i];
lookup.findIntoBuilder(x(e), y(e), z(e), r, builder);
}
progress++;
if (progress % 2500 === 0 && ctx.shouldUpdate) await ctx.update({ message: 'Include Surroudnings', isIndeterminate: true });
}
return !!params.wholeResidues ? getWholeResidues(ctx, source, builder.getStructure()) : builder.getStructure();
return !!params.wholeResidues ? getWholeResidues(source, builder.getStructure()) : builder.getStructure();
}
export function includeSurroundings(query: StructureQuery, params: IncludeSurroundingsParams): StructureQuery {
return async (ctx) => {
const inner = await query(ctx);
return ctx => {
const inner = query(ctx);
if (StructureSelection.isSingleton(inner)) {
const surr = await getIncludeSurroundings(ctx.taskCtx, ctx.inputStructure, inner.structure, params);
const surr = getIncludeSurroundings(ctx.inputStructure, inner.structure, params);
const ret = StructureSelection.Singletons(ctx.inputStructure, surr);
return ret;
} else {
const builder = new UniqueStructuresBuilder(ctx.inputStructure);
for (const s of inner.structures) {
builder.add(await getIncludeSurroundings(ctx.taskCtx, ctx.inputStructure, s, params));
builder.add(getIncludeSurroundings(ctx.inputStructure, s, params));
}
return builder.getSelection();
}
......
......@@ -4,19 +4,14 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { RuntimeContext, Task } from 'mol-task'
import { Structure } from '../structure'
import { StructureSelection } from './selection'
import { QueryContext } from './context';
interface StructureQuery { (ctx: QueryContext): Promise<StructureSelection> }
interface StructureQuery { (ctx: QueryContext): StructureSelection }
namespace StructureQuery {
export function run(query: StructureQuery, structure: Structure, ctx?: RuntimeContext) {
return query(new QueryContext(structure, ctx || RuntimeContext.Synchronous))
}
export function asTask(query: StructureQuery, structure: Structure) {
return Task.create('Structure Query', ctx => query(new QueryContext(structure, ctx)));
export function run1(query: StructureQuery, structure: Structure) {
return query(new QueryContext(structure))
}
}
......
......@@ -25,10 +25,10 @@ namespace StructureSymmetry {
const assembler = Structure.Builder();
const queryCtx = new QueryContext(structure, ctx);
const queryCtx = new QueryContext(structure);
for (const g of assembly.operatorGroups) {
const selection = await g.selector(queryCtx);
const selection = g.selector(queryCtx);
if (StructureSelection.structureCount(selection) === 0) {
continue;
}
......
......@@ -331,7 +331,7 @@ export namespace PropertyAccess {
radius: 5,
wholeResidues: true
});
const surr = StructureSelection.unionStructure(await StructureQuery.run(q1, a));
const surr = StructureSelection.unionStructure(StructureQuery.run1(q1, a));
console.timeEnd('symmetry')
// for (const u of surr.units) {
......@@ -372,7 +372,7 @@ export namespace PropertyAccess {
// }
function query(q: StructureQuery, s: Structure) {
return StructureQuery.run(q, s);
return StructureQuery.run1(q, s);
}
export async function run() {
......@@ -444,13 +444,13 @@ export namespace PropertyAccess {
//console.log(to_mmCIF('test', Selection.union(q0r)));
console.time('q1')
await query(q1, structures[0]);
query(q1, structures[0]);
console.timeEnd('q1')
console.time('q1')
await query(q1, structures[0]);
query(q1, structures[0]);
console.timeEnd('q1')
console.time('q2')
const q2r = await query(q2, structures[0]);
const q2r = query(q2, structures[0]);
console.timeEnd('q2')
console.log(StructureSelection.structureCount(q2r));
//console.log(q1(structures[0]));
......@@ -461,8 +461,8 @@ export namespace PropertyAccess {
//.add('test q', () => q1(structures[0]))
//.add('test q', () => q(structures[0]))
.add('test int', () => sumProperty(structures[0], l => col(l.element)))
.add('test q1', async () => await query(q1, structures[0]))
.add('test q3', async () => await query(q3, structures[0]))
.add('test q1', async () => query(q1, structures[0]))
.add('test q3', async () => query(q3, structures[0]))
// .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]))
......
......@@ -69,7 +69,7 @@ export async function resolveRequest(req: Request, writer: Writer) {
? await req.queryDefinition.structureTransform(req.normalizedParams, wrappedStructure.structure)
: wrappedStructure.structure;
const query = req.queryDefinition.query(req.normalizedParams, structure);
const result = StructureSelection.unionStructure(await StructureQuery.asTask(query, structure).run(abortingObserver, 250));
const result = StructureSelection.unionStructure(StructureQuery.run1(query, structure));
perf.end('query');
ConsoleLogger.logId(req.id, 'Query', 'Query finished.');
......
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