diff --git a/arc/species/conformers.py b/arc/species/conformers.py
index bc077cb801..a3240288f9 100644
--- a/arc/species/conformers.py
+++ b/arc/species/conformers.py
@@ -269,9 +269,12 @@ def generate_conformers(mol_list: Union[List[Molecule], Molecule],
         mol_list=mol_list, label=label, xyzs=xyzs, torsion_num=len(torsions), charge=charge, multiplicity=multiplicity,
         num_confs=num_confs_to_generate, force_field=force_field)
 
+    rings, rings_indices = determine_rings(mol_list)
     lowest_confs = list()
     if len(conformers):
         conformers = determine_dihedrals(conformers, torsions)
+        if len(rings):
+            conformers = determine_puckering(conformers, rings_indices)
 
         new_conformers, symmetries = deduce_new_conformers(
             label, conformers, torsions, tops, mol_list, smeared_scan_res, plot_path=plot_path,
@@ -887,6 +890,49 @@ def determine_dihedrals(conformers, torsions):
     return conformers
 
 
+def determine_rings(mol_list):
+    """
+    Determine the rings in the molecule.
+
+    Args:
+        mol_list (list): Localized structures (Molecule objects) by which all rotors will be determined.
+
+    Returns:
+        Tuple[list, list]:
+            - A list of ring atoms.
+            - A list of ring atom indices.
+    """
+    rings, rings_indexes = list(), list()
+    for mol in mol_list:
+        rings = mol.get_deterministic_sssr()
+        rings_indexes = [[mol.atoms.index(atom) for atom in ring] for ring in rings]
+    return rings, rings_indexes
+
+
+def determine_puckering(conformers, rings_indices):
+    """
+    For each conformer in `conformers` determine the respective puckering angles.
+
+    Args:
+        conformers (list): Entries are conformer dictionaries.
+        rings_indices (list): Entries are lists of ring atom indices.
+        
+    Returns:
+        list: Entries are conformer dictionaries.
+    """
+    for conformer in conformers:
+        if isinstance(conformer['xyz'], str):
+            xyz = converter.str_to_xyz(conformer['xyz'])
+        else:
+            xyz = conformer['xyz']
+        if 'puckering' not in conformer or not conformer['puckering']:
+            conformer['puckering'] = dict()
+            for i, ring in enumerate(rings_indices):
+                theta = vectors.calculate_ring_dihedral_angles(coords=xyz['coords'], ring=ring, index=0)
+                conformer['puckering'][tuple((ring[i%len(ring)], ring[(i + 1)%len(ring)], ring[(i + 2)%len(ring)], ring[(i + 3)%len(ring)]) for i in range(len(ring)))] = theta    
+    return conformers
+
+
 def determine_torsion_sampling_points(label, torsion_angles, smeared_scan_res=None, symmetry=1):
     """
     Determine how many points to consider in each well of a torsion for conformer combinations.
diff --git a/arc/species/vectors.py b/arc/species/vectors.py
index 99fe05e5b7..71ddd07fb1 100644
--- a/arc/species/vectors.py
+++ b/arc/species/vectors.py
@@ -205,7 +205,7 @@ def calculate_dihedral_angle(coords: Union[list, tuple, dict],
     """
     if isinstance(coords, dict) and 'coords' in coords:
         coords = coords['coords']
-    if not isinstance(coords, (list, tuple)):
+    if not isinstance(coords, (list, tuple, np.ndarray)):
         raise TypeError(f'coords must be a list or a tuple, got\n{coords}\nwhich is a {type(coords)}')
     if index not in [0, 1]:
         raise VectorsError(f'index must be either 0 or 1, got {index}')
@@ -232,6 +232,25 @@ def calculate_dihedral_angle(coords: Union[list, tuple, dict],
     return get_dihedral(v1, v2, v3, units=units)
 
 
+def calculate_ring_dihedral_angles(coords: Union[list, tuple, dict], 
+                                   ring: list, 
+                                   index: int = 0
+                                   ) -> list:
+    if isinstance(coords, dict) and 'coords' in coords:
+        coords = coords['coords']
+    if not isinstance(coords, (list, tuple)):
+        raise TypeError(f'coords must be a list or a tuple, got {type(coords)}')
+
+    coords = np.array(coords, dtype=np.float32)
+    ring = [atom - index for atom in ring]  # Adjusting for zero-indexed
+    angles = []
+    for i in range(len(ring)):
+        angle_deg = calculate_dihedral_angle(coords, [ring[i%len(ring)], ring[(i + 1)%len(ring)], ring[(i + 2)%len(ring)], ring[(i + 3)%len(ring)]])
+        angles.append(angle_deg)
+
+    return angles
+
+
 def calculate_param(coords: Union[list, tuple, dict],
                     atoms: list,
                     index: int = 0,