Parcourir la source

select method included

bioinsilico il y a 4 ans
Parent
commit
fb02113d28

+ 3 - 3
package-lock.json

@@ -1899,9 +1899,9 @@
       "integrity": "sha512-FM3y6kfJaj5MCoAjdv24EDCTDbuFz+4+pgAunbjYfugwIE4O/xx8mPNji1n/ouG8pHCntSnBr1xwTOensF23Gg=="
     },
     "@rcsb-bioinsilico/rcsb-molstar": {
-      "version": "1.0.24",
-      "resolved": "https://registry.npmjs.org/@rcsb-bioinsilico/rcsb-molstar/-/rcsb-molstar-1.0.24.tgz",
-      "integrity": "sha512-Ck8dtc9uswHHWJmK41LbP3KzRgBXiWR86upMjfRUwuq6LCdn6M0vBw/smgLid2ivSd/ybhdfjpocBdy19YobLA=="
+      "version": "1.0.25",
+      "resolved": "https://registry.npmjs.org/@rcsb-bioinsilico/rcsb-molstar/-/rcsb-molstar-1.0.25.tgz",
+      "integrity": "sha512-UcZ6tj9ZX4hL5f0+NNieso1ri8nyrwNh3eIU2cvMRsIXHXl0CazRo+B7GYME1Z4qG8SAJ1j0oSlvupInl8pKeg=="
     },
     "@rcsb/rcsb-saguaro": {
       "version": "1.0.2",

+ 1 - 1
package.json

@@ -74,7 +74,7 @@
     "webpack-cli": "^3.3.12"
   },
   "dependencies": {
-    "@rcsb-bioinsilico/rcsb-molstar": "^1.0.24",
+    "@rcsb-bioinsilico/rcsb-molstar": "^1.0.25",
     "@rcsb/rcsb-saguaro": "^1.0.2",
     "@rcsb/rcsb-saguaro-app": "^1.0.9",
     "molstar": "^1.2.3"

+ 0 - 2
src/RcsbFvSequence/SequenceViews/AbstractView.tsx

@@ -2,8 +2,6 @@ import * as React from "react";
 import * as classes from '../../styles/RcsbFvStyle.module.scss';
 import {RcsbFvDOMConstants} from "../../RcsbFvConstants/RcsbFvConstants";
 import {SaguaroPluginInterface} from "../../RcsbFvStructure/StructurePlugins/SaguaroPluginInterface";
-import {PluginContext} from "molstar/lib/mol-plugin/context";
-import {RcsbFv, RcsbFvTrackDataElementInterface} from "@rcsb/rcsb-saguaro";
 import { RcsbFvSelection} from "../../RcsbFvSelection/RcsbFvSelection";
 
 export interface AbstractViewInterface {

+ 21 - 18
src/RcsbFvSequence/SequenceViews/CustomView.tsx

@@ -7,7 +7,7 @@ import {
 } from "@rcsb/rcsb-saguaro";
 import * as React from "react";
 import {RcsbFvSelection} from "../../RcsbFvSelection/RcsbFvSelection";
-import {PluginContext} from "molstar/lib/mol-plugin/context";
+import {SaguaroPluginPublicInterface} from "../../RcsbFvStructure/StructurePlugins/SaguaroPluginInterface";
 
 export interface CustomViewInterface {
     config: FeatureBlockInterface | Array<FeatureBlockInterface>;
@@ -25,7 +25,7 @@ export interface FeatureViewInterface {
     boardId?:string;
     boardConfig: RcsbFvBoardConfigInterface;
     rowConfig: Array<RcsbFvRowConfigInterface>;
-    sequenceSelectionCallback: (plugin: PluginContext, selection: RcsbFvSelection, d: RcsbFvTrackDataElementInterface) => void;
+    sequenceSelectionCallback: (plugin: SaguaroPluginPublicInterface, selection: RcsbFvSelection, d: RcsbFvTrackDataElementInterface) => void;
     structureSelectionCallback: (pfv: RcsbFv, selection: RcsbFvSelection) => void;
 }
 
@@ -69,12 +69,11 @@ export class CustomView extends AbstractView<CustomViewInterface & AbstractViewI
                 this.boardMap.set(board.boardId, board);
             });
         });
-        this.blockViewSelector.setActiveBlock( (props.config instanceof Array ? props.config : [props.config])[0].blockId! );
     }
 
     componentDidMount(): void {
         super.componentDidMount();
-        this.buildBlockFv();
+        this.blockViewSelector.setActiveBlock( (this.props.config instanceof Array ? this.props.config : [this.props.config])[0].blockId! );
     }
 
     componentWillUnmount() {
@@ -85,6 +84,10 @@ export class CustomView extends AbstractView<CustomViewInterface & AbstractViewI
 
     private blockChange(): void{
         this.unmountBlockFv();
+        this.buildBlockFv();
+        setTimeout(()=>{
+            this.structureSelectionCallback();
+        },1000);
     }
 
     private unmountBlockFv(){
@@ -102,16 +105,15 @@ export class CustomView extends AbstractView<CustomViewInterface & AbstractViewI
             if(this.boardMap.get(boardId) == null)
                 return;
             const div: HTMLDivElement = document.createElement<"div">("div");
-            div.setAttribute("id", "boardDiv_"+boardId)
+            div.setAttribute("id", "boardDiv_"+boardId);
+            div.style.marginBottom = "2px";
             document.getElementById(this.componentDivId)?.append(div);
             const rcsbFv: RcsbFv = new RcsbFv({
                 elementId: "boardDiv_"+boardId,
                 boardConfigData:{
                     ...this.boardMap.get(boardId)!.boardConfig,
                     elementClickCallBack:(d:RcsbFvTrackDataElementInterface)=>{
-                        this.props.plugin.pluginCall((plugin: PluginContext)=>{
-                            this.boardMap.get(boardId)!.sequenceSelectionCallback(plugin, this.props.selection, d);
-                        });
+                        this.boardMap.get(boardId)!.sequenceSelectionCallback(this.props.plugin, this.props.selection, d);
                     }
                 },
                 rowConfigData: this.boardMap.get(boardId)!.rowConfig
@@ -119,14 +121,7 @@ export class CustomView extends AbstractView<CustomViewInterface & AbstractViewI
             this.rcsbFvMap.set(boardId, rcsbFv);
         });
         this.props.plugin.selectCallback(()=>{
-            this.blockMap.get(this.blockViewSelector.getActiveBlock())?.forEach(boardId=> {
-                if (this.boardMap.get(boardId) == null)
-                    return;
-                this.boardMap.get(boardId)!.structureSelectionCallback(
-                    this.rcsbFvMap.get(boardId)!,
-                    this.props.selection
-                )
-            });
+           this.structureSelectionCallback();
         });
     }
 
@@ -145,8 +140,16 @@ export class CustomView extends AbstractView<CustomViewInterface & AbstractViewI
         return this.props.additionalContent(this.blockViewSelector);
     }
 
-    protected objectChangeCallback(): void {}
+    protected objectChangeCallback(): void {
 
-    protected updatePfvDimensions(): void {}
+    }
+
+    protected updatePfvDimensions(): void {
+        this.rcsbFvMap.forEach((rcsbFv, boardId)=>{
+            const width: number = window.document.getElementById(this.componentDivId)?.getBoundingClientRect().width ?? 0;
+            const trackWidth: number = width - 190 - 55;
+            rcsbFv.updateBoardConfig({boardConfigData:{trackWidth:trackWidth}});
+        });
+    }
 
 }

+ 34 - 57
src/RcsbFvStructure/StructurePlugins/MolstarPlugin.ts

@@ -1,6 +1,6 @@
 import {Viewer, ViewerProps} from '@rcsb-bioinsilico/rcsb-molstar/build/src/viewer';
 import {PresetProps} from '@rcsb-bioinsilico/rcsb-molstar/build/src/viewer/helpers/preset';
-import {SaguaroPluginInterface} from "./SaguaroPluginInterface";
+import {SaguaroPluginInterface, SaguaroPluginPublicInterface} from "./SaguaroPluginInterface";
 
 import {PluginContext} from "molstar/lib/mol-plugin/context";
 import {MolScriptBuilder} from "molstar/lib/mol-script/language/builder";
@@ -44,9 +44,7 @@ interface LoadParams {
     id?:string;
 }
 
-
-
-export class MolstarPlugin extends AbstractPlugin implements SaguaroPluginInterface {
+export class MolstarPlugin extends AbstractPlugin implements SaguaroPluginInterface, SaguaroPluginPublicInterface {
     private plugin: Viewer;
     private localSelectionFlag: boolean = false;
     private loadingFlag: boolean = false;
@@ -122,68 +120,47 @@ export class MolstarPlugin extends AbstractPlugin implements SaguaroPluginInterf
     }
 
     public select(modelId:string, asymId: string, x: number, y: number): void {
-        const f:(plugin: PluginContext)=>void = (plugin: PluginContext) => {
-            this.localSelectionFlag = true;
-            const data: Structure | undefined = getStructureWithModelId(plugin.managers.structure.hierarchy.current.structures, this.getModelId(modelId));
-            if (data == null) return;
-            const seq_id: Array<number> = new Array<number>();
-            for(let n = x; n <= y; n++){
-                seq_id.push(n);
-            }
-            const sel = Script.getStructureSelection(Q => Q.struct.generator.atomGroups({
-                'chain-test': Q.core.rel.eq([asymId, MolScriptBuilder.ammp('label_asym_id')]),
-                'residue-test': Q.core.set.has([MolScriptBuilder.set(...SetUtils.toArray(new Set(seq_id))), MolScriptBuilder.ammp('label_seq_id')])
-            }), data);
-            const loci:Loci = StructureSelection.toLociWithSourceUnits(sel);
-            plugin.managers.structure.selection.fromLoci('set', loci);
-        }
-        this.plugin.pluginCall(f.bind(this));
+        this.localSelectionFlag = true;
+        this.plugin.select(this.getModelId(modelId), asymId, x, y)
     }
 
     public selectCallback( g:()=>void ){
-        const f: (plugin: PluginContext) => void = (plugin: PluginContext)=>{
-            plugin.managers.structure.selection.events.changed.subscribe((()=>{
-                if(this.localSelectionFlag) {
-                    this.localSelectionFlag = false;
-                    return;
-                }
-                const sequenceData: Array<ResidueSelectionInterface> = new Array<ResidueSelectionInterface>();
-                for(const structure of plugin.managers.structure.hierarchy.current.structures){
-                    const data: Structure | undefined = structure.cell.obj?.data;
-                    if(data == null) return;
-                    const loci: Loci = plugin.managers.structure.selection.getLoci(data);
-                    if(StructureElement.Loci.is(loci)){
-                        const loc = StructureElement.Location.create(loci.structure);
-                        for (const e of loci.elements) {
-                            const seqIds = new Set<number>();
-                            loc.unit = e.unit;
-                            for (let i = 0, il = OrderedSet.size(e.indices); i < il; ++i) {
-                                loc.element = e.unit.elements[OrderedSet.getAt(e.indices, i)];
-                                seqIds.add(SP.residue.label_seq_id(loc));
-                            }
-                            sequenceData.push({
-                                modelId: this.getModelId(data.model.id),
-                                labelAsymId: SP.chain.label_asym_id(loc),
-                                seqIds
-                            });
+        this.plugin.getPlugin().managers.structure.selection.events.changed.subscribe((()=>{
+            if(this.localSelectionFlag) {
+                this.localSelectionFlag = false;
+                return;
+            }
+            const sequenceData: Array<ResidueSelectionInterface> = new Array<ResidueSelectionInterface>();
+            for(const structure of this.plugin.getPlugin().managers.structure.hierarchy.current.structures){
+                const data: Structure | undefined = structure.cell.obj?.data;
+                if(data == null) return;
+                const loci: Loci = this.plugin.getPlugin().managers.structure.selection.getLoci(data);
+                if(StructureElement.Loci.is(loci)){
+                    const loc = StructureElement.Location.create(loci.structure);
+                    for (const e of loci.elements) {
+                        const seqIds = new Set<number>();
+                        loc.unit = e.unit;
+                        for (let i = 0, il = OrderedSet.size(e.indices); i < il; ++i) {
+                            loc.element = e.unit.elements[OrderedSet.getAt(e.indices, i)];
+                            seqIds.add(SP.residue.label_seq_id(loc));
                         }
-
+                        sequenceData.push({
+                            modelId: this.getModelId(data.model.id),
+                            labelAsymId: SP.chain.label_asym_id(loc),
+                            seqIds
+                        });
                     }
+
                 }
-                this.selection.setSelectionFromResidueSelection(sequenceData);
-                g();
-            }));
-        };
-        this.pluginCall(f.bind(this));
+            }
+            this.selection.setSelectionFromResidueSelection(sequenceData);
+            g();
+        }));
     }
 
     public clearSelect(): void {
-        const f:(plugin: PluginContext)=>void = (plugin: PluginContext) => {
-            this.localSelectionFlag = true;
-            plugin.managers.interactivity.lociSelects.deselectAll();
-            this.selection.clearSelection();
-        }
-        this.plugin.pluginCall(f);
+        this.plugin.getPlugin().managers.interactivity.lociSelects.deselectAll();
+        this.selection.clearSelection();
     }
 
     public pluginCall(f: (plugin: PluginContext) => void){

+ 4 - 0
src/RcsbFvStructure/StructurePlugins/SaguaroPluginInterface.ts

@@ -12,3 +12,7 @@ export interface SaguaroPluginInterface {
     getChains: () => Map<string,{entryId: string; chains:Array<{label:string, auth:string}>;}>;
     objectChangeCallback: (f:()=>void)=>void;
 }
+
+export interface SaguaroPluginPublicInterface {
+    select: (modelId:string, asymId: string, x: number, y: number) => void;
+}

+ 79 - 41
src/examples/custom-panel/example.tsx

@@ -1,10 +1,3 @@
-import {PluginContext} from "molstar/lib/mol-plugin/context";
-import {MolScriptBuilder} from "molstar/lib/mol-script/language/builder";
-import {Script} from "molstar/lib/mol-script/script";
-import {SetUtils} from "molstar/lib/mol-util/set";
-import {StructureSelection} from "molstar/lib/mol-model/structure/query";
-
-
 import {RcsbFv3DBuilder} from "../../RcsbFv3DBuilder";
 import {StructureViewInterface} from "../../RcsbFvStructure/RcsbFvStructure";
 import {SequenceViewInterface} from "../../RcsbFvSequence/RcsbFvSequence";
@@ -23,45 +16,39 @@ import {
     RcsbFvRowConfigInterface,
     RcsbFvTrackDataElementInterface
 } from "@rcsb/rcsb-saguaro";
-import {RcsbFvSelection} from "../../RcsbFvSelection/RcsbFvSelection";
-
+import {ChainSelectionInterface, RcsbFvSelection} from "../../RcsbFvSelection/RcsbFvSelection";
+import {SaguaroPluginPublicInterface} from "../../RcsbFvStructure/StructurePlugins/SaguaroPluginInterface";
 
 const structureConfig:StructureViewInterface = {
     loadConfig: {
-        method: LoadMethod.loadPdbId,
-        params: {
+        method: LoadMethod.loadPdbIds,
+        params: [{
             pdbId: "101m",
-            id:"101m_1"
-        }
+            id:"model_1"
+        },{
+            pdbId: "1ash",
+            id:"model_2"
+        }]
     }
 };
 
-const sequenceSelectionCallback = (plugin: PluginContext, ann: RcsbFvTrackDataElementInterface) => {
-    const data = plugin.managers.structure.hierarchy.current.structures[0]?.cell.obj?.data;
-    if (!data) return;
-    const MS = MolScriptBuilder;
-    const seq_id: Array<number> = new Array<number>();
-    const x: number = ann.begin;
-    const y: number = ann.end ?? ann.begin
-    for(let n = x; n <= y; n++){
-        seq_id.push(n);
-    }
-    const sel = Script.getStructureSelection(Q => Q.struct.generator.atomGroups({
-        'chain-test': Q.core.rel.eq(["A", MS.ammp('label_asym_id')]),
-        'residue-test': Q.core.set.has([MS.set(...SetUtils.toArray(new Set(seq_id))), MS.ammp('label_seq_id')])
-    }), data);
-    const loci = StructureSelection.toLociWithSourceUnits(sel);
-    plugin.managers.structure.selection.fromLoci('set', loci);
-};
-
 const additionalContent: (select: BlockViewSelector) => JSX.Element = (select: BlockViewSelector) => {
     function changeBlock(select: BlockViewSelector){
-        console.log(select.getActiveBlock());
+        select.setActiveBlock("MyBlock_2");
+    }
+    function changeBlock2(select: BlockViewSelector){
+        select.setActiveBlock("MyBlock_1");
     }
     return (
-        <div onClick={()=>{changeBlock(select)}}>
-            ClickMe
-        </div>);
+        <div>
+            <div onClick={()=>{changeBlock(select)}}>
+                Option 1
+            </div>
+            <div onClick={()=>{changeBlock2(select)}}>
+                Option 2
+            </div>
+        </div>
+    );
 }
 
 const rowConfig: Array<RcsbFvRowConfigInterface> = [{
@@ -75,8 +62,22 @@ const rowConfig: Array<RcsbFvRowConfigInterface> = [{
         begin: 30,
         end: 60
     }]
+}];
+
+const rowConfig2: Array<RcsbFvRowConfigInterface> = [{
+    trackId: "blockTrack",
+    trackHeight: 20,
+    trackColor: "#F9F9F9",
+    displayType: RcsbFvDisplayTypes.BLOCK,
+    displayColor: "#00FF00",
+    rowTitle: "BLOCK",
+    trackData: [{
+        begin: 30,
+        end: 60
+    }]
 }]
-const fv: FeatureViewInterface = {
+
+const fv1: FeatureViewInterface = {
     boardId:"101m_board",
     boardConfig: {
         range: {
@@ -88,19 +89,56 @@ const fv: FeatureViewInterface = {
         includeAxis: true
     },
     rowConfig: rowConfig,
-    sequenceSelectionCallback: (plugin: PluginContext, selection: RcsbFvSelection, d: RcsbFvTrackDataElementInterface) => {
-        sequenceSelectionCallback(plugin,d);
+    sequenceSelectionCallback: (plugin: SaguaroPluginPublicInterface, selection: RcsbFvSelection, d: RcsbFvTrackDataElementInterface) => {
+        selection.setSelectionFromRegion("model_1", "A", {begin:d.begin, end:d.end??d.begin});
+        plugin.select("model_1", "A", d.begin, d.end??d.begin);
+    },
+    structureSelectionCallback: (pfv: RcsbFv, selection: RcsbFvSelection) => {
+        const sel: ChainSelectionInterface | undefined = selection.getSelectionWithCondition("model_1", "A");
+        if(sel == null)
+            pfv.clearSelection();
+        else
+            pfv.setSelection(sel.regions);
+    }
+}
+
+const fv2: FeatureViewInterface = {
+    boardId:"1ash_board",
+    boardConfig: {
+        range: {
+            min: 1,
+            max: 150
+        },
+        trackWidth: 940,
+        rowTitleWidth: 60,
+        includeAxis: true
     },
-    structureSelectionCallback: (pfv: RcsbFv, selection: RcsbFvSelection) => {}
+    rowConfig: rowConfig2,
+    sequenceSelectionCallback: (plugin: SaguaroPluginPublicInterface, selection: RcsbFvSelection, d: RcsbFvTrackDataElementInterface) => {
+        selection.setSelectionFromRegion("model_2", "A", {begin:d.begin, end:d.end??d.begin});
+        plugin.select("model_2", "A", d.begin, d.end??d.begin);
+    },
+    structureSelectionCallback: (pfv: RcsbFv, selection: RcsbFvSelection) => {
+        const sel: ChainSelectionInterface | undefined = selection.getSelectionWithCondition("model_2", "A");
+        if(sel == null)
+            pfv.clearSelection();
+        else
+            pfv.setSelection(sel.regions);
+    }
 }
 
 const block: FeatureBlockInterface = {
     blockId:"MyBlock_1",
-    blockConfig: [fv]
+    blockConfig: [fv1]
+};
+
+const block2: FeatureBlockInterface = {
+    blockId:"MyBlock_2",
+    blockConfig: [fv2, fv1]
 };
 
 const customConfig: CustomViewInterface = {
-    config:[block],
+    config:[block, block2],
     additionalContent:additionalContent
 }