def fake_stereo_geometry(gra, ntries=5, max_dist_err=0.5): """ generate a fake stereo geometry """ # determine stereo "groups" with geometrically interdependent chirality atm_ngbs_dct = atom_neighborhoods(gra) bnd_ngbs_dct = bond_neighborhoods(gra) atm_ste_keys = atom_stereo_keys(gra) bnd_ste_keys = bond_stereo_keys(gra) atm_ste_groups = list( map(atom_keys, map(atm_ngbs_dct.__getitem__, atm_ste_keys))) bnd_ste_groups = list( map(atom_keys, map(bnd_ngbs_dct.__getitem__, bnd_ste_keys))) ste_groups = _aggregate_connected_groups(atm_ste_groups + bnd_ste_groups) ste_groups = list(map(sorted, ste_groups)) natms = 0 geo_idx_dct = {} geo = () for group in ste_groups: group_geo = geometry(gra, keys=group, ntries=ntries, max_dist_err=max_dist_err) group_natms = len(group) idxs = list(range(natms, natms + group_natms)) geo_idx_dct.update(dict(zip(group, idxs))) natms += group_natms geo = automol.geom.base.join(geo, group_geo) return geo, geo_idx_dct
def chirality_constraint_bounds(gra, keys): """ bounds for enforcing chirality restrictions """ ste_keys = set(atom_stereo_keys(gra)) & set(keys) par_dct = atom_stereo_parities(gra) ngb_key_dct = atoms_neighbor_atom_keys(gra) def _chirality_constraint(key): ngb_keys = ngb_key_dct[key] ngb_keys = atom_stereo_sorted_neighbor_atom_keys(gra, key, ngb_keys) idxs = tuple(map(keys.index, ngb_keys)) vol_range = (-999., -7.) if par_dct[key] else (+7., +999.) return idxs, vol_range chi_dct = dict(map(_chirality_constraint, ste_keys)) return chi_dct
def qualitative_convergence_checker_(gra, keys, rqq_bond_max=1.8, rqh_bond_max=1.3, rhh_bond_max=1.1, bond_nobond_diff=0.3): """ a convergence checker for error minimization, checking that the geometry is qualitatively correct (correct connectivity and stereo) """ symb_dct = atom_symbols(gra) pairs = set(map(frozenset, itertools.combinations(keys, 2))) bnd_keys = pairs & bond_keys(gra) nob_keys = pairs - bond_keys(gra) nob_symbs = tuple( tuple(map(symb_dct.__getitem__, nob_key)) for nob_key in nob_keys) bnd_symbs = tuple( tuple(map(symb_dct.__getitem__, bnd_key)) for bnd_key in bnd_keys) nob_idxs = tuple(tuple(map(keys.index, nob_key)) for nob_key in nob_keys) bnd_idxs = tuple(tuple(map(keys.index, bnd_key)) for bnd_key in bnd_keys) bnd_udists = tuple( (rqq_bond_max if 'H' not in symb else rhh_bond_max if set(symb) == {'H'} else rqh_bond_max) for symb in bnd_symbs) diff = bond_nobond_diff nob_ldists = tuple( (rqq_bond_max + diff if 'H' not in symb else rhh_bond_max + diff if set(symb) == {'H'} else rqh_bond_max + diff) for symb in nob_symbs) bnd_idxs += tuple(map(tuple, map(reversed, bnd_idxs))) bnd_idx_vecs = tuple(map(list, zip(*bnd_idxs))) bnd_udists *= 2 nob_idxs += tuple(map(tuple, map(reversed, nob_idxs))) nob_idx_vecs = tuple(map(list, zip(*nob_idxs))) nob_ldists *= 2 symbs = tuple(map(symb_dct.__getitem__, keys)) geo_idx_dct = dict(map(reversed, enumerate(keys))) atm_ste_keys = atom_stereo_keys(gra) & set(keys) bnd_ste_keys = bond_stereo_keys(gra) & bnd_keys atm_ste_par_dct = atom_stereo_parities(gra) bnd_ste_par_dct = bond_stereo_parities(gra) def _is_converged(xmat, err, grad): assert err and numpy.any(grad) xyzs = xmat[:, :3] dmat = embed.distance_matrix_from_coordinates(xyzs) # check for correct connectivity connectivity_check = ((numpy.all( dmat[bnd_idx_vecs] < bnd_udists) if bnd_udists else True) and (numpy.all(dmat[nob_idx_vecs] > nob_ldists) if nob_ldists else True)) # check for correct stereo parities geo = automol.geom.base.from_data(symbs, xyzs, angstrom=True) atom_stereo_check = all((atom_stereo_parity_from_geometry( gra, atm_key, geo, geo_idx_dct) == atm_ste_par_dct[atm_key]) for atm_key in atm_ste_keys) bond_stereo_check = all((bond_stereo_parity_from_geometry( gra, bnd_key, geo, geo_idx_dct) == bnd_ste_par_dct[bnd_key]) for bnd_key in bnd_ste_keys) return connectivity_check and atom_stereo_check and bond_stereo_check return _is_converged