Source code for chemistrylab.benches.extract_bench

# pylint: disable=invalid-name
# pylint: disable=wrong-import-position

# import external modules
import os
import pickle
import sys
from random import choice
from copy import deepcopy

from chemistrylab.util.reward import RewardGenerator
from chemistrylab import material, vessel
from chemistrylab.benches.general_bench import *

import importlib

from chemistrylab.reactions.reaction_info import ReactInfo, REACTION_PATH
from chemistrylab.lab.shelf import Shelf,VariableShelf


[docs] def wurtz_vessel(add_mat=""): """ Function to generate an input vessel for the wurtz extraction bench. Args: - add_mat (str): The target material to include in the vessel Returns: - extract_vessel (Vessel): A vessel containing add_mat and some undesired materials """ # initialize extraction vessel extraction_vessel = vessel.Vessel(label='extraction_vessel') # initialize DiEthylEther DiEthylEther = material.DiEthylEther() # initialize Na Na = material.Na() Na.charge = 1.0 Na.set_solute_flag(True) Na.set_color(0.0) Na.polarity = 2.0 Na.phase = 'l' Na._boiling_point = material.NaCl()._boiling_point # initialize Cl Cl = material.Cl() Cl.charge = -1.0 Cl.set_solute_flag(True) Cl.set_color(0.0) Cl.polarity = 2.0 Cl.phase = 'l' Cl._boiling_point = material.NaCl()._boiling_point # initialize material products = {'dodecane': material.Dodecane, '5-methylundecane': material.FiveMethylundecane, '4-ethyldecane': material.FourEthyldecane, '5,6-dimethyldecane': material.FiveSixDimethyldecane, '4-ethyl-5-methylnonane': material.FourEthylFiveMethylnonane, '4,5-diethyloctane': material.FourFiveDiethyloctane, 'NaCl': material.NaCl } try: if add_mat == "": add_mat = choice(list(products.keys())) if add_mat != "NaCl": add_material = products[add_mat]() else: add_material = products['dodecane']() except KeyError: add_mat = 'dodecane' add_material = products['dodecane']() add_material.set_solute_flag(True) add_material.set_color(0.0) add_material.phase = 'l' DiEthylEther.mol=4.0 Na.mol=1.0 Cl.mol=1.0 add_material.mol=1.0 # material_dict material_dict = { DiEthylEther.get_name(): DiEthylEther, Na.get_name(): Na, Cl.get_name(): Cl, add_material.get_name(): add_material, } extraction_vessel.material_dict=material_dict extraction_vessel.validate_solvents() extraction_vessel.validate_solutes() extraction_vessel._mix(-1000,None,-1000) return extraction_vessel, add_mat
[docs] def oil_vessel(): """ Function to generate an input vessel for the oil extraction bench. Returns: - extract_vessel (Vessel): A vessel containing oil and NaCl """ # initialize extraction vessel extraction_vessel = vessel.Vessel(label='extraction_vessel') # initialize H2O C6H14 = material.C6H14() C6H14.mol=1.0 # Get dissolved NaCl dissolved = material.NaCl().dissolve() for d in dissolved: d.mol=dissolved[d] mats = [C6H14]+[d for d in dissolved] # material_dict material_dict = {mat._name:mat for mat in mats} # Set up the vessel extraction_vessel.material_dict=material_dict extraction_vessel.validate_solvents() extraction_vessel.validate_solutes() return extraction_vessel
[docs] def make_solvent(mat): "Makes a Vessel with a single material" solvent_vessel = vessel.Vessel( label=f'{mat} Vessel', ) # create the material dictionary for the solvent vessel solvent_class = material.REGISTRY[mat]() solvent_class.set_solvent_flag(True) solvent_class.mol=1e6 solvent_vessel.material_dict = {mat:solvent_class} # instruct the vessel to update its material dictionary return solvent_vessel
[docs] class GeneralWurtzExtract_v2(GenBench): """ Class to define an environment which performs a Wurtz extraction on materials in a vessel. """ metadata = { "render_modes": ["rgb_array"], "render_fps": 10, } def __init__(self): e_rew= RewardGenerator(use_purity=True,exclude_solvents=True,include_dissolved=True) shelf = VariableShelf( [ lambda x:wurtz_vessel(x)[0], lambda x:vessel.Vessel("Beaker 1"), lambda x:vessel.Vessel("Beaker 2"), lambda x:make_solvent("C6H14"), lambda x:make_solvent("diethyl ether") ],[], n_working = 3) amounts=np.linspace(0.2,1,5).reshape([5,1]) pixels = (amounts*10).astype(np.int32) actions = [ Action([0], pixels, 'drain by pixel',[1], 0.01, False), Action([0],-amounts, 'mix', None, 0.01, False), Action([1], amounts, 'pour by volume',[0], 0.01, False), Action([2], amounts, 'pour by volume',[0], 0.01, False), Action([0], amounts, 'pour by volume',[2], 0.01, False), #If pouring by volume takes time, then there is no change in observation when waiting after pouring in some cases Action([3], amounts/2, 'pour by volume',[0], 0, False), Action([4], amounts/2, 'pour by volume',[0], 0, False), Action([0,1,2], 32**amounts/200, 'mix', None, 0, False), Action([0], [[0]], 'mix', None, 0, True) ] targets = ReactInfo.from_json(REACTION_PATH+"/chloro_wurtz.json").PRODUCTS super(GeneralWurtzExtract_v2, self).__init__( shelf, actions, ["layers","targets"], targets, reward_function=e_rew )
[docs] class WaterOilExtract_v0(GenBench): """ Class to define an environment which performs a Wurtz extraction on materials in a vessel. """ metadata = { "render_modes": ["rgb_array"], "render_fps": 10, } def __init__(self): e_rew= RewardGenerator(use_purity=False, exclude_solvents=True, include_dissolved=True, exclude_mat="C6H14") shelf =VariableShelf( [ lambda x:oil_vessel(), lambda x:vessel.Vessel("Beaker 1"), lambda x:vessel.Vessel("Waste Vessel"), lambda x:make_solvent("C6H14"), lambda x:make_solvent("H2O") ], [], n_working = 2) amounts=np.linspace(0.2,1,5).reshape([5,1]) pixels = (amounts*10).astype(np.int32) actions = [ Action([0], pixels, 'drain by pixel',[1], 0.01, False), Action([0],-amounts, 'mix', None, 0.01, False), Action([1], amounts, 'pour by volume',[0], 0.01, False), Action([2], amounts, 'pour by volume',[0], 0.01, False), Action([0], amounts, 'pour by volume',[2], 0.01, False), #If pouring by volume takes time, then there is no change in observation when waiting after pouring in some cases Action([3], amounts/2, 'pour by volume',[0], 0, False), Action([4], amounts/2, 'pour by volume',[0], 0, False), Action([0,1,2], 32**amounts/200, 'mix', None, 0, False), Action([0], [[0]], 'mix', None, 0, True) ] super(WaterOilExtract_v0, self).__init__( shelf, actions, ["layers","targets"], targets=["NaCl"], reward_function=e_rew, )
[docs] class WurtzExtractDemo_v0(GenBench): """ Class to define an environment which performs a Wurtz extraction on materials in a vessel. """ metadata = { "render_modes": ["rgb_array"], "render_fps": 60, } def __init__(self): e_rew= RewardGenerator(use_purity=True,exclude_solvents=True,include_dissolved=True) shelf = VariableShelf( [ lambda x:wurtz_vessel(x)[0], lambda x:vessel.Vessel("Beaker 1"), lambda x:vessel.Vessel("Beaker 2"), lambda x:make_solvent("C6H14"), lambda x:make_solvent("diethyl ether") ],[], n_working = 3) amounts=np.ones([1,1])*0.02 pixels = [[1]] actions = [ Action([0], pixels, 'drain by pixel',[1], 0.001, False), Action([0],-amounts, 'mix', None, 0, False), Action([1], amounts, 'pour by volume',[0], 0.001, False), Action([2], amounts, 'pour by volume',[0], 0.001, False), Action([0], amounts, 'pour by volume',[2], 0.001, False), Action([3], amounts/2, 'pour by volume',[0], 0, False), Action([4], amounts/2, 'pour by volume',[0], 0, False), Action([0,1,2], [[1e-3],[0.016]],'mix', None, 0, False), Action([0], [[0]], 'mix', None, 0, True) ] targets = ReactInfo.from_json(REACTION_PATH+"/chloro_wurtz.json").PRODUCTS super(WurtzExtractDemo_v0, self).__init__( shelf, actions, ["layers","targets"], targets, reward_function=e_rew, max_steps=500 )
[docs] def get_keys_to_action(self): # Control with the numpad or number keys. keys = {(ord(k),):i for i,k in enumerate("1234567890") } keys[()]=7 return keys
[docs] class SeparateTest_v0(GenBench): """ Class to define an environment which performs a Wurtz extraction on materials in a vessel. """ metadata = { "render_modes": ["rgb_array"], "render_fps": 60, } def __init__(self): e_rew= RewardGenerator(use_purity=True,exclude_solvents=True,include_dissolved=True) shelf = VariableShelf( [ lambda x:wurtz_vessel(x)[0], lambda x:vessel.Vessel("Beaker 1"), lambda x:vessel.Vessel("Beaker 2"), lambda x:make_solvent("C6H14"), lambda x:make_solvent("diethyl ether"), lambda x:make_solvent("H2O"), lambda x:make_solvent("ethoxyethane"), lambda x:make_solvent("ethyl acetate"), ],[], n_working = 3) amounts=np.ones([1,1])*0.02 pixels = [[1]] actions = [ Action([0], pixels, 'drain by pixel',[1], 0.001, False), Action([0],-amounts, 'mix', None, 0, False), Action([1], amounts, 'pour by volume',[0], 0.001, False), Action([2], amounts, 'pour by volume',[0], 0.001, False), Action([0], amounts, 'pour by volume',[2], 0.001, False), Action([3], amounts/2, 'pour by volume',[0], 0, False), Action([4], amounts/2, 'pour by volume',[0], 0, False), Action([5], amounts/2, 'pour by volume',[0], 0, False), Action([6], amounts/2, 'pour by volume',[0], 0, False), Action([7], amounts/2, 'pour by volume',[0], 0, False), Action([0,1,2], [[1e-3],[0.016]],'mix', None, 0, False), Action([0], [[0]], 'mix', None, 0, True) ] targets = ReactInfo.from_json(REACTION_PATH+"/chloro_wurtz.json").PRODUCTS super(SeparateTest_v0, self).__init__( shelf, actions, ["layers","targets"], targets, reward_function=e_rew, max_steps=5000 )