def _load_error_handlers(self):
     """If an error handler entry point is defined, load them. If the plugin cannot be loaded log it and pass."""
     if self._error_handler_entry_point is not None:
         for entry_point_name in get_entry_point_names(self._error_handler_entry_point):
             try:
                 load_entry_point(self._error_handler_entry_point, entry_point_name)
                 self.logger.info("loaded the '%s' entry point for the '%s' error handlers category",
                                  entry_point_name, self._error_handler_entry_point)
             except exceptions.EntryPointError as exception:
                 self.logger.warning("failed to load the '%s' entry point for the '%s' error handlers: %s",
                                     entry_point_name, self._error_handler_entry_point, exception)
 def _load_error_handlers(self):
     """Load the error handlers defined through entry points, if any."""
     if self._error_handler_entry_point is not None:
         for entry_point_name in get_entry_point_names(self._error_handler_entry_point):
             try:
                 load_entry_point(self._error_handler_entry_point, entry_point_name)
                 self.logger.info("loaded the '%s' entry point for the '%s' error handlers category",
                                  entry_point_name, self._error_handler_entry_point)
             except exceptions.EntryPointError as exception:
                 self.logger.warning("failed to load the '%s' entry point for the '%s' error handlers: %s",
                                     entry_point_name, self._error_handler_entry_point, exception)
def has_nwchem_plugin():
    from aiida.common.exceptions import MissingEntryPointError
    from aiida.plugins.entry_point import load_entry_point
    from aiida.tools.dbexporters.tcod_plugins import BaseTcodtranslator

    try:
        load_entry_point('aiida.tools.dbexporters.tcod_plugins', 'nwchem.nwcpymatgen')
    except MissingEntryPointError:
        return False

    return True
Beispiel #4
0
def load_node_class(type_string):
    """
    Return the `Node` sub class that corresponds to the given type string.

    :param type_string: the `type` string of the node
    :return: a sub class of `Node`
    """
    from aiida.orm import Data, Node
    from aiida.plugins.entry_point import load_entry_point

    if type_string == '':
        return Node

    if type_string == 'data.Data.':
        return Data

    if not type_string.endswith('.'):
        raise exceptions.DbContentError('The type string `{}` is invalid'.format(type_string))

    try:
        base_path = type_string.rsplit('.', 2)[0]
    except ValueError:
        raise exceptions.EntryPointError

    # This exception needs to be there to make migrations work that rely on the old type string starting with `node.`
    # Since now the type strings no longer have that prefix, we simply strip it and continue with the normal logic.
    if base_path.startswith('node.'):
        base_path = strip_prefix(base_path, 'node.')

    # Data nodes are the only ones with sub classes that are still external, so if the plugin is not available
    # we fall back on the base node type
    if base_path.startswith('data.'):
        entry_point_name = strip_prefix(base_path, 'data.')
        try:
            return load_entry_point('aiida.data', entry_point_name)
        except exceptions.MissingEntryPointError:
            return Data

    if base_path.startswith('process'):
        entry_point_name = strip_prefix(base_path, 'nodes.')
        return load_entry_point('aiida.node', entry_point_name)

    # At this point we really have an anomalous type string. At some point, storing nodes with unresolvable type strings
    # was allowed, for example by creating a sub class in a shell and then storing an instance. Attempting to load the
    # node then would fail miserably. This is now no longer allowed, but we need a fallback for existing cases, which
    # should be rare. We fallback on `Data` and not `Node` because bare node instances are also not storable and so the
    # logic of the ORM is not well defined for a loaded instance of the base `Node` class.
    warnings.warn('unknown type string `{}`, falling back onto `Data` class'.format(type_string))  # pylint: disable=no-member

    return Data
Beispiel #5
0
def calculation_plugins(entry_point):
    """Print a list of registered calculation plugins or details of a specific calculation plugin."""
    import json
    from aiida.common.exceptions import LoadingPluginFailed, MissingPluginError
    from aiida.plugins.entry_point import get_entry_point_names, load_entry_point

    if entry_point:
        try:
            plugin = load_entry_point('aiida.calculations', entry_point)
        except (LoadingPluginFailed, MissingPluginError) as exception:
            echo.echo_critical(exception)
        else:
            echo.echo_info(entry_point)
            echo.echo_info(
                plugin.__doc__ if plugin.__doc__ else 'no docstring available')
            echo.echo(json.dumps(plugin.process().get_description(), indent=4))

    else:
        entry_points = get_entry_point_names('aiida.calculations')
        if entry_points:
            echo.echo('Registered calculation entry points:')
            for ep in entry_points:
                echo.echo("* {}".format(ep))

            echo.echo('')
            echo.echo_info(
                'Pass the entry point as an argument to display detailed information'
            )
        else:
            echo.echo_error('No calculation plugins found')
Beispiel #6
0
    def tools(self):
        """Return the calculation tools that are registered for the process type associated with this calculation.

        If the entry point name stored in the `process_type` of the CalcJobNode has an accompanying entry point in the
        `aiida.tools.calculations` entry point category, it will attempt to load the entry point and instantiate it
        passing the node to the constructor. If the entry point does not exist, cannot be resolved or loaded, a warning
        will be logged and the base CalculationTools class will be instantiated and returned.

        :return: CalculationTools instance
        """
        from aiida.plugins.entry_point import is_valid_entry_point_string, get_entry_point_from_string, load_entry_point
        from aiida.tools.calculations import CalculationTools

        if self._tools is None:
            entry_point_string = self.process_type

            if is_valid_entry_point_string(entry_point_string):
                entry_point = get_entry_point_from_string(entry_point_string)

                try:
                    tools_class = load_entry_point('aiida.tools.calculations',
                                                   entry_point.name)
                    self._tools = tools_class(self)
                except exceptions.EntryPointError as exception:
                    self._tools = CalculationTools(self)
                    self.logger.warning(
                        f'could not load the calculation tools entry point {entry_point.name}: {exception}'
                    )

        return self._tools
Beispiel #7
0
def work_plugins(entry_point):
    """
    Print a list of registered workflow plugins or details of a specific workflow plugin
    """
    from aiida.common.exceptions import LoadingPluginFailed, MissingPluginError
    from aiida.plugins.entry_point import get_entry_point_names, load_entry_point

    if entry_point:
        try:
            plugin = load_entry_point('aiida.workflows', entry_point)
        except (LoadingPluginFailed, MissingPluginError) as exception:
            echo.echo_critical(exception)
        else:
            echo.echo_info(entry_point)
            echo.echo(plugin.get_description())
    else:
        entry_points = get_entry_point_names('aiida.workflows')
        if entry_points:
            echo.echo('Registered workflow entry points:')
            for registered_entry_point in entry_points:
                echo.echo("* {}".format(registered_entry_point))

            echo.echo('')
            echo.echo_info(
                'Pass the entry point as an argument to display detailed information'
            )
        else:
            echo.echo_error('No workflow plugins found')
Beispiel #8
0
    def load_type(cls, entry_name):
        """Load the entry point for a given potential type.

        :param entry_name: name of the entry point
        :type entry_name: str
        """
        return load_entry_point(cls.entry_name, entry_name)
Beispiel #9
0
    def get_all_download_formats(full_type=None):
        """
        returns dict of possible node formats for all available node types
        """

        all_formats = {}

        if full_type:
            try:
                node_cls = load_entry_point_from_full_type(full_type)
            except (TypeError, ValueError):
                raise RestInputValidationError(f'The full type {full_type} is invalid.')
            except EntryPointError:
                raise RestFeatureNotAvailable('The download formats for this node type are not available.')

            try:
                available_formats = node_cls.get_export_formats()
                all_formats[full_type] = available_formats
            except AttributeError:
                pass
        else:
            entry_point_group = 'aiida.data'

            for name in get_entry_point_names(entry_point_group):
                try:
                    node_cls = load_entry_point(entry_point_group, name)
                    available_formats = node_cls.get_export_formats()
                except (AttributeError, LoadingEntryPointError):
                    continue

                if available_formats:
                    full_type = construct_full_type(node_cls.class_node_type, '')
                    all_formats[full_type] = available_formats

        return all_formats
 def _load_error_handlers(self):
     # If an error handler entry point is defined, load them. If the plugin cannot be loaded log it and pass
     if self._error_handler_entry_point is not None:
         for entry_point_name in get_entry_point_names(
                 self._error_handler_entry_point):
             try:
                 load_entry_point(self._error_handler_entry_point,
                                  entry_point_name)
                 self.logger.info(
                     "loaded the '{}' entry point for the '{}' error handlers category"
                     .format(entry_point_name,
                             self._error_handler_entry_point, plugin))
             except EntryPointError as exception:
                 self.logger.warning(
                     "failed to load the '{}' entry point for the '{}' error handlers: '{}'"
                     .format(entry_point_name,
                             self._error_handler_entry_point, exception))
Beispiel #11
0
 def get_command(self, ctx, name):  # pylint: disable=arguments-differ
     """Try to load a subcommand from entry points, else defer to super."""
     command = None
     try:
         command = load_entry_point(self._entry_point_group, name)
     except MissingEntryPointError:
         command = super(Pluginable, self).get_command(ctx, name)
     return command
Beispiel #12
0
def load_node_class(type_string):
    """
    Return the `Node` sub class that corresponds to the given type string.

    :param type_string: the `type` string of the node
    :return: a sub class of `Node`
    """
    from aiida.orm import Data, Node
    from aiida.plugins.entry_point import load_entry_point

    if type_string == '':
        return Node

    if type_string == 'data.Data.':
        return Data

    if not type_string.endswith('.'):
        raise exceptions.DbContentError(
            'The type string `{}` is invalid'.format(type_string))

    try:
        base_path = type_string.rsplit('.', 2)[0]
    except ValueError:
        raise exceptions.EntryPointError

    # This exception needs to be there to make migrations work that rely on the old type string starting with `node.`
    # Since now the type strings no longer have that prefix, we simply strip it and continue with the normal logic.
    if base_path.startswith('node.'):
        base_path = strip_prefix(base_path, 'node.')

    # Data nodes are the only ones with sub classes that are still external, so if the plugin is not available
    # we fall back on the base node type
    if base_path.startswith('data.'):
        entry_point_name = strip_prefix(base_path, 'data.')
        try:
            return load_entry_point('aiida.data', entry_point_name)
        except exceptions.MissingEntryPointError:
            return Data

    if base_path.startswith('process'):
        entry_point_name = strip_prefix(base_path, 'nodes.')
        return load_entry_point('aiida.node', entry_point_name)

    raise exceptions.EntryPointError(
        'unknown type string {}'.format(type_string))
Beispiel #13
0
def BaseFactory(group, name):
    """
    Return the plugin class registered under a given entry point group and name

    :param group: entry point group
    :param name: entry point name
    :return: the plugin class
    """
    return load_entry_point(group, name)
Beispiel #14
0
def load_workflow_entry_point(workflow: str, plugin_name: str):
    """Load the entry point for the given plugin implementation of a certain common workflow.

    :param workflow: the name of the common workflow.
    :param plugin_name: name of the plugin implementation.
    :return: the workchain class of the plugin implementation of the common workflow.
    """
    prefix = f'{PACKAGE_PREFIX}.{workflow}.{plugin_name}'
    return entry_point.load_entry_point('aiida.workflows', prefix)
Beispiel #15
0
 def get_command(self, ctx, name):  # pylint: disable=arguments-differ
     """Try to load a subcommand from entry points, else defer to super."""
     command = None
     if not self._exclude_external_plugins:
         try:
             command = load_entry_point(self._entry_point_group, name)
         except exceptions.EntryPointError:
             command = super().get_command(ctx, name)
     else:
         command = super().get_command(ctx, name)
     return command
Beispiel #16
0
def plugin_list(entry_point_group, entry_point):
    """Display a list of all available plugins."""
    from aiida.common import EntryPointError
    from aiida.cmdline.utils.common import print_process_info
    from aiida.engine import Process
    from aiida.plugins.entry_point import get_entry_point_names, load_entry_point

    if entry_point_group is None:
        echo.echo_info('Available entry point groups:')
        for group in sorted(ENTRY_POINT_GROUP_TO_MODULE_PATH_MAP.keys()):
            echo.echo('* {}'.format(group))

        echo.echo('')
        echo.echo_info(
            'Pass one of the groups as an additional argument to show the registered plugins'
        )
        return

    if entry_point:
        try:
            plugin = load_entry_point(entry_point_group, entry_point)
        except EntryPointError as exception:
            echo.echo_critical(str(exception))
        else:
            try:
                if (inspect.isclass(plugin) and issubclass(
                        plugin, Process)) or plugin.is_process_function:
                    print_process_info(plugin)
                else:
                    echo.echo(str(plugin.get_description()))
            except AttributeError:
                echo.echo_error(
                    'No description available for {}'.format(entry_point))
    else:
        entry_points = get_entry_point_names(entry_point_group)
        if entry_points:
            echo.echo(
                'Registered entry points for {}:'.format(entry_point_group))
            for registered_entry_point in entry_points:
                echo.echo('* {}'.format(registered_entry_point))

            echo.echo('')
            echo.echo_info(
                'Pass the entry point as an argument to display detailed information'
            )
        else:
            echo.echo_error(
                'No plugins found for group {}'.format(entry_point_group))
Beispiel #17
0
    def get_all_download_formats(full_type=None):
        """
        returns dict of possible node formats for all available node types
        """
        from aiida.plugins.entry_point import load_entry_point, get_entry_point_names
        from aiida.restapi.common.identifiers import load_entry_point_from_full_type, construct_full_type
        from aiida.common import EntryPointError
        from aiida.common.exceptions import LoadingEntryPointError
        from aiida.restapi.common.exceptions import RestFeatureNotAvailable, RestInputValidationError

        all_formats = {}

        if full_type:
            try:
                node_cls = load_entry_point_from_full_type(full_type)
            except (TypeError, ValueError):
                raise RestInputValidationError(
                    'The full type {} is invalid.'.format(full_type))
            except EntryPointError:
                raise RestFeatureNotAvailable(
                    'The download formats for this node type are not available.'
                )

            try:
                available_formats = node_cls.get_export_formats()
                all_formats[full_type] = available_formats
            except AttributeError:
                pass
        else:
            entry_point_group = 'aiida.data'

            for name in get_entry_point_names(entry_point_group):
                try:
                    node_cls = load_entry_point(entry_point_group, name)
                except LoadingEntryPointError:
                    pass
                else:
                    node_cls.get_export_formats()
                try:
                    available_formats = node_cls.get_export_formats()
                    if available_formats:
                        full_type = construct_full_type(
                            node_cls.class_node_type, '')
                        all_formats[full_type] = available_formats
                except AttributeError:
                    pass
        return all_formats
Beispiel #18
0
def load_group_class(type_string):
    """Load the sub class of `Group` that corresponds to the given `type_string`.

    .. note:: will fall back on `aiida.orm.groups.Group` if `type_string` cannot be resolved to loadable entry point.

    :param type_string: the entry point name of the `Group` sub class
    :return: sub class of `Group` registered through an entry point
    """
    from aiida.common.exceptions import EntryPointError
    from aiida.plugins.entry_point import load_entry_point

    try:
        group_class = load_entry_point('aiida.groups', type_string)
    except EntryPointError:
        message = f'could not load entry point `{type_string}`, falling back onto `Group` base class.'
        warnings.warn(message)  # pylint: disable=no-member
        group_class = Group

    return group_class
Beispiel #19
0
def load_entry_point_from_full_type(full_type):
    """Return the loaded entry point for the given `full_type` unique node identifier.

    :param full_type: the `full_type` unique node identifier
    :raises ValueError: if the `full_type` is invalid
    :raises TypeError: if the `full_type` is not a string type
    :raises `~aiida.common.exceptions.EntryPointError`: if the corresponding entry point cannot be loaded
    """
    from aiida.common import EntryPointError
    from aiida.common.utils import strip_prefix
    from aiida.plugins.entry_point import is_valid_entry_point_string, load_entry_point, load_entry_point_from_string

    data_prefix = 'data.'

    validate_full_type(full_type)

    node_type, process_type = full_type.split(FULL_TYPE_CONCATENATOR)

    if is_valid_entry_point_string(process_type):

        try:
            return load_entry_point_from_string(process_type)
        except EntryPointError:
            raise EntryPointError(
                f'could not load entry point `{process_type}`')

    elif node_type.startswith(data_prefix):

        base_name = strip_prefix(node_type, data_prefix)
        entry_point_name = base_name.rsplit('.', 2)[0]

        try:
            return load_entry_point('aiida.data', entry_point_name)
        except EntryPointError:
            raise EntryPointError(
                f'could not load entry point `{process_type}`')

    # Here we are dealing with a `ProcessNode` with a `process_type` that is not an entry point string.
    # Which means it is most likely a full module path (the fallback option) and we cannot necessarily load the
    # class from this. We could try with `importlib` but not sure that we should
    raise EntryPointError(
        'entry point of the given full type cannot be loaded')
Beispiel #20
0
def potential_list(entry_point, schema_depth):
    """Display a list of all available plugins."""
    entry_point_group = "gulp.potentials"
    if entry_point:
        try:
            plugin = load_entry_point(entry_point_group, entry_point)
        except EntryPointError as exception:
            echo.echo_critical(str(exception))
        else:
            try:
                echo.echo(str(plugin.get_description()), bold=True)
            except (AttributeError, TypeError):
                echo.echo_error(
                    "No description available for {}".format(entry_point))
            try:
                schema = plugin.get_schema()
                echo.echo("Data Schema:")
                edict.pprint(schema,
                             depth=schema_depth,
                             print_func=echo.echo,
                             keycolor="blue")
            except (AttributeError, TypeError):
                echo.echo_error("No validation schema available for {}".format(
                    entry_point))
    else:
        entry_points = get_entry_point_names(entry_point_group)
        if entry_points:
            echo.echo(
                "Registered entry points for {}:".format(entry_point_group))
            for registered_entry_point in entry_points:
                echo.echo("* {}".format(registered_entry_point))

            echo.echo("")
            echo.echo_info(
                "Pass the entry point as an argument to display detailed information"
            )
        else:
            echo.echo_error(
                "No plugins found for group {}".format(entry_point_group))
Beispiel #21
0
    def test_pw_translation(self):
        from aiida.tools.dbexporters.tcod import translate_calculation_specific_values
        from aiida.orm.code import Code
        from aiida.orm.data.array import ArrayData
        from aiida.orm.data.array.kpoints import KpointsData
        from aiida.orm.data.parameter import ParameterData
        import numpy
        from aiida.plugins.entry_point import load_entry_point
        PWT = load_entry_point('aiida.tools.dbexporters.tcod_plugins',
                               'quantumespresso.pw')
        CPT = load_entry_point('aiida.tools.dbexporters.tcod_plugins',
                               'quantumespresso.cp')

        code = Code()
        code._set_attr('remote_exec_path', '/test')

        kpoints = KpointsData()
        kpoints.set_kpoints_mesh([2, 3, 4], offset=[0.25, 0.5, 0.75])

        def empty_list():
            return []

        calc = FakeObject({
            "inp": {
                "parameters": ParameterData(dict={}),
                "kpoints": kpoints,
                "code": code
            },
            "out": {
                "output_parameters": ParameterData(dict={})
            },
            "get_inputs": empty_list
        })

        res = translate_calculation_specific_values(calc, PWT)
        self.assertEquals(
            res, {
                '_dft_BZ_integration_grid_X': 2,
                '_dft_BZ_integration_grid_Y': 3,
                '_dft_BZ_integration_grid_Z': 4,
                '_dft_BZ_integration_grid_shift_X': 0.25,
                '_dft_BZ_integration_grid_shift_Y': 0.5,
                '_dft_BZ_integration_grid_shift_Z': 0.75,
                '_dft_pseudopotential_atom_type': [],
                '_dft_pseudopotential_type': [],
                '_dft_pseudopotential_type_other_name': [],
                '_tcod_software_package': 'Quantum ESPRESSO',
                '_tcod_software_executable_path': '/test',
            })

        calc = FakeObject({
            "inp": {
                "parameters":
                ParameterData(dict={
                    'SYSTEM': {
                        'ecutwfc': 40,
                        'occupations': 'smearing'
                    }
                })
            },
            "out": {
                "output_parameters":
                ParameterData(dict={
                    'number_of_electrons': 10,
                })
            },
            "get_inputs": empty_list
        })
        res = translate_calculation_specific_values(calc, PWT)
        self.assertEquals(
            res, {
                '_dft_cell_valence_electrons': 10,
                '_tcod_software_package': 'Quantum ESPRESSO',
                '_dft_BZ_integration_smearing_method': 'Gaussian',
                '_dft_pseudopotential_atom_type': [],
                '_dft_pseudopotential_type': [],
                '_dft_pseudopotential_type_other_name': [],
                '_dft_kinetic_energy_cutoff_EEX': 2176.910676048,
                '_dft_kinetic_energy_cutoff_charge_density': 2176.910676048,
                '_dft_kinetic_energy_cutoff_wavefunctions': 544.227669012,
            })

        calc = FakeObject({
            "inp": {
                "parameters": ParameterData(dict={})
            },
            "out": {
                "output_parameters": ParameterData(dict={
                    'energy_xc': 5,
                })
            },
            "get_inputs": empty_list
        })
        with self.assertRaises(ValueError):
            translate_calculation_specific_values(calc, PWT)

        calc = FakeObject({
            "inp": {
                "parameters": ParameterData(dict={})
            },
            "out": {
                "output_parameters":
                ParameterData(dict={
                    'energy_xc': 5,
                    'energy_xc_units': 'meV'
                })
            },
            "get_inputs": empty_list
        })
        with self.assertRaises(ValueError):
            translate_calculation_specific_values(calc, PWT)

        energies = {
            'energy': -3701.7004199449257,
            'energy_one_electron': -984.0078459766,
            'energy_xc': -706.6986753641559,
            'energy_ewald': -2822.6335103043157,
            'energy_hartree': 811.6396117001462,
            'fermi_energy': 10.25208617898623,
        }
        dct = energies
        for key in energies.keys():
            dct["{}_units".format(key)] = 'eV'
        calc = FakeObject({
            "inp": {
                "parameters":
                ParameterData(dict={'SYSTEM': {
                    'smearing': 'mp'
                }})
            },
            "out": {
                "output_parameters": ParameterData(dict=dct)
            },
            "get_inputs": empty_list
        })
        res = translate_calculation_specific_values(calc, PWT)
        self.assertEquals(
            res, {
                '_tcod_total_energy': energies['energy'],
                '_dft_1e_energy': energies['energy_one_electron'],
                '_dft_correlation_energy': energies['energy_xc'],
                '_dft_ewald_energy': energies['energy_ewald'],
                '_dft_hartree_energy': energies['energy_hartree'],
                '_dft_fermi_energy': energies['fermi_energy'],
                '_tcod_software_package': 'Quantum ESPRESSO',
                '_dft_BZ_integration_smearing_method': 'Methfessel-Paxton',
                '_dft_BZ_integration_MP_order': 1,
                '_dft_pseudopotential_atom_type': [],
                '_dft_pseudopotential_type': [],
                '_dft_pseudopotential_type_other_name': [],
            })
        dct = energies
        dct['number_of_electrons'] = 10
        for key in energies.keys():
            dct["{}_units".format(key)] = 'eV'
        calc = FakeObject({
            "inp": {
                "parameters":
                ParameterData(dict={'SYSTEM': {
                    'smearing': 'unknown-method'
                }})
            },
            "out": {
                "output_parameters": ParameterData(dict=dct)
            },
            "get_inputs": empty_list
        })
        res = translate_calculation_specific_values(calc, CPT)
        self.assertEquals(
            res, {
                '_dft_cell_valence_electrons': 10,
                '_tcod_software_package': 'Quantum ESPRESSO'
            })

        ad = ArrayData()
        ad.set_array("forces", numpy.array([[[1, 2, 3], [4, 5, 6]]]))
        calc = FakeObject({
            "inp": {
                "parameters":
                ParameterData(dict={'SYSTEM': {
                    'smearing': 'unknown-method'
                }})
            },
            "out": {
                "output_parameters": ParameterData(dict={}),
                "output_array": ad
            },
            "get_inputs": empty_list
        })
        res = translate_calculation_specific_values(calc, PWT)
        self.assertEquals(
            res,
            {
                '_tcod_software_package': 'Quantum ESPRESSO',
                '_dft_BZ_integration_smearing_method': 'other',
                '_dft_BZ_integration_smearing_method_other': 'unknown-method',
                '_dft_pseudopotential_atom_type': [],
                '_dft_pseudopotential_type': [],
                '_dft_pseudopotential_type_other_name': [],
                ## Residual forces are no longer produced, as they should
                ## be in the same CIF loop with coordinates -- to be
                ## implemented later, since it's not yet clear how.
                # '_tcod_atom_site_resid_force_Cartn_x': [1,4],
                # '_tcod_atom_site_resid_force_Cartn_y': [2,5],
                # '_tcod_atom_site_resid_force_Cartn_z': [3,6],
            })
Beispiel #22
0
 def load_type(cls, entry_name):
     return load_entry_point(cls.entry_name, entry_name)
Beispiel #23
0
def load_plugin(plugin_type, safe=False):
    """
    Load a plugin class from its plugin type, which is essentially its ORM type string
    minus the trailing period

    :param plugin_type: the plugin type string
    :param safe: when set to True, will always attempt to return the base class closest to the plugin_type if
        the actual entry point is not recognized
    :return: the plugin class
    :raises MissingPluginError: plugin_type could not be resolved to registered entry point
    :raises LoadingPluginFailed: the entry point matching the plugin_type could not be loaded
    """
    from aiida.orm.code import Code
    from aiida.orm.calculation import Calculation
    from aiida.orm.calculation.job import JobCalculation
    from aiida.orm.data import Data
    from aiida.orm.node import Node

    plugin = None
    base_class = Node

    if plugin_type == 'data.Data':
        return Data

    try:
        base_path, class_name = plugin_type.rsplit('.', 1)
    except ValueError:
        raise MissingPluginError

    type_string_to_entry_point_type_map = OrderedDict({
        'calculation.job.':
        EntryPoint('aiida.calculations', JobCalculation),
        'calculation.':
        EntryPoint('aiida.calculations', Calculation),
        'code.':
        EntryPoint('aiida.code', Code),
        'data.':
        EntryPoint('aiida.data', Data),
        'node.':
        EntryPoint('aiida.node', Node),
    })

    if base_path.count('.') == 0:
        base_path = '{}.{}'.format(base_path, base_path)

    for prefix, entry_point_type in type_string_to_entry_point_type_map.iteritems(
    ):
        if base_path.startswith(prefix):
            entry_point = strip_prefix(base_path, prefix)
            try:
                plugin = load_entry_point(entry_point_type.group, entry_point)
            except (MissingEntryPointError, MultipleEntryPointError,
                    LoadingEntryPointError):
                base_class = entry_point_type.base_class
            finally:
                break

    if not plugin and safe is False:
        raise MissingPluginError

    if plugin:
        return plugin
    else:
        return base_class
Beispiel #24
0
    def test_nwcpymatgen_translation(self):
        from tcodexporter import FakeObject
        from aiida.orm.data.parameter import ParameterData
        from aiida.plugins.entry_point import load_entry_point
        from aiida.tools.dbexporters.tcod import translate_calculation_specific_values

        nwchem_plugin = load_entry_point('aiida.tools.dbexporters.tcod_plugins', 'nwchem.nwcpymatgen')

        calc = FakeObject({
            "out": {"output":
                ParameterData(dict={
                    "basis_set": {
                        "H": {
                            "description": "6-31g",
                            "functions": "2",
                            "shells": "2",
                            "types": "2s"
                        },
                        "O": {
                            "description": "6-31g",
                            "functions": "9",
                            "shells": "5",
                            "types": "3s2p"
                        }
                    },
                    "corrections": {},
                    "energies": [
                        -2057.99011937535
                    ],
                    "errors": [],
                    "frequencies": None,
                    "has_error": False,
                    "job_type": "NWChem SCF Module"
                }),
                "job_info": ParameterData(dict={
                    "0 permanent": ".",
                    "0 scratch": ".",
                    "argument  1": "aiida.in",
                    "compiled": "Sun_Dec_22_04:02:59_2013",
                    "data base": "./aiida.db",
                    "date": "Mon May 11 17:10:07 2015",
                    "ga revision": "10379",
                    "global": "200.0 Mbytes (distinct from heap & stack)",
                    "hardfail": "no",
                    "heap": "100.0 Mbytes",
                    "hostname": "theospc11",
                    "input": "aiida.in",
                    "nproc": "6",
                    "nwchem branch": "6.3",
                    "nwchem revision": "24277",
                    "prefix": "aiida.",
                    "program": "/usr/bin/nwchem",
                    "source": "/build/buildd/nwchem-6.3+r1",
                    "stack": "100.0 Mbytes",
                    "status": "startup",
                    "time left": "-1s",
                    "total": "400.0 Mbytes",
                    "verify": "yes",
                })
            }})
        res = translate_calculation_specific_values(calc, nwchem_plugin)
        self.assertEquals(res, {
            '_tcod_software_package': 'NWChem',
            '_tcod_software_package_version': '6.3',
            '_tcod_software_package_compilation_date': '2013-12-22T04:02:59',
            '_atom_type_symbol': ['H', 'O'],
            '_dft_atom_basisset': ['6-31g', '6-31g'],
            '_dft_atom_type_valence_configuration': ['2s', '3s2p'],
        })
Beispiel #25
0
 def load_pair_style(cls, entry_name):
     return load_entry_point(cls.entry_name, entry_name)
Beispiel #26
0
            q = QueryBuilder()
            q.append(orm_class, project=["*"])
            return [data_class.from_orm(entry) for entry in q.iterall()]

        setattr(cls, name, single)
        setattr(cls, f"{name}s", multiple)


# PoC for looking up dataclasses on plugins and loading them dynamically
# Limited to aiida.data subclasses/entry point for now
ep_group_name = "aiida.data"
entry_points = get_entry_point_names(ep_group_name)
for registered_entry_point in entry_points:
    try:
        # Limit to the ones in our internal registry.
        # Could also be provided by the plugin or as part of the ORM class
        # Another option would be to look at the schema added for the REST API
        # but sometimes that doesn't give the access and it would be a bit more involved
        # to recover the typing information from that.
        adc = DC_REGISTRY[registered_entry_point]
    except KeyError:
        continue

    print(
        f"-> Loading dataclass for {ep_group_name}.{registered_entry_point}, to be registered as {registered_entry_point}"
    )
    cls = load_entry_point(ep_group_name, registered_entry_point)
    Root.add_field(registered_entry_point, cls, adc)

schema = strawberry.Schema(query=Root, types=[BareNode])