orthonym.assembly.substituent_naming#
Note
Internal API. Names and behaviour may change between releases.
Centralized substituent fragment naming module.
Provides name_substituent_fragment – the single entry point for naming any substituent (linear, branched, functionalized, or ring-containing) from its atom indices within a parent molecule.
- Architecture:
Fast path: linear terminal alkyl substituents use get_alkyl_name directly.
Retained PREFERRED names: phenyl, benzyl, retained cycloalkyls, tert-butyl (F-T9/DD6: isopropyl/sec-butyl/isobutyl/neopentyl are NOT retained — their located PINs come from _located_acyclic_alkyl_name in step 3/2d).
Located / recursive path: a branched or internally-attached acyclic alkyl is named by its own principal chain numbered from the free valence (_located_acyclic_alkyl_name: propan-2-yl, butan-2-yl, 2-methylpropyl); other fragments extract SMILES and convert via parent_to_prefix.
The function returns RAW prefix names WITHOUT enclosing marks (parentheses/brackets). The caller (format_substituent_prefix in naming_utils.py) handles wrapping based on is_complex_substituent and multiplier logic.
References
IUPAC 2013 (substituent prefix naming) IUPAC 2013 (compound substituent enclosing marks)
- orthonym.assembly.substituent_naming.polyfunctional_substituent_located(mol, sub_atoms, name, pos)#
The
locatedtriple for_add_substituent_stereofrom a_name_polyfunctional_acyclic_substituentnumbering, or None.(the Blue Book): “In preferred IUPAC names,
stereodescriptors, preceded by a locant, must be cited”; ‘[(1R)-1-chloropropyl]benzene (PIN)’ (:44668). The producer numbers its chain from the free valence and
posis that numbering, so the centre is cited at its own locant (‘(1R)-1-carboxyethyl’), not bare (‘(R)-1-carboxyethyl’). Admitted only when citing theposcentres expresses EVERY defined stereo element of the fragment (located_map_completes_substituent_stereo); the precondition holds by construction –posholds backbone carbons only, while any centre expressed insidenamesits in a nested composed branch.
- orthonym.assembly.substituent_naming.acyl_carbons_to_amido_prefix(acyl_carbons)#
method (1) prefix for a linear saturated acyl R-CO-.
acyl_carbonscounts the acyl carbons INCLUDING the carbonyl carbon: 1 -> ‘formamido’, 2 -> ‘acetamido’, n>=3 -> ‘{stem}anamido’ (propanamido, butanamido,…). Returns None when no chain stem exists.
- orthonym.assembly.substituent_naming.acid_name_to_amido_prefix(acid_name)#
method (1): acid name -> amido prefix via the amide name.
‘benzoic acid’ -> ‘benzamido’, ‘pentanoic acid’ -> ‘pentanamido’, ‘naphthalene-1-carboxylic acid’ -> ‘naphthalene-1-carboxamido’ (the amide names benzamide/pentanamide/naphthalene-1-carboxamide have their final ‘e’ changed to ‘o’). Returns None when no safe transform exists — poly-acids (’…dioic acid’, ‘…dicarboxylic acid’) and functional-replacement acids fail closed because a single amido prefix cannot describe them.
- orthonym.assembly.substituent_naming.record_prefix_from_acid_status(acid_name, prefix)#
Carry the PIN status of
acid_nameto the prefix built from it by a string conversion (’…oic acid’ -> ‘…amido’ / ‘…oyl’): a recorded non-PIN fragment in the acid name (record_derived_non_pin_fragment), or an acid parent spelled with the systematic alternative of a retained PIN acid (’…-2-phenylethanoic acid’ for a substituted acetic acid,:29725), labels the prefix non-PIN, so the name that cites it cannot ship as pin_verified. Label only.
- orthonym.assembly.substituent_naming.fragment_acid_name_verified(acid_name, acid_smiles)#
True iff OPSIN re-perceives
acid_nameasacid_smileson the FULL standard InChIKey (constitution, stereo, charge). A prefix built from an acid name by a string conversion (’…oic acid’ -> ‘…amido’ / ‘…oyl’) is only as right as that acid name, andname_fragment_recursivelycan return an unverified one at the best-effort tier (measured: ‘((4-chlorophenoxy)acetylamino) acetic acid’ for OC(=O)CN(CCC(C)C)C(=O)COc1ccc(Cl)cc1 – the 3-methylbutyl dropped). Fails closed: False when OPSIN rejects the name or cannot be consulted.
- orthonym.assembly.substituent_naming.acid_name_to_acyl_prefix(acid_name)#
Monovalent acyl prefix R-CO- from the name of the acid R-COOH.
(the Blue Book): ‘acetyl’, ‘formyl’, ‘benzoyl’ are the
preferred prefixes (:30442-:30446); (:30608) “changing the ending ‘oic acid’ to ‘oyl’”; (:30624) “changing the ‘carboxylic acid’ suffix to the suffix ‘carbonyl’”. A substituted acetic acid keeps its stem (‘(chloroacetyl)oxyl (PIN)’,:40694). The ‘1-oxopropyl’ form is general nomenclature only,:30430).
Fails closed (None) with the same guards as:func:acid_name_to_amido_prefix: a poly-acid (’…dioic acid’, ‘…dicarboxylic acid’, ‘diacetic acid’) would need a divalent or multiplied prefix, and functional-replacement / peroxy acids have their own acyl endings.
- orthonym.assembly.substituent_naming.acyl_prefix_from_branch(mol, carbonyl_c, attach_idx, acyl_atoms)#
acyl prefix for the acyl group R-CO- whose carbonyl carbon
carbonyl_cis bonded toattach_idx(an atom of the parent).acyl_atomsis the WHOLE acyl group (carbonyl C, its =O, and R), so nothing can be silently dropped: the group must be closed (no acyl atom bonded outside it except the carbonyl C toattach_idx) and carry exactly one C=O on the carbonyl carbon. The acyl is named as its acid (-OH added at the carbonyl carbon; stereo kept) – with a systematic retry for a retained amino-acid name – verified by OPSIN (fragment_acid_name_verified()), and converted byacid_name_to_acyl_prefix(). Returns the BARE prefix (‘acetyl’, ‘(2S)-2-methyl-3-sulfanylpropanoyl’); callers add enclosing marks. None = fail closed.
- orthonym.assembly.substituent_naming.oxamoyl_branch_name(mol, n_idx, acyl_c_idx)#
(BB 33071/55479): recognize the EXACT H2N-CO-CO- branch hanging from an imine N -> ‘oxamoyl’ (the preferred prefix for the H2N-CO-CO-N= group’s acyl part). Returns None for anything else (fail-closed): the first carbon must be a carbonyl (=O, no other substituents besides the =N-bearing N and the second carbonyl C); the second carbon must be a carbamoyl (=O + terminal NH2).
- orthonym.assembly.substituent_naming.linear_acyl_amido_prefix(mol, carbonyl_c, n_idx, sub_atoms)#
Amido prefix method (1)) for an N-acyl substituent.
Emits ‘formamido’ (HCO-NH-), ‘acetamido’ (CH3-CO-NH-) or ‘{stem}anamido’ (>=3 C) ONLY when the substituent is exactly -NH-CO-R with R an unbranched, saturated, acyclic, all-carbon chain and every substituent atom accounted for (the N, the carbonyl O and the chain carbons — nothing dropped). Returns None otherwise, so the strict builder can never mint a name for a branch it cannot fully describe; callers keep their legacy fallback for those.
- Parameters:
mol – RDKit Mol.
carbonyl_c (int) – atom index of the acyl C=O carbon.
n_idx (int) – atom index of the amide nitrogen (the attachment atom).
sub_atoms – all atom indices of the substituent (including n_idx).
- orthonym.assembly.substituent_naming.n_substituted_acyl_amido_prefix(mol, n_idx, sub_atoms, parent_atoms)#
method (1): an N-SUBSTITUTED acylamino branch
-N(R')-C(=O)-Ris the{N-R'}{acyl}amidoPREFIX – N-methylacetamido, N-methylformamido, N-ethylpropanamido (the Blue Book; verbatim2-(N-methylpropanamido)benzene-1-sulfonic acid (PIN):33040).The unsubstituted sibling
linear_acyl_amido_prefixfails closed on a substituted N (itssub_set == branch | {n_idx}check), and the legacy count fallback in_name_amino_branchrefuses a non-mono-substituted N (37cd122d F1), so before this builder the whole-N(R')C(=O)Rfragment dropped to the ugly general replacement name (1,2-dimethyl-3-oxa-1- azaprop-2-en-1-yl) or abstained.PIN ONLY as a PREFIX: this fires in
_name_amino_branch(a substituent namer), reached only when parent selection already made the amide a prefix (a senior characteristic group is elsewhere). When the amide is the PRINCIPAL group it is the SUFFIX – the Blue Book marks4-(N-methylacetamido) quinolineexplicitly NOT PIN, and Orthonym already names that moleculeN-methyl-N-(quinolin-2-yl)acetamidevia the suffix path, which this builder never sees.- Strict / fail-closed. Fires ONLY when, with FULL atom coverage:
N is uncharged/unradical/unlabelled, NOT a ring member, all single bonds, and has EXACTLY one bond into the parent (a bare tertiary amide N);
N carries EXACTLY two non-parent heavy branches – the acyl C (a clean C=O) and one other substituent R’;
the acyl side names via
linear_acyl_amido_prefix(an unbranched saturated acyclic all-carbon acyl -> formamido/acetamido/{stem}anamido);R’ names via the recursive substituent namer;
the fragment is EXACTLY {N} + acyl-subtree + R’-subtree (nothing dropped).
- Returns the BARE prefix core
'N-{R'}{amido}'(the caller applies the enclosing marks –
needs_brackets('N-methylacetamido')is
True, so it renders
(N-methylacetamido)); None otherwise.
- orthonym.assembly.substituent_naming.sulfonamido_prefix_from_n_branch(mol, n_idx, sub_atoms, parent_atoms)#
(the Blue Book): an N-attached
-NH-SO2-Rbranch is the{R}sulfonamidoPREFIX (methanesulfonamido / ethanesulfonamido / benzenesulfonamido / cyclohexanesulfonamido) — NOT anaminosplit of the N, and NOT the cascade’scarbamoylmisroot (which swaps S->C and DROPS S, the two =O and R: a different molecule).The stem is built by the SAME acid-stem sulfonyl primitive the sulfone-prefix path uses (
_acid_stem_oxide_prefix(mol, r_carbon, s_idx, 'sulfonyl')-> ‘methanesulfonyl’ / ‘benzenesulfonyl’ / ‘cyclohexanesulfonyl’), with the suffix rewrite sulfonyl -> sulfonamido. That primitive returns None (so this fails closed) for a substituted-arene / CF3 / branched-hetero R -> those keep abstaining rather than shipping a wrong or atom-dropped name.- Strict / fail-closed. Fires ONLY when, with FULL atom coverage:
N carries exactly ONE non-parent heavy neighbour, the sulfonyl S (a bare
-NH-, never N,N-disubstituted); N-S is a single bond,S is a clean sulfonyl: exactly two terminal
=O(both in the fragment) and exactly one further heavy neighbour R, a carbon,the fragment is EXACTLY {N, S, the two =O} plus the R subtree — nothing dropped.
Returns the BARE prefix core (e.g. ‘methanesulfonamido’), matching every sibling return in
_name_amino_branch; None otherwise.
- orthonym.assembly.substituent_naming.acyl_amido_prefix_from_branch(mol, n_idx, carbonyl_c, sub_atoms, verify_acid=False)#
method (1) amido prefix for a full N-attached acyl branch.
sub_atomsis the ENTIRE substituent (the amide N plus the whole acyl fragment). Fast path:linear_acyl_amido_prefix(). General path (ring / substituted acyls): take ALL branch atoms except the N as the acyl fragment — nothing can be silently dropped — convert it to the corresponding acid by adding an -OH at the carbonyl carbon, name that acid recursively, then apply:func:acid_name_to_amido_prefix (‘benzoic acid’ -> ‘benzamido’, ‘4-methylbenzoic acid’ -> ‘4-methylbenzamido’). Returns the BARE prefix (callers add enclosing marks for locant-bearing forms) or None (fail closed).verify_acid: accept the acid name only when OPSIN re-perceives it as the acid fragment on the full InChIKey (fragment_acid_name_verified()), and carry its PIN status to the prefix (record_prefix_from_acid_status()), so a name citing an amido prefix built from a non-PIN acid spelling is not labelled pin_verified. Off by default so existing callers keep their behaviour.
- orthonym.assembly.substituent_naming.imidamide_name_to_imidamido_prefix(name)#
Wave2 method 1): turn an amidine parent name (imidamide / carboximidamide) into the non-principal prefix by changing the final ‘e’ -> ‘o’: ‘ethanimidamide’ -> ‘ethanimidamido’, ‘benzenecarboximidamide’ -> ‘benzenecarboximidamido’. Fail-closed (None) for di/poly-imidamide names (one imidamido cannot describe a poly-amidine) or names carrying N-locants the branch cannot describe.
- orthonym.assembly.substituent_naming.imidoyl_amido_prefix_from_branch(mol, n_idx, imino_c, sub_atoms)#
Wave2: imidamido prefix for a full N-attached amidine branch
-N(H)-C(=NH)-R(the amidine’s AMINO nitrogen is the ring/chain attachment). Mirrors:func:acyl_amido_prefix_from_branch but keyed on the imino C=N instead of a carbonyl C=O. Reconstructs the imidamide parent R-C(=NH)-NH2, names it recursively, then appliesimidamide_name_to_imidamido_prefix(). Returns the BARE prefix or None.Guards (fail-closed): the imino carbon must have exactly one =N (double) whose N bears only H/C (reject amidrazone -C(=N-NH2)-); exactly one single-bonded N == n_idx (reject guanidine’s second amino N); the attachment N connects to the branch ONLY through this carbon; full-branch coverage (no dropped atoms).
- orthonym.assembly.substituent_naming.hydrazonamide_name_to_hydrazonamido_prefix(name)#
: turn an amidrazone parent name (hydrazonamide) into the non-principal prefix by changing the final ‘e’ -> ‘o’: ‘ethanehydrazonamide’ -> ‘ethanehydrazonamido’. Fail-closed (None) for di/poly names or names carrying N-locants the branch cannot describe.
- orthonym.assembly.substituent_naming.hydrazonoyl_amido_prefix_from_branch(mol, n_idx, imino_c, sub_atoms)#
: hydrazonamido prefix for a full N-attached amidrazone branch
-N(H)-C(=N-NH2)-R(the amidrazone AMINO nitrogen is the ring/chain attachment). Sibling of:func:imidoyl_amido_prefix_from_branch, but keyed on the hydrazonoC=N-NH2— the terminalNH2on the imino N is the discriminant vs a plain amidine (which that sibling rejects by design). Reconstructs the amidrazone parent R-C(=N-NH2)-NH2, names it recursively (-> ‘ethanehydrazonamide’), then applies the e->o transform. Returns the BARE prefix or None.Guards (fail-closed): the imino carbon has exactly one =N (double) whose N bears exactly one terminal degree-1 NH2 (neutral); exactly one single-bonded N == n_idx (rejects hydrazidine/guanidine); the attachment N connects to the branch ONLY through this carbon; zero formal charges; full-branch coverage.
- orthonym.assembly.substituent_naming.sulfino_hydrazonoyl_amido_prefix_from_branch(mol, n_idx, s_idx, sub_atoms)#
/ (plan P1AM Task 8): N-attached R-S(=N-NH2)(-NH-)[=O]? branch -> ‘{R-stem}sulfinohydrazonamido’ (no =O) or ‘{R-stem}sulfonohydrazonamido’ (one =O). Fail-closed None on any deviation (charges, extra substitution, unnameable R).
- orthonym.assembly.substituent_naming.ATTACH_LOCANT_UNKNOWN = ATTACH_LOCANT_UNKNOWN#
Explicit “this caller cannot prove where the free valence sits” value for
parent_to_prefix. It is a distinct object rather thanNoneso that a caller which simply has no locant is never confused with one that computed0/Noneby accident.
- orthonym.assembly.substituent_naming.parent_to_prefix(parent_name, chain_length, *, attach_locant)#
Convert a parent compound name to substituent prefix form.
Per IUPAC (the Blue Book), the parent compound name is transformed into a substituent prefix by: 1. Removing the suffix (e.g., -oic acid, -ol, -one) 2. Converting the suffix to its prefix form (e.g., -ol -> hydroxy) 3. Adding the prefix at the correct locant 4. Appending -yl at the free-valence position
⚠ This converter may only emit locants it can justify. (residue Task A.)
It is handed a name string and a carbon count, and nothing else. The string was produced by naming the fragment as a free molecule after capping its free valence with H, so every locant inside it belongs to the CAPPED molecule’s numbering – which was chosen to favour that molecule’s own principal characteristic group. criterion (h) / **** require the opposite for a substituent group: “The principal substituent chain has the lowest locants for free valences of any kind.”
The two numberings genuinely disagree. Measured witness (R8.2), fragment
-C(CH3)(C2H5)-(CH2)8-CH(NH2)-CH(CH3)2:capped + named as a molecule: 2,12-dimethyltetradecan-3-amine string-surgered to a prefix: 3-amino-2,12-dimethyltetradecyl numbered from the free valence: 12-amino-3,13-dimethyltetradecan-3-yl
The chain is numbered from opposite ends, so the amino locant and both methyl locants differ. Splicing a free-valence locant onto the borrowed stem therefore cannot repair these branches – it would produce
3-amino-2,12-dimethyltetradecan-3-yl, one name in two numberings. The numbering has to be recomputed from the structure, which only a caller holding the molecule can do (see_located_acyclic_alkyl_name).The count-derived branches fail the same way for a second reason. A whole fragment carbon COUNT is not a proof of the fragment’s shape: for the branched acyl
-C(=O)CH(CH3)2the count is 4 while the principal chain is 3, sof"{chain_length}-oxo"spliced locant 4 onto a three-carbonpropylstem (4-oxo-2-methylpropyl).So both families now DECLINE (return
None) rather than fabricate. A one-position stem is the exception that needs no proof: **** (the Blue Book) “All locants are omitted for parent compounds when all substitutable hydrogen atoms have the same locant” –carbamoylmethyl, never1-carbamoylmethyl.- Parameters:
parent_name (str) – Parent compound IUPAC name (e.g., “propan-2-ol”).
chain_length (int) – Number of carbons in the substituent chain.
attach_locant – Locant of the free-valence atom, or
ATTACH_LOCANT_UNKNOWNwhen the caller cannot prove one. Required – “make a prefix unrenderable without its locant” (eval/LOG.md:345). It used to default to1and was read by nothing, so all six call sites silently omitted it.
- Returns:
Prefix-form name (e.g., “hydroxymethyl”),
""/Nonewhen this converter cannot express the fragment. Returns the raw name WITHOUT enclosing marks.- Return type:
str
- orthonym.assembly.substituent_naming.located_map_completes_substituent_stereo(mol, sub_atoms, name, pos)#
Would citing descriptors for exactly the centres
poscovers makenameexpress EVERY defined stereo element ofsub_atoms?The admission test for a producer-supplied
locatedmap (see_add_substituent_stereo’slocatedargument). A producer that owns a CHAIN numbering can only cite its own chain’s centres; a ring-yl or heteroatom-branch centre it cannot reach must ALREADY be spelled insidename. When that is not the case, citing the reachable subset would ship a PARTIALLY stereo-specified prefix – a name that claims one configuration and leaves the rest silent. Under (“missing beats wrong”) and the same all-or-nothing principle asgeneral_engine_stereo_complete, that must fail CLOSED: the pre-existing descriptor-less name is emitted instead, and no partial configuration is ever asserted.PRECONDITION (caller’s responsibility – the count identity cannot see a violation): the centres reachable through
posmust be DISJOINT from the centres already expressed insidename. Every current caller (_compound_ring_on_chain_substituentvia Tier 1.95) satisfies this by construction –posholds only carrier-CHAIN carbons whilenameexpresses only the nested RING-yl centres, two disjoint sets. A future caller passing an OVERLAPPING map would get a false ADMIT (one centre double-cited, another left silent), so it must re-establish the disjointness first.Counts DEFINED elements only:
_CIPCodeon an atom, or on a bond with both ends inside the fragment. NOTE this atoms-AND-bonds population is WIDER than the atoms-onlystereo_atomsthat_add_substituent_stereocites over; a defined stereo BOND therefore pushes the sum away from equality and DECLINES (safe direction – carriers are all-single by the producer’s own guard, so no such bond reaches here today). Carbohydratealpha-D-notation is NOT counted as expressed bycount_expressed_stereo_descriptors, so a glycosyl-bearing fragment under-counts and therefore declines – safe again.
- orthonym.assembly.substituent_naming.carbocyclic_ring_yl_attachment_descriptor(mol, frag_atoms, attach_idx)#
'(1R)'(or'(1S)','(1r)',…) for a substituent group whose free-valence atomattach_idxlies in a carbocyclic monocycle and is the group’s ONLY stereogenic unit; elseNone.Derived from structure, not from the group’s name: in a carbocyclic monocycle no heteroatom or indicated hydrogen precedes the free valence in the order, so criterion (c) gives the free valence locant 1 (the Blue Book “(c) principal characteristic groups and free valences (suffixes)”,:3268 ‘cyclohex-3-en-1-yl (preferred prefix)’). (:44643): stereodescriptors relating to a substituent group “are cited at the front of the corresponding prefix. They are preceded by a numerical or letter locant to describe the position of the stereogenic unit when such locants are present” – ‘[(1R)-1-chloropropyl]benzene (PIN)’. So ‘(1R)-cyclohex-3-en-1-yl’, never the locant-free ‘(R)-cyclohex-3-en-1-yl’.
Guarded to the case where the numbering is certain: the ring of
attach_idxis a single, unfused, all-carbon, non-aromatic ring wholly inside the group; the group holds no other ring atom (a second ring could make the prefix a ring assembly with its own numbering); the only CIP-labelled atom of the group isattach_idxand no bond of the group carries a stereodescriptor.
- orthonym.assembly.substituent_naming.fragment_is_linear_terminal_alkyl(mol, sub_atoms, attach_idx)#
Is
get_alkyl_name(carbon_count)an HONEST name for this fragment?get_alkyl_name(n)can only ever spell an unbranched saturated acyclic chain attached at a terminus (‘propyl’). The two carbon-count fallbacks below used to call it for ANY fragment whose carbon count was non-zero, so a fragment they could not name recursively was renamed by counting its carbons and DISCARDING everything else:CCS[Zn]SCCcame out'ethylethane'andCCO[Zn]OCCcame out'oxylethane'. A name must never claim atoms it dropped, so the fallback is now gated on the fragment actually being the one shape the function can spell.Requires: every atom carbon, none in a ring, every internal bond single, the induced subgraph a simple path, and
attach_idxone of its two ends.
- orthonym.assembly.substituent_naming.name_substituent_fragment(mol, sub_atoms, attach_idx, parent_chain)#
_name_substituent_fragment_uncached(), memoised for the top-level naming call (assembly.memoscope;ORTHONYM_MEMO=verifyrecomputes and compares,offdisables it), None included.The recursive substituent naming asks for the same fragment of the same molecule object again and again: the chain tie-break names every substituent of each tied chain, and the located-FG namers, the compound-substituent namer and the alkoxy prefixes then name the same branches again for each enclosing candidate. Measured on the ChEBI lysine-rich peptide (136 heavy atoms, fresh process): 26,366 calls, 16,898 of them repeats of an earlier call with the same molecule, fragment, attachment and parent, every one returning the earlier value; the outermost repeats took about 26 of 84 s.
Only a call whose side effects a hit can repeat is stored: it charged no unit of the perf, analysis or work budget, the only provenance variable it wrote is the name-scoped non-PIN record, and it read no provenance (
metrics.provenance.PROVENANCE_READ). A hit makes the samerecord_non_pin_fragmentcalls the stored call made (logged, in order, also those whose fragment was already recorded) and returns the stored value. The repeat of such a call returns the same value: its nested namings are hits in caches whose entries never change once written (the fragment cache is consulted before the cycle and depth guards, and a miss there charges a work unit), so it takes the same path. It makes the same record calls or a subset (a nested memo hit skips the records its computation made); either way they only re-add fragments the stored call already added, because within one naming the record only grows (the one exception, the NP-parent probe’srestore_provenance, can at most leave a hit’s name labelled non-PIN where the repeat would not). Any other call is recomputed on every ask, as before. The key is_nsf_memo_key(); an RWMol (mutable) is never memoised.
- orthonym.assembly.substituent_naming.needs_recursive_naming(mol, sub_atoms)#
Check whether a substituent requires recursive naming.
Returns True if the substituent is branched or contains heteroatoms (i.e., not a simple linear alkyl chain).
- Parameters:
mol – RDKit Mol object.
sub_atoms (List[int]) – Atom indices of the substituent.
- Returns:
True if recursive naming may be needed, False for simple linear alkyls.
- Return type:
bool
- orthonym.assembly.substituent_naming.cation_to_prefix(mol, cation_idx, parent_attach_idx, as_free_ion=False)#
Build the cation-as-substituent prefix for a zwitterion.
The cationic atom (
cation_idx, e.g. a quaternary ammonium N) is the attachment atom of the substituent prefix;parent_attach_idxis its neighbour that lies on the path into the anionic parent (the bond that is “consumed” by the attachment). Every OTHER neighbour branch of the cation atom becomes an N-substituent prefix, named by the existing structured substituent machinery (name_substituent_fragment), then composed as:{alphabetized, multiplied N-substituent prefixes}azaniumyl
azane(NH3) is the parent hydride of a nitrogen cation;azanium= NH4+;azaniumyl= the N-attached cationic substituent , OPSIN-parseable equivalent of the -aminiumyl PIN — see module note above). Structured, NOT a hardcoded f-string.- Parameters:
mol – RDKit Mol of the whole zwitterion.
cation_idx (int) – Atom index of the (non-internal) cationic centre.
parent_attach_idx (int) – Neighbour atom index on the path to the anion.
as_free_ion (bool) – when True, build the standalone onium-cation UNIT name (stem +
ium, e.g.trimethylazanium) instead of the-iumylsubstituent-PREFIX form. Used by the /.2 multiplicative bis(…)/tris(…) polycation assembly (a phase, e.g.hexane-1,6-diylbis(trimethylazanium)), where the repeated cationic UNIT is cited as a complete parent-cation name, not a-ylsubstituent (cf. BB PIN example(1,4-phenylene)bis(phosphanium)). The N-substituent composition (alphabetized/multiplied) is identical either way; only the trailing suffix differs.
- Returns:
The cation prefix WITHOUT enclosing marks (e.g.
trimethylazaniumyl, ortrimethylazaniumwhenas_free_ion), or ‘’ for an out-of-scope cation (ylide / non-N onium / amine-oxide / 1,n-dipolar —deferred, honest-fail).
- Return type:
str
- orthonym.assembly.substituent_naming.record_amine_cation_prefix(fragment)#
Label a name that cites a CARBON-substituted N+ as ‘…azaniumyl’ (or a ‘…azanium’ unit) –
fragment– as a general-tier name, never a PIN. Label only: the name is unchanged, and only a shipped name that CONTAINS the fragment is demoted (record_non_pin_fragment), so a speculative or discarded call cannot demote a name built another way.A carbon group on the N+ makes the cation an AMINE cation, whose PIN prefix is built on the ‘-aminium’ suffix: method (1) “all prefix names are formed by adding the suffixes ‘yl’, ‘ylidene’, etc. to the cation name” (the Blue Book) and “Method (1) leads to preferred IUPAC names” (:42299), with the cation name from (:41431, ‘N,*N*,*N*-trimethylmethanaminium (PIN)’:41438). Hence ‘(N,*N*-dimethylmethanaminiumyl)acetate (PIN)’:42473), ‘2-(N,*N*-dimethylmethanaminiumyl)propan-2-ide (PIN)’ :42517), and for a polycation the substitutive ‘-bis(aminium)’ :42154,:42366). The round-trip parser reads none of the ‘-aminiumyl’ forms, so the verified azaniumyl/azanium form ships at a general tier. An N+ with no carbon group keeps ‘azaniumyl (preselected prefix)’ (:42303), and the P/As/O/S onium stems have no amine-type suffix (‘methyldi(phenyl)phosphaniumyl’ is part of a PIN at:42468).