mmcif.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { Column } from 'mol-data/db'
  8. import Iterator from 'mol-data/iterator'
  9. import * as Encoder from 'mol-io/writer/cif'
  10. // import { mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif'
  11. import { Structure, Element } from '../structure'
  12. import { Model } from '../model'
  13. import P from '../query/properties'
  14. interface Context {
  15. structure: Structure,
  16. model: Model
  17. }
  18. function str<K, D>(name: string, value: (k: K, d: D) => string, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, D> {
  19. return { name, type: Encoder.FieldType.Str, value, valueKind }
  20. }
  21. function int<K, D = any>(name: string, value: (k: K, d: D) => number, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, D> {
  22. return { name, type: Encoder.FieldType.Int, value, valueKind }
  23. }
  24. function float<K, D = any>(name: string, value: (k: K, d: D) => number, valueKind?: (k: K) => Column.ValueKind): Encoder.FieldDefinition<K, D> {
  25. return { name, type: Encoder.FieldType.Float, value, valueKind, digitCount: 3 }
  26. }
  27. // function col<K, D>(name: string, c: (data: D) => Column<any>): Encoder.FieldDefinition<K, D> {
  28. // const kind = c['@type'].kind;
  29. // // TODO: matrix/vector/support
  30. // const type = kind === 'str' ? Encoder.FieldType.Str : kind === 'int' ? Encoder.FieldType.Int : Encoder.FieldType.Float
  31. // return { name, type, value, valueKind }
  32. // }
  33. // type Entity = Table.Columns<typeof mmCIF_Schema.entity>
  34. // const entity: Encoder.CategoryDefinition<number, Entity> = {
  35. // name: 'entity',
  36. // fields: ofSchema(mmCIF_Schema.entity)
  37. // }
  38. // [
  39. // str('id', (i, e) => e.id.value(i)),
  40. // str('type', (i, e) => e.type.value(i)),
  41. // str('src_method', (i, e) => e.src_method.value(i)),
  42. // str('pdbx_description', (i, e) => e.pdbx_description.value(i)),
  43. // int('formula_weight', (i, e) => e.formula_weight.value(i)),
  44. // float('pdbx_number_of_molecules', (i, e) => e.pdbx_number_of_molecules.value(i)),
  45. // str('details', (i, e) => e.details.value(i)),
  46. // str('pdbx_mutation', (i, e) => e.pdbx_mutation.value(i)),
  47. // str('pdbx_fragment', (i, e) => e.pdbx_fragment.value(i)),
  48. // str('pdbx_ec', (i, e) => e.pdbx_ec.value(i)),
  49. // ]
  50. // type AtomSite = typeof mmCIF_Schema.atom_site;
  51. // type DataSource<Key, Schema extends Table.Schema> = { [P in keyof Schema]: (key: Key) => Schema[P]['T'] }
  52. // export const atom_site1: Partial<DataSource<Atom.Location, AtomSite>> = {
  53. // group_PDB: P.residue.group_PDB,
  54. // id: P.atom.id,
  55. // type_symbol: P.atom.type_symbol as any,
  56. // label_atom_id: P.atom.label_atom_id,
  57. // //...
  58. // }
  59. const atom_site: Encoder.CategoryDefinition<Element.Location> = {
  60. name: 'atom_site',
  61. fields: [
  62. str('group_PDB', P.residue.group_PDB),
  63. int('id', P.atom.id),
  64. str('type_symbol', P.atom.type_symbol as any),
  65. str('label_atom_id', P.atom.label_atom_id),
  66. str('label_alt_id', P.atom.label_alt_id),
  67. str('label_comp_id', P.residue.label_comp_id),
  68. int('label_seq_id', P.residue.label_seq_id),
  69. str('pdbx_PDB_ins_code', P.residue.pdbx_PDB_ins_code),
  70. str('label_asym_id', P.chain.label_asym_id),
  71. str('label_entity_id', P.chain.label_entity_id),
  72. float('Cartn_x', P.atom.x),
  73. float('Cartn_y', P.atom.y),
  74. float('Cartn_z', P.atom.z),
  75. float('occupancy', P.atom.occupancy),
  76. int('pdbx_formal_charge', P.atom.pdbx_formal_charge),
  77. str('auth_atom_id', P.atom.auth_atom_id),
  78. str('auth_comp_id', P.residue.auth_comp_id),
  79. int('auth_seq_id', P.residue.auth_seq_id),
  80. str('auth_asym_id', P.chain.auth_asym_id),
  81. int('pdbx_PDB_model_num', P.unit.model_num),
  82. str('operator_name', P.unit.operator_name)
  83. ]
  84. };
  85. function entityProvider({ model }: Context): Encoder.CategoryInstance {
  86. return {
  87. data: model.entities.data,
  88. definition: Encoder.CategoryDefinition.ofTable('entity', model.entities.data),
  89. keys: () => Iterator.Range(0, model.entities.data._rowCount - 1),
  90. rowCount: model.entities.data._rowCount
  91. }
  92. }
  93. function atomSiteProvider({ structure }: Context): Encoder.CategoryInstance {
  94. return {
  95. data: void 0,
  96. definition: atom_site,
  97. keys: () => structure.elementLocations(),
  98. rowCount: structure.elementCount
  99. }
  100. }
  101. /** Doesn't start a data block */
  102. export function encode_mmCIF_categories(encoder: Encoder.EncoderInstance, structure: Structure) {
  103. const models = Structure.getModels(structure);
  104. if (models.length !== 1) throw 'Can\'t export stucture composed from multiple models.';
  105. const model = models[0];
  106. const ctx: Context = { structure, model };
  107. encoder.writeCategory(entityProvider, [ctx]);
  108. encoder.writeCategory(atomSiteProvider, [ctx]);
  109. }
  110. function to_mmCIF(name: string, structure: Structure, asBinary = false) {
  111. const w = Encoder.create({ binary: asBinary });
  112. w.startDataBlock(name);
  113. encode_mmCIF_categories(w, structure);
  114. return w.getData();
  115. }
  116. export default to_mmCIF