-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathresult.ts
113 lines (96 loc) · 4.02 KB
/
result.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* Copyright (c) 2017 MolQL contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <[email protected]>
*/
import LiteMol from 'litemol'
import { Model } from '../reference-implementation/structure/data'
import mmCIFwriter from '../reference-implementation/structure/writer'
import AtomSelection from '../reference-implementation/molql/data/atom-selection'
import AtomSet from '../reference-implementation/molql/data/atom-set'
type Result =
| { kind: 'empty' }
| { kind: 'error', message: string }
| Result.Selection
export interface ResultEntry {
indices: number[],
info: string,
signature: string
}
export function ResultEntry(model: Model, atomSet: AtomSet): ResultEntry {
const { residueIndices } = AtomSet.hierarchy(model, atomSet);
const { dataIndex } = model.atoms;
const { atomOffset } = model.residues;
const { label_comp_id, label_atom_id } = model.data.atom_site;
let signature: string = '';
const indices = AtomSet.toIndices(atomSet) as number[];
if (indices.length === 1) {
const i = dataIndex[indices[0]]
signature = `${label_atom_id.getString(i)!} (${label_comp_id.getString(i)!})`;
} else {
const counts: { [name: string]: number } = { };
for (const rI of residueIndices) {
const i = dataIndex[atomOffset[rI]];
const n = label_comp_id.getString(i)!;
counts[n] = (counts[n] | 0) + 1;
}
signature = Object.keys(counts).sort().map(k => counts[k] > 1 ? `${k}x${counts[k]}` : k).join('-');
}
return {
indices,
info: `${indices.length} ${indices.length !== 1 ? 'atoms' : 'atom'} on ${residueIndices.length} ${residueIndices.length !== 1 ? 'residues' : 'residue'}`,
signature
};
}
function Result(model: Model, selection: AtomSelection, merge: boolean): Result.Selection {
const allIndices = AtomSelection.getAtomIndices(selection) as number[];
if (allIndices.length > 0 && merge) {
const atomSet = AtomSet(AtomSelection.getAtomIndices(selection));
return {
kind: 'selection',
allIndices,
entries: [ResultEntry(model, atomSet)]
}
}
return {
kind: 'selection',
allIndices,
entries: AtomSelection.atomSets(selection).map(s => ResultEntry(model, s))
};
}
namespace Result {
export type Selection = { kind: 'selection', allIndices: number[], entries: ResultEntry[] }
export const empty: Result = { kind: 'empty' };
export function error(message: string): Result { return { kind: 'error', message } };
}
export namespace ResultEntry {
export function focus(plugin: LiteMol.Plugin.Controller, set: ResultEntry) {
const model = plugin.selectEntities('model');
if (!model.length) return;
const query = LiteMol.Core.Structure.Query.atomsFromIndices(set.indices).compile();
plugin.command(LiteMol.Bootstrap.Command.Molecule.FocusQuery, { query, model: model[0] as LiteMol.Bootstrap.Entity.Molecule.Model });
}
export function highlight(plugin: LiteMol.Plugin.Controller, set: ResultEntry, isOn: boolean) {
const model = plugin.selectEntities('model');
if (!model.length) return;
const query = LiteMol.Core.Structure.Query.atomsFromIndices(set.indices).compile();
plugin.command(LiteMol.Bootstrap.Command.Molecule.Highlight, { query, model: model[0] as LiteMol.Bootstrap.Entity.Molecule.Model, isOn });
}
export function showCIF(model: Model, set: ResultEntry) {
const cif = btoa(mmCIFwriter(model, set.indices));
const uri = 'data:text/plain;base64,' + cif;
const a = document.createElement('a');
if ('download' in a) {
a.style.visibility = 'hidden';
a.href = uri;
a.target = '_blank';
a.download = 'atomset.cif';
document.body.appendChild(a);
a.click();
a.remove()
} else {
window.open(uri, '_blank');
}
}
}
export default Result