index.tsx 9.6 KB

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