def calibrate_pumps(pump_type, vials=None, dt=10): ''' Routine that runs all pumps sequentially assuming the outlet is sitting on on a balance. after running a pump for dt seconds, the user is prompted for the weight until all 15 pumps have been run ''' if vials is None: vials = range(15) calibration_morb = morb.morbidostat() print("Upon pressing enter, each pump will be run for " + str(dt) + " seconds.") print( "Before each pump, you will be prompted for the weight of the current set-up." ) s = input("press enter to start, q to stop: ") if len(s) > 0: print("Aborting calibration") return # loop over vials, prompt for weight weight = np.zeros(len(vials) + 1) for vi, vial in enumerate(vials): no_weight = True while no_weight: s = input('current weight: ') try: weight[vi] = float(s) no_weight = False except: print("invalid weight") calibration_morb.run_pump(pump_type, vial, run_time=dt) # get final weight no_weight = True while no_weight: s = input('final weight: ') try: weight[-1] = float(s) no_weight = False except: print("invalid weight") # calculate pump_rate and save to file pump_rate = np.diff(weight) / dt np.savetxt(morb.pump_calibration_file_base + '_' + pump_type + '.dat', pump_rate)
def calibrate_pumps(pump_type, vials = None, dt = 10): ''' Routine that runs all pumps sequentially assuming the outlet is sitting on on a balance. after running a pump for dt seconds, the user is prompted for the weight until all 15 pumps have been run ''' if vials is None: vials = range(15) calibration_morb = morb.morbidostat() print("Upon pressing enter, each pump will be run for "+str(dt)+" seconds.") print("Before each pump, you will be prompted for the weight of the current set-up.") s = raw_input("press enter to start, q to stop: ") if len(s)>0: print("Aborting calibration") return # loop over vials, prompt for weight weight = np.zeros(len(vials)+1) for vi,vial in enumerate(vials): no_weight = True while no_weight: s = raw_input('current weight: ') try: weight[vi] =float(s) no_weight = False except: print("invalid weight") calibration_morb.run_pump(pump_type, vial,run_time=dt) # get final weight no_weight = True while no_weight: s = raw_input('final weight: ') try: weight[-1] =float(s) no_weight = False except: print("invalid weight") # calculate pump_rate and save to file pump_rate = np.diff(weight)/dt np.savetxt(morb.pump_calibration_file_base+'_'+pump_type+'.dat', pump_rate)
def __init__(self, vials=range(15), experiment_duration=2 * 60 * 60, target_OD=0.1, dilution_factor=0.9, bug='tbd', drugA='tbd', drugB='tbd', drugA_concentration=0.3, drugB_concentration=2.0, OD_dt=30, cycle_dt=600): # the default experiment is a morbidostat measurement self.experiment_type = MORBIDOSTAT_EXPERIMENT # all times in seconds, define parameter second to speed up for testing self.second = 1.0 # set up the morbidostat self.morb = morb.morbidostat() self.morbidostat_port = self.morb.connect() if not self.morb.morbidostat_OK: print("Trouble setting up morbidostat") # sync time units self.morb.second = self.second # experiment parameters self.OD_dt = OD_dt self.cycle_dt = cycle_dt self.experiment_duration = experiment_duration if (np.max(vials) < 15): self.vials = copy.copy(vials) else: print( "Morbidostat set-up: all vial numbers must be between 0 and 14" ) self.vials = [] self.target_OD = target_OD self.culture_volume = 18 # target volume in milliliters self.dilution_factor = dilution_factor self.dilution_threshold = 0.03 self.extra_suction = 2 # extra volume that is being sucked out of the vials [ml] self.drugA = drugA self.drugB = drugB self.experiment_name = 'tbd' self.bug = bug self.drugA_concentration = drugA_concentration self.drugB_concentration = drugB_concentration # data acqusition specifics self.n_reps = 8 self.buffer_time = 10 # counters self.OD_measurement_counter = 0 self.cycle_counter = 0 self.restart_from_file = None # if a directory name, resume from there. #feedback parameters self.max_growth_fraction = 0.05 # increase antibiotics with 5% OD increase per cycle self.AB_switch_conc = 0.3 # use high concentration if culture conc is 30% of drug A self.feedback_time_scale = 12 # compare antibiotic concentration to that x cycles ago self.saturation_threshold = 0.22 # threshold beyond which OD can't be reliable measured self.anticipation_threshold = 0.7 # fraction of target_OD, at which increasing antibiotics is first considered # diagnostic variables self.max_AB_fold_increase = 1.1 # maximum amount by which the antibiotic concentration is allowed to increase within the feed back time scale self.mic_kd = 0.25 # fraction of the mic to which is added to low drug concentrations when calculating the AB_fold_increase self.stopped = True self.interrupted = False self.running = False self.override = False self.n_cycles = self.experiment_duration // self.cycle_dt self.n_vials = len(self.vials) self.calculate_derived_values() self.ODs_per_cycle = int(self.cycle_dt - self.morb.mixing_time - self.pump_time - self.buffer_time) // self.OD_dt
def calibrate_OD(vials=None): ''' measure OD of OD standard, calculate regression coefficients ''' import matplotlib.pyplot as plt if vials is None: vials = range(15) calibration_morb = morb.morbidostat() no_valid_standard = True ODs = [] voltages = [] all_cycles_measured = False while all_cycles_measured == False: while no_valid_standard: s = input("Enter OD of standard [q to quit]: ") if s == 'q': print("Aborting calibration") all_cycles_measured = True break try: cur_OD = float(s) no_valid_standard = False except: print("invalid entry") if not all_cycles_measured: # prompt user for 15 measurements while q is not pressed ODs.append(cur_OD) voltages.append(np.zeros(len(vials))) for vi, vial in enumerate(vials): OKstr = input("Place OD standard in receptible " + str(vial + 1) + ", press enter when done") time.sleep( 0.001 ) #delay for 1 second to allow for heating of the diode voltages[-1][vi] = calibration_morb.measure_voltage( vial, switch_light_off=True)[0] print(vial, "measurement ", voltages[-1][vi]) no_valid_standard = True if len(ODs) > 1: print("Collected " + str(len(ODs)) + " OD voltage pairs, calculating voltage -> OD conversion") ODs = np.array(ODs) voltages = np.array(voltages).T fit_parameters = np.zeros((len(vials), 2)) for vi, vial in enumerate(vials): good_measurements = voltages[vi, :] < 900 if good_measurements.sum() > 1: slope, intercept, r, p, stderr = linregress( ODs[good_measurements], voltages[vi, good_measurements]) else: print( "less than 2 good measurements, also using saturated measurements for vial" + str(vial)) slope, intercept, r, p, stderr = linregress( ODs, voltages[vi, :]) fit_parameters[vi, :] = [1.0 / slope, -intercept / slope] np.savetxt(morb.OD_calibration_file_name, fit_parameters) tmp_time = time.localtime() # make figure showing calibration plt.plot(ODs, voltages.T, 'o', ls='-') plt.xlabel('OD standard') plt.ylabel('measured signal (0-1023)') # save calibration measurements date_string = "".join([ format(v, '02d') for v in [tmp_time.tm_year, tmp_time.tm_mon, tmp_time.tm_mday] ]) with open( morb.morb_path + 'data/voltage_measurements_' + date_string + '.txt', 'w') as volt_file: for oi in range(len(ODs)): volt_file.write(str(ODs[oi])) for vi in range(len(vials)): volt_file.write('\t' + str(voltages[vi, oi])) volt_file.write('\n') else: print("need measurements for at least two OD standards") return fit_parameters, ODs, voltages
import arduino_interface as M import time # initialize an instance of the morbidostat. morb = M.morbidostat() # if it was found on the serial port, loop over all # pumps and switch them on for a few seconds if morb.morbidostat_OK: m,v,c = morb.measure_voltage(1, 10, 10) for pump_type in ['medium','drug A', 'drug B']: for pin in range(15): morb.run_pump(pump_type, pin, 1) time.sleep(1.2) else: print("Initializing morbidostat failed") # run the waste pump for 4 seconds morb.run_waste_pump(4) # close the serial port morb.disconnect()
def __init__(self, vials = range(15), experiment_duration = 2*60*60, target_OD = 0.1, dilution_factor = 0.9, bug = 'tbd', drugA ='tbd',drugB ='tbd', drugA_concentration = 0.3, drugB_concentration = 2.0, OD_dt = 30, cycle_dt = 600): # the default experiment is a morbidostat measurement self.experiment_type = MORBIDOSTAT_EXPERIMENT # all times in seconds, define parameter second to speed up for testing self.second = 1.0 # set up the morbidostat self.morb = morb.morbidostat() self.morbidostat_port = self.morb.connect() if not self.morb.morbidostat_OK: print("Trouble setting up morbidostat") # sync time units self.morb.second = self.second # experiment parameters self.OD_dt = OD_dt self.cycle_dt = cycle_dt self.experiment_duration = experiment_duration if (np.max(vials)<15): self.vials = copy.copy(vials) else: print("Morbidostat set-up: all vial numbers must be between 0 and 14") self.vials = [] self.target_OD = target_OD self.culture_volume = 18 # target volume in milliliters self.dilution_factor = dilution_factor self.dilution_threshold = 0.03 self.extra_suction = 2 # extra volume that is being sucked out of the vials [ml] self.drugA = drugA self.drugB = drugB self.experiment_name = 'tbd' self.bug = bug self.drugA_concentration = drugA_concentration self.drugB_concentration = drugB_concentration # data acqusition specifics self.n_reps=8 self.buffer_time = 10 # counters self.OD_measurement_counter = 0 self.cycle_counter = 0 self.restart_from_file=None # if a directory name, resume from there. #feedback parameters self.max_growth_fraction = 0.05 # increase antibiotics with 5% OD increase per cycle self.AB_switch_conc = 0.3 # use high concentration if culture conc is 30% of drug A self.feedback_time_scale = 12 # compare antibiotic concentration to that x cycles ago self.saturation_threshold = 0.22 # threshold beyond which OD can't be reliable measured self.anticipation_threshold = 0.7 # fraction of target_OD, at which increasing antibiotics is first considered # diagnostic variables self.max_AB_fold_increase = 1.1 # maximum amount by which the antibiotic concentration is allowed to increase within the feed back time scale self.mic_kd = 0.25 # fraction of the mic to which is added to low drug concentrations when calculating the AB_fold_increase self.stopped = True self.interrupted = False self.running = False self.override = False self.n_cycles = self.experiment_duration//self.cycle_dt self.n_vials = len(self.vials) self.calculate_derived_values() self.ODs_per_cycle = int(self.cycle_dt-self.morb.mixing_time-self.pump_time - self.buffer_time)//self.OD_dt
def calibrate_OD(vials = None): ''' measure OD of OD standard, calculate regression coefficients ''' import matplotlib.pyplot as plt if vials is None: vials = range(15) calibration_morb = morb.morbidostat() no_valid_standard=True ODs = [] voltages = [] all_cycles_measured = False while all_cycles_measured==False: while no_valid_standard: s = raw_input("Enter OD of standard [q to quit]: ") if s=='q': print("Aborting calibration") all_cycles_measured = True break try: cur_OD = float(s) no_valid_standard=False except: print("invalid entry") if not all_cycles_measured: # prompt user for 15 measurements while q is not pressed ODs.append(cur_OD) voltages.append(np.zeros(len(vials))) for vi,vial in enumerate(vials): OKstr = raw_input("Place OD standard in receptible "+str(vial+1)+ ", press enter when done") time.sleep(0.001) #delay for 1 second to allow for heating of the diode voltages[-1][vi] = calibration_morb.measure_voltage(vial, switch_light_off=True)[0] print vial, "measurement ", voltages[-1][vi] no_valid_standard=True if len(ODs)>1: print("Collected "+str(len(ODs))+" OD voltage pairs, calculating voltage -> OD conversion") ODs = np.array(ODs) voltages = np.array(voltages).T fit_parameters = np.zeros((len(vials), 2)) for vi,vial in enumerate(vials): good_measurements = voltages[vi,:]<900 if good_measurements.sum()>1: slope, intercept, r,p,stderr = linregress(ODs[good_measurements], voltages[vi,good_measurements]) else: print("less than 2 good measurements, also using saturated measurements for vial"+str(vial)) slope, intercept, r,p,stderr = linregress(ODs, voltages[vi,:]) fit_parameters[vi,:] = [1.0/slope, -intercept/slope] np.savetxt(morb.OD_calibration_file_name, fit_parameters) tmp_time = time.localtime() # make figure showing calibration plt.plot(ODs, voltages.T, 'o', ls='-') plt.xlabel('OD standard') plt.ylabel('measured signal (0-1023)') # save calibration measurements date_string = "".join([format(v,'02d') for v in [tmp_time.tm_year, tmp_time.tm_mon, tmp_time.tm_mday]]) with open(morb.morb_path+'data/voltage_measurements_'+date_string+'.txt', 'w') as volt_file: for oi in range(len(ODs)): volt_file.write(str(ODs[oi])) for vi in range(len(vials)): volt_file.write('\t'+str(voltages[vi,oi])) volt_file.write('\n') else: print("need measurements for at least two OD standards") return fit_parameters, ODs, voltages