Saltar al contenido

Coordenadas atómicas únicas de simetría

La guía o código que verás en este artículo es la resolución más sencilla y válida que encontramos a tu duda o problema.

Solución:

Jason B vio esto antes que yo, pero creo que lo siguiente reproduce razonablemente bien algunos de los ejemplos de entrada de JUEGOS.

f[mol_] := Module[al, out,
  al = AtomList[Molecule[mol], 
    All, "AtomicNumber", "AtomCoordinates"];
  out = QuantityMagnitude /@ 
    Flatten /@ al[[First /@ Molecule[mol]["SymmetryEquivalentAtoms"]]];
  out /. z_Integer :> Sequence[ElementData[z, "Abbreviation"], z]
  ]

f["Toluene"]

ingrese la descripción de la imagen aquí

El plan general para resolver esto es

  1. Genere todas las transformaciones de simetría para una molécula dada.
  2. Aplique estas transformaciones a cada coordenada de átomo, dando una lista de coordenadas para cada átomo.
  3. Los átomos del grupo que dan las listas de coordenadas equivalentes se consideran equivalentes.

Lamentablemente, los desarrolladores de Wolfram no brindan las funciones de transformación reales asociadas con un elemento de simetría dado a través de ninguna función integrada. Pero sí nos dan suficiente información en el "SymmetryElements" propiedad para construirlos nosotros mismos:

In[26]:= Molecule["methane"]["SymmetryElements"] // pf2

Out[26]= 
    <

Al examinar la estructura de esa salida, podemos escribir una función para devolver la transformación del elemento de simetría. me gusta usar KeyValuePattern para definiciones fácilmente legibles:

symmetryOperation[KeyValuePattern["Operation"->"Rotation","Degree"->d_,"RotationAxis"->InfiniteLine[point_,direction_]]] := RotationTransform[(2 * Pi) / d, direction, point];
symmetryOperation[KeyValuePattern["Operation"->"ImproperRotation","Degree"->d_,"RotationAxis"->InfiniteLine[point_,direction_]]] := ReflectionTransform[direction, point] @* RotationTransform[(2 * Pi) / d, direction, point];
reflectpoint[point_, center_] := point + 2 * (center + -point);
symmetryOperation[KeyValuePattern["Operation"->"Inversion","InversionCenter"->Point[center_]]] := Composition[
    ReflectionTransform[1, 0, 0, center], 
    ReflectionTransform[0, 1, 0, center], 
    ReflectionTransform[0, 0, 1, center]
];
symmetryOperation[KeyValuePattern["Operation"->"Reflection","SymmetryPlane"->Hyperplane[normal_,point_]]] := ReflectionTransform[normal, point]

Ahora tomamos escribir una función para devolver todas las transformaciones de simetría de una molécula, corrigiendo el descuido que Wolfram ha hecho al no incluir el elemento Identidad:

symmetryTransforms[mol_] := Join[Identity, Map[symmetryOperation, mol @ "SymmetryElements"]];

Ahora envuélvalo todo junto con una función para aplicar cada transformación a cada coordenada de átomo, y luego reúna aquellos que producen la misma lista de coordenadas:

symmetryUniqueAtomIndices[mol_, tolerance_:0.1] := Module[
    
        transforms = symmetryTransforms @ mol,
        points = QuantityMagnitude @ mol @ "AtomCoordinates"
    ,
    PrependTo[transforms, Identity];
    GatherBy[Range @ Length @ points,
        Sort[
            DeleteDuplicates[Round[Through[transforms[Part[points, #]]], tolerance]]
        ]&
    ]
]

Esto usa GatherBy para agrupar átomos equivalentes. La parte importante aquí es hacer una función para canonicalizar las coordenadas transformadas, y para eso solo estoy redondeando los valores numéricos, eliminando los duplicados y luego clasificándolos. Probablemente haya margen de mejora en este paso.

Puede ver las diferentes conformaciones de ciclohexano de este ejemplo:

labels = "planar", "chair", "twist-boat", "boat", "half-boat", "half-chair";
conformers = AssociationThread[
    labels -> CloudImport[
        CloudObject["https://www.wolframcloud.com/objects/555b1b48-9f89-45ef-a9e2-49c8fe5228b6"],
        "SDF"
    ]
];

Compara la simetría de las diferentes conformaciones:

In[10]:= symmetryUniqueAtomIndices /@ conformers

Out[10]= <|"planar" -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
    14, 15, 16, 17, 18, 
 "chair" -> 1, 2, 3, 4, 5, 6, 7, 9, 12, 13, 16, 18, 8, 10, 11, 
    14, 15, 17, 
 "twist-boat" -> 1, 4, 2, 3, 5, 6, 7, 8, 13, 14, 9, 12, 15, 
    17, 10, 11, 16, 18, 
 "boat" -> 1, 4, 2, 3, 5, 6, 7, 14, 8, 13, 9, 11, 15, 
    18, 10, 12, 16, 17, 
 "half-boat" -> 1, 2, 6, 3, 5, 4, 7, 8, 9, 18, 10, 
    17, 11, 15, 12, 16, 13, 14, 
 "half-chair" -> 1, 4, 2, 3, 5, 6, 7, 13, 8, 14, 9, 
    12, 10, 11, 15, 17, 16, 18|>

Si desea solo un átomo de cada grupo de equivalencia, use algo como

In[11]:= Map[First] /@ %

Out[11]= <|"planar" -> 1, 7, "chair" -> 1, 7, 8, 
 "twist-boat" -> 1, 2, 7, 9, 10, "boat" -> 1, 2, 7, 8, 9, 10, 
 "half-boat" -> 1, 2, 3, 4, 7, 8, 9, 10, 11, 12, 13, 14, 
 "half-chair" -> 1, 2, 5, 7, 8, 9, 10, 15, 16|>

Puede visualizar los grupos de simetría a través de algo como

MoleculePlot3D[conformers["chair"], 
 [email protected]
["chair"]]

ingrese la descripción de la imagen aquí

En esta imagen, todos los átomos de un color dado son equivalentes según las operaciones de simetría disponibles. Puede ver que los átomos de hidrógeno ahora se dividen en dos categorías, el ecuatorial (que irradia 'fuera' del anillo) en púrpura y el axial (con enlaces paralelos al eje de simetría principal) en azul.

valoraciones y comentarios

Tienes la opción de añadir valor a nuestra información tributando tu veteranía en las referencias.

¡Haz clic para puntuar esta entrada!
(Votos: 1 Promedio: 2)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *