<jupyter_start><jupyter_text>Code to Run OT2  Color Mixing by XX;Modified on Nov 17, 2020 by <NAME> for OT2<jupyter_code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import time
import utils
import ssh_command as ssh
import image_process as imp
import gpyopt_optimizer as gpyopt<jupyter_output><empty_output><jupyter_text>A "Fake" RGB function<jupyter_code>def RGB_func(X): 
    '''
    This is the 'fake' function to genration RGB from the x_A, x_B, x_C
    Please replace this function with the actual experimental data
    x is normalized. 
    '''
    X = np.array(X)
    RGB = X.dot(np.array([[1,0.2,0.0],[0.0,0.8,0.1],[0.3,0.0,1]]))
    return np.around(RGB*255+0.01* np.random.randn(*RGB.shape)*255)<jupyter_output><empty_output><jupyter_text>The Four Required Blocks<jupyter_code>def xinit():
    X_init = 

    return np.array(X_init)
def Ymetric (RGB_exp, RGB_ref):
    
    
    Y = 
    
    return np.array(Y)

def xnext(X, Y, i):

    X_new = 
    
    return np.array(X_new)
def stop_cond(RGB_exp, RGB_ref):
    stop_flag = False
    if len(RGB_exp)>25:
        print('Reach the max number of samples')
        stop_flag = True
        
    def color_difference(rgb, rgb_ref):
        return abs(rgb_ref[0]-rgb[0]), abs(rgb_ref[1]-rgb[1]), abs(rgb_ref[2]-rgb[2])
    diff = []
    for rgb in RGB_exp:
        rgb_ref = RGB_ref[0]
        r_err, g_err, b_err = color_difference(rgb, rgb_ref)
        diff.append((r_err<=8) & (g_err<=8) & (b_err<=8))
    if np.sum(diff)>=1:
        print("Success! Early stop after collecting", len(diff), "samples")
        print("Good match at ", np.arange(len(diff))[np.array(diff) == 1][0]+1)
        stop_flag = True 
          
    return stop_flag
import numpy as np

flag = False
############### TASK 1: Initial Conditions ###################
X_init = xinit()
###############################################################

##******************Check the X_init format****************#
for x in np.array(X_init):
    if len(x) != 3:
        print('ERROR! each row needs to be 3 elements for color A, B and C')
        print('you have', len(x), ' elements in one of the rows')
        flag = True
    if abs(sum(x)-200)> 0.01*200:
        print('ERROR! each row needs to sum up closed to 200 (or 198 - 200) [uL]')
        print('you have a sum of', sum(x), ' [uL] in one of the rows')
        flag = True
##*********************************************************#

if flag != True:
    X_new = np.array(X_init)
    X = []

    num_rounds = 25-len(X_init)
    for i in range(num_rounds):
        if X ==[]:
            X = X_new/200
        else:
            X = np.concatenate([X, X_new/200])
            if len(X)>25:
                X = X[0:25]

        RGB_ref = [np.array([ 83., 108.,  76.])+0.01* np.random.randn(3)*255] # each value is in the range 0-255
        RGB_exp = np.array(RGB_func(X))
        

#######TASK 2: Optimization Metric (e.g. error function)############
        Y = np.array(Ymetric(RGB_exp, RGB_ref))
####################################################################

##******************Check the Y format****************##
        if len(np.shape(Y))==2:
            if np.shape(Y)[1] != 1:
                print('we need a two dimensional array with 1 element at each row')
                print(np.shape(Y)[1])
                flag == True
        else:
            print('we need a two dimensional array with 1 element at each row')
            flag == True
        if flag == True:
            break 
##*********************************************************#



#######TASK 3: Suggest New Conditions############
        X_new = np.array(xnext(X, Y, i))
####################################################################

##******************Check the X_new format****************##
        for x in np.array(X_new):
            if len(x) != 3:
                print('ERROR! each row needs to be 3 elements for color A, B and C')
                print('you have', len(x), ' elements in one of the rows')
                flag = True
            if abs(sum(x)-200)> 0.01*200:
                print('ERROR! each row needs to sum up closed to 200 (or 198 - 200) [uL]')
                print('you have a sum of', sum(x), ' [uL] in one of the rows')
                flag = True
        if flag == True:
            break
##*********************************************************#


            
##############TASK 4: Early Stop Condition#########################

        stop_flag = stop_cond(RGB_exp, RGB_ref)
        if stop_flag:
            break
####################################################################

print("Lowest Error:", np.round(np.min(np.sqrt(Y))))
print("Lowest Error RGB", RGB_exp[np.argmin(np.sqrt(Y))],'at', np.argmin(np.sqrt(Y))+1)
print("Lowest ref RGB", np.around(RGB_ref[0]))<jupyter_output><empty_output><jupyter_text>Test the connection to OT2<jupyter_code># OT2_IP = '169.254.74.32'
# ssh.ssh_connect(OT2_IP)

# ssh.transfer_and_simulate_protocol(OT2_IP, 'color_test.csv', 'color_mixing.py')

# image_name = 'test.jpg'
# ssh.ssh_take_an_image(OT2_IP, image_name)

# ## image processing and RGB extraction
# image_ROI = imp.image_extractor(image_name)<jupyter_output><empty_output><jupyter_text>Run the OT2 with the code blocks<jupyter_code>ref_pos = 'C4'
init_pos = 'D1'

############### TASK 1: Initial Conditions ###################
X_init = xinit()
###############################################################
X_new = np.array(X_init)
X = []
num_rounds = 25-len(X_init)
for i in range(num_rounds):
    if X ==[]:
        X = X_new/200
    else:
        X = np.concatenate([X, X_new/200])
        if len(X)>25:
            X = X[0:25]
        
    ## Saving the new conditions
    header = ["colorA [uL]", "colorB [uL]", "colorC [uL]"]
    df_Xnew = pd.DataFrame(np.around(X_new), columns = header)
    dispense_pos = utils.get_dispense_positions(init_pos[0]+str(int(init_pos[1:])+len(X)), 
                                                len(X_new))
    df_Xnew['dispense pos'] = dispense_pos
    timestr = time.strftime("_%Y%m%d_%H%M%S")
    BO_csv = "BO_R"+str(i)+"_conditions_"+timestr+".csv"
    df_Xnew.to_csv('.\\data\\'+BO_csv, index=False)
    print('Iteration:',BO_csv[:5])
    print("Suggested Liquid Amount [µL]")   
    print(df_Xnew)
    ####
#     ## run the protocol on OT2
#     ssh.transfer_and_simulate_protocol(OT2_IP, BO_csv, 'color_mixing.py')
#     ssh.run_protocol(OT2_IP, 'color_mixing.py')
#     image_name = BO_csv[:-4]+timestr+'.jpg'
#     ssh.ssh_take_an_image(OT2_IP, image_name)
#     ####
    
#     ## image processing and RGB extraction
#     image_ROI = imp.image_extractor(image_name)

#     refs_pos = [ref_pos]
#     print("reference color sample")
#     rgb_ref = imp.get_rgb_from_samples(image_ROI, refs_pos)[0]
#     samples_pos = utils.get_dispense_positions(init_pos, len(X))
#     print("experiment color samples")
#     rgb_list = imp.get_rgb_from_samples(image_ROI, samples_pos)
#     RGB_ref = np.array(rgb_ref)
#     RGB_exp = np.array(rgb_list)
#     ####

    RGB_ref = [np.array([ 83., 108.,  76.])+0.01* np.random.randn(3)*255] # each value is in the range 0-255
    RGB_exp = np.array(RGB_func(X))

    #######TASK 2: Optimization Metric (e.g. error function)############
    Y = Ymetric(RGB_exp, RGB_ref)
    ####################################################################
    
    ## Data Processing and Saving 
    df_X= pd.DataFrame(np.append(np.around(np.append(X*200, np.sqrt(Y), axis=1),0),
                                    np.around(RGB_exp,0), axis = 1),
                          columns = ['Liquid A [uL]','Liquid B [uL]', 'Liquid C [uL]',
                                     'RGB RMSE', 'R', 'G', 'B'])
    print('Round', i, 'BO Results')
    print(df_X)
    
    df_X.to_csv('.\\archive\\'+'BO_R'+str(i)+'_results'+timestr+'.csv', index=False)
    df_Xnew.to_csv('.\\archive\\'+'BO_R'+str(i)+'conditions'+timestr+'.csv', index=False)
    ####
    
    #######TASK 3: Suggest New Conditions############
    X_new = np.array(xnext(X, Y, i))
    ####################################################################
    utils.barplot_RGB(RGB_ref[0], RGB_exp,'Round'+str(i)+': BO Experiemnt RGB ')
    ##############TASK 4: Early Stop Condition#########################
    stop_flag = stop_cond(RGB_exp, RGB_ref)
    if stop_flag:
        break
    ####################################################################

print("Lowest Error:", np.round(np.min(np.sqrt(Y))))
print("Lowest Error RGB", RGB_exp[np.argmin(np.sqrt(Y))],'at', np.argmin(np.sqrt(Y))+1)
print("Lowest ref RGB", np.around(RGB_ref[0]))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.24783662166839737, 'fraction_numerical': 0.02353755624783662, 'mean_word_length': 3.1493537577788415, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '598270', 'license': 'MIT', 'n_tokens_mistral': 3133, 'n_tokens_neox': 2897, 'n_words': 657, 'path': 'Week11/Color_Mixing_Example/2s986_Quiz2_XX-LZ_modified_for_OT2.ipynb', 'repo_name': 'PV-Lab/2s986_class', 'size': '8668'}