mmcif.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /**
  2. * Copyright (c) 2017-2020 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 { Model } from '../../mol-model/structure/model/model';
  8. import { Task } from '../../mol-task';
  9. import { ModelFormat } from '../format';
  10. import { CifFrame, CIF } from '../../mol-io/reader/cif';
  11. import { mmCIF_Database } from '../../mol-io/reader/cif/schema/mmcif';
  12. import { createModels } from './basic/parser';
  13. import { ModelSymmetry } from './property/symmetry';
  14. import { ModelSecondaryStructure } from './property/secondary-structure';
  15. import { Table } from '../../mol-data/db';
  16. import { AtomSiteAnisotrop } from './property/anisotropic';
  17. import { ComponentBond } from './property/bonds/comp';
  18. import { StructConn } from './property/bonds/struct_conn';
  19. function modelSymmetryFromMmcif(model: Model) {
  20. if (!MmcifFormat.is(model.sourceData)) return;
  21. return ModelSymmetry.fromData(model.sourceData.data.db);
  22. }
  23. ModelSymmetry.Provider.formatRegistry.add('mmCIF', modelSymmetryFromMmcif);
  24. function secondaryStructureFromMmcif(model: Model) {
  25. if (!MmcifFormat.is(model.sourceData)) return;
  26. const { struct_conf, struct_sheet_range } = model.sourceData.data.db;
  27. return ModelSecondaryStructure.fromStruct(struct_conf, struct_sheet_range, model.atomicHierarchy);
  28. }
  29. ModelSecondaryStructure.Provider.formatRegistry.add('mmCIF', secondaryStructureFromMmcif);
  30. function atomSiteAnisotropFromMmcif(model: Model) {
  31. if (!MmcifFormat.is(model.sourceData)) return;
  32. const { atom_site_anisotrop } = model.sourceData.data.db;
  33. const data = Table.ofColumns(AtomSiteAnisotrop.Schema, atom_site_anisotrop);
  34. const elementToAnsiotrop = AtomSiteAnisotrop.getElementToAnsiotrop(model.atomicConformation.atomId, atom_site_anisotrop.id);
  35. return { data, elementToAnsiotrop };
  36. }
  37. function atomSiteAnisotropApplicableMmcif(model: Model) {
  38. if (!MmcifFormat.is(model.sourceData)) return false;
  39. return model.sourceData.data.db.atom_site_anisotrop.U.isDefined;
  40. }
  41. AtomSiteAnisotrop.Provider.formatRegistry.add('mmCIF', atomSiteAnisotropFromMmcif, atomSiteAnisotropApplicableMmcif);
  42. function componentBondFromMmcif(model: Model) {
  43. if (!MmcifFormat.is(model.sourceData)) return;
  44. const { chem_comp_bond } = model.sourceData.data.db;
  45. if (chem_comp_bond._rowCount === 0) return;
  46. return {
  47. data: chem_comp_bond,
  48. entries: ComponentBond.getEntriesFromChemCompBond(chem_comp_bond)
  49. };
  50. }
  51. ComponentBond.Provider.formatRegistry.add('mmCIF', componentBondFromMmcif);
  52. function structConnFromMmcif(model: Model) {
  53. if (!MmcifFormat.is(model.sourceData)) return;
  54. const { struct_conn } = model.sourceData.data.db;
  55. if (struct_conn._rowCount === 0) return;
  56. const entries = StructConn.getEntriesFromStructConn(struct_conn, model);
  57. return {
  58. data: struct_conn,
  59. byAtomIndex: StructConn.getAtomIndexFromEntries(entries),
  60. entries,
  61. };
  62. }
  63. StructConn.Provider.formatRegistry.add('mmCIF', structConnFromMmcif);
  64. //
  65. export { MmcifFormat };
  66. type MmcifFormat = ModelFormat<MmcifFormat.Data>
  67. namespace MmcifFormat {
  68. export type Data = { db: mmCIF_Database, frame: CifFrame }
  69. export function is(x: ModelFormat): x is MmcifFormat {
  70. return x.kind === 'mmCIF';
  71. }
  72. export function fromFrame(frame: CifFrame, db?: mmCIF_Database): MmcifFormat {
  73. if (!db) db = CIF.schema.mmCIF(frame);
  74. return { kind: 'mmCIF', name: db._name, data: { db, frame } };
  75. }
  76. export function isBirdMolecule(model: Model, asymId: string) {
  77. if (!MmcifFormat.is(model.sourceData)) return false;
  78. const { _rowCount, asym_id } = model.sourceData.data.db.pdbx_molecule;
  79. for (let i = 0, il = _rowCount; i < il; ++i) {
  80. if (asym_id.value(i) === asymId) return true;
  81. }
  82. return false;
  83. }
  84. }
  85. export function trajectoryFromMmCIF(frame: CifFrame): Task<Model.Trajectory> {
  86. const format = MmcifFormat.fromFrame(frame);
  87. return Task.create('Create mmCIF Model', ctx => createModels(format.data.db, format, ctx));
  88. }