riverine.quantitate#

A module for handling “quantitation”: measuring concentration of strands, and diluting and hydrating to reach a desired concentration.

The main “easy” functions to use are hydrate_from_specs() and hydrate_and_measure_conc_and_dilute_from_specs().

>>> from riverine.quantitate import hydrate_from_specs, hydrate_and_measure_conc_and_dilute_from_specs
>>> specs_file = 'path/to/coa.csv'
>>> target_conc_high = '200 uM'
>>> target_conc_low = '100 uM'
>>> hydrate_from_specs(
...     filename=specs_file,
...     target_conc=target_conc_high,
...     strands=['5RF', '3RQ'],
... )
nmoles = 8.9 nmol
nmoles = 15.7 nmol
{'5RF': <Quantity(44.5, 'microliter')>,
 '3RQ': <Quantity(78.5, 'microliter')>}
>>> # now go to the lab and add the above quantities of water/buffer to the dry samples,
>>> # then measure absorbances, e.g., with a NanoDrop, to populate the dict `absorbances` below
>>> absorbances = {
...     '5RF': [48.46, 48.28],
...     '3RQ': [34.36, 34.82],
... }
>>> hydrate_and_measure_conc_and_dilute_from_specs(
...     filename=specs_file,
...     target_conc_high=target_conc_high,
...     target_conc_low=target_conc_low,
...     absorbances=absorbances,
... )
{'5RF': (<Quantity(213.931889, 'micromolar')>, <Quantity(48.4210528, 'microliter')>),
 '3RQ': (<Quantity(190.427429, 'micromolar')>, <Quantity(69.176983, 'microliter')>)}

For convenience in Jupyter notebooks, there are also versions of these functions beginning with display_: display_hydrate_from_specs() and display_hydrate_and_measure_conc_and_dilute_from_specs(). Instead of returning a dictionary, these methods display the result in the Jupyter notebook, as nicely-formatted Markdown.

Functions#

measure_conc_and_dilute(...)

Calculates concentration of DNA sample given an absorbance reading on a NanoDrop machine,

hydrate_and_measure_conc_and_dilute(...)

Assuming hydrate() is called with parameters nmol and target_conc_high to give initial

hydrate_and_measure_conc_and_dilute_from_specs(...)

Like hydrate_and_measure_conc_and_dilute(), but works with multiple strands,

hydrate_from_specs(→ dict[str, ...)

Indicates how much volume to add to a dry DNA sample to reach a particular concentration,

Module Contents#

riverine.quantitate.measure_conc_and_dilute(absorbance: float | Sequence[float], ext_coef: float, target_conc: float | str | riverine.units.DecimalQuantity, vol: float | str | riverine.units.DecimalQuantity, vol_removed: None | float | str | riverine.units.DecimalQuantity = None) tuple[riverine.units.DecimalQuantity, riverine.units.DecimalQuantity][source]#

Calculates concentration of DNA sample given an absorbance reading on a NanoDrop machine, then calculates the amount of buffer/water that must be added to dilute it to a target concentration.

Parameters:
  • absorbance – UV absorbance at 260 nm. Can either be a single float/int or a nonempty sequence of floats/ints representing repeated measurements; if the latter then an average is taken.

  • ext_coef – Extinction coefficient in L/mol*cm.

  • target_conc – target concentration. If float/int, units are µM (micromolar).

  • vol – current volume of sample. If float/int, units are µL (microliters) NOTE: This is the volume before samples are taken to measure absorbance. It is assumed that each sample taken to measure absorbance is 1 µL. If that is not the case, then set the parameter vol_removed to the total volume removed.

  • vol_removed – Total volume removed from vol to measure absorbance. For example, if two samples were taken, one at 1 µL and one at 1.5 µL, then set vol_removed = 2.5 µL. If not specified, it is assumed that each sample is 1 µL, and that the total number of samples taken is the number of entries in absorbance. If absorbance is a single volume (e.g., float, int, str, DecimalQuantity), then it is assumed the number of samples is 1 (i.e., vol_removed = 1 µL), otherwise if absorbance is a list, then the length of the list is assumed to be the number of samples taken, each at 1 µL.

Return type:

The pair (current concentration of DNA sample, volume to add to reach target_conc)

riverine.quantitate.hydrate_and_measure_conc_and_dilute(nmol: float | str | riverine.units.DecimalQuantity, target_conc_high: float | str | riverine.units.DecimalQuantity, target_conc_low: float | str | riverine.units.DecimalQuantity, absorbance: float | Sequence[float], ext_coef: float, vol_removed: None | float | str | riverine.units.DecimalQuantity = None) tuple[riverine.units.DecimalQuantity, riverine.units.DecimalQuantity][source]#

Assuming hydrate() is called with parameters nmol and target_conc_high to give initial volumes to add to a dry sample to reach a “high” concentration target_conc_high, and assuming absorbances are then measured, calculates subsequent dilution volumes to reach “low” concentration target_conc_low, and also actual “start” concentration (i.e., actual concentration after adding initial hydration that targeted target_conc_high, according to absorbance).

This is on the assumption that the first hydration step could result in a concentration below target_conc_high, so target_conc_high should be chosen sufficiently larger than target_conc_low so that the actual measured concentration after the first step is likely to be above target_conc_low, so that it is possible to reach concentration target_conc_low with a subsequent dilution step. (As opposed to requiring a vacufuge to concentrate the sample higher).

Parameters:
  • nmol – number of nmol (nanomoles) of dry product.

  • target_conc_high – target concentration for initial hydration. Should be higher than target_conc_low,

  • target_conc_low – the “real” target concentration that we will try to hit after the second addition of water/buffer.

  • absorbance – UV absorbance at 260 nm. Can either be a single float/int or a nonempty sequence of floats/ints representing repeated measurements; if the latter then an average is taken.

  • ext_coef – Extinction coefficient in L/mol*cm.

  • vol_removed – Total volume removed from vol to measure absorbance. For example, if two samples were taken, one at 1 µL and one at 1.5 µL, then set vol_removed = 2.5 µL. If not specified, it is assumed that each sample is 1 µL, and that the total number of samples taken is the number of entries in absorbance. If absorbance is a single volume (e.g., float, int, str, DecimalQuantity), then it is assumed the number of samples is 1 (i.e., vol_removed = 1 µL), otherwise if absorbance is a list, then the length of the list is assumed to be the number of samples taken, each at 1 µL.

:param : The pair (current concentration of DNA sample, volume to add to reach target_conc) :type : return:

riverine.quantitate.hydrate_and_measure_conc_and_dilute_from_specs(filename: str, target_conc_high: float | str | riverine.units.DecimalQuantity, target_conc_low: float | str | riverine.units.DecimalQuantity, absorbances: dict[str, float | Sequence[float]], vols_removed: dict[str, None | float | str | riverine.units.DecimalQuantity] | None = None, enforce_utf8: bool = True) dict[str, tuple[riverine.units.DecimalQuantity, riverine.units.DecimalQuantity]][source]#

Like hydrate_and_measure_conc_and_dilute(), but works with multiple strands, using an IDT spec file to look up nmoles and extinction coefficients.

The intended usage of this method is to be used in conjunction with the function hydrate_from_specs() as follows.

>>> from riverine.quantitate import hydrate_from_specs, hydrate_and_measure_conc_and_dilute_from_specs
>>> specs_file = 'path/to/coa.csv'
>>> target_conc_high = '200 uM'
>>> target_conc_low = '100 uM'
>>> hydrate_from_specs(
...     filename=specs_file,
...     target_conc=target_conc_high,
...     strands=['5RF', '3RQ'],
... )
nmoles = 8.9 nmol
nmoles = 15.7 nmol
{'5RF': <Quantity(44.5, 'microliter')>,
 '3RQ': <Quantity(78.5, 'microliter')>}
>>> # now go to the lab and add the above quantities of water/buffer to the dry samples,
>>> # then measure absorbances, e.g., with a NanoDrop, to populate the dict `absorbances` below
>>> absorbances = {
...     '5RF': [48.46, 48.28],
...     '3RQ': [34.36, 34.82],
... }
>>> hydrate_and_measure_conc_and_dilute_from_specs(
...     filename=specs_file,
...     target_conc_high=target_conc_high,
...     target_conc_low=target_conc_low,
...     absorbances=absorbances,
... )
{'5RF': (<Quantity(213.931889, 'micromolar')>, <Quantity(48.4210528, 'microliter')>),
 '3RQ': (<Quantity(190.427429, 'micromolar')>, <Quantity(69.176983, 'microliter')>)}

Note in particular that we do not need to specify the volume prior to the dilution step, since it is calculated based on the volume necessary for the first hydration step to reach concentration target_conc_high.

For convenience in Jupyter notebooks, there are also versions of these functions beginning with display_: display_hydrate_from_specs() and display_hydrate_and_measure_conc_and_dilute_from_specs(). Instead of returning a dictionary, these methods display the result in the Jupyter notebook, as nicely-formatted Markdown.

Parameters:
  • filename – path to IDT Excel/CSV spreadsheet with specs of strands (e.g., coa.csv)

  • target_conc_high – target concentration for initial hydration. Should be higher than target_conc_low,

  • target_conc_low – the “real” target concentration that we will try to hit after the second addition of water/buffer.

  • absorbances – UV absorbances at 260 nm. Is a dict mapping each strand name to an “absorbance” as defined in the absobance parameter of hydrate_and_measure_conc_and_dilute(). In other words the value to which each strand name maps can either be a single float/int, or a nonempty sequence of floats/ints representing repeated measurements; if the latter then an average is taken.

  • vols_removed – Total volumes removed from vol to measure absorbance; is a dict mapping strand names (should be subset of strand names that are keys in absorbances). Can be None, or can have strictly fewer strand names than in absorbances; defaults are assumed as explained next for any missing strand name key. For example, if two samples were taken, one at 1 µL and one at 1.5 µL, then set vol_removed = 2.5 µL. If not specified, it is assumed that each sample is 1 µL, and that the total number of samples taken is the number of entries in absorbance. If absorbance is a single volume (e.g., float, int, str, DecimalQuantity), then it is assumed the number of samples is 1 (i.e., vol_removed = 1 µL), otherwise if absorbance is a list, then the length of the list is assumed to be the number of samples taken, each at 1 µL.

  • enforce_utf8 – If filename is a text CSV file and this paramter is True, it enforces that filename is valid UTF-8, raising an exception if not. This helps to avoid accidentally dropping Unicode characters such as µ, which would silently convert a volume from µL to L. If do not want to convert the specs file to UTF-8 and you are certain that no important Unicode characters would be dropped, then you can set this parameter to false.

Returns:

  • dict mapping each strand name in keys of absorbances to a pair (conc, vol_to_add),

  • where conc is the measured concentration according to the absorbance value(s) of that strandm

  • and vol_to_add is the volume needed to add to reach concentration target_conc_low.

riverine.quantitate.hydrate_from_specs(filename: str, target_conc: float | str | riverine.units.DecimalQuantity, strands: Sequence[str] | Sequence[int] | None = None, enforce_utf8: bool = True) dict[str, riverine.units.DecimalQuantity][source]#

Indicates how much volume to add to a dry DNA sample to reach a particular concentration, given data in an Excel file in the IDT format.

Parameters:
  • filename – path to IDT Excel/CSV spreadsheet with specs of strands (e.g., coa.csv)

  • target_conc – target concentration. If float/int, units are µM (micromolar).

  • strands – strands to hydrate. Can be list of strand names (strings), or list of of ints indicating which rows in the Excel spreadsheet to hydrate

  • enforce_utf8 – If filename is a text CSV file and this paramter is True, it enforces that filename is valid UTF-8, raising an exception if not. This helps to avoid accidentally dropping Unicode characters such as µ, which would silently convert a volume from µL to L. If do not want to convert the specs file to UTF-8 and you are certain that no important Unicode characters would be dropped, then you can set this parameter to false.

Returns:

  • dict mapping each strand name to an amount of µL (microliters) of water/buffer

  • to pipette to reach target_conc concentration for that strand