Browse Source

LoadParamsProviderInterface

bioinsilico 2 years ago
parent
commit
c3f8e9e14b

File diff suppressed because it is too large
+ 0 - 0
docs/assets/main.js


+ 5 - 14
src/RcsbFv3D/RcsbFv3DAlignmentProvider.tsx

@@ -33,8 +33,7 @@ import {
 } from "../RcsbFvSequence/SequenceViews/RcsbView/PfvManagerFactoryImplementation/MsaPfvManagerFactory";
 import {buildDataProviderFv} from "@rcsb/rcsb-saguaro-app";
 import {
-    LocationProviderInterface,
-    TransformProviderInterface
+    LoadParamsProviderInterface
 } from "../RcsbFvStructure/StructureUtils/StructureLoaderInterface";
 
 import {
@@ -49,17 +48,13 @@ import {AbstractViewInterface} from "../RcsbFvSequence/SequenceViews/AbstractVie
 import {
     AlignmentProviderBehaviour
 } from "../RcsbFvSequence/SequenceViews/RcsbView/RcsbViewBehaviour/AlignmentProviderBehaviour";
-import {
-    FelxibleAlignmentTrajectoryParamsType
-} from "../RcsbFvStructure/StructureViewers/MolstarViewer/TrajectoryPresetProvider/FlexibleAlignmentTrajectoryPresetProvider";
 import {TrajectoryHierarchyPresetProvider} from "molstar/lib/mol-plugin-state/builder/structure/hierarchy-preset";
 
 export interface RcsbFv3DDataProviderInterface  {
     elementId?: string;
     config: {
         dataProvider: RcsbModuleDataProviderInterface;
-        transformProvider?: TransformProviderInterface;
-        structureLocationProvider?: LocationProviderInterface;
+        loadParamsProvider?: LoadParamsProviderInterface<{entryId: string; instanceId: string;},LoadMolstarInterface<AlignmentTrajectoryParamsType,LoadMolstarReturnType>>;
         title?: string;
         subtitle?: string;
         additionalContent?(props: AbstractViewInterface): JSX.Element;
@@ -67,10 +62,10 @@ export interface RcsbFv3DDataProviderInterface  {
     additionalConfig?: RcsbFvAdditionalConfig;
     molstarProps?: Partial<ViewerProps>;
     cssConfig?: RcsbFv3DCssConfig;
-    trajectoryProvider?: TrajectoryHierarchyPresetProvider<AlignmentTrajectoryParamsType|FelxibleAlignmentTrajectoryParamsType,LoadMolstarReturnType>;
+    trajectoryProvider?: TrajectoryHierarchyPresetProvider<AlignmentTrajectoryParamsType,LoadMolstarReturnType>;
 }
 
-type AlignmentLoadMolstarType = LoadMolstarInterface<AlignmentTrajectoryParamsType|FelxibleAlignmentTrajectoryParamsType,LoadMolstarReturnType>;
+type AlignmentLoadMolstarType = LoadMolstarInterface<AlignmentTrajectoryParamsType,LoadMolstarReturnType>;
 export class RcsbFv3DAlignmentProvider extends RcsbFv3DAbstract<
         MsaPfvManagerInterface<[RcsbModuleDataProviderInterface]>,
         AlignmentLoadMolstarType|undefined,
@@ -119,11 +114,7 @@ export class RcsbFv3DAlignmentProvider extends RcsbFv3DAbstract<
                 {viewerElement:string|HTMLElement,viewerProps:Partial<ViewerProps>}
             >( new MolstarManagerFactory(getModelIdFromTrajectory) ),
             structureViewerBehaviourObserver: new MsaBehaviourObserver<AlignmentLoadMolstarType,LoadMolstarReturnType>(
-                new MolstarAlignmentLoader({
-                    transformProvider: params.config.transformProvider,
-                    structureLocationProvider: params.config.structureLocationProvider,
-                    trajectoryProvider: params.trajectoryProvider
-                }),
+                new MolstarAlignmentLoader(params.config.loadParamsProvider),
                 new MolstarComponentActionFactory()
             )
         });

+ 2 - 5
src/RcsbFvStructure/StructureUtils/StructureLoaderInterface.ts

@@ -12,10 +12,7 @@ export type RigidTransformType =  {
     transform: TransformMatrixType,
     regions?: [number,number][]
 };
-export interface TransformProviderInterface {
-    get(entryId:string, asymId?:string): RigidTransformType[] | undefined;
-}
 
-export interface LocationProviderInterface {
-    get(entryId:string): string | undefined;
+export interface LoadParamsProviderInterface<X,R> {
+    get(args: X): R;
 }

+ 21 - 51
src/RcsbFvStructure/StructureViewers/MolstarViewer/MolstarUtils/MolstarAlignmentLoader.ts

@@ -4,9 +4,8 @@
 */
 
 import {
-    LocationProviderInterface,
-    StructureLoaderInterface,
-    TransformProviderInterface
+    LoadParamsProviderInterface,
+    StructureLoaderInterface
 } from "../../../StructureUtils/StructureLoaderInterface";
 import {ViewerActionManagerInterface} from "../../../StructureViewerInterface";
 import {
@@ -20,73 +19,44 @@ import {
     AlignmentTrajectoryParamsType
 } from "../TrajectoryPresetProvider/AlignmentTrajectoryPresetProvider";
 import {TargetAlignment} from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
-import {
-    FelxibleAlignmentTrajectoryParamsType,
-    FlexibleAlignmentTrajectoryPresetProvider
-} from "../TrajectoryPresetProvider/FlexibleAlignmentTrajectoryPresetProvider";
-import {TrajectoryHierarchyPresetProvider} from "molstar/lib/mol-plugin-state/builder/structure/hierarchy-preset";
+
 
 export class MolstarAlignmentLoader implements StructureLoaderInterface<[
-        ViewerActionManagerInterface<LoadMolstarInterface<AlignmentTrajectoryParamsType|FelxibleAlignmentTrajectoryParamsType,LoadMolstarReturnType>,LoadMolstarReturnType>,
+        ViewerActionManagerInterface<LoadMolstarInterface<AlignmentTrajectoryParamsType,LoadMolstarReturnType>,LoadMolstarReturnType>,
         {entryId:string;entityId:string;}|{entryId:string;instanceId:string;},
         TargetAlignment
     ], LoadMolstarReturnType> {
 
-    private readonly transformProvider?: TransformProviderInterface;
-    private readonly structureLocationProvider?: LocationProviderInterface;
-    private readonly trajectoryProvider?: TrajectoryHierarchyPresetProvider<AlignmentTrajectoryParamsType|FelxibleAlignmentTrajectoryParamsType,LoadMolstarReturnType>;
-    constructor(loadConfig?:{
-        transformProvider?: TransformProviderInterface;
-        structureLocationProvider?: LocationProviderInterface,
-        trajectoryProvider?: TrajectoryHierarchyPresetProvider<AlignmentTrajectoryParamsType|FelxibleAlignmentTrajectoryParamsType,LoadMolstarReturnType>
-    }) {
-        this.transformProvider = loadConfig?.transformProvider;
-        this.structureLocationProvider = loadConfig?.structureLocationProvider;
-        this.trajectoryProvider = loadConfig?.trajectoryProvider;
+    private readonly loadParamsProvider?: LoadParamsProviderInterface<{entryId: string; instanceId: string;}, LoadMolstarInterface<AlignmentTrajectoryParamsType,LoadMolstarReturnType>>;
+    constructor(loadParamsProvider?: LoadParamsProviderInterface<{entryId: string; instanceId: string;}, LoadMolstarInterface<AlignmentTrajectoryParamsType,LoadMolstarReturnType>>) {
+        this.loadParamsProvider = loadParamsProvider;
     }
     private readonly structureMap: Set<string> = new Set<string>();
 
     async load(
-        structureViewer: ViewerActionManagerInterface<LoadMolstarInterface<AlignmentTrajectoryParamsType|FelxibleAlignmentTrajectoryParamsType,LoadMolstarReturnType>,LoadMolstarReturnType>,
+        structureViewer: ViewerActionManagerInterface<LoadMolstarInterface<AlignmentTrajectoryParamsType,LoadMolstarReturnType>,LoadMolstarReturnType>,
         pdb:{entryId:string;entityId:string;}|{entryId:string;instanceId:string;},
         targetAlignment: TargetAlignment
     ): Promise<undefined|LoadMolstarReturnType> {
         const structureId: string = `${pdb.entryId}${"entityId" in pdb ? TagDelimiter.entity : TagDelimiter.instance}${"entityId" in pdb ? pdb.entityId : pdb.instanceId}`;
         if(!this.structureMap.has(structureId)){
-            const url: string|undefined = this.structureLocationProvider?.get(pdb.entryId);
-            const transform = ("instanceId" in pdb ? this.transformProvider?.get(pdb.entryId, pdb.instanceId) : undefined) ?? undefined;
-            const provider = !transform?.length || transform.length == 1 ? {
-                reprProvider: this.trajectoryProvider ?? AlignmentTrajectoryPresetProvider,
-                params:{
-                    modelIndex: 0,
-                    pdb,
-                    targetAlignment,
-                    transform: transform
-                }
-            } : {
-                reprProvider: this.trajectoryProvider ?? FlexibleAlignmentTrajectoryPresetProvider,
-                params:{
-                    modelIndex: 0,
-                    pdb,
-                    targetAlignment,
-                    transform: transform
-                }
-            };
-            const trajectory = await structureViewer.load({
-                loadMethod: url ? LoadMethod.loadStructureFromUrl : LoadMethod.loadPdbId,
+            this.structureMap.add(
+                structureId
+            );
+            const loadParams = 'instanceId' in pdb ? this.loadParamsProvider?.get(pdb) : undefined;
+            return loadParams ? await structureViewer.load(loadParams) : await structureViewer.load({
+                loadMethod: LoadMethod.loadPdbId,
                 loadParams: {
-                    url,
-                    format: url ? "mmcif" : undefined,
-                    isBinary: url ? false : undefined,
                     id: structureId,
-                    entryId:pdb.entryId,
-                    ...provider
+                    entryId: pdb.entryId,
+                    reprProvider: AlignmentTrajectoryPresetProvider,
+                    params:{
+                        modelIndex: 0,
+                        pdb,
+                        targetAlignment
+                    }
                 }
             });
-            this.structureMap.add(
-                structureId
-            );
-            return trajectory;
         } else {
             await structureViewer.removeStructure({
                 loadMethod: LoadMethod.loadPdbId,

+ 1 - 1
src/RcsbFvStructure/StructureViewers/MolstarViewer/TrajectoryPresetProvider/AlignmentTrajectoryPresetProvider.ts

@@ -14,7 +14,7 @@ import {StateObject} from "molstar/lib/mol-state/object";
 import {AlignmentRepresentationPresetProvider} from "./AlignmentRepresentationPresetProvider";
 import {TargetAlignment} from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
 import {Structure, StructureElement, StructureProperties as SP} from "molstar/lib/mol-model/structure";
-import {RigidTransformType, TransformMatrixType} from "../../../StructureUtils/StructureLoaderInterface";
+import {RigidTransformType} from "../../../StructureUtils/StructureLoaderInterface";
 
 
 export type AlignmentTrajectoryParamsType = {

+ 6 - 12
src/RcsbFvStructure/StructureViewers/MolstarViewer/TrajectoryPresetProvider/FlexibleAlignmentTrajectoryPresetProvider.ts

@@ -9,20 +9,13 @@ import {PluginStateObject} from "molstar/lib/mol-plugin-state/objects";
 import {ParamDefinition, ParamDefinition as PD} from "molstar/lib/mol-util/param-definition";
 import {StateObjectRef, StateObjectSelector} from "molstar/lib/mol-state";
 import {RootStructureDefinition} from "molstar/lib/mol-plugin-state/helpers/root-structure";
-import {StateTransformer} from "molstar/lib/mol-state/transformer";
 import {StateObject} from "molstar/lib/mol-state/object";
 import {Structure, StructureElement, StructureProperties as SP} from "molstar/lib/mol-model/structure";
 import {RigidTransformType, TransformMatrixType} from "../../../StructureUtils/StructureLoaderInterface";
 import {FlexibleAlignmentRepresentationPresetProvider} from "./FlexibleAlignmentRepresentationPresetProvider";
 import {FlexibleAlignmentBuiltIn} from "./FlexibleAlignmentBuiltIn";
-
-export type FelxibleAlignmentTrajectoryParamsType = {
-    pdb?:{entryId:string;entityId:string;}|{entryId:string;instanceId:string;};
-    transform?: RigidTransformType[];
-    modelIndex?: number;
-}
-
-type StructureObject = StateObjectSelector<PluginStateObject.Molecule.Structure, StateTransformer<StateObject<any, StateObject.Type<any>>, StateObject<any, StateObject.Type<any>>, any>>
+import {AlignmentTrajectoryParamsType} from "./AlignmentTrajectoryPresetProvider";
+import {TargetAlignment} from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
 
 export const FlexibleAlignmentTrajectoryPresetProvider = TrajectoryHierarchyPresetProvider({
     id: 'alignment-to-reference',
@@ -30,12 +23,13 @@ export const FlexibleAlignmentTrajectoryPresetProvider = TrajectoryHierarchyPres
         name: 'Alignment to Reference'
     },
     isApplicable: (trajectory: PluginStateObject.Molecule.Trajectory, plugin: PluginContext): boolean => true,
-    params: (trajectory: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext): ParamDefinition.For<FelxibleAlignmentTrajectoryParamsType> => ({
+    params: (trajectory: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext): ParamDefinition.For<AlignmentTrajectoryParamsType> => ({
         pdb:PD.Value<{entryId:string;entityId:string;}|{entryId:string;instanceId:string;}|undefined>(undefined),
         modelIndex:PD.Value<number|undefined>(undefined),
-        transform:PD.Value<RigidTransformType[]|undefined>(undefined)
+        transform:PD.Value<RigidTransformType[]|undefined>(undefined),
+        targetAlignment: PD.Value<TargetAlignment|undefined>(undefined),
     }),
-    apply: async (trajectory: StateObjectRef<PluginStateObject.Molecule.Trajectory>, params: FelxibleAlignmentTrajectoryParamsType, plugin: PluginContext) => {
+    apply: async (trajectory: StateObjectRef<PluginStateObject.Molecule.Trajectory>, params: AlignmentTrajectoryParamsType, plugin: PluginContext) => {
         if(!params.pdb)
             return {};
         const modelParams = { modelIndex: params.modelIndex || 0 };

+ 2 - 3
src/examples/alignment-provider/index.ts

@@ -1,13 +1,12 @@
 import {RcsbFv3DAlignmentProvider} from "../../RcsbFv3D/RcsbFv3DAlignmentProvider";
-import {dataProvider, structureLocationProvider, transformProvider} from "./providers/ExternalAlignmentProvider";
+import {dataProvider, loadParamsProvider} from "./providers/ExternalAlignmentProvider";
 
 document.addEventListener("DOMContentLoaded", function(event) {
 
     const panel3D = new RcsbFv3DAlignmentProvider({
         config:{
             dataProvider: dataProvider,
-            transformProvider: transformProvider,
-            structureLocationProvider: structureLocationProvider,
+            loadParamsProvider: loadParamsProvider,
             title: "Title >> Alignment Provider",
             subtitle: "Subtitle >> Alignment Provider"
         },

+ 78 - 6
src/examples/alignment-provider/providers/AlignmentReference.ts

@@ -3,6 +3,11 @@ import {
     AlignedRegion,
     AlignmentResponse,
 } from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
+import {Alignment} from "./alignment-response";
+import {RcsbRequestContextManager, TagDelimiter} from "@rcsb/rcsb-saguaro-app";
+import {
+    InstanceSequenceInterface
+} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbCollectTools/DataCollectors/MultipleInstanceSequencesCollector";
 
 type AlignmentRefType = (number|undefined)[];
 type AlignmentMemberType = {
@@ -12,15 +17,18 @@ type AlignmentMemberType = {
     target: AlignmentRefType;
 };
 export class AlignmentReference {
-    private readonly alignmentRefMap: AlignmentRefType;
-    private readonly refId:string;
-    private readonly alignmentRefGaps: Record<number, number>;
+    private alignmentRefMap: AlignmentRefType;
+    private refId:string;
+    private readonly alignmentRefGaps: Record<number, number> = {};
     private readonly memberRefList: AlignmentMemberType[] = [];
 
-    constructor(refId: string, length: number) {
+    private readonly alignmentMap = new Map<string,{entryId: string; instanceId: string; alignmentId: string; sequence: string; alignmentIndex:number; pairIndex: number;}>();
+
+    public async init(result: Alignment) {
+        this.alignmentMap.clear();
+        this.refId = this.addUniqueAlignmentId(result,0,0);
+        const length = (await this.getSequences())[0].sequence.length;
         this.alignmentRefMap = Array(length).fill(0).map((v,n)=>n+1);
-        this.alignmentRefGaps = {};
-        this.refId = refId;
     }
 
     public addAlignment(id:string, alignment: AlignmentRefType, target: AlignmentRefType): void {
@@ -45,6 +53,70 @@ export class AlignmentReference {
         return buildAlignments(this.refId, this.alignmentRefMap, this.memberRefList);
     }
 
+    public addUniqueAlignmentId(result: Alignment, alignmentIndex: number, pairIndex: 0|1 = 1): string {
+        const res = result.structures[pairIndex];
+        if(!res.selection)
+            throw new Error("Missing entry_id and name from result");
+        let entryId: string | undefined = undefined;
+        const asymId = 'asym_id' in res.selection ? res.selection.asym_id : undefined;
+        if("entry_id" in res && res.entry_id && res.selection && "asym_id" in res.selection)
+            entryId = res.entry_id;
+        else if("name" in res && res.selection &&"asym_id" in res.selection)
+            entryId = res.name;
+        if(!entryId || !asymId)
+            throw new Error("Missing entry_id and name from result");
+        if(!this.alignmentMap.has(`${entryId}${TagDelimiter.instance}${asymId}`)) {
+            this.alignmentMap.set(`${entryId}${TagDelimiter.instance}${asymId}`, {
+                entryId,
+                instanceId: asymId,
+                sequence: result.sequence_alignment?.[pairIndex].sequence ?? "",
+                alignmentIndex: alignmentIndex,
+                pairIndex: pairIndex,
+                alignmentId: `${entryId}${TagDelimiter.instance}${asymId}`
+            });
+            return `${entryId}${TagDelimiter.instance}${asymId}`;
+        }else{
+            let tag = 1;
+            while(this.alignmentMap.has(`${entryId}[${tag}]${TagDelimiter.instance}${asymId}`)){
+                tag ++;
+            }
+            this.alignmentMap.set(`${entryId}[${tag}]${TagDelimiter.instance}${asymId}`, {
+                entryId,
+                instanceId: asymId,
+                sequence: result.sequence_alignment?.[pairIndex].sequence ?? "",
+                alignmentIndex: alignmentIndex,
+                pairIndex: pairIndex,
+                alignmentId: `${entryId}[${tag}]${TagDelimiter.instance}${asymId}`
+            });
+            return `${entryId}[${tag}]${TagDelimiter.instance}${asymId}`;
+        }
+    }
+
+    public getAlignmentEntry(alignmentId: string): {entryId: string; instanceId: string; sequence: string; alignmentIndex:number; pairIndex: number; alignmentId:string;} {
+        const pdb = this.alignmentMap.get(alignmentId)
+        if(pdb)
+            return pdb;
+        throw new Error("Alignment Id not found");
+    }
+
+    public async getSequences(): Promise<InstanceSequenceInterface[]> {
+        const out = Array.from(this.alignmentMap.values()).filter(v=>v.sequence.length > 0).map(v=>({
+            rcsbId: v.alignmentId,
+            sequence: v.sequence
+        }));
+        const missingSeq = await RcsbRequestContextManager.getInstanceSequences(
+                Array.from(this.alignmentMap.values()).filter(v=>v.sequence.length == 0).map(
+                    v=>`${v.entryId}${TagDelimiter.instance}${v.instanceId}`
+                ).filter((value,index,list)=> list.indexOf(value) === index)
+            );
+        return out.concat(
+            Array.from(this.alignmentMap.values()).filter(v=>v.sequence.length == 0).map(v=>({
+                rcsbId: v.alignmentId,
+                sequence: missingSeq.find(s=>s.rcsbId === `${v.entryId}${TagDelimiter.instance}${v.instanceId}`)?.sequence ?? ""
+            }))
+        );
+    }
+
     private addRef(id: string, alignment: AlignmentRefType, target: AlignmentRefType): void {
         const map: AlignmentRefType = Array(this.alignmentRefMap.length).fill(undefined);
         alignment.forEach((v,n)=>{

+ 82 - 79
src/examples/alignment-provider/providers/ExternalAlignmentProvider.ts

@@ -1,26 +1,43 @@
 import {
-    AlignmentResponse, GroupReference,
+    AlignmentResponse,
+    GroupReference,
     SequenceReference,
 } from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
 import {
     AlignmentCollectConfig,
     AlignmentCollectorInterface
 } from "@rcsb/rcsb-saguaro-app/build/dist/RcsbCollectTools/AlignmentCollector/AlignmentCollectorInterface";
-import {RcsbRequestContextManager} from "@rcsb/rcsb-saguaro-app";
+import {TagDelimiter} from "@rcsb/rcsb-saguaro-app";
 
 import {
     RcsbModuleDataProviderInterface
 } from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvModule/RcsbFvModuleInterface";
 import {AlignmentReference} from "./AlignmentReference";
 import {
-    LocationProviderInterface,
-    RigidTransformType, TransformMatrixType,
-    TransformProviderInterface
+    LoadParamsProviderInterface,
+    RigidTransformType,
+    TransformMatrixType
 } from "../../../RcsbFvStructure/StructureUtils/StructureLoaderInterface";
+
+import {
+    Alignment,
+    AlignmentRegion,
+    StructureAlignmentResponse,
+    StructureEntry,
+    StructureURL
+} from "./alignment-response";
+import {
+    LoadMethod,
+    LoadMolstarInterface,
+    LoadMolstarReturnType
+} from "../../../RcsbFvStructure/StructureViewers/MolstarViewer/MolstarActionManager";
 import {
-    InstanceSequenceInterface
-} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbCollectTools/DataCollectors/MultipleInstanceSequencesCollector";
-import {Alignment, AlignmentRegion, StructureAlignmentResponse} from "./alignment-response";
+    AlignmentTrajectoryParamsType,
+    AlignmentTrajectoryPresetProvider
+} from "../../../RcsbFvStructure/StructureViewers/MolstarViewer/TrajectoryPresetProvider/AlignmentTrajectoryPresetProvider";
+import {
+    FlexibleAlignmentTrajectoryPresetProvider
+} from "../../../RcsbFvStructure/StructureViewers/MolstarViewer/TrajectoryPresetProvider/FlexibleAlignmentTrajectoryPresetProvider";
 
 const alignment = {
     "info": {
@@ -1630,13 +1647,16 @@ const alignmentExample = {
         }
     ]
 };
+const duplicatedAlignment = {"info":{"uuid":"dcc58c64-e606-441f-8c04-372381fb7c0e","status":"COMPLETE"},"meta":{"alignment_mode":"pairwise","alignment_method":"fatcat-rigid"},"results":[{"structures":[{"entry_id":"101M","selection":{"asym_id":"A"}},{"entry_id":"101M","selection":{"asym_id":"A"}}],"structure_alignment":[{"regions":[[{"asym_id":"A","beg_seq_id":1,"beg_index":0,"length":154}],[{"asym_id":"A","beg_seq_id":1,"beg_index":0,"length":154}]],"transformations":[[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0],[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]],"summary":{"scores":[{"value":456.0,"type":"similarity-score"},{"value":0.0,"type":"RMSD"}],"n_aln_residue_pairs":154}}],"sequence_alignment":[{"regions":[{"asym_id":"A","beg_seq_id":1,"beg_index":0,"length":154}]},{"regions":[{"asym_id":"A","beg_seq_id":1,"beg_index":0,"length":154}]}],"summary":{"scores":[{"value":1.0,"type":"sequence-identity"},{"value":1.0,"type":"TM-score"},{"value":1.0,"type":"sequence-similarity"},{"value":456.0,"type":"similarity-score"},{"value":0.0,"type":"RMSD"}],"n_aln_residue_pairs":154,"n_modeled_residues":[154,154],"seq_aln_len":154,"aln_coverage":[100,100]}}]};
 
 class RcsbStructuralAlignmentProvider implements AlignmentCollectorInterface {
 
     private alignmentResponse: AlignmentResponse | undefined = undefined;
     private readonly alignment: StructureAlignmentResponse;
-    constructor(alignment: StructureAlignmentResponse) {
+    private readonly alignmentReference: AlignmentReference;
+    constructor(alignment: StructureAlignmentResponse, alignmentReference: AlignmentReference) {
         this.alignment = alignment;
+        this.alignmentReference = alignmentReference;
     }
 
     async collect(requestConfig: AlignmentCollectConfig, filter?: Array<string>): Promise<AlignmentResponse> {
@@ -1664,7 +1684,7 @@ class RcsbStructuralAlignmentProvider implements AlignmentCollectorInterface {
         if(this.alignmentResponse)
             return this.alignmentResponse;
         return new Promise((resolve)=>{
-            alignmentTransform(this.alignment).then(ar=>{
+            alignmentTransform(this.alignment, this.alignmentReference).then(ar=>{
                 this.alignmentResponse = ar;
                 resolve(ar);
             })
@@ -1673,26 +1693,24 @@ class RcsbStructuralAlignmentProvider implements AlignmentCollectorInterface {
 
 }
 
-class RcsbStructuralTransformProvider implements TransformProviderInterface {
+class RcsbStructuralTransformProvider {
 
     private readonly alignment: StructureAlignmentResponse;
     constructor(alignment: StructureAlignmentResponse) {
         this.alignment = alignment;
     }
 
-    get(entryId: string, asymId?: string): RigidTransformType[] {
-        const res = this.alignment.results?.find(res=>{
-            const r = res.structures[1];
-            return ("entry_id" in r && r.entry_id == entryId && r.selection && "asym_id" in r.selection && r.selection.asym_id == asymId)
-        });
+    get(alignmentIndex: number, pairIndex: number): RigidTransformType[] {
+
+        const res = this.alignment.results?.[alignmentIndex];
         if(res?.structure_alignment.length == 1) {
             return [{
-                transform: res.structure_alignment[0].transformations[1] as TransformMatrixType
+                transform: res.structure_alignment[0].transformations[pairIndex] as TransformMatrixType
             }];
         }else if(res?.structure_alignment.length && res?.structure_alignment.length > 1){
             return res.structure_alignment.map(sa=>({
-                transform: sa.transformations[1] as TransformMatrixType,
-                regions: sa.regions?.[1].map(r=>[r.beg_seq_id,r.beg_seq_id+r.length-1])
+                transform: sa.transformations[pairIndex] as TransformMatrixType,
+                regions: sa.regions?.[pairIndex].map(r=>[r.beg_seq_id,r.beg_seq_id+r.length-1])
             }));
         }else{
             return [{
@@ -1703,33 +1721,53 @@ class RcsbStructuralTransformProvider implements TransformProviderInterface {
 
 }
 
-class RcsbStructureLocationProvider implements LocationProviderInterface {
+class RcsbLoadParamsProvider implements LoadParamsProviderInterface<{entryId: string; instanceId: string;},LoadMolstarInterface<AlignmentTrajectoryParamsType,LoadMolstarReturnType>> {
 
     private readonly alignment: StructureAlignmentResponse;
-    constructor(alignment: StructureAlignmentResponse) {
+    private readonly transformProvider: RcsbStructuralTransformProvider;
+    private readonly alignmentReference: AlignmentReference;
+    constructor(alignment: StructureAlignmentResponse,alignmentReference: AlignmentReference) {
         this.alignment = alignment;
+        this.transformProvider = new RcsbStructuralTransformProvider(alignment);
+        this.alignmentReference = alignmentReference;
     }
 
-    get(entryId:string): string|undefined {
-        for(const res of this.alignment.results ?? []){
-            if("url" in res.structures[0] && res.structures[0].url && res.structures[0].name == entryId ){
-                return res.structures[0].url;
-            }
-            if("url" in res.structures[1] && res.structures[1].url && res.structures[1].name == entryId ){
-                return res.structures[1].url;
+    get(pdb:{entryId: string; instanceId: string;}): LoadMolstarInterface<AlignmentTrajectoryParamsType,LoadMolstarReturnType> {
+        if(!this.alignment.results)
+            throw new Error("Alignments results not found");
+        const {alignmentIndex,pairIndex, entryId} =  this.alignmentReference.getAlignmentEntry(`${pdb.entryId}${TagDelimiter.instance}${pdb.instanceId}`);
+        const res = this.alignment.results[alignmentIndex]
+        const structure = res.structures[pairIndex] as StructureEntry & StructureURL;
+        const transform = this.transformProvider.get(alignmentIndex, pairIndex);
+        const reprProvider = !transform?.length || transform.length == 1 ? AlignmentTrajectoryPresetProvider : FlexibleAlignmentTrajectoryPresetProvider;
+        const loadMethod = "url" in structure && structure.url ? LoadMethod.loadStructureFromUrl : LoadMethod.loadPdbId;
+        const url: string|undefined = "url" in structure &&structure.url ? structure.url : undefined;
+
+        return {
+            loadMethod,
+            loadParams: {
+                url,
+                entryId,
+                format: url ? "mmcif" : undefined,
+                isBinary: url ? false : undefined,
+                id: `${pdb.entryId}${TagDelimiter.instance}${pdb.instanceId}`,
+                reprProvider,
+                params: {
+                    modelIndex: 0,
+                    pdb,
+                    transform: transform
+                }
             }
         }
-        return undefined;
     }
-
 }
 
-async function alignmentTransform(alignment: StructureAlignmentResponse): Promise<AlignmentResponse> {
+async function alignmentTransform(alignment: StructureAlignmentResponse, alignmentRef: AlignmentReference): Promise<AlignmentResponse> {
     if(!alignment.results)
         return {};
-    const alignmentRef = await mergeAlignments(alignment.results);
+    await mergeAlignments(alignment.results, alignmentRef);
     const out: AlignmentResponse = alignmentRef.buildAlignments();
-    const seqs = await getSequences(alignment.results);
+    const seqs = await alignmentRef.getSequences();
     out.target_alignment?.forEach(ta=>{
         const seq = seqs.find(s=>s.rcsbId===ta?.target_id)?.sequence
         if(seq && ta)
@@ -1738,28 +1776,18 @@ async function alignmentTransform(alignment: StructureAlignmentResponse): Promis
     return out;
 }
 
-async function mergeAlignments(results: Alignment[]): Promise<AlignmentReference> {
+async function mergeAlignments(results: Alignment[], alignmentRef: AlignmentReference): Promise<void> {
     const result = results[0];
     if(!result)
         throw "Results not available";
-    const seqs = await getSequences([result]);
-    const alignmentRef = new AlignmentReference( getInstanceId(result, 0), seqs[0].sequence.length)
-    results.forEach(result=>{
+    await alignmentRef.init( result );
+    results.forEach((result,n)=>{
+        const alignmentId = alignmentRef.addUniqueAlignmentId(result, n);
         if(result.sequence_alignment)
-            alignmentRef.addAlignment(getInstanceId(result), transformToGapedDomain(result.sequence_alignment[0].regions), transformToGapedDomain(result.sequence_alignment[1].regions));
+            alignmentRef.addAlignment(alignmentId, transformToGapedDomain(result.sequence_alignment[0].regions), transformToGapedDomain(result.sequence_alignment[1].regions));
         else if(result.structure_alignment && result.structure_alignment[0].regions && result.structure_alignment[1].regions)
-            alignmentRef.addAlignment(getInstanceId(result), transformToGapedDomain(result.structure_alignment[0].regions.flat()), transformToGapedDomain(result.structure_alignment[1].regions.flat()));
+            alignmentRef.addAlignment(alignmentId, transformToGapedDomain(result.structure_alignment[0].regions.flat()), transformToGapedDomain(result.structure_alignment[1].regions.flat()));
     });
-    return alignmentRef;
-}
-
-function getInstanceId(result: Alignment, index: 0|1 = 1): string {
-    const res = result.structures[index];
-    if("entry_id" in res && res.entry_id && res.selection && "asym_id" in res.selection)
-        return`${res.entry_id}.${res.selection.asym_id}`;
-    else if("name" in res && res.selection &&"asym_id" in res.selection)
-        return `${res.name}.${res.selection.asym_id}`;
-    throw new Error("Missing entry_id and name from result");
 }
 
 function transformToGapedDomain(regions: AlignmentRegion[]): (number|undefined)[] {
@@ -1782,36 +1810,13 @@ function transformToGapedDomain(regions: AlignmentRegion[]): (number|undefined)[
     return out;
 }
 
-async function getSequences(results: Alignment[]): Promise<InstanceSequenceInterface[]> {
-    const out: InstanceSequenceInterface[] = [];
-    const missingIds: string[] = [];
-    const res = results[0];
-    if(res.sequence_alignment?.[0].sequence) {
-        out.push( {
-            rcsbId: getInstanceId(res,0),
-            sequence: res.sequence_alignment[0].sequence
-        })
-    }else{
-        missingIds.push( getInstanceId(res, 0) )
-    }
-    results.forEach(res=>{
-        if(res.sequence_alignment?.[1].sequence) {
-            out.push( {
-                rcsbId: getInstanceId(res,1),
-                sequence: res.sequence_alignment[1].sequence
-            })
-        }else{
-            missingIds.push( getInstanceId(res) )
-        }
-    });
-    return  out.concat(await RcsbRequestContextManager.getInstanceSequences(missingIds));
-}
-
-const structuralAlignment: StructureAlignmentResponse = alignmentExample as StructureAlignmentResponse;
+//const structuralAlignment: StructureAlignmentResponse = alignmentExample as StructureAlignmentResponse;
+const structuralAlignment: StructureAlignmentResponse = duplicatedAlignment as StructureAlignmentResponse;
 
+const alignmentReference = new AlignmentReference();
 export const dataProvider: RcsbModuleDataProviderInterface = {
     alignments: {
-        collector: new RcsbStructuralAlignmentProvider(structuralAlignment),
+        collector: new RcsbStructuralAlignmentProvider(structuralAlignment, alignmentReference),
         context:{
             queryId: "structural-alignment",
             group: GroupReference.MatchingUniprotAccession,
@@ -1820,6 +1825,4 @@ export const dataProvider: RcsbModuleDataProviderInterface = {
     }
 };
 
-export const transformProvider = new RcsbStructuralTransformProvider(structuralAlignment);
-
-export const structureLocationProvider = new RcsbStructureLocationProvider(structuralAlignment);
+export const loadParamsProvider = new RcsbLoadParamsProvider(structuralAlignment, alignmentReference);

Some files were not shown because too many files changed in this diff