Skip to content

Commit

Permalink
Update to qe-tools 2.0.0rc1.
Browse files Browse the repository at this point in the history
The constants defined previously in 'qe_tools.constants' are
now a SimpleNamespace, importable as 'qe_tools.CONSTANTS'.
Furthermore, the 'PwInputFile' no longer accepts file handles or
file names as input, just a single string containing the file
contents. This is propagated through to the aiida-quantumespresso
InputFile classes.
  • Loading branch information
Dominik Gresch committed Oct 8, 2020
1 parent 7ec9eaa commit 604c2b9
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 87 deletions.
2 changes: 1 addition & 1 deletion aiida_quantumespresso/calculations/pwimmigrant.py
Expand Up @@ -199,7 +199,7 @@ class or using the ``set_`` methods (e.g. ``set_remote_workdir``).
# Parse the input file.
local_path = os.path.join(folder.abspath, self._INPUT_FILE_NAME)
with open(local_path) as fin:
pwinputfile = pwinputparser.PwInputFile(fin)
pwinputfile = pwinputparser.PwInputFile(fin.read())

# Determine PREFIX, if it hasn't already been set by the user.
if self._PREFIX is None:
Expand Down
3 changes: 2 additions & 1 deletion aiida_quantumespresso/cli/data/structure.py
Expand Up @@ -21,7 +21,8 @@ def cmd_import(filename, dry_run):
"""Import a `StructureData` from a Quantum ESPRESSO input file."""
from aiida_quantumespresso.tools.pwinputparser import PwInputFile

parser = PwInputFile(filename)
with open(filename, 'r') as input_file:
parser = PwInputFile(input_file.read())
structure = parser.get_structuredata()
formula = structure.get_formula()

Expand Down
8 changes: 5 additions & 3 deletions aiida_quantumespresso/data/force_constants.py
Expand Up @@ -2,8 +2,8 @@
"""Sub class of `Data` to handle interatomic force constants produced by the Quantum ESPRESSO q2r.x code."""
import numpy

from qe_tools.constants import bohr_to_ang
from aiida.orm import SinglefileData
from qe_tools import CONSTANTS


class ForceConstantsData(SinglefileData):
Expand Down Expand Up @@ -147,7 +147,9 @@ def parse_q2r_force_constants_file(lines, also_force_constants=False):

# read cell data
cell = tuple(
tuple(float(c) * celldm[0] * bohr_to_ang for c in l.split()) for l in lines[current_line:current_line + 3]
tuple(float(c) * celldm[0] * CONSTANTS.bohr_to_ang
for c in l.split())
for l in lines[current_line:current_line + 3]
)
parsed_data['cell'] = cell
current_line += 3
Expand All @@ -169,7 +171,7 @@ def parse_q2r_force_constants_file(lines, also_force_constants=False):
line[0] = atom_type_list[ityp - 1][0] # string with element name
line[1] = atom_type_list[ityp - 1][1] # element mass in amu_ry
# Convert atomic positions (in cartesian) from alat to Angstrom:
line[2:] = [pos * celldm[0] * bohr_to_ang for pos in line[2:]]
line[2:] = [pos * celldm[0] * CONSTANTS.bohr_to_ang for pos in line[2:]]
atom_list.append(tuple(line))
current_line += 1

Expand Down
35 changes: 19 additions & 16 deletions aiida_quantumespresso/parsers/cp.py
Expand Up @@ -5,7 +5,7 @@
from aiida.common import NotExistent
from aiida.orm import Dict, TrajectoryData

from qe_tools.constants import bohr_to_ang, hartree_to_ev, timeau_to_sec
from qe_tools import CONSTANTS
from aiida_quantumespresso.parsers.parse_raw.cp import parse_cp_raw_output, parse_cp_traj_stanzas
from .base import Parser

Expand Down Expand Up @@ -66,9 +66,12 @@ def parse(self, **kwargs):
return self.exit(self.exit_codes.ERROR_READING_POS_FILE)

trajectories = [
('positions', 'pos', bohr_to_ang, out_dict['number_of_atoms']),
('cells', 'cel', bohr_to_ang, 3),
('velocities', 'vel', bohr_to_ang / timeau_to_sec * 10**12, out_dict['number_of_atoms']),
('positions', 'pos', CONSTANTS.bohr_to_ang, out_dict['number_of_atoms']),
('cells', 'cel', CONSTANTS.bohr_to_ang, 3),
(
'velocities', 'vel', CONSTANTS.bohr_to_ang / CONSTANTS.timeau_to_sec * 10**12,
out_dict['number_of_atoms']
),
]

for name, extension, scale, elements in trajectories:
Expand Down Expand Up @@ -109,26 +112,26 @@ def parse(self, **kwargs):
#print "New version"
raw_trajectory['steps'] = numpy.array(matrix[:, 0], dtype=int)
raw_trajectory['evp_times'] = matrix[:, 1] # TPS, ps
raw_trajectory['electronic_kinetic_energy'] = matrix[:, 2] * hartree_to_ev # EKINC, eV
raw_trajectory['electronic_kinetic_energy'] = matrix[:, 2] * CONSTANTS.hartree_to_ev # EKINC, eV
raw_trajectory['cell_temperature'] = matrix[:, 3] # TEMPH, K
raw_trajectory['ionic_temperature'] = matrix[:, 4] # TEMPP, K
raw_trajectory['scf_total_energy'] = matrix[:, 5] * hartree_to_ev # ETOT, eV
raw_trajectory['enthalpy'] = matrix[:, 6] * hartree_to_ev # ENTHAL, eV
raw_trajectory['enthalpy_plus_kinetic'] = matrix[:, 7] * hartree_to_ev # ECONS, eV
raw_trajectory['energy_constant_motion'] = matrix[:, 8] * hartree_to_ev # ECONT, eV
raw_trajectory['volume'] = matrix[:, 9] * (bohr_to_ang**3) # volume, angstrom^3
raw_trajectory['scf_total_energy'] = matrix[:, 5] * CONSTANTS.hartree_to_ev # ETOT, eV
raw_trajectory['enthalpy'] = matrix[:, 6] * CONSTANTS.hartree_to_ev # ENTHAL, eV
raw_trajectory['enthalpy_plus_kinetic'] = matrix[:, 7] * CONSTANTS.hartree_to_ev # ECONS, eV
raw_trajectory['energy_constant_motion'] = matrix[:, 8] * CONSTANTS.hartree_to_ev # ECONT, eV
raw_trajectory['volume'] = matrix[:, 9] * (CONSTANTS.bohr_to_ang**3) # volume, angstrom^3
raw_trajectory['pressure'] = matrix[:, 10] # out_press, GPa
else:
#print "Old version"
raw_trajectory['steps'] = numpy.array(matrix[:, 0], dtype=int)
raw_trajectory['electronic_kinetic_energy'] = matrix[:, 1] * hartree_to_ev # EKINC, eV
raw_trajectory['electronic_kinetic_energy'] = matrix[:, 1] * CONSTANTS.hartree_to_ev # EKINC, eV
raw_trajectory['cell_temperature'] = matrix[:, 2] # TEMPH, K
raw_trajectory['ionic_temperature'] = matrix[:, 3] # TEMPP, K
raw_trajectory['scf_total_energy'] = matrix[:, 4] * hartree_to_ev # ETOT, eV
raw_trajectory['enthalpy'] = matrix[:, 5] * hartree_to_ev # ENTHAL, eV
raw_trajectory['enthalpy_plus_kinetic'] = matrix[:, 6] * hartree_to_ev # ECONS, eV
raw_trajectory['energy_constant_motion'] = matrix[:, 7] * hartree_to_ev # ECONT, eV
raw_trajectory['volume'] = matrix[:, 8] * (bohr_to_ang**3) # volume, angstrom^3
raw_trajectory['scf_total_energy'] = matrix[:, 4] * CONSTANTS.hartree_to_ev # ETOT, eV
raw_trajectory['enthalpy'] = matrix[:, 5] * CONSTANTS.hartree_to_ev # ENTHAL, eV
raw_trajectory['enthalpy_plus_kinetic'] = matrix[:, 6] * CONSTANTS.hartree_to_ev # ECONS, eV
raw_trajectory['energy_constant_motion'] = matrix[:, 7] * CONSTANTS.hartree_to_ev # ECONT, eV
raw_trajectory['volume'] = matrix[:, 8] * (CONSTANTS.bohr_to_ang**3) # volume, angstrom^3
raw_trajectory['pressure'] = matrix[:, 9] # out_press, GPa
raw_trajectory['evp_times'] = matrix[:, 10] # TPS, ps

Expand Down
4 changes: 2 additions & 2 deletions aiida_quantumespresso/parsers/matdyn.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from aiida import orm
from aiida.common import exceptions
from qe_tools.constants import invcm_to_THz
from qe_tools import CONSTANTS

from aiida_quantumespresso.calculations.matdyn import MatdynCalculation
from .base import Parser
Expand Down Expand Up @@ -114,7 +114,7 @@ def parse_raw_matdyn_phonon_file(phonon_frequencies):
for i in range(num_kpoints):
for j in range(num_bands):
try:
freq_matrix[i, j] = corrected_data[counter] * invcm_to_THz # from cm-1 to THz
freq_matrix[i, j] = corrected_data[counter] * CONSTANTS.invcm_to_THz # from cm-1 to THz
except ValueError:
parsed_data['warnings'].append('Error while parsing the frequencies')
except IndexError:
Expand Down
10 changes: 5 additions & 5 deletions aiida_quantumespresso/parsers/parse_raw/neb.py
Expand Up @@ -5,7 +5,7 @@
specific functionalities. The parsing will try to convert whatever it can in some dictionary, which by operative
decision doesn't have much structure encoded, [the values are simple ]
"""
from qe_tools.constants import bohr_to_ang
from qe_tools import CONSTANTS

from aiida_quantumespresso.parsers import QEOutputParsingError, get_parser_info
from aiida_quantumespresso.parsers.parse_raw import convert_qe_time_to_sec
Expand Down Expand Up @@ -148,10 +148,10 @@ def parse_neb_text_output(data, input_dict={}):
for count, line in enumerate(lines):
if 'initial path length' in line:
initial_path_length = float(line.split('=')[1].split('bohr')[0])
parsed_data['initial_path_length'] = initial_path_length * bohr_to_ang
parsed_data['initial_path_length'] = initial_path_length * CONSTANTS.bohr_to_ang
elif 'initial inter-image distance' in line:
initial_image_dist = float(line.split('=')[1].split('bohr')[0])
parsed_data['initial_image_dist'] = initial_image_dist * bohr_to_ang
parsed_data['initial_image_dist'] = initial_image_dist * CONSTANTS.bohr_to_ang
elif 'string_method' in line:
parsed_data['string_method'] = line.split('=')[1].strip()
elif 'restart_mode' in line:
Expand Down Expand Up @@ -235,9 +235,9 @@ def parse_neb_text_output(data, input_dict={}):
iteration_data['climbing_image_auto'].append([int(_) for _ in line.split('=')[1].split(',')])
elif 'path length' in line:
path_length = float(line.split('=')[1].split('bohr')[0])
iteration_data['path_length'].append(path_length * bohr_to_ang)
iteration_data['path_length'].append(path_length * CONSTANTS.bohr_to_ang)
elif 'inter-image distance' in line:
image_dist = float(line.split('=')[1].split('bohr')[0])
iteration_data['image_dist'].append(image_dist * bohr_to_ang)
iteration_data['image_dist'].append(image_dist * CONSTANTS.bohr_to_ang)

return parsed_data, dict(iteration_data), list(critical_warnings.values())
6 changes: 3 additions & 3 deletions aiida_quantumespresso/parsers/parse_raw/ph.py
Expand Up @@ -6,7 +6,7 @@
"""
import numpy

from qe_tools.constants import *
from qe_tools import CONSTANTS

from aiida_quantumespresso.parsers import QEOutputParsingError, get_parser_info
from aiida_quantumespresso.parsers.parse_raw.base import convert_qe_time_to_sec
Expand Down Expand Up @@ -282,7 +282,7 @@ def parse_ph_dynmat(data, logs, lattice_parameter=None, also_eigenvectors=False,
header_dict['ibrav'] = int(pieces[2])
header_dict['celldm'] = [float(i) for i in pieces[3:]]
# In angstrom
alat = header_dict['celldm'][0] * bohr_to_ang
alat = header_dict['celldm'][0] * CONSTANTS.bohr_to_ang
if abs(alat) < 1.e-5:
raise QEOutputParsingError(
'Lattice constant=0! Probably you are using an '
Expand Down Expand Up @@ -318,7 +318,7 @@ def parse_ph_dynmat(data, logs, lattice_parameter=None, also_eigenvectors=False,
try:
if int(pieces[0]) != idx:
raise QEOutputParsingError('Error with the indices of the species')
species.append([pieces[1].strip(), float(pieces[2]) / amu_Ry])
species.append([pieces[1].strip(), float(pieces[2]) / CONSTANTS.amu_Ry])
except ValueError:
raise QEOutputParsingError('Error parsing the species')

Expand Down
36 changes: 18 additions & 18 deletions aiida_quantumespresso/parsers/parse_raw/pw.py
Expand Up @@ -7,7 +7,7 @@
"""
import re
import numpy
from qe_tools.constants import ry_to_ev, bohr_to_ang, ry_si, bohr_si
from qe_tools import CONSTANTS

from aiida_quantumespresso.parsers import QEOutputParsingError
from aiida_quantumespresso.parsers.parse_raw import convert_qe_time_to_sec
Expand Down Expand Up @@ -334,8 +334,8 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)
elif 'Smooth grid' in line:
smooth_FFT_grid = [int(g) for g in line.split('(')[1].split(')')[0].split(',')]
break
alat *= bohr_to_ang
volume *= bohr_to_ang**3
alat *= CONSTANTS.bohr_to_ang
volume *= CONSTANTS.bohr_to_ang**3
parsed_data['lattice_parameter_initial'] = alat
parsed_data['number_of_bands'] = nbnd
try:
Expand Down Expand Up @@ -514,19 +514,19 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)
)

if 'alat' in lattice[0].lower():
a1 = [alat * bohr_to_ang * float(s) for s in a1]
a2 = [alat * bohr_to_ang * float(s) for s in a2]
a3 = [alat * bohr_to_ang * float(s) for s in a3]
a1 = [alat * CONSTANTS.bohr_to_ang * float(s) for s in a1]
a2 = [alat * CONSTANTS.bohr_to_ang * float(s) for s in a2]
a3 = [alat * CONSTANTS.bohr_to_ang * float(s) for s in a3]
lattice_parameter_b = float(lattice[1])
if abs(lattice_parameter_b - alat) > lattice_tolerance:
raise QEOutputParsingError(
'Lattice parameters mismatch! ' + '{} vs {}'.format(lattice_parameter_b, alat)
)
elif 'bohr' in lattice[0].lower():
lattice_parameter_b *= bohr_to_ang
a1 = [bohr_to_ang * float(s) for s in a1]
a2 = [bohr_to_ang * float(s) for s in a2]
a3 = [bohr_to_ang * float(s) for s in a3]
lattice_parameter_b *= CONSTANTS.bohr_to_ang
a1 = [CONSTANTS.bohr_to_ang * float(s) for s in a1]
a2 = [CONSTANTS.bohr_to_ang * float(s) for s in a2]
a3 = [CONSTANTS.bohr_to_ang * float(s) for s in a3]
trajectory_data.setdefault('lattice_vectors_relax', []).append([a1, a2, a3])

except Exception:
Expand All @@ -550,7 +550,7 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)
if metric == 'alat':
tau = [alat * float(s) for s in tau]
elif metric == 'bohr':
tau = [bohr_to_ang * float(s) for s in tau]
tau = [CONSTANTS.bohr_to_ang * float(s) for s in tau]
positions.append(tau)
trajectory_data.setdefault(this_key, []).append(positions)
except Exception:
Expand Down Expand Up @@ -590,7 +590,7 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)
# If for some step this line is not printed, the later check with the scf_accuracy array length should catch it
elif 'estimated scf accuracy' in line:
try:
value = float(line.split()[-2]) * ry_to_ev
value = float(line.split()[-2]) * CONSTANTS.ry_to_ev
trajectory_data.setdefault('scf_accuracy', []).append(value)
except Exception:
logs.warning.append('Error while parsing scf accuracy.')
Expand Down Expand Up @@ -654,7 +654,7 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)
elif '!' in line:
try:

En = float(line.split('=')[1].split('Ry')[0]) * ry_to_ev
En = float(line.split('=')[1].split('Ry')[0]) * CONSTANTS.ry_to_ev

# Up till v6.5, the line after total energy would be the Harris-Foulkes estimate, followed by the
# estimated SCF accuracy. However, pw.x v6.6 removed the HF estimate line.
Expand All @@ -663,7 +663,7 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)
subline = data_step[count + i]
if marker in subline:
try:
E_acc = float(subline.split('<')[1].split('Ry')[0]) * ry_to_ev
E_acc = float(subline.split('<')[1].split('Ry')[0]) * CONSTANTS.ry_to_ev
except Exception:
pass
else:
Expand Down Expand Up @@ -754,7 +754,7 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)
if 'atom ' in line2:
line2 = line2.split('=')[1].split()
# CONVERT FORCES IN eV/Ang
vec = [float(s) * ry_to_ev / bohr_to_ang for s in line2]
vec = [float(s) * CONSTANTS.ry_to_ev / CONSTANTS.bohr_to_ang for s in line2]
forces.append(vec)
if len(forces) == nat:
break
Expand All @@ -767,7 +767,7 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)

elif 'Total force =' in line:
try: # note that I can't check the units: not written in output!
value = float(line.split('=')[1].split('Total')[0]) * ry_to_ev / bohr_to_ang
value = float(line.split('=')[1].split('Total')[0]) * CONSTANTS.ry_to_ev / CONSTANTS.bohr_to_ang
trajectory_data.setdefault('total_force', []).append(value)
parsed_data['total_force' + units_suffix] = default_force_units
except Exception:
Expand All @@ -791,7 +791,7 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)
raise QEOutputParsingError('Error while parsing stress: unexpected units.')
for k in range(3):
line2 = data_step[count2 + k + 1].split()
vec = [float(s) * 10**(-9) * ry_si / (bohr_si)**3 for s in line2[0:3]]
vec = [float(s) * 10**(-9) * CONSTANTS.ry_si / (CONSTANTS.bohr_si)**3 for s in line2[0:3]]
stress.append(vec)
trajectory_data.setdefault('stress', []).append(stress)
parsed_data['stress' + units_suffix] = default_stress_units
Expand Down Expand Up @@ -910,6 +910,6 @@ def parse_stdout(stdout, input_parameters, parser_options=None, parsed_xml=None)

def grep_energy_from_line(line):
try:
return float(line.split('=')[1].split('Ry')[0]) * ry_to_ev
return float(line.split('=')[1].split('Ry')[0]) * CONSTANTS.ry_to_ev
except Exception:
raise QEOutputParsingError('Error while parsing energy')

0 comments on commit 604c2b9

Please sign in to comment.