Skip to content
Snippets Groups Projects
Commit 3157bff8 authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, first pass at mmcif schema code generation

parent cd04952a
No related branches found
No related tags found
No related merge requests found
// import dic from './dic'
import { Field, FrameSchema } from '../schema'
import * as Data from '../data-model'
const pooledStr = Field.pooledStr()
const str = Field.str()
const int = Field.int()
const float = Field.float()
export function getFieldType (type: string) {
export function getFieldType (type: string, values?: string[]) {
switch (type) {
case 'code':
case 'ucode':
if (values && values.length) {
return `str as Field.Schema<'${values.join("'|'")}'>`
} else {
return 'str'
}
case 'line':
case 'uline':
case 'text':
......@@ -47,32 +46,32 @@ export function getFieldType (type: string) {
case 'boolean':
case 'symmetry_operation':
case 'date_dep':
return str
return 'str'
case 'uchar3':
case 'uchar1':
case 'symop':
return pooledStr
return 'pooledStr'
case 'int':
case 'non_negative_int':
case 'positive_int':
return int
return 'int'
case 'float':
return float
return 'float'
}
console.log(`unknown type '${type}'`)
return str
return 'str'
}
type SafeFrameCategories = { [category: string]: Data.Frame }
type SafeFrameLinks = { [k: string]: string }
type FrameCategories = { [category: string]: Data.Frame }
type FrameLinks = { [k: string]: string }
interface SafeFrameData {
categories: SafeFrameCategories
links: SafeFrameLinks
interface FrameData {
categories: FrameCategories
links: FrameLinks
}
// get field from given or linked category
function getField ( category: string, field: string, d: Data.Frame, ctx: SafeFrameData): Data.Field|undefined {
function getField ( category: string, field: string, d: Data.Frame, ctx: FrameData): Data.Field|undefined {
const { categories, links } = ctx
const cat = d.categories[category]
......@@ -87,43 +86,64 @@ function getField ( category: string, field: string, d: Data.Frame, ctx: SafeFra
}
}
// function getEnums (d: Data.SafeFrame, ctx: SafeFrameData): string[]|undefined {
// const value = getField('_item_enumeration', 'value', d, ctx)
// if (value) {
// const enums: string[] = []
// for (let i = 0; i < value.rowCount; ++i) {
// enums.push(value.str(i))
// // console.log(value.str(i))
// }
// return enums
// } else {
// // console.log(`item_enumeration.value not found for '${d.header}'`)
// }
// }
function getCode (d: Data.Frame, ctx: SafeFrameData): string|undefined {
function getEnums (d: Data.Frame, ctx: FrameData): string[]|undefined {
const value = getField('_item_enumeration', 'value', d, ctx)
if (value) {
const enums: string[] = []
for (let i = 0; i < value.rowCount; ++i) {
enums.push(value.str(i))
// console.log(value.str(i))
}
return enums
} else {
// console.log(`item_enumeration.value not found for '${d.header}'`)
}
}
function getCode (d: Data.Frame, ctx: FrameData): [string, string[]]|undefined {
const code = getField('_item_type', 'code', d, ctx)
if (code) {
let c = code.str(0)
// if (c === 'ucode') {
// const enums = getEnums(d, ctx)
// if (enums) c += `: ${enums.join('|')}`
// }
return c
let e = []
if (c === 'ucode') {
const enums = getEnums(d, ctx)
if (enums) e.push(...enums)
}
return [c, e]
} else {
console.log(`item_type.code not found for '${d.header}'`)
}
}
export function getSchema (dic: Data.Block) { // todo Block needs to be specialized with safe frames as well
const schema: FrameSchema = {} // { [category: string]: Category.Schema } = {}
const header = `/**
* Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Your friendly code generator
*/
import { Field, TypedFrame } from '../schema'
const pooledStr = Field.pooledStr();
const str = Field.str();
const int = Field.int();
const float = Field.float();`
const footer = `
type mmCIF = TypedFrame<typeof mmCIF>
export default mmCIF;`
export function generateSchema (dic: Data.Block) { // todo Block needs to be specialized with safe frames as well
// const schema: FrameSchema = {} // { [category: string]: Category.Schema } = {}
const schema: { [category: string]: { [field: string]: string } } = {}
const codeLines: string[] = []
// TODO: for fields with finite allowed values, generate:
// type FieldValue = 'a' | 'b' | 'c'
// const catetegory = { field: <type> as Field.Schema<FieldValue> }
const categories: SafeFrameCategories = {}
const links: SafeFrameLinks = {}
const categories: FrameCategories = {}
const links: FrameLinks = {}
dic.saveFrames.forEach(d => {
if (d.header[0] !== '_') return
categories[d.header] = d
......@@ -158,11 +178,26 @@ export function getSchema (dic: Data.Block) { // todo Block needs to be special
const code = getCode(d, { categories, links })
if (code) {
fields[itemName] = getFieldType(code)
fields[itemName] = getFieldType(code[0], code[1])
} else {
console.log(`could not determine code for '${d.header}'`)
}
})
return schema;
schema.entry = { id: 'str' }
codeLines.push(`const mmCIF = {`)
Object.keys(schema).forEach(category => {
codeLines.push(`\t${category}: {`)
const fields = schema[category]
Object.keys(fields).forEach(field => {
const type = fields[field]
// TODO: check if quoting is required
codeLines.push(`\t\t'${field}': ${type},`)
})
codeLines.push('\t},')
})
codeLines.push('}')
return `${header}\n\n${codeLines.join('\n')}\n${footer}`
}
......@@ -10,12 +10,13 @@ import * as fs from 'fs'
require('util.promisify').shim();
const readFileAsync = util.promisify(fs.readFile);
const writeFileAsync = util.promisify(fs.writeFile);
import Gro from './reader/gro/parser'
import CIF from './reader/cif/index'
import { toTypedFrame as applySchema } from './reader/cif/schema'
import { getSchema } from './reader/cif/schema/utils'
// import { toTypedFrame as applySchema } from './reader/cif/schema'
import { generateSchema } from './reader/cif/schema/utils'
const file = '1crn.gro'
// const file = 'water.gro'
......@@ -109,16 +110,16 @@ async function runCIF(input: string | Uint8Array) {
console.log(mmcif.entity.type.toArray());
console.log(mmcif.pdbx_struct_oper_list.matrix.value(0));
const schema = await _dic()
if (schema) {
const mmcif2 = applySchema(schema, data)
// console.log(util.inspect(mmcif2.atom_site, {showHidden: false, depth: 3}))
console.log(mmcif2.atom_site.Cartn_x.value(0));
console.log(mmcif2.entity.type.toArray());
// console.log(mmcif2.pdbx_struct_oper_list.matrix.value(0)); // TODO
} else {
console.log('error getting mmcif schema from dic')
}
// const schema = await _dic()
// if (schema) {
// const mmcif2 = applySchema(schema, data)
// // console.log(util.inspect(mmcif2.atom_site, {showHidden: false, depth: 3}))
// console.log(mmcif2.atom_site.Cartn_x.value(0));
// console.log(mmcif2.entity.type.toArray());
// // console.log(mmcif2.pdbx_struct_oper_list.matrix.value(0)); // TODO
// } else {
// console.log('error getting mmcif schema from dic')
// }
}
export async function _cif() {
......@@ -153,10 +154,12 @@ async function runDic(input: string | Uint8Array) {
return;
}
const schema = getSchema(parsed.result.blocks[0])
console.log(util.inspect(schema, {showHidden: false, depth: 3}))
const schema = generateSchema(parsed.result.blocks[0])
// console.log(schema)
// console.log(util.inspect(Object.keys(schema).length, {showHidden: false, depth: 1}))
await writeFileAsync('./src/reader/cif/schema/mmcif-gen.ts', schema, 'utf8')
return schema
}
......@@ -168,7 +171,7 @@ export async function _dic() {
return runDic(input);
}
// _dic();
_dic();
import Computation from './utils/computation'
const comp = Computation.create(async ctx => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment