File size: 9,165 Bytes
fd5ba83 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | from __future__ import annotations
"""
Standard fragrance materials with known CAS/SMILES for registry expansion.
Why this module exists:
- The SQLite registry is sparse; real formulas (like the one in
data/formulas/matthew_tea_woods.json) contain many well-known materials that
are not yet registered.
- This file maps common trade names to canonical identifiers (CAS or SMILES)
so the importer can resolve them without web lookups every time.
- It is a stepping stone toward a richer, thermodynamically-validated registry.
"""
from typing import Any
# ---------------------------------------------------------------------------
# Trade name -> canonical identifier (CAS preferred, SMILES fallback).
# Many materials are listed by their primary CAS or a representative isomer.
# ---------------------------------------------------------------------------
MATERIALS: dict[str, dict[str, Any]] = {
# Hedione family
"Hedione HC": {"cas": "24851-98-7", "name": "Methyl dihydrojasmonate (Hedione HC)", "smiles": "CC1C(=O)CC[C@H](C)C1CC=CC(=O)OC"},
"MDJ": {"cas": "24851-98-7", "name": "Methyl dihydrojasmonate (MDJ)", "smiles": "CC1C(=O)CC[C@H](C)C1CC=CC(=O)OC"},
"Hedione HC / MDJ": {"cas": "24851-98-7", "name": "Methyl dihydrojasmonate (Hedione HC / MDJ)", "smiles": "CC1C(=O)CC[C@H](C)C1CC=CC(=O)OC"},
"Methyl dihydrojasmonate": {"cas": "24851-98-7", "name": "Methyl dihydrojasmonate", "smiles": "CC1C(=O)CC[C@H](C)C1CC=CC(=O)OC"},
# Iso E Super / Timbersilk
"Iso E Super": {"cas": "54452-50-3", "name": "Iso E Super (OTNE)", "smiles": "CC(C)C1CCC(C)CC1CC(C)C=O"},
"OTNE": {"cas": "54452-50-3", "name": "Iso E Super (OTNE)", "smiles": "CC(C)C1CCC(C)CC1CC(C)C=O"},
"Iso E Super / OTNE": {"cas": "54452-50-3", "name": "Iso E Super (OTNE)", "smiles": "CC(C)C1CCC(C)CC1CC(C)C=O"},
"Iso Myrcetone Gamma": {"cas": "68039-33-4", "name": "Iso Myrcetone gamma", "smiles": "CC(C)=CCCC(C)C1CC=C(C)CC1"},
"Timbersilk": {"cas": "68039-33-4", "name": "Timbersilk (Iso Myrcetone gamma)", "smiles": "CC(C)=CCCC(C)C1CC=C(C)CC1"},
"Iso Myrcetone Gamma / Timbersilk": {"cas": "68039-33-4", "name": "Timbersilk (Iso Myrcetone gamma)", "smiles": "CC(C)=CCCC(C)C1CC=C(C)CC1"},
# Damascones
"Beta-damascone": {"cas": "23726-91-2", "name": "Beta-damascone", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"},
"Beta-damascenone": {"cas": "23696-85-7", "name": "Beta-damascenone", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"},
"Beta-damascone / beta-damascenone 1%": {"cas": "23696-85-7", "name": "Beta-damascenone 1%", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"},
"Beta-damascone / beta-damascenone": {"cas": "23696-85-7", "name": "Beta-damascenone", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"},
# Musks / lactones
"Ambrettolide": {"cas": "142-62-3", "name": "Ambrettolide", "smiles": "O=C1CCCCCCCCCCCO1"},
"Habanolide": {"cas": "111-79-5", "name": "Habanolide", "smiles": "O=C1CCCCCCCCCO1"},
"Ambroxan": {"cas": "6790-58-9", "name": "Ambroxan", "smiles": "C[C@]12CC[C@@H](CC1=O)C(C)(C)C2"},
"Ambroxan 10%": {"cas": "6790-58-9", "name": "Ambroxan 10%", "smiles": "C[C@]12CC[C@@H](CC1=O)C(C)(C)C2"},
# Ionones
"Methyl Ionone Gamma": {"cas": "127-42-4", "name": "Methyl ionone gamma", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"},
"Ionone Beta": {"cas": "14901-07-6", "name": "Ionone beta", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"},
"Dihydro Ionone Beta": {"cas": "17283-81-7", "name": "Dihydro ionone beta", "smiles": "CC(=O)CCC1C(C)=CCCC1(C)C"},
# Orris / naturals
"Orris butter": {"cas": "8002-73-1", "name": "Orris butter", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"}, # proxy: ionone
"Orris CO2 10%": {"cas": "8002-73-1", "name": "Orris CO2 10%", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"},
# Vetiver / cedar
"Vetiveryl acetate": {"cas": "117-98-6", "name": "Vetiveryl acetate", "smiles": "CC(=O)OC1CC2CCC(C)C(C)C2C1"},
"Vetiver Haiti 10%": {"cas": "8022-68-4", "name": "Vetiver Haiti 10%", "smiles": "CC1=CCC2C(C)C(C)CCC2C1"},
"Cedarwood Virginia": {"cas": "8000-27-9", "name": "Cedarwood Virginia", "smiles": "CC1=CCC2C(C)C(C)CCC2C1"},
"Cedarwood Texas": {"cas": "8000-27-9", "name": "Cedarwood Texas", "smiles": "CC1=CCC2C(C)C(C)CCC2C1"},
# Green / leafy
"Cis-3-hexenyl salicylate": {"cas": "65405-77-8", "name": "cis-3-Hexenyl salicylate", "smiles": "O=C(Oc1ccccc1O)C/C=C/CC"},
"Cis-3-hexenol": {"cas": "928-96-1", "name": "cis-3-Hexenol", "smiles": "CC/C=C/CCO"},
"Cis-3-hexenol 1%": {"cas": "928-96-1", "name": "cis-3-Hexenol 1%", "smiles": "CC/C=C/CCO"},
# Other common materials
"Coumarin": {"cas": "91-64-5", "name": "Coumarin", "smiles": "O=c1ccc2ccccc2o1"},
"Coumarin 10%": {"cas": "91-64-5", "name": "Coumarin 10%", "smiles": "O=c1ccc2ccccc2o1"},
"Fumaric acid": {"cas": "110-17-8", "name": "Fumaric acid", "smiles": "O=C(O)/C=C/C(=O)O"},
"Cinnamyl alcohol": {"cas": "104-54-1", "name": "Cinnamyl alcohol", "smiles": "OC/C=C/c1ccccc1"},
"Sorbic acid": {"cas": "110-44-1", "name": "Sorbic acid", "smiles": "CC=CC=CC(=O)O"},
"Tetrahydroquinoline": {"cas": "119-64-2", "name": "Tetrahydroquinoline", "smiles": "c1ccc2c(c1)NCCC2"},
"Estragole": {"cas": "140-67-0", "name": "Estragole", "smiles": "COc1ccc(CC=C)cc1"},
"Linalool oxide": {"cas": "674-86-6", "name": "Linalool oxide", "smiles": "CC1(C)CC=C(CO)CC1"},
"Geraniol": {"cas": "106-24-1", "name": "Geraniol", "smiles": "CC(C)=CCC/C(C)=C/CO"},
"Geraniol 10%": {"cas": "106-24-1", "name": "Geraniol 10%", "smiles": "CC(C)=CCC/C(C)=C/CO"},
"Citral": {"cas": "5392-40-5", "name": "Citral", "smiles": "CC(C)=CCCC(C)=CC=O"},
"Citral 10%": {"cas": "5392-40-5", "name": "Citral 10%", "smiles": "CC(C)=CCCC(C)=CC=O"},
"alpha-Pinene": {"cas": "80-56-8", "name": "alpha-Pinene", "smiles": "CC1=CCC2CC1C2(C)C"},
"beta-Pinene": {"cas": "127-91-3", "name": "beta-Pinene", "smiles": "CC1=CCC2CC1C2(C)C"},
"Gamma-terpinene": {"cas": "99-85-4", "name": "Gamma-terpinene", "smiles": "CC1=CC=C(C(C)C)CC1"},
"Linalool": {"cas": "78-70-6", "name": "Linalool", "smiles": "CC(C)=CCCC(C)(O)C=C"},
"Nerol": {"cas": "106-25-2", "name": "Nerol", "smiles": "CC(C)=CCC/C(C)=C\CO"},
"d-Limonene": {"cas": "5989-27-5", "name": "d-Limonene", "smiles": "CC1=CC[C@@H](CC1)C(=C)C"},
"Anthranilic acid": {"cas": "89-43-0", "name": "Anthranilic acid", "smiles": "Nc1ccccc1C(=O)O"},
"cis-3-Hexenol": {"cas": "928-96-1", "name": "cis-3-Hexenol", "smiles": "CC/C=C/CCO"},
"cis-3-Hexenyl acetate": {"cas": "928-97-2", "name": "cis-3-Hexenyl acetate", "smiles": "CC(=O)OCC/C=C/CC"},
"Terpinen-4-ol": {"cas": "99-85-4", "name": "Terpinen-4-ol", "smiles": "CC1=CCC(C(C)(C)O)CC1"},
"Ethyl vanillin": {"cas": "121-34-6", "name": "Ethyl vanillin", "smiles": "CCOc1cc(C=O)ccc1O"},
"Methyl salicylate": {"cas": "119-36-8", "name": "Methyl salicylate", "smiles": "COC(=O)c1ccccc1O"},
"Benzyl salicylate": {"cas": "118-58-1", "name": "Benzyl salicylate", "smiles": "O=C(Oc1ccccc1)c2ccccc2O"},
"Nerolidol": {"cas": "7212-44-4", "name": "Nerolidol", "smiles": "CC(C)=CCCC(C)=CCCO"},
"Farnesol": {"cas": "4602-84-0", "name": "Farnesol", "smiles": "CC(C)=CCCC(C)=CCCO"},
"Neral": {"cas": "106-26-3", "name": "Neral", "smiles": "CC(C)=CCC/C(C)=C/C=O"},
"Guaiacol": {"cas": "90-05-1", "name": "Guaiacol", "smiles": "COc1ccccc1O"},
"Beta-thujone": {"cas": "89-86-1", "name": "Beta-thujone", "smiles": "CC1(C)C(=O)C2(C)CCC1C2"},
"Menthol": {"cas": "89-78-1", "name": "Menthol", "smiles": "CC(C)C1CCC(C)CC1O"},
"Cedrol": {"cas": "77-53-2", "name": "Cedrol", "smiles": "CC1(C)C2CCC3(C)C(C)(C)CCC3(C)C2C1"},
"Cedrene": {"cas": "469-01-2", "name": "Cedrene", "smiles": "CC1=CCC2C(C)C3CCC(C)C3CC2C1"},
"Cedryl acetate": {"cas": "5986-38-9", "name": "Cedryl acetate", "smiles": "CC(=O)OC1C(C)C2CCC(C)C2C1(C)C"},
"cis-3-Hexenyl salicylate": {"cas": "65405-77-8", "name": "cis-3-Hexenyl salicylate", "smiles": "O=C(OCCCC/C=C/CC)c1ccccc1O"},
# Common naturals and bases handled by accords.py
"Beta-damascenone": {"cas": "23696-85-7", "name": "Beta-damascenone", "smiles": "CC(=O)/C=C/C1C(C)=CCCC1(C)C"},
"Methyl salicylate 10%": {"cas": "119-36-8", "name": "Methyl salicylate 10%", "smiles": "COC(=O)c1ccccc1O"},
# Common naturals and bases handled by accords.py
"Green Tea Base": {"accord": "green_tea"},
"Tea Black Base": {"accord": "black_tea"},
"Tea Black Base 10%": {"accord": "black_tea"},
"Mate absolute": {"accord": "mate"},
"Mate absolute 10%": {"accord": "mate"},
"Orris butter / orris CO2 10%": {"accord": "orris"},
"Vetiver Haiti 10%": {"accord": "vetiver"},
"Cedarwood Virginia/Texas": {"accord": "cedarwood"},
}
def resolve_material(name: str) -> dict[str, Any] | None:
"""Return the canonical identifier(s) for a trade name, if known."""
return MATERIALS.get(name)
def is_accord(name: str) -> bool:
"""Return True if this material is a proprietary base we expand via accords."""
rec = MATERIALS.get(name)
return rec is not None and "accord" in rec
def all_material_names() -> list[str]:
return list(MATERIALS.keys())
|