Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix finding parent structure for KkrimpCalculation #141

Merged
merged 7 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10"]
aiida: [{version: 'aiida-core==2.1.2', name: '2.1.2'}]
aiida: [{version: 'aiida-core==2.3.0', name: '2.3.0'}]
masci-tools: [{version: 'git+https://github.com/JuDFTteam/masci-tools.git@develop', name: '-masci-develop'}]
allowed-to-fail: [false]

Expand Down Expand Up @@ -125,7 +125,7 @@ jobs:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10"]
aiida: [{version: 'aiida-core==2.1.2', name: '2.1.2'}]
aiida: [{version: 'aiida-core==2.3.0', name: '2.3.0'}]
masci-tools: [{version: 'git+https://github.com/JuDFTteam/masci-tools.git@develop', name: '-masci-develop'}]
allowed-to-fail: [false]

Expand Down
4 changes: 2 additions & 2 deletions aiida_kkr/parsers/kkrimp.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ def __init__(self, calc):
super(KkrimpParser, self).__init__(calc)

# pylint: disable=protected-access

def parse(self, debug=False, ignore_nan=True, **kwargs): # pylint: disable=unexpected-keyword-arg
# pylint: disable=unexpected-keyword-arg
def parse(self, debug=False, ignore_nan=True, **kwargs):
"""
Parse output data folder, store results in database.
Expand Down
6 changes: 5 additions & 1 deletion aiida_kkr/tools/find_parent.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ def get_remote(parent_folder):
try:
parent_folder_tmp = parent_folder_tmp0.get_incoming().get_node_by_label('remote_folder')
except NotExistent:
parent_folder_tmp = parent_folder_tmp0
try:
# check if GFhost_folder is there, this is the case for a KkrimpCalculation
parent_folder_tmp = parent_folder_tmp0.get_incoming().get_node_by_label('GFhost_folder')
except NotExistent:
parent_folder_tmp = parent_folder_tmp0
return parent_folder_tmp


Expand Down
81 changes: 72 additions & 9 deletions aiida_kkr/tools/plot_kkr.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,51 @@
__copyright__ = (u'Copyright (c), 2018, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
__version__ = '0.7.1'
__version__ = '0.7.2'
__contributors__ = ('Philipp Rüßmann')


def get_datetime_from_str(calc, verbose=False):
"""
Return a datetime object from the last time a calculation was checked by the scheduler.
Every calculation should have the 'scheduler_lastchecktime' attribute which has the
following format: '2023-11-08T22:44:13.543215+00:00'.
This is converted to a datetime object that can be sorted.
"""
from datetime import datetime
# get last time stamp of scheduler from calculation attribute
try:
last_time_on_computer = calc.attributes['scheduler_lastchecktime']
except:
raise ValueError('Failed to get "scheduler_lastchecktime" from calculation.')
# parse date and time from string
date = last_time_on_computer.split('T')[0]
time = last_time_on_computer.split('T')[1].split('.')[0]
# change format
datetime_str = date[2:].replace('-', '/') + ' ' + time
# convert to datetime object
datetime_object = datetime.strptime(datetime_str, '%y/%m/%d %H:%M:%S')

if verbose:
print(datetime_object) # printed in default format

#return datetime object of the last time the calculation was checked
return datetime_object


def get_sorting_indices(calcs):
"""
Get the sorting index for a list of calculations.
For each calculation the datetime object of the last time the scheduler checked the
calculation is extracted. This is then sorted and the sorting index array is returned.
"""
datetimes = [get_datetime_from_str(calc) for calc in calcs]
isort = np.array(datetimes).argsort()
return isort


def remove_empty_atoms(show_empty_atoms, structure, silent=False):
# check if empty sphere need to be removed for plotting (ase structgure cannot be constructed for alloys or vacancies)
#print('in remove empty atoms:', structure.has_vacancies, ('X' in [i.kind_name for i in structure.sites]) )
Expand Down Expand Up @@ -341,6 +382,8 @@ class plot_kkr(object):
:type switch_xy: bool
:param iatom: list of atom indices which are supposed to be plotted (default: [], i.e. show all atoms)
:type iatom: list
:param debug: activate debug output
:type debug: bool
additional keyword arguments are passed onto the plotting function which allows, for example,
to change the markers used in a DOS plot to crosses via `marker='x'`
Expand All @@ -359,8 +402,17 @@ def __init__(self, nodes=None, **kwargs):
from aiida import load_profile
load_profile()

# used to keep track of structure plotting
self.sview = None

# debug mode
self.debug = False
if 'debug' in kwargs:
self.debug = kwargs.pop('debug')
print('start plot_kkr')
print('kwargs:', kwargs)

# grouping of node if a list of nodes is the input instead of a single node
groupmode = False
if type(nodes) == list:
if len(nodes) > 1:
Expand Down Expand Up @@ -1006,8 +1058,12 @@ def plot_voro_calc(self, node, **kwargs):
def plot_kkrimp_calc(self, node, return_rms=False, return_stot=False, plot_rms=True, **kwargs):
"""plot things from a kkrimp Calculation node"""

if self.debug:
print('in plot_kkrimp_calc')
print('kwargs:', kwargs)

# plot impurity cluster
if kwargs.get('strucplot', True):
if kwargs.get('strucplot', False):
if _has_ase_notebook():
self.sview = plot_imp_cluster(node, **kwargs)
else:
Expand Down Expand Up @@ -1048,7 +1104,7 @@ def plot_kkrimp_calc(self, node, return_rms=False, return_stot=False, plot_rms=T
else:
ptitle = f'pk= {node.pk}'

self.make_kkrimp_rmsplot([rms], [stot], [0], rms_goal, ptitle, **kwargs)
self.make_kkrimp_rmsplot([rms], [stot], [node], rms_goal, ptitle, **kwargs)

# now return values
return_any, return_list = False, []
Expand All @@ -1074,10 +1130,14 @@ def plot_kkrimp_sub_wc(self, node, **kwargs):
"""plot things from a kkrimp_sub_wc workflow"""
from aiida_kkr.calculations import KkrimpCalculation

if self.debug:
print('in plot_kkrimp_sub_wc')
print('kwargs:', kwargs)

impcalcs = [i.node for i in node.get_outgoing(node_class=KkrimpCalculation).all()]

# plot impurity cluster
if len(impcalcs) > 0 and kwargs.get('strucplot', True):
if len(impcalcs) > 0 and kwargs.get('strucplot', False):
if _has_ase_notebook():
self.sview = plot_imp_cluster(impcalcs[0], **kwargs)
else:
Expand All @@ -1088,10 +1148,9 @@ def plot_kkrimp_sub_wc(self, node, **kwargs):
kwargs.pop(k)

# extract rms from calculations
rms_all, pks_all, stot_all = [], [], []
rms_all, stot_all = [], []
rms_goal = None
for impcalc in impcalcs:
pks_all.append(impcalc.pk)
rms_tmp, rms_goal_tmp, stot_tmp = self.plot_kkrimp_calc(
impcalc, return_rms=True, return_stot=True, plot_rms=False
)
Expand All @@ -1108,9 +1167,9 @@ def plot_kkrimp_sub_wc(self, node, **kwargs):
else:
ptitle = f'pk= {node.pk}'

self.make_kkrimp_rmsplot(rms_all, stot_all, pks_all, rms_goal, ptitle, **kwargs)
self.make_kkrimp_rmsplot(rms_all, stot_all, impcalcs, rms_goal, ptitle, **kwargs)

def make_kkrimp_rmsplot(self, rms_all, stot_all, pks_all, rms_goal, ptitle, **kwargs):
def make_kkrimp_rmsplot(self, rms_all, stot_all, list_of_impcalcs, rms_goal, ptitle, **kwargs):
"""
plot rms and total spin moment of kkrimp calculation or series of kkrimp calculations
"""
Expand Down Expand Up @@ -1141,7 +1200,7 @@ def make_kkrimp_rmsplot(self, rms_all, stot_all, pks_all, rms_goal, ptitle, **kw
# plotting of convergence properties (rms etc.)
if len(rms_all) > 0:
# sort rms values and flatten array
reorder_rms = array(pks_all).argsort()[::-1]
reorder_rms = get_sorting_indices(list_of_impcalcs)
rms, niter_calcs, stot = [], [0], []
rms_all_sorted = [rms_all[i] for i in reorder_rms]
for i in rms_all_sorted:
Expand Down Expand Up @@ -1192,6 +1251,10 @@ def plot_kkrimp_dos_wc(self, node, **kwargs):
from masci_tools.vis.kkr_plot_dos import dosplot
from matplotlib.pyplot import show, figure, title, xticks, xlabel, axvline

if self.debug:
print('in plot_kkrimp_dos_wc')
print('kwargs:', kwargs)

interpol, all_atoms, l_channels, sum_spins, switch_xy = True, False, True, False, False
ptitle = None
if 'ptitle' in list(kwargs.keys()):
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
15 changes: 15 additions & 0 deletions tests/tools/test_find_parent.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ def test_find_parent_structure():
assert voro_parent.uuid == '559b9d9b-3525-402e-9b24-ecd8b801853c'


def test_find_structure_kkrimp():
"""
find parent structure from a KkrimpCalculation
"""
import_with_migration('files/db_dump_kkrimp_out.tar.gz')
kkrimp_calc = load_node('eab8db1b-2cc7-4b85-a524-0df4ff2b7da6')

# now find voronoi parent and structure
struc, voro_parent = find_parent_structure(kkrimp_calc)

# check result
assert struc.uuid == 'e51ee6a1-bd27-4901-9612-7bac256bf117'
assert voro_parent.uuid == '559b9d9b-3525-402e-9b24-ecd8b801853c'


def test_get_calc_from_remote():
"""
find parent calc from remote
Expand Down
Loading