UNPKG

crystvis-js

Version:

A Three.js based crystallographic visualisation tool

114 lines (91 loc) 2.94 kB
'use strict'; /** * @fileoverview Function for loading CASTEP's Cell files * @module */ import _ from 'lodash'; import { Atoms } from 'crystcif-parse'; function cellBlocks(lines, units={}) { const block_re = /%BLOCK\s+([A-Z_]+)/; const endblock_re = /%ENDBLOCK\s+([A-Z_]+)/; let blocks = {}; _.forEach(lines, (l, i) => { let lu = l.toUpperCase(); let ms = block_re.exec(lu); let me = endblock_re.exec(lu); if (ms) { let name = ms[1].toUpperCase(); if (name in blocks) { throw Error('Duplicated ' + name + ' block found'); } blocks[name] = {start: i}; } else if (me) { let name = me[1].toUpperCase(); if (!(name in blocks)) { throw Error('Block ' + name + ' ends without starting'); } blocks[name]['end'] = i; // Assign the contents let i0 = blocks[name].start; // Identify any units let ul = lines[i0+1].trim().toLowerCase(); if (units[name] && (ul === units[name] || units[name].includes(ul))) { i0 += 1; blocks[name]['units'] = ul; } blocks[name]['lines'] = lines.slice(i0+1, i); } }); return blocks; } function load(contents, filename='cell') { // Split the file into lines let lines = _.split(contents, '\n'); // Admissible units const units = { 'LATTICE_CART': ['ang'], 'POSITIONS_ABS': ['ang'] }; // Find blocks let blocks = cellBlocks(lines, units); let pabs = ('POSITIONS_ABS' in blocks); let pfrac = ('POSITIONS_FRAC' in blocks); let ccart = ('LATTICE_CART' in blocks); let cabc = ('LATTICE_ABC' in blocks); switch(pabs+pfrac) { case 0: throw Error('No positions block found'); case 2: throw Error('Duplicated positions blocks found'); default: break; } switch(ccart+cabc) { case 0: throw Error('No lattice block found'); case 2: throw Error('Duplicated lattice blocks found'); default: break; } // Parse the cell let cell = ccart? blocks['LATTICE_CART'].lines : blocks['LATTICE_ABC'].lines; cell = cell.map((l) => (_.trim(l).split(/\s+/).map(parseFloat))); let elems = []; let positions = []; let pblock = pabs? blocks['POSITIONS_ABS'].lines : blocks['POSITIONS_FRAC'].lines; pblock.forEach((l) => { l = _.trim(l).split(/\s+/); if (l.length < 4) throw Error('Incomplete line in positions block'); elems.push(l[0]); positions.push(l.slice(1,4).map(parseFloat)); }); var a = new Atoms(elems, positions, cell, {}, pfrac); var structs = {}; structs[filename] = a; return structs; } export { load };