Skip to content

Fix divide-by-zero in aromaticity index calculation#26

Open
robertyoung3 wants to merge 2 commits intoEMSL-Computing:masterfrom
robertyoung3:fix/aromaticity-index-divide-by-zero
Open

Fix divide-by-zero in aromaticity index calculation#26
robertyoung3 wants to merge 2 commits intoEMSL-Computing:masterfrom
robertyoung3:fix/aromaticity-index-divide-by-zero

Conversation

@robertyoung3
Copy link

Summary

  • _calc_ai() and _calc_ai_mod() in MolecularFormulaCalc divide ai_n / ai_d without guarding against ai_d == 0
  • This raises ZeroDivisionError for molecular formulas where C - 0.5*O - N - S (or C - O - N - S for modified AI) equals zero
  • Returns 0 when denominator is zero, consistent with the existing clamping to [0, 1]

Before

ai = ai_n / ai_d

After

ai = ai_n / ai_d if ai_d != 0 else 0

Applied to both _calc_ai() (line 563) and _calc_ai_mod() (line 604).

References

Test plan

  • Verified both methods have the same pattern and same fix
  • A denominator of zero means no aromatic carbon skeleton is possible, so AI = 0 is the correct semantic value

@robertyoung3 robertyoung3 force-pushed the fix/aromaticity-index-divide-by-zero branch from ed6e03e to 615108a Compare March 3, 2026 00:54
Copy link
Collaborator

@kheal kheal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find. According to the literature, if either the ai_n <= 0 OR the ai_d <= 0, then ai (or ai_mod) should be 0. Can you adjust to encapsulate these scenarios more generally? That will fix the the divide-by-zero bug as well.

Per Koch and Dittmar (2006), if either the numerator or denominator
is non-positive, the aromaticity index should be 0. This is more
general than only guarding against ai_d == 0 (divide-by-zero) and
correctly handles all cases where AI is physically meaningless.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@robertyoung3
Copy link
Author

Thanks for the guidance! Updated to check both ai_n <= 0 and ai_d <= 0 — if either is non-positive, AI is set to 0. This follows Koch and Dittmar (2006) more faithfully and covers the divide-by-zero case as a subset.

The if ai < 0 clamping is now redundant (when both ai_n and ai_d are positive, AI is always non-negative), so I removed it to keep the logic clean. The if ai > 1 cap is retained since the ratio can still exceed 1.

Applied identically to both _calc_aromaticity_index() and _calc_aromaticity_index_mod().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants