riverine.mixes#
A module for handling mixes.
Classes#
Class denoting a Mix, a collection of source components mixed to |
Functions#
|
|
|
A "split mix" is a |
|
Create a "master mix" useful for saving pipetting steps when creating |
Module Contents#
- riverine.mixes._format_title(raw_title: str, level: int, tablefmt: str | tabulate.TableFormat) str[source]#
- class riverine.mixes.Mix(*args, **kwargs)[source]#
Bases:
riverine.components.AbstractComponentClass denoting a Mix, a collection of source components mixed to some volume or concentration.
- actions: riverine.units.Sequence[riverine.actions.AbstractAction][source]#
- fixed_concentration: str | riverine.units.DecimalQuantity | None[source]#
- reference: riverine.references.Reference | None = None[source]#
- min_volume: riverine.units.DecimalQuantity[source]#
- well: riverine.locations.WellPos | None[source]#
- property fixed_total_volume: riverine.units.DecimalQuantity[source]#
- property concentration: riverine.units.DecimalQuantity[source]#
Effective concentration of the mix. Calculated in order:
If the mix has a fixed concentration, then that concentration.
If fixed_concentration is a string, then the final concentration of the component with that name.
If fixed_concentration is none, then the final concentration of the first mix component.
- _get_concentration(_cache_key=None) riverine.units.DecimalQuantity[source]#
- property total_volume: riverine.units.DecimalQuantity[source]#
Total volume of the mix. If the mix has a fixed total volume, then that, otherwise, the sum of the transfer volumes of each component.
- _get_total_volume(_cache_key=None) riverine.units.DecimalQuantity[source]#
- property buffer_volume: riverine.units.Quantity[source]#
The volume of buffer to be added to the mix, in addition to the components.
- table(tablefmt: tabulate.TableFormat | str = 'pipe', raise_failed_validation: bool = False, stralign='default', missingval='', showindex='default', disable_numparse=False, colalign=None, _cache_key=None) str[source]#
Generate a table describing the mix.
- Parameters:
tablefmt – The output format for the table.
validate – Ensure volumes make sense.
- mixlines(tablefmt: str | tabulate.TableFormat = 'pipe', _cache_key=None) list[riverine.printing.MixLine][source]#
- validate(tablefmt: str | tabulate.TableFormat | None = None, mixlines: riverine.units.Sequence[riverine.printing.MixLine] | None = None, raise_errors: bool = False, _cache_key=None) list[riverine.units.VolumeError][source]#
- all_components() pandas.DataFrame[source]#
Return a Series of all component names, and their concentrations (as pint nM).
- with_experiment(experiment: riverine.experiments.Experiment, *, inplace: bool = True) Mix[source]#
- with_reference(reference: riverine.references.Reference, *, inplace: bool = True) Mix[source]#
- property location: tuple[str, riverine.locations.WellPos | None][source]#
- vol_to_tube_names(tablefmt: str | tabulate.TableFormat = 'pipe', validate: bool = True) dict[riverine.units.DecimalQuantity, list[str]][source]#
- Returns:
dict mapping a volume vol to a list of names of strands in this mix that should be pipetted with volume vol
- _tube_map_from_mixline(mixline: riverine.printing.MixLine) str[source]#
- tubes_markdown(tablefmt: str | tabulate.TableFormat = 'pipe') str[source]#
- Parameters:
tablefmt – table format (see
PlateMap.to_table()for description)- Returns:
a Markdown (or other format according to tablefmt)
string indicating which strands in test tubes to pipette, grouped by the volume
of each
- display_instructions(plate_type: riverine.locations.PlateType = PlateType.wells96, raise_failed_validation: bool = False, combine_plate_actions: bool = True, well_marker: None | str | Callable[[str], str] = None, title_level: Literal[1, 2, 3, 4, 5, 6] = 3, warn_unsupported_title_format: bool = True, tablefmt: str | tabulate.TableFormat = 'unsafehtml', include_plate_maps: bool = True) None[source]#
Displays in a Jupyter notebook the result of calling
Mix.instructions().- Parameters:
plate_type – 96-well or 384-well plate; default is 96-well.
raise_failed_validation – If validation fails (volumes don’t make sense), raise an exception.
combine_plate_actions – If True, then if multiple actions in the Mix take the same volume from the same plate, they will be combined into a single
PlateMap.well_marker – By default the strand’s name is put in the relevant plate entry. If well_marker is specified and is a string, then that string is put into every well with a strand in the plate map instead. This is useful for printing plate maps that just put, for instance, an ‘X’ in the well to pipette (e.g., specify
well_marker='X'), e.g., for experimental mixes that use only some strands in the plate. To enable the string to depend on the well position (instead of being the same string in every well), well_marker can also be a function that takes as input a string representing the well (such as"B3"or"E11"), and outputs a string. For example, giving the identity functionmix.to_table(well_marker=lambda x: x)puts the well address itself in the well.title_level – The “title” is the first line of the returned string, which contains the plate’s name and volume to pipette. The title_level controls the size, with 1 being the largest size, (header level 1, e.g., # title in Markdown or <h1>title</h1> in HTML).
warn_unsupported_title_format – If True, prints a warning if tablefmt is a currently unsupported option for the title. The currently supported formats for the title are ‘github’, ‘html’, ‘unsafehtml’, ‘rst’, ‘latex’, ‘latex_raw’, ‘latex_booktabs’, “latex_longtable”. If tablefmt is another valid option, then the title will be the Markdown format, i.e., same as for tablefmt = ‘github’.
tablefmt – By default set to ‘github’ to create a Markdown table. For other options see astanin/python-tabulate
include_plate_maps – If True, include plate maps as part of displayed instructions, otherwise only include the more compact mixing table (which is always displayed regardless of this parameter).
- Returns:
pipetting instructions in the form of strings combining results of
Mix.table()and
- generate_picklist(experiment: riverine.experiments.Experiment | None, _cache_key=None) Mix.generate_picklist.PickList | None[source]#
- Parameters:
experiment – experiment to use for generating picklist
- Return type:
picklist for the mix
- instructions(*, plate_type: riverine.locations.PlateType = PlateType.wells96, raise_failed_validation: bool = False, combine_plate_actions: bool = True, well_marker: None | str | Callable[[str], str] = None, title_level: Literal[1, 2, 3, 4, 5, 6] = 3, warn_unsupported_title_format: bool = True, tablefmt: str | tabulate.TableFormat = 'pipe', include_plate_maps: bool = True) str[source]#
Returns string combiniing the string results of calling
Mix.table()andMix.plate_maps()(then callingPlateMap.to_table()on eachPlateMap).- Parameters:
plate_type – 96-well or 384-well plate; default is 96-well.
- raise_failed_validation:
If validation fails (volumes don’t make sense), raise an exception.
- combine_plate_actions:
If True, then if multiple actions in the Mix take the same volume from the same plate, they will be combined into a single
PlateMap.- well_marker:
By default the strand’s name is put in the relevant plate entry. If well_marker is specified and is a string, then that string is put into every well with a strand in the plate map instead. This is useful for printing plate maps that just put, for instance, an ‘X’ in the well to pipette (e.g., specify
well_marker='X'), e.g., for experimental mixes that use only some strands in the plate. To enable the string to depend on the well position (instead of being the same string in every well), well_marker can also be a function that takes as input a string representing the well (such as"B3"or"E11"), and outputs a string. For example, giving the identity functionmix.to_table(well_marker=lambda x: x)puts the well address itself in the well.- title_level:
The “title” is the first line of the returned string, which contains the plate’s name and volume to pipette. The title_level controls the size, with 1 being the largest size, (header level 1, e.g., # title in Markdown or <h1>title</h1> in HTML).
- warn_unsupported_title_format:
If True, prints a warning if tablefmt is a currently unsupported option for the title. The currently supported formats for the title are ‘github’, ‘html’, ‘unsafehtml’, ‘rst’, ‘latex’, ‘latex_raw’, ‘latex_booktabs’, “latex_longtable”. If tablefmt is another valid option, then the title will be the Markdown format, i.e., same as for tablefmt = ‘github’.
- tablefmt:
By default set to ‘github’ to create a Markdown table. For other options see astanin/python-tabulate
- include_plate_maps:
If True, include plate maps as part of displayed instructions, otherwise only include the more compact mixing table (which is always displayed regardless of this parameter).
- Returns:
pipetting instructions in the form of strings combining results of
Mix.table()and
- plate_maps(plate_type: riverine.locations.PlateType = PlateType.wells96, validate: bool = True, combine_plate_actions: bool = True) list[PlateMap][source]#
Similar to
table(), but indicates only the strands to mix from each plate, in the form of aPlateMap.NOTE: this ignores any strands in the
Mixthat are in test tubes. To get a list of strand names in test tubes, callMix.vol_to_tube_names()orMix.tubes_markdown().By calling
PlateMap.to_markdown()on each plate map, one can create a Markdown representation of each plate map, for example,plate 1, 5 uL each | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |-----|------|--------|--------|------|----------|-----|-----|-----|-----|------|------|------| | A | mon0 | mon0_F | | adp0 | | | | | | | | | | B | mon1 | mon1_Q | mon1_F | adp1 | adp_sst1 | | | | | | | | | C | mon2 | mon2_F | mon2_Q | adp2 | adp_sst2 | | | | | | | | | D | mon3 | mon3_Q | mon3_F | adp3 | adp_sst3 | | | | | | | | | E | mon4 | | mon4_Q | adp4 | adp_sst4 | | | | | | | | | F | | | | adp5 | | | | | | | | | | G | | | | | | | | | | | | | | H | | | | | | | | | | | | |
or, with the well_marker parameter of
PlateMap.to_markdown()set to'X', for instance (in case you don’t need to see the strand names and just want to see which wells are marked):plate 1, 5 uL each | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|------|------| | A | * | * | | * | | | | | | | | | | B | * | * | * | * | * | | | | | | | | | C | * | * | * | * | * | | | | | | | | | D | * | * | * | * | * | | | | | | | | | E | * | | * | * | * | | | | | | | | | F | | | | * | | | | | | | | | | G | | | | | | | | | | | | | | H | | | | | | | | | | | | |
- Parameters:
plate_type – 96-well or 384-well plate; default is 96-well.
validate – Ensure volumes make sense.
combine_plate_actions – If True, then if multiple actions in the Mix take the same volume from the same plate, they will be combined into a single
PlateMap.
- Return type:
A list of all plate maps.
- _plate_map_from_mixline(mixline: riverine.printing.MixLine, plate_type: riverine.locations.PlateType, existing_plate_map: PlateMap | None) PlateMap[source]#
- _update_volumes(consumed_volumes: dict[str, riverine.units.Quantity] | None = None, made_volumes: dict[str, riverine.units.Quantity] | None = None, _cache_key=None) Tuple[dict[str, riverine.units.Quantity], dict[str, riverine.units.Quantity]][source]#
Given a
- _unstructure(experiment: riverine.experiments.Experiment | None = None) dict[str, Any][source]#
- classmethod _structure(d: dict[str, Any], experiment: riverine.experiments.Experiment | None = None) Mix[source]#
- riverine.mixes.split_mix(mix: Mix, num_tubes: int | None = None, names: Iterable[str] | None = None, excess: float | riverine.units.Decimal = Decimal(0.05)) Mix[source]#
A “split mix” is a
Mixthat involves creating a large volume mix and splitting it into several test tubes with identical contents. The advantage of specifying a split mix is that one can give the desired volumes/concentrations in the individual test tubes (post splitting) and the number of test tubes, and the correct amounts in the larger mix will automatically be calculated.The
Mix.instructions()method of a split mix includes the additional instruction at the end to aliquot from the larger mix.- Parameters:
mix – The
Mixobject describing what each individual smaller test tube should contain after the split.num_tubes – The number of test tubes into which to split the large mix. Should not be specified if names is specified; in that case num_tubes is assumed to be the number of strings in names.
excess –
A fraction (between 0 and 1) indicating how much extra of the large mix to make. This is useful when num_tubes is large, since the aliquots prior to the last test tube may take a small amount of extra volume, resulting in the final test tube receiving significantly less volume if the large mix contained only just enough total volume.
For example, if the total volume is 100 uL and num_tubes is 20, then each aliquot from the large mix to test tubes would be 100/20 = 5 uL. But if due to pipetting imprecision 5.05 uL is actually taken, then the first 19 aliquots will total to 19*5.05 = 95.95 uL, so there will only be 100 - 95.95 = 4.05 uL left for the last test tube. But by setting excess to 0.05, then to make 20 test tubes of 5 uL each, we would have 5*20*1.05 = 105 uL total, and in this case even assuming pipetting error resulting in taking 95.95 uL for the first 19 samples, there is still 105 - 95.95 = 9.05 uL left, more than enough for the 20’th test tube.
Note: using excess > 0 means than the test tube with the large mix should not be reused as one of the final test tubes, since it will have too much volume at the end.
names – Names of smaller individual test tubes (will be printed in instructions).
- Returns:
A “large” mix, from which num_tubes aliquots can be made to create each of the identical
”small” mixes.
- riverine.mixes.master_mix(mixes: Iterable[Mix], name: str = 'master mix', excess: float | riverine.units.Decimal = Decimal(0.05), exclude_shared_components: Iterable[str | riverine.components.Component] = ()) tuple[Mix, list[Mix]][source]#
Create a “master mix” useful for saving pipetting steps when creating
Mix’s in mixes by grouping components shared among eachMix’s in mixes into a single large master mix from which the shared components can be pipetted to create the downstream mixes.Components are considered “shared” if they appear in all
Mix’s in mixes.To ensure sufficient volume for the last mix when the number of mixes is large (due to slight pipetting error from the master mix adding up over many steps), the parameter excess can be used to control how much of a slight excess of necessary volume is included in the master mix.
Shared Components may be excluded from the master mix by putting them or their names in the parameter exclude_shared_components.
Example:
# staple mix to be shared in all mixes staples = [Strand(f"stap{i}", concentration="1uM") for i in range(5)] staple_mix = Mix( actions=[FixedConcentration(components=staples, fixed_concentration="100 nM")], name="staple mix", ) # "adapter" mixes that are different between mixes num_variants = 3 adapter_mixes = {} for adp_idx in range(num_variants): adapters = [Strand(f'adp_{adp_idx}_{i}', concentration="1uM") for i in range(5)] adapter_mix = Mix( actions=[FixedConcentration(components=adapters, fixed_concentration="50 nM")], name=f"adapters {adp_idx} mix", ) adapter_mixes[adp_idx] = adapter_mix m13 = Strand("m13 100nM", concentration="100 nM") mixes = [Mix( actions=[ FixedConcentration(components=[m13], fixed_concentration=f"1 nM"), FixedConcentration(components=[staple_mix], fixed_concentration=f"10 nM"), FixedConcentration(components=[adapter_mixes[adp_idx]], fixed_concentration=f"10 nM"), ], name="mm", fixed_total_volume=f"100 uL", ) for adp_idx, adapter_mix in adapter_mixes.items()] mm, final_mixes = master_mix(mixes=mixes, name='origami master mix', excess=0.1) print(mm.instructions()) for mix in final_mixes: print(mix.instructions())
This should print the following. Note that only 63 uL of master mix are strictly required, but the total master mix volume is 10% higher (69.3 uL) due to the parameter excess = 0.1.
## Mix "origami master mix": | Component | [Src] | [Dest] | # | Ea Tx Vol | Tot Tx Vol | Location | Note | |:------------|:----------|:-----------|:----|:------------|:-------------|:----------|:------| | staple mix | 100.00 nM | 47.62 nM | | 33.00 µl | 33.00 µl | | | | m13 100nM | 100.00 nM | 4.76 nM | | 3.30 µl | 3.30 µl | | | | 10x buffer | 100.00 mM | 47.62 mM | | 33.00 µl | 33.00 µl | | | | Buffer | | | | 0.00 µl | 0.00 µl | | | | *Total:* | | *47.62 nM* | *4* | | *69.30 µl* | | | Aliquot 21.00 µl from this mix into 3 different test tubes. ## Mix "mix0": | Component | [Src] | [Dest] | # | Ea Tx Vol | Tot Tx Vol | Location | Note | |:-------------------|:----------|:-----------|:----|:------------|:-------------|:----------|:------| | origami master mix | 47.62 nM | 10.00 nM | | 21.00 µl | 21.00 µl | | | | Mg++ | 125.00 mM | 12.50 mM | | 10.00 µl | 10.00 µl | | | | adapters 0 mix | 50.00 nM | 20.00 nM | | 40.00 µl | 40.00 µl | | | | Buffer | | | | 29.00 µl | 29.00 µl | | | | *Total:* | | *10.00 nM* | *4* | | *100.00 µl* | | | ## Mix "mix1": | Component | [Src] | [Dest] | # | Ea Tx Vol | Tot Tx Vol | Location | Note | |:-------------------|:----------|:-----------|:----|:------------|:-------------|:----------|:------| | origami master mix | 47.62 nM | 10.00 nM | | 21.00 µl | 21.00 µl | | | | Mg++ | 125.00 mM | 12.50 mM | | 10.00 µl | 10.00 µl | | | | adapters 1 mix | 55.00 nM | 20.00 nM | | 36.36 µl | 36.36 µl | | | | Buffer | | | | 32.64 µl | 32.64 µl | | | | *Total:* | | *10.00 nM* | *4* | | *100.00 µl* | | | ## Mix "mix2": | Component | [Src] | [Dest] | # | Ea Tx Vol | Tot Tx Vol | Location | Note | |:-------------------|:----------|:-----------|:----|:------------|:-------------|:----------|:------| | origami master mix | 47.62 nM | 10.00 nM | | 21.00 µl | 21.00 µl | | | | Mg++ | 125.00 mM | 12.50 mM | | 10.00 µl | 10.00 µl | | | | adapters 2 mix | 60.00 nM | 20.00 nM | | 33.33 µl | 33.33 µl | | | | Buffer | | | | 35.67 µl | 35.67 µl | | | | *Total:* | | *10.00 nM* | *4* | | *100.00 µl* | | |
- Parameters:
mixes – the list of
Mix’s of which to calculate a shared master mixname – name of the master mix
excess – fraction of “excess” volume to include in master mix to ensure sufficient volume in all downstream mixes; see parameter excess of
split_mix()for explanationexclude_shared_components – names of shared components (or Components themselves) to exclude from master mix; raises exception if any element of exclude_shared_components is not shared by all
Mix’s in the parameter mixes
- Returns:
pair (master_mix, final_mixes), where master_mix is the master mix to use in
downstream final_mixes. Length of final_mixes is the same as parameter mixes, and
they use the same names, but each
Mixin final_mixes will be created by a singlepipetting step from master_mix rather than individual pipetting steps for each shared component.