import './index.html'; import {RcsbFv3DCustom, RcsbFv3DCustomInterface} from "../../RcsbFv3D/RcsbFv3DCustom"; import {RcsbFvStructureInterface} from "../../RcsbFvStructure/RcsbFvStructure"; import {LoadMethod} from "../../RcsbFvStructure/StructurePlugins/MolstarPlugin"; import { CustomViewInterface, FeatureBlockInterface, FeatureViewInterface } from "../../RcsbFvSequence/SequenceViews/CustomView"; import * as React from "react"; import { RcsbFv, RcsbFvDisplayTypes, RcsbFvRowConfigInterface, RcsbFvTrackDataElementInterface } from "@rcsb/rcsb-saguaro"; import { RcsbFvSelectorManager, RegionSelectionInterface } from "../../RcsbFvSelection/RcsbFvSelectorManager"; import {SaguaroPluginPublicInterface, SaguaroRegionList} from "../../RcsbFvStructure/SaguaroPluginInterface"; import {AlignmentManager} from "./AlignmentManager"; import {Mat4} from "molstar/lib/mol-math/linear-algebra"; const sequence_101m: string = "MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRVKHLKTEAEMKASEDLKKHGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG"; const alignment = [{ query_begin: 1, query_end: 17, target_begin: 4, target_end: 20 },{ query_begin: 22, query_end: 51, target_begin: 21, target_end: 50 },{ query_begin: 52, query_end: 82, target_begin: 52, target_end: 82 },{ query_begin: 86, query_end: 99, target_begin: 83, target_end: 96 },{ query_begin: 101, query_end: 125, target_begin: 97, target_end: 121 },{ query_begin: 126, query_end: 147, target_begin: 124, target_end: 145 }]; const alignmentManager = new AlignmentManager(alignment); const rowConfig: Array = [ { trackId: "sequenceTrack", trackHeight: 20, trackColor: "#F9F9F9", displayType: RcsbFvDisplayTypes.SEQUENCE, nonEmptyDisplay: true, titleFlagColor: "#317a32", rowTitle: "1ASH SEQUENCE", trackData: [{ begin: 1, value: "ANKTRELCMKSLEHAKVDTSNEARQDGIDLYKHMFENYPPLRKYFKSREEYTAEDVQNDPFFAKQGQKILLACHVLCATYDDRETFNAYTRELLDRHARDHVHMPPEVWTDFWKLFEEYLGKKTTLDEPTKQAWHEIGREFAKEINKHGR" }] },{ trackId: "blockTrack", trackHeight: 20, trackColor: "#F9F9F9", displayType: RcsbFvDisplayTypes.COMPOSITE, displayColor: "#FF0000", titleFlagColor: "#d67600", rowTitle: "101M ALIGNMENT", displayConfig:[{ displayType: RcsbFvDisplayTypes.BLOCK, displayColor: "#9999FF", displayId: "alignmentBlock", displayData: alignment.map(a=>({ begin:a.query_begin, end:a.query_end })) },{ displayType: RcsbFvDisplayTypes.SEQUENCE, displayColor: "#000000", displayId: "alignmentSequence", displayData: alignment.map(a=>({ begin:a.query_begin, value: sequence_101m.substring(a.target_begin-1,a.target_end) })) }] } ]; const fvConfig: FeatureViewInterface = { boardId:"1ash_board", boardConfig: { range: { min: 1, max: 150 }, rowTitleWidth: 190, includeAxis: true }, rowConfig: rowConfig, sequenceSelectionChangeCallback: (plugin: SaguaroPluginPublicInterface, selectorManager: RcsbFvSelectorManager, sequenceRegion: Array) => { selectorManager.clearSelection("select", {modelId:"1ash_model", labelAsymId:"A"}); selectorManager.clearSelection("select", {modelId:"101m_model", labelAsymId:"A"}); if(sequenceRegion.length > 0) { const regions = sequenceRegion.map(r => ({ modelId: "1ash_model", labelAsymId: "A", region: {begin: r.begin, end: r.end ?? r.begin, source: "sequence"} as RegionSelectionInterface })).concat(sequenceRegion.map(r => ({ modelId: "101m_model", labelAsymId: "A", region: {begin: alignmentManager.getTargetPosition(r.begin), end: alignmentManager.getTargetPosition(r.end ?? r.begin), source: "sequence"} as RegionSelectionInterface }))); selectorManager.addSelectionFromMultipleRegions(regions, "select"); plugin.select(regions.map(r => ({ ...r, begin: r.region.begin, end: r.region.end })), "select", "set"); }else{ plugin.removeComponent("1ash_component"); plugin.removeComponent("101m_component"); plugin.clearSelection("select", {modelId: "1ash_model", labelAsymId: "A"}) plugin.clearSelection("select", {modelId: "101m_model", labelAsymId: "A"}) plugin.resetCamera(); } }, sequenceElementClickCallback: async (plugin: SaguaroPluginPublicInterface, selectorManager: RcsbFvSelectorManager, d: RcsbFvTrackDataElementInterface) => { plugin.removeComponent("1ash_component"); plugin.removeComponent("101m_component"); if(d.begin === d.end || !d.end){ await plugin.createComponent("1ash_component", "1ash_model", "A", d.begin, d.begin, "ball-and-stick"); await plugin.createComponent("101m_component", "101m_model", "A", alignmentManager.getTargetPosition(d.begin)!, alignmentManager.getTargetPosition(d.begin)!, "ball-and-stick"); } }, sequenceHoverCallback: (plugin: SaguaroPluginPublicInterface, selectorManager: RcsbFvSelectorManager, elements: Array) => { if (elements == null || elements.length == 0){ plugin.clearSelection("hover"); }else { plugin.select( elements.map(e => ({ modelId: "1ash_model", labelAsymId: "A", begin: e.begin, end: e.end ?? e.begin })).concat( elements.map(e => ({ modelId: "101m_model", labelAsymId: "A", begin: alignmentManager.getTargetPosition(e.begin)!, end: alignmentManager.getTargetPosition(e.end ?? e.begin)! })) ), "hover", "set"); } }, structureSelectionCallback: (plugin: SaguaroPluginPublicInterface, pfv: RcsbFv, selection: RcsbFvSelectorManager) => { const sel_1ash: SaguaroRegionList | undefined = selection.getSelectionWithCondition("1ash_model", "A", "select"); const sel_101m: SaguaroRegionList | undefined = selection.getSelectionWithCondition("101m_model", "A", "select"); pfv.clearSelection("select"); if(sel_1ash == null && sel_101m == null) { plugin.resetCamera(); }else { if(sel_1ash != null) pfv.addSelection({elements: sel_1ash.regions, mode: "select"}); if(sel_101m != null) pfv.addSelection({elements: sel_101m.regions.map(r=>({ ...r, begin: alignmentManager.getQueryPosition(r.begin)!, end: alignmentManager.getQueryPosition(r.end) })), mode: "select"}); } }, structureHoverCallback: (plugin: SaguaroPluginPublicInterface, pfv: RcsbFv, selection: RcsbFvSelectorManager) => { const sel_1ash: SaguaroRegionList | undefined = selection.getSelectionWithCondition("1ash_model", "A", "hover"); const sel_101m: SaguaroRegionList | undefined = selection.getSelectionWithCondition("101m_model", "A", "hover"); if(sel_1ash == null && sel_101m == null) pfv.clearSelection("hover"); else if(sel_1ash) pfv.setSelection({elements:sel_1ash.regions, mode:"hover"}); else if(sel_101m) pfv.setSelection({elements:sel_101m.regions.map(r=>({ ...r, begin: alignmentManager.getQueryPosition(r.begin)!, end: alignmentManager.getQueryPosition(r.end) })), mode:"hover"}); } } const block: FeatureBlockInterface = { blockId:"MyBlock_1", featureViewConfig: [fvConfig] }; const customConfig: CustomViewInterface = { blockConfig:[block] } const sequenceConfig = { title: "Structural alignment example", subtitle: "2 PDB entries and 1 Feature Viewer", config: customConfig }; const molstarConfig: RcsbFvStructureInterface = { loadConfig: { loadMethod: LoadMethod.loadPdbIds, loadParams: [{ pdbId: "1ash", id:"1ash_model" },{ pdbId: "101m", id:"101m_model", matrix:Mat4.ofRows([ [-0.7671995717115603, -0.5623954843039239, 0.30840904072376607, 46.883192662113345], [-0.6011420900233072, 0.4627787494512096, -0.6515090303739346,4.6939156458869125], [0.2236805864799372, -0.6852351043918645, -0.6931232552303105, 5.851782696060043], [0, 0, 0, 1] ]) }] }, pluginConfig: { showImportControls: true, showSessionControls: false } }; const custom3DConfig: RcsbFv3DCustomInterface = { elementId: "pfv", structurePanelConfig: molstarConfig, sequencePanelConfig: sequenceConfig, cssConfig:{ structurePanel:{ minWidth:800, minHeight:800 }, sequencePanel:{ minWidth:800 } } } document.addEventListener("DOMContentLoaded", function(event) { const panel3d = new RcsbFv3DCustom(custom3DConfig); panel3d.render(); });