Browse Source

support transformed export & structAsymMap parsing fix

dsehnal 3 years ago
parent
commit
9a73180c3c

+ 1 - 1
src/extensions/model-export/export.ts

@@ -28,7 +28,7 @@ async function _exportHierarchy(plugin: PluginContext, options?: { format?: 'cif
     const entryMap = new Map<string, number>();
 
     for (const _s of structures) {
-        const s = _s.cell.obj?.data;
+        const s = _s.transform?.cell.obj?.data ?? _s.cell.obj?.data;
         if (!s) continue;
         if (s.models.length > 1) {
             plugin.log.warn(`[Export] Skipping ${_s.cell.obj?.label}: Multimodel exports not supported.`);

+ 7 - 2
src/mol-math/geometry/symmetry-operator.ts

@@ -52,7 +52,7 @@ namespace SymmetryOperator {
     export const RotationTranslationEpsilon = 0.005;
 
     export type CreateInfo = { assembly?: SymmetryOperator['assembly'], ncsId?: number, hkl?: Vec3, spgrOp?: number }
-    export function create(name: string, matrix: Mat4, info?: CreateInfo): SymmetryOperator {
+    export function create(name: string, matrix: Mat4, info?: CreateInfo | SymmetryOperator): SymmetryOperator {
         let { assembly, ncsId, hkl, spgrOp } = info || { };
         const _hkl = hkl ? Vec3.clone(hkl) : Vec3();
         spgrOp = defaults(spgrOp, -1);
@@ -66,10 +66,15 @@ namespace SymmetryOperator {
         return { name, assembly, matrix, inverse: Mat4.invert(Mat4(), matrix), isIdentity: false, hkl: _hkl, spgrOp, ncsId, suffix };
     }
 
-    function getSuffix(info?: CreateInfo, isIdentity?: boolean) {
+    function isSymmetryOperator(x: any): x is SymmetryOperator {
+        return !!x && !!x.matrix && !!x.inverse && typeof x.name === 'string';
+    }
+
+    function getSuffix(info?: CreateInfo | SymmetryOperator, isIdentity?: boolean) {
         if (!info) return '';
 
         if (info.assembly) {
+            if (isSymmetryOperator(info)) return info.suffix;
             return isIdentity ? '' : `_${info.assembly.operId}`;
         }
 

+ 1 - 1
src/mol-model-formats/structure/basic/parser.ts

@@ -24,7 +24,7 @@ import { getModelGroupName } from './util';
 import { ArrayTrajectory } from '../../../mol-model/structure/trajectory';
 
 export async function createModels(data: BasicData, format: ModelFormat, ctx: RuntimeContext) {
-    const properties = getProperties(data);
+    const properties = getProperties(data, format);
     const models = data.ihm_model_list._rowCount > 0
         ? await readIntegrative(ctx, data, properties, format)
         : await readStandard(ctx, data, properties, format);

+ 22 - 12
src/mol-model-formats/structure/basic/properties.ts

@@ -12,6 +12,9 @@ import { SaccharideComponentMap, SaccharideComponent, SaccharidesSnfgMap, Saccha
 import { memoize1 } from '../../../mol-util/memoize';
 import { BasicData } from './schema';
 import { Table } from '../../../mol-data/db';
+import { ModelFormat } from '../../format';
+import { MmcifFormat } from '../mmcif';
+import { AtomSiteOperatorMappingCategoryName } from '../../../mol-model/structure/export/categories/atom_site_operator_mapping';
 
 function getMissingResidues(data: BasicData): Model['properties']['missingResidues'] {
     const map = new Map<string, MissingResidue>();
@@ -108,18 +111,25 @@ const getUniqueComponentNames = memoize1((data: BasicData) => {
 });
 
 
-function getStructAsymMap(data: BasicData): Model['properties']['structAsymMap'] {
+function getStructAsymMap(data: BasicData, format: ModelFormat): Model['properties']['structAsymMap'] {
     const map = new Map<string, StructAsym>();
 
-    const { label_asym_id, auth_asym_id, label_entity_id } = data.atom_site;
-    for (let i = 0, il = label_asym_id.rowCount; i < il; ++i) {
-        const id = label_asym_id.value(i);
-        if (!map.has(id)) {
-            map.set(id, {
-                id,
-                auth_id: auth_asym_id.value(i),
-                entity_id: label_entity_id.value(i)
-            });
+    // do not determine values from atom sites if mol_star atom site operator mapping is preset
+    const skipAtomSite = MmcifFormat.is(format)
+        && format.data.frame.categoryNames.indexOf(AtomSiteOperatorMappingCategoryName) >= 0
+        && data.struct_asym._rowCount > 0;
+
+    if (!skipAtomSite) {
+        const { label_asym_id, auth_asym_id, label_entity_id } = data.atom_site;
+        for (let i = 0, il = label_asym_id.rowCount; i < il; ++i) {
+            const id = label_asym_id.value(i);
+            if (!map.has(id)) {
+                map.set(id, {
+                    id,
+                    auth_id: auth_asym_id.value(i),
+                    entity_id: label_entity_id.value(i)
+                });
+            }
         }
     }
 
@@ -139,11 +149,11 @@ function getStructAsymMap(data: BasicData): Model['properties']['structAsymMap']
     return map;
 }
 
-export function getProperties(data: BasicData): Model['properties'] {
+export function getProperties(data: BasicData, format: ModelFormat): Model['properties'] {
     return {
         missingResidues: getMissingResidues(data),
         chemicalComponentMap: getChemicalComponentMap(data),
         saccharideComponentMap: getSaccharideComponentMap(data),
-        structAsymMap: getStructAsymMap(data)
+        structAsymMap: getStructAsymMap(data, format)
     };
 }