Browse Source

CifField builder

David Sehnal 6 years ago
parent
commit
619cf8a8ee

+ 4 - 0
src/mol-io/writer/cif.ts

@@ -21,6 +21,10 @@ export namespace CifWriter {
         return binary ? new BinaryEncoder(encoderName) : new TextEncoder();
     }
 
+    export function fields<K = number, D = any>() {
+        return Field.build<K, D>();
+    }
+
     import E = Encoding
     export const Encodings = {
         deltaRLE: E.by(E.delta).and(E.runLength).and(E.integerPacking),

+ 30 - 0
src/mol-io/writer/cif/encoder.ts

@@ -67,6 +67,36 @@ export namespace Field {
     export function index(name: string) {
         return int(name, (e, d, i) => i + 1, { typedArray: Int32Array, encoder: ArrayEncoding.by(ArrayEncoding.delta).and(ArrayEncoding.runLength).and(ArrayEncoding.integerPacking) })
     }
+
+    export class Builder<K = number, D = any> {
+        private fields: Field<K, D>[] = [];
+
+        index(name: string) {
+            this.fields.push(Field.index(name));
+            return this;
+        }
+
+        str(name: string, value: (k: K, d: D, index: number) => string, params?: ParamsBase<K, D>) {
+            this.fields.push(Field.str(name, value, params));
+            return this;
+        }
+
+        int(name: string, value: (k: K, d: D, index: number) => number, params?:  ParamsBase<K, D> & { typedArray?: ArrayEncoding.TypedArrayCtor }) {
+            this.fields.push(Field.int(name, value, params));
+            return this;
+        }
+
+        float(name: string, value: (k: K, d: D, index: number) => number, params?: ParamsBase<K, D> & { typedArray?: ArrayEncoding.TypedArrayCtor, digitCount?: number }) {
+            this.fields.push(Field.float(name, value, params));
+            return this;
+        }
+
+        getFields() { return this.fields; }
+    }
+
+    export function build<K = number, D = any>() {
+        return new Builder<K, D>();
+    }
 }
 
 export interface Category<Ctx = any> {

+ 40 - 40
src/mol-model/structure/export/categories/atom_site.ts

@@ -12,42 +12,42 @@ import CifField = CifWriter.Field
 import CifCategory = CifWriter.Category
 import E = CifWriter.Encodings
 
-const atom_site_fields: CifField<StructureElement, Structure>[] = [
-    CifField.str('group_PDB', P.residue.group_PDB),
-    CifField.index('id'),
-    CifField.str('type_symbol', P.atom.type_symbol as any),
-    CifField.str('label_atom_id', P.atom.label_atom_id),
+const atom_site_fields = CifWriter.fields<StructureElement, Structure>()
+    .str('group_PDB', P.residue.group_PDB)
+    .index('id')
+    .str('type_symbol', P.atom.type_symbol as any)
+    .str('label_atom_id', P.atom.label_atom_id)
 
-    CifField.str('label_comp_id', P.residue.label_comp_id),
-    CifField.int('label_seq_id', P.residue.label_seq_id, {
+    .str('label_comp_id', P.residue.label_comp_id)
+    .int('label_seq_id', P.residue.label_seq_id, {
         encoder: E.deltaRLE,
         valueKind: (k, d) => {
             const m = k.unit.model;
             return m.atomicHierarchy.residues.label_seq_id.valueKind(m.atomicHierarchy.residueAtomSegments.index[k.element]);
         }
-    }),
-    CifField.str('label_alt_id', P.atom.label_alt_id),
-    CifField.str('pdbx_PDB_ins_code', P.residue.pdbx_PDB_ins_code),
+    })
+    .str('label_alt_id', P.atom.label_alt_id)
+    .str('pdbx_PDB_ins_code', P.residue.pdbx_PDB_ins_code)
 
-    CifField.str('label_asym_id', P.chain.label_asym_id),
-    CifField.str('label_entity_id', P.chain.label_entity_id),
+    .str('label_asym_id', P.chain.label_asym_id)
+    .str('label_entity_id', P.chain.label_entity_id)
 
-    CifField.float('Cartn_x', P.atom.x, { digitCount: 3, encoder: E.fixedPoint3 }),
-    CifField.float('Cartn_y', P.atom.y, { digitCount: 3, encoder: E.fixedPoint3 }),
-    CifField.float('Cartn_z', P.atom.z, { digitCount: 3, encoder: E.fixedPoint3 }),
-    CifField.float('occupancy', P.atom.occupancy, { digitCount: 2, encoder: E.fixedPoint2 }),
-    CifField.int('pdbx_formal_charge', P.atom.pdbx_formal_charge, { encoder: E.deltaRLE }),
+    .float('Cartn_x', P.atom.x, { digitCount: 3, encoder: E.fixedPoint3 })
+    .float('Cartn_y', P.atom.y, { digitCount: 3, encoder: E.fixedPoint3 })
+    .float('Cartn_z', P.atom.z, { digitCount: 3, encoder: E.fixedPoint3 })
+    .float('occupancy', P.atom.occupancy, { digitCount: 2, encoder: E.fixedPoint2 })
+    .int('pdbx_formal_charge', P.atom.pdbx_formal_charge, { encoder: E.deltaRLE })
 
-    CifField.str('auth_atom_id', P.atom.auth_atom_id),
-    CifField.str('auth_comp_id', P.residue.auth_comp_id),
-    CifField.int('auth_seq_id', P.residue.auth_seq_id, { encoder: E.deltaRLE }),
-    CifField.str('auth_asym_id', P.chain.auth_asym_id),
+    .str('auth_atom_id', P.atom.auth_atom_id)
+    .str('auth_comp_id', P.residue.auth_comp_id)
+    .int('auth_seq_id', P.residue.auth_seq_id, { encoder: E.deltaRLE })
+    .str('auth_asym_id', P.chain.auth_asym_id)
 
-    CifField.int('pdbx_PDB_model_num', P.unit.model_num, { encoder: E.deltaRLE }),
-    CifField.str<StructureElement, Structure>('operator_name', P.unit.operator_name, {
+    .int('pdbx_PDB_model_num', P.unit.model_num, { encoder: E.deltaRLE })
+    .str('operator_name', P.unit.operator_name, {
         shouldInclude: structure => structure.units.some(u => !u.conformation.operator.isIdentity)
     })
-];
+    .getFields();
 
 export const _atom_site: CifCategory<CifExportContext> = {
     name: 'atom_site',
@@ -70,31 +70,31 @@ function mappedProp<K, D>(loc: (key: K, data: D) => StructureElement, prop: (e:
 }
 
 export function residueIdFields<K, D>(getLocation: (key: K, data: D) => StructureElement, prefix = ''): CifField<K, D>[] {
-    return [
-        CifField.str(prefixed(prefix, `label_comp_id`), mappedProp(getLocation, P.residue.label_comp_id)),
-        CifField.int(prefixed(prefix, `label_seq_id`), mappedProp(getLocation, P.residue.label_seq_id), {
+    return CifWriter.fields<K, D>()
+        .str(prefixed(prefix, `label_comp_id`), mappedProp(getLocation, P.residue.label_comp_id))
+        .int(prefixed(prefix, `label_seq_id`), mappedProp(getLocation, P.residue.label_seq_id), {
             encoder: E.deltaRLE,
             valueKind: (k, d) => {
                 const e = getLocation(k, d);
                 const m = e.unit.model;
                 return m.atomicHierarchy.residues.label_seq_id.valueKind(m.atomicHierarchy.residueAtomSegments.index[e.element]);
             }
-        }),
-        CifField.str(prefixed(prefix, `pdbx_PDB_ins_code`), mappedProp(getLocation, P.residue.pdbx_PDB_ins_code)),
+        })
+        .str(prefixed(prefix, `pdbx_PDB_ins_code`), mappedProp(getLocation, P.residue.pdbx_PDB_ins_code))
 
-        CifField.str(prefixed(prefix, `label_asym_id`), mappedProp(getLocation, P.chain.label_asym_id)),
-        CifField.str(prefixed(prefix, `label_entity_id`), mappedProp(getLocation, P.chain.label_entity_id)),
+        .str(prefixed(prefix, `label_asym_id`), mappedProp(getLocation, P.chain.label_asym_id))
+        .str(prefixed(prefix, `label_entity_id`), mappedProp(getLocation, P.chain.label_entity_id))
 
-        CifField.str(prefixed(prefix, `auth_comp_id`), mappedProp(getLocation, P.residue.auth_comp_id)),
-        CifField.int(prefixed(prefix, `auth_seq_id`), mappedProp(getLocation, P.residue.auth_seq_id), { encoder: E.deltaRLE }),
-        CifField.str(prefixed(prefix, `auth_asym_id`), mappedProp(getLocation, P.chain.auth_asym_id))
-    ];
+        .str(prefixed(prefix, `auth_comp_id`), mappedProp(getLocation, P.residue.auth_comp_id))
+        .int(prefixed(prefix, `auth_seq_id`), mappedProp(getLocation, P.residue.auth_seq_id), { encoder: E.deltaRLE })
+        .str(prefixed(prefix, `auth_asym_id`), mappedProp(getLocation, P.chain.auth_asym_id))
+        .getFields();
 }
 
 export function chainIdFields<K, D>(getLocation: (key: K, data: D) => StructureElement, prefix = ''): CifField<K, D>[] {
-    return [
-        CifField.str(prefixed(prefix, `label_asym_id`), mappedProp(getLocation, P.chain.label_asym_id)),
-        CifField.str(prefixed(prefix, `label_entity_id`), mappedProp(getLocation, P.chain.label_entity_id)),
-        CifField.str(prefixed(prefix, `auth_asym_id`), mappedProp(getLocation, P.chain.auth_asym_id))
-    ];
+    return CifField.build<K, D>()
+        .str(prefixed(prefix, `label_asym_id`), mappedProp(getLocation, P.chain.label_asym_id))
+        .str(prefixed(prefix, `label_entity_id`), mappedProp(getLocation, P.chain.label_entity_id))
+        .str(prefixed(prefix, `auth_asym_id`), mappedProp(getLocation, P.chain.auth_asym_id))
+        .getFields();
 }