index.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. * @author David Sehnal <david.sehnal@gmail.com>
  6. */
  7. import * as argparse from 'argparse'
  8. require('util.promisify').shim();
  9. // import { Table } from 'mol-data/db'
  10. import CIF from 'mol-io/reader/cif'
  11. import { Model, Structure, Element, ElementSet, Unit, ElementGroup, Queries } from 'mol-model/structure'
  12. // import { Run, Progress } from 'mol-task'
  13. import { OrderedSet } from 'mol-data/int';
  14. import { Table } from 'mol-data/db';
  15. import { mmCIF_Database } from 'mol-io/reader/cif/schema/mmcif';
  16. import CoarseGrained from 'mol-model/structure/model/properties/coarse-grained';
  17. import { openCif, downloadCif } from './helpers';
  18. async function downloadFromPdb(pdb: string) {
  19. // `https://files.rcsb.org/download/${pdb}.cif`
  20. const parsed = await downloadCif(`http://www.ebi.ac.uk/pdbe/static/entry/${pdb}_updated.cif`, false);
  21. return CIF.schema.mmCIF(parsed.result.blocks[0]);
  22. }
  23. async function readPdbFile(path: string) {
  24. const parsed = await openCif(path);
  25. return CIF.schema.mmCIF(parsed.result.blocks[0]);
  26. }
  27. export function atomLabel(model: Model, aI: number) {
  28. const { atoms, residues, chains, residueSegments, chainSegments } = model.hierarchy
  29. const { label_atom_id } = atoms
  30. const { label_comp_id, label_seq_id } = residues
  31. const { label_asym_id } = chains
  32. const rI = residueSegments.segmentMap[aI]
  33. const cI = chainSegments.segmentMap[aI]
  34. return `${label_asym_id.value(cI)} ${label_comp_id.value(rI)} ${label_seq_id.value(rI)} ${label_atom_id.value(aI)}`
  35. }
  36. export function printBonds(structure: Structure) {
  37. const { units, elements } = structure;
  38. const unitIds = ElementSet.unitIndices(elements);
  39. for (let i = 0, _i = OrderedSet.size(unitIds); i < _i; i++) {
  40. const unit = units[OrderedSet.getAt(unitIds, i)];
  41. const group = ElementSet.groupFromUnitIndex(elements, OrderedSet.getAt(unitIds, i));
  42. const { count, offset, neighbor } = Unit.getGroupBonds(unit, group);
  43. const { model } = unit;
  44. if (!count) continue;
  45. for (let j = 0; j < offset.length - 1; ++j) {
  46. const start = offset[j];
  47. const end = offset[j + 1];
  48. if (end <= start) continue;
  49. const aI = ElementGroup.getAt(group, j);
  50. for (let _bI = start; _bI < end; _bI++) {
  51. const bI = ElementGroup.getAt(group, neighbor[_bI])
  52. console.log(`${atomLabel(model, aI)} -- ${atomLabel(model, bI)}`);
  53. }
  54. }
  55. }
  56. }
  57. export function printSequence(model: Model) {
  58. console.log('Sequence\n=============');
  59. const { byEntityKey } = model.sequence;
  60. for (const key of Object.keys(byEntityKey)) {
  61. const seq = byEntityKey[+key];
  62. console.log(`${seq.entityId} (${seq.num.value(0)}, ${seq.num.value(seq.num.rowCount - 1)}) (${seq.compId.value(0)}, ${seq.compId.value(seq.compId.rowCount - 1)})`);
  63. // for (let i = 0; i < seq.compId.rowCount; i++) {
  64. // console.log(`${seq.entityId} ${seq.num.value(i)} ${seq.compId.value(i)}`);
  65. // }
  66. }
  67. console.log();
  68. }
  69. export function printUnits(structure: Structure) {
  70. console.log('Units\n=============');
  71. const { elements, units } = structure;
  72. const unitIds = ElementSet.unitIndices(elements);
  73. const l = Element.Location();
  74. for (let i = 0, _i = unitIds.length; i < _i; i++) {
  75. const unitId = unitIds[i];
  76. l.unit = units[unitId];
  77. const set = ElementSet.groupAt(elements, i).elements;
  78. const size = OrderedSet.size(set);
  79. if (Unit.isAtomic(l.unit)) {
  80. console.log(`Atomic unit ${unitId}: ${size} elements`);
  81. } else if (Unit.isCoarse(l.unit)) {
  82. console.log(`Coarse unit ${unitId} (${l.unit.elementType === CoarseGrained.ElementType.Sphere ? 'spheres' : 'gaussians'}): ${size} elements.`);
  83. const props = Queries.props.coarse_grained;
  84. const seq = l.unit.model.sequence;
  85. for (let j = 0, _j = Math.min(size, 10); j < _j; j++) {
  86. l.element = OrderedSet.getAt(set, j);
  87. const residues: string[] = [];
  88. const start = props.seq_id_begin(l), end = props.seq_id_end(l);
  89. const compId = seq.byEntityKey[props.entityKey(l)].compId.value;
  90. for (let e = start; e <= end; e++) residues.push(compId(e));
  91. console.log(`${props.asym_id(l)}:${start}-${end} (${residues.join('-')}) ${props.asym_id(l)} [${props.x(l).toFixed(2)}, ${props.y(l).toFixed(2)}, ${props.z(l).toFixed(2)}]`);
  92. }
  93. if (size > 10) console.log(`...`);
  94. }
  95. }
  96. }
  97. export function printIHMModels(model: Model) {
  98. if (!model.coarseGrained.isDefined) return false;
  99. console.log('IHM Models\n=============');
  100. console.log(Table.formatToString(model.coarseGrained.modelList));
  101. }
  102. async function run(mmcif: mmCIF_Database) {
  103. const models = Model.create({ kind: 'mmCIF', data: mmcif });
  104. const structure = Structure.ofModel(models[0]);
  105. printSequence(models[0]);
  106. printIHMModels(models[0]);
  107. printUnits(structure);
  108. }
  109. async function runDL(pdb: string) {
  110. const mmcif = await downloadFromPdb(pdb)
  111. run(mmcif);
  112. }
  113. async function runFile(filename: string) {
  114. const mmcif = await readPdbFile(filename);
  115. run(mmcif);
  116. }
  117. const parser = new argparse.ArgumentParser({
  118. addHelp: true,
  119. description: 'Print info about a structure, mainly to test and showcase the mol-model module'
  120. });
  121. parser.addArgument([ '--download', '-d' ], {
  122. help: 'Pdb entry id'
  123. });
  124. parser.addArgument([ '--file', '-f' ], {
  125. help: 'filename'
  126. });
  127. interface Args {
  128. download?: string,
  129. file?: string
  130. }
  131. const args: Args = parser.parseArgs();
  132. if (args.download) runDL(args.download)
  133. else if (args.file) runFile(args.file)