def is_stereo_compatible(tra, sgr1, sgr2): """ is this transformation compatible with the applyant/product stereo assignments? """ cgr1 = _without_stereo_parities(sgr1) cgr2 = _without_stereo_parities(sgr2) atm_key_dct = _full_isomorphism(apply(tra, cgr1), cgr2) # determine the stereo centers which are preserved in the transformation sgr1 = _relabel(sgr1, atm_key_dct) atm_keys = sorted(_atom_stereo_keys(sgr1) & _atom_stereo_keys(sgr2)) bnd_keys = sorted(_bond_stereo_keys(sgr1) & _bond_stereo_keys(sgr2)) atm_pars1 = dict_.values_by_key(_atom_stereo_parities(sgr1), atm_keys) atm_pars2 = dict_.values_by_key(_atom_stereo_parities(sgr2), atm_keys) bnd_pars1 = dict_.values_by_key(_bond_stereo_parities(sgr1), bnd_keys) bnd_pars2 = dict_.values_by_key(_bond_stereo_parities(sgr2), bnd_keys) atm_ngb_keys_dct1 = _atom_neighbor_keys(sgr1) atm_ngb_keys_dct2 = _atom_neighbor_keys(sgr2) ret = True for atm_key, par1, par2 in zip(atm_keys, atm_pars1, atm_pars2): atm_ngb_keys1 = _stereo_sorted_atom_neighbor_keys( sgr1, atm_key, atm_ngb_keys_dct1[atm_key]) atm_ngb_keys2 = _stereo_sorted_atom_neighbor_keys( sgr2, atm_key, atm_ngb_keys_dct2[atm_key]) if _permutation_parity(atm_ngb_keys1, atm_ngb_keys2): ret &= (par1 == par2) else: ret &= (par1 != par2) for bnd_key, par1, par2 in zip(bnd_keys, bnd_pars1, bnd_pars2): atm1_key, atm2_key = bnd_key atm1_ngb_key1 = _stereo_sorted_atom_neighbor_keys( sgr1, atm1_key, atm_ngb_keys_dct1[atm1_key] - {atm2_key})[0] atm2_ngb_key1 = _stereo_sorted_atom_neighbor_keys( sgr1, atm2_key, atm_ngb_keys_dct1[atm2_key] - {atm1_key})[0] atm1_ngb_key2 = _stereo_sorted_atom_neighbor_keys( sgr2, atm1_key, atm_ngb_keys_dct2[atm1_key] - {atm2_key})[0] atm2_ngb_key2 = _stereo_sorted_atom_neighbor_keys( sgr2, atm2_key, atm_ngb_keys_dct2[atm2_key] - {atm1_key})[0] if not ((atm1_ngb_key1 != atm1_ngb_key2) ^ (atm2_ngb_key1 != atm2_ngb_key2)): ret &= (par1 == par2) else: ret &= (par1 != par2) return ret
def atom_stereo_coordinates(sgr): """ stereo-specific coordinates for this molecular graph """ assert sgr == _explicit(sgr) last_xgr = None xgr = _without_stereo_parities(sgr) # first, get a set of non-stereo-specific coordinates for the graph atm_xyz_dct = _atom_coordinates(xgr) if has_stereo(sgr): full_atm_ste_par_dct = _atom_stereo_parities(sgr) full_bnd_ste_par_dct = _bond_stereo_parities(sgr) atm_keys = set() bnd_keys = set() while last_xgr != xgr: last_xgr = xgr atm_keys.update(stereogenic_atom_keys(xgr)) bnd_keys.update(stereogenic_bond_keys(xgr)) atm_ste_par_dct = { atm_key: full_atm_ste_par_dct[atm_key] for atm_key in atm_keys } bnd_ste_par_dct = { bnd_key: full_bnd_ste_par_dct[bnd_key] for bnd_key in bnd_keys } xgr, atm_xyz_dct = _correct_atom_stereo_coordinates( xgr, atm_ste_par_dct, atm_xyz_dct) xgr, atm_xyz_dct = _correct_bond_stereo_coordinates( xgr, bnd_ste_par_dct, atm_xyz_dct) return atm_xyz_dct
def _is_compatible(sgr): atm_ste_par_dct = _assigned(_atom_stereo_parities(sgr)) bnd_ste_par_dct = _assigned(_bond_stereo_parities(sgr)) _compat_atm_assgns = (set(known_atm_ste_par_dct.items()) <= set( atm_ste_par_dct.items())) _compat_bnd_assgns = (set(known_bnd_ste_par_dct.items()) <= set( bnd_ste_par_dct.items())) return _compat_atm_assgns and _compat_bnd_assgns
def substereomers(xgr): """ all stereomers compatible with this graph's assignments """ _assigned = functools.partial(dict_.filter_by_value, func=lambda x: x is not None) known_atm_ste_par_dct = _assigned(_atom_stereo_parities(xgr)) known_bnd_ste_par_dct = _assigned(_bond_stereo_parities(xgr)) def _is_compatible(sgr): atm_ste_par_dct = _assigned(_atom_stereo_parities(sgr)) bnd_ste_par_dct = _assigned(_bond_stereo_parities(sgr)) _compat_atm_assgns = (set(known_atm_ste_par_dct.items()) <= set( atm_ste_par_dct.items())) _compat_bnd_assgns = (set(known_bnd_ste_par_dct.items()) <= set( bnd_ste_par_dct.items())) return _compat_atm_assgns and _compat_bnd_assgns sgrs = tuple(filter(_is_compatible, stereomers(xgr))) return sgrs
def bond_stereo_keys(sgr): """ keys to bond stereo-centers """ bnd_ste_keys = dict_.keys_by_value(_bond_stereo_parities(sgr), lambda x: x in [True, False]) return bnd_ste_keys