Source code for ascii_importer

#! /usr/bin/env python3
"""
Functions relating to the import of v_sim ascii files
"""

import re 
from collections import namedtuple
from mathutils import Vector

[docs]class Mode(namedtuple('Mode', 'freq qpt vectors')): """ Collection of vibrational mode data imported from a v_sim ascii file :param freq: Vibrational frequency :type freq: float :param qpt: **q**-point of mode :type qpt: 3-list of reciprocal space coordinates :param vectors: Eigenvectors :type vectors: Nested list; 3-lists of complex numbers corresponding to atoms """ pass
[docs]def import_vsim(filename): """ Import data from v_sim ascii file, including lattice vectors, atomic positions and phonon modes :param filename: Path to .ascii file :returns: cell_vsim, positions, symbols, vibs :return cell_vsim: Lattice vectors in v_sim format :rtype: 2x3 nested lists of floats :return positions: Atomic positions :rtype: list of 3-Vectors :return symbols: Symbols corresponding to atomic positions :rtype: list of strings :return vibs: Vibrations :rtype: list of "Mode" namedtuples """ with open(filename,'r') as f: f.readline() # Skip header # Read in lattice vectors (2-row format) and cast as floats cell_vsim = [[float(x) for x in f.readline().split()], [float(x) for x in f.readline().split()]] # Read in all remaining non-commented lines as positions/symbols, commented lines to new array positions, symbols, commentlines = [], [], [] for line in f: if line[0] != '#' and line[0] != '\!': line = line.split() position = [float(x) for x in line[0:3]] symbol = line[3] positions.append(Vector(position)) symbols.append(symbol) else: commentlines.append(line.strip()) # remove comment characters and implement linebreaks (linebreak character \) for index, line in enumerate(commentlines): while line[-1] == '\\': line = line[:-1] + commentlines.pop(index+1)[1:] commentlines[index] = line[1:] # Import data from commentlines vibs = [] for line in commentlines: vector_txt = re.search('qpt=\[(.+)\]',line) if vector_txt: mode_data = vector_txt.group(1).split(';') qpt = [float(x) for x in mode_data[0:3]] freq = float(mode_data[3]) vector_list = [float(x) for x in mode_data[4:]] vector_set = [vector_list[6*i:6*i+6] for i in range(len(positions))] complex_vectors = [[complex(x[0],x[3]), complex(x[1],x[4]), complex(x[2],x[5])] for x in vector_set] vibs.append(Mode(freq, qpt, complex_vectors)) if _check_if_reduced(filename): positions = _reduced_to_cartesian(positions, cell_vsim) return (cell_vsim, positions, symbols, vibs)
def _check_if_reduced(filename): """ Scan a .ascii file for the "reduced" keyword :params filename: v_sim .ascii file to check :type filename: float :returns: Boolean """ with open(filename,'r') as f: f.readline() # Skip header for line in f: if 'reduced' in line: return True else: return False def _reduced_to_cartesian(positions, cell_vsim): """ Convert a set of atomic positions in lattice vector units to Cartesian coordinates :param positions: Atomic positions in reduced coordinates :type positions: List of 3-tuples/lists/Vectors :param cell_vsim: Lattice vectors in v_sim (6-value) format :format cell_vsim: 2x3 nested lists :returns: Atomic positions in Cartesian coordinates :rtype: List of 3-Vectors """ lattice_vectors = cell_vsim_to_vectors(cell_vsim) cartesian_positions = [] for position in positions: cartesian_position = Vector((0.,0.,0.)) for position_i, vector in zip(position, lattice_vectors): cartesian_position += position_i * vector cartesian_positions.append(cartesian_position) return cartesian_positions
[docs]def cell_vsim_to_vectors(cell_vsim): """ Convert between v_sim 6-value lattice vector format (`ref <http://inac.cea.fr/L_Sim/V_Sim/sample.html>`_) and set of three Cartesian vectors :param cell_vsim: Lattice vectors in v_sim format :type cell_vsim: 2x3 nested lists :returns: Cartesian lattice vectors :rtype: 3-list of 3-Vectors """ dxx, dyx, dyy = cell_vsim[0] dzx, dzy, dzz = cell_vsim[1] return [Vector([dxx, 0., 0.]), Vector([dyx, dyy, 0.]), Vector([dzx, dzy, dzz])]
if __name__ == "__main__": cell, positions, symbols, vibs = import_vsim('gamma_vibs.ascii') print(vibs) print(cell_vsim_to_vectors(cell)) print(symbols)