Skip to content

Releases: chython/chython

2.24

Choose a tag to compare

@stsouko stsouko released this 23 Aug 22:12

Changes since 2.22. Includes the interim 2.23 and 2.23.1 bumps.

Breaking

functional_fingerprint layout and width changed — stored fingerprints must be recomputed.
Protective groups were absent from the vector entirely: their patterns live in a separate rule set
and no functional pattern covers carbamates, silyl ethers or acetals, so a protected molecule
fingerprinted identically to its free analogue. The layout is now

bits content
0–34 descriptors (rings, degree, aromatic ratio, sp3 fraction, MW, rotatable bonds)
35–137 protective group presence (one bit per pattern in protective_rules)
138–341 functional group presence (one bit per pattern in functional_rules)

Currently 342 bits / 43 bytes, up from a fixed 256 bits / 32 bytes. Offsets and width are now
derived from the rule-set sizes rather than hard-coded, so the vector grows as patterns are added;
protective bits sit ahead of functional ones because functional_rules is the frequently extended
set, so appending there grows the tail without moving a protective bit. The format carries no
version field, so there is no migration path — recompute.

  • New fingerprint_size() -> int returns the current width in bytes.
  • fingerprint_schema() now also contains protective group names. Protective and functional names
    are disjoint, so both share one flat namespace and a bit is looked up by the same name
    protective_groups / functional_groups report.
  • Bits read the cached protective_groups property, so they agree with remove_protection,
    including its overlap filtering of nested sub-patterns.
  • Both rule dicts are lazy proxies and the layout resolves on first use, not at import (forcing them
    at import would close a cycle).

Sticky-fragment bond ownership: right-open ends no longer emit their trailing bond.
The junction bond now belongs to the left partner. A.sticky_right + B.sticky_left and
frag-linker-frag chains concatenate to exactly one bond token per junction, instead of "2 bonds in a
row" (invalid SMILES). Any code that stripped or compensated for the duplicate bond needs updating.

urea / thiourea functional-group patterns broadened from unsubstituted-only (D1 nitrogens)
to any substituted urea, so functional_groups now reports them on N-substituted ureas. Biginelli
moved onto the new nh_urea / nh_thiourea subsets (see below), so its behaviour is unchanged.

Added

Reaction templates — six new named reactions: epoxide_opening, knorr_pyrazolone,
acylhydrazone, sulfonylhydrazone, oxadiazole, hydrazide_formation. knorr_pyrazole extended
to aryl hydrazines; snar accepts tertiary alkoxides. 890 template rules across 77 named
reactions.

New functional groups:

  • aziridine_nh — isomorphism is induced, so the branched secondary_amine pattern can never match
    a 3-ring (its two carbons are bonded to each other). Aziridine gets a one-atom N pattern and is
    wired into every site that accepts a secondary amine: amidation, aminolysis, Buchwald-Hartwig,
    Chan-Lam, carbamoylation, urea formation, sulfonamide formation, reductive amination,
    N-alkylation, SNAr, epoxide opening. Also gets an alkyl_amine role cap.
  • succinimidyl_carbonate, aryl_carbonate, imidazolyl_carbonate — activated-carbonate
    chloroformate surrogates (NHS/DSC, phenyl / p-nitrophenyl / pentafluorophenyl, CDI adduct),
    numbered identically to chloroformate so they drop straight into carbamoylation.
  • terminal_epoxide — pins the attacked carbon to the CH2, giving base-mediated regiochemistry
    (attack at the less hindered carbon) instead of an arbitrary one; the symmetric epoxide pattern
    has its two mappings collapsed by the automorphism filter.
  • sulfonylhydrazide — the reagent that makes the already-supported sulfonylhydrazone, which
    previously had no route in (and so no route to the existing bamford_stevens transformation).
  • aryl_hydrazine_ortho_ch — the free-ortho-CH variant, which only fischer_indole needs;
    aryl_hydrazine itself relaxed to plain Ar-NH-NH2 so hydrazines with both ortho positions blocked
    (or hetaryl ones with no ortho CH at all) still condense.
  • nh_urea, nh_thiourea — acyclic, N-H on both nitrogens, i.e. the condensation-capable subset
    used by Biginelli. Excludes N,N-disubstituted ureas and ureas whose nitrogens already sit in a
    ring, neither of which gives a DHPM.

tries and hydrogens on sticky_fragments() / sticky_linkers(), forwarded to every
sticky_smiles call. The right terminal is serialized by a bounded random traversal (default 10
tries) that can exhaust on branched or symmetric skeletons and silently drop the compound; callers
can now raise the limit.

Fixed

reconstruct_mapping now handles salts. A logged reactant routinely bundles a spectator
counterion with the reactive species (K/Na trifluoroborate, amine.HCl, sodium alkoxide) in one
container. Handed the whole thing, the reactor faithfully carries the spectator into the generated
product, which then can never equal the salt-free target, and a real match is lost. Components are
now offered as extra candidates in addition to the intact container, never instead of it — the
counterion is sometimes retained on both sides (amine.HCl -> amine'.HCl) and that only reconstructs
from the intact form.

Masked atoms no longer drive couplings. A group revealed by an incidental deprotection is barred
from participating in the coupling a sticky fragment represents, in both ways it can participate:
as the attachment site (the fresh [At] cap hangs off it — addition/substitution roles such as a
freed amine as an alkyl_amine handle) and as a leaving group (the transform consumes it while
capping a neighbour — deaminative/deoxy/decarboxy roles such as the same freed amine as an
alkyl_deamino leaving group). Previously only the first case was checked.

Biginelli product template now spells out the surviving ester (ester carbon, its carbonyl O, its
alkoxy O). Pattern atoms left out of a product template are deleted, so the ester was being stripped
from the DHPM; only the two oxygens genuinely lost as water are omitted now.

2.22

Choose a tag to compare

@stsouko stsouko released this 08 Aug 22:09

Stereochemistry is the theme of this release. Every external toolkit bridge is now a direct graph builder instead of a SMILES or SDF round-trip, so atom order and chirality survive the trip; MDL read/write gained coordinate-free atom parity and enhanced stereo groups; and a long-standing class of silent stereo loss on export is closed.

Breaking changes

  • remove_protection() takes names (a list) instead of name (a string), and gains keyword-only start and logging. With logging=True it returns the list of freed atom numbers instead of a bool.
  • StickyFragment.sticky_smiles is replaced by two attributes, sticky_left (-A...B-, the role_left end open first) and sticky_right (the flipped -B...A-). Both are concatenation-ready.
  • to_rdkit() no longer always attaches a 2D conformer — see Fixes. Callers relying on a conformer always being present should pass keep_coordinates=True.
  • The optional RDKit floor moves to >=2025.9, required for the positional bondIds argument of CreateStereoGroup.
  • Minimum Python is 3.10.

New features

  • MoleculeContainer.iupac — cached property generating an IUPAC name from the structure via openclatura (installed with the iupac extra, Python >= 3.11). Returns None when naming fails, raises ImportError with install guidance when the library is absent. This is the inverse of the existing chython.iupac/opsin name-to-structure function.
  • sticky_fragments() and sticky_linkers() accept a masked set of atom numbers barred from becoming an attachment point. Feed it the output of remove_protection(logging=True) to keep a still-protected handle out of the first coupling step. For linkers only the left (step-1) end is filtered; the right (step-2) end is exempt by design, so a Boc-masked amine can sit there.
  • MDL enhanced stereo (AND/OR groups) round-trips through RDKit. AND maps to positive extended_stereo, OR to negative, group ids preserved. to_rdkit() gains the absolute flag of the MDL V3000 writers.
  • MDL atom parity: the V2000 sss column and V3000 atom CFG are now read and written — previously ignored on read and hardcoded to 0 on write. Parity resolves in the same work-list loop as wedge bonds and takes priority over wedges on shared centres.

Toolkit interop

All bridges now build the target structure directly from the graph, so atoms() order is preserved and clean2d can zip against self instead of consulting smiles_atoms_order.

  • to_openbabel — direct build with aromatic, tetrahedral and cis-trans stereo; roughly 3x faster than the former SMILES round-trip on fresh molecules.
  • to_indigo — direct build with aromatic and tetrahedral stereo. Cis-trans and allene omitted because Indigo derives them from 2D coordinates.
  • to_cdk — direct IAtomContainer builder with coordinate-free tetrahedral and cis-trans stereo elements; charge, isotope, implicit H and radical preserved. Validated 300/300 stereo-correct via InChI. About 2.5x slower than the SMILES round-trip because of per-atom JPype crossings, but it removes the need for a separate order lookup.
  • CDPKit conformers — the engine built its molecule through an intermediate SDF in both directions, which silently lost chirality: with no 2D layout the SDF carried wedges on zero coordinates, so both enantiomers produced identical 3D structures. Now built directly with coordinate-free StereoDescriptors and read back via getConformer3DCoordinates. Enantiomer sign matches RDKit 8/8 on a diverse set; cis/trans dihedrals correct.
  • clean2d's smilesdrawer engine hands the layout engine a parse tree built straight from the graph rather than a SMILES string, dropping the fragile string round-trip and positional re-mapping. Layout depends only on element and connectivity, so nodes carry a bare element symbol. Single deterministic, root-invariant pass, no retry loop.
  • Allene stereo is not portable through any of these toolkits; the docstrings now say so.

Fixes

  • to_rdkit() attached a 2D conformer even for molecules that had never been through clean2d(), putting every atom at (0, 0). That is worse than no conformer: MolToCXSmiles() appended a useless coordinate block, and MolToMolBlock() derived wedges and double-bond directions from the degenerate geometry, so C/C=C/CO came back as CC=CCO. The new keep_coordinates argument defaults to exporting a layout only when one actually exists. from_rdkit() likewise no longer fabricates a layout from the XY projection of a 3D conformer.
  • Salts and solvates lost their cis-trans marks on SMILES export: RDKit derives SMILES bond directions from stereo atoms only for single-fragment molecules. SetDoubleBondNeighborDirections is now called explicitly. GetStereo, molblock and InChI were unaffected.
  • The dative-bond direction fix reversed the begin/end atoms of every bond whose first atom was outside _inorganic, a set that omits B and At though both form double bonds, so SetStereoAtoms raised a pre-condition violation on C/C=C/C. The flip is now gated on bond order 8.
  • Enhanced-stereo export needs SetWriteId, otherwise RDKit renumbers groups from one and &3/o2 silently become &1/o1. Only stereogenic tetrahedrons are exported, matching the chirality tags.
  • _conformers is now consistent with the atom set by construction. It was an optional slot mutated in place, so stale geometry outlived structural edits and to_rdkit() on a 3D molecule after remove_protection() raised a bare KeyError (as did MDL write3d and depict3d). The slot is always initialized and flushed on any change to atoms or connectivity; implicify_hydrogens prunes only the removed keys since hiding an H does not move heavy atoms, and saturate()/neutralize() deliberately keep geometry. copy() deep-copies conformers, __exit__ restores them on rollback, and remap() renumbers the keys — copy() previously left the slot unset, which broke the PDB multi-model reader on its second model.
  • V3000 line continuation was detected with endswith('-\n'), which only holds when the caller keeps trailing newlines. mdl_mol/mdl_rxn pass splitlines() output, so continued SGROUP lines were never rejoined and crashed on the key/value split.
  • V3000 atom and enhanced-stereo collection lines (STERAC/STEREL/STEABS) are wrapped to the spec's 80-character limit with - continuation markers. A large AND/OR group previously emitted one long, non-conforming line.
  • V2000 coordinates are validated against the F10.4 column width. %10.4f overflows for |x| >= 1e5, shifting every following fixed-position field so the record silently failed to parse back. It now raises a clear error; coordinates that fit are formatted exactly as before.

Depiction

  • Inner aromatic dashes stay inside their ring. The near-collinear centroid guard was sign-asymmetric — aromatic_space / cr_y < .65 is always true for negative cr_y — so for half of all bond orientations it never fired, and on flattened or overstretched rings the dash shot far past both ring atoms. A skewed centroid could also slide the dash bodily out of the ring; both insets are now clamped to the bond footprint. On 4000 randomly distorted benzenes, 682 emitted an escaping dash before the fix and 0 after.
  • Bond joints at unlabeled carbons are smoothed with round line caps. At labeled atoms the symbol's mask hole hid the joint, but at silent carbons two butt-capped lines met at an angle and left a square notch. Dash patterns are compensated for the cap width so aromatic and dashed bonds keep their gaps.

Reaction templates and roles

  • New functional-group patterns: aryl_thiol, azinone, chloroazine, hydrazide, NO_dialkylhydroxylamine, activated_isocyanide. nhs_ester is generalized to redox_active_ester (NHPI/TCNHPI/NHS).
  • New reactions: thioetherification, decarboxylative_coupling via redox-active (Baran) ester, mitsunobu azinone O-alkylation, van_leusen_pyrrole (activator-agnostic), suzuki with alkenyl halide electrophiles, and weinreb_amidation generalized beyond the methyl case.
  • New transforms: azinone_chlorination and azinone_hydrolysis (POCl3 and H2O), and ester_to_hydrazide. borylation_acid/borylation_ester extend to alkenyl (vinyl) substrates, giving the boronic acid or Bpin.
  • Pyridone (azinone) lactam oxygen is treated as a phenol-like O-nucleophile via its hydroxyazine tautomer, adding azinone variants to ullmann_phenol, chan_lam, snar, williamson, sulfonylation, acylation and carbamate. It also joins the aryl_hydroxyl role, so sticky_fragments/sticky_linkers expose the pyridone oxygen as a coupling handle.
  • Pseudohalide coverage is broadened via shared leaving-group tuples (ARYL_LG/ALKYL_LG). SN2 reactions accept sulfonates (OTf/OMs/OTs) while C–X-bond reactions (Grignard, XEC) stay halide-only. New carbamoyl_halide, aryl_thiol and amidine_nitrogen roles cover coupling handles that reactions used but roles did not expose.
  • New roles: alkyl_hydroxyl, alkynyl_terminal, amide_nitrogen, azole_nitrogen, carbonyl_electrophile, sulfonyl. Role transformation enables ignore_pyrrole_hydrogen.

Build and docs

  • The smilesdrawer bundle moves from webpack + babel to an esbuild-only IIFE build, with smiles-drawer pinned at 2.4.1 (was 2.0.1). npm audit reports 0 vulnerabilities across 5 packages.
  • README.rst is converted to README.md with logo, badges, a regrouped feature list and an updated contributor list. Docs cover the changed remove_protection signature and the sticky fragment/linker API.

2.21

Choose a tag to compare

@stsouko stsouko released this 27 Jul 19:21
fa3d174

What's Changed

  • Sticky fragments by @stsouko in #66
  • New reaction templates
  • GIL free SSSR with timeout
  • ARM build fix

Full Changelog: 2.20...2.21

2.20

Choose a tag to compare

@stsouko stsouko released this 11 Jul 20:13
  • INCHI lib sync to upstream
  • reconstruct mapping refactored
  • reaction templates extended
  • linux arm builds

Full Changelog: 2.19...2.20

2.19

Choose a tag to compare

@stsouko stsouko released this 09 Jun 12:48

Major update

Reactor and predefined reactions extended.
Standardization of tautomers improved and aligned with chemical sense.

Full Changelog: 2.18...2.19

2.18

Choose a tag to compare

@stsouko stsouko released this 10 May 14:36
  • extended extended stereo support
  • reorganized PG and reactors
  • dropped some dependencies
  • fixed atom mapped
  • new api for reaction enumerations

Full Changelog: 2.17...2.18

2.17

Choose a tag to compare

@stsouko stsouko released this 28 Apr 21:20

Extended stereo handling by reactors
Docs regenerated

Full Changelog: 2.16...2.17

2.16

Choose a tag to compare

@stsouko stsouko released this 07 Mar 15:52

What's Changed

  • metal split and remover now conditional
  • bond length rescaler exposed as a method
  • UPD: workflow for macos arm and x86 by @aigulkhkmv in #64

New Contributors

Full Changelog: 2.15...2.16

2.15

Choose a tag to compare

@stsouko stsouko released this 30 Dec 17:26
  • Extended stereo depiction
  • Fixed wedge bonds depiction
  • New PG and Rxn templates
  • Integrated OPSIN, CDK, Indigo, OBabel
  • New clean2d engines

Full Changelog: 2.13...2.15

2.13

Choose a tag to compare

@stsouko stsouko released this 27 Nov 18:17

Minor release.
Improved tautomers standardization