diff --git a/src/mol-data/structure/export/mmcif.ts b/src/mol-data/structure/export/mmcif.ts index d3fb005b040bf5fcf146b59f468b284dadc8f95d..2d4a2443cfde1df0aba6e5fc8e6efaad3e35f3ef 100644 --- a/src/mol-data/structure/export/mmcif.ts +++ b/src/mol-data/structure/export/mmcif.ts @@ -4,10 +4,10 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { Column } from 'mol-base/collections/database' +import { Column, Table } from 'mol-base/collections/database' import Iterator from 'mol-base/collections/iterator' import * as Encoder from 'mol-io/writer/cif/encoder' -import { mmCIF_Database } from 'mol-io/reader/cif/schema/mmcif' +import { mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif' import CIFEncoder from 'mol-io/writer/cif/encoder/text' import { Structure, Atom, AtomSet } from '../structure' import { Model } from '../model' @@ -18,36 +18,75 @@ interface Context { model: Model } -function str<K, D = any>(name: string, value: (k: K, d: D) => string, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, any> { +function str<K, D>(name: string, value: (k: K, d: D) => string, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, D> { return { name, type: Encoder.FieldType.Str, value, valueKind } } -function int<K, D = any>(name: string, value: (k: K, d: D) => number, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, any> { +function int<K, D = any>(name: string, value: (k: K, d: D) => number, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, D> { return { name, type: Encoder.FieldType.Int, value, valueKind } } -function float<K, D = any>(name: string, value: (k: K, d: D) => number, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, any> { +function float<K, D = any>(name: string, value: (k: K, d: D) => number, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, D> { return { name, type: Encoder.FieldType.Float, value, valueKind } } -type Entity = mmCIF_Database['entity']; +// function col<K, D>(name: string, c: (data: D) => Column<any>): Encoder.FieldDefinition<K, D> { +// const kind = c['@type'].kind; +// // TODO: matrix/vector/support +// const type = kind === 'str' ? Encoder.FieldType.Str : kind === 'int' ? Encoder.FieldType.Int : Encoder.FieldType.Float +// return { name, type, value, valueKind } +// } + +function columnValue(k: string) { + return (i: number, d: any) => d[k].value(i); +} + +function columnValueKind(k: string) { + return (i: number, d: any) => d[k].valueKind(i); +} + +function ofSchema(schema: Table.Schema) { + const fields: Encoder.FieldDefinition[] = []; + for (const k of Object.keys(schema)) { + const t = schema[k]; + // TODO: matrix/vector/support + const type = t.kind === 'str' ? Encoder.FieldType.Str : t.kind === 'int' ? Encoder.FieldType.Int : Encoder.FieldType.Float; + fields.push({ name: k, type, value: columnValue(k), valueKind: columnValueKind(k) }) + } + return fields; +} + +type Entity = Table.Columns<typeof mmCIF_Schema.entity> const entity: Encoder.CategoryDefinition<number, Entity> = { name: 'entity', - fields: [ - str<number, Entity>('id', (i, e) => e.id.value(i)), - str<number, Entity>('type', (i, e) => e.type.value(i)), - str<number, Entity>('src_method', (i, e) => e.src_method.value(i)), - str<number, Entity>('pdbx_description', (i, e) => e.pdbx_description.value(i)), - int<number, Entity>('formula_weight', (i, e) => e.formula_weight.value(i)), - float<number, Entity>('pdbx_number_of_molecules', (i, e) => e.pdbx_number_of_molecules.value(i)), - str<number, Entity>('details', (i, e) => e.details.value(i)), - str<number, Entity>('pdbx_mutation', (i, e) => e.pdbx_mutation.value(i)), - str<number, Entity>('pdbx_fragment', (i, e) => e.pdbx_fragment.value(i)), - str<number, Entity>('pdbx_ec', (i, e) => e.pdbx_ec.value(i)), - ] + fields: ofSchema(mmCIF_Schema.entity) } +// [ +// str('id', (i, e) => e.id.value(i)), +// str('type', (i, e) => e.type.value(i)), +// str('src_method', (i, e) => e.src_method.value(i)), +// str('pdbx_description', (i, e) => e.pdbx_description.value(i)), +// int('formula_weight', (i, e) => e.formula_weight.value(i)), +// float('pdbx_number_of_molecules', (i, e) => e.pdbx_number_of_molecules.value(i)), +// str('details', (i, e) => e.details.value(i)), +// str('pdbx_mutation', (i, e) => e.pdbx_mutation.value(i)), +// str('pdbx_fragment', (i, e) => e.pdbx_fragment.value(i)), +// str('pdbx_ec', (i, e) => e.pdbx_ec.value(i)), +// ] + +// type AtomSite = typeof mmCIF_Schema.atom_site; +// type DataSource<Key, Schema extends Table.Schema> = { [P in keyof Schema]: (key: Key) => Schema[P]['T'] } + +// export const atom_site1: Partial<DataSource<Atom.Location, AtomSite>> = { +// group_PDB: P.residue.group_PDB, +// id: P.atom.id, +// type_symbol: P.atom.type_symbol as any, +// label_atom_id: P.atom.label_atom_id, +// //... +// } + const atom_site: Encoder.CategoryDefinition<Atom.Location> = { name: 'atom_site', fields: [ diff --git a/src/mol-io/writer/cif/encoder/text.ts b/src/mol-io/writer/cif/encoder/text.ts index 06c1d67d29f718b74c6f354e7d33fc6ee279a315..46b3fd4cdf599718e302f461442a5e75fecd19d2 100644 --- a/src/mol-io/writer/cif/encoder/text.ts +++ b/src/mol-io/writer/cif/encoder/text.ts @@ -60,7 +60,7 @@ export default class TextCIFEncoder<Context> implements Enc.CIFEncoder<string, C } } -function writeValue(builder: StringBuilder, data: any, key: any, f: Enc.FieldDefinition): boolean { +function writeValue(builder: StringBuilder, data: any, key: any, f: Enc.FieldDefinition<any, any>): boolean { const kind = f.valueKind; const p = kind ? kind(key, data) : Column.ValueKind.Present; if (p !== Column.ValueKind.Present) {