Spaces:
Running
Running
File size: 4,562 Bytes
a48faac | 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 127 128 129 130 131 132 133 134 135 136 137 | """
Binary Blending Tool CLI
Collects additive SMILES, base fuel selection, and sweep parameters
from the user interactively.
"""
from typing import Optional, List, Tuple
def _get_additive_smiles() -> str:
from rdkit import Chem
from rdkit.Chem import Descriptors
print("\nAdditive Configuration")
print("-" * 40)
while True:
smiles = input("Enter additive SMILES: ").strip()
if not smiles:
print("β SMILES cannot be empty.")
continue
mol = Chem.MolFromSmiles(smiles)
if mol is None:
print(f"β Invalid SMILES: '{smiles}'. Please try again.")
continue
formula = Chem.rdMolDescriptors.CalcMolFormula(mol)
mw = Descriptors.MolWt(mol)
print(f" β Valid molecule: {formula} (MW: {mw:.2f} g/mol)")
return smiles
def _get_base_fuel() -> Tuple[str, Optional[List[str]], Optional[List[float]]]:
from applications.mixture_aware_generator.cli import get_custom_base_fuel
print("\nBase Fuel Selection:")
print("1. Fossil diesel (typical petroleum diesel)")
print("2. Biodiesel (FAME)")
print("3. Custom (enter your own composition)")
while True:
choice = input("\nSelect base fuel (1-3): ").strip()
if choice == "1":
print("β Using fossil diesel")
return "fossil_diesel", None, None
elif choice == "2":
print("β Using biodiesel")
return "biodiesel", None, None
elif choice == "3":
smiles, fracs = get_custom_base_fuel()
if smiles is None:
print(" β Defaulting to fossil diesel.")
return "fossil_diesel", None, None
return "custom", smiles, fracs
else:
print("β Invalid choice. Enter 1, 2, or 3.")
def _get_sweep_config() -> Tuple[float, float, int]:
print("\nSweep Configuration")
print("-" * 40)
print("Define the range of additive mole fractions to evaluate.")
while True:
try:
raw = input("Min additive mole fraction [default 0.00]: ").strip()
min_frac = float(raw) if raw else 0.0
if not 0.0 <= min_frac < 1.0:
print("β Min fraction must be in [0, 1).")
continue
break
except ValueError:
print("β Please enter a number.")
while True:
try:
raw = input("Max additive mole fraction [default 0.30]: ").strip()
max_frac = float(raw) if raw else 0.30
if not min_frac < max_frac <= 1.0:
print(f"β Max fraction must be greater than {min_frac:.3f} and β€ 1.")
continue
break
except ValueError:
print("β Please enter a number.")
while True:
try:
raw = input("Number of sweep steps [default 20]: ").strip()
n_steps = int(raw) if raw else 20
if n_steps < 2:
print("β Need at least 2 steps.")
continue
break
except ValueError:
print("β Please enter a whole number.")
return min_frac, max_frac, n_steps
def get_user_config() -> dict:
"""Interactive CLI β returns a config dict that maps directly to run_blend_sweep kwargs."""
print("=" * 70)
print("BINARY BLENDING TOOL")
print("=" * 70)
print("\nPredict how DCN and YSI change as a single additive is blended")
print("into a base fuel across a range of mole fractions.")
additive_smiles = _get_additive_smiles()
base_fuel_type, base_fuel_smiles, base_fuel_mole_fractions = _get_base_fuel()
min_frac, max_frac, n_steps = _get_sweep_config()
print("\n" + "=" * 70)
print("CONFIGURATION SUMMARY")
print("=" * 70)
print(f" Additive SMILES : {additive_smiles}")
print(f" Base fuel : {base_fuel_type}")
if base_fuel_smiles:
print(f" Base components : {len(base_fuel_smiles)}")
print(f" Sweep : {min_frac:.3f} β {max_frac:.3f} ({n_steps} steps)")
print("=" * 70)
return {
"additive_smiles": additive_smiles,
"base_fuel_type": base_fuel_type,
"base_fuel_smiles": base_fuel_smiles,
"base_fuel_mole_fractions": base_fuel_mole_fractions,
"min_fraction": min_frac,
"max_fraction": max_frac,
"n_steps": n_steps,
}
|