feat(pino): literature seed integration, stratified dataset split, registry enrichment, and Space sync
31ee18f unverified | from __future__ import annotations | |
| import argparse | |
| import json | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).parent.parent / "src")) | |
| from pino.registry import AromaRegistry | |
| # Approximate placeholder records for natural extracts / complex mixtures that lack | |
| # a single PubChem structure. These are used so literature formulas containing them | |
| # can still be simulated (VLE falls back to ideal gamma=1.0). | |
| NATURAL_PLACEHOLDERS = { | |
| "68606-83-7": ("Rosa centifolia absolute", "rose absolute", 250.0), | |
| "68916-26-7": ("Musk extract", "musk", 300.0), | |
| "7462-86-6": ("Jasmin absolute", "jasmin", 240.0), | |
| "8000-25-7": ("Bay oil", "bay", 180.0), | |
| "8000-27-9": ("Lemon oil", "lemon", 180.0), | |
| "8000-28-0": ("Lime oil", "lime", 180.0), | |
| "8000-29-1": ("Neroli oil", "neroli", 200.0), | |
| "8000-41-7": ("Rose oil", "rose", 220.0), | |
| "8000-46-2": ("Rosemary oil", "rosemary", 180.0), | |
| "8002-73-1": ("Resinoid", "resin", 300.0), | |
| "8006-80-2": ("Citronella oil", "citronella", 180.0), | |
| "8006-81-3": ("Ginger oil", "ginger", 200.0), | |
| "8007-00-9": ("Amber oil", "amber", 250.0), | |
| "8007-46-3": ("Cinnamon oil", "cinnamon", 180.0), | |
| "8007-80-5": ("Musk seed oil", "musk seed", 250.0), | |
| "8008-31-9": ("Pine oil", "pine", 170.0), | |
| "8008-56-8": ("Palmarosa oil", "palmarosa", 190.0), | |
| "8008-57-9": ("Patchouli oil", "patchouli", 220.0), | |
| "8013-76-1": ("Cananga oil", "cananga", 190.0), | |
| "8014-17-3": ("Petitgrain oil", "petitgrain", 180.0), | |
| "8016-38-4": ("Basil oil", "basil", 180.0), | |
| "8016-63-5": ("Lavender oil", "lavender", 180.0), | |
| "8016-78-2": ("Pine needle oil", "pine needle", 170.0), | |
| "8016-96-4": ("Geranium oil", "geranium", 190.0), | |
| "8023-75-2": ("Ylang ylang oil", "ylang", 190.0), | |
| "8023-79-2": ("Musk tonkin", "musk tonkin", 300.0), | |
| "8023-91-4": ("Jasmin sambac", "jasmin sambac", 240.0), | |
| "8024-13-1": ("Styrax resinoid", "styrax", 280.0), | |
| "8031-03-6": ("Cardamom oil", "cardamom", 190.0), | |
| "8032-35-1": ("Pumilio pine oil", "pumilio pine", 170.0), | |
| "8046-19-3": ("Labdanum resinoid", "labdanum", 280.0), | |
| "8047-24-3": ("Benzoin resinoid", "benzoin", 280.0), | |
| "85409-36-9": ("Olibanum oil", "olibanum", 250.0), | |
| "85940-31-4": ("Elemi oil", "elemi", 220.0), | |
| "89997-75-1": ("Narcissus absolute", "narcissus", 250.0), | |
| "9000-50-4": ("Frankincense oil", "frankincense", 250.0), | |
| "9000-64-0": ("Mimosa absolute", "mimosa", 250.0), | |
| "9000-64-2": ("Orange flower absolute", "orange flower", 240.0), | |
| "8015-61-0": ("Cassie absolute", "cassie", 250.0), | |
| "8015-77-8": ("Rosewood oil", "rosewood", 190.0), | |
| "8016-26-0": ("Labdanum clair", "labdanum clair", 280.0), | |
| "8022-96-6": ("Jasmin absolute", "jasmin absolute", 240.0), | |
| "8000-34-8": ("Clove oil", "clove", 180.0), | |
| "8006-87-9": ("Sandalwood oil", "sandalwood", 220.0), | |
| "8007-01-0": ("Rose otto", "rose otto", 220.0), | |
| "8007-06-5": ("Cascarilla oil", "cascarilla", 180.0), | |
| "8007-75-8": ("Bergamot oil", "bergamot", 180.0), | |
| "8008-45-5": ("Nutmeg oil", "nutmeg", 180.0), | |
| "8013-90-9": ("Ionone", "ionone", 190.0), | |
| "8014-09-3": ("Patchouli oil", "patchouli", 220.0), | |
| } | |
| def main() -> int: | |
| parser = argparse.ArgumentParser(description="Add natural-extract placeholders to registry") | |
| parser.add_argument("--registry", default="src/pino/registry.db", help="Path to registry.db") | |
| args = parser.parse_args() | |
| registry = AromaRegistry(args.registry) | |
| added = 0 | |
| for cas, (name, _, mw) in NATURAL_PLACEHOLDERS.items(): | |
| try: | |
| registry.add({ | |
| "cas": cas, | |
| "name": name, | |
| "smiles": f"NATURAL:{cas}", | |
| "molecular_weight": mw, | |
| "logp": 3.0, | |
| "unifac_groups": {}, | |
| "vapor_pressure_pa": 0.01, | |
| "boiling_point_k": 450.0, | |
| "odor_threshold_ug_m3": None, | |
| "odor_description": "", | |
| }) | |
| added += 1 | |
| print(f"Added {cas} ({name})") | |
| except Exception as e: | |
| print(f"Skipped {cas}: {e}") | |
| registry.close() | |
| print(f"Added {added} natural placeholders") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |