diff --git a/src/mol-model-props/rcsb/graphql/symmetry.gql.ts b/src/mol-model-props/rcsb/graphql/symmetry.gql.ts index d442467aa317be0a3eea756408014b3b413ff145..264166e3ac2ff8bd808f9b8c887b4114068abaf8 100644 --- a/src/mol-model-props/rcsb/graphql/symmetry.gql.ts +++ b/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 diff --git a/src/mol-model-props/rcsb/graphql/types.ts b/src/mol-model-props/rcsb/graphql/types.ts index b75b4b0aea64045ce0d4909fd58cc18e34cef3bc..a5c7ebb3ed520bff17eafc1e4d8cd075c49f1202 100644 --- a/src/mol-model-props/rcsb/graphql/types.ts +++ b/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; }; } diff --git a/src/mol-model-props/rcsb/symmetry.ts b/src/mol-model-props/rcsb/symmetry.ts index 7690babf4ba6616c4089491ebc578a98f105f4b1..b3114645c81af51635607625ccdd9b592f86f210 100644 --- a/src/mol-model-props/rcsb/symmetry.ts +++ b/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; } diff --git a/src/servers/model/properties.ts b/src/servers/model/properties.ts index 95d1ade02545101bc935dd7644540de94f0ddf8f..fddf09e61fceea5f1f97ee5bc320eebac31ff351 100644 --- a/src/servers/model/properties.ts +++ b/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) ]; } \ No newline at end of file diff --git a/src/servers/model/properties/rcsb.ts b/src/servers/model/properties/rcsb.ts new file mode 100644 index 0000000000000000000000000000000000000000..fbc3347d3f2812891f9fc36e4a1f0387bda80a31 --- /dev/null +++ b/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) +} \ No newline at end of file