Source code for aiida_fleur.tools.merge_parameter

###############################################################################
# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany.         #
#                All rights reserved.                                         #
# This file is part of the AiiDA-FLEUR package.                               #
#                                                                             #
# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur    #
# For further information on the license, see the LICENSE.txt file            #
# For further information please visit http://www.flapw.de or                 #
# http://aiida-fleur.readthedocs.io/en/develop/                               #
###############################################################################
"""
This module, contains a method to merge Dict nodes used by the FLEUR inpgen.
This might also be of interest for other all-electron codes
"""
# Shall we allow for a python dictionary also instead of forcing paramteraData?
# but then we can not keep the provenace...

from aiida.plugins import DataFactory
from aiida.orm import Bool, Dict
from aiida.engine import calcfunction as cf
#Dict = DataFactory('dict')


[docs]def merge_parameter(Dict1, Dict2, overwrite=True, merge=True): """ Merges two Dict nodes. Additive: uses all namelists of both. If they have a namelist in common. Dict2 will overwrite the namelist of Dict. If this is not wanted. set overwrite = False. Then attributes of both will be added, but attributes from Dict1 won't be overwritten. :param Dict1: AiiDA Dict Node :param Dict2: AiiDA Dict Node :param overwrite: bool, default True :param merge: bool, default True returns: AiiDA Dict Node #TODO be more carefull how to merge ids in atom namelists, i.e species labels """ from aiida.common.exceptions import InputValidationError from aiida_fleur.tools.dict_util import recursive_merge #Dict = DataFactory('dict') # layout: # check input # get dictionaries # merge dictionaries into new dictionary # create a new Dict node new_dict = {} atoms_dict = {} atomlist = [] if not isinstance(Dict1, Dict): raise InputValidationError('Dict1, must be of type Dict') if not isinstance(Dict2, Dict): raise InputValidationError('Dict2, must be of type Dict') dict1 = Dict1.get_dict() dict2 = Dict2.get_dict() if dict1 == dict2: return Dict(dict1) for key in list(dict1.keys()): if 'atom' in key: val = dict1.pop(key) atomlist.append(val) for key in list(dict2.keys()): if 'atom' in key: val = dict2.pop(key) atomlist.append(val) # TODO do something on atom list, # we do not want doubles, check element and Id? Keep first ones? for i, atom in enumerate(atomlist): # TODO check for duplicates? what about key = f'atom{i}' atoms_dict[key] = atom # merge all namelists except atoms if overwrite: new_dict = dict1.copy() new_dict.update(dict2) else: # add second one later? new_dict = dict2.copy() if merge: new_dict = recursive_merge(new_dict, dict1) else: new_dict.update(dict1) # TODO mergeing does not make sense for all namelist keys. # be more specific here. new_dict.update(atoms_dict) # be carefull with atom namelist return Dict(new_dict)
[docs]def merge_parameters(DictList, overwrite=True): """ Merge together all parameter nodes in the given list. """ #Dict = DataFactory('dict') paremeter_data_new = Dict({}) for i, parameter in enumerate(DictList): if isinstance(parameter, Dict): # merge paremeter_data_new = merge_parameter(paremeter_data_new, parameter, overwrite=overwrite) else: print(f'WARNING: Entry : {i} {parameter} is not of type Dict, I skip it.') return paremeter_data_new
[docs]@cf def merge_parameter_cf(Dict1, Dict2, overwrite=None): """ calcfunction of merge_parameters """ if overwrite is None: overwrite = Bool(True) paremeter_data_new = merge_parameter(Dict1, Dict2, overwrite=overwrite) return paremeter_data_new
''' # TODO how to deal with a list? *args, prob is not the best, also it is not working here. # makeing a methods m(self, *args, **kwargs) and setting some fallbacks, does not work, because self, cannot be parsed # I guess... @cf def merge_parameters_wf(*Dicts, overwrite=Bool(True)): """ calcfunction of merge_parameters """ DictList = [] for parameter in Dicts: DictList.append(parameter) paremeter_data_new = merge_parameters(DictList, overwrite=overwrite) return paremeter_data_new ''' ''' #TODO this has to moved into cmdline if __name__ == '__main__': import argparse #Dict = DataFactory('dict') parser = argparse.ArgumentParser(description='Merge a Dict node.') parser.add_argument('--para1', type=Dict, dest='para1', help='The first Dict node', required=True) parser.add_argument('--para2', type=Dict, dest='para2', help='The second Dict node', required=True) parser.add_argument('--overwrite', type=bool, dest='overwrite', help='Shall values given in Dict2 overwrite the values from the first Dict?', required=False) args = parser.parse_args() merge_parameter(Dict1=args.para1, Dict2=args.para1, overwrite=args.overwrite) '''