Coverage for chempropstereo/stereochemistry/base.py: 100%

27 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-03-22 21:04 +0000

1"""Base classes for spatial arrangements and ranks in stereogenicgroups. 

2 

3.. module:: stereochemistry.base 

4.. moduleauthor:: Charlles Abreu <craabreu@mit.edu> 

5""" 

6 

7import enum 

8import typing as t 

9 

10from rdkit import Chem 

11 

12 

13class SpatialArrangement(enum.IntEnum): 

14 """Base class for enumerating spatial arrangements in stereogenic groups.""" 

15 

16 @classmethod 

17 def get_from(cls, entity: Chem.Atom | Chem.Bond) -> t.Self: 

18 """Classify the spatial arrangement of a stereogenic group. 

19 

20 The spatial arrangement is determined based on an atom's or bond's canonical 

21 stereo tag. 

22 

23 Parameters 

24 ---------- 

25 entity 

26 The atom or bond to get the spatial arrangement from. 

27 

28 Returns 

29 ------- 

30 SpatialArrangement 

31 The spatial arrangement obtained from the atom or bond. 

32 

33 """ 

34 if entity.HasProp(cls.tag): 

35 return cls(int(entity.GetProp(cls.tag)[0])) 

36 return cls.NONE 

37 

38 

39class Rank(enum.IntEnum): 

40 """Base class for ranks in stereogenic groups.""" 

41 

42 @classmethod 

43 def get_neighbors(cls, atom: Chem.Atom) -> tuple[Chem.Atom, ...]: 

44 """Get the neighbors of an atom in a specific order. 

45 

46 The order is determined based on a canonical stereogroup tag. 

47 

48 Parameters 

49 ---------- 

50 atom 

51 The atom whose neighbors are to be retrieved. 

52 

53 Returns 

54 ------- 

55 tuple[Chem.Atom, ...] 

56 A tuple of neighboring atoms in the specified order. 

57 

58 """ 

59 neighbors = atom.GetNeighbors() 

60 order = map(int, atom.GetProp(cls.tag)[1:]) 

61 return tuple(neighbors[i] for i in order) 

62 

63 @classmethod 

64 def from_bond(cls, bond: Chem.Bond, end_is_center: bool = False) -> t.Self: 

65 """Get the rank of a bond in a stereogenic group. 

66 

67 The rank is determined from its center atom's canonical stereo tag. 

68 

69 Parameters 

70 ---------- 

71 bond 

72 The bond to get the rank from. 

73 end_is_center 

74 Whether to treat the end atom as the center of the stereogenic group. 

75 If False (the default), the begin atom is treated as the center. 

76 

77 Returns 

78 ------- 

79 Rank 

80 The rank of the bond in the stereogenic group. 

81 

82 """ 

83 if end_is_center: 

84 center_atom, edge_index = bond.GetEndAtom(), bond.GetBeginAtomIdx() 

85 else: 

86 center_atom, edge_index = bond.GetBeginAtom(), bond.GetEndAtomIdx() 

87 if not center_atom.HasProp(cls.tag): 

88 return cls.NONE 

89 neighbors = cls.get_neighbors(center_atom) 

90 for rank, neighbor in enumerate(neighbors, start=1): 

91 if neighbor.GetIdx() == edge_index: 

92 return cls(rank) 

93 return cls.NONE