def get_protocol(self):
        transfer = self.volume * (f := self.inv_factor) / (1 - f)
        initial_volume = self.volume + transfer

        conc_high_str = format_quantity(self.conc_high, self.conc_unit, 'g')
        material_str = f'{conc_high_str} {self.material}'.lstrip()
        conc_table = [[i, format_quantity(conc, self.conc_unit, 'e')]
                      for i, conc in enumerate(self.concentrations, 1)]

        num_tubes = self.steps if self.include_zero else self.steps - 1
        each_tube = 'each tube *except the last*' if self.include_zero else 'each tube'

        protocol = stepwise.Protocol()
        protocol += pl(
            "Perform a serial dilution [1]:",
            ul(
                f"Put {initial_volume:.2f} μL {material_str} in a tube.",
                f"Put {self.volume:.2f} μL {self.diluent} in {plural(num_tubes):# adjacent tube/s}.",
                f"Transfer {transfer:.2f} μL between {each_tube} to make {self.steps} {self.factor:.2g}-fold dilutions.",
            ),
        )

        protocol.footnotes[1] = pl(
            "The final concentrations will be:",
            pre(stepwise.tabulate(conc_table, align='>>')),
            br='\n',
        )
        return protocol
    def get_gel_extraction_steps(self):
        p = stepwise.Protocol()
        names = self._cluster_names_by_molecule()

        desired = oxford_comma(x) if (x := self.desired_bands) else 'desired'
        n = plural(max(len(self.desired_bands), len(self.samples)))
        f = "Based on Fitzy's DNA PAGE purification protocol, [Nilson2013], and [Petrov2013]."

        p += pl(f"Cut the {desired} {n:band/s} out of the gel{p.add_footnotes(f)}.", ul(
            "Place the gel over a TLC plate.",
            "Use a UV light to visualize the RNA (dark spot).",
            "Consider visualizing remaining gel to ensure that all desired RNA was excised.",
        ))
        p += pl(f"Crush the gel {n:slice/s}.", ul(
            "Poke a hole in the bottom of a 0.65 mL tube with a 27 g needle.",
            "Place gel slice inside the 0.65 mL tube.",
            "Place the 0.65 mL tube inside a 1.5 mL tube.",
            "Spin at max speed for 5 min.",
        ))

        eb = elution_buffer()
        eb.hold_ratios.volume = 500 * len(self.samples), 'µL'
        p += pl(
                "Resuspend gel in 400 µL PAGE elution buffer:",
                eb,
        )

        if names['RNA']:
            p += f"Incubate {join_if(names['RNA'], names['DNA'])}at 4°C overnight with end-over-end mixing."

        if names['DNA']:
            p += f"Incubate {join_if(names['DNA'], names['RNA'])}at 55°C overnight with 800 rpm mixing."

        return p
    def get_protocol(self):
        p = stepwise.Protocol()
        s = ul()

        if self.names:
            p += pl(
                f"Purify {','.join(self.names)} by ethanol precipitation [1,2]:",
                s)
        else:
            p += pl("Perform an ethanol precipitation [1,2]:", s)

        s += f"""\
                Add {self.cation_name} to {self.cation_conc}."""
        s += f"""\
                Add {self.carrier_name} to {self.carrier_conc}."""
        s += f"""\
                Add {plural(self.solvent_volume):# volume/s} 
                {self.solvent_name} and mix well."""
        s += f"""\
                If necessary, divide the sample between microfuge tubes
                such that none holds more than 400 µL."""

        if self.incubation and (t := self.incubation_time):
            incubation_time = "overnight" if t == 'overnight' else f"for {t}"
            s += f"""\
Beispiel #4
0
    def get_protocol(self):
        protocol = stepwise.Protocol()
        pcr, primer_mix = self.reaction
        thermocycler = self.thermocycler_protocol
        footnotes = []

        # Primer mix (if applicable):

        example_uM = min(x.stock_uM for x in flatten(self.primer_pairs))
        footnotes.append(pl(
                f"For resuspending lyophilized primers:",
                f"{example_uM} µM = {1e3 / example_uM:g} µL/nmol",
                br='\n',
        ))

        if primer_mix:
            protocol += pl(
                    f"Prepare 10x primer mix{protocol.add_footnotes(*footnotes)}:",
                    primer_mix,
            )
            footnotes = []

        # PCR reaction setup:

        if self.footnote:
            # Before the footnote on resuspending the primers, if it hasn't 
            # been added to the protocol already.
            footnotes.insert(0, self.footnote)

        if x := pcr['template DNA'].stock_conc:
            footnotes.append(pl(
                    f"For diluting template DNA to {x}:",
                    f"Dilute 1 µL twice into {sqrt(1000/x.value):.1g}*sqrt([DNA]) µL",
                    br='\n',
            ))
Beispiel #5
0
    def get_protocol(self):
        # Maybe this should be the getter function for the assembly param...

        p = stepwise.Protocol()
        rxn = self.reaction
        n = rxn.num_reactions
        n_frags = self.num_fragments

        f = 'https://tinyurl.com/yaa5mqz5'
        p += pl(
            f"Setup {plural(n):# Golden Gate assembl/y/ies}{p.add_footnotes(f)}:",
            rxn,
        )
        if n_frags <= 2:
            p += pl(
                "Run the following thermocycler protocol:",
                ul("37°C for 5 min", ),
                "Or, to maximize the number of transformants:",
                ul(
                    "37°C for 60 min",
                    "60°C for 5 min",
                ),
            )

        elif n_frags <= 4:
            p += pl(
                "Run the following thermocycler protocol:",
                ul(
                    "37°C for 60 min",
                    "60°C for 5 min",
                ),
            )

        elif n_frags <= 10:
            p += pl(
                "Run the following thermocycler protocol:",
                ul(
                    "Repeat 30 times:",
                    ul(
                        "37°C for 1 min",
                        "16°C for 1 min",
                    ),
                    "60°C for 5 min",
                ),
            )

        else:
            p += pl(
                "Run the following thermocycler protocol:",
                ul(
                    "Repeat 30 times:",
                    ul(
                        "37°C for 5 min",
                        "16°C for 5 min",
                    ),
                    "60°C for 5 min",
                ),
            )

        return p
Beispiel #6
0
    def get_prep_step(self):
        def both_or_neither(key1, key2):
            has_key1 = has_key2 = True

            try:
                value1 = getattr(self, key1)
            except AttributeError:
                has_key1 = False

            try:
                value2 = getattr(self, key2)
            except AttributeError:
                has_key2 = False

            if has_key1 and not has_key2:
                raise ConfigError(f"specified {key1!r} but not {key2!r}")
            if has_key2 and not has_key1:
                raise ConfigError(f"specified {key2!r} but not {key1!r}")

            if has_key1 and has_key2:
                return value1, value2
            else:
                return False

        s = pl(
            f"Prepare {plural(self.num_samples):# sample/s} for {self.title}:",
            self.sample_mix,
        )
        if x := both_or_neither('incubate_temp_C', 'incubate_time_min'):
            temp_C, time_min = x
            s += ul(f"Incubate at {temp_C:g}°C for {time_min:g} min.")
Beispiel #7
0
    def get_protocol(self):
        p = stepwise.Protocol()
        rxn = self.reaction

        p += pl(
            f"Setup {plural(rxn.num_reactions):# ligation reaction/s}{p.add_footnotes('https://tinyurl.com/y7gxfv5m')}:",
            rxn,
        )
        p += pl(
            "Incubate at the following temperatures:",
            ul(
                "25°C for 15 min",
                "65°C for 10 min",
            ),
        )
        return p
Beispiel #8
0
 def get_protocol(self):
     p = stepwise.Protocol()
     p += pl(
         f"Setup {plural(self.num_reactions):# ligation reaction/s}:",
         self.reaction,
     )
     p += "Incubate at room temperature for 1h."
     return p
Beispiel #9
0
    def _format_stage(self, prefix):

        class SkipStage(Exception):
            pass

        def has(attr):
            return hasattr(self, f'{prefix}_{attr}')

        def get(attr, *args):
            return getattr(self, f'{prefix}_{attr}', *args)


        def have_repeats():
            n = get('repeats')
            return n > 1 if isinstance(n, int) else bool(n)

        def format_repeats():
            n = get('repeats')
            if isinstance(n, int):
                n = f'{n}x'
            return f"Repeat {n}:"

        def format_submerge():
            if not has('buffer'): raise SkipStage
            return f"Submerge gel in ≈{get('volume_mL', 30)} mL {get('buffer')}."

        def format_microwave():
            if get('microwave', False):
                return f"Microwave until almost boiling (≈{format_sec(get('microwave_time_s', 45))})."

        def format_incubate():
            return f"Shake gently for {format_min(get('time_min'))}."

        step_templates = get('steps', ['submerge', 'microwave', 'incubate'])
        step_formatters = {
                'submerge': format_submerge,
                'microwave': format_microwave,
                'incubate': format_incubate,
        }

        out = steps = ul()
        for template in step_templates:
            formatter = step_formatters.get(template, lambda: template)
            try:
                steps += formatter()
            except SkipStage:
                return

        if have_repeats():
            out = ul(pl(format_repeats(), steps, br='\n'))

        if n := get('rinse_repeats', False):
            out += f"Rinse {plural(n)://#x }with water."
Beispiel #10
0
    def get_protocol(self):
        p = stepwise.Protocol()
        rxn = self.reaction

        p += pl(
                f"Setup {plural(self.num_reactions):# {self.title} reaction/s}{p.add_footnotes(self.setup_footnote)}:",
                rxn,
                ul(*self.setup_instructions),
        )
        if self.incubation_time != '0':
            p += f"Incubate at {self.incubation_temp_C:g}°C for {self.incubation_time}{p.add_footnotes(self.incubation_footnote)}."

        return p
    def get_protocol(self):
        optics = [self.parse_optics(x) for x in self.optics]
        lasers = [f"{plural(optics):laser/s}:"
                  ] + [f"{x['laser']} nm" for x in optics]
        filters = [f"{plural(optics):filter/s}:"
                   ] + [x['filter'] for x in optics]

        p = stepwise.Protocol()
        p += pl(
            "Image with a laser scanner:",
            table([lasers, filters], align='<>>'),
        )
        return p
Beispiel #12
0
    def get_protocol(self):
        p = stepwise.Protocol()
        rxn = self.reaction
        n = rxn.num_reactions

        p += pl(
            f"Setup {plural(n):# annealing reaction/s} [1]:",
            rxn,
        )

        p.footnotes[1] = """\
                Using 0.6x linker reduces the amount of unligated 
                linker, see expt #1."""

        p += pl(
            f"Perform the {plural(n):annealing reaction/s}:",
            ul(
                "Incubate at 95°C for 2 min.",
                "Cool at room temperature.",
            ),
        )

        return p
Beispiel #13
0
    def get_protocol(self):
        p = stepwise.Protocol()
        rxn = self.reaction
        n = rxn.num_reactions

        f = "https://tinyurl.com/ychbvkra"
        p += pl(
                f"Setup {plural(n):# Gibson assembl/y/ies}{p.add_footnotes(f)}:",
                rxn,
        )

        incubation_time = '15 min' if self.num_fragments <= 3 else '1h'
        p += f"Incubate at 50°C for {incubation_time}."
        return p
Beispiel #14
0
    def get_protocol(self):
        p = stepwise.Protocol()
        rxn = self.reaction
        rxn_name = 'ligation' if self.use_ligase else 'negative control'
        n = rxn.num_reactions

        p += stepwise.pl(
                f"Setup {plural(n):# {rxn_name} reaction/s}:",
                rxn,
        )
        if self.incubate:
            p += pl(
                    f"Incubate the {plural(n):ligation reaction/s} as follows:",
                    s := ul(
                        f"{self.incubate_temp} for {self.incubate_time}."
                    ),
            )
            if self.quench:
    def get_product_recovery_steps(self):
        p = stepwise.Protocol()
        names = self._cluster_names_by_molecule()

        # Filter material:
        # - Corning has a good guide on which material to select:
        #   https://www.corning.com/catalog/cls/documents/selection-guides/t_filterselectionguide.pdf
        #
        # - I want 0.22 µm, because that's the standard size for filter 
        #   sterilizing biological buffers (that's not my application here, but 
        #   I can see myself wanting to do that).
        #
        # - I want cellulose acetate filters.  Nylon and cellulose nitrate have 
        #   high DNA binding, which will cause me to lose material.  The 
        #   downside to cellulose acetate is that it has a wetting agent that 
        #   will end up in the sample.  However, this will be removed by the 
        #   Zymo column in the subsequent step.
        #
        # - Product number: 8161 (non sterile)
        #
        # Centrifugation speed:
        # - Fitzy's DNA PAGE purification protocol calls for 4 min at 7000 rpm
        # - The Corning guide (see above) includes an agarose gel purification 
        #   protocol, which calls for 13,000g for 5-20 min.  But this protocol 
        #   has no incubation step, so I gather that the spin is supposed to 
        #   pull the solvent out of the gel.  I probably don't need to go so 
        #   fast, but why not go as fast as the columns can tolerate?
        f = "Nylon and cellulose nitrate have high DNA-binding: https://tinyurl.com/3pkyc8dr"
        p += pl(
                "Remove gel debris by spin filtration:",
                ul(
                    f"Load samples onto a 0.22 µm cellose-acetate Spin-X column{p.add_footnotes(f)}.",
                    "Spin at 13,000g for 5 min."
                ),
        )

        if self.cleanup:
            if names['RNA']:
                p += cleanup(self.rna_cleanup_preset, names['RNA'], names['DNA'])

            if names['DNA']:
                p += cleanup(self.dna_cleanup_preset, names['DNA'], names['RNA'])

        return p
Beispiel #16
0
 def get_run_step(self):
     p = stepwise.Protocol()
     additive = f" with {x}" if (x := self.gel_additive) else ""
     percent = x.replace('-', '–') if isinstance(x := self.gel_percent,
                                                 str) else x
     p += pl(
         f"Run a gel{p.add_footnotes(self.protocol_link)}:",
         dl(
             ("gel", f"{percent}% {self.gel_type}{additive}"),
             ("buffer", f"{self.gel_buffer}"),
             ("ladder", self.ladder_name
              and f"{self.ladder_volume_uL:g} µL {self.ladder_name}"),
             ("samples", self.load_volume_uL
              and f"{self.load_volume_uL:.3g} µL/lane"),
             ("prerun", self.prerun_time_min and
              f"{self.prerun_volts:g}V for {self.prerun_time_min:g} min"),
             ("run", f"{self.run_volts:g}V for {self.run_time_min:g} min"),
         ))
     return p
Beispiel #17
0
    def get_protocol(self):
        p = stepwise.Protocol()

        footnotes = [x] if (x := self.protocol_link) else []
        footnotes += self.footnotes

        s = pl(f"Stain gel with {self.title}{p.add_footnotes(*footnotes)}:")

        if self.light_sensitive:
            #s += "Keep gel in the dark in all following steps."
            s += ul("Keep the stain protected from light.")
            #s += ul("In all following steps, protect the stain from light.")

        s += self._format_stage('prep')
        s += self._format_stage('stain')
        s += self._format_stage('destain')

        p += s

        if self.imaging_cmd:
            p += stepwise.load(self.imaging_cmd)

        return p
Beispiel #18
0
class MergeParams(Params):
    args = 'inputs, output'

    params_empty = [
            ####################################
            ([
                Protocol(),
            ],
                Protocol(),
            ),
            ####################################
            ([
                Protocol(),
                Protocol(),
            ],
                Protocol(),
            ),
            ####################################
    ]
    params_dates = [
            ####################################
            ([
                Protocol(
                    date=arrow.get(1988, 11, 8),
                ),
            ],
                Protocol(
                    date=arrow.get(1988, 11, 8),
                ),
            ),
            ####################################
            ([
                Protocol(
                    date=arrow.get(1988, 11, 8),
                ),
                Protocol(
                    date=arrow.get(1989, 9, 19),
                ),
            ],
                Protocol(
                    date=arrow.get(1989, 9, 19),
                ),
            ),
            ####################################
            ([
                Protocol(),
                Protocol(
                    date=arrow.get(1988, 11, 8),
                ),
            ],
                Protocol(
                    date=arrow.get(1988, 11, 8),
                ),
            ),
    ]
    params_commands = [
            ####################################
            ([
                Protocol(
                    commands=['command-1']
                ),
            ],
                Protocol(
                    commands=['command-1']
                ),
            ),
            ####################################
            ([
                Protocol(),
                Protocol(
                    commands=['command-1']
                ),
            ],
                Protocol(
                    commands=['command-1']
                ),
            ),
            ####################################
            ([
                Protocol(
                    commands=['command-1']
                ),
                Protocol(
                    commands=['command-2']
                ),
            ],
                Protocol(
                    commands=['command-1', 'command-2']
                ),
            ),
            ####################################
            ([
                Protocol(
                    commands=['command-1', 'command-2']
                ),
                Protocol(
                    commands=['command-3', 'command-4']
                ),
            ],
                Protocol(
                    commands=['command-1', 'command-2', 'command-3', 'command-4']
                ),
            ),
    ]
    params_steps = [
            ####################################
            ([
                Protocol(
                    steps=['Step 1'],
                ),
            ],
                Protocol(
                    steps=['Step 1'],
                ),
            ),
            ####################################
            ([
                'Step 1'
            ],
                Protocol(
                    steps=['Step 1'],
                ),
            ),
            ####################################
            ([
                pl('Step 1')
            ],
                Protocol(
                    steps=[pl('Step 1')],
                ),
            ),
            ####################################
            ([
                Protocol(),
                Protocol(
                    steps=['Step 1'],
                ),
            ],
                Protocol(
                    steps=['Step 1'],
                ),
            ),
            ####################################
            ([
                Protocol(),
                'Step 1',
            ],
                Protocol(
                    steps=['Step 1'],
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step 1'],
                ),
                Protocol(
                    steps=['Step 2'],
                ),
            ],
                Protocol(
                    steps=['Step 1', 'Step 2'],
                ),
            ),
            ####################################
            ([
                'Step 1',
                'Step 2',
            ],
                Protocol(
                    steps=['Step 1', 'Step 2'],
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step 1', 'Step 2'],
                ),
                Protocol(
                    steps=['Step 3', 'Step 4'],
                ),
            ],
                Protocol(
                    steps=['Step 1', 'Step 2', 'Step 3', 'Step 4'],
                ),
            ),
            ####################################
            ([
                ['Step 1', 'Step 2'],
                ['Step 3', 'Step 4'],
            ],
                Protocol(
                    steps=['Step 1', 'Step 2', 'Step 3', 'Step 4'],
                ),
            ),
    ]
    params_footnotes = [
            ####################################
            ([
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: 'Footnote A'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: 'Footnote A'},
                ),
            ),
            ####################################
            ([
                Protocol(),
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: 'Footnote A'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: 'Footnote A'},
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: 'Footnote A'},
                ),
                Protocol(
                    steps=['Step B'],
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B'],
                    footnotes={1: 'Footnote A'},
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A'],
                ),
                Protocol(
                    steps=['Step B [1]'],
                    footnotes={1: 'Footnote B'},
                ),
            ],
                Protocol(
                    steps=['Step A', 'Step B [1]'],
                    footnotes={1: 'Footnote B'},
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: 'Footnote A'},
                ),
                Protocol(
                    steps=['Step B [1]'],
                    footnotes={1: 'Footnote B'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B [2]'],
                    footnotes={1: 'Footnote A', 2: 'Footnote B'},
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [2]'],
                    footnotes={2: 'Footnote A'},
                ),
                Protocol(
                    steps=['Step B [1]'],
                    footnotes={1: 'Footnote B'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B [2]'],
                    footnotes={1: 'Footnote A', 2: 'Footnote B'},
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1]', 'Step B [2]'],
                    footnotes={1: 'Footnote A', 2: 'Footnote B'},
                ),
                Protocol(
                    steps=['Step C [1]', 'Step D [2]'],
                    footnotes={1: 'Footnote C', 2: 'Footnote D'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B [2]', 'Step C [3]', 'Step D [4]'],
                    footnotes={1: 'Footnote A', 2: 'Footnote B',
                               3: 'Footnote C', 4: 'Footnote D'},
                ),
            ),
            ####################################
            ([
                Protocol(),
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: pre('Footnote A')},
                ),
            ],
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: pre('Footnote A')},
                ),
            ),
    ]
    params_footnotes_shared = [
            ####################################
            ([
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: 'Same footnote'},
                ),
                Protocol(
                    steps=['Step B [1]'],
                    footnotes={1: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B [1]'],
                    footnotes={1: 'Same footnote'}
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [2]'],
                    footnotes={2: 'Same footnote'},
                ),
                Protocol(
                    steps=['Step B [1]'],
                    footnotes={1: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B [1]'],
                    footnotes={1: 'Same footnote'}
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: 'Same footnote'},
                ),
                Protocol(
                    steps=['Step B [2]'],
                    footnotes={2: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B [1]'],
                    footnotes={1: 'Same footnote'}
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [2]'],
                    footnotes={2: 'Same footnote'},
                ),
                Protocol(
                    steps=['Step B [2]'],
                    footnotes={2: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B [1]'],
                    footnotes={1: 'Same footnote'}
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1] [2]',],
                    footnotes={1: 'Footnote 1', 2: 'Same footnote'},
                ),
                Protocol(
                    steps=['Step B [1]'],
                    footnotes={1: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1] [2]', 'Step B [2]'],
                    footnotes={1: 'Footnote 1', 2: 'Same footnote'}
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1] [2]',],
                    footnotes={1: 'Footnote 1', 2: 'Same footnote'},
                ),
                Protocol(
                    steps=['Step B [2]'],
                    footnotes={2: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1] [2]', 'Step B [2]'],
                    footnotes={1: 'Footnote 1', 2: 'Same footnote'}
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1] [2]',],
                    footnotes={1: 'Same footnote', 2: 'Footnote 2'},
                ),
                Protocol(
                    steps=['Step B [1]'],
                    footnotes={1: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1] [2]', 'Step B [1]'],
                    footnotes={1: 'Same footnote', 2: 'Footnote 2'},
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1] [2]',],
                    footnotes={1: 'Same footnote', 2: 'Footnote 2'},
                ),
                Protocol(
                    steps=['Step B [2]'],
                    footnotes={2: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1] [2]', 'Step B [1]'],
                    footnotes={1: 'Same footnote', 2: 'Footnote 2'},
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1] [2]',],
                    footnotes={1: 'Same footnote', 2: 'Footnote 2'},
                ),
                Protocol(
                    steps=['Step B [1] [2]'],
                    footnotes={1: 'Footnote 1', 2: 'Same footnote'},
                ),
            ],
                Protocol(
                    steps=['Step A [1] [2]', 'Step B [3] [1]'],
                    footnotes={1: 'Same footnote', 2: 'Footnote 2', 3: 'Footnote 1'}
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1] [2]',],
                    footnotes={1: 'Same footnote X', 2: 'Same footnote Y'},
                ),
                Protocol(
                    steps=['Step B [1] [2]'],
                    footnotes={1: 'Same footnote Y', 2: 'Same footnote Z'},
                ),
                Protocol(
                    steps=['Step C [1] [2]'],
                    footnotes={1: 'Same footnote Z', 2: 'Same footnote X'},
                ),
            ],
                Protocol(
                    steps=['Step A [1] [2]', 'Step B [2] [3]', 'Step C [3] [1]'],
                    footnotes={1: 'Same footnote X', 2: 'Same footnote Y', 3: 'Same footnote Z'}
                ),
            ),
            ####################################
            ([
                Protocol(
                    steps=['Step A [1]'],
                    footnotes={1: pre('Same footnote')},
                ),
                Protocol(
                    steps=['Step B [1]'],
                    footnotes={1: pre('Same footnote')},
                ),
            ],
                Protocol(
                    steps=['Step A [1]', 'Step B [1]'],
                    footnotes={1: pre('Same footnote')}
                ),
            ),
            ####################################
    ]
    params_typecasts = [
            ####################################
            ([
                Protocol(steps=['Step 1']),
                'Step 2',
            ],
                Protocol(steps=['Step 1', 'Step 2']),
            ),
            ####################################
            ([
                Protocol(steps=['Step 1']),
                ['Step 2', 'Step 3'],
            ],
                Protocol(steps=['Step 1', 'Step 2', 'Step 3']),
            ),
            ####################################
            ([
                Protocol(steps=['Step 1']),
                ProtocolIO(
                    protocol=Protocol(steps=['Step 2']),
                    errors=0,
                )
            ],
                Protocol(
                    steps=['Step 1', 'Step 2'],
                ),
            ),
            ####################################
            ([
                Protocol(steps=['Step 1']),
                ProtocolIO(
                    protocol='Error',
                    errors=1,
                )
            ],
                Protocol(
                    steps=['Step 1'],
                ),
            ),
            ####################################
    ]
Beispiel #19
0
def test_protocol_iadd():
    # The core functionality is tested by `test_protocol_merge()`; this just 
    # needs to make sure the `+=` syntax works.

    p = Protocol()
    assert p.steps == []

    p += "A"
    assert p.steps == ["A"]
    assert p[-1] == "A"

    # Do it again just to make sure the first addition didn't put the protocol 
    # into some kind of broken state.
    p += "B"
    assert p.steps == ["A", "B"]
    assert p[-1] == "B"

    p += ["C", "D"]
    assert p.steps == ["A", "B", "C", "D"]
    assert p[-1] == "D"

    p += pl("E")
    assert p.steps == ["A", "B", "C", "D", pl("E")]
    assert p[-1] == pl("E")

    p += [pl("F"), pl("G")]
    assert p.steps == ["A", "B", "C", "D", pl("E"), pl("F"), pl("G")]
    assert p[-1] == pl("G")

    p += Protocol(steps=["H"], footnotes={1: "h"})
    assert p.steps == ["A", "B", "C", "D", pl("E"), pl("F"), pl("G"), "H"]
    assert p.footnotes == {1: "h"}
    assert p[-1] == "H"
Beispiel #20
0
    def get_protocol(self):
        p = stepwise.Protocol()

        if self.dnase_treatment == 'pre':
            mm = stepwise.MasterMix("""\
                    Reagent                   Stock    Volume  MM?
                    ======================  =======  ========  ===
                    nuclease-free water              to 50 µL   +
                    DNA digestion buffer        10x      5 µL   +
                    DNase I [1]              1 U/µL      5 µL   +
                    RNA sample               <10 µg     40 µL   -
            """)

            step = "Setup a DNase I reaction for each sample:"
            if self.num_samples:
                step = f"Setup {plural(self.num_samples):# DNase I reaction/s}:"
                mm.num_reactions = self.num_samples

            if self.sample_volume_uL:
                mm['RNA sample'].volume = self.sample_volume_uL, 'µL'

            p += pl(step, mm)
            p += "Incubate at room temperature for 15 min."

            p.footnotes[
                1] = "Reconstitute lyophilized DNase I (#E1009-A; 250U) with 275 µL nuclease-free water and mix by gentle inversion.  Store frozen aliquots."

        if self.dnase_treatment == 'post':
            mm = stepwise.MasterMix("""\
                    Reagent                   Stock    Volume  MM?
                    ======================  =======  ========  ===
                    DNA digestion buffer        10x     75 µL   +
                    DNase I [1]              1 U/µL      5 µL   +
            """)
            if self.num_samples:
                mm.num_reactions = self.num_samples

            p += pl("Prepare 80 µL DNase I reaction mix for each sample:", mm)

        s = ul()
        p += pl("Purify RNA using Zymo Clean & Concentrator spin columns:", s)

        if self.sample_volume_uL:
            if self.sample_volume_uL < 50:
                s += f"Add {50 - self.sample_volume_uL:g} nuclease-free water to each sample"

            v = max(50, self.sample_volume_uL)
            s += f"Add {2*v:g} µL RNA binding buffer; mix."
            s += f"Add {3*v:g} µL >95% ethanol; mix."

        else:
            s += "If necessary, bring each sample to 50 µL."
            s += "Add 2 volumes RNA binding buffer; mix."
            s += "Add 3 volumes >95% ethanol; mix."

        s += f"Load sample on spin column."
        s += f"Spin 1 min, 16000g; discard flow-through."

        if self.dnase_treatment == 'post':
            s += f"Add 400 µL RNA wash buffer."
            s += f"Spin 30s, 16000g; discard flow-through."
            s += f"Add 80 µL DNase I reaction mix."
            s += f"Incubate at room temperature for 15 min."

        s += f"Add 400 µL RNA prep buffer."
        s += f"Spin 30s, 16000g; discard flow-through."
        s += f"Add 700 µL RNA wash buffer."
        s += f"Spin 30s, 16000g; discard flow-through."
        s += f"Add 400 µL RNA wash buffer."
        s += f"Spin 60s, 16000g; discard flow-through."
        s += f"Add {self.elute_volume_uL:g} µL nuclease-free water."
        s += f"Spin 30s, 16000g."

        return p
Beispiel #21
0
    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
Beispiel #22
0
            # Before the footnote on resuspending the primers, if it hasn't 
            # been added to the protocol already.
            footnotes.insert(0, self.footnote)

        if x := pcr['template DNA'].stock_conc:
            footnotes.append(pl(
                    f"For diluting template DNA to {x}:",
                    f"Dilute 1 µL twice into {sqrt(1000/x.value):.1g}*sqrt([DNA]) µL",
                    br='\n',
            ))

        title = 'qPCR' if self.qpcr else 'PCR'
        instructions = ul()
        protocol += pl(
                f"Setup {plural(pcr.num_reactions):# {title} reaction/s}{protocol.add_footnotes(*footnotes)}:",
                pcr,
                instructions,
        )

        if pcr.volume > '50 µL':
            instructions += f"Split each reaction into {ceil(pcr.volume.value / 50)} tubes."
        if pcr.num_reactions > 1:
            instructions += "Use any extra master mix as a negative control."

        # Thermocycler protocol:

        protocol += pl(
                "Run the following thermocycler protocol:",
                thermocycler,
        )
Beispiel #23
0
M = np.array([
    [mg_mM, -mg_stock_mM,           0,      0],
    [ k_mM,            0, -k_stock_mM,      0],
    [    1,           -1,          -1, rxn_uL],
])
salt_uL = np.linalg.solve(M[:,:3], M[:,3])

rxn = stepwise.MasterMix()
rxn.num_reactions = int(args['--num-reactions'])
rxn.extra_min_volume = 5, 'µL'
rxn.solvent = None
rxn['translation reaction'].volume = rxn_uL, 'µL'
rxn['translation reaction'].name = args['<reagent>']
rxn['translation reaction'].stock_conc = args['--ivtt-stock']
rxn['MgOAc'].stock_conc = mg_stock_mM, 'mM'
rxn['MgOAc'].volume = salt_uL[1], 'µL'
rxn['MgOAc'].master_mix = True
rxn['KCl'].stock_conc = k_stock_mM, 'mM'
rxn['KCl'].volume = salt_uL[2], 'µL'
rxn['KCl'].master_mix = True

p = stepwise.Protocol()
p += pl(
        f"Setup the coupling reaction:",
        rxn,
)
p += f"Incubate at {args['--incubate-temp']}°C for {args['--incubate-time']}."

p.print()
Beispiel #24
0
    def get_protocol(self):
        p = stepwise.Protocol()
        anneal, mmlv = self.reactions

        if self.nrt_control:
            mmlv_nrt = deepcopy(mmlv)
            mmlv_nrt.num_reactions = 1
            anneal.num_reactions += 1
            del mmlv_nrt['SMART MMLV RT']

        p += pl(
            f"Anneal the {plural(self.primers):RT primer/s} to the {plural(self.templates):RNA template/s} [1]:",
            anneal,
        )

        p.footnotes[1] = pre("""\
This protocol is based on the official Takara 
SMART MMLV reverse transcription protocol:

https://tinyurl.com/y4ash7dl

However, I made three modifications:

- I reduced the volume of the annealing step as 
  much as possible, the increase the 
  concentrations of the oligos.

- I added buffer to the annealing step, because 
  annealing works much better with some salt to 
  shield the backbone charge.  I don't actually 
  know how much salt is in the buffer, but some is 
  better than none.

- I included the MMLV in the transcription master 
  mix, because excluding it seemed too inaccurate.  
  The changes to the annealing step also mean that 
  the master mix has a 1x buffer concentration, so 
  I don't need to worry about the enzyme being 
  unhappy.
""")
        p += "Incubate at 70°C for 3 min, then immediately cool on ice."
        p += pl(
            "Setup {plural(mmlv.num_reactions):# reverse transcription reaction/s}:",
            mmlv,
        )
        if self.nrt_control:
            p += pl(
                f"Setup a −reverse transcriptase (NRT) control:",
                mmlv_nrt,
            )

        p += "Incubate at 42°C for 60 min [2]."
        p.footnotes[2] = "Samples can be incubated for 50-90 min if necessary."

        if self.quench == 'none':
            pass

        elif self.quench == 'heat':
            p += "Incubate at 70°C for 15 min."

        elif self.quench == 'edta':
            p += "Add 4 µL 60 mM EDTA."

        else:
            raise ConfigError(
                f"unexpected value for quench parameter: {self.quench}")

        return p
Beispiel #25
0
p += stepwise.load('cond optimize_click_freeze_cond.xlsx')

rxn = stepwise.MasterMix("""\
        Reagent   Stock  Volume  MM?
        =======  ======  ======  ===
        PBS          2x    2 µL   -
        o126     400 µM    1 µL   +
        o233     400 µM    1 µL   +
""")
rxn.num_reactions = 2
rxn.extra_percent = 0
rxn.hold_ratios.volume = '3 µL'

p += pl(
    f"Setup {rxn.num_reactions} click reactions:",
    rxn,
)
p += "Divide each reaction in three."

p += pl(
    "Incubate the reactions as follows:",
    ul(
        "−20°C overnight",
        "25°C for 4h, −20°C overnight",
        "25°C overnight",
    ),
)

p += "Label the product: o236"

p += stepwise.load(f"gel urea {3 * rxn.num_reactions + 2} -c 1730 -S")
Beispiel #26
0
    def get_protocol(self):
        from itertools import groupby
        from operator import itemgetter

        protocol = stepwise.Protocol()
        rxn = self.reaction
        rxn_type = (self.enzymes[0]['name']
                    if len(self.enzymes) == 1 else 'restriction')

        def incubate(temp_getter,
                     time_getter,
                     time_formatter=lambda x: f'{x} min'):
            incubate_params = [
                (k, max(time_getter(x) for x in group))
                for k, group in groupby(self.enzymes, temp_getter)
            ]
            return [
                f"{temp}°C for {time_formatter(time)}"
                for temp, time in sorted(incubate_params)
            ]

        if self.time:
            digest_steps = incubate(
                itemgetter('incubateTemp'),
                lambda x: self.time,
                lambda x: x,
            )
        else:
            digest_steps = incubate(
                itemgetter('incubateTemp'),
                lambda x: 15 if x['timeSaver'] else 60,
                lambda x: '5–15 min' if x == 15 else '1 hour',
            )

        inactivate_steps = incubate(
            itemgetter('heatInactivationTemp'),
            itemgetter('heatInactivationTime'),
        )

        protocol += pl(
            f"Setup {plural(rxn.num_reactions):# {rxn_type} digestion/s} [1,2]:",
            rxn,
        )
        protocol += pl(
            f"Incubate at the following temperatures [3]:",
            ul(*digest_steps, *inactivate_steps),
        )

        urls = [x['url'] for x in self.enzymes if x.get('url')]
        protocol.footnotes[1] = pl(*urls, br='\n')
        protocol.footnotes[2] = """\
NEB recommends 5–10 units of enzyme per µg DNA 
(10–20 units for genomic DNA).  Enzyme volume 
should not exceed 10% of the total reaction 
volume to prevent star activity due to excess 
glycerol.
"""
        protocol.footnotes[3] = """\
The heat inactivation step is not necessary if 
the DNA will be purified before use.
"""
        return protocol