NGL@1.0.0-beta.7 Home Manual Reference Source Gallery

src/writer/pdb-writer.js

  1. /**
  2. * @file Pdb Writer
  3. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  4. * @private
  5. */
  6.  
  7. import { defaults, ensureArray } from '../utils.js'
  8. import Writer from './writer.js'
  9.  
  10. import { sprintf } from '../../lib/sprintf.es6.js'
  11.  
  12. // http://www.wwpdb.org/documentation/file-format
  13.  
  14. // Sample PDB line, the coords X,Y,Z are fields 5,6,7 on each line.
  15. // ATOM 1 N ARG 1 29.292 13.212 -12.751 1.00 33.78 1BPT 108
  16.  
  17. const AtomFormat =
  18. 'ATOM %5d %-4s %3s %1s%4d %8.3f%8.3f%8.3f%6.2f%6.2f %4s%2s'
  19.  
  20. const HetatmFormat =
  21. 'HETATM%5d %-4s %3s %1s%4d %8.3f%8.3f%8.3f%6.2f%6.2f %4s%2s'
  22.  
  23. /**
  24. * Create a PDB file from a Structure object
  25. */
  26. class PdbWriter extends Writer {
  27. /**
  28. * @param {Structure} structure - the structure object
  29. * @param {Object} params - parameters]
  30. */
  31. constructor (structure, params) {
  32. const p = Object.assign({}, params)
  33.  
  34. super()
  35.  
  36. this.renumberSerial = defaults(p.renumberSerial, true)
  37. this.remarks = ensureArray(defaults(p.remarks, []))
  38.  
  39. this.structure = structure
  40. this._records = []
  41. }
  42.  
  43. get mimeType () { return 'text/plain' }
  44. get defaultName () { return 'structure' }
  45. get defaultExt () { return 'pdb' }
  46.  
  47. _writeRecords () {
  48. this._records.length = 0
  49.  
  50. this._writeTitle()
  51. this._writeRemarks()
  52. this._writeAtoms()
  53. }
  54.  
  55. _writeTitle () {
  56. // FIXME multiline if title line longer than 80 chars
  57. this._records.push(sprintf('TITLE %-74s', this.structure.name))
  58. }
  59.  
  60. _writeRemarks () {
  61. this.remarks.forEach(str => {
  62. this._records.push(sprintf('REMARK %-73s', str))
  63. })
  64.  
  65. if (this.structure.trajectory) {
  66. this._records.push(sprintf(
  67. 'REMARK %-73s',
  68. "Trajectory '" + this.structure.trajectory.name + "'"
  69. ))
  70. this._records.push(sprintf(
  71. 'REMARK %-73s',
  72. 'Frame ' + this.structure.trajectory.frame + ''
  73. ))
  74. }
  75. }
  76.  
  77. _writeAtoms () {
  78. let ia = 1
  79. let im = 1
  80.  
  81. this.structure.eachModel(m => {
  82. this._records.push(sprintf('MODEL %-74d', im++))
  83.  
  84. m.eachAtom(a => {
  85. const formatString = a.hetero ? HetatmFormat : AtomFormat
  86. const serial = this.renumberSerial ? ia : a.serial
  87.  
  88. // Alignment of one-letter atom name such as C starts at column 14,
  89. // while two-letter atom name such as FE starts at column 13.
  90. let atomname = a.atomname
  91. if (atomname.length === 1) atomname = ' ' + atomname
  92.  
  93. this._records.push(sprintf(
  94. formatString,
  95.  
  96. serial,
  97. atomname,
  98. a.resname,
  99. defaults(a.chainname, ' '),
  100. a.resno,
  101. a.x, a.y, a.z,
  102. defaults(a.occurence, 1.0),
  103. defaults(a.bfactor, 0.0),
  104. defaults(a.segid, ''),
  105. defaults(a.element, '')
  106. ))
  107. ia += 1
  108. })
  109.  
  110. this._records.push(sprintf('%-80s', 'ENDMDL'))
  111. im += 1
  112. })
  113.  
  114. this._records.push(sprintf('%-80s', 'END'))
  115. }
  116.  
  117. getString () {
  118. console.warn('PdbWriter.getString() is deprecated, use .getData instead')
  119. return this.getData()
  120. }
  121.  
  122. /**
  123. * Get string containing the PDB file data
  124. * @return {String} PDB file
  125. */
  126. getData () {
  127. this._writeRecords()
  128. return this._records.join('\n')
  129. }
  130. }
  131.  
  132. export default PdbWriter