Spaces:
				
			
			
	
			
			
		Sleeping
		
	
	
	
			
			
	
	
	
	
		
		
		Sleeping
		
	Commit 
							
							·
						
						ef03fc8
	
1
								Parent(s):
							
							f3034bd
								
fixed calc issue
Browse files
    	
        app.py
    CHANGED
    
    | @@ -1,19 +1,24 @@ | |
| 1 | 
             
            import numpy as np
         | 
| 2 | 
             
            import gradio as gr
         | 
| 3 | 
             
            import pickle
         | 
| 4 | 
            -
             | 
| 5 | 
             
            import plotly.graph_objects as go
         | 
| 6 | 
             
            import plotly.express as px
         | 
| 7 | 
            -
             | 
| 8 | 
             
            import pandas as pd
         | 
| 9 |  | 
| 10 | 
            -
            #  | 
| 11 | 
            -
            # define a Dataframe styler to highlight the Feasible? column to be green and red
         | 
| 12 | 
             
            def highlight_success(val):
         | 
| 13 | 
             
                color = 'lightgreen' if val == 'Success' else 'lightcoral'
         | 
| 14 | 
             
                return f'color:white;background-color: {color}'
         | 
| 15 |  | 
|  | |
| 16 | 
             
            def sim_espray_constrained(x, noise_se=None):
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 17 | 
             
                # Define the equations
         | 
| 18 | 
             
                conc = x[:, 0]
         | 
| 19 | 
             
                flow_rate = x[:, 1]
         | 
| @@ -25,6 +30,7 @@ def sim_espray_constrained(x, noise_se=None): | |
| 25 | 
             
                exp_con = (np.log(flow_rate) * (solvent - 0.5) + 1.40 >= 0).astype(float)
         | 
| 26 | 
             
                return np.column_stack((diameter, exp_con))
         | 
| 27 |  | 
|  | |
| 28 | 
             
            X_init = np.array([[0.5, 15, 10, 0],
         | 
| 29 | 
             
                               [0.5, 0.1, 10, 1],
         | 
| 30 | 
             
                               [3, 20, 15, 0],
         | 
| @@ -34,12 +40,11 @@ X_init = np.array([[0.5, 15, 10, 0], | |
| 34 | 
             
            Y_init = sim_espray_constrained(X_init)
         | 
| 35 | 
             
            exp_record_df = pd.DataFrame(X_init, columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent'])
         | 
| 36 | 
             
            exp_record_df['Size (um)'] = Y_init[:, 0]
         | 
| 37 | 
            -
            # map 1 to CHCl3 and 0 to DMAc
         | 
| 38 | 
             
            exp_record_df['Solvent'] = ['DMAc' if x == 0 else 'CHCl3' for x in exp_record_df['Solvent']]
         | 
| 39 | 
             
            exp_record_df['Feasible?'] = ['Success' if x == 1 else 'Failed' for x in Y_init[:, 1]]
         | 
|  | |
| 40 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
             
            def import_results():
         | 
| 44 | 
             
                strategies = ['qEI', 'qEI_vi_mixed_con', 'qEICF_vi_mixed_con', 'rnd']
         | 
| 45 |  | 
| @@ -58,13 +63,21 @@ def import_results(): | |
| 58 | 
             
                return best_distances_df_long
         | 
| 59 |  | 
| 60 | 
             
            def calc_human_performance(df):
         | 
|  | |
|  | |
|  | |
| 61 | 
             
                # convert back solvent to 0 and 1
         | 
| 62 | 
            -
                 | 
| 63 |  | 
| 64 | 
             
                TARGET_SIZE = 3.0  # Example target size
         | 
| 65 | 
            -
                ROUNDS = len( | 
| 66 |  | 
| 67 | 
            -
                 | 
|  | |
|  | |
|  | |
|  | |
|  | |
| 68 |  | 
| 69 | 
             
                X_human_init = X_init.copy()
         | 
| 70 | 
             
                Y_human_init = Y_init.copy()
         | 
| @@ -74,9 +87,15 @@ def calc_human_performance(df): | |
| 74 | 
             
                for iter in range(ROUNDS + 1):
         | 
| 75 | 
             
                    Y_distance = -np.abs(Y_human_init[:, 0] - TARGET_SIZE)
         | 
| 76 | 
             
                    best_human_distance.append(np.ma.masked_array(Y_distance, mask=~Y_human_init[:, 1].astype(bool)).max())
         | 
| 77 | 
            -
                     | 
| 78 | 
            -
                     | 
| 79 | 
            -
                     | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 80 |  | 
| 81 | 
             
                return -np.array(best_human_distance)
         | 
| 82 |  | 
| @@ -147,8 +166,8 @@ def plot_results(exp_data_df): | |
| 147 |  | 
| 148 | 
             
                return fig
         | 
| 149 |  | 
| 150 | 
            -
            #  | 
| 151 | 
            -
            def predict(state,  | 
| 152 | 
             
                # Get current results storage from state or initialize if None
         | 
| 153 | 
             
                if state is None:
         | 
| 154 | 
             
                    results_storage = pd.DataFrame(columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
         | 
| @@ -158,26 +177,17 @@ def predict(state, text1, conc1, flow_rate1, voltage1, solvent1, text2, conc2, f | |
| 158 | 
             
                solvent_value1 = 0 if solvent1 == 'DMAc' else 1
         | 
| 159 | 
             
                solvent_value2 = 0 if solvent2 == 'DMAc' else 1
         | 
| 160 |  | 
| 161 | 
            -
                #  | 
| 162 | 
             
                inputs1 = np.array([[conc1, flow_rate1, voltage1, solvent_value1]])
         | 
| 163 | 
             
                inputs2 = np.array([[conc2, flow_rate2, voltage2, solvent_value2]])
         | 
| 164 | 
            -
             | 
| 165 | 
            -
                # Get predictions
         | 
| 166 | 
             
                results1 = sim_espray_constrained(inputs1)
         | 
| 167 | 
             
                results2 = sim_espray_constrained(inputs2)
         | 
| 168 |  | 
| 169 | 
            -
                # Format  | 
| 170 | 
            -
                 | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 173 | 
            -
                 | 
| 174 | 
            -
                exp_con2 = results2[0, 1]
         | 
| 175 | 
            -
             | 
| 176 | 
            -
                # create a dataframe to store the results
         | 
| 177 | 
            -
                results_df = pd.DataFrame(np.array([
         | 
| 178 | 
            -
                    [conc1, flow_rate1, voltage1, solvent_value1, diameter1, exp_con1],
         | 
| 179 | 
            -
                    [conc2, flow_rate2, voltage2, solvent_value2, diameter2, exp_con2]
         | 
| 180 | 
            -
                ]), columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
         | 
| 181 |  | 
| 182 | 
             
                results_df['Solvent'] = ['DMAc' if x == 0 else 'CHCl3' for x in results_df['Solvent']]
         | 
| 183 | 
             
                results_df['Feasible?'] = ['Success' if x == 1 else 'Failed' for x in results_df['Feasible?']]
         | 
| @@ -185,73 +195,68 @@ def predict(state, text1, conc1, flow_rate1, voltage1, solvent1, text2, conc2, f | |
| 185 | 
             
                results_storage = pd.concat([results_storage, results_df], ignore_index=True)
         | 
| 186 | 
             
                results_display = results_storage.style.map(highlight_success, subset=['Feasible?']).format(precision=3)
         | 
| 187 |  | 
| 188 | 
            -
                 | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 189 |  | 
| 190 | 
            -
            #  | 
| 191 | 
             
            def reset_results(state):
         | 
| 192 | 
             
                results_storage = pd.DataFrame(columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
         | 
| 193 | 
            -
                return ( | 
| 194 | 
            -
             | 
| 195 | 
            -
             | 
| 196 | 
            -
             | 
| 197 | 
            -
             | 
| 198 | 
            -
                 | 
| 199 | 
            -
                gr.Number(value=15.0, label="Voltage (kV, range: 10.00-18.00)", minimum=10.0, maximum=18.0, precision=3),
         | 
| 200 | 
            -
                gr.Dropdown(['DMAc', 'CHCl3'], value='DMAc', label='Solvent'),
         | 
| 201 | 
            -
                gr.Markdown("### Experiment 2"),
         | 
| 202 | 
            -
                gr.Number(value=2.8, label="Concentration (%w/v, range: 0.05-5.00)", minimum=0.05, maximum=5.0, precision=3),
         | 
| 203 | 
            -
                gr.Number(value=20.0, label="Flow Rate (mL/h, range: 0.01-60.00)", minimum=0.01, maximum=60.0, precision=3),
         | 
| 204 | 
            -
                gr.Number(value=15.0, label="Voltage (kV, 10.00-18.00)", minimum=10.0, maximum=18.0, precision=3),
         | 
| 205 | 
            -
                gr.Dropdown(['DMAc', 'CHCl3'], value='CHCl3', label='Solvent')
         | 
| 206 | 
            -
            ]
         | 
| 207 | 
            -
             | 
| 208 | 
            -
            outputs = [gr_exp_record_df, gr.DataFrame(label="Your Results"), gr.Plot(label="Performance Comparison")]
         | 
| 209 |  | 
| 210 | 
            -
             | 
|  | |
| 211 |  | 
| 212 | 
            -
            # Create  | 
| 213 | 
             
            with gr.Blocks() as demo:
         | 
| 214 | 
            -
                
         | 
| 215 | 
            -
                gr.Markdown("## Human vs CCBO Campaign - Simulated Electrospray")
         | 
| 216 | 
             
                gr.Markdown(description)
         | 
| 217 |  | 
| 218 | 
             
                # Add state component to store user-specific results
         | 
| 219 | 
             
                results_state = gr.State()
         | 
| 220 |  | 
| 221 | 
             
                with gr.Row():
         | 
|  | |
| 222 | 
             
                    with gr.Column():
         | 
| 223 | 
             
                        gr.Markdown("### Experiment 1")
         | 
| 224 | 
            -
                        conc1 = gr. | 
| 225 | 
            -
                        flow_rate1 = gr. | 
| 226 | 
            -
                        voltage1 = gr. | 
| 227 | 
             
                        solvent1 = gr.Dropdown(['DMAc', 'CHCl3'], value='DMAc', label='Solvent')
         | 
| 228 |  | 
| 229 | 
             
                        gr.Markdown("### Experiment 2")
         | 
| 230 | 
            -
                        conc2 = gr. | 
| 231 | 
            -
                        flow_rate2 = gr. | 
| 232 | 
            -
                        voltage2 = gr. | 
| 233 | 
             
                        solvent2 = gr.Dropdown(['DMAc', 'CHCl3'], value='CHCl3', label='Solvent')
         | 
| 234 | 
            -
             | 
|  | |
| 235 | 
             
                    with gr.Column():
         | 
| 236 | 
            -
                        prior_experiments = gr.DataFrame(value= | 
| 237 | 
             
                        results_df = gr.DataFrame(label="Your Results")
         | 
| 238 | 
             
                        perf_plot = gr.Plot(label="Performance Comparison")
         | 
| 239 |  | 
|  | |
| 240 | 
             
                with gr.Row():
         | 
| 241 | 
             
                    submit_btn = gr.Button("Submit")
         | 
| 242 | 
             
                    reset_btn = gr.Button("Reset Results")
         | 
| 243 |  | 
| 244 | 
            -
                # Add invisible text input components to match the predict function signature
         | 
| 245 | 
            -
                text1 = gr.Textbox(visible=False)
         | 
| 246 | 
            -
                text2 = gr.Textbox(visible=False)
         | 
| 247 | 
            -
                
         | 
| 248 | 
             
                # Connect the submit button to the predict function
         | 
| 249 | 
             
                submit_btn.click(
         | 
| 250 | 
             
                    fn=predict,
         | 
| 251 | 
             
                    inputs=[
         | 
| 252 | 
            -
                        results_state,
         | 
| 253 | 
            -
                         | 
| 254 | 
            -
                         | 
| 255 | 
             
                    ],
         | 
| 256 | 
             
                    outputs=[results_state, prior_experiments, results_df, perf_plot]
         | 
| 257 | 
             
                )
         | 
|  | |
| 1 | 
             
            import numpy as np
         | 
| 2 | 
             
            import gradio as gr
         | 
| 3 | 
             
            import pickle
         | 
|  | |
| 4 | 
             
            import plotly.graph_objects as go
         | 
| 5 | 
             
            import plotly.express as px
         | 
|  | |
| 6 | 
             
            import pandas as pd
         | 
| 7 |  | 
| 8 | 
            +
            # Define styling for success/failure highlighting
         | 
|  | |
| 9 | 
             
            def highlight_success(val):
         | 
| 10 | 
             
                color = 'lightgreen' if val == 'Success' else 'lightcoral'
         | 
| 11 | 
             
                return f'color:white;background-color: {color}'
         | 
| 12 |  | 
| 13 | 
            +
            # Simulation function for electrospraying
         | 
| 14 | 
             
            def sim_espray_constrained(x, noise_se=None):
         | 
| 15 | 
            +
                # Ensure x is a numpy array with float data type
         | 
| 16 | 
            +
                x = np.array(x, dtype=float)
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                # Ensure x is a 2D array
         | 
| 19 | 
            +
                if x.ndim == 1:
         | 
| 20 | 
            +
                    x = x.reshape(1, -1)
         | 
| 21 | 
            +
                    
         | 
| 22 | 
             
                # Define the equations
         | 
| 23 | 
             
                conc = x[:, 0]
         | 
| 24 | 
             
                flow_rate = x[:, 1]
         | 
|  | |
| 30 | 
             
                exp_con = (np.log(flow_rate) * (solvent - 0.5) + 1.40 >= 0).astype(float)
         | 
| 31 | 
             
                return np.column_stack((diameter, exp_con))
         | 
| 32 |  | 
| 33 | 
            +
            # Initialize experiment data
         | 
| 34 | 
             
            X_init = np.array([[0.5, 15, 10, 0],
         | 
| 35 | 
             
                               [0.5, 0.1, 10, 1],
         | 
| 36 | 
             
                               [3, 20, 15, 0],
         | 
|  | |
| 40 | 
             
            Y_init = sim_espray_constrained(X_init)
         | 
| 41 | 
             
            exp_record_df = pd.DataFrame(X_init, columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent'])
         | 
| 42 | 
             
            exp_record_df['Size (um)'] = Y_init[:, 0]
         | 
|  | |
| 43 | 
             
            exp_record_df['Solvent'] = ['DMAc' if x == 0 else 'CHCl3' for x in exp_record_df['Solvent']]
         | 
| 44 | 
             
            exp_record_df['Feasible?'] = ['Success' if x == 1 else 'Failed' for x in Y_init[:, 1]]
         | 
| 45 | 
            +
            prior_experiments_display = exp_record_df.style.map(highlight_success, subset=['Feasible?']).format(precision=3)
         | 
| 46 |  | 
| 47 | 
            +
            # Functions for data processing and visualization
         | 
|  | |
| 48 | 
             
            def import_results():
         | 
| 49 | 
             
                strategies = ['qEI', 'qEI_vi_mixed_con', 'qEICF_vi_mixed_con', 'rnd']
         | 
| 50 |  | 
|  | |
| 63 | 
             
                return best_distances_df_long
         | 
| 64 |  | 
| 65 | 
             
            def calc_human_performance(df):
         | 
| 66 | 
            +
                # Make a copy of the dataframe to avoid modifying the original
         | 
| 67 | 
            +
                df_copy = df.copy()
         | 
| 68 | 
            +
                
         | 
| 69 | 
             
                # convert back solvent to 0 and 1
         | 
| 70 | 
            +
                df_copy['Solvent'] = [0 if x == 'DMAc' else 1 for x in df_copy['Solvent']]
         | 
| 71 |  | 
| 72 | 
             
                TARGET_SIZE = 3.0  # Example target size
         | 
| 73 | 
            +
                ROUNDS = len(df_copy) // 2
         | 
| 74 |  | 
| 75 | 
            +
                # Ensure all values are numeric
         | 
| 76 | 
            +
                numeric_cols = ['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent']
         | 
| 77 | 
            +
                for col in numeric_cols:
         | 
| 78 | 
            +
                    df_copy[col] = pd.to_numeric(df_copy[col])
         | 
| 79 | 
            +
                
         | 
| 80 | 
            +
                X_human = df_copy[numeric_cols].values
         | 
| 81 |  | 
| 82 | 
             
                X_human_init = X_init.copy()
         | 
| 83 | 
             
                Y_human_init = Y_init.copy()
         | 
|  | |
| 87 | 
             
                for iter in range(ROUNDS + 1):
         | 
| 88 | 
             
                    Y_distance = -np.abs(Y_human_init[:, 0] - TARGET_SIZE)
         | 
| 89 | 
             
                    best_human_distance.append(np.ma.masked_array(Y_distance, mask=~Y_human_init[:, 1].astype(bool)).max())
         | 
| 90 | 
            +
                    
         | 
| 91 | 
            +
                    # Check if we have more data for this iteration
         | 
| 92 | 
            +
                    if 2 * iter < len(X_human):
         | 
| 93 | 
            +
                        # Get the slice of new experiments
         | 
| 94 | 
            +
                        new_x = X_human[2 * iter:min(2 * (iter + 1), len(X_human))]
         | 
| 95 | 
            +
                        
         | 
| 96 | 
            +
                        # Add the new experiments to our dataset
         | 
| 97 | 
            +
                        X_human_init = np.vstack([X_human_init, new_x])
         | 
| 98 | 
            +
                        Y_human_init = np.vstack([Y_human_init, sim_espray_constrained(new_x)])
         | 
| 99 |  | 
| 100 | 
             
                return -np.array(best_human_distance)
         | 
| 101 |  | 
|  | |
| 166 |  | 
| 167 | 
             
                return fig
         | 
| 168 |  | 
| 169 | 
            +
            # Prediction function - simplified signature by removing unnecessary text params
         | 
| 170 | 
            +
            def predict(state, conc1, flow_rate1, voltage1, solvent1, conc2, flow_rate2, voltage2, solvent2):
         | 
| 171 | 
             
                # Get current results storage from state or initialize if None
         | 
| 172 | 
             
                if state is None:
         | 
| 173 | 
             
                    results_storage = pd.DataFrame(columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
         | 
|  | |
| 177 | 
             
                solvent_value1 = 0 if solvent1 == 'DMAc' else 1
         | 
| 178 | 
             
                solvent_value2 = 0 if solvent2 == 'DMAc' else 1
         | 
| 179 |  | 
| 180 | 
            +
                # Process inputs and get predictions
         | 
| 181 | 
             
                inputs1 = np.array([[conc1, flow_rate1, voltage1, solvent_value1]])
         | 
| 182 | 
             
                inputs2 = np.array([[conc2, flow_rate2, voltage2, solvent_value2]])
         | 
|  | |
|  | |
| 183 | 
             
                results1 = sim_espray_constrained(inputs1)
         | 
| 184 | 
             
                results2 = sim_espray_constrained(inputs2)
         | 
| 185 |  | 
| 186 | 
            +
                # Format and store results
         | 
| 187 | 
            +
                results_df = pd.DataFrame([
         | 
| 188 | 
            +
                    [conc1, flow_rate1, voltage1, solvent_value1, results1[0, 0], results1[0, 1]],
         | 
| 189 | 
            +
                    [conc2, flow_rate2, voltage2, solvent_value2, results2[0, 0], results2[0, 1]]
         | 
| 190 | 
            +
                ], columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 191 |  | 
| 192 | 
             
                results_df['Solvent'] = ['DMAc' if x == 0 else 'CHCl3' for x in results_df['Solvent']]
         | 
| 193 | 
             
                results_df['Feasible?'] = ['Success' if x == 1 else 'Failed' for x in results_df['Feasible?']]
         | 
|  | |
| 195 | 
             
                results_storage = pd.concat([results_storage, results_df], ignore_index=True)
         | 
| 196 | 
             
                results_display = results_storage.style.map(highlight_success, subset=['Feasible?']).format(precision=3)
         | 
| 197 |  | 
| 198 | 
            +
                # Return updated state and UI updates
         | 
| 199 | 
            +
                return (
         | 
| 200 | 
            +
                    results_storage, 
         | 
| 201 | 
            +
                    gr.DataFrame(value=prior_experiments_display, label="Prior Experiments"),
         | 
| 202 | 
            +
                    gr.DataFrame(value=results_display, label="Your Results"), 
         | 
| 203 | 
            +
                    plot_results(results_storage)
         | 
| 204 | 
            +
                )
         | 
| 205 |  | 
| 206 | 
            +
            # Reset results function
         | 
| 207 | 
             
            def reset_results(state):
         | 
| 208 | 
             
                results_storage = pd.DataFrame(columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
         | 
| 209 | 
            +
                return (
         | 
| 210 | 
            +
                    results_storage, 
         | 
| 211 | 
            +
                    gr.DataFrame(value=prior_experiments_display, label="Prior Experiments"),
         | 
| 212 | 
            +
                    gr.DataFrame(value=results_storage.style.map(highlight_success, subset=['Feasible?']).format(precision=3), label="Your Results"), 
         | 
| 213 | 
            +
                    plot_results(results_storage)
         | 
| 214 | 
            +
                )
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 215 |  | 
| 216 | 
            +
            # Application description
         | 
| 217 | 
            +
            description = "<h3>Welcome, challenger!</h3><p> If you think you may perform better than <strong>CCBO</strong>, try this interactive game to optimize electrospray! Rules are simple: <ul><li>Examine carefully the initial experiments you have on the right (or below if you're using your phone), remember, your target size is <u><i><strong>3.000 um</strong></i></u> ----></li><li>Select your parameters, you have <strong>2</strong> experiments (chances) in each round, use them wisely! </li><li>Click <strong>Submit</strong> to see the results, reflect and improve your selection!</li><li>Repeat the process for <strong>5</strong> rounds to see if you can beat CCBO!</li></ul></p><p>Your data will not be stored, so feel free to play again, good luck!</p>"
         | 
| 218 |  | 
| 219 | 
            +
            # Create Gradio interface
         | 
| 220 | 
             
            with gr.Blocks() as demo:
         | 
| 221 | 
            +
                gr.Markdown("## Human vs CCBO Campaign - Optimize Electrospray")
         | 
|  | |
| 222 | 
             
                gr.Markdown(description)
         | 
| 223 |  | 
| 224 | 
             
                # Add state component to store user-specific results
         | 
| 225 | 
             
                results_state = gr.State()
         | 
| 226 |  | 
| 227 | 
             
                with gr.Row():
         | 
| 228 | 
            +
                    # Input parameters column
         | 
| 229 | 
             
                    with gr.Column():
         | 
| 230 | 
             
                        gr.Markdown("### Experiment 1")
         | 
| 231 | 
            +
                        conc1 = gr.Slider(minimum=0.05, maximum=5.0, value=1.2, step=0.001, label="Concentration (%w/v)")
         | 
| 232 | 
            +
                        flow_rate1 = gr.Slider(minimum=0.01, maximum=60.0, value=20.0, step=0.001, label="Flow Rate (mL/h)")
         | 
| 233 | 
            +
                        voltage1 = gr.Slider(minimum=10.0, maximum=18.0, value=15.0, step=0.001, label="Voltage (kV)")
         | 
| 234 | 
             
                        solvent1 = gr.Dropdown(['DMAc', 'CHCl3'], value='DMAc', label='Solvent')
         | 
| 235 |  | 
| 236 | 
             
                        gr.Markdown("### Experiment 2")
         | 
| 237 | 
            +
                        conc2 = gr.Slider(minimum=0.05, maximum=5.0, value=2.8, step=0.001, label="Concentration (%w/v)")
         | 
| 238 | 
            +
                        flow_rate2 = gr.Slider(minimum=0.01, maximum=60.0, value=20.0, step=0.001, label="Flow Rate (mL/h)")
         | 
| 239 | 
            +
                        voltage2 = gr.Slider(minimum=10.0, maximum=18.0, value=15.0, step=0.001, label="Voltage (kV)")
         | 
| 240 | 
             
                        solvent2 = gr.Dropdown(['DMAc', 'CHCl3'], value='CHCl3', label='Solvent')
         | 
| 241 | 
            +
                    
         | 
| 242 | 
            +
                    # Results display column
         | 
| 243 | 
             
                    with gr.Column():
         | 
| 244 | 
            +
                        prior_experiments = gr.DataFrame(value=prior_experiments_display, label="Prior Experiments")
         | 
| 245 | 
             
                        results_df = gr.DataFrame(label="Your Results")
         | 
| 246 | 
             
                        perf_plot = gr.Plot(label="Performance Comparison")
         | 
| 247 |  | 
| 248 | 
            +
                # Action buttons
         | 
| 249 | 
             
                with gr.Row():
         | 
| 250 | 
             
                    submit_btn = gr.Button("Submit")
         | 
| 251 | 
             
                    reset_btn = gr.Button("Reset Results")
         | 
| 252 |  | 
|  | |
|  | |
|  | |
|  | |
| 253 | 
             
                # Connect the submit button to the predict function
         | 
| 254 | 
             
                submit_btn.click(
         | 
| 255 | 
             
                    fn=predict,
         | 
| 256 | 
             
                    inputs=[
         | 
| 257 | 
            +
                        results_state, 
         | 
| 258 | 
            +
                        conc1, flow_rate1, voltage1, solvent1,
         | 
| 259 | 
            +
                        conc2, flow_rate2, voltage2, solvent2
         | 
| 260 | 
             
                    ],
         | 
| 261 | 
             
                    outputs=[results_state, prior_experiments, results_df, perf_plot]
         | 
| 262 | 
             
                )
         |