Source code for aiida.tools.data.orbital.orbital

# -*- coding: utf-8 -*-
###########################################################################
# Copyright (c), The AiiDA team. All rights reserved.                     #
# This file is part of the AiiDA code.                                    #
#                                                                         #
# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core #
# For further information on the license, see the LICENSE.txt file        #
# For further information please visit http://www.aiida.net               #
###########################################################################
"""
Classes for describing atomic orbitals.

Contains general Orbital class.
For subclasses of Orbital, see submodules.
"""

from aiida.common.exceptions import ValidationError
from aiida.plugins.entry_point import get_entry_point_from_class


[docs]def validate_int(value): """ Validate that the value is an int """ try: conv_value = int(value) except ValueError: raise ValidationError('must be an int number') return conv_value
[docs]def validate_int_or_none(value): """ Validate that the value is a int or is None """ if value is None: return None return validate_int(value)
[docs]def validate_float(value): """ Validate that the value is a float """ try: conv_value = float(value) except ValueError: raise ValidationError('must be a float number') return conv_value
[docs]def validate_float_or_none(value): """ Validate that the value is a float or is None """ if value is None: return None return validate_float(value)
[docs]def validate_len3_list(value): """ Validate that the value is a list of three floats """ try: conv_value = list(float(i) for i in value) if len(conv_value) != 3: raise ValueError except (ValueError, TypeError): raise ValidationError('must be a list of three float number') return conv_value
[docs]def validate_len3_list_or_none(value): """ Validate that the value is a list of three floats or is None """ if value is None: return None return validate_len3_list(value)
[docs]class Orbital: """ Base class for Orbitals. Can handle certain basic fields, their setting and validation. More complex Orbital objects should then inherit from this class :param position: the absolute position (three floats) units in angstrom :param x_orientation: x,y,z unit vector defining polar angle theta in spherical coordinates unitless :param z_orientation: x,y,z unit vector defining azimuthal angle phi in spherical coordinates unitless :param orientation_spin: x,y,z unit vector defining the spin orientation unitless :param diffusivity: Float controls the radial term in orbital equation units are reciprocal Angstrom. """ # len-2 tuples, with name and validator function _base_fields_required = (('position', validate_len3_list), #NOTE: _orbital_type is internally used to manage the orbital type ) # len-3 tuples, with (name, validator, default_value) # See how it is defined in the RealhydrogenOrbital class _base_fields_optional = tuple()
[docs] def __init__(self, **kwargs): # This runs the validator as well self.set_orbital_dict(kwargs)
[docs] def __repr__(self): return f'<{self.__class__.__name__}: {str(self)}>'
[docs] def __str__(self) -> str: orb_dict = self.get_orbital_dict() position_string = f"{orb_dict['position'][0]:.4f},{orb_dict['position'][1]:.4f},{orb_dict['position'][2]:.4f}" return f'Orbital @ {position_string}'
[docs] def _validate_keys(self, input_dict): """ Checks all the input_dict and tries to validate them, to ensure that they have been properly set raises Exceptions indicating any problems that should arise during the validation :param input_dict: a dictionary of inputs :return: input_dict: the original dictionary with all validated kyes now removed :return: validated_dict: a dictionary containing all the input keys which have now been validated. """ validated_dict = {} if '_orbital_type' in input_dict: raise ValidationError('You cannot manually set the _orbital_type') entry_point = get_entry_point_from_class(self.__class__.__module__, self.__class__.__name__)[1] if entry_point is None: raise ValidationError( 'Unable to detect entry point for current class {}, maybe you did not register an entry point for it?'. format(self.__class__) ) validated_dict['_orbital_type'] = entry_point.name for name, validator in self._base_fields_required: try: value = input_dict.pop(name) except KeyError: raise ValidationError(f"Missing required parameter '{name}'") # This might raise ValidationError try: value = validator(value) except ValidationError as exc: raise exc.__class__(f"Error validating '{name}': {str(exc)}") validated_dict[name] = value for name, validator, default_value in self._base_fields_optional: try: value = input_dict.pop(name) except KeyError: value = default_value # This might raise ValidationError try: value = validator(value) except ValidationError as exc: raise exc.__class__(f"Error validating '{name}': {str(exc)}") validated_dict[name] = value if input_dict: raise ValidationError(f'Unknown keys: {list(input_dict.keys())}') return validated_dict
[docs] def set_orbital_dict(self, init_dict): """ Sets the orbital_dict, which can vary depending on the particular implementation of this base class. :param init_dict: the initialization dictionary """ self._orbital_dict = self._validate_keys(init_dict)
[docs] def get_orbital_dict(self): """ returns the internal keys as a dictionary """ return self._orbital_dict