import numpy as np
# Conversion factor from CFU on plate to CFU in well, and daily dilution factor during evolution experiment
CFUS_PER_ML_OVER_PLATE = 10**7
DAILY_DILUTION = 500
# Ancestral CFU counts and OD600 in platereader after growing at 30 degrees Celsius
Ancestral_NS001_Plating_Counts = np.array([54, 28, 15, 36, 24, 20, 33, 40, 11, 61, 47, 22, 45,
46, 74, 19, 37, 20, 35, 20, 23, 48, 13, 17, 16, 16,
17, 18, 45, 47, 81, 34, 51, 32, 50, 60, 78, 64, 45,
18, 20, 72, 68])
Ancestral_NS001_OD600s = np.array([0.276, 0.28613, 0.26408, 0.2913, 0.25755, 0.29297, 0.231,
0.16795, 0.16625, 0.20347, 0.19645, 0.15123, 0.18605, 0.2149,
0.15932, 0.18525, 0.15868, 0.18548, 0.15317, 0.16133, 0.18188,
0.17113, 0.1333, 0.14218, 0.16023, 0.18067, 0.17688, 0.2094,
0.21363, 0.18075, 0.1815, 0.14425, 0.15232, 0.17988, 0.17058,
0.16795, 0.15892, 0.17345, 0.13955, 0.15837, 0.14715, 0.14608,
0.1641])
Ancestral_NS001_OD_Blanks = np.array([.0794, .0791, .0869])
# Final Strain CFU counts and OD600 in platereader after growing at 30 degrees Celsius
High1_Plating_Counts = np.array([109, 128, 116, 113, 125, 178, 118, 117])
High1_OD600s = np.array([0.31783, 0.30065, 0.30998, 0.28337,
0.31538, 0.333, 0.29463, 0.28297])
HiMid1_Plating_Counts = np.array([136, 126, 203, 174, 225, 130, 223, 128, 144])
HiMid1_OD600s = np.array([0.38885, 0.36762, 0.37105, 0.38145, 0.3728,
0.4085, 0.38412, 0.3699, 0.35283])
Mid1_Plating_Counts = np.array([159, 143, 128, 186, 103, 133, 112, 105])
Mid1_OD600s = np.array([0.26927, 0.28328, 0.29468, 0.27982, 0.28565,
0.28475, 0.27565, 0.24793])
LoMid1_Plating_Counts = np.array([125, 100, 125, 86, 129, 91, 111, 95])
LoMid1_OD600s = np.array([0.30528, 0.31983, 0.32877, 0.33193, 0.33168,
0.31457, 0.32398, 0.3037])
LoMid5_Plating_Counts = np.array([94, 88, 76, 114, 98, 91, 125, 72, 76])
LoMid5_OD600s = np.array([0.34545, 0.33127, 0.32858, 0.37605, 0.34335,
0.35247, 0.37815, 0.3294, 0.32993])
Low1_Plating_Counts = np.array([86, 109, 111, 127, 99, 58, 61])
Low1_OD600s = np.array([0.30783, 0.31777, 0.32932, 0.34125,
0.33075, 0.30223, 0.3058])
Low5_Plating_Counts = np.array([58, 74, 54, 55, 100, 56, 43, 52])
Low5_OD600s = np.array([0.1811, 0.23818, 0.21805, 0.21475, 0.225,
0.1919, 0.1701, 0.19787])
High_to_Mid_OD_Blanks = np.array([0.08205, 0.0804, 0.0784])
LoMid_to_Low_OD_Blanks = np.array([0.0835, 0.08365, 0.081225])
Ancestral_CFU_per_ml_OD600 = (Ancestral_NS001_Plating_Counts
/ (Ancestral_NS001_OD600s - np.mean(Ancestral_NS001_OD_Blanks))
* CFUS_PER_ML_OVER_PLATE)
High1_CFU_per_ml_OD600 = (High1_Plating_Counts
/ (High1_OD600s - np.mean(High_to_Mid_OD_Blanks))
* CFUS_PER_ML_OVER_PLATE)
HiMid1_CFU_per_ml_OD600 = (HiMid1_Plating_Counts
/ (HiMid1_OD600s - np.mean(High_to_Mid_OD_Blanks))
* CFUS_PER_ML_OVER_PLATE)
Mid1_CFU_per_ml_OD600 = (Mid1_Plating_Counts
/ (Mid1_OD600s - np.mean(High_to_Mid_OD_Blanks))
* CFUS_PER_ML_OVER_PLATE)
LoMid1_CFU_per_ml_OD600 = (LoMid1_Plating_Counts
/ (LoMid1_OD600s - np.mean(LoMid_to_Low_OD_Blanks))
* CFUS_PER_ML_OVER_PLATE)
LoMid5_CFU_per_ml_OD600 = (LoMid5_Plating_Counts
/ (LoMid5_OD600s - np.mean(LoMid_to_Low_OD_Blanks))
* CFUS_PER_ML_OVER_PLATE)
Low1_CF_per_ml_OD600 = (Low1_Plating_Counts
/ (Low1_OD600s - np.mean(LoMid_to_Low_OD_Blanks))
* CFUS_PER_ML_OVER_PLATE)
Low5_CF_per_ml_OD600 = (Low5_Plating_Counts
/ (Low5_OD600s - np.mean(LoMid_to_Low_OD_Blanks))
* CFUS_PER_ML_OVER_PLATE)
Ancestral_mean = np.mean(Ancestral_CFU_per_ml_OD600)
Ancestral_std = np.std(Ancestral_CFU_per_ml_OD600)
High1_mean = np.mean(High1_CFU_per_ml_OD600)
High1_std = np.std(High1_CFU_per_ml_OD600)
HiMid1_mean = np.mean(HiMid1_CFU_per_ml_OD600)
HiMid1_std = np.std(HiMid1_CFU_per_ml_OD600)
Mid1_mean = np.mean(Mid1_CFU_per_ml_OD600)
Mid1_std = np.std(Mid1_CFU_per_ml_OD600)
LoMid1_mean = np.mean(LoMid1_CFU_per_ml_OD600)
LoMid1_std = np.std(LoMid1_CFU_per_ml_OD600)
LoMid5_mean = np.mean(LoMid5_CFU_per_ml_OD600)
LoMid5_std = np.std(LoMid5_CFU_per_ml_OD600)
Low1_mean = np.mean(Low1_CF_per_ml_OD600)
Low1_std = np.std(Low1_CF_per_ml_OD600)
Low5_mean = np.mean(Low5_CF_per_ml_OD600)
Low5_std = np.std(Low5_CF_per_ml_OD600)
print("Final CFUs per ml of OD600 culture are estimated at")
print(f"Ancestral: {Ancestral_mean:.2E} +- {Ancestral_std:.2E}")
print(f"High1: {High1_mean:.2E} +- {High1_std:.2E}")
print(f"HiMid1: {HiMid1_mean:.2E} +- {HiMid1_std:.2E}")
print(f"Mid1: {Mid1_mean:.2E} +- {Mid1_std:.2E}")
print(f"LoMid1: {LoMid1_mean:.2E} +- {LoMid1_std:.2E}")
print(f"LoMid5: {LoMid5_mean:.2E} +- {LoMid5_std:.2E}")
print(f"Low1: {Low1_mean:.2E} +- {Low1_std:.2E}")
print(f"Low5: {Low5_mean:.2E} +- {Low5_std:.2E}")
TRANSFER_VOLUME = .001
LOWEST_OD600 = .4
HIGHEST_OD600 = .9
Lowest_CFU_at_day_start_estimate = TRANSFER_VOLUME*LOWEST_OD600*(LoMid5_mean - LoMid5_std)
Highest_CFU_at_day_start_estimate = TRANSFER_VOLUME*HIGHEST_OD600*(Mid1_mean + Mid1_std)
print(f"The number of live cells at the start of each day would be"
f" between roughly {Lowest_CFU_at_day_start_estimate:.2E} and {Highest_CFU_at_day_start_estimate:.2E}.")