Kaynağa Gözat

Issue #2: exclude chains from author defined assembly

cycle20 2 yıl önce
ebeveyn
işleme
2547db9f5f

+ 1 - 1
src/apps/tm-viewer/index.ts

@@ -22,7 +22,7 @@ require('mol-plugin-ui/skin/light.scss');
 
 export { PLUGIN_VERSION as version } from '../../mol-plugin/version';
 export { setDebugMode, setProductionMode } from '../../mol-util/debug';
-export { loadWithUNITMPMembraneRepresentation, pdbtmDescriptor } from '../../extensions/tmdet/behavior';
+export { loadWithUNITMPMembraneRepresentation } from '../../extensions/tmdet/behavior';
 
 const Extensions = {
     'tmdet-membrane-orientation': PluginSpec.Behavior(TMDETMembraneOrientation)

+ 13 - 10
src/extensions/tmdet/behavior.ts

@@ -27,6 +27,7 @@ import { PluginUIContext } from '../../mol-plugin-ui/context';
 import { StateObjectSelector } from "../../mol-state/object";
 import { applyTransformations, createMembraneOrientation, getAtomGroupExpression } from './transformation';
 import { PDBTMDescriptor, PDBTMRegion, PMS } from './types';
+import { registerTmDetSymmetry } from './symmetry';
 
 type StructureComponentType = StateObjectSelector<
         PMS,
@@ -111,11 +112,9 @@ export const isTransmembrane = StructureSelectionQuery('Residues Embedded in Mem
 // //////////////////////////// TMDET VIEWER FUNCTIONS
 
 export let membraneOrientation: MembraneOrientation;
-export let pdbtmDescriptor: PDBTMDescriptor;
 
 export async function loadWithUNITMPMembraneRepresentation(plugin: PluginUIContext, params: any) {
-    // const pdbtmDescriptor: any = await downloadRegionDescriptor(plugin, params);
-    pdbtmDescriptor = await downloadRegionDescriptor(plugin, params);
+    const pdbtmDescriptor = await downloadRegionDescriptor(plugin, params);
 
     membraneOrientation = createMembraneOrientation(pdbtmDescriptor);
 
@@ -130,6 +129,13 @@ export async function loadWithUNITMPMembraneRepresentation(plugin: PluginUIConte
     requestAnimationFrame(() => plugin.canvas3d?.requestCameraReset());
 }
 
+async function downloadRegionDescriptor(plugin: PluginUIContext, params: any): Promise<any> {
+    // run a fetch task
+    const downloadResult: string = await plugin.runTask(plugin.fetch({ url: params.regionDescriptorUrl })) as string;
+    const pdbtmDescriptor: any = JSON.parse(downloadResult);
+    return pdbtmDescriptor;
+}
+
 async function createStructureRepresentation(plugin: PluginUIContext, pdbtmDescriptor: any) {
     // get the first structure of the first model
     const structure: StateObjectRef<PMS> = plugin.managers.structure.hierarchy.current.models[0].structures[0].cell;
@@ -212,6 +218,10 @@ async function buildStructureRepresentation(plugin: PluginUIContext, components:
 }
 
 async function loadStructure(ctx: PluginUIContext, params: any, pdbtmDescriptor: PDBTMDescriptor): Promise<void> {
+
+    // replace original symmetry format function
+    registerTmDetSymmetry(pdbtmDescriptor);
+
     const builders = ctx.builders;
     const data = await builders.data.download({
         url: params.structureUrl,
@@ -233,13 +243,6 @@ async function loadStructure(ctx: PluginUIContext, params: any, pdbtmDescriptor:
         trajectory, 'default', { representationPreset: 'preset-membrane-orientation' as any });
 }
 
-async function downloadRegionDescriptor(plugin: PluginUIContext, params: any): Promise<any> {
-    // run a fetch task
-    const downloadResult: string = await plugin.runTask(plugin.fetch({ url: params.regionDescriptorUrl })) as string;
-    const pdbtmDescriptor: any = JSON.parse(downloadResult);
-    return pdbtmDescriptor;
-}
-
 // //////////////////////////// END OF TMDET VIEWER SECTION
 
 //

+ 93 - 0
src/extensions/tmdet/symmetry.ts

@@ -0,0 +1,93 @@
+
+import { MmcifFormat } from '../../mol-model-formats/structure/mmcif';
+import { Column, Table } from '../../mol-data/db';
+import { mmCIF_Schema } from '../../mol-io/reader/cif/schema/mmcif';
+import { Model } from '../../mol-model/structure';
+import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
+import { PDBTMDescriptor } from './types';
+
+
+export function registerTmDetSymmetry(pdbtmDescriptor: PDBTMDescriptor) {
+    ModelSymmetry.Provider.formatRegistry.remove('mmCIF');
+    const chains = constructChainListFromOperations(pdbtmDescriptor);
+    ModelSymmetry.Provider.formatRegistry.add('mmCIF',  function(model: Model) {
+        return tmDetSymmetryFromMmCif(model, chains);
+    });
+}
+
+function constructChainListFromOperations(pdbtmDescriptor: PDBTMDescriptor): string[] {
+    console.log("PDBTMDesc", pdbtmDescriptor);
+    const excludedChains: string[] = [];
+    // add chain deletes
+    pdbtmDescriptor.additional_entry_annotations.biomatrix.chain_deletes.forEach(
+        chainId => excludedChains.push(chainId)
+    );
+    // exclude result of transformations
+    pdbtmDescriptor.additional_entry_annotations.biomatrix.matrix_list.forEach(
+        matrix => matrix.apply_to_chain_list.forEach(
+            applyItem => excludedChains.push(applyItem.new_chain_id)
+        )
+    );
+    console.log(excludedChains);
+    // todo all minus excluded
+
+    return excludedChains;
+}
+
+function tmDetSymmetryFromMmCif(model: Model, chainsForOperExpression: string[]) {
+    if (!MmcifFormat.is(model.sourceData)) return;
+
+    let data = model.sourceData.data.db;
+    let asymIdColumnData: string[][] = [];
+    // update chains (asym) for each author_defined_assemly
+    for (let i = 0; i < data.pdbx_struct_assembly._rowCount; i++) {
+        if (data.pdbx_struct_assembly.details.value(i).startsWith('author_defined_assembly')) {
+            const currentAssemblyId: string = data.pdbx_struct_assembly_gen.assembly_id.value(i);
+            const result: string[][] = createAsymIdColumnData(
+                data.pdbx_struct_assembly_gen, currentAssemblyId, chainsForOperExpression
+            );
+            asymIdColumnData = asymIdColumnData.concat(result);
+        }
+    }
+    const asym_id_list_column = Column.ofStringListArray(asymIdColumnData);
+    // create table with new column
+    let updated_pdbx_struct_assembly_gen = Table.ofColumns(
+        data.pdbx_struct_assembly_gen._schema,
+        {
+            assembly_id: data.pdbx_struct_assembly_gen.assembly_id,
+            asym_id_list: asym_id_list_column,
+            oper_expression: data.pdbx_struct_assembly_gen.oper_expression,
+
+        }
+    );
+
+    return ModelSymmetry.fromData({
+        symmetry: data.symmetry,
+        cell: data.cell,
+        struct_ncs_oper: data.struct_ncs_oper,
+        atom_sites: data.atom_sites,
+        pdbx_struct_assembly: data.pdbx_struct_assembly,
+        pdbx_struct_assembly_gen: updated_pdbx_struct_assembly_gen,
+        pdbx_struct_oper_list: data.pdbx_struct_oper_list
+    });
+}
+
+function createAsymIdColumnData(pdbx_struct_assembly_gen: Table<mmCIF_Schema['pdbx_struct_assembly_gen']>, assemblyId: string, chains: string[]) {
+
+    const asym_id_list: string[][] = [];
+    for (let i = 0; i < pdbx_struct_assembly_gen._rowCount; i++) {
+        const currentAsymIdList = pdbx_struct_assembly_gen.asym_id_list.value(i);
+        asym_id_list.push(
+            (assemblyId == pdbx_struct_assembly_gen.assembly_id.value(i))
+                ? minus(currentAsymIdList, chains)
+                : currentAsymIdList
+        );
+    }
+    return asym_id_list;
+}
+
+// difference of two string arrays (interpreted as sets)
+function minus(a: string[], b: string[]): string[] {
+    const b_set = new Set(b);
+    return a.filter(x => !b_set.has(x));
+}

+ 0 - 4
src/mol-model-formats/structure/property/assembly.ts

@@ -56,10 +56,6 @@ function operatorGroupsProvider(generators: Generator[], matrices: Matrices): ()
         let operatorOffset = 0;
         for (let i = 0; i < generators.length; i++) {
             const gen = generators[i];
-            console.log(`GEN ${i}`, gen.asymIds);
-            gen.asymIds = [ 'C' ];
-            console.log('ASYMs', gen.asymIds);
-
             const operatorList = parseOperatorList(gen.expression);
             const operatorNames = expandOperators(operatorList);
             const operators = getAssemblyOperators(matrices, operatorNames, operatorOffset, gen.assemblyId);