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

cellpack, add support for local ingredient files

parent 9fa56bf7
No related branches found
No related tags found
No related merge requests found
...@@ -9,7 +9,7 @@ import { PluginContext } from '../../../../mol-plugin/context'; ...@@ -9,7 +9,7 @@ import { PluginContext } from '../../../../mol-plugin/context';
import { PluginStateObject as PSO } from '../../../../mol-plugin-state/objects'; import { PluginStateObject as PSO } from '../../../../mol-plugin-state/objects';
import { ParamDefinition as PD } from '../../../../mol-util/param-definition'; import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
import { Ingredient, CellPacking } from './data'; import { Ingredient, CellPacking } from './data';
import { getFromPdb, getFromCellPackDB } from './util'; import { getFromPdb, getFromCellPackDB, IngredientFiles, parseCif, parsePDBfile } from './util';
import { Model, Structure, StructureSymmetry, StructureSelection, QueryContext, Unit } from '../../../../mol-model/structure'; import { Model, Structure, StructureSymmetry, StructureSelection, QueryContext, Unit } from '../../../../mol-model/structure';
import { trajectoryFromMmCIF, MmcifFormat } from '../../../../mol-model-formats/structure/mmcif'; import { trajectoryFromMmCIF, MmcifFormat } from '../../../../mol-model-formats/structure/mmcif';
import { trajectoryFromPDB } from '../../../../mol-model-formats/structure/pdb'; import { trajectoryFromPDB } from '../../../../mol-model-formats/structure/pdb';
...@@ -34,9 +34,21 @@ function getCellPackModelUrl(fileName: string, baseUrl: string) { ...@@ -34,9 +34,21 @@ function getCellPackModelUrl(fileName: string, baseUrl: string) {
return `${baseUrl}/results/${fileName}` return `${baseUrl}/results/${fileName}`
} }
async function getModel(id: string, baseUrl: string) { async function getModel(id: string, baseUrl: string, file?: File) {
let model: Model; let model: Model;
if (id.match(/^[1-9][a-zA-Z0-9]{3,3}$/i)) { if (file) {
const text = await file.text()
if (file.name.endsWith('.cif')) {
const cif = (await parseCif(text)).blocks[0]
model = (await trajectoryFromMmCIF(cif).run())[0]
} else if (file.name.endsWith('.pdb')) {
const pdb = await parsePDBfile(text, id)
model = (await trajectoryFromPDB(pdb).run())[0]
} else {
throw new Error(`unsupported file type '${file.name}'`)
}
} else if (id.match(/^[1-9][a-zA-Z0-9]{3,3}$/i)) {
// return // return
const cif = await getFromPdb(id) const cif = await getFromPdb(id)
model = (await trajectoryFromMmCIF(cif).run())[0] model = (await trajectoryFromMmCIF(cif).run())[0]
...@@ -225,19 +237,21 @@ async function getCurve(name: string, transforms: Mat4[], model: Model) { ...@@ -225,19 +237,21 @@ async function getCurve(name: string, transforms: Mat4[], model: Model) {
return getStructure(curveModel) return getStructure(curveModel)
} }
async function getIngredientStructure(ingredient: Ingredient, baseUrl: string) { async function getIngredientStructure(ingredient: Ingredient, baseUrl: string, ingredientFiles: IngredientFiles) {
const { name, source, results, nbCurve } = ingredient const { name, source, results, nbCurve } = ingredient
if (source.pdb === 'None') return
const file = ingredientFiles[source.pdb]
if (!file) {
// TODO can these be added to the library? // TODO can these be added to the library?
if (name === 'HIV1_CAhex_0_1_0') return if (name === 'HIV1_CAhex_0_1_0') return
if (name === 'HIV1_CAhexCyclophilA_0_1_0') return if (name === 'HIV1_CAhexCyclophilA_0_1_0') return
if (name === 'iLDL') return if (name === 'iLDL') return
if (name === 'peptides') return if (name === 'peptides') return
if (name === 'lypoglycane') return if (name === 'lypoglycane') return
}
if (source.pdb === 'None') return const model = await getModel(source.pdb || name, baseUrl, file)
const model = await getModel(source.pdb || name, baseUrl)
if (!model) return if (!model) return
if (nbCurve) { if (nbCurve) {
...@@ -248,13 +262,13 @@ async function getIngredientStructure(ingredient: Ingredient, baseUrl: string) { ...@@ -248,13 +262,13 @@ async function getIngredientStructure(ingredient: Ingredient, baseUrl: string) {
} }
} }
export function createStructureFromCellPack(packing: CellPacking, baseUrl: string) { export function createStructureFromCellPack(packing: CellPacking, baseUrl: string, ingredientFiles: IngredientFiles) {
return Task.create('Create Packing Structure', async ctx => { return Task.create('Create Packing Structure', async ctx => {
const { ingredients, name } = packing const { ingredients, name } = packing
const structures: Structure[] = [] const structures: Structure[] = []
for (const iName in ingredients) { for (const iName in ingredients) {
if (ctx.shouldUpdate) await ctx.update(iName) if (ctx.shouldUpdate) await ctx.update(iName)
const s = await getIngredientStructure(ingredients[iName], baseUrl) const s = await getIngredientStructure(ingredients[iName], baseUrl, ingredientFiles)
if (s) structures.push(s) if (s) structures.push(s)
} }
...@@ -345,7 +359,7 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat ...@@ -345,7 +359,7 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat
await handleHivRna({ runtime, fetch: plugin.fetch }, packings, params.baseUrl) await handleHivRna({ runtime, fetch: plugin.fetch }, packings, params.baseUrl)
for (let i = 0, il = packings.length; i < il; ++i) { for (let i = 0, il = packings.length; i < il; ++i) {
const p = { packing: i, baseUrl: params.baseUrl } const p = { packing: i, baseUrl: params.baseUrl, ingredientFiles: params.ingredients.files }
const packing = state.build().to(cellPackBuilder.ref).apply(StructureFromCellpack, p) const packing = state.build().to(cellPackBuilder.ref).apply(StructureFromCellpack, p)
await plugin.updateDataState(packing, { revertOnError: true }); await plugin.updateDataState(packing, { revertOnError: true });
...@@ -378,6 +392,9 @@ const LoadCellPackModelParams = { ...@@ -378,6 +392,9 @@ const LoadCellPackModelParams = {
'file': PD.File({ accept: 'id' }), 'file': PD.File({ accept: 'id' }),
}, { options: [['id', 'Id'], ['file', 'File']] }), }, { options: [['id', 'Id'], ['file', 'File']] }),
baseUrl: PD.Text(DefaultCellPackBaseUrl), baseUrl: PD.Text(DefaultCellPackBaseUrl),
ingredients : PD.Group({
files: PD.FileList({ accept: '.cif,.pdb' })
}, { isExpanded: true }),
preset: PD.Group({ preset: PD.Group({
traceOnly: PD.Boolean(false), traceOnly: PD.Boolean(false),
representation: PD.Select('gaussian-surface', PD.arrayToOptions(['spacefill', 'gaussian-surface', 'point', 'ellipsoid'])) representation: PD.Select('gaussian-surface', PD.arrayToOptions(['spacefill', 'gaussian-surface', 'point', 'ellipsoid']))
......
...@@ -9,6 +9,7 @@ import { ParamDefinition as PD } from '../../../../mol-util/param-definition'; ...@@ -9,6 +9,7 @@ import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
import { Task } from '../../../../mol-task'; import { Task } from '../../../../mol-task';
import { CellPack as _CellPack, Cell, CellPacking } from './data'; import { CellPack as _CellPack, Cell, CellPacking } from './data';
import { createStructureFromCellPack } from './model'; import { createStructureFromCellPack } from './model';
import { IngredientFiles } from './util';
export const DefaultCellPackBaseUrl = 'https://mesoscope.scripps.edu/data/cellPACK_data/cellPACK_database_1.1.0/' export const DefaultCellPackBaseUrl = 'https://mesoscope.scripps.edu/data/cellPACK_data/cellPACK_database_1.1.0/'
...@@ -53,20 +54,27 @@ const StructureFromCellpack = PluginStateTransform.BuiltIn({ ...@@ -53,20 +54,27 @@ const StructureFromCellpack = PluginStateTransform.BuiltIn({
if (!a) { if (!a) {
return { return {
packing: PD.Numeric(0, {}, { description: 'Packing Index' }), packing: PD.Numeric(0, {}, { description: 'Packing Index' }),
baseUrl: PD.Text(DefaultCellPackBaseUrl) baseUrl: PD.Text(DefaultCellPackBaseUrl),
ingredientFiles: PD.FileList({ accept: '.cif,.pdb' })
}; };
} }
const options = a.data.packings.map((d, i) => [i, d.name] as [number, string]) const options = a.data.packings.map((d, i) => [i, d.name] as [number, string])
return { return {
packing: PD.Select(0, options), packing: PD.Select(0, options),
baseUrl: PD.Text(DefaultCellPackBaseUrl) baseUrl: PD.Text(DefaultCellPackBaseUrl),
ingredientFiles: PD.FileList({ accept: '.cif,.pdb' })
} }
} }
})({ })({
apply({ a, params }) { apply({ a, params }) {
return Task.create('Structure from CellPack', async ctx => { return Task.create('Structure from CellPack', async ctx => {
const packing = a.data.packings[params.packing] const packing = a.data.packings[params.packing]
const structure = await createStructureFromCellPack(packing, params.baseUrl).runInContext(ctx) const ingredientFiles: IngredientFiles = {}
for (let i = 0, il = params.ingredientFiles.length; i < il; ++i) {
const file = params.ingredientFiles.item(i)
if (file) ingredientFiles[file.name] = file
}
const structure = await createStructureFromCellPack(packing, params.baseUrl, ingredientFiles).runInContext(ctx)
return new PSO.Molecule.Structure(structure, { label: packing.name }) return new PSO.Molecule.Structure(structure, { label: packing.name })
}); });
} }
......
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
import { CIF } from '../../../../mol-io/reader/cif' import { CIF } from '../../../../mol-io/reader/cif'
import { parsePDB } from '../../../../mol-io/reader/pdb/parser'; import { parsePDB } from '../../../../mol-io/reader/pdb/parser';
async function parseCif(data: string|Uint8Array) { export async function parseCif(data: string|Uint8Array) {
const comp = CIF.parse(data); const comp = CIF.parse(data);
const parsed = await comp.run(); const parsed = await comp.run();
if (parsed.isError) throw parsed; if (parsed.isError) throw parsed;
return parsed.result; return parsed.result;
} }
async function parsePDBfile(data: string, id: string) { export async function parsePDBfile(data: string, id: string) {
const comp = parsePDB(data, id); const comp = parsePDB(data, id);
const parsed = await comp.run(); const parsed = await comp.run();
if (parsed.isError) throw parsed; if (parsed.isError) throw parsed;
...@@ -46,3 +46,5 @@ export async function getFromCellPackDB(id: string, baseUrl: string) { ...@@ -46,3 +46,5 @@ export async function getFromCellPackDB(id: string, baseUrl: string) {
const parsed = await downloadPDB(getCellPackDataUrl(id, baseUrl), name); const parsed = await downloadPDB(getCellPackDataUrl(id, baseUrl), name);
return parsed; return parsed;
} }
export type IngredientFiles = { [name: string]: File }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment