Enumerate PCB Structures and Share via an EntityStore
A polychlorinated biphenyl (PCB) is an organic compound with chemical formula given by . PCBs were formerly used for a number of industrial applications, including in electrical transformers. Here, the generation and storing of all possible polychlorinated biphenyls (PCBs) as custom entities in an entity store is illustrated.
ChemicalData already contains the PCB scaffold, diphenyl (also often called "biphenyl").
Entity["Chemical", "Biphenyl"]["ColorStructureDiagram"]
ChemicalData also contains a particular congener of the PCB molecule.
Entity["Chemical", "PCB"][
EntityProperty["Chemical", "ColorStructureDiagram"]]
The generic PCB structure involves 10 sites, indicated below with X's. To obtain all possible mono- to deca-chlorinated derivatives (i.e. congeners), attach chloro-substituents at these 10 locants in all possible ways. Here, the generic structure as "MOL" format representation is loaded from a predefined CloudObject.
molString = CloudGet[CloudObject[
"https://www.wolframcloud.com/objects/user-722de5bb-ef39-4cbd-\
999d-546c888892d6/PCB_scaffold"]][[2]];
ImportString[molString, "MOL"]
With some basic group theory, all PCB structures can be enumerated. The essential symmetry property of the whole scaffold, expressed as a permutation group, is the starting point.
biphenylSymmetry =
PermutationGroup[{Cycles[{{6, 10}, {7, 9}}],
Cycles[{{1, 5}, {2, 4}}],
Cycles[{{1, 6}, {2, 7}, {3, 8}, {4, 9}, {5, 10}}]}];
Form the cycle index polynomial from Pólya's counting theorem and manipulate its coefficients to obtain a count of 210 congeners (including the unsubstituted hydrocarbon structure, which is not a PCB due to its lack of chlorine).
ci = Factor[
CycleIndexPolynomial[biphenylSymmetry, Array[Subscript[x, #] &, 4]]]
Total[CoefficientList[Expand[ci /. Subscript[x, i_] -> (x^i + 1)], x]]
After renaming the locant positions using simple string replacements, all 209 IUPAC-compliant names are generated.
conPos = Flatten[(PositionIndex /@
First /@
GroupOrbits[biphenylSymmetry, Permutations[#],
Permute]) & /@ (LowerTriangularize[
ConstantArray["Cl", {10, 10}]] /. 0 -> "H")] /.
Thread[Range[10] -> {"2", "3", "4", "5", "6", "2'", "3'", "4'",
"5'", "6'"}];
(names = Flatten[{StringJoin[Riffle[Sort[#["Cl"]], ","]] <>
"-" <> (Length[#["Cl"]] /.
Thread[Range[10] -> {"Chloro", "Dichloro", "Trichloro",
"Tetrachloro", "Pentachloro", "Hexachloro",
"Heptachloro", "Octachloro", "Nonachloro",
"Decachloro"}]) <> "biphenyl"} & /@ conPos] /.
"2,2',3,3',4,4',5,5',6,6'-Decachlorobiphenyl" ->
"Decachlorobiphenyl") // Short
In a similar manner, exhaustively generate all congener structures.
PCBstruct =
ImportString[
StringReplacePart[molString, #, StringPosition[molString, "X"]],
"MOL"] & /@
Flatten[(First /@
GroupOrbits[biphenylSymmetry, Permutations[#],
Permute]) & /@ (LowerTriangularize[
ConstantArray["Cl", {10, 10}]] /. 0 -> "H"), 1];
TextGrid[Transpose[{names, PCBstruct}] // Take[#, 2] &,
Dividers -> All]
To include more detailed properties of the congeners, import PCB as a dataset from a precomputed CloudObject.
imp = CloudGet[CloudObject[
"https://www.wolframcloud.com/objects/user-722de5bb-ef39-4cbd-\
999d-546c888892d6/PCB_congeners_propertylist"]];
TextGrid[Take[imp, 5], Background -> {Automatic, {LightBlue}},
Dividers -> All]
Combine the imported data with the previously computed structures and names.
TextGrid[(PCBdata =
SortBy[MapThread[
Flatten[{#1,
Pick[imp[[3 ;;]], imp[[3 ;;, 1]], #2]}] &, {PCBstruct,
names}], #[[3]] &]) // Take[#, 2] &, Dividers -> All]
Create a custom entity store for these PCB structures.
store = EntityStore[
"PCB" -> <|
"Label" -> "polychlorinated biphenyl",
"LabelPlural" -> "polychlorinated biphenyls",
"Entities" -> entities,
"Properties" -> properties,
"EntityClasses" -> classes
|>]
Register the store for this session.
PrependTo[$EntityStores, store];
Test the entity store by calling a random entity.
EntityValue[RandomEntity["PCB"], "PropertyAssociation"]
In order to make all custom entities available in future sessions or for public applications, write the entity store to a CloudObject.
CloudPut[store, "PCB_entity_store", Permissions -> "Public"]