Browse Source

fixed RCSB assembly symmetry prop

Alexander Rose 6 years ago
parent
commit
cc07b6a93d

+ 5 - 4
src/mol-model-props/rcsb/graphql/symmetry.gql.ts

@@ -2,12 +2,16 @@
 function gql (strs: TemplateStringsArray) { return strs.raw.join('') }
 
 export default
-gql`query AssemblySymmetry($pdbId: String) {
+gql`query AssemblySymmetry($pdbId: String!) {
     assemblies(pdbId: $pdbId) {
         assembly_id
         rcsb_assembly_symmetry {
             source
             symmetry_features {
+                symmetry {
+                    description
+                    value
+                }
                 clusters {
                     members
                     avg_rmsd
@@ -16,9 +20,6 @@ gql`query AssemblySymmetry($pdbId: String) {
                     description
                     value
                 }
-                symmetry {
-                    space_group_name_h_m
-                }
                 symmetry_axes {
                     start
                     end

+ 64 - 37
src/mol-model-props/rcsb/graphql/types.ts

@@ -1,5 +1,5 @@
 /* tslint:disable */
-/** Generated in 2018-08-17T12:05:55-07:00 */
+/** Generated in 2018-08-20T10:50:59-07:00 */
 
 export enum PdbxLeavingAtomFlag {
   N = "N",
@@ -31,7 +31,7 @@ export enum ExperimentalSupport {
   SURFACE_PLASMON_RESONANCE = "SURFACE_PLASMON_RESONANCE"
 }
 
-export enum Type {
+export enum SymmetryFeatureType {
   GLOBAL = "GLOBAL",
   LOCAL = "LOCAL",
   PSEUDO = "PSEUDO"
@@ -42,12 +42,6 @@ export enum UnpublishedFlag {
   Y = "Y"
 }
 
-export enum PdbxDiffrnProtocol {
-  LAUE = "LAUE",
-  MAD = "MAD",
-  SINGLE_WAVELENGTH = "SINGLE_WAVELENGTH"
-}
-
 export enum PdbxMonochromaticOrLaueML {
   L = "L",
   M = "M"
@@ -59,17 +53,6 @@ export enum PdbxScatteringType {
   X_RAY = "X_RAY"
 }
 
-export enum Source {
-  ELECTRON_MICROSCOPE = "ELECTRON_MICROSCOPE",
-  FREE_ELECTRON_LASER = "FREE_ELECTRON_LASER",
-  LIQUID_ANODE = "LIQUID_ANODE",
-  NUCLEAR_REACTOR = "NUCLEAR_REACTOR",
-  ROTATING_ANODE = "ROTATING_ANODE",
-  SEALED_TUBE = "SEALED_TUBE",
-  SPALLATION_SOURCE = "SPALLATION_SOURCE",
-  SYNCHROTRON = "SYNCHROTRON"
-}
-
 export enum RefSpace {
   REAL = "REAL",
   RECIPROCAL = "RECIPROCAL"
@@ -115,12 +98,55 @@ export enum VitrificationApplied {
   YES = "YES"
 }
 
+export enum Type {
+  NEGATIVE = "NEGATIVE",
+  NONE = "NONE",
+  POSITIVE = "POSITIVE"
+}
+
 export enum SrcMethod {
   MAN = "MAN",
   NAT = "NAT",
   SYN = "SYN"
 }
 
+export enum EntityType {
+  MACROLIDE = "MACROLIDE",
+  NON_POLYMER = "NON_POLYMER",
+  POLYMER = "POLYMER",
+  WATER = "WATER"
+}
+
+export enum EntityPolyType {
+  CYCLIC_PSEUDO_PEPTIDE = "CYCLIC_PSEUDO_PEPTIDE",
+  OTHER = "OTHER",
+  PEPTIDE_NUCLEIC_ACID = "PEPTIDE_NUCLEIC_ACID",
+  POLYDEOXYRIBONUCLEOTIDE = "POLYDEOXYRIBONUCLEOTIDE",
+  POLYDEOXYRIBONUCLEOTIDE_POLYRIBONUCLEOTIDE_HYBRID = "POLYDEOXYRIBONUCLEOTIDE_POLYRIBONUCLEOTIDE_HYBRID",
+  POLYPEPTIDE_D = "POLYPEPTIDE_D",
+  POLYPEPTIDE_L = "POLYPEPTIDE_L",
+  POLYRIBONUCLEOTIDE = "POLYRIBONUCLEOTIDE",
+  POLYSACCHARIDE_D = "POLYSACCHARIDE_D",
+  POLYSACCHARIDE_L = "POLYSACCHARIDE_L"
+}
+
+export enum RcsbHostOrganismSource {
+  MMCIF = "MMCIF",
+  NCBI = "NCBI",
+  UNIPROT = "UNIPROT"
+}
+
+export enum RcsbMembraneSource {
+  HOMOLOGY = "HOMOLOGY",
+  MPSTRUCT = "MPSTRUCT"
+}
+
+export enum RcsbOrganismSource {
+  MMCIF = "MMCIF",
+  NCBI = "NCBI",
+  UNIPROT = "UNIPROT"
+}
+
 export enum Level {
   _100 = "_100",
   _30 = "_30",
@@ -140,7 +166,7 @@ export enum PdbFormatCompatible {
 
 export namespace AssemblySymmetry {
   export type Variables = {
-    readonly pdbId?: string | null;
+    readonly pdbId: string;
   };
 
   export type Query = {
@@ -150,46 +176,47 @@ export namespace AssemblySymmetry {
 
   export type Assemblies = {
     readonly __typename?: "CoreAssembly";
-    readonly assembly_id?: number | null;
+    readonly assembly_id: number;
     readonly rcsb_assembly_symmetry?: RcsbAssemblySymmetry | null;
   };
 
   export type RcsbAssemblySymmetry = {
     readonly __typename?: "RcsbAssemblySymmetry";
-    readonly source?: string | null;
-    readonly symmetry_features?: ReadonlyArray<SymmetryFeatures | null> | null;
+    readonly source: string;
+    readonly symmetry_features: ReadonlyArray<SymmetryFeatures | null>;
   };
 
   export type SymmetryFeatures = {
     readonly __typename?: "SymmetryFeature";
-    readonly clusters?: ReadonlyArray<Clusters | null> | null;
-    readonly stoichiometry?: Stoichiometry | null;
-    readonly symmetry?: Symmetry | null;
+    readonly symmetry: Symmetry;
+    readonly clusters: ReadonlyArray<Clusters | null>;
+    readonly stoichiometry: Stoichiometry;
     readonly symmetry_axes?: ReadonlyArray<SymmetryAxes | null> | null;
-    readonly type?: Type | null;
+    readonly type: SymmetryFeatureType;
+  };
+
+  export type Symmetry = {
+    readonly __typename?: "QuaternarySymmetry";
+    readonly description: string;
+    readonly value: string;
   };
 
   export type Clusters = {
     readonly __typename?: "Cluster";
-    readonly members?: ReadonlyArray<string | null> | null;
+    readonly members: ReadonlyArray<string | null>;
     readonly avg_rmsd?: number | null;
   };
 
   export type Stoichiometry = {
     readonly __typename?: "Stoichiometry";
-    readonly description?: string | null;
-    readonly value?: ReadonlyArray<string | null> | null;
-  };
-
-  export type Symmetry = {
-    readonly __typename?: "Symmetry";
-    readonly space_group_name_h_m?: string | null;
+    readonly description: string;
+    readonly value: ReadonlyArray<string | null>;
   };
 
   export type SymmetryAxes = {
     readonly __typename?: "SymmetryAxis";
-    readonly start?: ReadonlyArray<number | null> | null;
-    readonly end?: ReadonlyArray<number | null> | null;
+    readonly start: ReadonlyArray<number | null>;
+    readonly end: ReadonlyArray<number | null>;
     readonly order?: number | null;
   };
 }

+ 77 - 23
src/mol-model-props/rcsb/symmetry.ts

@@ -15,6 +15,8 @@ import { Database as _Database, Column, Table } from 'mol-data/db'
 import { Category } from 'mol-io/writer/cif/encoder';
 import { Tensor } from 'mol-math/linear-algebra';
 import { CifExportContext } from 'mol-model/structure/export/mmcif';
+import { toTable } from 'mol-io/reader/cif/schema';
+import { CifCategory } from 'mol-io/reader/cif';
 
 const { str, int, float, Aliased, Vector, List } = Column.Schema;
 
@@ -38,28 +40,31 @@ function createDatabase(assemblies: ReadonlyArray<AssemblySymmetryGraphQL.Assemb
 
     let id = 0
     for (let i = 0, il = assemblies.length; i < il; ++i) {
-        const a = assemblies[i]
-        const assembly_id = (a.assembly_id!).toString()
-        const source = a.rcsb_assembly_symmetry!.source!
-        const symmetry_features = a.rcsb_assembly_symmetry!.symmetry_features!
+        const { assembly_id: _assembly_id, rcsb_assembly_symmetry } = assemblies[i]
+        if (!rcsb_assembly_symmetry) continue
+        const assembly_id = _assembly_id.toString() // TODO type will be fixed to string upstream
+        const source = rcsb_assembly_symmetry.source
+        const symmetry_features = rcsb_assembly_symmetry.symmetry_features
         for (let j = 0, jl = symmetry_features.length; j < jl; ++j) {
-            const f = symmetry_features[j]!
+            const f = symmetry_features[j]! // TODO upstream, array members should not be nullable
             featureRows.push({
                 id,
                 assembly_id,
                 source,
-                type: f.type!,
-                stoichiometry_value: (f.stoichiometry!.value!) as string[],
-                stoichiometry_description: f.stoichiometry!.description!
+                type: f.type,
+                stoichiometry_value: f.stoichiometry.value as string[],  // TODO upstream, array members should not be nullable
+                stoichiometry_description: f.stoichiometry.description,
+                symmetry_value: f.symmetry.value,
+                symmetry_description: f.symmetry.description
             })
 
             const clusters = f.clusters
             if (clusters) {
                 for (let k = 0, kl = clusters.length; k < kl; ++k) {
-                    const c = clusters[k]!
+                    const c = clusters[k]! // TODO upstream, array members should not be nullable
                     clusterRows.push({
                         feature_id: id,
-                        avg_rmsd: c.avg_rmsd!,
+                        avg_rmsd: c.avg_rmsd || 0, // TODO upstream, should not be nullable, or???
                         members: c.members as string[]
                     })
                 }
@@ -71,9 +76,9 @@ function createDatabase(assemblies: ReadonlyArray<AssemblySymmetryGraphQL.Assemb
                     const a = axes[k]!
                     axisRows.push({
                         feature_id: id,
-                        order: a.order!,
-                        start: a.start as Tensor.Data,
-                        end: a.end as Tensor.Data
+                        order: a.order!,  // TODO upstream, should not be nullable, or???
+                        start: a.start as Tensor.Data, // TODO upstream, array members should not be nullable
+                        end: a.end as Tensor.Data // TODO upstream, array members should not be nullable
                     })
                 }
             }
@@ -83,9 +88,9 @@ function createDatabase(assemblies: ReadonlyArray<AssemblySymmetryGraphQL.Assemb
     }
 
     return _Database.ofTables('assembly_symmetry', Schema, {
-        assembly_symmetry_feature: Table.ofRows(Schema.rcsb_assembly_symmetry_feature, featureRows),
-        assembly_symmetry_cluster: Table.ofRows(Schema.rcsb_assembly_symmetry_cluster, clusterRows),
-        assembly_symmetry_axis: Table.ofRows(Schema.rcsb_assembly_symmetry_axis, axisRows)
+        rcsb_assembly_symmetry_feature: Table.ofRows(Schema.rcsb_assembly_symmetry_feature, featureRows),
+        rcsb_assembly_symmetry_cluster: Table.ofRows(Schema.rcsb_assembly_symmetry_cluster, clusterRows),
+        rcsb_assembly_symmetry_axis: Table.ofRows(Schema.rcsb_assembly_symmetry_axis, axisRows)
     })
 }
 
@@ -107,22 +112,39 @@ const client = new GraphQLClient('http://rest-experimental.rcsb.org/graphql')
 export namespace AssemblySymmetry {
     export const Schema = {
         rcsb_assembly_symmetry_feature: {
+            /** Uniquely identifies a record in `rcsb_assembly_symmetry_feature` */
             id: int,
+            /** A pointer to `pdbx_struct_assembly.id` */
             assembly_id: str,
+            /** Name and version of software used to calculate protein symmetry */
             source: str,
+            /** Type of protein symmetry */
             type: Aliased<'GLOBAL' | 'LOCAL' | 'PSEUDO'>(str),
+            /** Quantitative description of every individual subunit in a given protein */
             stoichiometry_value: List(',', x => x),
-            stoichiometry_description: str
+            /** Oligomeric state for a given composition of subunits */
+            stoichiometry_description: str,
+            /** Point group symmetry value */
+            symmetry_value: str,
+            /** Point group symmetry description */
+            symmetry_description: str
         },
         rcsb_assembly_symmetry_cluster: {
+            /** A pointer to `rcsb_assembly_symmetry_feature.id` */
             feature_id: int,
+            /** Average RMSD between members of a given cluster */
             avg_rmsd: float,
+            /** List of `auth_label_id` values  */
             members: List(',', x => x)
         },
         rcsb_assembly_symmetry_axis: {
+            /** A pointer to `rcsb_assembly_symmetry_feature.id` */
             feature_id: int,
+            /** The order of the symmetry axis */
             order: int,
+            /** The x,y,z coordinate of the start point of a symmetry axis */
             start: Vector(3),
+            /** The x,y,z coordinate of the end point of a symmetry axis */
             end: Vector(3)
         }
     }
@@ -131,17 +153,49 @@ export namespace AssemblySymmetry {
 
     export const Descriptor = _Descriptor;
 
-    export async function attachFromRCSB(model: Model) {
+    export async function attachFromCifOrAPI(model: Model) {
         if (model.customProperties.has(Descriptor)) return true;
 
-        const variables: AssemblySymmetryGraphQL.Variables = { pdbId: model.label.toLowerCase() };
-        const result = await client.request<AssemblySymmetryGraphQL.Query>(query, variables);
-        if (!result || !result.assemblies) return false;
+        let db: Database
+
+        if (model.sourceData.kind === 'mmCIF' && model.sourceData.frame.categoryNames.includes('rcsb_assembly_symmetry_feature')) {
+            const rcsb_assembly_symmetry_feature = toTable(Schema.rcsb_assembly_symmetry_feature, model.sourceData.frame.categories.rcsb_assembly_symmetry_feature)
+
+            let rcsb_assembly_symmetry_cluster
+            if (model.sourceData.frame.categoryNames.includes('rcsb_assembly_symmetry_cluster')) {
+                rcsb_assembly_symmetry_cluster = toTable(Schema.rcsb_assembly_symmetry_cluster, model.sourceData.frame.categories.rcsb_assembly_symmetry_cluster)
+            } else {
+                rcsb_assembly_symmetry_cluster = CifCategory.empty
+            }
+
+            let rcsb_assembly_symmetry_axis
+            if (model.sourceData.frame.categoryNames.includes('rcsb_assembly_symmetry_axis')) {
+                rcsb_assembly_symmetry_axis = toTable(Schema.rcsb_assembly_symmetry_axis, model.sourceData.frame.categories.rcsb_assembly_symmetry_axis)
+            } else {
+                rcsb_assembly_symmetry_axis = CifCategory.empty
+            }
+
+            db = _Database.ofTables('assembly_symmetry', Schema, {
+                rcsb_assembly_symmetry_feature,
+                rcsb_assembly_symmetry_cluster,
+                rcsb_assembly_symmetry_axis
+            })
+        } else {
+            let result: AssemblySymmetryGraphQL.Query
+            const variables: AssemblySymmetryGraphQL.Variables = { pdbId: model.label.toLowerCase() };
+            try {
+                result = await client.request<AssemblySymmetryGraphQL.Query>(query, variables);
+            } catch (e) {
+                console.error(e)
+                return false;
+            }
+            if (!result || !result.assemblies) return false;
+
+            db = createDatabase(result.assemblies as ReadonlyArray<AssemblySymmetryGraphQL.Assemblies>)
+        }
 
-        const db: Database = createDatabase(result.assemblies as ReadonlyArray<AssemblySymmetryGraphQL.Assemblies>)
         model.customProperties.add(Descriptor);
         model._staticPropertyData.__AssemblySymmetry__ = db;
-
         return true;
     }
 

+ 3 - 3
src/servers/model/properties.ts

@@ -7,13 +7,13 @@
 
 import { Model } from 'mol-model/structure';
 import { PDBe_structureQualityReport } from './properties/pdbe';
+import { RCSB_assemblySymmetry } from './properties/rcsb';
 
 export function attachModelProperties(model: Model): Promise<any>[] {
     // return a list of promises that start attaching the props in parallel
     // (if there are downloads etc.)
     return [
-        PDBe_structureQualityReport(model)
-        // removed for now because of schema validation error
-        // SymmetryAnnotation.attachFromRCSB(model)
+        PDBe_structureQualityReport(model),
+        RCSB_assemblySymmetry(model)
     ];
 }

+ 12 - 0
src/servers/model/properties/rcsb.ts

@@ -0,0 +1,12 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Model } from 'mol-model/structure';
+import { AssemblySymmetry } from 'mol-model-props/rcsb/symmetry';
+
+export function RCSB_assemblySymmetry(model: Model) {
+    return AssemblySymmetry.attachFromCifOrAPI(model)
+}