index.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import {RcsbFv3DCustom, RcsbFv3DCustomInterface} from "../../RcsbFv3D/RcsbFv3DCustom";
  2. import {RcsbFvStructureConfigInterface} from "../../RcsbFvStructure/RcsbFvStructure";
  3. import {
  4. CustomViewInterface,
  5. FeatureBlockInterface,
  6. FeatureViewInterface
  7. } from "../../RcsbFvSequence/SequenceViews/CustomView/CustomView";
  8. import {
  9. RcsbFv,
  10. RcsbFvDisplayTypes,
  11. RcsbFvRowConfigInterface,
  12. RcsbFvTrackDataElementInterface
  13. } from "@rcsb/rcsb-saguaro";
  14. import {
  15. RcsbFvSelectorManager,
  16. RegionSelectionInterface
  17. } from "../../RcsbFvState/RcsbFvSelectorManager";
  18. import {StructureViewerPublicInterface, SaguaroRegionList} from "../../RcsbFvStructure/StructureViewerInterface";
  19. import {AlignmentManager} from "./AlignmentManager";
  20. import {Mat4} from "molstar/lib/mol-math/linear-algebra";
  21. import {
  22. LoadMethod,
  23. LoadMolstarInterface
  24. } from "../../RcsbFvStructure/StructureViewers/MolstarViewer/MolstarActionManager";
  25. import {ViewerProps} from "@rcsb/rcsb-molstar/build/src/viewer";
  26. import {RcsbFvStateManager} from "../../RcsbFvState/RcsbFvStateManager";
  27. const sequence_101m: string = "MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRVKHLKTEAEMKASEDLKKHGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG";
  28. const alignment = [{
  29. query_begin: 1,
  30. query_end: 17,
  31. target_begin: 4,
  32. target_end: 20
  33. },{
  34. query_begin: 22,
  35. query_end: 51,
  36. target_begin: 21,
  37. target_end: 50
  38. },{
  39. query_begin: 52,
  40. query_end: 82,
  41. target_begin: 52,
  42. target_end: 82
  43. },{
  44. query_begin: 86,
  45. query_end: 99,
  46. target_begin: 83,
  47. target_end: 96
  48. },{
  49. query_begin: 101,
  50. query_end: 125,
  51. target_begin: 97,
  52. target_end: 121
  53. },{
  54. query_begin: 126,
  55. query_end: 147,
  56. target_begin: 124,
  57. target_end: 145
  58. }];
  59. const alignmentManager = new AlignmentManager(alignment);
  60. const rowConfig: Array<RcsbFvRowConfigInterface> = [
  61. {
  62. trackId: "sequenceTrack",
  63. trackHeight: 20,
  64. trackColor: "#F9F9F9",
  65. displayType: RcsbFvDisplayTypes.SEQUENCE,
  66. nonEmptyDisplay: true,
  67. titleFlagColor: "#317a32",
  68. rowTitle: "1ASH SEQUENCE",
  69. trackData: [{
  70. begin: 1,
  71. value: "ANKTRELCMKSLEHAKVDTSNEARQDGIDLYKHMFENYPPLRKYFKSREEYTAEDVQNDPFFAKQGQKILLACHVLCATYDDRETFNAYTRELLDRHARDHVHMPPEVWTDFWKLFEEYLGKKTTLDEPTKQAWHEIGREFAKEINKHGR"
  72. }]
  73. },{
  74. trackId: "blockTrack",
  75. trackHeight: 20,
  76. trackColor: "#F9F9F9",
  77. displayType: RcsbFvDisplayTypes.COMPOSITE,
  78. displayColor: "#FF0000",
  79. titleFlagColor: "#d67600",
  80. rowTitle: "101M ALIGNMENT",
  81. displayConfig:[{
  82. displayType: RcsbFvDisplayTypes.BLOCK,
  83. displayColor: "#9999FF",
  84. displayId: "alignmentBlock",
  85. displayData: alignment.map(a=>({
  86. begin:a.query_begin,
  87. end:a.query_end
  88. }))
  89. },{
  90. displayType: RcsbFvDisplayTypes.SEQUENCE,
  91. displayColor: "#000000",
  92. displayId: "alignmentSequence",
  93. displayData: alignment.map(a=>({
  94. begin:a.query_begin,
  95. value: sequence_101m.substring(a.target_begin-1,a.target_end)
  96. }))
  97. }]
  98. }
  99. ];
  100. const fvConfig: FeatureViewInterface<LoadMolstarInterface> = {
  101. boardId:"1ash_board",
  102. boardConfig: {
  103. range: {
  104. min: 1,
  105. max: 150
  106. },
  107. disableMenu:true,
  108. rowTitleWidth: 70,
  109. trackWidth: 530,
  110. includeAxis: true
  111. },
  112. rowConfig: rowConfig,
  113. sequenceSelectionChangeCallback: (plugin: StructureViewerPublicInterface<LoadMolstarInterface>, stateManager: RcsbFvStateManager, sequenceRegion: Array<RcsbFvTrackDataElementInterface>) => {
  114. stateManager.selectionState.clearSelection("select", {modelId:"1ash_model", labelAsymId:"A"});
  115. stateManager.selectionState.clearSelection("select", {modelId:"101m_model", labelAsymId:"A"});
  116. if(sequenceRegion.length > 0) {
  117. const regions = sequenceRegion.map(r => ({
  118. modelId: "1ash_model",
  119. labelAsymId: "A",
  120. region: {begin: r.begin, end: r.end ?? r.begin, source: "sequence"} as RegionSelectionInterface
  121. })).concat(sequenceRegion.map(r => ({
  122. modelId: "101m_model",
  123. labelAsymId: "A",
  124. region: {begin: alignmentManager.getTargetPosition(r.begin), end: alignmentManager.getTargetPosition(r.end ?? r.begin), source: "sequence"} as RegionSelectionInterface
  125. })));
  126. stateManager.selectionState.addSelectionFromMultipleRegions(regions, "select");
  127. plugin.select(regions.map(r => ({
  128. ...r,
  129. begin: r.region.begin,
  130. end: r.region.end
  131. })), "select", "set");
  132. }else{
  133. plugin.removeComponent("1ash_component");
  134. plugin.removeComponent("101m_component");
  135. plugin.clearSelection("select", {modelId: "1ash_model", labelAsymId: "A"})
  136. plugin.clearSelection("select", {modelId: "101m_model", labelAsymId: "A"})
  137. plugin.resetCamera();
  138. }
  139. },
  140. sequenceElementClickCallback: async (plugin: StructureViewerPublicInterface<LoadMolstarInterface>, stateManager: RcsbFvStateManager, d: RcsbFvTrackDataElementInterface) => {
  141. plugin.removeComponent("1ash_component");
  142. plugin.removeComponent("101m_component");
  143. if(d.begin === d.end || !d.end){
  144. await plugin.createComponent("1ash_component", "1ash_model", "A", d.begin, d.begin, "ball-and-stick");
  145. await plugin.createComponent("101m_component", "101m_model", "A", alignmentManager.getTargetPosition(d.begin)!, alignmentManager.getTargetPosition(d.begin)!, "ball-and-stick");
  146. }
  147. },
  148. sequenceHoverCallback: (plugin: StructureViewerPublicInterface<LoadMolstarInterface>, stateManager: RcsbFvStateManager, elements: Array<RcsbFvTrackDataElementInterface>) => {
  149. if (elements == null || elements.length == 0){
  150. plugin.clearSelection("hover");
  151. }else {
  152. plugin.select(
  153. elements.map(e => ({
  154. modelId: "1ash_model",
  155. labelAsymId: "A",
  156. begin: e.begin,
  157. end: e.end ?? e.begin
  158. })).concat(
  159. elements.map(e => ({
  160. modelId: "101m_model",
  161. labelAsymId: "A",
  162. begin: alignmentManager.getTargetPosition(e.begin)!,
  163. end: alignmentManager.getTargetPosition(e.end ?? e.begin)!
  164. }))
  165. ), "hover", "set");
  166. }
  167. },
  168. structureSelectionCallback: (plugin: StructureViewerPublicInterface<LoadMolstarInterface>, pfv: RcsbFv, stateManager: RcsbFvStateManager) => {
  169. const sel_1ash: SaguaroRegionList | undefined = stateManager.selectionState.getSelectionWithCondition("1ash_model", "A", "select");
  170. const sel_101m: SaguaroRegionList | undefined = stateManager.selectionState.getSelectionWithCondition("101m_model", "A", "select");
  171. pfv.clearSelection("select");
  172. if(sel_1ash == null && sel_101m == null) {
  173. plugin.resetCamera();
  174. }else {
  175. if(sel_1ash != null)
  176. pfv.addSelection({elements: sel_1ash.regions, mode: "select"});
  177. if(sel_101m != null)
  178. pfv.addSelection({elements: sel_101m.regions.map(r=>({
  179. ...r,
  180. begin: alignmentManager.getQueryPosition(r.begin)!,
  181. end: alignmentManager.getQueryPosition(r.end)
  182. })), mode: "select"});
  183. }
  184. },
  185. structureHoverCallback: (plugin: StructureViewerPublicInterface<LoadMolstarInterface>, pfv: RcsbFv, stateManager: RcsbFvStateManager) => {
  186. const sel_1ash: SaguaroRegionList | undefined = stateManager.selectionState.getSelectionWithCondition("1ash_model", "A", "hover");
  187. const sel_101m: SaguaroRegionList | undefined = stateManager.selectionState.getSelectionWithCondition("101m_model", "A", "hover");
  188. if(sel_1ash == null && sel_101m == null)
  189. pfv.clearSelection("hover");
  190. else if(sel_1ash)
  191. pfv.setSelection({elements:sel_1ash.regions, mode:"hover"});
  192. else if(sel_101m)
  193. pfv.setSelection({elements:sel_101m.regions.map(r=>({
  194. ...r,
  195. begin: alignmentManager.getQueryPosition(r.begin)!,
  196. end: alignmentManager.getQueryPosition(r.end)
  197. })), mode:"hover"});
  198. }
  199. }
  200. const block: FeatureBlockInterface<LoadMolstarInterface> = {
  201. blockId:"MyBlock_1",
  202. featureViewConfig: [fvConfig]
  203. };
  204. const customConfig: CustomViewInterface<LoadMolstarInterface> = {
  205. blockConfig:[block]
  206. }
  207. const sequenceConfig = {
  208. title: undefined,
  209. subtitle: undefined,
  210. config: customConfig
  211. };
  212. const molstarConfig: RcsbFvStructureConfigInterface<LoadMolstarInterface,{viewerElement:string|HTMLElement,viewerProps:Partial<ViewerProps>}> = {
  213. loadConfig: {
  214. loadMethod: LoadMethod.loadPdbIds,
  215. loadParams: [{
  216. pdbId: "1ash",
  217. id:"1ash_model"
  218. },{
  219. pdbId: "101m",
  220. id:"101m_model",
  221. matrix:Mat4.ofRows([
  222. [-0.7671995717115603, -0.5623954843039239, 0.30840904072376607, 46.883192662113345],
  223. [-0.6011420900233072, 0.4627787494512096, -0.6515090303739346,4.6939156458869125],
  224. [0.2236805864799372, -0.6852351043918645, -0.6931232552303105, 5.851782696060043],
  225. [0, 0, 0, 1]
  226. ])
  227. }]
  228. },
  229. structureViewerConfig: {
  230. viewerElement:"pfv",
  231. viewerProps:{
  232. showImportControls: true,
  233. showSessionControls: false
  234. }
  235. }
  236. };
  237. const custom3DConfig: RcsbFv3DCustomInterface = {
  238. elementId: "pfv",
  239. structurePanelConfig: molstarConfig,
  240. sequencePanelConfig: sequenceConfig,
  241. cssConfig:{
  242. overwriteCss:true,
  243. rootPanel:{
  244. display:"flex",
  245. flexDirection:"column-reverse"
  246. },
  247. structurePanel:{
  248. width: 600,
  249. height: 600,
  250. minWidth: 400,
  251. minHeight: 400
  252. },
  253. sequencePanel:{
  254. minWidth:400,
  255. width:600,
  256. marginBottom:5
  257. }
  258. }
  259. }
  260. document.addEventListener("DOMContentLoaded", function(event) {
  261. const panel3d = new RcsbFv3DCustom(custom3DConfig);
  262. panel3d.render();
  263. });