def recalculate(ich, stereo=False): """ Recalculate an InChI string. :param ich: InChI string :type ich: str :param stereo: force the same stereochem in recalculated InChI :type stereo: bool :rtype: str """ # for now, just assert that we have no multi-component strings with # hardcoded parts -- these are guaranteed to fail ichs = split(ich) if len(ichs) > 1: if any(hardcoded_object_from_inchi_by_key('inchi', ich) for ich in ichs): ref_ichs = [] for ich_i in ichs: ref_ichs.append(recalculate(ich_i)) ref_ichs.sort() ret = join(ref_ichs) return ret # raise error.FailedInchiGenerationError ret = hardcoded_object_from_inchi_by_key('inchi', ich) if ret is None: _options = '-SUU' if stereo else '' rdm = rdkit_.from_inchi(ich) ret = rdkit_.to_inchi(rdm, options=_options, with_aux_info=False) return ret
def inchi_with_sort_from_geometry(gra, geo=None, geo_idx_dct=None): """ Generate an InChI string from a molecular graph. If coordinates are passed in, they are used to determine stereo. :param gra: molecular graph :type gra: automol graph data structure :param geo: molecular geometry :type geo: automol geometry data structure :param geo_idx_dct: :type geo_idx_dct: dict[:] :returns: the inchi string, along with the InChI sort order of the atoms :rtype: (str, tuple(int)) """ if geo is not None: natms = automol.geom.base.count(geo) geo_idx_dct = (dict(enumerate(range(natms))) if geo_idx_dct is None else geo_idx_dct) mlf, key_map_inv = molfile_with_atom_mapping(gra, geo=geo, geo_idx_dct=geo_idx_dct) rdm = rdkit_.from_molfile(mlf) ich, aux_info = rdkit_.to_inchi(rdm, with_aux_info=True) nums_lst = _parse_sort_order_from_aux_info(aux_info) nums_lst = tuple( tuple(map(key_map_inv.__getitem__, nums)) for nums in nums_lst) # Assuming the MolFile InChI works, the above code is all we need. What # follows is to correct cases where it fails. # This only appears to work sometimes, so when it doesn't, we fall back on # the original inchi output. if geo is not None: gra = set_stereo_from_geometry(gra, geo, geo_idx_dct=geo_idx_dct) gra = implicit(gra) sub_ichs = automol.inchi.split(ich) failed = False new_sub_ichs = [] for sub_ich, nums in zip(sub_ichs, nums_lst): sub_gra = subgraph(gra, nums, stereo=True) sub_ich = _connected_inchi_with_graph_stereo( sub_ich, sub_gra, nums) if sub_ich is None: failed = True break new_sub_ichs.append(sub_ich) # If it worked, replace the InChI with our forced-stereo InChI. if not failed: ich = automol.inchi.join(new_sub_ichs) ich = automol.inchi.standard_form(ich) return ich, nums_lst
def inchi(smi): """ Convert a SMILES string into an InChI string. :param smi: SMILES string :type smi: str :rtype: str """ ich = automol.inchi.base.hardcoded_object_to_inchi_by_key( 'smiles', smi, comp=_compare) if ich is None: rdm = rdkit_.from_smiles(smi) ich = rdkit_.to_inchi(rdm) return ich
def inchi_with_sort_from_geometry(gra, geo=None, geo_idx_dct=None): """ Generate an InChI string from a molecular graph. If coordinates are passed in, they are used to determine stereo. :param gra: molecular graph :type gra: automol graph data structure :param geo: molecular geometry :type geo: automol geometry data structure :param geo_idx_dct: :type geo_idx_dct: dict[:] :rtype: (str, tuple(int)) """ gra = without_dummy_atoms(gra) gra = dominant_resonance(gra) atm_keys = sorted(atom_keys(gra)) bnd_keys = list(bond_keys(gra)) atm_syms = dict_.values_by_key(atom_symbols(gra), atm_keys) atm_bnd_vlcs = dict_.values_by_key( atom_bond_valences(gra), atm_keys) atm_rad_vlcs = dict_.values_by_key( atom_unsaturated_valences(gra), atm_keys) bnd_ords = dict_.values_by_key(bond_orders(gra), bnd_keys) if geo is not None: assert geo_idx_dct is not None atm_xyzs = automol.geom.base.coordinates(geo) atm_xyzs = [atm_xyzs[geo_idx_dct[atm_key]] if atm_key in geo_idx_dct else (0., 0., 0.) for atm_key in atm_keys] else: atm_xyzs = None mlf, key_map_inv = molfile.from_data( atm_keys, bnd_keys, atm_syms, atm_bnd_vlcs, atm_rad_vlcs, bnd_ords, atm_xyzs=atm_xyzs) rdm = rdkit_.from_molfile(mlf) ich, aux_info = rdkit_.to_inchi(rdm, with_aux_info=True) nums = _parse_sort_order_from_aux_info(aux_info) nums = tuple(map(key_map_inv.__getitem__, nums)) return ich, nums