Browse Source

removed canvas app

Alexander Rose 6 years ago
parent
commit
813fd2a5f7

+ 0 - 2
package.json

@@ -19,8 +19,6 @@
     "test": "jest",
     "build-viewer": "webpack build/node_modules/apps/viewer/index.js --mode development -o build/viewer/index.js",
     "watch-viewer": "webpack build/node_modules/apps/viewer/index.js -w --mode development -o build/viewer/index.js",
-    "build-canvas": "webpack build/node_modules/apps/canvas/index.js --mode development -o build/canvas/index.js",
-    "watch-canvas": "webpack build/node_modules/apps/canvas/index.js -w --mode development -o build/canvas/index.js",
     "build-ms-query": "webpack build/node_modules/apps/model-server-query/index.js --mode development -o build/model-server-query/index.js",
     "watch-ms-query": "webpack build/node_modules/apps/model-server-query/index.js -w --mode development -o build/model-server-query/index.js",
     "model-server": "node build/node_modules/servers/model/server.js",

+ 0 - 146
src/apps/canvas/app.ts

@@ -1,146 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { Canvas3D } from 'mol-canvas3d/canvas3d';
-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';
-import { VolumeView } from './volume-view';
-import { Ccp4File } from 'mol-io/reader/ccp4/schema';
-import { Progress } from 'mol-task';
-import { ColorTheme } from 'mol-theme/color';
-import { SizeTheme } from 'mol-theme/size';
-import { StructureRepresentationRegistry } from 'mol-repr/structure/registry';
-import { VolumeRepresentationRegistry } from 'mol-repr/volume/registry';
-
-export class App {
-    canvas3d: Canvas3D
-    container: HTMLDivElement | null = null;
-    canvas: HTMLCanvasElement | null = null;
-    structureView: StructureView | null = null;
-    volumeView: VolumeView | null = null;
-
-    structureLoaded: BehaviorSubject<StructureView | null> = new BehaviorSubject<StructureView | null>(null)
-    volumeLoaded: BehaviorSubject<VolumeView | null> = new BehaviorSubject<VolumeView | null>(null)
-
-    colorThemeRegistry = new ColorTheme.Registry()
-    sizeThemeRegistry = new SizeTheme.Registry()
-    structureRepresentationRegistry = new StructureRepresentationRegistry()
-    volumeRepresentationRegistry = new VolumeRepresentationRegistry()
-
-    initViewer(_canvas: HTMLCanvasElement, _container: HTMLDivElement) {
-        this.canvas = _canvas
-        this.container = _container
-
-        try {
-            this.canvas3d = Canvas3D.create(this.canvas, this.container)
-            this.canvas3d.animate()
-            return true
-        } catch (e) {
-            console.error(e)
-            return false
-        }
-    }
-
-    setStatus(msg: string) {
-
-    }
-
-    private taskCount = 0
-    taskCountChanged = new BehaviorSubject({ count: 0, info: '' })
-
-    private changeTaskCount(delta: number, info = '') {
-        this.taskCount += delta
-        this.taskCountChanged.next({ count: this.taskCount, info })
-    }
-
-    async runTask<T>(promise: Promise<T>, info: string) {
-        this.changeTaskCount(1, info)
-        let result: T
-        try {
-            result = await promise
-        } finally {
-            this.changeTaskCount(-1)
-        }
-        return result
-    }
-
-    log(progress: Progress) {
-        console.log(Progress.format(progress))
-    }
-
-    get reprCtx () {
-        return {
-            webgl: this.canvas3d.webgl,
-            colorThemeRegistry: this.colorThemeRegistry,
-            sizeThemeRegistry: this.sizeThemeRegistry
-        }
-    }
-
-    //
-
-    async loadMmcif(cif: CifBlock, assemblyId?: string) {
-        const models = await this.runTask(getModelsFromMmcif(cif), 'Build models')
-        this.structureView = await this.runTask(StructureView(this, this.canvas3d, models, { assemblyId }), 'Init structure view')
-        this.structureLoaded.next(this.structureView)
-    }
-
-    async loadPdbIdOrMmcifUrl(idOrUrl: string, options?: { assemblyId?: string, binary?: boolean }) {
-        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.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.blocks[0])
-    }
-
-    //
-
-    async loadCcp4(ccp4: Ccp4File) {
-        const volume = await this.runTask(getVolumeFromCcp4(ccp4), 'Get Volume')
-        this.volumeView = await this.runTask(VolumeView(this, this.canvas3d, volume), 'Init volume view')
-        this.volumeLoaded.next(this.volumeView)
-    }
-
-    async loadCcp4File(file: File) {
-        if (this.volumeView) this.volumeView.destroy();
-        const ccp4 = await this.runTask(getCcp4FromFile(file), 'Load CCP4 from file')
-        this.loadCcp4(ccp4)
-    }
-
-    async loadCcp4Url(url: string) {
-        if (this.volumeView) this.volumeView.destroy();
-        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.canvas3d, 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])
-    }
-}

+ 0 - 99
src/apps/canvas/assembly-symmetry.ts

@@ -1,99 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { AssemblySymmetry } from 'mol-model-props/rcsb/symmetry';
-import { Table } from 'mol-data/db';
-import { Color, ColorScale } from 'mol-util/color';
-import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
-import { Tensor } from 'mol-math/linear-algebra';
-import { addSphere } from 'mol-geo/geometry/mesh/builder/sphere';
-import { addCylinder } from 'mol-geo/geometry/mesh/builder/cylinder';
-import { Shape } from 'mol-model/shape';
-import { ColorTheme } from 'mol-theme/color';
-import { Location } from 'mol-model/location';
-import { StructureElement, Unit, StructureProperties } from 'mol-model/structure';
-
-export function getAxesShape(symmetryId: number, assemblySymmetry: AssemblySymmetry) {
-    const s = assemblySymmetry.db.rcsb_assembly_symmetry
-    const symmetry = Table.pickRow(s, i => s.id.value(i) === symmetryId)
-    if (!symmetry) return
-
-    const axes = assemblySymmetry.getAxes(symmetryId)
-    if (!axes._rowCount) return
-
-    const vectorSpace = AssemblySymmetry.Schema.rcsb_assembly_symmetry_axis.start.space;
-
-    const colors: Color[] = []
-    const labels: string[] = []
-
-    const radius = 0.4
-    const cylinderProps = { radiusTop: radius, radiusBottom: radius }
-    const meshBuilder = MeshBuilder.create(256, 128)
-
-    for (let i = 0, il = axes._rowCount; i < il; ++i) {
-        const start = Tensor.toVec3(vectorSpace, axes.start.value(i))
-        const end = Tensor.toVec3(vectorSpace, axes.end.value(i))
-        meshBuilder.setGroup(i)
-        addSphere(meshBuilder, start, radius, 2)
-        addSphere(meshBuilder, end, radius, 2)
-        addCylinder(meshBuilder, start, end, 1, cylinderProps)
-        colors.push(Color(0xCCEE11))
-        labels.push(`Axis ${i + 1} for ${symmetry.kind} ${symmetry.type.toLowerCase()} symmetry`)
-    }
-    const mesh = meshBuilder.getMesh()
-    const shape = Shape.create('Axes', mesh, colors, labels)
-    return shape
-}
-
-function getAsymId(unit: Unit): StructureElement.Property<string> {
-    switch (unit.kind) {
-        case Unit.Kind.Atomic:
-            return StructureProperties.chain.label_asym_id
-        case Unit.Kind.Spheres:
-        case Unit.Kind.Gaussians:
-            return StructureProperties.coarse.asym_id
-    }
-}
-
-function clusterMemberKey (asym_id: string, oper_list_ids: string[]) {
-    return `${asym_id}-${oper_list_ids.join('x')}`
-}
-
-export function getClusterColorTheme(symmetryId: number, assemblySymmetry: AssemblySymmetry): ColorTheme {
-    const DefaultColor = Color(0xCCCCCC)
-    const s = assemblySymmetry.db.rcsb_assembly_symmetry
-    const symmetry = Table.pickRow(s, i => s.id.value(i) === symmetryId)
-    if (!symmetry) return { granularity: 'uniform', color: () => DefaultColor, props: {} }
-
-    const clusters = assemblySymmetry.getClusters(symmetryId)
-    if (!clusters._rowCount) return { granularity: 'uniform', color: () => DefaultColor, props: {} }
-
-    const clusterByMember = new Map<string, number>()
-    for (let i = 0, il = clusters._rowCount; i < il; ++i) {
-        const clusterMembers = assemblySymmetry.getClusterMembers(clusters.id.value(i))
-        for (let j = 0, jl = clusterMembers._rowCount; j < jl; ++j) {
-            const asym_id = clusterMembers.asym_id.value(j)
-            const oper_list_ids = clusterMembers.pdbx_struct_oper_list_ids.value(j)
-            clusterByMember.set(clusterMemberKey(asym_id, oper_list_ids), i)
-        }
-    }
-    const scale = ColorScale.create({ domain: [ 0, clusters._rowCount - 1 ] })
-
-    return {
-        granularity: 'instance',
-        color: (location: Location): Color => {
-            if (StructureElement.isLocation(location)) {
-                const asym_id = getAsymId(location.unit)
-                const ns = location.unit.conformation.operator.name.split('-')
-                const oper_list_ids = ns.length === 2 ? ns[1].split('x') : []
-                const cluster = clusterByMember.get(clusterMemberKey(asym_id(location), oper_list_ids))
-                return cluster !== undefined ? scale.color(cluster) : DefaultColor
-            }
-            return DefaultColor
-        },
-        props: {}
-    }
-}

+ 0 - 130
src/apps/canvas/component/app.tsx

@@ -1,130 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-import { StructureView } from '../structure-view';
-import { App } from '../app';
-import { Viewport } from './viewport';
-import { StructureViewComponent } from './structure-view';
-import { Examples } from '../examples';
-import { VolumeViewComponent } from './volume-view';
-import { VolumeView } from '../volume-view';
-
-export interface AppProps {
-    app: App
-}
-
-export interface AppState {
-    structureView: StructureView | null,
-    volumeView: VolumeView | null,
-    mmcifBinary: boolean,
-    volcifBinary: boolean
-}
-
-export class AppComponent extends React.Component<AppProps, AppState> {
-    state = {
-        structureView: this.props.app.structureView,
-        volumeView: this.props.app.volumeView,
-        mmcifBinary: false,
-        volcifBinary: true
-    }
-
-    componentDidMount() {
-        this.props.app.structureLoaded.subscribe((structureView) => {
-            this.setState({ structureView: this.props.app.structureView })
-        })
-        this.props.app.volumeLoaded.subscribe((volumeView) => {
-            this.setState({ volumeView: this.props.app.volumeView })
-        })
-    }
-
-    render() {
-        const { structureView, volumeView } = this.state
-
-        return <div style={{width: '100%', height: '100%'}}>
-            <div style={{left: '0px', right: '350px', height: '100%', position: 'absolute'}}>
-                <Viewport app={this.props.app} />
-            </div>
-
-            <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>&nbsp;&nbsp;
-                    <input type='checkbox' checked={this.state.mmcifBinary} onChange={e => this.setState({ mmcifBinary: 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.loadPdbIdOrMmcifUrl(value, { binary: this.state.mmcifBinary })
-                                }
-                            }
-                        }}
-                    />
-                </div>
-                <div>
-                    <span>Load CIF file </span>
-                    <input
-                        accept='*.cif'
-                        type='file'
-                        onChange={e => {
-                            if (e.target.files) this.props.app.loadMmcifFile(e.target.files[0])
-                        }}
-                    />
-                </div>
-                <div>
-                    <span>Load CCP4/MRC file </span>
-                    <input
-                        accept='*.ccp4,*.mrc, *.map'
-                        type='file'
-                        onChange={e => {
-                            if (e.target.files) this.props.app.loadCcp4File(e.target.files[0])
-                        }}
-                    />
-                </div>
-                <div style={{marginTop: '10px'}}>
-                    <span>Load DensityServer URL</span>&nbsp;&nbsp;
-                    <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
-                        style={{width: '200px'}}
-                        onChange={e => {
-                            this.props.app.loadPdbIdOrMmcifUrl(e.target.value)
-                        }}
-                    >
-                        <option value=''></option>
-                        {Examples.map(({label, id, description}, i) => {
-                            return <option key={i} value={id}>{`${label ? label : id} - ${description}`}</option>
-                        })}
-                    </select>
-                </div>
-                <hr/>
-                <div style={{marginBottom: '10px'}}>
-                    {structureView ? <StructureViewComponent structureView={structureView} /> : ''}
-                </div>
-                <hr/>
-                <div style={{marginBottom: '10px'}}>
-                    {volumeView ? <VolumeViewComponent volumeView={volumeView} /> : ''}
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 68
src/apps/canvas/component/representation.tsx

@@ -1,68 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-import { Canvas3D } from 'mol-canvas3d/canvas3d';
-import { App } from '../app';
-import { ParamDefinition as PD } from 'mol-util/param-definition';
-import { Representation } from 'mol-repr/representation';
-import { ParametersComponent } from 'mol-app/component/parameters';
-
-export interface RepresentationComponentProps<P extends PD.Params> {
-    app: App
-    canvas3d: Canvas3D
-    repr: Representation<P>
-}
-
-export interface RepresentationComponentState {
-    label: string
-    reprParams: PD.Params
-    reprProps: Readonly<{}>
-}
-
-export class RepresentationComponent<P extends PD.Params> extends React.Component<RepresentationComponentProps<P>, RepresentationComponentState> {
-
-    private stateFromRepr(repr: Representation<P>) {
-        return {
-            label: repr.label,
-            reprParams: repr.params,
-            reprProps: repr.props
-        }
-    }
-
-    componentWillMount() {
-        this.setState(this.stateFromRepr(this.props.repr))
-    }
-
-    async onChange(k: string, v: any) {
-        await this.props.app.runTask(this.props.repr.createOrUpdate(this.props.app.reprCtx, { [k]: v }).run(
-            progress => this.props.app.log(progress)
-        ), 'Representation Update')
-        this.setState(this.stateFromRepr(this.props.repr))
-    }
-
-    render() {
-        const { label, reprParams, reprProps } = this.state
-        // let colorTheme: ColorTheme | undefined = undefined
-        // if ('colorTheme' in reprProps) {
-        //     colorTheme = ColorTheme(getColorThemeProps(reprProps))
-        // }
-
-        return <div>
-            <div>
-                <h4>{label}</h4>
-            </div>
-            <div>
-                <ParametersComponent
-                    params={reprParams}
-                    values={reprProps}
-                    onChange={(k, v) => this.onChange(k as string, v)}
-                />
-            </div>
-            {/* { colorTheme !== undefined ? <ColorThemeComponent colorTheme={colorTheme} /> : '' } */}
-        </div>;
-    }
-}

+ 0 - 190
src/apps/canvas/component/structure-view.tsx

@@ -1,190 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-import { StructureView } from '../structure-view';
-import { RepresentationComponent } from './representation';
-import { Representation } from 'mol-repr/representation';
-import { StructureRepresentation } from 'mol-repr/structure/representation';
-
-export interface StructureViewComponentProps {
-    structureView: StructureView
-}
-
-export interface StructureViewComponentState {
-    structureView: StructureView
-
-    label: string
-    modelId: number
-    modelIds: { id: number, label: string }[]
-    assemblyId: string
-    assemblyIds: { id: string, label: string }[]
-    symmetryFeatureId: number
-    symmetryFeatureIds: { id: number, label: string }[]
-
-    active: { [k: string]: boolean }
-    structureRepresentations: { [k: string]: StructureRepresentation<any> }
-}
-
-export class StructureViewComponent extends React.Component<StructureViewComponentProps, StructureViewComponentState> {
-    state = this.stateFromStructureView(this.props.structureView)
-
-    private stateFromStructureView(sv: StructureView) {
-        return {
-            structureView: sv,
-
-            label: sv.label,
-            structure: sv.structure,
-            modelId: sv.modelId,
-            modelIds: sv.getModelIds(),
-            assemblyId: sv.assemblyId,
-            assemblyIds: sv.getAssemblyIds(),
-            symmetryFeatureId: sv.symmetryFeatureId,
-            symmetryFeatureIds: sv.getSymmetryFeatureIds(),
-
-            active: sv.active,
-            structureRepresentations: sv.structureRepresentations
-        }
-    }
-
-    componentWillMount() {
-        this.setState(this.stateFromStructureView(this.props.structureView))
-    }
-
-    componentDidMount() {
-        const sv = this.props.structureView
-
-        this.props.structureView.updated.subscribe(() => this.setState({
-            symmetryFeatureIds: sv.getSymmetryFeatureIds(),
-            structureRepresentations: sv.structureRepresentations
-        }))
-    }
-
-    componentWillReceiveProps(nextProps: StructureViewComponentProps) {
-        if (nextProps.structureView !== this.props.structureView) {
-            this.setState(this.stateFromStructureView(nextProps.structureView))
-
-            nextProps.structureView.updated.subscribe(() => this.setState({
-                symmetryFeatureIds: nextProps.structureView.getSymmetryFeatureIds(),
-                structureRepresentations: nextProps.structureView.structureRepresentations
-            }))
-        }
-    }
-
-    async update(state: Partial<StructureViewComponentState>) {
-        const sv = this.state.structureView
-
-        if (state.modelId !== undefined) await sv.setModel(state.modelId)
-        if (state.assemblyId !== undefined) await sv.setAssembly(state.assemblyId)
-        if (state.symmetryFeatureId !== undefined) await sv.setSymmetryFeature(state.symmetryFeatureId)
-
-        this.setState(this.stateFromStructureView(sv))
-    }
-
-    render() {
-        const { structureView, label, modelIds, assemblyIds, symmetryFeatureIds, active, structureRepresentations } = this.state
-
-        const modelIdOptions = modelIds.map(m => {
-            return <option key={m.id} value={m.id}>{m.label}</option>
-        })
-        const assemblyIdOptions = assemblyIds.map(a => {
-            return <option key={a.id} value={a.id}>{a.label}</option>
-        })
-        const symmetryFeatureIdOptions = symmetryFeatureIds.map(f => {
-            return <option key={f.id} value={f.id}>{f.label}</option>
-        })
-
-        return <div>
-            <div>
-                <h2>{label}</h2>
-            </div>
-            <div>
-                <div>
-                    <span>Model </span>
-                    <select
-                        style={{width: '100px'}}
-                        value={this.state.modelId}
-                        onChange={(e) => {
-                            this.update({ modelId: parseInt(e.target.value) })
-                        }}
-                    >
-                        {modelIdOptions}
-                    </select>
-                    <span> </span>
-                    <input type='range'
-                        defaultValue={this.state.modelId.toString()}
-                        min={Math.min(...modelIds.map(m => m.id))}
-                        max={Math.max(...modelIds.map(m => m.id))}
-                        step='1'
-                        onInput={(e) => {
-                            this.update({ modelId: parseInt(e.currentTarget.value) })
-                        }}
-                    >
-                    </input>
-                </div>
-                <div>
-                    <span>Assembly </span>
-                    <select
-                        style={{width: '150px'}}
-                        value={this.state.assemblyId}
-                        onChange={(e) => {
-                            this.update({ assemblyId: e.target.value })
-                        }}
-                    >
-                        {assemblyIdOptions}
-                    </select>
-                </div>
-                <div>
-                    <span>Symmetry Feature </span>
-                    <select
-                        style={{width: '150px'}}
-                        value={this.state.symmetryFeatureId}
-                        onChange={(e) => {
-                            this.update({ symmetryFeatureId: parseInt(e.target.value) })
-                        }}
-                    >
-                        {symmetryFeatureIdOptions}
-                    </select>
-                </div>
-                <div>
-                    <h4>Active</h4>
-                    { Object.keys(active).map((k, i) => {
-                        return <div key={i}>
-                            <input
-                                type='checkbox'
-                                checked={active[k]}
-                                onChange={(e) => {
-                                    const sv = structureView
-                                    if (k === 'symmetryAxes') {
-                                        sv.setSymmetryAxes(e.target.checked)
-                                    } else if (Object.keys(sv.structureRepresentations).includes(k)) {
-                                        sv.setStructureRepresentation(k, e.target.checked)
-                                    }
-                                }}
-                            /> {k}
-                        </div>
-                    } ) }
-                </div>
-                <div>
-                    <h3>Structure Representations</h3>
-                    { Object.keys(structureRepresentations).map((k, i) => {
-                        if (active[k]) {
-                            return <div key={i}>
-                                <RepresentationComponent
-                                    repr={structureRepresentations[k] as Representation<any>}
-                                    canvas3d={structureView.canvas3d}
-                                    app={structureView.app}
-                                />
-                            </div>
-                        } else {
-                            return ''
-                        }
-                    } ) }
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 187
src/apps/canvas/component/viewport.tsx

@@ -1,187 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-import { App } from '../app';
-import { MarkerAction } from 'mol-geo/geometry/marker-data';
-import { EmptyLoci, Loci, areLociEqual } from 'mol-model/loci';
-import { labelFirst } from 'mol-theme/label';
-import { ButtonsType } from 'mol-util/input/input-observer';
-import { throttleTime } from 'rxjs/operators'
-import { Camera } from 'mol-canvas3d/camera';
-import { ColorParamComponent } from 'mol-app/component/parameter/color';
-import { Color } from 'mol-util/color';
-import { ParamDefinition as PD } from 'mol-util/param-definition'
-
-interface ViewportProps {
-    app: App
-}
-
-interface ViewportState {
-    noWebGl: boolean
-    pickingInfo: string
-    taskInfo: string
-    cameraMode: Camera.Mode
-    backgroundColor: Color
-}
-
-const BackgroundColorParam = PD.Color(Color(0x000000), { label: 'Background Color' })
-
-export class Viewport extends React.Component<ViewportProps, ViewportState> {
-    private container: HTMLDivElement | null = null;
-    private canvas: HTMLCanvasElement | null = null;
-
-    state: ViewportState = {
-        noWebGl: false,
-        pickingInfo: '',
-        taskInfo: '',
-        cameraMode: 'perspective',
-        backgroundColor: Color(0x000000)
-    };
-
-    handleResize() {
-        this.props.app.canvas3d.handleResize()
-    }
-
-    componentDidMount() {
-        if (!this.canvas || !this.container || !this.props.app.initViewer(this.canvas, this.container)) {
-            this.setState({ noWebGl: true });
-        }
-        this.handleResize()
-
-        this.setState({
-            cameraMode: this.props.app.canvas3d.props.cameraMode,
-            backgroundColor: this.props.app.canvas3d.props.backgroundColor
-        })
-
-        const canvas3d = this.props.app.canvas3d
-
-        canvas3d.input.resize.subscribe(() => this.handleResize())
-
-        let prevHighlightLoci: Loci = EmptyLoci
-        // TODO can the 'only ever have one extra element in the queue' functionality be done with rxjs?
-        let highlightQueueLength = 0
-        canvas3d.input.move.pipe(throttleTime(50)).subscribe(async ({x, y, inside, buttons}) => {
-            if (!inside || buttons || highlightQueueLength > 2) return
-            ++highlightQueueLength
-            const p = await canvas3d.identify(x, y)
-            --highlightQueueLength
-            if (p) {
-                const { loci } = canvas3d.getLoci(p)
-
-                if (!areLociEqual(loci, prevHighlightLoci)) {
-                    canvas3d.mark(prevHighlightLoci, MarkerAction.RemoveHighlight)
-                    canvas3d.mark(loci, MarkerAction.Highlight)
-                    prevHighlightLoci = loci
-
-                    const label = labelFirst(loci)
-                    const pickingInfo = `${label}`
-                    this.setState({ pickingInfo })
-                }
-            }
-        })
-
-        canvas3d.input.click.subscribe(async ({x, y, buttons}) => {
-            if (buttons !== ButtonsType.Flag.Primary) return
-            const p = await canvas3d.identify(x, y)
-            if (p) {
-                const { loci } = canvas3d.getLoci(p)
-                canvas3d.mark(loci, MarkerAction.Toggle)
-            }
-        })
-
-        this.props.app.taskCountChanged.subscribe(({ count, info }) => {
-            this.setState({ taskInfo: count > 0 ? info : '' })
-        })
-    }
-
-    componentWillUnmount() {
-        if (super.componentWillUnmount) super.componentWillUnmount();
-        // TODO viewer cleanup
-    }
-
-    renderMissing() {
-        return <div>
-            <div>
-                <p><b>WebGL does not seem to be available.</b></p>
-                <p>This can be caused by an outdated browser, graphics card driver issue, or bad weather. Sometimes, just restarting the browser helps.</p>
-                <p>For a list of supported browsers, refer to <a href='http://caniuse.com/#feat=webgl' target='_blank'>http://caniuse.com/#feat=webgl</a>.</p>
-            </div>
-        </div>
-    }
-
-    render() {
-        if (this.state.noWebGl) return this.renderMissing();
-
-        return <div style={{ backgroundColor: 'rgb(0, 0, 0)', width: '100%', height: '100%'}}>
-            <div ref={elm => this.container = elm} style={{width: '100%', height: '100%'}}>
-                <canvas ref={elm => this.canvas = elm}></canvas>
-            </div>
-            <div
-                style={{
-                    position: 'absolute',
-                    top: 10,
-                    left: 10,
-                    padding: 10,
-                    color: 'lightgrey',
-                    background: 'rgba(0, 0, 0, 0.2)'
-                }}
-            >
-                {this.state.pickingInfo}
-            </div>
-            <div
-                style={{
-                    position: 'absolute',
-                    bottom: 10,
-                    right: 10,
-                    padding: 10,
-                    color: 'lightgrey',
-                    background: 'rgba(0, 0, 0, 0.2)'
-                }}
-            >
-                <div>
-                    <span>Camera Mode </span>
-                    <select
-                        value={this.state.cameraMode}
-                        style={{width: '150'}}
-                        onChange={e => {
-                            const p = { cameraMode: e.target.value as Camera.Mode }
-                            this.props.app.canvas3d.setProps(p)
-                            this.setState(p)
-                        }}
-                    >
-                        <option value='perspective'>Perspective</option>
-                        <option value='orthographic'>Orthographic</option>
-                    </select>
-                </div>
-                <ColorParamComponent
-                    label={BackgroundColorParam.label || ''}
-                    param={BackgroundColorParam}
-                    value={this.state.backgroundColor}
-                    onChange={value => {
-                        const p = { backgroundColor: value }
-                        this.props.app.canvas3d.setProps(p)
-                        this.setState(p)
-                    }}
-                />
-            </div>
-            { this.state.taskInfo ?
-                <div
-                    style={{
-                        position: 'absolute',
-                        top: 10,
-                        right: 10,
-                        padding: 10,
-                        color: 'lightgrey',
-                        background: 'rgba(0, 0, 0, 0.2)'
-                    }}
-                >
-                    {this.state.taskInfo}
-                </div>
-            : '' }
-        </div>;
-    }
-}

+ 0 - 105
src/apps/canvas/component/volume-view.tsx

@@ -1,105 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-import { RepresentationComponent } from './representation';
-import { Representation } from 'mol-repr/representation';
-import { VolumeView } from '../volume-view';
-import { VolumeRepresentation } from 'mol-repr/volume/representation';
-
-export interface VolumeViewComponentProps {
-    volumeView: VolumeView
-}
-
-export interface VolumeViewComponentState {
-    volumeView: VolumeView
-    label: string
-    active: { [k: string]: boolean }
-    volumeRepresentations: { [k: string]: VolumeRepresentation<any> }
-}
-
-export class VolumeViewComponent extends React.Component<VolumeViewComponentProps, VolumeViewComponentState> {
-    state = this.stateFromVolumeView(this.props.volumeView)
-
-    private stateFromVolumeView(vv: VolumeView) {
-        return {
-            volumeView: vv,
-            label: vv.label,
-            volume: vv.volume,
-            active: vv.active,
-            volumeRepresentations: vv.volumeRepresentations
-        }
-    }
-
-    componentWillMount() {
-        this.setState(this.stateFromVolumeView(this.props.volumeView))
-    }
-
-    componentDidMount() {
-        const vv = this.props.volumeView
-
-        this.props.volumeView.updated.subscribe(() => this.setState({
-            volumeRepresentations: vv.volumeRepresentations
-        }))
-    }
-
-    componentWillReceiveProps(nextProps: VolumeViewComponentProps) {
-        if (nextProps.volumeView !== this.props.volumeView) {
-            this.setState(this.stateFromVolumeView(nextProps.volumeView))
-
-            nextProps.volumeView.updated.subscribe(() => this.setState({
-                volumeRepresentations: nextProps.volumeView.volumeRepresentations
-            }))
-        }
-    }
-
-    // async update(state: Partial<VolumeViewComponentState>) {
-    //     const vv = this.state.volumeView
-    //     this.setState(this.stateFromVolumeView(vv))
-    // }
-
-    render() {
-        const { volumeView, label, active, volumeRepresentations } = this.state
-
-        return <div>
-            <div>
-                <h2>{label}</h2>
-            </div>
-            <div>
-                <div>
-                    <h4>Active</h4>
-                    { Object.keys(active).map((k, i) => {
-                        return <div key={i}>
-                            <input
-                                type='checkbox'
-                                checked={active[k]}
-                                onChange={(e) => {
-                                    volumeView.setVolumeRepresentation(k, e.target.checked)
-                                }}
-                            /> {k}
-                        </div>
-                    } ) }
-                </div>
-                <div>
-                    <h3>Volume Representations</h3>
-                    { Object.keys(volumeRepresentations).map((k, i) => {
-                        if (active[k]) {
-                            return <div key={i}>
-                                <RepresentationComponent
-                                    repr={volumeRepresentations[k] as Representation<any>}
-                                    canvas3d={volumeView.viewer}
-                                    app={volumeView.app}
-                                />
-                            </div>
-                        } else {
-                            return ''
-                        }
-                    } ) }
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 183
src/apps/canvas/examples.ts

@@ -1,183 +0,0 @@
-
-
-export interface Example {
-    label?: string
-    id: string
-    description: string
-}
-
-export const Examples: Example[] = [
-    {
-        id: '1jj2',
-        description: 'ribosome'
-    },
-    {
-        id: '1grm',
-        description: 'helix-like sheets'
-    },
-    {
-        id: '4umt',
-        description: 'ligand has bond with order 3'
-    },
-    {
-        id: '1crn',
-        description: 'small'
-    },
-    {
-        id: '1hrv',
-        description: 'viral assembly'
-    },
-    {
-        id: '1rb8',
-        description: 'virus'
-    },
-    {
-        id: '1blu',
-        description: 'metal coordination'
-    },
-    {
-        id: '3pqr',
-        description: 'inter unit bonds, two polymer chains, ligands, water, carbohydrates linked to protein'
-    },
-    {
-        id: '4v5a',
-        description: 'ribosome'
-    },
-    {
-        id: '6h7w',
-        description: 'retromer assembled on membrane'
-    },
-    {
-        id: '3j3q',
-        description: '...'
-    },
-    {
-        id: '5gob',
-        description: 'D-aminoacids'
-    },
-    {
-        id: '2np2',
-        description: 'dna'
-    },
-    {
-        id: '1d66',
-        description: 'dna'
-    },
-    {
-        id: '9dna',
-        description: 'A form dna'
-    },
-    {
-        id: '1bna',
-        description: 'B form dna'
-    },
-    {
-        id: '199d',
-        description: 'C form dna'
-    },
-    {
-        id: '4lb6',
-        description: 'Z form dna'
-    },
-    {
-        id: '1egk',
-        description: '4-way dna-rna junction'
-    },
-    {
-        id: '1y26',
-        description: 'rna'
-    },
-    {
-        id: '1xv6',
-        description: 'rna, modified nucleotides'
-    },
-    {
-        id: '3bbm',
-        description: 'rna with linker'
-    },
-    {
-        id: '1euq',
-        description: 't-rna'
-    },
-    {
-        id: '2e2i',
-        description: 'rna, dna, protein'
-    },
-    {
-        id: '1gfl',
-        description: 'GFP, flourophore has carbonyl oxygen removed'
-    },
-    {
-        id: '1sfi',
-        description: 'contains cyclic peptid'
-    },
-    {
-        id: '3sn6',
-        description: 'discontinuous chains'
-    },
-    {
-        id: '2zex',
-        description: 'contains carbohydrate polymer'
-    },
-    {
-        id: '3sgj',
-        description: 'contains carbohydrate polymer'
-    },
-    {
-        id: '3ina',
-        description: 'contains GlcN and IdoA'
-    },
-    {
-        id: '1umz',
-        description: 'contains Xyl (Xyloglucan)'
-    },
-    {
-        id: '1mfb',
-        description: 'contains Abe'
-    },
-    {
-        id: '2gdu',
-        description: 'contains sucrose'
-    },
-    {
-        id: '2fnc',
-        description: 'contains maltotriose'
-    },
-    {
-        id: '4zs9',
-        description: 'contains raffinose'
-    },
-    {
-        id: '2yft',
-        description: 'contains kestose'
-    },
-    {
-        id: '2b5t',
-        description: 'contains large carbohydrate polymer'
-    },
-    {
-        id: '1b5f',
-        description: 'contains carbohydrate with alternate locations'
-    },
-    {
-        id: '5u0q',
-        description: 'mixed dna/rna in same polymer'
-    },
-    {
-        id: '1xj9',
-        description: 'PNA (peptide nucleic acid)'
-    },
-    {
-        id: '5eme',
-        description: 'PNA (peptide nucleic acid) and RNA'
-    },
-    {
-        id: '2X3T',
-        description: 'temp'
-    },
-    {
-        label: 'ModelServer/1cbs/full',
-        id: 'http://localhost:1337/ModelServer/query?%7B%22id%22%3A%221cbs%22%2C%22name%22%3A%22full%22%7D',
-        description: '1cbs from model server'
-    }
-]

+ 0 - 33
src/apps/canvas/index.html

@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-    <head>
-        <meta charset="utf-8" />
-        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-        <title>Mol* Canvas</title>
-        <style>
-            * {
-                margin: 0;
-                padding: 0;
-            }
-            html, body {
-                width: 100%;
-                height: 100%;
-                overflow: hidden;
-            }
-            hr {
-                margin: 10px;
-            }
-            h1, h2, h3, h4, h5 {
-                margin-top: 5px;
-                margin-bottom: 3px;
-            }
-            button {
-                padding: 2px;
-            }
-        </style>
-    </head>
-    <body>
-        <div id="app" style="width: 100%; height: 100%"></div>
-        <script type="text/javascript" src="./index.js"></script>
-    </body>
-</html>

+ 0 - 49
src/apps/canvas/index.ts

@@ -1,49 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-import * as ReactDOM from 'react-dom'
-
-import './index.html'
-
-import { App } from './app';
-import { AppComponent } from './component/app';
-import { urlQueryParameter } from 'mol-util/url-query';
-
-const elm = document.getElementById('app') as HTMLElement
-if (!elm) throw new Error('Can not find element with id "app".')
-
-const app = new App()
-ReactDOM.render(React.createElement(AppComponent, { app }), elm);
-
-const assemblyId = urlQueryParameter('assembly')
-const pdbId = urlQueryParameter('pdb')
-if (pdbId) app.loadPdbIdOrMmcifUrl(pdbId, { assemblyId })
-
-// app.loadPdbIdOrMmcifUrl('http://localhost:8091/ngl/data/1crn.cif')
-
-// app.loadPdbIdOrMmcifUrl('3pqr')
-// app.loadCcp4Url('http://localhost:8091/ngl/data/3pqr-mode0.ccp4')
-
-app.loadPdbIdOrMmcifUrl('1lee')
-app.loadCcp4Url('http://localhost:8091/ngl/data/1lee.ccp4')
-
-// app.loadPdbIdOrMmcifUrl('6DRV')
-// 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)
-
-// app.loadPdbIdOrMmcifUrl('http://localhost:8091/test/pdb-dev/carb/1B5F-carb.cif')
-// app.loadPdbIdOrMmcifUrl('http://localhost:8091/test/pdb-dev/carb/2HYV-carb.cif')
-// app.loadPdbIdOrMmcifUrl('http://localhost:8091/test/pdb-dev/carb/2WMG-carb.cif')
-// app.loadPdbIdOrMmcifUrl('http://localhost:8091/test/pdb-dev/carb/5KDS-carb.cif')

+ 0 - 369
src/apps/canvas/structure-view.ts

@@ -1,369 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { Model, Structure } from 'mol-model/structure';
-import { getStructureFromModel } from './util';
-import { AssemblySymmetry } from 'mol-model-props/rcsb/symmetry';
-import { getAxesShape } from './assembly-symmetry';
-import { Canvas3D } from 'mol-canvas3d/canvas3d';
-// import { MeshBuilder } from 'mol-geo/mesh/mesh-builder';
-// import { addSphere } from 'mol-geo/mesh/builder/sphere';
-// import { Shape } from 'mol-model/shape';
-// import { Color } from 'mol-util/color';
-// import { computeUnitBoundary } from 'mol-model/structure/structure/util/boundary';
-// import { addBoundingBox } from 'mol-geo/mesh/builder/bounding-box';
-import { BehaviorSubject } from 'rxjs';
-import { App } from './app';
-import { StructureRepresentation } from 'mol-repr/structure/representation';
-import { ShapeRepresentation, ShapeParams } from 'mol-repr/shape/representation';
-
-export interface StructureView {
-    readonly app: App
-    readonly canvas3d: Canvas3D
-
-    readonly label: string
-    readonly models: ReadonlyArray<Model>
-    readonly structure: Structure | undefined
-    readonly assemblySymmetry: AssemblySymmetry | undefined
-
-    readonly active: { [k: string]: boolean }
-    readonly structureRepresentations: { [k: string]: StructureRepresentation<any> }
-    readonly updated: BehaviorSubject<null>
-    readonly symmetryAxes: ShapeRepresentation<ShapeParams>
-
-    setSymmetryAxes(value: boolean): void
-    setStructureRepresentation(name: string, value: boolean): void
-
-    readonly modelId: number
-    readonly assemblyId: string
-    readonly symmetryFeatureId: number
-
-    setModel(modelId: number): Promise<void>
-    getModelIds(): { id: number, label: string }[]
-    setAssembly(assemblyId: string): Promise<void>
-    getAssemblyIds(): { id: string, label: string }[]
-    setSymmetryFeature(symmetryFeatureId: number): Promise<void>
-    getSymmetryFeatureIds(): { id: number, label: string }[]
-
-    destroy: () => void
-}
-
-interface StructureViewProps {
-    assemblyId?: string
-    symmetryFeatureId?: number
-}
-
-export async function StructureView(app: App, canvas3d: Canvas3D, models: ReadonlyArray<Model>, props: StructureViewProps = {}): Promise<StructureView> {
-    const active: { [k: string]: boolean } = {
-        'cartoon': true,
-        'ball-and-stick': true,
-        // point: false,
-        // surface: false,
-        // carbohydrate: false,
-        // spacefill: false,
-        // distanceRestraint: false,
-        // symmetryAxes: true,
-        // polymerSphere: false,
-    }
-
-    const structureRepresentations: { [k: string]: StructureRepresentation<any> } = {}
-
-    const symmetryAxes = ShapeRepresentation()
-    const polymerSphere = ShapeRepresentation()
-
-    const updated: BehaviorSubject<null> = new BehaviorSubject<null>(null)
-
-    let label: string
-    let model: Model | undefined
-    let assemblySymmetry: AssemblySymmetry | undefined
-    let structure: Structure | undefined
-
-    let modelId: number
-    let assemblyId: string
-    let symmetryFeatureId: number
-
-    async function setSymmetryAxes(value: boolean) {
-        if (!value) {
-            assemblySymmetry = undefined
-        } else {
-            await app.runTask(AssemblySymmetry.attachFromCifOrAPI(models[modelId]), 'Load symmetry annotation')
-            assemblySymmetry = AssemblySymmetry.get(models[modelId])
-        }
-        active.symmetryAxes = value
-        await setSymmetryFeature()
-    }
-
-    async function setStructureRepresentation(k: string, value: boolean) {
-        active[k] = value
-        await createStructureRepr()
-    }
-
-    async function setModel(newModelId: number, newAssemblyId?: string, newSymmetryFeatureId?: number) {
-        console.log('setModel', newModelId)
-        modelId = newModelId
-        model = models[modelId]
-        if (active.symmetryAxes) {
-            await AssemblySymmetry.attachFromCifOrAPI(model)
-            assemblySymmetry = AssemblySymmetry.get(model)
-        }
-        await setAssembly(newAssemblyId, newSymmetryFeatureId)
-    }
-
-    function getModelIds() {
-        const modelIds: { id: number, label: string }[] = []
-        models.forEach((m, i) => {
-            modelIds.push({ id: i, label: `${i}: ${m.label} #${m.modelNum}` })
-        })
-        return modelIds
-    }
-
-    async function setAssembly(newAssemblyId?: string, newSymmetryFeatureId?: number) {
-        console.log('setAssembly', newAssemblyId)
-        if (newAssemblyId !== undefined) {
-            assemblyId = newAssemblyId
-        } else if (model && model.symmetry.assemblies.length) {
-            assemblyId = model.symmetry.assemblies[0].id
-        } else if (model) {
-            assemblyId = 'deposited'
-        } else {
-            assemblyId = '-1'
-        }
-        await getStructure()
-        await setSymmetryFeature(newSymmetryFeatureId)
-    }
-
-    function getAssemblyIds() {
-        const assemblyIds: { id: string, label: string }[] = [
-            { id: 'deposited', label: 'deposited' }
-        ]
-        if (model) model.symmetry.assemblies.forEach(a => {
-            assemblyIds.push({ id: a.id, label: `${a.id}: ${a.details}` })
-        })
-        return assemblyIds
-    }
-
-    async function setSymmetryFeature(newSymmetryFeatureId?: number) {
-        console.log('setSymmetryFeature', newSymmetryFeatureId)
-        if (newSymmetryFeatureId !== undefined) {
-            symmetryFeatureId = newSymmetryFeatureId
-        } else if (assemblySymmetry) {
-            const s = assemblySymmetry.getSymmetries(assemblyId)
-            if (s._rowCount) {
-                symmetryFeatureId = s.id.value(0)
-            } else {
-                symmetryFeatureId = -1
-            }
-        } else {
-            symmetryFeatureId = -1
-        }
-        await createSymmetryRepr()
-    }
-
-    function getSymmetryFeatureIds() {
-        const symmetryFeatureIds: { id: number, label: string }[] = []
-        if (assemblySymmetry) {
-            const symmetries = assemblySymmetry.getSymmetries(assemblyId)
-            for (let i = 0, il = symmetries._rowCount; i < il; ++i) {
-                const id = symmetries.id.value(i)
-                const kind = symmetries.kind.value(i)
-                const type = symmetries.type.value(i)
-                const stoichiometry = symmetries.stoichiometry.value(i)
-                const label = `${id}: ${kind} ${type} ${stoichiometry}`
-                symmetryFeatureIds.push({ id, label })
-            }
-        }
-        return symmetryFeatureIds
-    }
-
-    async function getStructure() {
-        if (model) structure = await app.runTask(getStructureFromModel(model, assemblyId), 'Build structure')
-        if (model && structure) {
-            label = `${model.label} - Assembly ${assemblyId}`
-        } else {
-            label = ''
-        }
-        await createStructureRepr()
-    }
-
-    async function createStructureRepr() {
-        if (structure) {
-            console.log('createStructureRepr')
-            for (const k in active) {
-                if (active[k]) {
-                    let repr: StructureRepresentation
-                    if (structureRepresentations[k]) {
-                        repr = structureRepresentations[k]
-                    } else {
-                        const provider = app.structureRepresentationRegistry.get(k)
-                        repr = provider.factory(provider.getParams)
-                        structureRepresentations[k] = repr
-                        canvas3d.add(repr)
-                    }
-                    await app.runTask(repr.createOrUpdate(app.reprCtx, {}, structure).run(
-                        progress => app.log(progress)
-                    ), 'Create/update representation')
-                } else {
-                    if (structureRepresentations[k]) {
-                        canvas3d.remove(structureRepresentations[k])
-                        structureRepresentations[k].destroy()
-                        delete structureRepresentations[k]
-                    }
-                }
-            }
-
-            canvas3d.camera.setState({ target: structure.boundary.sphere.center })
-
-            // const mb = MeshBuilder.create()
-            // mb.setGroup(0)
-            // addSphere(mb, structure.boundary.sphere.center, structure.boundary.sphere.radius, 3)
-            // addBoundingBox(mb, structure.boundary.box, 1, 2, 8)
-            // for (let i = 0, il = structure.units.length; i < il; ++i) {
-            //     mb.setGroup(1)
-            //     const u = structure.units[i]
-            //     const ci = u.model.atomicHierarchy.chainAtomSegments.index[u.elements[0]]
-            //     const ek = u.model.atomicHierarchy.getEntityKey(ci)
-            //     if (u.model.entities.data.type.value(ek) === 'water') continue
-            //     const boundary = computeUnitBoundary(u)
-            //     addSphere(mb, boundary.sphere.center, boundary.sphere.radius, 3)
-            //     addBoundingBox(mb, boundary.box, 0.5, 2, 8)
-            // }
-            // const shape = Shape.create('boundary', mb.getMesh(), [Color(0xCC6633), Color(0x3366CC)], ['sphere boundary'])
-            // await polymerSphere.createOrUpdate({
-            //     alpha: 0.5,
-            //     doubleSided: false,
-            //     depthMask: false,
-            //     useFog: false // TODO fog not working properly
-            // }, shape).run()
-        } else {
-            for (const k in structureRepresentations) structureRepresentations[k].destroy()
-            polymerSphere.destroy()
-        }
-
-        canvas3d.add(polymerSphere)
-
-        updated.next(null)
-        canvas3d.requestDraw(true)
-        console.log('stats', canvas3d.stats)
-    }
-
-    async function createSymmetryRepr() {
-        if (assemblySymmetry) {
-            const symmetries = assemblySymmetry.getSymmetries(assemblyId)
-            if (symmetries._rowCount) {
-                const axesShape = getAxesShape(symmetryFeatureId, assemblySymmetry)
-                if (axesShape) {
-                    // const colorTheme = getClusterColorTheme(symmetryFeatureId, assemblySymmetry)
-                    // await structureRepresentations['cartoon'].createOrUpdate({
-                    //     colorTheme: 'custom',
-                    //     colorFunction: colorTheme.color,
-                    //     colorGranularity: colorTheme.granularity,
-                    // }).run()
-                    await symmetryAxes.createOrUpdate(app.reprCtx, {}, axesShape).run()
-                    canvas3d.add(symmetryAxes)
-                } else {
-                    canvas3d.remove(symmetryAxes)
-                }
-            } else {
-                canvas3d.remove(symmetryAxes)
-            }
-        } else {
-            canvas3d.remove(symmetryAxes)
-        }
-        updated.next(null)
-        canvas3d.requestDraw(true)
-    }
-
-    await setModel(0, props.assemblyId, props.symmetryFeatureId)
-
-    return {
-        app,
-        canvas3d,
-
-        get label() { return label },
-        models,
-        get structure() { return structure },
-        get assemblySymmetry() { return assemblySymmetry },
-
-        active,
-        structureRepresentations,
-        updated,
-        symmetryAxes,
-
-        setSymmetryAxes,
-        setStructureRepresentation,
-
-        get modelId() { return modelId },
-        get assemblyId() { return assemblyId },
-        get symmetryFeatureId() { return symmetryFeatureId },
-
-        setModel,
-        getModelIds,
-        setAssembly,
-        getAssemblyIds,
-        setSymmetryFeature,
-        getSymmetryFeatureIds,
-
-        destroy: () => {
-            for (const k in structureRepresentations) {
-                canvas3d.remove(structureRepresentations[k])
-                structureRepresentations[k].destroy()
-            }
-            canvas3d.remove(polymerSphere)
-            canvas3d.remove(symmetryAxes)
-            canvas3d.requestDraw(true)
-
-            polymerSphere.destroy()
-            symmetryAxes.destroy()
-        }
-    }
-}
-
-// // create new structure via query
-// const q1 = Q.generators.atoms({
-//     residueTest: qtx => SP.residue.label_seq_id(qtx.element) < 7
-// });
-// const newStructure = StructureSelection.unionStructure(await StructureQuery.run(q1, structure));
-
-// // ball+stick for new structure
-// const newBallStickRepr = BallAndStickRepresentation()
-// await newBallStickRepr.create(newStructure, {
-//     colorTheme: { name: 'element-symbol' },
-//     sizeTheme: { name: 'uniform', value: 0.1 },
-//     useFog: false // TODO fog not working properly
-// }).run()
-// viewer.add(newBallStickRepr)
-
-// // create a mesh
-// const meshBuilder = MeshBuilder.create(256, 128)
-// const colors: Color[] = []
-// const labels: string[] = []
-// // red sphere
-// meshBuilder.setGroup(0)
-// colors[0] = Color(0xFF2233)
-// labels[0] = 'red sphere'
-// addSphere(meshBuilder, Vec3.create(0, 0, 0), 4, 2)
-// // green cube
-// meshBuilder.setGroup(1)
-// colors[1] = Color(0x2233FF)
-// labels[1] = 'blue cube'
-// const t = Mat4.identity()
-// Mat4.fromTranslation(t, Vec3.create(10, 0, 0))
-// Mat4.scale(t, t, Vec3.create(3, 3, 3))
-// meshBuilder.add(t, Box())
-// const mesh = meshBuilder.getMesh()
-// const mesh = getObjFromUrl('mesh.obj')
-
-// // create shape from mesh
-// const shape = Shape.create('myShape', mesh, colors, labels)
-
-// // add representation from shape
-// const customRepr = ShapeRepresentation()
-// await customRepr.create(shape, {
-//     colorTheme: { name: 'shape-group' },
-//     // colorTheme: { name: 'uniform', value: Color(0xFFCC22) },
-//     useFog: false // TODO fog not working properly
-// }).run()
-// viewer.add(customRepr)

+ 0 - 78
src/apps/canvas/util.ts

@@ -1,78 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { readUrl, readFile, readUrlAsBuffer, readFileAsBuffer } from 'mol-util/read';
-import CIF, { CifBlock } from 'mol-io/reader/cif'
-import { Model, Format, StructureSymmetry, Structure } from 'mol-model/structure';
-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) {
-//     const data = await readUrlAs(url, false) as string
-//     const comp = parseObj(data)
-//     const parsed = await comp.run()
-//     if (parsed.isError) throw parsed
-//     return parsed.result
-// }
-
-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
-}
-
-export async function getCifFromUrl(url: string, binary = false) {
-    return getCifFromData(await readUrl(url, binary))
-}
-
-export async function getCifFromFile(file: File, binary = false) {
-    return getCifFromData(await readFile(file, binary))
-}
-
-export async function getModelsFromMmcif(cif: CifBlock) {
-    return await Model.create(Format.mmCIF(cif)).run()
-}
-
-export async function getStructureFromModel(model: Model, assembly: string) {
-    const assemblies = model.symmetry.assemblies
-    if (assembly === 'deposited') {
-        return Structure.ofModel(model)
-    } else if (assemblies.find(a => a.id === assembly)) {
-        return await StructureSymmetry.buildAssembly(Structure.ofModel(model), assembly).run()
-    }
-}
-
-//
-
-export async function getCcp4FromUrl(url: string) {
-    return getCcp4FromData(await readUrlAsBuffer(url))
-}
-
-export async function getCcp4FromFile(file: File) {
-    return getCcp4FromData(await readFileAsBuffer(file))
-}
-
-export async function getCcp4FromData(data: Uint8Array) {
-    const file = FileHandle.fromBuffer(data)
-    const parsed = await CCP4(file).run()
-    if (parsed.isError) throw parsed
-    return parsed.result
-}
-
-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()
-}

+ 0 - 97
src/apps/canvas/volume-view.ts

@@ -1,97 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { Canvas3D } from 'mol-canvas3d/canvas3d';
-import { BehaviorSubject } from 'rxjs';
-import { App } from './app';
-import { VolumeData } from 'mol-model/volume';
-import { VolumeRepresentation } from 'mol-repr/volume/representation';
-import { IsosurfaceRepresentation } from 'mol-repr/volume/isosurface-mesh';
-import { DirectVolumeRepresentation } from 'mol-repr/volume/direct-volume';
-
-export interface VolumeView {
-    readonly app: App
-    readonly viewer: Canvas3D
-
-    readonly label: string
-    readonly volume: VolumeData
-
-    readonly active: { [k: string]: boolean }
-    readonly volumeRepresentations: { [k: string]: VolumeRepresentation<any> }
-    readonly updated: BehaviorSubject<null>
-
-    setVolumeRepresentation(name: string, value: boolean): void
-    destroy: () => void
-}
-
-interface VolumeViewProps {
-
-}
-
-export async function VolumeView(app: App, viewer: Canvas3D, volume: VolumeData, props: VolumeViewProps = {}): Promise<VolumeView> {
-    const active: { [k: string]: boolean } = {
-        isosurface: true,
-        directVolume: false,
-    }
-
-    const volumeRepresentations: { [k: string]: VolumeRepresentation<any> } = {
-        isosurface: IsosurfaceRepresentation(),
-        directVolume: DirectVolumeRepresentation(),
-    }
-
-    const updated: BehaviorSubject<null> = new BehaviorSubject<null>(null)
-
-    let label: string = 'Volume'
-
-    async function setVolumeRepresentation(k: string, value: boolean) {
-        active[k] = value
-        await createVolumeRepr()
-    }
-
-    async function createVolumeRepr() {
-        for (const k in volumeRepresentations) {
-            if (active[k]) {
-                await app.runTask(volumeRepresentations[k].createOrUpdate(app.reprCtx, {}, volume).run(
-                    progress => app.log(progress)
-                ), 'Create/update representation')
-                viewer.add(volumeRepresentations[k])
-            } else {
-                viewer.remove(volumeRepresentations[k])
-            }
-        }
-
-        // const center = Vec3.clone(volume.cell.size)
-        // Vec3.scale(center, center, 0.5)
-        // viewer.center(center)
-
-        updated.next(null)
-        viewer.requestDraw(true)
-        console.log('stats', viewer.stats)
-    }
-
-    await createVolumeRepr()
-
-    return {
-        app,
-        viewer,
-
-        get label() { return label },
-        volume,
-
-        active,
-        volumeRepresentations,
-        setVolumeRepresentation,
-        updated,
-
-        destroy: () => {
-            for (const k in volumeRepresentations) {
-                viewer.remove(volumeRepresentations[k])
-                volumeRepresentations[k].destroy()
-            }
-            viewer.requestDraw(true)
-        }
-    }
-}