Source code for aiida.common.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               #
###########################################################################
from aiida.common.exceptions import ValidationError, MissingPluginError
import math


[docs]class Orbital(object): """ 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. :param module_name: internal parameter, stores orbital type """ #NOTE x_orientation, z_orientation, spin_orientation, diffusivity might #all need to be moved to RealHydrogenOrbital _base_fields = ('position', 'x_orientation', 'z_orientation', 'spin_orientation', 'diffusivity', 'module_name', # Actually, this one is system reserved ) def __init__(self): self._orbital_dict = {} def __repr__(self): module_name = self.get_orbital_dict()['module_name'] return '<{}: {}>'.format(module_name, str(self)) def __str__(self): raise NotImplementedError 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 = {} for k in self._base_fields: v = input_dict.pop(k, None) if k == "module_name": if v is None: raise TypeError try: OrbitalFactory(v) except (MissingPluginError, TypeError): raise ValidationError("The module name {} was found to " "be invalid".format(v)) if k == "position": if v is None: validated_dict.update({k: v}) continue try: v = list(float(i) for i in v) if len(v) != 3: raise ValueError except (ValueError, TypeError): raise ValueError("Wrong format for position, must be a" " list of three float numbers.") if "orientation" in k : if v is None: validated_dict.update({k: v}) continue try: v = list(float(i) for i in v) if len(v) != 3: raise ValueError except (ValueError, TypeError): raise ValueError("Wrong format for {}, must be a" " list of three float numbers.") # From a spherical cooridnate version of orientation # try: # v = tuple(float(i) for i in v) # if len(v) != (2): # raise ValueError # if v[0] >= 2*math.pi or v[0] <= 0: # raise ValueError # if v[1] >= math.pi or v[1] <= 0: # raise ValueError # except(ValueError, TypeError): # raise ValueError("Wrong format for {}, must be two tuples" # " each having two floats theta, phi where" # " 0<=theta<2pi and 0<=phi<=pi.".format(k)) if k == "diffusivity": if v is None: validated_dict.update({k: v}) continue try: v = float(v) except ValueError: raise ValidationError("Diffusivity must always be a float") validated_dict.update({k: v}) 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 """ if not isinstance(init_dict, dict): raise Exception('You must supply a dict as an init') # Adds the module_name in hard-coded manner init_dict.update({"module_name": self._get_module_name()}) validated_dict = self._validate_keys(init_dict) for k, v in validated_dict.iteritems(): self._orbital_dict[k] = v
[docs] def get_orbital_dict(self): """ returns the internal keys as a dictionary """ output = {} for k in self._default_fields: try: output[k] = self._orbital_dict[k] except KeyError: pass return output
def _get_module_name(self): """ Sets the module name, or label, to the orbital """ return self.__module__.split('.')[-1]
[docs]def OrbitalFactory(module): """ Factory method that returns a suitable Orbital subclass. :param module: a valid string recognized as a Orbital subclass """ from aiida.common.pluginloader import BaseFactory return BaseFactory(module, Orbital, "aiida.common.orbital")