modified-residues.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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 { Segmentation } from '../../../../mol-data/int';
  8. import { CifWriter } from '../../../../mol-io/writer/cif';
  9. import { StructureElement, StructureProperties as P, Unit } from '../../../structure';
  10. import { CifExportContext } from '../mmcif';
  11. import CifField = CifWriter.Field
  12. import CifCategory = CifWriter.Category
  13. const pdbx_struct_mod_residue_fields: CifField<number, StructureElement.Location[]>[] = [
  14. CifField.index('id'),
  15. CifField.str(`label_comp_id`, (i, xs) => P.residue.label_comp_id(xs[i])),
  16. CifField.int(`label_seq_id`, (i, xs) => P.residue.label_seq_id(xs[i])),
  17. CifField.str(`pdbx_PDB_ins_code`, (i, xs) => P.residue.pdbx_PDB_ins_code(xs[i])),
  18. CifField.str(`label_asym_id`, (i, xs) => P.chain.label_asym_id(xs[i])),
  19. CifField.str(`label_entity_id`, (i, xs) => P.chain.label_entity_id(xs[i])),
  20. CifField.str(`auth_comp_id`, (i, xs) => P.residue.auth_comp_id(xs[i])),
  21. CifField.int(`auth_seq_id`, (i, xs) => P.residue.auth_seq_id(xs[i])),
  22. CifField.str(`auth_asym_id`, (i, xs) => P.chain.auth_asym_id(xs[i])),
  23. CifField.str<number, StructureElement.Location[]>('parent_comp_id', (i, xs) => xs[i].unit.model.properties.modifiedResidues.parentId.get(P.residue.label_comp_id(xs[i]))!),
  24. CifField.str('details', (i, xs) => xs[i].unit.model.properties.modifiedResidues.details.get(P.residue.label_comp_id(xs[i]))!)
  25. ];
  26. function getModifiedResidues({ structures }: CifExportContext): StructureElement.Location[] {
  27. // TODO: can different models (in the same mmCIF file) have different modified residues?
  28. const structure = structures[0], model = structure.model;
  29. const map = model.properties.modifiedResidues.parentId;
  30. if (!map.size) return [];
  31. const ret = [];
  32. const prop = P.residue.label_comp_id;
  33. const loc = StructureElement.Location.create(structure);
  34. for (const unit of structure.units) {
  35. if (!Unit.isAtomic(unit) || !unit.conformation.operator.isIdentity) continue;
  36. const residues = Segmentation.transientSegments(unit.model.atomicHierarchy.residueAtomSegments, unit.elements);
  37. loc.unit = unit;
  38. while (residues.hasNext) {
  39. const seg = residues.move();
  40. loc.element = unit.elements[seg.start];
  41. const name = prop(loc);
  42. if (map.has(name)) {
  43. ret[ret.length] = StructureElement.Location.clone(loc);
  44. }
  45. }
  46. }
  47. return ret;
  48. }
  49. export const _pdbx_struct_mod_residue: CifCategory<CifExportContext> = {
  50. name: 'pdbx_struct_mod_residue',
  51. instance(ctx) {
  52. const residues = getModifiedResidues(ctx);
  53. return {
  54. fields: pdbx_struct_mod_residue_fields,
  55. source: [{ data: residues, rowCount: residues.length }]
  56. };
  57. }
  58. }