Last active
February 20, 2021 21:01
-
-
Save dpgoldenberg/be5a5819667834d8d98cf19f2e7bb45a to your computer and use it in GitHub Desktop.
Simulation of Experiment 2, for Biol 3515/Chem 3515
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Gist title |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
code_dict = {'0GXY02': {'bsa_init': 0.6302333104590135, | |
'coli_pr': 0.02045782192688574, | |
'coli_na': 0.028069149086216168, | |
'curve_a': 7.628994080420339, | |
'curve_b': 79.97496754863742, | |
'brad_bkg': 0.21581014164096682}, | |
'DD0371': {'bsa_init': 1.4101514851390147, | |
'coli_pr': 0.03767113005479135, | |
'coli_na': 0.021727273260539227, | |
'curve_a': 5.23824112385952, | |
'curve_b': 49.18698368309747, | |
'brad_bkg': 0.12212849875848655}, | |
'X5FX87': {'bsa_init': 0.559451632519114, | |
'coli_pr': 0.020957560308467255, | |
'coli_na': 0.033079965658528755, | |
'curve_a': 5.159240302043729, | |
'curve_b': 53.65818471296826, | |
'brad_bkg': 0.1669654048420614}, | |
'FG188G': {'bsa_init': 0.6211684083261407, | |
'coli_pr': 0.03231224514606566, | |
'coli_na': 0.026218962171618555, | |
'curve_a': 4.009863518780299, | |
'curve_b': 35.88984445266249, | |
'brad_bkg': 0.13737469662134283}, | |
'34P10Q': {'bsa_init': 1.376685391815398, | |
'coli_pr': 0.02528454078577475, | |
'coli_na': 0.026161032352047427, | |
'curve_a': 7.13139579450825, | |
'curve_b': 70.80233394254888, | |
'brad_bkg': 0.2968686705047867}, | |
'Y4N6KZ': {'bsa_init': 1.2751079559604972, | |
'coli_pr': 0.03820446885747479, | |
'coli_na': 0.024273280915330177, | |
'curve_a': 2.8301783474888142, | |
'curve_b': 21.632619148181345, | |
'brad_bkg': 0.2027842300758498}, | |
'W5XM03': {'bsa_init': 1.1098918536440845, | |
'coli_pr': 0.02945901590496184, | |
'coli_na': 0.03527986928720504, | |
'curve_a': 8.758868767465232, | |
'curve_b': 96.11014225234263, | |
'brad_bkg': 0.16024179290090854}, | |
'9V51PV': {'bsa_init': 1.476152886320615, | |
'coli_pr': 0.021399381745099116, | |
'coli_na': 0.02969956384856809, | |
'curve_a': 3.2098048344317665, | |
'curve_b': 22.17740636850572, | |
'brad_bkg': 0.17408720658127075}, | |
'942913': {'bsa_init': 1.1354799906443611, | |
'coli_pr': 0.038162190388555825, | |
'coli_na': 0.028272147919856546, | |
'curve_a': 4.284229436479604, | |
'curve_b': 41.84982405373382, | |
'brad_bkg': 0.18584116162074565}, | |
'N898UN': {'bsa_init': 0.7268642396965732, | |
'coli_pr': 0.02340531599438036, | |
'coli_na': 0.03737296299646256, | |
'curve_a': 2.8702311632457067, | |
'curve_b': 24.509429893330523, | |
'brad_bkg': 0.10255978643675266}, | |
'H4CGP6': {'bsa_init': 0.899176843584752, | |
'coli_pr': 0.038362154215435075, | |
'coli_na': 0.03077414844871194, | |
'curve_a': 4.007799049683165, | |
'curve_b': 28.920431744257, | |
'brad_bkg': 0.2591649173049998}, | |
'13KE9N': {'bsa_init': 1.4006400447689598, | |
'coli_pr': 0.02128436030706538, | |
'coli_na': 0.023598989771235163, | |
'curve_a': 1.9842431271785594, | |
'curve_b': 9.846622888606351, | |
'brad_bkg': 0.21255397035988005}, | |
'31PQ53': {'bsa_init': 1.3030738346518123, | |
'coli_pr': 0.028280419363943814, | |
'coli_na': 0.038391045658602754, | |
'curve_a': 3.575812623335131, | |
'curve_b': 27.90323833988697, | |
'brad_bkg': 0.2532292114888188}, | |
'KK644G': {'bsa_init': 1.44262262813991, | |
'coli_pr': 0.024414664331468473, | |
'coli_na': 0.03970182089468849, | |
'curve_a': 8.295133070123354, | |
'curve_b': 90.51583976879485, | |
'brad_bkg': 0.18424263040479463}, | |
'2TNA45': {'bsa_init': 0.6573819881083176, | |
'coli_pr': 0.0295529286164187, | |
'coli_na': 0.032997819386657995, | |
'curve_a': 3.243219996073975, | |
'curve_b': 20.58218884087249, | |
'brad_bkg': 0.14928077253905697}, | |
'N6AADQ': {'bsa_init': 0.9165464914272847, | |
'coli_pr': 0.0208135230951118, | |
'coli_na': 0.0270873260762834, | |
'curve_a': 5.126060104627027, | |
'curve_b': 49.212607378598726, | |
'brad_bkg': 0.14632573829835882}, | |
'SV22HX': {'bsa_init': 1.2102861771752291, | |
'coli_pr': 0.02149718745729806, | |
'coli_na': 0.033603419002110536, | |
'curve_a': 2.169141768180557, | |
'curve_b': 9.187564457478402, | |
'brad_bkg': 0.13652892317839213}, | |
'VS8S0J': {'bsa_init': 0.8210403031893194, | |
'coli_pr': 0.03214794331807181, | |
'coli_na': 0.03755449581376081, | |
'curve_a': 2.7969844949982896, | |
'curve_b': 16.4075363572732, | |
'brad_bkg': 0.18558565154117743}, | |
'4U2RCD': {'bsa_init': 0.7469661758621895, | |
'coli_pr': 0.03210384852556212, | |
'coli_na': 0.03297312294071977, | |
'curve_a': 2.156737850263122, | |
'curve_b': 14.403610349405195, | |
'brad_bkg': 0.2869805591773925}, | |
'ZCRTWU': {'bsa_init': 1.3020990551424825, | |
'coli_pr': 0.036710243358538966, | |
'coli_na': 0.029314088966354887, | |
'curve_a': 7.289548559659246, | |
'curve_b': 79.7497851901377, | |
'brad_bkg': 0.20324338496663644}, | |
'7182Y1': {'bsa_init': 1.1147758578790397, | |
'coli_pr': 0.02686741656253151, | |
'coli_na': 0.031419781501426165, | |
'curve_a': 3.2516262455678944, | |
'curve_b': 25.12834609400917, | |
'brad_bkg': 0.19758276403588176}, | |
'W8Y4P3': {'bsa_init': 1.2173774020841588, | |
'coli_pr': 0.02387166620444361, | |
'coli_na': 0.029855130181537716, | |
'curve_a': 8.528339986272549, | |
'curve_b': 94.60510182724437, | |
'brad_bkg': 0.29618691038962786}, | |
'J9PWB4': {'bsa_init': 0.764189959208705, | |
'coli_pr': 0.020779208498265186, | |
'coli_na': 0.026119937104039558, | |
'curve_a': 7.10698263726603, | |
'curve_b': 71.09173203849825, | |
'brad_bkg': 0.16283605321341776}, | |
'43479S': {'bsa_init': 0.6405217918195514, | |
'coli_pr': 0.020302646047041423, | |
'coli_na': 0.03664699312309894, | |
'curve_a': 6.593018254224056, | |
'curve_b': 74.08008540507063, | |
'brad_bkg': 0.1480061012211324}, | |
'MYX1AX': {'bsa_init': 1.324833083691523, | |
'coli_pr': 0.037507549113220434, | |
'coli_na': 0.02750541064719787, | |
'curve_a': 6.272254329896093, | |
'curve_b': 58.12404333640464, | |
'brad_bkg': 0.26349046432563117}, | |
'S0E0YV': {'bsa_init': 0.5519978390278825, | |
'coli_pr': 0.020219007481144108, | |
'coli_na': 0.022951831385046556, | |
'curve_a': 6.727483299840219, | |
'curve_b': 64.3491054091928, | |
'brad_bkg': 0.2109578898211646}, | |
'DFKPU9': {'bsa_init': 0.5780804111841383, | |
'coli_pr': 0.035962532226912314, | |
'coli_na': 0.03865254889537133, | |
'curve_a': 4.083122690178636, | |
'curve_b': 35.137770058310714, | |
'brad_bkg': 0.1099716479937468}, | |
'9RFXYW': {'bsa_init': 0.5840088935776985, | |
'coli_pr': 0.025060748749074303, | |
'coli_na': 0.028553407441499038, | |
'curve_a': 1.8180500300948523, | |
'curve_b': 8.173002694225502, | |
'brad_bkg': 0.23280671380526333}, | |
'88PTV8': {'bsa_init': 0.6231275554173443, | |
'coli_pr': 0.02883746390785842, | |
'coli_na': 0.027125170963581857, | |
'curve_a': 7.570713178623864, | |
'curve_b': 85.2025846227128, | |
'brad_bkg': 0.24376978590583756}, | |
'H0X54M': {'bsa_init': 1.1321608009884556, | |
'coli_pr': 0.0385521238979127, | |
'coli_na': 0.03492765707915852, | |
'curve_a': 4.80734250970189, | |
'curve_b': 47.48176109145393, | |
'brad_bkg': 0.17255058087818656}, | |
'KD1K2N': {'bsa_init': 0.93302708835257, | |
'coli_pr': 0.03810359867424335, | |
'coli_na': 0.039373415170982154, | |
'curve_a': 6.971818997674599, | |
'curve_b': 74.67099883372816, | |
'brad_bkg': 0.1309919905971541}, | |
'23W0N6': {'bsa_init': 0.6482481699668515, | |
'coli_pr': 0.03597725617249658, | |
'coli_na': 0.027584702873477467, | |
'curve_a': 4.967113767289612, | |
'curve_b': 44.45956548525093, | |
'brad_bkg': 0.2810893702596993}, | |
'GQ5P11': {'bsa_init': 1.1277885478456056, | |
'coli_pr': 0.03941397156292144, | |
'coli_na': 0.03461178123080865, | |
'curve_a': 8.161992763569723, | |
'curve_b': 91.65048116557341, | |
'brad_bkg': 0.2107638583476281}, | |
'597J70': {'bsa_init': 1.1365077115146103, | |
'coli_pr': 0.027385812947625533, | |
'coli_na': 0.02622429133424256, | |
'curve_a': 7.3277594095638445, | |
'curve_b': 81.98070594169553, | |
'brad_bkg': 0.18827152305933278}, | |
'77YE98': {'bsa_init': 0.5963367750165631, | |
'coli_pr': 0.032655092026546456, | |
'coli_na': 0.024988468904814275, | |
'curve_a': 8.502338778781453, | |
'curve_b': 87.69796000054274, | |
'brad_bkg': 0.17526926659291908}, | |
'994A4U': {'bsa_init': 0.570985042171707, | |
'coli_pr': 0.025353537885538697, | |
'coli_na': 0.021490311974125587, | |
'curve_a': 8.52267011879738, | |
'curve_b': 99.50445959145006, | |
'brad_bkg': 0.24570163717107646}, | |
'22NZ8S': {'bsa_init': 0.9509898167137367, | |
'coli_pr': 0.03143947404778345, | |
'coli_na': 0.024006452599770123, | |
'curve_a': 2.3281500642172497, | |
'curve_b': 5.7608664652106185, | |
'brad_bkg': 0.20818558044013602}, | |
'33VZHV': {'bsa_init': 1.4058631822395942, | |
'coli_pr': 0.0373458404174298, | |
'coli_na': 0.024709811656972162, | |
'curve_a': 5.982193055726704, | |
'curve_b': 54.507989580099796, | |
'brad_bkg': 0.12465571443314515}, | |
'YD34E7': {'bsa_init': 1.4251831768823449, | |
'coli_pr': 0.03979283010807402, | |
'coli_na': 0.023466399008471604, | |
'curve_a': 5.662020644704536, | |
'curve_b': 51.946138776999106, | |
'brad_bkg': 0.1000674305851464}, | |
'B4EV54': {'bsa_init': 1.0613831943977985, | |
'coli_pr': 0.03412782658362859, | |
'coli_na': 0.0365328039154178, | |
'curve_a': 5.480578184396049, | |
'curve_b': 59.22235384904483, | |
'brad_bkg': 0.24923821797427856}, | |
'QXQEA0': {'bsa_init': 1.452191010481251, | |
'coli_pr': 0.03749655741528499, | |
'coli_na': 0.0206458168695719, | |
'curve_a': 7.61201780339441, | |
'curve_b': 85.99366245627897, | |
'brad_bkg': 0.1663318114344157}, | |
'RCE9Z2': {'bsa_init': 1.4604226493305035, | |
'coli_pr': 0.03165903021438017, | |
'coli_na': 0.025043850037061718, | |
'curve_a': 2.346241287267522, | |
'curve_b': 17.1769935120656, | |
'brad_bkg': 0.2833063738696384}, | |
'W382SW': {'bsa_init': 1.038445633316786, | |
'coli_pr': 0.038586439441352136, | |
'coli_na': 0.02681400144547896, | |
'curve_a': 3.73871352496779, | |
'curve_b': 32.58280973396393, | |
'brad_bkg': 0.24368297263640382}, | |
'Y1UUUA': {'bsa_init': 0.8729008931178693, | |
'coli_pr': 0.03157452594746815, | |
'coli_na': 0.021987245586348642, | |
'curve_a': 4.37913797898254, | |
'curve_b': 33.19143710008858, | |
'brad_bkg': 0.14328566320524383}, | |
'240125': {'bsa_init': 1.1580376473676264, | |
'coli_pr': 0.03154744238990789, | |
'coli_na': 0.025978305481204698, | |
'curve_a': 2.1520860602697325, | |
'curve_b': 10.922141767168352, | |
'brad_bkg': 0.2471519026095803}, | |
'0P20E8': {'bsa_init': 1.0222939756638887, | |
'coli_pr': 0.03882095525311787, | |
'coli_na': 0.02490080412321647, | |
'curve_a': 4.116207451793762, | |
'curve_b': 37.88070290591054, | |
'brad_bkg': 0.2276461792673584}, | |
'CTZKSB': {'bsa_init': 0.9043556567257972, | |
'coli_pr': 0.02071372149014222, | |
'coli_na': 0.03533266822319614, | |
'curve_a': 6.551683617811493, | |
'curve_b': 73.40920582461186, | |
'brad_bkg': 0.20424716060973047}, | |
'K60820': {'bsa_init': 1.0268399981969911, | |
'coli_pr': 0.0322084380814433, | |
'coli_na': 0.033458076385320765, | |
'curve_a': 5.74675831527346, | |
'curve_b': 50.39276748870875, | |
'brad_bkg': 0.2569968969963384}, | |
'WE21H5': {'bsa_init': 1.1047891362709161, | |
'coli_pr': 0.030276340460969622, | |
'coli_na': 0.020162556978298336, | |
'curve_a': 7.028432486851976, | |
'curve_b': 73.01961704325916, | |
'brad_bkg': 0.2299952113925479}, | |
'N180MF': {'bsa_init': 1.1881707717833925, | |
'coli_pr': 0.0378287611835832, | |
'coli_na': 0.02999539373677519, | |
'curve_a': 5.623675669865823, | |
'curve_b': 54.45278003042385, | |
'brad_bkg': 0.14742752267277526}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: exp_2_sim | |
channels: | |
- conda-forge | |
- defaults | |
- conda-forge/label/broken | |
dependencies: | |
- python=3.7.3 | |
- numpy=1.16.4 | |
- ipython=7.6.1 | |
- ipywidgets=7.5.0 | |
- voila = 0.2.6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Module for import into Jupyter for simulation of Experiment 2 | |
## in Biology 3515/Chem 3515 at the University of Utah, Spring 2021 | |
## https://goldenberg.biology.utah.edu/courses/biol3515/ | |
## David P. Goldenberg, January 2021 | |
## goldenberg@biology.utah.edu | |
import numpy as np | |
import random as rand | |
import ipywidgets as widgets | |
from IPython.display import display, HTML | |
display(HTML("<style>div.output_scroll { height: 100ex; }</style>")) | |
from time import sleep | |
import threading | |
from multiprocessing import Process | |
from labcodes import codes | |
from codeDictionary import code_dict | |
def make_code_dict(): | |
'''Function to build code dictionary specific to this experiment | |
Don't actually call this function when loading the module, or else | |
the dictionary will change with every execution. Instead save value | |
of dictionary in this module.''' | |
for code in codes: | |
bsa_init = 0.5 + rand.random() | |
coli_pr = 0.02 + 0.02*rand.random() | |
coli_na = 0.02 + 0.02*rand.random() | |
brad_bkg = 0.1 + 0.2*rand.random() | |
b = 5 + 95*rand.random() | |
a = 0.075*b + 1 + rand.random() | |
code_dict[code]={} | |
code_dict[code]['bsa_init']=bsa_init | |
code_dict[code]['coli_pr'] = coli_pr | |
code_dict[code]['coli_na']=coli_na | |
code_dict[code]['curve_a']=a | |
code_dict[code]['curve_b']=b | |
code_dict[code]['brad_bkg']=brad_bkg | |
class Tube(): | |
'''Tube class for putting stuff in''' | |
def __init__(self,vol=0.0,vol_n=0,max_vol=1.0,conc={}): | |
self.vol = vol # actual volume | |
self.vol_n= vol_n # nominal volume, reflecting pipette settings, vs actual delivered volumes | |
self.max_vol = max_vol # max volume of tube | |
self.conc = conc # concentrations of compounds | |
##-------------Create the tube dictionary-------------------# | |
tube_names = ['std 1','std 2','std 3','std 4','std 5','std 6','std 7','std 8','std 9', | |
'E.coli 1', 'E.coli 2','E.coli 3'] | |
tube_dict = {} | |
conc_dict = {'BSA':0.0, 'coliExtr':0.0,'bradford':0.0} | |
for name in tube_names: | |
tube_dict[name] = Tube() | |
tube_dict[name].conc = conc_dict.copy() | |
# A special tube for the dilute BSA | |
dil_bsa = Tube(conc=0,vol=0) | |
##--------------Some global variables ----------------# | |
# standard deviation for pipette errors | |
# Errors are based on max volume of the pipette used | |
pip_sigma = 0.04 | |
# Total time and number of steps for abs reading to settle | |
t_tot = 2 | |
steps = 25 | |
# Background absorbance of blank solutions | |
a260_bkg = 0.07 | |
a280_bkg = 0.03 | |
##----------------Functions-----------------## | |
def tube_reset(): | |
'''Reset volumes and concentrations in all of the tubes''' | |
for tube in tube_dict: | |
tube_dict[tube].vol = 0 | |
tube_dict[tube].vol_n = 0 | |
tube_dict[tube].conc['BSA'] = 0 | |
tube_dict[tube].conc['coliExtr'] = 0 | |
tube_dict[tube].conc['bradford'] = 0 | |
dil_bsa.vol = 0 | |
dil_bsa.vol_n = 0 | |
dil_bsa.conc = 0 | |
vol_table_update() | |
dilbsa_vol_update(0) | |
def a260_280(prot_conc,na_conc): | |
'''Calculate absorbance for protein and nucleic acid | |
solutions, using Warburg/Christian values''' | |
e_p260=0.512 | |
e_p280 = 0.894 | |
e_na260=22.1 | |
e_na280=10.8 | |
a260= prot_conc*e_p260 + na_conc*e_na260 | |
a280 = prot_conc*e_p280 + na_conc*e_na280 | |
return a260,a280 | |
def on_code_ch(value): | |
'''Respond to change in the code entered in the code box''' | |
if lab_code.value != '' and lab_code.value not in codes: | |
code_warn.value = '<span style="color:red;">Invalid code</span>' | |
else: | |
code_warn.value ='' | |
read_uvabs_butt.button_style = 'success' | |
read_uvabs_butt.description='Read Absorbance' | |
deliver_butt1.button_style = 'success' | |
deliver_butt1.description='Pipette!' | |
deliver_butt2.description='Pipette!' | |
deliver_butt2.button_style = 'success' | |
read_bradford_butt.button_style = 'success' | |
read_bradford_butt.description='Read Absorbance' | |
def on_wl_ch_a(value): | |
'''Respond to change in the wavelength widget''' | |
global zero_set | |
read_uvabs(0) | |
def on_wl_ch_b(value): | |
'''Respond to change in the wavelength widget''' | |
global zero_set | |
read_bradford(0) | |
def zero(change): | |
'''Respond to the Zero button''' | |
global zero_set | |
zero_set += abs_read | |
abs_update(0) | |
def damp_sin(t,nu,tau): | |
'''damped sine function to simulate settling | |
of absorbance reading. Input arguments: | |
t: time | |
nu: sine-function frequency | |
tau: exponential-decay time constant | |
''' | |
d_sin = np.exp(-t/tau)*np.sin(t*nu*2*np.pi) | |
return d_sin | |
def abs_update(absb): | |
'''function to set global abs_read variable and | |
Updates absorbance display, with settling time | |
Input arguments: | |
absb: settled absorbance value | |
global variables used: | |
t_tot: total time for reading to settle | |
steps: number of times to update display | |
as it settles. | |
''' | |
global abs_read | |
abs_read = absb | |
tau = 0.2*t_tot | |
nu = 5/t_tot | |
for i in range(steps+1): | |
t = t_tot*i/steps | |
abs_d = absb*(1+damp_sin(t,nu,tau)) | |
sleep(t_tot/steps) | |
abs_show(abs_d) | |
def abs_show(absb): | |
'''function to displays variable in the spec_dislp HTML widget''' | |
spec_displ.value='<h2> Abs: <span style="color:red;">\ | |
{:.3f}'.format(absb) + '</span></h>' | |
def read_uvabs(change): | |
'''function to responds to Read Abs button for Part A, uv abs''' | |
# check to see if there is a valid lab code | |
if lab_code.value not in codes: | |
read_uvabs_butt.description='Enter valid lab code' | |
read_uvabs_butt.button_style = 'warning' | |
return | |
a595 = 0 | |
if UV_samp.value == 'BSA': | |
# for BSA sample use specific extinction coefficients | |
pr = code_dict[lab_code.value]['bsa_init'] | |
e280 = 0.67 # mg/ml ext coef | |
e260 = 0.6*e280 | |
a260 = pr*e260 | |
a280 = pr*e280 | |
if UV_samp.value=='E. coli extract': | |
# for coli extract, use Warburg/Christian estimate | |
pr = code_dict[lab_code.value]['coli_pr'] | |
na = code_dict[lab_code.value]['coli_na'] | |
a260,a280 = a260_280(pr,na) | |
if UV_samp.value == 'H2O': | |
a260 = 0.0 | |
a280 = 0.0 | |
if wl_a.value == '260 nm': | |
abs_update(a260+a260_bkg-zero_set) | |
elif wl_a.value == '280 nm': | |
abs_update(a280+a280_bkg-zero_set) | |
elif wl_a.value == '595 nm': | |
abs_update(a595) | |
def dilbsa_vol_update(vol): | |
'''function to update dilute bsa HTML widget''' | |
vol = vol/1000 | |
html_str = ''' | |
<style> | |
table, th, td { | |
border: 1px solid black; | |
} | |
th, td { | |
padding: 5px; | |
} | |
table, {border-collapse: collapse;} | |
</style> | |
<table> | |
<tr> | |
<th style="width:150px"> Dilute BSA Volume </th> | |
''' | |
html_str += f'<td style="width:100px">{vol:.3f} mL</td></tr>' | |
dilbsa_vol.value=html_str | |
def vol_table_update(): | |
'''function to update the table of volumes for the bradford assay''' | |
html_str = ''' | |
<style> | |
table, th, td { | |
border: 1px solid black; | |
} | |
th, td { | |
padding: 5px; | |
} | |
table, {border-collapse: collapse;} | |
</style> | |
<table> | |
<tr> | |
<th style="width:100px"> Tube </th> | |
<th style="width:100px"> Volume </th> | |
</tr> | |
''' | |
for name in tube_names: | |
vol = tube_dict[name].vol_n | |
html_str += f'<tr><td>{name}</td><td>{vol:.0f} </td></tr>\n' | |
html_str += '</table>' | |
vol_table.value=html_str | |
def on_pipette_ch(change): | |
'''Function to changes volume parameters when pipette is changed.''' | |
pip_vol.max = 1000.0 | |
if pipette.value == 1000.0: | |
pip_vol.min = 200.0 | |
pip_vol.max = 1000.0 | |
pip_vol.step = 10.0 | |
elif pipette.value == 200.0: | |
pip_vol.min = 20.0 | |
pip_vol.max = 200.0 | |
pip_vol.step = 1.0 | |
elif pipette.value == 20.0: | |
pip_vol.min = 1.0 | |
pip_vol.max = 20.0 | |
pip_vol.step = 0.1 | |
pip_vol.value = pip_vol.max | |
def deliver1(change): | |
'''function for deliver button for bsa dilution''' | |
# check for valid lab code | |
if lab_code.value not in codes: | |
deliver_butt1.description='Enter valid lab code' | |
deliver_butt1.button_style = 'warning' | |
return | |
bsa_conc = code_dict[lab_code.value]['bsa_init'] | |
# get pipette err from normal distr | |
err_pipette = pipette.value*rand.normalvariate(0,pip_sigma) | |
vol = pip_vol.value+err_pipette | |
# save old volumes and calculate new volume | |
vol_old = dil_bsa.vol | |
vol_new = vol_old + vol | |
dil_bsa.vol = vol_new | |
dil_bsa.vol_n += pip_vol.value | |
# calculate increment to amount of BSA in tube | |
bsa_incr = 0 | |
if solns1.value == 'BSA': | |
bsa_incr = bsa_conc*pip_vol.value | |
# update concentration | |
conc_old = dil_bsa.conc | |
dil_bsa.conc = (conc_old*vol_old + bsa_incr)/vol_new | |
# update displayed volume of dilute bsa solution | |
dilbsa_vol_update(dil_bsa.vol_n) | |
def empty1(change): | |
'''Respond to Empty button for BSA dilution''' | |
dil_bsa.vol = 0 | |
dil_bsa.vol_n = 0 | |
dil_bsa.conc = 0 | |
dilbsa_vol_update(dil_bsa.vol) | |
def deliver2(change): | |
'''function for bradford tubes deliver button''' | |
# check for valid lab coed | |
if lab_code.value not in codes: | |
deliver_butt2.description='Enter valid lab code' | |
deliver_butt2.button_style = 'warning' | |
return | |
# concentrations of stock soulions | |
bsa_conc = dil_bsa.conc | |
coli_conc = code_dict[lab_code.value]['coli_pr'] | |
bradford_conc = 5 | |
# get pipette err from normal distr | |
err_pipette = pipette.value*rand.normalvariate(0,pip_sigma) | |
# calculate delivered volume | |
vol = pip_vol.value+err_pipette | |
# save old volume and calculate new | |
vol_old = tube_dict[tubes.value].vol | |
vol_new = vol_old + vol | |
# calculate increments of bsa, coli extract and bradford reagent | |
# as volume_delivered*conc | |
bsa_incr = 0 | |
coli_incr = 0 | |
bradford_incr = 0 | |
if solns2.value == 'Dilute BSA': | |
bsa_incr = bsa_conc*vol | |
elif solns2.value == 'E. coli extract': | |
coli_incr = coli_conc*vol | |
elif solns2.value == 'Bradford reagent': | |
bradford_incr = bradford_conc*vol | |
# update BSA conc | |
conc_old = tube_dict[tubes.value].conc['BSA'] | |
conc_new = (conc_old*vol_old + bsa_incr)/vol_new | |
tube_dict[tubes.value].conc['BSA'] = conc_new | |
# update E. coli extract conc | |
conc_old = tube_dict[tubes.value].conc['coliExtr'] | |
conc_new = (conc_old*vol_old + coli_incr)/vol_new | |
tube_dict[tubes.value].conc['coliExtr'] = conc_new | |
# update bradford reag conc | |
conc_old = tube_dict[tubes.value].conc['bradford'] | |
conc_new = (conc_old*vol_old + bradford_incr)/vol_new | |
tube_dict[tubes.value].conc['bradford'] = conc_new | |
#update volumes | |
tube_dict[tubes.value].vol = vol_new | |
tube_dict[tubes.value].vol_n += pip_vol.value | |
vol_table_update() | |
def empty2(change): | |
'''Function to empty selected tube for bradford''' | |
tube_dict[tubes.value].vol = 0 | |
tube_dict[tubes.value].vol_n = 0 | |
tube_dict[tubes.value].conc['BSA'] = 0 | |
tube_dict[tubes.value].conc['coliExtr'] = 0 | |
tube_dict[tubes.value].conc['bradford'] = 0 | |
vol_table_update() | |
def read_bradford(change): | |
'''function to calculate absorbance for bradford | |
using rect hyperbola function with parameters from | |
code dictionary''' | |
# check for valid lab code | |
if lab_code.value not in codes: | |
read_bradford_butt.description='Enter valid lab code' | |
read_bradford_butt.button_style = 'warning' | |
return | |
# check wavelength. Abs = 3 if uv | |
if wl_b.value != '595 nm': | |
abs_update(3.000-zero_set) | |
return | |
a = code_dict[lab_code.value]['curve_a'] | |
b = code_dict[lab_code.value]['curve_b'] | |
brad_conc = tube_dict[tubes.value].conc['bradford'] | |
bkg = brad_conc*code_dict[lab_code.value]['brad_bkg'] | |
pr_conc = tube_dict[tubes.value].conc['coliExtr'] + \ | |
tube_dict[tubes.value].conc['BSA'] | |
mcg_pr = 1000.0*pr_conc | |
absorb = brad_conc*mcg_pr*a/(mcg_pr+b) | |
absorb += bkg-zero_set | |
abs_update(absorb) | |
def background(): | |
'''Background task to keep keep the page from timing out on mybinder''' | |
while True: | |
sleep(0.1) | |
abs_show(abs_read) | |
##----------------------Widgets---------------------------## | |
header_html = """ | |
<h2> Biology 3515/Chemistry 3515 | |
<br> | |
Biological Chemistry Laboratory | |
<br> | |
University of Utah </h2> | |
<h3> Spring 2021 </h3> | |
<h3> Experiment 2: Spectrophotometry and Measurement of Protein Concentration</h3> | |
<p style="font-size:16px"> | |
This web page simulates the procedures to be carried out in Experiment 2. In the first part, UV absorbance is measured for two samples, a solution of bovine serum albumin and an extract prepared from <i>E. coli</i> bacteria. The second part uses the Bradford dye-binding assay to determine protein concentration. For this part, the BSA solution is diluted and used as a calibration standard, and the protein concentration of the <i>E. coli</i> is estimated using the calibration curve. | |
<hr border-width:6px, color:black> | |
<p style="font-size:16px"> | |
For this and the subsequent experiments, each lab group will be assigned a six-character code, which must be entered in the box below in order for the simulation to function. The same code will be used for all of the experiments. This code specifies parameters of the experiment, such as solution concentrations, which will generally be different for different groups. Thus, members of different groups are likely to see significant differences among their results. It is as if, in the lab, everyone was using different sets of reagents. When different members of the same group carry out the simulations, they should obtain similar, but not identical results. Just as in the lab, there will be inevitable experimental errors, particularly in the pipetting operations. The pipetting errors will generally be on the order of 1-2% of the maximum volume of the pipette used. | |
<br> | |
For different parts of the experiment, sets of radio buttons are used to select solutions to pipette from and the tubes to be pipetted into. The tables show the nominal volumes in the tubes as reagents are added. (The volumes shown in the table do not account the expected small errors in pipetting). The tables are provided to help you keep track of where you are in the process. But, they won't tell you WHAT is in the tubes, just the total volume. It's up to you to keep track of what have done! | |
<br><br> | |
If you do not have an assigned code, but want to experiment with this simulation, use the code "0GXY02". | |
<hr border-width:6px, color:black> | |
""" | |
style = {'description_width': 'initial'} | |
header = widgets.HTML( | |
value=header_html | |
) | |
footer = widgets.HTML( | |
value=''' | |
<hr border-width:6px, color:black> | |
David P. Goldenberg, January 2021<br> | |
<a href="mailto:goldenberg@biology.utah.edu" target="new">goldenberg@biology.utah.edu</a><br> | |
School of Biological Sciences, University of Utah<br> | |
Salt Lake City, Utah 8412-0840<br> | |
<a href="https://goldenberg.biology.utah.edu/courses/biol3515/index.shtml" | |
target="new">https://goldenberg.biology.utah.edu/courses/biol3550.</a> | |
''') | |
hrule = widgets.HTML( | |
# general purpose horizontal rule | |
value ='<hr border-width:6px, color:black>') | |
aheader = widgets.HTML( | |
# header for part A | |
value = '<h1> Part A: UV absorbance of protein solutions </h1>' | |
) | |
bheader = widgets.HTML( | |
# header for part B | |
value= '<h1> Part B: Bradford assay </h1>' | |
) | |
b1header = widgets.HTML( | |
# header for part B, part 1 | |
value = '<h2> 1. Dilution of BSA solution</h2>' | |
) | |
b2header = widgets.HTML( | |
# header for part B, part 2 | |
value = '<h2> 2. Set up tubes for Bradford assay</h2>' | |
) | |
b3header = widgets.HTML( | |
# header for part B, part 3 | |
value = '<h2> 3. Read Bradford absorbances</h2>' | |
) | |
code_label = widgets.HTML( | |
value = ''' <h3>Lab code: </h3>''' | |
) | |
lab_code = widgets.Text( | |
# text-entry widget to enter lab code | |
value = '', | |
placeholder='', | |
#description = 'Lab code', | |
layout=widgets.Layout(width='100px',margin='20px 0px 0px 15px') | |
) | |
code_warn = widgets.HTML( | |
# warning when invalid lab code is entered | |
value = '', | |
layout=widgets.Layout(width='200px',margin='15px 50px 15px 0px') | |
) | |
# part A UV absorbance | |
UV_samp = widgets.RadioButtons( | |
# radio buttons to select sample for UV measurement | |
options = ['H2O','BSA', 'E. coli extract'], | |
description='Sample:', | |
#layout=widgets.Layout(width='200px',margin='25px 100px 0px 0px') | |
) | |
wl_a = widgets.Dropdown( | |
# Dropdown to select wavelength for UV measurement | |
options = [('260 nm'),('280 nm'),('595 nm')], | |
description = 'Wavelength:', | |
style = style, | |
layout=widgets.Layout(width='200px') | |
) | |
wl_b = widgets.Dropdown( | |
# Dropdown to select wavelength for bradford | |
options = [('260 nm'),('280 nm'),('595 nm')], | |
description = 'Wavelength:', | |
style = style, | |
layout=widgets.Layout(width='200px') | |
) | |
read_uvabs_butt = widgets.Button( | |
# Button to read absorbance | |
description = 'Read Absorbance', | |
button_style = 'success', | |
#layout=widgets.Layout(width='200px',margin='25px 100px 15px 50px') | |
) | |
spec_displ = widgets.HTML( | |
# spectrophotometer display | |
value='', | |
layout=widgets.Layout(margin='-15px 50px 0px 50px') | |
) | |
zero_butt = widgets.Button( | |
# button to zero absorbance display | |
description = 'Zero', | |
button_style = 'success' | |
) | |
# part B widgets | |
# B1 BSA dilution | |
pipette = widgets.Dropdown( | |
# Choose pipette size | |
options = [('P1000',1000.0),('P200',200.0),('P20',20.0)], | |
description = 'Pipette:', | |
style=style, | |
layout=widgets.Layout(width='150px',margin='0px 0px 0px 50px') | |
) | |
pip_vol = widgets.BoundedFloatText( | |
# Pipette volume setting | |
value = 1000.0, | |
min = 200.0, | |
max = 1000.0, | |
step = 10.0, | |
description = 'Volume set (uL):', | |
style = style, | |
layout=widgets.Layout(width='200px',margin='0px 0px 0px 50px') | |
) | |
deliver_butt1 = widgets.Button( | |
# Button to deliver volume for BSA dilution | |
description = 'Pipette!', | |
button_style = 'success', | |
) | |
empty_butt1 = widgets.Button( | |
# button to empty tube for bsa dilution | |
description = 'Empty', | |
button_style = 'danger', | |
) | |
solns1 = widgets.RadioButtons( | |
# solutions for making dilute bsa | |
options=['H20','BSA'], | |
description='Solutions' | |
) | |
dilbsa_vol = widgets.HTML( | |
# display volume of the dilute bsa solution | |
value = '' | |
) | |
#B2 bradford tube set up | |
tubes= widgets.RadioButtons( | |
# radio buttons to select bradford tubes | |
options=tube_names, | |
description='Tubes:', | |
) | |
solns2 = widgets.RadioButtons( | |
# radiou buttons to select solutions for bradford tubes | |
options = ['H2O','Dilute BSA', 'E. coli extract', 'Bradford reagent'], | |
description='Solution:', | |
layout=widgets.Layout(width='30%',margin='0px 0px 0px 0px') | |
) | |
empty_butt2 = widgets.Button( | |
# button to empty selected bradford tube | |
description = 'Empty', | |
button_style = 'danger', | |
layout=widgets.Layout(width='35%',margin='0px 0px 0px 80px') | |
) | |
tubesVb=widgets.VBox([tubes,empty_butt2], | |
layout=widgets.Layout(width='40%',margin='0px 0px 0px 00px')) | |
vol_table = widgets.HTML( | |
# HTML table of volumes of bradford tubes | |
value = '', | |
layout=widgets.Layout(width='250px') | |
) | |
deliver_butt2 = widgets.Button( | |
# Button to deliver volume for BSA dilution | |
description = 'Pipette!', | |
button_style = 'success', | |
) | |
# B3 Bradford absorbance readings | |
read_bradford_butt = widgets.Button( | |
# Button to read absorbance for bradford | |
description = 'Read Absorbance', | |
button_style = 'success', | |
) | |
#---------------Layout widgets-------------------------# | |
# lab code | |
row0 = widgets.HBox([code_label,lab_code,code_warn]) | |
# uv absorbance | |
row1 = widgets.HBox([UV_samp,wl_a]) | |
row2 = widgets.HBox([read_uvabs_butt,spec_displ,zero_butt]) | |
# dilute bsa | |
row3 = widgets.HBox([solns1,dilbsa_vol,empty_butt1]) | |
row4 = widgets.HBox([deliver_butt1,pipette,pip_vol]) | |
# set up bradford tubes | |
row5 = widgets.HBox([solns2,tubesVb,vol_table]) | |
row6 = widgets.HBox([deliver_butt2,pipette,pip_vol], | |
layout=widgets.Layout(margin='15px 0px 0px 0px')) | |
# read bradford abs | |
row7 = widgets.HBox([tubes,wl_b]) | |
row8 = widgets.HBox([read_bradford_butt,spec_displ,zero_butt]) | |
uvabs_box = widgets.VBox([hrule,aheader,row1,row2,hrule]) | |
bsa_dil_box = widgets.VBox([bheader,b1header,row3,row4]) | |
brad_tube_box = widgets.VBox([hrule,b2header,row5,row6]) | |
brad_abs_box = widgets.VBox([hrule,b3header,row7,row8]) | |
## ----------------Widget actions---------------------------## | |
lab_code.observe(on_code_ch,names=['value']) | |
wl_a.observe(on_wl_ch_a,names=['value']) | |
wl_b.observe(on_wl_ch_b,names=['value']) | |
pipette.observe(on_pipette_ch,names=['value']) | |
read_uvabs_butt.on_click(read_uvabs) | |
zero_butt.on_click(zero) | |
deliver_butt1.on_click(deliver1) | |
empty_butt1.on_click(empty1) | |
deliver_butt2.on_click(deliver2) | |
empty_butt2.on_click(empty2) | |
read_bradford_butt.on_click(read_bradford) | |
##----------------Initialize Widgets--------------------------## | |
tube_reset() | |
abs_update(0) | |
zero_set=0 | |
zero(0) | |
dilbsa_vol_update(0) | |
vol_table_update() | |
##----------------Display Widgets --------------------------## | |
display(header) | |
display(row0) | |
display(uvabs_box) | |
display(bsa_dil_box) | |
display(brad_tube_box) | |
display(brad_abs_box) | |
display(footer) | |
#-----------------Start Background Process-------------------# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
codes =['0GXY02', | |
'DD0371', | |
'X5FX87', | |
'FG188G', | |
'34P10Q', | |
'Y4N6KZ', | |
'W5XM03', | |
'9V51PV', | |
'942913', | |
'N898UN', | |
'H4CGP6', | |
'13KE9N', | |
'31PQ53', | |
'KK644G', | |
'2TNA45', | |
'N6AADQ', | |
'SV22HX', | |
'VS8S0J', | |
'4U2RCD', | |
'ZCRTWU', | |
'7182Y1', | |
'W8Y4P3', | |
'J9PWB4', | |
'43479S', | |
'MYX1AX', | |
'S0E0YV', | |
'DFKPU9', | |
'9RFXYW', | |
'88PTV8', | |
'H0X54M', | |
'KD1K2N', | |
'23W0N6', | |
'GQ5P11', | |
'597J70', | |
'77YE98', | |
'994A4U', | |
'22NZ8S', | |
'33VZHV', | |
'YD34E7', | |
'B4EV54', | |
'QXQEA0', | |
'RCE9Z2', | |
'W382SW', | |
'Y1UUUA', | |
'240125', | |
'0P20E8', | |
'CTZKSB', | |
'K60820', | |
'WE21H5', | |
'N180MF'] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment