def set_extra(self, key, value): """Set an extra to the given value. :param key: name of the extra :param value: value of the extra """ if self.is_stored: value = clean_value(value) self._dbmodel.extras[key] = value self._flush_if_stored({'extras'})
def set_attribute(self, key, value): """Set an attribute to the given value. :param key: name of the attribute :param value: value of the attribute """ if self.is_stored: value = clean_value(value) self._dbmodel.attributes[key] = value self._flush_if_stored({'attributes'})
def _get_aiida_structure_pymatgen_inline(cif, **kwargs): """ Creates :py:class:`aiida.orm.nodes.data.structure.StructureData` using pymatgen. :param occupancy_tolerance: If total occupancy of a site is between 1 and occupancy_tolerance, the occupancies will be scaled down to 1. :param site_tolerance: This tolerance is used to determine if two sites are sitting in the same position, in which case they will be combined to a single disordered site. Defaults to 1e-4. .. note:: requires pymatgen module. """ from pymatgen.io.cif import CifParser from aiida.orm import Dict, StructureData parameters = kwargs.get('parameters', {}) if isinstance(parameters, Dict): # Note, if `parameters` is unstored, it might contain stored `Node` instances which might slow down the parsing # enormously, because each time their value is used, a database call is made to refresh the value parameters = clean_value(parameters.get_dict()) constructor_kwargs = {} parameters['primitive'] = parameters.pop('primitive_cell', False) for argument in ['occupancy_tolerance', 'site_tolerance']: if argument in parameters: constructor_kwargs[argument] = parameters.pop(argument) with cif.open() as handle: parser = CifParser(handle, **constructor_kwargs) try: structures = parser.get_structures(**parameters) except ValueError: # Verify whether the failure was due to wrong occupancy numbers try: constructor_kwargs['occupancy_tolerance'] = 1E10 with cif.open() as handle: parser = CifParser(handle, **constructor_kwargs) structures = parser.get_structures(**parameters) except ValueError: # If it still fails, the occupancies were not the reason for failure raise ValueError( 'pymatgen failed to provide a structure from the cif file') else: # If it now succeeds, non-unity occupancies were the culprit raise InvalidOccupationsError( 'detected atomic sites with an occupation number larger than the occupation tolerance' ) return {'structure': StructureData(pymatgen_structure=structures[0])}
def reset_extras(self, extras): """Reset the extras. .. note:: This will completely clear any existing extras and replace them with the new dictionary. :param extras: a dictionary with the extras to set """ if self.is_stored: extras = clean_value(extras) self.dbmodel.extras = extras self._flush_if_stored({'extras'})
def reset_attributes(self, attributes): """Reset the attributes. .. note:: This will completely clear any existing attributes and replace them with the new dictionary. :param attributes: a dictionary with the attributes to set """ if self.is_stored: attributes = clean_value(attributes) self.dbmodel.attributes = attributes self._flush_if_stored({'attributes'})
def set_extra_many(self, extras): """Set multiple extras. .. note:: This will override any existing extras that are present in the new dictionary. :param extras: a dictionary with the extras to set """ if self.is_stored: extras = {key: clean_value(value) for key, value in extras.items()} for key, value in extras.items(): self.dbmodel.extras[key] = value self._flush_if_stored({'extras'})
def set_attribute_many(self, attributes): """Set multiple attributes. .. note:: This will override any existing attributes that are present in the new dictionary. :param attributes: a dictionary with the attributes to set """ if self.is_stored: attributes = { key: clean_value(value) for key, value in attributes.items() } for key, value in attributes.items(): # We need to use `self.dbmodel` without the underscore, because otherwise the second iteration will refetch # what is in the database and we lose the initial changes. self.dbmodel.attributes[key] = value self._flush_if_stored({'attributes'})
def set_attribute_many(self, attributes): """Set multiple attributes. .. note:: This will override any existing attributes that are present in the new dictionary. :param attributes: a dictionary with the attributes to set """ if self.is_stored: attributes = { key: clean_value(value) for key, value in attributes.items() } for key, value in attributes.items(): self.dbmodel.attributes[key] = value self._flag_field('attributes') self._flush_if_stored()
def _get_aiida_structure_ase_inline(cif, **kwargs): """ Creates :py:class:`aiida.orm.nodes.data.structure.StructureData` using ASE. .. note:: unable to correctly import structures of alloys. .. note:: requires ASE module. """ from aiida.orm import Dict, StructureData parameters = kwargs.get('parameters', {}) if isinstance(parameters, Dict): # Note, if `parameters` is unstored, it might contain stored `Node` instances which might slow down the parsing # enormously, because each time their value is used, a database call is made to refresh the value parameters = clean_value(parameters.get_dict()) parameters.pop('occupancy_tolerance', None) parameters.pop('site_tolerance', None) return {'structure': StructureData(ase=cif.get_ase(**parameters))}
def clean_values(self): self._dbmodel.attributes = clean_value(self._dbmodel.attributes) self._dbmodel.extras = clean_value(self._dbmodel.extras)