# Path: mordred/Chi.py
# class Chi(ChiBase):
#     r"""chi descriptor.
# 
#     :type type: str
#     :param type: one of chi_types
# 
#     :type prop: str or function
#     :param prop: :ref:`atomic_properties`
# 
#     :type averaged: bool
#     :param averaged: averaged by number of subgraphs
# 
#     :returns: NaN when
# 
#         * any atomic properties <= 0
#         * averaged and :math:`N_{\chi} = 0`
#     """
# 
#     since = "1.0.0"
#     __slots__ = ("_type", "_order", "_prop", "_averaged")
# 
#     chi_types = tuple(t.name for t in ChiType)
# 
#     _deltas = ["d", "dv"]
# 
#     def description(self):
#         return "{}-ordered {}{} weighted by {}".format(
#             self._order,
#             "averaged " if self._averaged else "",
#             self._type.long,
#             self._prop.get_long(),
#         )
# 
#     @classmethod
#     def preset(cls, version):
#         return chain(
#             (cls(ChiType.chain, l, a) for a in cls._deltas for l in range(3, 8)),
#             (cls(ChiType.cluster, l, a) for a in cls._deltas for l in range(3, 7)),
#             (cls(ChiType.path_cluster, l, a) for a in cls._deltas for l in range(4, 7)),
#             (
#                 cls(ChiType.path, l, a, m)
#                 for a in cls._deltas
#                 for m in [False, True]
#                 for l in range(8)
#             ),
#         )
# 
#     def __str__(self):
#         prop = self._prop.as_argument
#         ct = self._type.short
#         averaged = "A" if self._averaged else ""
# 
#         return "{}X{}-{}{}".format(averaged, ct, self._order, prop)
# 
#     def parameters(self):
#         return self._type, self._order, self._prop, self._averaged
# 
#     def __init__(self, type="path", order=0, prop="d", averaged=False):
#         self._type = parse_enum(ChiType, type)
#         self._order = order
#         self._prop = AtomicProperty(self.explicit_hydrogens, prop)
#         self._averaged = averaged
# 
#     def dependencies(self):
#         d = {"P": self._prop}
#         if self._order > 0:
#             d["chi"] = ChiCache(self._order)
# 
#         return d
# 
#     def calculate(self, P, chi=None):
#         if self._order <= 0:
#             chi = ChiBonds([], [{a.GetIdx()} for a in self.mol.GetAtoms()], [], [])
# 
#         x = 0.0
#         node_sets = getattr(chi, self._type.name)
#         for nodes in node_sets:
#             c = 1
#             for node in nodes:
#                 c *= P[node]
# 
#             if c <= 0:
#                 self.fail(ValueError("some properties less then or equal to 0"))
# 
#             x += c ** -0.5
# 
#         if self._averaged:
#             with self.rethrow_zerodiv():
#                 x /= len(node_sets)
# 
#         return x
# 
#     rtype = float
# 
#     _extra_docs = ("chi_types",)
# 
# Path: mordred/ABCIndex.py
# class ABCIndex(ABCIndexBase):
#     r"""atom-bond connectivity index descriptor.
# 
#     References:
#         * :doi:`10.2298/FIL1204733D`
# 
#     """
# 
#     since = "1.0.0"
#     __slots__ = ()
# 
#     def description(self):
#         return "atom-bond connectivity index"
# 
#     @staticmethod
#     def _each_bond(bond):
#         du = bond.GetBeginAtom().GetDegree()
#         dv = bond.GetEndAtom().GetDegree()
# 
#         return np.sqrt((du + dv - 2.0) / (du * dv))
# 
#     def calculate(self):
#         return np.float(np.sum(self._each_bond(bond) for bond in self.mol.GetBonds()))


from rdkit import Chem
from mordred import Chi, ABCIndex


benzene = Chem.MolFromSmiles('c1ccccc1')

# create descriptor instance
abci = ABCIndex.ABCIndex()

# calculate descriptor value
result = abci(benzene)

print(str(abci), result)

# create descriptor instance with parameter

# Path: mordred/Chi.py
# class Chi(ChiBase):
#     r"""chi descriptor.
# 
#     :type type: str
#     :param type: one of chi_types
# 
#     :type prop: str or function
#     :param prop: :ref:`atomic_properties`
# 
#     :type averaged: bool
#     :param averaged: averaged by number of subgraphs
# 
#     :returns: NaN when
# 
#         * any atomic properties <= 0
#         * averaged and :math:`N_{\chi} = 0`
#     """
# 
#     since = "1.0.0"
#     __slots__ = ("_type", "_order", "_prop", "_averaged")
# 
#     chi_types = tuple(t.name for t in ChiType)
# 
#     _deltas = ["d", "dv"]
# 
#     def description(self):
#         return "{}-ordered {}{} weighted by {}".format(
#             self._order,
#             "averaged " if self._averaged else "",
#             self._type.long,
#             self._prop.get_long(),
#         )
# 
#     @classmethod
#     def preset(cls, version):
#         return chain(
#             (cls(ChiType.chain, l, a) for a in cls._deltas for l in range(3, 8)),
#             (cls(ChiType.cluster, l, a) for a in cls._deltas for l in range(3, 7)),
#             (cls(ChiType.path_cluster, l, a) for a in cls._deltas for l in range(4, 7)),
#             (
#                 cls(ChiType.path, l, a, m)
#                 for a in cls._deltas
#                 for m in [False, True]
#                 for l in range(8)
#             ),
#         )
# 
#     def __str__(self):
#         prop = self._prop.as_argument
#         ct = self._type.short
#         averaged = "A" if self._averaged else ""
# 
#         return "{}X{}-{}{}".format(averaged, ct, self._order, prop)
# 
#     def parameters(self):
#         return self._type, self._order, self._prop, self._averaged
# 
#     def __init__(self, type="path", order=0, prop="d", averaged=False):
#         self._type = parse_enum(ChiType, type)
#         self._order = order
#         self._prop = AtomicProperty(self.explicit_hydrogens, prop)
#         self._averaged = averaged
# 
#     def dependencies(self):
#         d = {"P": self._prop}
#         if self._order > 0:
#             d["chi"] = ChiCache(self._order)
# 
#         return d
# 
#     def calculate(self, P, chi=None):
#         if self._order <= 0:
#             chi = ChiBonds([], [{a.GetIdx()} for a in self.mol.GetAtoms()], [], [])
# 
#         x = 0.0
#         node_sets = getattr(chi, self._type.name)
#         for nodes in node_sets:
#             c = 1
#             for node in nodes:
#                 c *= P[node]
# 
#             if c <= 0:
#                 self.fail(ValueError("some properties less then or equal to 0"))
# 
#             x += c ** -0.5
# 
#         if self._averaged:
#             with self.rethrow_zerodiv():
#                 x /= len(node_sets)
# 
#         return x
# 
#     rtype = float
# 
#     _extra_docs = ("chi_types",)
# 
# Path: mordred/ABCIndex.py
# class ABCIndex(ABCIndexBase):
#     r"""atom-bond connectivity index descriptor.
# 
#     References:
#         * :doi:`10.2298/FIL1204733D`
# 
#     """
# 
#     since = "1.0.0"
#     __slots__ = ()
# 
#     def description(self):
#         return "atom-bond connectivity index"
# 
#     @staticmethod
#     def _each_bond(bond):
#         du = bond.GetBeginAtom().GetDegree()
#         dv = bond.GetEndAtom().GetDegree()
# 
#         return np.sqrt((du + dv - 2.0) / (du * dv))
# 
#     def calculate(self):
#         return np.float(np.sum(self._each_bond(bond) for bond in self.mol.GetBonds()))


# Path: examples/010-single_mol-single_desc.py
from rdkit import Chem
from mordred import Chi, ABCIndex



benzene = Chem.MolFromSmiles('c1ccccc1')

# create descriptor instance
abci = ABCIndex.ABCIndex()

# calculate descriptor value
result = abci(benzene)

print(str(abci), result)

# create descriptor instance with parameter

chi_pc4 = Chi.Chi(type='path_cluster', order=4)