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

src/parser/cube-parser.js

  1. /**
  2. * @file Cube Parser
  3. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  4. * @private
  5. */
  6.  
  7. import { Matrix4, Vector3 } from '../../lib/three.es6.js'
  8.  
  9. import { Debug, Log, ParserRegistry } from '../globals.js'
  10. import VolumeParser from './volume-parser.js'
  11.  
  12. // @author Johanna Tiemann <johanna.tiemann@googlemail.com>
  13. // @author Alexander Rose <alexander.rose@weirdbyte.de>
  14.  
  15. const reWhitespace = /\s+/
  16. const reScientificNotation = /-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?/g
  17. const bohrToAngstromFactor = 0.529177210859
  18.  
  19. class CubeParser extends VolumeParser {
  20. get type () { return 'cube' }
  21.  
  22. _parse () {
  23. // http://paulbourke.net/dataformats/cube/
  24.  
  25. if (Debug) Log.time('CubeParser._parse ' + this.name)
  26.  
  27. const v = this.volume
  28. const headerLines = this.streamer.peekLines(6)
  29. const header = {}
  30.  
  31. const scaleFactor = bohrToAngstromFactor * this.voxelSize
  32.  
  33. function h (k, l) {
  34. var field = headerLines[ k ].trim().split(reWhitespace)[ l ]
  35. return parseFloat(field)
  36. }
  37.  
  38. header.atomCount = Math.abs(h(2, 0)) // Number of atoms
  39. header.originX = h(2, 1) * bohrToAngstromFactor // Position of origin of volumetric data
  40. header.originY = h(2, 2) * bohrToAngstromFactor
  41. header.originZ = h(2, 3) * bohrToAngstromFactor
  42. header.NVX = h(3, 0) // Number of voxels
  43. header.NVY = h(4, 0)
  44. header.NVZ = h(5, 0)
  45.  
  46. header.basisX = new Vector3(h(3, 1), h(3, 2), h(3, 3))
  47. .multiplyScalar(scaleFactor)
  48. header.basisY = new Vector3(h(4, 1), h(4, 2), h(4, 3))
  49. .multiplyScalar(scaleFactor)
  50. header.basisZ = new Vector3(h(5, 1), h(5, 2), h(5, 3))
  51. .multiplyScalar(scaleFactor)
  52.  
  53. const data = new Float32Array(header.NVX * header.NVY * header.NVZ)
  54. let count = 0
  55. let lineNo = 0
  56. const oribitalFlag = h(2, 0) > 0 ? 0 : 1
  57.  
  58. function _parseChunkOfLines (_i, _n, lines) {
  59. for (let i = _i; i < _n; ++i) {
  60. const line = lines[ i ].trim()
  61.  
  62. if (line !== '' && lineNo >= header.atomCount + 6 + oribitalFlag) {
  63. const m = line.match(reScientificNotation)
  64. for (let j = 0, lj = m.length; j < lj; ++j) {
  65. data[ count ] = parseFloat(m[ j ])
  66. ++count
  67. }
  68. }
  69.  
  70. ++lineNo
  71. }
  72. }
  73.  
  74. this.streamer.eachChunkOfLines(function (lines/*, chunkNo, chunkCount */) {
  75. _parseChunkOfLines(0, lines.length, lines)
  76. })
  77.  
  78. v.header = header
  79. v.setData(data, header.NVZ, header.NVY, header.NVX)
  80.  
  81. if (Debug) Log.timeEnd('CubeParser._parse ' + this.name)
  82. }
  83.  
  84. getMatrix () {
  85. const h = this.volume.header
  86. const matrix = new Matrix4()
  87.  
  88. matrix.multiply(
  89. new Matrix4().makeTranslation(
  90. h.originX, h.originY, h.originZ
  91. )
  92. )
  93.  
  94. matrix.multiply(
  95. new Matrix4().makeBasis(
  96. h.basisZ, h.basisY, h.basisX
  97. )
  98. )
  99.  
  100. return matrix
  101. }
  102. }
  103.  
  104. ParserRegistry.add('cub', CubeParser)
  105. ParserRegistry.add('cube', CubeParser)
  106.  
  107. export default CubeParser