Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

  • d182a0b
  • /
  • src
  • /
  • chemfeat
  • /
  • features
  • /
  • calculators
  • /
  • padel.py
Raw File Download

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
content badge
swh:1:cnt:95a8c6346569831defd1e73cbc97e6379c26e8e2
directory badge
swh:1:dir:13045c0eb68ebdcc0513e8327289626b28c0b5cf

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
  • directory
(requires biblatex-software package)
Generating citation ...
(requires biblatex-software package)
Generating citation ...
padel.py
#!/usr/bin/env python3

'''
PaDEL feature calculators.

Given the number of PaDEL descriptors and fingerprints, this module generates
the corresponding classes programmatically.
'''

import logging
import sys
import textwrap
from typing import Optional

from PaDEL_pywrapper import PaDEL
from PaDEL_pywrapper.descriptor import descriptors, _fingerprints

from chemfeat.features.calculator import FeatureCalculator, FEATURE_CALCULATORS
from chemfeat.markdown import escape as escape_markdown


LOGGER = logging.getLogger(__name__)
THIS_MODULE = sys.modules[__name__]


def _get_class_name(desc):
    '''
    Get a class name for the given PaDEL descriptor or fingerprint.
    '''
    try:
        return f'padel_{desc.short_name}'
    except AttributeError:
        return f'padel_{desc.name}'


class _PaDELCommonFeatureCalculator(FeatureCalculator):  # pylint: disable=abstract-method
    '''
    Abstract base class for other PaDEL feature calculators.
    '''
    _IS_3D = False

    @property
    def is_3D(self):
        return self._IS_3D


class PaDELDescFeatureCalculator(_PaDELCommonFeatureCalculator):
    '''
    Base class for PaDEL feature calculator subclasses.
    '''
    _PADEL_DESC = NotImplemented

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.padel = PaDEL([self._PADEL_DESC])

    def is_numeric(self, _name):
        return True

    def add_features(self, features, molecule):
        features = self.padel.calculate([molecule], show_banner=False)
        for key, value in features.iloc[0].to_dict():
            features[self.add_prefix(key)] = value
        return features


class PaDELFPFeatureCalculator(_PaDELCommonFeatureCalculator):
    '''
    Base class for PaDEL fingerprint calculator subclasses.
    '''
    _PADEL_DESC = NotImplemented

    def __init__(
        self,
        *args,
        size: Optional[int] = None,
        search_depth: Optional[int] = None,
        **kwargs
    ):
        super().__init__(*args, **kwargs)
        self._padel_kwargs = {}
        if size is not None:
            self._padel_kwargs['size'] = int(size)
        if search_depth is not None:
            self._padel_kwargs['searchDepth'] = int(search_depth)
        self.padel = PaDEL([self._PADEL_DESC], **self._padel_kwargs)

    @property
    def parameters(self):
        return self._padel_kwargs.copy()

    def is_numeric(self, _name):
        return False

    def add_features(self, features, molecule):
        features = self.padel.calculate([molecule], show_banner=False)
        for i, value in enumerate(features.iloc[0], start=1):
            features[self.add_prefix(i)] = value
        return features


def _add_docstring_and_class(cls, name, docstring, features):
    citation_blurb = '''
All values are calculated with the [PaDEL_pywrapper Python
package](https://github.com/OlivierBeq/PaDEL_pywrapper) based on
[PaDEL-descriptor](https://doi.org/10.1002/jcc.21707).

> Yap, Chun Wei. “PaDEL-Descriptor: An Open Source Software to Calculate
> Molecular Descriptors and Fingerprints.” Journal of Computational Chemistry
> 32, no. 7 (May 2011): 1466–74. https://doi.org/10.1002/jcc.21707.
'''.strip()

    docstring = '\n\n'.join(
        '\n'.join(textwrap.wrap(block, width=80))
        for block in docstring.split('\n\n')
    )
    docstring += f'\n\n{features}\n\n{citation_blurb}'
    setattr(cls, '__doc__', docstring)

    setattr(THIS_MODULE, name, cls)
    FEATURE_CALCULATORS[name] = cls


def declare_classes():
    '''
    Declare the descriptor and fingerprint classes.
    '''
    for desc in descriptors:
        name = _get_class_name(desc)
        dcls = type(
            name,
            (PaDELDescFeatureCalculator, ),
            {
                '_PADEL_DESC': desc,
                '_IS_3D': desc.is_3D,
                'FEATURE_SET_NAME': name
            }
        )
        qualifier = '3D ' if desc.is_3D else ''
        features = '\n'.join(
            f'* {escape_markdown(name)}: {escape_markdown(desc)}'
            for name, desc in zip(desc.description.name, desc.description.description)
        )
        docstring = f'''{desc.name} {qualifier}PaDEL descriptor

The following features are calculated:'''
        _add_docstring_and_class(dcls, name, docstring, features)

    for pfp in _fingerprints:
        name = _get_class_name(pfp)
        fpcls = type(
            name,
            (PaDELFPFeatureCalculator, ),
            {
                '_PADEL_DESC': pfp,
                '_IS_3D': pfp.is_3D,
                'FEATURE_SET_NAME': name
            }
        )
        qualifier = '3D ' if pfp.is_3D else ''
        n_bits = pfp.nBits if pfp.nBits else 'variable'
        features = f'''* Number of bits: {n_bits}
* Bit prefix: {pfp.bit_prefix}
'''
        docstring = f'''{qualifier}PaDEL {pfp.short_name}fingerprint

{pfp.name} - {pfp.description.iloc[0]}
'''
        _add_docstring_and_class(fpcls, name, docstring, features)


declare_classes()

back to top

Software Heritage — Copyright (C) 2015–2026, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API