from __future__ import annotations """ PINO fragrance accords and standard material library. Why this module exists: - Many real-world formulas contain proprietary bases (e.g., "Green Tea Base") or complex naturals (e.g., "Orris butter") that are not single CAS records. - For physics and neural critique, we decompose these into representative ingredient proxies that capture the dominant volatility and odour character. - Accords are a first-class concept so the UI and composer can start from a known base (e.g., "citrus top accord", "green tea base") instead of raw single materials. """ from dataclasses import dataclass, field from typing import Any @dataclass class Accord: """A named aromatic accord represented as a weighted proxy formula.""" name: str description: str ingredients: list[dict[str, Any]] = field(default_factory=list) """ Each ingredient is {"cas": str, "name": str, "weight_fraction": float}. The fractions inside an accord sum to 1.0; they are scaled by the accord's overall weight when the accord is expanded into a full formula. """ def expand(self, overall_weight_fraction: float) -> list[dict[str, Any]]: """Return the accord's proxy formula scaled to a target weight fraction.""" return [ { "cas": item["cas"], "name": item["name"], "weight_fraction": item["weight_fraction"] * overall_weight_fraction, } for item in self.ingredients ] # --------------------------------------------------------------------------- # Standard accords used by the UI, composer, and formula importer. # These are intentionally approximate; they encode the *olfactory character* and # *volatility class* rather than an exact GC-MS reconstruction. # --------------------------------------------------------------------------- GREEN_TEA_BASE = Accord( name="Green Tea Base", description="Fresh, leafy, slightly phenolic green tea reconstruction", ingredients=[ {"cas": "928-96-1", "name": "cis-3-Hexenol", "weight_fraction": 0.15}, {"cas": "928-97-2", "name": "cis-3-Hexenyl acetate", "weight_fraction": 0.10}, {"cas": "140-67-0", "name": "Estragole", "weight_fraction": 0.05}, {"cas": "674-86-6", "name": "Linalool oxide", "weight_fraction": 0.10}, {"cas": "78-70-6", "name": "Linalool", "weight_fraction": 0.15}, {"cas": "110-44-1", "name": "Sorbic acid", "weight_fraction": 0.02}, {"cas": "121-33-5", "name": "Vanillin", "weight_fraction": 0.05}, {"cas": "119-64-2", "name": "Tetrahydroquinoline", "weight_fraction": 0.03}, {"cas": "4602-84-0", "name": "Farnesol", "weight_fraction": 0.05}, {"cas": "106-24-5", "name": "Geraniol", "weight_fraction": 0.10}, {"cas": "106-25-2", "name": "Nerol", "weight_fraction": 0.08}, {"cas": "5989-27-5", "name": "d-Limonene", "weight_fraction": 0.07}, {"cas": "89-43-0", "name": "Anthranilic acid", "weight_fraction": 0.05}, ], ) BLACK_TEA_BASE = Accord( name="Tea Black Base", description="Dark, smoky, phenolic black tea reconstruction", ingredients=[ {"cas": "105-95-3", "name": "Ethylene brassylate", "weight_fraction": 0.10}, {"cas": "91-64-5", "name": "Coumarin", "weight_fraction": 0.08}, {"cas": "121-33-5", "name": "Vanillin", "weight_fraction": 0.08}, {"cas": "121-34-6", "name": "Ethyl vanillin", "weight_fraction": 0.05}, {"cas": "119-36-8", "name": "Methyl salicylate", "weight_fraction": 0.07}, {"cas": "118-58-1", "name": "Benzyl salicylate", "weight_fraction": 0.10}, {"cas": "140-67-0", "name": "Estragole", "weight_fraction": 0.05}, {"cas": "89-86-1", "name": "Beta-thujone", "weight_fraction": 0.03}, {"cas": "90-05-1", "name": "Guaiacol", "weight_fraction": 0.24}, {"cas": "106-26-3", "name": "Neral", "weight_fraction": 0.05}, {"cas": "78-70-6", "name": "Linalool", "weight_fraction": 0.08}, {"cas": "106-24-5", "name": "Geraniol", "weight_fraction": 0.07}, ], ) MATE_ABSOLUTE = Accord( name="Mate absolute", description="Dry, herbal, tea-like yerba mate reconstruction", ingredients=[ {"cas": "928-96-1", "name": "cis-3-Hexenol", "weight_fraction": 0.10}, {"cas": "928-97-2", "name": "cis-3-Hexenyl acetate", "weight_fraction": 0.08}, {"cas": "140-67-0", "name": "Estragole", "weight_fraction": 0.08}, {"cas": "99-85-4", "name": "Terpinen-4-ol", "weight_fraction": 0.08}, {"cas": "77-53-2", "name": "Cedrol", "weight_fraction": 0.12}, {"cas": "106-24-5", "name": "Geraniol", "weight_fraction": 0.08}, {"cas": "78-70-6", "name": "Linalool", "weight_fraction": 0.08}, {"cas": "91-64-5", "name": "Coumarin", "weight_fraction": 0.05}, {"cas": "121-33-5", "name": "Vanillin", "weight_fraction": 0.05}, {"cas": "4602-84-0", "name": "Farnesol", "weight_fraction": 0.08}, {"cas": "7212-44-4", "name": "Nerolidol", "weight_fraction": 0.10}, {"cas": "5989-27-5", "name": "d-Limonene", "weight_fraction": 0.10}, ], ) ORRIS_BUTTER = Accord( name="Orris butter / orris CO2", description="Powdery, violet-iris orris root reconstruction", ingredients=[ {"cas": "127-42-4", "name": "Methyl ionone gamma", "weight_fraction": 0.18}, {"cas": "14901-07-6", "name": "Ionone beta", "weight_fraction": 0.12}, {"cas": "17283-81-7", "name": "Dihydro ionone beta", "weight_fraction": 0.10}, {"cas": "110-17-8", "name": "Fumaric acid", "weight_fraction": 0.02}, {"cas": "105-95-3", "name": "Ethylene brassylate", "weight_fraction": 0.15}, {"cas": "91-64-5", "name": "Coumarin", "weight_fraction": 0.08}, {"cas": "121-33-5", "name": "Vanillin", "weight_fraction": 0.05}, {"cas": "77-53-2", "name": "Cedrol", "weight_fraction": 0.10}, {"cas": "104-54-1", "name": "Cinnamyl alcohol", "weight_fraction": 0.05}, {"cas": "106-24-5", "name": "Geraniol", "weight_fraction": 0.05}, {"cas": "78-70-6", "name": "Linalool", "weight_fraction": 0.05}, {"cas": "4602-84-0", "name": "Farnesol", "weight_fraction": 0.05}, ], ) CEDARWOOD_VIRGINIA = Accord( name="Cedarwood Virginia/Texas", description="Dry, woody cedarwood oil reconstruction", ingredients=[ {"cas": "77-53-2", "name": "Cedrol", "weight_fraction": 0.35}, {"cas": "469-01-2", "name": "Cedrene", "weight_fraction": 0.30}, {"cas": "5986-38-9", "name": "Cedryl acetate", "weight_fraction": 0.15}, {"cas": "8000-27-9", "name": "Cedarwood oil (Virginia)", "weight_fraction": 0.20}, ], ) VETIVER_HAITI = Accord( name="Vetiver Haiti", description="Earthy, smoky, woody vetiver oil reconstruction", ingredients=[ {"cas": "117-98-6", "name": "Vetiveryl acetate", "weight_fraction": 0.30}, {"cas": "77-53-2", "name": "Cedrol", "weight_fraction": 0.15}, {"cas": "89-78-1", "name": "Menthol", "weight_fraction": 0.03}, {"cas": "4602-84-0", "name": "Farnesol", "weight_fraction": 0.10}, {"cas": "7212-44-4", "name": "Nerolidol", "weight_fraction": 0.12}, {"cas": "106-24-5", "name": "Geraniol", "weight_fraction": 0.05}, {"cas": "78-70-6", "name": "Linalool", "weight_fraction": 0.05}, {"cas": "5989-27-5", "name": "d-Limonene", "weight_fraction": 0.05}, {"cas": "8000-27-9", "name": "Cedarwood oil", "weight_fraction": 0.10}, {"cas": "105-95-3", "name": "Ethylene brassylate", "weight_fraction": 0.05}, ], ) AMBER_MUSK_BASE = Accord( name="Amber-Musk Base", description="Warm, clean, slightly sweet amber-musk reconstruction", ingredients=[ {"cas": "105-95-3", "name": "Ethylene brassylate", "weight_fraction": 0.20}, {"cas": "111-79-5", "name": "Habanolide", "weight_fraction": 0.15}, {"cas": "142-62-3", "name": "Ambrettolide", "weight_fraction": 0.10}, {"cas": "6790-58-9", "name": "Ambroxan", "weight_fraction": 0.15}, {"cas": "91-64-5", "name": "Coumarin", "weight_fraction": 0.08}, {"cas": "121-33-5", "name": "Vanillin", "weight_fraction": 0.07}, {"cas": "1222-05-5", "name": "Galaxolide", "weight_fraction": 0.10}, {"cas": "77-53-2", "name": "Cedrol", "weight_fraction": 0.10}, {"cas": "4602-84-0", "name": "Farnesol", "weight_fraction": 0.05}, ], ) CITRUS_TOP_ACCORD = Accord( name="Citrus Top Accord", description="Bright, sparkling citrus opening", ingredients=[ {"cas": "5989-27-5", "name": "d-Limonene", "weight_fraction": 0.35}, {"cas": "68647-72-3", "name": "Linalyl acetate", "weight_fraction": 0.15}, {"cas": "78-70-6", "name": "Linalool", "weight_fraction": 0.10}, {"cas": "94-48-4", "name": "Bergamot oil", "weight_fraction": 0.20}, {"cas": "8008-56-8", "name": "Lemon oil", "weight_fraction": 0.15}, {"cas": "119-64-2", "name": "Tetrahydroquinoline", "weight_fraction": 0.05}, ], ) FLORAL_HEART_ACCORD = Accord( name="Floral Heart Accord", description="Clean, elegant floral bouquet", ingredients=[ {"cas": "78-70-6", "name": "Linalool", "weight_fraction": 0.20}, {"cas": "106-24-5", "name": "Geraniol", "weight_fraction": 0.15}, {"cas": "106-25-2", "name": "Nerol", "weight_fraction": 0.10}, {"cas": "8007-44-1", "name": "Jasmine absolute (proxy: benzyl acetate)", "weight_fraction": 0.15}, {"cas": "140-11-4", "name": "Benzyl acetate", "weight_fraction": 0.15}, {"cas": "104-54-1", "name": "Cinnamyl alcohol", "weight_fraction": 0.05}, {"cas": "101-86-0", "name": "alpha-Hexylcinnamaldehyde", "weight_fraction": 0.10}, {"cas": "122-97-4", "name": "Phenethyl alcohol", "weight_fraction": 0.10}, ], ) WOODY_BASE_ACCORD = Accord( name="Woody Base Accord", description="Dry, warm woody dry-down", ingredients=[ {"cas": "77-53-2", "name": "Cedrol", "weight_fraction": 0.20}, {"cas": "469-01-2", "name": "Cedrene", "weight_fraction": 0.15}, {"cas": "54452-50-3", "name": "Iso E Super", "weight_fraction": 0.25}, {"cas": "68039-33-4", "name": "Timbersilk", "weight_fraction": 0.15}, {"cas": "8000-27-9", "name": "Cedarwood oil", "weight_fraction": 0.15}, {"cas": "105-95-3", "name": "Ethylene brassylate", "weight_fraction": 0.10}, ], ) ACCORDS: dict[str, Accord] = { "green_tea": GREEN_TEA_BASE, "black_tea": BLACK_TEA_BASE, "mate": MATE_ABSOLUTE, "orris": ORRIS_BUTTER, "cedarwood": CEDARWOOD_VIRGINIA, "vetiver": VETIVER_HAITI, "amber_musk": AMBER_MUSK_BASE, "citrus_top": CITRUS_TOP_ACCORD, "floral_heart": FLORAL_HEART_ACCORD, "woody_base": WOODY_BASE_ACCORD, } def expand_accord_by_name(name: str, overall_weight_fraction: float) -> list[dict[str, Any]]: """Expand a named accord to a weight-fraction list.""" key = name.lower().replace(" ", "_").replace("/", "_") if key not in ACCORDS: raise KeyError(f"Unknown accord '{name}'. Available: {list(ACCORDS.keys())}") return ACCORDS[key].expand(overall_weight_fraction)