Forráskód Böngészése

mol-plugin: volume streaming

David Sehnal 6 éve
szülő
commit
ed5f5819ad

+ 2 - 2
src/mol-model/volume/data.ts

@@ -21,10 +21,10 @@ interface VolumeData {
 }
 
 namespace VolumeData {
-    export const Empty: VolumeData = {
+    export const One: VolumeData = {
         cell: SpacegroupCell.Zero,
         fractionalBox: Box3D.empty(),
-        data: Tensor.create(Tensor.Space([0, 0, 0], [0, 1, 2]), Tensor.Data1([])),
+        data: Tensor.create(Tensor.Space([1, 1, 1], [0, 1, 2]), Tensor.Data1([0])),
         dataStats: { min: 0, max: 0, mean: 0, sigma: 0 }
     }
 

+ 18 - 3
src/mol-plugin/behavior/dynamic/volume.ts

@@ -41,7 +41,7 @@ export namespace VolumeStreaming {
                 topRight: PD.Vec3(Vec3.create(-7.1, -10, -0.9))
             }, { description: 'Static box defined by cartesian coords.' }),
             // 'around-selection': PD.Group({ radius: PD.Numeric(5, { min: 0, max: 10 }) }),
-            // 'whole-structure': PD.Group({  }),
+            'cell': PD.Group({  }),
             // 'auto': PD.Group({  }), // based on camera distance/active selection/whatever, show whole structure or slice.
         }),
         detailLevel: PD.Numeric(3, { min: 0, max: 7 }),
@@ -55,6 +55,7 @@ export namespace VolumeStreaming {
     export class Behavior implements PluginBehavior<Params> {
         // TODO: have special value for "cell"?
         private cache = LRUCache.create<ChannelData>(25);
+        // private ref: string = '';
 
         currentData: ChannelData = { }
 
@@ -109,14 +110,28 @@ export namespace VolumeStreaming {
         }
 
         register(ref: string): void {
-            // TODO: registr camera movement/loci so that "around selection box works"
+            // TODO: register camera movement/loci so that "around selection box works"
+            // alternatively, and maybe a better solution, write a global behavior that modifies this node from the outside
+            // this.ref = ref;
             this.update(this.params);
         }
 
         async update(params: Params): Promise<boolean> {
             this.params = params;
 
-            const box: Box3D = Box3D.create(params.box.params.bottomLeft, params.box.params.topRight);
+            let box: Box3D | undefined = void 0;
+
+            switch (params.box.name) {
+                case 'static-box':
+                    box = Box3D.create(params.box.params.bottomLeft, params.box.params.topRight);
+                    break;
+                case 'cell':
+                    box = this.params.levels.name === 'x-ray'
+                        ? void 0 // TODO get bounding box of the model (how to solve assemblies)
+                        : void 0;
+                    break;
+            }
+
             const data = await this.queryData(box);
             this.currentData = data || { };
 

+ 3 - 3
src/mol-plugin/state/transforms/representation.ts

@@ -195,16 +195,16 @@ const VolumeRepresentation3D = PluginStateTransform.BuiltIn({
                 type: PD.Mapped<any>(
                     registry.default.name,
                     registry.types,
-                    name => PD.Group<any>(registry.get(name).getParams(themeCtx, VolumeData.Empty ))),
+                    name => PD.Group<any>(registry.get(name).getParams(themeCtx, VolumeData.One ))),
                 colorTheme: PD.Mapped<any>(
                     type.defaultColorTheme,
                     themeCtx.colorThemeRegistry.types,
-                    name => PD.Group<any>(themeCtx.colorThemeRegistry.get(name).getParams({ volume: VolumeData.Empty }))
+                    name => PD.Group<any>(themeCtx.colorThemeRegistry.get(name).getParams({ volume: VolumeData.One }))
                 ),
                 sizeTheme: PD.Mapped<any>(
                     type.defaultSizeTheme,
                     themeCtx.sizeThemeRegistry.types,
-                    name => PD.Group<any>(themeCtx.sizeThemeRegistry.get(name).getParams({ volume: VolumeData.Empty }))
+                    name => PD.Group<any>(themeCtx.sizeThemeRegistry.get(name).getParams({ volume: VolumeData.One }))
                 )
             }
         }

+ 2 - 1
src/mol-plugin/state/transforms/volume.ts

@@ -111,6 +111,7 @@ const VolumeStreamingBehavior = PluginStateTransform.BuiltIn({
     apply: ({ params }, plugin: PluginContext) => Task.create('Volume Streaming', async ctx => {
         const behavior = new VolumeStreaming.Behavior(plugin, params);
         // get the initial data now so that the child projections dont get empty volumes.
+        // TODO: this is a temporary fix
         await behavior.update(behavior.params);
         return new VolumeStreaming.Obj(behavior, { label: 'Volume Streaming' });
     }),
@@ -174,7 +175,7 @@ const VolumeStreamingVisual = PluginStateTransform.BuiltIn({
 });
 
 function createVolumeProps(streaming: VolumeStreaming.Behavior, channel: keyof VolumeStreaming.ChannelData, level: VolumeStreaming.LevelType) {
-    const data = streaming.currentData[channel] || VolumeData.Empty;
+    const data = streaming.currentData[channel] || VolumeData.One;
     // TODO: createTheme fails when VolumeData.Empty is used for some reason.
 
     let isoValue: VolumeIsoValue, color: Color;

+ 3 - 3
src/mol-repr/volume/isosurface.ts

@@ -24,18 +24,18 @@ export function createIsoValueParam(defaultValue: VolumeIsoValue) {
         defaultValue,
         {
             'absolute': PD.Converted(
-                (v: VolumeIsoValue) => VolumeIsoValue.toAbsolute(v, VolumeData.Empty.dataStats).absoluteValue,
+                (v: VolumeIsoValue) => VolumeIsoValue.toAbsolute(v, VolumeData.One.dataStats).absoluteValue,
                 (v: number) => VolumeIsoValue.absolute(v),
                 PD.Numeric(0.5, { min: -1, max: 1, step: 0.01 })
             ),
             'relative': PD.Converted(
-                (v: VolumeIsoValue) => VolumeIsoValue.toRelative(v, VolumeData.Empty.dataStats).relativeValue,
+                (v: VolumeIsoValue) => VolumeIsoValue.toRelative(v, VolumeData.One.dataStats).relativeValue,
                 (v: number) => VolumeIsoValue.relative(v),
                 PD.Numeric(2, { min: -10, max: 10, step: 0.01 })
             )
         },
         (v: VolumeIsoValue) => v.kind === 'absolute' ? 'absolute' : 'relative',
-        (v: VolumeIsoValue, c: 'absolute' | 'relative') => c === 'absolute' ? VolumeIsoValue.toAbsolute(v, VolumeData.Empty.dataStats) : VolumeIsoValue.toRelative(v, VolumeData.Empty.dataStats)
+        (v: VolumeIsoValue, c: 'absolute' | 'relative') => c === 'absolute' ? VolumeIsoValue.toAbsolute(v, VolumeData.One.dataStats) : VolumeIsoValue.toRelative(v, VolumeData.One.dataStats)
     )
 }
 

+ 4 - 0
src/mol-state/transform.ts

@@ -56,6 +56,10 @@ namespace Transform {
         return { ...t, parent, version: UUID.create22() };
     }
 
+    export function withNewVersion(t: Transform): Transform {
+        return { ...t, version: UUID.create22() };
+    }
+
     export function createRoot(props?: Props): Transform {
         return create(RootRef, StateTransformer.ROOT, {}, { ref: RootRef, props });
     }

+ 10 - 0
src/mol-state/tree/transient.ts

@@ -96,6 +96,16 @@ class TransientTree implements StateTree {
         const old = this.transforms.get(ref);
         this.removeChild(old.parent, ref);
         this.addChild(newParent, ref);
+        this.changeNodes();
+        this.transforms.set(ref, StateTransform.withParent(old, newParent));
+    }
+
+    updateVersion(ref: StateTransform.Ref) {
+        ensurePresent(this.transforms, ref);
+
+        const t = this.transforms.get(ref);
+        this.changeNodes();
+        this.transforms.set(ref, StateTransform.withNewVersion(t));
     }
 
     add(transform: StateTransform, initialState?: Partial<StateObjectCell.State>) {