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 @@ ...@@ -2,6 +2,7 @@
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { PluginStateObject as SO, PluginStateTransform } from '../../../state/objects'; import { PluginStateObject as SO, PluginStateTransform } from '../../../state/objects';
...@@ -13,38 +14,39 @@ import { urlCombine } from '../../../../mol-util/url'; ...@@ -13,38 +14,39 @@ import { urlCombine } from '../../../../mol-util/url';
import { createIsoValueParam } from '../../../../mol-repr/volume/isosurface'; import { createIsoValueParam } from '../../../../mol-repr/volume/isosurface';
import { VolumeIsoValue } from '../../../../mol-model/volume'; import { VolumeIsoValue } from '../../../../mol-model/volume';
import { StateAction, StateObject, StateTransformer } from '../../../../mol-state'; import { StateAction, StateObject, StateTransformer } from '../../../../mol-state';
import { getStreamingMethod, getEmdbIdAndContourLevel } from './util'; import { getStreamingMethod, getId, getContourLevel, getEmdbId } from './util';
import { VolumeStreaming } from './behavior'; import { VolumeStreaming } from './behavior';
import { VolumeRepresentation3DHelpers } from '../../../../mol-plugin/state/transforms/representation'; import { VolumeRepresentation3DHelpers } from '../../../../mol-plugin/state/transforms/representation';
import { BuiltInVolumeRepresentations } from '../../../../mol-repr/volume/registry'; import { BuiltInVolumeRepresentations } from '../../../../mol-repr/volume/registry';
import { createTheme } from '../../../../mol-theme/theme'; import { createTheme } from '../../../../mol-theme/theme';
import { Box3D } from '../../../../mol-math/geometry'; import { Box3D } from '../../../../mol-math/geometry';
import { Vec3 } from '../../../../mol-math/linear-algebra'; import { Vec3 } from '../../../../mol-math/linear-algebra';
// import { PluginContext } from '../../../../mol-plugin/context';
export const InitVolumeStreaming = StateAction.build({ export const InitVolumeStreaming = StateAction.build({
display: { name: 'Volume Streaming' }, display: { name: 'Volume Streaming' },
from: SO.Molecule.Structure, from: SO.Molecule.Structure,
params(a) { params(a) {
const method = getStreamingMethod(a && a.data); const method = getStreamingMethod(a && a.data);
const id = getId(a && a.data);
return { return {
method: PD.Select<VolumeServerInfo.Kind>(method, [['em', 'EM'], ['x-ray', 'X-Ray']]), 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'), serverUrl: PD.Text('https://ds.litemol.org'),
defaultView: PD.Text<VolumeStreaming.ViewTypes>(method === 'em' ? 'cell' : 'selection-box'), 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 isApplicable: (a) => a.data.models.length === 1
})(({ ref, state, params }, plugin: PluginContext) => Task.create('Volume Streaming', async taskCtx => { })(({ 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; let dataId = params.id.toLowerCase(), emDefaultContourLevel: number | undefined;
if (params.method === 'em') { if (params.method === 'em') {
await taskCtx.update('Getting EMDB info...'); await taskCtx.update('Getting EMDB info...');
const emInfo = await getEmdbIdAndContourLevel(plugin, taskCtx, dataId); if (!dataId.toUpperCase().startsWith('EMD')) {
dataId = emInfo.emdbId; dataId = await getEmdbId(plugin, taskCtx, dataId)
emDefaultContourLevel = emInfo.contour; }
const contourLevel = await getContourLevel(params.emContourProvider, plugin, taskCtx, dataId);
emDefaultContourLevel = contourLevel || 0;
} }
const infoTree = state.build().to(ref) const infoTree = state.build().to(ref)
......
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { Structure } from '../../../../mol-model/structure'; import { Structure } from '../../../../mol-model/structure';
import { VolumeServerInfo } from './model'; import { VolumeServerInfo } from './model';
import { PluginContext } from '../../../../mol-plugin/context'; import { PluginContext } from '../../../../mol-plugin/context';
import { RuntimeContext } from '../../../../mol-task'; 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 { export function getStreamingMethod(s?: Structure, defaultKind: VolumeServerInfo.Kind = 'x-ray'): VolumeServerInfo.Kind {
if (!s) return defaultKind; if (!s) return defaultKind;
...@@ -23,7 +25,53 @@ export function getStreamingMethod(s?: Structure, defaultKind: VolumeServerInfo. ...@@ -23,7 +25,53 @@ export function getStreamingMethod(s?: Structure, defaultKind: VolumeServerInfo.
return 'x-ray'; 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 // 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); 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 ...@@ -39,13 +87,5 @@ export async function getEmdbIdAndContourLevel(plugin: PluginContext, taskCtx: R
throw new Error(`No related EMDB entry found for '${pdbId}'.`); throw new Error(`No related EMDB entry found for '${pdbId}'.`);
} }
// TODO: parametrize to a differnt URL? in plugin settings perhaps return emdbId
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 };
} }
\ 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