대칭 고유 원자 좌표
내가 Mathematica에 대해 좋아하는 한 가지는 분자의 이름에서 원자의 추정 좌표로 쉽게 이동할 수 있다는 것입니다.
AtomList[Molecule[Entity["Chemical", "Toluene"]], All, {"AtomicNumber", "AtomCoordinates"}]
(이상하게도 "AtomCoordinates"는 "AtomList"문서에 나타나지 않습니다.)
포인트 그룹도 쉽게 얻을 수 있습니다.
Molecule[Entity["Chemical", "Toluene"]]["PointGroup"]
이것은 GAMESS를 실행하고 양자 화학 계산을 수행하는 데 필요한 입력이기 때문에 흥미 롭습니다 (물론 JM이 이러한 좌표가 휴리스틱 추측이라고 알려 주었으므로 기하학 최적화로 시작 ).
그러나, 정말,이 아닙니다 정확히 내가 정말 필요한 경우에만 대칭 고유 원자의 좌표는 : 내가 필요로하는 입력.
GAMESS 입력에 사용할 수있는 대칭 고유 원자의 좌표를 얻는 방법이 없다고 생각합니까? 포인트 그룹 대칭과 관련된 몇 가지 기능 이 있다는 것을 알고 있지만 어떻게할지 생각하지 못했습니다.
명확히하기 위해 PointGroup 속성이 제공하는 포인트 그룹과 일치하는 답변을 찾고 있습니다. 예를 들어, 위의 코드는 의자 형태에 해당하는 사이클로 헥산에 대한 D3d의 점 그룹을 제공합니다. 따라서 축과 적도는 D3d의 대칭 요소에 의해 서로 변환 될 수 없기 때문에 탄소, 적도 수소 및 축 수소의 세 가지 등가 등급이 있어야합니다.
답변
이를 해결하기위한 일반적인 계획은
- 주어진 분자에 대한 모든 대칭 변환을 생성합니다.
- 이러한 변환을 각 원자 좌표에 적용하여 각 원자에 대한 좌표 목록을 제공합니다.
- 동등한 좌표 목록을 제공하는 그룹 원자는 동등한 것으로 간주됩니다.
슬프게도 Wolfram 개발자는 내장 함수를 통해 주어진 대칭 요소와 관련된 실제 변환 함수를 제공하지 않습니다. 그러나 그들은 "SymmetryElements"재산 에 대한 충분한 정보를 제공하여 직접 구성합니다.
In[26]:= Molecule["methane"]["SymmetryElements"] // pf2
Out[26]= {
<|
"Operation" -> "Rotation", "Name" -> Subscript["C", "3"],
"Degree" -> 3, "UniqueOperationsCount" -> 2,
"RotationAxis" -> InfiniteLine[
{0., 0., 0.},
{0.9312106494091753, 0.3062515387515941, 0.19762773448891885}
]
|>,
........,
<|
"Operation" -> "Reflection", "Name" -> "\[Sigma]",
"Degree" -> 1, "UniqueOperationsCount" -> 1,
"SymmetryPlane" -> Hyperplane[
{-0.6671653488434035, -0.16935533665066543, -0.7254027620919287},
{0., 0., 0.}
]
|>
}
해당 출력의 구조를 조사하여 대칭 요소에서 변환을 반환하는 함수를 작성할 수 있습니다. KeyValuePattern쉽게 읽을 수있는 defitions 에 사용 하고 싶습니다 .
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]
이제 분자에 대한 모든 대칭 변환을 반환하는 함수를 작성하여 Identity 요소를 포함하지 않음으로써 Wolfram이 만든 감독을 수정합니다.
symmetryTransforms[mol_] := Join[{Identity}, Map[symmetryOperation, mol @ "SymmetryElements"]];
이제 각 변환을 각 원자 좌표에 적용하는 함수로 모두 감싸고 동일한 좌표 목록을 생성하는 변환을 수집합니다.
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]]
]&
]
]
이것은 GatherBy동등한 원자를 그룹화하는 데 사용 됩니다. 여기서 중요한 부분은 변환 된 좌표를 정규화하는 함수를 만드는 것입니다.이를 위해 숫자 값을 반올림하고 중복을 삭제 한 다음 정렬합니다. 이 단계에서 개선의 여지가있을 것입니다.
이 예 에서 다른 시클로 헥산 형태를 볼 수 있습니다 .
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"
]
];
다른 형태의 대칭을 비교하십시오.
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}}|>
각 등가 그룹에서 하나의 원자 만 원하면 다음과 같이 사용하십시오.
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}|>
다음과 같은 방법으로 대칭 그룹을 시각화 할 수 있습니다.
MoleculePlot3D[conformers["chair"],
symmetryUniqueAtomIndices@conformers["chair"]]
이 이미지에서 주어진 색상의 모든 원자는 사용 가능한 대칭 작업에서 동일합니다. 이제 수소 원자가 보라색의 적도 (고리에서 '발사')와 파란색의 축 (주 대칭 축에 평행 한 결합 포함)의 두 가지 범주로 분류되는 것을 볼 수 있습니다.
Jason B는 내가 전에 이것을 보았지만 다음은 GAMES 입력 예제 중 일부를 합리적으로 잘 재현한다고 생각합니다.
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"]