diff --git a/src/reader/cif/schema.ts b/src/reader/cif/schema.ts index 28f2afca2d78d3956ce2ac46fd1d8bfa11f0585d..8b390a4862a022e49ddb34717ddba7d6509f91d1 100644 --- a/src/reader/cif/schema.ts +++ b/src/reader/cif/schema.ts @@ -101,6 +101,7 @@ export namespace Field { } } + // spec argument is to allow for specialised implementation for undefined fields function createSchema<T>(spec: Spec | undefined, ctor: (field: Data.Field, category: Data.Category, key: string) => Column.Column<T>): Schema<T> { return { type: 0 as any, ctor, undefinedField: (spec && spec.undefinedField) || Data.DefaultUndefinedField, alias: spec && spec.alias }; } diff --git a/src/reader/cif/schema/ddl.ts b/src/reader/cif/schema/ddl.ts new file mode 100644 index 0000000000000000000000000000000000000000..562133592a0ecb811f45af4ff26eccd6896a9c62 --- /dev/null +++ b/src/reader/cif/schema/ddl.ts @@ -0,0 +1,2 @@ + +// TODO save frame schema for ddl http://mmcif.wwpdb.org/dictionaries/mmcif_ddl.dic/Index/ diff --git a/src/reader/cif/schema/dic.ts b/src/reader/cif/schema/dic.ts new file mode 100644 index 0000000000000000000000000000000000000000..96f8d19c8b514aa3aee3750320db8401cd525f1c --- /dev/null +++ b/src/reader/cif/schema/dic.ts @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Field, Block } from '../schema' + +const str = Field.str() +const float = Field.float() + +const datablock = { + id: str, + description: str +} + +const dictionary = { + title: str, + datablock_id: str, + version: str +} + +const dictionary_history = { + version: str, + update: str, + revision: str +} + +const sub_category = { + id: str, + description: str +} + +const category_group_list = { + id: str, + parent_id: str, + description: str +} + +const item_type_list = { + code: str, + primitive_code: str, + construct: str, + detail: str +} + +const item_units_list = { + code: str, + detail: str +} + +const item_units_conversion = { + from_code: str, + to_code: str, + operator: str, + factor: float +} + +// TODO save frame dic schema + +const dic = { + datablock, + dictionary, + dictionary_history, + sub_category, + category_group_list, + item_type_list, + item_units_list, + item_units_conversion +} + +type dic = Block.Instance<typeof dic> +export default dic diff --git a/src/reader/cif/schema/utils.ts b/src/reader/cif/schema/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..42093d8391390b99cc3a7f6e5efb2161dd362af1 --- /dev/null +++ b/src/reader/cif/schema/utils.ts @@ -0,0 +1,100 @@ + +// import dic from './dic' +import { Field, Category } from '../schema' +import * as Data from '../data-model' + +const pooledStr = Field.pooledStr() +const str = Field.str() +const int = Field.int() +const float = Field.float() + +function getFieldType (type: string) { + switch (type) { + case 'code': + case 'ucode': + case 'line': + case 'uline': + case 'text': + case 'name': + case 'idname': + case 'any': + case 'atcode': + case 'fax': + case 'phone': + case 'email': + case 'code30': + case 'ec-type': + case 'seq-one-letter-code': + case 'author': + case 'orcid_id': + case 'sequence_dep': + case 'pdb_id': + case 'emd_id': + // todo, consider adding specialised fields + case 'yyyy-mm-dd': + case 'yyyy-mm-dd:hh:mm': + case 'yyyy-mm-dd:hh:mm-flex': + case 'int-range': + case 'float-range': + case 'binary': + case 'operation_expression': + case 'ucode-alphanum-csv': + case 'point_symmetry': + case 'id_list': + case '4x3_matrix': + case 'point_group': + case 'point_group_helical': + case 'boolean': + case 'symmetry_operation': + case 'date_dep': + return str + case 'uchar3': + case 'uchar1': + case 'symop': + return pooledStr + case 'int': + case 'non_negative_int': + case 'positive_int': + return int + case 'float': + return float + } + console.log(`unknown type '${type}'`) + return str +} + +export function getSchema (dic: Data.Block) { // todo Block needs to be specialized with safe frames as well + const schema: { [category: string]: Category.Schema } = {} + + dic.saveFrames.forEach(d => { + if (d.header[0] !== '_') { + schema[d.header] = {} + } else { + const categoryName = d.header.substring(1, d.header.indexOf('.')) + const itemName = d.header.substring(d.header.indexOf('.') + 1) + let fields + if (categoryName in schema) { + fields = schema[categoryName] + } else { + fields = {} + schema[categoryName] = fields + } + // console.log(util.inspect(d.categories, {showHidden: false, depth: 1})) + const item_type = d.categories['_item_type'] + if (item_type) { + const code = item_type.getField('code') + if (code) { + fields[itemName] = getFieldType(code.str(0)) + } else { + console.log(`item_type.code not found for '${d.header}'`) + } + } else { + // TODO check for _item_linked.parent_name and use its type + console.log(`item_type not found for '${d.header}'`) + } + + } + }) + + return schema +} diff --git a/src/script.ts b/src/script.ts index 724767d15e7d62088e67cd2cd27ef6ec260647e0..06868a492c54fa9971cfd113a919448c5a9051f8 100644 --- a/src/script.ts +++ b/src/script.ts @@ -11,6 +11,8 @@ import * as fs from 'fs' import Gro from './reader/gro/parser' import CIF from './reader/cif/index' +import { getSchema } from './reader/cif/schema/utils' + const file = '1crn.gro' // const file = 'water.gro' // const file = 'test.gro' @@ -148,8 +150,9 @@ async function runDic(input: string | Uint8Array) { return; } - const data = parsed.result.blocks[0]; - console.log(util.inspect(data.saveFrames, {showHidden: false, depth: 3})) + const schema = getSchema(parsed.result.blocks[0]) + // console.log(util.inspect(schema, {showHidden: false, depth: 1})) + console.log(util.inspect(Object.keys(schema).length, {showHidden: false, depth: 1})) } export function _dic() {