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

wip, DscifProvider

parent 171cda89
No related branches found
No related tags found
No related merge requests found
......@@ -6,7 +6,7 @@
*/
import { PluginContext } from 'mol-plugin/context';
import { StateTree, Transformer, StateObject } from 'mol-state';
import { StateTree, Transformer, StateObject, State } from 'mol-state';
import { StateAction } from 'mol-state/action';
import { StateSelection } from 'mol-state/state/selection';
import { StateTreeBuilder } from 'mol-state/tree/builder';
......@@ -14,9 +14,11 @@ import { ParamDefinition as PD } from 'mol-util/param-definition';
import { PluginStateObject } from '../objects';
import { StateTransforms } from '../transforms';
import { Download } from '../transforms/data';
import { StructureRepresentation3DHelpers } from '../transforms/representation';
import { StructureRepresentation3DHelpers, VolumeRepresentation3DHelpers } from '../transforms/representation';
import { getFileInfo, FileInfo } from 'mol-util/file-info';
import { Task } from 'mol-task';
import { ColorNames } from 'mol-util/color/tables';
import { VolumeIsoValue } from 'mol-model/volume';
// TODO: "structure/volume parser provider"
......@@ -171,8 +173,8 @@ export const UpdateTrajectory = StateAction.build({
//
export class DataFormatRegistry<D extends PluginStateObject.Data.Binary | PluginStateObject.Data.String, M extends StateObject> {
private _list: { name: string, provider: DataFormatProvider<D, M> }[] = []
private _map = new Map<string, DataFormatProvider<D, M>>()
private _list: { name: string, provider: DataFormatProvider<D> }[] = []
private _map = new Map<string, DataFormatProvider<D>>()
get default() { return this._list[0]; }
get types(): [string, string][] {
......@@ -185,7 +187,7 @@ export class DataFormatRegistry<D extends PluginStateObject.Data.Binary | Plugin
this.add('dscif', DscifProvider)
};
add(name: string, provider: DataFormatProvider<D, M>) {
add(name: string, provider: DataFormatProvider<D>) {
this._list.push({ name, provider })
this._map.set(name, provider)
}
......@@ -203,7 +205,7 @@ export class DataFormatRegistry<D extends PluginStateObject.Data.Binary | Plugin
throw new Error('no compatible data format provider available')
}
get(name: string): DataFormatProvider<D, M> {
get(name: string): DataFormatProvider<D> {
if (this._map.has(name)) {
return this._map.get(name)!
} else {
......@@ -216,53 +218,82 @@ export class DataFormatRegistry<D extends PluginStateObject.Data.Binary | Plugin
}
}
interface DataFormatProvider<D extends PluginStateObject.Data.Binary | PluginStateObject.Data.String, M extends StateObject> {
interface DataFormatProvider<D extends PluginStateObject.Data.Binary | PluginStateObject.Data.String> {
label: string
description: string
fileExtensions: string[]
isApplicable(info: FileInfo, data: string | Uint8Array): boolean
getDefaultBuilder(b: StateTreeBuilder.To<D>): StateTreeBuilder.To<M>
getDefaultBuilder(ctx: PluginContext, data: StateTreeBuilder.To<D>, state?: State): Task<void>
}
const Ccp4Provider: DataFormatProvider<any, any> = {
const Ccp4Provider: DataFormatProvider<any> = {
label: 'CCP4/MRC/BRIX',
description: 'CCP4/MRC/BRIX',
fileExtensions: ['ccp4', 'mrc', 'map'],
isApplicable: (info: FileInfo, data: Uint8Array) => {
return info.ext === 'ccp4' || info.ext === 'mrc' || info.ext === 'map'
},
getDefaultBuilder: (b: StateTreeBuilder.To<PluginStateObject.Data.Binary>) => {
return b.apply(StateTransforms.Data.ParseCcp4)
.apply(StateTransforms.Model.VolumeFromCcp4)
.apply(StateTransforms.Representation.VolumeRepresentation3D)
getDefaultBuilder: (ctx: PluginContext, data: StateTreeBuilder.To<PluginStateObject.Data.Binary>, state: State) => {
return Task.create('CCP4/MRC/BRIX default builder', async taskCtx => {
const tree = data.apply(StateTransforms.Data.ParseCcp4)
.apply(StateTransforms.Model.VolumeFromCcp4)
.apply(StateTransforms.Representation.VolumeRepresentation3D)
await state.updateTree(tree).runInContext(taskCtx)
})
}
}
const Dsn6Provider: DataFormatProvider<any, any> = {
const Dsn6Provider: DataFormatProvider<any> = {
label: 'DSN6/BRIX',
description: 'DSN6/BRIX',
fileExtensions: ['dsn6', 'brix'],
isApplicable: (info: FileInfo, data: Uint8Array) => {
return info.ext === 'dsn6' || info.ext === 'brix'
},
getDefaultBuilder: (b: StateTreeBuilder.To<PluginStateObject.Data.Binary>) => {
return b.apply(StateTransforms.Data.ParseDsn6)
.apply(StateTransforms.Model.VolumeFromDsn6)
.apply(StateTransforms.Representation.VolumeRepresentation3D)
getDefaultBuilder: (ctx: PluginContext, data: StateTreeBuilder.To<PluginStateObject.Data.Binary>, state: State) => {
return Task.create('DSN6/BRIX default builder', async taskCtx => {
const tree = data.apply(StateTransforms.Data.ParseDsn6)
.apply(StateTransforms.Model.VolumeFromDsn6)
.apply(StateTransforms.Representation.VolumeRepresentation3D)
await state.updateTree(tree).runInContext(taskCtx)
})
}
}
const DscifProvider: DataFormatProvider<any, any> = {
const DscifProvider: DataFormatProvider<any> = {
label: 'DensityServer CIF',
description: 'DensityServer CIF',
fileExtensions: ['cif'],
isApplicable: (info: FileInfo, data: Uint8Array) => {
return info.ext === 'cif'
},
getDefaultBuilder: (b: StateTreeBuilder.To<PluginStateObject.Data.Binary>) => {
return b.apply(StateTransforms.Data.ParseCif, { })
.apply(StateTransforms.Model.VolumeFromDensityServerCif)
.apply(StateTransforms.Representation.VolumeRepresentation3D)
getDefaultBuilder: (ctx: PluginContext, data: StateTreeBuilder.To<PluginStateObject.Data.Binary>, state: State) => {
return Task.create('DensityServer CIF default builder', async taskCtx => {
const cifBuilder = data.apply(StateTransforms.Data.ParseCif)
const cifStateObject = await state.updateTree(cifBuilder).runInContext(taskCtx)
const b = state.build().to(cifBuilder.ref);
const blocks = cifStateObject.data.blocks.slice(1); // zero block contains query meta-data
let tree: StateTreeBuilder.To<any>
if (blocks.length === 1) {
tree = b
.apply(StateTransforms.Model.VolumeFromDensityServerCif, { blockHeader: blocks[0].header })
.apply(StateTransforms.Representation.VolumeRepresentation3D, VolumeRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'isosurface', { isoValue: VolumeIsoValue.relative(1.5), alpha: 0.3 }))
} else if (blocks.length === 2) {
tree = b
.apply(StateTransforms.Model.VolumeFromDensityServerCif, { blockHeader: blocks[0].header })
.apply(StateTransforms.Representation.VolumeRepresentation3D, VolumeRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'isosurface', { isoValue: VolumeIsoValue.relative(1.5), alpha: 0.3 }, 'uniform', { value: ColorNames.blue }))
const vol = tree.to(cifBuilder.ref)
.apply(StateTransforms.Model.VolumeFromDensityServerCif, { blockHeader: blocks[1].header })
const posParams = VolumeRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'isosurface', { isoValue: VolumeIsoValue.relative(3), alpha: 0.3 }, 'uniform', { value: ColorNames.green })
tree = vol.apply(StateTransforms.Representation.VolumeRepresentation3D, posParams)
const negParams = VolumeRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'isosurface', { isoValue: VolumeIsoValue.relative(-3), alpha: 0.3 }, 'uniform', { value: ColorNames.red })
tree = tree.to(vol.ref).apply(StateTransforms.Representation.VolumeRepresentation3D, negParams)
} else {
throw new Error('unknown number of blocks')
}
await state.updateTree(tree).runInContext(taskCtx);
})
}
}
......@@ -302,9 +333,8 @@ export const OpenVolume = StateAction.build({
const provider = params.format === 'auto' ? ctx.dataFormat.registry.auto(getFileInfo(params.file), dataStateObject) : ctx.dataFormat.registry.get(params.format)
const b = state.build().to(data.ref);
const tree = provider.getDefaultBuilder(b).getTree()
// need to await the 2nd update the so that the enclosing Task finishes after the update is done.
await state.updateTree(tree).runInContext(taskCtx);
await provider.getDefaultBuilder(ctx, b, state).runInContext(taskCtx)
}));
export { DownloadDensity };
......@@ -341,7 +371,7 @@ const DownloadDensity = StateAction.build({
})(({ params, state }, ctx: PluginContext) => Task.create('Download Density', async taskCtx => {
const src = params.source;
let downloadParams: Transformer.Params<Download>;
let provider: DataFormatProvider<any, any>
let provider: DataFormatProvider<any>
switch (src.name) {
case 'url':
......@@ -386,6 +416,5 @@ const DownloadDensity = StateAction.build({
}
const b = state.build().to(data.ref);
const tree = provider.getDefaultBuilder(b).getTree()
await state.updateTree(tree).runInContext(taskCtx);
await provider.getDefaultBuilder(ctx, b, state).runInContext(taskCtx)
}));
\ No newline at end of file
......@@ -19,6 +19,8 @@ import { ExplodeRepresentation3D } from 'mol-plugin/behavior/dynamic/representat
import { VolumeData } from 'mol-model/volume';
import { BuiltInVolumeRepresentationsName } from 'mol-repr/volume/registry';
import { VolumeParams } from 'mol-repr/volume/representation';
import { BuiltInColorThemeName, ColorTheme } from 'mol-theme/color';
import { BuiltInSizeThemeName, SizeTheme } from 'mol-theme/size';
export namespace StructureRepresentation3DHelpers {
export function getDefaultParams(ctx: PluginContext, name: BuiltInStructureRepresentationsName, structure: Structure, structureParams?: Partial<PD.Values<StructureParams>>): Transformer.Params<StructureRepresentation3D> {
......@@ -162,14 +164,14 @@ export namespace VolumeRepresentation3DHelpers {
})
}
export function getDefaultParamsStatic(ctx: PluginContext, name: BuiltInVolumeRepresentationsName, volumeParams?: Partial<PD.Values<VolumeParams>>): Transformer.Params<VolumeRepresentation3D> {
export function getDefaultParamsStatic(ctx: PluginContext, name: BuiltInVolumeRepresentationsName, volumeParams?: Partial<PD.Values<PD.Params>>, colorName?: BuiltInColorThemeName, colorParams?: Partial<ColorTheme.Props>, sizeName?: BuiltInSizeThemeName, sizeParams?: Partial<SizeTheme.Props>): Transformer.Params<VolumeRepresentation3D> {
const type = ctx.volumeRepresentation.registry.get(name);
const colorParams = ctx.volumeRepresentation.themeCtx.colorThemeRegistry.get(type.defaultColorTheme).defaultValues;
const sizeParams = ctx.volumeRepresentation.themeCtx.sizeThemeRegistry.get(type.defaultSizeTheme).defaultValues
const colorType = ctx.volumeRepresentation.themeCtx.colorThemeRegistry.get(colorName || type.defaultColorTheme);
const sizeType = ctx.volumeRepresentation.themeCtx.sizeThemeRegistry.get(sizeName || type.defaultSizeTheme);
return ({
type: { name, params: volumeParams ? { ...type.defaultValues, ...volumeParams } : type.defaultValues },
colorTheme: { name: type.defaultColorTheme, params: colorParams },
sizeTheme: { name: type.defaultSizeTheme, params: sizeParams }
colorTheme: { name: type.defaultColorTheme, params: colorParams ? { ...colorType.defaultValues, ...colorParams } : colorType.defaultValues },
sizeTheme: { name: type.defaultSizeTheme, params: sizeParams ? { ...sizeType.defaultValues, ...sizeParams } : sizeType.defaultValues }
})
}
}
......@@ -234,7 +236,6 @@ const VolumeRepresentation3D = PluginStateTransform.BuiltIn({
repr.setTheme(createTheme(plugin.volumeRepresentation.themeCtx, { volume: a.data }, params))
// TODO set initial state, repr.setState({})
// TODO include isoValue in the label where available
console.log(params.type.params);
await repr.createOrUpdate(props, a.data).runInContext(ctx);
return new SO.Volume.Representation3D(repr, { label: provider.label });
});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment