qcscine / molassembler

Chemoinformatics toolkit with support for inorganic molecules
https://scine.ethz.ch/download/molassembler
BSD 3-Clause "New" or "Revised" License
31 stars 7 forks source link

Cannot get the conformer of Ir coordinate complex #12

Closed iuhgnor closed 1 year ago

iuhgnor commented 1 year ago

Hi,

I fail to get the conformer of Ir complex. The ligands are three bidentate ligands C1=Nc2ncccc2C1 and the coordination atoms are N atoms. Could you please give me some suggestions? Thank you.

Here is my code:

from scine_molassembler import io
from scine_molassembler import dg

shipscrew_smiles = '[Ir+3]123([N+]4=CCc5ccc[n+]1c54)([N+]1=CCc4ccc[n+]2c41)[N+]1=CCc2ccc[n+]3c21'
shipscrew = io.experimental.from_smiles(shipscrew_smiles)

permutator = shipscrew.stereopermutators.option(0)
assert permutator is not None

config = dg.Configuration()
# config.spatial_model_loosening = 2.0

for i in range(permutator.num_assignments):
    shipscrew.assign_stereopermutator(0, i)
    result = dg.generate_random_conformation(shipscrew, config)
    assert not isinstance(result, str)
    io.write("shipscrew-" + str(i) + ".mol", shipscrew, result)

Here is the output:

TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_6605/1604243307.py in 
     15     result = dg.generate_random_conformation(shipscrew, config)
     16     assert not isinstance(result, str)
---> 17     io.write("shipscrew-" + str(i) + ".mol", shipscrew, result)

TypeError: write(): incompatible function arguments. The following argument types are supported:
    1. (filename: str, molecule: scine_molassembler.Molecule, positions: numpy.ndarray[numpy.float64[m, 3]]) -> None
    2. (filename: str, molecule: scine_molassembler.Molecule) -> None

Invoked with: 'shipscrew-0.mol', , 
moritzBens commented 1 year ago

Hi iuhgnor, Molassembler is unable to find any geometrically feasible (in terms of UFF bond lengths and the fact that any polygon must not have one edge longer than the sum of all other edges) assignment for the bond stereopermutators at bonds 8-9, 17-18, and 26-27. If you remove the permutators, Molassembler generates molecules for you:

from scine_molassembler import io
from scine_molassembler import dg, BondIndex

shipscrew_smiles = '[Ir+3]123([N+]4=CCc5ccc[n+]1c54)([N+]1=CCc4ccc[n+]2c41)[N+]1=CCc2ccc[n+]3c21'
shipscrew = io.experimental.from_smiles(shipscrew_smiles)

permutator = shipscrew.stereopermutators.option(0)
assert permutator is not None
io.write("mol.svg", shipscrew)

config = dg.Configuration()
# config.spatial_model_loosening = 2.0

broken_bonds = [BondIndex(8, 9), BondIndex(26, 27), BondIndex(17, 18)]
for bond in broken_bonds:
    shipscrew.remove_permutator(bond)

for i in range(permutator.num_assignments):
    shipscrew.assign_stereopermutator(0, i)
    io.write("mol_assigned.svg", shipscrew)
    print("zero possible?", shipscrew.stereopermutators.has_unassigned_permutators())
    result = dg.generate_random_conformation(shipscrew, config)
    assert not isinstance(result, str)
    io.write("shipscrew-" + str(i) + ".mol", shipscrew, result)

You can check for impossible rearrangements by calling shipscrew.stereopermutators.has_unassigned_permutators() or look at the SVG representation of the molecule (the "0" in the string is u (0, 2) indicates 0 possible assignments for the permutator ):

impossible_assignment

Best Moritz

iuhgnor commented 1 year ago

Hi @moritzBens ,

Thanks for your prompt and detailed reply. It does solve my problem.

I have a little question. If I remove the assignment for the bond stereopermutators at some bonds, can I get all possible stereisomers of this complex?

moritzBens commented 1 year ago

The behavior of the function generate_random_conformation for unassigned conformers is documented as follows:

      Generate 3D positions for a molecule.

      In the case of a molecule that does not have unassigned
      stereopermutators, this is akin to generating a conformer.
      If there are unassigned stereopermutators, these are assigned at random
      (consistent with relative statistical occurrences of stereopermutations)
      for each structure. If, for instance, your molecules contains a single
      unassigned asymmetric tetrahedron atom stereopermutator, the resulting
      conformation will be one of both assignments.

So, if you run the function often enough, you may end up with all possible stereoisomers.

You could also run generate_ensemble or generate_random_ensemble to try to generate the whole ensemble of stereoisomers (the functions are also part of scine_molassembler.dg; you can get the documentation by calling help(scine_molassembler.dg)).

Best Moritz

iuhgnor commented 1 year ago

Thanks for your suggestion. I will try generate_ensemble and generate_random_ensemble.