diff --git a/src/apps/canvas/app.ts b/src/apps/canvas/app.ts index 862b01b07cb334e986aa927e78d00197ecb2618f..f72add32be2129c55e97d5824848a92a4dd1b251 100644 --- a/src/apps/canvas/app.ts +++ b/src/apps/canvas/app.ts @@ -5,7 +5,7 @@ */ import Viewer from 'mol-view/viewer'; -import { getCifFromUrl, getModelsFromMmcif, getCifFromFile, getCcp4FromUrl, getVolumeFromCcp4, getCcp4FromFile } from './util'; +import { getCifFromUrl, getModelsFromMmcif, getCifFromFile, getCcp4FromUrl, getVolumeFromCcp4, getCcp4FromFile, getVolumeFromVolcif } from './util'; import { StructureView } from './structure-view'; import { BehaviorSubject } from 'rxjs'; import { CifBlock } from 'mol-io/reader/cif'; @@ -71,14 +71,14 @@ export class App { if (this.structureView) this.structureView.destroy(); const url = idOrUrl.length <= 4 ? `https://files.rcsb.org/download/${idOrUrl}.cif` : idOrUrl; const cif = await this.runTask(getCifFromUrl(url, options ? !!options.binary : false), 'Load mmCIF from URL') - this.loadMmcif(cif, options ? options.assemblyId : void 0) + this.loadMmcif(cif.blocks[0], options ? options.assemblyId : void 0) } async loadMmcifFile(file: File) { if (this.structureView) this.structureView.destroy(); const binary = /\.bcif$/.test(file.name); const cif = await this.runTask(getCifFromFile(file, binary), 'Load mmCIF from file') - this.loadMmcif(cif) + this.loadMmcif(cif.blocks[0]) } // @@ -100,4 +100,25 @@ export class App { const ccp4 = await this.runTask(getCcp4FromUrl(url), 'Load CCP4 from URL') this.loadCcp4(ccp4) } + + // + + async loadVolcif(cif: CifBlock) { + const volume = await this.runTask(getVolumeFromVolcif(cif), 'Get Volume') + this.volumeView = await this.runTask(VolumeView(this, this.viewer, volume), 'Init volume view') + this.volumeLoaded.next(this.volumeView) + } + + async loadVolcifFile(file: File) { + if (this.volumeView) this.volumeView.destroy(); + const binary = /\.bcif$/.test(file.name); + const cif = await this.runTask(getCifFromFile(file, binary), 'Load volCif from file') + this.loadVolcif(cif.blocks[1]) + } + + async loadVolcifUrl(url: string, binary?: boolean) { + if (this.volumeView) this.volumeView.destroy(); + const cif = await this.runTask(getCifFromUrl(url, binary), 'Load volCif from URL') + this.loadVolcif(cif.blocks[1]) + } } \ No newline at end of file diff --git a/src/apps/canvas/component/app.tsx b/src/apps/canvas/component/app.tsx index 7f2d390928f589244c393de613d88f7209456de3..5d5c388507d29024e39d6c2a2fdd098f792c316a 100644 --- a/src/apps/canvas/component/app.tsx +++ b/src/apps/canvas/component/app.tsx @@ -20,14 +20,16 @@ export interface AppProps { export interface AppState { structureView: StructureView | null, volumeView: VolumeView | null, - binary: boolean + mmcifBinary: boolean, + volcifBinary: boolean } export class AppComponent extends React.Component<AppProps, AppState> { state = { structureView: this.props.app.structureView, volumeView: this.props.app.volumeView, - binary: false + mmcifBinary: false, + volcifBinary: true } componentDidMount() { @@ -50,7 +52,7 @@ export class AppComponent extends React.Component<AppProps, AppState> { <div style={{width: '330px', paddingLeft: '10px', paddingRight: '10px', right: '0px', height: '100%', position: 'absolute', overflow: 'auto'}}> <div style={{marginTop: '10px'}}> <span>Load PDB ID or URL</span> - <input type='checkbox' checked={this.state.binary} onChange={e => this.setState({ binary: e.target.checked })} /> Binary<br /> + <input type='checkbox' checked={this.state.mmcifBinary} onChange={e => this.setState({ mmcifBinary: e.target.checked })} /> Binary<br /> <input style={{ width: '100%' }} type='text' @@ -58,7 +60,7 @@ export class AppComponent extends React.Component<AppProps, AppState> { if (e.keyCode === 13) { const value = e.currentTarget.value.trim() if (value) { - this.props.app.loadPdbIdOrMmcifUrl(value, { binary: this.state.binary }) + this.props.app.loadPdbIdOrMmcifUrl(value, { binary: this.state.mmcifBinary }) } } }} @@ -84,6 +86,22 @@ export class AppComponent extends React.Component<AppProps, AppState> { }} /> </div> + <div style={{marginTop: '10px'}}> + <span>Load DensityServer URL</span> + <input type='checkbox' checked={this.state.volcifBinary} onChange={e => this.setState({ volcifBinary: e.target.checked })} /> Binary<br /> + <input + style={{ width: '100%' }} + type='text' + onKeyDown={e => { + if (e.keyCode === 13) { + const value = e.currentTarget.value.trim() + if (value) { + this.props.app.loadVolcifUrl(value, this.state.volcifBinary) + } + } + }} + /> + </div> <div> <span>Load example </span> <select diff --git a/src/apps/canvas/index.ts b/src/apps/canvas/index.ts index 45b617685d07779fb6dc3fac469d0117e0396319..c848f987e08498d97caee37b5c533be760e3c230 100644 --- a/src/apps/canvas/index.ts +++ b/src/apps/canvas/index.ts @@ -23,4 +23,13 @@ const assemblyId = urlQueryParameter('assembly') const pdbId = urlQueryParameter('pdb') if (pdbId) app.loadPdbIdOrMmcifUrl(pdbId, { assemblyId }) -// app.loadCcp4Url('http://localhost:8091/ngl/data/betaGal.mrc') \ No newline at end of file +// app.loadCcp4Url('http://localhost:8091/ngl/data/betaGal.mrc') + +// app.loadPdbIdOrMmcifUrl('3pqr') +// app.loadVolCifUrl('https://webchem.ncbr.muni.cz/DensityServer/x-ray/3pqr/cell?space=fractional', true) + +// app.loadPdbIdOrMmcifUrl('5ire') +// app.loadVolcifUrl('https://webchem.ncbr.muni.cz/DensityServer/em/emd-8116/cell?space=cartesian&detail=6', true) + +// app.loadPdbIdOrMmcifUrl('5gag') +// app.loadVolcifUrl('https://webchem.ncbr.muni.cz/DensityServer/em/emd-8003/cell?detail=3', true) \ No newline at end of file diff --git a/src/apps/canvas/structure-view.ts b/src/apps/canvas/structure-view.ts index 3b4658514a82a258c73edc8f7f15dacfef6b3dd1..dce28b08646960608f900b5a4ec2ba84edef3886 100644 --- a/src/apps/canvas/structure-view.ts +++ b/src/apps/canvas/structure-view.ts @@ -70,7 +70,7 @@ export async function StructureView(app: App, viewer: Viewer, models: ReadonlyAr const active: { [k: string]: boolean } = { cartoon: true, point: false, - surface: true, + surface: false, ballAndStick: false, carbohydrate: false, spacefill: false, diff --git a/src/apps/canvas/util.ts b/src/apps/canvas/util.ts index dcbc58697bd99d9897066ba0cd1c120bb9c6b27d..27581f68cbc2fdd956de7d61e04a65da7c21a92c 100644 --- a/src/apps/canvas/util.ts +++ b/src/apps/canvas/util.ts @@ -11,6 +11,7 @@ import CCP4 from 'mol-io/reader/ccp4/parser' import { FileHandle } from 'mol-io/common/file-handle'; import { Ccp4File } from 'mol-io/reader/ccp4/schema'; import { volumeFromCcp4 } from 'mol-model/volume/formats/ccp4'; +import { parseDensityServerData } from 'mol-model/volume'; // import { parse as parseObj } from 'mol-io/reader/obj/parser' // export async function getObjFromUrl(url: string) { @@ -25,7 +26,7 @@ export async function getCifFromData(data: string | Uint8Array) { const comp = CIF.parse(data) const parsed = await comp.run() if (parsed.isError) throw parsed - return parsed.result.blocks[0] + return parsed.result } export async function getCifFromUrl(url: string, binary = false) { @@ -68,4 +69,10 @@ export async function getCcp4FromData(data: Uint8Array) { export async function getVolumeFromCcp4(ccp4: Ccp4File) { return await volumeFromCcp4(ccp4).run() +} + +// + +export async function getVolumeFromVolcif(cif: CifBlock) { + return await parseDensityServerData(CIF.schema.densityServer(cif)).run() } \ No newline at end of file