Skip to content
Snippets Groups Projects
Commit 1819a2bb authored by Alexander Rose's avatar Alexander Rose
Browse files

add wwpdb provider for emdb contourLevel

parent aa3a42f9
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,7 @@
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { PluginStateObject as SO, PluginStateTransform } from '../../../state/objects';
......@@ -13,38 +14,39 @@ import { urlCombine } from '../../../../mol-util/url';
import { createIsoValueParam } from '../../../../mol-repr/volume/isosurface';
import { VolumeIsoValue } from '../../../../mol-model/volume';
import { StateAction, StateObject, StateTransformer } from '../../../../mol-state';
import { getStreamingMethod, getEmdbIdAndContourLevel } from './util';
import { getStreamingMethod, getId, getContourLevel, getEmdbId } from './util';
import { VolumeStreaming } from './behavior';
import { VolumeRepresentation3DHelpers } from '../../../../mol-plugin/state/transforms/representation';
import { BuiltInVolumeRepresentations } from '../../../../mol-repr/volume/registry';
import { createTheme } from '../../../../mol-theme/theme';
import { Box3D } from '../../../../mol-math/geometry';
import { Vec3 } from '../../../../mol-math/linear-algebra';
// import { PluginContext } from '../../../../mol-plugin/context';
export const InitVolumeStreaming = StateAction.build({
display: { name: 'Volume Streaming' },
from: SO.Molecule.Structure,
params(a) {
const method = getStreamingMethod(a && a.data);
const id = getId(a && a.data);
return {
method: PD.Select<VolumeServerInfo.Kind>(method, [['em', 'EM'], ['x-ray', 'X-Ray']]),
id: PD.Text((a && a.data.models.length > 0 && a.data.models[0].entry) || ''),
id: PD.Text(id),
serverUrl: PD.Text('https://ds.litemol.org'),
defaultView: PD.Text<VolumeStreaming.ViewTypes>(method === 'em' ? 'cell' : 'selection-box'),
behaviorRef: PD.Text('', { isHidden: true })
behaviorRef: PD.Text('', { isHidden: true }),
emContourProvider: PD.Select<'wwpdb' | 'pdbe'>('wwpdb', [['wwpdb', 'wwPDB'], ['pdbe', 'PDBe']], { isHidden: true }),
};
},
isApplicable: (a) => a.data.models.length === 1
})(({ ref, state, params }, plugin: PluginContext) => Task.create('Volume Streaming', async taskCtx => {
// TODO: custom react view for this and the VolumeStreamingBehavior transformer
let dataId = params.id.toLowerCase(), emDefaultContourLevel: number | undefined;
if (params.method === 'em') {
await taskCtx.update('Getting EMDB info...');
const emInfo = await getEmdbIdAndContourLevel(plugin, taskCtx, dataId);
dataId = emInfo.emdbId;
emDefaultContourLevel = emInfo.contour;
if (!dataId.toUpperCase().startsWith('EMD')) {
dataId = await getEmdbId(plugin, taskCtx, dataId)
}
const contourLevel = await getContourLevel(params.emContourProvider, plugin, taskCtx, dataId);
emDefaultContourLevel = contourLevel || 0;
}
const infoTree = state.build().to(ref)
......
......@@ -2,12 +2,14 @@
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Structure } from '../../../../mol-model/structure';
import { VolumeServerInfo } from './model';
import { PluginContext } from '../../../../mol-plugin/context';
import { RuntimeContext } from '../../../../mol-task';
import { getXMLNodeByName, XMLDocument } from '../../../../mol-util/xml-parser';
export function getStreamingMethod(s?: Structure, defaultKind: VolumeServerInfo.Kind = 'x-ray'): VolumeServerInfo.Kind {
if (!s) return defaultKind;
......@@ -23,7 +25,53 @@ export function getStreamingMethod(s?: Structure, defaultKind: VolumeServerInfo.
return 'x-ray';
}
export async function getEmdbIdAndContourLevel(plugin: PluginContext, taskCtx: RuntimeContext, pdbId: string) {
export function getId(s?: Structure): string {
if (!s) return ''
const model = s.models[0]
if (model.sourceData.kind !== 'mmCIF') return ''
const d = model.sourceData.data
for (let i = 0, il = d.pdbx_database_related._rowCount; i < il; ++i) {
if (d.pdbx_database_related.db_name.value(i).toUpperCase() === 'EMDB') {
return d.pdbx_database_related.db_id.value(i)
}
}
return s.models.length > 0 ? s.models[0].entryId : ''
}
export async function getContourLevel(provider: 'wwpdb' | 'pdbe', plugin: PluginContext, taskCtx: RuntimeContext, emdbId: string) {
switch (provider) {
case 'wwpdb': return getContourLevelWwpdb(plugin, taskCtx, emdbId)
case 'pdbe': return getContourLevelPdbe(plugin, taskCtx, emdbId)
}
}
export async function getContourLevelWwpdb(plugin: PluginContext, taskCtx: RuntimeContext, emdbId: string) {
// TODO: parametrize to a differnt URL? in plugin settings perhaps
const header = await plugin.fetch<XMLDocument>({ url: `https://ftp.wwpdb.org/pub/emdb/structures/${emdbId.toUpperCase()}/header/${emdbId.toLowerCase()}.xml`, type: 'xml' }).runInContext(taskCtx);
const map = getXMLNodeByName('map', header!.root!.children!)!
const contourLevel = parseFloat(getXMLNodeByName('contourLevel', map.children!)!.content!)
return contourLevel;
}
export async function getContourLevelPdbe(plugin: PluginContext, taskCtx: RuntimeContext, emdbId: string) {
emdbId = emdbId.toUpperCase()
// TODO: parametrize to a differnt URL? in plugin settings perhaps
const header = await plugin.fetch({ url: `https://www.ebi.ac.uk/pdbe/api/emdb/entry/map/${emdbId}`, type: 'json' }).runInContext(taskCtx);
const emdbEntry = header && header[emdbId];
let contourLevel: number | undefined = void 0;
if (emdbEntry && emdbEntry[0] && emdbEntry[0].map && emdbEntry[0].map.contour_level && emdbEntry[0].map.contour_level.value !== void 0) {
contourLevel = +emdbEntry[0].map.contour_level.value;
}
return contourLevel;
}
export async function getEmdbId(plugin: PluginContext, taskCtx: RuntimeContext, pdbId: string) {
// TODO: parametrize to a differnt URL? in plugin settings perhaps
const summary = await plugin.fetch({ url: `https://www.ebi.ac.uk/pdbe/api/pdb/entry/summary/${pdbId}`, type: 'json' }).runInContext(taskCtx);
......@@ -39,13 +87,5 @@ export async function getEmdbIdAndContourLevel(plugin: PluginContext, taskCtx: R
throw new Error(`No related EMDB entry found for '${pdbId}'.`);
}
// TODO: parametrize to a differnt URL? in plugin settings perhaps
const emdb = await plugin.fetch({ url: `https://www.ebi.ac.uk/pdbe/api/emdb/entry/map/${emdbId}`, type: 'json' }).runInContext(taskCtx);
const emdbEntry = emdb && emdb[emdbId];
let contour: number | undefined = void 0;
if (emdbEntry && emdbEntry[0] && emdbEntry[0].map && emdbEntry[0].map.contour_level && emdbEntry[0].map.contour_level.value !== void 0) {
contour = +emdbEntry[0].map.contour_level.value;
}
return { emdbId, contour };
return emdbId
}
\ No newline at end of file
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