Browse Source

Sequence Identity 1D3D Alignments

bioinsilico 2 years ago
parent
commit
719e5d1852

+ 9 - 9
package-lock.json

@@ -1,18 +1,18 @@
 {
   "name": "@rcsb/rcsb-saguaro-3d",
-  "version": "2.2.0-uniprot-msa.7",
+  "version": "2.2.0-uniprot-msa.8",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "@rcsb/rcsb-saguaro-3d",
-      "version": "2.2.0-uniprot-msa.7",
+      "version": "2.2.0-uniprot-msa.8",
       "license": "MIT",
       "dependencies": {
         "@rcsb/rcsb-api-tools": "^4.1.0",
         "@rcsb/rcsb-molstar": "^2.5.5",
         "@rcsb/rcsb-saguaro": "^2.2.15",
-        "@rcsb/rcsb-saguaro-app": "^4.4.10",
+        "@rcsb/rcsb-saguaro-app": "^4.4.12",
         "molstar": "^3.13.0"
       },
       "devDependencies": {
@@ -2515,9 +2515,9 @@
       }
     },
     "node_modules/@rcsb/rcsb-saguaro-app": {
-      "version": "4.4.10",
-      "resolved": "https://registry.npmjs.org/@rcsb/rcsb-saguaro-app/-/rcsb-saguaro-app-4.4.10.tgz",
-      "integrity": "sha512-P7nccp4iSnkUY9SIdSCJYVM7+OvzOYxO+t+ZkbiohMQw1sV+a5REcNWt0YYzofQX3ZJQk6/PYs088J4Qw+yzGQ==",
+      "version": "4.4.12",
+      "resolved": "https://registry.npmjs.org/@rcsb/rcsb-saguaro-app/-/rcsb-saguaro-app-4.4.12.tgz",
+      "integrity": "sha512-4dR2mq2jFnHeTa8+QSWLpB0e1XsSZXMU5c7pKG3Frx0PzaQ2gP6yzrowxqrBjQuWbvUFJnpnIa1t3l7FKqJplw==",
       "dependencies": {
         "@rcsb/rcsb-api-tools": "^4.1.0",
         "@rcsb/rcsb-saguaro": "^2.2.15",
@@ -14088,9 +14088,9 @@
       }
     },
     "@rcsb/rcsb-saguaro-app": {
-      "version": "4.4.10",
-      "resolved": "https://registry.npmjs.org/@rcsb/rcsb-saguaro-app/-/rcsb-saguaro-app-4.4.10.tgz",
-      "integrity": "sha512-P7nccp4iSnkUY9SIdSCJYVM7+OvzOYxO+t+ZkbiohMQw1sV+a5REcNWt0YYzofQX3ZJQk6/PYs088J4Qw+yzGQ==",
+      "version": "4.4.12",
+      "resolved": "https://registry.npmjs.org/@rcsb/rcsb-saguaro-app/-/rcsb-saguaro-app-4.4.12.tgz",
+      "integrity": "sha512-4dR2mq2jFnHeTa8+QSWLpB0e1XsSZXMU5c7pKG3Frx0PzaQ2gP6yzrowxqrBjQuWbvUFJnpnIa1t3l7FKqJplw==",
       "requires": {
         "@rcsb/rcsb-api-tools": "^4.1.0",
         "@rcsb/rcsb-saguaro": "^2.2.15",

+ 1 - 1
package.json

@@ -83,7 +83,7 @@
     "@rcsb/rcsb-api-tools": "^4.1.0",
     "@rcsb/rcsb-molstar": "^2.5.5",
     "@rcsb/rcsb-saguaro": "^2.2.15",
-    "@rcsb/rcsb-saguaro-app": "^4.4.10",
+    "@rcsb/rcsb-saguaro-app": "^4.4.12",
     "molstar": "^3.13.0"
   },
   "bugs": {

+ 84 - 0
src/RcsbFv3D/RcsbFv3DSequenceIdentity.tsx

@@ -0,0 +1,84 @@
+import {RcsbFv3DAbstract} from "./RcsbFv3DAbstract";
+import {
+    RcsbFvAdditionalConfig,
+    RcsbFvModulePublicInterface
+} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvModule/RcsbFvModuleInterface";
+import uniqid from "uniqid";
+
+import {LoadMethod, LoadMolstarInterface} from "../RcsbFvStructure/StructureViewers/MolstarViewer/MolstarActionManager";
+import {ViewerProps} from "@rcsb/rcsb-molstar/build/src/viewer";
+
+import {
+    UniprotSequenceOnchangeInterface
+} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvBuilder/RcsbFvUniprotBuilder";
+import {StructureViewer} from "../RcsbFvStructure/StructureViewers/StructureViewer";
+import {MolstarManagerFactory} from "../RcsbFvStructure/StructureViewers/MolstarViewer/MolstarManagerFactory";
+import {
+    UniprotPfvManagerFactory
+} from "../RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/UniprotPfvManagerFactory";
+import {
+    MsaCallbackManagerFactory
+} from "../RcsbFvSequence/SequenceViews/RcsbView/CallbackManagerFactoryImplementation/MsaCallbackManager";
+import {RcsbFvStructure} from "../RcsbFvStructure/RcsbFvStructure";
+import {RcsbFv3DCssConfig} from "./RcsbFv3DComponent";
+import {MolstarAlignmentLoader} from "../RcsbFvStructure/StructureUtils/MolstarAlignmentLoader";
+import {UniprotBehaviourObserver} from "../RcsbFvStructure/StructureViewerBehaviour/UniprotBehaviour";
+import {
+    SequenceIdentityPfvManagerFactory
+} from "../RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/SequenceIdentityPfvManagerFactory";
+import {
+    PolymerEntityInstanceInterface
+} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbCollectTools/DataCollectors/PolymerEntityInstancesCollector";
+
+export interface RcsbFv3DSequenceIdentityInterface  {
+    elementId?: string;
+    config: {
+        groupId: string;
+        title?: string;
+        subtitle?: string;
+    };
+    additionalConfig?:RcsbFvAdditionalConfig;
+    molstarProps?: Partial<ViewerProps>;
+    cssConfig?: RcsbFv3DCssConfig;
+}
+
+export class RcsbFv3DSequenceIdentity extends RcsbFv3DAbstract<{groupId:string},LoadMolstarInterface|undefined,{viewerElement:string|HTMLElement,viewerProps:Partial<ViewerProps>},{context:any,module:RcsbFvModulePublicInterface}> {
+    constructor(params:RcsbFv3DSequenceIdentityInterface){
+        const elementId: string = params.elementId ?? uniqid("RcsbFv3D_");
+        super({
+            elementId,
+            sequenceConfig:{
+                type: "rcsb",
+                title: params.config.title,
+                subtitle: params.config.subtitle,
+                config:{
+                    rcsbId: params.config.groupId,
+                    additionalConfig: params.additionalConfig,
+                    pfvParams:{
+                        groupId:params.config.groupId
+                    },
+                    buildPfvOnMount: true,
+                    pfvManagerFactory: new SequenceIdentityPfvManagerFactory<LoadMolstarInterface>(),
+                    callbackManagerFactory: new MsaCallbackManagerFactory<LoadMolstarInterface, {context:{groupId:string} & Partial<PolymerEntityInstanceInterface>}>({pluginLoadParamsDefinition})
+                }
+            },
+            structureConfig: {
+                loadConfig: undefined,
+                structureViewerConfig: {
+                    viewerElement:RcsbFvStructure.componentId(elementId),
+                    viewerProps: params.molstarProps ?? {}
+                }
+            },
+            structureViewer: new StructureViewer<LoadMolstarInterface,{viewerElement:string|HTMLElement,viewerProps:Partial<ViewerProps>}>( new MolstarManagerFactory() ),
+            structureViewerBehaviourObserver: new UniprotBehaviourObserver<LoadMolstarInterface>(new MolstarAlignmentLoader())
+        });
+    }
+
+}
+
+const pluginLoadParamsDefinition = (entryId:string)=>({
+    loadMethod: LoadMethod.loadPdbId,
+    loadParams:{
+        entryId
+    }
+})

+ 3 - 3
src/RcsbFv3D/RcsbFv3DUniprot.tsx

@@ -17,8 +17,8 @@ import {
     UniprotPfvManagerFactory
 } from "../RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/UniprotPfvManagerFactory";
 import {
-    UniprotCallbackManagerFactory
-} from "../RcsbFvSequence/SequenceViews/RcsbView/CallbackManagerFactoryImplementation/UniprotCallbackManager";
+    MsaCallbackManagerFactory
+} from "../RcsbFvSequence/SequenceViews/RcsbView/CallbackManagerFactoryImplementation/MsaCallbackManager";
 import {RcsbFvStructure} from "../RcsbFvStructure/RcsbFvStructure";
 import {RcsbFv3DCssConfig} from "./RcsbFv3DComponent";
 import {MolstarAlignmentLoader} from "../RcsbFvStructure/StructureUtils/MolstarAlignmentLoader";
@@ -53,7 +53,7 @@ export class RcsbFv3DUniprot extends RcsbFv3DAbstract<{upAcc:string},LoadMolstar
                     },
                     buildPfvOnMount: true,
                     pfvManagerFactory: new UniprotPfvManagerFactory<LoadMolstarInterface>(),
-                    callbackManagerFactory: new UniprotCallbackManagerFactory<LoadMolstarInterface>({pluginLoadParamsDefinition})
+                    callbackManagerFactory: new MsaCallbackManagerFactory<LoadMolstarInterface, {context: UniprotSequenceOnchangeInterface;}>({pluginLoadParamsDefinition})
                 }
             },
             structureConfig: {

+ 6 - 9
src/RcsbFvSequence/SequenceViews/RcsbView/CallbackManagerFactoryImplementation/UniprotCallbackManager.ts → src/RcsbFvSequence/SequenceViews/RcsbView/CallbackManagerFactoryImplementation/MsaCallbackManager.ts

@@ -4,29 +4,27 @@ import {
     CallbackManagerFactoryInterface, CallbackManagerInterface
 } from "../CallbackManagerFactoryInterface";
 import {RcsbFvTrackDataElementInterface} from "@rcsb/rcsb-saguaro";
-import {
-    UniprotSequenceOnchangeInterface
-} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvBuilder/RcsbFvUniprotBuilder";
 import {AlignedRegion, AlignmentResponse} from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
 import {RegionSelectionInterface} from "../../../../RcsbFvState/RcsbFvSelectorManager";
 import {ChainInfo, SaguaroRegionList} from "../../../../RcsbFvStructure/StructureViewerInterface";
 import {TagDelimiter} from "@rcsb/rcsb-saguaro-app";
 import {AlignmentMapper as AM} from "../../../../Utils/AlignmentMapper";
 
-export class UniprotCallbackManagerFactory<R> implements CallbackManagerFactoryInterface<R,{context: UniprotSequenceOnchangeInterface;}> {
+export class MsaCallbackManagerFactory<R,U> implements CallbackManagerFactoryInterface<R,U> {
 
     private readonly pluginLoadParamsDefinition:(id: string)=>R;
     constructor(config: {pluginLoadParamsDefinition:(id: string)=>R}) {
         this.pluginLoadParamsDefinition = config.pluginLoadParamsDefinition;
     }
 
-    getCallbackManager(config: CallbackConfigInterface<R>): CallbackManagerInterface<{context: UniprotSequenceOnchangeInterface;}> {
-        return new UniprotCallbackManager( {...config, loadParamRequest:this.pluginLoadParamsDefinition});
+    getCallbackManager(config: CallbackConfigInterface<R>): CallbackManagerInterface<U> {
+        return new MsaCallbackManager( {...config, loadParamRequest:this.pluginLoadParamsDefinition});
     }
+
 }
 
 type SelectedRegion = {modelId: string, labelAsymId: string, region: RegionSelectionInterface, operatorName?: string};
-class UniprotCallbackManager<R>  extends AbstractCallbackManager<R,{context: UniprotSequenceOnchangeInterface;}>{
+class MsaCallbackManager<R,U>  extends AbstractCallbackManager<R,U>{
 
     private readonly loadParamRequest:(id: string)=>R;
 
@@ -51,7 +49,7 @@ class UniprotCallbackManager<R>  extends AbstractCallbackManager<R,{context: Uni
         return Promise.resolve(undefined);
     }
 
-    async pfvChangeCallback(params:{context: UniprotSequenceOnchangeInterface;}): Promise<void> {
+    async pfvChangeCallback(params:U): Promise<void> {
         if(typeof this.rcsbFvContainer.get() === "undefined")
             return;
         return Promise.resolve(undefined);
@@ -65,7 +63,6 @@ class UniprotCallbackManager<R>  extends AbstractCallbackManager<R,{context: Uni
             allSel.forEach(sel => {
                 const chain: ChainInfo | undefined = this.stateManager.assemblyModelSate.getModelChainInfo(sel.modelId)?.chains.find(ch => ch.entityId == TagDelimiter.parseEntity(sel.modelId).entityId && ch.label == sel.labelAsymId);
                 if (chain) {
-                    sel.regions.forEach(r=>console.log(r));
                     regions = regions.concat(this.getModelRegions(sel.regions.map(r => ({
                         begin: r.begin,
                         end: r.end

+ 7 - 7
src/RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/UniprotPfvComponents/UniprotRowMarkComponent.tsx → src/RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/MsaPfvComponents/MsaRowMarkComponent.tsx

@@ -4,13 +4,13 @@
 */
 
 import React from "react";
-import classes from '../../../../../styles/UniprotPfvStyle.module.scss';
+import classes from '../../../../../styles/MsaPfvStyle.module.scss';
 import {Property} from "csstype";
 import {asyncScheduler, Subscription} from "rxjs";
 import {RcsbFvStateManager} from "../../../../../RcsbFvState/RcsbFvStateManager";
 import {TagDelimiter} from "@rcsb/rcsb-saguaro-app";
 
-interface UniprotRowMarkInterface  {
+interface MsaRowMarkInterface  {
     isGlowing:boolean;
     clickCallback?:()=>void;
     hoverCallback?:()=>void;
@@ -18,23 +18,23 @@ interface UniprotRowMarkInterface  {
     stateManager: RcsbFvStateManager;
 }
 
-interface UniprotRowMarkState {
+interface MsaRowMarkState {
     visibility: Property.Visibility | undefined;
     borderLeftColor: Property.BorderLeftColor | undefined;
     markHoverColor: string;
 }
 
-export class UniprotRowMarkComponent extends React.Component <UniprotRowMarkInterface,UniprotRowMarkState> {
+export class MsaRowMarkComponent extends React.Component <MsaRowMarkInterface,MsaRowMarkState> {
 
     private readonly HOVER_COLOR: string = "rgb(51, 122, 183)";
     private readonly ACTIVE_COLOR: string ="rgb(51, 122, 183)";
     private subscription: Subscription;
 
-    constructor(props:UniprotRowMarkInterface) {
+    constructor(props:MsaRowMarkInterface) {
         super(props);
     }
 
-    readonly state: UniprotRowMarkState = {
+    readonly state: MsaRowMarkState = {
         visibility: undefined,
         borderLeftColor: undefined,
         markHoverColor: this.HOVER_COLOR
@@ -44,7 +44,7 @@ export class UniprotRowMarkComponent extends React.Component <UniprotRowMarkInte
         return (
             <>
                 <div onClick={this.click.bind(this)} onMouseOver={this.hover.bind(this)} style={{visibility: this.state.visibility, cursor:"pointer", display:"inline-block", width:6, height:6, marginBottom: 4, marginRight:5}} >
-                    <div className={classes.uniprotRowMark} onMouseOut={()=>this.markHover(false)}onMouseOver={()=>this.markHover(true)} style={{borderLeftColor: this.props.isGlowing ? this.state.markHoverColor : (this.state.borderLeftColor)}}/>
+                    <div className={classes.msaRowMark} onMouseOut={()=>this.markHover(false)} onMouseOver={()=>this.markHover(true)} style={{borderLeftColor: this.props.isGlowing ? this.state.markHoverColor : (this.state.borderLeftColor)}}/>
                 </div>
             </>
         );

+ 8 - 8
src/RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/UniprotPfvComponents/UniprotRowTitleCheckbox.tsx → src/RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/MsaPfvComponents/MsaRowTitleCheckbox.tsx

@@ -8,7 +8,7 @@ import {RcsbFvStateManager} from "../../../../../RcsbFvState/RcsbFvStateManager"
 import {TagDelimiter} from "@rcsb/rcsb-saguaro-app";
 import {Subscription} from "rxjs";
 
-interface UniprotRowTitleCheckboxInterface {
+interface MsaRowTitleCheckboxInterface {
     disabled:boolean;
     entryId: string;
     entityId: string;
@@ -16,19 +16,19 @@ interface UniprotRowTitleCheckboxInterface {
     stateManager:RcsbFvStateManager
 }
 
-interface UniprotRowTitleCheckboxState {
+interface MsaRowTitleCheckboxState {
     checked:boolean;
 }
 
-export class UniprotRowTitleCheckbox extends React.Component <UniprotRowTitleCheckboxInterface,UniprotRowTitleCheckboxState> {
+export class MsaRowTitleCheckbox extends React.Component <MsaRowTitleCheckboxInterface,MsaRowTitleCheckboxState> {
 
-    readonly state: UniprotRowTitleCheckboxState = {
+    readonly state: MsaRowTitleCheckboxState = {
         checked: this.props.tag == "aligned"
     };
 
     private subscription: Subscription;
 
-    constructor(props: UniprotRowTitleCheckboxInterface) {
+    constructor(props: MsaRowTitleCheckboxInterface) {
         super(props);
         this.subscribe();
     }
@@ -38,7 +38,7 @@ export class UniprotRowTitleCheckbox extends React.Component <UniprotRowTitleChe
         return (<div style={this.style()} onClick={()=>{this.click()}}/>);
     }
 
-    public componentDidUpdate(prevProps: Readonly<UniprotRowTitleCheckboxInterface>, prevState: Readonly<UniprotRowTitleCheckboxState>, snapshot?: any) {
+    public componentDidUpdate(prevProps: Readonly<MsaRowTitleCheckboxInterface>, prevState: Readonly<MsaRowTitleCheckboxState>, snapshot?: any) {
         if(prevProps.disabled != this.props.disabled)
             this.setState({checked:(!this.props.disabled && this.props.tag == "aligned")});
     }
@@ -48,7 +48,7 @@ export class UniprotRowTitleCheckbox extends React.Component <UniprotRowTitleChe
     }
 
     private subscribe(): void{
-        this.subscription = this.props.stateManager.subscribe<"representation-change",{label:string;isHidden:boolean;} & {tag:UniprotRowTitleCheckboxInterface["tag"];isHidden:boolean;pdb:{entryId:string;entityId:string;};}>((o)=>{
+        this.subscription = this.props.stateManager.subscribe<"representation-change",{label:string;isHidden:boolean;} & {tag:MsaRowTitleCheckboxInterface["tag"];isHidden:boolean;pdb:{entryId:string;entityId:string;};}>((o)=>{
             if(o.type == "representation-change" && o.view == "3d-view" && o.data)
                 this.structureViewerRepresentationChange(o.data);
         })
@@ -73,7 +73,7 @@ export class UniprotRowTitleCheckbox extends React.Component <UniprotRowTitleChe
 
     private click(): void {
         this.setState({checked:!this.state.checked},()=>{
-            this.props.stateManager.next<"representation-change",{tag:UniprotRowTitleCheckboxInterface["tag"];isHidden:boolean;pdb:{entryId:string;entityId:string;};}>({
+            this.props.stateManager.next<"representation-change",{tag:MsaRowTitleCheckboxInterface["tag"];isHidden:boolean;pdb:{entryId:string;entityId:string;};}>({
                 view:"1d-view",
                 type: "representation-change",
                 data:{

+ 8 - 8
src/RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/UniprotPfvComponents/UniprotRowTitleComponent.tsx → src/RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/MsaPfvComponents/MsaRowTitleComponent.tsx

@@ -13,23 +13,23 @@ import {TargetAlignment} from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borr
 import {RcsbFvStateManager} from "../../../../../RcsbFvState/RcsbFvStateManager";
 import {Subscription} from "rxjs";
 import {TagDelimiter} from "@rcsb/rcsb-saguaro-app";
-import {UniprotRowTitleCheckbox} from "./UniprotRowTitleCheckbox";
+import {MsaRowTitleCheckbox} from "./MsaRowTitleCheckbox";
 import {MouseEvent} from "react";
 
-interface UniprotRowTitleInterface extends RcsbFvRowTitleInterface {
+interface MsaRowTitleInterface extends RcsbFvRowTitleInterface {
     alignmentContext: AlignmentRequestContextType;
     targetAlignment: TargetAlignment;
     stateManager:RcsbFvStateManager;
     titleClick: ()=>void;
 }
 
-interface UniprotRowTitleState {
+interface MsaRowTitleState {
     expandTitle: boolean;
     disabled: boolean;
     titleColor: string;
 }
 
-export class UniprotRowTitleComponent extends React.Component <UniprotRowTitleInterface, UniprotRowTitleState> {
+export class MsaRowTitleComponent extends React.Component <MsaRowTitleInterface, MsaRowTitleState> {
 
     private readonly configData : RcsbFvRowConfigInterface;
     private subscription: Subscription;
@@ -42,7 +42,7 @@ export class UniprotRowTitleComponent extends React.Component <UniprotRowTitleIn
         titleColor: this.HOVER_COLOR
     };
 
-    constructor(props: UniprotRowTitleInterface) {
+    constructor(props: MsaRowTitleInterface) {
         super(props);
         this.configData = this.props.data;
     }
@@ -57,9 +57,9 @@ export class UniprotRowTitleComponent extends React.Component <UniprotRowTitleIn
                color: this.state.titleColor,
                cursor: "pointer"
            }} onClick={(e: MouseEvent)=>this.click(e)} onMouseOver={()=>this.hover(true)} onMouseOut={()=>this.hover(false)}>{this.props.targetAlignment.target_id}</div>
-           <UniprotRowTitleCheckbox disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"aligned"} stateManager={this.props.stateManager}/>
-           <UniprotRowTitleCheckbox disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"polymer"} stateManager={this.props.stateManager}/>
-           <UniprotRowTitleCheckbox disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"non-polymer"} stateManager={this.props.stateManager}/>
+           <MsaRowTitleCheckbox disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"aligned"} stateManager={this.props.stateManager}/>
+           <MsaRowTitleCheckbox disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"polymer"} stateManager={this.props.stateManager}/>
+           <MsaRowTitleCheckbox disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"non-polymer"} stateManager={this.props.stateManager}/>
        </div>;
     }
 

+ 113 - 0
src/RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/SequenceIdentityPfvManagerFactory.ts

@@ -0,0 +1,113 @@
+import {
+    AbstractPfvManager,
+    PfvManagerFactoryConfigInterface,
+    PfvManagerInterface,
+    PfvManagerFactoryInterface
+} from "../PfvManagerFactoryInterface";
+import {
+    RcsbFvModulePublicInterface
+} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvModule/RcsbFvModuleInterface";
+import {TagDelimiter, buildSequenceIdentityAlignmentFv} from "@rcsb/rcsb-saguaro-app";
+
+import {
+    AlignmentRequestContextType
+} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvFactories/RcsbFvTrackFactory/TrackFactoryImpl/AlignmentTrackFactory";
+import {AlignmentResponse, TargetAlignment} from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
+import {MsaRowTitleComponent} from "./MsaPfvComponents/MsaRowTitleComponent";
+import {MsaRowMarkComponent} from "./MsaPfvComponents/MsaRowMarkComponent";
+import {
+    PolymerEntityInstanceInterface
+} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbCollectTools/DataCollectors/PolymerEntityInstancesCollector";
+
+interface SequenceIdentityPfvManagerInterface<R> extends PfvManagerFactoryConfigInterface<R,{context: {groupId:string};}> {
+    groupId:string;
+}
+
+export class SequenceIdentityPfvManagerFactory<R> implements PfvManagerFactoryInterface<{groupId:string},R,{context: {groupId:string};}> {
+
+    getPfvManager(config: SequenceIdentityPfvManagerInterface<R>): PfvManagerInterface {
+        return new SequenceIdentityPfvManager(config);
+    }
+
+}
+
+type AlignmentDataType = {
+    pdb:{
+        entryId:string;
+        entityId:string;
+    },
+    targetAlignment: TargetAlignment;
+};
+
+class SequenceIdentityPfvManager<R> extends AbstractPfvManager<{groupId:string},R,{context: {groupId:string} &  Partial<PolymerEntityInstanceInterface>;}>{
+
+    private readonly groupId:string;
+
+    private module:RcsbFvModulePublicInterface;
+
+    constructor(config:SequenceIdentityPfvManagerInterface<R>) {
+        super(config);
+        this.groupId = config.groupId;
+    }
+
+    async create(): Promise<RcsbFvModulePublicInterface | undefined> {
+        this.module = await buildSequenceIdentityAlignmentFv(
+            this.rcsbFvDivId,
+            this.groupId,
+            undefined,
+            {
+                ... this.additionalConfig,
+                boardConfig: this.boardConfigContainer.get(),
+                trackConfigModifier: {
+                    alignment: (alignmentContext: AlignmentRequestContextType, targetAlignment: TargetAlignment) => new Promise((resolve)=>{
+                        resolve({
+                            rowMark:{
+                                externalRowMark: {
+                                    component:MsaRowMarkComponent,
+                                    props:{
+                                        rowRef:TagDelimiter.parseEntity(targetAlignment.target_id!),
+                                        stateManager: this.stateManager
+                                    }
+                                },
+                                clickCallback:() => this.loadAlignment(alignmentContext,targetAlignment)
+                            },
+                            externalRowTitle: {
+                                rowTitleComponent:MsaRowTitleComponent,
+                                rowTitleAdditionalProps:{
+                                    alignmentContext,
+                                    targetAlignment,
+                                    stateManager: this.stateManager,
+                                    titleClick: ()=> this.loadAlignment(alignmentContext,targetAlignment)
+                                }
+                            }
+                        });
+                    })
+                }
+            }
+        );
+        this.rcsbFvContainer.set(this.module);
+        await this.readyStateLoad();
+        return this.module;
+    }
+
+    private async readyStateLoad(): Promise<void> {
+        const alignments: AlignmentResponse = await this.module.getAlignmentResponse();
+        if(alignments.target_alignment && alignments.target_alignment.length > 0 && typeof alignments.target_alignment[0]?.target_id === "string"){
+            this.loadAlignment({queryId:this.groupId}, alignments.target_alignment[0]);
+        }
+    }
+
+    private loadAlignment(alignmentContext: AlignmentRequestContextType, targetAlignment: TargetAlignment):void {
+        if(typeof targetAlignment.target_id === "string") {
+            this.stateManager.next<"model-change",AlignmentDataType>({
+                type:"model-change",
+                view:"1d-view",
+                data:{
+                    pdb:TagDelimiter.parseEntity(targetAlignment.target_id),
+                    targetAlignment
+                }
+            });
+        }
+    }
+
+}

+ 4 - 4
src/RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/UniprotPfvManagerFactory.ts

@@ -15,8 +15,8 @@ import {
     AlignmentRequestContextType
 } from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvFactories/RcsbFvTrackFactory/TrackFactoryImpl/AlignmentTrackFactory";
 import {AlignmentResponse, TargetAlignment} from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
-import {UniprotRowTitleComponent} from "./UniprotPfvComponents/UniprotRowTitleComponent";
-import {UniprotRowMarkComponent} from "./UniprotPfvComponents/UniprotRowMarkComponent";
+import {MsaRowTitleComponent} from "./MsaPfvComponents/MsaRowTitleComponent";
+import {MsaRowMarkComponent} from "./MsaPfvComponents/MsaRowMarkComponent";
 
 interface UniprotPfvManagerInterface<R> extends PfvManagerFactoryConfigInterface<R,{context: UniprotSequenceOnchangeInterface;}> {
     upAcc:string;
@@ -60,7 +60,7 @@ class UniprotPfvManager<R> extends AbstractPfvManager<{upAcc:string},R,{context:
                         resolve({
                             rowMark:{
                                 externalRowMark: {
-                                    component:UniprotRowMarkComponent,
+                                    component:MsaRowMarkComponent,
                                     props:{
                                         rowRef:TagDelimiter.parseEntity(targetAlignment.target_id!),
                                         stateManager: this.stateManager
@@ -69,7 +69,7 @@ class UniprotPfvManager<R> extends AbstractPfvManager<{upAcc:string},R,{context:
                                 clickCallback:() => this.loadAlignment(alignmentContext,targetAlignment)
                             },
                             externalRowTitle: {
-                                rowTitleComponent:UniprotRowTitleComponent,
+                                rowTitleComponent:MsaRowTitleComponent,
                                 rowTitleAdditionalProps:{
                                     alignmentContext,
                                     targetAlignment,

+ 16 - 0
src/examples/sequence-identity/index.ts

@@ -0,0 +1,16 @@
+
+import {RcsbFv3DSequenceIdentity} from "../../RcsbFv3D/RcsbFv3DSequenceIdentity";
+
+document.addEventListener("DOMContentLoaded", function(event) {
+
+    const panel3d = new RcsbFv3DSequenceIdentity({
+        config:{
+            groupId:"1_30",
+            title: "Title >> Sequence Identity 1_30",
+            subtitle: "Subtitle >> Sequence Identity 1_30",
+        }
+    });
+    panel3d.render();
+
+});
+

+ 1 - 1
src/styles/UniprotPfvStyle.module.scss → src/styles/MsaPfvStyle.module.scss

@@ -1,5 +1,5 @@
 
-.uniprotRowMark {
+.msaRowMark {
   width: 0;
   height: 0;
   border-top: 6px solid transparent;

+ 1 - 1
webpack.server.dev.config.js

@@ -39,7 +39,7 @@ const commonConfig = {
     devtool: 'source-map'
 };
 
-const examples = ['assembly','uniprot','structural-alignment'];
+const examples = ['assembly','uniprot','structural-alignment','sequence-identity'];
 const entries = examples.reduce((prev,current)=>{prev[current]=`./src/examples/${current}/index.ts`;return prev;},{});
 
 const server = {