def __init__(self, all_frags): self.fragments = all_frags # name, master_mix names = [x.name for x in all_frags] try: self.name = unanimous(names) self.master_mix = True except ValueError: self.name = ','.join(names) self.master_mix = False # conc frags = [x for x in all_frags if x is not null_reagent] self.conc_nM = inf self.conc = None for frag in frags: if frag.conc_nM < self.conc_nM: self.conc_nM = frag.conc_nM self.conc = frag.conc def all_close(x, threshold=0.1): try: a, b = max(x), min(x) return (a - b) / a < 0.1 except TypeError: return False concs = [x.conc for x in frags] concs_nM = [x.conc_nM for x in frags] if not all_close(concs_nM) or not all_close(concs): self.conc = self.conc_nM, 'nM' # volume self.vol_uL = uL_from_pmol(target_pmol, self.conc_nM)
def get_full_protocol(self): df = self.dilutions uL = lambda x: x if isinstance(x, str) else f'{x:.2f} µL' ## Main table: main_header = [ "Name", "Stock Vol", "Diluent Vol", ] main_row = lambda x: [ x['tag'], uL(x['stock_uL']), uL(x['diluent_uL']), ] main_align = '<>>' to_conc = "" in_diluent = "" try: target_conc = unanimous(df['target_conc']) except ValueError: show_conc = True else: show_conc = False to_conc = f"to {target_conc} " if self.diluent: in_diluent = f"in {self.diluent} " if show_conc or df['too_dilute'].any(): main_header.append("Final Conc") main_row_3 = main_row main_row = lambda x: [ *main_row_3(x), str(x['final_conc']), ] main_align += '>' main_table = stepwise.table( rows=[main_row(x) for _, x in df.iterrows()], header=main_header, align=main_align, ) ## Supplementary table: def stock_str(row): c0, c1 = row['stock_conc'], row['stock_conc_converted'] return f'{c0} = {c1}' if c0.unit != c1.unit else f'{c1}' def mw_str(row): mw = row['mw'] return f'{mw:.1f}' if mw else '?' supp_table = stepwise.table( rows=[[x['tag'], mw_str(x), stock_str(x), x['target_conc']] for _, x in df.iterrows()], header=['Name', 'MW', 'Stock Conc', 'Target Conc'], align='<>>>', ) ## Protocol: p = stepwise.Protocol() p += pl( f"Dilute the following {plural(df):stock solution/s} {to_conc}{in_diluent}[1]:", main_table, ) p.footnotes[1] = pl( "Concentrations:", supp_table, ) return p
mix.hold_ratios.volume = k * volume_uL, 'µL' mix['sample'].name = ','.join(str(x.name) for x in group) mix['sample'].stock_conc = conc p += prep_gel.prep_step if x := self.gel_percent: gel.gel_percent = x if x := self.gel_run_volts: gel.run_volts = x if x := self.gel_run_time_min: gel.run_time_min = x try: gel.load_volume_uL = unanimous( x.load_volume_per_lane_uL for x in self.samples ) except ValueError: gel.load_volume_uL = 0 p += pl(f"Load the {n:sample/s} in the gel as follows:", u := ul()) for sample in self.samples: num_lanes = f" in each of {m} lanes" if (m := sample.num_lanes) != 1 else "" u += f"{sample.load_volume_per_lane_uL:.2g} µL {sample.name}{num_lanes}" p += gel.run_step return p def get_gel_extraction_steps(self): p = stepwise.Protocol()
def use_mrna(self): return unanimous(x.is_mrna for x in self.templates)
def get_product_molecule(self): return unanimous(self._product_molecules)
def get_product_volume(self): return unanimous(self._product_volumes)
def get_product_conc(self): return unanimous(self._product_concs)
def get_product_conc(self): v0 = unanimous(x.precursor.volume for x in self.products) c0 = unanimous(x.precursor.conc for x in self.products) return c0 * (v0 / self.product_volume)