Commit 7ae2caa6 authored by Lauri Himanen's avatar Lauri Himanen

Merged the new nomad_utils folder to the new package structure under the utils-subpackage.

parents a86eb472 797171f7
This diff is collapsed.
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
import os import os
import logging import logging
from nomadcore.local_meta_info import InfoKindEl, loadJsonFile from nomadcore.metainfo.local_meta_info import InfoKindEl, loadJsonFile
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
baseDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) baseDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
...@@ -569,12 +569,17 @@ class CacheService(object): ...@@ -569,12 +569,17 @@ class CacheService(object):
"""Get the value identified by name. If the cachemode does not support """Get the value identified by name. If the cachemode does not support
getting the value, an exception is raised. getting the value, an exception is raised.
returns: Args:
name(string): The name of the cached object to return.
raises: Returns:
The requested object from the cache
""" """
cache_object = self.get_cache_object(name) cache_object = self.get_cache_object(name)
return cache_object.value if cache_object is None:
return None
return cache_object.value
def get_cache_object(self, name): def get_cache_object(self, name):
...@@ -586,8 +591,7 @@ class CacheService(object): ...@@ -586,8 +591,7 @@ class CacheService(object):
def __setitem__(self, name, value): def __setitem__(self, name, value):
"""Used to set the value for an item. The CacheObject corresponding to """Used to set the value for an item. The CacheObject corresponding to
the name has to be first created by using the function the name has to be first dclared by using the function add().
""" """
cache_object = self._cache[name] cache_object = self._cache[name]
cache_object.value = value cache_object.value = value
import ase.calculators.calculator
if 'potential_energy' not in calculator.all_properties:
calculator.all_properties += ['potential_energy', 'kinetic_energy']
This diff is collapsed.
This diff is collapsed.
from __future__ import print_function
import json
class CLICommand:
short_description = 'Get calculations from NOMAD and write to JSON files.'
def add_arguments(p):
p.add_argument('uri', nargs='+', metavar='nmd://<hash>',
+ help='URIs to get')
def run(args):
from ase.nomad import download
for uri in args.uri:
calculation = download(uri)
identifier = calculation.hash.replace('/', '.')
fname = 'nmd.{}.nomad.json'.format(identifier)
with open(fname, 'w') as fd:
json.dump(calculation, fd)
import json
from nomadcore.utils.nomad_fetch import dict2images
from ase.utils import basestring
def read_nomad_json(fd, index=':', only_atoms=False):
# wth, we should not be passing index like this!
from import string2index
if isinstance(index, basestring):
index = string2index(index)
d = json.load(fd)
images = dict2images(d, only_atoms=only_atoms)
return list(images)[index]
import ase
from ase.utils import basestring
import nomadcore.utils
def read_nomad_ziptxt(fd, index=':', only_atoms=False, skip_errors=False):
images = []
from import string2index
if isinstance(index, basestring):
index = string2index(index)
for bline in fd:
line = bline.decode("utf-8")
if line.startswith('#'):
nmduri = line.split('/section_run')
print('Requesting NOMAD archive at ' + nmduri[0])
entry =[0], only_atoms=only_atoms, skip_errors=skip_errors)
nmd_entry_images = entry.toatoms()
nmd_images = list(nmd_entry_images)
if len(nmd_images) > 0:
print('Adding ' + str(len(nmd_images)) + ' structure(s) with ' + ','.join(
list(set([str(ni.get_chemical_formula('reduce')) for ni in nmd_images]))))
print('No structures retrieved from this NOMAD archive!')
return list(images)[index]
import numpy as np
from ase.calculators.calculator import Calculator, all_properties
if 'potential_energy' not in all_properties:
all_properties += ['potential_energy', 'kinetic_energy']
from ase.calculators.calculator import PropertyNotImplementedError
class SinglePointCalculator(Calculator):
"""Special calculator for a single configuration.
Used to remember the energy, force and stress for a given
configuration. If the positions, atomic numbers, unit cell, or
boundary conditions are changed, then asking for
energy/forces/stress will raise an exception."""
name = 'unknown'
def __init__(self, atoms=None, **results):
"""Save energy, forces, stress, ... for the current configuration."""
self.results = {}
for property, value in results.items():
if property.startswith('nomad_'):
assert property in all_properties
if value is None:
if(property in ['energy', 'magmom', 'free_energy'] or
self.results[property] = value
self.results[property] = np.array(value, float)
if atoms:
self.atoms = atoms.copy()
def __str__(self):
tokens = []
for key, val in sorted(self.results.items()):
if np.isscalar(val):
txt = '{}={}'.format(key, val)
txt = '{}=...'.format(key)
return '{}({})'.format(self.__class__.__name__, ', '.join(tokens))
def get_property(self, name, atoms=None, allow_calculation=True):
if name not in self.results or self.check_state(atoms):
if allow_calculation:
raise PropertyNotImplementedError(
'The property "{0}" is not available.'.format(name))
return None
result = self.results[name]
if isinstance(result, np.ndarray):
result = result.copy()
return result
class SinglePointKPoint:
def __init__(self, weight, s, k, eps_n=[], f_n=[]):
self.weight = weight
self.s = s # spin index
self.k = k # k-point index
self.eps_n = eps_n
self.f_n = f_n
class SinglePointDFTCalculator(SinglePointCalculator):
def __init__(self, atoms,
efermi=None, bzkpts=None, ibzkpts=None, bz2ibz=None,
self.bz_kpts = bzkpts
self.ibz_kpts = ibzkpts
self.bz2ibz = bz2ibz
self.eFermi = efermi
SinglePointCalculator.__init__(self, atoms, **results)
self.kpts = None
def get_fermi_level(self):
"""Return the Fermi-level(s)."""
return self.eFermi
def get_bz_to_ibz_map(self):
return self.bz2ibz
def get_bz_k_points(self):
"""Return the k-points."""
return self.bz_kpts
def get_number_of_spins(self):
"""Return the number of spins in the calculation.
Spin-paired calculations: 1, spin-polarized calculation: 2."""
if self.kpts is not None:
nspin = set()
for kpt in self.kpts:
return len(nspin)
return None
def get_spin_polarized(self):
"""Is it a spin-polarized calculation?"""
nos = self.get_number_of_spins()
if nos is not None:
return nos == 2
return None
def get_ibz_k_points(self):
"""Return k-points in the irreducible part of the Brillouin zone."""
return self.ibz_kpts
def get_kpt(self, kpt=0, spin=0):
if self.kpts is not None:
counter = 0
for kpoint in self.kpts:
if kpoint.s == spin:
if kpt == counter:
return kpoint
counter += 1
return None
def get_occupation_numbers(self, kpt=0, spin=0):
"""Return occupation number array."""
kpoint = self.get_kpt(kpt, spin)
if kpoint is not None:
return kpoint.f_n
return None
def get_eigenvalues(self, kpt=0, spin=0):
"""Return eigenvalue array."""
kpoint = self.get_kpt(kpt, spin)
if kpoint is not None:
return kpoint.eps_n
return None
def get_homo_lumo(self):
"""Return HOMO and LUMO energies."""
if self.kpts is None:
raise RuntimeError('No kpts')
eHs = []
eLs = []
for kpt in self.kpts:
eH, eL = self.get_homo_lumo_by_spin(kpt.s)
return np.array(eHs).max(), np.array(eLs).min()
def get_homo_lumo_by_spin(self, spin=0):
"""Return HOMO and LUMO energies for a given spin."""
if self.kpts is None:
raise RuntimeError('No kpts')
for kpt in self.kpts:
if kpt.s == spin:
raise RuntimeError('No k-point with spin {0}'.format(spin))
if self.eFermi is None:
raise RuntimeError('Fermi level is not available')
eH = -1.e32
eL = 1.e32
for kpt in self.kpts:
if kpt.s == spin:
for e in kpt.eps_n:
if e <= self.eFermi:
eH = max(eH, e)
eL = min(eL, e)
return eH, eL
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment