def ring_arc_complement_atom_keys(gra, rng): """ non-intersecting arcs from a ring that shares segments with a graph """ gra_atm_bnd_dct = atoms_bond_keys(gra) rng_atm_bnd_dct = atoms_bond_keys(rng) # 1. find divergence points, given by the atom at which the divergence # occurs and the bond followed by the ring as it diverges div_dct = {} for atm_key in atom_keys(gra) & atom_keys(rng): div = rng_atm_bnd_dct[atm_key] - gra_atm_bnd_dct[atm_key] if div: bnd_key, = div div_dct[atm_key] = bnd_key # 2. cycle through the ring atoms; if you meet a starting divergence, start # an arc; extend the arc until you meet an ending divergence; repeat until # all divergences are accounted for atm_keys = sorted_ring_atom_keys_from_bond_keys(bond_keys(rng)) arcs = [] arc = [] for atm_key, next_atm_key in mit.windowed(itertools.cycle(atm_keys), 2): bnd_key = frozenset({atm_key, next_atm_key}) # if we haven't started an arc, see if we are at a starting divergence; # if so, start the arc now and cross the divergence from our list if not arc: if atm_key in div_dct and div_dct[atm_key] == bnd_key: div_dct.pop(atm_key) arc.append(atm_key) # if we've started an arc, extend it; then, check if we are at an # ending divergence; if so, end the arc and cross the divergence from # our list; add it to our list of arcs else: arc.append(atm_key) if next_atm_key in div_dct and div_dct[next_atm_key] == bnd_key: div_dct.pop(next_atm_key) arc.append(next_atm_key) arcs.append(arc) arc = [] # if no divergences are left, break out of the loop if not div_dct: break arcs = tuple(map(tuple, arcs)) return arcs
def branch_bond_keys(gra, atm_key, bnd_key): """ bond keys for branch extending along `bnd_key` away from `atm_key` """ # bnd_key is the set of atom indices for the bond of interest # atm_bnd_keys_dct is a dictionary of atoms that are connected to each atom bnd_key = frozenset(bnd_key) assert atm_key in bnd_key atm_bnd_keys_dct = atoms_bond_keys(gra) bnch_bnd_keys = {bnd_key} seen_bnd_keys = set() excl_bnd_keys = atm_bnd_keys_dct[atm_key] - {bnd_key} new_bnd_keys = {bnd_key} bnd_ngb_keys_dct = bonds_neighbor_bond_keys(gra) while new_bnd_keys: new_bnd_ngb_keys = set( itertools.chain( *dict_.values_by_key(bnd_ngb_keys_dct, new_bnd_keys))) bnch_bnd_keys.update(new_bnd_ngb_keys - excl_bnd_keys) seen_bnd_keys.update(new_bnd_keys) new_bnd_keys = bnch_bnd_keys - seen_bnd_keys return frozenset(bnch_bnd_keys)
def sigma_radical_atom_keys(rgr): """ keys for sigma radical atoms """ rgr = without_fractional_bonds(rgr) atm_rad_keys = nonresonant_radical_atom_keys(rgr) bnd_ords_dct = resonance_dominant_bond_orders(rgr) atm_bnd_keys_dct = atoms_bond_keys(rgr) atm_sig_keys = [] for atm_key in atm_rad_keys: for bnd_key in atm_bnd_keys_dct[atm_key]: if 3 in bnd_ords_dct[bnd_key]: atm_sig_keys.append(atm_key) break atm_sig_keys = frozenset(atm_sig_keys) return atm_sig_keys
def sigma_radical_atom_keys(rgr): """ keys for sigma radical atoms :param rgr: the molecular graph :returns: the sigma radical atom keys :rtype: frozenset[int] """ rgr = without_fractional_bonds(rgr) atm_rad_keys = nonresonant_radical_atom_keys(rgr) bnd_ords_dct = resonance_dominant_bond_orders(rgr) atm_bnd_keys_dct = atoms_bond_keys(rgr) atm_sig_keys = [] for atm_key in atm_rad_keys: for bnd_key in atm_bnd_keys_dct[atm_key]: if 3 in bnd_ords_dct[bnd_key]: atm_sig_keys.append(atm_key) break atm_sig_keys = frozenset(atm_sig_keys) return atm_sig_keys