0 | module Chem.QSAR.RotatableBonds
 1 |
 2 | import Data.Graph.Indexed.Ring.Util
 3 | import Data.SortedSet
 4 | import Chem
 5 | import Chem.QSAR.Util
 6 |
 7 | %default total
 8 |
 9 | parameters {0 b,e,c,p,r,h,t,ch,l : Type}
10 |            {auto ce          : Cast e Elem}
11 |            {auto cb          : Cast b BondOrder}
12 |            {k                : Nat}
13 |            (ringBonds        : EdgeSet k)
14 |            (includeTerminals : Bool)
15 |            (excludeAmides    : Bool)
16 |            (g                : IGraph k b (Atom e c p r h t ch l))
17 |
18 |   ||| True if the given edge counts as a rotatable bond.
19 |   |||
20 |   ||| A single bond is rotatable, if
21 |   |||  * it is not connected to a hydrogen atom
22 |   |||  * it is not a ring bond
23 |   |||  * the atoms it connects are not attached to triple bonds
24 |   |||  * it does not connect a terminal non-H atom (unless `includeTerminals`
25 |   |||    is set to `True`)
26 |   |||  * it is an amide bond and `excludeAmides` is set to `True`
27 |   export
28 |   isRotatableBond : Edge k b -> Bool
29 |   isRotatableBond (E x y l) =
30 |        cast l == Single
31 |     && not (isElem g H x || isElem g H y)
32 |     && not (contains (E x y ()) ringBonds)
33 |     && (maxBondOrder g x < Triple && maxBondOrder g y < Triple)
34 |     && (includeTerminals || (heavyDegree g x > 1 && heavyDegree g y > 1))
35 |     && (not $ excludeAmides && isAmideBond g x y)
36 |
37 |   ||| Returns the number of rotatable bonds in a molecule.
38 |   |||
39 |   ||| See also `isRotatableBond` about what counts as a rotatable bond.
40 |   export %inline
41 |   rotatableBondCount : Nat
42 |   rotatableBondCount = count isRotatableBond (edges g)
43 |