def test_fleurinp_modifier1(create_fleurinp): """Tests if fleurinp_modifier with various modifations on species""" from masci_tools.io.fleurxmlmodifier import ModifierTask fleurinp_tmp = create_fleurinp(inpxmlfilefolder) fm = FleurinpModifier(fleurinp_tmp) fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.shift_value({'Kmax': 0.1}, 'rel') fm.shift_value_species_label(' 222', 'radius', 3, mode='abs') fm.set_species('all', {'mtSphere': {'radius': 3.333}}) fm.undo() changes = fm.changes() assert changes == [ ModifierTask(name='set_inpchanges', args=({ 'dos': True, 'Kmax': 3.9 },), kwargs={}), ModifierTask(name='shift_value', args=({ 'Kmax': 0.1 }, 'rel'), kwargs={}), ModifierTask(name='shift_value_species_label', args=(' 222', 'radius', 3), kwargs={'mode': 'abs'}) ] fm.show(validate=True) fm.freeze() fm = FleurinpModifier(fleurinp_tmp) fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.undo(revert_all=True) changes = fm.changes() assert changes == []
def test_fleurxml_modifier_modify_xmlfile_simple(): """Tests if fleurinp_modifier with various modifations on species""" from masci_tools.io.fleurxmlmodifier import FleurXMLModifier, ModifierTask fm = FleurXMLModifier() fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.shift_value({'Kmax': 0.1}, 'rel') fm.shift_value_species_label(' 222', 'radius', 3, mode='abs') fm.set_species('all', {'mtSphere': {'radius': 3.333}}) fm.xml_set_attrib_value_no_create('/fleurInput/calculationSetup/cutoffs', 'Gmax', '14.0') assert fm.changes() == [ ModifierTask(name='set_inpchanges', args=({ 'dos': True, 'Kmax': 3.9 }, ), kwargs={}), ModifierTask(name='shift_value', args=({ 'Kmax': 0.1 }, 'rel'), kwargs={}), ModifierTask(name='shift_value_species_label', args=( ' 222', 'radius', 3, ), kwargs={'mode': 'abs'}), ModifierTask(name='set_species', args=('all', { 'mtSphere': { 'radius': 3.333 } }), kwargs={}), ModifierTask(name='xml_set_attrib_value_no_create', args=( '/fleurInput/calculationSetup/cutoffs', 'Gmax', '14.0', ), kwargs={}) ] #The underlying methods are tested in the specific tests for the setters #We only want to ensure that the procedure finishes without error xmltree = fm.modify_xmlfile(TEST_INPXML_PATH) assert xmltree is not None
def set_file(self, filename, dst_filename=None, node=None): """ Appends a :py:func:`~aiida_fleur.data.fleurinp.FleurinpData.set_file()` to the list of tasks that will be done on the FleurinpData instance. :param filename: absolute path to the file or a filename of node is specified :param dst_filename: str of the filename, which should be used instead of the real filename to store it :param node: a :class:`~aiida.orm.FolderData` node containing the file """ from aiida.orm import FolderData, load_node node_uuid = None if node is not None: if isinstance(node, FolderData): node_uuid = node.uuid num_nodes = sum('folder' in label for label in self._other_nodes) + 1 node_label = f'folder_{num_nodes}' # Be more careful? Needs to be stored, otherwise we cannot load it self._other_nodes[node_label] = load_node(node_uuid) self._tasks.append( ModifierTask('set_file', args=(filename, ), kwargs={ 'dst_filename': dst_filename, 'node': node_uuid }))
def del_file(self, filename): """ Appends a :py:func:`~aiida_fleur.data.fleurinp.FleurinpData.del_file()` to the list of tasks that will be done on the FleurinpData instance. :param filename: name of the file to be removed from FleurinpData instance """ self._tasks.append( ModifierTask('del_file', args=(filename, ), kwargs={}))
def set_kpointsdata(self, kpointsdata_uuid, name=None, switch=False): """ Appends a :py:func:`~aiida_fleur.tools.xml_aiida_modifiers.set_kpointsdata_f()` to the list of tasks that will be done on the FleurinpData. :param kpointsdata_uuid: an :class:`aiida.orm.KpointsData` or node uuid, since the node is self cannot be be serialized in tasks. """ from aiida.orm import KpointsData, load_node if isinstance(kpointsdata_uuid, KpointsData): kpointsdata_uuid = kpointsdata_uuid.uuid # Be more careful? Needs to be stored, otherwise we cannot load it num_nodes = sum('kpoints' in label for label in self._other_nodes) + 1 node_label = f'kpoints_{num_nodes}' self._other_nodes[node_label] = load_node(kpointsdata_uuid) self._tasks.append( ModifierTask('set_kpointsdata', args=(kpointsdata_uuid, ), kwargs={ 'name': name, 'switch': switch }))
def modify_fleurinpdata(original, modifications, **kwargs): """ A CalcFunction that performs the modification of the given FleurinpData and stores the result in a database. :param original: a FleurinpData to be modified :param modifications: a python dictionary of modifications in the form of {'task': ...} :param kwargs: dict of other aiida nodes to be linked to the modifications :returns new_fleurinp: a modified FleurinpData that is stored in a database """ # copy # get schema # read in inp.xml # add modifications # validate # save inp.xml # store new fleurinp (copy) import tempfile from masci_tools.util.xml.common_functions import reverse_xinclude new_fleurinp = original.clone() modification_tasks = modifications.get_dict()['tasks'] #We need to rebuild the namedtuples since the serialization for the calcufunction inputs #converts the namedtuples into lists modification_tasks = [ModifierTask(*task) for task in modification_tasks] FleurinpModifier.apply_fleurinp_modifications(new_fleurinp, modification_tasks) xmltree, schema_dict, included_tags = new_fleurinp.load_inpxml( remove_blank_text=True, return_included_tags=True) try: with new_fleurinp.open(path='n_mmp_mat', mode='r') as n_mmp_file: nmmplines = n_mmp_file.read().split('\n') except FileNotFoundError: nmmplines = None new_fleurtree, new_nmmplines = FleurinpModifier.apply_modifications(xmltree=xmltree,\ nmmp_lines=nmmplines,\ modification_tasks=modification_tasks, validate_changes=False) # To include object store storage this prob has to be done differently inpxmltree, includedtrees = reverse_xinclude(new_fleurtree, schema_dict, included_tags) new_fleurinp.del_file('inp.xml') with tempfile.TemporaryDirectory() as td: inpxml_path = os.path.join(td, 'inp.xml') inpxmltree.write(inpxml_path, encoding='utf-8', pretty_print=True) new_fleurinp.set_file(inpxml_path, 'inp.xml') for file_name, tree in includedtrees.items(): file_path = os.path.join(td, file_name) tree.write(file_path, encoding='utf-8', pretty_print=True) new_fleurinp.set_file(file_path, file_name) if new_nmmplines is not None: n_mmp_path = os.path.join(td, 'n_mmp_mat') with open(n_mmp_path, 'w') as n_mmp_file: n_mmp_file.write('\n'.join(new_nmmplines)) new_fleurinp.set_file(n_mmp_path, 'n_mmp_mat') # default label and description new_fleurinp.label = 'mod_fleurinp' new_fleurinp.description = 'Fleurinpdata with modifications (see inputs of modify_fleurinpdata)' return new_fleurinp
def test_fleurxml_modifier_from_list(): """Tests if fleurinp_modifier with various modifations on species""" from masci_tools.io.fleurxmlmodifier import FleurXMLModifier, ModifierTask fm = FleurXMLModifier.fromList([('set_inpchanges', { 'change_dict': { 'dos': True, 'Kmax': 3.9 } }), ('shift_value', { 'change_dict': { 'Kmax': 0.1 }, 'mode': 'rel' }), ('shift_value_species_label', { 'atom_label': ' 222', 'attributename': 'radius', 'value_given': 3, 'mode': 'abs' }), ('set_kpointlist', { 'kpoints': [[0, 0, 0]], 'weights': [1] }), ('set_species', { 'species_name': 'all', 'attributedict': { 'mtSphere': { 'radius': 3.333 } } })]) assert fm.changes() == [ ModifierTask(name='set_inpchanges', args=(), kwargs={'change_dict': { 'dos': True, 'Kmax': 3.9 }}), ModifierTask(name='shift_value', args=(), kwargs={ 'change_dict': { 'Kmax': 0.1 }, 'mode': 'rel' }), ModifierTask(name='shift_value_species_label', args=(), kwargs={ 'atom_label': ' 222', 'attributename': 'radius', 'value_given': 3, 'mode': 'abs' }), ModifierTask(name='set_kpointlist', args=(), kwargs={ 'kpoints': [[0, 0, 0]], 'weights': [1] }), ModifierTask(name='set_species', args=(), kwargs={ 'species_name': 'all', 'attributedict': { 'mtSphere': { 'radius': 3.333 } } }) ] #The underlying methods are tested in the specific tests for the setters #We only want to ensure that the procedure finishes without error xmltree = fm.modify_xmlfile(TEST_INPXML_PATH) assert xmltree is not None